@pega/custom-dx-components 0.24.7 → 0.24.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. package/package.json +1 -1
  2. package/src/constants.js +4 -0
  3. package/src/tasks/create/index.js +3 -0
  4. package/src/tasks/create/templates/Constellation/Field/Icon-Button-URL/PConnProps.d.ts.mustache +46 -0
  5. package/src/tasks/create/templates/Constellation/Field/Icon-Button-URL/config.json.mustache +64 -0
  6. package/src/tasks/create/templates/Constellation/Field/Icon-Button-URL/demo.stories.tsx.mustache +99 -0
  7. package/src/tasks/create/templates/Constellation/Field/Icon-Button-URL/index.tsx.mustache +145 -0
  8. package/src/tasks/create/templates/Constellation/Field/Icon-Button-URL/mock.ts.mustache +5 -0
  9. package/src/tasks/create/templates/Constellation/Field/Icon-Button-URL/styles.ts.mustache +8 -0
  10. package/src/tasks/create/templates/Constellation/Widget/PAGE/index.tsx.mustache +1 -1
  11. package/src/tasks/create-all/index.js +3 -0
  12. package/src/tasks/init/template/package.json.mustache +1 -1
  13. package/src/tasks/validator/index.js +7 -1
  14. package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyIconButtonURL/PConnProps.d.ts +46 -0
  15. package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyIconButtonURL/config.json +64 -0
  16. package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyIconButtonURL/demo.stories.tsx +99 -0
  17. package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyIconButtonURL/index.tsx +142 -0
  18. package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyIconButtonURL/mock.ts +5 -0
  19. package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyIconButtonURL/styles.ts +8 -0
  20. package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyPageWidget/index.tsx +1 -1
  21. package/tests/assets/components/createAll/Launchpad/Pega_DXIL_MyIconButtonURL/PConnProps.d.ts +46 -0
  22. package/tests/assets/components/createAll/Launchpad/Pega_DXIL_MyIconButtonURL/config.json +64 -0
  23. package/tests/assets/components/createAll/Launchpad/Pega_DXIL_MyIconButtonURL/demo.stories.tsx +99 -0
  24. package/tests/assets/components/createAll/Launchpad/Pega_DXIL_MyIconButtonURL/index.tsx +142 -0
  25. package/tests/assets/components/createAll/Launchpad/Pega_DXIL_MyIconButtonURL/mock.ts +5 -0
  26. package/tests/assets/components/createAll/Launchpad/Pega_DXIL_MyIconButtonURL/styles.ts +8 -0
  27. package/tests/assets/components/createAll/Launchpad/Pega_DXIL_MyPageWidget/index.tsx +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pega/custom-dx-components",
3
- "version": "0.24.7",
3
+ "version": "0.24.9",
4
4
  "description": "Utility for building custom UI components",
5
5
  "bin": "./bin/index.js",
