@pega/react-sdk-overrides 0.23.17 → 0.23.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/lib/designSystemExtension/CaseSummaryFields/CaseSummaryFields.tsx +37 -3
  2. package/lib/designSystemExtension/FieldGroup/FieldGroup.tsx +1 -2
  3. package/lib/designSystemExtension/FieldValueList/FieldValueList.tsx +38 -56
  4. package/lib/field/AutoComplete/AutoComplete.tsx +6 -4
  5. package/lib/field/Checkbox/Checkbox.tsx +7 -5
  6. package/lib/field/Currency/Currency.tsx +31 -6
  7. package/lib/field/Currency/currency-utils.ts +76 -0
  8. package/lib/field/Date/Date.tsx +25 -9
  9. package/lib/field/DateTime/DateTime.tsx +24 -10
  10. package/lib/field/Decimal/Decimal.tsx +8 -6
  11. package/lib/field/Dropdown/Dropdown.tsx +6 -4
  12. package/lib/field/Email/Email.tsx +8 -8
  13. package/lib/field/Integer/Integer.tsx +8 -6
  14. package/lib/field/Percentage/Percentage.tsx +8 -6
  15. package/lib/field/Phone/Phone.tsx +8 -7
  16. package/lib/field/RadioButtons/RadioButtons.tsx +7 -5
  17. package/lib/field/SemanticLink/SemanticLink.tsx +6 -0
  18. package/lib/field/TextArea/TextArea.tsx +8 -6
  19. package/lib/field/TextInput/TextInput.tsx +8 -6
  20. package/lib/field/Time/Time.tsx +7 -5
  21. package/lib/field/URL/URL.tsx +8 -6
  22. package/lib/helpers/authManager.js +1 -0
  23. package/lib/helpers/date-format-utils.ts +66 -0
  24. package/lib/helpers/event-utils.js +1 -1
  25. package/lib/helpers/formatters/Currency.js +13 -5
  26. package/lib/helpers/formatters/common.js +5 -1
  27. package/lib/helpers/formatters/index.js +5 -0
  28. package/lib/helpers/template-utils.ts +80 -0
  29. package/lib/infra/Containers/FlowContainer/FlowContainer.tsx +67 -72
  30. package/lib/infra/ErrorBoundary/ErrorBoundary.tsx +0 -44
  31. package/lib/infra/MultiStep/MultiStep.css +4 -18
  32. package/lib/infra/NavBar/NavBar.tsx +129 -219
  33. package/lib/infra/RootContainer/RootContainer.tsx +2 -54
  34. package/lib/infra/Stages/Stages.tsx +1 -2
  35. package/lib/infra/View/View.tsx +28 -21
  36. package/lib/template/AppShell/AppShell.tsx +2 -343
  37. package/lib/template/CaseSummary/CaseSummary.tsx +1 -1
  38. package/lib/template/CaseView/CaseView.tsx +2 -5
  39. package/lib/template/DefaultForm/DefaultForm.tsx +4 -0
  40. package/lib/template/Details/Details/Details.tsx +52 -21
  41. package/lib/template/Details/DetailsThreeColumn/DetailsThreeColumn.tsx +63 -31
  42. package/lib/template/Details/DetailsTwoColumn/DetailsTwoColumn.tsx +64 -30
  43. package/lib/template/ListView/DefaultViewMeta.js +222 -0
  44. package/lib/template/ListView/ListView.tsx +155 -94
  45. package/lib/template/ListView/hooks.js +97 -0
  46. package/lib/template/ListView/utils.js +636 -0
  47. package/lib/template/NarrowWide/NarrowWideDetails/NarrowWideDetails.tsx +69 -42
  48. package/lib/template/SimpleTable/SimpleTableManual/SimpleTableManual.tsx +3 -24
  49. package/lib/template/WideNarrow/WideNarrowDetails/WideNarrowDetails.tsx +69 -43
  50. package/lib/widget/Attachment/Attachment.css +7 -0
  51. package/lib/widget/Attachment/Attachment.tsx +37 -3
  52. package/lib/widget/SummaryItem/SummaryItem.tsx +1 -1
  53. package/package.json +1 -1
  54. package/lib/.DS_Store +0 -0
  55. package/lib/field/AutoComplete/.DS_Store +0 -0
  56. package/lib/field/Checkbox/.DS_Store +0 -0
  57. package/lib/field/Currency/.DS_Store +0 -0
  58. package/lib/field/Date/.DS_Store +0 -0
  59. package/lib/field/TextContent/.DS_Store +0 -0
  60. package/lib/infra/.DS_Store +0 -0
  61. package/lib/template/.DS_Store +0 -0
  62. package/lib/template/CaseView/.DS_Store +0 -0
  63. package/lib/template/SimpleTable/.DS_Store +0 -0
  64. package/lib/template/SimpleTable/SimpleTable/.DS_Store +0 -0
  65. package/lib/template/utils.ts +0 -23
