('');
+
+ // Get the inherited props from the parent to determine label settings
+ const inheritedProps = { ...getPConnect().getInheritedProps() };
+
+ const addRow = () => {
+ setNumRows(prevCount => {
+ const messageConfig = {
+ meta: props,
+ options: {
+ context: getPConnect().getContextName(),
+ pageReference: 'caseInfo.content',
+ referenceList: `.${embedDataRef}`,
+ viewName: getPConnect().options.viewName
+ }
+ };
+ const c11nEnv = (window as any).PCore.createPConnect(messageConfig);
+ c11nEnv.index = prevCount;
+ c11nEnv.getPConnect().getListActions().insert({}, prevCount);
+
+ return prevCount + 1;
+ });
+ setFields(prevFields => {
+ return prevFields.map((field: any) => {
+ const newField = { ...field };
+ // Add a new empty value
+ newField.value.push('');
+ return newField;
+ });
+ });
+ };
+
+ const deleteRow = (index: number) => {
+ setNumRows(prevCount => {
+ const messageConfig = {
+ meta: props,
+ options: {
+ context: getPConnect().getContextName(),
+ pageReference: 'caseInfo.content',
+ referenceList: `.${embedDataRef}`,
+ viewName: getPConnect().options.viewName
+ }
+ };
+ const c11nEnv = (window as any).PCore.createPConnect(messageConfig);
+
+ c11nEnv.getPConnect().getListActions().deleteEntry(index);
+
+ return prevCount - 1;
+ });
+ setFields(prevFields => {
+ return prevFields.map((field: any) => {
+ const newField = { ...field };
+ // Delete the value in index position
+ newField.value.splice(index, 1);
+ return newField;
+ });
+ });
+ };
+
+ const genField = (field: any, index: number, key: string) => {
+ const fieldInput: any = {
+ type: field.componentType,
+ config: {
+ value: field.propref,
+ label: field.label,
+ hideLabel: true,
+ classID: field.contextClass,
+ displayMode: ''
+ }
+ };
+ const messageConfig = {
+ meta: fieldInput,
+ options: {
+ context: getPConnect().getContextName(),
+ hasForm: true,
+ pageReference: `caseInfo.content.${embedDataRef}[${index}]`,
+ referenceList: `.${embedDataRef}`,
+ viewName: getPConnect().options.viewName
+ }
+ };
+ const c11nEnv = (window as any).PCore.createPConnect(messageConfig);
+
+ return {c11nEnv.getPConnect().createComponent(fieldInput)} | ;
+ };
+
+ useEffect(() => {
+ const tmpFields = getAllFields(getPConnect);
+ if (tmpFields && tmpFields[0] && tmpFields[0].value) {
+ setEmbedDataRef(tmpFields[0].pageref);
+
+ /* New API added in 24.2 - not needed for 24.1 */
+ (window as any).PCore.getContextTreeManager().addPageListNode(
+ getPConnect().getContextName(),
+ 'caseInfo.content',
+ getPConnect().meta.name,
+ tmpFields[0].pageref
+ );
+
+ setNumRows(tmpFields[0].value.length);
+ /* This logic will load the DX Component if it is not already loaded */
+ tmpFields.forEach((child: any) => {
+ if (
+ child.componentType &&
+ !(window as any).PCore.getComponentsRegistry().getLazyComponent(child.componentType)
+ ) {
+ (window as any).PCore.getAssetLoader()
+ .getLoader('component-loader')([child.componentType])
+ .then(() => {
+ setNumFields(prevCount => prevCount + 1);
+ });
+ } else {
+ setNumFields(prevCount => prevCount + 1);
+ }
+ });
+ setFields(tmpFields);
+ }
+ }, [getPConnect]);
+
+ useEffect(() => {
+ /* We will wait until all the components are loaded before rendering the table */
+ if (fields && fields.length > 0 && numFields === fields.length) {
+ setTableId(createUID());
+ setLoading(false);
+ }
+ }, [numFields, fields]);
+
+ if (loading) {
+ return ;
+ }
+
+ return (
+
+
+
+
+
+
+ {inheritedProps.label}
+
+
+
+ {fields.map((field: any, idx: number) => {
+ return (
+
+ {field.label}
+ |
+ );
+ })}
+ Action |
+
+
+
+ {Array.from({ length: numRows }, (_, i) => i).map((_, i) => {
+ return (
+
+ {fields.map((field: any, j: number) => {
+ return genField(field, i, `${tableId}-row-${i}-${j}`);
+ })}
+
+
+ |
+
+ );
+ })}
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export default withConfiguration(PegaExtensionsEditableTableLayout);
diff --git a/src/components/Pega_Extensions_EditableTableLayout/styles.ts b/src/components/Pega_Extensions_EditableTableLayout/styles.ts
new file mode 100644
index 0000000..d9ddf93
--- /dev/null
+++ b/src/components/Pega_Extensions_EditableTableLayout/styles.ts
@@ -0,0 +1,50 @@
+import styled, { css } from 'styled-components';
+
+export default styled.div(() => {
+ return css`
+ overflow: auto;
+ & table {
+ border-collapse: collapse;
+ border: 0.0625rem solid rgb(207, 207, 207);
+ }
+
+ & th {
+ outline: 0.0625rem solid rgb(207, 207, 207);
+ border: none;
+ padding: 0.25rem 0.5rem;
+ min-width: 30ch;
+ background: #ffffff;
+ }
+
+ & tr > th:first-child {
+ position: sticky;
+ top: 0;
+ left: 0;
+ z-index: 20;
+ }
+
+ & tr > td:first-child {
+ position: sticky;
+ left: 0;
+ z-index: 20;
+ }
+
+ & td {
+ outline: 0.0625rem solid rgb(207, 207, 207);
+ background: #ffffff;
+ padding: 0.25rem 0.5rem;
+ }
+
+ & caption {
+ padding: 0.5rem;
+ text-align: start;
+ height: 2rem;
+ }
+
+ & caption > h3 {
+ position: absolute;
+ left: 1rem;
+ top: 1rem;
+ }
+ `;
+});
diff --git a/src/components/Pega_Extensions_EditableTableLayout/utils.ts b/src/components/Pega_Extensions_EditableTableLayout/utils.ts
new file mode 100644
index 0000000..8e35395
--- /dev/null
+++ b/src/components/Pega_Extensions_EditableTableLayout/utils.ts
@@ -0,0 +1,46 @@
+/**
+ * Given the PConnect object of a Template component, retrieve the children
+ * metadata of all regions.
+ * @param {Function} pConnect PConnect of a Template component.
+ */
+export default function getAllFields(pConnect: any) {
+ const metadata = pConnect().getRawMetadata();
+ if (!metadata.children) {
+ return [];
+ }
+
+ let allFields = [];
+
+ const makeField = (f: any) => {
+ if (typeof f.config.value === 'string') {
+ return {
+ ...pConnect().resolveConfigProps(f.config),
+ type: f.type,
+ propref: `@P ${f.config.value.substring(f.config.value.lastIndexOf('.'))}`,
+ pageref: f.config.value.substring(
+ f.config.value.indexOf(' .') + 2,
+ f.config.value.indexOf('[].')
+ )
+ };
+ }
+ return {
+ ...pConnect().resolveConfigProps(f.config),
+ type: f.type
+ };
+ };
+
+ const hasRegions = !!metadata.children[0]?.children;
+ if (hasRegions) {
+ metadata.children.forEach((region: any) =>
+ region.children.forEach((field: any) => {
+ allFields.push(makeField(field));
+ if (field.type === 'Group' && field.children) {
+ field.children.forEach((gf: any) => allFields.push(makeField(gf)));
+ }
+ })
+ );
+ } else {
+ allFields = metadata.children.map(makeField);
+ }
+ return allFields;
+}
diff --git a/src/components/Pega_Extensions_FieldGroupAsRow/styles.ts b/src/components/Pega_Extensions_FieldGroupAsRow/styles.ts
index f93f0a6..1c678a4 100644
--- a/src/components/Pega_Extensions_FieldGroupAsRow/styles.ts
+++ b/src/components/Pega_Extensions_FieldGroupAsRow/styles.ts
@@ -7,12 +7,12 @@ export default styled.div(({ theme }: { theme: typeof themeDefinition }) => {
max-width: unset;
}
- & > div > div > div {
+ & fieldset > div > div > div > div > div > div > div:last-child > div {
display: flex;
flex-flow: row wrap;
}
- & > div > div > div > h3 {
+ & fieldset > div h1 {
display: none;
}
diff --git a/src/components/Pega_Extensions_KanbanBoard/demo.stories.tsx b/src/components/Pega_Extensions_KanbanBoard/demo.stories.tsx
index b78c577..a8a1aeb 100644
--- a/src/components/Pega_Extensions_KanbanBoard/demo.stories.tsx
+++ b/src/components/Pega_Extensions_KanbanBoard/demo.stories.tsx
@@ -1,6 +1,6 @@
import type { StoryObj } from '@storybook/react';
-import { FieldValueItem, DateTimeDisplay } from '@pega/cosmos-react-core';
-import { Details } from '@pega/cosmos-react-work';
+import { DateTimeDisplay, FieldValueItem } from '@pega/cosmos-react-core';
+import { Details, DetailsList } from '@pega/cosmos-react-work';
import { PegaExtensionsKanbanBoard } from './index';
export default {
@@ -128,24 +128,34 @@ const setPCore = () => {
];
return (
-
-
-
- }
- />
-
+
+ }
+ ]}
+ />
+ )
+ }}
+ />
);
}
})
diff --git a/src/components/Pega_Extensions_Map/demo.stories.tsx b/src/components/Pega_Extensions_Map/demo.stories.tsx
index 788f650..4d97d7d 100644
--- a/src/components/Pega_Extensions_Map/demo.stories.tsx
+++ b/src/components/Pega_Extensions_Map/demo.stories.tsx
@@ -37,6 +37,11 @@ const genComponent = (config: any) => {
const setPCore = () => {
(window as any).PCore = {
+ getContextTreeManager: () => {
+ return {
+ addPageListNode: () => {}
+ };
+ },
createPConnect: () => ({
getPConnect: () => ({
getActionsApi: () => ({ updateFieldValue: () => {} }),
@@ -109,6 +114,12 @@ export const Default: Story = {
...args,
getPConnect: () => {
return {
+ meta: {
+ name: ''
+ },
+ options: {
+ viewName: ''
+ },
getListActions: () => {
return {
update: () => {},
diff --git a/src/components/Pega_Extensions_Map/index.tsx b/src/components/Pega_Extensions_Map/index.tsx
index bde1330..2b1dcfa 100644
--- a/src/components/Pega_Extensions_Map/index.tsx
+++ b/src/components/Pega_Extensions_Map/index.tsx
@@ -116,6 +116,16 @@ export const PegaExtensionsMap = (props: MapProps) => {
let view: MapView;
let ptLayer: GraphicsLayer;
+ /* In 24.2, we need to initialize the context tree manager */
+ if (displayMode !== 'DISPLAY_ONLY') {
+ (window as any).PCore.getContextTreeManager().addPageListNode(
+ getPConnect().getContextName(),
+ 'caseInfo.content',
+ getPConnect().meta.name,
+ 'Locations'
+ );
+ }
+
/* Retrieve the name of the embedded object when bFreeFormDrawing is false */
if (!bFreeFormDrawing && tmpFields.length >= 2) {
let paths = tmpFields[0].path?.split(' ');
diff --git a/src/components/Pega_Extensions_SecureRichText/index.tsx b/src/components/Pega_Extensions_SecureRichText/index.tsx
index 93d3055..0f3caa0 100644
--- a/src/components/Pega_Extensions_SecureRichText/index.tsx
+++ b/src/components/Pega_Extensions_SecureRichText/index.tsx
@@ -2,8 +2,8 @@ import { useRef, useEffect, useState } from 'react';
import DOMPurify from 'dompurify';
import type { Editor as TinymceEditor } from 'tinymce/tinymce';
import { Editor, RichTextViewer, type EditorState } from '@pega/cosmos-react-rte';
-import { Details } from '@pega/cosmos-react-work';
-import { FieldValueItem, NoValue, withConfiguration } from '@pega/cosmos-react-core';
+import { Details, DetailsList } from '@pega/cosmos-react-work';
+import { NoValue, withConfiguration } from '@pega/cosmos-react-core';
import { formatExists, textFormatter } from './utils';
import '../create-nonce';
@@ -143,9 +143,22 @@ export const PegaExtensionsSecureRichText = (props: RichTextProps) => {
richTextComponent = hideLabel ? (
displayComponent
) : (
-
-
-
+
+ )
+ }}
+ />
);
} else {
// Rich Text editable component
diff --git a/tasks.config.json b/tasks.config.json
index ca3c9d4..e7107a3 100644
--- a/tasks.config.json
+++ b/tasks.config.json
@@ -1,10 +1,12 @@
{
"components-directory-path": "src/components",
+ "import-relative-path": "Downloads",
+ "export-relative-path": "Downloads",
"server-config": {
- "rulesetName": "",
- "rulesetVersion": "",
+ "rulesetName": "ConstellationUIGallery",
+ "rulesetVersion": "01-01-01",
"sourceOfComponents": "Server",
- "devBuild": false,
+ "devBuild": true,
"serverType": "infinity",
"server": "",
"clientId": "",
@@ -28,12 +30,14 @@
"questions_askedOnce": "server,authService"
},
"component": {
- "library": "Extensions",
+ "library": "ConstellationUIGallery",
"type": "",
- "version": "1.0.0",
+ "version": "0.0.1",
"subtype": "",
"description": "",
"icon": ""
},
- "usePromotedWebPack": false
-}
\ No newline at end of file
+ "usePromotedWebPack": false,
+ "libraryMode": false,
+ "showDebug": false
+}
diff --git a/tsconfig.json b/tsconfig.json
index ae3e951..fcc4cc1 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -2,9 +2,13 @@
"extends": "@pega/tsconfig/index.json",
"include": ["./**/*", ".storybook/**/*"],
"compilerOptions": {
- "skipLibCheck": true,
"noEmit": true,
"allowJs": true,
- "importsNotUsedAsValues": "remove"
+ "importsNotUsedAsValues": "remove",
+ "skipLibCheck": true,
+ "baseUrl": "./",
+ "paths": {
+ "@pega/pcore-pconnect-typedefs/*": ["node_modules/@pega/pcore-pconnect-typedefs/*"]
+ }
}
}