From 9f08d4a3e6b14594168115b609acc1a7ea2de943 Mon Sep 17 00:00:00 2001 From: Pablo Martinez Garcia Date: Sat, 23 Oct 2021 20:25:53 +0200 Subject: [PATCH] [MNT-22606] Support preset config as input in content-metadata component (#7311) --- .../content-metadata-card.component.md | 6 ++- .../content-metadata-card.component.ts | 5 +- .../content-metadata.component.spec.ts | 24 ++++++++++ .../content-metadata.component.ts | 6 +-- .../src/lib/content-metadata/public-api.ts | 2 + .../config/content-metadata-config.factory.ts | 2 +- .../services/content-metadata.service.spec.ts | 46 ++++++++++++++++++- .../services/content-metadata.service.ts | 18 +++++--- .../properties-viewer-wrapper.component.ts | 5 +- .../src/lib/form/public-api.ts | 1 + 10 files changed, 98 insertions(+), 17 deletions(-) diff --git a/docs/content-services/components/content-metadata-card.component.md b/docs/content-services/components/content-metadata-card.component.md index 1e3c29de2c..8ad84bb66f 100644 --- a/docs/content-services/components/content-metadata-card.component.md +++ b/docs/content-services/components/content-metadata-card.component.md @@ -48,7 +48,7 @@ Displays and edits metadata related to a node. | displayEmpty | `boolean` | false | (optional) This flag displays/hides empty metadata fields. | | multi | `boolean` | false | (optional) This flag allows the component to display more than one accordion at a time. | | node | `Node` | | (required) The node entity to fetch metadata about | -| preset | `string` | | (required) Name of the metadata preset, which defines aspects and their properties. | +| preset | `string` or `PresetConfig` | | (required) Name or configuration of the metadata preset, which defines aspects and their properties. | | readOnly | `boolean` | false | (optional) This flag sets the metadata in read only mode preventing changes. | | displayDefaultProperties | `boolean` | | (optional) This flag displays/hides the metadata properties. | @@ -57,7 +57,9 @@ Displays and edits metadata related to a node. The component shows metadata related to a given node. It uses the [Card View component](../../core/components/card-view.component.md) to render the properties of metadata aspects. The different aspects and their properties to be shown can be configured as application config -presets (see below). By default the component only shows the basic properties of the node. +presets (see below) or the preset config can be provided directly as +[PresetConfig](../../../lib/content-services/src/lib/content-metadata/interfaces/preset-config.interface.ts "PresetConfig in preset-config.interface.ts"). +By default the component only shows the basic properties of the node. The user can click on the pencil icon at the bottom of the component to edit the metadata properties. diff --git a/lib/content-services/src/lib/content-metadata/components/content-metadata-card/content-metadata-card.component.ts b/lib/content-services/src/lib/content-metadata/components/content-metadata-card/content-metadata-card.component.ts index 78acf4e501..d48cc0b063 100644 --- a/lib/content-services/src/lib/content-metadata/components/content-metadata-card/content-metadata-card.component.ts +++ b/lib/content-services/src/lib/content-metadata/components/content-metadata-card/content-metadata-card.component.ts @@ -19,6 +19,7 @@ import { Component, Input, OnChanges, SimpleChanges, ViewEncapsulation } from '@ import { Node } from '@alfresco/js-api'; import { ContentService, AllowableOperationsEnum, VersionCompatibilityService } from '@alfresco/adf-core'; import { NodeAspectService } from '../../../aspect-list/node-aspect.service'; +import { PresetConfig } from '../../interfaces/content-metadata.interfaces'; @Component({ selector: 'adf-content-metadata-card', templateUrl: './content-metadata-card.component.html', @@ -44,11 +45,11 @@ export class ContentMetadataCardComponent implements OnChanges { @Input() displayAspect: string = null; - /** (required) Name of the metadata preset, which defines aspects + /** (required) Name or configuration of the metadata preset, which defines aspects * and their properties. */ @Input() - preset: string; + preset: string | PresetConfig; /** (optional) This flag sets the metadata in read only mode * preventing changes. diff --git a/lib/content-services/src/lib/content-metadata/components/content-metadata/content-metadata.component.spec.ts b/lib/content-services/src/lib/content-metadata/components/content-metadata/content-metadata.component.spec.ts index acb1a883b5..4d88ad1c5d 100644 --- a/lib/content-services/src/lib/content-metadata/components/content-metadata/content-metadata.component.spec.ts +++ b/lib/content-services/src/lib/content-metadata/components/content-metadata/content-metadata.component.spec.ts @@ -299,6 +299,30 @@ describe('ContentMetadataComponent', () => { expect(contentMetadataService.getGroupedProperties).toHaveBeenCalledWith(expectedNode, 'custom-preset'); }); + it('should load the group properties when preset config is provided on node change', () => { + const presetConfig = [ + { + title: 'My custom preset', + items: [ + { + type: 'my:type', + properties: '*' + }, + { + aspect: 'my:aspect', + properties: '*' + } + ] + } + ]; + component.preset = presetConfig; + spyOn(contentMetadataService, 'getGroupedProperties'); + + component.ngOnChanges({ node: new SimpleChange(node, expectedNode, false) }); + + expect(contentMetadataService.getGroupedProperties).toHaveBeenCalledWith(expectedNode, presetConfig); + }); + it('should pass through the loaded group properties to the card view', async () => { const expectedProperties = []; component.expanded = true; diff --git a/lib/content-services/src/lib/content-metadata/components/content-metadata/content-metadata.component.ts b/lib/content-services/src/lib/content-metadata/components/content-metadata/content-metadata.component.ts index 2fdbb64afe..b22ef10479 100644 --- a/lib/content-services/src/lib/content-metadata/components/content-metadata/content-metadata.component.ts +++ b/lib/content-services/src/lib/content-metadata/components/content-metadata/content-metadata.component.ts @@ -30,7 +30,7 @@ import { UpdateNotification } from '@alfresco/adf-core'; import { ContentMetadataService } from '../../services/content-metadata.service'; -import { CardViewGroup } from '../../interfaces/content-metadata.interfaces'; +import { CardViewGroup, PresetConfig } from '../../interfaces/content-metadata.interfaces'; import { takeUntil, debounceTime, catchError, map } from 'rxjs/operators'; @Component({ @@ -68,9 +68,9 @@ export class ContentMetadataComponent implements OnChanges, OnInit, OnDestroy { @Input() multi = false; - /** Name of the metadata preset, which defines aspects and their properties */ + /** Name or configuration of the metadata preset, which defines aspects and their properties */ @Input() - preset: string; + preset: string | PresetConfig; /** Toggles whether the metadata properties should be shown */ @Input() diff --git a/lib/content-services/src/lib/content-metadata/public-api.ts b/lib/content-services/src/lib/content-metadata/public-api.ts index 5963f9d74f..a1696c12b9 100644 --- a/lib/content-services/src/lib/content-metadata/public-api.ts +++ b/lib/content-services/src/lib/content-metadata/public-api.ts @@ -28,4 +28,6 @@ export * from './services/config/indifferent-config.service'; export * from './services/config/layout-oriented-config.service'; export * from './services/config/aspect-oriented-config.service'; +export * from './interfaces/content-metadata.interfaces'; + export * from './content-metadata.module'; diff --git a/lib/content-services/src/lib/content-metadata/services/config/content-metadata-config.factory.ts b/lib/content-services/src/lib/content-metadata/services/config/content-metadata-config.factory.ts index f6d5a74ae7..0d25b70fe0 100644 --- a/lib/content-services/src/lib/content-metadata/services/config/content-metadata-config.factory.ts +++ b/lib/content-services/src/lib/content-metadata/services/config/content-metadata-config.factory.ts @@ -51,7 +51,7 @@ export class ContentMetadataConfigFactory { return this.createConfig(presetConfig); } - private createConfig(presetConfig: PresetConfig): ContentMetadataConfig { + public createConfig(presetConfig: PresetConfig): ContentMetadataConfig { let config: ContentMetadataConfig; if (this.isLayoutOrientedPreset(presetConfig)) { diff --git a/lib/content-services/src/lib/content-metadata/services/content-metadata.service.spec.ts b/lib/content-services/src/lib/content-metadata/services/content-metadata.service.spec.ts index fa04715a4f..9525a885e1 100644 --- a/lib/content-services/src/lib/content-metadata/services/content-metadata.service.spec.ts +++ b/lib/content-services/src/lib/content-metadata/services/content-metadata.service.spec.ts @@ -273,5 +273,49 @@ describe('ContentMetaDataService', () => { expect(classesApi.getClass).toHaveBeenCalledTimes(1); expect(classesApi.getClass).toHaveBeenCalledWith('cm_content'); }); - }); + }); + + describe('Provided preset config', () => { + it('should create the metadata config on the fly when preset config is provided', async(done) => { + const fakeNode: Node = { name: 'Node Action', id: 'fake-id', nodeType: 'cm:content', isFile: true, aspectNames: [] } ; + + const customLayoutOrientedScheme = [ + { + 'id': 'app.content.metadata.customGroup', + 'title': 'Exif', + 'items': [ + { + 'id': 'app.content.metadata.exifAspect2', + 'aspect': 'exif:exif', + 'properties': '*' + } + ] + }, + { + 'id': 'app.content.metadata.customGroup2', + 'title': 'Properties', + 'items': [ + { + 'id': 'app.content.metadata.content', + 'aspect': 'cm:content', + 'properties': '*' + } + ] + } + ]; + + spyOn(classesApi, 'getClass').and.returnValue(Promise.resolve(contentResponse)); + + service.getGroupedProperties(fakeNode, customLayoutOrientedScheme).subscribe( + (res) => { + expect(res.length).toEqual(1); + expect(res[0].title).toEqual('Properties'); + done(); + } + ); + + expect(classesApi.getClass).toHaveBeenCalledTimes(1); + expect(classesApi.getClass).toHaveBeenCalledWith('cm_content'); + }); + }); }); diff --git a/lib/content-services/src/lib/content-metadata/services/content-metadata.service.ts b/lib/content-services/src/lib/content-metadata/services/content-metadata.service.ts index e920d455ce..7480cd7c1c 100644 --- a/lib/content-services/src/lib/content-metadata/services/content-metadata.service.ts +++ b/lib/content-services/src/lib/content-metadata/services/content-metadata.service.ts @@ -21,7 +21,7 @@ import { BasicPropertiesService } from './basic-properties.service'; import { Observable, of, iif, Subject } from 'rxjs'; import { PropertyGroupTranslatorService } from './property-groups-translator.service'; import { CardViewItem } from '@alfresco/adf-core'; -import { CardViewGroup, OrganisedPropertyGroup } from '../interfaces/content-metadata.interfaces'; +import { CardViewGroup, OrganisedPropertyGroup, PresetConfig } from '../interfaces/content-metadata.interfaces'; import { ContentMetadataConfigFactory } from './config/content-metadata-config.factory'; import { PropertyDescriptorsService } from './property-descriptors.service'; import { map, switchMap } from 'rxjs/operators'; @@ -52,14 +52,20 @@ export class ContentMetadataService { return this.contentTypePropertyService.openContentTypeDialogConfirm(changedProperties.nodeType); } - getGroupedProperties(node: Node, presetName: string = 'default'): Observable { + getGroupedProperties(node: Node, preset: string | PresetConfig = 'default'): Observable { let groupedProperties = of([]); if (node.aspectNames) { - const contentMetadataConfig = this.contentMetadataConfigFactory.get(presetName), - groupNames = node.aspectNames - .concat(node.nodeType) - .filter((groupName) => contentMetadataConfig.isGroupAllowed(groupName)); + let contentMetadataConfig; + if (typeof preset === 'string') { + contentMetadataConfig = this.contentMetadataConfigFactory.get(preset); + } else { + contentMetadataConfig = this.contentMetadataConfigFactory.createConfig(preset); + } + + const groupNames = node.aspectNames + .concat(node.nodeType) + .filter((groupName) => contentMetadataConfig.isGroupAllowed(groupName)); if (groupNames.length > 0) { groupedProperties = this.propertyDescriptorsService.load(groupNames).pipe( diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/properties-viewer/properties-viewer-wrapper/properties-viewer-wrapper.component.ts b/lib/process-services-cloud/src/lib/form/components/widgets/properties-viewer/properties-viewer-wrapper/properties-viewer-wrapper.component.ts index 53bcc98707..e8c612668a 100644 --- a/lib/process-services-cloud/src/lib/form/components/widgets/properties-viewer/properties-viewer-wrapper/properties-viewer-wrapper.component.ts +++ b/lib/process-services-cloud/src/lib/form/components/widgets/properties-viewer/properties-viewer-wrapper/properties-viewer-wrapper.component.ts @@ -18,6 +18,7 @@ import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges, ViewEncapsulation } from '@angular/core'; import { NodesApiService } from '@alfresco/adf-core'; import { Node } from '@alfresco/js-api'; +import { PresetConfig } from '@alfresco/adf-content-services'; /* tslint:disable:component-selector */ @@ -52,9 +53,9 @@ export class PropertiesViewerWrapperComponent implements OnInit, OnChanges { @Input() multi; - /** Name of the metadata preset, which defines aspects and their properties */ + /** Name or configuration of the metadata preset, which defines aspects and their properties */ @Input() - preset: string; + preset: string | PresetConfig; /** Toggles whether the metadata properties should be shown */ @Input() diff --git a/lib/process-services-cloud/src/lib/form/public-api.ts b/lib/process-services-cloud/src/lib/form/public-api.ts index c9f356573f..f2e5533509 100644 --- a/lib/process-services-cloud/src/lib/form/public-api.ts +++ b/lib/process-services-cloud/src/lib/form/public-api.ts @@ -28,6 +28,7 @@ export * from './components/widgets/date/date-cloud.widget'; export * from './components/widgets/dropdown/dropdown-cloud.widget'; export * from './components/widgets/group/group-cloud.widget'; export * from './components/widgets/people/people-cloud.widget'; +export * from './components/widgets/properties-viewer/properties-viewer.widget'; export * from './services/content-cloud-node-selector.service'; export * from './services/form-cloud.service';