@genesislcap/foundation-forms 14.397.2 → 14.398.0
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/dist/custom-elements.json +389 -4
- package/dist/dts/form.d.ts +100 -1
- package/dist/dts/form.d.ts.map +1 -1
- package/dist/dts/form.styles.d.ts.map +1 -1
- package/dist/dts/form.template.d.ts.map +1 -1
- package/dist/dts/jsonforms/json-forms.d.ts +13 -0
- package/dist/dts/jsonforms/json-forms.d.ts.map +1 -1
- package/dist/dts/jsonforms/renderers/ArrayListWrapperRenderer.d.ts +5 -0
- package/dist/dts/jsonforms/renderers/ArrayListWrapperRenderer.d.ts.map +1 -1
- package/dist/dts/jsonforms/renderers/BooleanControlRenderer.d.ts.map +1 -1
- package/dist/dts/jsonforms/renderers/ConnectedMultiselectControlRenderer.d.ts.map +1 -1
- package/dist/dts/jsonforms/renderers/ControlWrapperRenderer.d.ts.map +1 -1
- package/dist/dts/jsonforms/renderers/EnumControlRenderer.d.ts.map +1 -1
- package/dist/dts/jsonforms/renderers/LayoutFormGridRenderer.d.ts +3 -0
- package/dist/dts/jsonforms/renderers/LayoutFormGridRenderer.d.ts.map +1 -0
- package/dist/dts/jsonforms/renderers/RenderersRanks.d.ts +1 -0
- package/dist/dts/jsonforms/renderers/RenderersRanks.d.ts.map +1 -1
- package/dist/dts/jsonforms/testers/isOneOfOptionMultiselect.d.ts.map +1 -1
- package/dist/dts/types.d.ts +89 -2
- package/dist/dts/types.d.ts.map +1 -1
- package/dist/dts/utils/csv-parser.d.ts +85 -0
- package/dist/dts/utils/csv-parser.d.ts.map +1 -0
- package/dist/dts/utils/index.d.ts +1 -0
- package/dist/dts/utils/index.d.ts.map +1 -1
- package/dist/dts/utils/schema-utils.d.ts +46 -0
- package/dist/dts/utils/schema-utils.d.ts.map +1 -0
- package/dist/dts/utils/validation.d.ts +2 -0
- package/dist/dts/utils/validation.d.ts.map +1 -1
- package/dist/esm/form.js +423 -5
- package/dist/esm/form.styles.js +41 -1
- package/dist/esm/form.template.js +33 -1
- package/dist/esm/jsonforms/json-forms.js +30 -0
- package/dist/esm/jsonforms/renderers/ArrayListWrapperRenderer.js +223 -22
- package/dist/esm/jsonforms/renderers/BooleanControlRenderer.js +1 -2
- package/dist/esm/jsonforms/renderers/ConnectedMultiselectControlRenderer.js +13 -2
- package/dist/esm/jsonforms/renderers/ControlWrapperRenderer.js +25 -4
- package/dist/esm/jsonforms/renderers/EnumControlRenderer.js +14 -5
- package/dist/esm/jsonforms/renderers/LayoutFormGridRenderer.js +39 -0
- package/dist/esm/jsonforms/renderers/RenderersRanks.js +1 -0
- package/dist/esm/jsonforms/testers/isOneOfOptionMultiselect.js +1 -1
- package/dist/esm/utils/csv-parser.js +486 -0
- package/dist/esm/utils/index.js +1 -0
- package/dist/esm/utils/schema-utils.js +120 -0
- package/dist/esm/utils/validation.js +2 -0
- package/dist/foundation-forms.api.json +1028 -34
- package/dist/foundation-forms.d.ts +285 -2
- package/docs/api/foundation-forms.arrayrendereroptions.md +2 -2
- package/docs/api/foundation-forms.bulkrowstatus.md +22 -0
- package/docs/api/foundation-forms.bulkrowsubmitstatus.md +13 -0
- package/docs/api/foundation-forms.bulksubmitfaileditem.md +20 -0
- package/docs/api/foundation-forms.bulksubmitresult.md +18 -0
- package/docs/api/foundation-forms.bulksubmitsuccessitem.md +17 -0
- package/docs/api/foundation-forms.childuischemaresolver.md +15 -0
- package/docs/api/foundation-forms.csvmappingresult.mappedrows.md +13 -0
- package/docs/api/foundation-forms.csvmappingresult.md +77 -0
- package/docs/api/foundation-forms.csvmappingresult.unmappedcolumns.md +13 -0
- package/docs/api/foundation-forms.csvparseresult.errors.md +13 -0
- package/docs/api/foundation-forms.csvparseresult.headers.md +13 -0
- package/docs/api/foundation-forms.csvparseresult.md +96 -0
- package/docs/api/foundation-forms.csvparseresult.rows.md +13 -0
- package/docs/api/foundation-forms.downloadcsvtemplate.md +74 -0
- package/docs/api/foundation-forms.form.bulkinsert.md +13 -0
- package/docs/api/foundation-forms.form.bulkinsertmaxitems.md +13 -0
- package/docs/api/foundation-forms.form.bulkinsertminitems.md +13 -0
- package/docs/api/foundation-forms.form.clearrowsubmitstatuses.md +17 -0
- package/docs/api/foundation-forms.form.downloadcsvtemplate.md +17 -0
- package/docs/api/foundation-forms.form.handlecsvfileselected.md +54 -0
- package/docs/api/foundation-forms.form.md +132 -0
- package/docs/api/foundation-forms.form.rowsubmitstatuses.md +13 -0
- package/docs/api/foundation-forms.form.submitsinglerow.md +56 -0
- package/docs/api/foundation-forms.generatecsvtemplate.md +104 -0
- package/docs/api/foundation-forms.mapcsvtoschema.md +88 -0
- package/docs/api/foundation-forms.md +147 -0
- package/docs/api/foundation-forms.parsecsv.md +56 -0
- package/docs/api/foundation-forms.uischemaelementtype.md +1 -1
- package/docs/api-report.md.api.md +87 -4
- package/package.json +19 -17
|
@@ -30,6 +30,16 @@ let JSONForms = class JSONForms extends FASTElement {
|
|
|
30
30
|
constructor() {
|
|
31
31
|
super(...arguments);
|
|
32
32
|
this.ajv = createAjv({ useDefaults: true, $data: true });
|
|
33
|
+
/**
|
|
34
|
+
* Row submit statuses for bulk insert mode.
|
|
35
|
+
* Passed from the parent foundation-form.
|
|
36
|
+
*/
|
|
37
|
+
this.rowSubmitStatuses = new Map();
|
|
38
|
+
/**
|
|
39
|
+
* Whether the form is in bulk insert mode.
|
|
40
|
+
* Passed from the parent foundation-form.
|
|
41
|
+
*/
|
|
42
|
+
this.bulkInsert = false;
|
|
33
43
|
this.dispatch = (action) => {
|
|
34
44
|
this.jsonforms = Object.assign(Object.assign({}, this.jsonforms), { core: coreReducer(this.jsonforms.core, action) });
|
|
35
45
|
this.$emit('data-change', {
|
|
@@ -113,6 +123,8 @@ let JSONForms = class JSONForms extends FASTElement {
|
|
|
113
123
|
i18n: i18nReducer(this.i18n, Actions.updateI18n((_b = this.i18n) === null || _b === void 0 ? void 0 : _b.locale, (_c = this.i18n) === null || _c === void 0 ? void 0 : _c.translate, ((_d = this.i18n) === null || _d === void 0 ? void 0 : _d.translateError) || errorTranslator)),
|
|
114
124
|
renderers: this.renderers,
|
|
115
125
|
readonly: this.readonly,
|
|
126
|
+
rowSubmitStatuses: this.rowSubmitStatuses,
|
|
127
|
+
bulkInsert: this.bulkInsert,
|
|
116
128
|
};
|
|
117
129
|
const additionalErrors = this.validate(this.uichemaToUse);
|
|
118
130
|
this.$emit('data-change', {
|
|
@@ -142,6 +154,18 @@ let JSONForms = class JSONForms extends FASTElement {
|
|
|
142
154
|
configChanged() {
|
|
143
155
|
this.schemaChanged();
|
|
144
156
|
}
|
|
157
|
+
rowSubmitStatusesChanged() {
|
|
158
|
+
// Update the jsonforms object to trigger re-render in child renderers
|
|
159
|
+
if (this.jsonforms) {
|
|
160
|
+
this.jsonforms = Object.assign(Object.assign({}, this.jsonforms), { rowSubmitStatuses: this.rowSubmitStatuses });
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
bulkInsertChanged() {
|
|
164
|
+
// Update the jsonforms object to trigger re-render in child renderers
|
|
165
|
+
if (this.jsonforms) {
|
|
166
|
+
this.jsonforms = Object.assign(Object.assign({}, this.jsonforms), { bulkInsert: this.bulkInsert });
|
|
167
|
+
}
|
|
168
|
+
}
|
|
145
169
|
get props() {
|
|
146
170
|
var _a;
|
|
147
171
|
if (!this.schema && !this.uischema) {
|
|
@@ -213,6 +237,12 @@ __decorate([
|
|
|
213
237
|
__decorate([
|
|
214
238
|
observable
|
|
215
239
|
], JSONForms.prototype, "config", void 0);
|
|
240
|
+
__decorate([
|
|
241
|
+
observable
|
|
242
|
+
], JSONForms.prototype, "rowSubmitStatuses", void 0);
|
|
243
|
+
__decorate([
|
|
244
|
+
observable
|
|
245
|
+
], JSONForms.prototype, "bulkInsert", void 0);
|
|
216
246
|
JSONForms = __decorate([
|
|
217
247
|
customElement({
|
|
218
248
|
name: 'json-forms',
|
|
@@ -3,6 +3,13 @@ import { Generate, composePaths, createDefaultValue } from '@jsonforms/core';
|
|
|
3
3
|
import { designUnit } from '@microsoft/fast-components';
|
|
4
4
|
import { html, css, observable, customElement, FASTElement, repeat, } from '@microsoft/fast-element';
|
|
5
5
|
import { logger } from '../../utils';
|
|
6
|
+
const resolveRowUiSchema = (childUiSchema, index, rowData, formData, fallback) => {
|
|
7
|
+
if (typeof childUiSchema === 'function') {
|
|
8
|
+
const result = childUiSchema(index, rowData, formData);
|
|
9
|
+
return result !== null && result !== void 0 ? result : fallback;
|
|
10
|
+
}
|
|
11
|
+
return fallback;
|
|
12
|
+
};
|
|
6
13
|
const isDeleteButtonHidden = (ctx) => {
|
|
7
14
|
var _a, _b, _c;
|
|
8
15
|
const canDeleteFn = (_a = ctx.parent.control.uischema.options) === null || _a === void 0 ? void 0 : _a.canDelete;
|
|
@@ -13,33 +20,81 @@ const isDeleteButtonHidden = (ctx) => {
|
|
|
13
20
|
const controlData = formData[ctx.parent.control.path] && formData[ctx.parent.control.path][ctx.index];
|
|
14
21
|
return !canDeleteFn(controlData);
|
|
15
22
|
};
|
|
23
|
+
const getRowStatus = (ctx) => {
|
|
24
|
+
var _a;
|
|
25
|
+
const statuses = (_a = ctx.parent.form.jsonforms) === null || _a === void 0 ? void 0 : _a.rowSubmitStatuses;
|
|
26
|
+
return statuses === null || statuses === void 0 ? void 0 : statuses.get(ctx.index);
|
|
27
|
+
};
|
|
28
|
+
const isRowInStatus = (ctx, targetStatus) => {
|
|
29
|
+
const rowStatus = getRowStatus(ctx);
|
|
30
|
+
return (rowStatus === null || rowStatus === void 0 ? void 0 : rowStatus.status) === targetStatus;
|
|
31
|
+
};
|
|
32
|
+
const isRowDisabled = (ctx) => isRowInStatus(ctx, 'success');
|
|
33
|
+
const isRowSubmitting = (ctx) => isRowInStatus(ctx, 'submitting');
|
|
16
34
|
export const ArrayListWrapperRendererTemplate = (prefix = 'zero') => html `
|
|
17
35
|
<template>
|
|
18
36
|
${repeat((x) => Array(x.control.data), html `
|
|
19
|
-
<div class="array-list
|
|
37
|
+
<div class="array-list ${(x, ctx) => {
|
|
38
|
+
const rowStatus = getRowStatus(ctx);
|
|
39
|
+
return rowStatus ? `row-status-${rowStatus.status}` : '';
|
|
40
|
+
}}"
|
|
41
|
+
data-row-index="${(x, ctx) => ctx.index}"
|
|
42
|
+
>
|
|
43
|
+
<div class="row-status-indicator">
|
|
44
|
+
<${prefix}-progress-ring class="status-spinner"></${prefix}-progress-ring>
|
|
45
|
+
<${prefix}-icon name="check-circle" class="status-icon status-success"></${prefix}-icon>
|
|
46
|
+
<${prefix}-icon
|
|
47
|
+
name="times-circle"
|
|
48
|
+
class="status-icon status-failed"
|
|
49
|
+
title="${(x, ctx) => {
|
|
50
|
+
var _a;
|
|
51
|
+
const rowStatus = getRowStatus(ctx);
|
|
52
|
+
return ((_a = rowStatus === null || rowStatus === void 0 ? void 0 : rowStatus.errors) === null || _a === void 0 ? void 0 : _a.map((e) => e.TEXT).join(', ')) || 'Failed';
|
|
53
|
+
}}"
|
|
54
|
+
></${prefix}-icon>
|
|
55
|
+
</div>
|
|
20
56
|
<dispatch-renderer
|
|
21
57
|
?submitted=${(x, ctx) => ctx.parent.form.submitted}
|
|
22
58
|
:dispatch=${(x, ctx) => ctx.parent.form.dispatch}
|
|
23
59
|
:jsonforms=${(x, ctx) => ctx.parent.form.jsonforms}
|
|
24
60
|
:prefix=${(x, ctx) => ctx.parent.form.prefix}
|
|
25
|
-
:props=${(x, ctx) =>
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
61
|
+
:props=${(x, ctx) => {
|
|
62
|
+
var _a, _b, _c, _d;
|
|
63
|
+
const childSchema = (_a = ctx.parent.control.uischema.options) === null || _a === void 0 ? void 0 : _a.childUiSchema;
|
|
64
|
+
const formData = (_c = (_b = ctx.parent.form.jsonforms) === null || _b === void 0 ? void 0 : _b.core) === null || _c === void 0 ? void 0 : _c.data;
|
|
65
|
+
const rowData = (_d = ctx.parent.control.data) === null || _d === void 0 ? void 0 : _d[ctx.index];
|
|
66
|
+
const uischema = resolveRowUiSchema(childSchema, ctx.index, rowData, formData, ctx.parent.uiSchema);
|
|
67
|
+
return {
|
|
68
|
+
uischema,
|
|
69
|
+
schema: ctx.parent.schema,
|
|
70
|
+
renderers: ctx.parent.control.renderers,
|
|
71
|
+
path: composePaths(ctx.parent.control.path, `${ctx.index}`),
|
|
72
|
+
enabled: ctx.parent.control.enabled && !isRowDisabled(ctx),
|
|
73
|
+
};
|
|
74
|
+
}}
|
|
32
75
|
></dispatch-renderer>
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
76
|
+
<div class="button-group">
|
|
77
|
+
<${prefix}-button
|
|
78
|
+
?hidden=${(x, ctx) => { var _a; return !((_a = ctx.parent.form.jsonforms) === null || _a === void 0 ? void 0 : _a.bulkInsert) || isRowDisabled(ctx); }}
|
|
79
|
+
?disabled=${(x, ctx) => isRowSubmitting(ctx)}
|
|
80
|
+
appearance="accent"
|
|
81
|
+
class="item-control-btn row-submit-btn"
|
|
82
|
+
data-test-id=${(x, ctx) => `${ctx.parent.control.path}-${ctx.index}-submit-item`}
|
|
83
|
+
@click=${(x, ctx) => ctx.parent.submitRow(ctx.index)}
|
|
84
|
+
>
|
|
85
|
+
<${prefix}-icon name="paper-plane"></${prefix}-icon>
|
|
86
|
+
</${prefix}-button>
|
|
87
|
+
<${prefix}-button
|
|
88
|
+
?hidden=${(x, ctx) => isDeleteButtonHidden(ctx) || isRowDisabled(ctx)}
|
|
89
|
+
appearance="stealth"
|
|
90
|
+
class="item-control-btn"
|
|
91
|
+
data-test-id=${(x, ctx) => `${ctx.parent.control.path}-${ctx.index}-delete-item`}
|
|
92
|
+
@click=${(x, ctx) => ctx.parent.deleteItem(ctx.index)}
|
|
93
|
+
>
|
|
94
|
+
<${prefix}-icon name="trash"></${prefix}-icon>
|
|
95
|
+
${(x, ctx) => { var _a; return ((_a = ctx.parent.control.uischema.options) === null || _a === void 0 ? void 0 : _a.deleteLabel) || ''; }}
|
|
96
|
+
</${prefix}-button>
|
|
97
|
+
</div>
|
|
43
98
|
</div>
|
|
44
99
|
`, { positioning: true })}
|
|
45
100
|
<${prefix}-button
|
|
@@ -56,27 +111,166 @@ export const ArrayListWrapperRendererTemplate = (prefix = 'zero') => html `
|
|
|
56
111
|
const styles = css `
|
|
57
112
|
:host {
|
|
58
113
|
padding-left: calc(${designUnit} * 1px);
|
|
114
|
+
display: flex;
|
|
115
|
+
flex-direction: column;
|
|
116
|
+
gap: calc(${designUnit} * 3px);
|
|
117
|
+
|
|
118
|
+
/* Row status color tokens - can be overridden via CSS custom properties */
|
|
119
|
+
--row-status-success-color: var(--success-color, #28a745);
|
|
120
|
+
--row-status-failed-color: var(--error-color, #dc3545);
|
|
121
|
+
--row-status-submitting-color: var(--accent-fill-rest, #0078d4);
|
|
122
|
+
|
|
123
|
+
/* Array item card styling - industrial/utilitarian aesthetic */
|
|
124
|
+
--array-item-shadow: 0 1px 2px rgba(0, 0, 0, 0.04), 0 4px 8px rgba(0, 0, 0, 0.06);
|
|
125
|
+
--array-item-shadow-hover: 0 2px 4px rgba(0, 0, 0, 0.06), 0 6px 12px rgba(0, 0, 0, 0.08);
|
|
126
|
+
--array-item-border: 1px solid var(--neutral-stroke-rest, rgba(0, 0, 0, 0.12));
|
|
127
|
+
--array-item-radius: calc(${designUnit} * 2px);
|
|
59
128
|
}
|
|
60
129
|
|
|
61
130
|
.array-list {
|
|
131
|
+
display: flex;
|
|
132
|
+
align-items: flex-start;
|
|
133
|
+
position: relative;
|
|
134
|
+
padding: calc(${designUnit} * 3px);
|
|
135
|
+
padding-left: calc(${designUnit} * 2px + 3px); /* Extra space for left accent bar */
|
|
136
|
+
margin: 0;
|
|
137
|
+
background-color: var(--neutral-layer-1, #fff);
|
|
138
|
+
border: var(--array-item-border);
|
|
139
|
+
border-radius: var(--array-item-radius);
|
|
140
|
+
box-shadow: var(--array-item-shadow);
|
|
141
|
+
transition:
|
|
142
|
+
background-color 0.15s ease-in-out,
|
|
143
|
+
box-shadow 0.2s ease,
|
|
144
|
+
border-color 0.15s ease;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.array-list:hover {
|
|
148
|
+
box-shadow: var(--array-item-shadow-hover);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/* Content area grows to fill space; min-width prevents flex overflow */
|
|
152
|
+
.array-list > dispatch-renderer {
|
|
153
|
+
flex: 1;
|
|
154
|
+
min-width: 0;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/* Left accent bar for visual hierarchy - industrial form-slot feel */
|
|
158
|
+
.array-list::before {
|
|
159
|
+
content: '';
|
|
160
|
+
position: absolute;
|
|
161
|
+
left: 0;
|
|
162
|
+
top: 0;
|
|
163
|
+
bottom: 0;
|
|
164
|
+
width: 3px;
|
|
165
|
+
border-radius: var(--array-item-radius) 0 0 var(--array-item-radius);
|
|
166
|
+
background: var(--neutral-stroke-subtle, rgba(0, 0, 0, 0.06));
|
|
167
|
+
pointer-events: none;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
.array-list.row-status-success::before {
|
|
171
|
+
background: var(--row-status-success-color);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
.array-list.row-status-failed::before {
|
|
175
|
+
background: var(--row-status-failed-color);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.array-list.row-status-submitting::before {
|
|
179
|
+
background: var(--row-status-submitting-color);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.array-list.row-status-success {
|
|
183
|
+
background-color: color-mix(in srgb, var(--row-status-success-color), transparent 90%);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
.array-list.row-status-failed {
|
|
187
|
+
background-color: color-mix(in srgb, var(--row-status-failed-color), transparent 90%);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.array-list.row-status-submitting {
|
|
191
|
+
background-color: color-mix(in srgb, var(--row-status-submitting-color), transparent 95%);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
.row-status-indicator {
|
|
62
195
|
display: flex;
|
|
63
196
|
align-items: center;
|
|
197
|
+
justify-content: center;
|
|
198
|
+
min-width: calc(${designUnit} * 6px);
|
|
199
|
+
margin-right: calc(${designUnit} * 2px);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/* Hide all status indicators by default */
|
|
203
|
+
.row-status-indicator .status-spinner,
|
|
204
|
+
.row-status-indicator .status-success,
|
|
205
|
+
.row-status-indicator .status-failed {
|
|
206
|
+
display: none;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/* Show spinner when submitting */
|
|
210
|
+
.array-list.row-status-submitting .row-status-indicator .status-spinner {
|
|
211
|
+
display: flex;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/* Show success icon when successful */
|
|
215
|
+
.array-list.row-status-success .row-status-indicator .status-success {
|
|
216
|
+
display: flex;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/* Show failed icon when failed */
|
|
220
|
+
.array-list.row-status-failed .row-status-indicator .status-failed {
|
|
221
|
+
display: flex;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
.status-icon {
|
|
225
|
+
width: calc(${designUnit} * 4px);
|
|
226
|
+
height: calc(${designUnit} * 4px);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
.status-success {
|
|
230
|
+
color: var(--row-status-success-color);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
.status-failed {
|
|
234
|
+
color: var(--row-status-failed-color);
|
|
235
|
+
cursor: help;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
.status-spinner {
|
|
239
|
+
width: calc(${designUnit} * 4px);
|
|
240
|
+
height: calc(${designUnit} * 4px);
|
|
64
241
|
}
|
|
65
242
|
|
|
66
243
|
.item-control-btn {
|
|
67
|
-
color: rgb(135, 155, 166);
|
|
68
|
-
margin-left:
|
|
244
|
+
color: var(--neutral-foreground-hint, rgb(135, 155, 166));
|
|
245
|
+
margin-left: calc(${designUnit} * 3px);
|
|
69
246
|
}
|
|
70
247
|
|
|
71
248
|
.item-control-btn:hover {
|
|
72
249
|
color: var(--accent-foreground-hover);
|
|
73
250
|
}
|
|
251
|
+
|
|
252
|
+
.row-submit-btn {
|
|
253
|
+
min-width: calc(${designUnit} * 8px);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
.row-submit-btn[disabled] {
|
|
257
|
+
opacity: 0.5;
|
|
258
|
+
cursor: not-allowed;
|
|
259
|
+
}
|
|
260
|
+
.button-group {
|
|
261
|
+
display: flex;
|
|
262
|
+
flex-direction: column;
|
|
263
|
+
gap: 8px;
|
|
264
|
+
}
|
|
74
265
|
`;
|
|
75
266
|
let ArrayListWrapper = class ArrayListWrapper extends FASTElement {
|
|
76
267
|
controlChanged() {
|
|
268
|
+
var _a;
|
|
77
269
|
this.schema = this.control.schema;
|
|
78
|
-
|
|
79
|
-
|
|
270
|
+
const childUiSchema = (_a = this.control.uischema.options) === null || _a === void 0 ? void 0 : _a.childUiSchema;
|
|
271
|
+
// Only use static childUiSchema; when it's a function, resolve per-row in template
|
|
272
|
+
if (childUiSchema && typeof childUiSchema !== 'function') {
|
|
273
|
+
this.uiSchema = childUiSchema;
|
|
80
274
|
return;
|
|
81
275
|
}
|
|
82
276
|
const arrayUiSchema = Generate.uiSchema(this.schema);
|
|
@@ -89,6 +283,13 @@ let ArrayListWrapper = class ArrayListWrapper extends FASTElement {
|
|
|
89
283
|
deleteItem(index) {
|
|
90
284
|
this.control.removeItems(this.control.path, [index])();
|
|
91
285
|
}
|
|
286
|
+
/**
|
|
287
|
+
* Submits a single row by emitting an event that bubbles up to the foundation-form.
|
|
288
|
+
* @param index - The row index to submit
|
|
289
|
+
*/
|
|
290
|
+
submitRow(index) {
|
|
291
|
+
this.$emit('submit-single-row', { index }, { bubbles: true, composed: true });
|
|
292
|
+
}
|
|
92
293
|
};
|
|
93
294
|
__decorate([
|
|
94
295
|
observable
|
|
@@ -9,7 +9,6 @@ export const BooleanControlRendererTemplate = (prefix = 'zero') => html `
|
|
|
9
9
|
:jsonForms=${(x) => x.jsonforms}
|
|
10
10
|
:touched=${(x) => x.touched}
|
|
11
11
|
?submitted=${(x) => x.submitted}
|
|
12
|
-
hide-label
|
|
13
12
|
>
|
|
14
13
|
<${prefix}-checkbox
|
|
15
14
|
?checked=${(x) => x.control.data}
|
|
@@ -23,7 +22,7 @@ export const BooleanControlRendererTemplate = (prefix = 'zero') => html `
|
|
|
23
22
|
}}
|
|
24
23
|
id=${(x) => x.control.path}
|
|
25
24
|
data-test-id=${(x) => x.control.path}
|
|
26
|
-
|
|
25
|
+
></${prefix}-checkbox>
|
|
27
26
|
</control-wrapper>
|
|
28
27
|
</template>
|
|
29
28
|
`;
|
|
@@ -16,10 +16,21 @@ export const ConnectedMultiselectControlRendererTemplate = (prefix = 'zero') =>
|
|
|
16
16
|
<${prefix}-multiselect
|
|
17
17
|
style="width: 100%"
|
|
18
18
|
async=${(x) => { var _a; return (_a = x.control.uischema.options) === null || _a === void 0 ? void 0 : _a.async; }}
|
|
19
|
-
|
|
19
|
+
?disabled=${(x) => !x.control.enabled}
|
|
20
|
+
:selectedOptions=${(x) => {
|
|
21
|
+
var _a, _b, _c;
|
|
22
|
+
const selectedOptions = ((_a = x.control.uischema.options) === null || _a === void 0 ? void 0 : _a.delimiter)
|
|
23
|
+
? (_b = x.control.data) === null || _b === void 0 ? void 0 : _b.split((_c = x.control.uischema.options) === null || _c === void 0 ? void 0 : _c.delimiter)
|
|
24
|
+
: x.control.data;
|
|
25
|
+
return selectedOptions || [];
|
|
26
|
+
}}
|
|
20
27
|
tabindex="${(x) => { var _a, _b; return (_b = (_a = x.control.uischema) === null || _a === void 0 ? void 0 : _a.options) === null || _b === void 0 ? void 0 : _b.tabIndex; }}"
|
|
21
28
|
@selectionChange=${(x, c) => {
|
|
22
|
-
|
|
29
|
+
var _a, _b, _c;
|
|
30
|
+
const value = !((_a = x.control.uischema.options) === null || _a === void 0 ? void 0 : _a.delimiter)
|
|
31
|
+
? c.event.detail
|
|
32
|
+
: (_b = c.event.detail) === null || _b === void 0 ? void 0 : _b.join((_c = x.control.uischema.options) === null || _c === void 0 ? void 0 : _c.delimiter);
|
|
33
|
+
x.control.handleChange(x.control.path, value);
|
|
23
34
|
x.$emit('change');
|
|
24
35
|
x.onBlur();
|
|
25
36
|
}}
|
|
@@ -13,13 +13,19 @@ export const ControlWrapperRendererTemplate = html `
|
|
|
13
13
|
}}
|
|
14
14
|
id=${(x) => x.control.path + '-wrapper'}
|
|
15
15
|
data-test-id=${(x) => x.control.path + '-wrapper'}
|
|
16
|
+
role="group"
|
|
17
|
+
aria-labelledby=${(x) => (x.computedLabel ? x.control.path + '-label' : null)}
|
|
16
18
|
>
|
|
17
|
-
${when((x) =>
|
|
18
|
-
<
|
|
19
|
+
${when((x) => x.computedLabel, html `
|
|
20
|
+
<label
|
|
21
|
+
id="${(x) => x.control.path + '-label'}"
|
|
22
|
+
for="${(x) => x.control.path}"
|
|
23
|
+
class="${(x) => classNames('label', ['visually-hidden', x.hideLabel])}"
|
|
24
|
+
>
|
|
19
25
|
<span>
|
|
20
26
|
${(x) => x.computedLabel}${when((x) => { var _a, _b; return (_b = (_a = x.control.uischema) === null || _a === void 0 ? void 0 : _a.options) === null || _b === void 0 ? void 0 : _b.tooltip; }, (x) => x.getPrefixedTooltip)}
|
|
21
27
|
</span>
|
|
22
|
-
</
|
|
28
|
+
</label>
|
|
23
29
|
`)}
|
|
24
30
|
|
|
25
31
|
<div class="wrapper">
|
|
@@ -39,6 +45,19 @@ export const ControlWrapperRendererTemplate = html `
|
|
|
39
45
|
</template>
|
|
40
46
|
`;
|
|
41
47
|
const styles = css `
|
|
48
|
+
.visually-hidden {
|
|
49
|
+
position: absolute;
|
|
50
|
+
width: 1px;
|
|
51
|
+
height: 1px;
|
|
52
|
+
padding: 0;
|
|
53
|
+
margin: -1px;
|
|
54
|
+
overflow: hidden;
|
|
55
|
+
clip: rect(0, 0, 0, 0);
|
|
56
|
+
clip-path: inset(50%);
|
|
57
|
+
white-space: nowrap;
|
|
58
|
+
border: 0;
|
|
59
|
+
}
|
|
60
|
+
|
|
42
61
|
.wrapperRoot {
|
|
43
62
|
margin-bottom: calc(var(--design-unit) * 4px);
|
|
44
63
|
}
|
|
@@ -50,10 +69,12 @@ const styles = css `
|
|
|
50
69
|
|
|
51
70
|
.label {
|
|
52
71
|
color: var(--neutral-foreground-hint);
|
|
53
|
-
margin-bottom: calc(var(--design-unit) * 2px);
|
|
72
|
+
margin-bottom: var(--control-label-margin, calc(var(--design-unit) * 2px));
|
|
54
73
|
display: flex;
|
|
55
74
|
justify-content: space-between;
|
|
56
75
|
font-weight: 700;
|
|
76
|
+
/* Reset label defaults to match former div appearance */
|
|
77
|
+
cursor: default;
|
|
57
78
|
}
|
|
58
79
|
|
|
59
80
|
.labelLeft .wrapper {
|
|
@@ -4,6 +4,7 @@ import { capitalCase } from 'change-case';
|
|
|
4
4
|
import { comboboxRendererStyles } from '../../form.styles';
|
|
5
5
|
import { isOneOfEnum } from '../testers/isOneOfEnum';
|
|
6
6
|
import { ENUM_CONTROL_RANK } from './RenderersRanks';
|
|
7
|
+
const getOptionLabel = (option, labelRowFormatter) => labelRowFormatter ? labelRowFormatter(option.label) : capitalCase(option.label);
|
|
7
8
|
// overrides https://github.com/eclipsesource/jsonforms/blob/69441cdfc48f359850d87fa4b842856f1f139eb2/packages/core/src/util/renderer.ts#L515
|
|
8
9
|
// to allow mapping of enums that come as oneOf
|
|
9
10
|
export const mapStateToEnumControlProps = (state, ownProps) => {
|
|
@@ -16,12 +17,13 @@ export const mapStateToEnumControlProps = (state, ownProps) => {
|
|
|
16
17
|
return Object.assign(Object.assign({}, props), { options });
|
|
17
18
|
};
|
|
18
19
|
const updateEnumData = (dispatchRenderer, data) => {
|
|
19
|
-
var _a;
|
|
20
|
-
|
|
20
|
+
var _a, _b, _c;
|
|
21
|
+
const formatter = (_b = (_a = dispatchRenderer.control.uischema) === null || _a === void 0 ? void 0 : _a.options) === null || _b === void 0 ? void 0 : _b.labelRowFormatter;
|
|
22
|
+
dispatchRenderer.control.handleChange(dispatchRenderer.control.path, (_c = dispatchRenderer.control.options.find((option) => getOptionLabel(option, formatter) === data)) === null || _c === void 0 ? void 0 : _c.value);
|
|
21
23
|
dispatchRenderer.onBlur();
|
|
22
24
|
};
|
|
23
25
|
const displaySetOrDefaultData = (dispatchRenderer) => {
|
|
24
|
-
var _a, _b, _c, _d;
|
|
26
|
+
var _a, _b, _c, _d, _e;
|
|
25
27
|
let data = dispatchRenderer.control.data;
|
|
26
28
|
if (!data) {
|
|
27
29
|
const enumDefault = (_c = (_b = (_a = dispatchRenderer.control.schema) === null || _a === void 0 ? void 0 : _a.oneOf) === null || _b === void 0 ? void 0 : _b.find((x) => x.hasOwnProperty('default'))) === null || _c === void 0 ? void 0 : _c.default;
|
|
@@ -30,7 +32,11 @@ const displaySetOrDefaultData = (dispatchRenderer) => {
|
|
|
30
32
|
updateEnumData(dispatchRenderer, data);
|
|
31
33
|
}
|
|
32
34
|
}
|
|
33
|
-
|
|
35
|
+
const option = dispatchRenderer.control.options.find((opt) => opt.value === data);
|
|
36
|
+
if (!option)
|
|
37
|
+
return '';
|
|
38
|
+
const formatter = (_e = (_d = dispatchRenderer.control.uischema) === null || _d === void 0 ? void 0 : _d.options) === null || _e === void 0 ? void 0 : _e.labelRowFormatter;
|
|
39
|
+
return getOptionLabel(option, formatter);
|
|
34
40
|
};
|
|
35
41
|
export const EnumControlRendererTemplate = (prefix = 'zero') => html `
|
|
36
42
|
<template>
|
|
@@ -54,7 +60,10 @@ export const EnumControlRendererTemplate = (prefix = 'zero') => html `
|
|
|
54
60
|
data-test-id=${(x) => x.control.path}
|
|
55
61
|
>
|
|
56
62
|
${repeat((x) => x.control.options, html `
|
|
57
|
-
<${prefix}-option>${(x) =>
|
|
63
|
+
<${prefix}-option>${(x, ctx) => {
|
|
64
|
+
var _a, _b, _c, _d;
|
|
65
|
+
return getOptionLabel(x, (_d = (_c = (_b = (_a = ctx.parent) === null || _a === void 0 ? void 0 : _a.control) === null || _b === void 0 ? void 0 : _b.uischema) === null || _c === void 0 ? void 0 : _c.options) === null || _d === void 0 ? void 0 : _d.labelRowFormatter);
|
|
66
|
+
}}</${prefix}-option>
|
|
58
67
|
`)}
|
|
59
68
|
</${prefix}-combobox>
|
|
60
69
|
</control-wrapper>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { mapStateToLayoutProps, rankWith } from '@jsonforms/core';
|
|
2
|
+
import { html, repeat } from '@microsoft/fast-element';
|
|
3
|
+
import { LayoutWrapper } from './LayoutRenderer';
|
|
4
|
+
import { LAYOUT_FORM_GRID_RANK } from './RenderersRanks';
|
|
5
|
+
LayoutWrapper;
|
|
6
|
+
export const LayoutFormGridRendererTemplate = html `
|
|
7
|
+
<template>
|
|
8
|
+
<layout-wrapper :control=${(x) => x.control}>
|
|
9
|
+
<div
|
|
10
|
+
style="
|
|
11
|
+
display: grid;
|
|
12
|
+
grid-template-columns: repeat(4, 1fr);
|
|
13
|
+
gap: 8px;
|
|
14
|
+
"
|
|
15
|
+
>
|
|
16
|
+
${repeat((x) => x.control.uischema.elements, html `
|
|
17
|
+
<dispatch-renderer
|
|
18
|
+
?submitted=${(x, ctx) => ctx.parent.submitted}
|
|
19
|
+
:dispatch=${(x, ctx) => ctx.parent.dispatch}
|
|
20
|
+
:jsonforms=${(x, ctx) => ctx.parent.jsonforms}
|
|
21
|
+
:prefix=${(x, ctx) => ctx.parent.prefix}
|
|
22
|
+
:props=${(x, ctx) => ({
|
|
23
|
+
uischema: x,
|
|
24
|
+
schema: ctx.parent.control.schema,
|
|
25
|
+
renderers: ctx.parent.control.renderers,
|
|
26
|
+
path: ctx.parent.control.path,
|
|
27
|
+
enabled: ctx.parent.control.enabled,
|
|
28
|
+
})}
|
|
29
|
+
></dispatch-renderer>
|
|
30
|
+
`)}
|
|
31
|
+
</div>
|
|
32
|
+
</layout-wrapper>
|
|
33
|
+
</template>
|
|
34
|
+
`;
|
|
35
|
+
export const LayoutFormGridEntry = {
|
|
36
|
+
renderer: LayoutFormGridRendererTemplate,
|
|
37
|
+
tester: rankWith(LAYOUT_FORM_GRID_RANK, (uiSchema) => uiSchema.type === 'FormGridLayout'),
|
|
38
|
+
mapper: mapStateToLayoutProps,
|
|
39
|
+
};
|
|
@@ -13,5 +13,6 @@ export const LAYOUT_GROUP_RANK = 2;
|
|
|
13
13
|
export const LAYOUT_HORIZONTAL_RANK = 2;
|
|
14
14
|
export const LAYOUT_STEPPER_RANK = 3;
|
|
15
15
|
export const LAYOUT2COLUMNS_RANK = 2;
|
|
16
|
+
export const LAYOUT_FORM_GRID_RANK = 2;
|
|
16
17
|
export const INVISIBLE_CONTROL_RANK = 5;
|
|
17
18
|
export const DIVIDER_CONTROL_RANK = 5;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { and, hasType, or, schemaMatches } from '@jsonforms/core';
|
|
2
2
|
import { optionIs } from './optionIs';
|
|
3
|
-
export const isOneOfOptionMultiselect = and(or(optionIs('allOptionsResourceName'), optionIs('data')), or(schemaMatches((schema) => hasType(schema, 'array')), schemaMatches((schema) => schema.hasOwnProperty('oneOf') && schema.oneOf.some((s) => hasType(s, 'array')))));
|
|
3
|
+
export const isOneOfOptionMultiselect = and(or(optionIs('allOptionsResourceName'), optionIs('data')), or(optionIs('delimiter'), schemaMatches((schema) => hasType(schema, 'array')), schemaMatches((schema) => schema.hasOwnProperty('oneOf') && schema.oneOf.some((s) => hasType(s, 'array')))));
|