@pega/react-sdk-overrides 24.2.11 → 25.1.11

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 (173) hide show
  1. package/lib/designSystemExtension/AlertBanner/AlertBanner.css +46 -0
  2. package/lib/designSystemExtension/AlertBanner/AlertBanner.tsx +37 -20
  3. package/lib/designSystemExtension/Banner/Banner.css +1 -1
  4. package/lib/designSystemExtension/Banner/Banner.tsx +10 -7
  5. package/lib/designSystemExtension/CaseSummaryFields/CaseSummaryFields.css +0 -1
  6. package/lib/designSystemExtension/CaseSummaryFields/CaseSummaryFields.tsx +53 -37
  7. package/lib/designSystemExtension/DetailsFields/DetailsFields.tsx +11 -13
  8. package/lib/designSystemExtension/FieldGroup/FieldGroup.tsx +8 -9
  9. package/lib/designSystemExtension/FieldGroupList/FieldGroupList.tsx +9 -9
  10. package/lib/designSystemExtension/FieldValueList/FieldValueList.tsx +7 -8
  11. package/lib/designSystemExtension/Operator/Operator.tsx +21 -19
  12. package/lib/designSystemExtension/Pulse/Pulse.tsx +1 -1
  13. package/lib/designSystemExtension/RichTextEditor/RichTextEditor.tsx +32 -4
  14. package/lib/designSystemExtension/WssQuickCreate/WssQuickCreate.css +7 -14
  15. package/lib/designSystemExtension/WssQuickCreate/WssQuickCreate.tsx +13 -2
  16. package/lib/field/AutoComplete/AutoComplete.tsx +1 -1
  17. package/lib/field/CancelAlert/CancelAlert.css +4 -4
  18. package/lib/field/CancelAlert/CancelAlert.tsx +6 -6
  19. package/lib/field/Checkbox/Checkbox.tsx +97 -4
  20. package/lib/field/Currency/Currency.tsx +3 -3
  21. package/lib/field/Currency/currency-utils.ts +1 -2
  22. package/lib/field/Date/Date.tsx +3 -7
  23. package/lib/field/DateTime/DateTime.tsx +3 -8
  24. package/lib/field/Decimal/Decimal.tsx +3 -5
  25. package/lib/field/Dropdown/Dropdown.tsx +5 -7
  26. package/lib/field/Email/Email.tsx +11 -13
  27. package/lib/field/Group/Group.tsx +10 -8
  28. package/lib/field/Integer/Integer.tsx +5 -7
  29. package/lib/field/Location/Location.css +4 -0
  30. package/lib/field/Location/Location.tsx +258 -0
  31. package/lib/field/Location/config-ext.json +8 -0
  32. package/lib/field/Location/index.tsx +1 -0
  33. package/lib/field/Multiselect/utils.ts +1 -1
  34. package/lib/field/ObjectReference/ObjectReference.tsx +235 -0
  35. package/lib/field/ObjectReference/index.tsx +1 -0
  36. package/lib/field/ObjectReference/utils.ts +111 -0
  37. package/lib/field/Percentage/Percentage.tsx +3 -7
  38. package/lib/field/Phone/Phone.tsx +7 -5
  39. package/lib/field/RadioButtons/RadioButtons.tsx +47 -2
  40. package/lib/field/RichText/RichText.css +79 -0
  41. package/lib/field/RichText/RichText.tsx +3 -1
  42. package/lib/field/ScalarList/ScalarList.tsx +2 -3
  43. package/lib/field/SelectableCard/SelectableCard.tsx +189 -0
  44. package/lib/field/SelectableCard/index.tsx +1 -0
  45. package/lib/field/SelectableCard/utils.tsx +223 -0
  46. package/lib/field/SemanticLink/SemanticLink.tsx +160 -28
  47. package/lib/field/SemanticLink/utils.ts +1 -1
  48. package/lib/field/TextArea/TextArea.tsx +5 -7
  49. package/lib/field/TextContent/TextContent.tsx +1 -2
  50. package/lib/field/TextInput/TextInput.tsx +5 -7
  51. package/lib/field/Time/Time.tsx +3 -7
  52. package/lib/field/URL/URL.tsx +5 -7
  53. package/lib/field/UserReference/UserReference.tsx +2 -3
  54. package/lib/helpers/attachmentShared.ts +6 -0
  55. package/lib/helpers/common-utils.ts +3 -4
  56. package/lib/helpers/data_page.ts +0 -1
  57. package/lib/helpers/field-group-utils.ts +1 -1
  58. package/lib/helpers/formatters/Currency.ts +9 -4
  59. package/lib/helpers/formatters/CurrencyMap.ts +0 -2
  60. package/lib/helpers/object-utils.ts +10 -0
  61. package/lib/helpers/simpleTableHelpers.ts +118 -6
  62. package/lib/helpers/utils.ts +8 -1
  63. package/lib/helpers/versionHelpers.ts +0 -1
  64. package/lib/infra/ActionButtons/ActionButtons.tsx +28 -21
  65. package/lib/infra/Assignment/Assignment.tsx +47 -31
  66. package/lib/infra/Assignment/useValidationBanner.ts +29 -0
  67. package/lib/infra/AssignmentCard/AssignmentCard.tsx +2 -2
  68. package/lib/infra/Containers/FlowContainer/FlowContainer.tsx +22 -102
  69. package/lib/infra/Containers/ModalViewContainer/ListViewActionButtons/ListViewActionButtons.tsx +1 -2
  70. package/lib/infra/Containers/ModalViewContainer/ModalViewContainer.tsx +12 -6
  71. package/lib/infra/Containers/ViewContainer/ViewContainer.tsx +8 -13
  72. package/lib/infra/Containers/container-helpers.ts +47 -1
  73. package/lib/infra/DashboardFilter/DashboardFilter.tsx +3 -6
  74. package/lib/infra/DashboardFilter/filterUtils.tsx +3 -4
  75. package/lib/infra/DeferLoad/DeferLoad.tsx +26 -13
  76. package/lib/infra/ErrorBoundary/ErrorBoundary.tsx +1 -3
  77. package/lib/infra/MultiStep/MultiStep.css +48 -70
  78. package/lib/infra/MultiStep/MultiStep.tsx +27 -53
  79. package/lib/infra/NavBar/NavBar.css +1 -1
  80. package/lib/infra/NavBar/NavBar.tsx +49 -34
  81. package/lib/infra/Reference/Reference.tsx +8 -4
  82. package/lib/infra/Region/Region.tsx +1 -1
  83. package/lib/infra/RootContainer/RootContainer.tsx +6 -8
  84. package/lib/infra/Stages/Stages.tsx +3 -4
  85. package/lib/infra/View/View.tsx +9 -9
  86. package/lib/template/AdvancedSearch/AdvancedSearch.tsx +86 -0
  87. package/lib/template/AdvancedSearch/SearchGroup/persistUtils.ts +52 -0
  88. package/lib/template/AdvancedSearch/SearchGroups/SearchGroups.tsx +244 -0
  89. package/lib/template/AdvancedSearch/SearchGroups/hooks.ts +37 -0
  90. package/lib/template/AdvancedSearch/SearchGroups/index.tsx +1 -0
  91. package/lib/template/AdvancedSearch/SearchGroups/utils.ts +29 -0
  92. package/lib/template/AdvancedSearch/TemplateContext.ts +11 -0
  93. package/lib/template/AdvancedSearch/config-ext.json +9 -0
  94. package/lib/template/AdvancedSearch/index.tsx +1 -0
  95. package/lib/template/AppShell/AppShell.css +1 -5
  96. package/lib/template/AppShell/AppShell.tsx +16 -17
  97. package/lib/template/BannerPage/BannerPage.tsx +2 -2
  98. package/lib/template/CaseSummary/CaseSummary.tsx +25 -43
  99. package/lib/template/CaseView/CaseView.tsx +28 -35
  100. package/lib/template/CaseViewActionsMenu/CaseViewActionsMenu.tsx +1 -1
  101. package/lib/template/Confirmation/Confirmation.tsx +2 -3
  102. package/lib/template/DataReference/DataReference.tsx +312 -106
  103. package/lib/template/DataReference/DataReferenceAdvancedSearchContext.ts +10 -0
  104. package/lib/template/DataReference/SearchForm.tsx +149 -0
  105. package/lib/template/DataReference/utils.ts +90 -0
  106. package/lib/template/DefaultForm/DefaultForm.tsx +3 -3
  107. package/lib/template/DefaultForm/utils/index.ts +1 -3
  108. package/lib/template/DefaultPage/DefaultPage.tsx +108 -0
  109. package/lib/template/DefaultPage/index.tsx +1 -0
  110. package/lib/template/Details/Details/Details.tsx +11 -11
  111. package/lib/template/Details/DetailsSubTabs/DetailsSubTabs.tsx +2 -2
  112. package/lib/template/Details/DetailsThreeColumn/DetailsThreeColumn.tsx +11 -11
  113. package/lib/template/Details/DetailsTwoColumn/DetailsTwoColumn.tsx +11 -11
  114. package/lib/template/Details/DynamicTabs/DynamicTabs.tsx +1 -1
  115. package/lib/template/FieldGroupTemplate/FieldGroupTemplate.tsx +12 -6
  116. package/lib/template/HierarchicalForm/HierarchicalForm.tsx +58 -0
  117. package/lib/template/HierarchicalForm/hooks.ts +224 -0
  118. package/lib/template/HierarchicalForm/index.tsx +1 -0
  119. package/lib/template/InlineDashboard/InlineDashboard.tsx +14 -16
  120. package/lib/template/InlineDashboardPage/InlineDashboardPage.tsx +2 -2
  121. package/lib/template/ListPage/ListPage.tsx +1 -1
  122. package/lib/template/ListView/ListView.tsx +342 -204
  123. package/lib/template/ListView/hooks.ts +1 -5
  124. package/lib/template/ListView/utils.ts +38 -5
  125. package/lib/template/MultiReferenceReadOnly/MultiReferenceReadOnly.tsx +17 -2
  126. package/lib/template/NarrowWide/NarrowWide/NarrowWide.tsx +5 -5
  127. package/lib/template/NarrowWide/NarrowWideDetails/NarrowWideDetails.tsx +11 -11
  128. package/lib/template/NarrowWide/NarrowWideForm/NarrowWideForm.tsx +2 -2
  129. package/lib/template/NarrowWide/NarrowWidePage/NarrowWidePage.tsx +2 -2
  130. package/lib/template/ObjectPage/index.tsx +1 -0
  131. package/lib/template/OneColumn/OneColumn/OneColumn.tsx +7 -7
  132. package/lib/template/OneColumn/OneColumnPage/OneColumnPage.tsx +1 -1
  133. package/lib/template/OneColumn/OneColumnTab/OneColumnTab.tsx +2 -2
  134. package/lib/template/PromotedFilters/PromotedFilters.tsx +1 -2
  135. package/lib/template/SelfServiceCaseView/SelfServiceCaseView.tsx +153 -0
  136. package/lib/template/SelfServiceCaseView/index.tsx +1 -0
  137. package/lib/template/SimpleTable/SimpleTable/SimpleTable.tsx +2 -3
  138. package/lib/template/SimpleTable/SimpleTableManual/SimpleTableManual.tsx +45 -34
  139. package/lib/template/SimpleTable/SimpleTableSelect/SimpleTableSelect.tsx +1 -1
  140. package/lib/template/SimpleTable/SimpleTableSelectReadonly/SimpleTableSelectReadonly.tsx +179 -0
  141. package/lib/template/SimpleTable/SimpleTableSelectReadonly/index.tsx +1 -0
  142. package/lib/template/SingleReferenceReadOnly/SingleReferenceReadOnly.tsx +10 -2
  143. package/lib/template/SubTabs/SubTabs.tsx +2 -2
  144. package/lib/template/SubTabs/tabUtils.ts +118 -1
  145. package/lib/template/TwoColumn/TwoColumn/TwoColumn.tsx +9 -10
  146. package/lib/template/TwoColumn/TwoColumnPage/TwoColumnPage.tsx +1 -1
  147. package/lib/template/TwoColumn/TwoColumnTab/TwoColumnTab.tsx +9 -10
  148. package/lib/template/WideNarrow/WideNarrow/WideNarrow.tsx +5 -5
  149. package/lib/template/WideNarrow/WideNarrowDetails/WideNarrowDetails.tsx +11 -11
  150. package/lib/template/WideNarrow/WideNarrowForm/WideNarrowForm.tsx +2 -2
  151. package/lib/template/WideNarrow/WideNarrowPage/WideNarrowPage.tsx +2 -2
  152. package/lib/template/WssNavBar/WssNavBar.css +1 -1
  153. package/lib/template/WssNavBar/WssNavBar.tsx +6 -6
  154. package/lib/template/utils.tsx +58 -0
  155. package/lib/widget/AppAnnouncement/AppAnnouncement.tsx +1 -1
  156. package/lib/widget/Attachment/Attachment.css +6 -8
  157. package/lib/widget/Attachment/Attachment.tsx +303 -225
  158. package/lib/widget/Attachment/Attachment.types.ts +96 -0
  159. package/lib/widget/Attachment/AttachmentUtils.ts +316 -0
  160. package/lib/widget/CaseHistory/CaseHistory.tsx +5 -5
  161. package/lib/widget/FileUtility/ActionButtonsForFileUtil/ActionButtonsForFileUtil.css +0 -14
  162. package/lib/widget/FileUtility/ActionButtonsForFileUtil/ActionButtonsForFileUtil.tsx +3 -3
  163. package/lib/widget/FileUtility/FileUtility/FileUtility.css +7 -6
  164. package/lib/widget/FileUtility/FileUtility/FileUtility.tsx +29 -22
  165. package/lib/widget/Followers/Followers.tsx +2 -4
  166. package/lib/widget/QuickCreate/QuickCreate.tsx +1 -2
  167. package/lib/widget/SummaryItem/SummaryItem.css +9 -11
  168. package/lib/widget/SummaryItem/SummaryItem.tsx +2 -2
  169. package/lib/widget/SummaryList/SummaryList.tsx +1 -1
  170. package/lib/widget/ToDo/ToDo.css +1 -13
  171. package/lib/widget/ToDo/ToDo.tsx +37 -36
  172. package/package.json +1 -1
  173. package/lib/helpers/attachmentHelpers.ts +0 -76
