@pega/react-sdk-overrides 8.23.10 → 8.23.11-debug

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 (84) hide show
  1. package/lib/designSystemExtension/AlertBanner/AlertBanner.tsx +43 -0
  2. package/lib/designSystemExtension/AlertBanner/index.tsx +1 -0
  3. package/lib/designSystemExtension/FieldGroupList/FieldGroupList.tsx +1 -3
  4. package/lib/designSystemExtension/Operator/Operator.tsx +16 -11
  5. package/lib/designSystemExtension/WssQuickCreate/WssQuickCreate.tsx +2 -2
  6. package/lib/field/CancelAlert/CancelAlert.tsx +12 -8
  7. package/lib/field/Checkbox/Checkbox.tsx +3 -2
  8. package/lib/field/Currency/currency-utils.ts +4 -1
  9. package/lib/field/Date/Date.tsx +12 -5
  10. package/lib/field/DateTime/DateTime.tsx +1 -1
  11. package/lib/field/Decimal/Decimal.tsx +66 -14
  12. package/lib/field/Dropdown/Dropdown.tsx +49 -10
  13. package/lib/field/Phone/Phone.tsx +2 -1
  14. package/lib/field/RadioButtons/RadioButtons.tsx +43 -4
  15. package/lib/field/SemanticLink/utils.ts +2 -1
  16. package/lib/field/TextInput/TextInput.tsx +26 -6
  17. package/lib/field/Time/Time.tsx +9 -1
  18. package/lib/field/URL/URL.tsx +8 -0
  19. package/lib/field/UserReference/UserReference.tsx +2 -0
  20. package/lib/helpers/{attachmentHelpers.js → attachmentHelpers.ts} +2 -2
  21. package/lib/helpers/auth.js +10 -3
  22. package/lib/helpers/authManager.js +16 -13
  23. package/lib/helpers/case-utils.tsx +104 -0
  24. package/lib/helpers/common-utils.ts +4 -0
  25. package/lib/helpers/config_access.js +122 -131
  26. package/lib/helpers/data_page.ts +2 -1
  27. package/lib/helpers/date-format-utils.ts +28 -18
  28. package/lib/helpers/{field-group-utils.js → field-group-utils.ts} +4 -3
  29. package/lib/helpers/formatters/{Currency.js → Currency.ts} +4 -3
  30. package/lib/helpers/formatters/{Date.js → Date.ts} +1 -1
  31. package/lib/helpers/formatters/common.ts +18 -0
  32. package/lib/helpers/simpleTableHelpers.ts +6 -2
  33. package/lib/helpers/state-utils.tsx +50 -0
  34. package/lib/helpers/template-utils.ts +3 -1
  35. package/lib/helpers/utils.ts +12 -4
  36. package/lib/helpers/versionHelpers.ts +3 -1
  37. package/lib/infra/ActionButtons/ActionButtons.tsx +7 -2
  38. package/lib/infra/Assignment/Assignment.tsx +23 -10
  39. package/lib/infra/Containers/FlowContainer/FlowContainer.tsx +24 -11
  40. package/lib/infra/Containers/FlowContainer/{helpers.js → helpers.ts} +21 -16
  41. package/lib/infra/Containers/ModalViewContainer/ModalViewContainer.tsx +28 -9
  42. package/lib/infra/Containers/ViewContainer/ViewContainer.tsx +7 -5
  43. package/lib/infra/DashboardFilter/DashboardFilter.tsx +5 -1
  44. package/lib/infra/DashboardFilter/filterUtils.tsx +2 -0
  45. package/lib/infra/DeferLoad/DeferLoad.tsx +4 -1
  46. package/lib/infra/ErrorBoundary/ErrorBoundary.tsx +10 -5
  47. package/lib/infra/MultiStep/MultiStep.tsx +2 -2
  48. package/lib/infra/NavBar/NavBar.tsx +11 -5
  49. package/lib/infra/RootContainer/RootContainer.tsx +16 -14
  50. package/lib/infra/Stages/Stages.tsx +5 -1
  51. package/lib/infra/View/View.tsx +7 -34
  52. package/lib/template/AppShell/AppShell.tsx +15 -9
  53. package/lib/template/CaseView/CaseView.tsx +116 -78
  54. package/lib/template/CaseViewActionsMenu/CaseViewActionsMenu.tsx +26 -17
  55. package/lib/template/Confirmation/Confirmation.tsx +4 -1
  56. package/lib/template/DataReference/DataReference.tsx +2 -0
  57. package/lib/template/DefaultForm/DefaultForm.tsx +15 -8
  58. package/lib/template/DefaultForm/utils/index.ts +33 -0
  59. package/lib/template/FieldGroupTemplate/FieldGroupTemplate.tsx +5 -2
  60. package/lib/template/ListView/ListView.tsx +3 -1
  61. package/lib/template/ListView/{hooks.js → hooks.ts} +3 -1
  62. package/lib/template/ListView/{utils.js → utils.ts} +12 -10
  63. package/lib/template/MultiReferenceReadOnly/MultiReferenceReadOnly.tsx +5 -1
  64. package/lib/template/PromotedFilters/PromotedFilters.tsx +9 -5
  65. package/lib/template/SimpleTable/SimpleTable/SimpleTable.tsx +4 -1
  66. package/lib/template/SimpleTable/SimpleTableManual/SimpleTableManual.tsx +8 -4
  67. package/lib/template/SimpleTable/SimpleTableSelect/SimpleTableSelect.tsx +6 -1
  68. package/lib/template/SubTabs/tabUtils.ts +3 -1
  69. package/lib/template/WssNavBar/WssNavBar.tsx +2 -2
  70. package/lib/widget/Attachment/Attachment.css +15 -3
  71. package/lib/widget/Attachment/Attachment.tsx +32 -25
  72. package/lib/widget/CaseHistory/CaseHistory.tsx +5 -5
  73. package/lib/widget/FileUtility/FileUtility/FileUtility.tsx +20 -19
  74. package/lib/widget/QuickCreate/QuickCreate.tsx +6 -3
  75. package/lib/widget/SummaryItem/SummaryItem.tsx +2 -4
  76. package/lib/widget/ToDo/ToDo.tsx +17 -9
  77. package/package.json +1 -1
  78. package/lib/helpers/formatters/common.js +0 -14
  79. /package/lib/helpers/{event-utils.js → event-utils.ts} +0 -0
  80. /package/lib/helpers/formatters/{Boolean.js → Boolean.ts} +0 -0
  81. /package/lib/helpers/formatters/{CurrencyMap.js → CurrencyMap.ts} +0 -0
  82. /package/lib/helpers/formatters/{index.js → index.ts} +0 -0
  83. /package/lib/helpers/{reactContextHelpers.js → reactContextHelpers.ts} +0 -0
  84. /package/lib/template/ListView/{DefaultViewMeta.js → DefaultViewMeta.ts} +0 -0
