@pega/custom-dx-components 0.24.14 → 0.24.16

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 (54) hide show
  1. package/package.json +1 -1
  2. package/src/tasks/create/templates/Constellation/Field/Icon-Button-URL/demo.stories.tsx.mustache +5 -0
  3. package/src/tasks/create/templates/Constellation/Field/Icon-Button-URL/index.tsx.mustache +26 -15
  4. package/src/tasks/create/templates/Constellation/Template/DETAILS/Avatar.tsx.mustache +78 -0
  5. package/src/tasks/create/templates/Constellation/Template/DETAILS/Operator.tsx.mustache +218 -0
  6. package/src/tasks/create/templates/Constellation/Template/DETAILS/demo.stories.tsx.mustache +47 -13
  7. package/src/tasks/create/templates/Constellation/Template/DETAILS/index.tsx.mustache +2 -2
  8. package/src/tasks/create/templates/Constellation/Template/DETAILS/mock.ts.mustache +69 -10
  9. package/src/tasks/create/templates/Constellation/Template/DETAILS-region/Avatar.tsx.mustache +78 -0
  10. package/src/tasks/create/templates/Constellation/Template/DETAILS-region/Operator.tsx.mustache +218 -0
  11. package/src/tasks/create/templates/Constellation/Template/DETAILS-region/demo.stories.tsx.mustache +46 -12
  12. package/src/tasks/create/templates/Constellation/Template/DETAILS-region/index.tsx.mustache +2 -2
  13. package/src/tasks/create/templates/Constellation/Template/DETAILS-region/mock.ts.mustache +55 -0
  14. package/src/tasks/create/templates/Constellation/Template/FORM/index.tsx.mustache +1 -1
  15. package/src/tasks/create/templates/Constellation/Template/FORM-region/index.tsx.mustache +2 -2
  16. package/src/tasks/create/templates/Constellation/Widget/PAGE/demo.stories.tsx.mustache +29 -22
  17. package/src/tasks/create/templates/Constellation/Widget/PAGE/index.tsx.mustache +34 -20
  18. package/src/tasks/create/templates/Launchpad/Field/Icon-Button-URL/demo.stories.tsx.mustache +5 -0
  19. package/src/tasks/create/templates/Launchpad/Field/Icon-Button-URL/index.tsx.mustache +30 -17
  20. package/src/tasks/create/templates/Launchpad/Widget/PAGE/demo.stories.tsx.mustache +30 -22
  21. package/src/tasks/create/templates/Launchpad/Widget/PAGE/index.tsx.mustache +34 -20
  22. package/src/tasks/init/template/package.json.mustache +1 -1
  23. package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyDetails/Avatar.tsx +78 -0
  24. package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyDetails/Operator.tsx +215 -0
  25. package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyDetails/demo.stories.tsx +47 -13
  26. package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyDetails/index.tsx +2 -2
  27. package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyDetails/mock.ts +69 -10
  28. package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyForm/index.tsx +1 -1
  29. package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyIconButtonURL/demo.stories.tsx +5 -0
  30. package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyIconButtonURL/index.tsx +26 -15
  31. package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyPageWidget/demo.stories.tsx +29 -22
  32. package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyPageWidget/index.tsx +34 -20
  33. package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyTwoColumnDetails/Avatar.tsx +78 -0
  34. package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyTwoColumnDetails/Operator.tsx +215 -0
  35. package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyTwoColumnDetails/demo.stories.tsx +46 -12
  36. package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyTwoColumnDetails/index.tsx +2 -2
  37. package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyTwoColumnDetails/mock.ts +55 -0
  38. package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyTwoColumnForm/index.tsx +2 -2
  39. package/tests/assets/components/createAll/Launchpad/Pega_DXIL_MyDetails/Avatar.tsx +78 -0
  40. package/tests/assets/components/createAll/Launchpad/Pega_DXIL_MyDetails/Operator.tsx +215 -0
  41. package/tests/assets/components/createAll/Launchpad/Pega_DXIL_MyDetails/demo.stories.tsx +47 -13
  42. package/tests/assets/components/createAll/Launchpad/Pega_DXIL_MyDetails/index.tsx +2 -2
  43. package/tests/assets/components/createAll/Launchpad/Pega_DXIL_MyDetails/mock.ts +69 -10
  44. package/tests/assets/components/createAll/Launchpad/Pega_DXIL_MyForm/index.tsx +1 -1
  45. package/tests/assets/components/createAll/Launchpad/Pega_DXIL_MyIconButtonURL/demo.stories.tsx +5 -0
  46. package/tests/assets/components/createAll/Launchpad/Pega_DXIL_MyIconButtonURL/index.tsx +30 -17
  47. package/tests/assets/components/createAll/Launchpad/Pega_DXIL_MyPageWidget/demo.stories.tsx +30 -22
  48. package/tests/assets/components/createAll/Launchpad/Pega_DXIL_MyPageWidget/index.tsx +34 -20
  49. package/tests/assets/components/createAll/Launchpad/Pega_DXIL_MyTwoColumnDetails/Avatar.tsx +78 -0
  50. package/tests/assets/components/createAll/Launchpad/Pega_DXIL_MyTwoColumnDetails/Operator.tsx +215 -0
  51. package/tests/assets/components/createAll/Launchpad/Pega_DXIL_MyTwoColumnDetails/demo.stories.tsx +46 -12
  52. package/tests/assets/components/createAll/Launchpad/Pega_DXIL_MyTwoColumnDetails/index.tsx +2 -2
  53. package/tests/assets/components/createAll/Launchpad/Pega_DXIL_MyTwoColumnDetails/mock.ts +55 -0
  54. package/tests/assets/components/createAll/Launchpad/Pega_DXIL_MyTwoColumnForm/index.tsx +2 -2
