@genesislcap/foundation-forms 14.492.0-FUI-2571.4 → 14.492.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.
Files changed (37) hide show
  1. package/dist/custom-elements.json +1 -341
  2. package/dist/dts/form.d.ts +0 -87
  3. package/dist/dts/form.d.ts.map +1 -1
  4. package/dist/dts/form.styles.d.ts.map +1 -1
  5. package/dist/dts/form.template.d.ts.map +1 -1
  6. package/dist/dts/index.d.ts +0 -3
  7. package/dist/dts/index.d.ts.map +1 -1
  8. package/dist/dts/jsonforms/renderers/CategorizationWrapperRenderer.d.ts.map +1 -1
  9. package/dist/dts/react.d.ts +0 -10
  10. package/dist/dts/utils/index.d.ts +0 -1
  11. package/dist/dts/utils/index.d.ts.map +1 -1
  12. package/dist/dts/utils/schema-utils.d.ts +0 -12
  13. package/dist/dts/utils/schema-utils.d.ts.map +1 -1
  14. package/dist/esm/form.js +2 -129
  15. package/dist/esm/form.styles.js +2 -9
  16. package/dist/esm/form.template.js +25 -59
  17. package/dist/esm/index.js +0 -3
  18. package/dist/esm/jsonforms/renderers/CategorizationWrapperRenderer.js +45 -1
  19. package/dist/esm/utils/index.js +0 -1
  20. package/dist/esm/utils/schema-utils.js +0 -48
  21. package/dist/foundation-forms.api.json +0 -428
  22. package/dist/foundation-forms.d.ts +0 -217
  23. package/dist/react.cjs +0 -7
  24. package/dist/react.mjs +0 -6
  25. package/package.json +15 -15
  26. package/dist/dts/review.d.ts +0 -34
  27. package/dist/dts/review.d.ts.map +0 -1
  28. package/dist/dts/review.styles.d.ts +0 -3
  29. package/dist/dts/review.styles.d.ts.map +0 -1
  30. package/dist/dts/review.template.d.ts +0 -6
  31. package/dist/dts/review.template.d.ts.map +0 -1
  32. package/dist/dts/utils/review-utils.d.ts +0 -82
  33. package/dist/dts/utils/review-utils.d.ts.map +0 -1
  34. package/dist/esm/review.js +0 -63
  35. package/dist/esm/review.styles.js +0 -93
  36. package/dist/esm/review.template.js +0 -38
  37. package/dist/esm/utils/review-utils.js +0 -241
package/dist/esm/form.js CHANGED
@@ -29,7 +29,7 @@ import { NumberControlRendererEntry } from './jsonforms/renderers/NumberControlR
29
29
  import { SegmentedControlRendererEntry } from './jsonforms/renderers/SegmentedControlRenderer';
30
30
  import { StringArrayEntry } from './jsonforms/renderers/StringArrayControlRenderer';
31
31
  import { StringControlRendererTemplate } from './jsonforms/renderers/StringControlRenderer';
32
- import { buildReviewSections, downloadCsvTemplate as downloadCsvFile, extractFieldsFromUiSchema, generateCsvTemplate, getDataValueAtPath, logger, mapCsvToSchema, mapGenesisFieldErrorsToAdditionalErrors, parseCsv, } from './utils';
32
+ import { downloadCsvTemplate as downloadCsvFile, extractFieldsFromUiSchema, generateCsvTemplate, logger, mapCsvToSchema, mapGenesisFieldErrorsToAdditionalErrors, parseCsv, } from './utils';
33
33
  import { findModalParent, showConfirmationDialog } from './utils/confirmation-dialog-utils';
34
34
  import { removeDataPropertiesNotInSchema } from './utils/form-utils';
35
35
  import { generateBulkUiSchema, isBulkUiSchema } from './utils/schema-utils';
