@limetech/lime-elements 39.12.0 → 39.12.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/dist/cjs/limel-form.cjs.entry.js +103 -178
- package/dist/cjs/limel-table.cjs.entry.js +40 -11
- package/dist/collection/components/form/form.js +13 -16
- package/dist/collection/components/form/schema-cache.js +66 -0
- package/dist/collection/components/table/table.js +40 -11
- package/dist/esm/limel-form.entry.js +103 -178
- package/dist/esm/limel-table.entry.js +40 -11
- package/dist/lime-elements/lime-elements.esm.js +1 -1
- package/dist/lime-elements/{p-a6fe98eb.entry.js → p-32ca0084.entry.js} +1 -1
- package/dist/lime-elements/p-f93163eb.entry.js +7 -0
- package/dist/types/components/form/form.d.ts +1 -0
- package/dist/types/components/form/schema-cache.d.ts +17 -0
- package/dist/types/components/table/table.d.ts +2 -1
- package/package.json +1 -2
- package/dist/lime-elements/p-fb6c42a6.entry.js +0 -7
|
@@ -2,15 +2,12 @@ import { h, } from "@stencil/core";
|
|
|
2
2
|
import React from "react";
|
|
3
3
|
import { createRoot } from "react-dom/client";
|
|
4
4
|
import JSONSchemaForm from "@rjsf/core";
|
|
5
|
-
import retargetEvents from "react-shadow-dom-retarget-events";
|
|
6
5
|
import { ArrayFieldTemplate, FieldTemplate, ObjectFieldTemplate, } from "./templates";
|
|
7
6
|
import { SchemaField as CustomSchemaField } from "./fields/schema-field";
|
|
8
7
|
import { ArrayField as CustomArrayField } from "./fields/array-field";
|
|
9
8
|
import { ObjectField as CustomObjectField } from "./fields/object-field";
|
|
10
9
|
import { widgets } from "./widgets";
|
|
11
|
-
import {
|
|
12
|
-
import Ajv from "ajv";
|
|
13
|
-
import { isInteger } from "./validators";
|
|
10
|
+
import { getValidator, getSchemaId } from "./schema-cache";
|
|
14
11
|
import { mapValues } from "lodash-es";
|
|
15
12
|
/**
|
|
16
13
|
* @exampleComponent limel-example-form
|
|
@@ -40,6 +37,7 @@ export class Form {
|
|
|
40
37
|
*/
|
|
41
38
|
this.disabled = false;
|
|
42
39
|
this.isValid = true;
|
|
40
|
+
this.initialized = false;
|
|
43
41
|
this.handleChange = this.handleChange.bind(this);
|
|
44
42
|
this.getCustomErrorMessages = this.getCustomErrorMessages.bind(this);
|
|
45
43
|
}
|
|
@@ -54,11 +52,14 @@ export class Form {
|
|
|
54
52
|
this.initialize();
|
|
55
53
|
}
|
|
56
54
|
initialize() {
|
|
55
|
+
if (this.initialized) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
57
58
|
if (!this.host.shadowRoot.querySelector('.root')) {
|
|
58
59
|
return;
|
|
59
60
|
}
|
|
61
|
+
this.initialized = true;
|
|
60
62
|
this.reactRender();
|
|
61
|
-
retargetEvents(this.host.shadowRoot);
|
|
62
63
|
this.validateForm(this.value);
|
|
63
64
|
}
|
|
64
65
|
componentDidUpdate() {
|
|
@@ -70,9 +71,10 @@ export class Form {
|
|
|
70
71
|
this.root.unmount();
|
|
71
72
|
this.root = undefined;
|
|
72
73
|
}
|
|
74
|
+
this.initialized = false;
|
|
73
75
|
}
|
|
74
76
|
render() {
|
|
75
|
-
return h("div", { key: '
|
|
77
|
+
return h("div", { key: '8e03d70f44885de2f18b20e649cd419e030208fd', class: "root" });
|
|
76
78
|
}
|
|
77
79
|
reactRender() {
|
|
78
80
|
if (!this.root) {
|
|
@@ -124,22 +126,17 @@ export class Form {
|
|
|
124
126
|
this.createValidator();
|
|
125
127
|
}
|
|
126
128
|
setSchemaId() {
|
|
127
|
-
//
|
|
128
|
-
//
|
|
129
|
+
// RJSF v2 requires a unique $id per distinct schema to avoid
|
|
130
|
+
// validation cache collisions.
|
|
129
131
|
// https://github.com/rjsf-team/react-jsonschema-form/issues/1563
|
|
130
|
-
const id =
|
|
132
|
+
const id = getSchemaId(this.schema);
|
|
131
133
|
this.modifiedSchema = Object.assign(Object.assign({}, this.schema), { id: id, $id: id });
|
|
132
134
|
}
|
|
133
135
|
createValidator() {
|
|
134
|
-
|
|
135
|
-
unknownFormats: 'ignore',
|
|
136
|
-
allErrors: true,
|
|
137
|
-
multipleOfPrecision: 2,
|
|
138
|
-
}).addFormat('integer', isInteger);
|
|
139
|
-
this.validator = validator.compile(this.schema);
|
|
136
|
+
this.validator = getValidator(this.schema);
|
|
140
137
|
}
|
|
141
138
|
getValidationErrors() {
|
|
142
|
-
const errors = this.validator.errors || [];
|
|
139
|
+
const errors = [...(this.validator.errors || [])];
|
|
143
140
|
return errors.map((error) => {
|
|
144
141
|
let property = error.dataPath;
|
|
145
142
|
if (error.keyword === 'required') {
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
+
var t = {};
|
|
3
|
+
for (var p in s)
|
|
4
|
+
if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
13
|
+
import Ajv from "ajv";
|
|
14
|
+
import { isInteger } from "./validators";
|
|
15
|
+
const ajv = new Ajv({
|
|
16
|
+
unknownFormats: 'ignore',
|
|
17
|
+
allErrors: true,
|
|
18
|
+
multipleOfPrecision: 2,
|
|
19
|
+
}).addFormat('integer', isInteger);
|
|
20
|
+
const validators = new Map();
|
|
21
|
+
/**
|
|
22
|
+
* Returns a compiled JSON Schema validator, using a cached version
|
|
23
|
+
* if the same schema content has been seen before.
|
|
24
|
+
*
|
|
25
|
+
* @param schema - the JSON Schema to compile
|
|
26
|
+
*/
|
|
27
|
+
export function getValidator(schema) {
|
|
28
|
+
const key = hashSchema(schema);
|
|
29
|
+
const cached = validators.get(key);
|
|
30
|
+
if (cached) {
|
|
31
|
+
return cached;
|
|
32
|
+
}
|
|
33
|
+
const { $id, id } = schema, schemaWithoutId = __rest(schema, ["$id", "id"]);
|
|
34
|
+
const validator = ajv.compile(schemaWithoutId);
|
|
35
|
+
validators.set(key, validator);
|
|
36
|
+
return validator;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Generates a deterministic ID from schema content, preserving any
|
|
40
|
+
* existing `$id` as a prefix. Used to work around RJSF #1563 where
|
|
41
|
+
* identical schemas need stable IDs to avoid validation cache collisions.
|
|
42
|
+
*
|
|
43
|
+
* @param schema - the JSON Schema to generate an ID for
|
|
44
|
+
*/
|
|
45
|
+
export function getSchemaId(schema) {
|
|
46
|
+
const hash = hashSchema(schema);
|
|
47
|
+
const prefix = schema.$id ? `${schema.$id}-` : '';
|
|
48
|
+
return `${prefix}${hash}`;
|
|
49
|
+
}
|
|
50
|
+
function hashSchema(schema) {
|
|
51
|
+
const { $id, id } = schema, schemaWithoutId = __rest(schema, ["$id", "id"]);
|
|
52
|
+
return djb2Hash(JSON.stringify(schemaWithoutId, sortedReplacer));
|
|
53
|
+
}
|
|
54
|
+
function sortedReplacer(_, value) {
|
|
55
|
+
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
56
|
+
return Object.fromEntries(Object.entries(value).sort(([a], [b]) => a.localeCompare(b)));
|
|
57
|
+
}
|
|
58
|
+
return value;
|
|
59
|
+
}
|
|
60
|
+
function djb2Hash(str) {
|
|
61
|
+
let hash = 5381;
|
|
62
|
+
for (let i = 0; i < str.length; i++) {
|
|
63
|
+
hash = ((hash << 5) + hash + str.codePointAt(i)) & 4294967295;
|
|
64
|
+
}
|
|
65
|
+
return (hash >>> 0).toString(36);
|
|
66
|
+
}
|
|
@@ -178,8 +178,8 @@ export class Table {
|
|
|
178
178
|
updateData(newData = [], oldData = []) {
|
|
179
179
|
const newIds = this.getRowIds(newData);
|
|
180
180
|
const oldIds = this.getRowIds(oldData);
|
|
181
|
-
const shouldReplace = this.
|
|
182
|
-
|
|
181
|
+
const shouldReplace = !this.areEqualIds(newIds, oldIds) ||
|
|
182
|
+
!this.isSameOrder(newIds, oldIds);
|
|
183
183
|
setTimeout(() => {
|
|
184
184
|
if (!this.tabulator || !this.initialized) {
|
|
185
185
|
return;
|
|
@@ -190,9 +190,15 @@ export class Table {
|
|
|
190
190
|
this.setSelection();
|
|
191
191
|
return;
|
|
192
192
|
}
|
|
193
|
-
if (
|
|
194
|
-
this.
|
|
195
|
-
this.
|
|
193
|
+
if (!areRowsEqual(newData, oldData)) {
|
|
194
|
+
const patched = this.fillMissingFields(newData, oldData);
|
|
195
|
+
this.tabulator.updateData(patched).then(() => {
|
|
196
|
+
if (!this.tabulator) {
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
this.reformatChangedRows(newData, oldData);
|
|
200
|
+
this.setSelection();
|
|
201
|
+
});
|
|
196
202
|
return;
|
|
197
203
|
}
|
|
198
204
|
if (newData.length > 0) {
|
|
@@ -259,9 +265,32 @@ export class Table {
|
|
|
259
265
|
}
|
|
260
266
|
this.tabulator.setSort(newSorting);
|
|
261
267
|
}
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
!
|
|
268
|
+
reformatChangedRows(newData, oldData) {
|
|
269
|
+
for (const [i, newRow] of newData.entries()) {
|
|
270
|
+
if (!!(newRow === null || newRow === void 0 ? void 0 : newRow.id) && !isEqual(newRow, oldData[i])) {
|
|
271
|
+
const row = this.tabulator.getRow(newRow.id);
|
|
272
|
+
if (row) {
|
|
273
|
+
row.reformat();
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
fillMissingFields(newData, oldData) {
|
|
279
|
+
return newData.map((newRow, index) => {
|
|
280
|
+
const oldRow = oldData[index];
|
|
281
|
+
if (!oldRow) {
|
|
282
|
+
return newRow;
|
|
283
|
+
}
|
|
284
|
+
const missingKeys = Object.keys(oldRow).filter((key) => !(key in newRow));
|
|
285
|
+
if (missingKeys.length === 0) {
|
|
286
|
+
return newRow;
|
|
287
|
+
}
|
|
288
|
+
const patched = Object.assign({}, newRow);
|
|
289
|
+
for (const key of missingKeys) {
|
|
290
|
+
patched[key] = undefined;
|
|
291
|
+
}
|
|
292
|
+
return patched;
|
|
293
|
+
});
|
|
265
294
|
}
|
|
266
295
|
getRowIds(data) {
|
|
267
296
|
return data.map((item) => { var _a; return (_a = item.id) !== null && _a !== void 0 ? _a : item; });
|
|
@@ -578,16 +607,16 @@ export class Table {
|
|
|
578
607
|
render() {
|
|
579
608
|
var _a, _b;
|
|
580
609
|
const totalRows = (_a = this.totalRows) !== null && _a !== void 0 ? _a : this.data.length;
|
|
581
|
-
return (h(Host, { key: '
|
|
610
|
+
return (h(Host, { key: '93dbd2f3ca88990432e28057035fcb538083d119', class: {
|
|
582
611
|
'has-low-density': this.layout === 'lowDensity',
|
|
583
612
|
'has-pagination-on-top': this.paginationLocation === 'top',
|
|
584
|
-
} }, h("div", { key: '
|
|
613
|
+
} }, h("div", { key: 'aa5355f9c10a3d75d40cffff4bc6620579fb3b6c', id: "tabulator-container", class: {
|
|
585
614
|
'has-pagination': totalRows > this.pageSize,
|
|
586
615
|
'has-aggregation': this.hasAggregation(this.columns),
|
|
587
616
|
'has-movable-columns': this.movableColumns,
|
|
588
617
|
'has-rowselector': this.selectable,
|
|
589
618
|
'has-selection': (_b = this.tableSelection) === null || _b === void 0 ? void 0 : _b.hasSelection,
|
|
590
|
-
} }, h("div", { key: '
|
|
619
|
+
} }, h("div", { key: '2263536b78e2bdece8fe5d80ed7d51aa29015c02', id: "tabulator-loader", style: { display: this.loading ? 'flex' : 'none' } }, h("limel-spinner", { key: '95c1c4e8864338f0415adc07313a16ee26618b17', size: "large" })), this.renderEmptyMessage(), this.renderSelectAll(), h("div", { key: '6c8ae89d20edbee0bf28cc759668900991fa55e6', id: "tabulator-table" }))));
|
|
591
620
|
}
|
|
592
621
|
renderSelectAll() {
|
|
593
622
|
var _a, _b, _c;
|