@reportwright/viewer 0.12.0 → 0.13.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/CHANGELOG.md +133 -1
- package/README.md +43 -6
- package/THIRD-PARTY-NOTICES.md +52 -0
- package/dist/{chunk-SBD55ZES.js → chunk-BF7GCWZY.js} +103 -41
- package/dist/chunk-BF7GCWZY.js.map +6 -0
- package/dist/chunk-BR5K6SBL.js +324 -0
- package/dist/chunk-BR5K6SBL.js.map +6 -0
- package/dist/chunk-CNDUJ7IV.js +758 -0
- package/dist/chunk-CNDUJ7IV.js.map +6 -0
- package/dist/{chunk-RYHJUQSV.js → chunk-DXHLIJEY.js} +2 -2
- package/dist/{chunk-M6GENFAH.js → chunk-EK5CJY22.js} +4021 -4631
- package/dist/chunk-EK5CJY22.js.map +6 -0
- package/dist/{chunk-KJTRZJHN.js → chunk-F5EPQTPF.js} +4 -3
- package/dist/chunk-F5EPQTPF.js.map +6 -0
- package/dist/{chunk-SR2TQ2ZK.js → chunk-F6RMRXIN.js} +2 -2
- package/dist/chunk-F6RMRXIN.js.map +6 -0
- package/dist/chunk-FEM2QVOO.js +18 -0
- package/dist/{chunk-ODREGGKA.js → chunk-IFYCJZNS.js} +9 -6
- package/dist/chunk-IFYCJZNS.js.map +6 -0
- package/dist/{chunk-EOVGKHAS.js → chunk-L6YEIVVD.js} +86 -57
- package/dist/chunk-L6YEIVVD.js.map +6 -0
- package/dist/{chunk-APRPSQOD.js → chunk-PQNM6ET7.js} +28 -9
- package/dist/chunk-PQNM6ET7.js.map +6 -0
- package/dist/chunk-QFLVVM3H.js +856 -0
- package/dist/chunk-QFLVVM3H.js.map +6 -0
- package/dist/{chunk-5N6OFCHJ.js → chunk-TZXEEVKE.js} +1319 -76
- package/dist/chunk-TZXEEVKE.js.map +6 -0
- package/dist/{chunk-FARG6X2U.js → chunk-UHHURTSV.js} +15 -9
- package/dist/chunk-UHHURTSV.js.map +6 -0
- package/dist/chunk-UJL7C2AS.js +546 -0
- package/dist/chunk-UJL7C2AS.js.map +6 -0
- package/dist/chunk-YIX3OJXU.js +34 -0
- package/dist/designer.d.ts +19 -4
- package/dist/designer.js +616 -405
- package/dist/designer.js.map +3 -3
- package/dist/{peer/chunk-GBITRNHE.js → engine.worker.js} +11006 -9030
- package/dist/engine.worker.js.map +6 -0
- package/dist/peer/{chunk-NPYKZINU.js → chunk-2CD5COHN.js} +66 -37
- package/dist/peer/chunk-2CD5COHN.js.map +6 -0
- package/dist/peer/{chunk-IPU2YRL2.js → chunk-3CBV5SAI.js} +28 -9
- package/dist/peer/chunk-3CBV5SAI.js.map +6 -0
- package/dist/peer/{chunk-MCJPN2KL.js → chunk-45GVDKP5.js} +15 -9
- package/dist/peer/chunk-45GVDKP5.js.map +6 -0
- package/dist/peer/{chunk-76ZABVTI.js → chunk-LWXQX3NJ.js} +4 -3
- package/dist/peer/chunk-MKY3SDXU.js +758 -0
- package/dist/peer/chunk-MKY3SDXU.js.map +6 -0
- package/dist/peer/chunk-S6LSPHSU.js +17 -0
- package/dist/peer/chunk-S6LSPHSU.js.map +6 -0
- package/dist/peer/{chunk-M4AGFUWE.js → chunk-V42KN7HD.js} +2 -2
- package/dist/peer/{chunk-KBT6ZGGO.js → chunk-VZHHNQYB.js} +1319 -76
- package/dist/peer/chunk-VZHHNQYB.js.map +6 -0
- package/dist/peer/{chunk-Y5CAHLXS.js → chunk-YITWGAR4.js} +9 -6
- package/dist/peer/chunk-YITWGAR4.js.map +6 -0
- package/dist/peer/chunk-Z5II55QT.js +33 -0
- package/dist/peer/chunk-Z5II55QT.js.map +6 -0
- package/dist/peer/designer.js +473 -262
- package/dist/peer/designer.js.map +3 -3
- package/dist/peer/engine.worker.js +16782 -0
- package/dist/peer/engine.worker.js.map +6 -0
- package/dist/peer/viewer.js +17 -7
- package/dist/peer/viewer.js.map +1 -1
- package/dist/viewer.d.ts +11 -2
- package/dist/viewer.js +17 -7
- package/dist/viewer.js.map +1 -1
- package/package.json +4 -2
- package/dist/chunk-3D43XGIN.js +0 -1167
- package/dist/chunk-3D43XGIN.js.map +0 -6
- package/dist/chunk-5N6OFCHJ.js.map +0 -6
- package/dist/chunk-AH47FS6Y.js +0 -13
- package/dist/chunk-APRPSQOD.js.map +0 -6
- package/dist/chunk-EOVGKHAS.js.map +0 -6
- package/dist/chunk-FARG6X2U.js.map +0 -6
- package/dist/chunk-M6GENFAH.js.map +0 -6
- package/dist/chunk-ODREGGKA.js.map +0 -6
- package/dist/chunk-SBD55ZES.js.map +0 -6
- package/dist/chunk-SR2TQ2ZK.js.map +0 -6
- package/dist/peer/chunk-76ZABVTI.js.map +0 -6
- package/dist/peer/chunk-GBITRNHE.js.map +0 -6
- package/dist/peer/chunk-IMQRHDR4.js +0 -12
- package/dist/peer/chunk-IPU2YRL2.js.map +0 -6
- package/dist/peer/chunk-KBT6ZGGO.js.map +0 -6
- package/dist/peer/chunk-MCJPN2KL.js.map +0 -6
- package/dist/peer/chunk-NPYKZINU.js.map +0 -6
- package/dist/peer/chunk-Y5CAHLXS.js.map +0 -6
- /package/dist/{chunk-RYHJUQSV.js.map → chunk-DXHLIJEY.js.map} +0 -0
- /package/dist/{chunk-AH47FS6Y.js.map → chunk-FEM2QVOO.js.map} +0 -0
- /package/dist/{peer/chunk-IMQRHDR4.js.map → chunk-YIX3OJXU.js.map} +0 -0
- /package/dist/{chunk-KJTRZJHN.js.map → peer/chunk-LWXQX3NJ.js.map} +0 -0
- /package/dist/peer/{chunk-M4AGFUWE.js.map → chunk-V42KN7HD.js.map} +0 -0
package/dist/designer.js
CHANGED
|
@@ -13,7 +13,18 @@ import {
|
|
|
13
13
|
setShadowStyles,
|
|
14
14
|
t,
|
|
15
15
|
uiFontCss
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-L6YEIVVD.js";
|
|
17
|
+
import {
|
|
18
|
+
customFonts,
|
|
19
|
+
fontsBase,
|
|
20
|
+
loadFontStore,
|
|
21
|
+
loadModelFonts,
|
|
22
|
+
origin,
|
|
23
|
+
reportFetch,
|
|
24
|
+
setAssetBase,
|
|
25
|
+
setFetchPolicy,
|
|
26
|
+
setStandalone
|
|
27
|
+
} from "./chunk-CNDUJ7IV.js";
|
|
17
28
|
import {
|
|
18
29
|
BASE_STYLE,
|
|
19
30
|
DEFAULT_THEME,
|
|
@@ -22,7 +33,6 @@ import {
|
|
|
22
33
|
ITEMS,
|
|
23
34
|
ODATA_DEFAULT_PAGES,
|
|
24
35
|
ODATA_MAX_PAGES,
|
|
25
|
-
PAGE_SIZES,
|
|
26
36
|
PALETTES,
|
|
27
37
|
TEXT_STYLE_PROPS,
|
|
28
38
|
THEME_COLORS,
|
|
@@ -32,14 +42,10 @@ import {
|
|
|
32
42
|
buildDataSets,
|
|
33
43
|
checkFunctions,
|
|
34
44
|
checkValue,
|
|
35
|
-
customFonts,
|
|
36
45
|
detectFields,
|
|
37
46
|
evalValue,
|
|
38
47
|
findItemNamed,
|
|
39
48
|
finishText,
|
|
40
|
-
fontStore,
|
|
41
|
-
fontsBase,
|
|
42
|
-
fromPt,
|
|
43
49
|
functionTable,
|
|
44
50
|
isDynamic,
|
|
45
51
|
isTablix,
|
|
@@ -47,52 +53,53 @@ import {
|
|
|
47
53
|
jsonPath,
|
|
48
54
|
layoutItems,
|
|
49
55
|
loadBarcodes,
|
|
50
|
-
loadModelFonts,
|
|
51
56
|
loadSources,
|
|
52
|
-
normBox,
|
|
53
57
|
normalizeMatrix,
|
|
54
58
|
odataMetadata,
|
|
55
|
-
origin,
|
|
56
59
|
parseBorder,
|
|
57
60
|
parseXml,
|
|
58
61
|
render,
|
|
59
|
-
reportFetch,
|
|
60
|
-
resolvePage,
|
|
61
62
|
resolveParameters,
|
|
62
|
-
setAssetBase,
|
|
63
|
-
setStandalone,
|
|
64
63
|
shiftItems,
|
|
65
64
|
sourceRows,
|
|
66
65
|
sourceUrl,
|
|
67
66
|
stylePropsFor,
|
|
68
67
|
themeContext,
|
|
69
|
-
toPt,
|
|
70
68
|
toText,
|
|
71
69
|
validate,
|
|
72
70
|
withPartProps,
|
|
73
71
|
xmlRowPaths
|
|
74
|
-
} from "./chunk-
|
|
72
|
+
} from "./chunk-EK5CJY22.js";
|
|
73
|
+
import {
|
|
74
|
+
PAGE_SIZES,
|
|
75
|
+
fromPt,
|
|
76
|
+
normBox,
|
|
77
|
+
resolvePage,
|
|
78
|
+
toPt
|
|
79
|
+
} from "./chunk-BR5K6SBL.js";
|
|
80
|
+
import "./chunk-72S6DETS.js";
|
|
75
81
|
import {
|
|
76
82
|
currencyOf
|
|
77
83
|
} from "./chunk-GJS242RR.js";
|
|
78
|
-
import "./chunk-
|
|
79
|
-
import
|
|
84
|
+
import "./chunk-F6RMRXIN.js";
|
|
85
|
+
import {
|
|
86
|
+
fontFaceCss,
|
|
87
|
+
fontFamilyCss,
|
|
88
|
+
pageToSvg
|
|
89
|
+
} from "./chunk-UJL7C2AS.js";
|
|
80
90
|
import {
|
|
81
91
|
BUNDLED_FAMILIES,
|
|
82
92
|
FONT_FAMILIES,
|
|
83
93
|
allFontKeys,
|
|
84
94
|
fallbackKeys,
|
|
85
|
-
fontFaceCss,
|
|
86
|
-
fontFamilyCss,
|
|
87
|
-
pageToSvg,
|
|
88
95
|
resolveFontKey
|
|
89
|
-
} from "./chunk-
|
|
96
|
+
} from "./chunk-QFLVVM3H.js";
|
|
90
97
|
import {
|
|
91
98
|
__toESM
|
|
92
99
|
} from "./chunk-OLLMACWA.js";
|
|
93
100
|
|
|
94
101
|
// src/embed/designer.js
|
|
95
|
-
var
|
|
102
|
+
var import_react23 = __toESM(require_react(), 1);
|
|
96
103
|
var import_client = __toESM(require_client(), 1);
|
|
97
104
|
|
|
98
105
|
// src/importers/rdlx.js
|
|
@@ -6146,7 +6153,8 @@ function toRdlx3(root, notes, reportName) {
|
|
|
6146
6153
|
const on = prop(b, "aggregateOn") ?? simpleList(b, "aggregateOn")[0]?.text;
|
|
6147
6154
|
const gc = { ...c, group: on && on !== "All" ? on : void 0 };
|
|
6148
6155
|
if (fn3) {
|
|
6149
|
-
const arg = listProp(b, "arguments").map((x) => prop(x, "value")).find((x) => x != null);
|
|
6156
|
+
const arg = listProp(b, "arguments").map((x) => prop(x, "value")).find((x) => x != null) ?? prop(b, "expression");
|
|
6157
|
+
if (arg == null && fn3 !== "count") throw new Untranslatable2(`the aggregate ${fn3.toUpperCase()} with no expression`);
|
|
6150
6158
|
const inner2 = arg != null ? vb2(arg, { ...c, inSet: false }, depth) : "1";
|
|
6151
6159
|
if (prop(b, "filterExpr")) throw new Untranslatable2(`the bound column "${prop(b, "name")}", an aggregate with a filter`);
|
|
6152
6160
|
const all = gc.group ?? c.region;
|
|
@@ -6859,10 +6867,10 @@ function readReportFile(name2, text) {
|
|
|
6859
6867
|
}
|
|
6860
6868
|
|
|
6861
6869
|
// src/designer/Designer.jsx
|
|
6862
|
-
var
|
|
6870
|
+
var import_react22 = __toESM(require_react(), 1);
|
|
6863
6871
|
|
|
6864
6872
|
// src/designer/ui.jsx
|
|
6865
|
-
var
|
|
6873
|
+
var import_react3 = __toESM(require_react(), 1);
|
|
6866
6874
|
|
|
6867
6875
|
// src/designer/fieldCheck.js
|
|
6868
6876
|
function exprParts(value) {
|
|
@@ -6960,7 +6968,7 @@ function nestedFields(rows) {
|
|
|
6960
6968
|
return [...top2].filter(([, m]) => m.size).map(([name2, m]) => ({ name: name2, type: "object", fields: [...m].map(([n, t3]) => ({ name: n, type: t3 === "null" ? "string" : t3 })) }));
|
|
6961
6969
|
}
|
|
6962
6970
|
|
|
6963
|
-
//
|
|
6971
|
+
// node_modules/zustand/esm/vanilla.mjs
|
|
6964
6972
|
var createStoreImpl = (createState) => {
|
|
6965
6973
|
let state;
|
|
6966
6974
|
const listeners = /* @__PURE__ */ new Set();
|
|
@@ -6984,7 +6992,7 @@ var createStoreImpl = (createState) => {
|
|
|
6984
6992
|
};
|
|
6985
6993
|
var createStore = ((createState) => createState ? createStoreImpl(createState) : createStoreImpl);
|
|
6986
6994
|
|
|
6987
|
-
//
|
|
6995
|
+
// node_modules/zustand/esm/react.mjs
|
|
6988
6996
|
var import_react = __toESM(require_react(), 1);
|
|
6989
6997
|
var identity = (arg) => arg;
|
|
6990
6998
|
function useStore(api, selector = identity) {
|
|
@@ -6996,15 +7004,11 @@ function useStore(api, selector = identity) {
|
|
|
6996
7004
|
import_react.default.useDebugValue(slice);
|
|
6997
7005
|
return slice;
|
|
6998
7006
|
}
|
|
6999
|
-
var createImpl = (createState) => {
|
|
7000
|
-
const api = createStore(createState);
|
|
7001
|
-
const useBoundStore = (selector) => useStore(api, selector);
|
|
7002
|
-
Object.assign(useBoundStore, api);
|
|
7003
|
-
return useBoundStore;
|
|
7004
|
-
};
|
|
7005
|
-
var create = ((createState) => createState ? createImpl(createState) : createImpl);
|
|
7006
7007
|
|
|
7007
|
-
//
|
|
7008
|
+
// src/designer/store.js
|
|
7009
|
+
var import_react2 = __toESM(require_react(), 1);
|
|
7010
|
+
|
|
7011
|
+
// node_modules/immer/dist/immer.mjs
|
|
7008
7012
|
var NOTHING = /* @__PURE__ */ Symbol.for("immer-nothing");
|
|
7009
7013
|
var DRAFTABLE = /* @__PURE__ */ Symbol.for("immer-draftable");
|
|
7010
7014
|
var DRAFT_STATE = /* @__PURE__ */ Symbol.for("immer-state");
|
|
@@ -7851,6 +7855,17 @@ function pageOf2(def, key2 = "body") {
|
|
|
7851
7855
|
return resolvePage({ ...def.page || {}, ...sec?.page || {} });
|
|
7852
7856
|
}
|
|
7853
7857
|
var rid = () => Math.random().toString(36).slice(2, 10);
|
|
7858
|
+
function stableId(key2, taken) {
|
|
7859
|
+
let h = 2166136261;
|
|
7860
|
+
for (let i2 = 0; i2 < key2.length; i2++) {
|
|
7861
|
+
h ^= key2.charCodeAt(i2);
|
|
7862
|
+
h = Math.imul(h, 16777619);
|
|
7863
|
+
}
|
|
7864
|
+
let id = `i${(h >>> 0).toString(36)}`;
|
|
7865
|
+
for (let k = 2; taken.has(id); k++) id = `i${(h >>> 0).toString(36)}_${k}`;
|
|
7866
|
+
taken.add(id);
|
|
7867
|
+
return id;
|
|
7868
|
+
}
|
|
7854
7869
|
function walk(def, fn3) {
|
|
7855
7870
|
const go = (list2, parent, section) => list2.forEach((it, i2) => {
|
|
7856
7871
|
fn3(it, list2, i2, parent, section);
|
|
@@ -7876,9 +7891,15 @@ function normalize(def) {
|
|
|
7876
7891
|
if (x && typeof x === "object") x.items || (x.items = []);
|
|
7877
7892
|
}
|
|
7878
7893
|
const used = allNames(d);
|
|
7894
|
+
const ids = /* @__PURE__ */ new Set();
|
|
7879
7895
|
walk(d, (it) => {
|
|
7880
|
-
it.id
|
|
7896
|
+
if (it.id) ids.add(it.id);
|
|
7897
|
+
});
|
|
7898
|
+
const path = /* @__PURE__ */ new Map();
|
|
7899
|
+
walk(d, (it, list2, i2, parent, section) => {
|
|
7900
|
+
path.set(it, `${parent ? path.get(parent) : section}/${i2}`);
|
|
7881
7901
|
if (!it.name) it.name = uniqueName(used, ITEMS[it.type]?.label.replace(/\s/g, "") || "Item");
|
|
7902
|
+
it.id || (it.id = stableId(`${path.get(it)}/${it.name}`, ids));
|
|
7882
7903
|
if (NESTING.has(it.type)) it.items || (it.items = []);
|
|
7883
7904
|
if (it.type === "table" && Array.isArray(it.columns)) tableSync(it);
|
|
7884
7905
|
});
|
|
@@ -7902,7 +7923,7 @@ function findItem(def, id) {
|
|
|
7902
7923
|
});
|
|
7903
7924
|
return hit;
|
|
7904
7925
|
}
|
|
7905
|
-
var
|
|
7926
|
+
var newDesignerStore = () => createStore((set2, get2) => ({
|
|
7906
7927
|
id: null,
|
|
7907
7928
|
def: null,
|
|
7908
7929
|
saved: true,
|
|
@@ -8033,7 +8054,18 @@ var useDesigner = create((set2, get2) => ({
|
|
|
8033
8054
|
set2({ rev: (res.headers.get("etag") || "").replace(/^W\/|"/g, "") || null, conflict: null });
|
|
8034
8055
|
}
|
|
8035
8056
|
}));
|
|
8036
|
-
var
|
|
8057
|
+
var active = newDesignerStore();
|
|
8058
|
+
var DesignerStore = (0, import_react2.createContext)(null);
|
|
8059
|
+
var activateStore = (store) => {
|
|
8060
|
+
active = store;
|
|
8061
|
+
};
|
|
8062
|
+
var activeStore2 = () => active;
|
|
8063
|
+
var useDesignerStore = () => (0, import_react2.useContext)(DesignerStore) || active;
|
|
8064
|
+
var useDesigner = (sel) => useStore(useDesignerStore(), sel);
|
|
8065
|
+
useDesigner.getState = () => active.getState();
|
|
8066
|
+
useDesigner.setState = (...a) => active.setState(...a);
|
|
8067
|
+
useDesigner.subscribe = (fn3) => active.subscribe(fn3);
|
|
8068
|
+
var S = () => active.getState();
|
|
8037
8069
|
function bodyWidth(def, key2 = "body") {
|
|
8038
8070
|
return pageOf2(def, key2).bodyWidth;
|
|
8039
8071
|
}
|
|
@@ -8081,7 +8113,7 @@ function addItem(type, section, x, y, extra = {}, parentId = null) {
|
|
|
8081
8113
|
} else {
|
|
8082
8114
|
const sec = secOf(d, section);
|
|
8083
8115
|
sec.items.push(it);
|
|
8084
|
-
if (it.y + it.h > sec.height) sec.height = Math.ceil(it.y + it.h + (isBodyKey(section) ? 24 : 4));
|
|
8116
|
+
if (it.y + it.h > (sec.height || 0)) sec.height = Math.ceil(it.y + it.h + (isBodyKey(section) ? 24 : 4));
|
|
8085
8117
|
}
|
|
8086
8118
|
});
|
|
8087
8119
|
S().select({ kind: "items", ids: [id] });
|
|
@@ -8107,9 +8139,21 @@ function insertItem(type, section, x, y, extra = {}, parentId = null) {
|
|
|
8107
8139
|
function updateItem(id, recipe, key2) {
|
|
8108
8140
|
S().apply((d) => {
|
|
8109
8141
|
const f = findItem(d, id);
|
|
8110
|
-
if (f)
|
|
8142
|
+
if (!f) return;
|
|
8143
|
+
recipe(f.item, d, f.section, f);
|
|
8144
|
+
minSize(f.item);
|
|
8145
|
+
const nf = findItem(d, id);
|
|
8146
|
+
if (nf) growToFit(d, nf);
|
|
8111
8147
|
}, key2);
|
|
8112
8148
|
}
|
|
8149
|
+
function minSize(it) {
|
|
8150
|
+
for (const k of ["w", "h"]) if (typeof it[k] === "number" && !(it[k] >= 0)) it[k] = 0;
|
|
8151
|
+
if (it.type === "line") {
|
|
8152
|
+
if (it.w === 0 && it.h === 0) it.w = 1;
|
|
8153
|
+
return;
|
|
8154
|
+
}
|
|
8155
|
+
for (const k of ["w", "h"]) if (typeof it[k] === "number" && it[k] < 1) it[k] = 1;
|
|
8156
|
+
}
|
|
8113
8157
|
function moveItems(ids, dx, dy) {
|
|
8114
8158
|
if (!dx && !dy) return;
|
|
8115
8159
|
if (S().cells && wouldOverlap(S().def, ids, (it) => ({ x: it.x + dx, y: it.y + dy, w: it.w, h: it.h }))) {
|
|
@@ -8240,14 +8284,16 @@ function duplicateSelection() {
|
|
|
8240
8284
|
const f = findItem(d, id);
|
|
8241
8285
|
if (!f) continue;
|
|
8242
8286
|
const copy = cloneWithIds(f.item, used);
|
|
8243
|
-
copy.x +=
|
|
8244
|
-
copy.y +=
|
|
8287
|
+
copy.x += PASTE_OFFSET;
|
|
8288
|
+
copy.y += PASTE_OFFSET;
|
|
8289
|
+
growToFit(d, { ...f, item: copy });
|
|
8245
8290
|
f.list.push(copy);
|
|
8246
8291
|
newIds.push(copy.id);
|
|
8247
8292
|
}
|
|
8248
8293
|
});
|
|
8249
8294
|
if (newIds.length) S().select({ kind: "items", ids: newIds });
|
|
8250
8295
|
}
|
|
8296
|
+
var PASTE_OFFSET = 12;
|
|
8251
8297
|
var CLIP = "pagewright/items@1";
|
|
8252
8298
|
async function copySelection() {
|
|
8253
8299
|
const { sel, def } = S();
|
|
@@ -8262,43 +8308,41 @@ async function copySelection() {
|
|
|
8262
8308
|
return items.length;
|
|
8263
8309
|
}
|
|
8264
8310
|
var memClip = null;
|
|
8265
|
-
|
|
8266
|
-
let text = null;
|
|
8267
|
-
try {
|
|
8268
|
-
text = await navigator.clipboard.readText();
|
|
8269
|
-
} catch {
|
|
8270
|
-
text = memClip;
|
|
8271
|
-
}
|
|
8272
|
-
if (!text || !text.includes(CLIP)) text = memClip;
|
|
8273
|
-
let data;
|
|
8311
|
+
var clipOf = (text) => {
|
|
8274
8312
|
try {
|
|
8275
|
-
|
|
8313
|
+
const d = JSON.parse(text);
|
|
8314
|
+
return d?.kind === CLIP && Array.isArray(d.items) ? d : null;
|
|
8276
8315
|
} catch {
|
|
8277
|
-
return
|
|
8316
|
+
return null;
|
|
8278
8317
|
}
|
|
8279
|
-
|
|
8318
|
+
};
|
|
8319
|
+
function pasteItems(section = "body", text = null) {
|
|
8320
|
+
const st = active;
|
|
8321
|
+
const data = clipOf(text) || clipOf(memClip);
|
|
8322
|
+
if (!data) return 0;
|
|
8280
8323
|
const ids = [];
|
|
8281
|
-
|
|
8324
|
+
st.getState().apply((d) => {
|
|
8282
8325
|
const used = allNames(d);
|
|
8283
8326
|
for (const it of data.items) {
|
|
8284
8327
|
const c = cloneWithIds(it, used);
|
|
8285
|
-
c.x +=
|
|
8286
|
-
c.y +=
|
|
8328
|
+
c.x += PASTE_OFFSET;
|
|
8329
|
+
c.y += PASTE_OFFSET;
|
|
8287
8330
|
if (c.type === "table" && !isBodyKey(section)) continue;
|
|
8288
8331
|
secOf(d, section).items.push(c);
|
|
8332
|
+
growToFit(d, { section, parent: null, item: c });
|
|
8289
8333
|
ids.push(c.id);
|
|
8290
8334
|
}
|
|
8291
8335
|
});
|
|
8292
|
-
if (ids.length)
|
|
8336
|
+
if (ids.length) st.getState().select({ kind: "items", ids });
|
|
8293
8337
|
return ids.length;
|
|
8294
8338
|
}
|
|
8295
|
-
function rowsOf(t3, part,
|
|
8339
|
+
function rowsOf(t3, part, create = false) {
|
|
8296
8340
|
const m = /^g(\d+)([hf])$/.exec(part);
|
|
8297
8341
|
const holder = m ? t3.groups?.[Number(m[1])] : t3;
|
|
8298
8342
|
if (!holder) return null;
|
|
8299
8343
|
const key2 = m ? m[2] === "h" ? "header" : "footer" : part;
|
|
8300
8344
|
if (!holder[key2]) {
|
|
8301
|
-
if (!
|
|
8345
|
+
if (!create) return [];
|
|
8302
8346
|
holder[key2] = [];
|
|
8303
8347
|
}
|
|
8304
8348
|
return holder[key2];
|
|
@@ -8498,6 +8542,7 @@ function tableRemoveGroup(id, level) {
|
|
|
8498
8542
|
}
|
|
8499
8543
|
var IMAGE_MAX = 10 * 1024 * 1024;
|
|
8500
8544
|
async function uploadImages(files, T) {
|
|
8545
|
+
const st = active;
|
|
8501
8546
|
const names = [];
|
|
8502
8547
|
let err = null;
|
|
8503
8548
|
for (const f of files) {
|
|
@@ -8516,7 +8561,7 @@ async function uploadImages(files, T) {
|
|
|
8516
8561
|
r.readAsDataURL(f);
|
|
8517
8562
|
});
|
|
8518
8563
|
const base2 = f.name.replace(/\.[^.]+$/, "").replace(/\W+/g, "_").replace(/^_+|_+$/g, "") || "image";
|
|
8519
|
-
|
|
8564
|
+
st.getState().apply((d) => {
|
|
8520
8565
|
d.images || (d.images = {});
|
|
8521
8566
|
let n = base2, k = 2;
|
|
8522
8567
|
while (d.images[n]) n = `${base2}${k++}`;
|
|
@@ -8583,6 +8628,13 @@ function wouldOverlap(def, ids, rectOf2) {
|
|
|
8583
8628
|
}
|
|
8584
8629
|
return false;
|
|
8585
8630
|
}
|
|
8631
|
+
function setMatrixShow(v, show) {
|
|
8632
|
+
const pct = !!show && show !== "value";
|
|
8633
|
+
if (pct) v.show = show;
|
|
8634
|
+
else delete v.show;
|
|
8635
|
+
if (pct && (!v.format || v.format === "N0")) v.format = "P1";
|
|
8636
|
+
else if (!pct && v.format === "P1") v.format = "N0";
|
|
8637
|
+
}
|
|
8586
8638
|
|
|
8587
8639
|
// src/designer/ui.jsx
|
|
8588
8640
|
var import_jsx_runtime = __toESM(require_jsx_runtime(), 1);
|
|
@@ -8594,8 +8646,8 @@ function TextInput({ value, onChange, mono, invalid, className, ...rest }) {
|
|
|
8594
8646
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { className: `input${mono ? " mono" : ""}${invalid ? " invalid" : ""}${className ? ` ${className}` : ""}`, value: value ?? "", onChange: (e) => onChange(e.target.value), ...rest });
|
|
8595
8647
|
}
|
|
8596
8648
|
function NumberInput({ value, onChange, step = 0.5, min, ...rest }) {
|
|
8597
|
-
const [draft, setDraft] = (0,
|
|
8598
|
-
(0,
|
|
8649
|
+
const [draft, setDraft] = (0, import_react3.useState)(value ?? "");
|
|
8650
|
+
(0, import_react3.useEffect)(() => {
|
|
8599
8651
|
setDraft(value ?? "");
|
|
8600
8652
|
}, [value]);
|
|
8601
8653
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
@@ -8631,18 +8683,18 @@ function ColorInput({ value, onChange }) {
|
|
|
8631
8683
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TextInput, { value, onChange: (v) => onChange(v === "" ? void 0 : v), mono: true, placeholder: T("i_colorPh") })
|
|
8632
8684
|
] });
|
|
8633
8685
|
}
|
|
8634
|
-
var FieldScope = (0,
|
|
8686
|
+
var FieldScope = (0, import_react3.createContext)(void 0);
|
|
8635
8687
|
var issueText = (T, i2) => i2.suggest ? T("ux_unknownFieldSuggest", { name: i2.name, suggest: i2.suggest }) : T("ux_unknownField", { name: i2.name });
|
|
8636
8688
|
function ExprInput({ value, onChange, onOpen, placeholder: placeholder2 }) {
|
|
8637
8689
|
const T = useT();
|
|
8638
|
-
const scope = (0,
|
|
8690
|
+
const scope = (0, import_react3.useContext)(FieldScope);
|
|
8639
8691
|
const dataSets = useDesigner((s) => s.def?.dataSets);
|
|
8640
8692
|
const err = value ? checkValue(value) : null;
|
|
8641
8693
|
const issues = !err && value && scope !== void 0 ? fieldIssues(value, dataSets, scope) : [];
|
|
8642
8694
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
8643
8695
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "expr-row", children: [
|
|
8644
8696
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TextInput, { value, onChange, mono: true, invalid: !!err, className: issues.length ? "squiggle" : void 0, "aria-invalid": err || issues.length ? true : void 0, placeholder: placeholder2 || T("i_exprPh") }),
|
|
8645
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { className: "fx", title: T("i_openExprEditor"), "aria-label": T("i_openExprEditor")
|
|
8697
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { className: "fx", title: T("i_openExprEditor"), "aria-label": `fx: ${T("i_openExprEditor")}`, onClick: onOpen, type: "button", children: "fx" })
|
|
8646
8698
|
] }),
|
|
8647
8699
|
err && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "err", children: err }),
|
|
8648
8700
|
issues.map((i2, k) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "warn", "data-testid": "field-warning", children: issueText(T, i2) }, k))
|
|
@@ -8662,14 +8714,19 @@ function Check({ label, checked, onChange }) {
|
|
|
8662
8714
|
] });
|
|
8663
8715
|
}
|
|
8664
8716
|
function Dialog({ title, children, onClose, footer, wide, className = "" }) {
|
|
8665
|
-
(0,
|
|
8717
|
+
const ref = (0, import_react3.useRef)(null);
|
|
8718
|
+
(0, import_react3.useEffect)(() => {
|
|
8719
|
+
const inOther = (e) => {
|
|
8720
|
+
const mine = ref.current?.closest(".designer");
|
|
8721
|
+
return e.composedPath().some((n) => n !== mine && n?.classList?.contains("designer"));
|
|
8722
|
+
};
|
|
8666
8723
|
const k = (e) => {
|
|
8667
|
-
if (e.key === "Escape" && !e.defaultPrevented) onClose();
|
|
8724
|
+
if (e.key === "Escape" && !e.defaultPrevented && !inOther(e)) onClose();
|
|
8668
8725
|
};
|
|
8669
8726
|
window.addEventListener("keydown", k);
|
|
8670
8727
|
return () => window.removeEventListener("keydown", k);
|
|
8671
8728
|
}, [onClose]);
|
|
8672
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "scrim", onPointerDown: (e) => {
|
|
8729
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "scrim", ref, onPointerDown: (e) => {
|
|
8673
8730
|
if (e.target === e.currentTarget) onClose();
|
|
8674
8731
|
}, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: `dialog${wide ? " wide" : ""}${className ? ` ${className}` : ""}`, role: "dialog", "aria-modal": "true", "aria-label": title, children: [
|
|
8675
8732
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("header", { children: title }),
|
|
@@ -8679,20 +8736,20 @@ function Dialog({ title, children, onClose, footer, wide, className = "" }) {
|
|
|
8679
8736
|
}
|
|
8680
8737
|
|
|
8681
8738
|
// src/embed/link.js
|
|
8682
|
-
var
|
|
8739
|
+
var import_react4 = __toESM(require_react(), 1);
|
|
8683
8740
|
function Link({ href, children, prefetch, replace: replace2, scroll, shallow, ...rest }) {
|
|
8684
|
-
return (0,
|
|
8741
|
+
return (0, import_react4.createElement)("a", { href: typeof href === "string" ? href : String(href?.pathname || ""), ...rest }, children);
|
|
8685
8742
|
}
|
|
8686
8743
|
|
|
8687
8744
|
// src/designer/SvgHtml.jsx
|
|
8688
|
-
var
|
|
8745
|
+
var import_react5 = __toESM(require_react(), 1);
|
|
8689
8746
|
var import_jsx_runtime2 = __toESM(require_jsx_runtime(), 1);
|
|
8690
8747
|
function SvgHtml({ html, as: Tag2 = "span", ...rest }) {
|
|
8691
|
-
const ref = (0,
|
|
8748
|
+
const ref = (0, import_react5.useRef)(
|
|
8692
8749
|
/** @type {HTMLElement|null} */
|
|
8693
8750
|
null
|
|
8694
8751
|
);
|
|
8695
|
-
(0,
|
|
8752
|
+
(0, import_react5.useLayoutEffect)(() => {
|
|
8696
8753
|
if (!ref.current) return;
|
|
8697
8754
|
ref.current.innerHTML = deferStyleAttributes(html);
|
|
8698
8755
|
applyStyleAttributes(ref.current);
|
|
@@ -8701,7 +8758,7 @@ function SvgHtml({ html, as: Tag2 = "span", ...rest }) {
|
|
|
8701
8758
|
}
|
|
8702
8759
|
|
|
8703
8760
|
// src/designer/Canvas.jsx
|
|
8704
|
-
var
|
|
8761
|
+
var import_react8 = __toESM(require_react(), 1);
|
|
8705
8762
|
|
|
8706
8763
|
// src/designer/tableGen.js
|
|
8707
8764
|
var HEAD = { fontWeight: "bold", backgroundColor: "#f1f5f9", borderBottom: "0.75 solid #94a3b8" };
|
|
@@ -8833,24 +8890,28 @@ function instantPicks(fields, rows = []) {
|
|
|
8833
8890
|
}
|
|
8834
8891
|
|
|
8835
8892
|
// src/designer/Reuse.jsx
|
|
8836
|
-
var
|
|
8893
|
+
var import_react7 = __toESM(require_react(), 1);
|
|
8837
8894
|
|
|
8838
8895
|
// src/designer/Fonts.jsx
|
|
8839
|
-
var
|
|
8896
|
+
var import_react6 = __toESM(require_react(), 1);
|
|
8840
8897
|
var import_jsx_runtime3 = __toESM(require_jsx_runtime(), 1);
|
|
8841
8898
|
function useFontFamilies() {
|
|
8842
8899
|
const fonts = useDesigner((s) => s.fonts);
|
|
8843
8900
|
return [...BUNDLED_FAMILIES, ...[...new Set(fonts.map((f) => f.family))].sort()];
|
|
8844
8901
|
}
|
|
8845
|
-
var refresh = async () =>
|
|
8902
|
+
var refresh = async () => {
|
|
8903
|
+
const api = activeStore2();
|
|
8904
|
+
const fonts = await customFonts(true);
|
|
8905
|
+
api.getState().setUi({ fonts });
|
|
8906
|
+
};
|
|
8846
8907
|
function FontsDialog({ onClose }) {
|
|
8847
8908
|
const fonts = useDesigner((s) => s.fonts);
|
|
8848
|
-
const [file, setFile] = (0,
|
|
8849
|
-
const [family, setFamily] = (0,
|
|
8850
|
-
const [weight, setWeight] = (0,
|
|
8851
|
-
const [style, setStyle] = (0,
|
|
8852
|
-
const [busy, setBusy] = (0,
|
|
8853
|
-
const [msg, setMsg] = (0,
|
|
8909
|
+
const [file, setFile] = (0, import_react6.useState)(null);
|
|
8910
|
+
const [family, setFamily] = (0, import_react6.useState)("");
|
|
8911
|
+
const [weight, setWeight] = (0, import_react6.useState)("");
|
|
8912
|
+
const [style, setStyle] = (0, import_react6.useState)("");
|
|
8913
|
+
const [busy, setBusy] = (0, import_react6.useState)(false);
|
|
8914
|
+
const [msg, setMsg] = (0, import_react6.useState)(null);
|
|
8854
8915
|
const upload = async () => {
|
|
8855
8916
|
if (!file) return;
|
|
8856
8917
|
setBusy(true);
|
|
@@ -8941,30 +9002,33 @@ var apply = (fn3, key2) => S2().apply(fn3, key2);
|
|
|
8941
9002
|
var server = () => S2().embed?.server || "";
|
|
8942
9003
|
var noServer = () => !!S2().embed && !S2().embed.server;
|
|
8943
9004
|
var pending = /* @__PURE__ */ new Map();
|
|
8944
|
-
function fetchReused(id, force = false) {
|
|
9005
|
+
function fetchReused(id, force = false, api = activeStore2()) {
|
|
8945
9006
|
if (!id || typeof id !== "string" || id.startsWith("=")) return Promise.resolve(null);
|
|
8946
|
-
|
|
8947
|
-
if (
|
|
8948
|
-
|
|
8949
|
-
const
|
|
8950
|
-
|
|
8951
|
-
useDesigner.setState((s) => ({ reused: { ...s.reused, [id]: d } }));
|
|
9007
|
+
const st = api.getState();
|
|
9008
|
+
if (!force && st.reused[id]) return Promise.resolve(st.reused[id]);
|
|
9009
|
+
const server2 = st.embed?.server || "", key2 = `${server2} ${id}`;
|
|
9010
|
+
const keep = (d) => {
|
|
9011
|
+
api.setState((s) => ({ reused: { ...s.reused, [id]: d } }));
|
|
8952
9012
|
return d;
|
|
8953
|
-
}
|
|
8954
|
-
pending.
|
|
8955
|
-
return
|
|
9013
|
+
};
|
|
9014
|
+
if (pending.has(key2)) return pending.get(key2).then(keep);
|
|
9015
|
+
if (st.embed && !server2) return Promise.resolve(null);
|
|
9016
|
+
const p = fetch(`${server2}/api/reports/${encodeURIComponent(id)}`).then((r) => r.ok ? r.json() : { __error: `HTTP ${r.status}` }).catch((e) => ({ __error: e.message })).finally(() => pending.delete(key2));
|
|
9017
|
+
pending.set(key2, p);
|
|
9018
|
+
return p.then(keep);
|
|
8956
9019
|
}
|
|
8957
9020
|
function useReused(id) {
|
|
9021
|
+
const api = useDesignerStore();
|
|
8958
9022
|
const d = useDesigner((s) => id ? s.reused[id] : void 0);
|
|
8959
|
-
(0,
|
|
8960
|
-
fetchReused(id);
|
|
8961
|
-
}, [id]);
|
|
9023
|
+
(0, import_react7.useEffect)(() => {
|
|
9024
|
+
fetchReused(id, false, api);
|
|
9025
|
+
}, [id, api]);
|
|
8962
9026
|
return d && !d.__error ? d : null;
|
|
8963
9027
|
}
|
|
8964
9028
|
var listCache = null;
|
|
8965
9029
|
function ReportSelect({ value, onChange, exclude, ...rest }) {
|
|
8966
|
-
const [list2, setList] = (0,
|
|
8967
|
-
(0,
|
|
9030
|
+
const [list2, setList] = (0, import_react7.useState)(listCache || []);
|
|
9031
|
+
(0, import_react7.useEffect)(() => {
|
|
8968
9032
|
if (noServer()) return;
|
|
8969
9033
|
fetch(`${server()}/api/reports`).then((r) => r.ok ? r.json() : []).then((l) => {
|
|
8970
9034
|
listCache = Array.isArray(l) ? l : [];
|
|
@@ -9031,7 +9095,7 @@ function ThemeSection() {
|
|
|
9031
9095
|
const id = useDesigner((s) => s.id);
|
|
9032
9096
|
const families = useFontFamilies();
|
|
9033
9097
|
const src = def.theme;
|
|
9034
|
-
const [mode, setMode] = (0,
|
|
9098
|
+
const [mode, setMode] = (0, import_react7.useState)(!src ? "own" : String(src).startsWith("=") ? "expr" : "report");
|
|
9035
9099
|
const td = def.themeDef || {};
|
|
9036
9100
|
const setTd = (fn3, key2) => apply((d) => {
|
|
9037
9101
|
d.themeDef || (d.themeDef = {});
|
|
@@ -9050,7 +9114,7 @@ function ThemeSection() {
|
|
|
9050
9114
|
else x.fonts[k][p] = v;
|
|
9051
9115
|
}, `theme.font.${k}.${p}`);
|
|
9052
9116
|
const consts = Object.entries(td.constants || {});
|
|
9053
|
-
const [newConst, setNewConst] = (0,
|
|
9117
|
+
const [newConst, setNewConst] = (0, import_react7.useState)("");
|
|
9054
9118
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "cat", "data-testid": "theme", children: [
|
|
9055
9119
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(CatHead, { children: T("theme") }),
|
|
9056
9120
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Field, { label: T("themeSource"), children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
@@ -9110,7 +9174,7 @@ function LayersPanel() {
|
|
|
9110
9174
|
const T = useT2();
|
|
9111
9175
|
const layers = useDesigner((s) => s.def.layers) || [];
|
|
9112
9176
|
const readOnly2 = useDesigner((s) => s.readOnly);
|
|
9113
|
-
const [name2, setName] = (0,
|
|
9177
|
+
const [name2, setName] = (0, import_react7.useState)("");
|
|
9114
9178
|
const set2 = (fn3, key2) => apply((d) => {
|
|
9115
9179
|
d.layers || (d.layers = []);
|
|
9116
9180
|
fn3(d.layers, d);
|
|
@@ -9265,7 +9329,7 @@ function PartsPanel() {
|
|
|
9265
9329
|
const libs = useDesigner((s) => s.def.libraries) || [];
|
|
9266
9330
|
const id = useDesigner((s) => s.id);
|
|
9267
9331
|
const readOnly2 = useDesigner((s) => s.readOnly);
|
|
9268
|
-
const [pick, setPick] = (0,
|
|
9332
|
+
const [pick, setPick] = (0, import_react7.useState)("");
|
|
9269
9333
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "pane", "data-testid": "parts-panel", children: [
|
|
9270
9334
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("h4", { children: [
|
|
9271
9335
|
T("parts"),
|
|
@@ -9394,7 +9458,7 @@ function PublishPart({ item }) {
|
|
|
9394
9458
|
if (v === void 0 || v === "") delete q2[k];
|
|
9395
9459
|
else q2[k] = v;
|
|
9396
9460
|
}, `part${i2}.q${j}.${k}`);
|
|
9397
|
-
const [newProp, setNewProp] = (0,
|
|
9461
|
+
const [newProp, setNewProp] = (0, import_react7.useState)("");
|
|
9398
9462
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "cat", "data-testid": "publish-part", children: [
|
|
9399
9463
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(CatHead, { children: T("reportPart") }),
|
|
9400
9464
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Check, { label: T("publishPart"), checked: !!p, onChange: (on) => set2((l) => {
|
|
@@ -9523,12 +9587,12 @@ function useDesignIssues() {
|
|
|
9523
9587
|
const def = useDesigner((s) => s.def);
|
|
9524
9588
|
const extents = useDesigner((s) => s.extents);
|
|
9525
9589
|
const saveCheck = useDesigner((s) => s.saveCheck);
|
|
9526
|
-
return (0,
|
|
9590
|
+
return (0, import_react8.useMemo)(() => {
|
|
9527
9591
|
const bands = sectionList(def).map((s) => ({ key: s.key, items: secOf(def, s.key)?.items || [], width: bodyWidth(def, s.key) }));
|
|
9528
9592
|
return [...designIssues(def, bands, extents || {}), ...checkIssues(bands, [...validate(def).errors, ...saveCheck?.missing || []])];
|
|
9529
9593
|
}, [def, extents, saveCheck]);
|
|
9530
9594
|
}
|
|
9531
|
-
var IssueMap = (0,
|
|
9595
|
+
var IssueMap = (0, import_react8.createContext)(/* @__PURE__ */ new Map());
|
|
9532
9596
|
function issueLine(T, i2) {
|
|
9533
9597
|
if (i2.kind === "overlap") return T("ux_issueOverlap", { name: i2.name, other: i2.other });
|
|
9534
9598
|
if (i2.kind === "wide") return T("ux_issueWide", { name: i2.name, width: i2.width, room: i2.room });
|
|
@@ -9593,9 +9657,9 @@ function Canvas() {
|
|
|
9593
9657
|
const bands = sectionList(def);
|
|
9594
9658
|
const widths2 = Object.fromEntries(bands.map((s) => [s.key, bodyWidth(def, s.key)]));
|
|
9595
9659
|
const bw = Math.max(...Object.values(widths2));
|
|
9596
|
-
const scrollRef = (0,
|
|
9597
|
-
const [fitW, setFitW] = (0,
|
|
9598
|
-
(0,
|
|
9660
|
+
const scrollRef = (0, import_react8.useRef)(null);
|
|
9661
|
+
const [fitW, setFitW] = (0, import_react8.useState)(0);
|
|
9662
|
+
(0, import_react8.useEffect)(() => {
|
|
9599
9663
|
if (zoom !== "fit" || !scrollRef.current) return;
|
|
9600
9664
|
const el = scrollRef.current;
|
|
9601
9665
|
const ro = new ResizeObserver(() => setFitW(el.clientWidth));
|
|
@@ -9603,10 +9667,10 @@ function Canvas() {
|
|
|
9603
9667
|
return () => ro.disconnect();
|
|
9604
9668
|
}, [zoom]);
|
|
9605
9669
|
const scale = zoom === "fit" ? Math.max(0.3, Math.min(3, ((fitW || 900) - 80) / bw)) : zoom * PX;
|
|
9606
|
-
const [drag, setDrag] = (0,
|
|
9670
|
+
const [drag, setDrag] = (0, import_react8.useState)(null);
|
|
9607
9671
|
const T = useT2();
|
|
9608
9672
|
const issues = useDesignIssues();
|
|
9609
|
-
const byId = (0,
|
|
9673
|
+
const byId = (0, import_react8.useMemo)(() => {
|
|
9610
9674
|
const m = /* @__PURE__ */ new Map();
|
|
9611
9675
|
for (const i2 of issues) m.set(i2.id, [...m.get(i2.id) || [], issueLine(T, i2)]);
|
|
9612
9676
|
return m;
|
|
@@ -9687,9 +9751,9 @@ function Band({ section, label, scale, bw: bandW, drag, setDrag, phBox = null })
|
|
|
9687
9751
|
const off = phBox || mb?.off || null;
|
|
9688
9752
|
const contentList = useDesigner((s) => s.def.sections?.content);
|
|
9689
9753
|
const bw = off?.w || bandW;
|
|
9690
|
-
const ref = (0,
|
|
9691
|
-
const [marquee, setMarquee] = (0,
|
|
9692
|
-
const [dropping, setDropping] = (0,
|
|
9754
|
+
const ref = (0, import_react8.useRef)(null);
|
|
9755
|
+
const [marquee, setMarquee] = (0, import_react8.useState)(null);
|
|
9756
|
+
const [dropping, setDropping] = (0, import_react8.useState)(false);
|
|
9693
9757
|
const h = drag?.mode === "band" && drag.section === section ? drag.h : sec.height || 0;
|
|
9694
9758
|
const DROP_ROOM = 96;
|
|
9695
9759
|
const toPt3 = (e) => {
|
|
@@ -9863,8 +9927,9 @@ var alerted = 0;
|
|
|
9863
9927
|
function alertOnce(msg) {
|
|
9864
9928
|
if (Date.now() - alerted > 3e3) {
|
|
9865
9929
|
alerted = Date.now();
|
|
9866
|
-
|
|
9867
|
-
|
|
9930
|
+
const api = activeStore2();
|
|
9931
|
+
api.setState({ saveError: msg });
|
|
9932
|
+
setTimeout(() => api.setState({ saveError: null }), 3e3);
|
|
9868
9933
|
}
|
|
9869
9934
|
}
|
|
9870
9935
|
function fieldStyle(f) {
|
|
@@ -9872,11 +9937,31 @@ function fieldStyle(f) {
|
|
|
9872
9937
|
const format = formatFor({ name: f.field, type: f.type }, (st.sample?.dataSets?.[f.dataSet] || []).slice(0, 200), { currency: st.def?.currency });
|
|
9873
9938
|
return format ? { format } : {};
|
|
9874
9939
|
}
|
|
9940
|
+
function useItemKeys(item) {
|
|
9941
|
+
const T = useT2();
|
|
9942
|
+
const type = T(`item_${item.type}`) === `item_${item.type}` ? ITEMS[item.type]?.label || item.type : T(`item_${item.type}`);
|
|
9943
|
+
return {
|
|
9944
|
+
tabIndex: 0,
|
|
9945
|
+
role: "group",
|
|
9946
|
+
"data-item-key": item.id,
|
|
9947
|
+
"aria-label": T("b9_itemLabel", { type, name: item.name, x: round(item.x), y: round(item.y) }),
|
|
9948
|
+
onKeyDown: (e) => {
|
|
9949
|
+
if (e.target !== e.currentTarget || e.key !== "Enter" && e.key !== " ") return;
|
|
9950
|
+
e.preventDefault();
|
|
9951
|
+
e.stopPropagation();
|
|
9952
|
+
const st = useDesigner.getState();
|
|
9953
|
+
const cur2 = st.sel.kind === "items" ? st.sel.ids : [];
|
|
9954
|
+
const ids = !e.shiftKey ? [item.id] : cur2.includes(item.id) ? cur2.filter((i2) => i2 !== item.id) : [...cur2, item.id];
|
|
9955
|
+
st.select(ids.length ? { kind: "items", ids } : { kind: "report" });
|
|
9956
|
+
}
|
|
9957
|
+
};
|
|
9958
|
+
}
|
|
9875
9959
|
function useItemDrag(item, scale, setDrag) {
|
|
9876
9960
|
return (e) => {
|
|
9877
9961
|
if (e.button !== 0) return;
|
|
9878
9962
|
e.preventDefault();
|
|
9879
9963
|
e.stopPropagation();
|
|
9964
|
+
e.currentTarget.closest?.("[data-item-key]")?.focus({ preventScroll: true });
|
|
9880
9965
|
const st = useDesigner.getState();
|
|
9881
9966
|
let ids;
|
|
9882
9967
|
if (e.shiftKey) {
|
|
@@ -9949,8 +10034,8 @@ function AnyItem(props) {
|
|
|
9949
10034
|
return layer?.locked ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "layer-locked", "data-locked": props.item.name, children: el }) : el;
|
|
9950
10035
|
}
|
|
9951
10036
|
function NestChildren({ item, scale, drag, setDrag, section }) {
|
|
9952
|
-
const ref = (0,
|
|
9953
|
-
const [over, setOver] = (0,
|
|
10037
|
+
const ref = (0, import_react8.useRef)(null);
|
|
10038
|
+
const [over, setOver] = (0, import_react8.useState)(false);
|
|
9954
10039
|
const accepts = (e) => e.dataTransfer.types.includes(MIME_TOOL) || e.dataTransfer.types.includes(MIME_FIELD) || e.dataTransfer.types.includes(MIME_PART);
|
|
9955
10040
|
const onDrop = (e) => {
|
|
9956
10041
|
setOver(false);
|
|
@@ -9995,8 +10080,9 @@ function ItemView({ item, scale, drag, setDrag, bw, nest, section }) {
|
|
|
9995
10080
|
const selected = useDesigner((s) => s.sel.kind === "items" && s.sel.ids.includes(item.id));
|
|
9996
10081
|
const single = useDesigner((s) => s.sel.kind === "items" && s.sel.ids.length === 1);
|
|
9997
10082
|
const onDown = useItemDrag(item, scale, setDrag);
|
|
10083
|
+
const keys = useItemKeys(item);
|
|
9998
10084
|
const r = rectOf(item, drag);
|
|
9999
|
-
const problems = (0,
|
|
10085
|
+
const problems = (0, import_react8.useContext)(IssueMap).get(item.id);
|
|
10000
10086
|
const onHandle = (dir) => (e) => {
|
|
10001
10087
|
e.preventDefault();
|
|
10002
10088
|
e.stopPropagation();
|
|
@@ -10055,6 +10141,7 @@ function ItemView({ item, scale, drag, setDrag, bw, nest, section }) {
|
|
|
10055
10141
|
title: problems?.join("\n"),
|
|
10056
10142
|
style: { left: r.x * scale, top: r.y * scale, width: Math.max(r.w * scale, 2), height: Math.max(r.h * scale, 2) },
|
|
10057
10143
|
onPointerDown: onDown,
|
|
10144
|
+
...keys,
|
|
10058
10145
|
children: [
|
|
10059
10146
|
nest ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(NestBox, { item: { ...item, ...r }, scale }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ItemBody, { item: { ...item, ...r }, scale }),
|
|
10060
10147
|
nest && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(NestChildren, { item, scale, drag, setDrag, section }),
|
|
@@ -10072,8 +10159,8 @@ function NestBox({ item, scale }) {
|
|
|
10072
10159
|
}
|
|
10073
10160
|
var LIVE = /* @__PURE__ */ new Set(["chart", "matrix", "barcode", "sparkline", "databar", "bullet", "iconset", "rangebar", "richtext"]);
|
|
10074
10161
|
var measurer = null;
|
|
10075
|
-
async function paintItemSvg(shape2, def, sample) {
|
|
10076
|
-
const store =
|
|
10162
|
+
async function paintItemSvg(shape2, def, sample, api = activeStore2()) {
|
|
10163
|
+
const store = await loadFontStore();
|
|
10077
10164
|
await Promise.all([store.load(), customFonts()]);
|
|
10078
10165
|
if (shape2.type === "barcode" || hasType(shape2.items, "barcode")) await loadBarcodes();
|
|
10079
10166
|
measurer || (measurer = new TextMeasurer(store));
|
|
@@ -10084,7 +10171,7 @@ async function paintItemSvg(shape2, def, sample) {
|
|
|
10084
10171
|
} catch {
|
|
10085
10172
|
}
|
|
10086
10173
|
const base2 = { fontFamily: "Inter", fontSize: 9, color: "#1f2937", padding: 2, lineHeight: 1.25, textAlign: "auto", verticalAlign: "top", ...def.styles?.base || {} };
|
|
10087
|
-
const theme3 = themeContext(typeof def.theme === "string" &&
|
|
10174
|
+
const theme3 = themeContext(typeof def.theme === "string" && api.getState().reused[def.theme]?.themeDef || def.themeDef);
|
|
10088
10175
|
const ctxBase = { params, globals: { PageNumber: 1, TotalPages: 1, ExecutionTime: /* @__PURE__ */ new Date(), ReportName: def.name }, dataSets, fields: null, locale: def.locale, currency: def.currency, functions: functionTable(def), theme: theme3 };
|
|
10089
10176
|
let seq = 0;
|
|
10090
10177
|
const lc = {
|
|
@@ -10126,20 +10213,21 @@ async function paintItemSvg(shape2, def, sample) {
|
|
|
10126
10213
|
return { html: pageToSvg({ items }, shape2.w, h, { background: false }), h, w };
|
|
10127
10214
|
}
|
|
10128
10215
|
function LivePreview({ item, scale }) {
|
|
10216
|
+
const api = useDesignerStore();
|
|
10129
10217
|
const sample = useDesigner((s) => s.sample);
|
|
10130
10218
|
const def = useDesigner((s) => s.def);
|
|
10131
|
-
const [svg, setSvg] = (0,
|
|
10219
|
+
const [svg, setSvg] = (0, import_react8.useState)(null);
|
|
10132
10220
|
const { x, y, ...shape2 } = item;
|
|
10133
10221
|
const key2 = JSON.stringify(shape2);
|
|
10134
|
-
(0,
|
|
10222
|
+
(0, import_react8.useEffect)(() => {
|
|
10135
10223
|
let alive = true;
|
|
10136
10224
|
const t3 = setTimeout(async () => {
|
|
10137
10225
|
try {
|
|
10138
|
-
const out = await paintItemSvg(shape2, def, sample);
|
|
10226
|
+
const out = await paintItemSvg(shape2, def, sample, api);
|
|
10139
10227
|
if (alive) {
|
|
10140
10228
|
setSvg(out);
|
|
10141
|
-
const ex2 =
|
|
10142
|
-
if (Math.round(ex2[item.id]?.w || 0) !== Math.round(out.w))
|
|
10229
|
+
const ex2 = api.getState().extents || {};
|
|
10230
|
+
if (Math.round(ex2[item.id]?.w || 0) !== Math.round(out.w)) api.setState({ extents: { ...ex2, [item.id]: { w: out.w } } });
|
|
10143
10231
|
}
|
|
10144
10232
|
} catch (e) {
|
|
10145
10233
|
if (alive) setSvg({ error: e.message });
|
|
@@ -10161,9 +10249,9 @@ function PartPreview({ item, scale }) {
|
|
|
10161
10249
|
const p = (lib?.parts || []).find((q2) => q2.name === item.part);
|
|
10162
10250
|
const src = p && findItemNamed(lib, p.item);
|
|
10163
10251
|
const props = { ...Object.fromEntries((p?.properties || []).map((q2) => [q2.name, q2.default ?? null])), ...item.properties || {} };
|
|
10164
|
-
const [svg, setSvg] = (0,
|
|
10252
|
+
const [svg, setSvg] = (0, import_react8.useState)(null);
|
|
10165
10253
|
const key2 = JSON.stringify([src, props]);
|
|
10166
|
-
(0,
|
|
10254
|
+
(0, import_react8.useEffect)(() => {
|
|
10167
10255
|
if (!src) return void 0;
|
|
10168
10256
|
let alive = true;
|
|
10169
10257
|
const t3 = setTimeout(() => {
|
|
@@ -10273,17 +10361,18 @@ function TableView({ item, scale, drag, setDrag }) {
|
|
|
10273
10361
|
const readOnly2 = useDesigner((s) => s.readOnly);
|
|
10274
10362
|
const tableSelected = sel.kind === "items" && sel.ids.includes(item.id);
|
|
10275
10363
|
const onGrip = useItemDrag(item, scale, setDrag);
|
|
10364
|
+
const keys = useItemKeys(item);
|
|
10276
10365
|
const r = rectOf(item, drag);
|
|
10277
10366
|
const widths2 = item.columns.map((c, i2) => drag?.mode === "col" && drag.id === item.id && drag.col === i2 ? drag.w : c.width);
|
|
10278
|
-
const [dropCell, setDropCell] = (0,
|
|
10279
|
-
const [menu, setMenu] = (0,
|
|
10280
|
-
const problems = (0,
|
|
10281
|
-
const tblRef = (0,
|
|
10367
|
+
const [dropCell, setDropCell] = (0, import_react8.useState)(null);
|
|
10368
|
+
const [menu, setMenu] = (0, import_react8.useState)(null);
|
|
10369
|
+
const problems = (0, import_react8.useContext)(IssueMap).get(item.id);
|
|
10370
|
+
const tblRef = (0, import_react8.useRef)(null);
|
|
10282
10371
|
const chosen = sel.kind === "cell" && sel.id === item.id ? selCells(sel) : [];
|
|
10283
|
-
(0,
|
|
10372
|
+
(0, import_react8.useEffect)(() => {
|
|
10284
10373
|
if (!menu) return void 0;
|
|
10285
10374
|
const close = (e) => {
|
|
10286
|
-
if (e.type === "keydown" ? e.key === "Escape" : !e.
|
|
10375
|
+
if (e.type === "keydown" ? e.key === "Escape" : !e.composedPath().some((n) => n.classList?.contains("cell-menu"))) setMenu(null);
|
|
10287
10376
|
};
|
|
10288
10377
|
window.addEventListener("pointerdown", close, true);
|
|
10289
10378
|
window.addEventListener("keydown", close);
|
|
@@ -10296,6 +10385,7 @@ function TableView({ item, scale, drag, setDrag }) {
|
|
|
10296
10385
|
e.stopPropagation();
|
|
10297
10386
|
if (e.button !== 0) return;
|
|
10298
10387
|
e.preventDefault();
|
|
10388
|
+
e.currentTarget.closest("[data-item-key]")?.focus({ preventScroll: true });
|
|
10299
10389
|
const st = useDesigner.getState();
|
|
10300
10390
|
const here = { part, row: ri, col: ci };
|
|
10301
10391
|
const cur2 = st.sel.kind === "cell" && st.sel.id === item.id ? st.sel : null;
|
|
@@ -10371,7 +10461,7 @@ function TableView({ item, scale, drag, setDrag }) {
|
|
|
10371
10461
|
const h = t3.header?.[t3.header.length - 1]?.cells?.[ci];
|
|
10372
10462
|
if (h && (!h.value || /^Column \d+$/.test(h.value))) h.value = f.field.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/^./, (c) => c.toUpperCase());
|
|
10373
10463
|
if (h && f.type === "number") h.style = { ...h.style || {}, textAlign: "right" };
|
|
10374
|
-
} else if ((part === "footer" || /^g\d+
|
|
10464
|
+
} else if ((part === "footer" || /^g\d+[hf]$/.test(part)) && f.type === "number") {
|
|
10375
10465
|
cell.value = `=Sum(Fields.${f.field})`;
|
|
10376
10466
|
cell.style = { ...cell.style || {}, ...fieldStyle(f) };
|
|
10377
10467
|
} else cell.value = `=Fields.${f.field}`;
|
|
@@ -10379,7 +10469,7 @@ function TableView({ item, scale, drag, setDrag }) {
|
|
|
10379
10469
|
useDesigner.getState().select({ kind: "cell", id: item.id, part, row: ri, col: ci });
|
|
10380
10470
|
};
|
|
10381
10471
|
let first = true;
|
|
10382
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { ref: tblRef, className: `tbl${tableSelected ? " sel" : ""}${problems ? " issue" : ""}`, "data-item": item.name, style: { left: r.x * scale, top: r.y * scale }, children: [
|
|
10472
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { ref: tblRef, className: `tbl${tableSelected ? " sel" : ""}${problems ? " issue" : ""}`, "data-item": item.name, style: { left: r.x * scale, top: r.y * scale }, ...keys, children: [
|
|
10383
10473
|
problems && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "issue-tag", title: problems.join("\n"), "aria-label": problems.join(". "), children: "!" }),
|
|
10384
10474
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "grip", title: "Select or move the table", onPointerDown: onGrip, children: "⠿" }),
|
|
10385
10475
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "col-handles", "aria-label": T("ux_columns"), role: "group", children: widths2.map((w, ci) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
@@ -10509,15 +10599,15 @@ function TableView({ item, scale, drag, setDrag }) {
|
|
|
10509
10599
|
}
|
|
10510
10600
|
|
|
10511
10601
|
// src/designer/Inspector.jsx
|
|
10512
|
-
var
|
|
10602
|
+
var import_react12 = __toESM(require_react(), 1);
|
|
10513
10603
|
|
|
10514
10604
|
// src/designer/ExpressionEditor.jsx
|
|
10515
|
-
var
|
|
10605
|
+
var import_react10 = __toESM(require_react(), 1);
|
|
10516
10606
|
|
|
10517
10607
|
// src/designer/ExprCode.jsx
|
|
10518
|
-
var
|
|
10608
|
+
var import_react9 = __toESM(require_react(), 1);
|
|
10519
10609
|
|
|
10520
|
-
//
|
|
10610
|
+
// node_modules/@marijn/find-cluster-break/src/index.js
|
|
10521
10611
|
var rangeFrom = [];
|
|
10522
10612
|
var rangeTo = [];
|
|
10523
10613
|
(() => {
|
|
@@ -10594,7 +10684,7 @@ function codePointSize(code2) {
|
|
|
10594
10684
|
return code2 < 65536 ? 1 : 2;
|
|
10595
10685
|
}
|
|
10596
10686
|
|
|
10597
|
-
//
|
|
10687
|
+
// node_modules/@codemirror/state/dist/index.js
|
|
10598
10688
|
var Text = class _Text {
|
|
10599
10689
|
/**
|
|
10600
10690
|
Get the line description around the given position.
|
|
@@ -12259,8 +12349,8 @@ var StateField = class _StateField {
|
|
|
12259
12349
|
way it is initialized. Can be useful when you need to provide a
|
|
12260
12350
|
non-default starting value for the field.
|
|
12261
12351
|
*/
|
|
12262
|
-
init(
|
|
12263
|
-
return [this, initField.of({ field: this, create
|
|
12352
|
+
init(create) {
|
|
12353
|
+
return [this, initField.of({ field: this, create })];
|
|
12264
12354
|
}
|
|
12265
12355
|
/**
|
|
12266
12356
|
State field instances can be used as
|
|
@@ -13488,10 +13578,10 @@ var RangeSet = class _RangeSet {
|
|
|
13488
13578
|
for (; ; ) {
|
|
13489
13579
|
let curTo = Math.min(cursor.to, to);
|
|
13490
13580
|
if (cursor.point) {
|
|
13491
|
-
let
|
|
13492
|
-
let openCount = cursor.pointFrom < from ?
|
|
13493
|
-
iterator.point(pos, curTo, cursor.point,
|
|
13494
|
-
openRanges = Math.min(cursor.openEnd(curTo),
|
|
13581
|
+
let active2 = cursor.activeForPoint(cursor.to);
|
|
13582
|
+
let openCount = cursor.pointFrom < from ? active2.length + 1 : cursor.point.startSide < 0 ? active2.length : Math.min(active2.length, openRanges);
|
|
13583
|
+
iterator.point(pos, curTo, cursor.point, active2, openCount, cursor.pointRank);
|
|
13584
|
+
openRanges = Math.min(cursor.openEnd(curTo), active2.length);
|
|
13495
13585
|
} else if (curTo > pos) {
|
|
13496
13586
|
iterator.span(pos, curTo, cursor.active, openRanges);
|
|
13497
13587
|
openRanges = cursor.openEnd(curTo);
|
|
@@ -13905,14 +13995,14 @@ var SpanCursor = class {
|
|
|
13905
13995
|
activeForPoint(to) {
|
|
13906
13996
|
if (!this.active.length)
|
|
13907
13997
|
return this.active;
|
|
13908
|
-
let
|
|
13998
|
+
let active2 = [];
|
|
13909
13999
|
for (let i2 = this.active.length - 1; i2 >= 0; i2--) {
|
|
13910
14000
|
if (this.activeRank[i2] < this.pointRank)
|
|
13911
14001
|
break;
|
|
13912
14002
|
if (this.activeTo[i2] > to || this.activeTo[i2] == to && this.active[i2].endSide >= this.point.endSide)
|
|
13913
|
-
|
|
14003
|
+
active2.push(this.active[i2]);
|
|
13914
14004
|
}
|
|
13915
|
-
return
|
|
14005
|
+
return active2.reverse();
|
|
13916
14006
|
}
|
|
13917
14007
|
openEnd(to) {
|
|
13918
14008
|
let open = 0;
|
|
@@ -14006,7 +14096,7 @@ function findColumn(string2, col, tabSize, strict) {
|
|
|
14006
14096
|
return strict === true ? -1 : string2.length;
|
|
14007
14097
|
}
|
|
14008
14098
|
|
|
14009
|
-
//
|
|
14099
|
+
// node_modules/style-mod/src/style-mod.js
|
|
14010
14100
|
var C = "ͼ";
|
|
14011
14101
|
var COUNT = typeof Symbol == "undefined" ? "__" + C : Symbol.for(C);
|
|
14012
14102
|
var SET = typeof Symbol == "undefined" ? "__styleSet" + Math.floor(Math.random() * 1e8) : /* @__PURE__ */ Symbol("styleSet");
|
|
@@ -14142,7 +14232,7 @@ var StyleSet = class {
|
|
|
14142
14232
|
}
|
|
14143
14233
|
};
|
|
14144
14234
|
|
|
14145
|
-
//
|
|
14235
|
+
// node_modules/w3c-keyname/index.js
|
|
14146
14236
|
var base = {
|
|
14147
14237
|
8: "Backspace",
|
|
14148
14238
|
9: "Tab",
|
|
@@ -14248,7 +14338,7 @@ function keyName(event) {
|
|
|
14248
14338
|
return name2;
|
|
14249
14339
|
}
|
|
14250
14340
|
|
|
14251
|
-
//
|
|
14341
|
+
// node_modules/@codemirror/view/dist/index.js
|
|
14252
14342
|
var nav = typeof navigator != "undefined" ? navigator : { userAgent: "", vendor: "", platform: "" };
|
|
14253
14343
|
var doc = typeof document != "undefined" ? document : { documentElement: { style: {} } };
|
|
14254
14344
|
var ie_edge = /* @__PURE__ */ /Edge\/(\d+)/.exec(nav.userAgent);
|
|
@@ -15431,9 +15521,9 @@ var viewPlugin = /* @__PURE__ */ Facet.define({
|
|
|
15431
15521
|
}
|
|
15432
15522
|
});
|
|
15433
15523
|
var ViewPlugin = class _ViewPlugin {
|
|
15434
|
-
constructor(id,
|
|
15524
|
+
constructor(id, create, domEventHandlers, domEventObservers, buildExtensions) {
|
|
15435
15525
|
this.id = id;
|
|
15436
|
-
this.create =
|
|
15526
|
+
this.create = create;
|
|
15437
15527
|
this.domEventHandlers = domEventHandlers;
|
|
15438
15528
|
this.domEventObservers = domEventObservers;
|
|
15439
15529
|
this.baseExtensions = buildExtensions(this);
|
|
@@ -15449,9 +15539,9 @@ var ViewPlugin = class _ViewPlugin {
|
|
|
15449
15539
|
Define a plugin from a constructor function that creates the
|
|
15450
15540
|
plugin's value, given an editor view.
|
|
15451
15541
|
*/
|
|
15452
|
-
static define(
|
|
15542
|
+
static define(create, spec) {
|
|
15453
15543
|
const { eventHandlers, eventObservers, provide, decorations: deco } = spec || {};
|
|
15454
|
-
return new _ViewPlugin(nextPluginID++,
|
|
15544
|
+
return new _ViewPlugin(nextPluginID++, create, eventHandlers, eventObservers, (plugin) => {
|
|
15455
15545
|
let ext = [];
|
|
15456
15546
|
if (deco)
|
|
15457
15547
|
ext.push(decorations.of((view) => {
|
|
@@ -15539,11 +15629,11 @@ function getIsolatedRanges(view, line2) {
|
|
|
15539
15629
|
RangeSet.spans(sets, line2.from, line2.to, {
|
|
15540
15630
|
point() {
|
|
15541
15631
|
},
|
|
15542
|
-
span(fromDoc, toDoc,
|
|
15632
|
+
span(fromDoc, toDoc, active2, open) {
|
|
15543
15633
|
let from = fromDoc - line2.from, to = toDoc - line2.from;
|
|
15544
15634
|
let level = result;
|
|
15545
|
-
for (let i2 =
|
|
15546
|
-
let direction =
|
|
15635
|
+
for (let i2 = active2.length - 1; i2 >= 0; i2--, open--) {
|
|
15636
|
+
let direction = active2[i2].spec.bidiIsolate, update;
|
|
15547
15637
|
if (direction == null)
|
|
15548
15638
|
direction = autoDirection(line2.text, from, to);
|
|
15549
15639
|
if (open > 0 && level.length && (update = level[level.length - 1]).to == from && update.direction == direction) {
|
|
@@ -16773,7 +16863,7 @@ var TileUpdate = class {
|
|
|
16773
16863
|
let pendingLineAttrs = null;
|
|
16774
16864
|
let b = this.builder, markCount = -1;
|
|
16775
16865
|
let openEnd = RangeSet.spans(this.decorations, from, to, {
|
|
16776
|
-
point: (from2, to2, deco,
|
|
16866
|
+
point: (from2, to2, deco, active2, openStart, index) => {
|
|
16777
16867
|
if (deco instanceof PointDecoration) {
|
|
16778
16868
|
if (this.disallowBlockEffectsFor[index]) {
|
|
16779
16869
|
if (deco.block)
|
|
@@ -16781,8 +16871,8 @@ var TileUpdate = class {
|
|
|
16781
16871
|
if (to2 > this.view.state.doc.lineAt(from2).to)
|
|
16782
16872
|
throw new RangeError("Decorations that replace line breaks may not be specified via plugins");
|
|
16783
16873
|
}
|
|
16784
|
-
markCount =
|
|
16785
|
-
if (openStart >
|
|
16874
|
+
markCount = active2.length;
|
|
16875
|
+
if (openStart > active2.length) {
|
|
16786
16876
|
b.continueWidget(to2 - from2);
|
|
16787
16877
|
} else {
|
|
16788
16878
|
let widget = deco.widget || (deco.block ? NullWidget.block : NullWidget.inline);
|
|
@@ -16794,7 +16884,7 @@ var TileUpdate = class {
|
|
|
16794
16884
|
b.addBlockWidget(tile);
|
|
16795
16885
|
} else {
|
|
16796
16886
|
b.ensureLine(pendingLineAttrs);
|
|
16797
|
-
b.addInlineWidget(tile,
|
|
16887
|
+
b.addInlineWidget(tile, active2, openStart);
|
|
16798
16888
|
}
|
|
16799
16889
|
}
|
|
16800
16890
|
pendingLineAttrs = null;
|
|
@@ -16804,7 +16894,7 @@ var TileUpdate = class {
|
|
|
16804
16894
|
if (to2 > from2)
|
|
16805
16895
|
this.text.skip(to2 - from2);
|
|
16806
16896
|
},
|
|
16807
|
-
span: (from2, to2,
|
|
16897
|
+
span: (from2, to2, active2, openStart) => {
|
|
16808
16898
|
for (let pos = from2; pos < to2; ) {
|
|
16809
16899
|
let chars = this.text.next(Math.min(512, to2 - pos));
|
|
16810
16900
|
if (chars == null) {
|
|
@@ -16813,12 +16903,12 @@ var TileUpdate = class {
|
|
|
16813
16903
|
pos++;
|
|
16814
16904
|
} else {
|
|
16815
16905
|
b.ensureLine(pendingLineAttrs);
|
|
16816
|
-
b.addText(chars,
|
|
16906
|
+
b.addText(chars, active2, pos == from2 ? openStart : active2.length);
|
|
16817
16907
|
pos += chars.length;
|
|
16818
16908
|
}
|
|
16819
16909
|
pendingLineAttrs = null;
|
|
16820
16910
|
}
|
|
16821
|
-
markCount =
|
|
16911
|
+
markCount = active2.length;
|
|
16822
16912
|
}
|
|
16823
16913
|
});
|
|
16824
16914
|
if (markCount > -1)
|
|
@@ -18807,9 +18897,9 @@ handlers.mousedown = (view, event) => {
|
|
|
18807
18897
|
if (mustFocus)
|
|
18808
18898
|
view.observer.ignore(() => {
|
|
18809
18899
|
focusPreventScroll(view.contentDOM);
|
|
18810
|
-
let
|
|
18811
|
-
if (
|
|
18812
|
-
|
|
18900
|
+
let active2 = view.root.activeElement;
|
|
18901
|
+
if (active2 && !active2.contains(view.contentDOM))
|
|
18902
|
+
active2.blur();
|
|
18813
18903
|
});
|
|
18814
18904
|
let mouseSel = view.inputState.mouseSelection;
|
|
18815
18905
|
if (mouseSel) {
|
|
@@ -23124,7 +23214,7 @@ GutterMarker.prototype.mapMode = MapMode.TrackBefore;
|
|
|
23124
23214
|
GutterMarker.prototype.startSide = GutterMarker.prototype.endSide = -1;
|
|
23125
23215
|
GutterMarker.prototype.point = true;
|
|
23126
23216
|
|
|
23127
|
-
//
|
|
23217
|
+
// node_modules/@lezer/common/dist/index.js
|
|
23128
23218
|
var DefaultBufferLength = 1024;
|
|
23129
23219
|
var nextPropID = 0;
|
|
23130
23220
|
var Range2 = class {
|
|
@@ -24748,7 +24838,7 @@ var StringInput = class {
|
|
|
24748
24838
|
};
|
|
24749
24839
|
var stoppedInner = new NodeProp({ perNode: true });
|
|
24750
24840
|
|
|
24751
|
-
//
|
|
24841
|
+
// node_modules/@lezer/highlight/dist/index.js
|
|
24752
24842
|
var nextTagID = 0;
|
|
24753
24843
|
var Tag = class _Tag {
|
|
24754
24844
|
/**
|
|
@@ -25472,7 +25562,7 @@ var classHighlighter = tagHighlighter([
|
|
|
25472
25562
|
{ tag: tags.punctuation, class: "tok-punctuation" }
|
|
25473
25563
|
]);
|
|
25474
25564
|
|
|
25475
|
-
//
|
|
25565
|
+
// node_modules/@codemirror/language/dist/index.js
|
|
25476
25566
|
var _a;
|
|
25477
25567
|
var languageDataProp = /* @__PURE__ */ new NodeProp();
|
|
25478
25568
|
function defineLanguageFacet(baseData) {
|
|
@@ -27099,7 +27189,7 @@ var marks = {
|
|
|
27099
27189
|
auto: /* @__PURE__ */ Decoration.mark({ class: "cm-iso", inclusive: true, attributes: { dir: "auto" }, bidiIsolate: null })
|
|
27100
27190
|
};
|
|
27101
27191
|
|
|
27102
|
-
//
|
|
27192
|
+
// node_modules/@codemirror/commands/dist/index.js
|
|
27103
27193
|
var toggleComment = (target) => {
|
|
27104
27194
|
let { state } = target, line2 = state.doc.lineAt(state.selection.main.from), config2 = getConfig(target.state, line2.from);
|
|
27105
27195
|
return config2.line ? toggleLineComment(target) : config2.block ? toggleBlockCommentByLine(target) : false;
|
|
@@ -28193,7 +28283,7 @@ var defaultKeymap = /* @__PURE__ */ [
|
|
|
28193
28283
|
{ key: "Ctrl-m", mac: "Shift-Alt-m", run: toggleTabFocusMode }
|
|
28194
28284
|
].concat(standardKeymap);
|
|
28195
28285
|
|
|
28196
|
-
//
|
|
28286
|
+
// node_modules/@codemirror/autocomplete/dist/index.js
|
|
28197
28287
|
var CompletionContext = class {
|
|
28198
28288
|
/**
|
|
28199
28289
|
Create a new completion context. (Mostly useful for testing
|
|
@@ -28852,7 +28942,7 @@ function scrollIntoView2(container2, element) {
|
|
|
28852
28942
|
function score(option) {
|
|
28853
28943
|
return (option.boost || 0) * 100 + (option.apply ? 10 : 0) + (option.info ? 5 : 0) + (option.type ? 1 : 0);
|
|
28854
28944
|
}
|
|
28855
|
-
function sortOptions(
|
|
28945
|
+
function sortOptions(active2, state) {
|
|
28856
28946
|
let options = [];
|
|
28857
28947
|
let sections = null, dynamicSectionScore = null;
|
|
28858
28948
|
let addOption = (option) => {
|
|
@@ -28867,7 +28957,7 @@ function sortOptions(active, state) {
|
|
|
28867
28957
|
}
|
|
28868
28958
|
};
|
|
28869
28959
|
let conf = state.facet(completionConfig);
|
|
28870
|
-
for (let a of
|
|
28960
|
+
for (let a of active2)
|
|
28871
28961
|
if (a.hasResult()) {
|
|
28872
28962
|
let getMatch = a.result.getMatch;
|
|
28873
28963
|
if (a.result.filter === false) {
|
|
@@ -28930,12 +29020,12 @@ var CompletionDialog = class _CompletionDialog {
|
|
|
28930
29020
|
setSelected(selected, id) {
|
|
28931
29021
|
return selected == this.selected || selected >= this.options.length ? this : new _CompletionDialog(this.options, makeAttrs(id, selected), this.tooltip, this.timestamp, selected, this.disabled);
|
|
28932
29022
|
}
|
|
28933
|
-
static build(
|
|
28934
|
-
if (prev && !didSetActive &&
|
|
29023
|
+
static build(active2, state, id, prev, conf, didSetActive) {
|
|
29024
|
+
if (prev && !didSetActive && active2.some((s) => s.isPending))
|
|
28935
29025
|
return prev.setDisabled();
|
|
28936
|
-
let options = sortOptions(
|
|
29026
|
+
let options = sortOptions(active2, state);
|
|
28937
29027
|
if (!options.length)
|
|
28938
|
-
return prev &&
|
|
29028
|
+
return prev && active2.some((a) => a.isPending) ? prev.setDisabled() : null;
|
|
28939
29029
|
let selected = state.facet(completionConfig).selectOnOpen ? 0 : -1;
|
|
28940
29030
|
if (prev && prev.selected != selected && prev.selected != -1) {
|
|
28941
29031
|
let selectedValue = prev.options[prev.selected].completion;
|
|
@@ -28946,7 +29036,7 @@ var CompletionDialog = class _CompletionDialog {
|
|
|
28946
29036
|
}
|
|
28947
29037
|
}
|
|
28948
29038
|
return new _CompletionDialog(options, makeAttrs(id, selected), {
|
|
28949
|
-
pos:
|
|
29039
|
+
pos: active2.reduce((a, b) => b.hasResult() ? Math.min(a, b.from) : a, 1e8),
|
|
28950
29040
|
create: createTooltip,
|
|
28951
29041
|
above: conf.aboveCursor
|
|
28952
29042
|
}, prev ? prev.timestamp : Date.now(), selected, false);
|
|
@@ -28959,8 +29049,8 @@ var CompletionDialog = class _CompletionDialog {
|
|
|
28959
29049
|
}
|
|
28960
29050
|
};
|
|
28961
29051
|
var CompletionState = class _CompletionState {
|
|
28962
|
-
constructor(
|
|
28963
|
-
this.active =
|
|
29052
|
+
constructor(active2, id, open) {
|
|
29053
|
+
this.active = active2;
|
|
28964
29054
|
this.id = id;
|
|
28965
29055
|
this.open = open;
|
|
28966
29056
|
}
|
|
@@ -28970,7 +29060,7 @@ var CompletionState = class _CompletionState {
|
|
|
28970
29060
|
update(tr) {
|
|
28971
29061
|
let { state } = tr, conf = state.facet(completionConfig);
|
|
28972
29062
|
let sources = conf.override || state.languageDataAt("autocomplete", cur(state)).map(asSource);
|
|
28973
|
-
let
|
|
29063
|
+
let active2 = sources.map((source) => {
|
|
28974
29064
|
let value = this.active.find((s) => s.source == source) || new ActiveSource(
|
|
28975
29065
|
source,
|
|
28976
29066
|
this.active.some(
|
|
@@ -28981,17 +29071,17 @@ var CompletionState = class _CompletionState {
|
|
|
28981
29071
|
);
|
|
28982
29072
|
return value.update(tr, conf);
|
|
28983
29073
|
});
|
|
28984
|
-
if (
|
|
28985
|
-
|
|
29074
|
+
if (active2.length == this.active.length && active2.every((a, i2) => a == this.active[i2]))
|
|
29075
|
+
active2 = this.active;
|
|
28986
29076
|
let open = this.open, didSet = tr.effects.some((e) => e.is(setActiveEffect));
|
|
28987
29077
|
if (open && tr.docChanged)
|
|
28988
29078
|
open = open.map(tr.changes);
|
|
28989
|
-
if (tr.selection ||
|
|
28990
|
-
open = CompletionDialog.build(
|
|
28991
|
-
else if (open && open.disabled && !
|
|
29079
|
+
if (tr.selection || active2.some((a) => a.hasResult() && tr.changes.touchesRange(a.from, a.to)) || !sameResults(active2, this.active) || didSet)
|
|
29080
|
+
open = CompletionDialog.build(active2, state, this.id, open, conf, didSet);
|
|
29081
|
+
else if (open && open.disabled && !active2.some((a) => a.isPending))
|
|
28992
29082
|
open = null;
|
|
28993
|
-
if (!open &&
|
|
28994
|
-
|
|
29083
|
+
if (!open && active2.every((a) => !a.isPending) && active2.some((a) => a.hasResult()))
|
|
29084
|
+
active2 = active2.map((a) => a.hasResult() ? new ActiveSource(
|
|
28995
29085
|
a.source,
|
|
28996
29086
|
0
|
|
28997
29087
|
/* State.Inactive */
|
|
@@ -28999,7 +29089,7 @@ var CompletionState = class _CompletionState {
|
|
|
28999
29089
|
for (let effect of tr.effects)
|
|
29000
29090
|
if (effect.is(setSelectedEffect))
|
|
29001
29091
|
open = open && open.setSelected(effect.value, this.id);
|
|
29002
|
-
return
|
|
29092
|
+
return active2 == this.active && open == this.open ? this : new _CompletionState(active2, this.id, open);
|
|
29003
29093
|
}
|
|
29004
29094
|
get tooltip() {
|
|
29005
29095
|
return this.open ? this.open.tooltip : null;
|
|
@@ -29084,9 +29174,9 @@ var ActiveSource = class _ActiveSource {
|
|
|
29084
29174
|
/* State.Inactive */
|
|
29085
29175
|
);
|
|
29086
29176
|
else if (effect.is(setActiveEffect)) {
|
|
29087
|
-
for (let
|
|
29088
|
-
if (
|
|
29089
|
-
value =
|
|
29177
|
+
for (let active2 of effect.value)
|
|
29178
|
+
if (active2.source == value.source)
|
|
29179
|
+
value = active2;
|
|
29090
29180
|
}
|
|
29091
29181
|
}
|
|
29092
29182
|
return value;
|
|
@@ -29230,8 +29320,8 @@ var closeCompletion = (view) => {
|
|
|
29230
29320
|
return true;
|
|
29231
29321
|
};
|
|
29232
29322
|
var RunningQuery = class {
|
|
29233
|
-
constructor(
|
|
29234
|
-
this.active =
|
|
29323
|
+
constructor(active2, context) {
|
|
29324
|
+
this.active = active2;
|
|
29235
29325
|
this.context = context;
|
|
29236
29326
|
this.time = Date.now();
|
|
29237
29327
|
this.updates = [];
|
|
@@ -29248,9 +29338,9 @@ var completionPlugin = /* @__PURE__ */ ViewPlugin.fromClass(class {
|
|
|
29248
29338
|
this.debounceAccept = -1;
|
|
29249
29339
|
this.pendingStart = false;
|
|
29250
29340
|
this.composing = 0;
|
|
29251
|
-
for (let
|
|
29252
|
-
if (
|
|
29253
|
-
this.startQuery(
|
|
29341
|
+
for (let active2 of view.state.field(completionState).active)
|
|
29342
|
+
if (active2.isPending)
|
|
29343
|
+
this.startQuery(active2);
|
|
29254
29344
|
}
|
|
29255
29345
|
update(update) {
|
|
29256
29346
|
let cState = update.state.field(completionState);
|
|
@@ -29295,19 +29385,19 @@ var completionPlugin = /* @__PURE__ */ ViewPlugin.fromClass(class {
|
|
|
29295
29385
|
this.debounceUpdate = -1;
|
|
29296
29386
|
this.pendingStart = false;
|
|
29297
29387
|
let { state } = this.view, cState = state.field(completionState);
|
|
29298
|
-
for (let
|
|
29299
|
-
if (
|
|
29300
|
-
this.startQuery(
|
|
29388
|
+
for (let active2 of cState.active) {
|
|
29389
|
+
if (active2.isPending && !this.running.some((r) => r.active.source == active2.source))
|
|
29390
|
+
this.startQuery(active2);
|
|
29301
29391
|
}
|
|
29302
29392
|
if (this.running.length && cState.open && cState.open.disabled)
|
|
29303
29393
|
this.debounceAccept = setTimeout(() => this.accept(), this.view.state.facet(completionConfig).updateSyncTime);
|
|
29304
29394
|
}
|
|
29305
|
-
startQuery(
|
|
29395
|
+
startQuery(active2) {
|
|
29306
29396
|
let { state } = this.view, pos = cur(state);
|
|
29307
|
-
let context = new CompletionContext(state, pos,
|
|
29308
|
-
let pending2 = new RunningQuery(
|
|
29397
|
+
let context = new CompletionContext(state, pos, active2.explicit, this.view);
|
|
29398
|
+
let pending2 = new RunningQuery(active2, context);
|
|
29309
29399
|
this.running.push(pending2);
|
|
29310
|
-
Promise.resolve(
|
|
29400
|
+
Promise.resolve(active2.source(context)).then((result) => {
|
|
29311
29401
|
if (!pending2.context.aborted) {
|
|
29312
29402
|
pending2.done = result || null;
|
|
29313
29403
|
this.scheduleAccept();
|
|
@@ -29340,26 +29430,26 @@ var completionPlugin = /* @__PURE__ */ ViewPlugin.fromClass(class {
|
|
|
29340
29430
|
if (query.done) {
|
|
29341
29431
|
let pos = cur(query.updates.length ? query.updates[0].startState : this.view.state);
|
|
29342
29432
|
let limit = Math.min(pos, query.done.from + (query.active.explicit ? 0 : 1));
|
|
29343
|
-
let
|
|
29433
|
+
let active2 = new ActiveResult(query.active.source, query.active.explicit, limit, query.done, query.done.from, (_a2 = query.done.to) !== null && _a2 !== void 0 ? _a2 : pos);
|
|
29344
29434
|
for (let tr of query.updates)
|
|
29345
|
-
|
|
29346
|
-
if (
|
|
29347
|
-
updated.push(
|
|
29435
|
+
active2 = active2.update(tr, conf);
|
|
29436
|
+
if (active2.hasResult()) {
|
|
29437
|
+
updated.push(active2);
|
|
29348
29438
|
continue;
|
|
29349
29439
|
}
|
|
29350
29440
|
}
|
|
29351
29441
|
let current2 = cState.active.find((a) => a.source == query.active.source);
|
|
29352
29442
|
if (current2 && current2.isPending) {
|
|
29353
29443
|
if (query.done == null) {
|
|
29354
|
-
let
|
|
29444
|
+
let active2 = new ActiveSource(
|
|
29355
29445
|
query.active.source,
|
|
29356
29446
|
0
|
|
29357
29447
|
/* State.Inactive */
|
|
29358
29448
|
);
|
|
29359
29449
|
for (let tr of query.updates)
|
|
29360
|
-
|
|
29361
|
-
if (!
|
|
29362
|
-
updated.push(
|
|
29450
|
+
active2 = active2.update(tr, conf);
|
|
29451
|
+
if (!active2.isPending)
|
|
29452
|
+
updated.push(active2);
|
|
29363
29453
|
} else {
|
|
29364
29454
|
this.startQuery(current2);
|
|
29365
29455
|
}
|
|
@@ -29816,12 +29906,12 @@ var theme2 = EditorView.theme({
|
|
|
29816
29906
|
"&.cm-focused .cm-selectionBackground, .cm-selectionBackground": { background: "var(--accent-soft)" }
|
|
29817
29907
|
});
|
|
29818
29908
|
var UNKNOWN = Decoration.mark({ class: "cm-unknown-field" });
|
|
29819
|
-
var ExprCode = (0,
|
|
29820
|
-
const host = (0,
|
|
29821
|
-
const view = (0,
|
|
29822
|
-
const latest2 = (0,
|
|
29909
|
+
var ExprCode = (0, import_react9.forwardRef)(function ExprCode2({ value, onChange, fields, parameters, invalid, check }, ref) {
|
|
29910
|
+
const host = (0, import_react9.useRef)(null);
|
|
29911
|
+
const view = (0, import_react9.useRef)(null);
|
|
29912
|
+
const latest2 = (0, import_react9.useRef)({ onChange, fields, parameters, check });
|
|
29823
29913
|
latest2.current = { onChange, fields, parameters, check };
|
|
29824
|
-
(0,
|
|
29914
|
+
(0, import_react9.useImperativeHandle)(ref, () => ({
|
|
29825
29915
|
insert(text) {
|
|
29826
29916
|
const v = view.current;
|
|
29827
29917
|
if (!v) return;
|
|
@@ -29835,7 +29925,7 @@ var ExprCode = (0, import_react8.forwardRef)(function ExprCode2({ value, onChang
|
|
|
29835
29925
|
view.current?.focus();
|
|
29836
29926
|
}
|
|
29837
29927
|
}));
|
|
29838
|
-
(0,
|
|
29928
|
+
(0, import_react9.useEffect)(() => {
|
|
29839
29929
|
const complete = (ctx) => {
|
|
29840
29930
|
const m = ctx.matchBefore(/(Fields|Parameters|Globals)\.\w*$/);
|
|
29841
29931
|
if (m) {
|
|
@@ -29924,8 +30014,8 @@ var SNIPPETS = {
|
|
|
29924
30014
|
function ExpressionEditor({ value, dataSet, onSave, onClose, title }) {
|
|
29925
30015
|
const def = useDesigner((s) => s.def);
|
|
29926
30016
|
const sample = useDesigner((s) => s.sample);
|
|
29927
|
-
const [text, setText] = (0,
|
|
29928
|
-
const ta = (0,
|
|
30017
|
+
const [text, setText] = (0, import_react10.useState)(value ?? "");
|
|
30018
|
+
const ta = (0, import_react10.useRef)(null);
|
|
29929
30019
|
const dsName = dataSet || def.dataSets?.[0]?.name;
|
|
29930
30020
|
const ds = def.dataSets?.find((d) => d.name === dsName);
|
|
29931
30021
|
const fields = fieldNames(ds).filter((n) => !(ds?.fields || []).some((f) => f.name === n && f.type === "object"));
|
|
@@ -29935,7 +30025,7 @@ function ExpressionEditor({ value, dataSet, onSave, onClose, title }) {
|
|
|
29935
30025
|
const insert2 = (s) => ta.current?.insert(s);
|
|
29936
30026
|
const err = checkValue(text);
|
|
29937
30027
|
const issues = err ? [] : check(text);
|
|
29938
|
-
const preview = (0,
|
|
30028
|
+
const preview = (0, import_react10.useMemo)(() => {
|
|
29939
30029
|
if (err || !sample?.dataSets) return null;
|
|
29940
30030
|
const rows = sample.dataSets[dsName] || [];
|
|
29941
30031
|
const params = Object.fromEntries((def.parameters || []).map((p) => [p.name, p.default ?? null]));
|
|
@@ -30008,7 +30098,7 @@ function ExpressionEditor({ value, dataSet, onSave, onClose, title }) {
|
|
|
30008
30098
|
}
|
|
30009
30099
|
|
|
30010
30100
|
// src/designer/CondFormat.jsx
|
|
30011
|
-
var
|
|
30101
|
+
var import_react11 = __toESM(require_react(), 1);
|
|
30012
30102
|
|
|
30013
30103
|
// src/designer/cfRules.js
|
|
30014
30104
|
var CF_OPS = ["eq", "ne", "lt", "le", "gt", "ge", "between", "top", "bottom", "aboveAvg", "belowAvg", "contains", "startsWith", "empty", "notEmpty"];
|
|
@@ -30128,7 +30218,7 @@ function CondFormat({ title, cf: start, fields, thisValue, kind, custom, onApply
|
|
|
30128
30218
|
const lang2 = useDesigner((s) => s.lang);
|
|
30129
30219
|
const T = (k, v) => t(lang2, k, v);
|
|
30130
30220
|
const blank = () => ({ field: thisValue ? void 0 : fields[0], op: "gt", value: "", format: kind === "chart" ? { backgroundColor: "#dc2626" } : { color: "#b42318", fontWeight: "bold" } });
|
|
30131
|
-
const [cf, setCf] = (0,
|
|
30221
|
+
const [cf, setCf] = (0, import_react11.useState)(() => JSON.parse(JSON.stringify(start || { mode: "first", rules: [blank()] })));
|
|
30132
30222
|
const rules = cf.rules || [];
|
|
30133
30223
|
const setRule = (i2, patch) => setCf((c) => ({ ...c, rules: c.rules.map((r, j) => j === i2 ? { ...r, ...patch } : r) }));
|
|
30134
30224
|
const setFmt = (i2, k, v) => setCf((c) => ({ ...c, rules: c.rules.map((r, j) => {
|
|
@@ -30219,7 +30309,7 @@ var catLabel = (tk, cat) => tk(`cat_${cat}`, cat);
|
|
|
30219
30309
|
function Inspector() {
|
|
30220
30310
|
const sel = useDesigner((s) => s.sel);
|
|
30221
30311
|
const def = useDesigner((s) => s.def);
|
|
30222
|
-
const [expr, setExpr] = (0,
|
|
30312
|
+
const [expr, setExpr] = (0, import_react12.useState)(null);
|
|
30223
30313
|
const openExpr = (cfg) => setExpr(cfg);
|
|
30224
30314
|
let body;
|
|
30225
30315
|
if (sel.kind === "items" && sel.ids.length > 1) body = /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Multi, { ids: sel.ids });
|
|
@@ -30234,13 +30324,13 @@ function Inspector() {
|
|
|
30234
30324
|
const one = sel.kind === "items" && sel.ids.length === 1 ? findItem(def, sel.ids[0])?.item : sel.kind === "cell" ? findItem(def, sel.id)?.item : null;
|
|
30235
30325
|
const scope = one ? one.dataSet || def.dataSets?.[0]?.name || null : void 0;
|
|
30236
30326
|
const selKey = sel.kind === "items" ? `i:${sel.ids.join(",")}` : sel.kind === "cell" ? `c:${sel.id}:${sel.part}:${sel.row}:${sel.col}:${sel.cells?.length || 0}` : `${sel.kind}:${sel.section || ""}`;
|
|
30237
|
-
const ref = (0,
|
|
30238
|
-
(0,
|
|
30327
|
+
const ref = (0, import_react12.useRef)(null);
|
|
30328
|
+
(0, import_react12.useLayoutEffect)(() => {
|
|
30239
30329
|
const pane = ref.current?.closest(".dright");
|
|
30240
30330
|
if (pane) pane.scrollTop = 0;
|
|
30241
30331
|
}, [selKey]);
|
|
30242
|
-
const [closed, setClosed] = (0,
|
|
30243
|
-
(0,
|
|
30332
|
+
const [closed, setClosed] = (0, import_react12.useState)(() => /* @__PURE__ */ new Set());
|
|
30333
|
+
(0, import_react12.useLayoutEffect)(() => {
|
|
30244
30334
|
for (const h of ref.current?.querySelectorAll(".cat > h5") || []) {
|
|
30245
30335
|
const shut = closed.has(h.textContent);
|
|
30246
30336
|
h.querySelector("button")?.setAttribute("aria-expanded", String(!shut));
|
|
@@ -30259,13 +30349,13 @@ function Inspector() {
|
|
|
30259
30349
|
});
|
|
30260
30350
|
};
|
|
30261
30351
|
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { "data-testid": "inspector", ref, onClick: toggle, children: [
|
|
30262
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(FieldScope.Provider, { value: scope, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
30352
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(FieldScope.Provider, { value: scope, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react12.Fragment, { children: body }, selKey) }),
|
|
30263
30353
|
expr && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ExpressionEditor, { ...expr, onClose: () => setExpr(null) })
|
|
30264
30354
|
] });
|
|
30265
30355
|
}
|
|
30266
|
-
function Geo({ label, value, onChange }) {
|
|
30356
|
+
function Geo({ label, value, onChange, min }) {
|
|
30267
30357
|
const unit = useDesigner((s) => s.unit);
|
|
30268
|
-
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Field, { label: `${label} (${unit})`, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(NumberInput, { value: round(fromPt(value ?? 0, unit) * 100) / 100, step: unit === "pt" ? 1 : unit === "in" ? 0.05 : 0.5, onChange: (v) => onChange(round(toPt(v, unit))) }) });
|
|
30358
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Field, { label: `${label} (${unit})`, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(NumberInput, { value: round(fromPt(value ?? 0, unit) * 100) / 100, min: min == null ? void 0 : round(fromPt(min, unit) * 100) / 100, step: unit === "pt" ? 1 : unit === "in" ? 0.05 : 0.5, onChange: (v) => onChange(round(toPt(v, unit))) }) });
|
|
30269
30359
|
}
|
|
30270
30360
|
function PropEditor({ p: spec, value, onChange, openExpr, dataSet, item }) {
|
|
30271
30361
|
const T = useT3();
|
|
@@ -30330,7 +30420,7 @@ function OverflowTarget({ value, onChange, self }) {
|
|
|
30330
30420
|
}
|
|
30331
30421
|
function ExprOr({ p, value, onChange, openExpr, dataSet, children }) {
|
|
30332
30422
|
const T = useT3();
|
|
30333
|
-
const [on, setOn] = (0,
|
|
30423
|
+
const [on, setOn] = (0, import_react12.useState)(isDynamic(value));
|
|
30334
30424
|
const label = T(on ? "useFixed" : "useExpr");
|
|
30335
30425
|
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Field, { label: p.label, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "expr-row", children: [
|
|
30336
30426
|
on ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ExprInput, { value, onChange: (v) => onChange(v || void 0), onOpen: () => openExpr({ value, dataSet, onSave: onChange, title: p.label }), placeholder: "=IIf(Fields.amount < 0, 'bold', 'normal')" }) : children,
|
|
@@ -30343,7 +30433,7 @@ function ExprOr({ p, value, onChange, openExpr, dataSet, children }) {
|
|
|
30343
30433
|
function PaletteEditor({ label, value, onChange }) {
|
|
30344
30434
|
const T = useT3();
|
|
30345
30435
|
const custom = Array.isArray(value);
|
|
30346
|
-
const [text, setText] = (0,
|
|
30436
|
+
const [text, setText] = (0, import_react12.useState)(custom ? value.join(", ") : "");
|
|
30347
30437
|
const parse2 = (t3) => t3.split(/[\s,;]+/).map((x) => x.trim()).filter((x) => /^#[0-9a-f]{6}$/i.test(x));
|
|
30348
30438
|
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: { display: "grid", gap: 6 }, children: [
|
|
30349
30439
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Field, { label, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
@@ -30370,17 +30460,18 @@ function PaletteEditor({ label, value, onChange }) {
|
|
|
30370
30460
|
custom && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: { display: "flex", gap: 3, flexWrap: "wrap" }, "aria-hidden": "true", children: value.map((c, i2) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { style: { width: 14, height: 14, borderRadius: 3, background: c, border: "1px solid var(--line)" } }, i2)) })
|
|
30371
30461
|
] });
|
|
30372
30462
|
}
|
|
30373
|
-
var
|
|
30463
|
+
var reportLists = /* @__PURE__ */ new Map();
|
|
30374
30464
|
function ReportPicker({ value, onChange }) {
|
|
30375
|
-
const [list2, setList] = (0,
|
|
30376
|
-
const listId = (0,
|
|
30377
|
-
(0,
|
|
30465
|
+
const [list2, setList] = (0, import_react12.useState)(() => reportLists.get(useDesigner.getState().embed?.server || "") || []);
|
|
30466
|
+
const listId = (0, import_react12.useState)(() => `reports-${Math.random().toString(36).slice(2, 8)}`)[0];
|
|
30467
|
+
(0, import_react12.useEffect)(() => {
|
|
30378
30468
|
const embed = useDesigner.getState().embed;
|
|
30379
|
-
if (reportList || embed && !embed.server) return;
|
|
30380
30469
|
const server2 = embed?.server || "";
|
|
30470
|
+
if (reportLists.has(server2) || embed && !embed.server) return;
|
|
30381
30471
|
fetch(`${server2}/api/reports`).then((r) => r.ok ? r.json() : []).then((l) => {
|
|
30382
|
-
|
|
30383
|
-
|
|
30472
|
+
const v = Array.isArray(l) ? l : [];
|
|
30473
|
+
reportLists.set(server2, v);
|
|
30474
|
+
setList(v);
|
|
30384
30475
|
}).catch(() => {
|
|
30385
30476
|
});
|
|
30386
30477
|
}, []);
|
|
@@ -30414,8 +30505,8 @@ function ItemProps({ item, section, openExpr }) {
|
|
|
30414
30505
|
const tk = useTk();
|
|
30415
30506
|
const def = useDesigner((s) => s.def);
|
|
30416
30507
|
const spec = ITEMS[item.type];
|
|
30417
|
-
const [nameErr, setNameErr] = (0,
|
|
30418
|
-
const [find2, setFind] = (0,
|
|
30508
|
+
const [nameErr, setNameErr] = (0, import_react12.useState)(null);
|
|
30509
|
+
const [find2, setFind] = (0, import_react12.useState)("");
|
|
30419
30510
|
const q2 = find2.trim().toLowerCase();
|
|
30420
30511
|
const hit = (p, type) => !q2 || propLabel(tk, p, type).toLowerCase().includes(q2) || p.key.toLowerCase().includes(q2);
|
|
30421
30512
|
const props = (spec?.props || []).filter((p) => (!p.showIf || p.showIf(item)) && hit(p, item.type));
|
|
@@ -30467,8 +30558,8 @@ function ItemProps({ item, section, openExpr }) {
|
|
|
30467
30558
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "grid2", children: [
|
|
30468
30559
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Geo, { label: "X", value: item.x, onChange: (v) => setGeo("x", Math.max(0, v)) }),
|
|
30469
30560
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Geo, { label: "Y", value: item.y, onChange: (v) => setGeo("y", Math.max(0, v)) }),
|
|
30470
|
-
item.type !== "table" && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Geo, { label: T("i_width"), value: item.w, onChange: (v) => setGeo("w", Math.max(0, v)) }),
|
|
30471
|
-
item.type !== "table" && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Geo, { label: T("i_height"), value: item.h, onChange: (v) => setGeo("h", Math.max(0, v)) }),
|
|
30561
|
+
item.type !== "table" && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Geo, { label: T("i_width"), value: item.w, min: item.type === "line" ? 0 : 1, onChange: (v) => setGeo("w", Math.max(0, v)) }),
|
|
30562
|
+
item.type !== "table" && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Geo, { label: T("i_height"), value: item.h, min: item.type === "line" ? 0 : 1, onChange: (v) => setGeo("h", Math.max(0, v)) }),
|
|
30472
30563
|
item.type === "table" && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Field, { label: T("tableSize"), hint: T("tableSizeHint"), children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(TextInput, { value: `${round(item.w)} × ${round(item.h)} pt`, readOnly: true, "data-testid": "table-size" }) })
|
|
30473
30564
|
] }),
|
|
30474
30565
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "hint", children: (() => {
|
|
@@ -30559,7 +30650,7 @@ function PivotEditor({ item, openExpr }) {
|
|
|
30559
30650
|
const def = useDesigner((s) => s.def);
|
|
30560
30651
|
const fields = fieldsOf2(def, item.dataSet);
|
|
30561
30652
|
const spec = normalizeMatrix(item);
|
|
30562
|
-
const [pick, setPick] = (0,
|
|
30653
|
+
const [pick, setPick] = (0, import_react12.useState)({ rowGroups: "", columnGroups: "", values: "" });
|
|
30563
30654
|
const edit = (fn3, key2) => updateItem(item.id, (it) => {
|
|
30564
30655
|
if (!isTablix(it)) {
|
|
30565
30656
|
const n = normalizeMatrix(it);
|
|
@@ -30638,7 +30729,17 @@ function PivotEditor({ item, openExpr }) {
|
|
|
30638
30729
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Field, { label: T("groupExpandLevels"), children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(NumberInput, { value: g.expandLevels ?? "", step: 1, onChange: (v) => setK(list2, i2, "expandLevels", Number.isFinite(v) && v >= 0 ? Math.round(v) : void 0) }) })
|
|
30639
30730
|
] })
|
|
30640
30731
|
] }),
|
|
30641
|
-
(i2 < spec[list2].length - 1 || list2 === "rowGroups" && g.parent) && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Check, { label: T("pivotCollapsible"), checked: g.collapsible, onChange: (v) =>
|
|
30732
|
+
(i2 < spec[list2].length - 1 || list2 === "rowGroups" && g.parent) && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Check, { label: T("pivotCollapsible"), checked: g.collapsible, onChange: (v) => edit((it) => {
|
|
30733
|
+
const o = it[list2][i2];
|
|
30734
|
+
if (v) {
|
|
30735
|
+
o.collapsible = true;
|
|
30736
|
+
o.initiallyCollapsed = true;
|
|
30737
|
+
} else {
|
|
30738
|
+
delete o.collapsible;
|
|
30739
|
+
delete o.initiallyCollapsed;
|
|
30740
|
+
}
|
|
30741
|
+
}, `${item.id}.${list2}${i2}.collapsible`) }),
|
|
30742
|
+
" ",
|
|
30642
30743
|
g.collapsible && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Check, { label: T("pivotStartCollapsed"), checked: g.initiallyCollapsed, onChange: (v) => setK(list2, i2, "initiallyCollapsed", v) }),
|
|
30643
30744
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { "data-testid": `pivot-${list2}${i2}-action`, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ActionEditor, { label: T("ux_headerAction"), value: g.action, onChange: (v) => setK(list2, i2, "action", v), openExpr, dataSet: item.dataSet }) }),
|
|
30644
30745
|
g.total && g.total !== "none" && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { "data-testid": `pivot-${list2}${i2}-total-action`, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ActionEditor, { label: T("ux_totalAction"), value: g.totalAction, onChange: (v) => setK(list2, i2, "totalAction", v), openExpr, dataSet: item.dataSet }) })
|
|
@@ -30664,7 +30765,7 @@ function PivotEditor({ item, openExpr }) {
|
|
|
30664
30765
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "grid2", children: [
|
|
30665
30766
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Field, { label: T("pivotLabel"), children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(TextInput, { value: v.label || "", onChange: (x) => setK("values", i2, "label", x) }) }),
|
|
30666
30767
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Field, { label: T("pivotFormat"), children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(TextInput, { value: v.format || "", onChange: (x) => setK("values", i2, "format", x), placeholder: "N0" }) }),
|
|
30667
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Field, { label: T("pivotShow"), children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Select, { value: v.show || "value", options: shows, onChange: (x) =>
|
|
30768
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Field, { label: T("pivotShow"), children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Select, { value: v.show || "value", options: shows, onChange: (x) => edit((it) => setMatrixShow(it.values[i2], x), `${item.id}.values${i2}.show`) }) })
|
|
30668
30769
|
] }),
|
|
30669
30770
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { "data-testid": `pivot-values${i2}-action`, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ActionEditor, { label: T("ux_cellAction"), value: v.action, onChange: (x) => setK("values", i2, "action", x), openExpr, dataSet: item.dataSet }) }),
|
|
30670
30771
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Field, { label: T("cellBookmark"), children: exprField("values", i2, "bookmark", v.bookmark, T("cellBookmark")) })
|
|
@@ -30706,8 +30807,8 @@ function GroupsEditor({ table: table2, openExpr }) {
|
|
|
30706
30807
|
const T = useT3();
|
|
30707
30808
|
const def = useDesigner((s) => s.def);
|
|
30708
30809
|
const fields = fieldsOf2(def, table2.dataSet);
|
|
30709
|
-
const [pick, setPick] = (0,
|
|
30710
|
-
const [drill, setDrill] = (0,
|
|
30810
|
+
const [pick, setPick] = (0, import_react12.useState)("");
|
|
30811
|
+
const [drill, setDrill] = (0, import_react12.useState)(false);
|
|
30711
30812
|
const setG = (i2, k, v) => updateItem(table2.id, (t3) => {
|
|
30712
30813
|
if (v === void 0 || v === "" || v === false) delete t3.groups[i2][k];
|
|
30713
30814
|
else t3.groups[i2][k] = v;
|
|
@@ -30949,7 +31050,7 @@ rimary" ? void 0 : v), "aria-label": `${T("overlayAxis")} ${i2 + 1}` }) }),
|
|
|
30949
31050
|
}
|
|
30950
31051
|
function CfButton({ label, title, target, at: at2, kind, fields, apply: apply2, testid }) {
|
|
30951
31052
|
const T = useT3();
|
|
30952
|
-
const [open, setOpen] = (0,
|
|
31053
|
+
const [open, setOpen] = (0, import_react12.useState)(false);
|
|
30953
31054
|
const n = target?.cf?.rules?.length || 0;
|
|
30954
31055
|
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
30955
31056
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("button", { type: "button", className: "btn sm", onClick: () => setOpen(true), "data-testid": testid, children: [
|
|
@@ -31016,14 +31117,16 @@ function VisualEditor({ cell, setCell, openExpr, dataSet }) {
|
|
|
31016
31117
|
}
|
|
31017
31118
|
var reportParams = /* @__PURE__ */ new Map();
|
|
31018
31119
|
function useReportParams(id) {
|
|
31019
|
-
const
|
|
31020
|
-
(0,
|
|
31120
|
+
const srv = () => useDesigner.getState().embed?.server || "";
|
|
31121
|
+
const [list2, setList] = (0, import_react12.useState)(() => reportParams.get(`${srv()} ${id}`) ?? null);
|
|
31122
|
+
(0, import_react12.useEffect)(() => {
|
|
31021
31123
|
if (!id || isDynamic(id)) {
|
|
31022
31124
|
setList(null);
|
|
31023
31125
|
return;
|
|
31024
31126
|
}
|
|
31025
|
-
|
|
31026
|
-
|
|
31127
|
+
const key2 = `${srv()} ${id}`;
|
|
31128
|
+
if (reportParams.has(key2)) {
|
|
31129
|
+
setList(reportParams.get(key2));
|
|
31027
31130
|
return;
|
|
31028
31131
|
}
|
|
31029
31132
|
let alive = true;
|
|
@@ -31036,7 +31139,7 @@ function useReportParams(id) {
|
|
|
31036
31139
|
fetch(`${server2}/api/reports/${encodeURIComponent(id)}`).then((r) => r.ok ? r.json() : null).then((r) => {
|
|
31037
31140
|
const d = r?.definition || r;
|
|
31038
31141
|
const ps = d && typeof d === "object" ? (d.parameters || []).map((p) => ({ name: p.name, required: !!p.required && p.default == null, prompt: p.prompt })) : null;
|
|
31039
|
-
if (ps) reportParams.set(
|
|
31142
|
+
if (ps) reportParams.set(key2, ps);
|
|
31040
31143
|
if (alive) setList(ps);
|
|
31041
31144
|
}).catch(() => {
|
|
31042
31145
|
if (alive) setList(null);
|
|
@@ -31050,7 +31153,7 @@ function useReportParams(id) {
|
|
|
31050
31153
|
function ParamMap({ value, onChange, known, openExpr, dataSet, testid }) {
|
|
31051
31154
|
const T = useT3();
|
|
31052
31155
|
const map = value || {};
|
|
31053
|
-
const [extra, setExtra] = (0,
|
|
31156
|
+
const [extra, setExtra] = (0, import_react12.useState)("");
|
|
31054
31157
|
const knownNames = new Set((known || []).map((p) => p.name));
|
|
31055
31158
|
const names = [...(known || []).map((p) => p.name), ...Object.keys(map).filter((k) => !knownNames.has(k))];
|
|
31056
31159
|
const set2 = (k, v, keep) => {
|
|
@@ -31469,7 +31572,7 @@ function ReportProps() {
|
|
|
31469
31572
|
const T = useT3();
|
|
31470
31573
|
const def = useDesigner((s) => s.def);
|
|
31471
31574
|
const families = useFontFamilies();
|
|
31472
|
-
const [fontsOpen, setFontsOpen] = (0,
|
|
31575
|
+
const [fontsOpen, setFontsOpen] = (0, import_react12.useState)(false);
|
|
31473
31576
|
const set2 = (fn3, key2) => useDesigner.getState().apply(fn3, key2);
|
|
31474
31577
|
const m = Array.isArray(def.page?.margins) ? def.page.margins : [36, 36, 36, 36];
|
|
31475
31578
|
const base2 = def.styles?.base || {};
|
|
@@ -31548,7 +31651,7 @@ function ReportProps() {
|
|
|
31548
31651
|
function ReportImages() {
|
|
31549
31652
|
const T = useT3();
|
|
31550
31653
|
const images = useDesigner((s) => s.def.images) || {};
|
|
31551
|
-
const [err, setErr] = (0,
|
|
31654
|
+
const [err, setErr] = (0, import_react12.useState)(null);
|
|
31552
31655
|
const set2 = (fn3) => useDesigner.getState().apply((d) => {
|
|
31553
31656
|
d.images || (d.images = {});
|
|
31554
31657
|
fn3(d.images);
|
|
@@ -31587,7 +31690,7 @@ function EmbeddedPicker({ item, onPick }) {
|
|
|
31587
31690
|
const images = useDesigner((s) => s.def.images) || {};
|
|
31588
31691
|
const names = Object.keys(images);
|
|
31589
31692
|
const cur2 = /^embedded:(.+)$/.exec(String(item.src || ""))?.[1];
|
|
31590
|
-
const [err, setErr] = (0,
|
|
31693
|
+
const [err, setErr] = (0, import_react12.useState)(null);
|
|
31591
31694
|
const upload = async (files) => {
|
|
31592
31695
|
setErr(null);
|
|
31593
31696
|
const r = await uploadImages(files, T);
|
|
@@ -31672,7 +31775,7 @@ function NamedStyles() {
|
|
|
31672
31775
|
const styleNames = useStyleNames();
|
|
31673
31776
|
const def = useDesigner((s) => s.def);
|
|
31674
31777
|
const named = def.styles?.named || {};
|
|
31675
|
-
const [newName, setNewName] = (0,
|
|
31778
|
+
const [newName, setNewName] = (0, import_react12.useState)("");
|
|
31676
31779
|
const setS = (name2, k, v) => useDesigner.getState().apply((d) => {
|
|
31677
31780
|
var _a2, _b;
|
|
31678
31781
|
d.styles || (d.styles = {});
|
|
@@ -31707,7 +31810,7 @@ function NamedStyles() {
|
|
|
31707
31810
|
}
|
|
31708
31811
|
|
|
31709
31812
|
// src/designer/DataPanel.jsx
|
|
31710
|
-
var
|
|
31813
|
+
var import_react15 = __toESM(require_react(), 1);
|
|
31711
31814
|
|
|
31712
31815
|
// src/designer/explore.js
|
|
31713
31816
|
var key = (k) => /^[A-Za-z_$][\w$]*$/.test(k) ? `.${k}` : `['${k}']`;
|
|
@@ -31743,7 +31846,7 @@ function bestRows(root) {
|
|
|
31743
31846
|
}
|
|
31744
31847
|
|
|
31745
31848
|
// src/designer/ODataEditor.jsx
|
|
31746
|
-
var
|
|
31849
|
+
var import_react13 = __toESM(require_react(), 1);
|
|
31747
31850
|
var import_jsx_runtime11 = __toESM(require_jsx_runtime(), 1);
|
|
31748
31851
|
var OPS3 = ["eq", "ne", "gt", "ge", "lt", "le", "contains", "startswith", "endswith"];
|
|
31749
31852
|
var OP_LABEL = { eq: "=", ne: "≠", gt: ">", ge: "≥", lt: "<", le: "≤" };
|
|
@@ -31758,7 +31861,7 @@ async function readMetadata(s) {
|
|
|
31758
31861
|
return odataMetadata(await res.text());
|
|
31759
31862
|
}
|
|
31760
31863
|
function ODataEditor({ s, setS, T }) {
|
|
31761
|
-
const [meta2, setMeta] = (0,
|
|
31864
|
+
const [meta2, setMeta] = (0, import_react13.useState)(null);
|
|
31762
31865
|
const sets = meta2?.sets || [];
|
|
31763
31866
|
const set2 = sets.find((x) => x.name === s.entitySet);
|
|
31764
31867
|
const props = set2 ? set2.properties : (s.select || []).map((name2) => ({ name: name2, type: s.types?.[name2] || "" }));
|
|
@@ -31849,7 +31952,7 @@ function ODataEditor({ s, setS, T }) {
|
|
|
31849
31952
|
}
|
|
31850
31953
|
|
|
31851
31954
|
// src/designer/SqlBuilder.jsx
|
|
31852
|
-
var
|
|
31955
|
+
var import_react14 = __toESM(require_react(), 1);
|
|
31853
31956
|
|
|
31854
31957
|
// src/designer/sqlBuild.js
|
|
31855
31958
|
var FILTER_OPS2 = ["=", "<>", "<", "<=", ">", ">=", "like", "in", "is null", "is not null"];
|
|
@@ -31922,8 +32025,8 @@ function normalizeSchema(body) {
|
|
|
31922
32025
|
return tables;
|
|
31923
32026
|
}
|
|
31924
32027
|
function useSchema(connection) {
|
|
31925
|
-
const [st, setSt] = (0,
|
|
31926
|
-
(0,
|
|
32028
|
+
const [st, setSt] = (0, import_react14.useState)(() => schemas.has(connection) ? { tables: schemas.get(connection) } : { loading: !!connection });
|
|
32029
|
+
(0, import_react14.useEffect)(() => {
|
|
31927
32030
|
if (!connection) {
|
|
31928
32031
|
setSt({});
|
|
31929
32032
|
return void 0;
|
|
@@ -31957,8 +32060,8 @@ function SqlBuilder({ s, setS, T, kind, onManual }) {
|
|
|
31957
32060
|
const nb = { ...b, ...patch };
|
|
31958
32061
|
setS({ ...s, builder: nb, query: buildSql(nb, kind) });
|
|
31959
32062
|
};
|
|
31960
|
-
const [find2, setFind] = (0,
|
|
31961
|
-
const [preview, setPreview] = (0,
|
|
32063
|
+
const [find2, setFind] = (0, import_react14.useState)("");
|
|
32064
|
+
const [preview, setPreview] = (0, import_react14.useState)(null);
|
|
31962
32065
|
const sql = buildSql(b, kind);
|
|
31963
32066
|
const tableOf2 = (name2) => (schema.tables || []).find((t3) => t3.name === name2);
|
|
31964
32067
|
const colsOf = (alias) => tableOf2(b.tables.find((t3) => t3.alias === alias)?.name)?.columns || [];
|
|
@@ -31987,7 +32090,7 @@ function SqlBuilder({ s, setS, T, kind, onManual }) {
|
|
|
31987
32090
|
if (from.t === to.t || b.joins.some((j) => j.from.t === from.t && j.from.c === from.c && j.to.t === to.t && j.to.c === to.c)) return;
|
|
31988
32091
|
set2({ joins: [...b.joins, { type: "inner", from, to }] });
|
|
31989
32092
|
};
|
|
31990
|
-
const offered = (0,
|
|
32093
|
+
const offered = (0, import_react14.useMemo)(() => b.tables.flatMap((t3) => suggestJoins(b, schema.tables, t3.alias)).filter((j, i2, a) => !b.joins.some((x) => x.from.t === j.from.t && x.from.c === j.from.c && x.to.t === j.to.t && x.to.c === j.to.c) && a.findIndex((y) => JSON.stringify(y) === JSON.stringify(j)) === i2), [b, schema.tables]);
|
|
31991
32094
|
const runPreview = async () => {
|
|
31992
32095
|
setPreview({ loading: true });
|
|
31993
32096
|
try {
|
|
@@ -32150,7 +32253,7 @@ function SqlBuilder({ s, setS, T, kind, onManual }) {
|
|
|
32150
32253
|
] });
|
|
32151
32254
|
}
|
|
32152
32255
|
function JoinAdder({ allCols, split, onAdd, T }) {
|
|
32153
|
-
const [a, setA] = (0,
|
|
32256
|
+
const [a, setA] = (0, import_react14.useState)(""), [z, setZ] = (0, import_react14.useState)("");
|
|
32154
32257
|
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "qb-row", children: [
|
|
32155
32258
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Select, { value: a, allowEmpty: true, options: allCols, onChange: (v) => setA(v || ""), "aria-label": T("qb_joinFrom") }),
|
|
32156
32259
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: "=" }),
|
|
@@ -32167,17 +32270,18 @@ function JoinAdder({ allCols, split, onAdd, T }) {
|
|
|
32167
32270
|
var import_jsx_runtime13 = __toESM(require_jsx_runtime(), 1);
|
|
32168
32271
|
var NAME2 = /^[A-Za-z_][\w]*$/;
|
|
32169
32272
|
var noSourceKey = (def) => (def?.dataSources || []).length ? null : "r4_noDataSource";
|
|
32170
|
-
async function loadSample() {
|
|
32171
|
-
const
|
|
32172
|
-
|
|
32273
|
+
async function loadSample(store) {
|
|
32274
|
+
const api = store?.getState ? store : activeStore();
|
|
32275
|
+
const { def } = api.getState();
|
|
32276
|
+
api.setState({ sample: { loading: true } });
|
|
32173
32277
|
try {
|
|
32174
32278
|
const params = resolveParameters(def, {});
|
|
32175
32279
|
const sources = await loadSources(def, { params, baseUrl: origin(), sqlPreview: true, fetch: reportFetch(origin(), void 0, { sqlPreview: true }) });
|
|
32176
32280
|
const ctx = { params, globals: { ExecutionTime: /* @__PURE__ */ new Date() }, dataSets: {}, fields: null, locale: def.locale, currency: def.currency, functions: functionTable(def) };
|
|
32177
32281
|
const dataSets = buildDataSets(def, sources, ctx);
|
|
32178
|
-
|
|
32282
|
+
api.setState({ sample: { dataSets, sources, at: Date.now() } });
|
|
32179
32283
|
} catch (e) {
|
|
32180
|
-
|
|
32284
|
+
api.setState({ sample: { error: e.message } });
|
|
32181
32285
|
}
|
|
32182
32286
|
}
|
|
32183
32287
|
function DataPanel() {
|
|
@@ -32185,8 +32289,8 @@ function DataPanel() {
|
|
|
32185
32289
|
const lang2 = useDesigner((s) => s.lang);
|
|
32186
32290
|
const T = (k, v) => t(lang2, k, v);
|
|
32187
32291
|
const sample = useDesigner((s) => s.sample);
|
|
32188
|
-
const [dlg, setDlg] = (0,
|
|
32189
|
-
const [open, setOpen] = (0,
|
|
32292
|
+
const [dlg, setDlg] = (0, import_react15.useState)(null);
|
|
32293
|
+
const [open, setOpen] = (0, import_react15.useState)(() => new Set((def.dataSets || []).map((d) => d.name)));
|
|
32190
32294
|
const toggle = (n) => setOpen((s) => {
|
|
32191
32295
|
const x = new Set(s);
|
|
32192
32296
|
x.has(n) ? x.delete(n) : x.add(n);
|
|
@@ -32335,10 +32439,10 @@ function ParamDialog({ index, onClose }) {
|
|
|
32335
32439
|
const lang2 = useDesigner((s) => s.lang);
|
|
32336
32440
|
const T = (k, v) => t(lang2, k, v);
|
|
32337
32441
|
const orig = index != null ? def.parameters[index] : null;
|
|
32338
|
-
const [p, setP] = (0,
|
|
32339
|
-
const [columns, setColumns] = (0,
|
|
32340
|
-
const [live, setLive] = (0,
|
|
32341
|
-
const [choicesText, setChoicesText] = (0,
|
|
32442
|
+
const [p, setP] = (0, import_react15.useState)(orig || { name: "", type: "string", prompt: "", default: "", required: false });
|
|
32443
|
+
const [columns, setColumns] = (0, import_react15.useState)(String(def.parameterLayout?.columns || 1));
|
|
32444
|
+
const [live, setLive] = (0, import_react15.useState)(def.liveParameters !== false);
|
|
32445
|
+
const [choicesText, setChoicesText] = (0, import_react15.useState)(() => (p.options || []).map(optionLine).join("\n"));
|
|
32342
32446
|
const fromFields = (def.dataSets?.find((d) => d.name === p.optionsFrom?.dataSet)?.fields || []).map((f) => f.name);
|
|
32343
32447
|
const labelOpts = [...fromFields.map((f) => ({ value: `=Fields.${f}`, label: f })), ...p.optionsFrom?.label && !fromFields.some((f) => `=Fields.${f}` === p.optionsFrom.label) ? [{ value: p.optionsFrom.label, label: p.optionsFrom.label }] : []];
|
|
32344
32448
|
const err = !NAME2.test(p.name) ? T("paramNameRule") : !uniqueIn(def.parameters, p.name, index) ? T("paramNameTaken") : p.optionsFrom && !p.optionsFrom.value ? T("ux_paramPickValueField") : null;
|
|
@@ -32485,7 +32589,7 @@ function SourceDialog({ index, onClose }) {
|
|
|
32485
32589
|
const lang2 = useDesigner((s2) => s2.lang);
|
|
32486
32590
|
const T = (k, v) => t(lang2, k, v);
|
|
32487
32591
|
const orig = index != null ? def.dataSources[index] : null;
|
|
32488
|
-
const [s, setS] = (0,
|
|
32592
|
+
const [s, setS] = (0, import_react15.useState)(() => ({
|
|
32489
32593
|
name: "",
|
|
32490
32594
|
type: "rest",
|
|
32491
32595
|
method: "GET",
|
|
@@ -32549,11 +32653,11 @@ function SourceDialog({ index, onClose }) {
|
|
|
32549
32653
|
if (!err && s.type === "sql" && !s.connection) err = "Pick a connection";
|
|
32550
32654
|
if (!err && s.type === "sql" && s.procedure != null && !s.procedure) err = "Pick a stored procedure";
|
|
32551
32655
|
if (!err && s.type === "sql" && s.procedure == null && !/^\s*(select|with)\b/i.test(s.query || "")) err = "Write a SELECT query";
|
|
32552
|
-
const [conns, setConns] = (0,
|
|
32656
|
+
const [conns, setConns] = (0, import_react15.useState)(null);
|
|
32553
32657
|
const procs = (conns || []).find((c) => c.name === s.connection)?.procs || [];
|
|
32554
32658
|
const sqlKind = (conns || []).find((c) => c.name === s.connection)?.kind || "sqlite";
|
|
32555
|
-
const [probe, setProbe] = (0,
|
|
32556
|
-
(0,
|
|
32659
|
+
const [probe, setProbe] = (0, import_react15.useState)(null);
|
|
32660
|
+
(0, import_react15.useEffect)(() => {
|
|
32557
32661
|
if (s.type !== "sql" || conns) return;
|
|
32558
32662
|
fetch("/api/data/sql/connections").then((r) => r.ok ? r.json() : []).then(setConns).catch(() => setConns([]));
|
|
32559
32663
|
}, [s.type, conns]);
|
|
@@ -32746,13 +32850,13 @@ function DataSetDialog({ index, onClose, onSaved }) {
|
|
|
32746
32850
|
const lang2 = useDesigner((s) => s.lang);
|
|
32747
32851
|
const T = (k, v) => t(lang2, k, v);
|
|
32748
32852
|
const orig = index != null ? def.dataSets[index] : null;
|
|
32749
|
-
const [d, setD] = (0,
|
|
32750
|
-
const [detect, setDetect] = (0,
|
|
32751
|
-
const [pathTyped, setPathTyped] = (0,
|
|
32853
|
+
const [d, setD] = (0, import_react15.useState)(() => ({ name: "", source: def.dataSources?.[0]?.name, path: "$", fields: [], sort: [], ...orig ? JSON.parse(JSON.stringify(orig)) : {} }));
|
|
32854
|
+
const [detect, setDetect] = (0, import_react15.useState)({ state: "idle" });
|
|
32855
|
+
const [pathTyped, setPathTyped] = (0, import_react15.useState)(!!orig);
|
|
32752
32856
|
const nested = !!d.relation;
|
|
32753
32857
|
const parents = (def.dataSets || []).filter((x, i2) => i2 !== index && x.name !== d.name);
|
|
32754
32858
|
const err = !NAME2.test(d.name) ? T("dsNameRule") : !uniqueIn(def.dataSets, d.name, index) ? T("dsNameTaken") : nested ? !d.relation.parent ? T("dsPickParent") : null : !d.source ? T("dsPickSource") : null;
|
|
32755
|
-
const [explore, setExplore] = (0,
|
|
32859
|
+
const [explore, setExplore] = (0, import_react15.useState)(null);
|
|
32756
32860
|
const loadSourceRaw = async (name2) => {
|
|
32757
32861
|
const params = resolveParameters(useDesigner.getState().def, {});
|
|
32758
32862
|
const src = useDesigner.getState().def.dataSources.find((s) => s.name === name2);
|
|
@@ -33002,7 +33106,7 @@ function DataSetDialog({ index, onClose, onSaved }) {
|
|
|
33002
33106
|
}
|
|
33003
33107
|
|
|
33004
33108
|
// src/designer/Outline.jsx
|
|
33005
|
-
var
|
|
33109
|
+
var import_react16 = __toESM(require_react(), 1);
|
|
33006
33110
|
var import_jsx_runtime14 = __toESM(require_jsx_runtime(), 1);
|
|
33007
33111
|
var MIME = "application/x-pw-outline";
|
|
33008
33112
|
function Outline() {
|
|
@@ -33011,11 +33115,32 @@ function Outline() {
|
|
|
33011
33115
|
const lang2 = useDesigner((s) => s.lang);
|
|
33012
33116
|
const readOnly2 = useDesigner((s) => s.readOnly);
|
|
33013
33117
|
const T = (k, v) => t(lang2, k, v);
|
|
33014
|
-
const [drop, setDrop] = (0,
|
|
33015
|
-
const [said, setSaid] = (0,
|
|
33016
|
-
const
|
|
33017
|
-
const
|
|
33118
|
+
const [drop, setDrop] = (0, import_react16.useState)(null);
|
|
33119
|
+
const [said, setSaid] = (0, import_react16.useState)("");
|
|
33120
|
+
const [cur2, setCur] = (0, import_react16.useState)(null);
|
|
33121
|
+
const dragged = (0, import_react16.useRef)(null);
|
|
33122
|
+
const body = (0, import_react16.useRef)(null);
|
|
33018
33123
|
const chosen = new Set(sel.kind === "items" ? sel.ids : sel.kind === "cell" ? [sel.id] : []);
|
|
33124
|
+
const keys = sectionList(def).flatMap(({ key: key2 }) => {
|
|
33125
|
+
const out = [`band:${key2}`];
|
|
33126
|
+
const go = (l) => l.forEach((it) => {
|
|
33127
|
+
out.push(it.id);
|
|
33128
|
+
if (NESTING.has(it.type)) go(it.items || []);
|
|
33129
|
+
});
|
|
33130
|
+
go(secOf(def, key2)?.items || []);
|
|
33131
|
+
return out;
|
|
33132
|
+
});
|
|
33133
|
+
const stop = keys.includes(cur2) ? cur2 : keys.find((k) => chosen.has(k) || sel.kind === "section" && k === `band:${sel.section}`) || keys[0];
|
|
33134
|
+
const roving = (k) => ({ tabIndex: k === stop ? 0 : -1, onFocus: () => setCur(k) });
|
|
33135
|
+
const nav2 = (e) => {
|
|
33136
|
+
if (e.defaultPrevented || e.altKey || e.metaKey || e.ctrlKey || e.target.getAttribute("role") !== "option") return;
|
|
33137
|
+
const all = [...e.currentTarget.querySelectorAll("[role=option]")];
|
|
33138
|
+
const i2 = all.indexOf(e.target);
|
|
33139
|
+
const j = e.key === "ArrowDown" ? i2 + 1 : e.key === "ArrowUp" ? i2 - 1 : e.key === "Home" ? 0 : e.key === "End" ? all.length - 1 : null;
|
|
33140
|
+
if (j == null) return;
|
|
33141
|
+
e.preventDefault();
|
|
33142
|
+
all[Math.max(0, Math.min(all.length - 1, j))]?.focus();
|
|
33143
|
+
};
|
|
33019
33144
|
const pick = (e, id) => {
|
|
33020
33145
|
const st = useDesigner.getState();
|
|
33021
33146
|
if (e.shiftKey && st.sel.kind === "items") {
|
|
@@ -33127,30 +33252,32 @@ function Outline() {
|
|
|
33127
33252
|
};
|
|
33128
33253
|
const rows = (list2, parent, depth, section) => list2.map((it, i2) => {
|
|
33129
33254
|
const mark = drop && drop.id != null && drop.id === it.id ? ` drop-${drop.where}` : "";
|
|
33130
|
-
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("li", { children: [
|
|
33255
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("li", { role: "none", children: [
|
|
33131
33256
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: `trow outline-row${chosen.has(it.id) ? " sel" : ""}${mark}`, style: { paddingInlineStart: depth * 14 }, "data-outline": it.name, "data-outline-id": it.id, ...dragProps(it, i2, parent, section), children: [
|
|
33132
33257
|
!readOnly2 && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "grip", "aria-hidden": "true", children: "⠿" }),
|
|
33133
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", className: "linklike nm", onClick: (e) => pick(e, it.id), onKeyDown: (e) => onKey(e, it, list2, i2, parent), "aria-
|
|
33258
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", role: "option", className: "linklike nm", onClick: (e) => pick(e, it.id), onKeyDown: (e) => onKey(e, it, list2, i2, parent), "aria-selected": chosen.has(it.id), "aria-describedby": readOnly2 ? "outline-nav" : "outline-nav outline-keys", ...roving(it.id), children: it.name }),
|
|
33134
33259
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "ty", children: T(`item_${it.type}`) === `item_${it.type}` ? ITEMS[it.type]?.label || it.type : T(`item_${it.type}`) }),
|
|
33135
33260
|
!readOnly2 && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "act", style: { display: "inline-flex", gap: 2 }, children: [
|
|
33136
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", className: "btn sm ghost icon", disabled: i2 === 0, onClick: () => reorderItem(it.id, -1), title: T("outlineBackward"), "aria-label": `${T("outlineBackward")}: ${it.name}`, children: "↑" }),
|
|
33137
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", className: "btn sm ghost icon", disabled: i2 === list2.length - 1, onClick: () => reorderItem(it.id, 1), title: T("outlineForward"), "aria-label": `${T("outlineForward")}: ${it.name}`, children: "↓" }),
|
|
33138
|
-
parent && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", className: "btn sm ghost icon", onClick: () => moveOutOfParent(it.id), title: T("outlineMoveOut", { name: parent.name }), "aria-label": `${T("outlineMoveOut", { name: parent.name })}: ${it.name}`, children: "⇱" })
|
|
33261
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", className: "btn sm ghost icon", tabIndex: -1, disabled: i2 === 0, onClick: () => reorderItem(it.id, -1), title: T("outlineBackward"), "aria-label": `${T("outlineBackward")}: ${it.name}`, children: "↑" }),
|
|
33262
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", className: "btn sm ghost icon", tabIndex: -1, disabled: i2 === list2.length - 1, onClick: () => reorderItem(it.id, 1), title: T("outlineForward"), "aria-label": `${T("outlineForward")}: ${it.name}`, children: "↓" }),
|
|
33263
|
+
parent && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", className: "btn sm ghost icon", tabIndex: -1, onClick: () => moveOutOfParent(it.id), title: T("outlineMoveOut", { name: parent.name }), "aria-label": `${T("outlineMoveOut", { name: parent.name })}: ${it.name}`, children: "⇱" })
|
|
33139
33264
|
] })
|
|
33140
33265
|
] }),
|
|
33141
|
-
NESTING.has(it.type) && (it.items || []).length > 0 && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("ul", { className: "tree", children: rows(it.items, it, depth + 1, section) })
|
|
33266
|
+
NESTING.has(it.type) && (it.items || []).length > 0 && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("ul", { className: "tree", role: "none", children: rows(it.items, it, depth + 1, section) })
|
|
33142
33267
|
] }, it.id);
|
|
33143
33268
|
});
|
|
33144
33269
|
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "pane", "data-testid": "outline", children: [
|
|
33145
33270
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h4", { children: T("outline") }),
|
|
33146
33271
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "pane-body", ref: body, children: [
|
|
33147
|
-
sectionList(def).map(({ key: key2, label }) => {
|
|
33272
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { role: "listbox", "aria-label": T("outline"), "aria-multiselectable": "true", onKeyDown: nav2, children: sectionList(def).map(({ key: key2, label }) => {
|
|
33148
33273
|
const items = secOf(def, key2)?.items || [];
|
|
33149
|
-
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: `outline-sec${drop?.band === key2 ? " drop-band" : ""}`, "data-outline-band": key2, ...bandDrop(key2), children: [
|
|
33150
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", className: `linklike outline-band${sel.kind === "section" && sel.section === key2 ? " sel" : ""}`, onClick: () => useDesigner.getState().select({ kind: "section", section: key2 }),
|
|
33151
|
-
|
|
33274
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { role: "group", "aria-label": label, className: `outline-sec${drop?.band === key2 ? " drop-band" : ""}`, "data-outline-band": key2, ...bandDrop(key2), children: [
|
|
33275
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", role: "option", "aria-selected": sel.kind === "section" && sel.section === key2, "aria-describedby": "outline-nav", className: `linklike outline-band${sel.kind === "section" && sel.section === key2 ? " sel" : ""}`, onClick: () => useDesigner.getState().select({ kind: "section", section: key2 }), ...roving(`band:${key2}`),
|
|
33276
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("b", { children: label }) }),
|
|
33277
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("ul", { className: "tree", role: "none", children: items.length ? rows(items, null, 1, key2) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("li", { className: "subtle", role: "none", children: T("outlineEmpty") }) })
|
|
33152
33278
|
] }, key2);
|
|
33153
|
-
}),
|
|
33279
|
+
}) }),
|
|
33280
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "sr-only", id: "outline-nav", children: T("b9_outlineKeys") }),
|
|
33154
33281
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "hint", children: T("outlineHint") }),
|
|
33155
33282
|
!readOnly2 && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "hint", id: "outline-keys", children: T("outlineKeys") }),
|
|
33156
33283
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "sr-only", role: "status", "aria-live": "polite", children: said })
|
|
@@ -33159,7 +33286,7 @@ function Outline() {
|
|
|
33159
33286
|
}
|
|
33160
33287
|
|
|
33161
33288
|
// src/theme/ThemeToggle.jsx
|
|
33162
|
-
var
|
|
33289
|
+
var import_react17 = __toESM(require_react(), 1);
|
|
33163
33290
|
|
|
33164
33291
|
// src/theme/theme.js
|
|
33165
33292
|
var THEME_KEY = "pw-theme";
|
|
@@ -33201,8 +33328,8 @@ function Icon2({ pref }) {
|
|
|
33201
33328
|
] });
|
|
33202
33329
|
}
|
|
33203
33330
|
function ThemeToggle({ className = "btn sm ghost icon" }) {
|
|
33204
|
-
const [pref, setPref] = (0,
|
|
33205
|
-
(0,
|
|
33331
|
+
const [pref, setPref] = (0, import_react17.useState)("system");
|
|
33332
|
+
(0, import_react17.useEffect)(() => {
|
|
33206
33333
|
setPref(readPreference());
|
|
33207
33334
|
const mq = window.matchMedia("(prefers-color-scheme: dark)");
|
|
33208
33335
|
const onChange = () => {
|
|
@@ -33220,7 +33347,7 @@ function ThemeToggle({ className = "btn sm ghost icon" }) {
|
|
|
33220
33347
|
}
|
|
33221
33348
|
|
|
33222
33349
|
// src/designer/ChartWizard.jsx
|
|
33223
|
-
var
|
|
33350
|
+
var import_react18 = __toESM(require_react(), 1);
|
|
33224
33351
|
var import_jsx_runtime16 = __toESM(require_jsx_runtime(), 1);
|
|
33225
33352
|
var TYPES = ["column", "bar", "line", "area", "pie", "donut", "scatter", "bubble", "radar", "funnel", "gauge", "treemap", "histogram", "boxplot", "waterfall", "gantt"];
|
|
33226
33353
|
var PER_ROW = /* @__PURE__ */ new Set(["scatter", "bubble"]);
|
|
@@ -33336,14 +33463,14 @@ function ChartWizard() {
|
|
|
33336
33463
|
const close = () => useDesigner.getState().setUi({ wizard: null });
|
|
33337
33464
|
const lang2 = useDesigner((s) => s.lang);
|
|
33338
33465
|
const tr = (k, v) => t(lang2, `cw_${k}`, v);
|
|
33339
|
-
const [c, setC] = (0,
|
|
33466
|
+
const [c, setC] = (0, import_react18.useState)(() => {
|
|
33340
33467
|
if (editing) return configFromChart(editing);
|
|
33341
33468
|
const score2 = (d) => ((d.fields || []).some((f) => f.type === "number") ? 1e6 : 0) + (sample?.dataSets?.[d.name]?.length || 0);
|
|
33342
33469
|
const ds2 = [...def.dataSets || []].sort((a, b) => score2(b) - score2(a))[0];
|
|
33343
33470
|
return { title: "", split: "", stacked: false, format: "N0", ...guess(ds2, sample?.dataSets?.[ds2?.name] || []) };
|
|
33344
33471
|
});
|
|
33345
33472
|
const set2 = (patch) => setC((x) => ({ ...x, ...patch, custom: false }));
|
|
33346
|
-
(0,
|
|
33473
|
+
(0, import_react18.useEffect)(() => {
|
|
33347
33474
|
if (!sample?.dataSets && !sample?.loading) loadSample();
|
|
33348
33475
|
}, []);
|
|
33349
33476
|
const ds = (def.dataSets || []).find((d) => d.name === c.dataSet);
|
|
@@ -33354,7 +33481,7 @@ function ChartWizard() {
|
|
|
33354
33481
|
const good = suggested(c, rows, fields);
|
|
33355
33482
|
const dateCategory = fields.find((f) => f.name === c.category)?.type === "date";
|
|
33356
33483
|
const monthish = fields.find((f) => f.name === c.category)?.type === "number" && /month/i.test(c.category) && rows.length > 0 && rows.every((r) => r[c.category] == null || Number.isInteger(r[c.category]) && r[c.category] >= 1 && r[c.category] <= 12);
|
|
33357
|
-
const compact = (0,
|
|
33484
|
+
const compact = (0, import_react18.useMemo)(() => {
|
|
33358
33485
|
if (!c.value || c.agg === "Count" || c.format === "P1") return null;
|
|
33359
33486
|
const per = /* @__PURE__ */ new Map();
|
|
33360
33487
|
for (const r of rows) {
|
|
@@ -33370,14 +33497,14 @@ function ChartWizard() {
|
|
|
33370
33497
|
const d = def.dataSets.find((x) => x.name === name2);
|
|
33371
33498
|
setC((x) => ({ ...x, split: "", ...guess(d, sample?.dataSets?.[name2] || []) }));
|
|
33372
33499
|
};
|
|
33373
|
-
(0,
|
|
33500
|
+
(0, import_react18.useEffect)(() => {
|
|
33374
33501
|
if (editing || !rows.length || c.touched) return;
|
|
33375
33502
|
setC((x) => ({ ...x, ...guess(ds, rows), touched: true }));
|
|
33376
33503
|
}, [rows.length]);
|
|
33377
|
-
const [thumbs, setThumbs] = (0,
|
|
33378
|
-
const [big, setBig] = (0,
|
|
33504
|
+
const [thumbs, setThumbs] = (0, import_react18.useState)({});
|
|
33505
|
+
const [big, setBig] = (0, import_react18.useState)(null);
|
|
33379
33506
|
const cfgKey = JSON.stringify({ ...c, touched: void 0 });
|
|
33380
|
-
(0,
|
|
33507
|
+
(0, import_react18.useEffect)(() => {
|
|
33381
33508
|
if (!sample?.dataSets || !c.dataSet) return;
|
|
33382
33509
|
let alive = true;
|
|
33383
33510
|
const t3 = setTimeout(async () => {
|
|
@@ -33565,7 +33692,7 @@ function rawText(raw) {
|
|
|
33565
33692
|
}
|
|
33566
33693
|
|
|
33567
33694
|
// src/designer/TableWizard.jsx
|
|
33568
|
-
var
|
|
33695
|
+
var import_react19 = __toESM(require_react(), 1);
|
|
33569
33696
|
var import_jsx_runtime17 = __toESM(require_jsx_runtime(), 1);
|
|
33570
33697
|
var LAYOUTS = [
|
|
33571
33698
|
{ id: "list", label: "List", when: "Every row, with totals" },
|
|
@@ -33578,12 +33705,13 @@ function TableWizard() {
|
|
|
33578
33705
|
const wiz = useDesigner((s) => s.tableWizard);
|
|
33579
33706
|
const def = useDesigner((s) => s.def);
|
|
33580
33707
|
const sample = useDesigner((s) => s.sample);
|
|
33708
|
+
const lang2 = useDesigner((s) => s.lang);
|
|
33581
33709
|
const close = () => useDesigner.getState().setUi({ tableWizard: null });
|
|
33582
33710
|
const parent = wiz?.parentId ? findItem(def, wiz.parentId)?.item : null;
|
|
33583
33711
|
const width = Math.max(120, Math.round((parent ? parent.w : bodyWidth(def, wiz?.section || "body")) - (wiz?.x || 0)));
|
|
33584
|
-
const [c, setC] = (0,
|
|
33712
|
+
const [c, setC] = (0, import_react19.useState)(() => ({ dataSet: wiz?.dataSet || def.dataSets?.[0]?.name, layout: wiz?.type === "matrix" ? "matrix" : "list", groupBy: "", fields: null, mRows: "", mCols: "", mValue: "" }));
|
|
33585
33713
|
const set2 = (patch) => setC((x) => ({ ...x, ...patch }));
|
|
33586
|
-
(0,
|
|
33714
|
+
(0, import_react19.useEffect)(() => {
|
|
33587
33715
|
if (!sample?.dataSets && !sample?.loading) loadSample();
|
|
33588
33716
|
}, []);
|
|
33589
33717
|
const ds = (def.dataSets || []).find((d) => d.name === c.dataSet);
|
|
@@ -33597,9 +33725,9 @@ function TableWizard() {
|
|
|
33597
33725
|
const groupBy2 = c.groupBy || groupGuess;
|
|
33598
33726
|
const mRows = c.mRows || groupBy2, mCols = c.mCols || text.find((f) => f.name !== mRows)?.name || "", mValue = c.mValue || nums[0]?.name || "";
|
|
33599
33727
|
const itemFor = (layout, w) => layout === "matrix" ? mRows && mCols ? matrixFor(ds, { rows: mRows, columns: mCols, value: mValue, agg: mValue ? "Sum" : "Count", width: w, sample: rows, currency: def.currency }) : null : tableFor(ds, { layout, groupBy: groupBy2, width: w, rows, fields: chosen, currency: def.currency });
|
|
33600
|
-
const [thumbs, setThumbs] = (0,
|
|
33728
|
+
const [thumbs, setThumbs] = (0, import_react19.useState)({});
|
|
33601
33729
|
const key2 = JSON.stringify([c, groupBy2, mRows, mCols, mValue, chosen]);
|
|
33602
|
-
(0,
|
|
33730
|
+
(0, import_react19.useEffect)(() => {
|
|
33603
33731
|
if (!ds || !sample?.dataSets) return;
|
|
33604
33732
|
let alive = true;
|
|
33605
33733
|
const t3 = setTimeout(async () => {
|
|
@@ -33644,7 +33772,7 @@ function TableWizard() {
|
|
|
33644
33772
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("button", { className: "btn ghost", onClick: () => {
|
|
33645
33773
|
useDesigner.getState().setUi({ tableWizard: null, pivotWizard: { section: wiz.section, x: wiz.x, y: wiz.y, parentId: wiz.parentId, dataSet: c.dataSet } });
|
|
33646
33774
|
}, "data-testid": "open-pivot-wizard", children: [
|
|
33647
|
-
t(
|
|
33775
|
+
t(lang2, "pivotWizard"),
|
|
33648
33776
|
"…"
|
|
33649
33777
|
] }),
|
|
33650
33778
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("button", { className: "btn", onClick: close, children: "Cancel" }),
|
|
@@ -33657,7 +33785,7 @@ function TableWizard() {
|
|
|
33657
33785
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("section", { className: "cw-side", "aria-label": "Data for the table", children: [
|
|
33658
33786
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Field, { label: "Data set", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Select, { value: c.dataSet, options: (def.dataSets || []).map((d) => d.name), onChange: (v) => set2({ dataSet: v, fields: null, groupBy: "", mRows: "", mCols: "", mValue: "" }) }) }),
|
|
33659
33787
|
sample?.loading && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "hint", children: "Calling the API…" }),
|
|
33660
|
-
noSourceKey(def) && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "hint", role: "status", "data-testid": "no-source", children: t(
|
|
33788
|
+
noSourceKey(def) && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "hint", role: "status", "data-testid": "no-source", children: t(lang2, noSourceKey(def)) }),
|
|
33661
33789
|
sample?.error && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "err", children: sample.error }),
|
|
33662
33790
|
c.layout !== "matrix" && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
|
|
33663
33791
|
c.layout !== "list" && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Field, { label: "Group by", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Select, { value: groupBy2, options: text.map((f) => f.name), onChange: (v) => set2({ groupBy: v }) }) }),
|
|
@@ -33687,7 +33815,7 @@ function TableWizard() {
|
|
|
33687
33815
|
}
|
|
33688
33816
|
|
|
33689
33817
|
// src/designer/AskAi.jsx
|
|
33690
|
-
var
|
|
33818
|
+
var import_react20 = __toESM(require_react(), 1);
|
|
33691
33819
|
var import_jsx_runtime18 = __toESM(require_jsx_runtime(), 1);
|
|
33692
33820
|
var trim = (v, n = 200) => Array.isArray(v) ? v.slice(0, n).map((x) => trim(x, n)) : v && typeof v === "object" ? Object.fromEntries(Object.entries(v).map(([k, x]) => [k, trim(x, n)])) : v;
|
|
33693
33821
|
function changes(before, after) {
|
|
@@ -33703,9 +33831,9 @@ function changes(before, after) {
|
|
|
33703
33831
|
function AskAi({ onClose }) {
|
|
33704
33832
|
const def = useDesigner((s) => s.def);
|
|
33705
33833
|
const sample = useDesigner((s) => s.sample);
|
|
33706
|
-
const [prompt, setPrompt] = (0,
|
|
33707
|
-
const [st, setSt] = (0,
|
|
33708
|
-
(0,
|
|
33834
|
+
const [prompt, setPrompt] = (0, import_react20.useState)("");
|
|
33835
|
+
const [st, setSt] = (0, import_react20.useState)({ state: "idle" });
|
|
33836
|
+
(0, import_react20.useEffect)(() => {
|
|
33709
33837
|
if (!sample?.dataSets && !sample?.loading) loadSample();
|
|
33710
33838
|
}, []);
|
|
33711
33839
|
const ask = async () => {
|
|
@@ -33719,7 +33847,7 @@ function AskAi({ onClose }) {
|
|
|
33719
33847
|
let preview = null;
|
|
33720
33848
|
try {
|
|
33721
33849
|
const params = resolveParameters(out.definition, {}, { lenient: true });
|
|
33722
|
-
const model = await render(out.definition, { fontStore:
|
|
33850
|
+
const model = await render(out.definition, { fontStore: await loadFontStore(), parameters: params, sources: sources ? Object.fromEntries((out.definition.dataSources || []).map((s) => [s.name, sources[s.name] ?? (s.type === "json" ? s.data : [])])) : void 0, baseUrl: origin(), fetch: reportFetch(origin()) });
|
|
33723
33851
|
preview = { html: pageToSvg(model.pages[0], model.width, model.height), pages: model.pages.length };
|
|
33724
33852
|
} catch (e) {
|
|
33725
33853
|
preview = { error: e.message };
|
|
@@ -33790,7 +33918,7 @@ function AskAi({ onClose }) {
|
|
|
33790
33918
|
}
|
|
33791
33919
|
|
|
33792
33920
|
// src/designer/PivotWizard.jsx
|
|
33793
|
-
var
|
|
33921
|
+
var import_react21 = __toESM(require_react(), 1);
|
|
33794
33922
|
var import_jsx_runtime19 = __toESM(require_jsx_runtime(), 1);
|
|
33795
33923
|
var MIME_PF = "application/x-pw-pivot-field";
|
|
33796
33924
|
var AGGS2 = ["Sum", "Avg", "Count", "Min", "Max"];
|
|
@@ -33822,9 +33950,9 @@ function Thumb({ item }) {
|
|
|
33822
33950
|
const T = useT2();
|
|
33823
33951
|
const def = useDesigner((s) => s.def);
|
|
33824
33952
|
const sample = useDesigner((s) => s.sample);
|
|
33825
|
-
const [svg, setSvg] = (0,
|
|
33953
|
+
const [svg, setSvg] = (0, import_react21.useState)(null);
|
|
33826
33954
|
const key2 = JSON.stringify(item);
|
|
33827
|
-
(0,
|
|
33955
|
+
(0, import_react21.useEffect)(() => {
|
|
33828
33956
|
if (!item || !sample?.dataSets) return void 0;
|
|
33829
33957
|
let alive = true;
|
|
33830
33958
|
const t3 = setTimeout(() => {
|
|
@@ -33846,7 +33974,7 @@ function Thumb({ item }) {
|
|
|
33846
33974
|
function useData(name2) {
|
|
33847
33975
|
const def = useDesigner((s) => s.def);
|
|
33848
33976
|
const sample = useDesigner((s) => s.sample);
|
|
33849
|
-
(0,
|
|
33977
|
+
(0, import_react21.useEffect)(() => {
|
|
33850
33978
|
if (!sample?.dataSets && !sample?.loading) loadSample();
|
|
33851
33979
|
}, []);
|
|
33852
33980
|
const ds = (def.dataSets || []).find((d) => d.name === name2);
|
|
@@ -33861,10 +33989,10 @@ function placeOf(w, def) {
|
|
|
33861
33989
|
function PivotWizard() {
|
|
33862
33990
|
const T = useT2();
|
|
33863
33991
|
const w = useDesigner((s) => s.pivotWizard);
|
|
33864
|
-
const [dsName, setDs] = (0,
|
|
33992
|
+
const [dsName, setDs] = (0, import_react21.useState)(() => w?.dataSet || useDesigner.getState().def.dataSets?.[0]?.name);
|
|
33865
33993
|
const { def, ds, fields, rows } = useData(dsName);
|
|
33866
|
-
const [lay, setLay] = (0,
|
|
33867
|
-
const [totals, setTotals] = (0,
|
|
33994
|
+
const [lay, setLay] = (0, import_react21.useState)({ rows: [], columns: [], values: [] });
|
|
33995
|
+
const [totals, setTotals] = (0, import_react21.useState)(true);
|
|
33868
33996
|
const close = () => useDesigner.getState().setUi({ pivotWizard: null });
|
|
33869
33997
|
const width = Math.round(bodyWidth(def, w?.section || "body") - (w?.x || 0));
|
|
33870
33998
|
const add = (zone2, f) => setLay((l) => {
|
|
@@ -33985,13 +34113,13 @@ function InstantVisuals() {
|
|
|
33985
34113
|
const T = useT2();
|
|
33986
34114
|
const w = useDesigner((s) => s.instantVisuals);
|
|
33987
34115
|
const { def, ds, fields, rows } = useData(w?.dataSet);
|
|
33988
|
-
const [picked, setPickedRaw] = (0,
|
|
33989
|
-
const [touched, setTouched] = (0,
|
|
34116
|
+
const [picked, setPickedRaw] = (0, import_react21.useState)(() => instantPicks(ds?.fields || [], rows));
|
|
34117
|
+
const [touched, setTouched] = (0, import_react21.useState)(false);
|
|
33990
34118
|
const setPicked = (fn3) => {
|
|
33991
34119
|
setTouched(true);
|
|
33992
34120
|
setPickedRaw(fn3);
|
|
33993
34121
|
};
|
|
33994
|
-
(0,
|
|
34122
|
+
(0, import_react21.useEffect)(() => {
|
|
33995
34123
|
if (!touched) setPickedRaw(instantPicks(ds?.fields || [], rows));
|
|
33996
34124
|
}, [rows.length, ds]);
|
|
33997
34125
|
const close = () => useDesigner.getState().setUi({ instantVisuals: null });
|
|
@@ -34191,9 +34319,10 @@ var TOOLS = [
|
|
|
34191
34319
|
] }) }
|
|
34192
34320
|
];
|
|
34193
34321
|
function Toolbox({ T, hide = [] }) {
|
|
34322
|
+
const api = useDesignerStore();
|
|
34194
34323
|
const name2 = (type) => T(`item_${type}`) === `item_${type}` ? ITEMS[type].label : T(`item_${type}`);
|
|
34195
34324
|
const add = (type) => {
|
|
34196
|
-
const s =
|
|
34325
|
+
const s = api.getState();
|
|
34197
34326
|
const at2 = insertSpot(s.def, s.sel);
|
|
34198
34327
|
insertItem(type, at2.section, 0, at2.y, {}, at2.parentId);
|
|
34199
34328
|
};
|
|
@@ -34242,12 +34371,15 @@ var TbGroup = ({ label, children }) => /* @__PURE__ */ (0, import_jsx_runtime20.
|
|
|
34242
34371
|
] });
|
|
34243
34372
|
var QUICK = [["textbox", "text"], ["table", "table"], ["chart", "chart"], ["image", "image"]];
|
|
34244
34373
|
function LeftRail({ T, readOnly: readOnly2, embed }) {
|
|
34245
|
-
const body = (0,
|
|
34246
|
-
const [at2, setAt] = (0,
|
|
34374
|
+
const body = (0, import_react22.useRef)(null);
|
|
34375
|
+
const [at2, setAt] = (0, import_react22.useState)("tools");
|
|
34247
34376
|
const tabs = [!readOnly2 && ["tools", "b2_toolbox", "tools"], embed?.panels?.data !== false && ["data", "b2_data", "data"], ["outline", "b2_outline", "outline"]].filter(Boolean);
|
|
34248
34377
|
const go = (id) => {
|
|
34249
34378
|
const el = body.current?.querySelector(`[data-rail="${id}"]`);
|
|
34250
|
-
if (el)
|
|
34379
|
+
if (el) {
|
|
34380
|
+
body.current.scrollTo({ top: el.offsetTop - body.current.offsetTop, behavior: "smooth" });
|
|
34381
|
+
(el.querySelector('[role=listbox] [tabindex="0"]') || el.querySelector("button, input, select, textarea"))?.focus({ preventScroll: true });
|
|
34382
|
+
}
|
|
34251
34383
|
setAt(id);
|
|
34252
34384
|
};
|
|
34253
34385
|
const spy = () => {
|
|
@@ -34349,8 +34481,9 @@ var framed = () => {
|
|
|
34349
34481
|
}
|
|
34350
34482
|
};
|
|
34351
34483
|
function useAutosave(id, T, lang2, user) {
|
|
34352
|
-
const
|
|
34353
|
-
(0,
|
|
34484
|
+
const api = useDesignerStore();
|
|
34485
|
+
const [offer, setOffer] = (0, import_react22.useState)(null);
|
|
34486
|
+
(0, import_react22.useEffect)(() => {
|
|
34354
34487
|
if (!id || user == null || framed()) return void 0;
|
|
34355
34488
|
let store;
|
|
34356
34489
|
try {
|
|
@@ -34360,10 +34493,10 @@ function useAutosave(id, T, lang2, user) {
|
|
|
34360
34493
|
}
|
|
34361
34494
|
clearDrafts(store, user);
|
|
34362
34495
|
const d = readDraft(store, user, id);
|
|
34363
|
-
if (d && plain(mergeDraft(d.def,
|
|
34496
|
+
if (d && plain(mergeDraft(d.def, api.getState().def)) !== plain(api.getState().def)) setOffer(d);
|
|
34364
34497
|
else if (d) clearDraft(store, user, id);
|
|
34365
34498
|
const keep = () => {
|
|
34366
|
-
const s =
|
|
34499
|
+
const s = api.getState();
|
|
34367
34500
|
if (!s.saved && !s.readOnly) writeDraft(store, user, id, s.def, Date.now(), s.rev || null);
|
|
34368
34501
|
};
|
|
34369
34502
|
const t3 = setInterval(keep, AUTOSAVE_MS);
|
|
@@ -34372,7 +34505,7 @@ function useAutosave(id, T, lang2, user) {
|
|
|
34372
34505
|
};
|
|
34373
34506
|
window.addEventListener("pagehide", keep);
|
|
34374
34507
|
document.addEventListener("visibilitychange", hide);
|
|
34375
|
-
const unsub =
|
|
34508
|
+
const unsub = api.subscribe((s, prev) => {
|
|
34376
34509
|
if (s.saved && !prev.saved) clearDraft(store, user, id);
|
|
34377
34510
|
});
|
|
34378
34511
|
return () => {
|
|
@@ -34384,13 +34517,13 @@ function useAutosave(id, T, lang2, user) {
|
|
|
34384
34517
|
}, [id, user]);
|
|
34385
34518
|
if (!offer) return null;
|
|
34386
34519
|
const when = new Date(offer.at).toLocaleString(lang2 === "en" ? "en-IN" : lang2, { dateStyle: "medium", timeStyle: "short" });
|
|
34387
|
-
const stale = staleDraft(offer,
|
|
34520
|
+
const stale = staleDraft(offer, api.getState().rev);
|
|
34388
34521
|
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "draft-bar", role: "alert", "data-testid": "draft-offer", "data-stale": stale || void 0, children: [
|
|
34389
34522
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { children: T(stale ? "ux_draftStale" : "ux_draftFound", { when }) }),
|
|
34390
34523
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { className: `btn sm${stale ? "" : " primary"}`, "data-testid": "draft-restore", onClick: () => {
|
|
34391
|
-
const d = mergeDraft(offer.def,
|
|
34392
|
-
|
|
34393
|
-
|
|
34524
|
+
const d = mergeDraft(offer.def, api.getState().def);
|
|
34525
|
+
api.getState().apply(() => JSON.parse(JSON.stringify(d)));
|
|
34526
|
+
api.getState().fixSelection();
|
|
34394
34527
|
setOffer(null);
|
|
34395
34528
|
}, children: T(stale ? "ux_draftRestoreAnyway" : "ux_draftRestore") }),
|
|
34396
34529
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { className: "btn sm", "data-testid": "draft-discard", onClick: () => {
|
|
@@ -34403,12 +34536,13 @@ function useAutosave(id, T, lang2, user) {
|
|
|
34403
34536
|
] });
|
|
34404
34537
|
}
|
|
34405
34538
|
function ConflictBar({ T }) {
|
|
34539
|
+
const api = useDesignerStore();
|
|
34406
34540
|
const conflict = useDesigner((s) => s.conflict);
|
|
34407
34541
|
if (!conflict) return null;
|
|
34408
34542
|
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "draft-bar", role: "alert", "data-testid": "save-conflict", children: [
|
|
34409
34543
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { children: T("ux_conflict") }),
|
|
34410
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { className: "btn sm", "data-testid": "conflict-mine", onClick: () =>
|
|
34411
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { className: "btn sm", "data-testid": "conflict-theirs", onClick: () =>
|
|
34544
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { className: "btn sm", "data-testid": "conflict-mine", onClick: () => api.getState().save({ overwrite: true }), children: T("ux_conflictMine") }),
|
|
34545
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { className: "btn sm", "data-testid": "conflict-theirs", onClick: () => api.getState().takeTheirs(), children: T("ux_conflictTheirs") })
|
|
34412
34546
|
] });
|
|
34413
34547
|
}
|
|
34414
34548
|
var AL = (d) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("svg", { width: "16", height: "14", viewBox: "0 0 16 14", "aria-hidden": "true", children: d });
|
|
@@ -34458,7 +34592,7 @@ var ALIGN2 = [
|
|
|
34458
34592
|
];
|
|
34459
34593
|
function AlignBar({ T }) {
|
|
34460
34594
|
const sel = useDesigner((s) => s.sel);
|
|
34461
|
-
const [toPage, setToPage] = (0,
|
|
34595
|
+
const [toPage, setToPage] = (0, import_react22.useState)(false);
|
|
34462
34596
|
if (sel.kind !== "items" || !sel.ids.length) return null;
|
|
34463
34597
|
const n = sel.ids.length;
|
|
34464
34598
|
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { className: "align-bar", role: "toolbar", "aria-label": T("ux_alignBar"), "data-testid": "align-bar", children: [
|
|
@@ -34473,13 +34607,14 @@ function AlignBar({ T }) {
|
|
|
34473
34607
|
] });
|
|
34474
34608
|
}
|
|
34475
34609
|
function IssuesButton({ T }) {
|
|
34610
|
+
const api = useDesignerStore();
|
|
34476
34611
|
const issues = useDesignIssues();
|
|
34477
|
-
const [open, setOpen] = (0,
|
|
34478
|
-
(0,
|
|
34612
|
+
const [open, setOpen] = (0, import_react22.useState)(false);
|
|
34613
|
+
(0, import_react22.useEffect)(() => {
|
|
34479
34614
|
if (!issues.length) setOpen(false);
|
|
34480
34615
|
}, [issues.length]);
|
|
34481
|
-
const listRef = (0,
|
|
34482
|
-
(0,
|
|
34616
|
+
const listRef = (0, import_react22.useRef)(null);
|
|
34617
|
+
(0, import_react22.useLayoutEffect)(() => {
|
|
34483
34618
|
const el = listRef.current;
|
|
34484
34619
|
if (!el) return void 0;
|
|
34485
34620
|
const place = () => {
|
|
@@ -34496,7 +34631,7 @@ function IssuesButton({ T }) {
|
|
|
34496
34631
|
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { className: "issues-wrap", children: [
|
|
34497
34632
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", className: "btn sm issues-btn", "aria-expanded": open, onClick: () => setOpen((v) => !v), "data-testid": "issues", children: T("ux_issues", { n: issues.length }) }),
|
|
34498
34633
|
open && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("ul", { className: "issues-list", "data-testid": "issues-list", ref: listRef, children: issues.map((i2, k) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", className: "linklike", onClick: () => {
|
|
34499
|
-
if (i2.id)
|
|
34634
|
+
if (i2.id) api.getState().select({ kind: "items", ids: [i2.id] });
|
|
34500
34635
|
}, children: issueLine(T, i2) }) }, k)) })
|
|
34501
34636
|
] });
|
|
34502
34637
|
}
|
|
@@ -34520,9 +34655,10 @@ var SHORTCUTS = [
|
|
|
34520
34655
|
["?", "sc_help"]
|
|
34521
34656
|
];
|
|
34522
34657
|
function HistoryDialog({ id, onClose, T, lang: lang2 }) {
|
|
34523
|
-
const
|
|
34524
|
-
const [
|
|
34525
|
-
(0,
|
|
34658
|
+
const api = useDesignerStore();
|
|
34659
|
+
const [list2, setList] = (0, import_react22.useState)(null);
|
|
34660
|
+
const [err, setErr] = (0, import_react22.useState)(null);
|
|
34661
|
+
(0, import_react22.useEffect)(() => {
|
|
34526
34662
|
fetch(`/api/reports/${id}/versions`).then((r) => r.json()).then(setList).catch((e) => setErr(e.message));
|
|
34527
34663
|
}, [id]);
|
|
34528
34664
|
const restore = async (v) => {
|
|
@@ -34532,7 +34668,7 @@ function HistoryDialog({ id, onClose, T, lang: lang2 }) {
|
|
|
34532
34668
|
return;
|
|
34533
34669
|
}
|
|
34534
34670
|
const def = await res.json();
|
|
34535
|
-
|
|
34671
|
+
api.getState().init(id, def);
|
|
34536
34672
|
onClose();
|
|
34537
34673
|
};
|
|
34538
34674
|
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(Dialog, { title: T("versionHistory"), onClose, footer: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { className: "btn", onClick: onClose, children: T("close") }), children: [
|
|
@@ -34554,18 +34690,48 @@ function HistoryDialog({ id, onClose, T, lang: lang2 }) {
|
|
|
34554
34690
|
] }, v.version))
|
|
34555
34691
|
] });
|
|
34556
34692
|
}
|
|
34557
|
-
function Designer({
|
|
34693
|
+
function Designer({ store: storeIn = null, ...props }) {
|
|
34694
|
+
const [store] = (0, import_react22.useState)(() => {
|
|
34695
|
+
const s = storeIn || newDesignerStore();
|
|
34696
|
+
activateStore(s);
|
|
34697
|
+
return s;
|
|
34698
|
+
});
|
|
34699
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DesignerStore.Provider, { value: store, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DesignerIn, { ...props }) });
|
|
34700
|
+
}
|
|
34701
|
+
var ACTIVATE = [
|
|
34702
|
+
"onPointerDownCapture",
|
|
34703
|
+
"onMouseDownCapture",
|
|
34704
|
+
"onKeyDownCapture",
|
|
34705
|
+
"onFocusCapture",
|
|
34706
|
+
"onClickCapture",
|
|
34707
|
+
"onInputCapture",
|
|
34708
|
+
"onChangeCapture",
|
|
34709
|
+
"onDragStartCapture",
|
|
34710
|
+
"onDragOverCapture",
|
|
34711
|
+
"onDropCapture",
|
|
34712
|
+
"onPasteCapture",
|
|
34713
|
+
"onWheelCapture",
|
|
34714
|
+
"onContextMenuCapture",
|
|
34715
|
+
"onDoubleClickCapture",
|
|
34716
|
+
"onSubmitCapture"
|
|
34717
|
+
];
|
|
34718
|
+
function DesignerIn({ id, initial, rev = null, lang: langIn, embed = null, user = null, ai = false }) {
|
|
34719
|
+
const api = useDesignerStore();
|
|
34720
|
+
const activators = (0, import_react22.useMemo)(() => {
|
|
34721
|
+
const on = () => activateStore(api);
|
|
34722
|
+
return Object.fromEntries(ACTIVATE.map((k) => [k, on]));
|
|
34723
|
+
}, [api]);
|
|
34558
34724
|
const lang2 = pickLang(langIn);
|
|
34559
34725
|
const T = (k, v) => t(lang2, k, v);
|
|
34560
34726
|
const q2 = lang2 === "en" ? "" : `?lang=${encodeURIComponent(lang2)}`;
|
|
34561
|
-
const ready = (0,
|
|
34727
|
+
const ready = (0, import_react22.useRef)(false);
|
|
34562
34728
|
if (!ready.current && typeof window !== "undefined") {
|
|
34563
|
-
|
|
34564
|
-
|
|
34729
|
+
api.getState().init(id, initial);
|
|
34730
|
+
api.getState().setUi({ lang: lang2, embed, readOnly: !!embed?.readOnly, rev, conflict: null });
|
|
34565
34731
|
ready.current = true;
|
|
34566
34732
|
}
|
|
34567
34733
|
const readOnly2 = !!embed?.readOnly;
|
|
34568
|
-
const rootRef = (0,
|
|
34734
|
+
const rootRef = (0, import_react22.useRef)(null);
|
|
34569
34735
|
const def = useDesigner((s) => s.def);
|
|
34570
34736
|
const tab = useDesigner((s) => s.tab);
|
|
34571
34737
|
const saved = useDesigner((s) => s.saved);
|
|
@@ -34575,23 +34741,23 @@ function Designer({ id, initial, rev = null, lang: langIn, embed = null, user =
|
|
|
34575
34741
|
const snap = useDesigner((s) => s.snap);
|
|
34576
34742
|
const unit = useDesigner((s) => s.unit);
|
|
34577
34743
|
const fonts = useDesigner((s) => s.fonts);
|
|
34578
|
-
const fontCss = (0,
|
|
34579
|
-
(0,
|
|
34744
|
+
const fontCss = (0, import_react22.useMemo)(() => fontFaceCss(allFontKeys(), fontsBase().replace(/\/$/, "")), [fonts]);
|
|
34745
|
+
(0, import_react22.useEffect)(() => {
|
|
34580
34746
|
if (embed) declareDocumentStyles("pw-designer-fonts", fontCss);
|
|
34581
34747
|
}, [embed, fontCss]);
|
|
34582
|
-
(0,
|
|
34583
|
-
customFonts().then((list2) =>
|
|
34748
|
+
(0, import_react22.useEffect)(() => {
|
|
34749
|
+
customFonts().then((list2) => api.getState().setUi({ fonts: list2 }));
|
|
34584
34750
|
}, []);
|
|
34585
|
-
(0,
|
|
34751
|
+
(0, import_react22.useEffect)(() => {
|
|
34586
34752
|
const z = savedZoom();
|
|
34587
|
-
if (z != null)
|
|
34753
|
+
if (z != null) api.getState().setUi({ zoom: z });
|
|
34588
34754
|
}, []);
|
|
34589
34755
|
const canUndo = useDesigner((s) => s.past.length > 0);
|
|
34590
34756
|
const canRedo = useDesigner((s) => s.future.length > 0);
|
|
34591
|
-
const st =
|
|
34592
|
-
const [dialog, setDialog] = (0,
|
|
34593
|
-
const [showLeft, setShowLeft] = (0,
|
|
34594
|
-
const [showRight, setShowRight] = (0,
|
|
34757
|
+
const st = api.getState;
|
|
34758
|
+
const [dialog, setDialog] = (0, import_react22.useState)(null);
|
|
34759
|
+
const [showLeft, setShowLeft] = (0, import_react22.useState)(true);
|
|
34760
|
+
const [showRight, setShowRight] = (0, import_react22.useState)(true);
|
|
34595
34761
|
const selKind = useDesigner((s) => s.sel.kind);
|
|
34596
34762
|
const wizard = useDesigner((s) => s.wizard);
|
|
34597
34763
|
const tableWizard = useDesigner((s) => s.tableWizard);
|
|
@@ -34600,12 +34766,18 @@ function Designer({ id, initial, rev = null, lang: langIn, embed = null, user =
|
|
|
34600
34766
|
const cells = useDesigner((s) => s.cells);
|
|
34601
34767
|
const cellSize = useDesigner((s) => s.cellSize);
|
|
34602
34768
|
const dataKey = useDesigner((s) => `${(s.def?.dataSources || []).map((x) => x.name)}|${(s.def?.dataSets || []).map((x) => x.name)}`);
|
|
34603
|
-
(0,
|
|
34604
|
-
loadSample();
|
|
34769
|
+
(0, import_react22.useEffect)(() => {
|
|
34770
|
+
loadSample(api);
|
|
34605
34771
|
}, [dataKey]);
|
|
34606
|
-
(0,
|
|
34772
|
+
(0, import_react22.useEffect)(() => {
|
|
34773
|
+
let lastInside = false;
|
|
34774
|
+
const inside = (e) => (e.composedPath?.() || []).includes(rootRef.current);
|
|
34775
|
+
const onDown = (e) => {
|
|
34776
|
+
lastInside = inside(e);
|
|
34777
|
+
};
|
|
34778
|
+
const ours = (e) => inside(e) || lastInside && (e.target === document.body || e.target === document.documentElement);
|
|
34607
34779
|
const onKey = (e) => {
|
|
34608
|
-
if (embed && !(e
|
|
34780
|
+
if (embed && !ours(e)) return;
|
|
34609
34781
|
const mod = e.metaKey || e.ctrlKey;
|
|
34610
34782
|
if (mod && e.key.toLowerCase() === "s") {
|
|
34611
34783
|
e.preventDefault();
|
|
@@ -34624,7 +34796,7 @@ function Designer({ id, initial, rev = null, lang: langIn, embed = null, user =
|
|
|
34624
34796
|
st().save();
|
|
34625
34797
|
return;
|
|
34626
34798
|
}
|
|
34627
|
-
if (isTyping(e) || st().tab !== "design") return;
|
|
34799
|
+
if (isTyping(e) || st().tab !== "design" || e.defaultPrevented) return;
|
|
34628
34800
|
if (mod && e.key.toLowerCase() === "z") {
|
|
34629
34801
|
e.preventDefault();
|
|
34630
34802
|
e.shiftKey ? st().redo() : st().undo();
|
|
@@ -34647,11 +34819,7 @@ function Designer({ id, initial, rev = null, lang: langIn, embed = null, user =
|
|
|
34647
34819
|
}
|
|
34648
34820
|
return;
|
|
34649
34821
|
}
|
|
34650
|
-
if (mod && e.key.toLowerCase() === "v")
|
|
34651
|
-
e.preventDefault();
|
|
34652
|
-
pasteItems(st().sel.kind === "section" ? st().sel.section : "body");
|
|
34653
|
-
return;
|
|
34654
|
-
}
|
|
34822
|
+
if (mod && e.key.toLowerCase() === "v") return;
|
|
34655
34823
|
if (e.key === "Delete" || e.key === "Backspace") {
|
|
34656
34824
|
if (st().sel.kind === "items") {
|
|
34657
34825
|
e.preventDefault();
|
|
@@ -34683,10 +34851,24 @@ function Designer({ id, initial, rev = null, lang: langIn, embed = null, user =
|
|
|
34683
34851
|
e.returnValue = "";
|
|
34684
34852
|
}
|
|
34685
34853
|
};
|
|
34854
|
+
const onPaste = (e) => {
|
|
34855
|
+
if (embed && !ours(e) || isTyping(e) || st().tab !== "design") return;
|
|
34856
|
+
e.preventDefault();
|
|
34857
|
+
if (!pasteItems(st().sel.kind === "section" ? st().sel.section : "body", e.clipboardData?.getData("text/plain"))) {
|
|
34858
|
+
st().setUi({ saveError: t(lang2, "b9_nothingToPaste") });
|
|
34859
|
+
setTimeout(() => st().setUi({ saveError: null }), 3e3);
|
|
34860
|
+
}
|
|
34861
|
+
};
|
|
34686
34862
|
window.addEventListener("keydown", onKey);
|
|
34863
|
+
window.addEventListener("paste", onPaste);
|
|
34864
|
+
window.addEventListener("pointerdown", onDown, true);
|
|
34865
|
+
window.addEventListener("focusin", onDown, true);
|
|
34687
34866
|
if (!embed) window.addEventListener("beforeunload", onLeave);
|
|
34688
34867
|
return () => {
|
|
34689
34868
|
window.removeEventListener("keydown", onKey);
|
|
34869
|
+
window.removeEventListener("paste", onPaste);
|
|
34870
|
+
window.removeEventListener("pointerdown", onDown, true);
|
|
34871
|
+
window.removeEventListener("focusin", onDown, true);
|
|
34690
34872
|
window.removeEventListener("beforeunload", onLeave);
|
|
34691
34873
|
};
|
|
34692
34874
|
}, [st, embed]);
|
|
@@ -34705,17 +34887,17 @@ function Designer({ id, initial, rev = null, lang: langIn, embed = null, user =
|
|
|
34705
34887
|
const d = await embed.onOpen();
|
|
34706
34888
|
if (d && typeof d === "object") {
|
|
34707
34889
|
st().init(id, d);
|
|
34708
|
-
loadSample();
|
|
34890
|
+
loadSample(api);
|
|
34709
34891
|
}
|
|
34710
34892
|
};
|
|
34711
|
-
const importInput = (0,
|
|
34712
|
-
const [imported, setImported] = (0,
|
|
34893
|
+
const importInput = (0, import_react22.useRef)(null);
|
|
34894
|
+
const [imported, setImported] = (0, import_react22.useState)(null);
|
|
34713
34895
|
const importFile = async (file) => {
|
|
34714
34896
|
if (!file) return;
|
|
34715
34897
|
const r = readReportFile(file.name, await file.text());
|
|
34716
34898
|
if (r.definition) {
|
|
34717
34899
|
st().init(id, r.definition);
|
|
34718
|
-
loadSample();
|
|
34900
|
+
loadSample(api);
|
|
34719
34901
|
}
|
|
34720
34902
|
setImported({ name: file.name, ok: !!r.definition, warnings: r.warnings || [], error: r.error });
|
|
34721
34903
|
};
|
|
@@ -34729,7 +34911,7 @@ function Designer({ id, initial, rev = null, lang: langIn, embed = null, user =
|
|
|
34729
34911
|
] }),
|
|
34730
34912
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "hint", children: T("loadingDesigner") })
|
|
34731
34913
|
] }) });
|
|
34732
|
-
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "designer", "data-testid": "designer", dir: dirOf(lang2), lang: lang2, ref: rootRef, "data-readonly": readOnly2 || void 0, children: [
|
|
34914
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "designer", "data-testid": "designer", dir: dirOf(lang2), lang: lang2, ref: rootRef, "data-readonly": readOnly2 || void 0, ...activators, children: [
|
|
34733
34915
|
!embed && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("style", { children: fontCss }),
|
|
34734
34916
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("header", { className: "dtop dbar", children: [
|
|
34735
34917
|
embed ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { className: "brand", children: [
|
|
@@ -34836,7 +35018,7 @@ function Designer({ id, initial, rev = null, lang: langIn, embed = null, user =
|
|
|
34836
35018
|
imported.warnings.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("ul", { children: imported.warnings.map((w, i2) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("li", { children: w }, i2)) })
|
|
34837
35019
|
] }),
|
|
34838
35020
|
dialog === "keys" && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Dialog, { title: T("shortcuts"), onClose: () => setDialog(null), footer: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { className: "btn", onClick: () => setDialog(null), children: T("close") }), children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "kbd-grid", children: SHORTCUTS.map(([k, d]) => /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
34839
|
-
|
|
35021
|
+
import_react22.Fragment, { children: [
|
|
34840
35022
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "kbd", children: k }),
|
|
34841
35023
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { children: T(d) })
|
|
34842
35024
|
] }, d)) }) }),
|
|
@@ -34918,6 +35100,7 @@ var CSS2 = true ? `/* Layout: a drafting table. Cool grey workspace, white paper
|
|
|
34918
35100
|
--ink: #16202a;
|
|
34919
35101
|
--muted: #5f6b77;
|
|
34920
35102
|
--faint: #64717e; /* 5:1 on panel (was #8e99a4, 2.9:1) */
|
|
35103
|
+
--faint-desk: #5a6672; /* small text on the desk: 4.85:1 on #e6eaee (--faint is 4.13:1 there) */
|
|
34921
35104
|
--line-strong: #848f9b; /* control borders, 3:1 */
|
|
34922
35105
|
--accent: #0e7490;
|
|
34923
35106
|
--accent-ink: #ffffff;
|
|
@@ -34971,6 +35154,7 @@ var CSS2 = true ? `/* Layout: a drafting table. Cool grey workspace, white paper
|
|
|
34971
35154
|
--ink: #e6edf3;
|
|
34972
35155
|
--muted: #a3afbb;
|
|
34973
35156
|
--faint: #8693a0;
|
|
35157
|
+
--faint-desk: #8693a0;
|
|
34974
35158
|
--accent: #3cbfd4;
|
|
34975
35159
|
--accent-ink: #03222a;
|
|
34976
35160
|
--accent-soft: #123a44;
|
|
@@ -35309,7 +35493,7 @@ a.cell-name:hover { color: var(--accent); }
|
|
|
35309
35493
|
.tbl .grip { position: absolute; left: -18px; top: -18px; width: 14px; height: 14px; border-radius: 3px; background: var(--panel-2); border: 1px solid var(--line); display: grid; place-items: center; cursor: move; font-size: var(--fs-2xs); color: var(--muted); }
|
|
35310
35494
|
.tbl.sel .grip { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
|
|
35311
35495
|
.tbl .row { position: relative; display: flex; }
|
|
35312
|
-
.tbl .row-tag { position: absolute; left: -18px; width: 14px; display: grid; place-items: center; font: var(--fs-2xs) var(--mono); color: var(--faint); height: 100%; }
|
|
35496
|
+
.tbl .row-tag { position: absolute; left: -18px; width: 14px; display: grid; place-items: center; font: var(--fs-2xs) var(--mono); color: var(--faint-desk); height: 100%; }
|
|
35313
35497
|
.tbl .cell { position: relative; overflow: hidden; display: flex; border-right: 1px dashed rgba(95,107,119,.3); border-bottom: 1px dashed rgba(95,107,119,.3); cursor: cell; }
|
|
35314
35498
|
.tbl .cell:first-child { border-left: 1px dashed rgba(95,107,119,.3); }
|
|
35315
35499
|
.tbl .row:first-child .cell { border-top: 1px dashed rgba(95,107,119,.3); }
|
|
@@ -35451,6 +35635,7 @@ a.cell-name:hover { color: var(--accent); }
|
|
|
35451
35635
|
.vfrozen-head { position: absolute; top: 0; background: var(--paper); box-shadow: 0 3px 8px rgba(16, 24, 40, .18); pointer-events: none; }
|
|
35452
35636
|
.vfrozen-head svg { display: block; width: 100%; height: 100%; }
|
|
35453
35637
|
.search .opt { font-size: var(--fs-xs); font-weight: var(--fw-strong); }
|
|
35638
|
+
.search .opt .ww::before { content: "ab"; text-decoration: underline; } /* CSS, not text: the name is "Whole word" alone */
|
|
35454
35639
|
.search .opt[aria-pressed="true"] { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); }
|
|
35455
35640
|
.vmatches button { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
35456
35641
|
.vmatches button[aria-current] { background: var(--accent-soft); color: var(--accent); }
|
|
@@ -35828,13 +36013,14 @@ input[type=checkbox], input[type=radio] { width: 16px; height: 16px; accent-colo
|
|
|
35828
36013
|
|
|
35829
36014
|
.pw-embed{display:block;font:var(--fw-regular) var(--fs-base)/var(--lh) var(--ui);color:var(--ink);background:var(--desk);border:1px solid var(--line);border-radius:8px;overflow:hidden}
|
|
35830
36015
|
` : "";
|
|
35831
|
-
var BLANK = { $schema: "pagewright/report@1", name: "
|
|
36016
|
+
var BLANK = { $schema: "pagewright/report@1", name: "Untitled report", page: { size: "A4", margins: [36, 36, 36, 36] }, dataSources: [], dataSets: [], sections: { body: { items: [] } } };
|
|
35832
36017
|
function mountDesigner(target, opts = {}) {
|
|
35833
36018
|
const el = typeof target === "string" ? document.querySelector(target) : target;
|
|
35834
36019
|
if (!el) throw new Error(`mountDesigner: no element for ${target}`);
|
|
35835
36020
|
const server2 = String(opts.server || "").replace(/\/$/, "");
|
|
35836
36021
|
setAssetBase(server2);
|
|
35837
36022
|
setStandalone({ standalone: !server2, fontsUrl: opts.fontsUrl });
|
|
36023
|
+
setFetchPolicy({ allowHosts: opts.allowHosts, unsafeFetch: opts.unsafeFetch, fetch: opts.fetch });
|
|
35838
36024
|
if (server2) declareDocumentStyles("pw-embed-fonts", uiFontCss(server2), opts.nonce);
|
|
35839
36025
|
const shadow = el.shadowRoot || el.attachShadow({ mode: "open" });
|
|
35840
36026
|
shadow.innerHTML = '<div class="pw-embed"></div>';
|
|
@@ -35845,18 +36031,43 @@ function mountDesigner(target, opts = {}) {
|
|
|
35845
36031
|
);
|
|
35846
36032
|
box.style.height = opts.height || "760px";
|
|
35847
36033
|
const root = (0, import_client.createRoot)(box);
|
|
36034
|
+
const store = newDesignerStore();
|
|
35848
36035
|
const embed = { onSave: opts.onSave, onOpen: opts.onOpen, readOnly: !!opts.readOnly, toolbox: opts.toolbox, panels: opts.panels, dataSourceTemplates: opts.dataSourceTemplates, server: server2 };
|
|
35849
36036
|
const show = (definition) => loadLanguage(opts.lang).catch(() => {
|
|
35850
|
-
}).then(() => root.render((0,
|
|
36037
|
+
}).then(() => root.render((0, import_react23.createElement)(Designer, { id: opts.report, initial: definition, lang: opts.lang, embed, store })));
|
|
35851
36038
|
if (opts.definition || !opts.report) show(opts.definition || BLANK);
|
|
35852
36039
|
else fetch(`${server2}/api/reports/${encodeURIComponent(opts.report)}`).then((r) => r.ok ? r.json() : r.json().then((j) => Promise.reject(new Error(j.error || `HTTP ${r.status}`)))).then(show).catch((e) => {
|
|
35853
36040
|
box.innerHTML = `<div class="vmsg error">The report did not load: ${String(e.message).replace(/</g, "<")}</div>`;
|
|
35854
36041
|
});
|
|
36042
|
+
const onLeave = (e) => {
|
|
36043
|
+
e.preventDefault();
|
|
36044
|
+
e.returnValue = "";
|
|
36045
|
+
};
|
|
36046
|
+
let dirty = false;
|
|
36047
|
+
const unsub = store.subscribe((s) => {
|
|
36048
|
+
if (!s.saved === dirty) return;
|
|
36049
|
+
dirty = !s.saved;
|
|
36050
|
+
if (opts.warnOnLeave !== false) {
|
|
36051
|
+
if (dirty) window.addEventListener("beforeunload", onLeave);
|
|
36052
|
+
else window.removeEventListener("beforeunload", onLeave);
|
|
36053
|
+
}
|
|
36054
|
+
try {
|
|
36055
|
+
opts.onDirtyChange?.(dirty);
|
|
36056
|
+
} catch (e) {
|
|
36057
|
+
console.error(e);
|
|
36058
|
+
}
|
|
36059
|
+
});
|
|
35855
36060
|
return {
|
|
35856
|
-
unmount: () =>
|
|
36061
|
+
unmount: () => {
|
|
36062
|
+
unsub();
|
|
36063
|
+
window.removeEventListener("beforeunload", onLeave);
|
|
36064
|
+
root.unmount();
|
|
36065
|
+
},
|
|
36066
|
+
/** whether there are changes not saved yet */
|
|
36067
|
+
isDirty: () => !store.getState().saved,
|
|
35857
36068
|
/** the definition as it is now (a plain copy) */
|
|
35858
|
-
getDefinition: () => JSON.parse(JSON.stringify(
|
|
35859
|
-
save: () =>
|
|
36069
|
+
getDefinition: () => JSON.parse(JSON.stringify(store.getState().def)),
|
|
36070
|
+
save: () => store.getState().save()
|
|
35860
36071
|
};
|
|
35861
36072
|
}
|
|
35862
36073
|
export {
|