6
6
  "scripts": {
package/src/constants.js CHANGED
@@ -139,6 +139,10 @@ export const COMPONENT_SCHEMA = {
139
139
  name: 'URL',
140
140
  value: 'Text-URL'
141
141
  },
142
+ {
143
+ name: 'Icon Button URL',
144
+ value: 'Icon-Button-URL'
145
+ },
142
146
  {
143
147
  name: 'Integer',
144
148
  value: 'Integer'
@@ -73,6 +73,9 @@ const compileMustacheTemplates = async (
73
73
  case 'Picklist-RadioButtons':
74
74
  mustacheSubType = 'Picklist';
75
75
  break;
76
+ case 'Icon-Button-URL':
77
+ mustacheSubType = 'Text-URL';
78
+ break;
76
79
  }
77
80
  }
78
81
 
@@ -0,0 +1,46 @@
1
+ import {PConnect } from '@pega/pcore-pconnect-typedefs';
2
+
3
+ // PConnProps.d.ts
4
+ // This gives us a place to have each component (which is most DX Components) that is
5
+ // expected to have a getPConnect extend its props (from BaseProps)
6
+ // such that every component will be expected to have a getPConnect() function
7
+ // that returns a PConnect object. (new/better way of doing .propTypes).
8
+ // This PConnProps can be extended to include other props that we know are in every component
9
+ export interface PConnProps {
10
+ // getPConnect should exist for every C11n component. (add @ts-ignore in special cases where it isn't)
11
+ getPConnect: () => typeof PConnect;
12
+
13
+ // Allow any/all other key/value pairs in the BaseProps for now
14
+ // TODO: refine which other props are always expected for various component
15
+ // types and consider further interface "subclassing". For example, we may
16
+ // want to create a "BasePropsForm" that gives guidance on required, readonly, etc.
17
+ // and any other props that every Form component expects.
18
+ // For example, see the PConnFieldProps below.
19
+ // NOTE: if you uncomment the line below, the PConnProps type will allow
20
+ // otherwise undefined types to appear. This can be helpful for debugging
21
+ // or when adding new components whose types aren't yet known.
22
+ // [key: string]: any;
23
+ }
24
+
25
+
26
+ // PConnFieldProps extends PConnProps to bring in the common properties that are
27
+ // associated with most field components (ex: Dropdown, TextInput, etc.) in the
28
+ // components/field directory
29
+ export interface PConnFieldProps extends PConnProps {
30
+ label: string,
31
+ required: boolean,
32
+ disabled: boolean,
33
+ value: any,
34
+ validatemessage: string,
35
+ status?: string,
36
+ onChange?: any,
37
+ onBlur?: any,
38
+ readOnly: boolean,
39
+ testId: string,
40
+ helperText: string,
41
+ displayMode?: string,
42
+ hideLabel: boolean,
43
+ placeholder?: string,
44
+ fieldMetadata?: any,
45
+ additionalProps?: any
46
+ }
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "{{COMPONENT_KEY}}",
3
+ "label": "{{COMPONENT_LABEL}}",
4
+ "description": "{{DESCRIPTION}}",
5
+ "organization": "{{ORGANIZATION}}",
6
+ "version": "{{VERSION}}",
7
+ "library": "{{LIBRARY}}",
8
+ "allowedApplications": {{{ALLOWEDAPPS}}},
9
+ "componentKey": "{{COMPONENT_KEY}}",
10
+ "type": "{{TYPE}}",
11
+ "subtype": {{{SUB_TYPE}}},
12
+ "icon": "images/pz-url-active.svg",
13
+ "properties": [
14
+ {
15
+ "format": "SELECT",
16
+ "name": "countryCode",
17
+ "label": "Country code",
18
+ "defaultValue": "USA",
19
+ "source": [
20
+ {
21
+ "key": "USA",
22
+ "value": "United States"
23
+ },
24
+ {
25
+ "key": "CAN",
26
+ "value": "Canada"
27
+ },
28
+ {
29
+ "key": "AUS",
30
+ "value": "Australia"
31
+ },
32
+ {
33
+ "key": "JPN",
34
+ "value": "Japan"
35
+ },
36
+ {
37
+ "key": "IND",
38
+ "value": "India"
39
+ },
40
+ {
41
+ "key": "TUR",
42
+ "value": "Turkey"
43
+ }
44
+ ]
45
+ },
46
+ {
47
+ "label": "Advanced",
48
+ "format": "GROUP",
49
+ "collapsible": true,
50
+ "properties": [
51
+ {
52
+ "name": "testId",
53
+ "label": "Test ID",
54
+ "format": "TEXT",
55
+ "ignorePattern": "[^-_\\p{N}\\p{L}]",
56
+ "includeAnnotations": false
57
+ }
58
+ ]
59
+ }
60
+ ],
61
+ "defaultConfig": {
62
+ "label": "@L $this.label"
63
+ }
64
+ }
@@ -0,0 +1,99 @@
1
+
2
+ /* eslint-disable react/jsx-no-useless-fragment */
3
+ // @ts-nocheck
4
+ import type { Meta, StoryObj } from '@storybook/react';
5
+
6
+ import {{COMPONENT_CLASS_NAME}} from './index';
7
+ import { stateProps, configProps } from './mock';
8
+
9
+ const meta: Meta<typeof {{COMPONENT_CLASS_NAME}}> = {
10
+ title: '{{COMPONENT_CLASS_NAME}}',
11
+ component: {{COMPONENT_CLASS_NAME}},
12
+ excludeStories: /.*Data$/
13
+ };
14
+
15
+ export default meta;
16
+ type Story = StoryObj<typeof {{COMPONENT_CLASS_NAME}}>;
17
+
18
+ if (!window.PCore) {
19
+ window.PCore = {};
20
+ }
21
+
22
+ const statelistData = {
23
+ data: [
24
+ {
25
+ pyLabel: 'Massachusetts',
26
+ pyStateCode: 'MA'
27
+ },
28
+ {
29
+ pyLabel: 'Rhode Island',
30
+ pyStateCode: 'RI'
31
+ },
32
+ {
33
+ pyLabel: 'Connecticut',
34
+ pyStateCode: 'CT'
35
+ }
36
+ ]
37
+ };
38
+
39
+ window.PCore.getDataPageUtils = () => {
40
+ return {
41
+ getDataAsync: () => {
42
+ return new Promise(resolve => {
43
+ resolve(statelistData);
44
+ });
45
+ }
46
+ };
47
+ };
48
+
49
+ export const Base{{COMPONENT_CLASS_NAME}}: Story = args => {
50
+
51
+ const props = {
52
+ countryCode: configProps.countryCode,
53
+ getPConnect: () => {
54
+ return {
55
+ getValue: value => {
56
+ return value;
57
+ },
58
+ getContextName: () => {
59
+ return 'app/primary_1';
60
+ },
61
+ getLocalizedValue: value => {
62
+ return value;
63
+ },
64
+ getActionsApi: () => {
65
+ return {
66
+ updateFieldValue: () => {
67
+ /* nothing */
68
+ },
69
+ triggerFieldChange: () => {
70
+ /* nothing */
71
+ }
72
+ };
73
+ },
74
+ ignoreSuggestion: () => {
75
+ /* nothing */
76
+ },
77
+ acceptSuggestion: () => {
78
+ /* nothing */
79
+ },
80
+ setInheritedProps: () => {
81
+ /* nothing */
82
+ },
83
+ resolveConfigProps: () => {
84
+ /* nothing */
85
+ }
86
+ };
87
+ }
88
+ };
89
+
90
+ return (
91
+ <>
92
+ <{{COMPONENT_CLASS_NAME}} {...props} {...args} />
93
+ </>
94
+ );
95
+ };
96
+
97
+ Base{{COMPONENT_CLASS_NAME}}.args = {
98
+ countryCode: configProps.countryCode
99
+ };
@@ -0,0 +1,145 @@
1
+ import { useEffect, useState } from 'react';
2
+ import {
3
+ Icon,
4
+ Button,
5
+ withConfiguration,
6
+ registerIcon,
7
+ Table,
8
+ Label
9
+ } from '@pega/cosmos-react-core';
10
+ import type { PConnFieldProps } from './PConnProps';
11
+
12
+ // IMPORTANT
13
+ // To use Icons, need to individually import the icon file form @pega/cosmos-react-core (see path below)
14
+ // Icons filename is kabab case (file-name), where as the icon you import is camel case (fileName)
15
+ // Icons need to be registered (camel case), and then used (kabab case)
16
+ import * as listNumber from '@pega/cosmos-react-core/lib/components/Icon/icons/list-number.icon';
17
+ import * as arrowRight from '@pega/cosmos-react-core/lib/components/Icon/icons/arrow-right.icon';
18
+
19
+ import Styled{{COMPONENT_CLASS_NAME}}Wrapper from './styles';
20
+
21
+ // interface for props
22
+ interface {{COMPONENT_CLASS_NAME}}Props extends PConnFieldProps {
23
+ // If any, enter additional props that only exist on TextInput here
24
+ countryCode: string;
25
+ }
26
+
27
+ // *************
28
+ // This component is meant to be an example of usage (Icon, Button, etc.) and NOT meant to be
29
+ // used "as is"
30
+ //
31
+ // In this example, Icon is shown on its own and inside a Button
32
+ // Though an Icon can have an "onClick" event is it recommended if you want to click on it,
33
+ // to put it in a Button (shown below), so you can have a tooltip and hover style
34
+ //
35
+ // In this example, the click will get a list of states for a given country and display in a
36
+ // table below. The table dispaly will toggle with the click of the button icon.
37
+ //
38
+ // NOTE: because icons have to be imported and registered, you can NOT put the icon name
39
+ // inside the config.json and let the user pick it, if it is not already part of your
40
+ // import and registration (can't be done on the fly)
41
+ // **************
42
+
43
+ // props passed in combination of props from property panel (config.json) and run time props from Constellation
44
+ // any default values in config.pros should be set in defaultProps at bottom of this file
45
+ function {{COMPONENT_CLASS_NAME}}(props: {{COMPONENT_CLASS_NAME}}Props) {
46
+ const { countryCode = 'USA', getPConnect } = props;
47
+ const [statelist, setStatelist] = useState([]);
48
+ const [showTable, setShowTable] = useState(false);
49
+ const PConnect = getPConnect();
50
+
51
+ // IMPORTANT: need to register icons used in camel case
52
+ registerIcon(listNumber, arrowRight);
53
+
54
+
55
+ // setting up columns for the work list table
56
+ const columns = [
57
+ { renderer: 'stateName', label: PConnect.getLocalizedValue('State name', '', '') },
58
+ { renderer: 'stateCode', label: PConnect.getLocalizedValue('State code', '', '') }
59
+ ];
60
+
61
+ // toggle showing table and getting table data
62
+ function showHideTable() {
63
+ setShowTable(prevShowTable => !prevShowTable);
64
+ }
65
+
66
+ // going to get data for worklist to put into a table
67
+ // data comes from calling a PCore function to get
68
+ // get data from a data page and a PConnect function
69
+ // to get getContextName
70
+ useEffect(() => {
71
+ const dataViewName = 'D_pyStateList';
72
+ const context = PConnect.getContextName();
73
+ const params = { pyCountry: countryCode };
74
+
75
+ // only retrieve table data if table is shown
76
+ if (showTable) {
77
+ PCore.getDataPageUtils()
78
+ .getDataAsync(dataViewName, context, params, null, null)
79
+ // @ts-ignore
80
+ .then((response: any) => {
81
+ // table requires an index or will get setExtraStackFrame error
82
+ setStatelist(
83
+ response.data.map((entry: any, index: number) => {
84
+ // mapping the data into the column names
85
+ // MUST have an id/index or will get a setExtraStackFrame error
86
+ // put a key in the table
87
+ return {
88
+ stateName: entry.pyLabel,
89
+ stateCode: entry.pyStateCode,
90
+ id: index
91
+ };
92
+ })
93
+ );
94
+ })
95
+ .catch((error: any) => {
96
+ console.log(error);
97
+ });
98
+ }
99
+ }, [PConnect, countryCode, showTable]);
100
+
101
+ return (
102
+ <Styled{{COMPONENT_CLASS_NAME}}Wrapper>
103
+ {{! pick new delimiters for mustache }}
104
+ {{=<% %>=}}
105
+ <Icon
106
+ style={{ height: '1.5rem', width: '1.5rem' }}
107
+ // icon name is kabab case
108
+ name='arrow-right'
109
+ role='img'
110
+ aria-label='arrow right'
111
+ />
112
+ <Label>
113
+ {' '}
114
+ {PConnect.getLocalizedValue('State list for', '', '')}{' '}
115
+ {PConnect.getLocalizedValue(`${countryCode}`, '', '')}{' '}
116
+ </Label>
117
+ <Button
118
+ icon
119
+ label={PConnect.getLocalizedValue('Click to show/hide state list', '', '')}
120
+ variant='link'
121
+ compact={false}
122
+ onClick={showHideTable}
123
+ >
124
+ <Icon
125
+ style={{ height: '1.5rem', width: '1.5rem' }}
126
+ // icon name is kabab case
127
+ name='list-number'
128
+ role='img'
129
+ aria-label='numbered list'
130
+ />
131
+ </Button>
132
+ {showTable && (
133
+ <Table
134
+ title={PConnect.getLocalizedValue('State list', '', '')}
135
+ columns={columns}
136
+ data={statelist}
137
+ />
138
+ )}
139
+ <%={{ }}=%> {{! revert delimiters for mustache }}
140
+ </Styled{{COMPONENT_CLASS_NAME}}Wrapper>
141
+ );
142
+ }
143
+
144
+
145
+ export default withConfiguration({{COMPONENT_CLASS_NAME}});
@@ -0,0 +1,5 @@
1
+
2
+ // @ts-nocheck
3
+ export const configProps = {
4
+ countryCode: 'USA'
5
+ };
@@ -0,0 +1,8 @@
1
+ // individual style, comment out above, and uncomment here and add styles
2
+ import styled, { css } from 'styled-components';
3
+
4
+ export default styled.div(() => {
5
+ return css`
6
+ margin: 0px 0;
7
+ `;
8
+ });
@@ -48,7 +48,7 @@ function {{COMPONENT_CLASS_NAME}}(props: {{COMPONENT_CLASS_NAME}}Props) {
48
48
  const context = PConnect.getContextName();
49
49
 
50
50
  PCore.getDataPageUtils()
51
- .getDataAsync(dataViewName, context)
51
+ .getDataAsync(dataViewName, context, {}, null, null)
52
52
  // @ts-ignore
53
53
  .then((response: any) => {
54
54
  // table requires an index or will get setExtraStackFrame error
@@ -82,6 +82,9 @@ export const compileMustacheTemplates = async (
82
82
  case 'Picklist-RadioButtons':
83
83
  mustacheSubType = 'Picklist';
84
84
  break;
85
+ case 'Icon-Button-URL':
86
+ mustacheSubType = 'Text-URL';
87
+ break;
85
88
  }
86
89
  }
87
90
 
@@ -69,7 +69,7 @@
69
69
  },
70
70
  "devDependencies": {
71
71
  "@pega/configs": "^0.6.0",
72
- "@pega/custom-dx-components": "0.24.7",
72
+ "@pega/custom-dx-components": "0.24.9",
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",
@@ -350,7 +350,13 @@ export default async (option) => {
350
350
  }
351
351
 
352
352
  //const data = JSON.parse(fs.readFileSync(path.resolve(configFile), 'utf8'));
353
- const data = JSON.parse(configData);
353
+ let data;
354
+ try {
355
+ data = JSON.parse(configData);
356
+ }
357
+ catch (er) {
358
+ throw new Error(`Invalid schema json in config.json: ${er}`);
359
+ }
354
360
 
355
361
  const valid = validateSchema(data);
356
362
 
@@ -0,0 +1,46 @@
1
+ import {PConnect } from '@pega/pcore-pconnect-typedefs';
2
+
3
+ // PConnProps.d.ts
4
+ // This gives us a place to have each component (which is most DX Components) that is
5
+ // expected to have a getPConnect extend its props (from BaseProps)
6
+ // such that every component will be expected to have a getPConnect() function
7
+ // that returns a PConnect object. (new/better way of doing .propTypes).
8
+ // This PConnProps can be extended to include other props that we know are in every component
9
+ export interface PConnProps {
10
+ // getPConnect should exist for every C11n component. (add @ts-ignore in special cases where it isn't)
11
+ getPConnect: () => typeof PConnect;
12
+
13
+ // Allow any/all other key/value pairs in the BaseProps for now
14
+ // TODO: refine which other props are always expected for various component
15
+ // types and consider further interface "subclassing". For example, we may
16
+ // want to create a "BasePropsForm" that gives guidance on required, readonly, etc.
17
+ // and any other props that every Form component expects.
18
+ // For example, see the PConnFieldProps below.
19
+ // NOTE: if you uncomment the line below, the PConnProps type will allow
20
+ // otherwise undefined types to appear. This can be helpful for debugging
21
+ // or when adding new components whose types aren't yet known.
22
+ // [key: string]: any;
23
+ }
24
+
25
+
26
+ // PConnFieldProps extends PConnProps to bring in the common properties that are
27
+ // associated with most field components (ex: Dropdown, TextInput, etc.) in the
28
+ // components/field directory
29
+ export interface PConnFieldProps extends PConnProps {
30
+ label: string,
31
+ required: boolean,
32
+ disabled: boolean,
33
+ value: any,
34
+ validatemessage: string,
35
+ status?: string,
36
+ onChange?: any,
37
+ onBlur?: any,
38
+ readOnly: boolean,
39
+ testId: string,
40
+ helperText: string,
41
+ displayMode?: string,
42
+ hideLabel: boolean,
43
+ placeholder?: string,
44
+ fieldMetadata?: any,
45
+ additionalProps?: any
46
+ }
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "Pega_DXIL_MyIconButtonURL",
3
+ "label": "My Icon Button URL",
4
+ "description": "My Icon Button URL",
5
+ "organization": "Pega",
6
+ "version": "0.0.1",
7
+ "library": "DXIL",
8
+ "allowedApplications": [],
9
+ "componentKey": "Pega_DXIL_MyIconButtonURL",
10
+ "type": "Field",
11
+ "subtype": "Text-URL",
12
+ "icon": "images/pz-url-active.svg",
13
+ "properties": [
14
+ {
15
+ "format": "SELECT",
16
+ "name": "countryCode",
17
+ "label": "Country code",
18
+ "defaultValue": "USA",
19
+ "source": [
20
+ {
21
+ "key": "USA",
22
+ "value": "United States"
23
+ },
24
+ {
25
+ "key": "CAN",
26
+ "value": "Canada"
27
+ },
28
+ {
29
+ "key": "AUS",
30
+ "value": "Australia"
31
+ },
32
+ {
33
+ "key": "JPN",
34
+ "value": "Japan"
35
+ },
36
+ {
37
+ "key": "IND",
38
+ "value": "India"
39
+ },
40
+ {
41
+ "key": "TUR",
42
+ "value": "Turkey"
43
+ }
44
+ ]
45
+ },
46
+ {
47
+ "label": "Advanced",
48
+ "format": "GROUP",
49
+ "collapsible": true,
50
+ "properties": [
51
+ {
52
+ "name": "testId",
53
+ "label": "Test ID",
54
+ "format": "TEXT",
55
+ "ignorePattern": "[^-_\\p{N}\\p{L}]",
56
+ "includeAnnotations": false
57
+ }
58
+ ]
59
+ }
60
+ ],
61
+ "defaultConfig": {
62
+ "label": "@L $this.label"
63
+ }
64
+ }
@@ -0,0 +1,99 @@
1
+
2
+ /* eslint-disable react/jsx-no-useless-fragment */
3
+ // @ts-nocheck
4
+ import type { Meta, StoryObj } from '@storybook/react';
5
+
6
+ import PegaDxilMyIconButtonUrl from './index';
7
+ import { stateProps, configProps } from './mock';
8
+
9
+ const meta: Meta<typeof PegaDxilMyIconButtonUrl> = {
10
+ title: 'PegaDxilMyIconButtonUrl',
11
+ component: PegaDxilMyIconButtonUrl,
12
+ excludeStories: /.*Data$/
13
+ };
14
+
15
+ export default meta;
16
+ type Story = StoryObj<typeof PegaDxilMyIconButtonUrl>;
17
+
18
+ if (!window.PCore) {
19
+ window.PCore = {};
20
+ }
21
+
22
+ const statelistData = {
23
+ data: [
24
+ {
25
+ pyLabel: 'Massachusetts',
26
+ pyStateCode: 'MA'
27
+ },
28
+ {
29
+ pyLabel: 'Rhode Island',
30
+ pyStateCode: 'RI'
31
+ },
32
+ {
33
+ pyLabel: 'Connecticut',
34
+ pyStateCode: 'CT'
35
+ }
36
+ ]
37
+ };
38
+
39
+ window.PCore.getDataPageUtils = () => {
40
+ return {
41
+ getDataAsync: () => {
42
+ return new Promise(resolve => {
43
+ resolve(statelistData);
44
+ });
45
+ }
46
+ };
47
+ };
48
+
49
+ export const BasePegaDxilMyIconButtonUrl: Story = args => {
50
+
51
+ const props = {
52
+ countryCode: configProps.countryCode,
53
+ getPConnect: () => {
54
+ return {
55
+ getValue: value => {
56
+ return value;
57
+ },
58
+ getContextName: () => {
59
+ return 'app/primary_1';
60
+ },
61
+ getLocalizedValue: value => {
62
+ return value;
63
+ },
64
+ getActionsApi: () => {
65
+ return {
66
+ updateFieldValue: () => {
67
+ /* nothing */
68
+ },
69
+ triggerFieldChange: () => {
70
+ /* nothing */
71
+ }
72
+ };
73
+ },
74
+ ignoreSuggestion: () => {
75
+ /* nothing */
76
+ },
77
+ acceptSuggestion: () => {
78
+ /* nothing */
79
+ },
80
+ setInheritedProps: () => {
81
+ /* nothing */
82
+ },
83
+ resolveConfigProps: () => {
84
+ /* nothing */
85
+ }
86
+ };
87
+ }
88
+ };
89
+
90
+ return (
91
+ <>
92
+ <PegaDxilMyIconButtonUrl {...props} {...args} />
93
+ </>
94
+ );
95
+ };
96
+
97
+ BasePegaDxilMyIconButtonUrl.args = {
98
+ countryCode: configProps.countryCode
99
+ };
@@ -0,0 +1,142 @@
1
+ import { useEffect, useState } from 'react';
2
+ import {
3
+ Icon,
4
+ Button,
5
+ withConfiguration,
6
+ registerIcon,
7
+ Table,
8
+ Label
9
+ } from '@pega/cosmos-react-core';
10
+ import type { PConnFieldProps } from './PConnProps';
11
+
12
+ // IMPORTANT
13
+ // To use Icons, need to individually import the icon file form @pega/cosmos-react-core (see path below)
14
+ // Icons filename is kabab case (file-name), where as the icon you import is camel case (fileName)
15
+ // Icons need to be registered (camel case), and then used (kabab case)
16
+ import * as listNumber from '@pega/cosmos-react-core/lib/components/Icon/icons/list-number.icon';
17
+ import * as arrowRight from '@pega/cosmos-react-core/lib/components/Icon/icons/arrow-right.icon';
18
+
19
+ import StyledPegaDxilMyIconButtonUrlWrapper from './styles';
20
+
21
+ // interface for props
22
+ interface PegaDxilMyIconButtonUrlProps extends PConnFieldProps {
23
+ // If any, enter additional props that only exist on TextInput here
24
+ countryCode: string;
25
+ }
26
+
27
+ // *************
28
+ // This component is meant to be an example of usage (Icon, Button, etc.) and NOT meant to be
29
+ // used "as is"
30
+ //
31
+ // In this example, Icon is shown on its own and inside a Button
32
+ // Though an Icon can have an "onClick" event is it recommended if you want to click on it,
33
+ // to put it in a Button (shown below), so you can have a tooltip and hover style
34
+ //
35
+ // In this example, the click will get a list of states for a given country and display in a
36
+ // table below. The table dispaly will toggle with the click of the button icon.
37
+ //
38
+ // NOTE: because icons have to be imported and registered, you can NOT put the icon name
39
+ // inside the config.json and let the user pick it, if it is not already part of your
40
+ // import and registration (can't be done on the fly)
41
+ // **************
42
+
43
+ // props passed in combination of props from property panel (config.json) and run time props from Constellation
44
+ // any default values in config.pros should be set in defaultProps at bottom of this file
45
+ function PegaDxilMyIconButtonUrl(props: PegaDxilMyIconButtonUrlProps) {
46
+ const { countryCode = 'USA', getPConnect } = props;
47
+ const [statelist, setStatelist] = useState([]);
48
+ const [showTable, setShowTable] = useState(false);
49
+ const PConnect = getPConnect();
50
+
51
+ // IMPORTANT: need to register icons used in camel case
52
+ registerIcon(listNumber, arrowRight);
53
+
54
+
55
+ // setting up columns for the work list table
56
+ const columns = [
57
+ { renderer: 'stateName', label: PConnect.getLocalizedValue('State name', '', '') },
58
+ { renderer: 'stateCode', label: PConnect.getLocalizedValue('State code', '', '') }
59
+ ];
60
+
61
+ // toggle showing table and getting table data
62
+ function showHideTable() {
63
+ setShowTable(prevShowTable => !prevShowTable);
64
+ }
65
+
66
+ // going to get data for worklist to put into a table
67
+ // data comes from calling a PCore function to get
68
+ // get data from a data page and a PConnect function
69
+ // to get getContextName
70
+ useEffect(() => {
71
+ const dataViewName = 'D_pyStateList';
72
+ const context = PConnect.getContextName();
73
+ const params = { pyCountry: countryCode };
74
+
75
+ // only retrieve table data if table is shown
76
+ if (showTable) {
77
+ PCore.getDataPageUtils()
78
+ .getDataAsync(dataViewName, context, params, null, null)
79
+ // @ts-ignore
80
+ .then((response: any) => {
81
+ // table requires an index or will get setExtraStackFrame error
82
+ setStatelist(
83
+ response.data.map((entry: any, index: number) => {
84
+ // mapping the data into the column names
85
+ // MUST have an id/index or will get a setExtraStackFrame error
86
+ // put a key in the table
87
+ return {
88
+ stateName: entry.pyLabel,
89
+ stateCode: entry.pyStateCode,
90
+ id: index
91
+ };
92
+ })
93
+ );
94
+ })
95
+ .catch((error: any) => {
96
+ console.log(error);
97
+ });
98
+ }
99
+ }, [PConnect, countryCode, showTable]);
100
+
101
+ return (
102
+ <StyledPegaDxilMyIconButtonUrlWrapper>
103
+ <Icon
104
+ style={{ height: '1.5rem', width: '1.5rem' }}
105
+ // icon name is kabab case
106
+ name='arrow-right'
107
+ role='img'
108
+ aria-label='arrow right'
109
+ />
110
+ <Label>
111
+ {' '}
112
+ {PConnect.getLocalizedValue('State list for', '', '')}{' '}
113
+ {PConnect.getLocalizedValue(`${countryCode}`, '', '')}{' '}
114
+ </Label>
115
+ <Button
116
+ icon
117
+ label={PConnect.getLocalizedValue('Click to show/hide state list', '', '')}
118
+ variant='link'
119
+ compact={false}
120
+ onClick={showHideTable}
121
+ >
122
+ <Icon
123
+ style={{ height: '1.5rem', width: '1.5rem' }}
124
+ // icon name is kabab case
125
+ name='list-number'
126
+ role='img'
127
+ aria-label='numbered list'
128
+ />
129
+ </Button>
130
+ {showTable && (
131
+ <Table
132
+ title={PConnect.getLocalizedValue('State list', '', '')}
133
+ columns={columns}
134
+ data={statelist}
135
+ />
136
+ )}
137
+ </StyledPegaDxilMyIconButtonUrlWrapper>
138
+ );
139
+ }
140
+
141
+
142
+ export default withConfiguration(PegaDxilMyIconButtonUrl);
@@ -0,0 +1,5 @@
1
+
2
+ // @ts-nocheck
3
+ export const configProps = {
4
+ countryCode: 'USA'
5
+ };
@@ -0,0 +1,8 @@
1
+ // individual style, comment out above, and uncomment here and add styles
2
+ import styled, { css } from 'styled-components';
3
+
4
+ export default styled.div(() => {
5
+ return css`
6
+ margin: 0px 0;
7
+ `;
8
+ });
@@ -48,7 +48,7 @@ function PegaDxilMyPageWidget(props: PegaDxilMyPageWidgetProps) {
48
48
  const context = PConnect.getContextName();
49
49
 
50
50
  PCore.getDataPageUtils()
51
- .getDataAsync(dataViewName, context)
51
+ .getDataAsync(dataViewName, context, {}, null, null)
52
52
  // @ts-ignore
53
53
  .then((response: any) => {
54
54
  // table requires an index or will get setExtraStackFrame error
@@ -0,0 +1,46 @@
1
+ import {PConnect } from '@pega/pcore-pconnect-typedefs';
2
+
3
+ // PConnProps.d.ts
4
+ // This gives us a place to have each component (which is most DX Components) that is
5
+ // expected to have a getPConnect extend its props (from BaseProps)
6
+ // such that every component will be expected to have a getPConnect() function
7
+ // that returns a PConnect object. (new/better way of doing .propTypes).
8
+ // This PConnProps can be extended to include other props that we know are in every component
9
+ export interface PConnProps {
10
+ // getPConnect should exist for every C11n component. (add @ts-ignore in special cases where it isn't)
11
+ getPConnect: () => typeof PConnect;
12
+
13
+ // Allow any/all other key/value pairs in the BaseProps for now
14
+ // TODO: refine which other props are always expected for various component
15
+ // types and consider further interface "subclassing". For example, we may
16
+ // want to create a "BasePropsForm" that gives guidance on required, readonly, etc.
17
+ // and any other props that every Form component expects.
18
+ // For example, see the PConnFieldProps below.
19
+ // NOTE: if you uncomment the line below, the PConnProps type will allow
20
+ // otherwise undefined types to appear. This can be helpful for debugging
21
+ // or when adding new components whose types aren't yet known.
22
+ // [key: string]: any;
23
+ }
24
+
25
+
26
+ // PConnFieldProps extends PConnProps to bring in the common properties that are
27
+ // associated with most field components (ex: Dropdown, TextInput, etc.) in the
28
+ // components/field directory
29
+ export interface PConnFieldProps extends PConnProps {
30
+ label: string,
31
+ required: boolean,
32
+ disabled: boolean,
33
+ value: any,
34
+ validatemessage: string,
35
+ status?: string,
36
+ onChange?: any,
37
+ onBlur?: any,
38
+ readOnly: boolean,
39
+ testId: string,
40
+ helperText: string,
41
+ displayMode?: string,
42
+ hideLabel: boolean,
43
+ placeholder?: string,
44
+ fieldMetadata?: any,
45
+ additionalProps?: any
46
+ }
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "Pega_DXIL_MyIconButtonURL",
3
+ "label": "My Icon Button URL",
4
+ "description": "My Icon Button URL",
5
+ "organization": "Pega",
6
+ "version": "0.0.1",
7
+ "library": "DXIL",
8
+ "allowedApplications": [],
9
+ "componentKey": "Pega_DXIL_MyIconButtonURL",
10
+ "type": "Field",
11
+ "subtype": "Text-URL",
12
+ "icon": "images/pz-url-active.svg",
13
+ "properties": [
14
+ {
15
+ "format": "SELECT",
16
+ "name": "countryCode",
17
+ "label": "Country code",
18
+ "defaultValue": "USA",
19
+ "source": [
20
+ {
21
+ "key": "USA",
22
+ "value": "United States"
23
+ },
24
+ {
25
+ "key": "CAN",
26
+ "value": "Canada"
27
+ },
28
+ {
29
+ "key": "AUS",
30
+ "value": "Australia"
31
+ },
32
+ {
33
+ "key": "JPN",
34
+ "value": "Japan"
35
+ },
36
+ {
37
+ "key": "IND",
38
+ "value": "India"
39
+ },
40
+ {
41
+ "key": "TUR",
42
+ "value": "Turkey"
43
+ }
44
+ ]
45
+ },
46
+ {
47
+ "label": "Advanced",
48
+ "format": "GROUP",
49
+ "collapsible": true,
50
+ "properties": [
51
+ {
52
+ "name": "testId",
53
+ "label": "Test ID",
54
+ "format": "TEXT",
55
+ "ignorePattern": "[^-_\\p{N}\\p{L}]",
56
+ "includeAnnotations": false
57
+ }
58
+ ]
59
+ }
60
+ ],
61
+ "defaultConfig": {
62
+ "label": "@L $this.label"
63
+ }
64
+ }
@@ -0,0 +1,99 @@
1
+
2
+ /* eslint-disable react/jsx-no-useless-fragment */
3
+ // @ts-nocheck
4
+ import type { Meta, StoryObj } from '@storybook/react';
5
+
6
+ import PegaDxilMyIconButtonUrl from './index';
7
+ import { stateProps, configProps } from './mock';
8
+
9
+ const meta: Meta<typeof PegaDxilMyIconButtonUrl> = {
10
+ title: 'PegaDxilMyIconButtonUrl',
11
+ component: PegaDxilMyIconButtonUrl,
12
+ excludeStories: /.*Data$/
13
+ };
14
+
15
+ export default meta;
16
+ type Story = StoryObj<typeof PegaDxilMyIconButtonUrl>;
17
+
18
+ if (!window.PCore) {
19
+ window.PCore = {};
20
+ }
21
+
22
+ const statelistData = {
23
+ data: [
24
+ {
25
+ pyLabel: 'Massachusetts',
26
+ pyStateCode: 'MA'
27
+ },
28
+ {
29
+ pyLabel: 'Rhode Island',
30
+ pyStateCode: 'RI'
31
+ },
32
+ {
33
+ pyLabel: 'Connecticut',
34
+ pyStateCode: 'CT'
35
+ }
36
+ ]
37
+ };
38
+
39
+ window.PCore.getDataPageUtils = () => {
40
+ return {
41
+ getDataAsync: () => {
42
+ return new Promise(resolve => {
43
+ resolve(statelistData);
44
+ });
45
+ }
46
+ };
47
+ };
48
+
49
+ export const BasePegaDxilMyIconButtonUrl: Story = args => {
50
+
51
+ const props = {
52
+ countryCode: configProps.countryCode,
53
+ getPConnect: () => {
54
+ return {
55
+ getValue: value => {
56
+ return value;
57
+ },
58
+ getContextName: () => {
59
+ return 'app/primary_1';
60
+ },
61
+ getLocalizedValue: value => {
62
+ return value;
63
+ },
64
+ getActionsApi: () => {
65
+ return {
66
+ updateFieldValue: () => {
67
+ /* nothing */
68
+ },
69
+ triggerFieldChange: () => {
70
+ /* nothing */
71
+ }
72
+ };
73
+ },
74
+ ignoreSuggestion: () => {
75
+ /* nothing */
76
+ },
77
+ acceptSuggestion: () => {
78
+ /* nothing */
79
+ },
80
+ setInheritedProps: () => {
81
+ /* nothing */
82
+ },
83
+ resolveConfigProps: () => {
84
+ /* nothing */
85
+ }
86
+ };
87
+ }
88
+ };
89
+
90
+ return (
91
+ <>
92
+ <PegaDxilMyIconButtonUrl {...props} {...args} />
93
+ </>
94
+ );
95
+ };
96
+
97
+ BasePegaDxilMyIconButtonUrl.args = {
98
+ countryCode: configProps.countryCode
99
+ };
@@ -0,0 +1,142 @@
1
+ import { useEffect, useState } from 'react';
2
+ import {
3
+ Icon,
4
+ Button,
5
+ withConfiguration,
6
+ registerIcon,
7
+ Table,
8
+ Label
9
+ } from '@pega/cosmos-react-core';
10
+ import type { PConnFieldProps } from './PConnProps';
11
+
12
+ // IMPORTANT
13
+ // To use Icons, need to individually import the icon file form @pega/cosmos-react-core (see path below)
14
+ // Icons filename is kabab case (file-name), where as the icon you import is camel case (fileName)
15
+ // Icons need to be registered (camel case), and then used (kabab case)
16
+ import * as listNumber from '@pega/cosmos-react-core/lib/components/Icon/icons/list-number.icon';
17
+ import * as arrowRight from '@pega/cosmos-react-core/lib/components/Icon/icons/arrow-right.icon';
18
+
19
+ import StyledPegaDxilMyIconButtonUrlWrapper from './styles';
20
+
21
+ // interface for props
22
+ interface PegaDxilMyIconButtonUrlProps extends PConnFieldProps {
23
+ // If any, enter additional props that only exist on TextInput here
24
+ countryCode: string;
25
+ }
26
+
27
+ // *************
28
+ // This component is meant to be an example of usage (Icon, Button, etc.) and NOT meant to be
29
+ // used "as is"
30
+ //
31
+ // In this example, Icon is shown on its own and inside a Button
32
+ // Though an Icon can have an "onClick" event is it recommended if you want to click on it,
33
+ // to put it in a Button (shown below), so you can have a tooltip and hover style
34
+ //
35
+ // In this example, the click will get a list of states for a given country and display in a
36
+ // table below. The table dispaly will toggle with the click of the button icon.
37
+ //
38
+ // NOTE: because icons have to be imported and registered, you can NOT put the icon name
39
+ // inside the config.json and let the user pick it, if it is not already part of your
40
+ // import and registration (can't be done on the fly)
41
+ // **************
42
+
43
+ // props passed in combination of props from property panel (config.json) and run time props from Constellation
44
+ // any default values in config.pros should be set in defaultProps at bottom of this file
45
+ function PegaDxilMyIconButtonUrl(props: PegaDxilMyIconButtonUrlProps) {
46
+ const { countryCode = 'USA', getPConnect } = props;
47
+ const [statelist, setStatelist] = useState([]);
48
+ const [showTable, setShowTable] = useState(false);
49
+ const PConnect = getPConnect();
50
+
51
+ // IMPORTANT: need to register icons used in camel case
52
+ registerIcon(listNumber, arrowRight);
53
+
54
+
55
+ // setting up columns for the work list table
56
+ const columns = [
57
+ { renderer: 'stateName', label: PConnect.getLocalizedValue('State name', '', '') },
58
+ { renderer: 'stateCode', label: PConnect.getLocalizedValue('State code', '', '') }
59
+ ];
60
+
61
+ // toggle showing table and getting table data
62
+ function showHideTable() {
63
+ setShowTable(prevShowTable => !prevShowTable);
64
+ }
65
+
66
+ // going to get data for worklist to put into a table
67
+ // data comes from calling a PCore function to get
68
+ // get data from a data page and a PConnect function
69
+ // to get getContextName
70
+ useEffect(() => {
71
+ const dataViewName = 'D_pyStateList';
72
+ const context = PConnect.getContextName();
73
+ const params = { pyCountry: countryCode };
74
+
75
+ // only retrieve table data if table is shown
76
+ if (showTable) {
77
+ PCore.getDataPageUtils()
78
+ .getDataAsync(dataViewName, context, params, null, null)
79
+ // @ts-ignore
80
+ .then((response: any) => {
81
+ // table requires an index or will get setExtraStackFrame error
82
+ setStatelist(
83
+ response.data.map((entry: any, index: number) => {
84
+ // mapping the data into the column names
85
+ // MUST have an id/index or will get a setExtraStackFrame error
86
+ // put a key in the table
87
+ return {
88
+ stateName: entry.pyLabel,
89
+ stateCode: entry.pyStateCode,
90
+ id: index
91
+ };
92
+ })
93
+ );
94
+ })
95
+ .catch((error: any) => {
96
+ console.log(error);
97
+ });
98
+ }
99
+ }, [PConnect, countryCode, showTable]);
100
+
101
+ return (
102
+ <StyledPegaDxilMyIconButtonUrlWrapper>
103
+ <Icon
104
+ style={{ height: '1.5rem', width: '1.5rem' }}
105
+ // icon name is kabab case
106
+ name='arrow-right'
107
+ role='img'
108
+ aria-label='arrow right'
109
+ />
110
+ <Label>
111
+ {' '}
112
+ {PConnect.getLocalizedValue('State list for', '', '')}{' '}
113
+ {PConnect.getLocalizedValue(`${countryCode}`, '', '')}{' '}
114
+ </Label>
115
+ <Button
116
+ icon
117
+ label={PConnect.getLocalizedValue('Click to show/hide state list', '', '')}
118
+ variant='link'
119
+ compact={false}
120
+ onClick={showHideTable}
121
+ >
122
+ <Icon
123
+ style={{ height: '1.5rem', width: '1.5rem' }}
124
+ // icon name is kabab case
125
+ name='list-number'
126
+ role='img'
127
+ aria-label='numbered list'
128
+ />
129
+ </Button>
130
+ {showTable && (
131
+ <Table
132
+ title={PConnect.getLocalizedValue('State list', '', '')}
133
+ columns={columns}
134
+ data={statelist}
135
+ />
136
+ )}
137
+ </StyledPegaDxilMyIconButtonUrlWrapper>
138
+ );
139
+ }
140
+
141
+
142
+ export default withConfiguration(PegaDxilMyIconButtonUrl);
@@ -0,0 +1,5 @@
1
+
2
+ // @ts-nocheck
3
+ export const configProps = {
4
+ countryCode: 'USA'
5
+ };
@@ -0,0 +1,8 @@
1
+ // individual style, comment out above, and uncomment here and add styles
2
+ import styled, { css } from 'styled-components';
3
+
4
+ export default styled.div(() => {
5
+ return css`
6
+ margin: 0px 0;
7
+ `;
8
+ });
@@ -48,7 +48,7 @@ function PegaDxilMyPageWidget(props: PegaDxilMyPageWidgetProps) {
48
48
  const context = PConnect.getContextName();
49
49
 
50
50
  PCore.getDataPageUtils()
51
- .getDataAsync(dataViewName, context)
51
+ .getDataAsync(dataViewName, context, {}, null, null)
52
52
  // @ts-ignore
53
53
  .then((response: any) => {
54
54
  // table requires an index or will get setExtraStackFrame error