From 9909dfff94ad8a289340b081fe92a4b16f6008ac Mon Sep 17 00:00:00 2001 From: Humberto Morera <31667212+hmoreras@users.noreply.github.com> Date: Thu, 26 Sep 2024 17:16:18 -0500 Subject: [PATCH] implementation ( Edit Content ) : #30015 Implement Show/Hide Toggle for Hidden Column (#30147) ### Proposed Changes * Hide/show the content information. * Safe the state based on local storage. ### Screenshots https://github.com/user-attachments/assets/b05007a0-5316-4a53-94d7-f2f167651129 --------- Co-authored-by: Arcadio Quintero --- .../dot-edit-content-aside.component.html | 47 +++++++- .../dot-edit-content-aside.component.scss | 16 +++ .../dot-edit-content-aside.component.spec.ts | 17 ++- .../dot-edit-content-aside.component.ts | 29 ++++- .../dot-edit-content-toolbar.component.html | 5 +- .../dot-edit-content-toolbar.component.scss | 8 ++ ...dot-edit-content-toolbar.component.spec.ts | 4 +- .../dot-edit-content-toolbar.component.ts | 6 +- .../edit-content.layout.component.html | 42 ++++++- .../edit-content.layout.component.scss | 18 +++ .../edit-content.layout.component.spec.ts | 36 ++++-- .../edit-content.layout.component.ts | 108 ++++++++++++++---- .../store/edit-content.store.spec.ts | 25 +++- .../edit-content/store/edit-content.store.ts | 29 ++++- .../models/dot-edit-content-form.interface.ts | 3 + .../libs/edit-content/src/lib/utils/mocks.ts | 5 +- 16 files changed, 338 insertions(+), 60 deletions(-) diff --git a/core-web/libs/edit-content/src/lib/components/dot-edit-content-aside/dot-edit-content-aside.component.html b/core-web/libs/edit-content/src/lib/components/dot-edit-content-aside/dot-edit-content-aside.component.html index dec39f661df2..21517c482a14 100644 --- a/core-web/libs/edit-content/src/lib/components/dot-edit-content-aside/dot-edit-content-aside.component.html +++ b/core-web/libs/edit-content/src/lib/components/dot-edit-content-aside/dot-edit-content-aside.component.html @@ -1,12 +1,49 @@ diff --git a/core-web/libs/edit-content/src/lib/components/dot-edit-content-aside/dot-edit-content-aside.component.scss b/core-web/libs/edit-content/src/lib/components/dot-edit-content-aside/dot-edit-content-aside.component.scss index 1a37a83e0879..ffbd8a07456f 100644 --- a/core-web/libs/edit-content/src/lib/components/dot-edit-content-aside/dot-edit-content-aside.component.scss +++ b/core-web/libs/edit-content/src/lib/components/dot-edit-content-aside/dot-edit-content-aside.component.scss @@ -16,6 +16,22 @@ overflow: auto; } +.p-button.content-aside__closeBtn { + rect { + stroke: $color-palette-primary; + } + + path { + fill: $color-palette-primary; + } +} + +.content-aside__toolbar { + padding: $spacing-2; + display: flex; + justify-content: space-between; +} + .content-aside, .content-aside__section { display: block; diff --git a/core-web/libs/edit-content/src/lib/components/dot-edit-content-aside/dot-edit-content-aside.component.spec.ts b/core-web/libs/edit-content/src/lib/components/dot-edit-content-aside/dot-edit-content-aside.component.spec.ts index cbe7724d943a..25146bf70c2c 100644 --- a/core-web/libs/edit-content/src/lib/components/dot-edit-content-aside/dot-edit-content-aside.component.spec.ts +++ b/core-web/libs/edit-content/src/lib/components/dot-edit-content-aside/dot-edit-content-aside.component.spec.ts @@ -16,7 +16,6 @@ describe('DotEditContentAsideComponent', () => { let spectator: Spectator; const createComponent = createComponentFactory({ component: DotEditContentAsideComponent, - detectChanges: false, imports: [ HttpClientTestingModule, DotContentAsideInformationComponent, @@ -42,8 +41,10 @@ describe('DotEditContentAsideComponent', () => { spectator = createComponent({ props: { contentlet: CONTENT_FORM_DATA_MOCK.contentlet, - contentType: dotcmsContentTypeBasicMock - } + contentType: dotcmsContentTypeBasicMock, + loading: false, + collapsed: false + } as unknown }); }); @@ -70,4 +71,14 @@ describe('DotEditContentAsideComponent', () => { ); expect(dotContentAsideWorkflowComponent.contentType).toEqual(dotcmsContentTypeBasicMock); }); + + it('should emit toggle event on button click', () => { + const spy = jest.spyOn(spectator.component.$toggle, 'emit'); + + const toggleBtn = spectator.query('[data-testId="toggle-button"]'); + + spectator.click(toggleBtn); + + expect(spy).toHaveBeenCalled(); + }); }); diff --git a/core-web/libs/edit-content/src/lib/components/dot-edit-content-aside/dot-edit-content-aside.component.ts b/core-web/libs/edit-content/src/lib/components/dot-edit-content-aside/dot-edit-content-aside.component.ts index cb22bd647cde..32219aa25154 100644 --- a/core-web/libs/edit-content/src/lib/components/dot-edit-content-aside/dot-edit-content-aside.component.ts +++ b/core-web/libs/edit-content/src/lib/components/dot-edit-content-aside/dot-edit-content-aside.component.ts @@ -1,4 +1,4 @@ -import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; +import { ChangeDetectionStrategy, Component, input, output } from '@angular/core'; import { DotCMSContentType, DotCMSContentlet } from '@dotcms/dotcms-models'; import { DotMessagePipe } from '@dotcms/ui'; @@ -15,7 +15,28 @@ import { DotContentAsideWorkflowComponent } from './components/dot-content-aside imports: [DotMessagePipe, DotContentAsideInformationComponent, DotContentAsideWorkflowComponent] }) export class DotEditContentAsideComponent { - @Input() contentlet!: DotCMSContentlet; - @Input() contentType!: DotCMSContentType; - @Input() loading!: boolean; + /** + * A variable with the contentlet information + */ + $contentlet = input.required({ alias: 'contentlet' }); + + /** + * A variable with the content type + */ + $contentType = input.required({ alias: 'contentType' }); + + /** + * A variable to control the loading state + */ + $loading = input.required({ alias: 'loading' }); + + /** + * A variable to control the collapsed state + */ + $collapsed = input.required({ alias: 'collapsed' }); + + /** + * A variable to control the toggle state + */ + $toggle = output({ alias: 'toggle' }); } diff --git a/core-web/libs/edit-content/src/lib/components/dot-edit-content-toolbar/dot-edit-content-toolbar.component.html b/core-web/libs/edit-content/src/lib/components/dot-edit-content-toolbar/dot-edit-content-toolbar.component.html index 85a2b99f479e..66f502e07571 100644 --- a/core-web/libs/edit-content/src/lib/components/dot-edit-content-toolbar/dot-edit-content-toolbar.component.html +++ b/core-web/libs/edit-content/src/lib/components/dot-edit-content-toolbar/dot-edit-content-toolbar.component.html @@ -1,9 +1,10 @@
+
diff --git a/core-web/libs/edit-content/src/lib/components/dot-edit-content-toolbar/dot-edit-content-toolbar.component.scss b/core-web/libs/edit-content/src/lib/components/dot-edit-content-toolbar/dot-edit-content-toolbar.component.scss index 3579d20feb0b..bd3e16d6a8a3 100644 --- a/core-web/libs/edit-content/src/lib/components/dot-edit-content-toolbar/dot-edit-content-toolbar.component.scss +++ b/core-web/libs/edit-content/src/lib/components/dot-edit-content-toolbar/dot-edit-content-toolbar.component.scss @@ -5,3 +5,11 @@ justify-content: flex-start; flex-direction: row-reverse; // Make the order of the buttons to be from right to left } + +:host:not(.showSidebar) { + ::ng-deep { + .p-toolbar { + padding-right: 0.75rem; + } + } +} diff --git a/core-web/libs/edit-content/src/lib/components/dot-edit-content-toolbar/dot-edit-content-toolbar.component.spec.ts b/core-web/libs/edit-content/src/lib/components/dot-edit-content-toolbar/dot-edit-content-toolbar.component.spec.ts index 1a1e14b5a15c..ac56df010f58 100644 --- a/core-web/libs/edit-content/src/lib/components/dot-edit-content-toolbar/dot-edit-content-toolbar.component.spec.ts +++ b/core-web/libs/edit-content/src/lib/components/dot-edit-content-toolbar/dot-edit-content-toolbar.component.spec.ts @@ -22,7 +22,7 @@ describe('DotEditContentToolbarComponent', () => { spectator = createComponent({ props: { actions: WORKFLOW_ACTIONS_MOCK - } + } as unknown }); spectator.detectComponentChanges(); }); @@ -36,7 +36,7 @@ describe('DotEditContentToolbarComponent', () => { }); it('should emit the action dot-workflow-actions emits the fired action', () => { - const spy = jest.spyOn(spectator.component.actionFired, 'emit'); + const spy = jest.spyOn(spectator.component.$actionFired, 'emit'); const component = spectator.query(DotWorkflowActionsComponent); component.actionFired.emit(WORKFLOW_ACTIONS_MOCK[0]); diff --git a/core-web/libs/edit-content/src/lib/components/dot-edit-content-toolbar/dot-edit-content-toolbar.component.ts b/core-web/libs/edit-content/src/lib/components/dot-edit-content-toolbar/dot-edit-content-toolbar.component.ts index f679afe52371..12c56f100b17 100644 --- a/core-web/libs/edit-content/src/lib/components/dot-edit-content-toolbar/dot-edit-content-toolbar.component.ts +++ b/core-web/libs/edit-content/src/lib/components/dot-edit-content-toolbar/dot-edit-content-toolbar.component.ts @@ -1,4 +1,4 @@ -import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core'; +import { ChangeDetectionStrategy, Component, input, output } from '@angular/core'; import { ToolbarModule } from 'primeng/toolbar'; @@ -14,6 +14,6 @@ import { DotWorkflowActionsComponent } from '@dotcms/ui'; changeDetection: ChangeDetectionStrategy.OnPush }) export class DotEditContentToolbarComponent { - @Input() actions: DotCMSWorkflowAction[]; - @Output() actionFired = new EventEmitter(); + $actions = input.required({ alias: 'actions' }); + $actionFired = output({ alias: 'actionFired' }); } diff --git a/core-web/libs/edit-content/src/lib/feature/edit-content/edit-content.layout.component.html b/core-web/libs/edit-content/src/lib/feature/edit-content/edit-content.layout.component.html index dcf7eb6bcb1a..e998384ef2d8 100644 --- a/core-web/libs/edit-content/src/lib/feature/edit-content/edit-content.layout.component.html +++ b/core-web/libs/edit-content/src/lib/feature/edit-content/edit-content.layout.component.html @@ -1,5 +1,5 @@ @if (vm$ | async; as vm) { - @if (vm?.contentType?.metadata?.[featuredFlagContentKEY]) { + @if (vm?.contentType?.metadata?.[$featuredFlagContentKEY()]) { + class="header" + [class.showSidebar]="vm.layout.showSidebar"> + + } @else { {{ 'edit.content.layout.no.content.to.show ' | dm }} diff --git a/core-web/libs/edit-content/src/lib/feature/edit-content/edit-content.layout.component.scss b/core-web/libs/edit-content/src/lib/feature/edit-content/edit-content.layout.component.scss index 4d9f7a75a579..7249e54bcc3b 100644 --- a/core-web/libs/edit-content/src/lib/feature/edit-content/edit-content.layout.component.scss +++ b/core-web/libs/edit-content/src/lib/feature/edit-content/edit-content.layout.component.scss @@ -13,6 +13,24 @@ width: 100%; } +.edit-content-layout__sidebar-btn { + rect { + stroke: $color-palette-primary; + } + + path { + fill: $color-palette-primary; + } + transition: all 300ms ease-in-out; + &.showSidebar { + width: 0; + min-width: 0; + height: 0; + padding: 0; + visibility: hidden; + } +} + .topBar { grid-area: topBar; diff --git a/core-web/libs/edit-content/src/lib/feature/edit-content/edit-content.layout.component.spec.ts b/core-web/libs/edit-content/src/lib/feature/edit-content/edit-content.layout.component.spec.ts index d1ce256487be..bc1870a940bc 100644 --- a/core-web/libs/edit-content/src/lib/feature/edit-content/edit-content.layout.component.spec.ts +++ b/core-web/libs/edit-content/src/lib/feature/edit-content/edit-content.layout.component.spec.ts @@ -63,7 +63,10 @@ describe('EditContentLayoutComponent', () => { actions: mockWorkflowsActions, contentType: CONTENT_TYPE_MOCK, contentlet: BINARY_FIELD_CONTENTLET, - loading: false + loading: false, + layout: { + showSidebar: true + } }; beforeEach(async () => { @@ -119,22 +122,22 @@ describe('EditContentLayoutComponent', () => { spectator.detectChanges(); const toolbarComponent = spectator.query(DotEditContentToolbarComponent); expect(toolbarComponent).toBeDefined(); - expect(toolbarComponent.actions).toEqual(mockData.actions); + expect(toolbarComponent.$actions).toEqual(mockData.actions); }); it('should pass the contentlet and contentType to the DotEditContentAside Component', () => { spectator.detectChanges(); const asideComponent = spectator.query(DotEditContentAsideComponent); expect(asideComponent).toBeDefined(); - expect(asideComponent.contentlet).toEqual(mockData.contentlet); - expect(asideComponent.contentType).toEqual(mockData.contentType); + expect(asideComponent.$contentlet).toEqual(mockData.contentlet); + expect(asideComponent.$contentType).toEqual(mockData.contentType); }); it('should fire workflow action', () => { const spyStore = jest.spyOn(dotEditContentStore, 'fireWorkflowActionEffect'); spectator.detectChanges(); const toolbarComponent = spectator.query(DotEditContentToolbarComponent); - toolbarComponent.actionFired.emit(mockWorkflowsActions[0]); + toolbarComponent.$actionFired.emit(mockWorkflowsActions[0]); expect(spyStore).toHaveBeenCalledWith({ actionId: mockWorkflowsActions[0].id, @@ -162,6 +165,18 @@ describe('EditContentLayoutComponent', () => { const betaTopbar = spectator.query(byTestId('topBar')); expect(betaTopbar).not.toBeNull(); }); + + it('should toggle the sidebar when the toggle button is clicked', () => { + spectator.detectChanges(); + const toggleBtn = spectator.query(byTestId('sidebar-toggle')); + + expect(toggleBtn.classList).toContain('showSidebar'); + + spectator.click(toggleBtn); + + expect(toggleBtn.classList).not.toContain('showSidebar'); + spectator.component.toggleSidebar(); + }); }); describe('New content', () => { @@ -169,7 +184,10 @@ describe('EditContentLayoutComponent', () => { actions: mockWorkflowsActions, contentType: CONTENT_TYPE_MOCK, contentlet: null, - loading: false + loading: false, + layout: { + showSidebar: true + } }; beforeEach(async () => { @@ -226,15 +244,15 @@ describe('EditContentLayoutComponent', () => { spectator.detectChanges(); const toolbarComponent = spectator.query(DotEditContentToolbarComponent); expect(toolbarComponent).toBeDefined(); - expect(toolbarComponent.actions).toEqual(mockData.actions); + expect(toolbarComponent.$actions).toEqual(mockData.actions); }); it('should pass the contentlet and contentType to the DotEditContentAside Component', () => { spectator.detectChanges(); const asideComponent = spectator.query(DotEditContentAsideComponent); expect(asideComponent).toBeDefined(); - expect(asideComponent.contentlet).toEqual(mockData.contentlet); - expect(asideComponent.contentType).toEqual(mockData.contentType); + expect(asideComponent.$contentlet).toEqual(mockData.contentlet); + expect(asideComponent.$contentType).toEqual(mockData.contentType); }); }); }); diff --git a/core-web/libs/edit-content/src/lib/feature/edit-content/edit-content.layout.component.ts b/core-web/libs/edit-content/src/lib/feature/edit-content/edit-content.layout.component.ts index f7b4fa69169c..a409da6506b9 100644 --- a/core-web/libs/edit-content/src/lib/feature/edit-content/edit-content.layout.component.ts +++ b/core-web/libs/edit-content/src/lib/feature/edit-content/edit-content.layout.component.ts @@ -1,7 +1,15 @@ import { Observable, forkJoin, of } from 'rxjs'; +import { animate, state, style, transition, trigger } from '@angular/animations'; import { AsyncPipe } from '@angular/common'; -import { ChangeDetectionStrategy, Component, OnInit, inject } from '@angular/core'; +import { + ChangeDetectionStrategy, + Component, + OnInit, + inject, + HostBinding, + signal +} from '@angular/core'; import { ActivatedRoute, RouterLink } from '@angular/router'; import { MessageService } from 'primeng/api'; @@ -19,7 +27,7 @@ import { import { FeaturedFlags } from '@dotcms/dotcms-models'; import { DotMessagePipe } from '@dotcms/ui'; -import { DotEditContentStore } from './store/edit-content.store'; +import { DotEditContentStore, SIDEBAR_LOCAL_STORAGE_KEY } from './store/edit-content.store'; import { DotEditContentAsideComponent } from '../../components/dot-edit-content-aside/dot-edit-content-aside.component'; import { DotEditContentFormComponent } from '../../components/dot-edit-content-form/dot-edit-content-form.component'; @@ -50,36 +58,75 @@ import { DotEditContentService } from '../../services/dot-edit-content.service'; DotEditContentService, MessageService, DotEditContentStore + ], + animations: [ + trigger('sidebarAnimation', [ + state( + 'false', + style({ + 'grid-template-columns': '1fr 0rem' + }) + ), + state( + 'true', + style({ + 'grid-template-columns': '1fr 21.875rem' + }) + ), + transition('false <=> true', animate('300ms ease-in-out')) + ]) ] }) export class EditContentLayoutComponent implements OnInit { - private readonly store = inject(DotEditContentStore); + @HostBinding('@sidebarAnimation') showSidebar: boolean; + + readonly #store = inject(DotEditContentStore); - private readonly dotEditContentService = inject(DotEditContentService); - private readonly workflowActionService = inject(DotWorkflowsActionsService); - private readonly activatedRoute = inject(ActivatedRoute); + readonly #dotEditContentService = inject(DotEditContentService); + readonly #workflowActionService = inject(DotWorkflowsActionsService); + readonly #activatedRoute = inject(ActivatedRoute); - private contentType = this.activatedRoute.snapshot.params['contentType']; - private initialInode = this.activatedRoute.snapshot.params['id']; + #$contentType = signal( + this.#activatedRoute.snapshot.params['contentType'] + ).asReadonly(); + #$initialInode = signal(this.#activatedRoute.snapshot.params['id']).asReadonly(); - private formValue: Record; + #formValue: Record; - vm$: Observable = this.store.vm$; - featuredFlagContentKEY = FeaturedFlags.FEATURE_FLAG_CONTENT_EDITOR2_ENABLED; + vm$: Observable = this.#store.vm$; + $featuredFlagContentKEY = signal( + FeaturedFlags.FEATURE_FLAG_CONTENT_EDITOR2_ENABLED + ).asReadonly(); ngOnInit(): void { - const obs$ = !this.initialInode - ? this.getNewContent(this.contentType) - : this.getExistingContent(this.initialInode); + const obs$ = !this.#$initialInode() + ? this.getNewContent(this.#$contentType()) + : this.getExistingContent(this.#$initialInode()); obs$.subscribe(({ contentType, actions, contentlet }) => { - this.store.setState({ + this.#store.setState({ contentType, actions, contentlet, - loading: false + loading: false, + layout: { + showSidebar: this.getSidebarSateFromLocalStorage() + } }); }); + + this.#store.layout$.subscribe((layout) => { + this.showSidebar = layout.showSidebar; + }); + } + + /** + * Toggle the show of the sidebar. + * + * @memberof EditContentLayoutComponent + */ + toggleSidebar() { + this.#store.updateSidebarState(!this.showSidebar); } /** @@ -89,7 +136,7 @@ export class EditContentLayoutComponent implements OnInit { * @memberof EditContentLayoutComponent */ setFormValue(formValue: Record) { - this.formValue = formValue; + this.#formValue = formValue; } /** @@ -99,12 +146,12 @@ export class EditContentLayoutComponent implements OnInit { * @memberof EditContentLayoutComponent */ fireWorkflowAction({ actionId, inode, contentType }): void { - this.store.fireWorkflowActionEffect({ + this.#store.fireWorkflowActionEffect({ actionId, inode, data: { contentlet: { - ...this.formValue, + ...this.#formValue, contentType } } @@ -121,8 +168,8 @@ export class EditContentLayoutComponent implements OnInit { */ private getNewContent(contentTypeVar: string) { return forkJoin({ - contentType: this.dotEditContentService.getContentType(contentTypeVar), - actions: this.workflowActionService.getDefaultActions(contentTypeVar), + contentType: this.#dotEditContentService.getContentType(contentTypeVar), + actions: this.#workflowActionService.getDefaultActions(contentTypeVar), contentlet: of(null) }); } @@ -136,16 +183,29 @@ export class EditContentLayoutComponent implements OnInit { * @memberof EditContentLayoutComponent */ private getExistingContent(inode) { - return this.dotEditContentService.getContentById(inode).pipe( + return this.#dotEditContentService.getContentById(inode).pipe( switchMap((contentlet) => { const { contentType } = contentlet; return forkJoin({ - contentType: this.dotEditContentService.getContentType(contentType), - actions: this.workflowActionService.getByInode(inode, DotRenderMode.EDITING), + contentType: this.#dotEditContentService.getContentType(contentType), + actions: this.#workflowActionService.getByInode(inode, DotRenderMode.EDITING), contentlet: of(contentlet) }); }) ); } + + /** + * Get the sidebar state from local storage + * + * @private + * @return {*} + * @memberof EditContentLayoutComponent + */ + private getSidebarSateFromLocalStorage() { + const localStorageData = localStorage.getItem(SIDEBAR_LOCAL_STORAGE_KEY); + + return localStorageData ? localStorageData === 'true' : true; + } } diff --git a/core-web/libs/edit-content/src/lib/feature/edit-content/store/edit-content.store.spec.ts b/core-web/libs/edit-content/src/lib/feature/edit-content/store/edit-content.store.spec.ts index bbad9d9726bd..50aba4a65cb4 100644 --- a/core-web/libs/edit-content/src/lib/feature/edit-content/store/edit-content.store.spec.ts +++ b/core-web/libs/edit-content/src/lib/feature/edit-content/store/edit-content.store.spec.ts @@ -82,7 +82,10 @@ describe('DotEditContentStore', () => { actions: mockWorkflowsActions, contentType: CONTENT_TYPE_MOCK, contentlet: BINARY_FIELD_CONTENTLET, - loading: false + loading: false, + layout: { + showSidebar: true + } }); }); @@ -98,7 +101,10 @@ describe('DotEditContentStore', () => { actions: [], contentType: CONTENT_TYPE_MOCK, contentlet: BINARY_FIELD_CONTENTLET, - loading: false + loading: false, + layout: { + showSidebar: true + } }); done(); }); @@ -106,7 +112,10 @@ describe('DotEditContentStore', () => { actions: [], contentType: CONTENT_TYPE_MOCK, contentlet: BINARY_FIELD_CONTENTLET, - loading: false + loading: false, + layout: { + showSidebar: true + } }); }); @@ -129,6 +138,16 @@ describe('DotEditContentStore', () => { contentlet: NEW_BINARY_FIELD_CONTENTLET }); }); + + it('should update the sidebar state', (done) => { + spectator.service.updateSidebarState(false); + spectator.service.layout$.pipe().subscribe((state) => { + expect(state).toEqual({ + showSidebar: false + }); + done(); + }); + }); }); describe('effects', () => { diff --git a/core-web/libs/edit-content/src/lib/feature/edit-content/store/edit-content.store.ts b/core-web/libs/edit-content/src/lib/feature/edit-content/store/edit-content.store.ts index 8db79f123e16..02a86cabaffb 100644 --- a/core-web/libs/edit-content/src/lib/feature/edit-content/store/edit-content.store.ts +++ b/core-web/libs/edit-content/src/lib/feature/edit-content/store/edit-content.store.ts @@ -18,11 +18,16 @@ import { } from '@dotcms/data-access'; import { DotCMSContentType, DotCMSContentlet, DotCMSWorkflowAction } from '@dotcms/dotcms-models'; +export const SIDEBAR_LOCAL_STORAGE_KEY = 'dot-edit-content-form-sidebar'; + interface EditContentState { actions: DotCMSWorkflowAction[]; contentType: DotCMSContentType; contentlet: DotCMSContentlet; loading: boolean; + layout: { + showSidebar: boolean; + }; } /** @@ -44,13 +49,16 @@ export class DotEditContentStore extends ComponentStore { private readonly dotMessageService = inject(DotMessageService); private readonly location = inject(Location); - readonly vm$ = this.select(({ actions, contentType, contentlet, loading }) => ({ + readonly vm$ = this.select(({ actions, contentType, contentlet, loading, layout }) => ({ actions, contentType, contentlet, - loading + loading, + layout })); + readonly layout$ = this.select(({ layout }) => layout); + /** * Update the state * @@ -61,6 +69,23 @@ export class DotEditContentStore extends ComponentStore { ...newState })); + /** + * Update the sidebar state and save it in local storage. + * + * @memberof DotEditContentStore + */ + readonly updateSidebarState = this.updater((state, showSidebar: boolean) => { + localStorage.setItem(SIDEBAR_LOCAL_STORAGE_KEY, String(showSidebar)); + + return { + ...state, + layout: { + ...state.layout, + showSidebar + } + }; + }); + /** * Update the loading state * diff --git a/core-web/libs/edit-content/src/lib/models/dot-edit-content-form.interface.ts b/core-web/libs/edit-content/src/lib/models/dot-edit-content-form.interface.ts index 2f386e9c9853..3d1fa111df9d 100644 --- a/core-web/libs/edit-content/src/lib/models/dot-edit-content-form.interface.ts +++ b/core-web/libs/edit-content/src/lib/models/dot-edit-content-form.interface.ts @@ -5,4 +5,7 @@ export interface EditContentPayload { actions: DotCMSWorkflowAction[]; contentlet?: DotCMSContentlet; loading: boolean; + layout: { + showSidebar: boolean; + }; } diff --git a/core-web/libs/edit-content/src/lib/utils/mocks.ts b/core-web/libs/edit-content/src/lib/utils/mocks.ts index 3637b1fc2b2e..a9525f74a8a0 100644 --- a/core-web/libs/edit-content/src/lib/utils/mocks.ts +++ b/core-web/libs/edit-content/src/lib/utils/mocks.ts @@ -1092,7 +1092,10 @@ export const CONTENT_FORM_DATA_MOCK: EditContentPayload = { contentTypeIcon: 'event_note', variant: 'DEFAULT' }, - loading: false + loading: false, + layout: { + showSidebar: true + } }; /* CONTENT TYPE MOCKS */