@richardmcquiston01/dashboard-widgets-toolkit 0.13.0 → 0.15.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/core.cjs +1089 -347
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +2 -2
- package/dist/core.d.ts +2 -2
- package/dist/core.js +1061 -348
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +1089 -347
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1061 -348
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +1173 -121
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +57 -4
- package/dist/react.d.ts +57 -4
- package/dist/react.js +1173 -122
- package/dist/react.js.map +1 -1
- package/dist/{storage-DNB7gjvT.d.cts → storage-DwJ-vGJg.d.cts} +264 -3
- package/dist/{storage-DNB7gjvT.d.ts → storage-DwJ-vGJg.d.ts} +264 -3
- package/dist/styles.css +146 -0
- package/package.json +1 -1
package/dist/core.js
CHANGED
|
@@ -87,12 +87,14 @@ var WIDGET_FILLS = ["height", "width", "both"];
|
|
|
87
87
|
var NOT_LOCKED = Object.freeze({
|
|
88
88
|
move: false,
|
|
89
89
|
hide: false,
|
|
90
|
-
minimize: false
|
|
90
|
+
minimize: false,
|
|
91
|
+
options: false
|
|
91
92
|
});
|
|
92
93
|
var FULLY_LOCKED = Object.freeze({
|
|
93
94
|
move: true,
|
|
94
95
|
hide: true,
|
|
95
|
-
minimize: true
|
|
96
|
+
minimize: true,
|
|
97
|
+
options: true
|
|
96
98
|
});
|
|
97
99
|
function resolveWidgetLock(definition) {
|
|
98
100
|
const setting = definition.locked;
|
|
@@ -101,7 +103,8 @@ function resolveWidgetLock(definition) {
|
|
|
101
103
|
return {
|
|
102
104
|
move: setting.move === true,
|
|
103
105
|
hide: setting.hide === true,
|
|
104
|
-
minimize: setting.minimize === true
|
|
106
|
+
minimize: setting.minimize === true,
|
|
107
|
+
options: setting.options === true
|
|
105
108
|
};
|
|
106
109
|
}
|
|
107
110
|
function defineWidget(definition) {
|
|
@@ -683,261 +686,261 @@ function placeAndFillRows(items, columns, spanOf) {
|
|
|
683
686
|
return { spans, rows };
|
|
684
687
|
}
|
|
685
688
|
|
|
686
|
-
// src/core/
|
|
687
|
-
var
|
|
688
|
-
var
|
|
689
|
-
var
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
}
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
value = JSON.parse(raw);
|
|
708
|
-
} catch {
|
|
709
|
-
return EMPTY_LAYOUT;
|
|
710
|
-
}
|
|
711
|
-
}
|
|
712
|
-
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
713
|
-
return EMPTY_LAYOUT;
|
|
714
|
-
}
|
|
715
|
-
const record = value;
|
|
716
|
-
const order = uniqueStrings(record["order"]);
|
|
717
|
-
const hidden = uniqueStrings(record["hidden"]);
|
|
718
|
-
const minimized = uniqueStrings(record["minimized"]);
|
|
719
|
-
const pages = parsePages(record["pages"]);
|
|
720
|
-
if (pages.length > 0) {
|
|
721
|
-
return {
|
|
722
|
-
order: EMPTY_LAYOUT.order,
|
|
723
|
-
hidden: EMPTY_LAYOUT.hidden,
|
|
724
|
-
minimized: EMPTY_LAYOUT.minimized,
|
|
725
|
-
pages
|
|
726
|
-
};
|
|
727
|
-
}
|
|
728
|
-
if (order.length === 0 && hidden.length === 0 && minimized.length === 0) {
|
|
729
|
-
return EMPTY_LAYOUT;
|
|
730
|
-
}
|
|
731
|
-
return { order, hidden, minimized };
|
|
689
|
+
// src/core/views.ts
|
|
690
|
+
var BASE_VIEW_KEY = "base";
|
|
691
|
+
var MAX_WIDGET_VIEWS = 8;
|
|
692
|
+
var VIEW_CONVERSIONS = {
|
|
693
|
+
tableToBarList: { from: "TABLE", to: "BAR_LIST" },
|
|
694
|
+
tableToGraph: { from: "TABLE", to: "GRAPH" },
|
|
695
|
+
barListToTable: { from: "BAR_LIST", to: "TABLE" },
|
|
696
|
+
graphToTable: { from: "GRAPH", to: "TABLE" },
|
|
697
|
+
barListToGraph: { from: "BAR_LIST", to: "GRAPH" }
|
|
698
|
+
};
|
|
699
|
+
var KIND_LABELS = {
|
|
700
|
+
TEXT: "Text",
|
|
701
|
+
KPI: "Number",
|
|
702
|
+
GAUGE: "Gauge",
|
|
703
|
+
TABLE: "Table",
|
|
704
|
+
BAR_LIST: "Bars",
|
|
705
|
+
ALERT_LIST: "List",
|
|
706
|
+
GRAPH: "Chart"
|
|
707
|
+
};
|
|
708
|
+
function kindLabel(kind) {
|
|
709
|
+
return KIND_LABELS[kind];
|
|
732
710
|
}
|
|
733
|
-
function
|
|
734
|
-
|
|
735
|
-
const pages = [];
|
|
736
|
-
const keys = /* @__PURE__ */ new Set();
|
|
737
|
-
for (const entry of value.slice(0, MAX_PARSED_PAGES)) {
|
|
738
|
-
if (typeof entry !== "object" || entry === null || Array.isArray(entry)) {
|
|
739
|
-
continue;
|
|
740
|
-
}
|
|
741
|
-
const record = entry;
|
|
742
|
-
const key = record["key"];
|
|
743
|
-
if (typeof key !== "string" || key === "" || keys.has(key)) continue;
|
|
744
|
-
keys.add(key);
|
|
745
|
-
const rawTitle = record["title"];
|
|
746
|
-
const title = typeof rawTitle === "string" && rawTitle.trim() !== "" ? rawTitle.trim().slice(0, MAX_PAGE_TITLE_LENGTH) : `Page ${pages.length + 1}`;
|
|
747
|
-
const maxRows = record["maxRows"];
|
|
748
|
-
const held = /* @__PURE__ */ new Set();
|
|
749
|
-
for (const earlier of pages) {
|
|
750
|
-
for (const k of [...earlier.order, ...earlier.hidden]) held.add(k);
|
|
751
|
-
}
|
|
752
|
-
const keep = (list) => uniqueStrings(list).filter((k) => !held.has(k));
|
|
753
|
-
pages.push({
|
|
754
|
-
key,
|
|
755
|
-
title,
|
|
756
|
-
order: keep(record["order"]),
|
|
757
|
-
hidden: keep(record["hidden"]),
|
|
758
|
-
minimized: keep(record["minimized"]),
|
|
759
|
-
...typeof maxRows === "number" && Number.isInteger(maxRows) && maxRows >= 1 && maxRows <= MAX_PAGE_ROWS ? { maxRows } : {}
|
|
760
|
-
});
|
|
761
|
-
}
|
|
762
|
-
return pages;
|
|
711
|
+
function hasViews(item) {
|
|
712
|
+
return item.views !== void 0 && item.views.length > 0;
|
|
763
713
|
}
|
|
764
|
-
function
|
|
765
|
-
return
|
|
766
|
-
order: [...layout.order],
|
|
767
|
-
hidden: [...layout.hidden],
|
|
768
|
-
minimized: [...layout.minimized],
|
|
769
|
-
...layout.pages === void 0 || layout.pages.length === 0 ? {} : {
|
|
770
|
-
pages: layout.pages.map((page) => ({
|
|
771
|
-
key: page.key,
|
|
772
|
-
title: page.title,
|
|
773
|
-
order: [...page.order],
|
|
774
|
-
hidden: [...page.hidden],
|
|
775
|
-
minimized: [...page.minimized],
|
|
776
|
-
...page.maxRows === void 0 ? {} : { maxRows: page.maxRows }
|
|
777
|
-
}))
|
|
778
|
-
}
|
|
779
|
-
});
|
|
714
|
+
function findView(item, key) {
|
|
715
|
+
return item.views?.find((view) => view.key === key);
|
|
780
716
|
}
|
|
781
|
-
function
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
717
|
+
function viewChoices(item) {
|
|
718
|
+
if (!hasViews(item)) return [];
|
|
719
|
+
return [
|
|
720
|
+
{
|
|
721
|
+
key: BASE_VIEW_KEY,
|
|
722
|
+
label: item.baseViewLabel ?? kindLabel(item.kind),
|
|
723
|
+
kind: item.kind
|
|
724
|
+
},
|
|
725
|
+
...(item.views ?? []).map(({ key, label, kind }) => ({
|
|
726
|
+
key,
|
|
727
|
+
label,
|
|
728
|
+
kind
|
|
729
|
+
}))
|
|
730
|
+
];
|
|
785
731
|
}
|
|
786
|
-
function
|
|
787
|
-
return
|
|
732
|
+
function isKnownView(item, key) {
|
|
733
|
+
return key !== void 0 && (key === BASE_VIEW_KEY || findView(item, key) !== void 0);
|
|
788
734
|
}
|
|
789
|
-
function
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
if (definition !== void 0) {
|
|
795
|
-
ordered.push(definition);
|
|
796
|
-
byKey.delete(key);
|
|
797
|
-
}
|
|
798
|
-
}
|
|
799
|
-
for (const definition of bySortOrder(visible)) {
|
|
800
|
-
if (byKey.has(definition.key)) ordered.push(definition);
|
|
801
|
-
}
|
|
802
|
-
return ordered;
|
|
735
|
+
function effectiveViewKey(item, chosen) {
|
|
736
|
+
if (!hasViews(item)) return BASE_VIEW_KEY;
|
|
737
|
+
if (isKnownView(item, chosen)) return chosen;
|
|
738
|
+
if (isKnownView(item, item.defaultView)) return item.defaultView;
|
|
739
|
+
return BASE_VIEW_KEY;
|
|
803
740
|
}
|
|
804
|
-
function
|
|
805
|
-
|
|
806
|
-
(item) => isPinned(item) ? item : void 0
|
|
807
|
-
);
|
|
808
|
-
let next = 0;
|
|
809
|
-
return slots.map((pinned) => pinned ?? free[next++]);
|
|
741
|
+
function viewKind(item, chosen) {
|
|
742
|
+
return findView(item, effectiveViewKey(item, chosen))?.kind ?? item.kind;
|
|
810
743
|
}
|
|
811
|
-
function
|
|
812
|
-
const
|
|
813
|
-
|
|
814
|
-
const ordered = viewerOrder(visible, layout);
|
|
815
|
-
if (!visible.some(isPinned)) return ordered;
|
|
816
|
-
return placeAroundPinned(
|
|
817
|
-
visible,
|
|
818
|
-
ordered.filter((item) => !isPinned(item))
|
|
819
|
-
);
|
|
744
|
+
function cellValue2(cell) {
|
|
745
|
+
const value = cell?.value;
|
|
746
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
820
747
|
}
|
|
821
|
-
function
|
|
822
|
-
|
|
823
|
-
return bySortOrder(definitions.filter((d) => hidden.has(d.key)));
|
|
748
|
+
function columnName(table, index) {
|
|
749
|
+
return table.columns[index]?.label ?? `#${index + 1}`;
|
|
824
750
|
}
|
|
825
|
-
function
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
const mover = current[fromIndex];
|
|
829
|
-
if (mover === void 0 || !Number.isInteger(toIndex) || toIndex < 0 || toIndex >= current.length || toIndex === fromIndex || isPinned(mover) || isPinned(current[toIndex])) {
|
|
830
|
-
return layout;
|
|
751
|
+
function checkColumn(table, index, field, context) {
|
|
752
|
+
if (!Number.isInteger(index) || index < 0 || index >= table.columns.length) {
|
|
753
|
+
return `${context.where}: ${field} column ${index} does not exist (the table has ${table.columns.length} columns, numbered from 0).`;
|
|
831
754
|
}
|
|
832
|
-
|
|
833
|
-
const free = current.filter((item) => !isPinned(item));
|
|
834
|
-
const fromFree = freeSlots.indexOf(fromIndex);
|
|
835
|
-
const toFree = freeSlots.indexOf(toIndex);
|
|
836
|
-
free.splice(fromFree, 1);
|
|
837
|
-
free.splice(toFree, 0, mover);
|
|
838
|
-
const next = placeAroundPinned(current, free);
|
|
839
|
-
return { ...layout, order: next.map((d) => d.key) };
|
|
755
|
+
return void 0;
|
|
840
756
|
}
|
|
841
|
-
function
|
|
842
|
-
const
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
757
|
+
function numericColumn(table, index, context) {
|
|
758
|
+
const numbers = [];
|
|
759
|
+
for (const [rowIndex, row] of table.rows.entries()) {
|
|
760
|
+
const value = cellValue2(row[index]);
|
|
761
|
+
if (value === void 0) {
|
|
762
|
+
return err(
|
|
763
|
+
`${context.where}: row ${rowIndex + 1}, column ${index + 1} ("${columnName(table, index)}") has no numeric value. Add value to the cells.`
|
|
764
|
+
);
|
|
765
|
+
}
|
|
766
|
+
numbers.push(value);
|
|
767
|
+
}
|
|
768
|
+
return ok(numbers);
|
|
769
|
+
}
|
|
770
|
+
function tableToBarList(table, conversion, context) {
|
|
771
|
+
const bad = checkColumn(table, conversion.label, "label", context) ?? checkColumn(table, conversion.value, "value", context);
|
|
772
|
+
if (bad !== void 0) return err(bad);
|
|
773
|
+
const numbers = numericColumn(table, conversion.value, context);
|
|
774
|
+
if (!numbers.ok) return numbers;
|
|
775
|
+
const items = table.rows.map((row, index) => ({
|
|
776
|
+
label: row[conversion.label]?.text ?? "",
|
|
777
|
+
value: numbers.value[index],
|
|
778
|
+
display: row[conversion.value]?.text ?? String(numbers.value[index])
|
|
779
|
+
}));
|
|
780
|
+
return ok({ kind: "BAR_LIST", items });
|
|
847
781
|
}
|
|
848
|
-
function
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
782
|
+
function tableToGraph(table, conversion, context) {
|
|
783
|
+
if (conversion.values.length === 0 || conversion.values.length > MAX_GRAPH_SERIES) {
|
|
784
|
+
return err(
|
|
785
|
+
`${context.where}: a chart needs 1 to ${MAX_GRAPH_SERIES} series columns, got ${conversion.values.length}.`
|
|
786
|
+
);
|
|
787
|
+
}
|
|
788
|
+
let bad = checkColumn(
|
|
789
|
+
table,
|
|
790
|
+
conversion.label,
|
|
791
|
+
"label",
|
|
792
|
+
context
|
|
858
793
|
);
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
794
|
+
for (const index of conversion.values) {
|
|
795
|
+
bad ??= checkColumn(table, index, "series", context);
|
|
796
|
+
}
|
|
797
|
+
if (bad !== void 0) return err(bad);
|
|
798
|
+
const series = [];
|
|
799
|
+
for (const index of conversion.values) {
|
|
800
|
+
const numbers = numericColumn(table, index, context);
|
|
801
|
+
if (!numbers.ok) return numbers;
|
|
802
|
+
series.push({
|
|
803
|
+
name: columnName(table, index),
|
|
804
|
+
points: table.rows.map((row, rowIndex) => ({
|
|
805
|
+
label: row[conversion.label]?.text ?? "",
|
|
806
|
+
value: numbers.value[rowIndex]
|
|
807
|
+
}))
|
|
808
|
+
});
|
|
809
|
+
}
|
|
810
|
+
return ok({
|
|
811
|
+
kind: "GRAPH",
|
|
812
|
+
series,
|
|
813
|
+
chartType: conversion.chartType,
|
|
814
|
+
valueFormat: conversion.valueFormat ?? "number",
|
|
815
|
+
...conversion.currency === void 0 ? {} : { currency: conversion.currency },
|
|
816
|
+
xLabel: columnName(table, conversion.label)
|
|
817
|
+
});
|
|
872
818
|
}
|
|
873
|
-
function
|
|
874
|
-
|
|
875
|
-
|
|
819
|
+
function barListToTable(list, conversion) {
|
|
820
|
+
return ok({
|
|
821
|
+
kind: "TABLE",
|
|
822
|
+
columns: [
|
|
823
|
+
{ label: conversion.labelHeading ?? "Name" },
|
|
824
|
+
{ label: conversion.valueHeading ?? "Value", numeric: true }
|
|
825
|
+
],
|
|
826
|
+
rows: list.items.map((item) => [
|
|
827
|
+
{ text: item.label },
|
|
828
|
+
{ text: item.display ?? String(item.value), value: item.value }
|
|
829
|
+
])
|
|
830
|
+
});
|
|
876
831
|
}
|
|
877
|
-
function
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
832
|
+
function graphToTable(graph, context) {
|
|
833
|
+
const first = graph.series[0];
|
|
834
|
+
if (first === void 0)
|
|
835
|
+
return err(`${context.where}: the chart has no series.`);
|
|
836
|
+
const format = {
|
|
837
|
+
...graph.currency === void 0 ? {} : { currency: graph.currency },
|
|
838
|
+
...context.locale === void 0 ? {} : { locale: context.locale }
|
|
883
839
|
};
|
|
840
|
+
return ok({
|
|
841
|
+
kind: "TABLE",
|
|
842
|
+
columns: [
|
|
843
|
+
{ label: graph.xLabel ?? "Label" },
|
|
844
|
+
...graph.series.map((series) => ({ label: series.name, numeric: true }))
|
|
845
|
+
],
|
|
846
|
+
rows: first.points.map((point, index) => [
|
|
847
|
+
{ text: point.label },
|
|
848
|
+
...graph.series.map((series) => {
|
|
849
|
+
const value = series.points[index]?.value;
|
|
850
|
+
return value === void 0 ? { text: "\u2014" } : { text: formatValue(value, graph.valueFormat, format), value };
|
|
851
|
+
})
|
|
852
|
+
])
|
|
853
|
+
});
|
|
884
854
|
}
|
|
885
|
-
function
|
|
886
|
-
return
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
}
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
const known = new Set(definitions.map((d) => d.key));
|
|
901
|
-
const keep = (keys) => keys.every((k) => known.has(k)) ? keys : keys.filter((k) => known.has(k));
|
|
902
|
-
return mapLayoutLists(layout, (lists) => ({
|
|
903
|
-
order: keep(lists.order),
|
|
904
|
-
hidden: keep(lists.hidden),
|
|
905
|
-
minimized: keep(lists.minimized)
|
|
906
|
-
}));
|
|
907
|
-
}
|
|
908
|
-
function mapLayoutLists(layout, change) {
|
|
909
|
-
const top = change(layout);
|
|
910
|
-
const pages = layout.pages?.map((page) => {
|
|
911
|
-
const next = change(page);
|
|
912
|
-
return next.order === page.order && next.hidden === page.hidden && next.minimized === page.minimized ? page : { ...page, ...next };
|
|
855
|
+
function barListToGraph(list, conversion) {
|
|
856
|
+
return ok({
|
|
857
|
+
kind: "GRAPH",
|
|
858
|
+
series: [
|
|
859
|
+
{
|
|
860
|
+
name: conversion.seriesName ?? "Value",
|
|
861
|
+
points: list.items.map((item) => ({
|
|
862
|
+
label: item.label,
|
|
863
|
+
value: item.value
|
|
864
|
+
}))
|
|
865
|
+
}
|
|
866
|
+
],
|
|
867
|
+
chartType: conversion.chartType,
|
|
868
|
+
valueFormat: conversion.valueFormat ?? "number",
|
|
869
|
+
...conversion.currency === void 0 ? {} : { currency: conversion.currency }
|
|
913
870
|
});
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
871
|
+
}
|
|
872
|
+
function convertView(widgetKey, view, data, options = {}) {
|
|
873
|
+
const conversion = view.convert;
|
|
874
|
+
const context = {
|
|
875
|
+
where: `Widget ${JSON.stringify(widgetKey)} view ${JSON.stringify(view.key)}`,
|
|
876
|
+
...options.locale === void 0 ? {} : { locale: options.locale }
|
|
877
|
+
};
|
|
878
|
+
const expected = VIEW_CONVERSIONS[conversion.type]?.from;
|
|
879
|
+
if (expected === void 0) {
|
|
880
|
+
return err(
|
|
881
|
+
`${context.where}: unknown conversion type ${JSON.stringify(conversion.type)}.`
|
|
882
|
+
);
|
|
917
883
|
}
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
884
|
+
if (data.kind !== expected) {
|
|
885
|
+
return err(
|
|
886
|
+
`${context.where}: ${conversion.type} reads a ${expected} payload, but the widget returned ${data.kind}.`
|
|
887
|
+
);
|
|
888
|
+
}
|
|
889
|
+
switch (conversion.type) {
|
|
890
|
+
case "tableToBarList":
|
|
891
|
+
return tableToBarList(data, conversion, context);
|
|
892
|
+
case "tableToGraph":
|
|
893
|
+
return tableToGraph(data, conversion, context);
|
|
894
|
+
case "barListToTable":
|
|
895
|
+
return barListToTable(data, conversion);
|
|
896
|
+
case "graphToTable":
|
|
897
|
+
return graphToTable(data, context);
|
|
898
|
+
case "barListToGraph":
|
|
899
|
+
return barListToGraph(data, conversion);
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
function viewNote(view, data) {
|
|
903
|
+
if (data?.kind !== "TABLE") return "";
|
|
904
|
+
const conversion = view.convert;
|
|
905
|
+
let indexes;
|
|
906
|
+
if (conversion.type === "tableToBarList") {
|
|
907
|
+
indexes = [conversion.label, conversion.value];
|
|
908
|
+
} else if (conversion.type === "tableToGraph") {
|
|
909
|
+
indexes = [conversion.label, ...conversion.values];
|
|
910
|
+
} else {
|
|
911
|
+
return "";
|
|
912
|
+
}
|
|
913
|
+
const names = indexes.map(
|
|
914
|
+
(index) => data.columns[index]?.label ?? `#${index + 1}`
|
|
915
|
+
);
|
|
916
|
+
return `Shows ${names.join(", ")} only.`;
|
|
917
|
+
}
|
|
918
|
+
function applyView(widget, chosen, options = {}) {
|
|
919
|
+
const key = effectiveViewKey(widget.definition, chosen);
|
|
920
|
+
const view = findView(widget.definition, key);
|
|
921
|
+
if (view === void 0) return widget;
|
|
922
|
+
const definition = {
|
|
923
|
+
...widget.definition,
|
|
924
|
+
kind: view.kind
|
|
922
925
|
};
|
|
923
|
-
}
|
|
924
|
-
|
|
925
|
-
if (
|
|
926
|
-
const
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
926
|
+
if (widget.status === "loading") return { ...widget, definition };
|
|
927
|
+
if (widget.status === "empty") return { ...widget, definition };
|
|
928
|
+
if (widget.status === "error") return { ...widget, definition };
|
|
929
|
+
const converted = convertView(
|
|
930
|
+
widget.definition.key,
|
|
931
|
+
view,
|
|
932
|
+
widget.data,
|
|
933
|
+
options
|
|
934
|
+
);
|
|
935
|
+
if (!converted.ok) {
|
|
936
|
+
return {
|
|
937
|
+
definition,
|
|
938
|
+
status: "error",
|
|
939
|
+
error: converted.error,
|
|
940
|
+
...widget.options === void 0 ? {} : { options: widget.options }
|
|
941
|
+
};
|
|
934
942
|
}
|
|
935
|
-
|
|
936
|
-
return mapLayoutLists(layout, (lists) => ({
|
|
937
|
-
order: without2(lists.order, noMove),
|
|
938
|
-
hidden: without2(lists.hidden, noHide),
|
|
939
|
-
minimized: without2(lists.minimized, noMinimize)
|
|
940
|
-
}));
|
|
943
|
+
return { ...widget, definition, data: converted.value };
|
|
941
944
|
}
|
|
942
945
|
|
|
943
946
|
// src/core/options.ts
|
|
@@ -1114,107 +1117,644 @@ function coerceOptionValue(option, value, context = {}) {
|
|
|
1114
1117
|
}
|
|
1115
1118
|
}
|
|
1116
1119
|
}
|
|
1117
|
-
function defaultOptionValue(option, context = {}) {
|
|
1118
|
-
switch (option.type) {
|
|
1119
|
-
case "dateRange":
|
|
1120
|
-
return resolveDateRange(option.default, context);
|
|
1121
|
-
case "sort":
|
|
1122
|
-
return option.default;
|
|
1123
|
-
case "columns":
|
|
1124
|
-
return [...option.default];
|
|
1125
|
-
default:
|
|
1126
|
-
return option.default;
|
|
1127
|
-
}
|
|
1120
|
+
function defaultOptionValue(option, context = {}) {
|
|
1121
|
+
switch (option.type) {
|
|
1122
|
+
case "dateRange":
|
|
1123
|
+
return resolveDateRange(option.default, context);
|
|
1124
|
+
case "sort":
|
|
1125
|
+
return option.default;
|
|
1126
|
+
case "columns":
|
|
1127
|
+
return [...option.default];
|
|
1128
|
+
default:
|
|
1129
|
+
return option.default;
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
var NO_VALUES = Object.freeze({});
|
|
1133
|
+
function resolveOptionValues(definition, chosen, context = {}) {
|
|
1134
|
+
const options = definition.options;
|
|
1135
|
+
if (options === void 0 || options.length === 0) return NO_VALUES;
|
|
1136
|
+
const values = {};
|
|
1137
|
+
for (const option of options) {
|
|
1138
|
+
const picked = chosen?.[option.key];
|
|
1139
|
+
const value = (picked === void 0 ? void 0 : coerceOptionValue(option, picked, context)) ?? defaultOptionValue(option, context);
|
|
1140
|
+
if (value !== void 0) values[option.key] = value;
|
|
1141
|
+
}
|
|
1142
|
+
return values;
|
|
1143
|
+
}
|
|
1144
|
+
function sameValue(a, b) {
|
|
1145
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
1146
|
+
return a.length === b.length && a.every((item, i) => item === b[i]);
|
|
1147
|
+
}
|
|
1148
|
+
return a === b;
|
|
1149
|
+
}
|
|
1150
|
+
function sameOptionValues(a, b) {
|
|
1151
|
+
const keys = Object.keys({ ...a, ...b });
|
|
1152
|
+
return keys.every((key) => sameValue(a[key], b[key]));
|
|
1153
|
+
}
|
|
1154
|
+
function optionsCacheSuffix(definition, values, context = {}) {
|
|
1155
|
+
const parts = [];
|
|
1156
|
+
for (const option of definition.options ?? []) {
|
|
1157
|
+
if (isClientApplied(option)) continue;
|
|
1158
|
+
const value = values[option.key];
|
|
1159
|
+
if (sameValue(value, defaultOptionValue(option, context))) continue;
|
|
1160
|
+
parts.push(
|
|
1161
|
+
`${option.key}=${encodeURIComponent(JSON.stringify(value ?? null))}`
|
|
1162
|
+
);
|
|
1163
|
+
}
|
|
1164
|
+
parts.sort();
|
|
1165
|
+
return parts.length === 0 ? "" : `?${parts.join("&")}`;
|
|
1166
|
+
}
|
|
1167
|
+
function tableColumnIndex(key) {
|
|
1168
|
+
const match = /^c(\d+)$/.exec(key);
|
|
1169
|
+
return match === null ? void 0 : Number(match[1]);
|
|
1170
|
+
}
|
|
1171
|
+
function sortBarItems(items, sort) {
|
|
1172
|
+
const sign = sort.direction === "desc" ? -1 : 1;
|
|
1173
|
+
return items.map((item, index) => ({ item, index })).sort((a, b) => {
|
|
1174
|
+
const order = sort.column === "value" ? a.item.value - b.item.value : a.item.label.localeCompare(b.item.label);
|
|
1175
|
+
return order * sign || a.index - b.index;
|
|
1176
|
+
}).map(({ item }) => item);
|
|
1177
|
+
}
|
|
1178
|
+
function applyClientOptions(definition, data, values) {
|
|
1179
|
+
const options = definition.options ?? [];
|
|
1180
|
+
const sortOption = options.find(
|
|
1181
|
+
(o) => o.type === "sort" && o.apply === "client"
|
|
1182
|
+
);
|
|
1183
|
+
const columnsOption = options.find(
|
|
1184
|
+
(o) => o.type === "columns" && o.apply === "client"
|
|
1185
|
+
);
|
|
1186
|
+
const sortValue = sortOption === void 0 ? void 0 : values[sortOption.key];
|
|
1187
|
+
const columnsValue = columnsOption === void 0 ? void 0 : values[columnsOption.key];
|
|
1188
|
+
let next = data;
|
|
1189
|
+
if (typeof sortValue === "string") {
|
|
1190
|
+
const sort = parseSortValue(sortValue);
|
|
1191
|
+
if (sort !== void 0 && next.kind === "BAR_LIST") {
|
|
1192
|
+
if (sort.column === "label" || sort.column === "value") {
|
|
1193
|
+
next = { ...next, items: sortBarItems(next.items, sort) };
|
|
1194
|
+
}
|
|
1195
|
+
} else if (sort !== void 0 && next.kind === "TABLE") {
|
|
1196
|
+
const index = tableColumnIndex(sort.column);
|
|
1197
|
+
if (index !== void 0 && index < next.columns.length) {
|
|
1198
|
+
const sorted = queryRows(tableDetailData(next), {
|
|
1199
|
+
page: 1,
|
|
1200
|
+
pageSize: Math.max(1, next.rows.length),
|
|
1201
|
+
sort
|
|
1202
|
+
});
|
|
1203
|
+
if (sorted.ok) next = { ...next, rows: sorted.value.rows };
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
if (Array.isArray(columnsValue) && next.kind === "TABLE") {
|
|
1208
|
+
const table = next;
|
|
1209
|
+
const indexes = columnsValue.map(tableColumnIndex).filter(
|
|
1210
|
+
(index) => index !== void 0 && index < table.columns.length
|
|
1211
|
+
);
|
|
1212
|
+
if (indexes.length > 0) {
|
|
1213
|
+
next = {
|
|
1214
|
+
...table,
|
|
1215
|
+
columns: indexes.map((i) => table.columns[i]),
|
|
1216
|
+
rows: table.rows.map((row) => indexes.map((i) => row[i]))
|
|
1217
|
+
};
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
return next;
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
// src/core/settings.ts
|
|
1224
|
+
var MAX_WIDGET_TITLE_LENGTH = 80;
|
|
1225
|
+
var MAX_PARSED_SETTINGS = 500;
|
|
1226
|
+
var MAX_COLUMN_LIST = 100;
|
|
1227
|
+
var MAX_VALUE_LENGTH = 500;
|
|
1228
|
+
function isRecord(value) {
|
|
1229
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1230
|
+
}
|
|
1231
|
+
function parseOptionValue(value) {
|
|
1232
|
+
if (typeof value === "string") {
|
|
1233
|
+
return value.length <= MAX_VALUE_LENGTH ? value : void 0;
|
|
1234
|
+
}
|
|
1235
|
+
if (typeof value === "number")
|
|
1236
|
+
return Number.isFinite(value) ? value : void 0;
|
|
1237
|
+
if (typeof value === "boolean") return value;
|
|
1238
|
+
if (Array.isArray(value) && value.length <= MAX_COLUMN_LIST) {
|
|
1239
|
+
return value.every(
|
|
1240
|
+
(entry) => typeof entry === "string" && entry.length <= MAX_VALUE_LENGTH
|
|
1241
|
+
) ? value : void 0;
|
|
1242
|
+
}
|
|
1243
|
+
return void 0;
|
|
1244
|
+
}
|
|
1245
|
+
function parseOne(raw) {
|
|
1246
|
+
if (!isRecord(raw)) return void 0;
|
|
1247
|
+
const title = raw["title"];
|
|
1248
|
+
const width = raw["width"];
|
|
1249
|
+
const flexible = raw["flexible"];
|
|
1250
|
+
const options = raw["options"];
|
|
1251
|
+
const view = raw["view"];
|
|
1252
|
+
const cleanTitle = typeof title === "string" ? title.trim().slice(0, MAX_WIDGET_TITLE_LENGTH) : "";
|
|
1253
|
+
const chosen = {};
|
|
1254
|
+
if (isRecord(options)) {
|
|
1255
|
+
for (const [key, value] of Object.entries(options)) {
|
|
1256
|
+
const parsed = parseOptionValue(value);
|
|
1257
|
+
if (parsed !== void 0) chosen[key] = parsed;
|
|
1258
|
+
}
|
|
1259
|
+
}
|
|
1260
|
+
const settings = {
|
|
1261
|
+
...cleanTitle === "" ? {} : { title: cleanTitle },
|
|
1262
|
+
...isWidgetWidth(width) ? { width } : {},
|
|
1263
|
+
...typeof flexible === "boolean" ? { flexible } : {},
|
|
1264
|
+
...Object.keys(chosen).length === 0 ? {} : { options: chosen },
|
|
1265
|
+
...typeof view === "string" && view !== "" && view.length <= 80 ? { view } : {}
|
|
1266
|
+
};
|
|
1267
|
+
return Object.keys(settings).length === 0 ? void 0 : settings;
|
|
1268
|
+
}
|
|
1269
|
+
function parseSettings(raw) {
|
|
1270
|
+
if (!isRecord(raw)) return void 0;
|
|
1271
|
+
const parsed = {};
|
|
1272
|
+
for (const [key, value] of Object.entries(raw).slice(
|
|
1273
|
+
0,
|
|
1274
|
+
MAX_PARSED_SETTINGS
|
|
1275
|
+
)) {
|
|
1276
|
+
if (key === "") continue;
|
|
1277
|
+
const one = parseOne(value);
|
|
1278
|
+
if (one !== void 0) parsed[key] = one;
|
|
1279
|
+
}
|
|
1280
|
+
return Object.keys(parsed).length === 0 ? void 0 : parsed;
|
|
1281
|
+
}
|
|
1282
|
+
function serializeSettings(settings) {
|
|
1283
|
+
if (settings === void 0) return void 0;
|
|
1284
|
+
const out = {};
|
|
1285
|
+
for (const key of Object.keys(settings)) {
|
|
1286
|
+
const one = settings[key];
|
|
1287
|
+
if (one === void 0) continue;
|
|
1288
|
+
const piece = {
|
|
1289
|
+
...one.title === void 0 ? {} : { title: one.title },
|
|
1290
|
+
...one.width === void 0 ? {} : { width: one.width },
|
|
1291
|
+
...one.flexible === void 0 ? {} : { flexible: one.flexible },
|
|
1292
|
+
...one.options === void 0 || Object.keys(one.options).length === 0 ? {} : { options: { ...one.options } },
|
|
1293
|
+
...one.view === void 0 ? {} : { view: one.view }
|
|
1294
|
+
};
|
|
1295
|
+
if (Object.keys(piece).length > 0) out[key] = piece;
|
|
1296
|
+
}
|
|
1297
|
+
return Object.keys(out).length === 0 ? void 0 : out;
|
|
1298
|
+
}
|
|
1299
|
+
function widthRange(item) {
|
|
1300
|
+
const min = isWidgetWidth(item.minWidth) ? item.minWidth : MIN_WIDGET_WIDTH;
|
|
1301
|
+
const max = isWidgetWidth(item.maxWidth) ? item.maxWidth : MAX_WIDGET_WIDTH;
|
|
1302
|
+
return { min, max: Math.max(min, max) };
|
|
1303
|
+
}
|
|
1304
|
+
var WIDTH_SHARES = {
|
|
1305
|
+
2: "1/6",
|
|
1306
|
+
3: "1/4",
|
|
1307
|
+
4: "1/3",
|
|
1308
|
+
5: "5/12",
|
|
1309
|
+
6: "1/2",
|
|
1310
|
+
7: "7/12",
|
|
1311
|
+
8: "2/3",
|
|
1312
|
+
9: "3/4",
|
|
1313
|
+
10: "5/6",
|
|
1314
|
+
11: "11/12",
|
|
1315
|
+
12: "Full"
|
|
1316
|
+
};
|
|
1317
|
+
function widthShareLabel(width) {
|
|
1318
|
+
return WIDTH_SHARES[width] ?? `${width}/12`;
|
|
1319
|
+
}
|
|
1320
|
+
function isOptionsLocked(item) {
|
|
1321
|
+
return resolveWidgetLock(item).options;
|
|
1322
|
+
}
|
|
1323
|
+
function fillWith(fill, flexible) {
|
|
1324
|
+
const heightToo = fill === "height" || fill === "both";
|
|
1325
|
+
if (flexible) return heightToo ? "both" : "width";
|
|
1326
|
+
return heightToo ? "height" : void 0;
|
|
1327
|
+
}
|
|
1328
|
+
function isFlexible(item, settings) {
|
|
1329
|
+
if (settings?.flexible !== void 0) return settings.flexible;
|
|
1330
|
+
return item.fill === "width" || item.fill === "both";
|
|
1331
|
+
}
|
|
1332
|
+
function applySettings(definition, settings) {
|
|
1333
|
+
if (settings === void 0) return definition;
|
|
1334
|
+
const range = widthRange(definition);
|
|
1335
|
+
const width = settings.width === void 0 ? void 0 : Math.min(range.max, Math.max(range.min, settings.width));
|
|
1336
|
+
const title = settings.title === void 0 || settings.title.trim() === "" ? void 0 : settings.title;
|
|
1337
|
+
const flexibleChanged = settings.flexible !== void 0 && settings.flexible !== isFlexible(definition, void 0);
|
|
1338
|
+
if (title === void 0 && width === void 0 && !flexibleChanged) {
|
|
1339
|
+
return definition;
|
|
1340
|
+
}
|
|
1341
|
+
const next = { ...definition };
|
|
1342
|
+
if (title !== void 0) next.title = title;
|
|
1343
|
+
if (width !== void 0) next.width = width;
|
|
1344
|
+
if (flexibleChanged) {
|
|
1345
|
+
const fill = fillWith(
|
|
1346
|
+
definition.fill,
|
|
1347
|
+
settings.flexible === true
|
|
1348
|
+
);
|
|
1349
|
+
if (fill === void 0) {
|
|
1350
|
+
delete next.fill;
|
|
1351
|
+
} else {
|
|
1352
|
+
next.fill = fill;
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
return next;
|
|
1356
|
+
}
|
|
1357
|
+
function effectiveDefinitions(definitions, layout, options = {}) {
|
|
1358
|
+
return definitions.map(
|
|
1359
|
+
(definition) => options.overrideLocks !== true && isOptionsLocked(definition) ? definition : applySettings(definition, layout.settings?.[definition.key])
|
|
1360
|
+
);
|
|
1361
|
+
}
|
|
1362
|
+
function widgetOptionValues(definition, settings) {
|
|
1363
|
+
const declared = definition.options ?? [];
|
|
1364
|
+
const values = {};
|
|
1365
|
+
for (const option of declared) {
|
|
1366
|
+
const picked = settings?.options?.[option.key];
|
|
1367
|
+
const value = (picked === void 0 ? void 0 : coerceOptionValue(option, picked)) ?? defaultOptionValue(option);
|
|
1368
|
+
if (value !== void 0) values[option.key] = value;
|
|
1369
|
+
}
|
|
1370
|
+
return values;
|
|
1371
|
+
}
|
|
1372
|
+
function optionValuesFromLayout(definitions, layout, options = {}) {
|
|
1373
|
+
const out = {};
|
|
1374
|
+
for (const definition of definitions) {
|
|
1375
|
+
if (definition.options === void 0 || definition.options.length === 0) {
|
|
1376
|
+
continue;
|
|
1377
|
+
}
|
|
1378
|
+
const locked = options.overrideLocks !== true && isOptionsLocked(definition);
|
|
1379
|
+
out[definition.key] = locked ? {} : layout.settings?.[definition.key]?.options ?? {};
|
|
1380
|
+
}
|
|
1381
|
+
return out;
|
|
1382
|
+
}
|
|
1383
|
+
function sameSettings(a, b) {
|
|
1384
|
+
if (a === b) return true;
|
|
1385
|
+
return a?.title === b?.title && a?.width === b?.width && a?.flexible === b?.flexible && a?.view === b?.view && sameOptionValues(a?.options ?? {}, b?.options ?? {});
|
|
1386
|
+
}
|
|
1387
|
+
function setWidgetSettings(layout, key, patch) {
|
|
1388
|
+
const before = layout.settings?.[key];
|
|
1389
|
+
const draft = { ...before };
|
|
1390
|
+
for (const field of [
|
|
1391
|
+
"title",
|
|
1392
|
+
"width",
|
|
1393
|
+
"flexible",
|
|
1394
|
+
"options",
|
|
1395
|
+
"view"
|
|
1396
|
+
]) {
|
|
1397
|
+
if (!(field in patch)) continue;
|
|
1398
|
+
const value = patch[field];
|
|
1399
|
+
if (value === void 0) {
|
|
1400
|
+
delete draft[field];
|
|
1401
|
+
} else {
|
|
1402
|
+
draft[field] = value;
|
|
1403
|
+
}
|
|
1404
|
+
}
|
|
1405
|
+
const merged = parseOne(draft);
|
|
1406
|
+
if (sameSettings(before, merged)) return layout;
|
|
1407
|
+
const rest = { ...layout.settings };
|
|
1408
|
+
if (merged === void 0) {
|
|
1409
|
+
delete rest[key];
|
|
1410
|
+
} else {
|
|
1411
|
+
rest[key] = merged;
|
|
1412
|
+
}
|
|
1413
|
+
const { settings: _previous, ...others } = layout;
|
|
1414
|
+
return Object.keys(rest).length === 0 ? others : { ...others, settings: rest };
|
|
1415
|
+
}
|
|
1416
|
+
function clearWidgetSettings(layout, key) {
|
|
1417
|
+
if (layout.settings?.[key] === void 0) return layout;
|
|
1418
|
+
return setWidgetSettings(layout, key, {
|
|
1419
|
+
title: void 0,
|
|
1420
|
+
width: void 0,
|
|
1421
|
+
flexible: void 0,
|
|
1422
|
+
options: void 0,
|
|
1423
|
+
view: void 0
|
|
1424
|
+
});
|
|
1425
|
+
}
|
|
1426
|
+
function normalizeTitle(title) {
|
|
1427
|
+
return title.normalize("NFKC").trim().toLowerCase();
|
|
1428
|
+
}
|
|
1429
|
+
function isTitleInUse(definitions, layout, key, title) {
|
|
1430
|
+
const wanted = normalizeTitle(title);
|
|
1431
|
+
if (wanted === "") return false;
|
|
1432
|
+
return effectiveDefinitions(definitions, layout, {
|
|
1433
|
+
overrideLocks: true
|
|
1434
|
+
}).some(
|
|
1435
|
+
(other) => other.key !== key && normalizeTitle(other.title ?? other.key) === wanted
|
|
1436
|
+
);
|
|
1437
|
+
}
|
|
1438
|
+
function uniqueTitle(taken, title) {
|
|
1439
|
+
if (!taken.has(normalizeTitle(title))) return title;
|
|
1440
|
+
for (let n = 2; ; n += 1) {
|
|
1441
|
+
const suffix = ` (#${n})`;
|
|
1442
|
+
const candidate = `${title.slice(0, MAX_WIDGET_TITLE_LENGTH - suffix.length)}${suffix}`;
|
|
1443
|
+
if (!taken.has(normalizeTitle(candidate))) return candidate;
|
|
1444
|
+
}
|
|
1445
|
+
}
|
|
1446
|
+
function normalizeSettings(definitions, layout, options = {}) {
|
|
1447
|
+
const settings = layout.settings;
|
|
1448
|
+
if (settings === void 0) return layout;
|
|
1449
|
+
const cleaned = {};
|
|
1450
|
+
const taken = /* @__PURE__ */ new Set();
|
|
1451
|
+
for (const definition of definitions) {
|
|
1452
|
+
const renamed = settings[definition.key]?.title !== void 0 && (options.overrideLocks === true || !isOptionsLocked(definition));
|
|
1453
|
+
if (!renamed) taken.add(normalizeTitle(definition.title ?? definition.key));
|
|
1454
|
+
}
|
|
1455
|
+
for (const definition of definitions) {
|
|
1456
|
+
const one = settings[definition.key];
|
|
1457
|
+
if (one === void 0) continue;
|
|
1458
|
+
if (options.overrideLocks !== true && isOptionsLocked(definition)) continue;
|
|
1459
|
+
const range = widthRange(definition);
|
|
1460
|
+
const chosen = {};
|
|
1461
|
+
for (const option of definition.options ?? []) {
|
|
1462
|
+
const picked = one.options?.[option.key];
|
|
1463
|
+
if (picked === void 0) continue;
|
|
1464
|
+
const value = coerceOptionValue(option, picked);
|
|
1465
|
+
if (value !== void 0) {
|
|
1466
|
+
chosen[option.key] = option.type === "dateRange" ? picked : value;
|
|
1467
|
+
}
|
|
1468
|
+
}
|
|
1469
|
+
let title = one.title;
|
|
1470
|
+
if (title !== void 0) {
|
|
1471
|
+
title = title.trim().slice(0, MAX_WIDGET_TITLE_LENGTH);
|
|
1472
|
+
if (title === "") {
|
|
1473
|
+
title = void 0;
|
|
1474
|
+
} else {
|
|
1475
|
+
title = uniqueTitle(taken, title);
|
|
1476
|
+
taken.add(normalizeTitle(title));
|
|
1477
|
+
}
|
|
1478
|
+
}
|
|
1479
|
+
const next = {
|
|
1480
|
+
...title === void 0 ? {} : { title },
|
|
1481
|
+
...one.width === void 0 ? {} : { width: Math.min(range.max, Math.max(range.min, one.width)) },
|
|
1482
|
+
...one.flexible === void 0 ? {} : { flexible: one.flexible },
|
|
1483
|
+
...Object.keys(chosen).length === 0 ? {} : { options: chosen },
|
|
1484
|
+
...one.view !== void 0 && (one.view === BASE_VIEW_KEY || findView(definition, one.view) !== void 0) ? { view: one.view } : {}
|
|
1485
|
+
};
|
|
1486
|
+
if (Object.keys(next).length > 0) {
|
|
1487
|
+
cleaned[definition.key] = sameSettings(one, next) ? one : next;
|
|
1488
|
+
}
|
|
1489
|
+
}
|
|
1490
|
+
const keys = Object.keys(cleaned);
|
|
1491
|
+
const unchanged = keys.length === Object.keys(settings).length && keys.every((key) => cleaned[key] === settings[key]);
|
|
1492
|
+
if (unchanged) return layout;
|
|
1493
|
+
const { settings: _previous, ...others } = layout;
|
|
1494
|
+
return keys.length === 0 ? others : { ...others, settings: cleaned };
|
|
1495
|
+
}
|
|
1496
|
+
|
|
1497
|
+
// src/core/layout.ts
|
|
1498
|
+
var MAX_PAGE_TITLE_LENGTH = 30;
|
|
1499
|
+
var MAX_PARSED_PAGES = 50;
|
|
1500
|
+
var MAX_PAGE_ROWS = 20;
|
|
1501
|
+
var EMPTY_LAYOUT = Object.freeze({
|
|
1502
|
+
order: Object.freeze([]),
|
|
1503
|
+
hidden: Object.freeze([]),
|
|
1504
|
+
minimized: Object.freeze([])
|
|
1505
|
+
});
|
|
1506
|
+
function uniqueStrings(value) {
|
|
1507
|
+
if (!Array.isArray(value)) return [];
|
|
1508
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1509
|
+
for (const entry of value) {
|
|
1510
|
+
if (typeof entry === "string" && entry !== "") seen.add(entry);
|
|
1511
|
+
}
|
|
1512
|
+
return [...seen];
|
|
1513
|
+
}
|
|
1514
|
+
function parseLayout(raw) {
|
|
1515
|
+
let value = raw;
|
|
1516
|
+
if (typeof raw === "string") {
|
|
1517
|
+
try {
|
|
1518
|
+
value = JSON.parse(raw);
|
|
1519
|
+
} catch {
|
|
1520
|
+
return EMPTY_LAYOUT;
|
|
1521
|
+
}
|
|
1522
|
+
}
|
|
1523
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
1524
|
+
return EMPTY_LAYOUT;
|
|
1525
|
+
}
|
|
1526
|
+
const record = value;
|
|
1527
|
+
const order = uniqueStrings(record["order"]);
|
|
1528
|
+
const hidden = uniqueStrings(record["hidden"]);
|
|
1529
|
+
const minimized = uniqueStrings(record["minimized"]);
|
|
1530
|
+
const pages = parsePages(record["pages"]);
|
|
1531
|
+
const settings = parseSettings(
|
|
1532
|
+
record["settings"]
|
|
1533
|
+
);
|
|
1534
|
+
const withSettings = settings === void 0 ? {} : { settings };
|
|
1535
|
+
if (pages.length > 0) {
|
|
1536
|
+
return {
|
|
1537
|
+
order: EMPTY_LAYOUT.order,
|
|
1538
|
+
hidden: EMPTY_LAYOUT.hidden,
|
|
1539
|
+
minimized: EMPTY_LAYOUT.minimized,
|
|
1540
|
+
pages,
|
|
1541
|
+
...withSettings
|
|
1542
|
+
};
|
|
1543
|
+
}
|
|
1544
|
+
if (order.length === 0 && hidden.length === 0 && minimized.length === 0) {
|
|
1545
|
+
return settings === void 0 ? EMPTY_LAYOUT : { ...EMPTY_LAYOUT, settings };
|
|
1546
|
+
}
|
|
1547
|
+
return { order, hidden, minimized, ...withSettings };
|
|
1548
|
+
}
|
|
1549
|
+
function parsePages(value) {
|
|
1550
|
+
if (!Array.isArray(value)) return [];
|
|
1551
|
+
const pages = [];
|
|
1552
|
+
const keys = /* @__PURE__ */ new Set();
|
|
1553
|
+
for (const entry of value.slice(0, MAX_PARSED_PAGES)) {
|
|
1554
|
+
if (typeof entry !== "object" || entry === null || Array.isArray(entry)) {
|
|
1555
|
+
continue;
|
|
1556
|
+
}
|
|
1557
|
+
const record = entry;
|
|
1558
|
+
const key = record["key"];
|
|
1559
|
+
if (typeof key !== "string" || key === "" || keys.has(key)) continue;
|
|
1560
|
+
keys.add(key);
|
|
1561
|
+
const rawTitle = record["title"];
|
|
1562
|
+
const title = typeof rawTitle === "string" && rawTitle.trim() !== "" ? rawTitle.trim().slice(0, MAX_PAGE_TITLE_LENGTH) : `Page ${pages.length + 1}`;
|
|
1563
|
+
const maxRows = record["maxRows"];
|
|
1564
|
+
const held = /* @__PURE__ */ new Set();
|
|
1565
|
+
for (const earlier of pages) {
|
|
1566
|
+
for (const k of [...earlier.order, ...earlier.hidden]) held.add(k);
|
|
1567
|
+
}
|
|
1568
|
+
const keep = (list) => uniqueStrings(list).filter((k) => !held.has(k));
|
|
1569
|
+
pages.push({
|
|
1570
|
+
key,
|
|
1571
|
+
title,
|
|
1572
|
+
order: keep(record["order"]),
|
|
1573
|
+
hidden: keep(record["hidden"]),
|
|
1574
|
+
minimized: keep(record["minimized"]),
|
|
1575
|
+
...typeof maxRows === "number" && Number.isInteger(maxRows) && maxRows >= 1 && maxRows <= MAX_PAGE_ROWS ? { maxRows } : {}
|
|
1576
|
+
});
|
|
1577
|
+
}
|
|
1578
|
+
return pages;
|
|
1579
|
+
}
|
|
1580
|
+
function serializeLayout(layout) {
|
|
1581
|
+
return JSON.stringify({
|
|
1582
|
+
order: [...layout.order],
|
|
1583
|
+
hidden: [...layout.hidden],
|
|
1584
|
+
minimized: [...layout.minimized],
|
|
1585
|
+
...layout.pages === void 0 || layout.pages.length === 0 ? {} : {
|
|
1586
|
+
pages: layout.pages.map((page) => ({
|
|
1587
|
+
key: page.key,
|
|
1588
|
+
title: page.title,
|
|
1589
|
+
order: [...page.order],
|
|
1590
|
+
hidden: [...page.hidden],
|
|
1591
|
+
minimized: [...page.minimized],
|
|
1592
|
+
...page.maxRows === void 0 ? {} : { maxRows: page.maxRows }
|
|
1593
|
+
}))
|
|
1594
|
+
},
|
|
1595
|
+
...serializeSettings(layout.settings) === void 0 ? {} : { settings: serializeSettings(layout.settings) }
|
|
1596
|
+
});
|
|
1597
|
+
}
|
|
1598
|
+
function bySortOrder(items) {
|
|
1599
|
+
return items.map((item, index) => ({ item, index })).sort(
|
|
1600
|
+
(a, b) => (a.item.sortOrder ?? 0) - (b.item.sortOrder ?? 0) || a.index - b.index
|
|
1601
|
+
).map(({ item }) => item);
|
|
1602
|
+
}
|
|
1603
|
+
function isPinned(item) {
|
|
1604
|
+
return resolveWidgetLock(item).move;
|
|
1605
|
+
}
|
|
1606
|
+
function viewerOrder(visible, layout) {
|
|
1607
|
+
const byKey = new Map(visible.map((d) => [d.key, d]));
|
|
1608
|
+
const ordered = [];
|
|
1609
|
+
for (const key of layout.order) {
|
|
1610
|
+
const definition = byKey.get(key);
|
|
1611
|
+
if (definition !== void 0) {
|
|
1612
|
+
ordered.push(definition);
|
|
1613
|
+
byKey.delete(key);
|
|
1614
|
+
}
|
|
1615
|
+
}
|
|
1616
|
+
for (const definition of bySortOrder(visible)) {
|
|
1617
|
+
if (byKey.has(definition.key)) ordered.push(definition);
|
|
1618
|
+
}
|
|
1619
|
+
return ordered;
|
|
1620
|
+
}
|
|
1621
|
+
function placeAroundPinned(visible, free) {
|
|
1622
|
+
const slots = bySortOrder(visible).map(
|
|
1623
|
+
(item) => isPinned(item) ? item : void 0
|
|
1624
|
+
);
|
|
1625
|
+
let next = 0;
|
|
1626
|
+
return slots.map((pinned) => pinned ?? free[next++]);
|
|
1627
|
+
}
|
|
1628
|
+
function visibleWidgets(definitions, layout) {
|
|
1629
|
+
const hidden = new Set(layout.hidden);
|
|
1630
|
+
const visible = definitions.filter((d) => !hidden.has(d.key));
|
|
1631
|
+
const ordered = viewerOrder(visible, layout);
|
|
1632
|
+
if (!visible.some(isPinned)) return ordered;
|
|
1633
|
+
return placeAroundPinned(
|
|
1634
|
+
visible,
|
|
1635
|
+
ordered.filter((item) => !isPinned(item))
|
|
1636
|
+
);
|
|
1637
|
+
}
|
|
1638
|
+
function hiddenWidgets(definitions, layout) {
|
|
1639
|
+
const hidden = new Set(layout.hidden);
|
|
1640
|
+
return bySortOrder(definitions.filter((d) => hidden.has(d.key)));
|
|
1641
|
+
}
|
|
1642
|
+
function moveWidget(definitions, layout, key, toIndex) {
|
|
1643
|
+
const current = visibleWidgets(definitions, layout);
|
|
1644
|
+
const fromIndex = current.findIndex((d) => d.key === key);
|
|
1645
|
+
const mover = current[fromIndex];
|
|
1646
|
+
if (mover === void 0 || !Number.isInteger(toIndex) || toIndex < 0 || toIndex >= current.length || toIndex === fromIndex || isPinned(mover) || isPinned(current[toIndex])) {
|
|
1647
|
+
return layout;
|
|
1648
|
+
}
|
|
1649
|
+
const freeSlots = freeSlotIndexes(current);
|
|
1650
|
+
const free = current.filter((item) => !isPinned(item));
|
|
1651
|
+
const fromFree = freeSlots.indexOf(fromIndex);
|
|
1652
|
+
const toFree = freeSlots.indexOf(toIndex);
|
|
1653
|
+
free.splice(fromFree, 1);
|
|
1654
|
+
free.splice(toFree, 0, mover);
|
|
1655
|
+
const next = placeAroundPinned(current, free);
|
|
1656
|
+
return { ...layout, order: next.map((d) => d.key) };
|
|
1657
|
+
}
|
|
1658
|
+
function freeSlotIndexes(ordered) {
|
|
1659
|
+
const slots = [];
|
|
1660
|
+
ordered.forEach((item, index) => {
|
|
1661
|
+
if (!isPinned(item)) slots.push(index);
|
|
1662
|
+
});
|
|
1663
|
+
return slots;
|
|
1664
|
+
}
|
|
1665
|
+
function moveWidgetBy(definitions, layout, key, offset) {
|
|
1666
|
+
const current = visibleWidgets(definitions, layout);
|
|
1667
|
+
const fromIndex = current.findIndex((d) => d.key === key);
|
|
1668
|
+
if (fromIndex === -1) return layout;
|
|
1669
|
+
const freeSlots = freeSlotIndexes(current);
|
|
1670
|
+
const fromFree = freeSlots.indexOf(fromIndex);
|
|
1671
|
+
if (fromFree === -1) return layout;
|
|
1672
|
+
const toFree = Math.max(
|
|
1673
|
+
0,
|
|
1674
|
+
Math.min(freeSlots.length - 1, fromFree + Math.trunc(offset))
|
|
1675
|
+
);
|
|
1676
|
+
return moveWidget(definitions, layout, key, freeSlots[toFree]);
|
|
1677
|
+
}
|
|
1678
|
+
function moveWidgetUp(definitions, layout, key) {
|
|
1679
|
+
return moveWidgetBy(definitions, layout, key, -1);
|
|
1128
1680
|
}
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
const options = definition.options;
|
|
1132
|
-
if (options === void 0 || options.length === 0) return NO_VALUES;
|
|
1133
|
-
const values = {};
|
|
1134
|
-
for (const option of options) {
|
|
1135
|
-
const picked = chosen?.[option.key];
|
|
1136
|
-
const value = (picked === void 0 ? void 0 : coerceOptionValue(option, picked, context)) ?? defaultOptionValue(option, context);
|
|
1137
|
-
if (value !== void 0) values[option.key] = value;
|
|
1138
|
-
}
|
|
1139
|
-
return values;
|
|
1681
|
+
function moveWidgetDown(definitions, layout, key) {
|
|
1682
|
+
return moveWidgetBy(definitions, layout, key, 1);
|
|
1140
1683
|
}
|
|
1141
|
-
function
|
|
1142
|
-
|
|
1143
|
-
return a.length === b.length && a.every((item, i) => item === b[i]);
|
|
1144
|
-
}
|
|
1145
|
-
return a === b;
|
|
1684
|
+
function isHidden(layout, key) {
|
|
1685
|
+
return layout.hidden.includes(key);
|
|
1146
1686
|
}
|
|
1147
|
-
function
|
|
1148
|
-
|
|
1149
|
-
return keys.every((key) => sameValue(a[key], b[key]));
|
|
1687
|
+
function isMinimized(layout, key) {
|
|
1688
|
+
return layout.minimized.includes(key);
|
|
1150
1689
|
}
|
|
1151
|
-
function
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
if (isClientApplied(option)) continue;
|
|
1155
|
-
const value = values[option.key];
|
|
1156
|
-
if (sameValue(value, defaultOptionValue(option, context))) continue;
|
|
1157
|
-
parts.push(
|
|
1158
|
-
`${option.key}=${encodeURIComponent(JSON.stringify(value ?? null))}`
|
|
1159
|
-
);
|
|
1160
|
-
}
|
|
1161
|
-
parts.sort();
|
|
1162
|
-
return parts.length === 0 ? "" : `?${parts.join("&")}`;
|
|
1690
|
+
function hideWidget(layout, key) {
|
|
1691
|
+
if (isHidden(layout, key)) return layout;
|
|
1692
|
+
return { ...layout, hidden: [...layout.hidden, key] };
|
|
1163
1693
|
}
|
|
1164
|
-
function
|
|
1165
|
-
|
|
1166
|
-
return
|
|
1694
|
+
function showWidget(layout, key) {
|
|
1695
|
+
if (!isHidden(layout, key)) return layout;
|
|
1696
|
+
return {
|
|
1697
|
+
...layout,
|
|
1698
|
+
hidden: layout.hidden.filter((k) => k !== key),
|
|
1699
|
+
minimized: layout.minimized.filter((k) => k !== key)
|
|
1700
|
+
};
|
|
1167
1701
|
}
|
|
1168
|
-
function
|
|
1169
|
-
|
|
1170
|
-
return items.map((item, index) => ({ item, index })).sort((a, b) => {
|
|
1171
|
-
const order = sort.column === "value" ? a.item.value - b.item.value : a.item.label.localeCompare(b.item.label);
|
|
1172
|
-
return order * sign || a.index - b.index;
|
|
1173
|
-
}).map(({ item }) => item);
|
|
1702
|
+
function toggleHidden(layout, key) {
|
|
1703
|
+
return isHidden(layout, key) ? showWidget(layout, key) : hideWidget(layout, key);
|
|
1174
1704
|
}
|
|
1175
|
-
function
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1705
|
+
function minimizeWidget(layout, key) {
|
|
1706
|
+
if (isMinimized(layout, key)) return layout;
|
|
1707
|
+
return { ...layout, minimized: [...layout.minimized, key] };
|
|
1708
|
+
}
|
|
1709
|
+
function restoreWidget(layout, key) {
|
|
1710
|
+
if (!isMinimized(layout, key)) return layout;
|
|
1711
|
+
return { ...layout, minimized: layout.minimized.filter((k) => k !== key) };
|
|
1712
|
+
}
|
|
1713
|
+
function toggleMinimized(layout, key) {
|
|
1714
|
+
return isMinimized(layout, key) ? restoreWidget(layout, key) : minimizeWidget(layout, key);
|
|
1715
|
+
}
|
|
1716
|
+
function pruneLayout(definitions, layout) {
|
|
1717
|
+
const known = new Set(definitions.map((d) => d.key));
|
|
1718
|
+
const keep = (keys) => keys.every((k) => known.has(k)) ? keys : keys.filter((k) => known.has(k));
|
|
1719
|
+
return mapLayoutLists(layout, (lists) => ({
|
|
1720
|
+
order: keep(lists.order),
|
|
1721
|
+
hidden: keep(lists.hidden),
|
|
1722
|
+
minimized: keep(lists.minimized)
|
|
1723
|
+
}));
|
|
1724
|
+
}
|
|
1725
|
+
function mapLayoutLists(layout, change) {
|
|
1726
|
+
const top = change(layout);
|
|
1727
|
+
const pages = layout.pages?.map((page) => {
|
|
1728
|
+
const next = change(page);
|
|
1729
|
+
return next.order === page.order && next.hidden === page.hidden && next.minimized === page.minimized ? page : { ...page, ...next };
|
|
1730
|
+
});
|
|
1731
|
+
const pagesChanged = pages !== void 0 && pages.some((page, i) => page !== layout.pages?.[i]);
|
|
1732
|
+
if (top.order === layout.order && top.hidden === layout.hidden && top.minimized === layout.minimized && !pagesChanged) {
|
|
1733
|
+
return layout;
|
|
1203
1734
|
}
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1735
|
+
return {
|
|
1736
|
+
...layout,
|
|
1737
|
+
...top,
|
|
1738
|
+
...pages === void 0 ? {} : { pages }
|
|
1739
|
+
};
|
|
1740
|
+
}
|
|
1741
|
+
function enforceLocks(definitions, layout, options = {}) {
|
|
1742
|
+
if (options.overrideLocks === true) return layout;
|
|
1743
|
+
const noMove = /* @__PURE__ */ new Set();
|
|
1744
|
+
const noHide = /* @__PURE__ */ new Set();
|
|
1745
|
+
const noMinimize = /* @__PURE__ */ new Set();
|
|
1746
|
+
for (const definition of definitions) {
|
|
1747
|
+
const lock = resolveWidgetLock(definition);
|
|
1748
|
+
if (lock.move) noMove.add(definition.key);
|
|
1749
|
+
if (lock.hide) noHide.add(definition.key);
|
|
1750
|
+
if (lock.minimize) noMinimize.add(definition.key);
|
|
1216
1751
|
}
|
|
1217
|
-
|
|
1752
|
+
const without2 = (keys, drop) => keys.some((key) => drop.has(key)) ? keys.filter((key) => !drop.has(key)) : keys;
|
|
1753
|
+
return mapLayoutLists(layout, (lists) => ({
|
|
1754
|
+
order: without2(lists.order, noMove),
|
|
1755
|
+
hidden: without2(lists.hidden, noHide),
|
|
1756
|
+
minimized: without2(lists.minimized, noMinimize)
|
|
1757
|
+
}));
|
|
1218
1758
|
}
|
|
1219
1759
|
|
|
1220
1760
|
// src/core/validate.ts
|
|
@@ -1227,7 +1767,7 @@ function describeType2(value) {
|
|
|
1227
1767
|
}
|
|
1228
1768
|
return typeof value;
|
|
1229
1769
|
}
|
|
1230
|
-
function
|
|
1770
|
+
function isRecord2(value) {
|
|
1231
1771
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1232
1772
|
}
|
|
1233
1773
|
function join(path, field) {
|
|
@@ -1309,7 +1849,7 @@ function requireOneOf(record, field, options, path, problems) {
|
|
|
1309
1849
|
function eachRecord(items, path, problems, check) {
|
|
1310
1850
|
items.forEach((item, index) => {
|
|
1311
1851
|
const itemPath = `${path}[${index}]`;
|
|
1312
|
-
if (
|
|
1852
|
+
if (isRecord2(item)) {
|
|
1313
1853
|
check(item, itemPath);
|
|
1314
1854
|
} else {
|
|
1315
1855
|
problems.push(
|
|
@@ -1458,7 +1998,7 @@ function checkPayloadFields(kind, data, problems) {
|
|
|
1458
1998
|
}
|
|
1459
1999
|
function checkDetailOption(detail, problems) {
|
|
1460
2000
|
if (detail === void 0 || typeof detail === "boolean") return;
|
|
1461
|
-
if (!
|
|
2001
|
+
if (!isRecord2(detail)) {
|
|
1462
2002
|
problems.push(
|
|
1463
2003
|
`detail must be true, false or an options object, got ${describeType2(detail)}.`
|
|
1464
2004
|
);
|
|
@@ -1477,13 +2017,13 @@ function checkDetailOption(detail, problems) {
|
|
|
1477
2017
|
}
|
|
1478
2018
|
function checkTableControlsOption(controls, kind, problems) {
|
|
1479
2019
|
if (controls === void 0 || controls === false) return;
|
|
1480
|
-
if (typeof controls !== "boolean" && !
|
|
2020
|
+
if (typeof controls !== "boolean" && !isRecord2(controls)) {
|
|
1481
2021
|
problems.push(
|
|
1482
2022
|
`tableControls must be true, false or an options object, got ${describeType2(controls)}.`
|
|
1483
2023
|
);
|
|
1484
2024
|
return;
|
|
1485
2025
|
}
|
|
1486
|
-
if (
|
|
2026
|
+
if (isRecord2(controls)) {
|
|
1487
2027
|
optionalBoolean(controls, "search", "tableControls", problems);
|
|
1488
2028
|
optionalBoolean(controls, "sort", "tableControls", problems);
|
|
1489
2029
|
}
|
|
@@ -1493,9 +2033,39 @@ function checkTableControlsOption(controls, kind, problems) {
|
|
|
1493
2033
|
);
|
|
1494
2034
|
}
|
|
1495
2035
|
}
|
|
2036
|
+
function checkWidthLimits(value, problems) {
|
|
2037
|
+
for (const field of ["minWidth", "maxWidth"]) {
|
|
2038
|
+
const limit = value[field];
|
|
2039
|
+
if (limit !== void 0 && !isWidgetWidth(limit)) {
|
|
2040
|
+
problems.push(
|
|
2041
|
+
`${field} must be an integer from ${MIN_WIDGET_WIDTH} to ${MAX_WIDGET_WIDTH} (twelfths of the row), got ${typeof limit === "number" ? String(limit) : describeType2(limit)}.`
|
|
2042
|
+
);
|
|
2043
|
+
return;
|
|
2044
|
+
}
|
|
2045
|
+
}
|
|
2046
|
+
const { minWidth, maxWidth, width } = value;
|
|
2047
|
+
if (isWidgetWidth(minWidth) && isWidgetWidth(maxWidth) && minWidth > maxWidth) {
|
|
2048
|
+
problems.push(
|
|
2049
|
+
`minWidth (${minWidth}) must not be more than maxWidth (${maxWidth}).`
|
|
2050
|
+
);
|
|
2051
|
+
return;
|
|
2052
|
+
}
|
|
2053
|
+
if (isWidgetWidth(width)) {
|
|
2054
|
+
if (isWidgetWidth(minWidth) && width < minWidth) {
|
|
2055
|
+
problems.push(
|
|
2056
|
+
`width (${width}) must not be less than minWidth (${minWidth}).`
|
|
2057
|
+
);
|
|
2058
|
+
}
|
|
2059
|
+
if (isWidgetWidth(maxWidth) && width > maxWidth) {
|
|
2060
|
+
problems.push(
|
|
2061
|
+
`width (${width}) must not be more than maxWidth (${maxWidth}).`
|
|
2062
|
+
);
|
|
2063
|
+
}
|
|
2064
|
+
}
|
|
2065
|
+
}
|
|
1496
2066
|
function checkLockedOption(locked, problems) {
|
|
1497
2067
|
if (locked === void 0 || typeof locked === "boolean") return;
|
|
1498
|
-
if (!
|
|
2068
|
+
if (!isRecord2(locked)) {
|
|
1499
2069
|
problems.push(
|
|
1500
2070
|
`locked must be true, false or an object, got ${describeType2(locked)}.`
|
|
1501
2071
|
);
|
|
@@ -1504,6 +2074,7 @@ function checkLockedOption(locked, problems) {
|
|
|
1504
2074
|
optionalBoolean(locked, "move", "locked", problems);
|
|
1505
2075
|
optionalBoolean(locked, "hide", "locked", problems);
|
|
1506
2076
|
optionalBoolean(locked, "minimize", "locked", problems);
|
|
2077
|
+
optionalBoolean(locked, "options", "locked", problems);
|
|
1507
2078
|
}
|
|
1508
2079
|
function checkOptionColumns(option, path, kind, problems) {
|
|
1509
2080
|
const columns = option["columns"];
|
|
@@ -1516,7 +2087,7 @@ function checkOptionColumns(option, path, kind, problems) {
|
|
|
1516
2087
|
const keys = [];
|
|
1517
2088
|
columns.forEach((entry, index) => {
|
|
1518
2089
|
const entryPath = `${path}.columns[${index}]`;
|
|
1519
|
-
if (!
|
|
2090
|
+
if (!isRecord2(entry)) {
|
|
1520
2091
|
problems.push(
|
|
1521
2092
|
`${entryPath} must be an object, got ${describeType2(entry)}.`
|
|
1522
2093
|
);
|
|
@@ -1541,7 +2112,7 @@ function checkOptionColumns(option, path, kind, problems) {
|
|
|
1541
2112
|
return keys;
|
|
1542
2113
|
}
|
|
1543
2114
|
function checkOption(option, path, kind, seenKeys, seenTypes, problems) {
|
|
1544
|
-
if (!
|
|
2115
|
+
if (!isRecord2(option)) {
|
|
1545
2116
|
problems.push(`${path} must be an object, got ${describeType2(option)}.`);
|
|
1546
2117
|
return;
|
|
1547
2118
|
}
|
|
@@ -1573,7 +2144,7 @@ function checkOption(option, path, kind, seenKeys, seenTypes, problems) {
|
|
|
1573
2144
|
} else {
|
|
1574
2145
|
choices.forEach((choice, index) => {
|
|
1575
2146
|
const choicePath = `${path}.choices[${index}]`;
|
|
1576
|
-
if (!
|
|
2147
|
+
if (!isRecord2(choice)) {
|
|
1577
2148
|
problems.push(
|
|
1578
2149
|
`${choicePath} must be an object, got ${describeType2(choice)}.`
|
|
1579
2150
|
);
|
|
@@ -1663,7 +2234,7 @@ function checkOption(option, path, kind, seenKeys, seenTypes, problems) {
|
|
|
1663
2234
|
} else {
|
|
1664
2235
|
presets.forEach((preset, index) => {
|
|
1665
2236
|
const presetPath = `${path}.presets[${index}]`;
|
|
1666
|
-
if (!
|
|
2237
|
+
if (!isRecord2(preset)) {
|
|
1667
2238
|
problems.push(
|
|
1668
2239
|
`${presetPath} must be an object, got ${describeType2(preset)}.`
|
|
1669
2240
|
);
|
|
@@ -1783,6 +2354,137 @@ function checkOptions(options, kind, problems) {
|
|
|
1783
2354
|
);
|
|
1784
2355
|
});
|
|
1785
2356
|
}
|
|
2357
|
+
var MAX_VIEW_COLUMN = 1e3;
|
|
2358
|
+
function checkColumnIndex(value, path, problems) {
|
|
2359
|
+
if (typeof value !== "number" || !Number.isInteger(value) || value < 0 || value > MAX_VIEW_COLUMN) {
|
|
2360
|
+
problems.push(
|
|
2361
|
+
`${path} must be a column index (a whole number from 0), got ${typeof value === "number" ? String(value) : describeType2(value)}.`
|
|
2362
|
+
);
|
|
2363
|
+
}
|
|
2364
|
+
}
|
|
2365
|
+
function checkConversion(conversion, path, baseKind, viewKind2, problems) {
|
|
2366
|
+
if (!isRecord2(conversion)) {
|
|
2367
|
+
problems.push(
|
|
2368
|
+
`${path} must be an object with a type, got ${describeType2(conversion)}.`
|
|
2369
|
+
);
|
|
2370
|
+
return;
|
|
2371
|
+
}
|
|
2372
|
+
const type = conversion["type"];
|
|
2373
|
+
const known = typeof type === "string" && Object.hasOwn(VIEW_CONVERSIONS, type) ? VIEW_CONVERSIONS[type] : void 0;
|
|
2374
|
+
if (known === void 0) {
|
|
2375
|
+
problems.push(
|
|
2376
|
+
`${path}.type must be one of ${Object.keys(VIEW_CONVERSIONS).map((name) => `"${name}"`).join(", ")}, got ${describeType2(type)}.`
|
|
2377
|
+
);
|
|
2378
|
+
return;
|
|
2379
|
+
}
|
|
2380
|
+
if (baseKind !== known.from) {
|
|
2381
|
+
problems.push(
|
|
2382
|
+
`${path}.type "${String(type)}" reads a ${known.from} widget, but this one is ${String(baseKind)}.`
|
|
2383
|
+
);
|
|
2384
|
+
}
|
|
2385
|
+
if (viewKind2 !== known.to) {
|
|
2386
|
+
problems.push(
|
|
2387
|
+
`${path}.type "${String(type)}" produces ${known.to}, but the view's kind is ${String(viewKind2)}.`
|
|
2388
|
+
);
|
|
2389
|
+
}
|
|
2390
|
+
switch (type) {
|
|
2391
|
+
case "tableToBarList":
|
|
2392
|
+
checkColumnIndex(conversion["label"], `${path}.label`, problems);
|
|
2393
|
+
checkColumnIndex(conversion["value"], `${path}.value`, problems);
|
|
2394
|
+
break;
|
|
2395
|
+
case "tableToGraph": {
|
|
2396
|
+
checkColumnIndex(conversion["label"], `${path}.label`, problems);
|
|
2397
|
+
const values = conversion["values"];
|
|
2398
|
+
if (!Array.isArray(values) || values.length === 0) {
|
|
2399
|
+
problems.push(`${path}.values must list 1 or more column indexes.`);
|
|
2400
|
+
} else if (values.length > MAX_GRAPH_SERIES) {
|
|
2401
|
+
problems.push(
|
|
2402
|
+
`${path}.values lists ${values.length} series; a chart carries at most ${MAX_GRAPH_SERIES}.`
|
|
2403
|
+
);
|
|
2404
|
+
} else {
|
|
2405
|
+
values.forEach(
|
|
2406
|
+
(index, at) => checkColumnIndex(index, `${path}.values[${at}]`, problems)
|
|
2407
|
+
);
|
|
2408
|
+
}
|
|
2409
|
+
if (conversion["chartType"] !== "bar" && conversion["chartType"] !== "line") {
|
|
2410
|
+
problems.push(`${path}.chartType must be "bar" or "line".`);
|
|
2411
|
+
}
|
|
2412
|
+
break;
|
|
2413
|
+
}
|
|
2414
|
+
case "barListToGraph":
|
|
2415
|
+
if (conversion["chartType"] !== "bar" && conversion["chartType"] !== "line") {
|
|
2416
|
+
problems.push(`${path}.chartType must be "bar" or "line".`);
|
|
2417
|
+
}
|
|
2418
|
+
break;
|
|
2419
|
+
}
|
|
2420
|
+
if (conversion["valueFormat"] !== void 0 && !VALUE_FORMATS.includes(conversion["valueFormat"])) {
|
|
2421
|
+
problems.push(
|
|
2422
|
+
`${path}.valueFormat must be one of ${VALUE_FORMATS.map((f) => `"${f}"`).join(", ")}.`
|
|
2423
|
+
);
|
|
2424
|
+
}
|
|
2425
|
+
}
|
|
2426
|
+
function checkViews(value, problems) {
|
|
2427
|
+
const views = value["views"];
|
|
2428
|
+
const defaultView = value["defaultView"];
|
|
2429
|
+
optionalString(value, "baseViewLabel", "", problems);
|
|
2430
|
+
if (value["baseViewLabel"] === "") {
|
|
2431
|
+
problems.push("baseViewLabel must not be empty.");
|
|
2432
|
+
}
|
|
2433
|
+
const declared = /* @__PURE__ */ new Set([BASE_VIEW_KEY]);
|
|
2434
|
+
if (views !== void 0) {
|
|
2435
|
+
if (!Array.isArray(views)) {
|
|
2436
|
+
problems.push(`views must be an array, got ${describeType2(views)}.`);
|
|
2437
|
+
} else if (views.length > MAX_WIDGET_VIEWS) {
|
|
2438
|
+
problems.push(
|
|
2439
|
+
`views lists ${views.length} views; the most a widget may declare is ${MAX_WIDGET_VIEWS}.`
|
|
2440
|
+
);
|
|
2441
|
+
} else {
|
|
2442
|
+
views.forEach((view, index) => {
|
|
2443
|
+
const path = `views[${index}]`;
|
|
2444
|
+
if (!isRecord2(view)) {
|
|
2445
|
+
problems.push(
|
|
2446
|
+
`${path} must be an object, got ${describeType2(view)}.`
|
|
2447
|
+
);
|
|
2448
|
+
return;
|
|
2449
|
+
}
|
|
2450
|
+
const key = view["key"];
|
|
2451
|
+
if (typeof key !== "string" || key.trim() === "") {
|
|
2452
|
+
problems.push(`${path}.key must be a non-empty string.`);
|
|
2453
|
+
} else if (declared.has(key)) {
|
|
2454
|
+
problems.push(
|
|
2455
|
+
key === BASE_VIEW_KEY ? `${path}.key "${BASE_VIEW_KEY}" is reserved for the widget's own kind.` : `${path}.key "${key}" is used twice.`
|
|
2456
|
+
);
|
|
2457
|
+
} else {
|
|
2458
|
+
declared.add(key);
|
|
2459
|
+
}
|
|
2460
|
+
if (typeof view["label"] !== "string" || view["label"].trim() === "") {
|
|
2461
|
+
problems.push(`${path}.label must be a non-empty string.`);
|
|
2462
|
+
}
|
|
2463
|
+
requireOneOf(view, "kind", WIDGET_KINDS, path, problems);
|
|
2464
|
+
if (view["convert"] === void 0) {
|
|
2465
|
+
problems.push(
|
|
2466
|
+
`${path}.convert is required: views supplied by a provider are not supported yet.`
|
|
2467
|
+
);
|
|
2468
|
+
} else {
|
|
2469
|
+
checkConversion(
|
|
2470
|
+
view["convert"],
|
|
2471
|
+
`${path}.convert`,
|
|
2472
|
+
value["kind"],
|
|
2473
|
+
view["kind"],
|
|
2474
|
+
problems
|
|
2475
|
+
);
|
|
2476
|
+
}
|
|
2477
|
+
});
|
|
2478
|
+
}
|
|
2479
|
+
}
|
|
2480
|
+
if (defaultView !== void 0) {
|
|
2481
|
+
if (typeof defaultView !== "string" || !declared.has(defaultView)) {
|
|
2482
|
+
problems.push(
|
|
2483
|
+
`defaultView must be "${BASE_VIEW_KEY}" or the key of a declared view, got ${typeof defaultView === "string" ? JSON.stringify(defaultView) : describeType2(defaultView)}.`
|
|
2484
|
+
);
|
|
2485
|
+
}
|
|
2486
|
+
}
|
|
2487
|
+
}
|
|
1786
2488
|
function formatProblems(prefix, problems) {
|
|
1787
2489
|
const shown = problems.slice(0, MAX_REPORTED_PROBLEMS);
|
|
1788
2490
|
const more = problems.length - shown.length;
|
|
@@ -1790,7 +2492,7 @@ function formatProblems(prefix, problems) {
|
|
|
1790
2492
|
}
|
|
1791
2493
|
function validateWidgetData(value, options = {}) {
|
|
1792
2494
|
const subject = options.widgetKey === void 0 ? "Widget data" : `Widget ${JSON.stringify(options.widgetKey)}`;
|
|
1793
|
-
if (!
|
|
2495
|
+
if (!isRecord2(value)) {
|
|
1794
2496
|
return err(`${subject}: must be an object, got ${describeType2(value)}.`);
|
|
1795
2497
|
}
|
|
1796
2498
|
if (value["empty"] === true) {
|
|
@@ -1820,7 +2522,7 @@ function validateWidgetData(value, options = {}) {
|
|
|
1820
2522
|
return ok(value);
|
|
1821
2523
|
}
|
|
1822
2524
|
function validateWidgetDefinition(value) {
|
|
1823
|
-
if (!
|
|
2525
|
+
if (!isRecord2(value)) {
|
|
1824
2526
|
return err(
|
|
1825
2527
|
`Widget definition: must be an object, got ${describeType2(value)}.`
|
|
1826
2528
|
);
|
|
@@ -1854,10 +2556,12 @@ function validateWidgetDefinition(value) {
|
|
|
1854
2556
|
`width must be an integer from ${MIN_WIDGET_WIDTH} to ${MAX_WIDGET_WIDTH} (twelfths of the row), got ${typeof value["width"] === "number" ? String(value["width"]) : describeType2(value["width"])}.`
|
|
1855
2557
|
);
|
|
1856
2558
|
}
|
|
2559
|
+
checkWidthLimits(value, problems);
|
|
1857
2560
|
checkDetailOption(value["detail"], problems);
|
|
1858
2561
|
checkTableControlsOption(value["tableControls"], value["kind"], problems);
|
|
1859
2562
|
checkLockedOption(value["locked"], problems);
|
|
1860
2563
|
checkOptions(value["options"], value["kind"], problems);
|
|
2564
|
+
checkViews(value, problems);
|
|
1861
2565
|
if (value["page"] !== void 0) {
|
|
1862
2566
|
if (typeof value["page"] !== "string" || value["page"].trim() === "") {
|
|
1863
2567
|
problems.push(
|
|
@@ -2515,7 +3219,7 @@ function withoutLockField(definition) {
|
|
|
2515
3219
|
delete copy.locked;
|
|
2516
3220
|
return copy;
|
|
2517
3221
|
}
|
|
2518
|
-
function
|
|
3222
|
+
function uniqueTitle2(taken, title, index) {
|
|
2519
3223
|
let base = title.trim().slice(0, MAX_PAGE_TITLE_LENGTH);
|
|
2520
3224
|
if (base === "") base = `Page ${index + 1}`;
|
|
2521
3225
|
let candidate = base;
|
|
@@ -2536,9 +3240,18 @@ function samePages(a, b) {
|
|
|
2536
3240
|
}
|
|
2537
3241
|
function normalizeLayout(definitions, layout, options = {}) {
|
|
2538
3242
|
const known = pruneLayout(definitions, layout);
|
|
2539
|
-
const
|
|
3243
|
+
const enforced = enforceLocks(definitions, known, options);
|
|
3244
|
+
const locked = normalizeSettings(
|
|
3245
|
+
definitions,
|
|
3246
|
+
enforced,
|
|
3247
|
+
options
|
|
3248
|
+
);
|
|
2540
3249
|
if (!hasPages(locked)) return locked === layout ? layout : locked;
|
|
2541
|
-
const defs =
|
|
3250
|
+
const defs = effectiveDefinitions(
|
|
3251
|
+
options.overrideLocks === true ? definitions.map(withoutLockField) : definitions,
|
|
3252
|
+
locked,
|
|
3253
|
+
options
|
|
3254
|
+
);
|
|
2542
3255
|
const taken = /* @__PURE__ */ new Set();
|
|
2543
3256
|
const seenKeys = /* @__PURE__ */ new Set();
|
|
2544
3257
|
const held = /* @__PURE__ */ new Set();
|
|
@@ -2551,7 +3264,7 @@ function normalizeLayout(definitions, layout, options = {}) {
|
|
|
2551
3264
|
];
|
|
2552
3265
|
const next = {
|
|
2553
3266
|
...page,
|
|
2554
|
-
title:
|
|
3267
|
+
title: uniqueTitle2(taken, page.title, index),
|
|
2555
3268
|
order: keep(page.order),
|
|
2556
3269
|
hidden: keep(page.hidden),
|
|
2557
3270
|
minimized: keep(page.minimized)
|
|
@@ -2639,7 +3352,7 @@ function normalizeLayout(definitions, layout, options = {}) {
|
|
|
2639
3352
|
}
|
|
2640
3353
|
if (!placed) {
|
|
2641
3354
|
const key = nextPageKey(work());
|
|
2642
|
-
const title =
|
|
3355
|
+
const title = uniqueTitle2(
|
|
2643
3356
|
new Set(pages.map((p) => normalizedTitle(p.title))),
|
|
2644
3357
|
`Page ${pages.length + 1}`,
|
|
2645
3358
|
pages.length
|
|
@@ -2651,7 +3364,7 @@ function normalizeLayout(definitions, layout, options = {}) {
|
|
|
2651
3364
|
}
|
|
2652
3365
|
}
|
|
2653
3366
|
const result = work();
|
|
2654
|
-
return samePages(layout.pages ?? [], pages) && sameKeys(layout.order, result.order) ? layout : result;
|
|
3367
|
+
return samePages(layout.pages ?? [], pages) && sameKeys(layout.order, result.order) && locked.settings === layout.settings ? layout : result;
|
|
2655
3368
|
}
|
|
2656
3369
|
|
|
2657
3370
|
// src/core/scale.ts
|
|
@@ -3483,6 +4196,6 @@ function indent(block) {
|
|
|
3483
4196
|
return block.split("\n").map((line) => ` ${line}`).join("\n");
|
|
3484
4197
|
}
|
|
3485
4198
|
|
|
3486
|
-
export { DATE_RANGE_PRESETS, DEFAULT_COMPARISON_LABEL, DEFAULT_CURRENCY, DEFAULT_DETAIL_PAGE_SIZE, DEFAULT_EMPTY_TEXT, DEFAULT_MAX_LAYOUT_BYTES, DEFAULT_PAGE_KEY, DEFAULT_PAGE_ROWS, DETAIL_MODES, EMPTY_LAYOUT, LAYOUT_ENVELOPE_VERSION, MAX_DETAIL_PAGE_SIZE, MAX_GRAPH_SERIES, MAX_PAGE_ROWS, MAX_PAGE_TITLE_LENGTH, MAX_PARSED_PAGES, MAX_REPORTED_PROBLEMS, MAX_TEXT_OPTION_LENGTH, MAX_WIDGET_OPTIONS, MAX_WIDGET_WIDTH, MIN_WIDGET_WIDTH, OPTION_KEY_PATTERN, THEME_TOKEN_VARIABLES, VALUE_FORMATS, WIDGET_FILLS, WIDGET_KINDS, WIDGET_OPTION_TYPES, WIDGET_SIZES, WIDTH_COLUMNS, addPage, applyClientOptions, assignPages, baseColumnSpan, cacheKeyFor, coerceOptionValue, createLayoutPersistence, createTheme, createWidgetLoader, defaultDetailQuery, defaultOptionValue, defineWidget, deriveDetailData, describeUnknownError, emptyTextFor, emptyWidget, enforceLocks, err, failedWidget, fillColumnSpans, fillWidthSpans, fillsHeight, fillsWidth, finalizeWidget, fitCount, formatCount, formatPercentChange, formatValue, fromLegacyDefinition, hasPages, hiddenWidgets, hideWidget, isClientApplied, isColumnKeyFor, isHidden, isIsoInterval, isMinimized, isSafeHref, isSafeImageUrl, isWidgetEmptyState, isWidgetKind, isWidgetVisibleTo, isWidgetWidth, itemWidth, kpiDelta, labelStride, loadingWidgets, memoryAdapter, minimizeWidget, movePage, moveWidget, moveWidgetBy, moveWidgetDown, moveWidgetToPage, moveWidgetUp, nextPageKey, niceDomain, niceStep, normalizeLayout, ok, optionValuesFor, optionsCacheSuffix, pageLayout, pageList, pageOf, pageRoom, pageWidgets, parseDetailQuery, parseLayout, parseSortValue, percentChange, placeRows, pruneLayout, queryRows, readOnly, removePage, renamePage, resolveDateRange, resolveDetailOptions, resolveOptionValues, resolvePageKey, resolvePayload, resolveTableControls, resolveWidget, resolveWidgetLock, resolveWidgetUnapplied, resolveWidgets, restoreWidget, sameOptionValues, serializeDetailQuery, serializeLayout, shareOf, showWidget, sortDefinitions, sortFromOptions, tableDetailData, toggleHidden, toggleMinimized, upgradeLegacyWidgetData, usesWidthColumns, utf8Length, validateDetailData, validateWidgetData, validateWidgetDefinition, visibleWidgets, widgetsFor, widthForSize, withEncoding, withFallback, withLogging, withPageLayout, withPrefix, withReadCache, withRetry };
|
|
4199
|
+
export { BASE_VIEW_KEY, DATE_RANGE_PRESETS, DEFAULT_COMPARISON_LABEL, DEFAULT_CURRENCY, DEFAULT_DETAIL_PAGE_SIZE, DEFAULT_EMPTY_TEXT, DEFAULT_MAX_LAYOUT_BYTES, DEFAULT_PAGE_KEY, DEFAULT_PAGE_ROWS, DETAIL_MODES, EMPTY_LAYOUT, LAYOUT_ENVELOPE_VERSION, MAX_DETAIL_PAGE_SIZE, MAX_GRAPH_SERIES, MAX_PAGE_ROWS, MAX_PAGE_TITLE_LENGTH, MAX_PARSED_PAGES, MAX_PARSED_SETTINGS, MAX_REPORTED_PROBLEMS, MAX_TEXT_OPTION_LENGTH, MAX_WIDGET_OPTIONS, MAX_WIDGET_TITLE_LENGTH, MAX_WIDGET_VIEWS, MAX_WIDGET_WIDTH, MIN_WIDGET_WIDTH, OPTION_KEY_PATTERN, THEME_TOKEN_VARIABLES, VALUE_FORMATS, VIEW_CONVERSIONS, WIDGET_FILLS, WIDGET_KINDS, WIDGET_OPTION_TYPES, WIDGET_SIZES, WIDTH_COLUMNS, addPage, applyClientOptions, applySettings, applyView, assignPages, baseColumnSpan, cacheKeyFor, clearWidgetSettings, coerceOptionValue, convertView, createLayoutPersistence, createTheme, createWidgetLoader, defaultDetailQuery, defaultOptionValue, defineWidget, deriveDetailData, describeUnknownError, effectiveDefinitions, effectiveViewKey, emptyTextFor, emptyWidget, enforceLocks, err, failedWidget, fillColumnSpans, fillWidthSpans, fillsHeight, fillsWidth, finalizeWidget, findView, fitCount, formatCount, formatPercentChange, formatValue, fromLegacyDefinition, hasPages, hasViews, hiddenWidgets, hideWidget, isClientApplied, isColumnKeyFor, isFlexible, isHidden, isIsoInterval, isMinimized, isOptionsLocked, isSafeHref, isSafeImageUrl, isTitleInUse, isWidgetEmptyState, isWidgetKind, isWidgetVisibleTo, isWidgetWidth, itemWidth, kindLabel, kpiDelta, labelStride, loadingWidgets, memoryAdapter, minimizeWidget, movePage, moveWidget, moveWidgetBy, moveWidgetDown, moveWidgetToPage, moveWidgetUp, nextPageKey, niceDomain, niceStep, normalizeLayout, normalizeSettings, normalizeTitle, ok, optionValuesFor, optionValuesFromLayout, optionsCacheSuffix, pageLayout, pageList, pageOf, pageRoom, pageWidgets, parseDetailQuery, parseLayout, parseSettings, parseSortValue, percentChange, placeRows, pruneLayout, queryRows, readOnly, removePage, renamePage, resolveDateRange, resolveDetailOptions, resolveOptionValues, resolvePageKey, resolvePayload, resolveTableControls, resolveWidget, resolveWidgetLock, resolveWidgetUnapplied, resolveWidgets, restoreWidget, sameOptionValues, serializeDetailQuery, serializeLayout, serializeSettings, setWidgetSettings, shareOf, showWidget, sortDefinitions, sortFromOptions, tableDetailData, toggleHidden, toggleMinimized, upgradeLegacyWidgetData, usesWidthColumns, utf8Length, validateDetailData, validateWidgetData, validateWidgetDefinition, viewChoices, viewKind, viewNote, visibleWidgets, widgetOptionValues, widgetsFor, widthForSize, widthRange, widthShareLabel, withEncoding, withFallback, withLogging, withPageLayout, withPrefix, withReadCache, withRetry };
|
|
3487
4200
|
//# sourceMappingURL=core.js.map
|
|
3488
4201
|
//# sourceMappingURL=core.js.map
|