@@ -1,7 +1,7 @@
1
1
  // Helper singleton class to assist with loading and accessing
2
2
  // the SDK Config JSON
3
- import {sdkGetAuthHeader} from './authManager';
4
- import Utils from './utils';
3
+ import { sdkGetAuthHeader } from './authManager';
4
+ import { isEmptyObject } from './common-utils';
5
5
 
6
6
  // Create a singleton for this class (with async loading of config file) and export it
7
7
  // Note: Initialzing SdkConfigAccess to null seems to cause lots of compile issues with references
@@ -9,9 +9,7 @@ import Utils from './utils';
9
9
  let SdkConfigAccess;
10
10
  let SdkConfigAccessCreateInProgress = false;
11
11
 
12
-
13
12
  class ConfigAccess {
14
-
15
13
  constructor() {
16
14
  // sdkConfig is the JSON object read from the sdk-config.json file
17
15
  this.sdkConfig = {};
@@ -27,23 +25,24 @@ class ConfigAccess {
27
25
  * @returns Promise of config file fetch
28
26
  */
29
27
  async readSdkConfig() {
30
- if(Utils.isEmptyObject(this.sdkConfig)) {
31
- return fetch("./sdk-config.json")
32
- .then ( (response) => {
33
- if( response.ok ) {
28
+ if (isEmptyObject(this.sdkConfig)) {
29
+ return fetch('./sdk-config.json')
30
+ .then(response => {
31
+ if (response.ok) {
34
32
  return response.json();
35
33
  } else {
36
34
  throw new Error(`Failed with status:${response.status}`);
37
35
  }
38
36
  })
39
- .then ( (data) => {
40
- this.sdkConfig = data;
41
- this.fixupConfigSettings();
42
- return Promise.resolve(this.sdkConfig);
43
- }).catch(err => {
44
- console.error("Fetch for sdk-config.js failed.");
45
- console.error(err);
46
- return Promise.reject(err);
37
+ .then(data => {
38
+ this.sdkConfig = data;
39
+ this.fixupConfigSettings();
40
+ return Promise.resolve(this.sdkConfig);
41
+ })
42
+ .catch(err => {
43
+ console.error('Fetch for sdk-config.js failed.');
44
+ console.error(err);
45
+ return Promise.reject(err);
47
46
  });
48
47
  } else {
49
48
  return Promise.resolve(this.sdkConfig);
@@ -52,24 +51,33 @@ class ConfigAccess {
52
51
 
53
52
  // Adjust any settings like setting up defaults or making sure URIs have a trailing slash
54
53
  fixupConfigSettings() {
55
- const oServerConfig = this.sdkConfig["serverConfig"];
54
+ const oServerConfig = this.sdkConfig['serverConfig'];
56
55
  // If not present, then use current root path
57
56
  oServerConfig.sdkContentServerUrl = oServerConfig.sdkContentServerUrl || window.location.origin;
58
57
  // Needs a trailing slash so add one if not there
59
- if( !oServerConfig.sdkContentServerUrl.endsWith('/') ) {
58
+ if (!oServerConfig.sdkContentServerUrl.endsWith('/')) {
60
59
  oServerConfig.sdkContentServerUrl = `${oServerConfig.sdkContentServerUrl}/`;
61
60
  }
62
- console.log(`Using sdkContentServerUrl: ${this.sdkConfig["serverConfig"].sdkContentServerUrl}`);
61
+ console.log(`Using sdkContentServerUrl: ${this.sdkConfig['serverConfig'].sdkContentServerUrl}`);
63
62
 
64
63
  // Don't want a trailing slash for infinityRestServerUrl
65
- if( oServerConfig.infinityRestServerUrl.endsWith('/') ) {
66
- oServerConfig.infinityRestServerUrl = oServerConfig.infinityRestServerUrl.slice(0, -1)
64
+ if (oServerConfig.infinityRestServerUrl.endsWith('/')) {
65
+ oServerConfig.infinityRestServerUrl = oServerConfig.infinityRestServerUrl.slice(0, -1);
67
66
  }
68
67
 
69
68
  // Specify our own internal list of well known portals to exclude (if one not specified)
70
- if( !oServerConfig.excludePortals ) {
71
- oServerConfig.excludePortals = ["pxExpress", "Developer", "pxPredictionStudio", "pxAdminStudio", "pyCaseWorker", "pyCaseManager7"];
72
- console.warn(`No exludePortals entry found within serverConfig section of sdk-config.json. Using the following default list: ["pxExpress", "Developer", "pxPredictionStudio", "pxAdminStudio", "pyCaseWorker", "pyCaseManager7"]`);
69
+ if (!oServerConfig.excludePortals) {
70
+ oServerConfig.excludePortals = [
71
+ 'pxExpress',
72
+ 'Developer',
73
+ 'pxPredictionStudio',
74
+ 'pxAdminStudio',
75
+ 'pyCaseWorker',
76
+ 'pyCaseManager7'
77
+ ];
78
+ console.warn(
79
+ `No exludePortals entry found within serverConfig section of sdk-config.json. Using the following default list: ["pxExpress", "Developer", "pxPredictionStudio", "pxAdminStudio", "pyCaseWorker", "pyCaseManager7"]`
80
+ );
73
81
  }
74
82
  }
75
83
 
@@ -78,145 +86,128 @@ class ConfigAccess {
78
86
  * @returns the sdk-config JSON object
79
87
  */
80
88
  getSdkConfig = async () => {
81
- if(Utils.isEmptyObject(this.sdkConfig)) {
89
+ if (isEmptyObject(this.sdkConfig)) {
82
90
  await getSdkConfig();
83
91
  }
84
92
  return this.sdkConfig;
85
- }
86
-
93
+ };
87
94
 
88
95
  /**
89
96
  *
90
97
  * @returns the authConfig block in the SDK Config object
91
98
  */
92
99
  getSdkConfigAuth = () => {
93
- if(Utils.isEmptyObject(this.sdkConfig)) {
100
+ if (isEmptyObject(this.sdkConfig)) {
94
101
  const config = this.getSdkConfig();
95
102
  }
96
- return this.sdkConfig["authConfig"];
97
- }
103
+ return this.sdkConfig['authConfig'];
104
+ };
98
105
 
99
106
  /**
100
107
  *
101
108
  * @returns the serverConfig bloc from the sdk-config.json file
102
109
  */
103
110
  getSdkConfigServer = () => {
104
- if(Utils.isEmptyObject(this.sdkConfig)) {
111
+ if (isEmptyObject(this.sdkConfig)) {
105
112
  const config = this.getSdkConfig();
106
113
  }
107
- return this.sdkConfig["serverConfig"];
108
- }
109
-
114
+ return this.sdkConfig['serverConfig'];
115
+ };
110
116
 
111
117
  /**
112
- * @param {String} key the key to be inserted/updated in serverConfig
113
- * @param {String} value the value to be assigned to the given key
114
- */
118
+ * @param {String} key the key to be inserted/updated in serverConfig
119
+ * @param {String} value the value to be assigned to the given key
120
+ */
115
121
  setSdkConfigServer = (key, value) => {
116
-
117
122
  this.sdkConfig.serverConfig[key] = value;
118
-
119
- }
123
+ };
120
124
 
121
125
  /**
122
- * If this.sdkConfig.serverConfig.appPortal is set, leave it and the specified portal will be used.
123
- * If not set, set this.sdkConfig.serverConfig.appPortal to default portal of currently logged in user
126
+ * Get available portals which supports SDK
127
+ * @returns list of available portals (portals other than excludingPortals list)
124
128
  */
125
- async selectPortal() {
126
-
127
- if(Utils.isEmptyObject(this.sdkConfig)) {
128
- await getSdkConfig();
129
- }
130
-
131
- const serverConfig = this.sdkConfig.serverConfig;
132
-
133
- if ((serverConfig.appPortal !== "") &&
134
- (serverConfig.appPortal !== undefined) ) {
135
- // use the specified portal
136
- console.log(`Using appPortal: ${serverConfig.appPortal}`);
137
- return;
138
- }
129
+ async getAvailablePortals() {
130
+ return new Promise(async (resolve, reject) => {
131
+ if (isEmptyObject(this.sdkConfig)) {
132
+ await getSdkConfig();
133
+ }
139
134
 
140
- const userAccessGroup = PCore.getEnvironmentInfo().getAccessGroup();
141
- const dataPageName = "D_OperatorAccessGroups";
142
- const serverUrl = serverConfig.infinityRestServerUrl;
143
- const appAlias = serverConfig.appAlias;
144
- const appAliasPath = appAlias ? `/app/${appAlias}` : '';
145
- const arExcludedPortals = serverConfig["excludePortals"];
135
+ const serverConfig = this.sdkConfig.serverConfig;
136
+
137
+ const userAccessGroup = PCore.getEnvironmentInfo().getAccessGroup();
138
+ const dataPageName = 'D_OperatorAccessGroups';
139
+ const serverUrl = serverConfig.infinityRestServerUrl;
140
+ const appAlias = serverConfig.appAlias;
141
+ const appAliasPath = appAlias ? `/app/${appAlias}` : '';
142
+ const arExcludedPortals = serverConfig['excludePortals'];
143
+ let headers = {
144
+ Authorization: sdkGetAuthHeader(),
145
+ 'Content-Type': 'application/json'
146
+ };
146
147
 
147
- // Using v1 API here as v2 data_views is not able to access same data page currently. Should move to avoid having this logic to find
148
- // a default portal or constellation portal and rather have Constellation JS Engine API just load the default portal
149
- await fetch ( `${serverUrl}${appAliasPath}/api/v1/data/${dataPageName}`,
150
- {
148
+ // Using v1 API here as v2 data_views is not able to access same data page currently. Should move to avoid having this logic to find
149
+ // a default portal or constellation portal and rather have Constellation JS Engine API just load the default portal
150
+ fetch(`${serverUrl}${appAliasPath}/api/v1/data/${dataPageName}`, {
151
151
  method: 'GET',
152
- headers: {
153
- 'Content-Type' : 'application/json',
154
- 'Authorization' : sdkGetAuthHeader()
155
- }
152
+ headers
156
153
  })
157
- .then( response => {
158
- if( response.ok && response.status === 200) {
159
- return response.json();
160
- } else {
161
- if( response.status === 401 ) {
162
- // Might be either a real token expiration or revoke, but more likely that the "api" service package is misconfigured
163
- throw( new Error(`Attempt to access ${dataPageName} failed. The "api" service package is likely not configured to use "OAuth 2.0"`));
164
- };
165
- throw( new Error(`HTTP Error: ${response.status}`));
166
- }
167
- })
168
- .then( async (agData) => {
169
-
170
- let arAccessGroups = agData.pxResults;
171
- let selectedPortal = null;
172
-
173
- for (let ag of arAccessGroups) {
174
- if (ag.pyAccessGroup === userAccessGroup) {
175
- // Check if default portal works
176
- if( !arExcludedPortals.includes(ag.pyPortal) ) {
177
- selectedPortal = ag.pyPortal;
178
- } else {
179
- console.error(`Default portal for current operator (${ag.pyPortal}) is not compatible with SDK.\nConsider using a different operator, adjusting the default portal for this operator, or using "appPortal" setting within sdk-config.json to specify a specific portal to load.`);
180
- // Find first portal that is not excluded (might work)
181
- for (let portal of ag.pyUserPortals ) {
182
- if( !arExcludedPortals.includes(portal.pyPortalLayout) ) {
183
- selectedPortal = portal.pyPortalLayout;
184
- break;
154
+ .then(response => {
155
+ if (response.ok && response.status === 200) {
156
+ return response.json();
157
+ } else {
158
+ if (response.status === 401) {
159
+ // Might be either a real token expiration or revoke, but more likely that the "api" service package is misconfigured
160
+ throw new Error(
161
+ `Attempt to access ${dataPageName} failed. The "api" service package is likely not configured to use "OAuth 2.0"`
162
+ );
163
+ }
164
+ throw new Error(`HTTP Error: ${response.status}`);
165
+ }
166
+ })
167
+ .then(async agData => {
168
+ const arAccessGroups = agData.pxResults;
169
+ const availablePortals = [];
170
+
171
+ for (let ag of arAccessGroups) {
172
+ if (ag.pyAccessGroup === userAccessGroup) {
173
+ console.error(
174
+ `Default portal for current operator (${ag.pyPortal}) is not compatible with SDK.\nConsider using a different operator, adjusting the default portal for this operator, or using "appPortal" setting within sdk-config.json to specify a specific portal to load.`
175
+ );
176
+ for (let portal of ag.pyUserPortals) {
177
+ if (!arExcludedPortals.includes(portal.pyPortalLayout)) {
178
+ availablePortals.push(portal.pyPortalLayout);
185
179
  }
186
180
  }
181
+ break;
187
182
  }
188
- break;
189
183
  }
190
- }
191
- if( selectedPortal ) {
184
+
192
185
  // Found operator's current access group. Use its portal
193
- this.setSdkConfigServer("appPortal", selectedPortal);
194
- console.log(`Using non-excluded portal: ${serverConfig.appPortal}`);
195
- }
196
- })
197
- .catch( e => {
198
- console.error(e.message);
199
- // check specific error if 401, and wiped out if so stored token is stale. Fetch new tokens.
200
- });
186
+ console.log(`Available portals: ${availablePortals}`);
201
187
 
188
+ resolve(availablePortals);
189
+ })
190
+ .catch(e => {
191
+ console.error(e.message);
192
+ // check specific error if 401, and wiped out if so stored token is stale. Fetch new tokens.
193
+ });
194
+ });
202
195
  }
203
196
 
204
197
  /**
205
198
  * Path to the BootstrapCSS
206
199
  * @returns the locBootstrapCSS from the serverConfig block of the sdk-config.json file
207
200
  */
208
- getSdkConfigBootstrapCSS = () => {
209
- const serverConfig = this.getSdkConfigServer();
210
- const locBootstrapCSS = serverConfig.locBootstrapCSS;
211
- if (locBootstrapCSS === undefined) {
212
- console.error(`locBootstrapCSS: ${locBootstrapCSS}`);
213
- }
201
+ getSdkConfigBootstrapCSS = () => {
202
+ const serverConfig = this.getSdkConfigServer();
203
+ const locBootstrapCSS = serverConfig.locBootstrapCSS;
204
+ if (locBootstrapCSS === undefined) {
205
+ console.error(`locBootstrapCSS: ${locBootstrapCSS}`);
206
+ }
214
207
  return locBootstrapCSS;
215
- }
216
-
208
+ };
217
209
  }
218
210
 
219
-
220
211
  // Implement Factory function to allow async load
221
212
  // See https://stackoverflow.com/questions/49905178/asynchronous-operations-in-constructor/49906064#49906064 for inspiration
222
213
  async function createSdkConfigAccess() {
@@ -224,36 +215,36 @@ async function createSdkConfigAccess() {
224
215
  let singleton = new ConfigAccess();
225
216
  await singleton.readSdkConfig();
226
217
  return singleton;
227
- };
218
+ }
228
219
 
229
220
  // Initialize exported SdkConfigAccess structure
230
221
  async function getSdkConfig() {
231
- return new Promise( (resolve) => {
222
+ return new Promise(resolve => {
232
223
  let idNextCheck = null;
233
- if( !SdkConfigAccess && !SdkConfigAccessCreateInProgress ) {
224
+ if (!SdkConfigAccess && !SdkConfigAccessCreateInProgress) {
234
225
  SdkConfigAccessCreateInProgress = true;
235
- createSdkConfigAccess().then( theConfigAccess => {
226
+ createSdkConfigAccess().then(theConfigAccess => {
236
227
  // Key initialization of SdkConfigAccess
237
228
  SdkConfigAccess = theConfigAccess;
238
229
  SdkConfigAccessCreateInProgress = false;
239
230
  // console.log(`SdkConfigAccess: ${JSON.stringify(SdkConfigAccess)}`);
240
231
  // Create and dispatch the SdkConfigAccessReady event
241
- const event = new CustomEvent("SdkConfigAccessReady", { });
232
+ const event = new CustomEvent('SdkConfigAccessReady', {});
242
233
  document.dispatchEvent(event);
243
- return resolve( SdkConfigAccess.sdkConfig );
234
+ return resolve(SdkConfigAccess.sdkConfig);
244
235
  });
245
236
  } else {
246
237
  const fnCheckForConfig = () => {
247
- if( SdkConfigAccess ) {
248
- if( idNextCheck ) {
238
+ if (SdkConfigAccess) {
239
+ if (idNextCheck) {
249
240
  clearInterval(idNextCheck);
250
241
  }
251
- return resolve( SdkConfigAccess.sdkConfig );
242
+ return resolve(SdkConfigAccess.sdkConfig);
252
243
  }
253
244
  idNextCheck = setInterval(fnCheckForConfig, 500);
254
245
  };
255
- if( SdkConfigAccess ) {
256
- return resolve( SdkConfigAccess.sdkConfig );
246
+ if (SdkConfigAccess) {
247
+ return resolve(SdkConfigAccess.sdkConfig);
257
248
  } else {
258
249
  idNextCheck = setInterval(fnCheckForConfig, 500);
259
250
  }
@@ -261,8 +252,8 @@ async function getSdkConfig() {
261
252
  });
262
253
  }
263
254
 
264
- if( true ) {
255
+ if (true) {
265
256
  let ignore = getSdkConfig();
266
257
  }
267
258
 
268
- export {SdkConfigAccess, getSdkConfig};
259
+ export { SdkConfigAccess, getSdkConfig };
@@ -1,4 +1,5 @@
1
- declare const PCore;
1
+ // Remove this and use "real" PCore type once .d.ts is fixed (currently shows 1 error)
2
+ declare const PCore: any;
2
3
 
3
4
  // eslint-disable-next-line import/prefer-default-export
4
5
  export const getDataPage = (dataPageName, parameters, context) => {
@@ -1,16 +1,17 @@
1
1
  import { getLocale } from './formatters/common';
2
2
 
3
-
4
3
  export const dateFormatInfoDefault = {
5
- dateFormatString: "MM/DD/YYYY",
6
- dateFormatStringLong: "MMM DD, YYYY",
7
- dateFormatStringLC: "mm/dd/yyyy",
8
- dateFormatMask: "__/__/____"
9
- }
4
+ dateFormatString: 'MM/DD/YYYY',
5
+ dateFormatStringLong: 'MMM DD, YYYY',
6
+ dateFormatStringLC: 'mm/dd/yyyy',
7
+ dateFormatMask: '__/__/____'
8
+ };
10
9
 
11
10
  export const getDateFormatInfo = () => {
11
+ const localizedVal = PCore.getLocaleUtils().getLocaleValue;
12
+ const localeCategory = 'CosmosFields';
12
13
  const theDateFormatInfo = dateFormatInfoDefault;
13
- const theLocale = getLocale(); // PCore.getEnvironmentInfo().getUseLocale() || "US-en";
14
+ const theLocale = getLocale();
14
15
 
15
16
  // NOTE: this date was chosen since it has a day larger than 12. If you change it,
16
17
  // you'll need to change the indexOf values below!
@@ -25,29 +26,38 @@ export const getDateFormatInfo = () => {
25
26
  const locDD = theTestDateLocaleString.indexOf('30');
26
27
  const locYYYY = theTestDateLocaleString.indexOf('2023');
27
28
 
29
+ // If localized placeholder exists for one of day/month/year then show it otherwise fall back to ddmmyyyy
30
+ const localizedPlaceholderExists =
31
+ localizedVal('month_placeholder', localeCategory) !== 'month_placeholder' ||
32
+ localizedVal('day_placeholder', localeCategory) !== 'day_placeholder' ||
33
+ localizedVal('year_placeholder', localeCategory) !== 'year_placeholder';
34
+
28
35
  const arrPieces = [
29
36
  {
30
37
  loc: locMM,
31
38
  format: 'MM',
32
39
  longFormat: 'MMM',
33
- placeholder: 'mm',
34
- mask: '__'
40
+ placeholder: localizedPlaceholderExists ? localizedVal('month_placeholder', localeCategory) : 'mm',
41
+ mask: '__',
42
+ separator: theTestDateLocaleString[locMM+2]
35
43
  },
36
44
  {
37
45
  loc: locDD,
38
46
  format: 'DD',
39
47
  longFormat: 'DD',
40
- placeholder: 'dd',
41
- mask: '__'
48
+ placeholder: localizedPlaceholderExists ? localizedVal('day_placeholder', localeCategory) : 'dd',
49
+ mask: '__',
50
+ separator: theTestDateLocaleString[locDD+2]
42
51
  },
43
52
  {
44
53
  loc: locYYYY,
45
54
  format: 'YYYY',
46
55
  longFormat: 'YYYY',
47
- placeholder: 'yyyy',
48
- mask: '____'
56
+ placeholder: localizedPlaceholderExists ? localizedVal('year_placeholder', localeCategory) : 'yyyy',
57
+ mask: '____',
58
+ separator: theTestDateLocaleString[locYYYY+4]
49
59
  }
50
- ];
60
+ ];
51
61
 
52
62
  // Sort the associative array by order of appearance (loc) of each piece
53
63
  arrPieces.sort((a, b) => {
@@ -57,10 +67,10 @@ export const getDateFormatInfo = () => {
57
67
  });
58
68
 
59
69
  // Construct the structure to return...
60
- theDateFormatInfo.dateFormatString = `${arrPieces[0].format}/${arrPieces[1].format}/${arrPieces[2].format}`;
70
+ theDateFormatInfo.dateFormatString = `${arrPieces[0].format}${arrPieces[0].separator}${arrPieces[1].format}${arrPieces[1].separator}${arrPieces[2].format}`;
61
71
  theDateFormatInfo.dateFormatStringLong = `${arrPieces[0].longFormat} ${arrPieces[1].longFormat}, ${arrPieces[2].longFormat}`;
62
- theDateFormatInfo.dateFormatStringLC = `${arrPieces[0].placeholder}/${arrPieces[1].placeholder}/${arrPieces[2].placeholder}`;
63
- theDateFormatInfo.dateFormatMask = `${arrPieces[0].mask}/${arrPieces[1].mask}/${arrPieces[2].mask}`;
72
+ theDateFormatInfo.dateFormatStringLC = `${arrPieces[0].placeholder}${arrPieces[0].separator}${arrPieces[1].placeholder}${arrPieces[1].separator}${arrPieces[2].placeholder}`;
73
+ theDateFormatInfo.dateFormatMask = `${arrPieces[0].mask}${arrPieces[0].separator}${arrPieces[1].mask}${arrPieces[1].separator}${arrPieces[2].mask}`;
64
74
 
65
75
  return theDateFormatInfo;
66
- }
76
+ };
@@ -1,7 +1,8 @@
1
- import { createElement } from 'react';
1
+ import { createElement, ReactElement } from 'react';
2
2
 
3
3
  import createPConnectComponent from '@pega/react-sdk-components/lib/bridge/react_pconnect';
4
4
 
5
+
5
6
  /**
6
7
  *
7
8
  * @param {*} pConn - pConnect object of the view
@@ -28,7 +29,7 @@ export const getReferenceList = pConn => {
28
29
  * @param {*} viewConfigPath - boolean value to check for children in config
29
30
  * @returns {*} - return the react element of the view
30
31
  */
31
- export const buildView = (pConn, index, viewConfigPath) => {
32
+ export function buildView(pConn, index, viewConfigPath): ReactElement {
32
33
  const context = pConn.getContextName();
33
34
  const referenceList = getReferenceList(pConn);
34
35
 
@@ -48,7 +49,7 @@ export const buildView = (pConn, index, viewConfigPath) => {
48
49
  hasForm: true
49
50
  }
50
51
  };
51
- // eslint-disable-next-line no-undef
52
+
52
53
  const view = PCore.createPConnect(config);
53
54
  if (pConn.getConfigProps()?.displayMode === 'LABELS_LEFT') {
54
55
  view.getPConnect()?.setInheritedProp('displayMode', 'LABELS_LEFT');
@@ -1,7 +1,8 @@
1
1
  import { getLocale } from "./common";
2
2
  import CurrencyMap from "./CurrencyMap";
3
3
 
4
- function NumberFormatter(value, { locale, decPlaces = 2 } = {}) {
4
+ // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
5
+ function NumberFormatter(value, { locale = "en-US", decPlaces = 2, style="", currency="USD" } = {}) {
5
6
  const currentLocale = getLocale(locale);
6
7
  if (value !== null && value !== undefined) {
7
8
  return Number(value).toLocaleString(currentLocale, {
@@ -14,7 +15,7 @@ function NumberFormatter(value, { locale, decPlaces = 2 } = {}) {
14
15
 
15
16
  function CurrencyFormatter(
16
17
  value,
17
- { symbol = true, position, locale, decPlaces = 2, style = "currency", currency = "USD" } = {}
18
+ { symbol = true, position="before", locale="en-US", decPlaces = 2, style = "currency", currency = "USD" } = {}
18
19
  ) {
19
20
  const currentLocale = getLocale(locale);
20
21
  let formattedValue = value;
@@ -56,7 +57,7 @@ function CurrencyFormatter(
56
57
  return formattedValue;
57
58
  }
58
59
 
59
- function SymbolFormatter(value, { symbol, suffix = true, locale } = {}) {
60
+ function SymbolFormatter(value, { symbol="$", suffix = true, locale="en-US" } = {}) {
60
61
  let formattedValue = value;
61
62
  if (value !== null && value !== undefined) {
62
63
  formattedValue = NumberFormatter(value, { locale });
@@ -14,7 +14,7 @@ const types = ["fromNow", "customFormat"];
14
14
  // value should be in ISO 8601 format.
15
15
  function DateFormatter(
16
16
  value,
17
- { type = types[1], format = "DD/MM/YYYY", timezone } = {}
17
+ { type = types[1], format = "DD/MM/YYYY", timezone = "America/New_York" } = {}
18
18
  ) {
19
19
  if (!value) return value;
20
20
  switch (type) {
@@ -0,0 +1,18 @@
1
+ import PCoreType from '@pega/pcore-pconnect-typedefs/types/pcore';
2
+
3
+ declare const PCore: typeof PCoreType;
4
+
5
+
6
+ export function getLocale(locale='') {
7
+ // use locale if specified
8
+ if (locale) return locale;
9
+ // otherwise, use operator locale if it's defined
10
+ if (PCore.getEnvironmentInfo().getLocale()) return PCore.getEnvironmentInfo().getLocale();
11
+ // fallback
12
+ return Intl.DateTimeFormat().resolvedOptions().locale;
13
+ }
14
+
15
+ export function getCurrentTimezone(timezone="America/New_York") {
16
+ if (timezone) return timezone;
17
+ return PCore?.getLocaleUtils?.().getTimeZoneInUse?.();
18
+ }
@@ -1,6 +1,8 @@
1
1
  import { Utils } from './utils';
2
+ import PCoreType from '@pega/pcore-pconnect-typedefs/types/pcore';
3
+
4
+ declare const PCore: typeof PCoreType;
2
5
 
3
- declare const PCore;
4
6
 
5
7
  export const TABLE_CELL = "SdkRenderer";
6
8
  export const DELETE_ICON = "DeleteIcon";
@@ -216,7 +218,9 @@ export const getAddRowCallback = (pConnect, index) => {
216
218
  * @param {string} referenceList - referenceList
217
219
  * @param {string} pageReference - pageReference
218
220
  */
219
- export const createPConnect = (contextName, referenceList, pageReference) => {
221
+ // NOTE: use of type "any" is required since TypeScript doesn't allow private/protected properties
222
+ // to be exported from a class (TS4094 error)
223
+ export function createPConnect(contextName, referenceList, pageReference): any {
220
224
  const options = {
221
225
  context: contextName,
222
226
  pageReference,
@@ -0,0 +1,50 @@
1
+ import React, { useContext } from 'react';
2
+ import { connect, Provider, shallowEqual } from 'react-redux';
3
+ import ReactReduxContext from '@pega/react-sdk-components/lib/bridge/Context/StoreContext';
4
+ import PCoreType from '@pega/pcore-pconnect-typedefs/types/pcore';
5
+
6
+ declare const PCore: typeof PCoreType;
7
+
8
+
9
+ const connectToState = (mapStateToProps = () => {}) => {
10
+ return (Component: any) => {
11
+ const ConnectedComponent = connect(mapStateToProps, null, null, {
12
+ areStatePropsEqual: (next, prev: any) => {
13
+ // Compare visibility
14
+ const prevWasVisible = prev.visibility !== false;
15
+ if (next.visibility !== undefined && next.visibility !== prevWasVisible) {
16
+ return false;
17
+ }
18
+ // Compare start props
19
+ const c11nEnv = next.getPConnect();
20
+ const allStateProps = c11nEnv.getStateProps();
21
+ for (const key in allStateProps) {
22
+ if (
23
+ !shallowEqual(next[key], prev[key]) ||
24
+ (next.routingInfo && !PCore.isDeepEqual(next.routingInfo, prev.routingInfo))
25
+ ) {
26
+ return false;
27
+ }
28
+ }
29
+ /* TODO For some rawConfig we are not getting routingInfo under allStateProps */
30
+ return !(
31
+ 'routingInfo' in next &&
32
+ (!shallowEqual(next.routingInfo, prev.routingInfo) ||
33
+ !PCore.isDeepEqual(next.routingInfo, prev.routingInfo))
34
+ );
35
+ }
36
+ })(Component);
37
+
38
+ return (ownProps = {}) => {
39
+ const { store } = useContext<any>(ReactReduxContext);
40
+
41
+ return (
42
+ <Provider store={store}>
43
+ <ConnectedComponent {...ownProps} />
44
+ </Provider>
45
+ );
46
+ };
47
+ };
48
+ };
49
+
50
+ export default connectToState;
@@ -1,6 +1,8 @@
1
1
  // This file is adapted from React DX components/template/utils.js
2
+ import PCoreType from '@pega/pcore-pconnect-typedefs/types/pcore';
3
+
4
+ declare const PCore: typeof PCoreType;
2
5
 
3
- declare const PCore: any;
4
6
 
5
7
  export function getAllFields(pConnect: any) {
6
8
  const metadata = pConnect.getRawMetadata();