@@ -1,5 +1,4 @@
1
1
 
2
-
3
2
  // @ts-nocheck
4
3
  export const pyReviewRaw = {
5
4
  name: 'pyReview',
@@ -18,6 +17,7 @@ export const pyReviewRaw = {
18
17
  value: '@P .pyStatusWork',
19
18
  label: '@L Work Status',
20
19
  hideLabel: true,
20
+ displayMode: 'STACKED_LARGE_VAL',
21
21
  displayAsStatus: true,
22
22
  key: 'pyStatusWork'
23
23
  }
@@ -28,6 +28,7 @@ export const pyReviewRaw = {
28
28
  value: '@P .pyID',
29
29
  label: '@L Case ID',
30
30
  hideLabel: true,
31
+ displayMode: 'STACKED_LARGE_VAL',
31
32
  key: 'pyID'
32
33
  }
33
34
  },
@@ -37,6 +38,7 @@ export const pyReviewRaw = {
37
38
  value: '@P .pxCreateDateTime',
38
39
  label: '@L Create date/time',
39
40
  hideLabel: true,
41
+ displayMode: 'STACKED_LARGE_VAL',
40
42
  key: 'pxCreateDateTime'
41
43
  }
42
44
  },
@@ -47,6 +49,7 @@ export const pyReviewRaw = {
47
49
  hideLabel: true,
48
50
  value: '@USER .pxCreateOperator',
49
51
  placeholder: 'Select...',
52
+ displayMode: 'STACKED_LARGE_VAL',
50
53
  key: 'pxCreateOperator'
51
54
  }
52
55
  }
