@pega/dx-component-builder-sdk
Version:
Utility for building custom UI components
297 lines (270 loc) • 8.06 kB
text/typescript
import { getSeconds } from '@pega/angular-sdk-components';
export const TABLE_CELL = 'SdkRenderer';
export const DELETE_ICON = 'DeleteIcon';
// BUG-615253: Workaround for autosize in table with lazy loading components
/* istanbul ignore next */
function getFieldWidth(field, label) {
let width;
switch (field.type) {
case 'Time':
width = 150;
break;
case 'Date':
width = 160;
break;
case 'DateTime':
width = 205;
break;
case 'AutoComplete':
case 'TextArea':
width = 190;
break;
case 'Currency':
case 'TextInput':
width = 182;
break;
case 'Checkbox':
// eslint-disable-next-line no-case-declarations
const text = document.createElement('span');
document.body.appendChild(text);
text.style.fontSize = '13px';
text.style.position = 'absolute';
text.innerHTML = label;
width = Math.ceil(text.clientWidth) + 30;
document.body.removeChild(text);
break;
default:
width = 180;
}
return width;
}
export const getContext = thePConn => {
const contextName = thePConn.getContextName();
const pageReference = thePConn.getPageReference();
const { readonlyContextList, referenceList = readonlyContextList } = thePConn.getStateProps()?.config || thePConn.getStateProps();
const pageReferenceForRows = referenceList.startsWith('.') ? `${pageReference}.${referenceList.substring(1)}` : referenceList;
const viewName = thePConn.viewName;
// removing "caseInfo.content" prefix to avoid setting it as a target while preparing pageInstructions
// skipping the removal as StateMachine itself is removing this case info prefix while preparing pageInstructions
// referenceList = pageReferenceForRows.replace(PCore.getConstants().CASE_INFO.CASE_INFO_CONTENT, '');
return {
contextName,
referenceListStr: referenceList,
pageReferenceForRows,
viewName
};
};
export const populateRowKey = rawData => {
return rawData.map((row, index) => {
return { ...row, index };
});
};
export const getApiContext = (processedData, pConnect, reorderCB) => {
return {
fetchData: () => {
return new Promise(resolve => {
resolve({
data: processedData,
filteredRecordCount: processedData.length,
totalRecordCount: processedData.length
});
});
},
fetchPersonalizations: () => {
return Promise.resolve({});
},
applyRowReorder: (sourceKey, destinationKey) => {
// indexes are keys for simple table so, it should work.
reorderCB();
return Promise.resolve(pConnect.getListActions().reorder(parseInt(sourceKey, 10), parseInt(destinationKey, 10)));
}
};
};
export const buildMetaForListView = (fieldMetadata, fields, type, ruleClass, name, propertyLabel, isDataObject, parameters) => {
return {
name,
config: {
type,
referenceList: fieldMetadata.datasource.name,
parameters: parameters ?? fieldMetadata.datasource.parameters,
personalization: false,
isDataObject,
grouping: true,
globalSearch: true,
reorderFields: true,
toggleFieldVisibility: true,
title: propertyLabel,
personalizationId: '' /* TODO */,
template: 'ListView',
presets: [
{
name: 'presets',
template: 'Table',
config: {},
children: [
{
name: 'Columns',
type: 'Region',
children: fields
}
],
label: propertyLabel,
id: 'P_' /* TODO */
}
],
ruleClass
}
};
};
export const buildFieldsForTable = (configFields, fields, showDeleteButton) => {
const fieldDefs = configFields?.map((field, index) => {
return {
type: 'text',
label: fields[index].config.label || fields[index].config.caption,
fillAvailableSpace: !!field.config.fillAvailableSpace,
id: `${index}`,
name: field.config.value.substr(4),
cellRenderer: TABLE_CELL,
sort: false,
noContextMenu: true,
showMenu: false,
meta: {
...field
},
// BUG-615253: Workaround for autosize in table with lazy loading components
width: getFieldWidth(field, fields[index].config.label)
};
});
// ONLY add DELETE_ICON to fields when the table is requested as EDITABLE
if (showDeleteButton) {
fieldDefs.push({
type: 'text',
label: '',
name: DELETE_ICON,
id: fieldDefs.length,
cellRenderer: DELETE_ICON,
sort: false,
noContextMenu: true,
showMenu: false,
// BUG-615253: Workaround for autosize in table with lazy loading components
width: 46
});
}
return fieldDefs;
};
export const createMetaForTable = (fields, renderMode) => {
return {
height: {
minHeight: 'auto',
fitHeightToElement: 'fitHeightToElement',
deltaAdjustment: 'deltaAdjustment',
autoSize: true
},
fieldDefs: fields,
itemKey: 'index',
grouping: false,
reorderFields: false,
reorderItems: renderMode === 'Editable',
dragHandle: renderMode === 'Editable',
globalSearch: false,
personalization: false,
toggleFieldVisibility: false,
toolbar: false,
footer: false,
filterExpression: null,
editing: false,
timezone: PCore.getEnvironmentInfo().getTimeZone()
};
};
export const filterDataByDate = (item, filterObj) => {
let bKeep = true;
let value = item[filterObj.ref] != null || item[filterObj.ref] != '' ? getSeconds(item[filterObj.ref]) : null;
let filterValue = filterObj.containsFilterValue != null && filterObj.containsFilterValue != '' ? getSeconds(filterObj.containsFilterValue) : null;
switch (filterObj.containsFilter) {
case 'notequal':
// becasue filterValue is in minutes, need to have a range of less than 60 secons
if (value != null && filterValue != null) {
// get rid of millisecons
value /= 1000;
filterValue /= 1000;
const diff = value - filterValue;
if (diff >= 0 && diff < 60) {
bKeep = false;
}
}
break;
case 'after':
if (value < filterValue) {
bKeep = false;
}
break;
case 'before':
if (value > filterValue) {
bKeep = false;
}
break;
case 'null':
if (value != null) {
bKeep = false;
}
break;
case 'notnull':
if (value == null) {
bKeep = false;
}
break;
default:
break;
}
return bKeep;
};
export const filterDataByCommonFields = (item, filterObj) => {
let bKeep = true;
const value = item[filterObj.ref].toLowerCase();
const filterValue = filterObj.containsFilterValue.toLowerCase();
switch (filterObj.containsFilter) {
case 'contains':
if (value.indexOf(filterValue) < 0) {
bKeep = false;
}
break;
case 'equals':
if (value != filterValue) {
bKeep = false;
}
break;
case 'startswith':
if (value.indexOf(filterValue) != 0) {
bKeep = false;
}
break;
default:
break;
}
return bKeep;
};
/**
* This method returns a callBack function for Add action.
* @param {object} pConnect - PConnect object
* @param {number} index - index of the page list to add
*/
export const getAddRowCallback = (pConnect, index) => {
return () => pConnect.getListActions().insert({}, index);
};
/**
* This method creates a PConnect object with proper options for Add and Delete actions
* @param {string} contextName - contextName
* @param {string} referenceList - referenceList
* @param {string} pageReference - pageReference
*/
export const createPConnect = (contextName, referenceList, pageReference) => {
const options = {
context: contextName,
pageReference,
referenceList
};
// create PConnect object
const config = { meta: {}, options };
const { getPConnect } = PCore.createPConnect(config);
return getPConnect();
};