@pega/custom-dx-components 0.25.53 → 0.25.55
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/README.md +18 -0
- package/package.json +2 -2
- package/src/tasks/create/templates/Launchpad/Field/Text-Phone/config.json.mustache +146 -0
- package/src/tasks/create/templates/Launchpad/Field/Text-Phone/demo.stories.tsx.mustache +61 -0
- package/src/tasks/create/templates/Launchpad/Field/Text-Phone/demo.test.tsx.mustache +23 -0
- package/src/tasks/create/templates/Launchpad/Field/Text-Phone/event-utils.ts.mustache +18 -0
- package/src/tasks/create/templates/Launchpad/Field/Text-Phone/index.tsx.mustache +246 -0
- package/src/tasks/create/templates/Launchpad/Field/Text-Phone/mock.ts.mustache +40 -0
- package/src/tasks/create/templates/Launchpad/Field/Text-Phone/styles.ts.mustache +8 -0
- package/src/tasks/create/templates/Launchpad/Template/FORM/DefaultForm.svg +29 -0
- package/src/tasks/create/templates/Launchpad/Template/FORM/DetailsRender.tsx.mustache +59 -0
- package/src/tasks/create/templates/Launchpad/Template/FORM/config.json.mustache +45 -0
- package/src/tasks/create/templates/Launchpad/Template/FORM/demo.stories.tsx.mustache +255 -0
- package/src/tasks/create/templates/Launchpad/Template/FORM/demo.test.tsx.mustache +40 -0
- package/src/tasks/create/templates/Launchpad/Template/FORM/index.tsx.mustache +75 -0
- package/src/tasks/create/templates/Launchpad/Template/FORM/mock.ts.mustache +135 -0
- package/src/tasks/create/templates/Launchpad/Template/FORM/styles.ts.mustache +8 -0
- package/src/tasks/create/templates/Launchpad/Template/FORM-region/DetailsRender.tsx.mustache +59 -0
- package/src/tasks/create/templates/Launchpad/Template/FORM-region/TwoColumn.svg +38 -0
- package/src/tasks/create/templates/Launchpad/Template/FORM-region/config.json.mustache +27 -0
- package/src/tasks/create/templates/Launchpad/Template/FORM-region/demo.stories.tsx.mustache +272 -0
- package/src/tasks/create/templates/Launchpad/Template/FORM-region/demo.test.tsx.mustache +56 -0
- package/src/tasks/create/templates/Launchpad/Template/FORM-region/index.tsx.mustache +80 -0
- package/src/tasks/create/templates/Launchpad/Template/FORM-region/mock.ts.mustache +141 -0
- package/src/tasks/create/templates/Launchpad/Template/FORM-region/styles.ts.mustache +8 -0
- package/src/tasks/delete-lib/index.js +6 -0
- package/src/tasks/init/template/README.md +18 -0
- package/src/tasks/init/template/package.json.mustache +2 -2
- package/src/tasks/restore/index.js +35 -14
- package/src/tasks/store/index.js +34 -13
- package/tests/assets/original/components/createAll/Launchpad/Pega_DXIL_MyForm/mock.ts +0 -4
- package/tests/assets/original/components/createAll/Launchpad/Pega_DXIL_MyPhone/config.json +1 -6
- package/tests/assets/original/components/createAll/Launchpad/Pega_DXIL_MyPhone/mock.ts +1 -6
- package/tests/assets/original/components/createAll/Launchpad/Pega_DXIL_MyTwoColumnForm/mock.ts +0 -4
- package/tests/assets/original/components/createAll/Constellation/shared/suggestions-handler.ts +0 -9
- package/tests/assets/original/components/createAll/Launchpad/shared/suggestions-handler.ts +0 -9
- /package/{tests/assets/original/components/create/shared/PConnProps.d.ts → src/tasks/create/templates/Launchpad/Field/Text-Phone/PConnProps.d.ts.mustache} +0 -0
- /package/{tests/assets/original/components/create/shared/create-nonce.ts → src/tasks/create/templates/Launchpad/Field/Text-Phone/create-nonce.ts.mustache} +0 -0
- /package/{tests/assets/original/components/create/shared/suggestions-handler.ts → src/tasks/create/templates/Launchpad/Field/Text-Phone/suggestions-handler.ts.mustache} +0 -0
- /package/{tests/assets/original/components/createAll/Launchpad/shared/PConnProps.d.ts → src/tasks/create/templates/Launchpad/Template/FORM/PConnProps.d.ts.mustache} +0 -0
- /package/{tests/assets/original/components/createAll/Launchpad/shared/create-nonce.ts → src/tasks/create/templates/Launchpad/Template/FORM/create-nonce.ts.mustache} +0 -0
- /package/{tests/assets/original/components/createAll/Constellation/shared/PConnProps.d.ts → src/tasks/create/templates/Launchpad/Template/FORM-region/PConnProps.d.ts.mustache} +0 -0
- /package/{tests/assets/original/components/createAll/Constellation/shared/create-nonce.ts → src/tasks/create/templates/Launchpad/Template/FORM-region/create-nonce.ts.mustache} +0 -0
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
4
|
+
|
|
5
|
+
import {{COMPONENT_CLASS_NAME}} from './index';
|
|
6
|
+
import { DateInput, Input, FieldValueList, Text } from '@pega/cosmos-react-core';
|
|
7
|
+
import { PhoneInput as CosmosPhone } from '@pega/cosmos-react-core';
|
|
8
|
+
import { pyReviewRaw, regionChildrenResolved } from './mock';
|
|
9
|
+
|
|
10
|
+
const meta: Meta<typeof {{COMPONENT_CLASS_NAME}}> = {
|
|
11
|
+
title: '{{COMPONENT_CLASS_NAME}}',
|
|
12
|
+
component: {{COMPONENT_CLASS_NAME}},
|
|
13
|
+
excludeStories: /.*Data$/,
|
|
14
|
+
parameters: {
|
|
15
|
+
type: 'TwoColumnForm'
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export default meta;
|
|
20
|
+
type Story = StoryObj<typeof {{COMPONENT_CLASS_NAME}}>;
|
|
21
|
+
|
|
22
|
+
const renderField = resolvedProps => {
|
|
23
|
+
const { displayMode, value = '', label = '', key, readOnly } = resolvedProps;
|
|
24
|
+
|
|
25
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
26
|
+
const [inputValue, setInputValue] = useState(value);
|
|
27
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
28
|
+
const [phoneValue, setPhoneValue] = useState('+16397975093');
|
|
29
|
+
|
|
30
|
+
const variant = displayMode === 'LABELS_LEFT' ? 'inline' : 'stacked';
|
|
31
|
+
|
|
32
|
+
let val =
|
|
33
|
+
value !== '' ? (
|
|
34
|
+
<Text
|
|
35
|
+
variant='h1'
|
|
36
|
+
as='span'
|
|
37
|
+
key={key}
|
|
38
|
+
onChange={e => {
|
|
39
|
+
setInputValue(e.target.value);
|
|
40
|
+
}}
|
|
41
|
+
>
|
|
42
|
+
{inputValue}
|
|
43
|
+
</Text>
|
|
44
|
+
) : (
|
|
45
|
+
''
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
{{! pick new delimiters for mustache }}
|
|
49
|
+
{{=<% %>=}}
|
|
50
|
+
|
|
51
|
+
if (label === 'Service Date')
|
|
52
|
+
val = (
|
|
53
|
+
<DateInput
|
|
54
|
+
value={inputValue}
|
|
55
|
+
style={{ fontSize: '14px' }}
|
|
56
|
+
key={key}
|
|
57
|
+
onChange={dateVal => {
|
|
58
|
+
const { valueAsISOString: date } = dateVal;
|
|
59
|
+
const trimmedDate = date ? date.substring(0, date.indexOf('T')) : date;
|
|
60
|
+
setInputValue(trimmedDate);
|
|
61
|
+
}}
|
|
62
|
+
/>
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
if (label === 'Email')
|
|
66
|
+
val = (
|
|
67
|
+
<Input
|
|
68
|
+
type='email'
|
|
69
|
+
value={inputValue}
|
|
70
|
+
style={{ fontSize: '14px' }}
|
|
71
|
+
key={key}
|
|
72
|
+
onChange={e => {
|
|
73
|
+
setInputValue(e.target.value);
|
|
74
|
+
}}
|
|
75
|
+
/>
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
if (label === 'First Name' || label === 'Last Name' || label === 'Middle Name')
|
|
79
|
+
val = (
|
|
80
|
+
<Input
|
|
81
|
+
value={inputValue}
|
|
82
|
+
style={{ fontSize: '14px' }}
|
|
83
|
+
key={key}
|
|
84
|
+
onChange={e => {
|
|
85
|
+
setInputValue(e.target.value);
|
|
86
|
+
}}
|
|
87
|
+
/>
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
if (label === 'Phone Number')
|
|
91
|
+
val = (
|
|
92
|
+
<CosmosPhone
|
|
93
|
+
value={phoneValue}
|
|
94
|
+
showCountryCode
|
|
95
|
+
style={{ fontSize: '14px' }}
|
|
96
|
+
key={key}
|
|
97
|
+
onChange={phoneVal => {
|
|
98
|
+
setPhoneValue(phoneVal);
|
|
99
|
+
}}
|
|
100
|
+
/>
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
<%={{ }}=%> {{! revert delimiters for mustache }}
|
|
104
|
+
|
|
105
|
+
if (variant === 'inline') {
|
|
106
|
+
val = value || (
|
|
107
|
+
<span
|
|
108
|
+
aria-hidden='true'
|
|
109
|
+
key={key}
|
|
110
|
+
onChange={e => {
|
|
111
|
+
setInputValue(e.target.value);
|
|
112
|
+
}}
|
|
113
|
+
>
|
|
114
|
+
––
|
|
115
|
+
</span>
|
|
116
|
+
);
|
|
117
|
+
} else {
|
|
118
|
+
val = (
|
|
119
|
+
<Text
|
|
120
|
+
variant='h1'
|
|
121
|
+
as='span'
|
|
122
|
+
key={key}
|
|
123
|
+
onChange={e => {
|
|
124
|
+
setInputValue(e.target.value);
|
|
125
|
+
}}
|
|
126
|
+
>
|
|
127
|
+
{val}
|
|
128
|
+
</Text>
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
if (readOnly) {
|
|
132
|
+
return {
|
|
133
|
+
getPConnect: () => {
|
|
134
|
+
return {
|
|
135
|
+
getRawMetadata: () => {
|
|
136
|
+
return {};
|
|
137
|
+
},
|
|
138
|
+
resolveConfigProps: props => {
|
|
139
|
+
return props;
|
|
140
|
+
},
|
|
141
|
+
getConfigProps: () => {
|
|
142
|
+
return {
|
|
143
|
+
value: '',
|
|
144
|
+
label: label,
|
|
145
|
+
displayMode: 'LABELS_LEFT'
|
|
146
|
+
};
|
|
147
|
+
},
|
|
148
|
+
getComponent: () => {
|
|
149
|
+
return val;
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
return (
|
|
156
|
+
<FieldValueList
|
|
157
|
+
variant={variant}
|
|
158
|
+
fields={[{ name: label, value: val }]}
|
|
159
|
+
key={key}
|
|
160
|
+
onChange={() => {
|
|
161
|
+
/* nothing */
|
|
162
|
+
}}
|
|
163
|
+
/>
|
|
164
|
+
);
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
export const Base{{COMPONENT_CLASS_NAME}}: Story = args => {
|
|
168
|
+
const { readOnly } = args;
|
|
169
|
+
|
|
170
|
+
const props = {
|
|
171
|
+
readOnly: readOnly,
|
|
172
|
+
getPConnect: () => {
|
|
173
|
+
return {
|
|
174
|
+
getChildren: () => {
|
|
175
|
+
return pyReviewRaw.children;
|
|
176
|
+
},
|
|
177
|
+
getInheritedProps: () => {
|
|
178
|
+
return pyReviewRaw.config.inheritedProps;
|
|
179
|
+
},
|
|
180
|
+
createComponent: config => {
|
|
181
|
+
// eslint-disable-next-line default-case
|
|
182
|
+
switch (config.config.value) {
|
|
183
|
+
case '@P .FirstName':
|
|
184
|
+
return renderField({
|
|
185
|
+
...regionChildrenResolved[0],
|
|
186
|
+
readOnly,
|
|
187
|
+
displayMode: readOnly ? 'LABELS_LEFT' : ''
|
|
188
|
+
});
|
|
189
|
+
case '@P .MiddleName':
|
|
190
|
+
return renderField({
|
|
191
|
+
...regionChildrenResolved[1],
|
|
192
|
+
readOnly,
|
|
193
|
+
displayMode: readOnly ? 'LABELS_LEFT' : ''
|
|
194
|
+
});
|
|
195
|
+
case '@P .LastName':
|
|
196
|
+
return renderField({
|
|
197
|
+
...regionChildrenResolved[2],
|
|
198
|
+
readOnly,
|
|
199
|
+
displayMode: readOnly ? 'LABELS_LEFT' : ''
|
|
200
|
+
});
|
|
201
|
+
case '@P .Email':
|
|
202
|
+
return renderField({
|
|
203
|
+
...regionChildrenResolved[3],
|
|
204
|
+
readOnly,
|
|
205
|
+
displayMode: readOnly ? 'LABELS_LEFT' : ''
|
|
206
|
+
});
|
|
207
|
+
case '@P .PhoneNumber':
|
|
208
|
+
return renderField({
|
|
209
|
+
...regionChildrenResolved[4],
|
|
210
|
+
readOnly,
|
|
211
|
+
displayMode: readOnly ? 'LABELS_LEFT' : ''
|
|
212
|
+
});
|
|
213
|
+
case '@P .ServiceDate':
|
|
214
|
+
return renderField({
|
|
215
|
+
...regionChildrenResolved[5],
|
|
216
|
+
readOnly,
|
|
217
|
+
displayMode: readOnly ? 'LABELS_LEFT' : ''
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
const regionAChildren = readOnly
|
|
226
|
+
? {
|
|
227
|
+
props: {
|
|
228
|
+
getPConnect: () => {
|
|
229
|
+
return {
|
|
230
|
+
getChildren: () => {
|
|
231
|
+
return pyReviewRaw.children[0].children.map(child => {
|
|
232
|
+
return props.getPConnect().createComponent(child);
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
: pyReviewRaw.children[0].children.map(child => {
|
|
240
|
+
return props.getPConnect().createComponent(child);
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
const regionBChildren = readOnly
|
|
244
|
+
? {
|
|
245
|
+
props: {
|
|
246
|
+
getPConnect: () => {
|
|
247
|
+
return {
|
|
248
|
+
getChildren: () => {
|
|
249
|
+
return pyReviewRaw.children[1].children.map(child => {
|
|
250
|
+
return props.getPConnect().createComponent(child);
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
: pyReviewRaw.children[1].children.map(child => {
|
|
258
|
+
return props.getPConnect().createComponent(child);
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
return (
|
|
262
|
+
<{{COMPONENT_CLASS_NAME}} {...props} {...args}>
|
|
263
|
+
{[regionAChildren, regionBChildren]}
|
|
264
|
+
</{{COMPONENT_CLASS_NAME}}>
|
|
265
|
+
);
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
Base{{COMPONENT_CLASS_NAME}}.args = {
|
|
269
|
+
readOnly: false,
|
|
270
|
+
showLabel: true,
|
|
271
|
+
label: 'Form Region template',
|
|
272
|
+
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// import { expect, test } from '@jest/globals';
|
|
2
|
+
import { render, screen } from '@testing-library/react';
|
|
3
|
+
import { composeStories } from '@storybook/react';
|
|
4
|
+
import '@testing-library/jest-dom';
|
|
5
|
+
|
|
6
|
+
import * as DemoStories from './demo.stories';
|
|
7
|
+
|
|
8
|
+
const { Base{{COMPONENT_CLASS_NAME}} } = composeStories(DemoStories);
|
|
9
|
+
|
|
10
|
+
test('renders {{COMPONENT_CLASS_NAME}}', async () => {
|
|
11
|
+
render(<Base{{COMPONENT_CLASS_NAME}} />);
|
|
12
|
+
expect(await screen.findByText('Form Region template')).toBeVisible();
|
|
13
|
+
|
|
14
|
+
// labels
|
|
15
|
+
expect(await screen.findByText('First Name')).toBeVisible();
|
|
16
|
+
expect(await screen.findByText('Middle Name')).toBeVisible();
|
|
17
|
+
expect(await screen.findByText('Last Name')).toBeVisible();
|
|
18
|
+
expect(await screen.findByText('Email')).toBeVisible();
|
|
19
|
+
expect(await screen.findByText('Phone Number')).toBeVisible();
|
|
20
|
+
expect(await screen.findByText('Service Date')).toBeVisible();
|
|
21
|
+
|
|
22
|
+
const inputElements = screen.getAllByTestId(':input:control');
|
|
23
|
+
expect((inputElements[0] as HTMLInputElement).value).toBe('John');
|
|
24
|
+
expect((inputElements[1] as HTMLInputElement).value).toBe('');
|
|
25
|
+
expect((inputElements[2] as HTMLInputElement).value).toBe('Doe');
|
|
26
|
+
expect((inputElements[3] as HTMLInputElement).value).toBe('John@doe.com');
|
|
27
|
+
|
|
28
|
+
const myPhone = (screen.getByTestId(':phone-input:control') as HTMLInputElement).value;
|
|
29
|
+
expect(myPhone).toContain('(639) 797-5093');
|
|
30
|
+
|
|
31
|
+
const myClearMonth = (screen.getByTestId(':date-input:control-month') as HTMLInputElement).value;
|
|
32
|
+
expect(myClearMonth).toContain('01');
|
|
33
|
+
|
|
34
|
+
const myClearDay = (screen.getByTestId(':date-input:control-day') as HTMLInputElement).value;
|
|
35
|
+
expect(myClearDay).toContain('25');
|
|
36
|
+
|
|
37
|
+
const myClearYear = (screen.getByTestId(':date-input:control-year') as HTMLInputElement).value;
|
|
38
|
+
expect(myClearYear).toContain('2023');
|
|
39
|
+
|
|
40
|
+
// verify 2 columns
|
|
41
|
+
const fieldSet = screen.getByRole('group');
|
|
42
|
+
|
|
43
|
+
// <fieldset>
|
|
44
|
+
// <legend></legend>
|
|
45
|
+
// <div>
|
|
46
|
+
// <div>
|
|
47
|
+
// <div> 2 divs (columns) </div>
|
|
48
|
+
// </div>
|
|
49
|
+
// </div>
|
|
50
|
+
// </fieldset>
|
|
51
|
+
|
|
52
|
+
// eslint-disable-next-line testing-library/no-node-access
|
|
53
|
+
expect(fieldSet.children[1].children[0].children[0].children).toHaveLength(2);
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
});
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { Grid, Flex, FieldGroup, withConfiguration } from '@pega/cosmos-react-core';
|
|
2
|
+
|
|
3
|
+
import type { PConnFieldProps } from './PConnProps';
|
|
4
|
+
import './create-nonce';
|
|
5
|
+
import DetailsRender from './DetailsRender';
|
|
6
|
+
|
|
7
|
+
import Styled{{COMPONENT_CLASS_NAME}}Wrapper from './styles';
|
|
8
|
+
|
|
9
|
+
// interface for props
|
|
10
|
+
interface {{COMPONENT_CLASS_NAME}}Props extends PConnFieldProps {
|
|
11
|
+
// If any, enter additional props that only exist on TextInput here
|
|
12
|
+
showLabel: boolean;
|
|
13
|
+
children: any;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// props passed in combination of props from property panel (config.json) and run time props from Constellation
|
|
17
|
+
// any default values in config.pros should be set in defaultProps at bottom of this file
|
|
18
|
+
function {{COMPONENT_CLASS_NAME}}(props: {{COMPONENT_CLASS_NAME}}Props) {
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
const { children = [], label, showLabel, getPConnect, readOnly, displayMode } = props;
|
|
22
|
+
const propsToUse = { label, showLabel, ...getPConnect().getInheritedProps() };
|
|
23
|
+
|
|
24
|
+
const numRegions = children?.length;
|
|
25
|
+
const gridRepeat = "repeat(".concat(numRegions).concat(", 1fr)");
|
|
26
|
+
const gridContainer = {"colGap" : 6};
|
|
27
|
+
// @ts-ignore
|
|
28
|
+
gridContainer.cols = gridRepeat;
|
|
29
|
+
// @ts-ignore
|
|
30
|
+
gridContainer.alignItems = 'start';
|
|
31
|
+
|
|
32
|
+
const flexContainer = {direction: 'column'};
|
|
33
|
+
// @ts-ignore
|
|
34
|
+
flexContainer.gap = 2;
|
|
35
|
+
|
|
36
|
+
if (readOnly && readOnly === true || displayMode && displayMode === 'DISPLAY_ONLY') {
|
|
37
|
+
return (
|
|
38
|
+
<Styled{{COMPONENT_CLASS_NAME}}Wrapper>
|
|
39
|
+
{{! pick new delimiters for mustache }}
|
|
40
|
+
{{=<% %>=}}
|
|
41
|
+
<FieldGroup name={propsToUse.showLabel ? propsToUse.label : ''}>
|
|
42
|
+
<Grid container={gridContainer} data-testid={`column-count-${numRegions}`}>
|
|
43
|
+
{children.map((child: any, i: number) => (
|
|
44
|
+
<Flex
|
|
45
|
+
// @ts-ignore
|
|
46
|
+
container={{ direction: 'column', alignItems: 'normal', colGap: 1, rowGap: 1.5 }}
|
|
47
|
+
key={`r-${i + 1}`}
|
|
48
|
+
>
|
|
49
|
+
<DetailsRender child={child} />
|
|
50
|
+
</Flex>
|
|
51
|
+
))}
|
|
52
|
+
</Grid>
|
|
53
|
+
</FieldGroup>
|
|
54
|
+
<%={{ }}=%> {{! revert delimiters for mustache }}
|
|
55
|
+
</Styled{{COMPONENT_CLASS_NAME}}Wrapper>
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return (
|
|
60
|
+
<Styled{{COMPONENT_CLASS_NAME}}Wrapper>
|
|
61
|
+
{{! pick new delimiters for mustache }}
|
|
62
|
+
{{=<% %>=}}
|
|
63
|
+
<FieldGroup name={propsToUse.showLabel ? propsToUse.label : ''}>
|
|
64
|
+
<Grid container={gridContainer}>
|
|
65
|
+
{children.map((child: any, i: number) => (
|
|
66
|
+
// @ts-ignore
|
|
67
|
+
<Flex container={flexContainer} key={`r-${i + 1}`}>
|
|
68
|
+
{child}
|
|
69
|
+
</Flex>
|
|
70
|
+
))}
|
|
71
|
+
</Grid>
|
|
72
|
+
</FieldGroup>
|
|
73
|
+
<%={{ }}=%> {{! revert delimiters for mustache }}
|
|
74
|
+
</Styled{{COMPONENT_CLASS_NAME}}Wrapper>
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
export default withConfiguration({{COMPONENT_CLASS_NAME}});
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
export const pyReviewRaw = {
|
|
4
|
+
name: 'CollectInformation',
|
|
5
|
+
type: 'View',
|
|
6
|
+
config: {
|
|
7
|
+
template: 'DefaultForm',
|
|
8
|
+
ruleClass: 'OM5W9U-SampleApp-Work-Test',
|
|
9
|
+
localeReference: '@LR OM5W9U-SAMPLEAPP-WORK-TEST!VIEW!COLLECTINFORMATION',
|
|
10
|
+
context: '@P .pyViewContext'
|
|
11
|
+
},
|
|
12
|
+
children: [
|
|
13
|
+
{
|
|
14
|
+
name: 'A',
|
|
15
|
+
type: 'Region',
|
|
16
|
+
children: [
|
|
17
|
+
{
|
|
18
|
+
type: 'TextInput',
|
|
19
|
+
config: {
|
|
20
|
+
value: '@P .FirstName',
|
|
21
|
+
label: '@L First Name',
|
|
22
|
+
key: 'FirstName'
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
type: 'TextInput',
|
|
27
|
+
config: {
|
|
28
|
+
value: '@P .MiddleName',
|
|
29
|
+
label: '@L Middle Name',
|
|
30
|
+
key: 'MiddleName'
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
type: 'TextInput',
|
|
35
|
+
config: {
|
|
36
|
+
value: '@P .LastName',
|
|
37
|
+
label: '@L Last Name',
|
|
38
|
+
key: 'LastName'
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
]
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
name: 'B',
|
|
45
|
+
type: 'Region',
|
|
46
|
+
children: [
|
|
47
|
+
{
|
|
48
|
+
type: 'Email',
|
|
49
|
+
config: {
|
|
50
|
+
value: '@P .Email',
|
|
51
|
+
label: '@L Email',
|
|
52
|
+
key: 'Email'
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
type: 'Phone',
|
|
57
|
+
config: {
|
|
58
|
+
value: '@P .PhoneNumber',
|
|
59
|
+
label: '@L Phone Number',
|
|
60
|
+
datasource: {
|
|
61
|
+
},
|
|
62
|
+
key: 'PhoneNumber'
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
type: 'Date',
|
|
67
|
+
config: {
|
|
68
|
+
value: '@P .ServiceDate',
|
|
69
|
+
label: '@L Service Date',
|
|
70
|
+
key: 'ServiceDate'
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
]
|
|
74
|
+
}
|
|
75
|
+
],
|
|
76
|
+
classID: 'OM5W9U-SampleApp-Work-Test'
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export const regionChildrenResolved = [
|
|
80
|
+
{
|
|
81
|
+
readOnly: undefined,
|
|
82
|
+
value: 'John',
|
|
83
|
+
label: 'First Name',
|
|
84
|
+
hasSuggestions: false,
|
|
85
|
+
key: 'First Name'
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
readOnly: undefined,
|
|
89
|
+
value: '',
|
|
90
|
+
label: 'Middle Name',
|
|
91
|
+
hasSuggestions: false,
|
|
92
|
+
key: 'Middle Name'
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
readOnly: undefined,
|
|
96
|
+
value: 'Doe',
|
|
97
|
+
label: 'Last Name',
|
|
98
|
+
hasSuggestions: false,
|
|
99
|
+
key: 'Last Name'
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
readOnly: undefined,
|
|
103
|
+
value: 'John@doe.com',
|
|
104
|
+
label: 'Email',
|
|
105
|
+
hasSuggestions: false,
|
|
106
|
+
key: 'Email'
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
readOnly: undefined,
|
|
110
|
+
value: '+16397975093',
|
|
111
|
+
label: 'Phone Number',
|
|
112
|
+
datasource: {
|
|
113
|
+
fields: {
|
|
114
|
+
value: undefined
|
|
115
|
+
},
|
|
116
|
+
source: [
|
|
117
|
+
{
|
|
118
|
+
value: '+1'
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
value: '+91'
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
value: '+48'
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
value: '+44'
|
|
128
|
+
}
|
|
129
|
+
]
|
|
130
|
+
},
|
|
131
|
+
hasSuggestions: false,
|
|
132
|
+
key: 'Phone Number'
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
readOnly: undefined,
|
|
136
|
+
value: '2023-01-25',
|
|
137
|
+
label: 'Service Date',
|
|
138
|
+
hasSuggestions: false,
|
|
139
|
+
key: 'Service Date'
|
|
140
|
+
}
|
|
141
|
+
];
|
|
@@ -242,6 +242,12 @@ addDebugLog("deleteLibrary", "", "+");
|
|
|
242
242
|
}
|
|
243
243
|
|
|
244
244
|
libraryName = inputConfig.libraryName;
|
|
245
|
+
if (libraryName.indexOf("_") < 0) {
|
|
246
|
+
// need to add in organization
|
|
247
|
+
libraryName = `${compDef.organization}_${libraryName}`;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
|
|
245
251
|
version = inputConfig.libraryVersion;
|
|
246
252
|
const isPermanent = inputConfig?.isPermanent || "N";
|
|
247
253
|
let permBuild = convertYNToBoolean(isPermanent);
|
|
@@ -4,6 +4,24 @@
|
|
|
4
4
|
|
|
5
5
|
This project provides you with an environment to extend Constellation by giving you tools to create and publish custom components that are not available from the Constellation installation.
|
|
6
6
|
|
|
7
|
+
## Before you begin
|
|
8
|
+
Review the following checklist before you create a Constellation DX component:
|
|
9
|
+
|
|
10
|
+
## Design considerations
|
|
11
|
+
Involve an Experience Designer in your process. This will help you determine the exact issue to be resolved. For more information on the role of an Experience Designer, see **Experience Designer**[here](https://community.pega.com/roles/experience-designer).
|
|
12
|
+
|
|
13
|
+
## The Experience Designer must meet the following requirements:
|
|
14
|
+
Must have a background in UI and UX design.
|
|
15
|
+
Must understand Pega's best practices for design. For more information, see **Best practices for designing with the Constellation design system**[here](https://design.pega.com/design/getting-started/).
|
|
16
|
+
|
|
17
|
+
## Functionality considerations
|
|
18
|
+
Check if an existing component in App Studio contains the features you need. If not, check for existing components that contain similar features.
|
|
19
|
+
Connect with Pega Support to find out if a component containing a similar feature will be included in the next release. If yes, assess if you can wait for the next release.
|
|
20
|
+
|
|
21
|
+
## Maintenance considerations
|
|
22
|
+
Ensure you have the bandwidth to maintain the Constellation DX component and keep it up-to-date with every release of Pega Infinity. Evaluate if doing this might prevent you from upgrading to future releases of Pega Infinity.
|
|
23
|
+
Evaluate if you are able to meet the compliance standards for data privacy and accessibility for Constellation DX components. Note that not meeting these standards might lead to legal compliance issues.
|
|
24
|
+
|
|
7
25
|
## Prerequisites
|
|
8
26
|
|
|
9
27
|
Ensure you have access to the following in your system:
|
|
@@ -107,8 +107,8 @@
|
|
|
107
107
|
"@babel/preset-react": "^7.27.1",
|
|
108
108
|
"@babel/preset-typescript": "^7.27.1",
|
|
109
109
|
"@pega/configs": "^0.16.3",
|
|
110
|
-
"@pega/custom-dx-components": "~0.25.
|
|
111
|
-
"@pega/pcore-pconnect-typedefs": "^4.
|
|
110
|
+
"@pega/custom-dx-components": "~0.25.55",
|
|
111
|
+
"@pega/pcore-pconnect-typedefs": "^4.0.0-alpha.0",
|
|
112
112
|
"@storybook/addon-actions": "^8.6.14",
|
|
113
113
|
"@storybook/addon-essentials": "^8.6.14",
|
|
114
114
|
"@storybook/addon-links": "^8.6.14",
|
|
@@ -11,7 +11,10 @@ import {
|
|
|
11
11
|
getLibraryBased,
|
|
12
12
|
restoreFromArchive,
|
|
13
13
|
cleanUpTemp,
|
|
14
|
-
forceDefaultsUpdate
|
|
14
|
+
forceDefaultsUpdate,
|
|
15
|
+
getUseInputConfig,
|
|
16
|
+
getInputConfigForCommand,
|
|
17
|
+
convertYNToBoolean
|
|
15
18
|
} from '../../util.js';
|
|
16
19
|
|
|
17
20
|
import { showCurrentStatus } from '../show-status/index.js';
|
|
@@ -19,6 +22,7 @@ import {
|
|
|
19
22
|
export default async options => {
|
|
20
23
|
await showVersion();
|
|
21
24
|
await checkLibraryAndArchives();
|
|
25
|
+
const useInputConfig = getUseInputConfig();
|
|
22
26
|
|
|
23
27
|
addDebugLog("restoreComponent", "", "+");
|
|
24
28
|
|
|
@@ -31,26 +35,43 @@ addDebugLog("restoreComponent", "", "+");
|
|
|
31
35
|
}
|
|
32
36
|
const confDef = getConfigDefaults();
|
|
33
37
|
|
|
34
|
-
console.log(chalk.bold.yellow('\nChanges not saved to local storage will be LOST, code will be restored from local storage.'));
|
|
35
|
-
console.log("");
|
|
36
38
|
|
|
37
39
|
let restoreFromStore = {};
|
|
38
40
|
|
|
39
|
-
if (
|
|
40
|
-
const
|
|
41
|
-
|
|
41
|
+
if (useInputConfig) {
|
|
42
|
+
const inputConfig = await getInputConfigForCommand("restoreLibVersion");
|
|
43
|
+
if (!inputConfig || Object.keys(inputConfig).length === 0) {
|
|
44
|
+
console.log(chalk.redBright("Configured for input config, but no input.config.json file found."));
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const okToRestore = convertYNToBoolean(inputConfig.okToRestore);
|
|
49
|
+
|
|
50
|
+
restoreFromStore.confirmRestore = okToRestore;
|
|
51
|
+
|
|
42
52
|
}
|
|
43
53
|
else {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
54
|
+
console.log(chalk.bold.yellow('\nChanges not saved to local storage will be LOST, code will be restored from local storage.'));
|
|
55
|
+
console.log("");
|
|
56
|
+
|
|
57
|
+
if (options.params.length === 4) {
|
|
58
|
+
const optConfirm = options.params[3];
|
|
59
|
+
restoreFromStore["confirmRestore"] = optConfirm === 'Y' || optConfirm === 'y' || optConfirm === true || optConfirm === 'true' ? true : false;
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
restoreFromStore = await inquirer.prompt([
|
|
63
|
+
{
|
|
64
|
+
name: 'confirmRestore',
|
|
65
|
+
type: 'confirm',
|
|
66
|
+
message: `Restoring ${chalk.bold.green(`${confDef.displayLibVersion}`)} from local storage, proceed ?`,
|
|
67
|
+
default: true
|
|
68
|
+
}
|
|
69
|
+
]);
|
|
70
|
+
}
|
|
52
71
|
}
|
|
53
72
|
|
|
73
|
+
|
|
74
|
+
|
|
54
75
|
if (restoreFromStore.confirmRestore) {
|
|
55
76
|
const switchToFileName = `${confDef.currentOrgLib}_${confDef.version}.arch.zip`;
|
|
56
77
|
const tasks = new Listr(
|