@pega/cosmos-react-demos 4.0.0-dev.5.1 → 4.0.0-dev.6.1
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/jsx/build/FlowModeller/FlowModeller.mocks.d.ts.map +1 -1
- package/jsx/build/FlowModeller/FlowModeller.mocks.jsx +17 -2
- package/jsx/build/FlowModeller/FlowModeller.mocks.jsx.map +1 -1
- package/jsx/build/ObjectSelect/ObjectSelect.mocks.d.ts +3 -2
- package/jsx/build/ObjectSelect/ObjectSelect.mocks.d.ts.map +1 -1
- package/jsx/build/ObjectSelect/ObjectSelect.mocks.jsx.map +1 -1
- package/jsx/build/PageTemplates/PageTemplates.stories.jsx.map +1 -1
- package/jsx/core/Backdrop/Backdrop.stories.d.ts.map +1 -1
- package/jsx/core/Backdrop/Backdrop.stories.jsx +12 -12
- package/jsx/core/Backdrop/Backdrop.stories.jsx.map +1 -1
- package/jsx/core/Badges/Count.stories.jsx +1 -1
- package/jsx/core/Badges/Count.stories.jsx.map +1 -1
- package/jsx/core/Dialog/Dialog.mocks.d.ts +26 -0
- package/jsx/core/Dialog/Dialog.mocks.d.ts.map +1 -0
- package/jsx/core/Dialog/Dialog.mocks.jsx +136 -0
- package/jsx/core/Dialog/Dialog.mocks.jsx.map +1 -0
- package/jsx/core/Dialog/Dialog.stories.d.ts +1 -1
- package/jsx/core/Dialog/Dialog.stories.d.ts.map +1 -1
- package/jsx/core/Dialog/Dialog.stories.jsx +78 -69
- package/jsx/core/Dialog/Dialog.stories.jsx.map +1 -1
- package/jsx/cs/InteractionNotification/InteractionNotification.stories.d.ts +3 -1
- package/jsx/cs/InteractionNotification/InteractionNotification.stories.d.ts.map +1 -1
- package/jsx/cs/InteractionNotification/InteractionNotification.stories.jsx +18 -4
- package/jsx/cs/InteractionNotification/InteractionNotification.stories.jsx.map +1 -1
- package/jsx/work/CaseView/CaseView.mocks.d.ts +2 -14
- package/jsx/work/CaseView/CaseView.mocks.d.ts.map +1 -1
- package/jsx/work/CaseView/CaseView.mocks.jsx +23 -11
- package/jsx/work/CaseView/CaseView.mocks.jsx.map +1 -1
- package/jsx/work/SearchResults/SearchResults.stories.d.ts.map +1 -1
- package/jsx/work/SearchResults/SearchResults.stories.jsx +21 -2
- package/jsx/work/SearchResults/SearchResults.stories.jsx.map +1 -1
- package/jsx/wss/CaseView/CaseView.stories.jsx +1 -1
- package/jsx/wss/CaseView/CaseView.stories.jsx.map +1 -1
- package/lib/build/FlowModeller/FlowModeller.mocks.d.ts.map +1 -1
- package/lib/build/FlowModeller/FlowModeller.mocks.js +17 -2
- package/lib/build/FlowModeller/FlowModeller.mocks.js.map +1 -1
- package/lib/build/ObjectSelect/ObjectSelect.mocks.d.ts +3 -2
- package/lib/build/ObjectSelect/ObjectSelect.mocks.d.ts.map +1 -1
- package/lib/build/ObjectSelect/ObjectSelect.mocks.js.map +1 -1
- package/lib/build/PageTemplates/PageTemplates.stories.js.map +1 -1
- package/lib/core/Backdrop/Backdrop.stories.d.ts.map +1 -1
- package/lib/core/Backdrop/Backdrop.stories.js +2 -2
- package/lib/core/Backdrop/Backdrop.stories.js.map +1 -1
- package/lib/core/Badges/Count.stories.js +1 -1
- package/lib/core/Badges/Count.stories.js.map +1 -1
- package/lib/core/Dialog/Dialog.mocks.d.ts +26 -0
- package/lib/core/Dialog/Dialog.mocks.d.ts.map +1 -0
- package/lib/core/Dialog/Dialog.mocks.js +132 -0
- package/lib/core/Dialog/Dialog.mocks.js.map +1 -0
- package/lib/core/Dialog/Dialog.stories.d.ts +1 -1
- package/lib/core/Dialog/Dialog.stories.d.ts.map +1 -1
- package/lib/core/Dialog/Dialog.stories.js +65 -41
- package/lib/core/Dialog/Dialog.stories.js.map +1 -1
- package/lib/cs/InteractionNotification/InteractionNotification.stories.d.ts +3 -1
- package/lib/cs/InteractionNotification/InteractionNotification.stories.d.ts.map +1 -1
- package/lib/cs/InteractionNotification/InteractionNotification.stories.js +18 -4
- package/lib/cs/InteractionNotification/InteractionNotification.stories.js.map +1 -1
- package/lib/work/CaseView/CaseView.mocks.d.ts +2 -14
- package/lib/work/CaseView/CaseView.mocks.d.ts.map +1 -1
- package/lib/work/CaseView/CaseView.mocks.js +23 -11
- package/lib/work/CaseView/CaseView.mocks.js.map +1 -1
- package/lib/work/SearchResults/SearchResults.stories.d.ts.map +1 -1
- package/lib/work/SearchResults/SearchResults.stories.js +21 -2
- package/lib/work/SearchResults/SearchResults.stories.js.map +1 -1
- package/lib/wss/CaseView/CaseView.stories.js +1 -1
- package/lib/wss/CaseView/CaseView.stories.js.map +1 -1
- package/package.json +9 -9
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { useEffect, useReducer, useState } from 'react';
|
|
2
|
+
import { ComboBox, createUID, Flex, FormDialog, Input } from '@pega/cosmos-react-core';
|
|
3
|
+
const errorText = 'Cannot be blank';
|
|
4
|
+
const categories = Array.from({ length: 5 }, (_, i) => `Category ${i + 1}`);
|
|
5
|
+
const initialItems = Array.from({ length: 3 }, (_, i) => {
|
|
6
|
+
return {
|
|
7
|
+
id: createUID(),
|
|
8
|
+
name: `Editable item ${i + 1}`,
|
|
9
|
+
category: categories[i]
|
|
10
|
+
};
|
|
11
|
+
});
|
|
12
|
+
const itemReducer = (items, payload) => {
|
|
13
|
+
switch (payload.type) {
|
|
14
|
+
case 'add': {
|
|
15
|
+
return [...items, { ...payload.item, id: createUID() }];
|
|
16
|
+
}
|
|
17
|
+
case 'edit': {
|
|
18
|
+
return items.map(item => {
|
|
19
|
+
return item.id === payload.item.id
|
|
20
|
+
? { ...item, name: payload.item.name, category: payload.item.category }
|
|
21
|
+
: item;
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
case 'remove': {
|
|
25
|
+
const itemIndex = items.findIndex(item => item.id === payload.item.id);
|
|
26
|
+
if (itemIndex === -1)
|
|
27
|
+
return items;
|
|
28
|
+
items.splice(itemIndex, 1);
|
|
29
|
+
return [...items];
|
|
30
|
+
}
|
|
31
|
+
default: {
|
|
32
|
+
return items;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
const progressStates = {
|
|
37
|
+
loading: 'Loading...',
|
|
38
|
+
submitting: 'Submitting...'
|
|
39
|
+
};
|
|
40
|
+
export const useMockItems = () => {
|
|
41
|
+
return useReducer(itemReducer, undefined, () => initialItems);
|
|
42
|
+
};
|
|
43
|
+
export const ItemDialog = ({ target, item: itemProp, dispatch, onComplete }) => {
|
|
44
|
+
const [nameField, setNameField] = useState(() => {
|
|
45
|
+
return {
|
|
46
|
+
value: itemProp?.name ?? null,
|
|
47
|
+
error: null,
|
|
48
|
+
errorOnPriorBlur: false
|
|
49
|
+
};
|
|
50
|
+
});
|
|
51
|
+
const [categoryField, setCategoryField] = useState(() => {
|
|
52
|
+
return {
|
|
53
|
+
value: itemProp?.category ?? null,
|
|
54
|
+
error: null
|
|
55
|
+
};
|
|
56
|
+
});
|
|
57
|
+
const [progress, setProgress] = useState(progressStates.loading);
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
let timerId;
|
|
60
|
+
if (progress === progressStates.loading) {
|
|
61
|
+
timerId = window.setTimeout(() => {
|
|
62
|
+
setProgress(false);
|
|
63
|
+
}, 1000);
|
|
64
|
+
}
|
|
65
|
+
else if (progress === progressStates.submitting) {
|
|
66
|
+
timerId = window.setTimeout(() => {
|
|
67
|
+
setProgress(false);
|
|
68
|
+
dispatch({ name: nameField.value, category: categoryField.value });
|
|
69
|
+
onComplete();
|
|
70
|
+
}, 2000);
|
|
71
|
+
}
|
|
72
|
+
return () => {
|
|
73
|
+
window.clearTimeout(timerId);
|
|
74
|
+
};
|
|
75
|
+
}, [progress]);
|
|
76
|
+
return (<FormDialog target={target} heading={`${itemProp ? 'Edit' : 'Add'} item`} progress={progress} onCancel={{
|
|
77
|
+
handler: () => {
|
|
78
|
+
setProgress(false);
|
|
79
|
+
onComplete();
|
|
80
|
+
}
|
|
81
|
+
}} onSubmit={{
|
|
82
|
+
disabled: !!progress || [nameField, categoryField].some(field => !field.value || field.error),
|
|
83
|
+
handler: () => {
|
|
84
|
+
setProgress(progressStates.submitting);
|
|
85
|
+
}
|
|
86
|
+
}}>
|
|
87
|
+
{(!progress || progress !== progressStates.loading) && (<Flex container={{ direction: 'column', gap: 2 }}>
|
|
88
|
+
<Input required label='Name' value={nameField.value ?? ''} onChange={(e) => {
|
|
89
|
+
setNameField(cur => ({
|
|
90
|
+
...cur,
|
|
91
|
+
value: e.target.value,
|
|
92
|
+
error: !e.target.value && cur.errorOnPriorBlur ? errorText : null
|
|
93
|
+
}));
|
|
94
|
+
}} onBlur={(e) => {
|
|
95
|
+
if (!e.target.value) {
|
|
96
|
+
setNameField(cur => ({
|
|
97
|
+
...cur,
|
|
98
|
+
error: errorText,
|
|
99
|
+
errorOnPriorBlur: true
|
|
100
|
+
}));
|
|
101
|
+
}
|
|
102
|
+
else if (nameField.errorOnPriorBlur) {
|
|
103
|
+
setNameField(cur => ({ ...cur, errorOnPriorBlur: false }));
|
|
104
|
+
}
|
|
105
|
+
}} status={nameField.error ? 'error' : undefined} info={nameField.error}/>
|
|
106
|
+
<ComboBox required label='Category' selected={categoryField.value
|
|
107
|
+
? {
|
|
108
|
+
items: {
|
|
109
|
+
id: categoryField.value,
|
|
110
|
+
text: categoryField.value
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
: undefined} menu={{
|
|
114
|
+
mode: 'single-select',
|
|
115
|
+
onItemClick: category => {
|
|
116
|
+
setCategoryField({
|
|
117
|
+
value: category,
|
|
118
|
+
error: null
|
|
119
|
+
});
|
|
120
|
+
},
|
|
121
|
+
items: categories.map(category => {
|
|
122
|
+
return {
|
|
123
|
+
id: category,
|
|
124
|
+
primary: category,
|
|
125
|
+
selected: category === categoryField.value
|
|
126
|
+
};
|
|
127
|
+
})
|
|
128
|
+
}} onBlur={selected => {
|
|
129
|
+
if (!selected) {
|
|
130
|
+
setCategoryField(cur => ({ ...cur, error: errorText }));
|
|
131
|
+
}
|
|
132
|
+
}} status={categoryField.error ? 'error' : undefined} info={categoryField.error}/>
|
|
133
|
+
</Flex>)}
|
|
134
|
+
</FormDialog>);
|
|
135
|
+
};
|
|
136
|
+
//# sourceMappingURL=Dialog.mocks.jsx.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Dialog.mocks.jsx","sourceRoot":"","sources":["../../../src/core/Dialog/Dialog.mocks.tsx"],"names":[],"mappings":"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","sourcesContent":["import { ChangeEvent, FocusEvent, useEffect, useReducer, useState } from 'react';\n\nimport {\n ComboBox,\n createUID,\n Flex,\n FormDialog,\n FormDialogProps,\n Input\n} from '@pega/cosmos-react-core';\n\nexport type MockCategory = `Category ${number}`;\n\nexport interface MockItem {\n readonly id: string;\n name: string;\n category: MockCategory;\n}\n\nexport type MockReducerPayload =\n | {\n type: 'add';\n item: Pick<MockItem, 'name' | 'category'>;\n }\n | {\n type: 'edit';\n item: MockItem;\n }\n | {\n type: 'remove';\n item: Pick<MockItem, 'id'>;\n };\n\nexport interface MockItemDialogProps extends Pick<FormDialogProps, 'target'> {\n item: MockItem | null;\n dispatch: (fieldValues: Pick<MockItem, 'name' | 'category'>) => void;\n onComplete: () => void;\n}\n\nconst errorText = 'Cannot be blank';\n\nconst categories = Array.from({ length: 5 }, (_, i): MockCategory => `Category ${i + 1}`);\n\nconst initialItems: MockItem[] = Array.from({ length: 3 }, (_, i) => {\n return {\n id: createUID(),\n name: `Editable item ${i + 1}`,\n category: categories[i]\n };\n});\n\nconst itemReducer = (items: MockItem[], payload: MockReducerPayload) => {\n switch (payload.type) {\n case 'add': {\n return [...items, { ...payload.item, id: createUID() }];\n }\n\n case 'edit': {\n return items.map(item => {\n return item.id === payload.item.id\n ? { ...item, name: payload.item.name, category: payload.item.category }\n : item;\n });\n }\n\n case 'remove': {\n const itemIndex = items.findIndex(item => item.id === payload.item.id);\n if (itemIndex === -1) return items;\n items.splice(itemIndex, 1);\n return [...items];\n }\n\n default: {\n return items;\n }\n }\n};\n\nconst progressStates = {\n loading: 'Loading...',\n submitting: 'Submitting...'\n} as const;\n\nexport const useMockItems = () => {\n return useReducer(itemReducer, undefined, () => initialItems);\n};\n\nexport const ItemDialog = ({\n target,\n item: itemProp,\n dispatch,\n onComplete\n}: MockItemDialogProps) => {\n const [nameField, setNameField] = useState<{\n value: string | null;\n error: typeof errorText | null;\n errorOnPriorBlur: boolean;\n }>(() => {\n return {\n value: itemProp?.name ?? null,\n error: null,\n errorOnPriorBlur: false\n };\n });\n\n const [categoryField, setCategoryField] = useState<{\n value: MockCategory | null;\n error: typeof errorText | null;\n }>(() => {\n return {\n value: itemProp?.category ?? null,\n error: null\n };\n });\n\n const [progress, setProgress] = useState<\n typeof progressStates[keyof typeof progressStates] | false\n >(progressStates.loading);\n\n useEffect(() => {\n let timerId: number;\n\n if (progress === progressStates.loading) {\n timerId = window.setTimeout(() => {\n setProgress(false);\n }, 1000);\n } else if (progress === progressStates.submitting) {\n timerId = window.setTimeout(() => {\n setProgress(false);\n dispatch({ name: nameField.value!, category: categoryField.value! });\n onComplete();\n }, 2000);\n }\n\n return () => {\n window.clearTimeout(timerId);\n };\n }, [progress]);\n\n return (\n <FormDialog\n target={target}\n heading={`${itemProp ? 'Edit' : 'Add'} item`}\n progress={progress}\n onCancel={{\n handler: () => {\n setProgress(false);\n onComplete();\n }\n }}\n onSubmit={{\n disabled:\n !!progress || [nameField, categoryField].some(field => !field.value || field.error),\n handler: () => {\n setProgress(progressStates.submitting);\n }\n }}\n >\n {(!progress || progress !== progressStates.loading) && (\n <Flex container={{ direction: 'column', gap: 2 }}>\n <Input\n required\n label='Name'\n value={nameField.value ?? ''}\n onChange={(e: ChangeEvent<HTMLInputElement>) => {\n setNameField(cur => ({\n ...cur,\n value: e.target.value,\n error: !e.target.value && cur.errorOnPriorBlur ? errorText : null\n }));\n }}\n onBlur={(e: FocusEvent<HTMLInputElement>) => {\n if (!e.target.value) {\n setNameField(cur => ({\n ...cur,\n error: errorText,\n errorOnPriorBlur: true\n }));\n } else if (nameField.errorOnPriorBlur) {\n setNameField(cur => ({ ...cur, errorOnPriorBlur: false }));\n }\n }}\n status={nameField.error ? 'error' : undefined}\n info={nameField.error}\n />\n <ComboBox\n required\n label='Category'\n selected={\n categoryField.value\n ? {\n items: {\n id: categoryField.value,\n text: categoryField.value\n }\n }\n : undefined\n }\n menu={{\n mode: 'single-select',\n onItemClick: category => {\n setCategoryField({\n value: category as MockCategory,\n error: null\n });\n },\n items: categories.map(category => {\n return {\n id: category,\n primary: category,\n selected: category === categoryField.value\n };\n })\n }}\n onBlur={selected => {\n if (!selected) {\n setCategoryField(cur => ({ ...cur, error: errorText }));\n }\n }}\n status={categoryField.error ? 'error' : undefined}\n info={categoryField.error}\n />\n </Flex>\n )}\n </FormDialog>\n );\n};\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Meta, Story } from '@storybook/react';
|
|
2
2
|
declare const _default: Meta<import("@storybook/react").Args>;
|
|
3
3
|
export default _default;
|
|
4
|
-
export declare const
|
|
4
|
+
export declare const InfoDialogDemo: Story;
|
|
5
5
|
export declare const FormDialogDemo: Story;
|
|
6
6
|
//# sourceMappingURL=Dialog.stories.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Dialog.stories.d.ts","sourceRoot":"","sources":["../../../src/core/Dialog/Dialog.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;;
|
|
1
|
+
{"version":3,"file":"Dialog.stories.d.ts","sourceRoot":"","sources":["../../../src/core/Dialog/Dialog.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;;AAiB/C,wBAEU;AAGV,eAAO,MAAM,cAAc,EAAE,KA+B5B,CAAC;AAGF,eAAO,MAAM,cAAc,EAAE,KA0E5B,CAAC"}
|
|
@@ -1,79 +1,88 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
import { Button, Flex, Text, useElement, InfoDialog, SummaryList } from '@pega/cosmos-react-core';
|
|
3
|
+
import { FieldValueListDemo } from '../FieldValueList/FieldValueList.stories';
|
|
4
|
+
import { ItemDialog, useMockItems } from './Dialog.mocks';
|
|
4
5
|
export default {
|
|
5
|
-
title: 'Core/Dialog'
|
|
6
|
-
component: Dialog
|
|
6
|
+
title: 'Core/Dialog'
|
|
7
7
|
};
|
|
8
|
-
export const
|
|
9
|
-
const
|
|
8
|
+
export const InfoDialogDemo = () => {
|
|
9
|
+
const [target, setTarget] = useElement(null);
|
|
10
10
|
return (<>
|
|
11
|
-
<Button variant='secondary' {
|
|
11
|
+
<Button variant='secondary' onClick={(e) => {
|
|
12
|
+
setTarget(e.currentTarget);
|
|
13
|
+
}}>
|
|
12
14
|
Open dialog
|
|
13
15
|
</Button>
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
|
|
17
|
+
{target && (<InfoDialog heading='General information' target={target} onDismiss={() => setTarget(null)}>
|
|
18
|
+
<Flex container={{ direction: 'column', gap: 2 }}>
|
|
19
|
+
<Text as='p'>
|
|
20
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
|
|
21
|
+
incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud
|
|
22
|
+
exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
|
|
23
|
+
dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
|
|
24
|
+
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt
|
|
25
|
+
mollit anim id est laborum.
|
|
26
|
+
</Text>
|
|
27
|
+
<FieldValueListDemo name='Demo field' value='demo value'/>
|
|
28
|
+
</Flex>
|
|
29
|
+
</InfoDialog>)}
|
|
17
30
|
</>);
|
|
18
31
|
};
|
|
19
32
|
export const FormDialogDemo = () => {
|
|
20
|
-
const
|
|
21
|
-
const
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
</Flex>
|
|
75
|
-
</Dialog>
|
|
76
|
-
</CardContent>
|
|
77
|
-
</Card>);
|
|
33
|
+
const [dialogTarget, setDialogTarget] = useState(null);
|
|
34
|
+
const [editItem, setEditItem] = useState(null);
|
|
35
|
+
const [items, dispatch] = useMockItems();
|
|
36
|
+
return (<>
|
|
37
|
+
<SummaryList name='Editable items' icon='list' count={items.length} actions={[
|
|
38
|
+
{
|
|
39
|
+
id: 'Add',
|
|
40
|
+
text: 'Add',
|
|
41
|
+
icon: 'plus',
|
|
42
|
+
onClick: (_, e) => {
|
|
43
|
+
setDialogTarget(e.currentTarget);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
]} items={items.map(({ id, name, category }) => {
|
|
47
|
+
return {
|
|
48
|
+
id,
|
|
49
|
+
primary: name,
|
|
50
|
+
secondary: <Text variant='secondary'>{category}</Text>,
|
|
51
|
+
actions: [
|
|
52
|
+
{
|
|
53
|
+
id: 'Edit',
|
|
54
|
+
text: 'Edit',
|
|
55
|
+
icon: 'pencil',
|
|
56
|
+
onClick: (_, e, menuButton) => {
|
|
57
|
+
if (menuButton)
|
|
58
|
+
setDialogTarget(menuButton);
|
|
59
|
+
setEditItem({
|
|
60
|
+
id,
|
|
61
|
+
name,
|
|
62
|
+
category
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
id: 'Remove',
|
|
68
|
+
text: 'Remove',
|
|
69
|
+
icon: 'trash',
|
|
70
|
+
onClick: () => {
|
|
71
|
+
dispatch({ type: 'remove', item: { id } });
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
]
|
|
75
|
+
};
|
|
76
|
+
})}/>
|
|
77
|
+
|
|
78
|
+
{dialogTarget && (<ItemDialog target={dialogTarget} item={editItem} dispatch={fields => {
|
|
79
|
+
dispatch(editItem
|
|
80
|
+
? { type: 'edit', item: { id: editItem.id, ...fields } }
|
|
81
|
+
: { type: 'add', item: { ...fields } });
|
|
82
|
+
}} onComplete={() => {
|
|
83
|
+
setDialogTarget(null);
|
|
84
|
+
setEditItem(null);
|
|
85
|
+
}}/>)}
|
|
86
|
+
</>);
|
|
78
87
|
};
|
|
79
88
|
//# sourceMappingURL=Dialog.stories.jsx.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Dialog.stories.jsx","sourceRoot":"","sources":["../../../src/core/Dialog/Dialog.stories.tsx"],"names":[],"mappings":"AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"Dialog.stories.jsx","sourceRoot":"","sources":["../../../src/core/Dialog/Dialog.stories.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Meta, Story } from '@storybook/react';\nimport { MouseEvent, useState } from 'react';\n\nimport {\n Button,\n Flex,\n Text,\n useElement,\n InfoDialog,\n SummaryList,\n SummaryListItem\n} from '@pega/cosmos-react-core';\n\nimport { FieldValueListDemo } from '../FieldValueList/FieldValueList.stories';\n\nimport { ItemDialog, MockItem, MockItemDialogProps, useMockItems } from './Dialog.mocks';\n\nexport default {\n title: 'Core/Dialog'\n} as Meta;\n\n// InfoDialogDemo\nexport const InfoDialogDemo: Story = () => {\n const [target, setTarget] = useElement<HTMLButtonElement>(null);\n\n return (\n <>\n <Button\n variant='secondary'\n onClick={(e: MouseEvent<HTMLButtonElement>) => {\n setTarget(e.currentTarget);\n }}\n >\n Open dialog\n </Button>\n\n {target && (\n <InfoDialog heading='General information' target={target} onDismiss={() => setTarget(null)}>\n <Flex container={{ direction: 'column', gap: 2 }}>\n <Text as='p'>\n Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor\n incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud\n exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure\n dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.\n Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt\n mollit anim id est laborum.\n </Text>\n <FieldValueListDemo name='Demo field' value='demo value' />\n </Flex>\n </InfoDialog>\n )}\n </>\n );\n};\n\n// FormDialogDemo\nexport const FormDialogDemo: Story = () => {\n const [dialogTarget, setDialogTarget] = useState<MockItemDialogProps['target'] | null>(null);\n const [editItem, setEditItem] = useState<MockItem | null>(null);\n const [items, dispatch] = useMockItems();\n\n return (\n <>\n <SummaryList\n name='Editable items'\n icon='list'\n count={items.length}\n actions={[\n {\n id: 'Add',\n text: 'Add',\n icon: 'plus',\n onClick: (_, e) => {\n setDialogTarget(e.currentTarget);\n }\n }\n ]}\n items={items.map<SummaryListItem>(({ id, name, category }) => {\n return {\n id,\n primary: name,\n secondary: <Text variant='secondary'>{category}</Text>,\n actions: [\n {\n id: 'Edit',\n text: 'Edit',\n icon: 'pencil',\n onClick: (_, e, menuButton) => {\n if (menuButton) setDialogTarget(menuButton);\n\n setEditItem({\n id,\n name,\n category\n });\n }\n },\n {\n id: 'Remove',\n text: 'Remove',\n icon: 'trash',\n onClick: () => {\n dispatch({ type: 'remove', item: { id } });\n }\n }\n ]\n };\n })}\n />\n\n {dialogTarget && (\n <ItemDialog\n target={dialogTarget}\n item={editItem}\n // Wrap dispatch so the dialog can only affect the item it creates or updates.\n dispatch={fields => {\n dispatch(\n editItem\n ? { type: 'edit', item: { id: editItem.id, ...fields } }\n : { type: 'add', item: { ...fields } }\n );\n }}\n onComplete={() => {\n setDialogTarget(null);\n setEditItem(null);\n }}\n />\n )}\n </>\n );\n};\n"]}
|
|
@@ -4,7 +4,9 @@ export default _default;
|
|
|
4
4
|
interface InteractionNotificationDemoProps {
|
|
5
5
|
icon: string;
|
|
6
6
|
secondaryText: string;
|
|
7
|
-
|
|
7
|
+
declineAvailable: boolean;
|
|
8
|
+
timerAvailable: boolean;
|
|
9
|
+
answerTimeout: number;
|
|
8
10
|
}
|
|
9
11
|
export declare const InteractionNotificationDemo: Story<InteractionNotificationDemoProps>;
|
|
10
12
|
//# sourceMappingURL=InteractionNotification.stories.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InteractionNotification.stories.d.ts","sourceRoot":"","sources":["../../../src/cs/InteractionNotification/InteractionNotification.stories.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;;
|
|
1
|
+
{"version":3,"file":"InteractionNotification.stories.d.ts","sourceRoot":"","sources":["../../../src/cs/InteractionNotification/InteractionNotification.stories.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;;AAM/C,wBAGU;AAEV,UAAU,gCAAgC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,cAAc,EAAE,OAAO,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,eAAO,MAAM,2BAA2B,EAAE,KAAK,CAAC,gCAAgC,CA+C/E,CAAC"}
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { action } from '@storybook/addon-actions';
|
|
2
|
+
import { useRef } from 'react';
|
|
2
3
|
import { InteractionNotification } from '@pega/cosmos-react-cs';
|
|
3
|
-
import { icons } from '@pega/cosmos-react-core';
|
|
4
|
+
import { icons, useI18n, useToaster } from '@pega/cosmos-react-core';
|
|
4
5
|
export default {
|
|
5
6
|
title: 'Customer Service/InteractionNotification',
|
|
6
7
|
component: InteractionNotification
|
|
7
8
|
};
|
|
8
9
|
export const InteractionNotificationDemo = (args) => {
|
|
10
|
+
const incomingNotificationTimeout = useRef(Date.now());
|
|
11
|
+
const { push } = useToaster();
|
|
12
|
+
const t = useI18n();
|
|
9
13
|
return (<InteractionNotification icon={args.icon} title='Incoming call' primaryText='John Brown' secondaryText={args.secondaryText} status={{
|
|
10
14
|
variant: 'success',
|
|
11
15
|
text: 'VERIFIED PLATINUM CUSTOMER'
|
|
@@ -25,16 +29,26 @@ export const InteractionNotificationDemo = (args) => {
|
|
|
25
29
|
name: 'Last interaction',
|
|
26
30
|
value: new Date().toLocaleDateString()
|
|
27
31
|
}
|
|
28
|
-
]}
|
|
32
|
+
]} incomingNotificationTimeout={args.timerAvailable
|
|
33
|
+
? {
|
|
34
|
+
startTime: incomingNotificationTimeout.current,
|
|
35
|
+
answerTimeout: args.answerTimeout,
|
|
36
|
+
onTimerEnd: () => push({ content: t('interaction_time_expired') })
|
|
37
|
+
}
|
|
38
|
+
: undefined} onAccept={action('accept')} onDecline={args.declineAvailable ? action('decline') : undefined}/>);
|
|
29
39
|
};
|
|
30
40
|
InteractionNotificationDemo.args = {
|
|
31
41
|
icon: 'phone-in-solid',
|
|
32
42
|
secondaryText: '(123) 456-7890',
|
|
33
|
-
|
|
43
|
+
declineAvailable: true,
|
|
44
|
+
timerAvailable: true,
|
|
45
|
+
answerTimeout: 30
|
|
34
46
|
};
|
|
35
47
|
InteractionNotificationDemo.argTypes = {
|
|
36
48
|
icon: { options: icons, control: { type: 'select', icons: true } },
|
|
37
49
|
secondaryText: { options: { type: 'text' } },
|
|
38
|
-
|
|
50
|
+
declineAvailable: { options: { type: 'boolean' } },
|
|
51
|
+
timerAvailable: { options: { type: 'boolean' } },
|
|
52
|
+
answerTimeout: { options: { type: 'number' } }
|
|
39
53
|
};
|
|
40
54
|
//# sourceMappingURL=InteractionNotification.stories.jsx.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InteractionNotification.stories.jsx","sourceRoot":"","sources":["../../../src/cs/InteractionNotification/InteractionNotification.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"InteractionNotification.stories.jsx","sourceRoot":"","sources":["../../../src/cs/InteractionNotification/InteractionNotification.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAElD,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAErE,eAAe;IACb,KAAK,EAAE,0CAA0C;IACjD,SAAS,EAAE,uBAAuB;CAC3B,CAAC;AAUV,MAAM,CAAC,MAAM,2BAA2B,GAA4C,CAClF,IAAsC,EACtC,EAAE;IACF,MAAM,2BAA2B,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IACvD,MAAM,EAAE,IAAI,EAAE,GAAG,UAAU,EAAE,CAAC;IAC9B,MAAM,CAAC,GAAG,OAAO,EAAE,CAAC;IAEpB,OAAO,CACL,CAAC,uBAAuB,CACtB,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAChB,KAAK,CAAC,eAAe,CACrB,WAAW,CAAC,YAAY,CACxB,aAAa,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAClC,MAAM,CAAC,CAAC;YACN,OAAO,EAAE,SAAS;YAClB,IAAI,EAAE,4BAA4B;SACnC,CAAC,CACF,MAAM,CAAC,CAAC;YACN;gBACE,EAAE,EAAE,QAAQ;gBACZ,IAAI,EAAE,oBAAoB;gBAC1B,KAAK,EAAE,kBAAkB;aAC1B;YACD;gBACE,EAAE,EAAE,WAAW;gBACf,IAAI,EAAE,YAAY;gBAClB,KAAK,EAAE,GAAG;aACX;YACD;gBACE,EAAE,EAAE,iBAAiB;gBACrB,IAAI,EAAE,kBAAkB;gBACxB,KAAK,EAAE,IAAI,IAAI,EAAE,CAAC,kBAAkB,EAAE;aACvC;SACF,CAAC,CACF,2BAA2B,CAAC,CAC1B,IAAI,CAAC,cAAc;YACjB,CAAC,CAAC;gBACE,SAAS,EAAE,2BAA2B,CAAC,OAAO;gBAC9C,aAAa,EAAE,IAAI,CAAC,aAAa;gBACjC,UAAU,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,0BAA0B,CAAC,EAAE,CAAC;aACnE;YACH,CAAC,CAAC,SAAS,CACd,CACD,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAC3B,SAAS,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,EACjE,CACH,CAAC;AACJ,CAAC,CAAC;AAEF,2BAA2B,CAAC,IAAI,GAAG;IACjC,IAAI,EAAE,gBAAgB;IACtB,aAAa,EAAE,gBAAgB;IAC/B,gBAAgB,EAAE,IAAI;IACtB,cAAc,EAAE,IAAI;IACpB,aAAa,EAAE,EAAE;CAClB,CAAC;AAEF,2BAA2B,CAAC,QAAQ,GAAG;IACrC,IAAI,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;IAClE,aAAa,EAAE,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE;IAC5C,gBAAgB,EAAE,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE;IAClD,cAAc,EAAE,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE;IAChD,aAAa,EAAE,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;CAC/C,CAAC","sourcesContent":["import { action } from '@storybook/addon-actions';\nimport { Meta, Story } from '@storybook/react';\nimport { useRef } from 'react';\n\nimport { InteractionNotification } from '@pega/cosmos-react-cs';\nimport { icons, useI18n, useToaster } from '@pega/cosmos-react-core';\n\nexport default {\n title: 'Customer Service/InteractionNotification',\n component: InteractionNotification\n} as Meta;\n\ninterface InteractionNotificationDemoProps {\n icon: string;\n secondaryText: string;\n declineAvailable: boolean;\n timerAvailable: boolean;\n answerTimeout: number;\n}\n\nexport const InteractionNotificationDemo: Story<InteractionNotificationDemoProps> = (\n args: InteractionNotificationDemoProps\n) => {\n const incomingNotificationTimeout = useRef(Date.now());\n const { push } = useToaster();\n const t = useI18n();\n\n return (\n <InteractionNotification\n icon={args.icon}\n title='Incoming call'\n primaryText='John Brown'\n secondaryText={args.secondaryText}\n status={{\n variant: 'success',\n text: 'VERIFIED PLATINUM CUSTOMER'\n }}\n fields={[\n {\n id: 'reason',\n name: 'Reason for calling',\n value: 'Billing question'\n },\n {\n id: 'openCases',\n name: 'Open cases',\n value: '1'\n },\n {\n id: 'lastInteraction',\n name: 'Last interaction',\n value: new Date().toLocaleDateString()\n }\n ]}\n incomingNotificationTimeout={\n args.timerAvailable\n ? {\n startTime: incomingNotificationTimeout.current,\n answerTimeout: args.answerTimeout,\n onTimerEnd: () => push({ content: t('interaction_time_expired') })\n }\n : undefined\n }\n onAccept={action('accept')}\n onDecline={args.declineAvailable ? action('decline') : undefined}\n />\n );\n};\n\nInteractionNotificationDemo.args = {\n icon: 'phone-in-solid',\n secondaryText: '(123) 456-7890',\n declineAvailable: true,\n timerAvailable: true,\n answerTimeout: 30\n};\n\nInteractionNotificationDemo.argTypes = {\n icon: { options: icons, control: { type: 'select', icons: true } },\n secondaryText: { options: { type: 'text' } },\n declineAvailable: { options: { type: 'boolean' } },\n timerAvailable: { options: { type: 'boolean' } },\n answerTimeout: { options: { type: 'number' } }\n};\n"]}
|
|
@@ -37,24 +37,12 @@ export declare const getPrimaryFields: () => {
|
|
|
37
37
|
name: string;
|
|
38
38
|
value: string;
|
|
39
39
|
}[];
|
|
40
|
-
export declare const getSecondaryFields: ({ setPreviewCaseId, setPreviewCurrentTabId }: PreviewSetters) => (
|
|
41
|
-
name: string;
|
|
42
|
-
value: JSX.Element;
|
|
43
|
-
} | {
|
|
44
|
-
name: string;
|
|
45
|
-
value: string;
|
|
46
|
-
})[];
|
|
40
|
+
export declare const getSecondaryFields: ({ setPreviewCaseId, setPreviewCurrentTabId }: PreviewSetters) => import("@pega/cosmos-react-work/lib/components/CaseView/CaseView.types").SummaryField[];
|
|
47
41
|
export declare const casePreviewPrimaryFields: {
|
|
48
42
|
name: string;
|
|
49
43
|
value: string;
|
|
50
44
|
}[];
|
|
51
|
-
export declare const casePreviewSecondaryFields: (
|
|
52
|
-
name: string;
|
|
53
|
-
value: JSX.Element;
|
|
54
|
-
} | {
|
|
55
|
-
name: string;
|
|
56
|
-
value: string;
|
|
57
|
-
})[];
|
|
45
|
+
export declare const casePreviewSecondaryFields: import("@pega/cosmos-react-work/lib/components/CaseView/CaseView.types").SummaryField[];
|
|
58
46
|
export declare const getParentCases: ({ caseId, setPreviewCaseId, setPreviewCurrentTabId }: {
|
|
59
47
|
caseId: CaseViewProps['caseId'];
|
|
60
48
|
} & PreviewSetters) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CaseView.mocks.d.ts","sourceRoot":"","sources":["../../../src/work/CaseView/CaseView.mocks.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAgC,MAAM,OAAO,CAAC;AAG/E,OAAO,EAQL,gBAAgB,EAWjB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,wDAAwD,CAAC;AAClF,OAAO,
|
|
1
|
+
{"version":3,"file":"CaseView.mocks.d.ts","sourceRoot":"","sources":["../../../src/work/CaseView/CaseView.mocks.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAgC,MAAM,OAAO,CAAC;AAG/E,OAAO,EAQL,gBAAgB,EAWjB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,wDAAwD,CAAC;AAClF,OAAO,EAAW,aAAa,EAAyB,MAAM,yBAAyB,CAAC;AACxF,OAAO,EAAE,QAAQ,EAAkB,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,MAAM,oDAAoD,CAAC;AAa/E,UAAU,cAAc;IACtB,gBAAgB,EAAE,QAAQ,CAAC,cAAc,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;IAC1D,sBAAsB,EAAE,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC;CAC1D;AAMD,eAAO,MAAM,SAAS,UAAmC,CAAC;AAE1D,eAAO,MAAM,YAAY,OAKvB,CAAC;AAIH,eAAO,MAAM,2BAA2B,oBAAqB,GAAG,gBAwC/D,CAAC;AAEF,eAAO,MAAM,eAAe;;;iBAqD3B,CAAC;AAEF,eAAO,MAAM,sBAAsB,mBA8ElC,CAAC;AAEF,eAAO,MAAM,oBAAoB,mEAI9B;IAAE,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAA;CAAE,GAAG,cAAc,gBAa9C,CAAC;AAEF,eAAO,MAAM,mBAAmB,iDAG7B,cAAc,KAAG,SAAS,CAAC,aAAa,CAc1C,CAAC;AAEF,eAAO,MAAM,gBAAgB;QAMvB,MAAM;UACJ,MAAM;2BAMb,CAAC;AAEF,eAAO,MAAM,aAAa,iDAAkD,cAAc;;;GA0BzF,CAAC;AAEF,eAAO,MAAM,iBAAiB;;;GAiB7B,CAAC;AAEF,eAAO,MAAM,gBAAgB;;;;GAmB5B,CAAC;AAuBF,eAAO,MAAM,kBAAkB,iDAG5B,cAAc,4FAuBhB,CAAC;AAEF,eAAO,MAAM,wBAAwB;;;GASpC,CAAC;AAEF,eAAO,MAAM,0BAA0B,yFAAsB,CAAC;AAE9D,eAAO,MAAM,cAAc;YAKjB,aAAa,CAAC,QAAQ,CAAC;;;;;;;GAuBhC,CAAC;AAEF,eAAO,MAAM,SAAS,mBASrB,CAAC;AAEF,eAAO,MAAM,wBAAwB,QAAO,aAAa,CAAC,uBAAuB,CAOhF,CAAC;AAEF,eAAO,MAAM,cAAc;;;;GAQ1B,CAAC;AAEF,eAAO,MAAM,kBAAkB;;;;GAE9B,CAAC;AASF,eAAO,MAAM,wBAAwB,mBASpC,CAAC;AAEF,MAAM,WAAW,iBACf,SAAQ,IAAI,CAAC,aAAa,EAAE,SAAS,GAAG,OAAO,GAAG,QAAQ,GAAG,mBAAmB,CAAC;IACjF,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,eAAO,MAAM,YAAY,+DAMtB,iBAAiB,gBAkHnB,CAAC"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { useEffect, useMemo, useState } from 'react';
|
|
2
2
|
import styled, { css } from 'styled-components';
|
|
3
3
|
import { Avatar, Button, Link, createStringMatcher, Modal, Popover, SummaryList, useModalManager, useElement, useOuterEvent, ViewAll, Status, createUID, Flex, useBreakpoint, Icon, Grid } from '@pega/cosmos-react-core';
|
|
4
|
-
import { Glimpse, CaseView, CasePreview
|
|
4
|
+
import { Glimpse, CaseView, CasePreview } from '@pega/cosmos-react-work';
|
|
5
|
+
import { RichTextViewer } from '@pega/cosmos-react-rte';
|
|
5
6
|
import { TableDemo } from '../../core/Table/Table.stories';
|
|
6
7
|
import { useMockListData } from '../../core/SummaryList/SummaryList.mocks';
|
|
7
8
|
import { StakeHoldersDemo } from '../Stakeholders/Stakeholders.stories';
|
|
@@ -199,10 +200,18 @@ export const previewTabContent = [
|
|
|
199
200
|
];
|
|
200
201
|
export const getPrimaryFields = () => {
|
|
201
202
|
return [
|
|
203
|
+
{
|
|
204
|
+
name: 'Create date',
|
|
205
|
+
value: createDate.toDateString()
|
|
206
|
+
},
|
|
202
207
|
{
|
|
203
208
|
name: 'Member ID',
|
|
204
209
|
value: 'M205435569FD'
|
|
205
210
|
},
|
|
211
|
+
{
|
|
212
|
+
name: 'Assigned to',
|
|
213
|
+
value: 'Dean Thomas'
|
|
214
|
+
},
|
|
206
215
|
{
|
|
207
216
|
name: 'Priority',
|
|
208
217
|
value: '95'
|
|
@@ -214,17 +223,14 @@ const baseSecondaryFields = [
|
|
|
214
223
|
name: 'Status',
|
|
215
224
|
value: <Status variant='info'>New</Status>
|
|
216
225
|
},
|
|
217
|
-
{
|
|
218
|
-
name: 'Assigned to',
|
|
219
|
-
value: 'Dean Thomas'
|
|
220
|
-
},
|
|
221
|
-
{
|
|
222
|
-
name: 'Create date',
|
|
223
|
-
value: createDate.toDateString()
|
|
224
|
-
},
|
|
225
226
|
{
|
|
226
227
|
name: 'Update date',
|
|
227
228
|
value: `${diffInYears} years ago`
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
name: 'Description',
|
|
232
|
+
value: (<RichTextViewer content='<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse commodo nulla vitae mi bibendum, a fringilla nisl efficitur. Praesent vitae nulla lobortis, finibus felis ultricies, fermentum mi. Nunc lorem ligula, placerat nec elit id, auctor pellentesque est.</p> </br> <p>Pellentesque pharetra justo augue, non maximus nulla venenatis et. Sed laoreet ultricies ullamcorper. Mauris ac nulla quis ipsum semper fringilla in eget risus. Fusce cursus sollicitudin nibh molestie volutpat.</p>' type='html'/>),
|
|
233
|
+
variant: 'stacked'
|
|
228
234
|
}
|
|
229
235
|
];
|
|
230
236
|
export const getSecondaryFields = ({ setPreviewCaseId, setPreviewCurrentTabId }) => {
|
|
@@ -348,7 +354,10 @@ export const CaseViewMock = ({ parentCases, tasks, stages, persistentUtility, he
|
|
|
348
354
|
? [...parentCasesContent]
|
|
349
355
|
.filter(c => c.id !== previewCaseId)
|
|
350
356
|
.map(c => ({ ...c, id: `preview-${c.id}` }))
|
|
351
|
-
: undefined} heading='Previewable demo case' subheading={previewCaseId} caseLink={{ href: `/cases/${previewCaseId}`, target: '_blank' }} icon={<Icon name='user-solid'/>} followed={!followed} onEdit={() => { }} actions={getCaseActions()}
|
|
357
|
+
: undefined} heading='Previewable demo case' subheading={previewCaseId} caseLink={{ href: `/cases/${previewCaseId}`, target: '_blank' }} icon={<Icon name='user-solid'/>} followed={!followed} onEdit={() => { }} actions={getCaseActions()} summaryFields={{
|
|
358
|
+
primary: casePreviewPrimaryFields,
|
|
359
|
+
secondary: casePreviewSecondaryFields
|
|
360
|
+
}} stages={demoStages} tasks={<TasksDemo count={4}/>} tabs={previewTabs} tabContent={tabContent} utilities={<Grid container={{ rowGap: 2 }}>
|
|
352
361
|
<Utilities />
|
|
353
362
|
</Grid>}/>)}
|
|
354
363
|
|
|
@@ -358,7 +367,10 @@ export const CaseViewMock = ({ parentCases, tasks, stages, persistentUtility, he
|
|
|
358
367
|
setPreviewCaseId,
|
|
359
368
|
setPreviewCurrentTabId
|
|
360
369
|
})
|
|
361
|
-
: undefined} heading={heading} subheading={caseId} icon={<Icon name='user-solid'/>} followed={followed} onFollowedChange={setFollowed} actions={getCaseActions()} promotedActions={getPromotedActions()} onEdit={() => { }}
|
|
370
|
+
: undefined} heading={heading} subheading={caseId} icon={<Icon name='user-solid'/>} followed={followed} onFollowedChange={setFollowed} actions={getCaseActions()} promotedActions={getPromotedActions()} onEdit={() => { }} summaryFields={{
|
|
371
|
+
primary: getPrimaryFields(),
|
|
372
|
+
secondary: getSecondaryFields({ setPreviewCaseId, setPreviewCurrentTabId })
|
|
373
|
+
}} summaryExpanded={summaryExpanded} onToggleSummary={() => {
|
|
362
374
|
setSummaryExpanded(cur => !cur);
|
|
363
375
|
}} tabs={demoTabs} persistentUtility={persistentUtility} stages={stages && demoStages} tasks={tasks && <TasksDemo count={4}/>} tabContent={tabContent} utilities={<Utilities />} utilitiesSummaryItems={getUtilitiesSummaryItems()} utilitiesExpanded={utilitiesExpanded} onToggleUtilities={() => {
|
|
364
376
|
setUtilitiesExpanded(cur => !cur);
|