@@ -3,7 +3,7 @@ import { TextField } from '@mui/material';
3
3
 
4
4
  import handleEvent from '@pega/react-sdk-components/lib/components/helpers/event-utils';
5
5
  import { getComponentFromMap } from '@pega/react-sdk-components/lib/bridge/helpers/sdk_component_map';
6
- import { PConnFieldProps } from '@pega/react-sdk-components/lib/types/PConnProps';
6
+ import type { PConnFieldProps } from '@pega/react-sdk-components/lib/types/PConnProps';
7
7
 
8
8
  interface IntegerProps extends PConnFieldProps {
9
9
  // If any, enter additional props that only exist on Integer here
@@ -54,11 +54,7 @@ export default function Integer(props: IntegerProps) {
54
54
  return <TextInput {...props} />;
55
55
  }
56
56
 
57
- let testProp = {};
58
-
59
- testProp = {
60
- 'data-test-id': testId
61
- };
57
+ const testProps: any = { 'data-test-id': testId };
62
58
 
63
59
  function intOnChange(event) {
64
60
  // console.log(`Integer intOnChange inValue: ${event.target.value}`);
@@ -96,7 +92,9 @@ export default function Integer(props: IntegerProps) {
96
92
  label={label}
97
93
  value={inputValue}
98
94
  type='text'
99
- inputProps={{ inputMode: 'numeric', pattern: '[0-9]*', ...testProp }}
95
+ slotProps={{
96
+ htmlInput: { inputMode: 'numeric', pattern: '[0-9]*', ...testProps }
97
+ }}
100
98
  />
101
99
  );
102
100
  }
@@ -0,0 +1,4 @@
1
+ /* Support for google map autocomplete */
2
+ .pac-container {
3
+ z-index: 2147483647;
4
+ }
@@ -0,0 +1,258 @@
1
+ import { useEffect, useState, useCallback, useRef } from 'react';
2
+ import { Box, TextField, Alert } from '@mui/material';
3
+ import AddLocationAltIcon from '@mui/icons-material/AddLocationAlt';
4
+ import InputAdornment from '@mui/material/InputAdornment';
5
+ import IconButton from '@mui/material/IconButton';
6
+ import { GoogleMap, Marker, useLoadScript } from '@react-google-maps/api';
7
+ import { getComponentFromMap } from '@pega/react-sdk-components/lib/bridge/helpers/sdk_component_map';
8
+ import type { PConnFieldProps } from '@pega/react-sdk-components/lib/types/PConnProps';
9
+ import handleEvent from '@pega/react-sdk-components/lib/components/helpers/event-utils';
10
+
11
+ import './Location.css';
12
+
13
+ interface LocationProps extends PConnFieldProps {
14
+ coordinates?: string;
15
+ onlyCoordinates?: boolean;
16
+ showMap?: boolean;
17
+ showMapReadOnly?: boolean;
18
+ }
19
+
20
+ const mapContainerStyle = {
21
+ width: '100%',
22
+ height: '300px',
23
+ marginTop: '0px'
24
+ };
25
+
26
+ const defaultCenter = {
27
+ lat: 18.5204,
28
+ lng: 73.8567
29
+ };
30
+
31
+ const disabledMapOptions = {
32
+ gestureHandling: 'none',
33
+ keyboardShortcuts: false,
34
+ disableDefaultUI: true,
35
+ clickableIcons: false,
36
+ zoomControl: false,
37
+ mapTypeControl: false,
38
+ scaleControl: false,
39
+ streetViewControl: false,
40
+ rotateControl: false,
41
+ fullscreenControl: false
42
+ };
43
+
44
+ export default function Location(props: LocationProps) {
45
+ const TextInput = getComponentFromMap('TextInput');
46
+ const FieldValueList = getComponentFromMap('FieldValueList');
47
+
48
+ const {
49
+ getPConnect,
50
+ label,
51
+ required = false,
52
+ disabled = false,
53
+ value = '',
54
+ validatemessage,
55
+ status,
56
+ readOnly = false,
57
+ testId,
58
+ displayMode,
59
+ hideLabel = false,
60
+ placeholder,
61
+ helperText,
62
+ coordinates = '',
63
+ onlyCoordinates = false,
64
+ showMap,
65
+ showMapReadOnly
66
+ } = props;
67
+
68
+ const pConn = getPConnect();
69
+ const actions = pConn.getActionsApi();
70
+ const propName = (pConn.getStateProps() as any).value;
71
+ const coordPropName = (pConn.getStateProps() as any).coordinates;
72
+
73
+ const [inputValue, setInputValue] = useState<string>(value ?? '');
74
+ const [mapCenter, setMapCenter] = useState(defaultCenter);
75
+ const [markerPosition, setMarkerPosition] = useState<google.maps.LatLngLiteral | null>(null);
76
+
77
+ const inputRef = useRef<HTMLInputElement | null>(null);
78
+ const autocompleteRef = useRef<google.maps.places.Autocomplete | null>(null);
79
+
80
+ const { isLoaded } = useLoadScript({
81
+ googleMapsApiKey: pConn.getGoogleMapsAPIKey?.() || '',
82
+ libraries: ['places', 'geocoding']
83
+ });
84
+
85
+ const hasError = status === 'error' && !!validatemessage && !disabled;
86
+
87
+ useEffect(() => {
88
+ if (onlyCoordinates && coordinates) {
89
+ setInputValue(coordinates);
90
+ } else {
91
+ setInputValue(value ?? '');
92
+ }
93
+ if (coordinates) {
94
+ const [lat, lng] = coordinates.split(',').map(parseFloat);
95
+
96
+ if (!isNaN(lat) && !isNaN(lng)) {
97
+ setMapCenter({ lat, lng });
98
+ setMarkerPosition({ lat, lng });
99
+ }
100
+ }
101
+ }, [value, coordinates, onlyCoordinates]);
102
+
103
+ const handleChange = useCallback(
104
+ (event: React.ChangeEvent<HTMLInputElement>) => {
105
+ const newValue = event.target.value ?? '';
106
+ setInputValue(newValue);
107
+ handleEvent(actions, 'changeNblur', propName, newValue);
108
+
109
+ if (newValue === '' && coordPropName) {
110
+ actions.updateFieldValue(coordPropName, '');
111
+ setMarkerPosition(null);
112
+ }
113
+ },
114
+ [actions, propName, coordPropName]
115
+ );
116
+
117
+ const handlePlaceChanged = useCallback(() => {
118
+ if (autocompleteRef.current) {
119
+ const place = autocompleteRef.current.getPlace();
120
+ if (place.geometry?.location) {
121
+ const lat = place.geometry.location.lat();
122
+ const lng = place.geometry.location.lng();
123
+ const address = place.formatted_address || place.name || '';
124
+ const coordinateString = `${lat}, ${lng}`;
125
+
126
+ setMapCenter({ lat, lng });
127
+ setMarkerPosition({ lat, lng });
128
+
129
+ if (onlyCoordinates) {
130
+ setInputValue(coordinateString);
131
+ handleEvent(actions, 'changeNblur', propName, coordinateString);
132
+ if (coordPropName) {
133
+ actions.updateFieldValue(coordPropName, coordinateString);
134
+ }
135
+ } else {
136
+ setInputValue(address);
137
+ handleEvent(actions, 'changeNblur', propName, address);
138
+ if (coordPropName) {
139
+ actions.updateFieldValue(coordPropName, coordinateString);
140
+ }
141
+ }
142
+ }
143
+ }
144
+ }, [actions, propName, coordPropName, onlyCoordinates]);
145
+
146
+ useEffect(() => {
147
+ if (isLoaded && inputRef.current && !autocompleteRef.current) {
148
+ autocompleteRef.current = new google.maps.places.Autocomplete(inputRef.current);
149
+ autocompleteRef.current.addListener('place_changed', handlePlaceChanged);
150
+ }
151
+ }, [isLoaded, handlePlaceChanged]);
152
+
153
+ const handleGetCurrentLocation = useCallback(() => {
154
+ if (navigator.geolocation) {
155
+ navigator.geolocation.getCurrentPosition(
156
+ position => {
157
+ const lat = position.coords.latitude;
158
+ const lng = position.coords.longitude;
159
+ const coordinateString = `${lat}, ${lng}`;
160
+
161
+ setMapCenter({ lat, lng });
162
+ setMarkerPosition({ lat, lng });
163
+
164
+ if (onlyCoordinates) {
165
+ setInputValue(coordinateString);
166
+ handleEvent(actions, 'changeNblur', propName, coordinateString);
167
+ if (coordPropName) {
168
+ actions.updateFieldValue(coordPropName, coordinateString);
169
+ }
170
+ } else {
171
+ const geocoder = new window.google.maps.Geocoder();
172
+ geocoder.geocode({ location: { lat, lng } }, (results, responseStatus) => {
173
+ if (responseStatus === 'OK' && results && results[0]) {
174
+ const address = results[0].formatted_address;
175
+ setInputValue(address);
176
+ handleEvent(actions, 'changeNblur', propName, address);
177
+ if (coordPropName) {
178
+ actions.updateFieldValue(coordPropName, coordinateString);
179
+ }
180
+ }
181
+ });
182
+ }
183
+ },
184
+ error => {
185
+ console.error('Error getting current location: ', error);
186
+ }
187
+ );
188
+ }
189
+ }, [actions, propName, coordPropName, onlyCoordinates]);
190
+
191
+ if (displayMode === 'DISPLAY_ONLY') {
192
+ return <FieldValueList name={hideLabel ? '' : label} value={value} />;
193
+ }
194
+
195
+ if (displayMode === 'STACKED_LARGE_VAL') {
196
+ return <FieldValueList name={hideLabel ? '' : label} value={value} variant='stacked' />;
197
+ }
198
+
199
+ const map = (
200
+ <div style={{ opacity: disabled ? 0.7 : 1 }}>
201
+ <Box mt={1} style={{ flex: 1 }}>
202
+ <GoogleMap mapContainerStyle={mapContainerStyle} center={mapCenter} zoom={14} options={disabled ? disabledMapOptions : undefined}>
203
+ {markerPosition && <Marker position={markerPosition} />}
204
+ </GoogleMap>
205
+ </Box>
206
+ </div>
207
+ );
208
+
209
+ if (readOnly) {
210
+ return (
211
+ <div>
212
+ <TextInput {...props} />
213
+ {isLoaded && showMapReadOnly && map}
214
+ </div>
215
+ );
216
+ }
217
+
218
+ const testProps: any = { 'data-test-id': testId };
219
+
220
+ return (
221
+ <div>
222
+ {hasError && (
223
+ <Alert severity='error' sx={{ mb: 1 }}>
224
+ {validatemessage}
225
+ </Alert>
226
+ )}
227
+
228
+ {isLoaded && (
229
+ <TextField
230
+ fullWidth
231
+ label={hideLabel ? '' : label}
232
+ required={required}
233
+ disabled={disabled}
234
+ error={hasError}
235
+ placeholder={placeholder ?? 'Search location'}
236
+ helperText={helperText}
237
+ value={inputValue}
238
+ onChange={handleChange}
239
+ inputRef={inputRef}
240
+ slotProps={{
241
+ input: {
242
+ endAdornment: (
243
+ <InputAdornment position='end'>
244
+ <IconButton onClick={handleGetCurrentLocation} disabled={disabled} edge='end'>
245
+ <AddLocationAltIcon />
246
+ </IconButton>
247
+ </InputAdornment>
248
+ ),
249
+ inputProps: { ...testProps }
250
+ }
251
+ }}
252
+ />
253
+ )}
254
+
255
+ {isLoaded && showMap && map}
256
+ </div>
257
+ );
258
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "name": "Location",
3
+ "description": "Location input field with optional coordinates",
4
+ "type": "Field",
5
+ "subtype": "Text-Location",
6
+ "icon": "images/pz-text-input-active.svg",
7
+ "properties": []
8
+ }
@@ -0,0 +1 @@
1
+ export { default } from './Location';
@@ -1,6 +1,6 @@
1
1
  import { useRef } from 'react';
2
2
  import equal from 'fast-deep-equal';
3
- import cloneDeep from 'lodash/cloneDeep';
3
+ import cloneDeep from 'lodash.clonedeep';
4
4
  import { updateNewInstuctions, insertInstruction, deleteInstruction } from '@pega/react-sdk-components/lib/components/helpers/instructions-utils';
5
5
 
6
6
  export const setVisibilityForList = (c11nEnv, visibility) => {
@@ -0,0 +1,235 @@
1
+ import { useMemo } from 'react';
2
+
3
+ import Grid2 from '@mui/material/Grid2';
4
+
5
+ import { SELECTION_MODE, generateColumns, getDataRelationshipContextFromKey } from './utils';
6
+ import { getComponentFromMap } from '@pega/react-sdk-components/lib/bridge/helpers/sdk_component_map';
7
+ import type { PConnFieldProps } from '@pega/react-sdk-components/lib/types/PConnProps';
8
+
9
+ interface ObjectReferenceProps extends Omit<PConnFieldProps, 'value'> {
10
+ // If any, enter additional props that only exist on ObjectReference here
11
+ getPConnect: any;
12
+ displayMode;
13
+ allowAndPersistChangesInReviewMode: any;
14
+ targetObjectType: any;
15
+ mode: string;
16
+ parameters: object;
17
+ hideLabel: boolean;
18
+ inline: boolean;
19
+ showPromotedFilters: boolean;
20
+ additionalFields: any;
21
+ }
22
+
23
+ export default function ObjectReference(props: ObjectReferenceProps) {
24
+ const {
25
+ getPConnect,
26
+ displayMode,
27
+ allowAndPersistChangesInReviewMode: editableInReview = false,
28
+ targetObjectType,
29
+ mode = '',
30
+ parameters,
31
+ hideLabel = false,
32
+ inline = false,
33
+ showPromotedFilters = false,
34
+ additionalFields
35
+ } = props;
36
+
37
+ const SingleReferenceReadonly = getComponentFromMap('SingleReferenceReadOnly');
38
+
39
+ // Configs
40
+ const pConn = getPConnect();
41
+ const referenceType = targetObjectType === 'case' ? 'Case' : 'Data';
42
+ const rawViewMetadata = pConn.getRawMetadata();
43
+ const refFieldMetadata = pConn.getFieldMetadata(rawViewMetadata?.config?.value?.split('.', 2)[1]);
44
+
45
+ // Destructured properties
46
+ const propsToUse = { ...pConn.getInheritedProps(), ...props };
47
+
48
+ // Computed variables
49
+ const isDisplayModeEnabled = displayMode === 'DISPLAY_ONLY';
50
+ const canBeChangedInReviewMode = editableInReview && ['Autocomplete', 'Dropdown'].includes(rawViewMetadata.config.componentType);
51
+
52
+ // Editable first child on change handler
53
+ const onRecordChange = event => {
54
+ const caseKey = pConn.getCaseInfo().getKey();
55
+ const refreshOptions = { autoDetectRefresh: true, propertyName: '' };
56
+ refreshOptions.propertyName = rawViewMetadata.config?.value;
57
+
58
+ if (!canBeChangedInReviewMode || !pConn.getValue('__currentPageTabViewName')) {
59
+ const pgRef = pConn.getPageReference().replace('caseInfo.content', '');
60
+ const viewName = rawViewMetadata.name;
61
+ if (viewName && viewName.length > 0) {
62
+ getPConnect().getActionsApi().refreshCaseView(caseKey, viewName, pgRef, refreshOptions);
63
+ }
64
+ }
65
+
66
+ // AutoComplete sets value on event.id whereas Dropdown sets it on event.target.value if event.id is unset
67
+ // When value is empty propValue will be undefined here and no value will be set for the reference
68
+ const propValue = event?.id || event?.target?.value;
69
+ const propName =
70
+ rawViewMetadata.type === 'SimpleTableSelect' && mode === SELECTION_MODE.MULTI
71
+ ? PCore.getAnnotationUtils().getPropertyName(rawViewMetadata.config.selectionList)
72
+ : PCore.getAnnotationUtils().getPropertyName(rawViewMetadata.config?.value);
73
+
74
+ if (propValue && canBeChangedInReviewMode && isDisplayModeEnabled) {
75
+ PCore.getCaseUtils()
76
+ .getCaseEditLock(caseKey, '')
77
+ .then(caseResponse => {
78
+ const pageTokens = pConn.getPageReference().replace('caseInfo.content', '').split('.');
79
+ let curr = {};
80
+ const commitData = curr;
81
+
82
+ pageTokens.forEach(el => {
83
+ if (el !== '') {
84
+ curr[el] = {};
85
+ curr = curr[el];
86
+ }
87
+ });
88
+
89
+ // expecting format like {Customer: {pyID:"C-100"}}
90
+ const propArr = propName.split('.');
91
+ propArr.forEach((element, idx) => {
92
+ if (idx + 1 === propArr.length) {
93
+ curr[element] = propValue;
94
+ } else {
95
+ curr[element] = {};
96
+ curr = curr[element];
97
+ }
98
+ });
99
+
100
+ PCore.getCaseUtils()
101
+ .updateCaseEditFieldsData(caseKey, { [caseKey]: commitData }, caseResponse.headers.etag, pConn.getContextName())
102
+ .then(response => {
103
+ PCore.getContainerUtils().updateParentLastUpdateTime(pConn.getContextName(), (response.data as any).data.caseInfo.lastUpdateTime);
104
+ PCore.getContainerUtils().updateRelatedContextEtag(pConn.getContextName(), response.headers.etag);
105
+ });
106
+ });
107
+ }
108
+ };
109
+
110
+ // Prepare first child
111
+ const recreatedFirstChild = useMemo(() => {
112
+ const type = rawViewMetadata.config.componentType;
113
+
114
+ /* Read-only variants */
115
+ if (type === 'SemanticLink' && !canBeChangedInReviewMode) {
116
+ const config = {
117
+ ...rawViewMetadata.config,
118
+ primaryField: rawViewMetadata.config.displayField
119
+ };
120
+ config.caseClass = rawViewMetadata.config.targetObjectClass;
121
+ config.text = config.primaryField;
122
+ config.caseID = config.value;
123
+ config.contextPage = `@P .${
124
+ rawViewMetadata.config?.displayField ? getDataRelationshipContextFromKey(rawViewMetadata.config.displayField) : null
125
+ }`;
126
+ config.resourceParams = {
127
+ workID: config.value
128
+ };
129
+ config.resourcePayload = {
130
+ caseClassName: config.caseClass
131
+ };
132
+
133
+ return getPConnect().createComponent({
134
+ type: 'SemanticLink',
135
+ config: {
136
+ ...config,
137
+ displayMode,
138
+ referenceType,
139
+ hideLabel,
140
+ dataRelationshipContext: rawViewMetadata.config?.displayField
141
+ ? getDataRelationshipContextFromKey(rawViewMetadata.config.displayField)
142
+ : null
143
+ }
144
+ });
145
+ }
146
+ if (isDisplayModeEnabled && !canBeChangedInReviewMode) {
147
+ return (
148
+ <SingleReferenceReadonly
149
+ config={{
150
+ ...rawViewMetadata.config,
151
+ primaryField: rawViewMetadata.config.displayField
152
+ }}
153
+ getPConnect={getPConnect}
154
+ label={propsToUse.label}
155
+ type={type}
156
+ displayAs='readonly'
157
+ displayMode={displayMode}
158
+ activeViewRuleClass={rawViewMetadata.config.targetObjectClass} // for older views which may not have context class set, fall back to previous behavior
159
+ referenceType={referenceType}
160
+ hideLabel={hideLabel}
161
+ dataRelationshipContext={
162
+ rawViewMetadata.config?.displayField ? getDataRelationshipContextFromKey(rawViewMetadata.config.displayField) : null
163
+ }
164
+ additionalFields={additionalFields}
165
+ />
166
+ );
167
+ }
168
+
169
+ // 1) Set datasource
170
+ generateColumns(rawViewMetadata.config, pConn, referenceType);
171
+ rawViewMetadata.config.deferDatasource = true;
172
+ rawViewMetadata.config.listType = 'datapage';
173
+ if (['Dropdown', 'AutoComplete'].includes(type) && !rawViewMetadata.config.placeholder) {
174
+ rawViewMetadata.config.placeholder = '@L Select...';
175
+ }
176
+
177
+ // 2) Pass through configs
178
+ rawViewMetadata.config.showPromotedFilters = showPromotedFilters;
179
+
180
+ if (!canBeChangedInReviewMode) {
181
+ rawViewMetadata.config.displayMode = displayMode;
182
+ }
183
+
184
+ // 3) Define field meta
185
+ let fieldMetaData: any = null;
186
+
187
+ fieldMetaData = {
188
+ datasourceMetadata: {
189
+ datasource: {
190
+ parameters: {}
191
+ }
192
+ }
193
+ };
194
+ if (rawViewMetadata.config?.parameters) {
195
+ fieldMetaData.datasourceMetadata.datasource.parameters = parameters;
196
+ }
197
+ fieldMetaData.datasourceMetadata.datasource.propertyForDisplayText = rawViewMetadata?.config?.datasource?.fields?.text.startsWith('@P')
198
+ ? rawViewMetadata?.config?.datasource?.fields?.text?.substring(3)
199
+ : rawViewMetadata?.config?.datasource?.fields?.text;
200
+ fieldMetaData.datasourceMetadata.datasource.propertyForValue = rawViewMetadata?.config?.datasource?.fields?.value.startsWith('@P')
201
+ ? rawViewMetadata?.config?.datasource?.fields?.value?.substring(3)
202
+ : rawViewMetadata?.config?.datasource?.fields?.value;
203
+ fieldMetaData.datasourceMetadata.datasource.name = rawViewMetadata.config?.referenceList;
204
+
205
+ return getPConnect().createComponent({
206
+ type,
207
+ config: {
208
+ ...rawViewMetadata.config,
209
+ descriptors: mode === SELECTION_MODE.SINGLE ? refFieldMetadata?.descriptors : null,
210
+ datasourceMetadata: fieldMetaData?.datasourceMetadata,
211
+ required: propsToUse.required,
212
+ visibility: propsToUse.visibility,
213
+ disabled: propsToUse.disabled,
214
+ label: propsToUse.label,
215
+ parameters: rawViewMetadata.config.parameters,
216
+ readOnly: false,
217
+ localeReference: rawViewMetadata.config.localeReference,
218
+ ...(mode === SELECTION_MODE.SINGLE ? { referenceType } : ''),
219
+ contextClass: rawViewMetadata.config.targetObjectClass,
220
+ primaryField: rawViewMetadata.config?.displayField,
221
+ dataRelationshipContext: rawViewMetadata.config?.displayField ? getDataRelationshipContextFromKey(rawViewMetadata.config.displayField) : null,
222
+ hideLabel,
223
+ onRecordChange,
224
+ inline
225
+ }
226
+ });
227
+ }, [rawViewMetadata.config?.datasource?.source, parameters, propsToUse.required, propsToUse.disabled, getPConnect().getPageReference()]);
228
+
229
+ // Prepare children to render
230
+ return (
231
+ <Grid2 container>
232
+ <Grid2>{recreatedFirstChild}</Grid2>
233
+ </Grid2>
234
+ );
235
+ }
@@ -0,0 +1 @@
1
+ export { default } from './ObjectReference';
@@ -0,0 +1,111 @@
1
+ import { Utils } from '@pega/react-sdk-components/lib/components/helpers/utils';
2
+
3
+ export const SELECTION_MODE = { SINGLE: 'single', MULTI: 'multi' };
4
+
5
+ const getLeafNameFromPropertyName = property => property?.substr(property.lastIndexOf('.'));
6
+
7
+ const isSelfReferencedProperty = (param, referenceProp) => param === referenceProp?.split('.', 2)[1];
8
+
9
+ export const AT_FILTEREDLIST = '@FILTERED_LIST';
10
+ export const AT_PROPERTY = '@P';
11
+ export const SQUARE_BRACKET_START = '[';
12
+ export const SQUARE_BRACKET_END = ']';
13
+
14
+ export const SIMPLE_TABLE_MANUAL_READONLY = 'SimpleTableManualReadOnly';
15
+ export const PAGE = '!P!';
16
+ export const PAGELIST = '!PL!';
17
+ export const PERIOD = '.';
18
+ const AT = '@';
19
+
20
+ export function updatePageListPropertyValue(value) {
21
+ value = value.substring(0, value.indexOf(SQUARE_BRACKET_START)) + value.substring(value.indexOf(SQUARE_BRACKET_END) + 1);
22
+ return value;
23
+ }
24
+
25
+ export function getPropertyValue(value) {
26
+ if (value.startsWith(AT)) {
27
+ value = value.substring(value.indexOf(' ') + 1);
28
+ if (value.startsWith(PERIOD)) value = value.substring(1);
29
+ }
30
+ if (value.includes(SQUARE_BRACKET_START)) {
31
+ value = updatePageListPropertyValue(value);
32
+ }
33
+ return value;
34
+ }
35
+
36
+ const getCompositeKeys = (c11nEnv, property) => {
37
+ const { datasource: { parameters = {} } = {} } = c11nEnv.getFieldMetadata(property) || {};
38
+ return Object.values(parameters).reduce((compositeKeys: any, param) => {
39
+ if (isSelfReferencedProperty(property, param)) {
40
+ let propName = getPropertyValue(param);
41
+ propName = propName.substring(propName.indexOf('.'));
42
+ compositeKeys.push(propName);
43
+ }
44
+ return compositeKeys;
45
+ }, []);
46
+ };
47
+
48
+ export const generateColumns = (config, pConn, referenceType) => {
49
+ const displayField = getLeafNameFromPropertyName(config.displayField);
50
+ const referenceProp = config.value.split('.', 2)[1];
51
+ const compositeKeys: any = getCompositeKeys(pConn, referenceProp);
52
+ let value = getLeafNameFromPropertyName(config.value);
53
+
54
+ const columns: any = [];
55
+ if (displayField) {
56
+ columns.push({
57
+ value: displayField,
58
+ display: 'true',
59
+ useForSearch: true,
60
+ primary: 'true'
61
+ });
62
+ }
63
+ if (value && compositeKeys.indexOf(value) !== -1) {
64
+ columns.push({
65
+ value,
66
+ setProperty: 'Associated property',
67
+ key: 'true'
68
+ });
69
+ } else {
70
+ const actualValue = compositeKeys.length > 0 ? compositeKeys[0] : value;
71
+ config.value = `@P .${referenceProp}${actualValue}`;
72
+ value = actualValue;
73
+ columns.push({
74
+ value: actualValue,
75
+ setProperty: 'Associated property',
76
+ key: 'true'
77
+ });
78
+ }
79
+
80
+ config.datasource = {
81
+ fields: {
82
+ key: getLeafNameFromPropertyName(config.value),
83
+ text: getLeafNameFromPropertyName(config.displayField),
84
+ value: getLeafNameFromPropertyName(config.value)
85
+ }
86
+ };
87
+
88
+ if (referenceType === 'Case') {
89
+ columns.push({
90
+ secondary: 'true',
91
+ display: 'true',
92
+ value: Utils.getMappedKey('pyID'),
93
+ useForSearch: true
94
+ });
95
+ }
96
+
97
+ compositeKeys.forEach(key => {
98
+ if (value !== key)
99
+ columns.push({
100
+ value: key,
101
+ display: 'false',
102
+ secondary: 'true',
103
+ useForSearch: false,
104
+ setProperty: `.${referenceProp}${key}`
105
+ });
106
+ });
107
+
108
+ config.columns = columns;
109
+ };
110
+
111
+ export const getDataRelationshipContextFromKey = key => key.split('.', 2)[1];