@pega/dx-component-builder-sdk 0.23.21 → 0.24.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/cli.js +1 -1
- package/src/constants.js +4 -0
- package/src/tasks/build-all/helper.js +6 -0
- package/src/tasks/build-comp/helper.js +6 -0
- package/src/tasks/bundle/builderAngular/webpack.config.js +14 -1
- package/src/tasks/bundle/builderAssociated/webpack.config.js +13 -0
- package/src/tasks/bundle/builderReact/webpack.config.js +14 -1
- package/src/tasks/create/templates/Constellation/field/Boolean/index.tsx.mustache +3 -2
- package/src/tasks/create/templates/Constellation/field/Icon-Button-URL/PConnProps.d.ts.mustache +46 -0
- package/src/tasks/create/templates/Constellation/field/Icon-Button-URL/config.json.mustache +64 -0
- package/src/tasks/create/templates/Constellation/field/Icon-Button-URL/demo.stories.tsx.mustache +99 -0
- package/src/tasks/create/templates/Constellation/field/Icon-Button-URL/index.tsx.mustache +204 -0
- package/src/tasks/create/templates/Constellation/field/Icon-Button-URL/mock.ts.mustache +5 -0
- package/src/tasks/create/templates/Constellation/field/Icon-Button-URL/styles.ts.mustache +8 -0
- package/src/tasks/create/templates/Constellation/field/Picklist-Autocomplete/index.tsx.mustache +11 -0
- package/src/tasks/create/templates/Constellation/field/Picklist-Autocomplete/utils.ts.mustache +3 -0
- package/src/tasks/create/templates/Constellation/field/Text/index.tsx.mustache +94 -4
- package/src/tasks/create/templates/Constellation/template/DETAILS/Avatar.tsx.mustache +78 -0
- package/src/tasks/create/templates/Constellation/template/DETAILS/DetailsRender.tsx.mustache +55 -0
- package/src/tasks/create/templates/Constellation/template/DETAILS/HighlightRender.tsx.mustache +49 -0
- package/src/tasks/create/templates/Constellation/template/DETAILS/Operator.tsx.mustache +218 -0
- package/src/tasks/create/templates/Constellation/template/DETAILS/demo.stories.tsx.mustache +77 -23
- package/src/tasks/create/templates/Constellation/template/DETAILS/index.tsx.mustache +51 -40
- package/src/tasks/create/templates/Constellation/template/DETAILS/mock.ts.mustache +78 -20
- package/src/tasks/create/templates/Constellation/template/DETAILS/styles.ts.mustache +16 -0
- package/src/tasks/create/templates/Constellation/template/DETAILS-region/Avatar.tsx.mustache +78 -0
- package/src/tasks/create/templates/Constellation/template/DETAILS-region/DetailsRender.tsx.mustache +55 -0
- package/src/tasks/create/templates/Constellation/template/DETAILS-region/HighlightRender.tsx.mustache +49 -0
- package/src/tasks/create/templates/Constellation/template/DETAILS-region/Operator.tsx.mustache +218 -0
- package/src/tasks/create/templates/Constellation/template/DETAILS-region/demo.stories.tsx.mustache +95 -26
- package/src/tasks/create/templates/Constellation/template/DETAILS-region/index.tsx.mustache +43 -40
- package/src/tasks/create/templates/Constellation/template/DETAILS-region/mock.ts.mustache +68 -10
- package/src/tasks/create/templates/Constellation/template/DETAILS-region/styles.ts.mustache +15 -0
- package/src/tasks/create/templates/Constellation/template/FORM/DetailsRender.tsx +59 -0
- package/src/tasks/create/templates/Constellation/template/FORM/index.tsx.mustache +31 -5
- package/src/tasks/create/templates/Constellation/template/FORM-region/DetailsRender.tsx +59 -0
- package/src/tasks/create/templates/Constellation/template/FORM-region/index.tsx.mustache +29 -7
- package/src/tasks/create/templates/Constellation/template/PAGE/GetNextWork.tsx.mustache +2 -1
- package/src/tasks/create/templates/Constellation/template/PAGE/localizations.json.mustache +4 -2
- package/src/tasks/create/templates/Constellation/widget/PAGE/demo.stories.tsx.mustache +87 -6
- package/src/tasks/create/templates/Constellation/widget/PAGE/index.tsx.mustache +67 -5
- package/src/tasks/create/templates/SDK-Angular/field/Icon-Button-URL/config.json.mustache +64 -0
- package/src/tasks/create/templates/SDK-Angular/field/Icon-Button-URL/demo.stories.tsx.mustache +42 -0
- package/src/tasks/create/templates/SDK-Angular/field/Icon-Button-URL/mock.ts.mustache +17 -0
- package/src/tasks/create/templates/SDK-Angular/field/Icon-Button-URL/text-url.component.html.mustache +29 -0
- package/src/tasks/create/templates/SDK-Angular/field/Icon-Button-URL/text-url.component.scss.mustache +20 -0
- package/src/tasks/create/templates/SDK-Angular/field/Icon-Button-URL/text-url.component.spec.ts.mustache +26 -0
- package/src/tasks/create/templates/SDK-Angular/field/Icon-Button-URL/text-url.component.ts.mustache +179 -0
- package/src/tasks/create/templates/SDK-React/field/Icon-Button-URL/config.json.mustache +64 -0
- package/src/tasks/create/templates/SDK-React/field/Icon-Button-URL/demo.stories.tsx.mustache +58 -0
- package/src/tasks/create/templates/SDK-React/field/Icon-Button-URL/index.tsx.mustache +79 -0
- package/src/tasks/create/templates/SDK-React/field/Icon-Button-URL/mock.ts.mustache +16 -0
- package/src/tasks/create/templates/SDK-React/field/Icon-Button-URL/styles.js.mustache +7 -0
- package/src/tasks/create/templates/SDK-React/template/DETAILS/demo.stories.tsx.mustache +0 -3
- package/src/tasks/create/templates/SDK-React/template/DETAILS/index.tsx.mustache +1 -1
- package/src/tasks/create/templates/SDK-React/template/DETAILS-region/demo.stories.tsx.mustache +0 -3
- package/src/tasks/create/templates/SDK-React/template/DETAILS-region/index.tsx.mustache +1 -1
- package/src/tasks/create-all/index.js +3 -0
- package/src/tasks/publish/helper.js +4 -0
- package/src/tasks/publish-all/helper.js +6 -2
- package/src/tasks/validator/index.js +7 -1
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
|
|
2
|
+
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
|
3
|
+
|
|
4
|
+
import { {{COMPONENT_CLASS_NAME}}Component } from './{{COMPONENT_CLASS_NAME_KEBAB}}.component';
|
|
5
|
+
|
|
6
|
+
describe('{{COMPONENT_CLASS_NAME}}Component', () => {
|
|
7
|
+
let component: {{COMPONENT_CLASS_NAME}}Component;
|
|
8
|
+
let fixture: ComponentFixture<{{COMPONENT_CLASS_NAME}}Component>;
|
|
9
|
+
|
|
10
|
+
beforeEach(waitForAsync(() => {
|
|
11
|
+
TestBed.configureTestingModule({
|
|
12
|
+
declarations: [ {{COMPONENT_CLASS_NAME}}Component ]
|
|
13
|
+
})
|
|
14
|
+
.compileComponents();
|
|
15
|
+
}));
|
|
16
|
+
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
fixture = TestBed.createComponent({{COMPONENT_CLASS_NAME}}Component);
|
|
19
|
+
component = fixture.componentInstance;
|
|
20
|
+
fixture.detectChanges();
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('should create', () => {
|
|
24
|
+
expect(component).toBeTruthy();
|
|
25
|
+
});
|
|
26
|
+
});
|
package/src/tasks/create/templates/SDK-Angular/field/Icon-Button-URL/text-url.component.ts.mustache
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { Component, OnInit, Input, ChangeDetectorRef, forwardRef, OnDestroy } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
|
|
4
|
+
import { MatInputModule } from '@angular/material/input';
|
|
5
|
+
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
6
|
+
import { interval } from 'rxjs';
|
|
7
|
+
import { AngularPConnectData, AngularPConnectService } from '@pega/angular-sdk-components';
|
|
8
|
+
import { Utils } from '@pega/angular-sdk-components';
|
|
9
|
+
import { ComponentMapperComponent } from '@pega/angular-sdk-components';
|
|
10
|
+
import { PConnFieldProps } from '@pega/angular-sdk-components';
|
|
11
|
+
|
|
12
|
+
interface {{COMPONENT_CLASS_NAME}}Props extends PConnFieldProps {
|
|
13
|
+
// If any, enter additional props that only exist on URL here
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
@Component({
|
|
17
|
+
selector: 'app-{{COMPONENT_CLASS_NAME_KEBAB}}',
|
|
18
|
+
templateUrl: './{{COMPONENT_CLASS_NAME_KEBAB}}.component.html',
|
|
19
|
+
styleUrls: ['./{{COMPONENT_CLASS_NAME_KEBAB}}.component.scss'],
|
|
20
|
+
standalone: true,
|
|
21
|
+
imports: [CommonModule, ReactiveFormsModule, MatFormFieldModule, MatInputModule, forwardRef(() => ComponentMapperComponent)]
|
|
22
|
+
})
|
|
23
|
+
export class {{COMPONENT_CLASS_NAME}}Component implements OnInit, OnDestroy {
|
|
24
|
+
@Input() pConn$: typeof PConnect;
|
|
25
|
+
@Input() formGroup$: FormGroup;
|
|
26
|
+
|
|
27
|
+
// Used with AngularPConnect
|
|
28
|
+
angularPConnectData: AngularPConnectData = {};
|
|
29
|
+
configProps$: {{COMPONENT_CLASS_NAME}}Props;
|
|
30
|
+
|
|
31
|
+
label$ = '';
|
|
32
|
+
value$ = '';
|
|
33
|
+
bRequired$ = false;
|
|
34
|
+
bReadonly$ = false;
|
|
35
|
+
bDisabled$ = false;
|
|
36
|
+
bVisible$ = true;
|
|
37
|
+
displayMode$?: string = '';
|
|
38
|
+
controlName$: string;
|
|
39
|
+
bHasForm$ = true;
|
|
40
|
+
componentReference = '';
|
|
41
|
+
helperText: string;
|
|
42
|
+
placeholder: string;
|
|
43
|
+
|
|
44
|
+
fieldControl = new FormControl('', null);
|
|
45
|
+
|
|
46
|
+
constructor(
|
|
47
|
+
private angularPConnect: AngularPConnectService,
|
|
48
|
+
private cdRef: ChangeDetectorRef,
|
|
49
|
+
private utils: Utils
|
|
50
|
+
) {}
|
|
51
|
+
|
|
52
|
+
ngOnInit(): void {
|
|
53
|
+
// First thing in initialization is registering and subscribing to the AngularPConnect service
|
|
54
|
+
this.angularPConnectData = this.angularPConnect.registerAndSubscribeComponent(this, this.onStateChange);
|
|
55
|
+
this.controlName$ = this.angularPConnect.getComponentID(this);
|
|
56
|
+
|
|
57
|
+
// Then, continue on with other initialization
|
|
58
|
+
|
|
59
|
+
// call updateSelf when initializing
|
|
60
|
+
// this.updateSelf();
|
|
61
|
+
this.checkAndUpdate();
|
|
62
|
+
|
|
63
|
+
if (this.formGroup$) {
|
|
64
|
+
// add control to formGroup
|
|
65
|
+
this.formGroup$.addControl(this.controlName$, this.fieldControl);
|
|
66
|
+
this.fieldControl.setValue(this.value$);
|
|
67
|
+
this.bHasForm$ = true;
|
|
68
|
+
} else {
|
|
69
|
+
this.bReadonly$ = true;
|
|
70
|
+
this.bHasForm$ = false;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
ngOnDestroy(): void {
|
|
75
|
+
if (this.formGroup$) {
|
|
76
|
+
this.formGroup$.removeControl(this.controlName$);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (this.angularPConnectData.unsubscribeFn) {
|
|
80
|
+
this.angularPConnectData.unsubscribeFn();
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Callback passed when subscribing to store change
|
|
85
|
+
onStateChange() {
|
|
86
|
+
this.checkAndUpdate();
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
checkAndUpdate() {
|
|
90
|
+
// Should always check the bridge to see if the component should
|
|
91
|
+
// update itself (re-render)
|
|
92
|
+
const bUpdateSelf = this.angularPConnect.shouldComponentUpdate(this);
|
|
93
|
+
|
|
94
|
+
// ONLY call updateSelf when the component should update
|
|
95
|
+
if (bUpdateSelf) {
|
|
96
|
+
this.updateSelf();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// updateSelf
|
|
101
|
+
updateSelf(): void {
|
|
102
|
+
// moved this from ngOnInit() and call this from there instead...
|
|
103
|
+
this.configProps$ = this.pConn$.resolveConfigProps(this.pConn$.getConfigProps()) as {{COMPONENT_CLASS_NAME}}Props;
|
|
104
|
+
|
|
105
|
+
if (this.configProps$.value != undefined) {
|
|
106
|
+
this.value$ = this.configProps$.value;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
this.label$ = this.configProps$.label;
|
|
110
|
+
this.displayMode$ = this.configProps$.displayMode;
|
|
111
|
+
this.helperText = this.configProps$.helperText;
|
|
112
|
+
this.placeholder = this.configProps$.placeholder || '';
|
|
113
|
+
|
|
114
|
+
// timeout and detectChanges to avoid ExpressionChangedAfterItHasBeenCheckedError
|
|
115
|
+
setTimeout(() => {
|
|
116
|
+
if (this.configProps$.required != null) {
|
|
117
|
+
this.bRequired$ = this.utils.getBooleanValue(this.configProps$.required);
|
|
118
|
+
}
|
|
119
|
+
this.cdRef.detectChanges();
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
if (this.configProps$.visibility != null) {
|
|
123
|
+
this.bVisible$ = this.utils.getBooleanValue(this.configProps$.visibility);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// disabled
|
|
127
|
+
if (this.configProps$.disabled != undefined) {
|
|
128
|
+
this.bDisabled$ = this.utils.getBooleanValue(this.configProps$.disabled);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (this.bDisabled$) {
|
|
132
|
+
this.fieldControl.disable();
|
|
133
|
+
} else {
|
|
134
|
+
this.fieldControl.enable();
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (this.configProps$.readOnly != null) {
|
|
138
|
+
this.bReadonly$ = this.utils.getBooleanValue(this.configProps$.readOnly);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
this.componentReference = (this.pConn$.getStateProps() as any).value;
|
|
142
|
+
|
|
143
|
+
// trigger display of error message with field control
|
|
144
|
+
if (this.angularPConnectData.validateMessage != null && this.angularPConnectData.validateMessage != '') {
|
|
145
|
+
const timer = interval(100).subscribe(() => {
|
|
146
|
+
this.fieldControl.setErrors({ message: true });
|
|
147
|
+
this.fieldControl.markAsTouched();
|
|
148
|
+
|
|
149
|
+
timer.unsubscribe();
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
fieldOnChange(event: any) {
|
|
155
|
+
this.angularPConnectData.actions?.onChange(this, event);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
fieldOnBlur(event: any) {
|
|
159
|
+
// PConnect wants to use eventHandler for onBlur
|
|
160
|
+
this.angularPConnectData.actions?.onBlur(this, event);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
getErrorMessage() {
|
|
164
|
+
let errMessage = '';
|
|
165
|
+
|
|
166
|
+
// look for validation messages for json, pre-defined or just an error pushed from workitem (400)
|
|
167
|
+
if (this.fieldControl.hasError('message')) {
|
|
168
|
+
errMessage = this.angularPConnectData.validateMessage ?? '';
|
|
169
|
+
return errMessage;
|
|
170
|
+
}
|
|
171
|
+
if (this.fieldControl.hasError('required')) {
|
|
172
|
+
errMessage = 'You must enter a value';
|
|
173
|
+
} else if (this.fieldControl.errors) {
|
|
174
|
+
errMessage = this.fieldControl.errors.toString();
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
return errMessage;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
@@ -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,58 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
3
|
+
|
|
4
|
+
import {{COMPONENT_CLASS_NAME}} from './index';
|
|
5
|
+
import { configProps } from './mock';
|
|
6
|
+
|
|
7
|
+
const meta: Meta<typeof {{COMPONENT_CLASS_NAME}}> = {
|
|
8
|
+
title: '{{COMPONENT_CLASS_NAME}}',
|
|
9
|
+
component: {{COMPONENT_CLASS_NAME}},
|
|
10
|
+
excludeStories: /.*Data$/
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export default meta;
|
|
14
|
+
type Story = StoryObj<typeof {{COMPONENT_CLASS_NAME}}>;
|
|
15
|
+
|
|
16
|
+
export const Base{{COMPONENT_CLASS_NAME}}: Story = args => {
|
|
17
|
+
const [value, setValue] = useState(configProps.value);
|
|
18
|
+
|
|
19
|
+
const props = {
|
|
20
|
+
value,
|
|
21
|
+
placeholder: configProps.placeholder,
|
|
22
|
+
getPConnect: () => {
|
|
23
|
+
return {
|
|
24
|
+
getActionsApi: () => {
|
|
25
|
+
return {
|
|
26
|
+
updateFieldValue: (propName, theValue) => {
|
|
27
|
+
setValue(theValue);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
},
|
|
31
|
+
getStateProps: () => {
|
|
32
|
+
return { value: '.name' };
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
},
|
|
36
|
+
onChange: event => {
|
|
37
|
+
setValue(event.target.value);
|
|
38
|
+
},
|
|
39
|
+
onBlur: () => {
|
|
40
|
+
return configProps.value;
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
return <{{COMPONENT_CLASS_NAME}} {...props} {...args} />;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
Base{{COMPONENT_CLASS_NAME}}.args = {
|
|
48
|
+
label: configProps.label,
|
|
49
|
+
helperText: configProps.helperText,
|
|
50
|
+
testId: configProps.testId,
|
|
51
|
+
readOnly: configProps.readOnly,
|
|
52
|
+
disabled: configProps.disabled,
|
|
53
|
+
required: configProps.required,
|
|
54
|
+
status: configProps.status,
|
|
55
|
+
hideLabel: configProps.hideLabel,
|
|
56
|
+
displayMode: configProps.displayMode,
|
|
57
|
+
validatemessage: configProps.validatemessage
|
|
58
|
+
};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { TextField } from '@material-ui/core';
|
|
2
|
+
|
|
3
|
+
import { getComponentFromMap } from '@pega/react-sdk-components/lib/bridge/helpers/sdk_component_map';
|
|
4
|
+
import { PConnFieldProps } from '@pega/react-sdk-components/lib/types/PConnProps';
|
|
5
|
+
import Styled{{COMPONENT_CLASS_NAME}}Wrapper from './styles';
|
|
6
|
+
|
|
7
|
+
interface {{COMPONENT_CLASS_NAME}}Props extends PConnFieldProps {
|
|
8
|
+
// If any, enter additional props that only exist on this componentName
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// Duplicated runtime code from React SDK
|
|
12
|
+
|
|
13
|
+
// props passed in combination of props from property panel (config.json) and run time props from Constellation
|
|
14
|
+
export default function {{COMPONENT_CLASS_NAME}}(props: {{COMPONENT_CLASS_NAME}}Props) {
|
|
15
|
+
// Get emitted components from map (so we can get any override that may exist)
|
|
16
|
+
const FieldValueList = getComponentFromMap('FieldValueList');
|
|
17
|
+
const TextInput = getComponentFromMap('TextInput');
|
|
18
|
+
|
|
19
|
+
const {
|
|
20
|
+
label,
|
|
21
|
+
required,
|
|
22
|
+
disabled,
|
|
23
|
+
value = '',
|
|
24
|
+
validatemessage,
|
|
25
|
+
status,
|
|
26
|
+
onChange,
|
|
27
|
+
onBlur,
|
|
28
|
+
readOnly,
|
|
29
|
+
testId,
|
|
30
|
+
helperText,
|
|
31
|
+
displayMode,
|
|
32
|
+
hideLabel,
|
|
33
|
+
placeholder
|
|
34
|
+
} = props;
|
|
35
|
+
const helperTextToDisplay = validatemessage || helperText;
|
|
36
|
+
|
|
37
|
+
if (displayMode === 'LABELS_LEFT') {
|
|
38
|
+
return <FieldValueList name={hideLabel ? '' : label} value={value} />;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (displayMode === 'STACKED_LARGE_VAL') {
|
|
42
|
+
return <FieldValueList name={hideLabel ? '' : label} value={value} variant='stacked' />;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (readOnly) {
|
|
46
|
+
return <TextInput {...props} />;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
let testProp = {};
|
|
50
|
+
|
|
51
|
+
testProp = {
|
|
52
|
+
'data-test-id': testId
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<Styled{{COMPONENT_CLASS_NAME}}Wrapper>
|
|
57
|
+
<TextField
|
|
58
|
+
type='url'
|
|
59
|
+
fullWidth
|
|
60
|
+
variant='outlined'
|
|
61
|
+
helperText={helperTextToDisplay}
|
|
62
|
+
placeholder={placeholder ?? ''}
|
|
63
|
+
size='small'
|
|
64
|
+
required={required}
|
|
65
|
+
disabled={disabled}
|
|
66
|
+
onChange={onChange}
|
|
67
|
+
onBlur={!readOnly ? onBlur : undefined}
|
|
68
|
+
error={status === 'error'}
|
|
69
|
+
label={label}
|
|
70
|
+
value={value}
|
|
71
|
+
{{! pick new delimiters for mustache }}
|
|
72
|
+
{{=<% %>=}}
|
|
73
|
+
InputProps={{ inputProps: { ...testProp } }}
|
|
74
|
+
<%={{ }}=%> {{! revert delimiters for mustache }}
|
|
75
|
+
/>
|
|
76
|
+
</Styled{{COMPONENT_CLASS_NAME}}Wrapper>
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// eslint-disable-next-line import/prefer-default-export
|
|
2
|
+
export const configProps = {
|
|
3
|
+
value: '',
|
|
4
|
+
label: 'URL Sample',
|
|
5
|
+
placeholder: 'URL Placeholder',
|
|
6
|
+
helperText: 'URL Helper Text',
|
|
7
|
+
testId: 'url-12345678',
|
|
8
|
+
hasSuggestions: false,
|
|
9
|
+
required: false,
|
|
10
|
+
disabled: false,
|
|
11
|
+
readOnly: false,
|
|
12
|
+
displayMode: '',
|
|
13
|
+
status: '',
|
|
14
|
+
hideLabel: false,
|
|
15
|
+
validatemessage: ''
|
|
16
|
+
};
|
|
@@ -49,7 +49,7 @@ export default function {{COMPONENT_CLASS_NAME}}(props: {{COMPONENT_CLASS_NAME}}
|
|
|
49
49
|
field.config.displayAsStatus = true;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
return getPConnect().createComponent(field, '',
|
|
52
|
+
return getPConnect().createComponent(field, '', 0, {}); // 2nd, 3rd, and 4th args empty string/object/null until typedef marked correctly as optional
|
|
53
53
|
});
|
|
54
54
|
}
|
|
55
55
|
|
|
@@ -49,7 +49,7 @@ export default function {{COMPONENT_CLASS_NAME}}(props: {{COMPONENT_CLASS_NAME}}
|
|
|
49
49
|
field.config.displayAsStatus = true;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
return getPConnect().createComponent(field, '',
|
|
52
|
+
return getPConnect().createComponent(field, '', 0, {}); // 2nd, 3rd, and 4th args empty string/object/null until typedef marked correctly as optional
|
|
53
53
|
});
|
|
54
54
|
}
|
|
55
55
|
|
|
@@ -141,6 +141,7 @@ export const zipComponent = async (componentKey, category = CATEGORY_CUSTOM) =>
|
|
|
141
141
|
|
|
142
142
|
const configJson = `${srcDirectory}/config.json`;
|
|
143
143
|
const configExtJson = `${srcDirectory}/config-ext.json`;
|
|
144
|
+
const localizationJson = `${srcDirectory}/localizations.json`;
|
|
144
145
|
|
|
145
146
|
const zip = new AdmZip();
|
|
146
147
|
|
|
@@ -148,6 +149,9 @@ export const zipComponent = async (componentKey, category = CATEGORY_CUSTOM) =>
|
|
|
148
149
|
if (category === CATEGORY_CUSTOM || category == CATEGORY_CONSTELLATION) {
|
|
149
150
|
zip.addLocalFolder(srcDirectory, 'src/');
|
|
150
151
|
zip.addLocalFile(configJson);
|
|
152
|
+
if (fs.existsSync(localizationJson)) {
|
|
153
|
+
zip.addLocalFile(localizationJson);
|
|
154
|
+
}
|
|
151
155
|
}
|
|
152
156
|
else {
|
|
153
157
|
// check to see if have file
|
|
@@ -127,6 +127,7 @@ export const zipComponent = async (componentKey, category = CATEGORY_CUSTOM) =>
|
|
|
127
127
|
const buildDirectory = await path.join(path.resolve(), 'dist/components', componentKey);
|
|
128
128
|
const configJson = `${srcDirectory}/config.json`;
|
|
129
129
|
const configExtJson = `${srcDirectory}/config-ext.json`;
|
|
130
|
+
const localizationJson = `${srcDirectory}/localizations.json`;
|
|
130
131
|
|
|
131
132
|
const zip = new AdmZip();
|
|
132
133
|
|
|
@@ -134,6 +135,9 @@ export const zipComponent = async (componentKey, category = CATEGORY_CUSTOM) =>
|
|
|
134
135
|
if (category === CATEGORY_CUSTOM || category == CATEGORY_CONSTELLATION) {
|
|
135
136
|
zip.addLocalFolder(srcDirectory, 'src/');
|
|
136
137
|
zip.addLocalFile(configJson);
|
|
138
|
+
if (fs.existsSync(localizationJson)) {
|
|
139
|
+
zip.addLocalFile(localizationJson);
|
|
140
|
+
}
|
|
137
141
|
}
|
|
138
142
|
else {
|
|
139
143
|
// check to see if have file
|
|
@@ -151,7 +155,7 @@ export const zipComponent = async (componentKey, category = CATEGORY_CUSTOM) =>
|
|
|
151
155
|
let configContent = "{ }";
|
|
152
156
|
if (category === CATEGORY_CUSTOM || category === CATEGORY_CONSTELLATION) {
|
|
153
157
|
configContent = Buffer.from(fs.readFileSync(`${srcDirectory}/config.json`)).toString();
|
|
154
|
-
|
|
158
|
+
|
|
155
159
|
// cleanup will remove this directory
|
|
156
160
|
|
|
157
161
|
}
|
|
@@ -160,7 +164,7 @@ export const zipComponent = async (componentKey, category = CATEGORY_CUSTOM) =>
|
|
|
160
164
|
configContent = Buffer.from(fs.readFileSync(`${srcDirectory}/config-ext.json`)).toString();
|
|
161
165
|
|
|
162
166
|
// cleanup will remove this directory
|
|
163
|
-
|
|
167
|
+
|
|
164
168
|
}
|
|
165
169
|
else {
|
|
166
170
|
const tempConfig = { "componentKey" : ""};
|
|
@@ -365,7 +365,13 @@ export default async (option, category = CATEGORY_CUSTOM) => {
|
|
|
365
365
|
}
|
|
366
366
|
|
|
367
367
|
// const data = JSON.parse(fs.readFileSync(path.resolve(configFile), 'utf8'));
|
|
368
|
-
|
|
368
|
+
let data;
|
|
369
|
+
try {
|
|
370
|
+
data = JSON.parse(configData);
|
|
371
|
+
}
|
|
372
|
+
catch (er) {
|
|
373
|
+
throw new Error(`Invalid schema json in config.json: ${er}`);
|
|
374
|
+
}
|
|
369
375
|
|
|
370
376
|
// for now a special case for ScalarList & Group, those doesn't have a "subtype", so for now manualy
|
|
371
377
|
// add one in here, just to pass validation
|