@@ -66,6 +69,7 @@ export const pyReviewRaw = {
66
69
  {
67
70
  name: 'A',
68
71
  type: 'Region',
72
+ key: 'A',
69
73
  getPConnect: () => {
70
74
  return {
71
75
  getRawMetadata: () => {
@@ -78,17 +82,17 @@ export const pyReviewRaw = {
78
82
  type: 'DateTime',
79
83
  config: {
80
84
  value: '@P .pySLADeadline',
81
- label: '@L SLA Deadline'
82
- },
83
- key: '1'
85
+ label: '@L SLA Deadline',
86
+ key: 'pySLADeadline'
87
+ }
84
88
  },
85
89
  {
86
90
  type: 'DateTime',
87
91
  config: {
88
92
  value: '@P .pySLAGoal',
89
- label: '@L SLA Goal'
90
- },
91
- key: '2'
93
+ label: '@L SLA Goal',
94
+ key: 'pySLAGoal'
95
+ }
92
96
  },
93
97
  {
94
98
  type: 'RadioButtons',
@@ -96,9 +100,9 @@ export const pyReviewRaw = {
96
100
  value: '@P .pySLAStartTime',
97
101
  label: '@L SLA Start Time',
98
102
  listType: 'associated',
99
- datasource: '@ASSOCIATED .pySLAStartTime'
100
- },
101
- key: '3'
103
+ datasource: '@ASSOCIATED .pySLAStartTime',
104
+ key: 'pySLAStartTime'
105
+ }
102
106
  }
103
107
  ]
104
108
  }
@@ -189,3 +193,58 @@ export const regionChildrenResolved = [
189
193
  key: 'SLA Start Time'
190
194
  }
191
195
  ];
