UNPKG

@pega/custom-dx-components

Version:

Utility for building custom UI components

315 lines (297 loc) 11.4 kB
import { isEmbeddedField, isPageListInPath, PAGE, PAGELIST, buildAggOrCalcId } from './repeat-utils'; export const AT_FILTEREDLIST = '@FILTERED_LIST'; export const AT_PROPERTY = '@P'; /** * [getFieldNameFromEmbeddedFieldName] * Description - converting embeddedField name starting with !P! or !PL! to normal field * @ignore * @param {string} propertyName EmbeddedField name starting with !P! or !PL! * @returns {string} returns converted string without !P! or !PL! and : * * @example <caption>Example for getFieldNameFromEmbeddedFieldName </caption> * getFieldNameFromEmbeddedFieldName('!P!Organisation:Name') return 'Organisation.Name' * getFieldNameFromEmbeddedFieldName('!PL!Employees:Name') return 'Employees.Name' */ export function getFieldNameFromEmbeddedFieldName(propertyName: string) { let value = propertyName; if (value.startsWith(PAGE) || value.startsWith(PAGELIST)) { value = value.substring(value.lastIndexOf('!') + 1); value = value.replace(/:/g, '.'); } return value; } /** * [getEmbeddedFieldName] * Description - converting normal field name to embedded field starting with !P! or !PL! * @ignore * @param {string} propertyName Field name * @param {string} classID classID of datapage * @returns {string} returns converted string with !P! or !PL! and : * * @example <caption>Example for getEmbeddedFieldName </caption> * For page property, getEmbeddedFieldName('Organisation.Name') return '!P!Organisation:Name' * For pageList property, getEmbeddedFieldName('Employees.Name') return '!PL!Employees:Name' */ export function getEmbeddedFieldName(propertyName: string, classID: string) { let value = propertyName; if (isPageListInPath(value, classID)) { value = `!PL!${value.replace(/\./g, ':')}`; } else { value = `!P!${value.replace(/\./g, ':')}`; } return value; } /** * [updateMetaEmbeddedFieldID] * Description - If the fieldID in meta starts with '!P!' or '!PL!' and contains ':' then replace them with .(dot) * @ignore * @param {Array} metaFields Fields metadata Array. Contains metadata of all the fields. */ export function updateMetaEmbeddedFieldID(metaFields: any[]) { return metaFields.forEach((metaField) => { if (metaField.fieldID?.startsWith(PAGE) || metaField.fieldID?.startsWith(PAGELIST)) { metaField.fieldID = getFieldNameFromEmbeddedFieldName(metaField.fieldID); } }); } /** * [getConfigEmbeddedFieldsMeta] * Description - Get the metadata for configured embedded fields * @ignore * @param {Set} configFields Set of config fields * @param {string} classID clasID of datapage * @returns {Array} Metadata of configured embedded fields */ export function getConfigEmbeddedFieldsMeta(configFields: any, classID: string) { const configEmbeddedFieldsMeta: (object | null)[] = []; configFields.forEach((field: any) => { let value = field; if (isEmbeddedField(value)) { // conversion Page.PageList[].property => Page.PageList.property if (value.includes('[')) { value = value.substring(0, value.indexOf('[')) + value.substring(value.indexOf(']') + 1); } const meta: any = PCore.getMetadataUtils().getEmbeddedPropertyMetadata(value, classID); meta.fieldID = field; configEmbeddedFieldsMeta.push(meta); } }); return configEmbeddedFieldsMeta; } /** * [mergeConfigEmbeddedFieldsMeta] * Description - Get the metadata for configured embedded fields * @ignore * @param {Array} configEmbeddedFieldsMeta config fields metadata. * @param {Array} metaFields Fields metadata Array. Contains metadata of all the fields */ export function mergeConfigEmbeddedFieldsMeta(configEmbeddedFieldsMeta: any[], metaFields: any[]) { const mergedMetaFields = [...metaFields]; configEmbeddedFieldsMeta.forEach((configFieldMeta) => { const fieldMeta = metaFields.find((metaField) => metaField.fieldID === configFieldMeta.fieldID); if (!fieldMeta) mergedMetaFields.push(configFieldMeta); }); return mergedMetaFields; } /** * [preparePropertyValue] * Description - Preparing pageList value from FILTERED_LIST annotation to Property annotation * @ignore * @param {string} value Pagelist value starts with FILTERED_LIST annotation * @returns {string} returns converted string starting with Property annotation * * @example <caption>Example for preparePropertyValue </caption> * preparePropertyValue('@FILTERED_LIST .Employees[].Name') return '@P .Employees.Name' */ // FIXME #EmbeddedPropertyPatch // TODO: Remove this utility when we have nested response for queryable pageList and supports @FILTERED_LIST annotation export function preparePropertyValue(value: any) { if (value.startsWith(AT_FILTEREDLIST)) { value = value.substring(value.indexOf(' ') + 1); value = value.substring(0, value.indexOf('[')) + value.substring(value.indexOf(']') + 1); value = `${AT_PROPERTY} ${value}`; } return value; } /** * [updatePageListFieldsConfig] * Description - updating configured pageList property's type and value * @ignore * @param {Array} configFields configured fields * * @example <caption>Modified config pageListField </caption> * { "type": "ScalarList", "config": { "value": "@FILTERED_LIST .Employees[].Name", "label": "@L Emp_Name", "componentType": "TextInput", "readOnly": true } } modified to { "type": "TextInput", "config": { "value": "@P .Employees.Name", "label": "@L Emp_Name", "componentType": "TextInput", "readOnly": true } } */ // FIXME #EmbeddedPropertyPatch // TODO: Remove this utility when we have nested response for queryable pageList and supports scalarList component export function updatePageListFieldsConfig(configFields: any[]) { return configFields.forEach((item) => { if (item.type === 'ScalarList') { if (!item.config.originalValue) { item.config.originalValue = item.config.value; } item.config.value = preparePropertyValue(item.config.value); } }); } /** * Update the renderer type for the properties of type Page. */ export function updatePageFieldsConfig(configFields: any[], parentClassID: string) { return configFields.forEach((item) => { const { type, config: { value } } = item; const propertyName = PCore.getAnnotationUtils().getPropertyName(value); if (isEmbeddedField(value) && !isPageListInPath(propertyName, parentClassID)) { item.config.componentType = type; item.type = 'PagePropertyRenderer'; } }); } export function updateChangeSetValueKeys(changeSetObj: any, getOriginalProperty: any) { const newChangeSetObject: any = {}; for (const [key, value] of Object.entries(changeSetObj)) { let newKey = key; if (newKey.startsWith(PAGE)) { newKey = `.${getOriginalProperty(newKey)}`; } newChangeSetObject[newKey] = value; } return newChangeSetObject; } /** * [isPageListProperty] * Description - checking if propertyName is pageList or not * @ignore * @param {string} propertyName PropertyName * @returns {boolean} true if property is pageList else false * * @example <caption>Example for isPageListProperty </caption> * isPageListProperty('!PL!Employees.Name') return true * isPageListProperty('!P!Employees.Name') return false * isPageListProperty('Name') return false */ export function isPageListProperty(propertyName: string) { return propertyName.startsWith(PAGELIST); } /** * [preparePropertyMaps] * Description - preparing maps for property names and set it in dataApi context * @ignore * @param {Array} fields fields array * @param {string} classID classID of datapage * @param {string} context dataApi context * @returns {boolean} true if pageListProperty is present */ export function preparePropertyMaps(fields: any[], classID: string, context: string) { const { setPropertyMaps } : any = context; const maps = fields.reduce( (acc, field) => { let { value } = field.config; if (value.startsWith('@')) { value = value.substring(value.indexOf(' ') + 1); if (value[0] === '.') value = value.substring(1); } let name = value; // Preparing name for embedded property if (isEmbeddedField(name)) { name = getEmbeddedFieldName(name, classID); } if (isPageListProperty(name) && !acc[2]) { acc[2] = true; } acc[0][value] = name; acc[1][name] = value; return acc; }, [{}, {}, false] ); setPropertyMaps(maps[0], maps[1]); return maps[2]; } /** * [getPageListFields] * Description - getting pageListFields names from the fields * @ignore * @param {Array} fields fields array * @returns {Array} array of pageListFields name */ // FIXME #EmbeddedPropertyPatch // TODO: Remove this utility when we have nested response for queryable pageList property export function getPageListFields(fields: any[]) { const parentPaths = new Set(); const pageListFields: any = []; fields.forEach((field) => { const { name } = field; if (isPageListProperty(name)) { const parentPath = name.substring(0, name.lastIndexOf(':')); if (!parentPaths.has(parentPath)) { parentPaths.add(parentPath); pageListFields.push(name); } } }); return pageListFields; } export function mergePageListFieldAggregation( pageListName :string, select: { aggregation: string; }[], existingAggregations: { [x: string]: { field: string; summaryFunction: string; }; }, existingAggregationsName: string | string[]) { // Build a dummy genericAggregationId to check if any type of aggregation for that pagelist is included in existing aggregations. const genericAggregationId = buildAggOrCalcId(pageListName, ''); if (existingAggregationsName.includes(genericAggregationId)) { return; } const countAggregationId = buildAggOrCalcId(pageListName, 'COUNT'); select.push({ aggregation: countAggregationId }); existingAggregations[countAggregationId] = { field: pageListName, summaryFunction: 'COUNT' }; } export function mergePageListFieldsAggregation(fields: any[], select: { aggregation: string; }[], existingAggregations: { [x: string]: { field: string; summaryFunction: string; }; }) { const parentPaths = new Set(); const existingAggregationsName = Object.keys(existingAggregations).toString(); const pageListFields: any[] = []; fields.forEach((field) => { const { name } = field; if (isPageListProperty(name)) { const parentPath = name.substring(0, name.lastIndexOf(':')); if (!parentPaths.has(parentPath)) { parentPaths.add(parentPath); pageListFields.push(name); mergePageListFieldAggregation(name, select, existingAggregations, existingAggregationsName); } } }); return pageListFields; } /** * [hasPageListProperty] * Description - getting pageListFields names from the fields * @ignore * @param {Array} fieldDefs fields array * @returns {object | undefined} value of first pageListProperty found */ export function hasPageListProperty(fieldDefs: any[]) { return fieldDefs?.find((field) => isPageListProperty(field.name)); }