@genesislcap/foundation-forms 14.396.4 → 14.397.1-alpha-87a7828.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 +565 -241
- 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/types.d.ts +88 -1
- package/dist/dts/types.d.ts.map +1 -1
- package/dist/dts/utils/csv-parser.d.ts +82 -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 +421 -5
- package/dist/esm/form.styles.js +38 -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 +207 -13
- package/dist/esm/utils/csv-parser.js +458 -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 +1006 -29
- package/dist/foundation-forms.d.ts +281 -1
- 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 +72 -0
- package/docs/api/foundation-forms.md +147 -0
- package/docs/api/foundation-forms.parsecsv.md +56 -0
- package/docs/api-report.md.api.md +85 -3
- package/package.json +19 -17
|
@@ -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,25 +20,71 @@ 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
76
|
<${prefix}-button
|
|
34
|
-
?hidden=${(x, ctx) =>
|
|
77
|
+
?hidden=${(x, ctx) => { var _a; return !((_a = ctx.parent.form.jsonforms) === null || _a === void 0 ? void 0 : _a.bulkInsert) || isRowDisabled(ctx); }}
|
|
78
|
+
?disabled=${(x, ctx) => isRowSubmitting(ctx)}
|
|
79
|
+
appearance="accent"
|
|
80
|
+
class="item-control-btn row-submit-btn"
|
|
81
|
+
data-test-id=${(x, ctx) => `${ctx.parent.control.path}-${ctx.index}-submit-item`}
|
|
82
|
+
@click=${(x, ctx) => ctx.parent.submitRow(ctx.index)}
|
|
83
|
+
>
|
|
84
|
+
<${prefix}-icon name="paper-plane"></${prefix}-icon>
|
|
85
|
+
</${prefix}-button>
|
|
86
|
+
<${prefix}-button
|
|
87
|
+
?hidden=${(x, ctx) => isDeleteButtonHidden(ctx) || isRowDisabled(ctx)}
|
|
35
88
|
appearance="lightweight"
|
|
36
89
|
class="item-control-btn"
|
|
37
90
|
data-test-id=${(x, ctx) => `${ctx.parent.control.path}-${ctx.index}-delete-item`}
|
|
@@ -56,27 +109,161 @@ export const ArrayListWrapperRendererTemplate = (prefix = 'zero') => html `
|
|
|
56
109
|
const styles = css `
|
|
57
110
|
:host {
|
|
58
111
|
padding-left: calc(${designUnit} * 1px);
|
|
112
|
+
display: flex;
|
|
113
|
+
flex-direction: column;
|
|
114
|
+
gap: calc(${designUnit} * 3px);
|
|
115
|
+
|
|
116
|
+
/* Row status color tokens - can be overridden via CSS custom properties */
|
|
117
|
+
--row-status-success-color: var(--success-color, #28a745);
|
|
118
|
+
--row-status-failed-color: var(--error-color, #dc3545);
|
|
119
|
+
--row-status-submitting-color: var(--accent-fill-rest, #0078d4);
|
|
120
|
+
|
|
121
|
+
/* Array item card styling - industrial/utilitarian aesthetic */
|
|
122
|
+
--array-item-shadow: 0 1px 2px rgba(0, 0, 0, 0.04), 0 4px 8px rgba(0, 0, 0, 0.06);
|
|
123
|
+
--array-item-shadow-hover: 0 2px 4px rgba(0, 0, 0, 0.06), 0 6px 12px rgba(0, 0, 0, 0.08);
|
|
124
|
+
--array-item-border: 1px solid var(--neutral-stroke-rest, rgba(0, 0, 0, 0.12));
|
|
125
|
+
--array-item-radius: calc(${designUnit} * 2px);
|
|
59
126
|
}
|
|
60
127
|
|
|
61
128
|
.array-list {
|
|
129
|
+
display: flex;
|
|
130
|
+
align-items: flex-start;
|
|
131
|
+
position: relative;
|
|
132
|
+
padding: calc(${designUnit} * 2px) calc(${designUnit} * 3px);
|
|
133
|
+
padding-left: calc(${designUnit} * 2px + 3px); /* Extra space for left accent bar */
|
|
134
|
+
margin: 0;
|
|
135
|
+
background-color: var(--neutral-layer-1, #fff);
|
|
136
|
+
border: var(--array-item-border);
|
|
137
|
+
border-radius: var(--array-item-radius);
|
|
138
|
+
box-shadow: var(--array-item-shadow);
|
|
139
|
+
transition:
|
|
140
|
+
background-color 0.15s ease-in-out,
|
|
141
|
+
box-shadow 0.2s ease,
|
|
142
|
+
border-color 0.15s ease;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.array-list:hover {
|
|
146
|
+
box-shadow: var(--array-item-shadow-hover);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/* Content area grows to fill space; min-width prevents flex overflow */
|
|
150
|
+
.array-list > dispatch-renderer {
|
|
151
|
+
flex: 1;
|
|
152
|
+
min-width: 0;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/* Left accent bar for visual hierarchy - industrial form-slot feel */
|
|
156
|
+
.array-list::before {
|
|
157
|
+
content: '';
|
|
158
|
+
position: absolute;
|
|
159
|
+
left: 0;
|
|
160
|
+
top: 0;
|
|
161
|
+
bottom: 0;
|
|
162
|
+
width: 3px;
|
|
163
|
+
border-radius: var(--array-item-radius) 0 0 var(--array-item-radius);
|
|
164
|
+
background: var(--neutral-stroke-subtle, rgba(0, 0, 0, 0.06));
|
|
165
|
+
pointer-events: none;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
.array-list.row-status-success::before {
|
|
169
|
+
background: var(--row-status-success-color);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
.array-list.row-status-failed::before {
|
|
173
|
+
background: var(--row-status-failed-color);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.array-list.row-status-submitting::before {
|
|
177
|
+
background: var(--row-status-submitting-color);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.array-list.row-status-success {
|
|
181
|
+
background-color: color-mix(in srgb, var(--row-status-success-color), transparent 90%);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
.array-list.row-status-failed {
|
|
185
|
+
background-color: color-mix(in srgb, var(--row-status-failed-color), transparent 90%);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
.array-list.row-status-submitting {
|
|
189
|
+
background-color: color-mix(in srgb, var(--row-status-submitting-color), transparent 95%);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.row-status-indicator {
|
|
62
193
|
display: flex;
|
|
63
194
|
align-items: center;
|
|
195
|
+
justify-content: center;
|
|
196
|
+
min-width: calc(${designUnit} * 6px);
|
|
197
|
+
margin-right: calc(${designUnit} * 2px);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/* Hide all status indicators by default */
|
|
201
|
+
.row-status-indicator .status-spinner,
|
|
202
|
+
.row-status-indicator .status-success,
|
|
203
|
+
.row-status-indicator .status-failed {
|
|
204
|
+
display: none;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/* Show spinner when submitting */
|
|
208
|
+
.array-list.row-status-submitting .row-status-indicator .status-spinner {
|
|
209
|
+
display: flex;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/* Show success icon when successful */
|
|
213
|
+
.array-list.row-status-success .row-status-indicator .status-success {
|
|
214
|
+
display: flex;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/* Show failed icon when failed */
|
|
218
|
+
.array-list.row-status-failed .row-status-indicator .status-failed {
|
|
219
|
+
display: flex;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.status-icon {
|
|
223
|
+
width: calc(${designUnit} * 4px);
|
|
224
|
+
height: calc(${designUnit} * 4px);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
.status-success {
|
|
228
|
+
color: var(--row-status-success-color);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
.status-failed {
|
|
232
|
+
color: var(--row-status-failed-color);
|
|
233
|
+
cursor: help;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
.status-spinner {
|
|
237
|
+
width: calc(${designUnit} * 4px);
|
|
238
|
+
height: calc(${designUnit} * 4px);
|
|
64
239
|
}
|
|
65
240
|
|
|
66
241
|
.item-control-btn {
|
|
67
|
-
color: rgb(135, 155, 166);
|
|
68
|
-
margin-left:
|
|
242
|
+
color: var(--neutral-foreground-hint, rgb(135, 155, 166));
|
|
243
|
+
margin-left: calc(${designUnit} * 2px);
|
|
69
244
|
}
|
|
70
245
|
|
|
71
246
|
.item-control-btn:hover {
|
|
72
247
|
color: var(--accent-foreground-hover);
|
|
73
248
|
}
|
|
249
|
+
|
|
250
|
+
.row-submit-btn {
|
|
251
|
+
min-width: calc(${designUnit} * 8px);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
.row-submit-btn[disabled] {
|
|
255
|
+
opacity: 0.5;
|
|
256
|
+
cursor: not-allowed;
|
|
257
|
+
}
|
|
74
258
|
`;
|
|
75
259
|
let ArrayListWrapper = class ArrayListWrapper extends FASTElement {
|
|
76
260
|
controlChanged() {
|
|
261
|
+
var _a;
|
|
77
262
|
this.schema = this.control.schema;
|
|
78
|
-
|
|
79
|
-
|
|
263
|
+
const childUiSchema = (_a = this.control.uischema.options) === null || _a === void 0 ? void 0 : _a.childUiSchema;
|
|
264
|
+
// Only use static childUiSchema; when it's a function, resolve per-row in template
|
|
265
|
+
if (childUiSchema && typeof childUiSchema !== 'function') {
|
|
266
|
+
this.uiSchema = childUiSchema;
|
|
80
267
|
return;
|
|
81
268
|
}
|
|
82
269
|
const arrayUiSchema = Generate.uiSchema(this.schema);
|
|
@@ -89,6 +276,13 @@ let ArrayListWrapper = class ArrayListWrapper extends FASTElement {
|
|
|
89
276
|
deleteItem(index) {
|
|
90
277
|
this.control.removeItems(this.control.path, [index])();
|
|
91
278
|
}
|
|
279
|
+
/**
|
|
280
|
+
* Submits a single row by emitting an event that bubbles up to the foundation-form.
|
|
281
|
+
* @param index - The row index to submit
|
|
282
|
+
*/
|
|
283
|
+
submitRow(index) {
|
|
284
|
+
this.$emit('submit-single-row', { index }, { bubbles: true, composed: true });
|
|
285
|
+
}
|
|
92
286
|
};
|
|
93
287
|
__decorate([
|
|
94
288
|
observable
|