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 f5743e550..71889e74b 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 @@ -219,11 +219,23 @@ describe('SettingsComponent', () => { HideableSidebarItemID.Workflows ) + settingsService.updateSidebarItemVisibility( + HideableSidebarItemID.Mail, + false + ) + + expect(component.settingsForm.value.sidebarHiddenItems).toContain( + HideableSidebarItemID.Mail + ) + component.reset() expect(component.settingsForm.value.sidebarHiddenItems).not.toContain( HideableSidebarItemID.Workflows ) + expect(component.settingsForm.value.sidebarHiddenItems).not.toContain( + HideableSidebarItemID.Mail + ) }) it('enables sidebar item controls on general settings until destroyed', () => { 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 09fd12ddb..9076d2a3e 100644 --- a/src-ui/src/app/components/admin/settings/settings.component.ts +++ b/src-ui/src/app/components/admin/settings/settings.component.ts @@ -200,6 +200,7 @@ export class SettingsComponent store: BehaviorSubject storeSub: Subscription + sidebarItemsSub: Subscription isDirty$: Observable isDirty: boolean = false unsubscribeNotifier: Subject = new Subject() @@ -248,6 +249,10 @@ export class SettingsComponent constructor() { super() + this.sidebarItemsSub = + this.settings.sidebarHiddenItemsEditingChanged.subscribe((hiddenItems) => + this.settingsForm.controls.sidebarHiddenItems.setValue(hiddenItems) + ) this.settings.settingsSaved.subscribe(() => { if (!this.savePending) this.initialize() this.savedViewsService.maybeRefreshDocumentCounts() @@ -307,7 +312,11 @@ export class SettingsComponent } } this.activeNavID.set(navID) - this.settings.organizingSidebarItems.set(navID === SettingsNavIDs.General) + this.settings.sidebarHiddenItemsEditing.set( + navID === SettingsNavIDs.General + ? [...this.settingsForm.controls.sidebarHiddenItems.value] + : null + ) }) } @@ -458,6 +467,12 @@ export class SettingsComponent this.settingsForm.patchValue(currentFormValue) } + if (this.settings.organizingSidebarItems()) { + this.settings.sidebarHiddenItemsEditing.set([ + ...this.settingsForm.controls.sidebarHiddenItems.value, + ]) + } + if (this.canViewSystemStatus) { this.systemStatusService.get().subscribe((status) => { this.systemStatus.set(status) @@ -466,9 +481,10 @@ export class SettingsComponent } ngOnDestroy() { - this.settings.organizingSidebarItems.set(false) + this.settings.sidebarHiddenItemsEditing.set(null) if (this.isDirty) this.settings.updateAppearanceSettings() // in case user changed appearance but didn't save this.storeSub && this.storeSub.unsubscribe() + this.sidebarItemsSub.unsubscribe() } isSidebarItemShown(item: HideableSidebarItemID): boolean { @@ -476,15 +492,7 @@ export class SettingsComponent } toggleSidebarItem(item: HideableSidebarItemID, checked: boolean): void { - const hiddenItems = new Set( - this.settingsForm.value.sidebarHiddenItems || [] - ) - if (checked) { - hiddenItems.delete(item) - } else { - hiddenItems.add(item) - } - this.settingsForm.controls.sidebarHiddenItems.setValue([...hiddenItems]) + this.settings.updateSidebarItemVisibility(item, checked) } public saveSettings() { @@ -675,6 +683,11 @@ export class SettingsComponent reset() { this.settingsForm.patchValue(this.store.getValue()) + if (this.settings.organizingSidebarItems()) { + this.settings.sidebarHiddenItemsEditing.set([ + ...this.settingsForm.controls.sidebarHiddenItems.value, + ]) + } } clearThemeColor() { diff --git a/src-ui/src/app/components/app-frame/app-frame.component.spec.ts b/src-ui/src/app/components/app-frame/app-frame.component.spec.ts index 8b2587a70..d78db67a1 100644 --- a/src-ui/src/app/components/app-frame/app-frame.component.spec.ts +++ b/src-ui/src/app/components/app-frame/app-frame.component.spec.ts @@ -312,7 +312,9 @@ describe('AppFrameComponent', () => { settingsService.set(SETTINGS_KEYS.SIDEBAR_HIDDEN_ITEMS, [ HideableSidebarItemID.Dashboard, ]) - settingsService.organizingSidebarItems.set(true) + settingsService.sidebarHiddenItemsEditing.set([ + HideableSidebarItemID.Dashboard, + ]) fixture.detectChanges() expect( diff --git a/src-ui/src/app/components/app-frame/app-frame.component.ts b/src-ui/src/app/components/app-frame/app-frame.component.ts index 402cf4458..7b4c29d2f 100644 --- a/src-ui/src/app/components/app-frame/app-frame.component.ts +++ b/src-ui/src/app/components/app-frame/app-frame.component.ts @@ -205,22 +205,7 @@ export class AppFrameComponent } toggleSidebarItem(item: HideableSidebarItemID, visible: boolean): void { - const previousHiddenItems = this.settingsService.hiddenSidebarItems() - this.settingsService - .updateSidebarItemVisibility(item, visible) - .pipe(first()) - .subscribe({ - error: (error) => { - this.settingsService.set( - SETTINGS_KEYS.SIDEBAR_HIDDEN_ITEMS, - previousHiddenItems - ) - this.toastService.showError( - $localize`An error occurred while saving settings.`, - error - ) - }, - }) + this.settingsService.updateSidebarItemVisibility(item, visible) } toggleAttributesSections(event?: Event): void { diff --git a/src-ui/src/app/services/settings.service.spec.ts b/src-ui/src/app/services/settings.service.spec.ts index be8e393c9..010f2f1c7 100644 --- a/src-ui/src/app/services/settings.service.spec.ts +++ b/src-ui/src/app/services/settings.service.spec.ts @@ -251,6 +251,7 @@ describe('SettingsService', () => { expect( settingsService.sidebarItemIsHidden(HideableSidebarItemID.Workflows) ).toBe(true) + expect(settingsService.get(SETTINGS_KEYS.SIDEBAR_HIDDEN_ITEMS)).toEqual([]) settingsService.updateSidebarItemVisibility( HideableSidebarItemID.Workflows, diff --git a/src-ui/src/app/services/settings.service.ts b/src-ui/src/app/services/settings.service.ts index f012b56de..ef27e6e55 100644 --- a/src-ui/src/app/services/settings.service.ts +++ b/src-ui/src/app/services/settings.service.ts @@ -314,7 +314,15 @@ export class SettingsService { readonly globalDropzoneEnabled = signal(true) readonly globalDropzoneActive = signal(false) readonly organizingSidebarSavedViews = signal(false) - readonly organizingSidebarItems = signal(false) + readonly sidebarHiddenItemsEditing = signal( + null + ) + readonly organizingSidebarItems = computed( + () => this.sidebarHiddenItemsEditing() !== null + ) + readonly sidebarHiddenItemsEditingChanged = new EventEmitter< + HideableSidebarItemID[] + >() readonly hiddenSidebarItems = this.getSignal( SETTINGS_KEYS.SIDEBAR_HIDDEN_ITEMS ) @@ -755,21 +763,26 @@ export class SettingsService { } sidebarItemIsHidden(item: HideableSidebarItemID): boolean { - return this.hiddenSidebarItems().includes(item) + return ( + this.sidebarHiddenItemsEditing() ?? this.hiddenSidebarItems() + ).includes(item) } updateSidebarItemVisibility( item: HideableSidebarItemID, visible: boolean - ): Observable { - const hiddenItems = new Set(this.hiddenSidebarItems()) + ): void { + const hiddenItems = new Set( + this.sidebarHiddenItemsEditing() ?? this.hiddenSidebarItems() + ) if (visible) { hiddenItems.delete(item) } else { hiddenItems.add(item) } - this.set(SETTINGS_KEYS.SIDEBAR_HIDDEN_ITEMS, [...hiddenItems]) - return this.storeSettings() + const updatedHiddenItems = [...hiddenItems] + this.sidebarHiddenItemsEditing.set(updatedHiddenItems) + this.sidebarHiddenItemsEditingChanged.emit(updatedHiddenItems) } updateSavedViewsVisibility(