[ADF-3484] - Metadata drop-down list option for properties constrained by a list of values (#5892)

* update js-api

* include definition field

* process LIST constraint

* update tests

* dropdown visibility

* optional chaining
This commit is contained in:
Cilibiu Bogdan
2020-07-22 00:46:46 +03:00
committed by GitHub
parent 826bd32e60
commit 5257917258
10 changed files with 4337 additions and 3332 deletions

View File

@@ -63,7 +63,7 @@ export class ContentMetadataService {
map((groups) => contentMetadataConfig.filterExcludedPreset(groups)),
map((groups) => this.filterEmptyPreset(groups)),
map((groups) => this.setTitleToNameIfNotSet(groups)),
map((groups) => this.propertyGroupTranslatorService.translateToCardViewGroups(groups, node.properties))
map((groups) => this.propertyGroupTranslatorService.translateToCardViewGroups(groups, node.properties, node.definition))
);
}
}

View File

@@ -26,10 +26,13 @@ import {
LogService,
CardViewBoolItemModel,
CardViewDatetimeItemModel,
setupTestBed
CardViewSelectItemModel,
setupTestBed,
CardViewSelectItemProperties
} from '@alfresco/adf-core';
import { ContentTestingModule } from '../../testing/content.testing.module';
import { TranslateModule } from '@ngx-translate/core';
import { Constraint, Definition } from '@alfresco/js-api';
describe('PropertyGroupTranslatorService', () => {
@@ -95,7 +98,7 @@ describe('PropertyGroupTranslatorService', () => {
propertyValues = { 'FAS:PLAGUE': 'The Chariot Line' };
const cardViewGroup = service.translateToCardViewGroups(propertyGroups, propertyValues);
const cardViewGroup = service.translateToCardViewGroups(propertyGroups, propertyValues, null);
expect(cardViewGroup[0].properties.length).toBe(2);
expect(cardViewGroup[0].properties[0] instanceof CardViewTextItemModel).toBeTruthy('First property should be instance of CardViewTextItemModel');
expect(cardViewGroup[0].properties[1] instanceof CardViewTextItemModel).toBeTruthy('Second property should be instance of CardViewTextItemModel');
@@ -127,7 +130,7 @@ describe('PropertyGroupTranslatorService', () => {
propertyValues = { 'FAS:PLAGUE': 'The Chariot Line' };
const cardViewGroup = service.translateToCardViewGroups(propertyGroups, propertyValues);
const cardViewGroup = service.translateToCardViewGroups(propertyGroups, propertyValues, null);
expect(cardViewGroup.length).toBe(2);
expect(cardViewGroup[0].properties[0] instanceof CardViewTextItemModel).toBeTruthy('First group\'s property should be instance of CardViewTextItemModel');
expect(cardViewGroup[1].properties[0] instanceof CardViewTextItemModel).toBeTruthy('Second group\'s property should be instance of CardViewTextItemModel');
@@ -145,7 +148,7 @@ describe('PropertyGroupTranslatorService', () => {
propertyGroups.push(Object.assign({}, propertyGroup));
service.translateToCardViewGroups(propertyGroups, propertyValues);
service.translateToCardViewGroups(propertyGroups, propertyValues, null);
expect(logService.error).toHaveBeenCalledWith('Unknown type for mapping: daemonic:scorcher');
});
@@ -161,7 +164,7 @@ describe('PropertyGroupTranslatorService', () => {
propertyValues = { 'FAS:PLAGUE': 'The Chariot Line' };
const cardViewGroup = service.translateToCardViewGroups(propertyGroups, propertyValues);
const cardViewGroup = service.translateToCardViewGroups(propertyGroups, propertyValues, null);
const cardViewProperty: CardViewTextItemModel = <CardViewTextItemModel> cardViewGroup[0].properties[0];
expect(cardViewProperty instanceof CardViewTextItemModel).toBeTruthy('Property should be instance of CardViewTextItemModel');
});
@@ -181,7 +184,7 @@ describe('PropertyGroupTranslatorService', () => {
property.dataType = dataType;
propertyValues = { 'prefix:name': null };
const cardViewGroup = service.translateToCardViewGroups(propertyGroups, propertyValues);
const cardViewGroup = service.translateToCardViewGroups(propertyGroups, propertyValues, null);
const cardViewProperty = cardViewGroup[0].properties[0];
expect(cardViewProperty.label).toBe(property.title);
@@ -195,7 +198,7 @@ describe('PropertyGroupTranslatorService', () => {
property.dataType = 'd:text';
propertyValues = { 'FAS:PLAGUE': 'The Chariot Line' };
const cardViewGroup = service.translateToCardViewGroups(propertyGroups, propertyValues);
const cardViewGroup = service.translateToCardViewGroups(propertyGroups, propertyValues, null);
const cardViewProperty: CardViewTextItemModel = <CardViewTextItemModel> cardViewGroup[0].properties[0];
expect(cardViewProperty instanceof CardViewTextItemModel).toBeTruthy('Property should be instance of CardViewTextItemModel');
@@ -207,7 +210,7 @@ describe('PropertyGroupTranslatorService', () => {
property.dataType = 'd:mltext';
propertyValues = { 'FAS:PLAGUE': 'The Chariot Line' };
const cardViewGroup = service.translateToCardViewGroups(propertyGroups, propertyValues);
const cardViewGroup = service.translateToCardViewGroups(propertyGroups, propertyValues, null);
const cardViewProperty: CardViewTextItemModel = <CardViewTextItemModel> cardViewGroup[0].properties[0];
expect(cardViewProperty instanceof CardViewTextItemModel).toBeTruthy('Property should be instance of CardViewTextItemModel');
@@ -220,7 +223,7 @@ describe('PropertyGroupTranslatorService', () => {
property.dataType = 'd:date';
propertyValues = { 'FAS:PLAGUE': expectedValue };
const cardViewGroup = service.translateToCardViewGroups(propertyGroups, propertyValues);
const cardViewGroup = service.translateToCardViewGroups(propertyGroups, propertyValues, null);
const cardViewProperty: CardViewDateItemModel = <CardViewDateItemModel> cardViewGroup[0].properties[0];
expect(cardViewProperty instanceof CardViewDateItemModel).toBeTruthy('Property should be instance of CardViewDateItemModel');
@@ -232,7 +235,7 @@ describe('PropertyGroupTranslatorService', () => {
property.dataType = 'd:datetime';
propertyValues = { 'FAS:PLAGUE': expectedValue };
const cardViewGroup = service.translateToCardViewGroups(propertyGroups, propertyValues);
const cardViewGroup = service.translateToCardViewGroups(propertyGroups, propertyValues, null);
const cardViewProperty: CardViewDatetimeItemModel = <CardViewDatetimeItemModel> cardViewGroup[0].properties[0];
expect(cardViewProperty instanceof CardViewDatetimeItemModel).toBeTruthy('Property should be instance of CardViewDatetimeItemModel');
@@ -243,7 +246,7 @@ describe('PropertyGroupTranslatorService', () => {
property.dataType = 'd:int';
propertyValues = { 'FAS:PLAGUE': '1024' };
const cardViewGroup = service.translateToCardViewGroups(propertyGroups, propertyValues);
const cardViewGroup = service.translateToCardViewGroups(propertyGroups, propertyValues, null);
const cardViewProperty: CardViewIntItemModel = <CardViewIntItemModel> cardViewGroup[0].properties[0];
expect(cardViewProperty instanceof CardViewIntItemModel).toBeTruthy('Property should be instance of CardViewIntItemModel');
@@ -254,7 +257,7 @@ describe('PropertyGroupTranslatorService', () => {
property.dataType = 'd:long';
propertyValues = { 'FAS:PLAGUE': '1024' };
const cardViewGroup = service.translateToCardViewGroups(propertyGroups, propertyValues);
const cardViewGroup = service.translateToCardViewGroups(propertyGroups, propertyValues, null);
const cardViewProperty: CardViewIntItemModel = <CardViewIntItemModel> cardViewGroup[0].properties[0];
expect(cardViewProperty instanceof CardViewIntItemModel).toBeTruthy('Property should be instance of CardViewIntItemModel');
@@ -265,7 +268,7 @@ describe('PropertyGroupTranslatorService', () => {
property.dataType = 'd:float';
propertyValues = { 'FAS:PLAGUE': '1024.24' };
const cardViewGroup = service.translateToCardViewGroups(propertyGroups, propertyValues);
const cardViewGroup = service.translateToCardViewGroups(propertyGroups, propertyValues, null);
const cardViewProperty: CardViewFloatItemModel = <CardViewFloatItemModel> cardViewGroup[0].properties[0];
expect(cardViewProperty instanceof CardViewFloatItemModel).toBeTruthy('Property should be instance of CardViewFloatItemModel');
@@ -276,7 +279,7 @@ describe('PropertyGroupTranslatorService', () => {
property.dataType = 'd:double';
propertyValues = { 'FAS:PLAGUE': '1024.24' };
const cardViewGroup = service.translateToCardViewGroups(propertyGroups, propertyValues);
const cardViewGroup = service.translateToCardViewGroups(propertyGroups, propertyValues, null);
const cardViewProperty: CardViewFloatItemModel = <CardViewFloatItemModel> cardViewGroup[0].properties[0];
expect(cardViewProperty instanceof CardViewFloatItemModel).toBeTruthy('Property should be instance of CardViewFloatItemModel');
@@ -287,11 +290,34 @@ describe('PropertyGroupTranslatorService', () => {
property.dataType = 'd:boolean';
propertyValues = { 'FAS:PLAGUE': true };
const cardViewGroup = service.translateToCardViewGroups(propertyGroups, propertyValues);
const cardViewGroup = service.translateToCardViewGroups(propertyGroups, propertyValues, null);
const cardViewProperty: CardViewBoolItemModel = <CardViewBoolItemModel> cardViewGroup[0].properties[0];
expect(cardViewProperty instanceof CardViewBoolItemModel).toBeTruthy('Property should be instance of CardViewBoolItemModel');
expect(cardViewProperty.value).toBe(true);
});
it('should translate property for type LIST constraint', () => {
const definition: Definition = {
properties: [{
id: 'FAS:PLAGUE',
constraints: [
{
type: 'LIST',
parameters: {
allowedValues: ['one', 'two', 'three']
}
}
]
} as Constraint ]
};
property.dataType = 'd:text';
propertyValues = { 'FAS:PLAGUE': 'two' };
const cardViewGroup = service.translateToCardViewGroups(propertyGroups, propertyValues, definition);
const cardViewProperty: CardViewSelectItemModel<CardViewSelectItemProperties<string>> = <CardViewSelectItemModel<CardViewSelectItemProperties<string>>> cardViewGroup[0].properties[0];
expect(cardViewProperty instanceof CardViewSelectItemModel).toBeTruthy('Property should be instance of CardViewBoolItemModel');
expect(cardViewProperty.value).toBe('two');
});
});
});

View File

@@ -22,6 +22,7 @@ import {
CardViewTextItemModel,
CardViewBoolItemModel,
CardViewDateItemModel,
CardViewSelectItemModel,
CardViewDatetimeItemModel,
CardViewIntItemModel,
CardViewFloatItemModel,
@@ -31,6 +32,8 @@ import {
DecimalNumberPipe
} from '@alfresco/adf-core';
import { Property, CardViewGroup, OrganisedPropertyGroup } from '../interfaces/content-metadata.interfaces';
import { of } from 'rxjs';
import { Definition, Constraint } from '@alfresco/js-api';
const D_TEXT = 'd:text';
const D_MLTEXT = 'd:mltext';
@@ -58,21 +61,21 @@ export class PropertyGroupTranslatorService {
this.valueSeparator = this.appConfig.get<string>('content-metadata.multi-value-pipe-separator');
}
public translateToCardViewGroups(propertyGroups: OrganisedPropertyGroup[], propertyValues): CardViewGroup[] {
public translateToCardViewGroups(propertyGroups: OrganisedPropertyGroup[], propertyValues, definition: Definition): CardViewGroup[] {
return propertyGroups.map((propertyGroup) => {
const translatedPropertyGroup: any = Object.assign({}, propertyGroup);
translatedPropertyGroup.properties = this.translateArray(propertyGroup.properties, propertyValues);
translatedPropertyGroup.properties = this.translateArray(propertyGroup.properties, propertyValues, definition);
return translatedPropertyGroup;
});
}
private translateArray(properties: Property[], propertyValues: any): CardViewItem[] {
private translateArray(properties: Property[], propertyValues: any, definition: Definition): CardViewItem[] {
return properties.map((property) => {
return this.translate(property, propertyValues);
return this.translate(property, propertyValues, this.getPropertyConstraints(property.name, definition));
});
}
private translate(property: Property, propertyValues: any): CardViewItem {
private translate(property: Property, propertyValues: any, constraints: Constraint[]): CardViewItem {
let propertyValue;
if (propertyValues && propertyValues[property.name]) {
propertyValue = propertyValues[property.name];
@@ -87,54 +90,70 @@ export class PropertyGroupTranslatorService {
value: propertyValue,
key: `${prefix}${property.name}`,
default: property.defaultValue,
editable: property.editable !== undefined ? property.editable : true
editable: property.editable !== undefined ? property.editable : true,
constraints: constraints
};
let cardViewItemProperty;
switch (property.dataType) {
if (this.isListOfValues(propertyDefinition.constraints)) {
const options = propertyDefinition.constraints[0].parameters.allowedValues.map((value) => ({ key: value, label: value }));
const properties = Object.assign(propertyDefinition, { options$: of(options) });
case D_MLTEXT:
cardViewItemProperty = new CardViewTextItemModel(Object.assign(propertyDefinition, {
multiline: true
}));
break;
cardViewItemProperty = new CardViewSelectItemModel(properties);
} else {
switch (property.dataType) {
case D_MLTEXT:
cardViewItemProperty = new CardViewTextItemModel(Object.assign(propertyDefinition, {
multiline: true
}));
break;
case D_INT:
case D_LONG:
cardViewItemProperty = new CardViewIntItemModel(propertyDefinition);
break;
case D_INT:
case D_LONG:
cardViewItemProperty = new CardViewIntItemModel(propertyDefinition);
break;
case D_FLOAT:
case D_DOUBLE:
cardViewItemProperty = new CardViewFloatItemModel(Object.assign(propertyDefinition, {
pipes: [{ pipe: this.decimalNumberPipe }]
}));
break;
case D_FLOAT:
case D_DOUBLE:
cardViewItemProperty = new CardViewFloatItemModel(Object.assign(propertyDefinition, {
pipes: [{ pipe: this.decimalNumberPipe }]
}));
break;
case D_DATE:
cardViewItemProperty = new CardViewDateItemModel(propertyDefinition);
break;
case D_DATE:
cardViewItemProperty = new CardViewDateItemModel(propertyDefinition);
break;
case D_DATETIME:
cardViewItemProperty = new CardViewDatetimeItemModel(propertyDefinition);
break;
case D_DATETIME:
cardViewItemProperty = new CardViewDatetimeItemModel(propertyDefinition);
break;
case D_BOOLEAN:
cardViewItemProperty = new CardViewBoolItemModel(propertyDefinition);
break;
case D_BOOLEAN:
cardViewItemProperty = new CardViewBoolItemModel(propertyDefinition);
break;
case D_TEXT:
default:
cardViewItemProperty = new CardViewTextItemModel(Object.assign(propertyDefinition, {
multivalued: property.multiValued,
multiline: property.multiValued,
pipes: [{ pipe: this.multiValuePipe, params: [this.valueSeparator]}]
}));
case D_TEXT:
default:
cardViewItemProperty = new CardViewTextItemModel(Object.assign(propertyDefinition, {
multivalued: property.multiValued,
multiline: property.multiValued,
pipes: [{ pipe: this.multiValuePipe, params: [this.valueSeparator]}]
}));
}
}
return cardViewItemProperty;
}
private isListOfValues(constraint: Constraint[]): boolean {
return constraint?.[0]?.type === 'LIST';
}
private getPropertyConstraints(propertyName: string, definition: Definition): Constraint[] {
return definition?.properties.find((item) => item.id === propertyName)?.constraints ?? [];
}
private checkECMTypeValidity(ecmPropertyType) {
if (PropertyGroupTranslatorService.RECOGNISED_ECM_TYPES.indexOf(ecmPropertyType) === -1) {
this.logService.error(`Unknown type for mapping: ${ecmPropertyType}`);

View File

@@ -125,7 +125,7 @@ export class DocumentListService implements DocumentListLoader {
*/
getNode(nodeId: string, includeFields: string[] = []): Observable<NodeEntry> {
const includeFieldsRequest = ['path', 'properties', 'allowableOperations', 'permissions', ...includeFields]
const includeFieldsRequest = ['path', 'properties', 'allowableOperations', 'permissions', 'definition', ...includeFields]
.filter((element, index, array) => index === array.indexOf(element));
const opts: any = {