From bf88d232fb48d4b5bde458ee2fb8a8ee7024c148 Mon Sep 17 00:00:00 2001 From: shamoon <4887959+shamoon@users.noreply.github.com> Date: Tue, 16 Apr 2024 20:19:58 -0700 Subject: [PATCH] Customizable dashboard views --- .../e2e/dashboard/requests/api-dashboard1.har | 2 +- .../e2e/dashboard/requests/api-dashboard2.har | 2 +- .../e2e/dashboard/requests/api-dashboard3.har | 2 +- .../e2e/dashboard/requests/api-dashboard4.har | 2 +- .../saved-view-widget.component.html | 109 +++++++++----- .../saved-view-widget.component.scss | 49 ++++++- .../saved-view-widget.component.spec.ts | 134 +++++++++++++++++- .../saved-view-widget.component.ts | 107 +++++++++++--- .../widget-frame/widget-frame.component.html | 4 +- src-ui/src/app/data/saved-view.ts | 21 +++ ...7_savedview_dasboard_view_mode_and_more.py | 52 +++++++ src/documents/models.py | 33 +++++ src/documents/serialisers.py | 7 + 13 files changed, 452 insertions(+), 72 deletions(-) create mode 100644 src/documents/migrations/1047_savedview_dasboard_view_mode_and_more.py diff --git a/src-ui/e2e/dashboard/requests/api-dashboard1.har b/src-ui/e2e/dashboard/requests/api-dashboard1.har index 3e0829c2f..0cc2171f6 100644 --- a/src-ui/e2e/dashboard/requests/api-dashboard1.har +++ b/src-ui/e2e/dashboard/requests/api-dashboard1.har @@ -124,7 +124,7 @@ "content": { "size": -1, "mimeType": "application/json", - "text": "{\"count\":6,\"next\":null,\"previous\":null,\"all\":[8,17,7,4,11,15],\"results\":[{\"id\":8,\"name\":\"Correspondent 2\",\"show_on_dashboard\":false,\"show_in_sidebar\":false,\"sort_field\":\"created\",\"sort_reverse\":true,\"filter_rules\":[{\"rule_type\":3,\"value\":\"2\"}],\"owner\":\"2\",\"user_can_change\":true},{\"id\":17,\"name\":\"In the Last Month\",\"show_on_dashboard\":false,\"show_in_sidebar\":false,\"sort_field\":\"created\",\"sort_reverse\":true,\"filter_rules\":[{\"rule_type\":20,\"value\":\"created:[-1 month to now]\"}],\"owner\":\"2\",\"user_can_change\":true},{\"id\":7,\"name\":\"Inbox\",\"show_on_dashboard\":true,\"show_in_sidebar\":true,\"sort_field\":\"created\",\"sort_reverse\":true,\"filter_rules\":[{\"rule_type\":6,\"value\":\"9\"}],\"owner\":\"2\",\"user_can_change\":true},{\"id\":4,\"name\":\"Recently Added\",\"show_on_dashboard\":true,\"show_in_sidebar\":true,\"sort_field\":\"created\",\"sort_reverse\":true,\"filter_rules\":[],\"owner\":\"2\",\"user_can_change\":true},{\"id\":11,\"name\":\"Tag: Another Sample Tag\",\"show_on_dashboard\":false,\"show_in_sidebar\":true,\"sort_field\":\"created\",\"sort_reverse\":true,\"filter_rules\":[{\"rule_type\":6,\"value\":\"4\"}],\"owner\":\"2\",\"user_can_change\":true},{\"id\":15,\"name\":\"View ASN not empty\",\"show_on_dashboard\":false,\"show_in_sidebar\":false,\"sort_field\":\"created\",\"sort_reverse\":true,\"filter_rules\":[{\"rule_type\":18,\"value\":\"false\"}],\"owner\":\"2\",\"user_can_change\":true}]}" + "text": "{\"count\":6,\"next\":null,\"previous\":null,\"all\":[8,17,7,4,11,15],\"results\":[{\"id\":8,\"name\":\"Correspondent 2\",\"show_on_dashboard\":false,\"show_in_sidebar\":false,\"sort_field\":\"created\",\"sort_reverse\":true,\"filter_rules\":[{\"rule_type\":3,\"value\":\"2\"}],\"owner\":\"2\",\"user_can_change\":true,\"dashboard_view_limit\":10,\"dashboard_view_mode\":\"table\",\"dashboard_view_table_columns\":[\"created\",\"title\",\"tag\",\"documenttype\"]},{\"id\":17,\"name\":\"In the Last Month\",\"show_on_dashboard\":false,\"show_in_sidebar\":false,\"sort_field\":\"created\",\"sort_reverse\":true,\"filter_rules\":[{\"rule_type\":20,\"value\":\"created:[-1 month to now]\"}],\"owner\":\"2\",\"user_can_change\":true,\"dashboard_view_limit\":10,\"dashboard_view_mode\":\"table\",\"dashboard_view_table_columns\":[\"created\",\"title\",\"tag\",\"documenttype\"]},{\"id\":7,\"name\":\"Inbox\",\"show_on_dashboard\":true,\"show_in_sidebar\":true,\"sort_field\":\"created\",\"sort_reverse\":true,\"filter_rules\":[{\"rule_type\":6,\"value\":\"9\"}],\"owner\":\"2\",\"user_can_change\":true,\"dashboard_view_limit\":10,\"dashboard_view_mode\":\"table\",\"dashboard_view_table_columns\":[\"created\",\"title\",\"tag\",\"documenttype\"]},{\"id\":4,\"name\":\"Recently Added\",\"show_on_dashboard\":true,\"show_in_sidebar\":true,\"sort_field\":\"created\",\"sort_reverse\":true,\"filter_rules\":[],\"owner\":\"2\",\"user_can_change\":true,\"dashboard_view_limit\":10,\"dashboard_view_mode\":\"table\",\"dashboard_view_table_columns\":[\"created\",\"title\",\"tag\",\"documenttype\"]},{\"id\":11,\"name\":\"Tag: Another Sample Tag\",\"show_on_dashboard\":false,\"show_in_sidebar\":true,\"sort_field\":\"created\",\"sort_reverse\":true,\"filter_rules\":[{\"rule_type\":6,\"value\":\"4\"}],\"owner\":\"2\",\"user_can_change\":true,\"dashboard_view_limit\":10,\"dashboard_view_mode\":\"table\",\"dashboard_view_table_columns\":[\"created\",\"title\",\"tag\",\"documenttype\"]},{\"id\":15,\"name\":\"View ASN not empty\",\"show_on_dashboard\":false,\"show_in_sidebar\":false,\"sort_field\":\"created\",\"sort_reverse\":true,\"filter_rules\":[{\"rule_type\":18,\"value\":\"false\"}],\"owner\":\"2\",\"user_can_change\":true,\"dashboard_view_limit\":10,\"dashboard_view_mode\":\"table\",\"dashboard_view_table_columns\":[\"created\",\"title\",\"tag\",\"documenttype\"]}]}" }, "headersSize": -1, "bodySize": -1, diff --git a/src-ui/e2e/dashboard/requests/api-dashboard2.har b/src-ui/e2e/dashboard/requests/api-dashboard2.har index 2436a6272..f3b4e9e8b 100644 --- a/src-ui/e2e/dashboard/requests/api-dashboard2.har +++ b/src-ui/e2e/dashboard/requests/api-dashboard2.har @@ -124,7 +124,7 @@ "content": { "size": -1, "mimeType": "application/json", - "text": "{\"count\":6,\"next\":null,\"previous\":null,\"all\":[8,17,7,4,11,15],\"results\":[{\"id\":8,\"name\":\"Correspondent 2\",\"show_on_dashboard\":false,\"show_in_sidebar\":false,\"sort_field\":\"created\",\"sort_reverse\":true,\"filter_rules\":[{\"rule_type\":3,\"value\":\"2\"}],\"owner\":\"2\",\"user_can_change\":true},{\"id\":17,\"name\":\"In the Last Month\",\"show_on_dashboard\":false,\"show_in_sidebar\":false,\"sort_field\":\"created\",\"sort_reverse\":true,\"filter_rules\":[{\"rule_type\":20,\"value\":\"created:[-1 month to now]\"}],\"owner\":\"2\",\"user_can_change\":true},{\"id\":7,\"name\":\"Inbox\",\"show_on_dashboard\":true,\"show_in_sidebar\":true,\"sort_field\":\"created\",\"sort_reverse\":true,\"filter_rules\":[{\"rule_type\":6,\"value\":\"9\"}],\"owner\":\"2\",\"user_can_change\":true},{\"id\":4,\"name\":\"Recently Added\",\"show_on_dashboard\":true,\"show_in_sidebar\":true,\"sort_field\":\"created\",\"sort_reverse\":true,\"filter_rules\":[],\"owner\":\"2\",\"user_can_change\":true},{\"id\":11,\"name\":\"Tag: Another Sample Tag\",\"show_on_dashboard\":false,\"show_in_sidebar\":true,\"sort_field\":\"created\",\"sort_reverse\":true,\"filter_rules\":[{\"rule_type\":6,\"value\":\"4\"}],\"owner\":\"2\",\"user_can_change\":true},{\"id\":15,\"name\":\"View ASN not empty\",\"show_on_dashboard\":false,\"show_in_sidebar\":false,\"sort_field\":\"created\",\"sort_reverse\":true,\"filter_rules\":[{\"rule_type\":18,\"value\":\"false\"}],\"owner\":\"2\",\"user_can_change\":true}]}" + "text": "{\"count\":6,\"next\":null,\"previous\":null,\"all\":[8,17,7,4,11,15],\"results\":[{\"id\":8,\"name\":\"Correspondent 2\",\"show_on_dashboard\":false,\"show_in_sidebar\":false,\"sort_field\":\"created\",\"sort_reverse\":true,\"filter_rules\":[{\"rule_type\":3,\"value\":\"2\"}],\"owner\":\"2\",\"user_can_change\":true,\"dashboard_view_limit\":10,\"dashboard_view_mode\":\"table\",\"dashboard_view_table_columns\":[\"created\",\"title\",\"tag\",\"documenttype\"]},{\"id\":17,\"name\":\"In the Last Month\",\"show_on_dashboard\":false,\"show_in_sidebar\":false,\"sort_field\":\"created\",\"sort_reverse\":true,\"filter_rules\":[{\"rule_type\":20,\"value\":\"created:[-1 month to now]\"}],\"owner\":\"2\",\"user_can_change\":true,\"dashboard_view_limit\":10,\"dashboard_view_mode\":\"table\",\"dashboard_view_table_columns\":[\"created\",\"title\",\"tag\",\"documenttype\"]},{\"id\":7,\"name\":\"Inbox\",\"show_on_dashboard\":true,\"show_in_sidebar\":true,\"sort_field\":\"created\",\"sort_reverse\":true,\"filter_rules\":[{\"rule_type\":6,\"value\":\"9\"}],\"owner\":\"2\",\"user_can_change\":true,\"dashboard_view_limit\":10,\"dashboard_view_mode\":\"table\",\"dashboard_view_table_columns\":[\"created\",\"title\",\"tag\",\"documenttype\"]},{\"id\":4,\"name\":\"Recently Added\",\"show_on_dashboard\":true,\"show_in_sidebar\":true,\"sort_field\":\"created\",\"sort_reverse\":true,\"filter_rules\":[],\"owner\":\"2\",\"user_can_change\":true,\"dashboard_view_limit\":10,\"dashboard_view_mode\":\"table\",\"dashboard_view_table_columns\":[\"created\",\"title\",\"tag\",\"documenttype\"]},{\"id\":11,\"name\":\"Tag: Another Sample Tag\",\"show_on_dashboard\":false,\"show_in_sidebar\":true,\"sort_field\":\"created\",\"sort_reverse\":true,\"filter_rules\":[{\"rule_type\":6,\"value\":\"4\"}],\"owner\":\"2\",\"user_can_change\":true,\"dashboard_view_limit\":10,\"dashboard_view_mode\":\"table\",\"dashboard_view_table_columns\":[\"created\",\"title\",\"tag\",\"documenttype\"]},{\"id\":15,\"name\":\"View ASN not empty\",\"show_on_dashboard\":false,\"show_in_sidebar\":false,\"sort_field\":\"created\",\"sort_reverse\":true,\"filter_rules\":[{\"rule_type\":18,\"value\":\"false\"}],\"owner\":\"2\",\"user_can_change\":true,\"dashboard_view_limit\":10,\"dashboard_view_mode\":\"table\",\"dashboard_view_table_columns\":[\"created\",\"title\",\"tag\",\"documenttype\"]}]}" }, "headersSize": -1, "bodySize": -1, diff --git a/src-ui/e2e/dashboard/requests/api-dashboard3.har b/src-ui/e2e/dashboard/requests/api-dashboard3.har index 328c9db6e..8e3c59b55 100644 --- a/src-ui/e2e/dashboard/requests/api-dashboard3.har +++ b/src-ui/e2e/dashboard/requests/api-dashboard3.har @@ -124,7 +124,7 @@ "content": { "size": -1, "mimeType": "application/json", - "text": "{\"count\":6,\"next\":null,\"previous\":null,\"all\":[8,17,7,4,11,15],\"results\":[{\"id\":8,\"name\":\"Correspondent 2\",\"show_on_dashboard\":false,\"show_in_sidebar\":false,\"sort_field\":\"created\",\"sort_reverse\":true,\"filter_rules\":[{\"rule_type\":3,\"value\":\"2\"}],\"owner\":\"2\",\"user_can_change\":true},{\"id\":17,\"name\":\"In the Last Month\",\"show_on_dashboard\":false,\"show_in_sidebar\":false,\"sort_field\":\"created\",\"sort_reverse\":true,\"filter_rules\":[{\"rule_type\":20,\"value\":\"created:[-1 month to now]\"}],\"owner\":\"2\",\"user_can_change\":true},{\"id\":7,\"name\":\"Inbox\",\"show_on_dashboard\":true,\"show_in_sidebar\":true,\"sort_field\":\"created\",\"sort_reverse\":true,\"filter_rules\":[{\"rule_type\":6,\"value\":\"9\"}],\"owner\":\"2\",\"user_can_change\":true},{\"id\":4,\"name\":\"Recently Added\",\"show_on_dashboard\":true,\"show_in_sidebar\":true,\"sort_field\":\"created\",\"sort_reverse\":true,\"filter_rules\":[],\"owner\":\"2\",\"user_can_change\":true},{\"id\":11,\"name\":\"Tag: Another Sample Tag\",\"show_on_dashboard\":false,\"show_in_sidebar\":true,\"sort_field\":\"created\",\"sort_reverse\":true,\"filter_rules\":[{\"rule_type\":6,\"value\":\"4\"}],\"owner\":\"2\",\"user_can_change\":true},{\"id\":15,\"name\":\"View ASN not empty\",\"show_on_dashboard\":false,\"show_in_sidebar\":false,\"sort_field\":\"created\",\"sort_reverse\":true,\"filter_rules\":[{\"rule_type\":18,\"value\":\"false\"}],\"owner\":\"2\",\"user_can_change\":true}]}" + "text": "{\"count\":6,\"next\":null,\"previous\":null,\"all\":[8,17,7,4,11,15],\"results\":[{\"id\":8,\"name\":\"Correspondent 2\",\"show_on_dashboard\":false,\"show_in_sidebar\":false,\"sort_field\":\"created\",\"sort_reverse\":true,\"filter_rules\":[{\"rule_type\":3,\"value\":\"2\"}],\"owner\":\"2\",\"user_can_change\":true,\"dashboard_view_limit\":10,\"dashboard_view_mode\":\"table\",\"dashboard_view_table_columns\":[\"created\",\"title\",\"tag\",\"documenttype\"]},{\"id\":17,\"name\":\"In the Last Month\",\"show_on_dashboard\":false,\"show_in_sidebar\":false,\"sort_field\":\"created\",\"sort_reverse\":true,\"filter_rules\":[{\"rule_type\":20,\"value\":\"created:[-1 month to now]\"}],\"owner\":\"2\",\"user_can_change\":true,\"dashboard_view_limit\":10,\"dashboard_view_mode\":\"table\",\"dashboard_view_table_columns\":[\"created\",\"title\",\"tag\",\"documenttype\"]},{\"id\":7,\"name\":\"Inbox\",\"show_on_dashboard\":true,\"show_in_sidebar\":true,\"sort_field\":\"created\",\"sort_reverse\":true,\"filter_rules\":[{\"rule_type\":6,\"value\":\"9\"}],\"owner\":\"2\",\"user_can_change\":true,\"dashboard_view_limit\":10,\"dashboard_view_mode\":\"table\",\"dashboard_view_table_columns\":[\"created\",\"title\",\"tag\",\"documenttype\"]},{\"id\":4,\"name\":\"Recently Added\",\"show_on_dashboard\":true,\"show_in_sidebar\":true,\"sort_field\":\"created\",\"sort_reverse\":true,\"filter_rules\":[],\"owner\":\"2\",\"user_can_change\":true,\"dashboard_view_limit\":10,\"dashboard_view_mode\":\"table\",\"dashboard_view_table_columns\":[\"created\",\"title\",\"tag\",\"documenttype\"]},{\"id\":11,\"name\":\"Tag: Another Sample Tag\",\"show_on_dashboard\":false,\"show_in_sidebar\":true,\"sort_field\":\"created\",\"sort_reverse\":true,\"filter_rules\":[{\"rule_type\":6,\"value\":\"4\"}],\"owner\":\"2\",\"user_can_change\":true,\"dashboard_view_limit\":10,\"dashboard_view_mode\":\"table\",\"dashboard_view_table_columns\":[\"created\",\"title\",\"tag\",\"documenttype\"]},{\"id\":15,\"name\":\"View ASN not empty\",\"show_on_dashboard\":false,\"show_in_sidebar\":false,\"sort_field\":\"created\",\"sort_reverse\":true,\"filter_rules\":[{\"rule_type\":18,\"value\":\"false\"}],\"owner\":\"2\",\"user_can_change\":true,\"dashboard_view_limit\":10,\"dashboard_view_mode\":\"table\",\"dashboard_view_table_columns\":[\"created\",\"title\",\"tag\",\"documenttype\"]}]}" }, "headersSize": -1, "bodySize": -1, diff --git a/src-ui/e2e/dashboard/requests/api-dashboard4.har b/src-ui/e2e/dashboard/requests/api-dashboard4.har index ca0101d59..53a835307 100644 --- a/src-ui/e2e/dashboard/requests/api-dashboard4.har +++ b/src-ui/e2e/dashboard/requests/api-dashboard4.har @@ -124,7 +124,7 @@ "content": { "size": -1, "mimeType": "application/json", - "text": "{\"count\":6,\"next\":null,\"previous\":null,\"all\":[8,17,7,4,11,15],\"results\":[{\"id\":8,\"name\":\"Correspondent 2\",\"show_on_dashboard\":false,\"show_in_sidebar\":false,\"sort_field\":\"created\",\"sort_reverse\":true,\"filter_rules\":[{\"rule_type\":3,\"value\":\"2\"}],\"owner\":\"2\",\"user_can_change\":true},{\"id\":7,\"name\":\"Inbox\",\"show_on_dashboard\":true,\"show_in_sidebar\":true,\"sort_field\":\"created\",\"sort_reverse\":true,\"filter_rules\":[{\"rule_type\":6,\"value\":\"9\"}],\"owner\":\"2\",\"user_can_change\":true},{\"id\":11,\"name\":\"Tag: Another Sample Tag\",\"show_on_dashboard\":false,\"show_in_sidebar\":true,\"sort_field\":\"created\",\"sort_reverse\":true,\"filter_rules\":[{\"rule_type\":6,\"value\":\"4\"}],\"owner\":\"2\",\"user_can_change\":true}]}" + "text": "{\"count\":6,\"next\":null,\"previous\":null,\"all\":[8,17,7,4,11,15],\"results\":[{\"id\":8,\"name\":\"Correspondent 2\",\"show_on_dashboard\":false,\"show_in_sidebar\":false,\"sort_field\":\"created\",\"sort_reverse\":true,\"filter_rules\":[{\"rule_type\":3,\"value\":\"2\"}],\"owner\":\"2\",\"user_can_change\":true,\"dashboard_view_limit\":10,\"dashboard_view_mode\":\"table\",\"dashboard_view_table_columns\":[\"created\",\"title\",\"tag\",\"documenttype\"]},{\"id\":17,\"name\":\"In the Last Month\",\"show_on_dashboard\":false,\"show_in_sidebar\":false,\"sort_field\":\"created\",\"sort_reverse\":true,\"filter_rules\":[{\"rule_type\":20,\"value\":\"created:[-1 month to now]\"}],\"owner\":\"2\",\"user_can_change\":true,\"dashboard_view_limit\":10,\"dashboard_view_mode\":\"table\",\"dashboard_view_table_columns\":[\"created\",\"title\",\"tag\",\"documenttype\"]},{\"id\":7,\"name\":\"Inbox\",\"show_on_dashboard\":true,\"show_in_sidebar\":true,\"sort_field\":\"created\",\"sort_reverse\":true,\"filter_rules\":[{\"rule_type\":6,\"value\":\"9\"}],\"owner\":\"2\",\"user_can_change\":true,\"dashboard_view_limit\":10,\"dashboard_view_mode\":\"table\",\"dashboard_view_table_columns\":[\"created\",\"title\",\"tag\",\"documenttype\"]},{\"id\":4,\"name\":\"Recently Added\",\"show_on_dashboard\":true,\"show_in_sidebar\":true,\"sort_field\":\"created\",\"sort_reverse\":true,\"filter_rules\":[],\"owner\":\"2\",\"user_can_change\":true,\"dashboard_view_limit\":10,\"dashboard_view_mode\":\"table\",\"dashboard_view_table_columns\":[\"created\",\"title\",\"tag\",\"documenttype\"]},{\"id\":11,\"name\":\"Tag: Another Sample Tag\",\"show_on_dashboard\":false,\"show_in_sidebar\":true,\"sort_field\":\"created\",\"sort_reverse\":true,\"filter_rules\":[{\"rule_type\":6,\"value\":\"4\"}],\"owner\":\"2\",\"user_can_change\":true,\"dashboard_view_limit\":10,\"dashboard_view_mode\":\"table\",\"dashboard_view_table_columns\":[\"created\",\"title\",\"tag\",\"documenttype\"]},{\"id\":15,\"name\":\"View ASN not empty\",\"show_on_dashboard\":false,\"show_in_sidebar\":false,\"sort_field\":\"created\",\"sort_reverse\":true,\"filter_rules\":[{\"rule_type\":18,\"value\":\"false\"}],\"owner\":\"2\",\"user_can_change\":true,\"dashboard_view_limit\":10,\"dashboard_view_mode\":\"table\",\"dashboard_view_table_columns\":[\"created\",\"title\",\"tag\",\"documenttype\"]}]}" }, "headersSize": -1, "bodySize": -1, diff --git a/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html b/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html index de46991d2..b8e02bfac 100644 --- a/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html +++ b/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html @@ -9,58 +9,89 @@ Show all } - @if (documents.length) { -
Created | -Title | - @if (permissionsService.currentUserCan(PermissionAction.View, PermissionType.Tag)) { -Tags | - } - @if (permissionsService.currentUserCan(PermissionAction.View, PermissionType.Correspondent)) { -Correspondent | - } @else { -+ @for (column of savedView.dashboard_view_table_columns; track column; let i = $index) { + @if (columnIsVisible(column)) { + | 1, + 'w-25': column === DashboardViewTableColumn.CREATED || column === DashboardViewTableColumn.ADDED + }"> + {{ getColumnTitle(column) }} + | + } }
---|---|---|---|---|---|
{{doc.created_date | customDate}} | -- {{doc.title | documentTitle}} - | - @if (permissionsService.currentUserCan(PermissionAction.View, PermissionType.Tag)) { -
- @for (t of doc.tags$ | async; track t) {
- |
- }
- - @if (permissionsService.currentUserCan(PermissionAction.View, PermissionType.Correspondent) && doc.correspondent !== null) { - {{(doc.correspondent$ | async)?.name}} + @for (column of savedView.dashboard_view_table_columns; track column; let i = $index) { + @if (columnIsVisible(column)) { + | 1 }">
+ @switch (column) {
+ @case (DashboardViewTableColumn.ADDED) {
+ {{doc.added | customDate}}
+ }
+ @case (DashboardViewTableColumn.CREATED) {
+ {{doc.created_date | customDate}}
+ }
+ @case (DashboardViewTableColumn.TITLE) {
+ {{doc.title | documentTitle}}
+ }
+ @case (DashboardViewTableColumn.CORRESPONDENT) {
+ @if (doc.correspondent) {
+ {{(doc.correspondent$ | async)?.name}}
+ }
+ }
+ @case (DashboardViewTableColumn.TAGS) {
+ @for (t of doc.tags$ | async; track t) {
+ |
}
-
-
+ }
No documents
} diff --git a/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.scss b/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.scss index bf1894b48..8c445f18e 100644 --- a/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.scss +++ b/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.scss @@ -3,10 +3,9 @@ table { table-layout: fixed; } -th:first-child { - width: 25%; - @media (min-width: 768px) { - width: 15%; +@media (min-width: 768px) { + th.w-25 { + width: 15% !important; } } @@ -30,3 +29,45 @@ td.py-3 { padding-top: 0.75em !important; padding-bottom: 0.75em !important; } + +$paperless-card-breakpoints: ( + // 0: 2, // xs is manual for slim-sidebar + 768px: 2, //md + 992px: 2, //lg + 1200px: 3, //xl + 1600px: 4, + 1800px: 5, + 2000px: 6 +); + +.row-cols-paperless-cards { + // xs, we dont want in .col-slim block + > * { + flex: 0 0 auto; + width: calc(100% / 2); + } + + @each $width, $n_cols in $paperless-card-breakpoints { + @media(min-width: $width) { + > * { + flex: 0 0 auto; + width: calc(100% / $n-cols); + } + } + } +} + +::ng-deep .col-slim .row-cols-paperless-cards { + @each $width, $n_cols in $paperless-card-breakpoints { + @media(min-width: $width) { + > * { + flex: 0 0 auto; + width: calc(100% / ($n-cols + 1)) !important; + } + } + } +} + +::ng-deep .document-card-check { + display: none !important; // override for dashboard +} diff --git a/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.spec.ts b/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.spec.ts index 545f5696b..2ace024a1 100644 --- a/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.spec.ts +++ b/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.spec.ts @@ -11,8 +11,17 @@ import { RouterTestingModule } from '@angular/router/testing' import { NgbModule } from '@ng-bootstrap/ng-bootstrap' import { of, Subject } from 'rxjs' import { routes } from 'src/app/app-routing.module' -import { FILTER_HAS_TAGS_ALL } from 'src/app/data/filter-rule-type' -import { SavedView } from 'src/app/data/saved-view' +import { + FILTER_CORRESPONDENT, + FILTER_DOCUMENT_TYPE, + FILTER_HAS_TAGS_ALL, + FILTER_STORAGE_PATH, +} from 'src/app/data/filter-rule-type' +import { + DashboardViewMode, + DashboardViewTableColumn, + SavedView, +} from 'src/app/data/saved-view' import { IfPermissionsDirective } from 'src/app/directives/if-permissions.directive' import { PermissionsGuard } from 'src/app/guards/permissions.guard' import { CustomDatePipe } from 'src/app/pipes/custom-date.pipe' @@ -45,6 +54,14 @@ const savedView: SavedView = { value: '1,2', }, ], + dashboard_view_limit: 20, + dashboard_view_mode: DashboardViewMode.TABLE, + dashboard_view_table_columns: [ + DashboardViewTableColumn.CREATED, + DashboardViewTableColumn.TITLE, + DashboardViewTableColumn.TAGS, + DashboardViewTableColumn.CORRESPONDENT, + ], } const documentResults = [ @@ -170,7 +187,7 @@ describe('SavedViewWidgetComponent', () => { component.ngOnInit() expect(listAllSpy).toHaveBeenCalledWith( 1, - 10, + 20, savedView.sort_field, savedView.sort_reverse, savedView.filter_rules, @@ -204,11 +221,120 @@ describe('SavedViewWidgetComponent', () => { }) }) + it('should navigate to document', () => { + const routerSpy = jest.spyOn(router, 'navigate') + component.openDocumentDetail(documentResults[0]) + expect(routerSpy).toHaveBeenCalledWith(['documents', documentResults[0].id]) + }) + it('should navigate via quickfilter on click tag', () => { const qfSpy = jest.spyOn(documentListViewService, 'quickFilter') - component.clickTag({ id: 11, name: 'Tag11' }, new MouseEvent('click')) + component.clickTag(11, new MouseEvent('click')) expect(qfSpy).toHaveBeenCalledWith([ { rule_type: FILTER_HAS_TAGS_ALL, value: '11' }, ]) + component.clickTag(11) // coverage + }) + + it('should navigate via quickfilter on click correspondent', () => { + const qfSpy = jest.spyOn(documentListViewService, 'quickFilter') + component.clickCorrespondent(11, new MouseEvent('click')) + expect(qfSpy).toHaveBeenCalledWith([ + { rule_type: FILTER_CORRESPONDENT, value: '11' }, + ]) + component.clickCorrespondent(11) // coverage + }) + + it('should navigate via quickfilter on click doc type', () => { + const qfSpy = jest.spyOn(documentListViewService, 'quickFilter') + component.clickDocType(11, new MouseEvent('click')) + expect(qfSpy).toHaveBeenCalledWith([ + { rule_type: FILTER_DOCUMENT_TYPE, value: '11' }, + ]) + component.clickDocType(11) // coverage + }) + + it('should navigate via quickfilter on click storage path', () => { + const qfSpy = jest.spyOn(documentListViewService, 'quickFilter') + component.clickStoragePath(11, new MouseEvent('click')) + expect(qfSpy).toHaveBeenCalledWith([ + { rule_type: FILTER_STORAGE_PATH, value: '11' }, + ]) + component.clickStoragePath(11) // coverage + }) + + it('should get correct column title', () => { + expect(component.getColumnTitle(DashboardViewTableColumn.TITLE)).toEqual( + 'Title' + ) + expect(component.getColumnTitle(DashboardViewTableColumn.CREATED)).toEqual( + 'Created' + ) + expect(component.getColumnTitle(DashboardViewTableColumn.ADDED)).toEqual( + 'Added' + ) + expect(component.getColumnTitle(DashboardViewTableColumn.TAGS)).toEqual( + 'Tags' + ) + expect( + component.getColumnTitle(DashboardViewTableColumn.CORRESPONDENT) + ).toEqual('Correspondent') + expect( + component.getColumnTitle(DashboardViewTableColumn.DOCUMENT_TYPE) + ).toEqual('Document type') + expect( + component.getColumnTitle(DashboardViewTableColumn.STORAGE_PATH) + ).toEqual('Storage path') + }) + + it('should check if column is visible including permissions', () => { + expect( + component.columnIsVisible(DashboardViewTableColumn.TITLE) + ).toBeTruthy() + expect( + component.columnIsVisible(DashboardViewTableColumn.CREATED) + ).toBeTruthy() + expect( + component.columnIsVisible(DashboardViewTableColumn.ADDED) + ).toBeTruthy() + expect( + component.columnIsVisible(DashboardViewTableColumn.TAGS) + ).toBeTruthy() + expect( + component.columnIsVisible(DashboardViewTableColumn.CORRESPONDENT) + ).toBeTruthy() + expect( + component.columnIsVisible(DashboardViewTableColumn.DOCUMENT_TYPE) + ).toBeTruthy() + expect( + component.columnIsVisible(DashboardViewTableColumn.STORAGE_PATH) + ).toBeTruthy() + + jest + .spyOn(component.permissionsService, 'currentUserCan') + .mockReturnValue(false) + expect( + component.columnIsVisible(DashboardViewTableColumn.TITLE) + ).toBeTruthy() + expect( + component.columnIsVisible(DashboardViewTableColumn.CREATED) + ).toBeTruthy() + expect( + component.columnIsVisible(DashboardViewTableColumn.ADDED) + ).toBeTruthy() + expect(component.columnIsVisible(DashboardViewTableColumn.TAGS)).toBeFalsy() + expect( + component.columnIsVisible(DashboardViewTableColumn.CORRESPONDENT) + ).toBeFalsy() + expect( + component.columnIsVisible(DashboardViewTableColumn.DOCUMENT_TYPE) + ).toBeFalsy() + expect( + component.columnIsVisible(DashboardViewTableColumn.STORAGE_PATH) + ).toBeFalsy() + + expect( + component.columnIsVisible('unknown' as DashboardViewTableColumn) + ).toBeFalsy() // coverage }) }) diff --git a/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.ts b/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.ts index c81ea5484..cddfd2bf5 100644 --- a/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.ts +++ b/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.ts @@ -6,23 +6,31 @@ import { QueryList, ViewChildren, } from '@angular/core' -import { Params, Router } from '@angular/router' +import { Router } from '@angular/router' import { Subject, takeUntil } from 'rxjs' import { Document } from 'src/app/data/document' -import { SavedView } from 'src/app/data/saved-view' +import { + DashboardViewTableColumn, + DashboardViewMode, + SavedView, +} from 'src/app/data/saved-view' import { ConsumerStatusService } from 'src/app/services/consumer-status.service' import { DocumentService } from 'src/app/services/rest/document.service' -import { Tag } from 'src/app/data/tag' import { FILTER_CORRESPONDENT, + FILTER_DOCUMENT_TYPE, FILTER_HAS_TAGS_ALL, + FILTER_STORAGE_PATH, } from 'src/app/data/filter-rule-type' import { OpenDocumentsService } from 'src/app/services/open-documents.service' import { DocumentListViewService } from 'src/app/services/document-list-view.service' import { ComponentWithPermissions } from 'src/app/components/with-permissions/with-permissions.component' import { NgbPopover } from '@ng-bootstrap/ng-bootstrap' -import { queryParamsFromFilterRules } from 'src/app/utils/query-params' -import { PermissionsService } from 'src/app/services/permissions.service' +import { + PermissionAction, + PermissionType, + PermissionsService, +} from 'src/app/services/permissions.service' @Component({ selector: 'pngx-saved-view-widget', @@ -33,6 +41,9 @@ export class SavedViewWidgetComponent extends ComponentWithPermissions implements OnInit, OnDestroy { + public DashboardViewMode = DashboardViewMode + public DashboardViewTableColumn = DashboardViewTableColumn + loading: boolean = true constructor( @@ -80,7 +91,7 @@ export class SavedViewWidgetComponent this.documentService .listFiltered( 1, - 10, + this.savedView.dashboard_view_limit, this.savedView.sort_field, this.savedView.sort_reverse, this.savedView.filter_rules, @@ -103,15 +114,46 @@ export class SavedViewWidgetComponent } } - clickTag(tag: Tag, event: MouseEvent) { - event.preventDefault() - event.stopImmediatePropagation() + clickTag(tagID: number, event: MouseEvent = null) { + event?.preventDefault() + event?.stopImmediatePropagation() this.list.quickFilter([ - { rule_type: FILTER_HAS_TAGS_ALL, value: tag.id.toString() }, + { rule_type: FILTER_HAS_TAGS_ALL, value: tagID.toString() }, ]) } + clickCorrespondent(correspondentId: number, event: MouseEvent = null) { + event?.preventDefault() + event?.stopImmediatePropagation() + + this.list.quickFilter([ + { rule_type: FILTER_CORRESPONDENT, value: correspondentId.toString() }, + ]) + } + + clickDocType(docTypeId: number, event: MouseEvent = null) { + event?.preventDefault() + event?.stopImmediatePropagation() + + this.list.quickFilter([ + { rule_type: FILTER_DOCUMENT_TYPE, value: docTypeId.toString() }, + ]) + } + + clickStoragePath(storagePathId: number, event: MouseEvent = null) { + event?.preventDefault() + event?.stopImmediatePropagation() + + this.list.quickFilter([ + { rule_type: FILTER_STORAGE_PATH, value: storagePathId.toString() }, + ]) + } + + openDocumentDetail(document: Document) { + this.router.navigate(['documents', document.id]) + } + getPreviewUrl(document: Document): string { return this.documentService.getPreviewUrl(document.id) } @@ -161,14 +203,41 @@ export class SavedViewWidgetComponent }, 300) } - getCorrespondentQueryParams(correspondentId: number): Params { - return correspondentId !== undefined - ? queryParamsFromFilterRules([ - { - rule_type: FILTER_CORRESPONDENT, - value: correspondentId.toString(), - }, - ]) - : null + public columnIsVisible(column: DashboardViewTableColumn): boolean { + if ( + [ + DashboardViewTableColumn.TITLE, + DashboardViewTableColumn.CREATED, + DashboardViewTableColumn.ADDED, + ].includes(column) + ) { + return true + } else { + const type: PermissionType = Object.values(PermissionType).find((t) => + t.includes(column) + ) + return type + ? this.permissionsService.currentUserCan(PermissionAction.View, type) + : false + } + } + + public getColumnTitle(column: DashboardViewTableColumn): string { + switch (column) { + case DashboardViewTableColumn.TITLE: + return $localize`Title` + case DashboardViewTableColumn.CREATED: + return $localize`Created` + case DashboardViewTableColumn.ADDED: + return $localize`Added` + case DashboardViewTableColumn.TAGS: + return $localize`Tags` + case DashboardViewTableColumn.CORRESPONDENT: + return $localize`Correspondent` + case DashboardViewTableColumn.DOCUMENT_TYPE: + return $localize`Document type` + case DashboardViewTableColumn.STORAGE_PATH: + return $localize`Storage path` + } } } diff --git a/src-ui/src/app/components/dashboard/widgets/widget-frame/widget-frame.component.html b/src-ui/src/app/components/dashboard/widgets/widget-frame/widget-frame.component.html index 49af71b08..b64d5e567 100644 --- a/src-ui/src/app/components/dashboard/widgets/widget-frame/widget-frame.component.html +++ b/src-ui/src/app/components/dashboard/widgets/widget-frame/widget-frame.component.html @@ -13,11 +13,11 @@