@@ -149,55 +149,17 @@ let Form = class Form extends LifecycleMixin(FoundationElement) {
149
149
  * @public
150
150
  */
151
151
  this.data = {};
152
- /**
153
- * Text to appear on submit button
154
- * @default Submit
155
- * @public
156
- */
157
- this.submitButtonText = 'Submit';
158
- /**
159
- * Text to appear on submit button in bulk insert mode
160
- * @default Submit AllS
161
- * @public
162
- */
163
- this.bulkSubmitButtonText = 'Submit All';
164
- /**
165
- * Text to appear on reset button
166
- * @default Submit
167
- * @public
168
- */
169
- this.resetButtonText = 'Reset';
170
152
  /**
171
153
  * Minimum number of items required in bulk insert mode.
172
154
  * @public
173
155
  */
174
156
  this.bulkInsertMinItems = 1;
175
- /**
176
- * Text to appear on reset button
177
- * @public
178
- */
179
- this.reviewButtonText = 'Review';
180
- /**
181
- * Heading shown at the top of the review panel.
182
- * @public
183
- */
184
- this.reviewHeading = 'Review';
185
157
  /**
186
158
  * Tracks the submission status for each row in bulk insert mode.
187
159
  * Key is the row index, value is the status object.
188
160
  * @public
189
161
  */
190
162
  this.rowSubmitStatuses = new Map();
191
- /**
192
- * Whether the form is currently showing the submit-review preview panel.
193
- * @internal
194
- */
195
- this.reviewMode = false;
196
- /**
197
- * Field label/value pairs rendered in the review panel, grouped into sections.
198
- * @internal
199
- */
200
- this.reviewSections = [];
201
163
  }
