-
-
-
-
-
-
-
-
+
+ @if (savedViewGroup.get(view.id.toString()).get('show_on_dashboard').value) {
+
+
+
+
+
+
+
+ @if (savedViewGroup.get(view.id.toString()).get('dashboard_view_mode').value === DashboardViewMode.TABLE) {
+
+ }
+ }
+
+
+
}
@if (savedViews && savedViews.length === 0) {
-
No saved views defined.
+
+ No saved views defined.
+
}
@if (!savedViews) {
-
+
}
-
+
@@ -374,4 +393,5 @@
+
diff --git a/src-ui/src/app/components/admin/settings/settings.component.spec.ts b/src-ui/src/app/components/admin/settings/settings.component.spec.ts
index d53f57b69..2f76ec361 100644
--- a/src-ui/src/app/components/admin/settings/settings.component.spec.ts
+++ b/src-ui/src/app/components/admin/settings/settings.component.spec.ts
@@ -437,4 +437,11 @@ describe('SettingsComponent', () => {
size: 'xl',
})
})
+
+ it('should support reset', () => {
+ completeSetup()
+ component.settingsForm.get('themeColor').setValue('#ff0000')
+ component.reset()
+ expect(component.settingsForm.get('themeColor').value).toEqual('')
+ })
})
diff --git a/src-ui/src/app/components/admin/settings/settings.component.ts b/src-ui/src/app/components/admin/settings/settings.component.ts
index 33f6949a1..5e59d561d 100644
--- a/src-ui/src/app/components/admin/settings/settings.component.ts
+++ b/src-ui/src/app/components/admin/settings/settings.component.ts
@@ -26,7 +26,12 @@ import {
tap,
} from 'rxjs'
import { Group } from 'src/app/data/group'
-import { SavedView } from 'src/app/data/saved-view'
+import {
+ DASHBOARD_VIEW_TABLE_COLUMNS,
+ DashboardViewMode,
+ DashboardViewTableColumn,
+ SavedView,
+} from 'src/app/data/saved-view'
import { SETTINGS_KEYS } from 'src/app/data/ui-settings'
import { User } from 'src/app/data/user'
import { DocumentListViewService } from 'src/app/services/document-list-view.service'
@@ -73,8 +78,8 @@ export class SettingsComponent
extends ComponentWithPermissions
implements OnInit, AfterViewInit, OnDestroy, DirtyComponent
{
- SettingsNavIDs = SettingsNavIDs
activeNavID: number
+ DashboardViewMode = DashboardViewMode
savedViewGroup = new FormGroup({})
@@ -110,6 +115,8 @@ export class SettingsComponent
})
savedViews: SavedView[]
+ SettingsNavIDs = SettingsNavIDs
+ DASHBOARD_VIEW_TABLE_COLUMNS = DASHBOARD_VIEW_TABLE_COLUMNS
store: BehaviorSubject
storeSub: Subscription
@@ -340,6 +347,9 @@ export class SettingsComponent
name: view.name,
show_on_dashboard: view.show_on_dashboard,
show_in_sidebar: view.show_in_sidebar,
+ dashboard_view_limit: view.dashboard_view_limit,
+ dashboard_view_mode: view.dashboard_view_mode,
+ dashboard_view_table_columns: view.dashboard_view_table_columns,
}
this.savedViewGroup.addControl(
view.id.toString(),
@@ -348,6 +358,9 @@ export class SettingsComponent
name: new FormControl(null),
show_on_dashboard: new FormControl(null),
show_in_sidebar: new FormControl(null),
+ dashboard_view_limit: new FormControl(null),
+ dashboard_view_mode: new FormControl(null),
+ dashboard_view_table_columns: new FormControl([]),
})
)
}
@@ -592,6 +605,10 @@ export class SettingsComponent
}
}
+ reset() {
+ this.settingsForm.patchValue(this.store.getValue())
+ }
+
clearThemeColor() {
this.settingsForm.get('themeColor').patchValue('')
}
diff --git a/src-ui/src/app/components/common/input/drag-drop-select/drag-drop-select.component.html b/src-ui/src/app/components/common/input/drag-drop-select/drag-drop-select.component.html
new file mode 100644
index 000000000..e0ef64e71
--- /dev/null
+++ b/src-ui/src/app/components/common/input/drag-drop-select/drag-drop-select.component.html
@@ -0,0 +1,24 @@
+
+
Selected:
+
+ @for (item of selectedItems; track item.id) {
+
{{item.name}}
+ }
+
+
+
+
+
+ @for (item of unselectedItems; track item.id) {
+
{{item.name}}
+ }
+
+
diff --git a/src-ui/src/app/components/common/input/drag-drop-select/drag-drop-select.component.scss b/src-ui/src/app/components/common/input/drag-drop-select/drag-drop-select.component.scss
new file mode 100644
index 000000000..483c6c592
--- /dev/null
+++ b/src-ui/src/app/components/common/input/drag-drop-select/drag-drop-select.component.scss
@@ -0,0 +1,3 @@
+.badge {
+ cursor: move;
+}
diff --git a/src-ui/src/app/components/common/input/drag-drop-select/drag-drop-select.component.spec.ts b/src-ui/src/app/components/common/input/drag-drop-select/drag-drop-select.component.spec.ts
new file mode 100644
index 000000000..4477c9e92
--- /dev/null
+++ b/src-ui/src/app/components/common/input/drag-drop-select/drag-drop-select.component.spec.ts
@@ -0,0 +1,99 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing'
+import { DragDropModule } from '@angular/cdk/drag-drop'
+import { FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms'
+import { DragDropSelectComponent } from './drag-drop-select.component'
+
+describe('DragDropSelectComponent', () => {
+ let component: DragDropSelectComponent
+ let fixture: ComponentFixture
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ imports: [DragDropModule, FormsModule],
+ declarations: [DragDropSelectComponent],
+ }).compileComponents()
+
+ fixture = TestBed.createComponent(DragDropSelectComponent)
+ component = fixture.componentInstance
+ fixture.debugElement.injector.get(NG_VALUE_ACCESSOR)
+ fixture.detectChanges()
+ })
+
+ it('should update selectedItems when writeValue is called', () => {
+ const newValue = ['1', '2', '3']
+ component.items = [
+ { id: '1', name: 'Item 1' },
+ { id: '2', name: 'Item 2' },
+ { id: '3', name: 'Item 3' },
+ ]
+ component.writeValue(newValue)
+ expect(component.selectedItems).toEqual([
+ { id: '1', name: 'Item 1' },
+ { id: '2', name: 'Item 2' },
+ { id: '3', name: 'Item 3' },
+ ])
+ })
+
+ it('should update selectedItems when an item is dropped within selectedList', () => {
+ component.items = [
+ { id: '1', name: 'Item 1' },
+ { id: '2', name: 'Item 2' },
+ { id: '3', name: 'Item 3' },
+ { id: '4', name: 'Item 4' },
+ ]
+ component.writeValue(['1', '2', '3'])
+ const event = {
+ previousContainer: component.selectedList,
+ container: component.selectedList,
+ previousIndex: 1,
+ currentIndex: 2,
+ }
+ component.drop(event as any)
+ expect(component.selectedItems).toEqual([
+ { id: '1', name: 'Item 1' },
+ { id: '3', name: 'Item 3' },
+ { id: '2', name: 'Item 2' },
+ ])
+ })
+
+ it('should update selectedItems when an item is dropped from unselectedList to selectedList', () => {
+ component.items = [
+ { id: '1', name: 'Item 1' },
+ { id: '2', name: 'Item 2' },
+ { id: '3', name: 'Item 3' },
+ ]
+ component.writeValue(['1', '2'])
+ const event = {
+ previousContainer: component.unselectedList,
+ container: component.selectedList,
+ previousIndex: 0,
+ currentIndex: 2,
+ }
+ component.drop(event as any)
+ expect(component.selectedItems).toEqual([
+ { id: '1', name: 'Item 1' },
+ { id: '2', name: 'Item 2' },
+ { id: '3', name: 'Item 3' },
+ ])
+ })
+
+ it('should update selectedItems when an item is dropped from selectedList to unselectedList', () => {
+ component.items = [
+ { id: '1', name: 'Item 1' },
+ { id: '2', name: 'Item 2' },
+ { id: '3', name: 'Item 3' },
+ ]
+ component.writeValue(['1', '2', '3'])
+ const event = {
+ previousContainer: component.selectedList,
+ container: component.unselectedList,
+ previousIndex: 1,
+ currentIndex: 0,
+ }
+ component.drop(event as any)
+ expect(component.selectedItems).toEqual([
+ { id: '1', name: 'Item 1' },
+ { id: '3', name: 'Item 3' },
+ ])
+ })
+})
diff --git a/src-ui/src/app/components/common/input/drag-drop-select/drag-drop-select.component.ts b/src-ui/src/app/components/common/input/drag-drop-select/drag-drop-select.component.ts
new file mode 100644
index 000000000..8adfbad06
--- /dev/null
+++ b/src-ui/src/app/components/common/input/drag-drop-select/drag-drop-select.component.ts
@@ -0,0 +1,61 @@
+import { Component, Input, ViewChild, forwardRef } from '@angular/core'
+import { NG_VALUE_ACCESSOR } from '@angular/forms'
+import { AbstractInputComponent } from '../abstract-input'
+import {
+ CdkDragDrop,
+ CdkDropList,
+ moveItemInArray,
+} from '@angular/cdk/drag-drop'
+
+@Component({
+ providers: [
+ {
+ provide: NG_VALUE_ACCESSOR,
+ useExisting: forwardRef(() => DragDropSelectComponent),
+ multi: true,
+ },
+ ],
+ selector: 'pngx-input-drag-drop-select',
+ templateUrl: './drag-drop-select.component.html',
+ styleUrl: './drag-drop-select.component.scss',
+})
+export class DragDropSelectComponent extends AbstractInputComponent {
+ @Input() items: { id: string; name: string }[] = []
+ public selectedItems: { id: string; name: string }[] = []
+
+ @ViewChild('selectedList') selectedList: CdkDropList
+ @ViewChild('unselectedList') unselectedList: CdkDropList
+
+ get unselectedItems(): { id: string; name: string }[] {
+ return this.items.filter((i) => !this.selectedItems.includes(i))
+ }
+
+ writeValue(newValue: string[]): void {
+ super.writeValue(newValue)
+ this.selectedItems = newValue.map((id) =>
+ this.items.find((i) => i.id === id)
+ )
+ }
+
+ public drop(event: CdkDragDrop) {
+ if (
+ event.previousContainer === event.container &&
+ event.container === this.selectedList
+ ) {
+ moveItemInArray(
+ this.selectedItems,
+ event.previousIndex,
+ event.currentIndex
+ )
+ } else if (event.container === this.selectedList) {
+ this.selectedItems.splice(
+ event.currentIndex,
+ 0,
+ this.unselectedItems[event.previousIndex]
+ )
+ } else {
+ this.selectedItems.splice(event.previousIndex, 1)
+ }
+ this.onChange(this.selectedItems.map((i) => i.id))
+ }
+}
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 cddfd2bf5..6496698dd 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
@@ -13,6 +13,7 @@ import {
DashboardViewTableColumn,
DashboardViewMode,
SavedView,
+ DASHBOARD_VIEW_TABLE_COLUMNS,
} from 'src/app/data/saved-view'
import { ConsumerStatusService } from 'src/app/services/consumer-status.service'
import { DocumentService } from 'src/app/services/rest/document.service'
@@ -223,21 +224,6 @@ export class SavedViewWidgetComponent
}
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`
- }
+ return DASHBOARD_VIEW_TABLE_COLUMNS.find((c) => c.id === column)?.name
}
}
diff --git a/src-ui/src/app/data/saved-view.ts b/src-ui/src/app/data/saved-view.ts
index ced629507..605b2d934 100644
--- a/src-ui/src/app/data/saved-view.ts
+++ b/src-ui/src/app/data/saved-view.ts
@@ -16,6 +16,37 @@ export enum DashboardViewTableColumn {
STORAGE_PATH = 'storagepath',
}
+export const DASHBOARD_VIEW_TABLE_COLUMNS = [
+ {
+ id: DashboardViewTableColumn.TITLE,
+ name: $localize`Title`,
+ },
+ {
+ id: DashboardViewTableColumn.CREATED,
+ name: $localize`Created`,
+ },
+ {
+ id: DashboardViewTableColumn.ADDED,
+ name: $localize`Added`,
+ },
+ {
+ id: DashboardViewTableColumn.TAGS,
+ name: $localize`Tags`,
+ },
+ {
+ id: DashboardViewTableColumn.CORRESPONDENT,
+ name: $localize`Correspondent`,
+ },
+ {
+ id: DashboardViewTableColumn.DOCUMENT_TYPE,
+ name: $localize`Document type`,
+ },
+ {
+ id: DashboardViewTableColumn.STORAGE_PATH,
+ name: $localize`Storage path`,
+ },
+]
+
export interface SavedView extends ObjectWithPermissions {
name?: string