From bacd61da4d6894581c0105d4174d193f601e20bd Mon Sep 17 00:00:00 2001 From: Nicolas Molina Monroy Date: Wed, 19 Jun 2024 09:36:55 -0400 Subject: [PATCH] Filter system host when is isRequired (#28931) If a host/folder field is marked as required, then we do not allow/show SYSTEM_HOST ### Proposed Changes * Add isRequired attr to enable filter ### Checklist - [x] Tests - [x] Translations - [x] Security Implications Contemplated (add notes if applicable) --- ...dit-content-host-folder-field.component.ts | 8 +++- .../store/host-folder-field.store.ts | 2 +- .../store/methods/loadSites.spec.ts | 47 +++++++++++++++++++ .../store/methods/loadSites.ts | 18 ++++++- .../libs/edit-content/src/lib/utils/mocks.ts | 11 +++++ .../ema-contentlet-tools.component.html | 12 ++--- .../edit-ema-editor.component.html | 32 +++++++------ 7 files changed, 104 insertions(+), 26 deletions(-) create mode 100644 core-web/libs/edit-content/src/lib/fields/dot-edit-content-host-folder-field/store/methods/loadSites.spec.ts diff --git a/core-web/libs/edit-content/src/lib/fields/dot-edit-content-host-folder-field/dot-edit-content-host-folder-field.component.ts b/core-web/libs/edit-content/src/lib/fields/dot-edit-content-host-folder-field/dot-edit-content-host-folder-field.component.ts index c85e58d10471..2181313bc740 100644 --- a/core-web/libs/edit-content/src/lib/fields/dot-edit-content-host-folder-field/dot-edit-content-host-folder-field.component.ts +++ b/core-web/libs/edit-content/src/lib/fields/dot-edit-content-host-folder-field/dot-edit-content-host-folder-field.component.ts @@ -8,7 +8,7 @@ import { effect, inject } from '@angular/core'; -import { ControlContainer, FormControl, ReactiveFormsModule } from '@angular/forms'; +import { ControlContainer, FormControl, ReactiveFormsModule, Validators } from '@angular/forms'; import { DotCMSContentTypeField } from '@dotcms/dotcms-models'; @@ -64,7 +64,11 @@ export class DotEditContentHostFolderFieldComponent implements OnInit { ngOnInit() { const currentPath = this.formControl.value; - this.store.loadSites(currentPath); + const isRequired = this.formControl.hasValidator(Validators.required); + this.store.loadSites({ + path: currentPath, + isRequired + }); } get formControl(): FormControl { diff --git a/core-web/libs/edit-content/src/lib/fields/dot-edit-content-host-folder-field/store/host-folder-field.store.ts b/core-web/libs/edit-content/src/lib/fields/dot-edit-content-host-folder-field/store/host-folder-field.store.ts index 1fd28a4ad12d..b0412f07a4d1 100644 --- a/core-web/libs/edit-content/src/lib/fields/dot-edit-content-host-folder-field/store/host-folder-field.store.ts +++ b/core-web/libs/edit-content/src/lib/fields/dot-edit-content-host-folder-field/store/host-folder-field.store.ts @@ -21,7 +21,7 @@ export type HostFolderFiledState = { error: string | null; }; -const initialState: HostFolderFiledState = { +export const initialState: HostFolderFiledState = { nodeSelected: null, nodeExpaned: null, tree: [], diff --git a/core-web/libs/edit-content/src/lib/fields/dot-edit-content-host-folder-field/store/methods/loadSites.spec.ts b/core-web/libs/edit-content/src/lib/fields/dot-edit-content-host-folder-field/store/methods/loadSites.spec.ts new file mode 100644 index 000000000000..c6f3d00cadef --- /dev/null +++ b/core-web/libs/edit-content/src/lib/fields/dot-edit-content-host-folder-field/store/methods/loadSites.spec.ts @@ -0,0 +1,47 @@ +import { SpyObject, createSpyObject } from '@ngneat/spectator/jest'; +import { signalStore, withState } from '@ngrx/signals'; +import { of } from 'rxjs'; + +import { TestBed } from '@angular/core/testing'; + +import { loadSites, SYSTEM_HOST_NAME } from './loadSites'; + +import { DotEditContentService } from '../../../../services/dot-edit-content.service'; +import { TREE_SELECT_SITES_MOCK } from '../../../../utils/mocks'; +import { initialState } from '../host-folder-field.store'; + +describe('rxMethod: loadSites', () => { + let Store = signalStore(withState(initialState)); + let store: InstanceType; + let service: SpyObject; + + beforeEach(() => { + service = createSpyObject(DotEditContentService); + Store = signalStore(withState(initialState)); + store = new Store(); + }); + + it('should include System Host when isRequired is false.', () => { + service.getSitesTreePath.mockReturnValue(of(TREE_SELECT_SITES_MOCK)); + const rxMethod = TestBed.runInInjectionContext(() => loadSites(store, service)); + const props = { + path: '', + isRequired: false + }; + rxMethod(props); + const hasSystemHost = store.tree().some((item) => item.label === SYSTEM_HOST_NAME); + expect(hasSystemHost).toBe(true); + }); + + it('should not include System Host when isRequired is true.', () => { + service.getSitesTreePath.mockReturnValue(of(TREE_SELECT_SITES_MOCK)); + const rxMethod = TestBed.runInInjectionContext(() => loadSites(store, service)); + const props = { + path: '', + isRequired: true + }; + rxMethod(props); + const hasSystemHost = store.tree().some((item) => item.label === SYSTEM_HOST_NAME); + expect(hasSystemHost).toBe(false); + }); +}); diff --git a/core-web/libs/edit-content/src/lib/fields/dot-edit-content-host-folder-field/store/methods/loadSites.ts b/core-web/libs/edit-content/src/lib/fields/dot-edit-content-host-folder-field/store/methods/loadSites.ts index 2ee0e272be09..cadd21cffedf 100644 --- a/core-web/libs/edit-content/src/lib/fields/dot-edit-content-host-folder-field/store/methods/loadSites.ts +++ b/core-web/libs/edit-content/src/lib/fields/dot-edit-content-host-folder-field/store/methods/loadSites.ts @@ -11,14 +11,28 @@ import type { HostFolderFiledState } from './../host-folder-field.store'; const PEER_PAGE_LIMIT = 7000; +type Props = { + path: string | null; + isRequired: boolean; +}; + +export const SYSTEM_HOST_NAME = 'System Host'; + export const loadSites = (store, dotEditContentService: DotEditContentService) => { - return rxMethod( + return rxMethod( pipe( tap(() => patchState(store, { status: 'LOADING' })), - switchMap((path) => { + switchMap(({ path, isRequired }) => { return dotEditContentService .getSitesTreePath({ perPage: PEER_PAGE_LIMIT, filter: '*' }) .pipe( + map((sites) => { + if (isRequired) { + return sites.filter((site) => site.label !== SYSTEM_HOST_NAME); + } + + return sites; + }), tapResponse({ next: (sites) => patchState(store, { tree: sites }), error: () => patchState(store, { status: 'FAILED', error: '' }), 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 d94d3cffc211..e52555a4978f 100644 --- a/core-web/libs/edit-content/src/lib/utils/mocks.ts +++ b/core-web/libs/edit-content/src/lib/utils/mocks.ts @@ -1211,6 +1211,17 @@ export const TREE_SELECT_SITES_MOCK: TreeNodeItem[] = [ }, expandedIcon: 'pi pi-folder-open', collapsedIcon: 'pi pi-folder' + }, + { + key: 'System Host', + label: 'System Host', + data: { + hostname: 'System Host', + path: '', + type: 'site' + }, + expandedIcon: 'pi pi-folder-open', + collapsedIcon: 'pi pi-folder' } ]; diff --git a/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/ema-contentlet-tools/ema-contentlet-tools.component.html b/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/ema-contentlet-tools/ema-contentlet-tools.component.html index 50b395c77bf3..bd039facb875 100644 --- a/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/ema-contentlet-tools/ema-contentlet-tools.component.html +++ b/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/ema-contentlet-tools/ema-contentlet-tools.component.html @@ -13,12 +13,12 @@
@if (contentletArea.payload.vtlFiles?.length) { - - + + } - @if ( es.editorData.canEditVariant && (es.editorData.mode === editorMode.EDIT || - es.editorData.mode === editorMode.EDIT_VARIANT) ) { - - + @if ( + es.editorData.canEditVariant && + (es.editorData.mode === editorMode.EDIT || es.editorData.mode === editorMode.EDIT_VARIANT) + ) { + + }