202
164
  resourceNameChanged() {
203
165
  return __awaiter(this, void 0, void 0, function* () {
@@ -296,17 +258,6 @@ let Form = class Form extends LifecycleMixin(FoundationElement) {
296
258
  const { renderers: defaultRenderers = [], additionalRenderers = [] } = this;
297
259
  this.mergedRenderers = [...defaultRenderers, ...additionalRenderers];
298
260
  }
299
- /**
300
- * Value of `reviewIdField` resolved from the current form data, if set.
301
- * @internal
302
- */
303
- get reviewRecordId() {
304
- if (!this.reviewIdField) {
305
- return undefined;
306
- }
307
- const value = getDataValueAtPath(this.data, this.reviewIdField);
308
- return value === undefined || value === null ? undefined : String(value);
309
- }
310
261
  /**
311
262
  * @internal
312
263
  */
@@ -336,60 +287,11 @@ let Form = class Form extends LifecycleMixin(FoundationElement) {
336
287
  yield this._submitBulk();
337
288
  return;
338
289
  }
339
- // Show review preview if enabled and the form has no validation errors.
340
- if (this.showSubmitReview && !this.hasValidationErrors()) {
341
- this.reviewSections = yield buildReviewSections(this.data || {}, this.userProvidedUiSchema || this.uischema, this.originalDetailsSchema || this.jsonSchema);
342
- this.reviewMode = true;
343
- return;
344
- }
345
- yield this._performSubmit();
346
- });
347
- }
348
- /**
349
- * Called from the review panel to go back to the form.
350
- * @internal
351
- */
352
- backFromReview() {
353
- this.reviewMode = false;
354
- }
355
- /**
356
- * Called from the review panel submit button to perform the actual submission.
357
- * @internal
358
- */
359
- _submitFromReview() {
360
- return __awaiter(this, void 0, void 0, function* () {
361
- this.reviewMode = false;
362
- yield this._performSubmit();
363
- });
364
- }
365
- /**
366
- * Whether the form currently has validation errors. Reads live errors directly from the
367
- * json-forms element when it's mounted, so we always use the current validation state
368
- * (this.errors can lag in edge cases such as required fields with empty-string values not
369
- * yet reported via data-change). Falls back to this.errors when json-forms isn't mounted
370
- * (e.g. while the read-only review panel is showing), which is safe since no interactive
371
- * editing happens during review.
372
- * @internal
373
- */
374
- hasValidationErrors() {
375
- var _a, _b, _c, _d, _e, _f, _g, _h;
376
- const jfEl = this.jsonFormsEl;
377
- return jfEl
378
- ? ((_d = (_c = (_b = (_a = jfEl.jsonforms) === null || _a === void 0 ? void 0 : _a.core) === null || _b === void 0 ? void 0 : _b.errors) === null || _c === void 0 ? void 0 : _c.length) !== null && _d !== void 0 ? _d : 0) > 0 ||
379
- ((_h = (_g = (_f = (_e = jfEl.jsonforms) === null || _e === void 0 ? void 0 : _e.core) === null || _f === void 0 ? void 0 : _f.additionalErrors) === null || _g === void 0 ? void 0 : _g.length) !== null && _h !== void 0 ? _h : 0) > 0
380
- : this.errors.length > 0;
381
- }
382
- /**
383
- * Performs the actual API submission after review (or directly when review is disabled).
384
- * @internal
385
- */
386
- _performSubmit() {
387
- return __awaiter(this, void 0, void 0, function* () {
388
290
  const payload = Object.assign({}, this.data);
389
291
  const commitPayload = this.buildCommitPayload(payload);
390
292
  logger.debug({ payload, errors: this.errors });
391
293
  this.$emit('submit', { payload, errors: this.errors });
392
- if (Object.entries(payload).length !== 0 && !this.hasValidationErrors() && this.resourceName) {
294
+ if (Object.entries(payload).length !== 0 && !this.errors.length && this.resourceName) {
393
295
  this.submitting = true;
394
296
  const formSubmitReq = yield this.connect.commitEvent(this.resourceName, commitPayload);
395
297
  this.submitting = false;
@@ -736,8 +638,6 @@ let Form = class Form extends LifecycleMixin(FoundationElement) {
736
638
  */
737
639
  reset(clearData = true) {
738
640
  this.submitted = false;
739
- this.reviewMode = false;
740
- this.reviewSections = [];
741
641
  this.clearRowSubmitStatuses();
742
642
  this.serverFieldErrors = [];
743
643
  if (clearData) {
@@ -1002,15 +902,6 @@ __decorate([
1002
902
  __decorate([
1003
903
  attr({ attribute: 'bulk-insert', mode: 'boolean' })
1004
904
  ], Form.prototype, "bulkInsert", void 0);
1005
- __decorate([
1006
- attr({ attribute: 'submit-button-text' })
1007
- ], Form.prototype, "submitButtonText", void 0);
1008
- __decorate([
1009
- attr({ attribute: 'bulk-submit-button-text' })
1010
- ], Form.prototype, "bulkSubmitButtonText", void 0);
1011
- __decorate([
1012
- attr({ attribute: 'reset-button-text' })
1013
- ], Form.prototype, "resetButtonText", void 0);
1014
905
  __decorate([
1015
906
  attr({
1016
907
  attribute: 'bulk-insert-min-items',
@@ -1029,27 +920,9 @@ __decorate([
1029
920
  },
1030
921
  })
1031
922
  ], Form.prototype, "bulkInsertMaxItems", void 0);
1032
- __decorate([
1033
- attr({ attribute: 'show-submit-review', mode: 'boolean' })
1034
- ], Form.prototype, "showSubmitReview", void 0);
1035
- __decorate([
1036
- attr({ attribute: 'review-button-text' })
1037
- ], Form.prototype, "reviewButtonText", void 0);
1038
- __decorate([
1039
- attr({ attribute: 'review-heading' })
1040
- ], Form.prototype, "reviewHeading", void 0);
1041
- __decorate([
1042
- attr({ attribute: 'review-id-field' })
1043
- ], Form.prototype, "reviewIdField", void 0);
1044
923
  __decorate([
1045
924
  observable
1046
925
  ], Form.prototype, "rowSubmitStatuses", void 0);
1047
- __decorate([
1048
- observable
1049
- ], Form.prototype, "reviewMode", void 0);
1050
- __decorate([
1051
- observable
1052
- ], Form.prototype, "reviewSections", void 0);
1053
926
  __decorate([
1054
927
  volatile
1055
928
  ], Form.prototype, "isSubmitHidden", null);
@@ -22,17 +22,10 @@ export const foundationFormStyles = css `
22
22
  min-width: 64px;
23
23
  width: 100%;
24
24
  height: 100%;
25
- display: flex;
26
- flex-direction: column;
27
- overflow: hidden;
28
- box-sizing: border-box;
29
- }
30
-
31
- foundation-form json-forms {
32
- flex: 1;
33
25
  overflow-y: auto;
34
- min-height: 0;
26
+ display: inline-block;
35
27
  scrollbar-color: var(--neutral-stroke-rest) transparent;
28
+ box-sizing: border-box;
36
29
  }
37
30
 
38
31
  foundation-form .actions {
@@ -6,12 +6,11 @@ import { CategorizationWrapper } from './jsonforms/renderers/CategorizationWrapp
6
6
  import { DispatchRenderer } from './jsonforms/renderers/dispatch-renderer';
7
7
  import { StepperWrapper } from './jsonforms/renderers/StepperWrapperRenderer';
8
8
  import { VerticalCategorizationWrapper } from './jsonforms/renderers/VerticalCategorizationWrapperRenderer';
9
- import { Review } from './review';
10
- avoidTreeShaking(JSONForms, ArrayListWrapper, CategorizationWrapper, VerticalCategorizationWrapper, DispatchRenderer, StepperWrapper, Review);
9
+ avoidTreeShaking(JSONForms, ArrayListWrapper, CategorizationWrapper, VerticalCategorizationWrapper, DispatchRenderer, StepperWrapper);
11
10
  /** @internal */
12
11
  export const getPrefixedForm = (prefix) => html `
13
12
  <template>
14
- ${when((x) => !x.reviewMode && x.bulkInsert, html `
13
+ ${when((x) => x.bulkInsert, html `
15
14
  <div class="csv-upload-section" part="csv-upload">
16
15
  <input
17
16
  type="file"
@@ -40,76 +39,43 @@ export const getPrefixedForm = (prefix) => html `
40
39
  </${prefix}-button>
41
40
  </div>
42
41
  `)}
43
- ${when((x) => !x.reviewMode, html `
44
- <json-forms
45
- ${ref('jsonFormsEl')}
46
- @submit-button-clicked=${(x) => x._submit()}
47
- @submit-part=${(x, c) => x.submitPart(c.event)}
48
- @submit-single-row=${(x, c) => x.submitSingleRow(c.event.detail.index)}
49
- @reset-form=${(x) => x.reset(false)}
50
- ?readonly=${(x) => x.readonly}
51
- :submitted=${(x) => x.submitted}
52
- :renderers=${(x) => x.mergedRenderers}
53
- :uischema=${(x) => x.uischema}
54
- :schema=${(x) => x.jsonSchema}
55
- :data=${(x) => x.data}
56
- :serverFieldErrors=${(x) => x.serverFieldErrors}
57
- :prefix=${(x) => x.prefix}
58
- :rowSubmitStatuses=${(x) => x.rowSubmitStatuses}
59
- :bulkInsert=${(x) => x.bulkInsert}
60
- @data-change=${(x, c) => x.onChange(c.event)}
61
- ></json-forms>
62
- `)}
63
- ${when((x) => x.reviewMode, html `
64
- <foundation-form-review
65
- part="review-panel"
66
- design-system-prefix=${(x) => x.prefix}
67
- heading=${(x) => x.reviewHeading}
68
- :recordId=${(x) => x.reviewRecordId}
69
- :sections=${(x) => x.reviewSections}
70
- ></foundation-form-review>
71
- `)}
72
- ${when((x) => x.reviewMode || x.isSubmitHidden || x.isResetVisible, html `
42
+ <json-forms
43
+ @submit-button-clicked=${(x) => x._submit()}
44
+ @submit-part=${(x, c) => x.submitPart(c.event)}
45
+ @submit-single-row=${(x, c) => x.submitSingleRow(c.event.detail.index)}
46
+ @reset-form=${(x) => x.reset(false)}
47
+ ?readonly=${(x) => x.readonly}
48
+ :submitted=${(x) => x.submitted}
49
+ :renderers=${(x) => x.mergedRenderers}
50
+ :uischema=${(x) => x.uischema}
51
+ :schema=${(x) => x.jsonSchema}
52
+ :data=${(x) => x.data}
53
+ :serverFieldErrors=${(x) => x.serverFieldErrors}
54
+ :prefix=${(x) => x.prefix}
55
+ :rowSubmitStatuses=${(x) => x.rowSubmitStatuses}
56
+ :bulkInsert=${(x) => x.bulkInsert}
57
+ @data-change=${(x, c) => x.onChange(c.event)}
58
+ ></json-forms>
59
+ ${when((x) => x.isSubmitHidden || x.isResetVisible, html `
73
60
  <slot name="userActions" part="userActions" class="actions">
74
- ${when((x) => !x.reviewMode && x.isResetVisible, html `
61
+ ${when((x) => x.isResetVisible, html `
75
62
  <${prefix}-button
76
63
  @click="${(x) => x.handleResetClicked()}"
77
64
  class="reset-button"
78
65
  appearance="neutral"
79
66
  data-test-id="reset-button"
80
67
  >
81
- ${(x) => x.resetButtonText}
82
- </${prefix}-button>
83
- `)}
84
- ${when((x) => x.reviewMode, html `
85
- <${prefix}-button
86
- @click="${(x) => x.backFromReview()}"
87
- class="reset-button"
88
- appearance="neutral"
89
- data-test-id="review-back-button"
90
- >
91
- Back
68
+ Reset
92
69
  </${prefix}-button>
93
70
  `)}
94
- ${when((x) => !x.reviewMode && x.isSubmitHidden, html `
71
+ ${when((x) => x.isSubmitHidden, html `
95
72
  <${prefix}-button
96
73
  @click="${(x) => x._submit()}"
97
- ?disabled=${(x) => !x.submitting}
98
- class="submit-button"
99
- appearance="accent"
100
- >
101
- ${(x) => (x.bulkInsert ? x.bulkSubmitButtonText : x.submitButtonText)}
102
- </${prefix}-button>
103
- `)}
104
- ${when((x) => x.reviewMode, html `
105
- <${prefix}-button
106
- @click="${(x) => x._submitFromReview()}"
107
- ?disabled=${(x) => x.submitting}
74
+ ?disable=${(x) => !x.submitting}
108
75
  class="submit-button"
109
76
  appearance="accent"
110
- data-test-id="review-submit-button"
111
77
  >
112
- ${(x) => (x.showSubmitReview ? x.reviewButtonText : x.submitButtonText)}
78
+ ${(x) => (x.bulkInsert ? 'Submit All' : 'Submit')}
113
79
  </${prefix}-button>
114
80
  `)}
115
81
  </slot>
package/dist/esm/index.js CHANGED
@@ -2,9 +2,6 @@ export * from './filters';
2
2
  export * from './form';
3
3
  export * from './form.styles';
4
4
  export * from './form.template';
5
- export * from './review';
6
- export * from './review.styles';
7
- export * from './review.template';
8
5
  export { MulticolumnDropdownControlRendererEntry, MulticolumnDropdownControlRendererTemplate, } from './jsonforms/renderers/MulticolumnDropdownControlRenderer';
9
6
  export { LayoutVerticalCategorizationRendererEntry } from './jsonforms/renderers/LayoutVerticalCategorizationRenderer';
10
7
  export { controlWrapperTemplate, controlWrapperStyles,
@@ -1,7 +1,6 @@
1
1
  import { __decorate } from "tslib";
2
2
  import { html, css, observable, customElement, FASTElement, repeat, when, } from '@microsoft/fast-element';
3
3
  import { classNames } from '@microsoft/fast-web-utilities';
4
- import { extractErrorScopes, uiSchemaHasAnyError } from '../../utils/schema-utils';
5
4
  /**
6
5
  * Resolves the `activeCategory` option (the zero-based index of the category
7
6
  * tab that should open on first render) to a valid tab index. Out-of-bounds or
@@ -161,3 +160,48 @@ CategorizationWrapper = __decorate([
161
160
  })
162
161
  ], CategorizationWrapper);
163
162
  export { CategorizationWrapper };
163
+ function uiSchemaHasAnyError(uiSchema, errorScopes) {
164
+ // Direct scope match
165
+ if (typeof uiSchema.scope === 'string' &&
166
+ errorScopes.includes(uiSchema.scope)) {
167
+ return true;
168
+ }
169
+ // Check composite children via options.childElements
170
+ const options = uiSchema.options;
171
+ const childElements = options === null || options === void 0 ? void 0 : options.childElements;
172
+ if (Array.isArray(childElements)) {
173
+ for (const child of childElements) {
174
+ if (uiSchemaHasAnyError(child, errorScopes)) {
175
+ return true;
176
+ }
177
+ }
178
+ }
179
+ // Check layout children (elements)
180
+ if (Array.isArray(uiSchema.elements)) {
181
+ for (const el of uiSchema.elements) {
182
+ if (uiSchemaHasAnyError(el, errorScopes)) {
183
+ return true;
184
+ }
185
+ }
186
+ }
187
+ return false;
188
+ }
189
+ function extractErrorScopes(errors) {
190
+ var _a;
191
+ const scopes = new Set();
192
+ for (const error of errors) {
193
+ if (error.keyword === 'required' && ((_a = error.params) === null || _a === void 0 ? void 0 : _a.missingProperty)) {
194
+ const basePath = error.instancePath || '';
195
+ const prop = error.params.missingProperty;
196
+ // Normalize the base path
197
+ const fullPath = basePath === '' ? `#/properties/${prop}` : `#${basePath}/properties/${prop}`;
198
+ scopes.add(fullPath);
199
+ }
200
+ else if (error.instancePath) {
201
+ // Remove leading slash and convert to JSON Pointer path
202
+ const instancePath = `#${error.instancePath.replace(/\//g, '/properties/')}`;
203
+ scopes.add(instancePath);
204
+ }
205
+ }
206
+ return Array.from(scopes);
207
+ }
@@ -1,5 +1,4 @@
1
1
  export * from './csv-parser';
2
- export * from './review-utils';
3
2
  export * from './filters';
4
3
  export * from './logger';
5
4
  export * from './translation';
@@ -93,54 +93,6 @@ export function isBulkUiSchema(uischema) {
93
93
  var _a;
94
94
  return (_a = uischema === null || uischema === void 0 ? void 0 : uischema.elements) === null || _a === void 0 ? void 0 : _a.some((element) => element.scope === '#/properties/items' && element.type === 'Control');
95
95
  }
96
- /**
97
- * Converts AJV validation errors to the JSON Schema scope strings they correspond to
98
- * (e.g. `#/properties/ADDRESS/properties/STREET`). Used to match errors back to UI
99
- * schema controls for features like categorization-tab error indicators.
100
- */
101
- export function extractErrorScopes(errors) {
102
- var _a;
103
- const scopes = new Set();
104
- for (const error of errors) {
105
- if (error.keyword === 'required' && ((_a = error.params) === null || _a === void 0 ? void 0 : _a.missingProperty)) {
106
- const basePath = error.instancePath || '';
107
- const prop = error.params.missingProperty;
108
- const fullPath = basePath === '' ? `#/properties/${prop}` : `#${basePath}/properties/${prop}`;
109
- scopes.add(fullPath);
110
- }
111
- else if (error.instancePath) {
112
- // Convert JSON Pointer /ADDRESS/STREET → #/properties/ADDRESS/properties/STREET
113
- const instancePath = `#${error.instancePath.replace(/\//g, '/properties/')}`;
114
- scopes.add(instancePath);
115
- }
116
- }
117
- return Array.from(scopes);
118
- }
119
- /**
120
- * Returns true when `uiSchema` (or any of its descendants) has a scope that appears
121
- * in `errorScopes`. Walks both `elements` and `options.childElements`.
122
- */
123
- export function uiSchemaHasAnyError(uiSchema, errorScopes) {
124
- var _a;
125
- if (typeof uiSchema.scope === 'string' &&
126
- errorScopes.includes(uiSchema.scope)) {
127
- return true;
128
- }
129
- const childElements = (_a = uiSchema.options) === null || _a === void 0 ? void 0 : _a.childElements;
130
- if (Array.isArray(childElements)) {
131
- for (const child of childElements) {
132
- if (uiSchemaHasAnyError(child, errorScopes))
133
- return true;
134
- }
135
- }
136
- if (Array.isArray(uiSchema.elements)) {
137
- for (const el of uiSchema.elements) {
138
- if (uiSchemaHasAnyError(el, errorScopes))
139
- return true;
140
- }
141
- }
142
- return false;
143
- }
144
96
  /**
145
97
  * Generates a UI schema suitable for bulk insert mode with array control.
146
98
  * @param userProvidedUiSchema - Optional user-provided UI schema to use as childUiSchema