@pega/react-sdk-overrides 0.24.4 → 0.25.2

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 (139) hide show
  1. package/lib/designSystemExtension/AlertBanner/AlertBanner.tsx +1 -1
  2. package/lib/designSystemExtension/Banner/Banner.tsx +1 -1
  3. package/lib/designSystemExtension/CaseSummaryFields/CaseSummaryFields.css +0 -2
  4. package/lib/designSystemExtension/CaseSummaryFields/CaseSummaryFields.tsx +59 -32
  5. package/lib/designSystemExtension/DetailsFields/DetailsFields.tsx +4 -4
  6. package/lib/designSystemExtension/FieldGroup/FieldGroup.tsx +5 -5
  7. package/lib/designSystemExtension/FieldGroupList/FieldGroupList.tsx +4 -4
  8. package/lib/designSystemExtension/FieldValueList/FieldValueList.tsx +6 -6
  9. package/lib/designSystemExtension/Operator/Operator.tsx +16 -12
  10. package/lib/designSystemExtension/Pulse/Pulse.tsx +3 -3
  11. package/lib/designSystemExtension/RichTextEditor/RichTextEditor.tsx +3 -2
  12. package/lib/designSystemExtension/WssQuickCreate/WssQuickCreate.tsx +1 -1
  13. package/lib/field/AutoComplete/AutoComplete.tsx +5 -5
  14. package/lib/field/CancelAlert/CancelAlert.tsx +5 -8
  15. package/lib/field/Checkbox/Checkbox.tsx +5 -5
  16. package/lib/field/Currency/Currency.tsx +12 -9
  17. package/lib/field/Date/Date.tsx +29 -48
  18. package/lib/field/DateTime/DateTime.tsx +37 -39
  19. package/lib/field/Decimal/Decimal.tsx +12 -9
  20. package/lib/field/Dropdown/Dropdown.tsx +34 -27
  21. package/lib/field/Email/Email.tsx +39 -20
  22. package/lib/field/Group/Group.tsx +4 -4
  23. package/lib/field/Integer/Integer.tsx +27 -15
  24. package/lib/field/Multiselect/Multiselect.tsx +8 -14
  25. package/lib/field/Multiselect/utils.ts +1 -1
  26. package/lib/field/Percentage/Percentage.tsx +11 -11
  27. package/lib/field/Phone/Phone.tsx +13 -10
  28. package/lib/field/Phone/config-ext.json +8 -0
  29. package/lib/field/RadioButtons/RadioButtons.tsx +4 -7
  30. package/lib/field/RichText/RichText.tsx +2 -2
  31. package/lib/field/RichText/config-ext.json +10 -0
  32. package/lib/field/ScalarList/ScalarList.tsx +4 -5
  33. package/lib/field/SemanticLink/SemanticLink.tsx +5 -5
  34. package/lib/field/TextArea/TextArea.tsx +30 -14
  35. package/lib/field/TextContent/TextContent.tsx +2 -2
  36. package/lib/field/TextInput/TextInput.tsx +7 -9
  37. package/lib/field/Time/Time.tsx +30 -27
  38. package/lib/field/URL/URL.tsx +29 -12
  39. package/lib/field/UserReference/UserReference.tsx +4 -6
  40. package/lib/helpers/common-utils.ts +24 -1
  41. package/lib/helpers/field-group-utils.ts +3 -3
  42. package/lib/helpers/formatters/Currency.ts +11 -16
  43. package/lib/helpers/formatters/common.ts +2 -1
  44. package/lib/helpers/formatters/index.ts +2 -4
  45. package/lib/helpers/simpleTableHelpers.ts +1 -1
  46. package/lib/infra/ActionButtons/ActionButtons.tsx +3 -3
  47. package/lib/infra/Assignment/Assignment.tsx +14 -14
  48. package/lib/infra/AssignmentCard/AssignmentCard.tsx +2 -2
  49. package/lib/infra/Containers/FlowContainer/FlowContainer.tsx +17 -29
  50. package/lib/infra/Containers/FlowContainer/helpers.ts +1 -5
  51. package/lib/infra/Containers/ModalViewContainer/ListViewActionButtons/ListViewActionButtons.tsx +10 -5
  52. package/lib/infra/Containers/ModalViewContainer/ModalViewContainer.tsx +9 -9
  53. package/lib/infra/Containers/SimpleView/helper.ts +1 -1
  54. package/lib/infra/Containers/ViewContainer/ViewContainer.tsx +2 -2
  55. package/lib/infra/DashboardFilter/DashboardFilter.tsx +6 -8
  56. package/lib/infra/DashboardFilter/filterUtils.tsx +3 -4
  57. package/lib/infra/DeferLoad/DeferLoad.tsx +9 -9
  58. package/lib/infra/ErrorBoundary/ErrorBoundary.tsx +1 -1
  59. package/lib/infra/MultiStep/MultiStep.tsx +17 -16
  60. package/lib/infra/NavBar/NavBar.css +1 -0
  61. package/lib/infra/NavBar/NavBar.tsx +49 -38
  62. package/lib/infra/Reference/Reference.tsx +1 -1
  63. package/lib/infra/Region/Region.tsx +1 -1
  64. package/lib/infra/RootContainer/RootContainer.tsx +7 -8
  65. package/lib/infra/Stages/Stages.tsx +5 -5
  66. package/lib/infra/VerticalTabs/LeftAlignVerticalTabs/LeftAlignVerticalTabs.tsx +4 -3
  67. package/lib/infra/VerticalTabs/VerticalTabs/VerticalTabs.tsx +2 -2
  68. package/lib/infra/View/View.tsx +38 -4
  69. package/lib/template/AdvancedSearch/AdvancedSearch.tsx +87 -0
  70. package/lib/template/AdvancedSearch/SearchGroup/persistUtils.ts +58 -0
  71. package/lib/template/AdvancedSearch/SearchGroups/SearchGroups.tsx +245 -0
  72. package/lib/template/AdvancedSearch/SearchGroups/hooks.ts +37 -0
  73. package/lib/template/AdvancedSearch/SearchGroups/index.tsx +1 -0
  74. package/lib/template/AdvancedSearch/SearchGroups/utils.ts +29 -0
  75. package/lib/template/AdvancedSearch/TemplateContext.ts +11 -0
  76. package/lib/template/AdvancedSearch/config-ext.json +9 -0
  77. package/lib/template/AdvancedSearch/index.tsx +1 -0
  78. package/lib/template/AppShell/AppShell.tsx +62 -12
  79. package/lib/template/BannerPage/BannerPage.tsx +2 -2
  80. package/lib/template/BannerPage/config-ext.json +9 -0
  81. package/lib/template/CaseSummary/CaseSummary.tsx +2 -2
  82. package/lib/template/CaseView/CaseView.tsx +12 -11
  83. package/lib/template/CaseViewActionsMenu/CaseViewActionsMenu.tsx +8 -8
  84. package/lib/template/Confirmation/Confirmation.tsx +5 -4
  85. package/lib/template/DataReference/DataReference.tsx +318 -108
  86. package/lib/template/DataReference/DataReferenceAdvancedSearchContext.js +10 -0
  87. package/lib/template/DataReference/SearchForm.tsx +148 -0
  88. package/lib/template/DataReference/utils.js +90 -0
  89. package/lib/template/DefaultForm/DefaultForm.tsx +2 -2
  90. package/lib/template/DefaultForm/utils/index.ts +1 -3
  91. package/lib/template/Details/Details/Details.tsx +3 -3
  92. package/lib/template/Details/DetailsSubTabs/DetailsSubTabs.tsx +5 -5
  93. package/lib/template/Details/DetailsThreeColumn/DetailsThreeColumn.tsx +3 -3
  94. package/lib/template/Details/DetailsTwoColumn/DetailsTwoColumn.tsx +3 -3
  95. package/lib/template/Details/DynamicTabs/DynamicTabs.tsx +5 -5
  96. package/lib/template/FieldGroupTemplate/FieldGroupTemplate.tsx +11 -6
  97. package/lib/template/InlineDashboard/InlineDashboard.tsx +4 -4
  98. package/lib/template/InlineDashboardPage/InlineDashboardPage.tsx +2 -2
  99. package/lib/template/InlineDashboardPage/config-ext.json +9 -0
  100. package/lib/template/ListPage/ListPage.tsx +1 -1
  101. package/lib/template/ListView/ListView.tsx +201 -95
  102. package/lib/template/ListView/utils.ts +38 -6
  103. package/lib/template/MultiReferenceReadOnly/MultiReferenceReadOnly.tsx +1 -1
  104. package/lib/template/NarrowWide/NarrowWide/NarrowWide.tsx +2 -2
  105. package/lib/template/NarrowWide/NarrowWideDetails/NarrowWideDetails.tsx +3 -3
  106. package/lib/template/NarrowWide/NarrowWideForm/NarrowWideForm.tsx +2 -2
  107. package/lib/template/NarrowWide/NarrowWidePage/NarrowWidePage.tsx +2 -2
  108. package/lib/template/OneColumn/OneColumn/OneColumn.tsx +4 -4
  109. package/lib/template/OneColumn/OneColumnPage/OneColumnPage.tsx +1 -1
  110. package/lib/template/OneColumn/OneColumnTab/OneColumnTab.tsx +2 -2
  111. package/lib/template/PromotedFilters/PromotedFilters.tsx +2 -3
  112. package/lib/template/SimpleTable/SimpleTable/SimpleTable.tsx +1 -3
  113. package/lib/template/SimpleTable/SimpleTableManual/SimpleTableManual.tsx +112 -88
  114. package/lib/template/SimpleTable/SimpleTableSelect/SimpleTableSelect.tsx +3 -5
  115. package/lib/template/SingleReferenceReadOnly/SingleReferenceReadOnly.tsx +1 -1
  116. package/lib/template/SubTabs/SubTabs.tsx +4 -4
  117. package/lib/template/SubTabs/tabUtils.ts +118 -1
  118. package/lib/template/TwoColumn/TwoColumn/TwoColumn.tsx +10 -10
  119. package/lib/template/TwoColumn/TwoColumnPage/TwoColumnPage.tsx +1 -1
  120. package/lib/template/TwoColumn/TwoColumnTab/TwoColumnTab.tsx +10 -10
  121. package/lib/template/WideNarrow/WideNarrow/WideNarrow.tsx +2 -2
  122. package/lib/template/WideNarrow/WideNarrowDetails/WideNarrowDetails.tsx +3 -3
  123. package/lib/template/WideNarrow/WideNarrowForm/WideNarrowForm.tsx +2 -2
  124. package/lib/template/WideNarrow/WideNarrowPage/WideNarrowPage.tsx +2 -2
  125. package/lib/template/WssNavBar/WssNavBar.tsx +10 -10
  126. package/lib/widget/AppAnnouncement/AppAnnouncement.tsx +3 -3
  127. package/lib/widget/Attachment/Attachment.css +1 -0
  128. package/lib/widget/Attachment/Attachment.tsx +8 -10
  129. package/lib/widget/CaseHistory/CaseHistory.tsx +13 -11
  130. package/lib/widget/FileUtility/ActionButtonsForFileUtil/ActionButtonsForFileUtil.tsx +2 -2
  131. package/lib/widget/FileUtility/FileUtility/FileUtility.tsx +6 -5
  132. package/lib/widget/Followers/Followers.tsx +4 -4
  133. package/lib/widget/QuickCreate/QuickCreate.tsx +1 -2
  134. package/lib/widget/QuickCreate/config-ext.json +9 -0
  135. package/lib/widget/SummaryItem/SummaryItem.tsx +5 -4
  136. package/lib/widget/SummaryList/SummaryList.tsx +1 -1
  137. package/lib/widget/ToDo/ToDo.tsx +102 -40
  138. package/package.json +1 -1
  139. /package/lib/infra/Containers/{helpers.ts → container-helpers.ts} +0 -0