196
+
197
+ export const operatorDetails = {
198
+ data: {
199
+ pzLoadTime: 'January 18, 2023 10:33:19 AM EST',
200
+ pzPageNameHash: '_pa1519192551088960pz',
201
+ pyOperatorInfo: {
202
+ pyUserName: 'french DigV2',
203
+ pyPosition: '',
204
+ pyImageInsKey: '',
205
+ pySkills: [
206
+ {
207
+ pySkillName: '',
208
+ pzIndexOwnerKey: 'DATA-ADMIN-OPERATOR-ID FRENCHTEST.DIGV2',
209
+ pySkillRating: 0
210
+ }
211
+ ],
212
+ pyReportToUserName: '',
213
+ pyReportTo: '',
214
+ pyOrganization: 'DXIL',
215
+ pyTitle: '',
216
+ pyLabel: 'frenchTest.DigV2',
217
+ pyEmailAddress: 'User@DigV2',
218
+ pyTelephone: ''
219
+ }
220
+ },
221
+ status: 200,
222
+ statusText: '',
223
+ headers: {
224
+ 'content-length': '435',
225
+ 'content-type': 'application/json;charset=UTF-8'
226
+ },
227
+ request: {}
228
+ };
229
+
230
+ export const configProps = {
231
+ label: 'Create operator',
232
+ createLabel: 'Created',
233
+ updateLabel: 'Updated',
234
+ updateDateTime: '2023-01-16T14:53:33.280Z',
235
+ createDateTime: '2023-01-16T14:53:33.198Z',
236
+ updateOperator: {
237
+ userId: 'admin@mediaco',
238
+ userName: 'admin'
239
+ },
240
+ createOperator: {
241
+ userId: 'admin@mediaco',
242
+ userName: 'admin'
243
+ },
244
+ resolveLabel: '',
245
+ resolveOperator: '',
246
+ resolveDateTime: '',
247
+ hideLabel: true,
248
+ key: '_532zx1dah',
249
+ displayMode: 'LABELS_LEFT'
250
+ };
@@ -38,7 +38,7 @@ function PegaDxilMyForm(props: PegaDxilMyFormProps) {
38
38
  {children.map((child: any, i: number) => (
39
39
  <Flex
40
40
  // @ts-ignore
41
- container={{ direction: 'column', alignItems: 'normal', colGap: 0, rowGap: 1.5 }}
41
+ container={{ direction: 'column', alignItems: 'normal', colGap: 1, rowGap: 1.5 }}
42
42
  key={`r-${i + 1}`}
43
43
  >
44
44
  <DetailsRender child={child} />
@@ -38,6 +38,11 @@ const countrylistData = {
38
38
 
39
39
  window.PCore.getDataPageUtils = () => {
40
40
  return {
41
+ getData: () => {
42
+ return new Promise(resolve => {
43
+ resolve(countrylistData);
44
+ });
45
+ },
41
46
  getDataAsync: () => {
42
47
  return new Promise(resolve => {
43
48
  resolve(countrylistData);
@@ -60,10 +60,13 @@ export const textFormatter = (value: string) => {
60
60
  // any default values in config.pros should be set in defaultProps at bottom of this file
61
61
  function PegaDxilMyIconButtonUrl(props: PegaDxilMyIconButtonUrlProps) {
62
62
  const { value, displayMode, getPConnect, testId } = props;
63
- const [statelist, setStatelist] = useState([]);
63
+ const [countrylist, setCountrylist] = useState([]);
64
64
  const [showTable, setShowTable] = useState(false);
65
+ const [isLoading, setIsLoading] = useState(true);
65
66
  const [validUrl, setValidUrl] = useState('about:blank');
66
67
  const PConnect = getPConnect();
68
+ const dataViewName = 'CountryList';
69
+ const context = PConnect.getContextName();
67
70
 
68
71
  // IMPORTANT: need to register icons used in camel case
69
72
  registerIcon(listNumber, arrowRight, globe);
@@ -108,8 +111,6 @@ function PegaDxilMyIconButtonUrl(props: PegaDxilMyIconButtonUrlProps) {
108
111
  // get data from a data page and a PConnect function
109
112
  // to get getContextName
110
113
  useEffect(() => {
111
- const dataViewName = 'CountryList';
112
- const context = PConnect.getContextName();
113
114
  const params = { };
114
115
 
115
116
  // only retrieve table data if table is shown
@@ -118,25 +119,35 @@ function PegaDxilMyIconButtonUrl(props: PegaDxilMyIconButtonUrlProps) {
118
119
  .getDataAsync(dataViewName, context, params, null, null)
119
120
  // @ts-ignore
120
121
  .then((response: any) => {
122
+ setIsLoading(false);
121
123
  // table requires an index or will get setExtraStackFrame error
122
- setStatelist(
123
- response.data.map((entry: any, index: number) => {
124
- // mapping the data into the column names
125
- // MUST have an id/index or will get a setExtraStackFrame error
126
- // put a key in the table
127
- return {
128
- countryName: entry.Name,
129
- shortName: entry.ShortName,
130
- id: index
131
- };
132
- })
133
- );
124
+ if (response.data !== null) {
125
+ setCountrylist(
126
+ response.data.map((entry: any, index: number) => {
127
+ // mapping the data into the column names
128
+ // MUST have an id/index or will get a setExtraStackFrame error
129
+ // put a key in the table
130
+ return {
131
+ countryName: entry.Name,
132
+ shortName: entry.ShortName,
133
+ id: index
134
+ };
135
+ })
136
+ );
137
+ }
138
+ else {
139
+ setCountrylist([]);
140
+ setIsLoading(false);
141
+ }
142
+
134
143
  })
135
144
  .catch((error: any) => {
145
+ setCountrylist([]);
146
+ setIsLoading(false);
136
147
  console.log(error);
137
148
  });
138
149
  }
139
- }, [PConnect, showTable]);
150
+ }, [context, showTable]);
140
151
 
141
152
  // when DISPLAY_ONLY, in this example we will just show the URL.
142
153
  if (displayMode === 'DISPLAY_ONLY') {
@@ -189,7 +200,9 @@ function PegaDxilMyIconButtonUrl(props: PegaDxilMyIconButtonUrlProps) {
189
200
  <Table
190
201
  title={PConnect.getLocalizedValue('State list', '', '')}
191
202
  columns={columns}
192
- data={statelist}
203
+ data={countrylist}
204
+ loading={isLoading}
205
+ loadingMessage={PConnect.getLocalizedValue('Loading country list', '', '')}
193
206
  />
194
207
  )}
195
208
  </StyledPegaDxilMyIconButtonUrlWrapper>
@@ -22,30 +22,38 @@ if (!window.PCore) {
22
22
  }
23
23
 
24
24
  const worklistData = {
25
- data: [
26
- {
27
- CaseName: 'Loan',
28
- BusinessID: ' A-8002',
29
- ProcessName: 'New',
30
- TaskName: 'Details'
31
- },
32
- {
33
- CaseName: 'Loan',
34
- BusinessID: ' A-7001',
35
- ProcessName: 'Open',
36
- TaskName: 'Info'
37
- },
38
- {
39
- CaseName: 'Loan',
40
- BusinessID: ' A-9000',
41
- ProcessName: 'Open',
42
- TaskName: 'Amount'
43
- }
44
- ]
25
+ data: {
26
+ data: [
27
+ {
28
+ CaseName: 'Loan',
29
+ BusinessID: ' A-8002',
30
+ ProcessName: 'New',
31
+ TaskName: 'Details'
32
+ },
33
+ {
34
+ CaseName: 'Loan',
35
+ BusinessID: ' A-7001',
36
+ ProcessName: 'Open',
37
+ TaskName: 'Info'
38
+ },
39
+ {
40
+ CaseName: 'Loan',
41
+ BusinessID: ' A-9000',
42
+ ProcessName: 'Open',
43
+ TaskName: 'Amount'
44
+ }
45
+ ]
46
+ }
47
+
45
48
  };
46
49
 
47
- window.PCore.getDataPageUtils = () => {
50
+ window.PCore.getDataApiUtils = () => {
48
51
  return {
52
+ getData: () => {
53
+ return new Promise(resolve => {
54
+ resolve(worklistData);
55
+ });
56
+ },
49
57
  getDataAsync: () => {
50
58
  return new Promise(resolve => {
51
59
  resolve(worklistData);
@@ -59,7 +67,7 @@ window.PCore.getDataPageUtils = () => {
59
67
  export const BasePegaDxilMyPageWidget: Story = args => {
60
68
 
61
69
  const props = {
62
- image: configProps.image,
70
+ ...configProps,
63
71
  getPConnect: () => {
64
72
  return {
65
73
  getValue: value => {
@@ -21,7 +21,11 @@ function PegaDxilMyPageWidget(props: PegaDxilMyPageWidgetProps) {
21
21
 
22
22
  const { header, description, datasource = [], whatsnewlink, image, getPConnect } = props;
23
23
  const [worklist, setWorklist] = useState([]);
24
+ const [isLoading, setIsLoading] = useState(true);
24
25
  const PConnect = getPConnect();
26
+ const dataViewName = 'MyWorkList';
27
+ const context = PConnect.getContextName();
28
+
25
29
  let details = [];
26
30
  // @ts-ignore
27
31
  if (datasource && datasource.source) {
@@ -44,33 +48,41 @@ function PegaDxilMyPageWidget(props: PegaDxilMyPageWidgetProps) {
44
48
  // get data from a data page and a PConnect function
45
49
  // to get getContextName
46
50
  useEffect(() => {
47
- const dataViewName = 'MyWorkList';
48
- const context = PConnect.getContextName();
49
51
 
50
- PCore.getDataPageUtils()
51
- .getDataAsync(dataViewName, context, {}, null, null)
52
+ PCore.getDataApiUtils()
53
+ .getData(dataViewName, {}, context)
52
54
  // @ts-ignore
53
55
  .then((response: any) => {
54
- // table requires an index or will get setExtraStackFrame error
55
- setWorklist(
56
- response.data.map((entry: any, index: number) => {
57
- // mapping the data into the column names
58
- // MUST have an id/index or will get a setExtraStackFrame error
59
- // put a key in the table
60
- return {
61
- caseType: entry.CaseName,
62
- insKey: entry.BusinessID,
63
- status: entry.ProcessName,
64
- stage: entry.TaskName,
65
- id: index
66
- };
67
- })
68
- );
56
+ setIsLoading(false);
57
+ if (response.data.data !== null) {
58
+ // table requires an index or will get setExtraStackFrame error
59
+ setWorklist(
60
+ response.data.data.map((entry: any, index: number) => {
61
+ // mapping the data into the column names
62
+ // MUST have an id/index or will get a setExtraStackFrame error
63
+ // put a key in the table
64
+ return {
65
+ caseType: entry.CaseName,
66
+ insKey: entry.BusinessID,
67
+ status: entry.ProcessName,
68
+ stage: entry.TaskName,
69
+ id: index
70
+ };
71
+ })
72
+ );
73
+ }
74
+ else {
75
+ setWorklist([]);
76
+ setIsLoading(false);
77
+ }
78
+
69
79
  })
70
80
  .catch((error: any) => {
81
+ setWorklist([]);
82
+ setIsLoading(false);
71
83
  console.log(error);
72
84
  });
73
- }, [PConnect]);
85
+ }, [context]);
74
86
 
75
87
  return (
76
88
  <StyledPegaDxilMyPageWidgetWrapper>
@@ -86,6 +98,8 @@ function PegaDxilMyPageWidget(props: PegaDxilMyPageWidgetProps) {
86
98
  title={PConnect.getLocalizedValue('Work list', '', '')}
87
99
  columns={columns}
88
100
  data={worklist}
101
+ loading={isLoading}
102
+ loadingMessage={PConnect.getLocalizedValue('Loading Work list', '', '')}
89
103
  />
90
104
  </StyledPegaDxilMyPageWidgetWrapper>
91
105
  );
@@ -0,0 +1,78 @@
1
+ /* eslint-disable react-hooks/rules-of-hooks */
2
+ import React from 'react';
3
+ import { useEffect, useState } from 'react';
4
+ import { Avatar as CosmosAvatar, withConfiguration } from '@pega/cosmos-react-core';
5
+ import type { PConnFieldProps } from './PConnProps';
6
+
7
+
8
+ // interface for props
9
+ interface PegaDxilMyTwoColumnDetailsAvatarProps extends PConnFieldProps {
10
+ // If any, enter additional props that only exist on TextInput here
11
+ metaObj: any;
12
+ showStatus: boolean;
13
+
14
+ }
15
+
16
+ function Avatar(props: PegaDxilMyTwoColumnDetailsAvatarProps) {
17
+ const { metaObj, showStatus = false } = props;
18
+ const [imageBlobUrl, setImageBlobUrl] = useState(null);
19
+ let userName: string;
20
+ let userIdentifier: string;
21
+
22
+ // TODO Below if conditions can be removed once we have apis to get worklist/mywork info
23
+ // This is non CaseView case (Dashboard, MyWork etc)
24
+ if (!metaObj) {
25
+ userName = PCore.getEnvironmentInfo().getOperatorName();
26
+ userIdentifier = PCore.getEnvironmentInfo().getOperatorIdentifier();
27
+ } else {
28
+ userName = metaObj.name;
29
+ userIdentifier = metaObj.ID;
30
+ }
31
+ if (!userName && userIdentifier) {
32
+ userName = userIdentifier;
33
+ }
34
+
35
+ useEffect(() => {
36
+ const imageKey = !metaObj ? PCore.getEnvironmentInfo().getOperatorImageInsKey() : metaObj.image;
37
+ if (imageKey) {
38
+ PCore.getAssetLoader()
39
+ .getSvcImage(imageKey)
40
+ .then((blob) => window.URL.createObjectURL(blob))
41
+ .then((imagePath) => setImageBlobUrl(imagePath as React.SetStateAction<any>));
42
+ }
43
+ }, [metaObj]);
44
+
45
+ if (showStatus) {
46
+ const currentState = PCore.getMessagingServiceManager().getUserPresence().getUserState(userIdentifier);
47
+ const [userState, setUserState]: any = useState(currentState === 'online' ? 'active' : 'inactive');
48
+
49
+ // @ts-ignore
50
+ const handleUserStateChange = ({ state }) => {
51
+ setUserState(state === 'online' ? 'active' : 'inactive');
52
+ };
53
+
54
+ useEffect(() => {
55
+ const subId = PCore.getMessagingServiceManager()
56
+ .getUserPresence()
57
+ // @ts-ignore
58
+ .subscribe(userIdentifier, handleUserStateChange);
59
+
60
+ return function cleanup() {
61
+ PCore.getMessagingServiceManager().getUserPresence().unsubscribe(userIdentifier, subId);
62
+ };
63
+ }, [userIdentifier, handleUserStateChange]);
64
+ // @ts-ignore
65
+ return <CosmosAvatar name={userName} imageSrc={imageBlobUrl as React.SetStateAction<any>} status={userState} />;
66
+ }
67
+
68
+ // Do not render when userName does not exists
69
+ // TODO : In CNR case, pxRequestor is not available, please remove this condition once it populates
70
+ if (!userName) {
71
+ return null;
72
+ }
73
+
74
+ return <CosmosAvatar name={userName} imageSrc={imageBlobUrl as React.SetStateAction<any>} />;
75
+ }
76
+
77
+
78
+ export default withConfiguration(Avatar);
@@ -0,0 +1,215 @@
1
+ // @ts-nocheck
2
+ import { useState, useEffect, Fragment } from 'react';
3
+ import {
4
+ Link,
5
+ Button,
6
+ Popover,
7
+ useOuterEvent,
8
+ useElement,
9
+ Progress,
10
+ FormField,
11
+ useTheme,
12
+ withConfiguration
13
+ } from '@pega/cosmos-react-core';
14
+ import { Glimpse } from '@pega/cosmos-react-work';
15
+ import { EmailDisplay } from '@pega/cosmos-react-core';
16
+
17
+ import type { PConnFieldProps } from './PConnProps';
18
+
19
+ import Avatar from './Avatar';
20
+
21
+
22
+ // interface for props
23
+ interface PegaDxilMyTwoColumnDetailsOperatorProps extends PConnFieldProps {
24
+ // If any, enter additional props that only exist on TextInput here
25
+ name: string;
26
+ id: string;
27
+ label: string;
28
+ metaObj: any;
29
+ externalUser: any;
30
+ }
31
+
32
+ let pTarget = null;
33
+
34
+ function Operator(props: PegaDxilMyTwoColumnDetailsOperatorProps) {
35
+ const { id, name, label, testId, helperText, externalUser, metaObj } = props;
36
+ const [isOpen, setIsOpen] = useState(false);
37
+ const [isLoading, setIsLoading] = useState(true);
38
+ const [popoverEl, setPopoverEl] = useElement(null);
39
+ const [popoverContent, setpopoverContent] = useState(null);
40
+ const theme: any = useTheme();
41
+
42
+ /* If the id has changed, we need to reset the popover */
43
+ useEffect(() => {
44
+ pTarget = null;
45
+ }, [id]);
46
+
47
+
48
+
49
+ const OperatorPreview = () => {
50
+ const localizedVal = PCore.getLocaleUtils().getLocaleValue;
51
+ const localeCategory = 'Operator';
52
+ setpopoverContent(
53
+ <Progress variant='ring' message={localizedVal('Loading operator...', localeCategory)} placement='local' />
54
+ );
55
+ if (externalUser && externalUser.classID !== 'Data-Party-Operator') {
56
+ const fields = [
57
+ {
58
+ id: 'pyFirstName',
59
+ name: localizedVal('Name', localeCategory),
60
+ value: externalUser.name
61
+ },
62
+ {
63
+ id: 'pyEmail1',
64
+ name: localizedVal('Email', localeCategory),
65
+ value:
66
+ externalUser.email !== '' ? <Link href={`mailto:${externalUser.email}`}>{externalUser.email}</Link> : ''
67
+ },
68
+ {
69
+ id: 'pyPhoneNumber',
70
+ name: localizedVal('Phone', localeCategory),
71
+ value: externalUser.phone !== '' ? <Link href={`tel:${externalUser.phone}`}>{externalUser.phone}</Link> : ''
72
+ }
73
+ ];
74
+ setIsLoading(false);
75
+ setpopoverContent(
76
+ <Glimpse
77
+ visual={
78
+ <Avatar
79
+ metaObj={{
80
+ name: externalUser.name
81
+ }}
82
+ />
83
+ }
84
+ primary={externalUser.name}
85
+ secondary={[externalUser.position]}
86
+ fields={fields}
87
+ target={pTarget}
88
+ />
89
+ );
90
+ } else {
91
+ return PCore.getUserApi()
92
+ .getOperatorDetails(id, true)
93
+ .then(res => {
94
+ if (res.data?.pyOperatorInfo) {
95
+ const fields = [];
96
+ const data = res.data;
97
+ if (data.pyOperatorInfo && data.pyOperatorInfo.pyUserName) {
98
+ fields.push({
99
+ id: 'Name',
100
+ name: localizedVal('Name', localeCategory),
101
+ value: data.pyOperatorInfo.pyUserName
102
+ });
103
+ }
104
+ if (data.pyOperatorInfo && data.pyOperatorInfo.pyEmailAddress) {
105
+ fields.push({
106
+ id: 'Email',
107
+ name: localizedVal('Email address', localeCategory),
108
+ value: <EmailDisplay value={data.pyOperatorInfo.pyEmailAddress} />
109
+ });
110
+ }
111
+ const opAvatar = (
112
+ <Avatar
113
+ metaObj={{
114
+ image: '',
115
+ name: data.pyOperatorInfo.pyUserName
116
+ }}
117
+ />
118
+ );
119
+
120
+ setIsLoading(false);
121
+ setpopoverContent(
122
+ <Glimpse
123
+ heading={{
124
+ primary: data.pyOperatorInfo.pyUserName,
125
+ secondary: data.pyOperatorInfo.pyEmailAddress,
126
+ visual: opAvatar
127
+ }}
128
+ fields={fields}
129
+ target={pTarget}
130
+ onDismiss={() => {pTarget = null;}}
131
+ />
132
+ );
133
+ }
134
+ });
135
+ }
136
+ };
137
+
138
+
139
+ const clickAction = (e: any) => {
140
+
141
+ setIsOpen(!isOpen);
142
+ if (pTarget === null) {
143
+ pTarget = e.currentTarget;
144
+ OperatorPreview();
145
+ }
146
+ };
147
+
148
+ const hidePopover = () => {
149
+ if (isOpen) {
150
+ setIsOpen(false);
151
+ }
152
+ };
153
+
154
+ useOuterEvent('mousedown', [popoverEl], hidePopover); // Call the method on clicking outside these elements
155
+
156
+ const hideOnEscape = (e: any) => {
157
+ if (e.key === 'Escape') hidePopover(); // Call the method when Escape key is pressed
158
+ };
159
+
160
+ const comp = (
161
+ <Fragment>
162
+ {metaObj ? (
163
+ <Button
164
+ variant='text'
165
+ aria-haspopup
166
+ aria-expanded={isOpen}
167
+ onClick={clickAction}
168
+ onKeyDown={hideOnEscape}
169
+ data-test-id={testId}
170
+ style={label !== null ? { width: 'max-content', height: theme.components.input.height } : undefined}
171
+ >
172
+ <Avatar {...props} />
173
+ </Button>
174
+ ) : (
175
+ <Button
176
+ variant='link'
177
+ aria-haspopup
178
+ aria-expanded={isOpen}
179
+ onClick={clickAction}
180
+ onKeyDown={hideOnEscape}
181
+ data-test-id={testId}
182
+ style={label !== null ? { width: 'max-content', height: theme.components.input.height } : undefined}
183
+ >
184
+ {name}
185
+ </Button>
186
+ )}
187
+
188
+ {isOpen && (
189
+ <Popover
190
+ ref={setPopoverEl}
191
+ groupId='operator'
192
+ target={pTarget}
193
+ placement='bottom-start'
194
+ style={isLoading ? { position: 'relative', width: '10rem', minHeight: '4rem' } : undefined}
195
+ strategy='fixed'
196
+ >
197
+ {popoverContent}
198
+ </Popover>
199
+ )}
200
+ </Fragment>
201
+ );
202
+
203
+ if (label !== null) {
204
+ return (
205
+ <FormField label={label} info={helperText}>
206
+ {comp}
207
+ </FormField>
208
+ );
209
+ }
210
+
211
+ return comp;
212
+ };
213
+
214
+
215
+ export default withConfiguration(Operator);