Customizable dashboard views
This commit is contained in:
parent
8e39315586
commit
bf88d232fb
@ -124,7 +124,7 @@
|
|||||||
"content": {
|
"content": {
|
||||||
"size": -1,
|
"size": -1,
|
||||||
"mimeType": "application/json",
|
"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,
|
"headersSize": -1,
|
||||||
"bodySize": -1,
|
"bodySize": -1,
|
||||||
|
@ -124,7 +124,7 @@
|
|||||||
"content": {
|
"content": {
|
||||||
"size": -1,
|
"size": -1,
|
||||||
"mimeType": "application/json",
|
"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,
|
"headersSize": -1,
|
||||||
"bodySize": -1,
|
"bodySize": -1,
|
||||||
|
@ -124,7 +124,7 @@
|
|||||||
"content": {
|
"content": {
|
||||||
"size": -1,
|
"size": -1,
|
||||||
"mimeType": "application/json",
|
"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,
|
"headersSize": -1,
|
||||||
"bodySize": -1,
|
"bodySize": -1,
|
||||||
|
@ -124,7 +124,7 @@
|
|||||||
"content": {
|
"content": {
|
||||||
"size": -1,
|
"size": -1,
|
||||||
"mimeType": "application/json",
|
"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,
|
"headersSize": -1,
|
||||||
"bodySize": -1,
|
"bodySize": -1,
|
||||||
|
@ -9,40 +9,62 @@
|
|||||||
<a class="btn-link text-decoration-none" header-buttons [routerLink]="[]" (click)="showAll()" i18n>Show all</a>
|
<a class="btn-link text-decoration-none" header-buttons [routerLink]="[]" (click)="showAll()" i18n>Show all</a>
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (documents.length) {
|
@if (documents.length && savedView.dashboard_view_mode === DashboardViewMode.TABLE) {
|
||||||
<table content class="table table-hover mb-0 align-middle">
|
<table content class="table table-hover mb-0 mt-n2 align-middle">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col" i18n>Created</th>
|
@for (column of savedView.dashboard_view_table_columns; track column; let i = $index) {
|
||||||
<th scope="col" i18n>Title</th>
|
@if (columnIsVisible(column)) {
|
||||||
@if (permissionsService.currentUserCan(PermissionAction.View, PermissionType.Tag)) {
|
<th
|
||||||
<th scope="col" class="d-none d-md-table-cell" i18n>Tags</th>
|
scope="col"
|
||||||
|
[ngClass]="{
|
||||||
|
'd-none d-md-table-cell': i > 1,
|
||||||
|
'w-25': column === DashboardViewTableColumn.CREATED || column === DashboardViewTableColumn.ADDED
|
||||||
|
}">
|
||||||
|
{{ getColumnTitle(column) }}
|
||||||
|
</th>
|
||||||
}
|
}
|
||||||
@if (permissionsService.currentUserCan(PermissionAction.View, PermissionType.Correspondent)) {
|
|
||||||
<th scope="col" class="d-none d-md-table-cell" i18n>Correspondent</th>
|
|
||||||
} @else {
|
|
||||||
<th scope="col" class="d-none d-md-table-cell"></th>
|
|
||||||
}
|
}
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@for (doc of documents; track doc) {
|
@for (doc of documents; track doc) {
|
||||||
<tr (mouseleave)="maybeClosePopover()">
|
<tr (mouseleave)="maybeClosePopover()">
|
||||||
<td class="py-2 py-md-3"><a routerLink="/documents/{{doc.id}}" class="btn-link text-dark text-decoration-none py-2 py-md-3">{{doc.created_date | customDate}}</a></td>
|
@for (column of savedView.dashboard_view_table_columns; track column; let i = $index) {
|
||||||
<td class="py-2 py-md-3">
|
@if (columnIsVisible(column)) {
|
||||||
|
<td class="py-2 py-md-3 position-relative" [ngClass]="{ 'd-none d-md-table-cell': i > 1 }">
|
||||||
|
@switch (column) {
|
||||||
|
@case (DashboardViewTableColumn.ADDED) {
|
||||||
|
<a routerLink="/documents/{{doc.id}}" class="btn-link text-dark text-decoration-none py-2 py-md-3">{{doc.added | customDate}}</a>
|
||||||
|
}
|
||||||
|
@case (DashboardViewTableColumn.CREATED) {
|
||||||
|
<a routerLink="/documents/{{doc.id}}" class="btn-link text-dark text-decoration-none py-2 py-md-3">{{doc.created_date | customDate}}</a>
|
||||||
|
}
|
||||||
|
@case (DashboardViewTableColumn.TITLE) {
|
||||||
<a routerLink="/documents/{{doc.id}}" title="Edit" i18n-title class="btn-link text-dark text-decoration-none py-2 py-md-3">{{doc.title | documentTitle}}</a>
|
<a routerLink="/documents/{{doc.id}}" title="Edit" i18n-title class="btn-link text-dark text-decoration-none py-2 py-md-3">{{doc.title | documentTitle}}</a>
|
||||||
</td>
|
}
|
||||||
@if (permissionsService.currentUserCan(PermissionAction.View, PermissionType.Tag)) {
|
@case (DashboardViewTableColumn.CORRESPONDENT) {
|
||||||
<td class="py-2 py-md-3 d-none d-md-table-cell">
|
@if (doc.correspondent) {
|
||||||
|
<a class="btn-link text-dark text-decoration-none" type="button" (click)="clickCorrespondent(doc.correspondent, $event)">{{(doc.correspondent$ | async)?.name}}</a>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@case (DashboardViewTableColumn.TAGS) {
|
||||||
@for (t of doc.tags$ | async; track t) {
|
@for (t of doc.tags$ | async; track t) {
|
||||||
<pngx-tag [tag]="t" class="ms-1" (click)="clickTag(t, $event)"></pngx-tag>
|
<pngx-tag [tag]="t" class="ms-1" (click)="clickTag(t.id, $event)"></pngx-tag>
|
||||||
}
|
}
|
||||||
</td>
|
|
||||||
}
|
}
|
||||||
<td class="position-relative py-2 py-md-3 d-none d-md-table-cell">
|
@case (DashboardViewTableColumn.DOCUMENT_TYPE) {
|
||||||
@if (permissionsService.currentUserCan(PermissionAction.View, PermissionType.Correspondent) && doc.correspondent !== null) {
|
@if (doc.document_type) {
|
||||||
<a class="btn-link text-dark text-decoration-none py-2 py-md-3" routerLink="/documents" [queryParams]="getCorrespondentQueryParams(doc.correspondent)">{{(doc.correspondent$ | async)?.name}}</a>
|
<a class="btn-link text-dark text-decoration-none" type="button" (click)="clickDocType(doc.document_type, $event)">{{(doc.document_type$ | async)?.name}}</a>
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@case (DashboardViewTableColumn.STORAGE_PATH) {
|
||||||
|
@if (doc.storage_path) {
|
||||||
|
<a class="btn-link text-dark text-decoration-none" type="button" (click)="clickStoragePath(doc.storage_path, $event)">{{(doc.storage_path$ | async)?.name}}</a>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@if (i === savedView.dashboard_view_table_columns.length - 1) {
|
||||||
<div class="btn-group position-absolute top-50 end-0 translate-middle-y">
|
<div class="btn-group position-absolute top-50 end-0 translate-middle-y">
|
||||||
<a [href]="getPreviewUrl(doc)" title="View Preview" i18n-title target="_blank" class="btn px-4 btn-dark border-dark-subtle"
|
<a [href]="getPreviewUrl(doc)" title="View Preview" i18n-title target="_blank" class="btn px-4 btn-dark border-dark-subtle"
|
||||||
[ngbPopover]="previewContent" [popoverTitle]="doc.title | documentTitle"
|
[ngbPopover]="previewContent" [popoverTitle]="doc.title | documentTitle"
|
||||||
@ -56,11 +78,20 @@
|
|||||||
<i-bs width="0.8em" height="0.8em" name="download"></i-bs>
|
<i-bs width="0.8em" height="0.8em" name="download"></i-bs>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
</td>
|
</td>
|
||||||
|
}
|
||||||
|
}
|
||||||
</tr>
|
</tr>
|
||||||
}
|
}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
} @else if (documents.length && savedView.dashboard_view_mode === DashboardViewMode.SMALL_CARDS) {
|
||||||
|
<div class="row row-cols-paperless-cards my-n2">
|
||||||
|
@for (d of documents; track d.id) {
|
||||||
|
<pngx-document-card-small class="p-0" (dblClickDocument)="openDocumentDetail(d)" [document]="d" (clickTag)="clickTag($event)" (clickCorrespondent)="clickCorrespondent($event)" (clickStoragePath)="clickStoragePath($event)" (clickDocumentType)="clickDocumentType($event)"></pngx-document-card-small>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
} @else {
|
} @else {
|
||||||
<p i18n class="text-center text-muted mb-0 fst-italic">No documents</p>
|
<p i18n class="text-center text-muted mb-0 fst-italic">No documents</p>
|
||||||
}
|
}
|
||||||
|
@ -3,10 +3,9 @@ table {
|
|||||||
table-layout: fixed;
|
table-layout: fixed;
|
||||||
}
|
}
|
||||||
|
|
||||||
th:first-child {
|
@media (min-width: 768px) {
|
||||||
width: 25%;
|
th.w-25 {
|
||||||
@media (min-width: 768px) {
|
width: 15% !important;
|
||||||
width: 15%;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,3 +29,45 @@ td.py-3 {
|
|||||||
padding-top: 0.75em !important;
|
padding-top: 0.75em !important;
|
||||||
padding-bottom: 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
|
||||||
|
}
|
||||||
|
@ -11,8 +11,17 @@ import { RouterTestingModule } from '@angular/router/testing'
|
|||||||
import { NgbModule } from '@ng-bootstrap/ng-bootstrap'
|
import { NgbModule } from '@ng-bootstrap/ng-bootstrap'
|
||||||
import { of, Subject } from 'rxjs'
|
import { of, Subject } from 'rxjs'
|
||||||
import { routes } from 'src/app/app-routing.module'
|
import { routes } from 'src/app/app-routing.module'
|
||||||
import { FILTER_HAS_TAGS_ALL } from 'src/app/data/filter-rule-type'
|
import {
|
||||||
import { SavedView } from 'src/app/data/saved-view'
|
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 { IfPermissionsDirective } from 'src/app/directives/if-permissions.directive'
|
||||||
import { PermissionsGuard } from 'src/app/guards/permissions.guard'
|
import { PermissionsGuard } from 'src/app/guards/permissions.guard'
|
||||||
import { CustomDatePipe } from 'src/app/pipes/custom-date.pipe'
|
import { CustomDatePipe } from 'src/app/pipes/custom-date.pipe'
|
||||||
@ -45,6 +54,14 @@ const savedView: SavedView = {
|
|||||||
value: '1,2',
|
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 = [
|
const documentResults = [
|
||||||
@ -170,7 +187,7 @@ describe('SavedViewWidgetComponent', () => {
|
|||||||
component.ngOnInit()
|
component.ngOnInit()
|
||||||
expect(listAllSpy).toHaveBeenCalledWith(
|
expect(listAllSpy).toHaveBeenCalledWith(
|
||||||
1,
|
1,
|
||||||
10,
|
20,
|
||||||
savedView.sort_field,
|
savedView.sort_field,
|
||||||
savedView.sort_reverse,
|
savedView.sort_reverse,
|
||||||
savedView.filter_rules,
|
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', () => {
|
it('should navigate via quickfilter on click tag', () => {
|
||||||
const qfSpy = jest.spyOn(documentListViewService, 'quickFilter')
|
const qfSpy = jest.spyOn(documentListViewService, 'quickFilter')
|
||||||
component.clickTag({ id: 11, name: 'Tag11' }, new MouseEvent('click'))
|
component.clickTag(11, new MouseEvent('click'))
|
||||||
expect(qfSpy).toHaveBeenCalledWith([
|
expect(qfSpy).toHaveBeenCalledWith([
|
||||||
{ rule_type: FILTER_HAS_TAGS_ALL, value: '11' },
|
{ 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
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -6,23 +6,31 @@ import {
|
|||||||
QueryList,
|
QueryList,
|
||||||
ViewChildren,
|
ViewChildren,
|
||||||
} from '@angular/core'
|
} from '@angular/core'
|
||||||
import { Params, Router } from '@angular/router'
|
import { Router } from '@angular/router'
|
||||||
import { Subject, takeUntil } from 'rxjs'
|
import { Subject, takeUntil } from 'rxjs'
|
||||||
import { Document } from 'src/app/data/document'
|
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 { ConsumerStatusService } from 'src/app/services/consumer-status.service'
|
||||||
import { DocumentService } from 'src/app/services/rest/document.service'
|
import { DocumentService } from 'src/app/services/rest/document.service'
|
||||||
import { Tag } from 'src/app/data/tag'
|
|
||||||
import {
|
import {
|
||||||
FILTER_CORRESPONDENT,
|
FILTER_CORRESPONDENT,
|
||||||
|
FILTER_DOCUMENT_TYPE,
|
||||||
FILTER_HAS_TAGS_ALL,
|
FILTER_HAS_TAGS_ALL,
|
||||||
|
FILTER_STORAGE_PATH,
|
||||||
} from 'src/app/data/filter-rule-type'
|
} from 'src/app/data/filter-rule-type'
|
||||||
import { OpenDocumentsService } from 'src/app/services/open-documents.service'
|
import { OpenDocumentsService } from 'src/app/services/open-documents.service'
|
||||||
import { DocumentListViewService } from 'src/app/services/document-list-view.service'
|
import { DocumentListViewService } from 'src/app/services/document-list-view.service'
|
||||||
import { ComponentWithPermissions } from 'src/app/components/with-permissions/with-permissions.component'
|
import { ComponentWithPermissions } from 'src/app/components/with-permissions/with-permissions.component'
|
||||||
import { NgbPopover } from '@ng-bootstrap/ng-bootstrap'
|
import { NgbPopover } from '@ng-bootstrap/ng-bootstrap'
|
||||||
import { queryParamsFromFilterRules } from 'src/app/utils/query-params'
|
import {
|
||||||
import { PermissionsService } from 'src/app/services/permissions.service'
|
PermissionAction,
|
||||||
|
PermissionType,
|
||||||
|
PermissionsService,
|
||||||
|
} from 'src/app/services/permissions.service'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'pngx-saved-view-widget',
|
selector: 'pngx-saved-view-widget',
|
||||||
@ -33,6 +41,9 @@ export class SavedViewWidgetComponent
|
|||||||
extends ComponentWithPermissions
|
extends ComponentWithPermissions
|
||||||
implements OnInit, OnDestroy
|
implements OnInit, OnDestroy
|
||||||
{
|
{
|
||||||
|
public DashboardViewMode = DashboardViewMode
|
||||||
|
public DashboardViewTableColumn = DashboardViewTableColumn
|
||||||
|
|
||||||
loading: boolean = true
|
loading: boolean = true
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@ -80,7 +91,7 @@ export class SavedViewWidgetComponent
|
|||||||
this.documentService
|
this.documentService
|
||||||
.listFiltered(
|
.listFiltered(
|
||||||
1,
|
1,
|
||||||
10,
|
this.savedView.dashboard_view_limit,
|
||||||
this.savedView.sort_field,
|
this.savedView.sort_field,
|
||||||
this.savedView.sort_reverse,
|
this.savedView.sort_reverse,
|
||||||
this.savedView.filter_rules,
|
this.savedView.filter_rules,
|
||||||
@ -103,15 +114,46 @@ export class SavedViewWidgetComponent
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
clickTag(tag: Tag, event: MouseEvent) {
|
clickTag(tagID: number, event: MouseEvent = null) {
|
||||||
event.preventDefault()
|
event?.preventDefault()
|
||||||
event.stopImmediatePropagation()
|
event?.stopImmediatePropagation()
|
||||||
|
|
||||||
this.list.quickFilter([
|
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 {
|
getPreviewUrl(document: Document): string {
|
||||||
return this.documentService.getPreviewUrl(document.id)
|
return this.documentService.getPreviewUrl(document.id)
|
||||||
}
|
}
|
||||||
@ -161,14 +203,41 @@ export class SavedViewWidgetComponent
|
|||||||
}, 300)
|
}, 300)
|
||||||
}
|
}
|
||||||
|
|
||||||
getCorrespondentQueryParams(correspondentId: number): Params {
|
public columnIsVisible(column: DashboardViewTableColumn): boolean {
|
||||||
return correspondentId !== undefined
|
if (
|
||||||
? queryParamsFromFilterRules([
|
[
|
||||||
{
|
DashboardViewTableColumn.TITLE,
|
||||||
rule_type: FILTER_CORRESPONDENT,
|
DashboardViewTableColumn.CREATED,
|
||||||
value: correspondentId.toString(),
|
DashboardViewTableColumn.ADDED,
|
||||||
},
|
].includes(column)
|
||||||
])
|
) {
|
||||||
: null
|
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`
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,11 +13,11 @@
|
|||||||
<div class="spinner-border spinner-border-sm fw-normal ms-2 me-auto" role="status"></div>
|
<div class="spinner-border spinner-border-sm fw-normal ms-2 me-auto" role="status"></div>
|
||||||
<div class="visually-hidden" i18n>Loading...</div>
|
<div class="visually-hidden" i18n>Loading...</div>
|
||||||
}
|
}
|
||||||
<ng-content select ="[header-buttons]"></ng-content>
|
<ng-content select="[header-buttons]"></ng-content>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body text-dark">
|
<div class="card-body text-dark">
|
||||||
<ng-content select ="[content]"></ng-content>
|
<ng-content select="[content]"></ng-content>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,6 +1,21 @@
|
|||||||
import { FilterRule } from './filter-rule'
|
import { FilterRule } from './filter-rule'
|
||||||
import { ObjectWithPermissions } from './object-with-permissions'
|
import { ObjectWithPermissions } from './object-with-permissions'
|
||||||
|
|
||||||
|
export enum DashboardViewMode {
|
||||||
|
TABLE = 'table',
|
||||||
|
SMALL_CARDS = 'small_cards',
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum DashboardViewTableColumn {
|
||||||
|
TITLE = 'title',
|
||||||
|
CREATED = 'created',
|
||||||
|
ADDED = 'added',
|
||||||
|
TAGS = 'tag',
|
||||||
|
CORRESPONDENT = 'correspondent',
|
||||||
|
DOCUMENT_TYPE = 'documenttype',
|
||||||
|
STORAGE_PATH = 'storagepath',
|
||||||
|
}
|
||||||
|
|
||||||
export interface SavedView extends ObjectWithPermissions {
|
export interface SavedView extends ObjectWithPermissions {
|
||||||
name?: string
|
name?: string
|
||||||
|
|
||||||
@ -13,4 +28,10 @@ export interface SavedView extends ObjectWithPermissions {
|
|||||||
sort_reverse: boolean
|
sort_reverse: boolean
|
||||||
|
|
||||||
filter_rules: FilterRule[]
|
filter_rules: FilterRule[]
|
||||||
|
|
||||||
|
dashboard_view_limit?: number
|
||||||
|
|
||||||
|
dashboard_view_mode?: DashboardViewMode
|
||||||
|
|
||||||
|
dashboard_view_table_columns?: DashboardViewTableColumn[]
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,52 @@
|
|||||||
|
# Generated by Django 4.2.11 on 2024-04-16 18:35
|
||||||
|
|
||||||
|
import django.core.validators
|
||||||
|
import multiselectfield.db.fields
|
||||||
|
from django.db import migrations
|
||||||
|
from django.db import models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("documents", "1046_workflowaction_remove_all_correspondents_and_more"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="savedview",
|
||||||
|
name="dashboard_view_mode",
|
||||||
|
field=models.CharField(
|
||||||
|
choices=[("table", "Table"), ("small_cards", "Small Cards")],
|
||||||
|
default="table",
|
||||||
|
max_length=128,
|
||||||
|
verbose_name="Dashboard view display mode",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="savedview",
|
||||||
|
name="dashboard_view_limit",
|
||||||
|
field=models.PositiveIntegerField(
|
||||||
|
default=10,
|
||||||
|
validators=[django.core.validators.MinValueValidator(1)],
|
||||||
|
verbose_name="Dashboard view limit",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="savedview",
|
||||||
|
name="dashboard_view_table_columns",
|
||||||
|
field=multiselectfield.db.fields.MultiSelectField(
|
||||||
|
choices=[
|
||||||
|
("title", "Title"),
|
||||||
|
("created", "Created"),
|
||||||
|
("added", "Added"),
|
||||||
|
("tag", "Tags"),
|
||||||
|
("documenttype", "Document Type"),
|
||||||
|
("correspondent", "Correspondent"),
|
||||||
|
("storagepath", "Storage Path"),
|
||||||
|
],
|
||||||
|
default="created,title,tags,correspondent",
|
||||||
|
max_length=128,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
@ -394,6 +394,19 @@ class Log(models.Model):
|
|||||||
|
|
||||||
|
|
||||||
class SavedView(ModelWithOwner):
|
class SavedView(ModelWithOwner):
|
||||||
|
class DashboardViewDisplayMode(models.TextChoices):
|
||||||
|
TABLE = ("table", _("Table"))
|
||||||
|
SMALL_CARDS = ("small_cards", _("Small Cards"))
|
||||||
|
|
||||||
|
class DashboardViewTableColumns(models.TextChoices):
|
||||||
|
TITLE = ("title", _("Title"))
|
||||||
|
CREATED = ("created", _("Created"))
|
||||||
|
ADDED = ("added", _("Added"))
|
||||||
|
TAGS = ("tag"), _("Tags")
|
||||||
|
DOCUMENT_TYPE = ("documenttype", _("Document Type"))
|
||||||
|
CORRESPONDENT = ("correspondent", _("Correspondent"))
|
||||||
|
STORAGE_PATH = ("storagepath", _("Storage Path"))
|
||||||
|
|
||||||
name = models.CharField(_("name"), max_length=128)
|
name = models.CharField(_("name"), max_length=128)
|
||||||
|
|
||||||
show_on_dashboard = models.BooleanField(
|
show_on_dashboard = models.BooleanField(
|
||||||
@ -411,6 +424,26 @@ class SavedView(ModelWithOwner):
|
|||||||
)
|
)
|
||||||
sort_reverse = models.BooleanField(_("sort reverse"), default=False)
|
sort_reverse = models.BooleanField(_("sort reverse"), default=False)
|
||||||
|
|
||||||
|
dashboard_view_limit = models.PositiveIntegerField(
|
||||||
|
_("Dashboard view limit"),
|
||||||
|
default=10,
|
||||||
|
validators=[MinValueValidator(1)],
|
||||||
|
)
|
||||||
|
|
||||||
|
dashboard_view_mode = models.CharField(
|
||||||
|
max_length=128,
|
||||||
|
verbose_name=_("Dashboard view display mode"),
|
||||||
|
choices=DashboardViewDisplayMode.choices,
|
||||||
|
default=DashboardViewDisplayMode.TABLE,
|
||||||
|
)
|
||||||
|
|
||||||
|
dashboard_view_table_columns = MultiSelectField(
|
||||||
|
max_length=128,
|
||||||
|
verbose_name=_("Dashboard view table display columns"),
|
||||||
|
choices=DashboardViewTableColumns.choices,
|
||||||
|
default=f"{DashboardViewTableColumns.CREATED},{DashboardViewTableColumns.TITLE},{DashboardViewTableColumns.TAGS},{DashboardViewTableColumns.CORRESPONDENT}",
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ("name",)
|
ordering = ("name",)
|
||||||
verbose_name = _("saved view")
|
verbose_name = _("saved view")
|
||||||
|
@ -799,6 +799,10 @@ class SavedViewFilterRuleSerializer(serializers.ModelSerializer):
|
|||||||
|
|
||||||
class SavedViewSerializer(OwnedObjectSerializer):
|
class SavedViewSerializer(OwnedObjectSerializer):
|
||||||
filter_rules = SavedViewFilterRuleSerializer(many=True)
|
filter_rules = SavedViewFilterRuleSerializer(many=True)
|
||||||
|
dashboard_view_table_columns = fields.MultipleChoiceField(
|
||||||
|
choices=SavedView.DashboardViewTableColumns.choices,
|
||||||
|
required=False,
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = SavedView
|
model = SavedView
|
||||||
@ -810,6 +814,9 @@ class SavedViewSerializer(OwnedObjectSerializer):
|
|||||||
"sort_field",
|
"sort_field",
|
||||||
"sort_reverse",
|
"sort_reverse",
|
||||||
"filter_rules",
|
"filter_rules",
|
||||||
|
"dashboard_view_limit",
|
||||||
|
"dashboard_view_mode",
|
||||||
|
"dashboard_view_table_columns",
|
||||||
"owner",
|
"owner",
|
||||||
"permissions",
|
"permissions",
|
||||||
"user_can_change",
|
"user_can_change",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user