@@ -1,7 +1,12 @@
1
- import { PropsWithChildren, ReactElement, useEffect, useMemo, useState } from 'react';
1
+ import React, { type PropsWithChildren, type ReactElement, useEffect, useMemo, useState } from 'react';
2
2
 
3
3
  import { getComponentFromMap } from '@pega/react-sdk-components/lib/bridge/helpers/sdk_component_map';
4
- import { PConnProps } from '@pega/react-sdk-components/lib/types/PConnProps';
4
+ import type { PConnProps } from '@pega/react-sdk-components/lib/types/PConnProps';
5
+ import useIsMount from '@pega/react-sdk-components/lib/hooks/useIsMount';
6
+ import componentCachePersistUtils from '@pega/react-sdk-components/lib/components/template/AdvancedSearch/SearchGroup/persistUtils';
7
+ import { getMappedKey } from '@pega/react-sdk-components/lib/components/template/AdvancedSearch/SearchGroup/persistUtils';
8
+ import DataReferenceAdvancedSearchContext from './DataReferenceAdvancedSearchContext';
9
+ import { getFirstChildConfig } from './utils';
5
10
 
6
11
  // ReferenceProps can't be used until getComponentConfig() is NOT private
7
12
  interface DataReferenceProps extends PConnProps {
@@ -16,6 +21,13 @@ interface DataReferenceProps extends PConnProps {
16
21
  ruleClass: string;
17
22
  parameters: string[]; // need to fix
18
23
  hideLabel: boolean;
24
+ imagePosition: string;
25
+ showImageDescription: string;
26
+ showPromotedFilters: boolean;
27
+ isCreationOfNewRecordAllowedForReference: boolean;
28
+ contextClass: string;
29
+ inline: any;
30
+ selectionList: any;
19
31
  }
20
32
 
21
33
  const SELECTION_MODE = { SINGLE: 'single', MULTI: 'multi' };
@@ -24,7 +36,7 @@ export default function DataReference(props: PropsWithChildren<DataReferenceProp
24
36
  // Get emitted components from map (so we can get any override that may exist)
25
37
  const SingleReferenceReadonly = getComponentFromMap('SingleReferenceReadOnly');
26
38
  const MultiReferenceReadonly = getComponentFromMap('MultiReferenceReadOnly');
27
-
39
+ const SearchForm = getComponentFromMap('SearchForm');
28
40
  const {
29
41
  children,
30
42
  getPConnect,
@@ -37,8 +49,17 @@ export default function DataReference(props: PropsWithChildren<DataReferenceProp
37
49
  displayAs,
38
50
  ruleClass,
39
51
  parameters,
40
- hideLabel
52
+ hideLabel,
53
+ imagePosition,
54
+ showImageDescription,
55
+ showPromotedFilters,
56
+ isCreationOfNewRecordAllowedForReference,
57
+ contextClass,
58
+ inline,
59
+ selectionList
41
60
  } = props;
61
+
62
+ const isMounted = useIsMount();
42
63
  let childrenToRender = children as ReactElement[];
43
64
  const pConn = getPConnect();
44
65
  const [dropDownDataSource, setDropDownDataSource] = useState(null);
@@ -47,50 +68,84 @@ export default function DataReference(props: PropsWithChildren<DataReferenceProp
47
68
  propsToUse.label = '';
48
69
  }
49
70
  const rawViewMetadata: any = pConn.getRawMetadata();
50
- const viewName = rawViewMetadata.name;
71
+ const refFieldMetadata = pConn.getFieldMetadata(rawViewMetadata.config?.authorContext);
72
+
51
73
  const [firstChildMeta] = rawViewMetadata.children;
52
74
  const refList = rawViewMetadata.config.referenceList;
53
75
  const canBeChangedInReviewMode = allowAndPersistChangesInReviewMode && (displayAs === 'autocomplete' || displayAs === 'dropdown');
54
- let propName;
55
- const isDisplayModeEnabled = ['LABELS_LEFT', 'STACKED_LARGE_VAL'].includes(displayMode);
76
+ const isDisplayModeEnabled = ['STACKED_LARGE_VAL', 'DISPLAY_ONLY'].includes(displayMode);
77
+ const isDDSourceDeferred =
78
+ (firstChildMeta?.type === 'Dropdown' && selectionMode === SELECTION_MODE.SINGLE && refFieldMetadata?.descriptors) ||
79
+ firstChildMeta.config.deferDatasource;
80
+ const pyID = getMappedKey('pyID');
81
+ const isInfinity = pyID === 'pyID';
82
+ const { allowImplicitRefresh } = isInfinity
83
+ ? PCore.getFieldDefaultUtils().fieldDefaults.DataReference || {}
84
+ : {
85
+ allowImplicitRefresh: true
86
+ };
87
+
56
88
  let firstChildPConnect;
57
89
 
90
+ const localizedPlaceholderOption = placeholder => {
91
+ const { GENERIC_BUNDLE_KEY } = PCore.getLocaleUtils?.() ?? {};
92
+ const localizedDefaultPlaceholder = pConn.getLocalizedValue('select_placeholder_default', 'CosmosFields', GENERIC_BUNDLE_KEY);
93
+ // If we have a placeholder, push that option in the list of items
94
+ if (placeholder === 'Select...' && localizedDefaultPlaceholder !== 'select_placeholder_default') {
95
+ return localizedDefaultPlaceholder;
96
+ }
97
+ return pConn.getLocalizedValue(placeholder);
98
+ };
99
+
100
+ if (['Dropdown', 'AutoComplete'].includes(firstChildMeta?.type)) {
101
+ firstChildMeta.config.placeholder = localizedPlaceholderOption(firstChildMeta.config.placeholder);
102
+ }
103
+
104
+ if (['Checkbox', 'RadioButtons'].includes(firstChildMeta?.type) && firstChildMeta.config.variant === 'card') {
105
+ firstChildMeta.config.imagePosition = imagePosition;
106
+ firstChildMeta.config.showImageDescription = showImageDescription;
107
+ }
108
+
58
109
  /* Only for dropdown when it has param use data api to get the data back and add it to datasource */
59
110
  useEffect(() => {
60
- if (firstChildMeta?.type === 'Dropdown' && rawViewMetadata.config?.parameters) {
111
+ if (rawViewMetadata.config?.parameters && !isDDSourceDeferred && ['Checkbox', 'Dropdown', 'RadioButtons'].includes(firstChildMeta?.type)) {
61
112
  const { value, key, text } = firstChildMeta.config.datasource.fields;
62
- (
63
- PCore.getDataApiUtils().getData(
64
- refList,
65
- {
66
- dataViewParameters: parameters
67
- } as any,
68
- ''
69
- ) as Promise<any>
70
- )
71
- .then(res => {
72
- if (res.data.data !== null) {
73
- const ddDataSource = res.data.data
74
- .map(listItem => ({
75
- key: listItem[key.split(' .', 2)[1]],
76
- text: listItem[text.split(' .', 2)[1]],
77
- value: listItem[value.split(' .', 2)[1]]
78
- }))
79
- .filter(item => item.key);
80
- // Filtering out undefined entries that will break preview
81
- setDropDownDataSource(ddDataSource);
82
- } else {
83
- const ddDataSource: any = [];
84
- setDropDownDataSource(ddDataSource);
85
- }
86
- })
87
- .catch(err => {
88
- // eslint-disable-next-line no-console
89
- console.error(err?.stack);
90
- return Promise.resolve({
91
- data: { data: [] }
113
+ if (firstChildMeta.config.variant !== 'card' || (firstChildMeta.config.variant === 'card' && !isMounted)) {
114
+ (
115
+ PCore.getDataApiUtils().getData(
116
+ refList,
117
+ {
118
+ dataViewParameters: parameters
119
+ } as any,
120
+ ''
121
+ ) as Promise<any>
122
+ )
123
+ .then(res => {
124
+ if (res.data.data !== null) {
125
+ const ddDataSource = firstChildMeta.config.datasource.filterDownloadedFields
126
+ ? res.data.data
127
+ : res.data.data
128
+ .map(listItem => ({
129
+ key: listItem[key.split(' .', 2)[1]],
130
+ text: listItem[text.split(' .', 2)[1]],
131
+ value: listItem[value.split(' .', 2)[1]]
132
+ }))
133
+ .filter(item => item.key);
134
+ // Filtering out undefined entries that will break preview
135
+ setDropDownDataSource(ddDataSource);
136
+ } else {
137
+ const ddDataSource: any = [];
138
+ setDropDownDataSource(ddDataSource);
139
+ }
140
+ })
141
+ .catch(err => {
142
+ // eslint-disable-next-line no-console
143
+ console.error(err?.stack);
144
+ return Promise.resolve({
145
+ data: { data: [] }
146
+ });
92
147
  });
93
- });
148
+ }
94
149
  }
95
150
  }, [firstChildMeta, rawViewMetadata, parameters]);
96
151
 
@@ -116,28 +171,43 @@ export default function DataReference(props: PropsWithChildren<DataReferenceProp
116
171
  if (!canBeChangedInReviewMode) {
117
172
  firstChildMeta.config.displayMode = displayMode;
118
173
  }
119
- if (firstChildMeta.type === 'SimpleTableSelect' && selectionMode === SELECTION_MODE.MULTI) {
120
- propName = PCore.getAnnotationUtils().getPropertyName(firstChildMeta.config.selectionList);
121
- } else {
122
- propName = PCore.getAnnotationUtils().getPropertyName(firstChildMeta.config.value);
123
- }
124
174
  }
125
175
 
126
176
  const handleSelection = event => {
127
177
  const caseKey = pConn.getCaseInfo().getKey();
128
- const refreshOptions = { autoDetectRefresh: true };
129
- if (canBeChangedInReviewMode && pConn.getValue('__currentPageTabViewName', '')) {
130
- // 2nd arg empty string until typedef marked correctly
131
- getPConnect().getActionsApi().refreshCaseView(caseKey, pConn.getValue('__currentPageTabViewName', ''), '', refreshOptions); // 2nd arg empty string until typedef marked correctly
132
- PCore.getDeferLoadManager().refreshActiveComponents(pConn.getContextName());
133
- } else {
134
- const pgRef = pConn.getPageReference().replace('caseInfo.content', '');
135
- getPConnect().getActionsApi().refreshCaseView(caseKey, viewName, pgRef, refreshOptions);
178
+ const refreshOptions: any = { autoDetectRefresh: true };
179
+
180
+ if (pConn.getRawMetadata()?.children?.length > 0 && pConn.getRawMetadata()?.children[0].config?.value) {
181
+ refreshOptions.propertyName = pConn.getRawMetadata()?.children[0].config.value;
182
+ refreshOptions.classID = (pConn.getRawMetadata() as any).classID;
136
183
  }
137
184
 
138
- // AutoComplete sets value on event.id whereas Dropdown sets it on event.target.value
139
- const propValue = event?.id || event?.target.value;
140
- if (propValue && canBeChangedInReviewMode && isDisplayModeEnabled) {
185
+ // AutoComplete sets value on event.id whereas Dropdown sets it on event.target.value if event.id is unset
186
+ // When value is empty propValue will be undefined here and no value will be set for the reference
187
+ const propValue = event?.id || event?.target?.value;
188
+ const propName =
189
+ firstChildMeta.type === 'SimpleTableSelect' && selectionMode === SELECTION_MODE.MULTI
190
+ ? PCore.getAnnotationUtils().getPropertyName(firstChildMeta.config.selectionList)
191
+ : PCore.getAnnotationUtils().getPropertyName(firstChildMeta.config.value);
192
+
193
+ const hasAssociatedViewConfigured = rawViewMetadata.children[1].children?.length;
194
+
195
+ if (pConn.getContextName().includes('modal') || pConn.getContextName().includes('workarea')) {
196
+ if (hasAssociatedViewConfigured || allowImplicitRefresh) {
197
+ const pageReference = pConn.getPageReference();
198
+ let pgRef: any = null;
199
+ if (pageReference.startsWith('objectInfo')) {
200
+ pgRef = pageReference.replace('objectInfo.content', '');
201
+ } else {
202
+ pgRef = pageReference.replace('caseInfo.content', '');
203
+ }
204
+ const viewName = rawViewMetadata.name;
205
+ getPConnect()
206
+ .getActionsApi()
207
+ .refreshCaseView(caseKey, viewName, pgRef, refreshOptions)
208
+ .catch(() => {});
209
+ }
210
+ } else if (propValue && canBeChangedInReviewMode && isDisplayModeEnabled) {
141
211
  (PCore.getDataApiUtils().getCaseEditLock(caseKey, '') as Promise<any>).then(caseResponse => {
142
212
  const pageTokens = pConn.getPageReference().replace('caseInfo.content', '').split('.');
143
213
  let curr = {};
@@ -181,81 +251,221 @@ export default function DataReference(props: PropsWithChildren<DataReferenceProp
181
251
  // rerenders without any actual change
182
252
  const recreatedFirstChild = useMemo(() => {
183
253
  const { type, config } = firstChildMeta;
184
- if (firstChildMeta?.type !== 'Region') {
185
- pConn.clearErrorMessages({
186
- // Need to add empty string for category and context to match typdef
187
- property: propName,
188
- category: '',
189
- context: ''
190
- });
191
- if (!canBeChangedInReviewMode && isDisplayModeEnabled && selectionMode === SELECTION_MODE.SINGLE) {
192
- return (
193
- <SingleReferenceReadonly
194
- config={config}
195
- getPConnect={firstChildPConnect}
196
- label={propsToUse.label}
197
- type={type}
198
- displayAs={displayAs}
199
- displayMode={displayMode}
200
- ruleClass={ruleClass}
201
- referenceType={referenceType}
202
- hideLabel={hideLabel}
203
- dataRelationshipContext={rawViewMetadata.config.contextClass && rawViewMetadata.config.name ? rawViewMetadata.config.name : null}
204
- />
205
- );
254
+ if (firstChildMeta?.type === 'Region' && displayAs !== 'advancedSearch') {
255
+ return;
256
+ }
257
+
258
+ if ((displayAs === 'readonly' || isDisplayModeEnabled) && !canBeChangedInReviewMode && selectionMode === SELECTION_MODE.SINGLE) {
259
+ return (
260
+ <SingleReferenceReadonly
261
+ config={config}
262
+ getPConnect={firstChildPConnect}
263
+ label={propsToUse.label}
264
+ type={type}
265
+ displayAs={displayAs}
266
+ displayMode={displayMode}
267
+ ruleClass={ruleClass}
268
+ referenceType={referenceType}
269
+ hideLabel={hideLabel}
270
+ dataRelationshipContext={rawViewMetadata.config.contextClass && rawViewMetadata.config.name ? rawViewMetadata.config.name : null}
271
+ />
272
+ );
273
+ }
274
+
275
+ if ((['readonly', 'readonlyMulti', 'map'].includes(displayAs) || isDisplayModeEnabled) && selectionMode === SELECTION_MODE.MULTI) {
276
+ return (
277
+ <MultiReferenceReadonly
278
+ config={{
279
+ ...firstChildMeta.config,
280
+ localeReference: rawViewMetadata.config.localeReference
281
+ }}
282
+ getPConnect={firstChildPConnect}
283
+ displayAs={displayAs}
284
+ label={propsToUse.label}
285
+ hideLabel={hideLabel}
286
+ displayMode={displayMode}
287
+ />
288
+ );
289
+ }
290
+
291
+ /* Editable variants */
292
+ // Datasource w/ parameters cannot load the dropdown before the parameters
293
+ if (type === 'Dropdown' && dropDownDataSource === null && !isDDSourceDeferred && rawViewMetadata.config?.parameters) {
294
+ return null;
295
+ }
296
+
297
+ if (firstChildMeta.config?.readOnly) {
298
+ delete firstChildMeta.config.readOnly;
299
+ }
300
+
301
+ // 2) Set datasource
302
+ if (
303
+ ['Dropdown', 'Checkbox', 'RadioButtons'].includes(firstChildMeta?.type) &&
304
+ !firstChildMeta.config.deferDatasource &&
305
+ firstChildMeta.config.datasource
306
+ ) {
307
+ firstChildMeta.config.datasource.source =
308
+ (firstChildMeta.config.variant === 'card' && dropDownDataSource) ||
309
+ (firstChildMeta.config.variant !== 'card' && rawViewMetadata.config?.parameters)
310
+ ? dropDownDataSource
311
+ : '@DATASOURCE '.concat(refList).concat('.pxResults');
312
+ } else if (firstChildMeta?.type === 'AutoComplete') {
313
+ firstChildMeta.config.datasource = refList;
314
+
315
+ if (rawViewMetadata.config?.parameters) {
316
+ firstChildMeta.config.parameters = parameters;
206
317
  }
318
+ }
207
319
 
208
- if (isDisplayModeEnabled && selectionMode === SELECTION_MODE.MULTI) {
209
- return <MultiReferenceReadonly config={config} getPConnect={firstChildPConnect} label={propsToUse.label} hideLabel={hideLabel} />;
320
+ // 3) Pass through configs
321
+ if (firstChildMeta.config) {
322
+ firstChildMeta.config.showPromotedFilters = showPromotedFilters;
323
+ if (!canBeChangedInReviewMode) {
324
+ firstChildMeta.config.displayMode = displayMode;
210
325
  }
326
+ }
211
327
 
212
- // In the case of a datasource with parameters you cannot load the dropdown before the parameters
213
- if (type === 'Dropdown' && rawViewMetadata.config?.parameters && dropDownDataSource === null) {
214
- return null;
328
+ // 4) Define field meta
329
+ let fieldMetaData: any = null;
330
+ if (isDDSourceDeferred && !firstChildMeta.config.deferDatasource) {
331
+ fieldMetaData = {
332
+ datasourceMetadata: refFieldMetadata
333
+ };
334
+ if (rawViewMetadata.config?.parameters) {
335
+ fieldMetaData.datasourceMetadata.datasource.parameters = parameters;
215
336
  }
337
+ fieldMetaData.datasourceMetadata.datasource.propertyForDisplayText = firstChildMeta?.config?.datasource?.fields?.text.startsWith('@P')
338
+ ? firstChildMeta?.config?.datasource?.fields?.text?.substring(3)
339
+ : firstChildMeta?.config?.datasource?.fields?.text;
340
+ fieldMetaData.datasourceMetadata.datasource.propertyForValue = firstChildMeta?.config?.datasource?.fields?.value.startsWith('@P')
341
+ ? firstChildMeta?.config?.datasource?.fields?.value?.substring(3)
342
+ : firstChildMeta?.config?.datasource?.fields?.value;
343
+ fieldMetaData.datasourceMetadata.datasource.name = rawViewMetadata.config?.referenceList;
344
+ }
345
+ // @ts-ignore
346
+ const { disableStartingFieldsForReference = false } = PCore.getEnvironmentInfo().environmentInfoObject?.features?.form || {};
347
+ // @ts-ignore
348
+ let { isCreateNewReferenceEnabled = false } = PCore.getEnvironmentInfo().environmentInfoObject?.features?.form || {};
216
349
 
217
- return firstChildPConnect().createComponent(
218
- {
219
- type,
220
- config: {
221
- ...config,
222
- required: propsToUse.required,
223
- visibility: propsToUse.visibility,
224
- disabled: propsToUse.disabled,
225
- label: propsToUse.label,
226
- viewName: getPConnect().getCurrentView(),
227
- parameters: rawViewMetadata.config.parameters,
228
- readOnly: false,
229
- localeReference: rawViewMetadata.config.localeReference,
230
- ...(selectionMode === SELECTION_MODE.SINGLE ? { referenceType } : ''),
231
- dataRelationshipContext: rawViewMetadata.config.contextClass && rawViewMetadata.config.name ? rawViewMetadata.config.name : null,
232
- hideLabel,
233
- onRecordChange: handleSelection
234
- }
235
- },
236
- '',
237
- '',
238
- {}
239
- ); // 2nd, 3rd, and 4th args empty string/object/null until typedef marked correctly as optional);
350
+ if (isCreateNewReferenceEnabled) {
351
+ // @ts-ignore
352
+ isCreateNewReferenceEnabled = isCreationOfNewRecordAllowedForReference && PCore.getAccessPrivilege().hasCreateAccess(contextClass);
240
353
  }
354
+
355
+ const startingFields: any = {};
356
+ const createNewRecord = () => {
357
+ if (referenceType === 'Case' || firstChildMeta?.config?.referenceType === 'Case') {
358
+ if (!disableStartingFieldsForReference) {
359
+ startingFields.pyAddCaseContextPage = { pyID: pConn.getCaseInfo().getKey()?.split(' ')?.pop() };
360
+ }
361
+ // @ts-ignore
362
+ return pConn.getActionsApi().createWork(contextClass, {
363
+ openCaseViewAfterCreate: false,
364
+ startingFields
365
+ });
366
+ }
367
+ if (referenceType === 'Data' || firstChildMeta?.config?.referenceType === 'Data') {
368
+ return getPConnect().getActionsApi().showDataObjectCreateView(contextClass);
369
+ }
370
+ };
371
+
372
+ const additionalInfo = refFieldMetadata?.additionalInformation
373
+ ? {
374
+ content: refFieldMetadata.additionalInformation
375
+ }
376
+ : undefined;
377
+
378
+ const dataReferenceConfigToChild = {
379
+ selectionMode,
380
+ additionalInfo,
381
+ descriptors: selectionMode === SELECTION_MODE.SINGLE ? refFieldMetadata?.descriptors : null,
382
+ datasourceMetadata: fieldMetaData?.datasourceMetadata,
383
+ required: propsToUse.required,
384
+ visibility: propsToUse.visibility,
385
+ disabled: propsToUse.disabled,
386
+ label: propsToUse.label,
387
+ displayAs,
388
+ readOnly: false,
389
+ ...(selectionMode === SELECTION_MODE.SINGLE && {
390
+ referenceType
391
+ }),
392
+ ...(selectionMode === SELECTION_MODE.SINGLE &&
393
+ displayAs === 'advancedSearch' && {
394
+ value: rawViewMetadata.config.value,
395
+ contextPage: rawViewMetadata.config.contextPage
396
+ }),
397
+ ...(selectionMode === SELECTION_MODE.MULTI &&
398
+ displayAs === 'advancedSearch' && {
399
+ selectionList,
400
+ readonlyContextList: rawViewMetadata.config.readonlyContextList
401
+ }),
402
+ dataRelationshipContext: rawViewMetadata.config.contextClass && rawViewMetadata.config.name ? rawViewMetadata.config.name : null,
403
+ hideLabel,
404
+ onRecordChange: handleSelection,
405
+ createNewRecord: isCreateNewReferenceEnabled ? createNewRecord : undefined,
406
+ inline
407
+ };
408
+
409
+ const searchSelectCacheKey = componentCachePersistUtils.getComponentStateKey(getPConnect, rawViewMetadata.config.name);
410
+
411
+ const dataReferenceAdvancedSearchContext = {
412
+ dataReferenceConfigToChild,
413
+ isCreateNewReferenceEnabled,
414
+ disableStartingFieldsForReference,
415
+ pyID,
416
+ searchSelectCacheKey
417
+ };
418
+
419
+ if (displayAs === 'advancedSearch') {
420
+ return (
421
+ <DataReferenceAdvancedSearchContext.Provider value={dataReferenceAdvancedSearchContext}>
422
+ <SearchForm getPConnect={getPConnect} searchSelectCacheKey={searchSelectCacheKey}>
423
+ {children}
424
+ </SearchForm>
425
+ </DataReferenceAdvancedSearchContext.Provider>
426
+ );
427
+ }
428
+
429
+ return firstChildPConnect().createComponent({
430
+ type,
431
+ config: {
432
+ ...getFirstChildConfig({
433
+ firstChildMeta,
434
+ getPConnect,
435
+ rawViewMetadata,
436
+ contextClass,
437
+ dataReferenceConfigToChild,
438
+ isCreateNewReferenceEnabled,
439
+ disableStartingFieldsForReference,
440
+ pyID
441
+ })
442
+ }
443
+ });
241
444
  }, [firstChildMeta.config?.datasource?.source, parameters, dropDownDataSource, propsToUse.required, propsToUse.disabled]);
242
445
 
243
446
  // Only include the views region for rendering when it has content
244
447
  if (firstChildMeta?.type !== 'Region') {
245
448
  const viewsRegion = rawViewMetadata.children[1];
246
449
  if (viewsRegion?.name === 'Views' && viewsRegion.children.length) {
450
+ viewsRegion.children.map(child => {
451
+ child.config.isEmbeddedInDataReference = true;
452
+ return child;
453
+ });
247
454
  childrenToRender = [recreatedFirstChild, ...(children as ReactElement[]).slice(1)];
248
455
  } else {
249
456
  childrenToRender = [recreatedFirstChild];
250
457
  }
458
+ } else if (displayAs === 'advancedSearch') {
459
+ childrenToRender = [recreatedFirstChild];
251
460
  }
252
461
 
253
462
  return childrenToRender.length === 1 ? (
254
- childrenToRender[0] ?? null
463
+ (childrenToRender[0] ?? null)
255
464
  ) : (
256
465
  <div>
257
- {childrenToRender.map(child => (
258
- <>{child}</>
466
+ {childrenToRender.map((child, index) => (
467
+ // eslint-disable-next-line react/no-array-index-key
468
+ <React.Fragment key={index}>{child}</React.Fragment>
259
469
  ))}
260
470
  </div>
261
471
  );
@@ -0,0 +1,10 @@
1
+ import { createContext } from 'react';
2
+
3
+ const DataReferenceAdvancedSearchContext = createContext({
4
+ disableStartingFieldsForReference: true,
5
+ dataReferenceConfigToChild: {
6
+ selectionMode: 'single'
7
+ }
8
+ });
9
+
10
+ export default DataReferenceAdvancedSearchContext;
@@ -0,0 +1,148 @@
1
+ import { useState } from 'react';
2
+ import { Tab, Tabs, Typography, RadioGroup, FormControlLabel, Radio, Select, MenuItem, Grid, Box } from '@mui/material';
3
+ import { TabContext, TabPanel } from '@mui/lab';
4
+ import { Dialog, DialogTitle, DialogContent, DialogActions, Button } from '@mui/material';
5
+
6
+ import useGetTabsCount from '@pega/react-sdk-components/lib/hooks/useGetTabsCount';
7
+ import { searchtabsClick, getActiveTabId, getFirstVisibleTabId } from '@pega/react-sdk-components/lib/components/template/SubTabs/tabUtils';
8
+ import { getFieldMeta } from './utils';
9
+
10
+ const publishEvent = ({ clearSelections, viewName }) => {
11
+ const payload: any = {};
12
+
13
+ if (clearSelections) {
14
+ payload.clearSelections = clearSelections;
15
+ }
16
+
17
+ if (viewName) {
18
+ payload.viewName = viewName;
19
+ }
20
+
21
+ PCore.getPubSubUtils().publish('update-advanced-search-selections', payload);
22
+ };
23
+
24
+ const checkIfSelectionsExist = getPConnect => {
25
+ const { MULTI } = PCore.getConstants().LIST_SELECTION_MODE;
26
+ const { selectionMode, readonlyContextList, contextPage, contextClass, name } = getPConnect().getConfigProps();
27
+ const isMultiSelectMode = selectionMode === MULTI;
28
+
29
+ const dataRelationshipContext = contextClass && name ? name : null;
30
+
31
+ const { compositeKeys } = getFieldMeta(getPConnect, dataRelationshipContext);
32
+
33
+ let selectionsExist = false;
34
+ if (isMultiSelectMode) {
35
+ selectionsExist = readonlyContextList?.length > 0;
36
+ } else if (contextPage) {
37
+ selectionsExist = compositeKeys?.filter(key => !['', null, undefined].includes(contextPage[key]))?.length > 0;
38
+ }
39
+ return selectionsExist;
40
+ };
41
+
42
+ const SearchForm = props => {
43
+ const { children, getPConnect, searchSelectCacheKey } = props;
44
+
45
+ const deferLoadedTabs = children[2];
46
+ const cache: any = PCore.getNavigationUtils().getComponentCache(searchSelectCacheKey) ?? {};
47
+ const { selectedCategory } = cache;
48
+ const firstTabId = getFirstVisibleTabId(deferLoadedTabs, selectedCategory);
49
+ const [open, setOpen] = useState(false);
50
+ const [currentTabId, setCurrentTabId] = useState(getActiveTabId(deferLoadedTabs.props.getPConnect().getChildren(), firstTabId));
51
+ const [nextTabId, setNextTabId] = useState(null); // State to store the next tab ID
52
+ const { getLocaleValue } = PCore.getLocaleUtils();
53
+
54
+ // @ts-ignore
55
+ const { data: tabData } = useGetTabsCount(deferLoadedTabs, 'searchForm', currentTabId);
56
+
57
+ const handleTabClick = event => {
58
+ const tabId: any = event.target.value;
59
+ const viewName = tabData
60
+ .find(tab => tab.id === currentTabId)
61
+ .getPConnect()
62
+ .getConfigProps().name;
63
+
64
+ if (checkIfSelectionsExist(getPConnect)) {
65
+ setNextTabId(tabId); // Store the next tab ID
66
+ setOpen(true); // Open the dialog
67
+ } else {
68
+ // @ts-ignore
69
+ publishEvent({ viewName, tabId });
70
+ searchtabsClick(tabId, tabData, currentTabId, setCurrentTabId);
71
+ }
72
+ };
73
+
74
+ const clearSelectionAndSwitchTab = () => {
75
+ const viewName = tabData
76
+ .find(tab => tab.id === currentTabId)
77
+ .getPConnect()
78
+ .getConfigProps().name;
79
+ publishEvent({ clearSelections: true, viewName });
80
+ searchtabsClick(nextTabId, tabData, currentTabId, setCurrentTabId);
81
+ setOpen(false);
82
+ };
83
+
84
+ const onDialogClose = () => {
85
+ setOpen(false); // Close the dialog
86
+ };
87
+
88
+ const tabItems = tabData?.filter(tab => tab.visibility()) || [];
89
+ const propsToUse = { ...getPConnect().getInheritedProps() };
90
+
91
+ let searchCategoriesComp;
92
+ if (tabItems.length > 3) {
93
+ searchCategoriesComp = (
94
+ <Grid container spacing={2}>
95
+ <Select value={currentTabId} onChange={handleTabClick} fullWidth>
96
+ {tabItems.map(tab => (
97
+ <MenuItem key={tab.id} value={tab.id}>
98
+ {tab.name}
99
+ </MenuItem>
100
+ ))}
101
+ </Select>
102
+ </Grid>
103
+ );
104
+ } else if (tabItems.length > 1) {
105
+ searchCategoriesComp = (
106
+ <RadioGroup row value={currentTabId} onChange={handleTabClick}>
107
+ {tabItems.map(tab => (
108
+ <FormControlLabel key={tab.id} value={tab.id} control={<Radio />} label={tab.name} />
109
+ ))}
110
+ </RadioGroup>
111
+ );
112
+ }
113
+
114
+ return (
115
+ <Box display='flex' flexDirection='column' gap={2}>
116
+ <Typography variant='h5'>{propsToUse.label}</Typography>
117
+ {searchCategoriesComp}
118
+ <TabContext value={currentTabId}>
119
+ <Tabs style={{ display: 'none' }} value={currentTabId} onChange={(e, newValue) => setCurrentTabId(newValue)}>
120
+ {tabItems.map(tab => (
121
+ <Tab key={tab.id} label={tab.name} value={tab.id} />
122
+ ))}
123
+ </Tabs>
124
+ {tabItems.map(tab => (
125
+ <TabPanel style={{ padding: '0px' }} key={tab.id} value={tab.id}>
126
+ <div className='search-form'>{tab.content}</div>
127
+ </TabPanel>
128
+ ))}
129
+ </TabContext>
130
+ <Dialog open={open} onClose={onDialogClose}>
131
+ <DialogTitle>{getLocaleValue('Discard selections?', 'DataReference')}</DialogTitle>
132
+ <DialogContent>
133
+ <div>{getLocaleValue('When changing search categories, any previous selections will be lost.', 'DataReference')}</div>
134
+ </DialogContent>
135
+ <DialogActions>
136
+ <Button onClick={onDialogClose} variant='outlined' color='primary'>
137
+ {getLocaleValue('Go back', 'ModalContainer')}
138
+ </Button>
139
+ <Button onClick={clearSelectionAndSwitchTab} variant='contained' color='primary'>
140
+ {getLocaleValue('Discard', 'ModalContainer')}
141
+ </Button>
142
+ </DialogActions>
143
+ </Dialog>
144
+ </Box>
145
+ );
146
+ };
147
+
148
+ export default SearchForm;