@pega/dx-component-builder-sdk 0.23.21 → 0.24.2

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 (130) hide show
  1. package/package.json +1 -1
  2. package/src/cli.js +1 -1
  3. package/src/constants.js +4 -0
  4. package/src/tasks/build-all/helper.js +6 -0
  5. package/src/tasks/build-comp/helper.js +6 -0
  6. package/src/tasks/bundle/builderAngular/webpack.config.js +14 -1
  7. package/src/tasks/bundle/builderAssociated/webpack.config.js +13 -0
  8. package/src/tasks/bundle/builderReact/webpack.config.js +14 -1
  9. package/src/tasks/create/templates/Constellation/field/Boolean/index.tsx.mustache +3 -2
  10. package/src/tasks/create/templates/Constellation/field/Icon-Button-URL/PConnProps.d.ts.mustache +46 -0
  11. package/src/tasks/create/templates/Constellation/field/Icon-Button-URL/config.json.mustache +64 -0
  12. package/src/tasks/create/templates/Constellation/field/Icon-Button-URL/demo.stories.tsx.mustache +99 -0
  13. package/src/tasks/create/templates/Constellation/field/Icon-Button-URL/index.tsx.mustache +204 -0
  14. package/src/tasks/create/templates/Constellation/field/Icon-Button-URL/mock.ts.mustache +5 -0
  15. package/src/tasks/create/templates/Constellation/field/Icon-Button-URL/styles.ts.mustache +8 -0
  16. package/src/tasks/create/templates/Constellation/field/Picklist/index.tsx.mustache +0 -1
  17. package/src/tasks/create/templates/Constellation/field/Picklist-Autocomplete/date.ts.mustache +15 -37
  18. package/src/tasks/create/templates/Constellation/field/Picklist-Autocomplete/index.tsx.mustache +11 -0
  19. package/src/tasks/create/templates/Constellation/field/Picklist-Autocomplete/utils.ts.mustache +3 -0
  20. package/src/tasks/create/templates/Constellation/field/Text/index.tsx.mustache +94 -4
  21. package/src/tasks/create/templates/Constellation/template/DETAILS/Avatar.tsx.mustache +78 -0
  22. package/src/tasks/create/templates/Constellation/template/DETAILS/DetailsRender.tsx.mustache +55 -0
  23. package/src/tasks/create/templates/Constellation/template/DETAILS/HighlightRender.tsx.mustache +49 -0
  24. package/src/tasks/create/templates/Constellation/template/DETAILS/Operator.tsx.mustache +218 -0
  25. package/src/tasks/create/templates/Constellation/template/DETAILS/demo.stories.tsx.mustache +77 -23
  26. package/src/tasks/create/templates/Constellation/template/DETAILS/index.tsx.mustache +51 -40
  27. package/src/tasks/create/templates/Constellation/template/DETAILS/mock.ts.mustache +78 -20
  28. package/src/tasks/create/templates/Constellation/template/DETAILS/styles.ts.mustache +16 -0
  29. package/src/tasks/create/templates/Constellation/template/DETAILS-region/Avatar.tsx.mustache +78 -0
  30. package/src/tasks/create/templates/Constellation/template/DETAILS-region/DetailsRender.tsx.mustache +55 -0
  31. package/src/tasks/create/templates/Constellation/template/DETAILS-region/HighlightRender.tsx.mustache +49 -0
  32. package/src/tasks/create/templates/Constellation/template/DETAILS-region/Operator.tsx.mustache +218 -0
  33. package/src/tasks/create/templates/Constellation/template/DETAILS-region/demo.stories.tsx.mustache +95 -26
  34. package/src/tasks/create/templates/Constellation/template/DETAILS-region/index.tsx.mustache +42 -39
  35. package/src/tasks/create/templates/Constellation/template/DETAILS-region/mock.ts.mustache +68 -10
  36. package/src/tasks/create/templates/Constellation/template/DETAILS-region/styles.ts.mustache +15 -0
  37. package/src/tasks/create/templates/Constellation/template/FORM/DetailsRender.tsx +59 -0
  38. package/src/tasks/create/templates/Constellation/template/FORM/index.tsx.mustache +31 -5
  39. package/src/tasks/create/templates/Constellation/template/FORM-region/DetailsRender.tsx +59 -0
  40. package/src/tasks/create/templates/Constellation/template/FORM-region/index.tsx.mustache +29 -7
  41. package/src/tasks/create/templates/Constellation/template/PAGE/GetNextWork.tsx.mustache +2 -1
  42. package/src/tasks/create/templates/Constellation/template/PAGE/localizations.json.mustache +4 -2
  43. package/src/tasks/create/templates/Constellation/widget/PAGE/demo.stories.tsx.mustache +87 -6
  44. package/src/tasks/create/templates/Constellation/widget/PAGE/index.tsx.mustache +67 -5
  45. package/src/tasks/create/templates/SDK-Angular/field/Boolean/boolean.component.html.mustache +19 -18
  46. package/src/tasks/create/templates/SDK-Angular/field/Boolean/boolean.component.ts.mustache +127 -44
  47. package/src/tasks/create/templates/SDK-Angular/field/Icon-Button-URL/config.json.mustache +64 -0
  48. package/src/tasks/create/templates/SDK-Angular/field/Icon-Button-URL/demo.stories.tsx.mustache +63 -0
  49. package/src/tasks/create/templates/SDK-Angular/field/Icon-Button-URL/icon-button-url.component.html.mustache +40 -0
  50. package/src/tasks/create/templates/SDK-Angular/field/Icon-Button-URL/icon-button-url.component.scss.mustache +24 -0
  51. package/src/tasks/create/templates/SDK-Angular/field/Icon-Button-URL/icon-button-url.component.spec.ts.mustache +26 -0
  52. package/src/tasks/create/templates/SDK-Angular/field/Icon-Button-URL/icon-button-url.component.ts.mustache +195 -0
  53. package/src/tasks/create/templates/SDK-Angular/field/Icon-Button-URL/mock.ts.mustache +37 -0
  54. package/src/tasks/create/templates/SDK-Angular/field/Text-URL/text-url.component.html.mustache +1 -0
  55. package/src/tasks/create/templates/SDK-Angular/field/Text-URL/text-url.component.ts.mustache +2 -0
  56. package/src/tasks/create/templates/SDK-Angular/field/TimeOfDay/time-of-day.component.html.mustache +1 -0
  57. package/src/tasks/create/templates/SDK-Angular/field/TimeOfDay/time-of-day.component.ts.mustache +2 -0
  58. package/src/tasks/create/templates/SDK-Angular/template/FORM-region/form.component.scss.mustache +1 -1
  59. package/src/tasks/create/templates/SDK-Angular/widget/CASE/case.component.ts.mustache +2 -2
  60. package/src/tasks/create/templates/SDK-Angular/widget/PAGE/page.component.html.mustache +1 -1
  61. package/src/tasks/create/templates/SDK-React/field/Boolean/demo.stories.tsx.mustache +1 -1
  62. package/src/tasks/create/templates/SDK-React/field/Boolean/mock.ts.mustache +8 -8
  63. package/src/tasks/create/templates/SDK-React/field/Date/index.tsx.mustache +2 -2
  64. package/src/tasks/create/templates/SDK-React/field/Date/mock.ts.mustache +7 -7
  65. package/src/tasks/create/templates/SDK-React/field/DateTime/demo.stories.tsx.mustache +1 -1
  66. package/src/tasks/create/templates/SDK-React/field/DateTime/index.tsx.mustache +2 -3
  67. package/src/tasks/create/templates/SDK-React/field/DateTime/mock.ts.mustache +6 -6
  68. package/src/tasks/create/templates/SDK-React/field/Decimal/index.tsx.mustache +51 -35
  69. package/src/tasks/create/templates/SDK-React/field/Decimal/mock.ts.mustache +1 -1
  70. package/src/tasks/create/templates/SDK-React/field/Decimal-Currency/config.json.mustache +1 -1
  71. package/src/tasks/create/templates/SDK-React/field/Decimal-Currency/demo.stories.tsx.mustache +1 -1
  72. package/src/tasks/create/templates/SDK-React/field/Decimal-Currency/index.tsx.mustache +47 -37
  73. package/src/tasks/create/templates/SDK-React/field/Decimal-Currency/mock.ts.mustache +1 -1
  74. package/src/tasks/create/templates/SDK-React/field/Decimal-Percentage/config.json.mustache +1 -1
  75. package/src/tasks/create/templates/SDK-React/field/Decimal-Percentage/index.tsx.mustache +36 -21
  76. package/src/tasks/create/templates/SDK-React/field/Decimal-Percentage/mock.ts.mustache +1 -1
  77. package/src/tasks/create/templates/SDK-React/field/Icon-Button-URL/config.json.mustache +64 -0
  78. package/src/tasks/create/templates/SDK-React/field/Icon-Button-URL/demo.stories.tsx.mustache +91 -0
  79. package/src/tasks/create/templates/SDK-React/field/Icon-Button-URL/index.tsx.mustache +160 -0
  80. package/src/tasks/create/templates/SDK-React/field/Icon-Button-URL/mock.ts.mustache +4 -0
  81. package/src/tasks/create/templates/SDK-React/field/Icon-Button-URL/styles.js.mustache +7 -0
  82. package/src/tasks/create/templates/SDK-React/field/Integer/config.json.mustache +1 -1
  83. package/src/tasks/create/templates/SDK-React/field/Integer/index.tsx.mustache +19 -20
  84. package/src/tasks/create/templates/SDK-React/field/Integer/mock.ts.mustache +1 -1
  85. package/src/tasks/create/templates/SDK-React/field/Picklist/index.tsx.mustache +26 -26
  86. package/src/tasks/create/templates/SDK-React/field/Picklist-RadioButtons/mock.ts.mustache +0 -1
  87. package/src/tasks/create/templates/SDK-React/field/Text/config.json.mustache +1 -1
  88. package/src/tasks/create/templates/SDK-React/field/Text/index.tsx.mustache +0 -1
  89. package/src/tasks/create/templates/SDK-React/field/Text/mock.ts.mustache +1 -1
  90. package/src/tasks/create/templates/SDK-React/field/Text-Email/config.json.mustache +1 -1
  91. package/src/tasks/create/templates/SDK-React/field/Text-Email/mock.ts.mustache +1 -1
  92. package/src/tasks/create/templates/SDK-React/field/Text-Input/config.json.mustache +1 -1
  93. package/src/tasks/create/templates/SDK-React/field/Text-Input/index.tsx.mustache +0 -1
  94. package/src/tasks/create/templates/SDK-React/field/Text-Input/mock.ts.mustache +1 -1
  95. package/src/tasks/create/templates/SDK-React/field/Text-Paragraph/index.tsx.mustache +1 -3
  96. package/src/tasks/create/templates/SDK-React/field/Text-Paragraph/mock.ts.mustache +1 -1
  97. package/src/tasks/create/templates/SDK-React/field/Text-Phone/index.tsx.mustache +1 -2
  98. package/src/tasks/create/templates/SDK-React/field/Text-URL/index.tsx.mustache +1 -2
  99. package/src/tasks/create/templates/SDK-React/field/Text-URL/mock.ts.mustache +1 -1
  100. package/src/tasks/create/templates/SDK-React/field/TimeOfDay/demo.stories.tsx.mustache +4 -4
  101. package/src/tasks/create/templates/SDK-React/field/TimeOfDay/index.tsx.mustache +0 -2
  102. package/src/tasks/create/templates/SDK-React/field/TimeOfDay/mock.ts.mustache +6 -6
  103. package/src/tasks/create/templates/SDK-React/template/DETAILS/demo.stories.tsx.mustache +1 -7
  104. package/src/tasks/create/templates/SDK-React/template/DETAILS/index.tsx.mustache +4 -9
  105. package/src/tasks/create/templates/SDK-React/template/DETAILS/mock.ts.mustache +181 -165
  106. package/src/tasks/create/templates/SDK-React/template/DETAILS-region/demo.stories.tsx.mustache +1 -6
  107. package/src/tasks/create/templates/SDK-React/template/DETAILS-region/index.tsx.mustache +4 -9
  108. package/src/tasks/create/templates/SDK-React/template/DETAILS-region/mock.ts.mustache +207 -163
  109. package/src/tasks/create/templates/SDK-React/template/FORM/config.json.mustache +1 -1
  110. package/src/tasks/create/templates/SDK-React/template/FORM/demo.stories.tsx.mustache +0 -1
  111. package/src/tasks/create/templates/SDK-React/template/FORM/index.tsx.mustache +14 -16
  112. package/src/tasks/create/templates/SDK-React/template/FORM/utils.ts.mustache +1 -1
  113. package/src/tasks/create/templates/SDK-React/template/FORM-region/demo.stories.tsx.mustache +0 -2
  114. package/src/tasks/create/templates/SDK-React/template/FORM-region/mock.ts.mustache +121 -122
  115. package/src/tasks/create/templates/SDK-React/template/PAGE/OneColumn.tsx.mustache +12 -13
  116. package/src/tasks/create/templates/SDK-React/template/PAGE/demo.stories.tsx.mustache +1 -1
  117. package/src/tasks/create/templates/SDK-React/template/PAGE/index.tsx.mustache +3 -5
  118. package/src/tasks/create/templates/SDK-React/template/PAGE/mock.ts.mustache +8 -9
  119. package/src/tasks/create/templates/SDK-React/widget/CASE/config.json.mustache +2 -2
  120. package/src/tasks/create/templates/SDK-React/widget/CASE/demo.stories.tsx.mustache +0 -1
  121. package/src/tasks/create/templates/SDK-React/widget/CASE/index.tsx.mustache +3 -3
  122. package/src/tasks/create/templates/SDK-React/widget/PAGE/config.json.mustache +43 -43
  123. package/src/tasks/create/templates/SDK-React/widget/PAGE/mock.ts.mustache +1 -1
  124. package/src/tasks/create/templates/SDK-React/widget/PAGE-CASE/demo.stories.tsx.mustache +1 -2
  125. package/src/tasks/create/templates/SDK-React/widget/PAGE-CASE/index.tsx.mustache +0 -1
  126. package/src/tasks/create/templates/SDK-React/widget/PAGE-CASE/mock.ts.mustache +0 -1
  127. package/src/tasks/create-all/index.js +3 -0
  128. package/src/tasks/publish/helper.js +4 -0
  129. package/src/tasks/publish-all/helper.js +6 -2
  130. package/src/tasks/validator/index.js +7 -1
