@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.
- package/package.json +1 -1
- package/src/tasks/create/templates/Constellation/Field/Icon-Button-URL/demo.stories.tsx.mustache +5 -0
- package/src/tasks/create/templates/Constellation/Field/Icon-Button-URL/index.tsx.mustache +26 -15
- package/src/tasks/create/templates/Constellation/Template/DETAILS/Avatar.tsx.mustache +78 -0
- package/src/tasks/create/templates/Constellation/Template/DETAILS/Operator.tsx.mustache +218 -0
- package/src/tasks/create/templates/Constellation/Template/DETAILS/demo.stories.tsx.mustache +47 -13
- package/src/tasks/create/templates/Constellation/Template/DETAILS/index.tsx.mustache +2 -2
- package/src/tasks/create/templates/Constellation/Template/DETAILS/mock.ts.mustache +69 -10
- package/src/tasks/create/templates/Constellation/Template/DETAILS-region/Avatar.tsx.mustache +78 -0
- package/src/tasks/create/templates/Constellation/Template/DETAILS-region/Operator.tsx.mustache +218 -0
- package/src/tasks/create/templates/Constellation/Template/DETAILS-region/demo.stories.tsx.mustache +46 -12
- package/src/tasks/create/templates/Constellation/Template/DETAILS-region/index.tsx.mustache +2 -2
- package/src/tasks/create/templates/Constellation/Template/DETAILS-region/mock.ts.mustache +55 -0
- package/src/tasks/create/templates/Constellation/Template/FORM/index.tsx.mustache +1 -1
- package/src/tasks/create/templates/Constellation/Template/FORM-region/index.tsx.mustache +2 -2
- package/src/tasks/create/templates/Constellation/Widget/PAGE/demo.stories.tsx.mustache +29 -22
- package/src/tasks/create/templates/Constellation/Widget/PAGE/index.tsx.mustache +34 -20
- package/src/tasks/create/templates/Launchpad/Field/Icon-Button-URL/demo.stories.tsx.mustache +5 -0
- package/src/tasks/create/templates/Launchpad/Field/Icon-Button-URL/index.tsx.mustache +30 -17
- package/src/tasks/create/templates/Launchpad/Widget/PAGE/demo.stories.tsx.mustache +30 -22
- package/src/tasks/create/templates/Launchpad/Widget/PAGE/index.tsx.mustache +34 -20
- package/src/tasks/init/template/package.json.mustache +1 -1
- package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyDetails/Avatar.tsx +78 -0
- package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyDetails/Operator.tsx +215 -0
- package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyDetails/demo.stories.tsx +47 -13
- package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyDetails/index.tsx +2 -2
- package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyDetails/mock.ts +69 -10
- package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyForm/index.tsx +1 -1
- package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyIconButtonURL/demo.stories.tsx +5 -0
- package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyIconButtonURL/index.tsx +26 -15
- package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyPageWidget/demo.stories.tsx +29 -22
- package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyPageWidget/index.tsx +34 -20
- package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyTwoColumnDetails/Avatar.tsx +78 -0
- package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyTwoColumnDetails/Operator.tsx +215 -0
- package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyTwoColumnDetails/demo.stories.tsx +46 -12
- package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyTwoColumnDetails/index.tsx +2 -2
- package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyTwoColumnDetails/mock.ts +55 -0
- package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyTwoColumnForm/index.tsx +2 -2
- package/tests/assets/components/createAll/Launchpad/Pega_DXIL_MyDetails/Avatar.tsx +78 -0
- package/tests/assets/components/createAll/Launchpad/Pega_DXIL_MyDetails/Operator.tsx +215 -0
- package/tests/assets/components/createAll/Launchpad/Pega_DXIL_MyDetails/demo.stories.tsx +47 -13
- package/tests/assets/components/createAll/Launchpad/Pega_DXIL_MyDetails/index.tsx +2 -2
- package/tests/assets/components/createAll/Launchpad/Pega_DXIL_MyDetails/mock.ts +69 -10
- package/tests/assets/components/createAll/Launchpad/Pega_DXIL_MyForm/index.tsx +1 -1
- package/tests/assets/components/createAll/Launchpad/Pega_DXIL_MyIconButtonURL/demo.stories.tsx +5 -0
- package/tests/assets/components/createAll/Launchpad/Pega_DXIL_MyIconButtonURL/index.tsx +30 -17
- package/tests/assets/components/createAll/Launchpad/Pega_DXIL_MyPageWidget/demo.stories.tsx +30 -22
- package/tests/assets/components/createAll/Launchpad/Pega_DXIL_MyPageWidget/index.tsx +34 -20
- package/tests/assets/components/createAll/Launchpad/Pega_DXIL_MyTwoColumnDetails/Avatar.tsx +78 -0
- package/tests/assets/components/createAll/Launchpad/Pega_DXIL_MyTwoColumnDetails/Operator.tsx +215 -0
- package/tests/assets/components/createAll/Launchpad/Pega_DXIL_MyTwoColumnDetails/demo.stories.tsx +46 -12
- package/tests/assets/components/createAll/Launchpad/Pega_DXIL_MyTwoColumnDetails/index.tsx +2 -2
- package/tests/assets/components/createAll/Launchpad/Pega_DXIL_MyTwoColumnDetails/mock.ts +55 -0
- package/tests/assets/components/createAll/Launchpad/Pega_DXIL_MyTwoColumnForm/index.tsx +2 -2
|
@@ -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 {{COMPONENT_CLASS_NAME}}(props: {{COMPONENT_CLASS_NAME}}Props) {
|
|
62
62
|
const { value, displayMode, getPConnect, testId } = props;
|
|
63
|
-
const [
|
|
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 {{COMPONENT_CLASS_NAME}}(props: {{COMPONENT_CLASS_NAME}}Props) {
|
|
|
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 {{COMPONENT_CLASS_NAME}}(props: {{COMPONENT_CLASS_NAME}}Props) {
|
|
|
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
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
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
|
-
}, [
|
|
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') {
|
|
@@ -191,7 +202,9 @@ function {{COMPONENT_CLASS_NAME}}(props: {{COMPONENT_CLASS_NAME}}Props) {
|
|
|
191
202
|
<Table
|
|
192
203
|
title={PConnect.getLocalizedValue('State list', '', '')}
|
|
193
204
|
columns={columns}
|
|
194
|
-
data={
|
|
205
|
+
data={countrylist}
|
|
206
|
+
loading={isLoading}
|
|
207
|
+
loadingMessage={PConnect.getLocalizedValue('Loading country list', '', '')}
|
|
195
208
|
/>
|
|
196
209
|
)}
|
|
197
210
|
<%={{ }}=%> {{! revert delimiters for mustache }}
|
|
@@ -22,30 +22,38 @@ if (!window.PCore) {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
const worklistData = {
|
|
25
|
-
data:
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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.
|
|
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 Base{{COMPONENT_CLASS_NAME}}: Story = args => {
|
|
60
68
|
|
|
61
69
|
const props = {
|
|
62
|
-
|
|
70
|
+
...configProps,
|
|
63
71
|
getPConnect: () => {
|
|
64
72
|
return {
|
|
65
73
|
getValue: value => {
|
|
@@ -21,7 +21,11 @@ function {{COMPONENT_CLASS_NAME}}(props: {{COMPONENT_CLASS_NAME}}Props) {
|
|
|
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 {{COMPONENT_CLASS_NAME}}(props: {{COMPONENT_CLASS_NAME}}Props) {
|
|
|
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.
|
|
51
|
-
.
|
|
52
|
+
PCore.getDataApiUtils()
|
|
53
|
+
.getData(dataViewName, {}, context)
|
|
52
54
|
// @ts-ignore
|
|
53
55
|
.then((response: any) => {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
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
|
-
}, [
|
|
85
|
+
}, [context]);
|
|
74
86
|
|
|
75
87
|
return (
|
|
76
88
|
<Styled{{COMPONENT_CLASS_NAME}}Wrapper>
|
|
@@ -86,6 +98,8 @@ function {{COMPONENT_CLASS_NAME}}(props: {{COMPONENT_CLASS_NAME}}Props) {
|
|
|
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
|
</Styled{{COMPONENT_CLASS_NAME}}Wrapper>
|
|
91
105
|
);
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
71
|
"@pega/configs": "^0.6.0",
|
|
72
|
-
"@pega/custom-dx-components": "0.24.
|
|
72
|
+
"@pega/custom-dx-components": "0.24.16",
|
|
73
73
|
"@pega/pcore-pconnect-typedefs": "~3.0.0",
|
|
74
74
|
"@storybook/addon-actions": "^7.6.7",
|
|
75
75
|
"@storybook/addon-essentials": "^7.6.7",
|
|
@@ -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 PegaDxilMyDetailsAvatarProps 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: PegaDxilMyDetailsAvatarProps) {
|
|
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 PegaDxilMyDetailsOperatorProps 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: PegaDxilMyDetailsOperatorProps) {
|
|
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);
|
package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyDetails/demo.stories.tsx
CHANGED
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
import type { Meta, StoryObj } from '@storybook/react';
|
|
5
5
|
import { Text, FieldValueList, Button, DateTimeDisplay, useTheme } from '@pega/cosmos-react-core';
|
|
6
6
|
import PegaDxilMyDetails from './index';
|
|
7
|
-
import { pyReviewRaw, pyReviewResolved, regionChildrenResolved } from './mock';
|
|
7
|
+
import { pyReviewRaw, pyReviewResolved, regionChildrenResolved, operatorDetails, configProps } from './mock';
|
|
8
8
|
import StatusWorkRenderer from './StatusWork';
|
|
9
|
-
|
|
9
|
+
import Operator from './Operator';
|
|
10
10
|
|
|
11
11
|
const meta: Meta<typeof PegaDxilMyDetails> = {
|
|
12
12
|
title: 'PegaDxilMyDetails',
|
|
@@ -20,10 +20,33 @@ const meta: Meta<typeof PegaDxilMyDetails> = {
|
|
|
20
20
|
export default meta;
|
|
21
21
|
type Story = StoryObj<typeof PegaDxilMyDetails>;
|
|
22
22
|
|
|
23
|
+
if (!window.PCore) {
|
|
24
|
+
window.PCore = {};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
window.PCore.getLocaleUtils = () => {
|
|
28
|
+
return {
|
|
29
|
+
getLocaleValue: value => {
|
|
30
|
+
return value;
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
window.PCore.getUserApi = () => {
|
|
36
|
+
return {
|
|
37
|
+
getOperatorDetails: () => {
|
|
38
|
+
return new Promise(resolve => {
|
|
39
|
+
resolve(operatorDetails);
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
|
|
23
45
|
const Region = props => {
|
|
24
46
|
return <></>;
|
|
25
47
|
};
|
|
26
48
|
|
|
49
|
+
|
|
27
50
|
const renderField = resolvedProps => {
|
|
28
51
|
const {
|
|
29
52
|
displayAsStatus = false,
|
|
@@ -59,19 +82,30 @@ const renderField = resolvedProps => {
|
|
|
59
82
|
|
|
60
83
|
if (displayAsStatus === true) val = <StatusWorkRenderer value={value} key={key} />;
|
|
61
84
|
|
|
85
|
+
const [_label] =
|
|
86
|
+
label === 'Create operator'
|
|
87
|
+
? [configProps.createLabel, configProps.createOperator, configProps.createDateTime]
|
|
88
|
+
: label === 'Update operator'
|
|
89
|
+
? [configProps.updateLabel, configProps.updateOperator, configProps.updateDateTime]
|
|
90
|
+
: [configProps.resolveLabel, configProps.resolveOperator, configProps.resolveDateTime];
|
|
91
|
+
|
|
62
92
|
if (label === 'Create Operator')
|
|
63
93
|
val = (
|
|
64
|
-
<
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
{
|
|
74
|
-
|
|
94
|
+
<Operator
|
|
95
|
+
label={configProps.hideLabel ? '' : _label}
|
|
96
|
+
name={configProps.createOperator.userName}
|
|
97
|
+
id={configProps.createOperator.userId}
|
|
98
|
+
value={undefined}
|
|
99
|
+
validatemessage=''
|
|
100
|
+
hideLabel={false}
|
|
101
|
+
readOnly={false}
|
|
102
|
+
required={false}
|
|
103
|
+
disabled={false}
|
|
104
|
+
externalUser={undefined}
|
|
105
|
+
metaObj={undefined}
|
|
106
|
+
testId=''
|
|
107
|
+
helperText=''
|
|
108
|
+
/>
|
|
75
109
|
);
|
|
76
110
|
|
|
77
111
|
if (variant === 'inline') {
|
|
@@ -41,7 +41,7 @@ function PegaDxilMyDetails(props: PegaDxilMyDetailsProps) {
|
|
|
41
41
|
const numRegions = getAllFields(getPConnect)?.length;
|
|
42
42
|
const gridRepeat = "repeat(".concat(numRegions).concat(", 1fr)");
|
|
43
43
|
|
|
44
|
-
const gridContainer: GridContainerProps = { colGap:
|
|
44
|
+
const gridContainer: GridContainerProps = { colGap: 6 };
|
|
45
45
|
gridContainer.cols = gridRepeat;
|
|
46
46
|
gridContainer.alignItems = 'start';
|
|
47
47
|
|
|
@@ -82,7 +82,7 @@ function PegaDxilMyDetails(props: PegaDxilMyDetailsProps) {
|
|
|
82
82
|
|
|
83
83
|
<Flex
|
|
84
84
|
// @ts-ignore
|
|
85
|
-
container={{ direction: 'column', alignItems: 'normal', colGap:
|
|
85
|
+
container={{ direction: 'column', alignItems: 'normal', colGap: 1, rowGap: 1.5 }}
|
|
86
86
|
key={`r-${i + 1}`}
|
|
87
87
|
>
|
|
88
88
|
<DetailsRender child={child} />
|