diff --git a/e2e/content-services/metadata/metadata-smoke-tests.e2e.ts b/e2e/content-services/metadata/metadata-smoke-tests.e2e.ts index 834bd27730..85e375d636 100644 --- a/e2e/content-services/metadata/metadata-smoke-tests.e2e.ts +++ b/e2e/content-services/metadata/metadata-smoke-tests.e2e.ts @@ -160,23 +160,23 @@ describe('Metadata component', () => { await expect(await viewerPage.getActiveTab()).toEqual(METADATA.PROPERTY_TAB); await metadataViewPage.editIconClick(); - await metadataViewPage.editPropertyIconIsDisplayed('name'); + await metadataViewPage.editPropertyIconIsDisplayed('properties.cm:name'); await metadataViewPage.editPropertyIconIsDisplayed('properties.cm:title'); await metadataViewPage.editPropertyIconIsDisplayed('properties.cm:description'); - await expect(await metadataViewPage.getPropertyIconTooltip('name')).toEqual('Edit'); + await expect(await metadataViewPage.getPropertyIconTooltip('properties.cm:name')).toEqual('Edit'); await expect(await metadataViewPage.getPropertyIconTooltip('properties.cm:title')).toEqual('Edit'); await expect(await metadataViewPage.getPropertyIconTooltip('properties.cm:description')).toEqual('Edit'); - await metadataViewPage.enterPropertyText('name', 'exampleText'); + await metadataViewPage.enterPropertyText('properties.cm:name', 'exampleText'); await metadataViewPage.clickResetMetadata(); - await expect(await metadataViewPage.getPropertyText('name')).toEqual(browser.params.resources.Files.ADF_DOCUMENTS.PNG.file_name); + await expect(await metadataViewPage.getPropertyText('properties.cm:name')).toEqual(browser.params.resources.Files.ADF_DOCUMENTS.PNG.file_name); - await metadataViewPage.enterPropertyText('name', 'exampleText.png'); + await metadataViewPage.enterPropertyText('properties.cm:name', 'exampleText.png'); await metadataViewPage.enterPropertyText('properties.cm:title', 'example title'); await metadataViewPage.enterDescriptionText('example description'); - await expect(await metadataViewPage.getPropertyText('name')).toEqual('exampleText.png'); + await expect(await metadataViewPage.getPropertyText('properties.cm:name')).toEqual('exampleText.png'); await expect(await metadataViewPage.getPropertyText('properties.cm:title')).toEqual('example title'); await expect(await metadataViewPage.getPropertyText('properties.cm:description')).toEqual('example description'); await metadataViewPage.clickSaveMetadata(); @@ -190,13 +190,13 @@ describe('Metadata component', () => { await metadataViewPage.clickOnPropertiesTab(); await metadataViewPage.editIconIsDisplayed(); - await expect(await metadataViewPage.getPropertyText('name')).toEqual('exampleText.png'); + await expect(await metadataViewPage.getPropertyText('properties.cm:name')).toEqual('exampleText.png'); await expect(await metadataViewPage.getPropertyText('properties.cm:title')).toEqual('example title'); await expect(await metadataViewPage.getPropertyText('properties.cm:description')).toEqual('example description'); await metadataViewPage.editIconClick(); - await metadataViewPage.enterPropertyText('name', browser.params.resources.Files.ADF_DOCUMENTS.PNG.file_name); - await expect(await metadataViewPage.getPropertyText('name')).toEqual(browser.params.resources.Files.ADF_DOCUMENTS.PNG.file_name); + await metadataViewPage.enterPropertyText('properties.cm:name', browser.params.resources.Files.ADF_DOCUMENTS.PNG.file_name); + await expect(await metadataViewPage.getPropertyText('properties.cm:name')).toEqual(browser.params.resources.Files.ADF_DOCUMENTS.PNG.file_name); await metadataViewPage.clickSaveMetadata(); }); @@ -243,7 +243,7 @@ describe('Metadata component', () => { it('[C261157] Should be possible use the metadata component When the node is a Folder', async () => { await contentServicesPage.metadataContent(folderName); - await expect(await metadataViewPage.getPropertyText('name')).toEqual(folderName); + await expect(await metadataViewPage.getPropertyText('properties.cm:name')).toEqual(folderName); await expect(await metadataViewPage.getPropertyText('createdByUser.displayName')).toEqual(`${acsUser.firstName} ${acsUser.lastName}`); await BrowserActions.closeMenuAndDialogs(); }); @@ -253,17 +253,17 @@ describe('Metadata component', () => { await metadataViewPage.editIconClick(); - await metadataViewPage.enterPropertyText('name', 'newnameFolder'); + await metadataViewPage.enterPropertyText('properties.cm:name', 'newnameFolder'); await metadataViewPage.clickResetButton(); - await expect(await metadataViewPage.getPropertyText('name')).toEqual(folderName); + await expect(await metadataViewPage.getPropertyText('properties.cm:name')).toEqual(folderName); - await metadataViewPage.enterPropertyText('name', 'newnameFolder'); + await metadataViewPage.enterPropertyText('properties.cm:name', 'newnameFolder'); await metadataViewPage.clickSaveMetadata(); - await expect(await metadataViewPage.getPropertyText('name')).toEqual('newnameFolder'); + await expect(await metadataViewPage.getPropertyText('properties.cm:name')).toEqual('newnameFolder'); - await metadataViewPage.enterPropertyText('name', folderName); + await metadataViewPage.enterPropertyText('properties.cm:name', folderName); await metadataViewPage.clickSaveMetadata(); - await expect(await metadataViewPage.getPropertyText('name')).toEqual(folderName); + await expect(await metadataViewPage.getPropertyText('properties.cm:name')).toEqual(folderName); }); }); diff --git a/e2e/core/pages/metadata-view.page.ts b/e2e/core/pages/metadata-view.page.ts index 996b587d4a..4eabcac9d7 100644 --- a/e2e/core/pages/metadata-view.page.ts +++ b/e2e/core/pages/metadata-view.page.ts @@ -23,7 +23,7 @@ export class MetadataViewPage { title = element(by.css(`div[info-drawer-title]`)); expandedAspect = element(by.css(`mat-expansion-panel-header[aria-expanded='true']`)); aspectTitle: Locator = by.css(`mat-panel-title`); - name = element(by.css(`[data-automation-id='card-textitem-value-name']`)); + name = element(by.css(`[data-automation-id='card-textitem-value-properties.cm:name']`)); creator = element(by.css(`[data-automation-id='card-textitem-value-createdByUser.displayName']`)); createdDate = element(by.css(`span[data-automation-id='card-dateitem-createdAt'] span`)); modifier = element(by.css(`[data-automation-id='card-textitem-value-modifiedByUser.displayName']`)); diff --git a/e2e/core/viewer/viewer-content-services-component.e2e.ts b/e2e/core/viewer/viewer-content-services-component.e2e.ts index 53b22f3269..7219592668 100644 --- a/e2e/core/viewer/viewer-content-services-component.e2e.ts +++ b/e2e/core/viewer/viewer-content-services-component.e2e.ts @@ -464,7 +464,7 @@ describe('Content Services Viewer', () => { await viewerPage.clickOnTab('Properties'); await viewerPage.checkTabIsActive('Properties'); await metadataViewPage.editIconClick(); - await metadataViewPage.enterPropertyText('name', newName); + await metadataViewPage.enterPropertyText('properties.cm:name', newName); await metadataViewPage.clickSaveMetadata(); await viewerPage.clickCloseButton(); } 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 9289ca1f83..c974fef615 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 @@ -240,7 +240,7 @@ describe('ContentMetadataComponent', () => { component.ngOnChanges({ node: new SimpleChange(node, expectedNode, false) }); - expect(contentMetadataService.getContentTypeProperty).toHaveBeenCalledWith(node.nodeType); + expect(contentMetadataService.getContentTypeProperty).toHaveBeenCalledWith(expectedNode); expect(contentMetadataService.getBasicProperties).toHaveBeenCalledWith(expectedNode); }); 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 0fd8e93cec..3ef18277c5 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 @@ -168,9 +168,12 @@ export class ContentMetadataComponent implements OnChanges, OnInit, OnDestroy { private getProperties(node: Node) { const properties$ = this.contentMetadataService.getBasicProperties(node); - const contentTypeProperty$ = this.contentMetadataService.getContentTypeProperty(node.nodeType); + const contentTypeProperty$ = this.contentMetadataService.getContentTypeProperty(node); return zip(properties$, contentTypeProperty$) - .pipe(map(([properties, contentTypeProperty]) => [...properties, ...contentTypeProperty])); + .pipe(map(([properties, contentTypeProperty]) => { + const filteredProperties = contentTypeProperty.filter((property) => properties.findIndex((baseProperty) => baseProperty.key === property.key) === -1); + return [...properties, ...filteredProperties]; + })); } updateChanges(updatedNodeChanges) { diff --git a/lib/content-services/src/lib/content-metadata/services/basic-properties.service.ts b/lib/content-services/src/lib/content-metadata/services/basic-properties.service.ts index f867c76061..78e2703f48 100644 --- a/lib/content-services/src/lib/content-metadata/services/basic-properties.service.ts +++ b/lib/content-services/src/lib/content-metadata/services/basic-properties.service.ts @@ -38,7 +38,7 @@ export class BasicPropertiesService { new CardViewTextItemModel({ label: 'CORE.METADATA.BASIC.NAME', value: node.name, - key: 'name', + key: 'properties.cm:name', editable: true }), new CardViewTextItemModel({ 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 3b2157fc73..2d958f2346 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 @@ -93,9 +93,19 @@ describe('ContentMetaDataService', () => { }); it('should return the content type property', () => { + const fakeNode: Node = { + name: 'Node', + id: 'fake-id', + isFile: true, + aspectNames: ['exif:exif'], + nodeType: 'fn:fakenode', + createdByUser: {displayName: 'test-user'}, + modifiedByUser: {displayName: 'test-user-modified'}, + properties: [] + }; spyOn(contentPropertyService, 'getContentTypeCardItem').and.returnValue(of({ label: 'hello i am a weird content type'})); - service.getContentTypeProperty('fn:fakenode').subscribe( + service.getContentTypeProperty(fakeNode).subscribe( (res: any) => { expect(res).toBeDefined(); expect(res).not.toBeNull(); 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 61d2c0d2c6..e920d455ce 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 @@ -44,8 +44,8 @@ export class ContentMetadataService { return of(this.basicPropertiesService.getProperties(node)); } - getContentTypeProperty(nodeType: string): Observable { - return this.contentTypePropertyService.getContentTypeCardItem(nodeType); + getContentTypeProperty(node: Node): Observable { + return this.contentTypePropertyService.getContentTypeCardItem(node); } openConfirmDialog(changedProperties): Observable { diff --git a/lib/content-services/src/lib/content-metadata/services/content-type-property.service.spec.ts b/lib/content-services/src/lib/content-metadata/services/content-type-property.service.spec.ts index 61a148344c..f94b67cb95 100644 --- a/lib/content-services/src/lib/content-metadata/services/content-type-property.service.spec.ts +++ b/lib/content-services/src/lib/content-metadata/services/content-type-property.service.spec.ts @@ -22,6 +22,7 @@ import { ContentTestingModule } from '../../testing/content.testing.module'; import { TranslateModule } from '@ngx-translate/core'; import { ContentTypeService } from '../../content-type'; import { of } from 'rxjs'; +import { Node } from '@alfresco/js-api'; describe('ContentTypePropertyService', () => { @@ -29,16 +30,59 @@ describe('ContentTypePropertyService', () => { let versionCompatibilityService: VersionCompatibilityService; let contentTypeService: ContentTypeService; - const mockContent: any = { 'entry': - { 'associations': [], - 'isArchive': true, - 'includedInSupertypeQuery': true, - 'description': 'Base Content Object', - 'isContainer': false, - 'id': 'fk:nodeType', - 'title': 'Content', - 'properties': [{ 'id': 'cm:name', 'title': 'Name', 'description': 'Name', 'dataType': 'd:text', 'isMultiValued': false, 'isMandatory': true, 'isMandatoryEnforced': true, 'isProtected': false}], - 'parentId': 'cm:cmobject' } }; + const mockContent: any = { + 'entry': + { + 'associations': [], + 'isArchive': true, + 'includedInSupertypeQuery': true, + 'description': 'Base Content Object', + 'isContainer': false, + 'id': 'fk:nodeType', + 'title': 'Content', + 'model': { 'namespacePrefix': 'fk' }, + 'properties': [{ 'id': 'cm:name', 'title': 'Name', 'description': 'Name', 'dataType': 'd:text', 'isMultiValued': false, 'isMandatory': true, 'isMandatoryEnforced': true, 'isProtected': false }], + 'parentId': 'cm:cmobject' + } + }; + + const mockContentWithProperties: any = { + 'entry': + { + 'associations': [], + 'isArchive': true, + 'includedInSupertypeQuery': true, + 'description': 'Base Content Object', + 'isContainer': false, + 'id': 'fk:nodeType', + 'title': 'Content', + 'model': { 'namespacePrefix': 'fk' }, + 'properties': [ + { + 'id': 'cm:name', + 'title': 'Name', + 'description': 'Name', + 'dataType': 'd:text', + 'isMultiValued': false, + 'isMandatory': true, + 'isMandatoryEnforced': true, + 'isProtected': false + }, + { + 'id': 'fk:brendonstare', + 'title': 'Brendon', + 'description': 'is watching the dark emperor', + 'dataType': 'd:text', + 'isMultiValued': false, + 'isMandatory': true, + 'defaultValue': 'default', + 'isMandatoryEnforced': true, + 'isProtected': false + }], + 'parentId': 'cm:cmobject' + } + }; + const mockSelectOptions = { 'list': { @@ -88,8 +132,18 @@ describe('ContentTypePropertyService', () => { }); it('should return a card text item for ACS version below 7', (done) => { + const fakeNode: Node = { + name: 'Node', + id: 'fake-id', + isFile: true, + aspectNames: ['exif:exif'], + nodeType: 'fk:nodeType', + createdByUser: { displayName: 'test-user' }, + modifiedByUser: { displayName: 'test-user-modified' }, + properties: {} + }; spyOn(versionCompatibilityService, 'isVersionSupported').and.returnValue(false); - service.getContentTypeCardItem('fk:nodeType').subscribe((items: CardViewItem[]) => { + service.getContentTypeCardItem(fakeNode).subscribe((items: CardViewItem[]) => { expect(items.length).toBe(1); expect(items[0] instanceof CardViewTextItemModel).toBeTruthy(); expect(items[0].label).toBe('CORE.METADATA.BASIC.CONTENT_TYPE'); @@ -101,10 +155,20 @@ describe('ContentTypePropertyService', () => { }); it('should return a card select item for ACS version 7 and above', (done) => { + const fakeNode: Node = { + name: 'Node', + id: 'fake-id', + isFile: true, + aspectNames: ['exif:exif'], + nodeType: 'fn:fakenode', + createdByUser: { displayName: 'test-user' }, + modifiedByUser: { displayName: 'test-user-modified' }, + properties: {} + }; spyOn(versionCompatibilityService, 'isVersionSupported').and.returnValue(true); spyOn(contentTypeService, 'getContentTypeByPrefix').and.returnValue(of(mockContent)); spyOn(contentTypeService, 'getContentTypeChildren').and.returnValue(of(mockSelectOptions)); - service.getContentTypeCardItem('fk:nodeType').subscribe((items: CardViewItem[]) => { + service.getContentTypeCardItem(fakeNode).subscribe((items: CardViewItem[]) => { expect(items.length).toBe(1); expect(items[0] instanceof CardViewSelectItemModel).toBeTruthy(); expect(items[0].label).toBe('CORE.METADATA.BASIC.CONTENT_TYPE'); @@ -115,4 +179,66 @@ describe('ContentTypePropertyService', () => { }); }); + it('should return a list of cards for the content type and all its own properties', (done) => { + const fakeNode: Node = { + name: 'Node', + id: 'fake-id', + isFile: true, + aspectNames: ['exif:exif'], + nodeType: 'fn:fakenode', + createdByUser: { displayName: 'test-user' }, + modifiedByUser: { displayName: 'test-user-modified' }, + properties: {} + }; + spyOn(versionCompatibilityService, 'isVersionSupported').and.returnValue(true); + spyOn(contentTypeService, 'getContentTypeByPrefix').and.returnValue(of(mockContentWithProperties)); + spyOn(contentTypeService, 'getContentTypeChildren').and.returnValue(of(mockSelectOptions)); + service.getContentTypeCardItem(fakeNode).subscribe((items: CardViewItem[]) => { + expect(items.length).toBe(2); + expect(items[0] instanceof CardViewSelectItemModel).toBeTruthy(); + expect(items[0].label).toBe('CORE.METADATA.BASIC.CONTENT_TYPE'); + expect(items[0].value).toBe('fk:nodeType'); + expect(items[0].key).toBe('nodeType'); + expect(items[0].editable).toBeTruthy(); + + expect(items[1] instanceof CardViewTextItemModel).toBeTruthy(); + expect(items[1].label).toBe('Brendon'); + expect(items[1].value).toBe('default'); + expect(items[1].key).toBe('properties.fk:brendonstare'); + expect(items[1].editable).toBeTruthy(); + done(); + }); + }); + + it('should return a list of cards for the content type and all its own properties with relative value set', (done) => { + const fakeNode: Node = { + name: 'Node', + id: 'fake-id', + isFile: true, + aspectNames: ['exif:exif'], + nodeType: 'fn:fakenode', + createdByUser: { displayName: 'test-user' }, + modifiedByUser: { displayName: 'test-user-modified' }, + properties: {'fk:brendonstare': 'i keep staring i do not know why'} + }; + spyOn(versionCompatibilityService, 'isVersionSupported').and.returnValue(true); + spyOn(contentTypeService, 'getContentTypeByPrefix').and.returnValue(of(mockContentWithProperties)); + spyOn(contentTypeService, 'getContentTypeChildren').and.returnValue(of(mockSelectOptions)); + service.getContentTypeCardItem(fakeNode).subscribe((items: CardViewItem[]) => { + expect(items.length).toBe(2); + expect(items[0] instanceof CardViewSelectItemModel).toBeTruthy(); + expect(items[0].label).toBe('CORE.METADATA.BASIC.CONTENT_TYPE'); + expect(items[0].value).toBe('fk:nodeType'); + expect(items[0].key).toBe('nodeType'); + expect(items[0].editable).toBeTruthy(); + + expect(items[1] instanceof CardViewTextItemModel).toBeTruthy(); + expect(items[1].label).toBe('Brendon'); + expect(items[1].value).toBe('i keep staring i do not know why'); + expect(items[1].key).toBe('properties.fk:brendonstare'); + expect(items[1].editable).toBeTruthy(); + done(); + }); + }); + }); diff --git a/lib/content-services/src/lib/content-metadata/services/content-type-property.service.ts b/lib/content-services/src/lib/content-metadata/services/content-type-property.service.ts index 742670de20..de8c357041 100644 --- a/lib/content-services/src/lib/content-metadata/services/content-type-property.service.ts +++ b/lib/content-services/src/lib/content-metadata/services/content-type-property.service.ts @@ -23,7 +23,8 @@ import { distinctUntilChanged, map } from 'rxjs/operators'; import { ContentTypeDialogComponent } from '../../content-type/content-type-dialog.component'; import { ContentTypeDialogComponentData } from '../../content-type/content-type-metadata.interface'; import { ContentTypeService } from '../../content-type/content-type.service'; -import { TypeEntry } from '@alfresco/js-api'; +import { Node, Property, TypeEntry } from '@alfresco/js-api'; +import { PropertyGroupTranslatorService } from './property-groups-translator.service'; @Injectable({ providedIn: 'root' @@ -32,23 +33,41 @@ export class ContentTypePropertiesService { constructor(private contentTypeService: ContentTypeService, private dialog: MatDialog, - private versionCompatibilityService: VersionCompatibilityService) { + private versionCompatibilityService: VersionCompatibilityService, + private propertyGroupTranslatorService: PropertyGroupTranslatorService) { } - getContentTypeCardItem(nodeType: string): Observable { + getContentTypeCardItem(node: Node): Observable { if (this.versionCompatibilityService.isVersionSupported('7')) { - return this.contentTypeService.getContentTypeByPrefix(nodeType). + return this.contentTypeService.getContentTypeByPrefix(node.nodeType). pipe( map((contentType) => { const contentTypesOptions$ = this.getContentTypesAsSelectOption(contentType); const contentTypeCard = this.buildContentTypeSelectCardModel(contentType.entry.id, contentTypesOptions$); - return [contentTypeCard]; + const filteredProperties = this.getContentTypeSpecificProperties(contentType); + const propertiesCard = this.buildCardItemsFromPropertyList(filteredProperties, node.properties); + return [contentTypeCard, ...propertiesCard]; })); } else { - return of([this.buildContentTypeTextCardModel(nodeType)]); + return of([this.buildContentTypeTextCardModel(node.nodeType)]); } } + buildCardItemsFromPropertyList(properties: Property[], currentProperties: any): CardViewItem[] { + return properties.map((property) => { + const propertyValue = currentProperties ? currentProperties[property.id] : null; + return this.buildCardItemFromProperty(property, propertyValue); + }); + } + + private buildCardItemFromProperty(property: Property, propertyValue: any): CardViewItem { + return this.propertyGroupTranslatorService.translateProperty(property, propertyValue, true); + } + + private getContentTypeSpecificProperties(contentType: TypeEntry): Property[] { + return contentType.entry.properties.filter((property) => property.id.startsWith(contentType.entry.model.namespacePrefix)); + } + private buildContentTypeTextCardModel(currentValue: string): CardViewTextItemModel { const contentTypeCard = new CardViewTextItemModel({ label: 'CORE.METADATA.BASIC.CONTENT_TYPE', diff --git a/lib/content-services/src/lib/content-metadata/services/property-groups-translator.service.spec.ts b/lib/content-services/src/lib/content-metadata/services/property-groups-translator.service.spec.ts index 5126fb0782..d3e15f4dfb 100644 --- a/lib/content-services/src/lib/content-metadata/services/property-groups-translator.service.spec.ts +++ b/lib/content-services/src/lib/content-metadata/services/property-groups-translator.service.spec.ts @@ -32,7 +32,7 @@ import { } from '@alfresco/adf-core'; import { ContentTestingModule } from '../../testing/content.testing.module'; import { TranslateModule } from '@ngx-translate/core'; -import { Constraint, Definition } from '@alfresco/js-api'; +import { Constraint, Definition, Property as PropertyBase } from '@alfresco/js-api'; describe('PropertyGroupTranslatorService', () => { @@ -341,5 +341,45 @@ describe('PropertyGroupTranslatorService', () => { expect(cardViewProperty instanceof CardViewSelectItemModel).toBeTruthy('Property should be instance of CardViewBoolItemModel'); expect(cardViewProperty.value).toBe('two'); }); + + it('should translate content type properties into card items', () => { + const propertyBase = { + 'id': 'fk:brendonstare', + 'title': 'Brendon', + 'description': 'is watching the dark emperor', + 'dataType': 'd:text', + 'isMultiValued': true, + 'isMandatory': true, + 'defaultValue': 'default', + 'isMandatoryEnforced': true, + 'isProtected': false + }; + + const cardViewProperty = service.translateProperty(propertyBase, 'Scary Brandon and the DuckTales', true); + + expect(cardViewProperty instanceof CardViewTextItemModel).toBeTruthy('Property should be instance of CardViewTextItemModel'); + expect(cardViewProperty.value).toBe('Scary Brandon and the DuckTales'); + expect(cardViewProperty.key).toBe('properties.fk:brendonstare'); + }); + + it('should translate content type properties into card items with default value when no value is passed', () => { + const propertyBase = { + 'id': 'fk:brendonstare', + 'title': 'Brendon', + 'description': 'is watching the dark emperor', + 'dataType': 'd:text', + 'isMultiValued': true, + 'isMandatory': true, + 'defaultValue': 'default', + 'isMandatoryEnforced': true, + 'isProtected': false + }; + + const cardViewProperty = service.translateProperty(propertyBase, null, true); + + expect(cardViewProperty instanceof CardViewTextItemModel).toBeTruthy('Property should be instance of CardViewTextItemModel'); + expect(cardViewProperty.value).toBe('default'); + expect(cardViewProperty.key).toBe('properties.fk:brendonstare'); + }); }); }); diff --git a/lib/content-services/src/lib/content-metadata/services/property-groups-translator.service.ts b/lib/content-services/src/lib/content-metadata/services/property-groups-translator.service.ts index a3803dec1f..acb70e6a62 100644 --- a/lib/content-services/src/lib/content-metadata/services/property-groups-translator.service.ts +++ b/lib/content-services/src/lib/content-metadata/services/property-groups-translator.service.ts @@ -33,7 +33,7 @@ import { } from '@alfresco/adf-core'; import { Property, CardViewGroup, OrganisedPropertyGroup } from '../interfaces/content-metadata.interfaces'; import { of } from 'rxjs'; -import { Definition, Constraint } from '@alfresco/js-api'; +import { Definition, Constraint, Property as PropertyBase } from '@alfresco/js-api'; const D_TEXT = 'd:text'; const D_MLTEXT = 'd:mltext'; @@ -69,6 +69,23 @@ export class PropertyGroupTranslatorService { }); } + public translateProperty(property: PropertyBase, startValue?: any, allowEditing: boolean = false): CardViewItem { + this.checkECMTypeValidity(property.dataType); + + const prefix = 'properties.'; + + const propertyDefinition: CardViewItemProperties = { + label: property.title || property.id, + value: startValue ? startValue : property.defaultValue, + key: `${prefix}${property.id}`, + default: property.defaultValue, + editable: !!allowEditing ? allowEditing : false, + constraints: property?.constraints + }; + + return this.transform(propertyDefinition, property.dataType, property.isMultiValued); + } + private translateArray(properties: Property[], propertyValues: any, definition: Definition): CardViewItem[] { return properties.map((property) => { return this.translate(property, propertyValues, this.getPropertyConstraints(property.name, definition)); @@ -94,6 +111,10 @@ export class PropertyGroupTranslatorService { constraints: constraints }; + return this.transform(propertyDefinition, property.dataType, property.multiValued); + } + + private transform(propertyDefinition: CardViewItemProperties, dataType: string, isMultiValued: boolean): CardViewItem { let cardViewItemProperty: CardViewItem; if (this.isListOfValues(propertyDefinition.constraints)) { @@ -102,7 +123,7 @@ export class PropertyGroupTranslatorService { cardViewItemProperty = new CardViewSelectItemModel(properties); } else { - switch (property.dataType) { + switch (dataType) { case D_MLTEXT: cardViewItemProperty = new CardViewTextItemModel(Object.assign(propertyDefinition, { multiline: true @@ -136,8 +157,8 @@ export class PropertyGroupTranslatorService { case D_TEXT: default: cardViewItemProperty = new CardViewTextItemModel(Object.assign(propertyDefinition, { - multivalued: property.multiValued, - multiline: property.multiValued, + multivalued: isMultiValued, + multiline: isMultiValued, pipes: [{ pipe: this.multiValuePipe, params: [this.valueSeparator]}] })); }