@@ -1,5 +1,6 @@
1
- import CurrencyTextField from '@unicef/material-ui-currency-textfield';
2
-
1
+ import { TextField } from '@material-ui/core';
2
+ import { useState } from 'react';
3
+ import { NumericFormat } from 'react-number-format';
3
4
  import { getComponentFromMap } from '@pega/react-sdk-components/lib/bridge/helpers/sdk_component_map';
4
5
  import { PConnFieldProps } from '@pega/react-sdk-components/lib/types/PConnProps';
5
6
  import handleEvent from '@pega/react-sdk-components/lib/components/helpers/event-utils';
@@ -7,13 +8,14 @@ import { format } from '@pega/react-sdk-components/lib/components/helpers/format
7
8
  import { getCurrencyCharacters, getCurrencyOptions } from '@pega/react-sdk-components/lib/components/field/Currency/currency-utils.js';
8
9
  import Styled{{COMPONENT_CLASS_NAME}}Wrapper from './styles';
9
10
 
10
- /* Using @unicef/material-ui-currency-textfield component here, since it allows formatting decimal values,
11
+ /* Using react-number-format component here, since it allows formatting decimal values,
11
12
  as per the locale.
12
13
  */
13
14
 
14
15
  interface {{COMPONENT_CLASS_NAME}}Props extends PConnFieldProps {
15
16
  // If any, enter additional props that only exist on this componentName
16
17
  currencyISOCode?: string;
18
+ allowDecimals: boolean;
17
19
  }