@@ -1,5 +1,4 @@
1
1
  import React from "react";
2
- // import { Stages as CosmosStages } from "@pega/cosmos-react-work";
3
2
  import PropTypes from "prop-types";
4
3
  import { Breadcrumbs, Card, Typography } from "@material-ui/core";
5
4
  import DoubleArrowIcon from '@material-ui/icons/DoubleArrow';
@@ -54,7 +53,7 @@ function getFilteredStages(stages) {
54
53
  );
55
54
  }
56
55
 
57
- /* TODO - this component should be refactored and not exposed as top level Nebula component -
56
+ /* TODO - this component should be refactored and not exposed as top level DX Component -
58
57
  the stages should be created as part of the CaseView */
59
58
  export default function Stages(props) {
60
59
  const classes = useStyles();
@@ -6,7 +6,7 @@ import PropTypes from 'prop-types';
6
6
  import { SdkComponentMap } from '@pega/react-sdk-components/lib/bridge/helpers/sdk_component_map';
7
7
  import ErrorBoundary from '@pega/react-sdk-components/lib/components/infra/ErrorBoundary';
8
8
 
9
- import { getAllFields } from '@pega/react-sdk-components/lib/components/template/utils';
9
+ import { getAllFields } from '@pega/react-sdk-components/lib/components/helpers/template-utils';
10
10
 
11
11
  // Need to import any templates that we might render
12
12
 
@@ -18,6 +18,15 @@ import './View.css';
18
18
  //
19
19
 
20
20
  const FORMTEMPLATES = ['OneColumn', 'TwoColumn', 'DefaultForm', 'WideNarrow', 'NarrowWide'];
21
+ const NO_HEADER_TEMPLATES = [
22
+ 'SubTabs',
23
+ 'SimpleTable',
24
+ 'Details',
25
+ 'DetailsTwoColumn',
26
+ 'DetailsThreeColumn',
27
+ 'NarrowWideDetails',
28
+ 'WideNarrowDetails'
29
+ ];
21
30
 
22
31
  export default function View(props) {
23
32
  const { children, template, getPConnect, mode } = props;
@@ -45,35 +54,33 @@ export default function View(props) {
45
54
  if (SdkComponentMap) {
46
55
  // This is the node_modules version of react_pconnect!
47
56
  const theLocalComponent = SdkComponentMap.getLocalComponentMap()[template];
48
- if ( theLocalComponent !== undefined) {
49
- // eslint-disable-next-line no-console
50
- console.log(`View component found ${template}: Local`);
51
- ViewTemplate = theLocalComponent
57
+ if (theLocalComponent !== undefined) {
58
+ // eslint-disable-next-line no-console
59
+ console.log(`View component found ${template}: Local`);
60
+ ViewTemplate = theLocalComponent;
52
61
  } else {
53
- const thePegaProvidedComponent = SdkComponentMap.getPegaProvidedComponentMap()[template];
54
- if ( thePegaProvidedComponent !== undefined) {
55
- // console.log(`View component found ${template}: Pega-provided`);
56
- ViewTemplate = thePegaProvidedComponent;
57
- } else {
58
- // eslint-disable-next-line no-console
59
- console.error(`View component can't find template type ${template}`);
60
- ViewTemplate = ErrorBoundary;
61
- }
62
+ const thePegaProvidedComponent = SdkComponentMap.getPegaProvidedComponentMap()[template];
63
+ if (thePegaProvidedComponent !== undefined) {
64
+ // console.log(`View component found ${template}: Pega-provided`);
65
+ ViewTemplate = thePegaProvidedComponent;
66
+ } else {
67
+ // eslint-disable-next-line no-console
68
+ console.error(`View component can't find template type ${template}`);
69
+ ViewTemplate = ErrorBoundary;
70
+ }
62
71
  }
63
72
 
64
- if (template === "ListView") {
73
+ if (template === 'ListView') {
65
74
  // special case for ListView - add in a prop
66
75
  const bInForm = true;
67
- props = { ...props, bInForm};
76
+ props = { ...props, bInForm };
68
77
  }
69
78
  } else {
70
-
71
79
  // eslint-disable-next-line no-console
72
- console.warn(`View: SdkComponentMap expected but not found.`)
80
+ console.warn(`View: SdkComponentMap expected but not found.`);
73
81
 
74
82
  // eslint-disable-next-line no-console
75
83
  console.error(`View: Trying to render an unknown template: ${template}`);
76
-
77
84
  }
78
85
 
79
86
  // for debugging/investigation
@@ -104,7 +111,7 @@ export default function View(props) {
104
111
 
105
112
  return (
106
113
  <div className='grid-column'>
107
- {showLabel && template !== 'SubTabs' && template !== 'SimpleTable' && template !== 'Details' && (
114
+ {showLabel && !NO_HEADER_TEMPLATES.includes(template) && (
108
115
  <div className='template-title-container'>
109
116
  <span>{label}</span>
110
117
  </div>
@@ -143,7 +150,7 @@ View.propTypes = {
143
150
  title: PropTypes.string
144
151
  };
145
152
 
146
- // Adapted from Nebula/Constellation to add in additional props for some templates
153
+ // Adapted from Constellation DX Component to add in additional props for some templates
147
154
  View.additionalProps = (state, getPConnect) => {
148
155
  const thePConn = getPConnect();
149
156
  const { template } = thePConn.getConfigProps();
@@ -3,20 +3,9 @@ import PropTypes from "prop-types";
3
3
  import { makeStyles } from '@material-ui/core/styles';
4
4
 
5
5
  import { NavContext } from '@pega/react-sdk-components/lib/components/helpers/reactContextHelpers';
6
-
7
- // import {
8
- // Avatar,
9
- // Toaster,
10
- // Banner,
11
- // AppShell as CosmosAppShell
12
- // } from "@pega/cosmos-react-core";
13
-
14
- // import createPConnectComponent from "../../../bridge/react_pconnect";
15
- // import { buildRecentList, onRecentClickHandler } from "./Recents/utils";
16
-
17
6
  import './AppShell.css';
18
7
 
19
- // AppShell can emit NavBar and ViewContainer
8
+ // AppShell can emit NavBar
20
9
  import NavBar from '@pega/react-sdk-components/lib/components/infra/NavBar';
21
10
 
22
11
  const useStyles = makeStyles((theme) => ({
@@ -35,10 +24,6 @@ const useStyles = makeStyles((theme) => ({
35
24
  declare const PCore;
36
25
 
37
26
 
38
- /*
39
- * The wrapper handles knowing how to take in just children and mapping
40
- * to the Cosmos template. This could be a combination of things but it knows...
41
- */
42
27
  export default function AppShell(props) {
43
28
  const {
44
29
  pages,
@@ -50,298 +35,11 @@ export default function AppShell(props) {
50
35
  const [open, setOpen] = useState(true);
51
36
 
52
37
  const pConn = getPConnect();
53
- // const actionsAPI = pConn.getActionsApi();
54
38
  const envInfo = PCore.getEnvironmentInfo();
55
39
 
56
- // const bannerRef = useRef(null);
57
- // const hasBanner = httpMessages && httpMessages.length ? httpMessages.length > 0 : false;
58
-
59
40
  const appNameToDisplay = showAppName ? envInfo.getApplicationLabel() : "";
60
41
 
61
42
  const classes = useStyles();
62
- // let banners = null;
63
- // banners = hasBanner && (
64
- // <Banner
65
- // ref={bannerRef}
66
- // id="appShellBanner"
67
- // variant="urgent"
68
- // heading="Error"
69
- // onDismiss={() =>
70
- // pConn.clearErrorMessages({
71
- // category: "HTTP",
72
- // context: null
73
- // })
74
- // }
75
- // messages={httpMessages}
76
- // />
77
- // );
78
-
79
- // useEffect(() => {
80
- // if (hasBanner && bannerRef.current) {
81
- // bannerRef.current.focus();
82
- // window.scrollTo(0, bannerRef.current.offsetTop);
83
- // }
84
- // }, [hasBanner]);
85
-
86
- /**
87
- *
88
- * Function to dispatch a show page action for the page links in
89
- * the left nav of the app shell
90
- *
91
- * @param {string} searchString Name of view to show
92
- */
93
- // function showSearchResults(searchString) {
94
- // if (searchString === "") {
95
- // actionsAPI.showPage("pySearchPage", "Data-Portal");
96
- // return;
97
- // }
98
- // const searchTerm = searchString.replace(/['"]+/g, "");
99
- // PCore.getDataApiUtils()
100
- // .getData(
101
- // "D_pySearch",
102
- // `{"dataViewParameters": {"SearchString": "${encodeURIComponent(
103
- // searchTerm
104
- // )}"}}`
105
- // )
106
- // .then((response) => {
107
- // if (
108
- // response.data.data !== null &&
109
- // response.data.resultCount === 1 &&
110
- // response.data.data[0].pyID === searchTerm
111
- // ) {
112
- // /* This is a match for a work item - then we will open it */
113
- // pConn
114
- // .getActionsApi()
115
- // .openWorkByHandle(
116
- // response.data.data[0].pzInsKey,
117
- // response.data.data[0].pzCategoryActionKeys
118
- // );
119
- // return;
120
- // }
121
- // // window.searchResults = {
122
- // // searchString: searchTerm,
123
- // // results: response.data
124
- // // };
125
- // actionsAPI.showPage("pySearchPage", "Data-Portal");
126
- // });
127
- // }
128
-
129
- /**
130
- *
131
- * Function to dispatch a show page action for the page links in
132
- * the left nav of the app shell
133
- *
134
- * @param {string} viewName Name of view to show
135
- * @param {string} className Pega Applies to class of the page
136
- */
137
- // function showPage(viewName, className) {
138
- // actionsAPI.showPage(viewName, className);
139
- // }
140
-
141
- /**
142
- *
143
- * Function to dispatch a create work action
144
- * @param {string} className - placeholder string of case type being created
145
- */
146
- // function createWork(className) {
147
- // actionsAPI
148
- // .createWork(className)
149
- // .catch((error) =>
150
- // // eslint-disable-next-line no-console
151
- // console.log("Error in case creation: ", error?.message)
152
- // );
153
- // }
154
-
155
- /**
156
- * Returns the Custome Component for each active case
157
- */
158
- // const VisualComponent = useCallback(
159
- // (context) => {
160
- // if (activeCases && activeCases.length > 0) {
161
- // const meta = PCore.getViewResources().fetchViewResources(
162
- // "pyCaseVisual",
163
- // getPConnect(),
164
- // PCore.getStoreValue(".caseTypeID", "caseInfo", context)
165
- // );
166
- // if (meta?.config && !meta.config.defaultVisual) {
167
- // const config = {
168
- // meta,
169
- // options: {
170
- // context,
171
- // pageReference: "caseInfo.content"
172
- // }
173
- // };
174
- // const visualConfig = PCore.createPConnect(config);
175
- // return React.createElement(createPConnectComponent(), visualConfig);
176
- // }
177
- // }
178
- // return undefined;
179
- // },
180
- // [getPConnect, activeCases]
181
- // );
182
-
183
- /**
184
- * Transforms the active cases information into the model that cosmos expect.
185
- */
186
- // function getActiveCases() {
187
- // if (activeCases) {
188
- // const activeCaseLinks = [];
189
- // activeCases.forEach((activeCase) => {
190
- // const { caseID, className, workID, active, context } = activeCase;
191
- // // activeCaseLinks.push({
192
- // // onDismiss: () => {
193
- // // PCore.getContainerUtils().closeContainerItem(
194
- // // activeCase.containerItemID
195
- // // );
196
- // // },
197
- // // key: caseID,
198
- // // name: caseID,
199
- // // onClick: () => {
200
- // // actionsAPI.openWorkByHandle(workID, className);
201
- // // },
202
- // // active,
203
- // // visual: VisualComponent(context)
204
- // // });
205
- // });
206
- // return activeCaseLinks;
207
- // }
208
- // return activeCases;
209
- // }
210
-
211
- /**
212
- * Translate Pega Data Page into the model that Cosmos expects
213
- *
214
- * Example:
215
- * pxPageViewIcon: "pi pi-home-solid"
216
- * pxURLPath: "Home"
217
- * pyClassName: "Data-Portal"
218
- * pyLabel: "Home"
219
- * pyRuleName: "pyHome"
220
- */
221
- // const links = !pages
222
- // ? []
223
- // : pages.map((page) => {
224
- // return {
225
- // name: page.pyLabel,
226
- // icon: page.pxPageViewIcon.replace("pi pi-", ""),
227
- // onClick: () => showPage(page.pyRuleName, page.pyClassName)
228
- // };
229
- // });
230
-
231
- // const userName = envInfo.getOperatorName();
232
- // const imageKey = envInfo.getOperatorImageInsKey();
233
-
234
- // const logOffAction = () => {
235
- // actionsAPI.logout().then(() => window?.top?.location?.reload());
236
- // };
237
-
238
- // const getOperator = () => {
239
- // const operatorActions = [
240
- // [{ text: "Logoff", id: "1", onClick: logOffAction }]
241
- // ];
242
- // if (imageKey) {
243
- // return {
244
- // avatar: (
245
- // <div id="AvatarWithImageKey">Avatar with image key</div>
246
- // // <Avatar
247
- // // name={userName}
248
- // // imageSrc={getPConnect().getImagePath(imageKey)}
249
- // // />
250
- // ),
251
- // actions: operatorActions,
252
- // name: userName
253
- // };
254
- // }
255
- // return {
256
- // avatar: (
257
- // <div id="Avatar">Avatar</div>
258
- // // <Avatar name={userName}>
259
- // // {userName
260
- // // .split(" ")
261
- // // .map((i) => i.charAt(0))
262
- // // .join("")
263
- // // .toUpperCase()}
264
- // // </Avatar>
265
- // ),
266
- // actions: operatorActions,
267
- // name: userName
268
- // };
269
- // };
270
-
271
- /**
272
- * Translate Case Types page into what is expected by Cosmos
273
- *
274
- * Example:
275
- * pyClassName: ""
276
- * pyFlowType: ""
277
- * pyLabel: "No case types defined"
278
- */
279
- // const cases = !caseTypes
280
- // ? []
281
- // : caseTypes.map((caseType) => {
282
- // let action = {};
283
- // // Only add actions to entries with a class name to create so in case of empty message no action is added
284
- // if (caseType.pyClassName) {
285
- // action = { onClick: () => createWork(caseType.pyClassName) };
286
- // }
287
- // return {
288
- // name: caseType.pyLabel,
289
- // ...action
290
- // };
291
- // });
292
-
293
- // const [recents, setRecents] = useState([]);
294
-
295
- // const [searchVal, setSearchVal] = useState("");
296
-
297
- // // default the icon to be empty. This will cause the image to be initially broken.
298
- // const [iconURL, setIconURL] = useState("");
299
- // useEffect(() => {
300
- // // using the default icon then fetch it from the static folder (not auth involved)
301
- // if (
302
- // !portalLogo ||
303
- // portalLogo.toLowerCase().includes("pzpega-logo-mark") ||
304
- // portalLogo.toLowerCase().includes("py-logo")
305
- // ) {
306
- // setIconURL(
307
- // `${PCore.getAssetLoader().getStaticServerUrl()}static/py-logo.svg`
308
- // );
309
- // }
310
- // // not using default icon to fetch it using the way which uses authentication
311
- // else {
312
- // PCore.getAssetLoader()
313
- // .getSvcImage(portalLogo)
314
- // .then((data) => {
315
- // setIconURL(window.URL.createObjectURL(data));
316
- // })
317
- // .catch(() => {
318
- // console.error(
319
- // `Unable to load the image for the portal logo/icon with the insName:${portalLogo}`
320
- // );
321
- // });
322
- // }
323
- // }, [portalLogo]);
324
-
325
- /**
326
- * To fetch recents and translate items into what Cosmos expects
327
- */
328
- // const fetchRecents = () => {
329
- // actionsAPI.getRecents(15).then((response) => {
330
- // const recentsitems = response.data.recents;
331
- // // setRecents(buildRecentList(recentsitems));
332
- // });
333
- // };
334
-
335
- /**
336
- * To handle on click of any recent item after the drawer is open
337
- *
338
- * @param {*} id : Recent item unique id
339
- */
340
-
341
- // const onItemClick = (id, e) => {
342
- // e.preventDefault();
343
- // // onRecentClickHandler(id, actionsAPI);
344
- // };
345
43
 
346
44
  // useState for appName and mapChildren - note these are ONLY updated once (on component mount!)
347
45
  // eslint-disable-next-line @typescript-eslint/no-unused-vars, no-unused-vars
@@ -382,57 +80,18 @@ export default function AppShell(props) {
382
80
  </div>
383
81
  </div>
384
82
  </NavContext.Provider>
385
-
386
- // <Toaster dismissAfter={3000}>
387
- // <CosmosAppShell
388
- // {...{
389
- // appInfo: {
390
- // imageSrc: `${iconURL}`,
391
- // appName: `${appNameToDisplay}`,
392
- // portalName
393
- // },
394
- // recents: {
395
- // items: recents,
396
- // onDrawerOpen: fetchRecents,
397
- // onItemClick
398
- // },
399
- // searchInput: {
400
- // onSearchChange: (value) => {
401
- // setSearchVal(value);
402
- // },
403
- // onSearchSubmit: (value) => {
404
- // showSearchResults(value.trim());
405
- // setSearchVal("");
406
- // },
407
- // value: searchVal
408
- // },
409
- // caseTypes: cases,
410
- // links,
411
- // cases: getActiveCases(),
412
- // operator: getOperator()
413
- // }}
414
- // main={[children]}
415
- // banners={banners}
416
- // className="app-shell"
417
- // />
418
- // </Toaster>
419
83
  );
420
84
  }
85
+
421
86
  AppShell.defaultProps = {
422
87
  pages: [],
423
88
  caseTypes: [],
424
89
  children: [],
425
- // httpMessages: [],
426
- // activeCases: null
427
90
  };
428
91
  AppShell.propTypes = {
429
- // portalName: PropTypes.string/* .isRequired */,
430
- // portalLogo: PropTypes.string/* .isRequired */,
431
92
  showAppName: PropTypes.bool/* .isRequired */,
432
93
  pages: PropTypes.arrayOf(PropTypes.object),
433
94
  caseTypes: PropTypes.arrayOf(PropTypes.object),
434
95
  children: PropTypes.arrayOf(PropTypes.node),
435
96
  getPConnect: PropTypes.func.isRequired,
436
- // httpMessages: PropTypes.arrayOf(PropTypes.string),
437
- // activeCases: PropTypes.arrayOf(PropTypes.object)
438
97
  };
@@ -9,7 +9,7 @@ export default function CaseSummary(props) {
9
9
  const theConfigProps = thePConn.getConfigProps();
10
10
  const { status, showStatus } = theConfigProps;
11
11
 
12
- // from Nebula
12
+ // from Constellation DX Components
13
13
  // get the primary and secondary fields with the raw data (which has the non-resolved property values)
14
14
  // const regionsRaw = getPConnect().getRawMetadata().children;
15
15
  // const primaryFieldsRaw = regionsRaw[0].children;
@@ -62,6 +62,7 @@ export default function CaseView(props) {
62
62
 
63
63
  const classes = useStyles();
64
64
 
65
+ const editAction = availableActions.find((action) => action.ID === 'pyUpdateCaseDetails');
65
66
 
66
67
  /**
67
68
  *
@@ -163,9 +164,6 @@ export default function CaseView(props) {
163
164
 
164
165
  function _editClick() {
165
166
 
166
- const editAction = availableActions.find(
167
- (action) => action.ID === "pyUpdateCaseDetails"
168
- );
169
167
  const actionsAPI = thePConn.getActionsApi();
170
168
  const openLocalAction = actionsAPI.openLocalAction.bind(actionsAPI);
171
169
 
@@ -176,8 +174,7 @@ export default function CaseView(props) {
176
174
  function getActionButtonsHtml(): any {
177
175
 
178
176
  const aBHtml = <Box>
179
- <Button onClick={() => {_editClick()}}>Edit</Button>
180
- &nbsp;
177
+ {editAction && (<Button onClick={() => {_editClick()}}>Edit</Button>)}
181
178
  <CaseViewActionsMenu getPConnect={getPConnect} availableActions={availableActions} availableProcesses={availableProcesses} />
182
179
  </Box>;
183
180
 
@@ -1,12 +1,15 @@
1
1
  import React, { createElement } from "react";
2
2
  import PropTypes from "prop-types";
3
3
 
4
+ import { getInstructions } from '@pega/react-sdk-components/lib/components/helpers/template-utils';
4
5
  import createPConnectComponent from '@pega/react-sdk-components/lib/bridge/react_pconnect';
5
6
 
6
7
  import './DefaultForm.css';
7
8
 
8
9
  export default function DefaultForm(props) {
9
10
  const { getPConnect, NumCols } = props;
11
+ const instructions = getInstructions(getPConnect(), props.instructions);
12
+ const instructionText = instructions?.replace(/<\/?[^>]+(>|$)/g, '');
10
13
 
11
14
  let divClass: string;
12
15
 
@@ -37,6 +40,7 @@ export default function DefaultForm(props) {
37
40
 
38
41
  return (
39
42
  <div className={divClass}>
43
+ <div>{instructionText}</div>
40
44
  {dfChildren}
41
45
  </div>
42
46
  )
@@ -1,46 +1,77 @@
1
- import React from 'react';
1
+ import React, { createElement } from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import Grid from '@material-ui/core/Grid';
4
- import DetailsFields from '@pega/react-sdk-components/lib/components/designSystemExtension/DetailsFields';
4
+ import createPConnectComponent from '@pega/react-sdk-components/lib/bridge/react_pconnect';
5
+ import FieldGroup from '@pega/react-sdk-components/lib/components/designSystemExtension/FieldGroup';
5
6
 
6
7
  export default function Details(props) {
7
- const { children, label, showLabel, getPConnect } = props;
8
- const arFields: Array<any> = [];
8
+ const { label, showLabel, getPConnect, showHighlightedData } = props;
9
9
 
10
10
  // Get the inherited props from the parent to determine label settings
11
11
  const propsToUse = { label, showLabel, ...getPConnect().getInheritedProps() };
12
12
 
13
- for (const child of children) {
14
- const theChildPConn = child.props.getPConnect();
15
- theChildPConn.setInheritedProp('displayMode', 'LABELS_LEFT');
16
- theChildPConn.setInheritedProp('readOnly', true);
17
- const theChildrenOfChild = theChildPConn.getChildren();
18
- arFields.push(theChildrenOfChild);
13
+ // Set display mode prop and re-create the children so this part of the dom tree renders
14
+ // in a readonly (display) mode instead of a editable
15
+ getPConnect().setInheritedProp('displayMode', 'LABELS_LEFT');
16
+ getPConnect().setInheritedProp('readOnly', true);
17
+ const children = getPConnect()
18
+ .getChildren()
19
+ .map((configObject, index) =>
20
+ createElement(createPConnectComponent(), {
21
+ ...configObject,
22
+ // eslint-disable-next-line react/no-array-index-key
23
+ key: index.toString()
24
+ })
25
+ );
26
+
27
+ // Set up highlighted data to pass in return if is set to show, need raw metadata to pass to createComponent
28
+ let highlightedDataArr = [];
29
+ if (showHighlightedData) {
30
+ const { highlightedData = [] } = getPConnect().getRawMetadata().config;
31
+ highlightedDataArr = highlightedData.map(field => {
32
+ field.config.displayMode = 'STACKED_LARGE_VAL';
33
+
34
+ // Mark as status display when using pyStatusWork
35
+ if (field.config.value === '@P .pyStatusWork') {
36
+ field.type = 'TextInput';
37
+ field.config.displayAsStatus = true;
38
+ }
39
+
40
+ return getPConnect().createComponent(field);
41
+ });
19
42
  }
20
43
 
21
44
  return (
22
- <div id='DetailsOneColumn'>
23
- {propsToUse.showLabel && (
24
- <div className='template-title-container'>
25
- <span>{propsToUse.label}</span>
26
- </div>
45
+ <FieldGroup name={propsToUse.showLabel ? propsToUse.label : ''}>
46
+ {showHighlightedData && highlightedDataArr.length > 0 && (
47
+ <Grid container spacing={1} style={{ padding: '0 0 1em' }}>
48
+ {highlightedDataArr.map((child, i) => (
49
+ <Grid item xs={12} key={`hf-${i + 1}`}>
50
+ {child}
51
+ </Grid>
52
+ ))}
53
+ </Grid>
27
54
  )}
28
55
  <Grid container spacing={1}>
29
- <Grid item xs={12}>
30
- <DetailsFields fields={arFields[0]} />
31
- </Grid>
56
+ {children.map((child, i) => (
57
+ <Grid item xs={12} key={`r-${i + 1}`}>
58
+ {child}
59
+ </Grid>
60
+ ))}
32
61
  </Grid>
33
- </div>
62
+ </FieldGroup>
34
63
  );
35
64
  }
36
65
 
37
66
  Details.defaultProps = {
38
67
  label: undefined,
39
- showLabel: true
68
+ showLabel: true,
69
+ showHighlightedData: false
40
70
  };
41
71
 
42
72
  Details.propTypes = {
43
73
  showLabel: PropTypes.bool,
44
74
  label: PropTypes.string,
45
- getPConnect: PropTypes.func.isRequired
75
+ getPConnect: PropTypes.func.isRequired,
76
+ showHighlightedData: PropTypes.bool
46
77
  };