@pega/react-sdk-overrides 24.2.11 → 25.1.10

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