18
20
 
19
21
  // Duplicated runtime code from React SDK
@@ -38,15 +40,15 @@ export default function {{COMPONENT_CLASS_NAME}}(props: {{COMPONENT_CLASS_NAME}}
38
40
  displayMode,
39
41
  hideLabel,
40
42
  currencyISOCode = 'USD',
41
- placeholder
43
+ placeholder,
44
+ allowDecimals
42
45
  } = props;
43
46
 
44
47
  const pConn = getPConnect();
45
48
  const actions = pConn.getActionsApi();
46
49
  const propName = (pConn.getStateProps() as any).value;
47
50
  const helperTextToDisplay = validatemessage || helperText;
48
-
49
- // console.log(`Currency: label: ${label} value: ${value}`);
51
+ const [values, setValues] = useState(value.toString());
50
52
 
51
53
  const testProp = {
52
54
  'data-test-id': testId
@@ -61,6 +63,15 @@ export default function {{COMPONENT_CLASS_NAME}}(props: {{COMPONENT_CLASS_NAME}}
61
63
  const theCurrencyOptions = getCurrencyOptions(currencyISOCode);
62
64
  const formattedValue = format(value, pConn.getComponentName().toLowerCase(), theCurrencyOptions);
63
65
 
66
+ let readOnlyProp = {}; // Note: empty if NOT ReadOnly
67
+
68
+ if (readOnly) {
69
+ readOnlyProp = { readOnly: true };
70
+ }
71
+
72
+ let currencyProp = {};
73
+ currencyProp = { prefix: theCurrSym, decimalSeparator: theCurrDec, thousandSeparator: theCurrSep };
74
+
64
75
  if (displayMode === 'LABELS_LEFT') {
65
76
  return <FieldValueList name={hideLabel ? '' : label} value={formattedValue} />;
66
77
  }
@@ -69,40 +80,39 @@ export default function {{COMPONENT_CLASS_NAME}}(props: {{COMPONENT_CLASS_NAME}}
69
80
  return <FieldValueList name={hideLabel ? '' : label} value={formattedValue} variant='stacked' />;
70
81
  }
71
82
 
72
- function currOnBlur(event, inValue) {
73
- // console.log(`Currency currOnBlur inValue: ${inValue}`);
74
- handleEvent(actions, 'changeNblur', propName, inValue !== '' ? Number(inValue) : inValue);
83
+ function currOnBlur() {
84
+ handleEvent(actions, 'changeNblur', propName, values);
75
85
  }
76
86
 
77
- // console.log(`theCurrSym: ${theCurrSym} | theCurrDec: ${theCurrDec} | theCurrSep: ${theCurrSep}`);
87
+ const handleChange = val => {
88
+ setValues(val.value);
89
+ };
78
90
 
79
91
  return (
80
- <Styled{{COMPONENT_CLASS_NAME}}Wrapper>
81
- <CurrencyTextField
82
- fullWidth
83
- variant={readOnly ? 'standard' : 'outlined'}
84
- helperText={helperTextToDisplay}
85
- placeholder={placeholder ?? ''}
86
- size='small'
87
- required={required}
88
- disabled={disabled}
89
- readOnly={!!readOnly}
90
- error={status === 'error'}
91
- label={label}
92
- value={value}
93
- type='text'
94
- outputFormat='number'
95
- textAlign='left'
96
- {{! pick new delimiters for mustache }}
97
- {{=<% %>=}}
98
- InputProps={{ inputProps: { ...testProp } }}
99
- <%={{ }}=%> {{! revert delimiters for mustache }}
100
- currencySymbol={theCurrSym}
101
- decimalCharacter={theCurrDec}
102
- digitGroupSeparator={theCurrSep}
103
- onBlur={!readOnly ? currOnBlur : undefined}
104
- />
105
- </Styled{{COMPONENT_CLASS_NAME}}Wrapper>
92
+ <Styled{{COMPONENT_CLASS_NAME}}Wrapper>
93
+ <NumericFormat
94
+ valueIsNumericString
95
+ label={label}
96
+ helperText={helperTextToDisplay}
97
+ placeholder={placeholder ?? ''}
98
+ required={required}
99
+ disabled={disabled}
100
+ onValueChange={val => {
101
+ handleChange(val);
102
+ }}
103
+ onBlur={!readOnly ? currOnBlur : undefined}
104
+ error={status === 'error'}
105
+ name='numberformat'
106
+ value={values}
107
+ {...currencyProp}
108
+ decimalScale={allowDecimals !== false ? 2 : 0}
109
+ fixedDecimalScale={allowDecimals}
110
+ {{! pick new delimiters for mustache }}
111
+ {{=<% %>=}}
112
+ InputProps={{ ...readOnlyProp, inputProps: { ...testProp } }}
113
+ <%={{ }}=%> {{! revert delimiters for mustache }}
114
+ customInput={TextField}
115
+ />
116
+ </Styled{{COMPONENT_CLASS_NAME}}Wrapper>
106
117
  );
107
118
  }
108
-
@@ -18,4 +18,4 @@ export const fieldMetadata = {
18
18
  type: 'Decimal',
19
19
  displayAs: 'pxCurrency',
20
20
  label: 'Currency sample'
21
- };
21
+ };
@@ -10,7 +10,7 @@
10
10
  "type": "{{TYPE}}",
11
11
  "subtype": {{{SUB_TYPE}}},
12
12
  "icon": "images/pz-text-input-active.svg",
13
- "properties": [
13
+ "properties": [
14
14
  {
15
15
  "name": "label",
16
16
  "label": "Field label",
@@ -1,5 +1,6 @@
1
- import CurrencyTextField from '@unicef/material-ui-currency-textfield';
2
-
1
+ import { TextField } from '@material-ui/core';
2
+ import { NumericFormat } from 'react-number-format';
3
+ import { useState } from 'react';
3
4
  import { getComponentFromMap } from '@pega/react-sdk-components/lib/bridge/helpers/sdk_component_map';
4
5
  import { PConnFieldProps } from '@pega/react-sdk-components/lib/types/PConnProps';
5
6
  import { getCurrencyCharacters, getCurrencyOptions } from '@pega/react-sdk-components/lib/components/field/Currency/currency-utils.js';
@@ -7,13 +8,15 @@ import handleEvent from '@pega/react-sdk-components/lib/components/helpers/event
7
8
  import { format } from '@pega/react-sdk-components/lib/components/helpers/formatters';
8
9
  import Styled{{COMPONENT_CLASS_NAME}}Wrapper from './styles';
9
10
 
10
- /* Using @unicef/material-ui-currency-textfield component here, since it allows formatting decimal values,
11
+ /* Using react-number-format component here, since it allows formatting decimal values,
11
12
  as per the locale.
12
13
  */
13
14
 
14
15
  interface {{COMPONENT_CLASS_NAME}}Props extends PConnFieldProps {
15
16
  // If any, enter additional props that only exist on this componentName
16
- currencyISOCode: string;
17
+ currencyISOCode?: string;
18
+ showGroupSeparators?: string;
19
+ decimalPrecision?: number;
17
20
  }
18
21
 
19
22
  // props passed in combination of props from property panel (config.json) and run time props from Constellation
@@ -37,9 +40,13 @@ export default function {{COMPONENT_CLASS_NAME}}(props: {{COMPONENT_CLASS_NAME}}
37
40
  helperText,
38
41
  displayMode,
39
42
  hideLabel,
40
- placeholder
43
+ placeholder,
44
+ showGroupSeparators,
45
+ decimalPrecision
41
46
  } = props;
42
47
 
48
+ const [values, setValues] = useState(value.toString());
49
+
43
50
  const pConn = getPConnect();
44
51
  const actions = pConn.getActionsApi();
45
52
  const propName = (pConn.getStateProps() as any).value;
@@ -48,7 +55,11 @@ export default function {{COMPONENT_CLASS_NAME}}(props: {{COMPONENT_CLASS_NAME}}
48
55
  const theCurrencyOptions = getCurrencyOptions(currencyISOCode);
49
56
  const formattedValue = format(value, pConn.getComponentName().toLowerCase(), theCurrencyOptions);
50
57
 
51
- // console.log(`Percentage: label: ${label} value: ${value}`);
58
+ let readOnlyProp = {}; // Note: empty if NOT ReadOnly
59
+
60
+ if (readOnly) {
61
+ readOnlyProp = { readOnly: true };
62
+ }
52
63
 
53
64
  if (displayMode === 'LABELS_LEFT') {
54
65
  return <FieldValueList name={hideLabel ? '' : label} value={formattedValue} />;
@@ -68,13 +79,18 @@ export default function {{COMPONENT_CLASS_NAME}}(props: {{COMPONENT_CLASS_NAME}}
68
79
  const theCurrDec = theSymbols.theDecimalIndicator;
69
80
  const theCurrSep = theSymbols.theDigitGroupSeparator;
70
81
 
71
- function PercentageOnBlur(event, inValue) {
72
- handleEvent(actions, 'changeNblur', propName, inValue !== '' ? Number(inValue) : inValue);
82
+ function PercentageOnBlur() {
83
+ handleEvent(actions, 'changeNblur', propName, values);
73
84
  }
74
85
 
86
+ const handleChange = val => {
87
+ setValues(val.value);
88
+ };
89
+
75
90
  return (
76
91
  <Styled{{COMPONENT_CLASS_NAME}}Wrapper>
77
- <CurrencyTextField
92
+ <NumericFormat
93
+ valueIsNumericString
78
94
  fullWidth
79
95
  variant={readOnly ? 'standard' : 'outlined'}
80
96
  helperText={helperTextToDisplay}
@@ -82,23 +98,22 @@ export default function {{COMPONENT_CLASS_NAME}}(props: {{COMPONENT_CLASS_NAME}}
82
98
  size='small'
83
99
  required={required}
84
100
  disabled={disabled}
85
- readOnly={!!readOnly}
86
101
  error={status === 'error'}
87
102
  label={label}
88
- value={value}
89
- type='text'
90
- outputFormat='number'
91
- textAlign='left'
103
+ value={values}
104
+ onValueChange={val => {
105
+ handleChange(val);
106
+ }}
107
+ onBlur={!readOnly ? PercentageOnBlur : undefined}
108
+ decimalSeparator={theCurrDec}
109
+ thousandSeparator={showGroupSeparators ? theCurrSep : ''}
110
+ decimalScale={decimalPrecision}
111
+ suffix='%'
92
112
  {{! pick new delimiters for mustache }}
93
113
  {{=<% %>=}}
94
- InputProps={{
95
- inputProps: { ...testProp }
96
- }}
114
+ InputProps={{ ...readOnlyProp, inputProps: { ...testProp } }}
97
115
  <%={{ }}=%> {{! revert delimiters for mustache }}
98
- currencySymbol=''
99
- decimalCharacter={theCurrDec}
100
- digitGroupSeparator={theCurrSep}
101
- onBlur={!readOnly ? PercentageOnBlur : undefined}
116
+ customInput={TextField}
102
117
  />
103
118
  </Styled{{COMPONENT_CLASS_NAME}}Wrapper>
104
119
  );
@@ -18,4 +18,4 @@ export const fieldMetadata = {
18
18
  type: 'Decimal',
19
19
  displayAs: 'pxPercentage',
20
20
  label: 'Percentage sample'
21
- };
21
+ };
@@ -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,91 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+
3
+ import {{COMPONENT_CLASS_NAME}} from './index';
4
+ import { configProps } from './mock';
5
+
6
+ const meta: Meta<typeof {{COMPONENT_CLASS_NAME}}> = {
7
+ title: '{{COMPONENT_CLASS_NAME}}',
8
+ component: {{COMPONENT_CLASS_NAME}},
9
+ excludeStories: /.*Data$/
10
+ };
11
+
12
+ export default meta;
13
+ type Story = StoryObj<typeof {{COMPONENT_CLASS_NAME}}>;
14
+
15
+ if (!window.PCore) {
16
+ window.PCore = {} as any;
17
+ }
18
+
19
+ const statelistData = {
20
+ data: [
21
+ {
22
+ pyLabel: 'Massachusetts',
23
+ pyStateCode: 'MA'
24
+ },
25
+ {
26
+ pyLabel: 'Rhode Island',
27
+ pyStateCode: 'RI'
28
+ },
29
+ {
30
+ pyLabel: 'Connecticut',
31
+ pyStateCode: 'CT'
32
+ }
33
+ ]
34
+ };
35
+
36
+ window.PCore.getDataPageUtils = (() => {
37
+ return {
38
+ getDataAsync: () => {
39
+ return new Promise(resolve => {
40
+ resolve(statelistData);
41
+ });
42
+ }
43
+ };
44
+ }) as any;
45
+
46
+ export const Base{{COMPONENT_CLASS_NAME}}: Story = args => {
47
+ const props = {
48
+ countryCode: configProps.countryCode,
49
+ getPConnect: () => {
50
+ return {
51
+ getValue: value => {
52
+ return value;
53
+ },
54
+ getContextName: () => {
55
+ return 'app/primary_1';
56
+ },
57
+ getLocalizedValue: value => {
58
+ return value;
59
+ },
60
+ getActionsApi: () => {
61
+ return {
62
+ updateFieldValue: () => {
63
+ /* nothing */
64
+ },
65
+ triggerFieldChange: () => {
66
+ /* nothing */
67
+ }
68
+ };
69
+ },
70
+ ignoreSuggestion: () => {
71
+ /* nothing */
72
+ },
73
+ acceptSuggestion: () => {
74
+ /* nothing */
75
+ },
76
+ setInheritedProps: () => {
77
+ /* nothing */
78
+ },
79
+ resolveConfigProps: () => {
80
+ /* nothing */
81
+ }
82
+ };
83
+ }
84
+ };
85
+
86
+ return <{{COMPONENT_CLASS_NAME}} {...props} {...args} />;
87
+ };
88
+
89
+ Base{{COMPONENT_CLASS_NAME}}.args = {
90
+ countryCode: configProps.countryCode
91
+ };
@@ -0,0 +1,160 @@
1
+ import { useEffect, useState } from 'react';
2
+ import { Tooltip, IconButton, Link } from '@material-ui/core';
3
+ import Table from '@material-ui/core/Table';
4
+ import TableBody from '@material-ui/core/TableBody';
5
+ import TableCell from '@material-ui/core/TableCell';
6
+ import TableContainer from '@material-ui/core/TableContainer';
7
+ import TableHead from '@material-ui/core/TableHead';
8
+ import TableRow from '@material-ui/core/TableRow';
9
+ import Paper from '@material-ui/core/Paper';
10
+
11
+ import { getComponentFromMap } from '@pega/react-sdk-components/lib/bridge/helpers/sdk_component_map';
12
+ import { PConnFieldProps } from '@pega/react-sdk-components/lib/types/PConnProps';
13
+ import Styled{{COMPONENT_CLASS_NAME}}Wrapper from './styles';
14
+
15
+ // IMPORTANT
16
+ // import LanguageIcon from '@mui/icons-material/Language';
17
+ import ArrowForwardIcon from '@material-ui/icons/ArrowForward';
18
+ import LanguageIcon from '@material-ui/icons/Language';
19
+ import FormatListNumberedIcon from '@material-ui/icons/FormatListNumbered';
20
+
21
+ interface {{COMPONENT_CLASS_NAME}}Props extends PConnFieldProps {
22
+ // If any, enter additional props that only exist on this componentName
23
+ countryCode: string;
24
+ }
25
+
26
+ export const textFormatter = (value: string, validUrl: string) => {
27
+ return <Link href={validUrl}>{value}</Link>;
28
+ };
29
+
30
+ // props passed in combination of props from property panel (config.json) and run time props from Constellation
31
+ export default function {{COMPONENT_CLASS_NAME}}(props: {{COMPONENT_CLASS_NAME}}Props) {
32
+ // Get emitted components from map (so we can get any override that may exist)
33
+ const TextContent = getComponentFromMap('TextContent');
34
+
35
+ const { value, displayMode, countryCode = 'USA', getPConnect, testId } = props;
36
+ const [stateList, setStateList] = useState<any[]>([]);
37
+ const [showTable, setShowTable] = useState(false);
38
+ const [validUrl, setValidUrl] = useState('about:blank');
39
+ const PConnect = getPConnect();
40
+
41
+ // toggle showing table and getting table data
42
+ function showHideTable() {
43
+ setShowTable(prevShowTable => !prevShowTable);
44
+ }
45
+
46
+ // check if url is valid (simple)
47
+ function validateUrl(href: string) {
48
+ return /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(
49
+ href
50
+ );
51
+ }
52
+
53
+ // Testing to see if value entered is valid url, if not can't use it.
54
+ // Reason for this code is that you can NOT pass to Link component
55
+ // a bad url, or it will error out.
56
+ // For example: Since the value is the property field,
57
+ // it could be entered from another component and thus as it is
58
+ // entered (typed in), it won't be valid until it is all entered.
59
+ // NOTE: can't have a blank value for the url as the Link element will error out
60
+ // in App studio preview
61
+ useEffect(() => {
62
+ if (validateUrl(value as string)) {
63
+ setValidUrl(value as string);
64
+ } else {
65
+ setValidUrl('about:blank');
66
+ }
67
+ }, [value]);
68
+
69
+ // going to get data for worklist to put into a table
70
+ // data comes from calling a PCore function to get
71
+ // get data from a data page and a PConnect function
72
+ // to get getContextName
73
+ useEffect(() => {
74
+ const dataViewName = 'D_pyStateList';
75
+ const context = PConnect.getContextName();
76
+ const params = { pyCountry: countryCode };
77
+
78
+ // only retrieve table data if table is shown
79
+ if (showTable) {
80
+ PCore.getDataPageUtils()
81
+ .getDataAsync(dataViewName, context, params, null, null)
82
+ // @ts-ignore
83
+ .then((response: any) => {
84
+ // table requires an index or will get setExtraStackFrame error
85
+ setStateList(
86
+ response.data.map((entry: any, index: number) => {
87
+ // mapping the data into the column names
88
+ // MUST have an id/index or will get a setExtraStackFrame error
89
+ // put a key in the table
90
+ return {
91
+ stateName: entry.pyLabel,
92
+ stateCode: entry.pyStateCode,
93
+ id: index
94
+ };
95
+ })
96
+ );
97
+ })
98
+ .catch((error: any) => {
99
+ // eslint-disable-next-line no-console
100
+ console.log(error);
101
+ });
102
+ }
103
+ }, [PConnect, countryCode, showTable]);
104
+
105
+ // when DISPLAY_ONLY, in this example we will just show the URL.
106
+ if (displayMode === 'DISPLAY_ONLY') {
107
+ const displayComp = textFormatter(validUrl, validUrl);
108
+ return <Styled{{COMPONENT_CLASS_NAME}}Wrapper> {displayComp} </Styled{{COMPONENT_CLASS_NAME}}Wrapper>;
109
+ }
110
+
111
+ const localLabel = ''
112
+ .concat(PConnect.getLocalizedValue('State list for', '', ''))
113
+ .concat(PConnect.getLocalizedValue(` ${countryCode}`, '', ''))
114
+ .concat(' ');
115
+
116
+ return (
117
+ <Styled{{COMPONENT_CLASS_NAME}}Wrapper>
118
+ {{! pick new delimiters for mustache }}
119
+ {{=<% %>=}}
120
+ <div style={{ display: 'flex' }} data-testid={testId}>
121
+ <ArrowForwardIcon />
122
+ <TextContent displayAs='body' content={localLabel} />
123
+ <Tooltip title={PConnect.getLocalizedValue('Click to show/hide state list', '', '')}>
124
+ <IconButton onClick={showHideTable} style={{ padding: '0 0.25rem' }}>
125
+ <FormatListNumberedIcon />
126
+ </IconButton>
127
+ </Tooltip>
128
+ {
129
+ // eslint-disable-next-line jsx-a11y/control-has-associated-label
130
+ <a href={validUrl} style={{ padding: '0 0.25rem' }}>
131
+ <LanguageIcon />
132
+ </a>
133
+ }
134
+ </div>
135
+ {showTable && (
136
+ <TableContainer component={Paper}>
137
+ <Table aria-label="{PConnect.getLocalizedValue('State list', '', '')}">
138
+ <TableHead>
139
+ <TableRow>
140
+ <TableCell>{PConnect.getLocalizedValue('State name', '', '')}</TableCell>
141
+ <TableCell>{PConnect.getLocalizedValue('State code', '', '')}</TableCell>
142
+ </TableRow>
143
+ </TableHead>
144
+ <TableBody>
145
+ {stateList.map(row => (
146
+ <TableRow key={row.stateName}>
147
+ <TableCell component='th' scope='row'>
148
+ {row.stateName}
149
+ </TableCell>
150
+ <TableCell>{row.stateCode}</TableCell>
151
+ </TableRow>
152
+ ))}
153
+ </TableBody>
154
+ </Table>
155
+ </TableContainer>
156
+ )}
157
+ <%={{ }}=%> {{! revert delimiters for mustache }}
158
+ </Styled{{COMPONENT_CLASS_NAME}}Wrapper>
159
+ );
160
+ }
@@ -0,0 +1,4 @@
1
+ // eslint-disable-next-line import/prefer-default-export
2
+ export const configProps = {
3
+ countryCode: 'USA'
4
+ };
@@ -0,0 +1,7 @@
1
+ import styled, { css } from 'styled-components';
2
+
3
+ export default styled.div(() => {
4
+ return css`
5
+ margin: 0px 0;
6
+ `;
7
+ });
@@ -10,7 +10,7 @@
10
10
  "type": "{{TYPE}}",
11
11
  "subtype": {{{SUB_TYPE}}},
12
12
  "icon": "images/pz-integer-active.svg",
13
- "properties": [
13
+ "properties": [
14
14
  {
15
15
  "name": "label",
16
16
  "label": "Field label",
@@ -73,26 +73,25 @@ export default function {{COMPONENT_CLASS_NAME}}(props: {{COMPONENT_CLASS_NAME}}
73
73
 
74
74
  return (
75
75
  <Styled{{COMPONENT_CLASS_NAME}}Wrapper>
76
- <TextField
77
- fullWidth
78
- variant={readOnly ? 'standard' : 'outlined'}
79
- helperText={helperTextToDisplay}
80
- placeholder={placeholder ?? ''}
81
- size='small'
82
- required={required}
83
- disabled={disabled}
84
- onChange={intOnChange}
85
- onBlur={!readOnly ? onBlur : undefined}
86
- error={status === 'error'}
87
- label={label}
88
- value={value}
89
- type='text'
90
- {{! pick new delimiters for mustache }}
91
- {{=<% %>=}}
92
- inputProps={{ inputMode: 'numeric', pattern: '[0-9]*', ...testProp }}
93
- <%={{ }}=%> {{! revert delimiters for mustache }}
94
- />
76
+ <TextField
77
+ fullWidth
78
+ variant={readOnly ? 'standard' : 'outlined'}
79
+ helperText={helperTextToDisplay}
80
+ placeholder={placeholder ?? ''}
81
+ size='small'
82
+ required={required}
83
+ disabled={disabled}
84
+ onChange={intOnChange}
85
+ onBlur={!readOnly ? onBlur : undefined}
86
+ error={status === 'error'}
87
+ label={label}
88
+ value={value}
89
+ type='text'
90
+ {{! pick new delimiters for mustache }}
91
+ {{=<% %>=}}
92
+ inputProps={{ inputMode: 'numeric', pattern: '[0-9]*', ...testProp }}
93
+ <%={{ }}=%> {{! revert delimiters for mustache }}
94
+ />
95
95
  </Styled{{COMPONENT_CLASS_NAME}}Wrapper>
96
96
  );
97
97
  }
98
-
@@ -18,4 +18,4 @@ export const fieldMetadata = {
18
18
  type: 'Integer',
19
19
  displayAs: 'pxInteger',
20
20
  label: 'Integer sample'
21
- };
21
+ };