@reportwright/viewer 0.12.1 → 0.13.1
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 +93 -0
- package/README.md +18 -1
- package/THIRD-PARTY-NOTICES.md +52 -0
- package/dist/{chunk-DXHLIJEY.js → chunk-47ZAKRVN.js} +6 -6
- package/dist/{chunk-NR2G4TMG.js → chunk-B5ZCT3UK.js} +47 -26
- package/dist/chunk-B5ZCT3UK.js.map +6 -0
- package/dist/chunk-BR5K6SBL.js +324 -0
- package/dist/chunk-BR5K6SBL.js.map +6 -0
- package/dist/chunk-CCH7CFU5.js +5026 -0
- package/dist/chunk-CCH7CFU5.js.map +6 -0
- package/dist/{peer/chunk-BQFI3DHK.js → chunk-ES2LYZ6S.js} +292 -25
- package/dist/chunk-ES2LYZ6S.js.map +6 -0
- package/dist/{chunk-S2IUUI6N.js → chunk-GOCWG6FG.js} +67 -49
- package/dist/chunk-GOCWG6FG.js.map +6 -0
- package/dist/{chunk-3D2KFKG2.js → chunk-GRYITZPG.js} +11 -9
- package/dist/chunk-GRYITZPG.js.map +6 -0
- package/dist/{chunk-2BPBQMH2.js → chunk-H422SRD3.js} +8 -8
- package/dist/chunk-JD6EJ3LI.js +18 -0
- package/dist/{chunk-Z7MKH66Z.js → chunk-MS2LQC2O.js} +236 -12
- package/dist/chunk-MS2LQC2O.js.map +6 -0
- package/dist/{chunk-Q6MMPKQA.js → chunk-PF4RFKX2.js} +13 -12
- package/dist/chunk-PF4RFKX2.js.map +6 -0
- package/dist/{chunk-PGP3QA6L.js → chunk-PKXTMC4J.js} +1351 -75
- package/dist/chunk-PKXTMC4J.js.map +6 -0
- package/dist/{chunk-M6AYND5G.js → chunk-U2ZY2NPQ.js} +16 -7
- package/dist/chunk-U2ZY2NPQ.js.map +6 -0
- package/dist/{chunk-DPVJEFKP.js → chunk-WOBRKNIA.js} +13 -13
- package/dist/{chunk-DPVJEFKP.js.map → chunk-WOBRKNIA.js.map} +1 -1
- package/dist/chunk-XXTAPZO4.js +34 -0
- package/dist/{chunk-VNOWPSE6.js → chunk-ZGRJJ6OW.js} +1226 -887
- package/dist/chunk-ZGRJJ6OW.js.map +6 -0
- package/dist/designer.d.ts +11 -3
- package/dist/designer.js +598 -390
- package/dist/designer.js.map +3 -3
- package/dist/engine.worker.bwip.js +51422 -0
- package/dist/engine.worker.bwip.js.map +6 -0
- package/dist/engine.worker.js +59582 -26
- package/dist/engine.worker.js.map +3 -3
- package/dist/peer/{chunk-WSNRD2AQ.js → chunk-3EYYRJR4.js} +13 -12
- package/dist/{chunk-Q6MMPKQA.js.map → peer/chunk-3EYYRJR4.js.map} +1 -1
- package/dist/peer/{chunk-TSC4RAH3.js → chunk-3XZY54LM.js} +1351 -75
- package/dist/peer/chunk-3XZY54LM.js.map +6 -0
- package/dist/peer/chunk-5RUNOIS7.js +33 -0
- package/dist/peer/chunk-5RUNOIS7.js.map +6 -0
- package/dist/peer/{chunk-6I2EAAVN.js → chunk-7IP67PA6.js} +47 -26
- package/dist/peer/chunk-7IP67PA6.js.map +6 -0
- package/dist/peer/{chunk-R4VX5UC7.js → chunk-A6UXBSTP.js} +8 -8
- package/dist/peer/{chunk-V42KN7HD.js → chunk-CFTFTV2O.js} +6 -6
- package/dist/peer/chunk-JQTRDHQP.js +866 -0
- package/dist/peer/chunk-JQTRDHQP.js.map +6 -0
- package/dist/peer/chunk-KD6CDYGE.js +5024 -0
- package/dist/peer/chunk-KD6CDYGE.js.map +6 -0
- package/dist/peer/chunk-MXR6JBMP.js +546 -0
- package/dist/peer/chunk-MXR6JBMP.js.map +6 -0
- package/dist/peer/chunk-N42DCZZA.js +378 -0
- package/dist/peer/chunk-N42DCZZA.js.map +6 -0
- package/dist/{chunk-6TPZ7G74.js → peer/chunk-RKFP7SDY.js} +292 -25
- package/dist/peer/chunk-RKFP7SDY.js.map +6 -0
- package/dist/peer/{chunk-BMAXIBP2.js → chunk-WABYQWMT.js} +13 -13
- package/dist/peer/{chunk-BMAXIBP2.js.map → chunk-WABYQWMT.js.map} +1 -1
- package/dist/peer/chunk-WVQQCD4M.js +14211 -0
- package/dist/peer/chunk-WVQQCD4M.js.map +6 -0
- package/dist/peer/chunk-XHCRHVRK.js +17 -0
- package/dist/peer/chunk-XHCRHVRK.js.map +6 -0
- package/dist/peer/{chunk-WQGENQZO.js → chunk-ZS3J4WBH.js} +11 -9
- package/dist/peer/chunk-ZS3J4WBH.js.map +6 -0
- package/dist/peer/designer.js +455 -247
- package/dist/peer/designer.js.map +3 -3
- package/dist/peer/engine.worker.bwip.js +51422 -0
- package/dist/peer/engine.worker.bwip.js.map +6 -0
- package/dist/peer/engine.worker.js +59582 -25
- package/dist/peer/engine.worker.js.map +3 -3
- package/dist/peer/viewer.js +16 -12
- package/dist/peer/viewer.js.map +1 -1
- package/dist/viewer.d.ts +2 -1
- package/dist/viewer.js +16 -12
- package/dist/viewer.js.map +1 -1
- package/package.json +3 -2
- package/dist/chunk-3D2KFKG2.js.map +0 -6
- package/dist/chunk-6TPZ7G74.js.map +0 -6
- package/dist/chunk-BRB34AJ2.js +0 -16
- package/dist/chunk-M6AYND5G.js.map +0 -6
- package/dist/chunk-NR2G4TMG.js.map +0 -6
- package/dist/chunk-PGP3QA6L.js.map +0 -6
- package/dist/chunk-S2IUUI6N.js.map +0 -6
- package/dist/chunk-ULKEEARQ.js +0 -553
- package/dist/chunk-ULKEEARQ.js.map +0 -6
- package/dist/chunk-VNOWPSE6.js.map +0 -6
- package/dist/chunk-Z7MKH66Z.js.map +0 -6
- package/dist/peer/chunk-2FZTYEDE.js +0 -15
- package/dist/peer/chunk-6I2EAAVN.js.map +0 -6
- package/dist/peer/chunk-BQFI3DHK.js.map +0 -6
- package/dist/peer/chunk-TSC4RAH3.js.map +0 -6
- package/dist/peer/chunk-WQGENQZO.js.map +0 -6
- package/dist/peer/chunk-WSNRD2AQ.js.map +0 -6
- /package/dist/{chunk-DXHLIJEY.js.map → chunk-47ZAKRVN.js.map} +0 -0
- /package/dist/{chunk-2BPBQMH2.js.map → chunk-H422SRD3.js.map} +0 -0
- /package/dist/{chunk-BRB34AJ2.js.map → chunk-JD6EJ3LI.js.map} +0 -0
- /package/dist/{peer/chunk-2FZTYEDE.js.map → chunk-XXTAPZO4.js.map} +0 -0
- /package/dist/peer/{chunk-R4VX5UC7.js.map → chunk-A6UXBSTP.js.map} +0 -0
- /package/dist/peer/{chunk-V42KN7HD.js.map → chunk-CFTFTV2O.js.map} +0 -0
package/dist/designer.js
CHANGED
|
@@ -13,16 +13,18 @@ import {
|
|
|
13
13
|
setShadowStyles,
|
|
14
14
|
t,
|
|
15
15
|
uiFontCss
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-B5ZCT3UK.js";
|
|
17
17
|
import {
|
|
18
18
|
customFonts,
|
|
19
|
-
fontStore,
|
|
20
19
|
fontsBase,
|
|
20
|
+
loadFontStore,
|
|
21
21
|
loadModelFonts,
|
|
22
22
|
origin,
|
|
23
|
+
reportFetch,
|
|
23
24
|
setAssetBase,
|
|
25
|
+
setFetchPolicy,
|
|
24
26
|
setStandalone
|
|
25
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-ES2LYZ6S.js";
|
|
26
28
|
import {
|
|
27
29
|
BASE_STYLE,
|
|
28
30
|
DEFAULT_THEME,
|
|
@@ -31,10 +33,10 @@ import {
|
|
|
31
33
|
ITEMS,
|
|
32
34
|
ODATA_DEFAULT_PAGES,
|
|
33
35
|
ODATA_MAX_PAGES,
|
|
34
|
-
PAGE_SIZES,
|
|
35
36
|
PALETTES,
|
|
36
37
|
TEXT_STYLE_PROPS,
|
|
37
38
|
THEME_COLORS,
|
|
39
|
+
TextMeasurer,
|
|
38
40
|
XmlError,
|
|
39
41
|
bestXmlRows,
|
|
40
42
|
buildDataSets,
|
|
@@ -43,7 +45,7 @@ import {
|
|
|
43
45
|
detectFields,
|
|
44
46
|
evalValue,
|
|
45
47
|
findItemNamed,
|
|
46
|
-
|
|
48
|
+
finishText,
|
|
47
49
|
functionTable,
|
|
48
50
|
isDynamic,
|
|
49
51
|
isTablix,
|
|
@@ -52,54 +54,52 @@ import {
|
|
|
52
54
|
layoutItems,
|
|
53
55
|
loadBarcodes,
|
|
54
56
|
loadSources,
|
|
55
|
-
normBox,
|
|
56
57
|
normalizeMatrix,
|
|
57
58
|
odataMetadata,
|
|
58
59
|
parseBorder,
|
|
59
60
|
parseXml,
|
|
60
61
|
render,
|
|
61
|
-
reportFetch,
|
|
62
|
-
resolvePage,
|
|
63
62
|
resolveParameters,
|
|
64
|
-
setFetchPolicy,
|
|
65
63
|
shiftItems,
|
|
66
64
|
sourceRows,
|
|
67
65
|
sourceUrl,
|
|
68
66
|
stylePropsFor,
|
|
69
67
|
themeContext,
|
|
70
|
-
toPt,
|
|
71
68
|
toText,
|
|
72
69
|
validate,
|
|
73
70
|
withPartProps,
|
|
74
71
|
xmlRowPaths
|
|
75
|
-
} from "./chunk-
|
|
76
|
-
import {
|
|
77
|
-
TextMeasurer,
|
|
78
|
-
finishText
|
|
79
|
-
} from "./chunk-ULKEEARQ.js";
|
|
80
|
-
import "./chunk-72S6DETS.js";
|
|
72
|
+
} from "./chunk-ZGRJJ6OW.js";
|
|
81
73
|
import {
|
|
82
|
-
|
|
83
|
-
|
|
74
|
+
PAGE_SIZES,
|
|
75
|
+
fromPt,
|
|
76
|
+
normBox,
|
|
77
|
+
resolvePage,
|
|
78
|
+
toPt
|
|
79
|
+
} from "./chunk-BR5K6SBL.js";
|
|
84
80
|
import "./chunk-F6RMRXIN.js";
|
|
85
81
|
import {
|
|
86
82
|
fontFaceCss,
|
|
87
83
|
fontFamilyCss,
|
|
88
84
|
pageToSvg
|
|
89
|
-
} from "./chunk-
|
|
85
|
+
} from "./chunk-U2ZY2NPQ.js";
|
|
86
|
+
import "./chunk-72S6DETS.js";
|
|
90
87
|
import {
|
|
91
88
|
BUNDLED_FAMILIES,
|
|
92
89
|
FONT_FAMILIES,
|
|
93
90
|
allFontKeys,
|
|
94
91
|
fallbackKeys,
|
|
95
92
|
resolveFontKey
|
|
96
|
-
} from "./chunk-
|
|
93
|
+
} from "./chunk-MS2LQC2O.js";
|
|
94
|
+
import {
|
|
95
|
+
currencyOf
|
|
96
|
+
} from "./chunk-GJS242RR.js";
|
|
97
97
|
import {
|
|
98
98
|
__toESM
|
|
99
99
|
} from "./chunk-OLLMACWA.js";
|
|
100
100
|
|
|
101
101
|
// src/embed/designer.js
|
|
102
|
-
var
|
|
102
|
+
var import_react23 = __toESM(require_react(), 1);
|
|
103
103
|
var import_client = __toESM(require_client(), 1);
|
|
104
104
|
|
|
105
105
|
// src/importers/rdlx.js
|
|
@@ -6867,10 +6867,10 @@ function readReportFile(name2, text) {
|
|
|
6867
6867
|
}
|
|
6868
6868
|
|
|
6869
6869
|
// src/designer/Designer.jsx
|
|
6870
|
-
var
|
|
6870
|
+
var import_react22 = __toESM(require_react(), 1);
|
|
6871
6871
|
|
|
6872
6872
|
// src/designer/ui.jsx
|
|
6873
|
-
var
|
|
6873
|
+
var import_react3 = __toESM(require_react(), 1);
|
|
6874
6874
|
|
|
6875
6875
|
// src/designer/fieldCheck.js
|
|
6876
6876
|
function exprParts(value) {
|
|
@@ -7004,13 +7004,9 @@ function useStore(api, selector = identity) {
|
|
|
7004
7004
|
import_react.default.useDebugValue(slice);
|
|
7005
7005
|
return slice;
|
|
7006
7006
|
}
|
|
7007
|
-
|
|
7008
|
-
|
|
7009
|
-
|
|
7010
|
-
Object.assign(useBoundStore, api);
|
|
7011
|
-
return useBoundStore;
|
|
7012
|
-
};
|
|
7013
|
-
var create = ((createState) => createState ? createImpl(createState) : createImpl);
|
|
7007
|
+
|
|
7008
|
+
// src/designer/store.js
|
|
7009
|
+
var import_react2 = __toESM(require_react(), 1);
|
|
7014
7010
|
|
|
7015
7011
|
// node_modules/immer/dist/immer.mjs
|
|
7016
7012
|
var NOTHING = /* @__PURE__ */ Symbol.for("immer-nothing");
|
|
@@ -7859,6 +7855,17 @@ function pageOf2(def, key2 = "body") {
|
|
|
7859
7855
|
return resolvePage({ ...def.page || {}, ...sec?.page || {} });
|
|
7860
7856
|
}
|
|
7861
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
|
+
}
|
|
7862
7869
|
function walk(def, fn3) {
|
|
7863
7870
|
const go = (list2, parent, section) => list2.forEach((it, i2) => {
|
|
7864
7871
|
fn3(it, list2, i2, parent, section);
|
|
@@ -7884,9 +7891,15 @@ function normalize(def) {
|
|
|
7884
7891
|
if (x && typeof x === "object") x.items || (x.items = []);
|
|
7885
7892
|
}
|
|
7886
7893
|
const used = allNames(d);
|
|
7894
|
+
const ids = /* @__PURE__ */ new Set();
|
|
7887
7895
|
walk(d, (it) => {
|
|
7888
|
-
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}`);
|
|
7889
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));
|
|
7890
7903
|
if (NESTING.has(it.type)) it.items || (it.items = []);
|
|
7891
7904
|
if (it.type === "table" && Array.isArray(it.columns)) tableSync(it);
|
|
7892
7905
|
});
|
|
@@ -7910,7 +7923,7 @@ function findItem(def, id) {
|
|
|
7910
7923
|
});
|
|
7911
7924
|
return hit;
|
|
7912
7925
|
}
|
|
7913
|
-
var
|
|
7926
|
+
var newDesignerStore = () => createStore((set2, get2) => ({
|
|
7914
7927
|
id: null,
|
|
7915
7928
|
def: null,
|
|
7916
7929
|
saved: true,
|
|
@@ -8041,7 +8054,18 @@ var useDesigner = create((set2, get2) => ({
|
|
|
8041
8054
|
set2({ rev: (res.headers.get("etag") || "").replace(/^W\/|"/g, "") || null, conflict: null });
|
|
8042
8055
|
}
|
|
8043
8056
|
}));
|
|
8044
|
-
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();
|
|
8045
8069
|
function bodyWidth(def, key2 = "body") {
|
|
8046
8070
|
return pageOf2(def, key2).bodyWidth;
|
|
8047
8071
|
}
|
|
@@ -8089,7 +8113,7 @@ function addItem(type, section, x, y, extra = {}, parentId = null) {
|
|
|
8089
8113
|
} else {
|
|
8090
8114
|
const sec = secOf(d, section);
|
|
8091
8115
|
sec.items.push(it);
|
|
8092
|
-
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));
|
|
8093
8117
|
}
|
|
8094
8118
|
});
|
|
8095
8119
|
S().select({ kind: "items", ids: [id] });
|
|
@@ -8115,9 +8139,21 @@ function insertItem(type, section, x, y, extra = {}, parentId = null) {
|
|
|
8115
8139
|
function updateItem(id, recipe, key2) {
|
|
8116
8140
|
S().apply((d) => {
|
|
8117
8141
|
const f = findItem(d, id);
|
|
8118
|
-
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);
|
|
8119
8147
|
}, key2);
|
|
8120
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
|
+
}
|
|
8121
8157
|
function moveItems(ids, dx, dy) {
|
|
8122
8158
|
if (!dx && !dy) return;
|
|
8123
8159
|
if (S().cells && wouldOverlap(S().def, ids, (it) => ({ x: it.x + dx, y: it.y + dy, w: it.w, h: it.h }))) {
|
|
@@ -8248,14 +8284,23 @@ function duplicateSelection() {
|
|
|
8248
8284
|
const f = findItem(d, id);
|
|
8249
8285
|
if (!f) continue;
|
|
8250
8286
|
const copy = cloneWithIds(f.item, used);
|
|
8251
|
-
|
|
8252
|
-
copy
|
|
8287
|
+
offsetCopy(f.list, copy);
|
|
8288
|
+
growToFit(d, { ...f, item: copy });
|
|
8253
8289
|
f.list.push(copy);
|
|
8254
8290
|
newIds.push(copy.id);
|
|
8255
8291
|
}
|
|
8256
8292
|
});
|
|
8257
8293
|
if (newIds.length) S().select({ kind: "items", ids: newIds });
|
|
8258
8294
|
}
|
|
8295
|
+
var PASTE_OFFSET = 12;
|
|
8296
|
+
function offsetCopy(list2, c) {
|
|
8297
|
+
for (const k of ["x", "y"]) if (!Number.isFinite(c[k])) c[k] = 0;
|
|
8298
|
+
for (let n = 0; n <= list2.length; n++) {
|
|
8299
|
+
c.x += PASTE_OFFSET;
|
|
8300
|
+
c.y += PASTE_OFFSET;
|
|
8301
|
+
if (!list2.some((i2) => i2 !== c && i2.x === c.x && i2.y === c.y)) return;
|
|
8302
|
+
}
|
|
8303
|
+
}
|
|
8259
8304
|
var CLIP = "pagewright/items@1";
|
|
8260
8305
|
async function copySelection() {
|
|
8261
8306
|
const { sel, def } = S();
|
|
@@ -8270,43 +8315,40 @@ async function copySelection() {
|
|
|
8270
8315
|
return items.length;
|
|
8271
8316
|
}
|
|
8272
8317
|
var memClip = null;
|
|
8273
|
-
|
|
8274
|
-
let text = null;
|
|
8275
|
-
try {
|
|
8276
|
-
text = await navigator.clipboard.readText();
|
|
8277
|
-
} catch {
|
|
8278
|
-
text = memClip;
|
|
8279
|
-
}
|
|
8280
|
-
if (!text || !text.includes(CLIP)) text = memClip;
|
|
8281
|
-
let data;
|
|
8318
|
+
var clipOf = (text) => {
|
|
8282
8319
|
try {
|
|
8283
|
-
|
|
8320
|
+
const d = JSON.parse(text);
|
|
8321
|
+
return d?.kind === CLIP && Array.isArray(d.items) ? d : null;
|
|
8284
8322
|
} catch {
|
|
8285
|
-
return
|
|
8323
|
+
return null;
|
|
8286
8324
|
}
|
|
8287
|
-
|
|
8325
|
+
};
|
|
8326
|
+
function pasteItems(section = "body", text = null) {
|
|
8327
|
+
const st = active;
|
|
8328
|
+
const data = clipOf(text) || clipOf(memClip);
|
|
8329
|
+
if (!data) return 0;
|
|
8288
8330
|
const ids = [];
|
|
8289
|
-
|
|
8331
|
+
st.getState().apply((d) => {
|
|
8290
8332
|
const used = allNames(d);
|
|
8291
8333
|
for (const it of data.items) {
|
|
8292
8334
|
const c = cloneWithIds(it, used);
|
|
8293
|
-
c.x += 12;
|
|
8294
|
-
c.y += 12;
|
|
8295
8335
|
if (c.type === "table" && !isBodyKey(section)) continue;
|
|
8336
|
+
offsetCopy(secOf(d, section).items, c);
|
|
8296
8337
|
secOf(d, section).items.push(c);
|
|
8338
|
+
growToFit(d, { section, parent: null, item: c });
|
|
8297
8339
|
ids.push(c.id);
|
|
8298
8340
|
}
|
|
8299
8341
|
});
|
|
8300
|
-
if (ids.length)
|
|
8342
|
+
if (ids.length) st.getState().select({ kind: "items", ids });
|
|
8301
8343
|
return ids.length;
|
|
8302
8344
|
}
|
|
8303
|
-
function rowsOf(t3, part,
|
|
8345
|
+
function rowsOf(t3, part, create = false) {
|
|
8304
8346
|
const m = /^g(\d+)([hf])$/.exec(part);
|
|
8305
8347
|
const holder = m ? t3.groups?.[Number(m[1])] : t3;
|
|
8306
8348
|
if (!holder) return null;
|
|
8307
8349
|
const key2 = m ? m[2] === "h" ? "header" : "footer" : part;
|
|
8308
8350
|
if (!holder[key2]) {
|
|
8309
|
-
if (!
|
|
8351
|
+
if (!create) return [];
|
|
8310
8352
|
holder[key2] = [];
|
|
8311
8353
|
}
|
|
8312
8354
|
return holder[key2];
|
|
@@ -8506,6 +8548,7 @@ function tableRemoveGroup(id, level) {
|
|
|
8506
8548
|
}
|
|
8507
8549
|
var IMAGE_MAX = 10 * 1024 * 1024;
|
|
8508
8550
|
async function uploadImages(files, T) {
|
|
8551
|
+
const st = active;
|
|
8509
8552
|
const names = [];
|
|
8510
8553
|
let err = null;
|
|
8511
8554
|
for (const f of files) {
|
|
@@ -8524,7 +8567,7 @@ async function uploadImages(files, T) {
|
|
|
8524
8567
|
r.readAsDataURL(f);
|
|
8525
8568
|
});
|
|
8526
8569
|
const base2 = f.name.replace(/\.[^.]+$/, "").replace(/\W+/g, "_").replace(/^_+|_+$/g, "") || "image";
|
|
8527
|
-
|
|
8570
|
+
st.getState().apply((d) => {
|
|
8528
8571
|
d.images || (d.images = {});
|
|
8529
8572
|
let n = base2, k = 2;
|
|
8530
8573
|
while (d.images[n]) n = `${base2}${k++}`;
|
|
@@ -8591,6 +8634,13 @@ function wouldOverlap(def, ids, rectOf2) {
|
|
|
8591
8634
|
}
|
|
8592
8635
|
return false;
|
|
8593
8636
|
}
|
|
8637
|
+
function setMatrixShow(v, show) {
|
|
8638
|
+
const pct = !!show && show !== "value";
|
|
8639
|
+
if (pct) v.show = show;
|
|
8640
|
+
else delete v.show;
|
|
8641
|
+
if (pct && (!v.format || v.format === "N0")) v.format = "P1";
|
|
8642
|
+
else if (!pct && v.format === "P1") v.format = "N0";
|
|
8643
|
+
}
|
|
8594
8644
|
|
|
8595
8645
|
// src/designer/ui.jsx
|
|
8596
8646
|
var import_jsx_runtime = __toESM(require_jsx_runtime(), 1);
|
|
@@ -8602,8 +8652,8 @@ function TextInput({ value, onChange, mono, invalid, className, ...rest }) {
|
|
|
8602
8652
|
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 });
|
|
8603
8653
|
}
|
|
8604
8654
|
function NumberInput({ value, onChange, step = 0.5, min, ...rest }) {
|
|
8605
|
-
const [draft, setDraft] = (0,
|
|
8606
|
-
(0,
|
|
8655
|
+
const [draft, setDraft] = (0, import_react3.useState)(value ?? "");
|
|
8656
|
+
(0, import_react3.useEffect)(() => {
|
|
8607
8657
|
setDraft(value ?? "");
|
|
8608
8658
|
}, [value]);
|
|
8609
8659
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
@@ -8639,18 +8689,18 @@ function ColorInput({ value, onChange }) {
|
|
|
8639
8689
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TextInput, { value, onChange: (v) => onChange(v === "" ? void 0 : v), mono: true, placeholder: T("i_colorPh") })
|
|
8640
8690
|
] });
|
|
8641
8691
|
}
|
|
8642
|
-
var FieldScope = (0,
|
|
8692
|
+
var FieldScope = (0, import_react3.createContext)(void 0);
|
|
8643
8693
|
var issueText = (T, i2) => i2.suggest ? T("ux_unknownFieldSuggest", { name: i2.name, suggest: i2.suggest }) : T("ux_unknownField", { name: i2.name });
|
|
8644
8694
|
function ExprInput({ value, onChange, onOpen, placeholder: placeholder2 }) {
|
|
8645
8695
|
const T = useT();
|
|
8646
|
-
const scope = (0,
|
|
8696
|
+
const scope = (0, import_react3.useContext)(FieldScope);
|
|
8647
8697
|
const dataSets = useDesigner((s) => s.def?.dataSets);
|
|
8648
8698
|
const err = value ? checkValue(value) : null;
|
|
8649
8699
|
const issues = !err && value && scope !== void 0 ? fieldIssues(value, dataSets, scope) : [];
|
|
8650
8700
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
8651
8701
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "expr-row", children: [
|
|
8652
8702
|
/* @__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") }),
|
|
8653
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { className: "fx", title: T("i_openExprEditor"), "aria-label": T("i_openExprEditor")
|
|
8703
|
+
/* @__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" })
|
|
8654
8704
|
] }),
|
|
8655
8705
|
err && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "err", children: err }),
|
|
8656
8706
|
issues.map((i2, k) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "warn", "data-testid": "field-warning", children: issueText(T, i2) }, k))
|
|
@@ -8670,14 +8720,19 @@ function Check({ label, checked, onChange }) {
|
|
|
8670
8720
|
] });
|
|
8671
8721
|
}
|
|
8672
8722
|
function Dialog({ title, children, onClose, footer, wide, className = "" }) {
|
|
8673
|
-
(0,
|
|
8723
|
+
const ref = (0, import_react3.useRef)(null);
|
|
8724
|
+
(0, import_react3.useEffect)(() => {
|
|
8725
|
+
const inOther = (e) => {
|
|
8726
|
+
const mine = ref.current?.closest(".designer");
|
|
8727
|
+
return e.composedPath().some((n) => n !== mine && n?.classList?.contains("designer"));
|
|
8728
|
+
};
|
|
8674
8729
|
const k = (e) => {
|
|
8675
|
-
if (e.key === "Escape" && !e.defaultPrevented) onClose();
|
|
8730
|
+
if (e.key === "Escape" && !e.defaultPrevented && !inOther(e)) onClose();
|
|
8676
8731
|
};
|
|
8677
8732
|
window.addEventListener("keydown", k);
|
|
8678
8733
|
return () => window.removeEventListener("keydown", k);
|
|
8679
8734
|
}, [onClose]);
|
|
8680
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "scrim", onPointerDown: (e) => {
|
|
8735
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "scrim", ref, onPointerDown: (e) => {
|
|
8681
8736
|
if (e.target === e.currentTarget) onClose();
|
|
8682
8737
|
}, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: `dialog${wide ? " wide" : ""}${className ? ` ${className}` : ""}`, role: "dialog", "aria-modal": "true", "aria-label": title, children: [
|
|
8683
8738
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("header", { children: title }),
|
|
@@ -8687,20 +8742,20 @@ function Dialog({ title, children, onClose, footer, wide, className = "" }) {
|
|
|
8687
8742
|
}
|
|
8688
8743
|
|
|
8689
8744
|
// src/embed/link.js
|
|
8690
|
-
var
|
|
8745
|
+
var import_react4 = __toESM(require_react(), 1);
|
|
8691
8746
|
function Link({ href, children, prefetch, replace: replace2, scroll, shallow, ...rest }) {
|
|
8692
|
-
return (0,
|
|
8747
|
+
return (0, import_react4.createElement)("a", { href: typeof href === "string" ? href : String(href?.pathname || ""), ...rest }, children);
|
|
8693
8748
|
}
|
|
8694
8749
|
|
|
8695
8750
|
// src/designer/SvgHtml.jsx
|
|
8696
|
-
var
|
|
8751
|
+
var import_react5 = __toESM(require_react(), 1);
|
|
8697
8752
|
var import_jsx_runtime2 = __toESM(require_jsx_runtime(), 1);
|
|
8698
8753
|
function SvgHtml({ html, as: Tag2 = "span", ...rest }) {
|
|
8699
|
-
const ref = (0,
|
|
8754
|
+
const ref = (0, import_react5.useRef)(
|
|
8700
8755
|
/** @type {HTMLElement|null} */
|
|
8701
8756
|
null
|
|
8702
8757
|
);
|
|
8703
|
-
(0,
|
|
8758
|
+
(0, import_react5.useLayoutEffect)(() => {
|
|
8704
8759
|
if (!ref.current) return;
|
|
8705
8760
|
ref.current.innerHTML = deferStyleAttributes(html);
|
|
8706
8761
|
applyStyleAttributes(ref.current);
|
|
@@ -8709,7 +8764,7 @@ function SvgHtml({ html, as: Tag2 = "span", ...rest }) {
|
|
|
8709
8764
|
}
|
|
8710
8765
|
|
|
8711
8766
|
// src/designer/Canvas.jsx
|
|
8712
|
-
var
|
|
8767
|
+
var import_react8 = __toESM(require_react(), 1);
|
|
8713
8768
|
|
|
8714
8769
|
// src/designer/tableGen.js
|
|
8715
8770
|
var HEAD = { fontWeight: "bold", backgroundColor: "#f1f5f9", borderBottom: "0.75 solid #94a3b8" };
|
|
@@ -8841,24 +8896,28 @@ function instantPicks(fields, rows = []) {
|
|
|
8841
8896
|
}
|
|
8842
8897
|
|
|
8843
8898
|
// src/designer/Reuse.jsx
|
|
8844
|
-
var
|
|
8899
|
+
var import_react7 = __toESM(require_react(), 1);
|
|
8845
8900
|
|
|
8846
8901
|
// src/designer/Fonts.jsx
|
|
8847
|
-
var
|
|
8902
|
+
var import_react6 = __toESM(require_react(), 1);
|
|
8848
8903
|
var import_jsx_runtime3 = __toESM(require_jsx_runtime(), 1);
|
|
8849
8904
|
function useFontFamilies() {
|
|
8850
8905
|
const fonts = useDesigner((s) => s.fonts);
|
|
8851
8906
|
return [...BUNDLED_FAMILIES, ...[...new Set(fonts.map((f) => f.family))].sort()];
|
|
8852
8907
|
}
|
|
8853
|
-
var refresh = async () =>
|
|
8908
|
+
var refresh = async () => {
|
|
8909
|
+
const api = activeStore2();
|
|
8910
|
+
const fonts = await customFonts(true);
|
|
8911
|
+
api.getState().setUi({ fonts });
|
|
8912
|
+
};
|
|
8854
8913
|
function FontsDialog({ onClose }) {
|
|
8855
8914
|
const fonts = useDesigner((s) => s.fonts);
|
|
8856
|
-
const [file, setFile] = (0,
|
|
8857
|
-
const [family, setFamily] = (0,
|
|
8858
|
-
const [weight, setWeight] = (0,
|
|
8859
|
-
const [style, setStyle] = (0,
|
|
8860
|
-
const [busy, setBusy] = (0,
|
|
8861
|
-
const [msg, setMsg] = (0,
|
|
8915
|
+
const [file, setFile] = (0, import_react6.useState)(null);
|
|
8916
|
+
const [family, setFamily] = (0, import_react6.useState)("");
|
|
8917
|
+
const [weight, setWeight] = (0, import_react6.useState)("");
|
|
8918
|
+
const [style, setStyle] = (0, import_react6.useState)("");
|
|
8919
|
+
const [busy, setBusy] = (0, import_react6.useState)(false);
|
|
8920
|
+
const [msg, setMsg] = (0, import_react6.useState)(null);
|
|
8862
8921
|
const upload = async () => {
|
|
8863
8922
|
if (!file) return;
|
|
8864
8923
|
setBusy(true);
|
|
@@ -8949,30 +9008,33 @@ var apply = (fn3, key2) => S2().apply(fn3, key2);
|
|
|
8949
9008
|
var server = () => S2().embed?.server || "";
|
|
8950
9009
|
var noServer = () => !!S2().embed && !S2().embed.server;
|
|
8951
9010
|
var pending = /* @__PURE__ */ new Map();
|
|
8952
|
-
function fetchReused(id, force = false) {
|
|
9011
|
+
function fetchReused(id, force = false, api = activeStore2()) {
|
|
8953
9012
|
if (!id || typeof id !== "string" || id.startsWith("=")) return Promise.resolve(null);
|
|
8954
|
-
|
|
8955
|
-
if (
|
|
8956
|
-
|
|
8957
|
-
const
|
|
8958
|
-
|
|
8959
|
-
useDesigner.setState((s) => ({ reused: { ...s.reused, [id]: d } }));
|
|
9013
|
+
const st = api.getState();
|
|
9014
|
+
if (!force && st.reused[id]) return Promise.resolve(st.reused[id]);
|
|
9015
|
+
const server2 = st.embed?.server || "", key2 = `${server2} ${id}`;
|
|
9016
|
+
const keep = (d) => {
|
|
9017
|
+
api.setState((s) => ({ reused: { ...s.reused, [id]: d } }));
|
|
8960
9018
|
return d;
|
|
8961
|
-
}
|
|
8962
|
-
pending.
|
|
8963
|
-
return
|
|
9019
|
+
};
|
|
9020
|
+
if (pending.has(key2)) return pending.get(key2).then(keep);
|
|
9021
|
+
if (st.embed && !server2) return Promise.resolve(null);
|
|
9022
|
+
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));
|
|
9023
|
+
pending.set(key2, p);
|
|
9024
|
+
return p.then(keep);
|
|
8964
9025
|
}
|
|
8965
9026
|
function useReused(id) {
|
|
9027
|
+
const api = useDesignerStore();
|
|
8966
9028
|
const d = useDesigner((s) => id ? s.reused[id] : void 0);
|
|
8967
|
-
(0,
|
|
8968
|
-
fetchReused(id);
|
|
8969
|
-
}, [id]);
|
|
9029
|
+
(0, import_react7.useEffect)(() => {
|
|
9030
|
+
fetchReused(id, false, api);
|
|
9031
|
+
}, [id, api]);
|
|
8970
9032
|
return d && !d.__error ? d : null;
|
|
8971
9033
|
}
|
|
8972
9034
|
var listCache = null;
|
|
8973
9035
|
function ReportSelect({ value, onChange, exclude, ...rest }) {
|
|
8974
|
-
const [list2, setList] = (0,
|
|
8975
|
-
(0,
|
|
9036
|
+
const [list2, setList] = (0, import_react7.useState)(listCache || []);
|
|
9037
|
+
(0, import_react7.useEffect)(() => {
|
|
8976
9038
|
if (noServer()) return;
|
|
8977
9039
|
fetch(`${server()}/api/reports`).then((r) => r.ok ? r.json() : []).then((l) => {
|
|
8978
9040
|
listCache = Array.isArray(l) ? l : [];
|
|
@@ -9039,7 +9101,7 @@ function ThemeSection() {
|
|
|
9039
9101
|
const id = useDesigner((s) => s.id);
|
|
9040
9102
|
const families = useFontFamilies();
|
|
9041
9103
|
const src = def.theme;
|
|
9042
|
-
const [mode, setMode] = (0,
|
|
9104
|
+
const [mode, setMode] = (0, import_react7.useState)(!src ? "own" : String(src).startsWith("=") ? "expr" : "report");
|
|
9043
9105
|
const td = def.themeDef || {};
|
|
9044
9106
|
const setTd = (fn3, key2) => apply((d) => {
|
|
9045
9107
|
d.themeDef || (d.themeDef = {});
|
|
@@ -9058,7 +9120,7 @@ function ThemeSection() {
|
|
|
9058
9120
|
else x.fonts[k][p] = v;
|
|
9059
9121
|
}, `theme.font.${k}.${p}`);
|
|
9060
9122
|
const consts = Object.entries(td.constants || {});
|
|
9061
|
-
const [newConst, setNewConst] = (0,
|
|
9123
|
+
const [newConst, setNewConst] = (0, import_react7.useState)("");
|
|
9062
9124
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "cat", "data-testid": "theme", children: [
|
|
9063
9125
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(CatHead, { children: T("theme") }),
|
|
9064
9126
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Field, { label: T("themeSource"), children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
@@ -9118,7 +9180,7 @@ function LayersPanel() {
|
|
|
9118
9180
|
const T = useT2();
|
|
9119
9181
|
const layers = useDesigner((s) => s.def.layers) || [];
|
|
9120
9182
|
const readOnly2 = useDesigner((s) => s.readOnly);
|
|
9121
|
-
const [name2, setName] = (0,
|
|
9183
|
+
const [name2, setName] = (0, import_react7.useState)("");
|
|
9122
9184
|
const set2 = (fn3, key2) => apply((d) => {
|
|
9123
9185
|
d.layers || (d.layers = []);
|
|
9124
9186
|
fn3(d.layers, d);
|
|
@@ -9273,7 +9335,7 @@ function PartsPanel() {
|
|
|
9273
9335
|
const libs = useDesigner((s) => s.def.libraries) || [];
|
|
9274
9336
|
const id = useDesigner((s) => s.id);
|
|
9275
9337
|
const readOnly2 = useDesigner((s) => s.readOnly);
|
|
9276
|
-
const [pick, setPick] = (0,
|
|
9338
|
+
const [pick, setPick] = (0, import_react7.useState)("");
|
|
9277
9339
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "pane", "data-testid": "parts-panel", children: [
|
|
9278
9340
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("h4", { children: [
|
|
9279
9341
|
T("parts"),
|
|
@@ -9402,7 +9464,7 @@ function PublishPart({ item }) {
|
|
|
9402
9464
|
if (v === void 0 || v === "") delete q2[k];
|
|
9403
9465
|
else q2[k] = v;
|
|
9404
9466
|
}, `part${i2}.q${j}.${k}`);
|
|
9405
|
-
const [newProp, setNewProp] = (0,
|
|
9467
|
+
const [newProp, setNewProp] = (0, import_react7.useState)("");
|
|
9406
9468
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "cat", "data-testid": "publish-part", children: [
|
|
9407
9469
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(CatHead, { children: T("reportPart") }),
|
|
9408
9470
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Check, { label: T("publishPart"), checked: !!p, onChange: (on) => set2((l) => {
|
|
@@ -9531,12 +9593,12 @@ function useDesignIssues() {
|
|
|
9531
9593
|
const def = useDesigner((s) => s.def);
|
|
9532
9594
|
const extents = useDesigner((s) => s.extents);
|
|
9533
9595
|
const saveCheck = useDesigner((s) => s.saveCheck);
|
|
9534
|
-
return (0,
|
|
9596
|
+
return (0, import_react8.useMemo)(() => {
|
|
9535
9597
|
const bands = sectionList(def).map((s) => ({ key: s.key, items: secOf(def, s.key)?.items || [], width: bodyWidth(def, s.key) }));
|
|
9536
9598
|
return [...designIssues(def, bands, extents || {}), ...checkIssues(bands, [...validate(def).errors, ...saveCheck?.missing || []])];
|
|
9537
9599
|
}, [def, extents, saveCheck]);
|
|
9538
9600
|
}
|
|
9539
|
-
var IssueMap = (0,
|
|
9601
|
+
var IssueMap = (0, import_react8.createContext)(/* @__PURE__ */ new Map());
|
|
9540
9602
|
function issueLine(T, i2) {
|
|
9541
9603
|
if (i2.kind === "overlap") return T("ux_issueOverlap", { name: i2.name, other: i2.other });
|
|
9542
9604
|
if (i2.kind === "wide") return T("ux_issueWide", { name: i2.name, width: i2.width, room: i2.room });
|
|
@@ -9601,9 +9663,9 @@ function Canvas() {
|
|
|
9601
9663
|
const bands = sectionList(def);
|
|
9602
9664
|
const widths2 = Object.fromEntries(bands.map((s) => [s.key, bodyWidth(def, s.key)]));
|
|
9603
9665
|
const bw = Math.max(...Object.values(widths2));
|
|
9604
|
-
const scrollRef = (0,
|
|
9605
|
-
const [fitW, setFitW] = (0,
|
|
9606
|
-
(0,
|
|
9666
|
+
const scrollRef = (0, import_react8.useRef)(null);
|
|
9667
|
+
const [fitW, setFitW] = (0, import_react8.useState)(0);
|
|
9668
|
+
(0, import_react8.useEffect)(() => {
|
|
9607
9669
|
if (zoom !== "fit" || !scrollRef.current) return;
|
|
9608
9670
|
const el = scrollRef.current;
|
|
9609
9671
|
const ro = new ResizeObserver(() => setFitW(el.clientWidth));
|
|
@@ -9611,10 +9673,10 @@ function Canvas() {
|
|
|
9611
9673
|
return () => ro.disconnect();
|
|
9612
9674
|
}, [zoom]);
|
|
9613
9675
|
const scale = zoom === "fit" ? Math.max(0.3, Math.min(3, ((fitW || 900) - 80) / bw)) : zoom * PX;
|
|
9614
|
-
const [drag, setDrag] = (0,
|
|
9676
|
+
const [drag, setDrag] = (0, import_react8.useState)(null);
|
|
9615
9677
|
const T = useT2();
|
|
9616
9678
|
const issues = useDesignIssues();
|
|
9617
|
-
const byId = (0,
|
|
9679
|
+
const byId = (0, import_react8.useMemo)(() => {
|
|
9618
9680
|
const m = /* @__PURE__ */ new Map();
|
|
9619
9681
|
for (const i2 of issues) m.set(i2.id, [...m.get(i2.id) || [], issueLine(T, i2)]);
|
|
9620
9682
|
return m;
|
|
@@ -9695,9 +9757,9 @@ function Band({ section, label, scale, bw: bandW, drag, setDrag, phBox = null })
|
|
|
9695
9757
|
const off = phBox || mb?.off || null;
|
|
9696
9758
|
const contentList = useDesigner((s) => s.def.sections?.content);
|
|
9697
9759
|
const bw = off?.w || bandW;
|
|
9698
|
-
const ref = (0,
|
|
9699
|
-
const [marquee, setMarquee] = (0,
|
|
9700
|
-
const [dropping, setDropping] = (0,
|
|
9760
|
+
const ref = (0, import_react8.useRef)(null);
|
|
9761
|
+
const [marquee, setMarquee] = (0, import_react8.useState)(null);
|
|
9762
|
+
const [dropping, setDropping] = (0, import_react8.useState)(false);
|
|
9701
9763
|
const h = drag?.mode === "band" && drag.section === section ? drag.h : sec.height || 0;
|
|
9702
9764
|
const DROP_ROOM = 96;
|
|
9703
9765
|
const toPt3 = (e) => {
|
|
@@ -9871,8 +9933,9 @@ var alerted = 0;
|
|
|
9871
9933
|
function alertOnce(msg) {
|
|
9872
9934
|
if (Date.now() - alerted > 3e3) {
|
|
9873
9935
|
alerted = Date.now();
|
|
9874
|
-
|
|
9875
|
-
|
|
9936
|
+
const api = activeStore2();
|
|
9937
|
+
api.setState({ saveError: msg });
|
|
9938
|
+
setTimeout(() => api.setState({ saveError: null }), 3e3);
|
|
9876
9939
|
}
|
|
9877
9940
|
}
|
|
9878
9941
|
function fieldStyle(f) {
|
|
@@ -9880,11 +9943,31 @@ function fieldStyle(f) {
|
|
|
9880
9943
|
const format = formatFor({ name: f.field, type: f.type }, (st.sample?.dataSets?.[f.dataSet] || []).slice(0, 200), { currency: st.def?.currency });
|
|
9881
9944
|
return format ? { format } : {};
|
|
9882
9945
|
}
|
|
9946
|
+
function useItemKeys(item) {
|
|
9947
|
+
const T = useT2();
|
|
9948
|
+
const type = T(`item_${item.type}`) === `item_${item.type}` ? ITEMS[item.type]?.label || item.type : T(`item_${item.type}`);
|
|
9949
|
+
return {
|
|
9950
|
+
tabIndex: 0,
|
|
9951
|
+
role: "group",
|
|
9952
|
+
"data-item-key": item.id,
|
|
9953
|
+
"aria-label": T("b9_itemLabel", { type, name: item.name, x: round(item.x), y: round(item.y) }),
|
|
9954
|
+
onKeyDown: (e) => {
|
|
9955
|
+
if (e.target !== e.currentTarget || e.key !== "Enter" && e.key !== " ") return;
|
|
9956
|
+
e.preventDefault();
|
|
9957
|
+
e.stopPropagation();
|
|
9958
|
+
const st = useDesigner.getState();
|
|
9959
|
+
const cur2 = st.sel.kind === "items" ? st.sel.ids : [];
|
|
9960
|
+
const ids = !e.shiftKey ? [item.id] : cur2.includes(item.id) ? cur2.filter((i2) => i2 !== item.id) : [...cur2, item.id];
|
|
9961
|
+
st.select(ids.length ? { kind: "items", ids } : { kind: "report" });
|
|
9962
|
+
}
|
|
9963
|
+
};
|
|
9964
|
+
}
|
|
9883
9965
|
function useItemDrag(item, scale, setDrag) {
|
|
9884
9966
|
return (e) => {
|
|
9885
9967
|
if (e.button !== 0) return;
|
|
9886
9968
|
e.preventDefault();
|
|
9887
9969
|
e.stopPropagation();
|
|
9970
|
+
e.currentTarget.closest?.("[data-item-key]")?.focus({ preventScroll: true });
|
|
9888
9971
|
const st = useDesigner.getState();
|
|
9889
9972
|
let ids;
|
|
9890
9973
|
if (e.shiftKey) {
|
|
@@ -9957,8 +10040,8 @@ function AnyItem(props) {
|
|
|
9957
10040
|
return layer?.locked ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "layer-locked", "data-locked": props.item.name, children: el }) : el;
|
|
9958
10041
|
}
|
|
9959
10042
|
function NestChildren({ item, scale, drag, setDrag, section }) {
|
|
9960
|
-
const ref = (0,
|
|
9961
|
-
const [over, setOver] = (0,
|
|
10043
|
+
const ref = (0, import_react8.useRef)(null);
|
|
10044
|
+
const [over, setOver] = (0, import_react8.useState)(false);
|
|
9962
10045
|
const accepts = (e) => e.dataTransfer.types.includes(MIME_TOOL) || e.dataTransfer.types.includes(MIME_FIELD) || e.dataTransfer.types.includes(MIME_PART);
|
|
9963
10046
|
const onDrop = (e) => {
|
|
9964
10047
|
setOver(false);
|
|
@@ -10003,8 +10086,9 @@ function ItemView({ item, scale, drag, setDrag, bw, nest, section }) {
|
|
|
10003
10086
|
const selected = useDesigner((s) => s.sel.kind === "items" && s.sel.ids.includes(item.id));
|
|
10004
10087
|
const single = useDesigner((s) => s.sel.kind === "items" && s.sel.ids.length === 1);
|
|
10005
10088
|
const onDown = useItemDrag(item, scale, setDrag);
|
|
10089
|
+
const keys = useItemKeys(item);
|
|
10006
10090
|
const r = rectOf(item, drag);
|
|
10007
|
-
const problems = (0,
|
|
10091
|
+
const problems = (0, import_react8.useContext)(IssueMap).get(item.id);
|
|
10008
10092
|
const onHandle = (dir) => (e) => {
|
|
10009
10093
|
e.preventDefault();
|
|
10010
10094
|
e.stopPropagation();
|
|
@@ -10063,6 +10147,7 @@ function ItemView({ item, scale, drag, setDrag, bw, nest, section }) {
|
|
|
10063
10147
|
title: problems?.join("\n"),
|
|
10064
10148
|
style: { left: r.x * scale, top: r.y * scale, width: Math.max(r.w * scale, 2), height: Math.max(r.h * scale, 2) },
|
|
10065
10149
|
onPointerDown: onDown,
|
|
10150
|
+
...keys,
|
|
10066
10151
|
children: [
|
|
10067
10152
|
nest ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(NestBox, { item: { ...item, ...r }, scale }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ItemBody, { item: { ...item, ...r }, scale }),
|
|
10068
10153
|
nest && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(NestChildren, { item, scale, drag, setDrag, section }),
|
|
@@ -10080,8 +10165,8 @@ function NestBox({ item, scale }) {
|
|
|
10080
10165
|
}
|
|
10081
10166
|
var LIVE = /* @__PURE__ */ new Set(["chart", "matrix", "barcode", "sparkline", "databar", "bullet", "iconset", "rangebar", "richtext"]);
|
|
10082
10167
|
var measurer = null;
|
|
10083
|
-
async function paintItemSvg(shape2, def, sample) {
|
|
10084
|
-
const store =
|
|
10168
|
+
async function paintItemSvg(shape2, def, sample, api = activeStore2()) {
|
|
10169
|
+
const store = await loadFontStore();
|
|
10085
10170
|
await Promise.all([store.load(), customFonts()]);
|
|
10086
10171
|
if (shape2.type === "barcode" || hasType(shape2.items, "barcode")) await loadBarcodes();
|
|
10087
10172
|
measurer || (measurer = new TextMeasurer(store));
|
|
@@ -10092,7 +10177,7 @@ async function paintItemSvg(shape2, def, sample) {
|
|
|
10092
10177
|
} catch {
|
|
10093
10178
|
}
|
|
10094
10179
|
const base2 = { fontFamily: "Inter", fontSize: 9, color: "#1f2937", padding: 2, lineHeight: 1.25, textAlign: "auto", verticalAlign: "top", ...def.styles?.base || {} };
|
|
10095
|
-
const theme3 = themeContext(typeof def.theme === "string" &&
|
|
10180
|
+
const theme3 = themeContext(typeof def.theme === "string" && api.getState().reused[def.theme]?.themeDef || def.themeDef);
|
|
10096
10181
|
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 };
|
|
10097
10182
|
let seq = 0;
|
|
10098
10183
|
const lc = {
|
|
@@ -10134,20 +10219,21 @@ async function paintItemSvg(shape2, def, sample) {
|
|
|
10134
10219
|
return { html: pageToSvg({ items }, shape2.w, h, { background: false }), h, w };
|
|
10135
10220
|
}
|
|
10136
10221
|
function LivePreview({ item, scale }) {
|
|
10222
|
+
const api = useDesignerStore();
|
|
10137
10223
|
const sample = useDesigner((s) => s.sample);
|
|
10138
10224
|
const def = useDesigner((s) => s.def);
|
|
10139
|
-
const [svg, setSvg] = (0,
|
|
10225
|
+
const [svg, setSvg] = (0, import_react8.useState)(null);
|
|
10140
10226
|
const { x, y, ...shape2 } = item;
|
|
10141
10227
|
const key2 = JSON.stringify(shape2);
|
|
10142
|
-
(0,
|
|
10228
|
+
(0, import_react8.useEffect)(() => {
|
|
10143
10229
|
let alive = true;
|
|
10144
10230
|
const t3 = setTimeout(async () => {
|
|
10145
10231
|
try {
|
|
10146
|
-
const out = await paintItemSvg(shape2, def, sample);
|
|
10232
|
+
const out = await paintItemSvg(shape2, def, sample, api);
|
|
10147
10233
|
if (alive) {
|
|
10148
10234
|
setSvg(out);
|
|
10149
|
-
const ex2 =
|
|
10150
|
-
if (Math.round(ex2[item.id]?.w || 0) !== Math.round(out.w))
|
|
10235
|
+
const ex2 = api.getState().extents || {};
|
|
10236
|
+
if (Math.round(ex2[item.id]?.w || 0) !== Math.round(out.w)) api.setState({ extents: { ...ex2, [item.id]: { w: out.w } } });
|
|
10151
10237
|
}
|
|
10152
10238
|
} catch (e) {
|
|
10153
10239
|
if (alive) setSvg({ error: e.message });
|
|
@@ -10169,9 +10255,9 @@ function PartPreview({ item, scale }) {
|
|
|
10169
10255
|
const p = (lib?.parts || []).find((q2) => q2.name === item.part);
|
|
10170
10256
|
const src = p && findItemNamed(lib, p.item);
|
|
10171
10257
|
const props = { ...Object.fromEntries((p?.properties || []).map((q2) => [q2.name, q2.default ?? null])), ...item.properties || {} };
|
|
10172
|
-
const [svg, setSvg] = (0,
|
|
10258
|
+
const [svg, setSvg] = (0, import_react8.useState)(null);
|
|
10173
10259
|
const key2 = JSON.stringify([src, props]);
|
|
10174
|
-
(0,
|
|
10260
|
+
(0, import_react8.useEffect)(() => {
|
|
10175
10261
|
if (!src) return void 0;
|
|
10176
10262
|
let alive = true;
|
|
10177
10263
|
const t3 = setTimeout(() => {
|
|
@@ -10281,17 +10367,18 @@ function TableView({ item, scale, drag, setDrag }) {
|
|
|
10281
10367
|
const readOnly2 = useDesigner((s) => s.readOnly);
|
|
10282
10368
|
const tableSelected = sel.kind === "items" && sel.ids.includes(item.id);
|
|
10283
10369
|
const onGrip = useItemDrag(item, scale, setDrag);
|
|
10370
|
+
const keys = useItemKeys(item);
|
|
10284
10371
|
const r = rectOf(item, drag);
|
|
10285
10372
|
const widths2 = item.columns.map((c, i2) => drag?.mode === "col" && drag.id === item.id && drag.col === i2 ? drag.w : c.width);
|
|
10286
|
-
const [dropCell, setDropCell] = (0,
|
|
10287
|
-
const [menu, setMenu] = (0,
|
|
10288
|
-
const problems = (0,
|
|
10289
|
-
const tblRef = (0,
|
|
10373
|
+
const [dropCell, setDropCell] = (0, import_react8.useState)(null);
|
|
10374
|
+
const [menu, setMenu] = (0, import_react8.useState)(null);
|
|
10375
|
+
const problems = (0, import_react8.useContext)(IssueMap).get(item.id);
|
|
10376
|
+
const tblRef = (0, import_react8.useRef)(null);
|
|
10290
10377
|
const chosen = sel.kind === "cell" && sel.id === item.id ? selCells(sel) : [];
|
|
10291
|
-
(0,
|
|
10378
|
+
(0, import_react8.useEffect)(() => {
|
|
10292
10379
|
if (!menu) return void 0;
|
|
10293
10380
|
const close = (e) => {
|
|
10294
|
-
if (e.type === "keydown" ? e.key === "Escape" : !e.
|
|
10381
|
+
if (e.type === "keydown" ? e.key === "Escape" : !e.composedPath().some((n) => n.classList?.contains("cell-menu"))) setMenu(null);
|
|
10295
10382
|
};
|
|
10296
10383
|
window.addEventListener("pointerdown", close, true);
|
|
10297
10384
|
window.addEventListener("keydown", close);
|
|
@@ -10304,6 +10391,7 @@ function TableView({ item, scale, drag, setDrag }) {
|
|
|
10304
10391
|
e.stopPropagation();
|
|
10305
10392
|
if (e.button !== 0) return;
|
|
10306
10393
|
e.preventDefault();
|
|
10394
|
+
e.currentTarget.closest("[data-item-key]")?.focus({ preventScroll: true });
|
|
10307
10395
|
const st = useDesigner.getState();
|
|
10308
10396
|
const here = { part, row: ri, col: ci };
|
|
10309
10397
|
const cur2 = st.sel.kind === "cell" && st.sel.id === item.id ? st.sel : null;
|
|
@@ -10379,7 +10467,7 @@ function TableView({ item, scale, drag, setDrag }) {
|
|
|
10379
10467
|
const h = t3.header?.[t3.header.length - 1]?.cells?.[ci];
|
|
10380
10468
|
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());
|
|
10381
10469
|
if (h && f.type === "number") h.style = { ...h.style || {}, textAlign: "right" };
|
|
10382
|
-
} else if ((part === "footer" || /^g\d+
|
|
10470
|
+
} else if ((part === "footer" || /^g\d+[hf]$/.test(part)) && f.type === "number") {
|
|
10383
10471
|
cell.value = `=Sum(Fields.${f.field})`;
|
|
10384
10472
|
cell.style = { ...cell.style || {}, ...fieldStyle(f) };
|
|
10385
10473
|
} else cell.value = `=Fields.${f.field}`;
|
|
@@ -10387,7 +10475,7 @@ function TableView({ item, scale, drag, setDrag }) {
|
|
|
10387
10475
|
useDesigner.getState().select({ kind: "cell", id: item.id, part, row: ri, col: ci });
|
|
10388
10476
|
};
|
|
10389
10477
|
let first = true;
|
|
10390
|
-
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: [
|
|
10478
|
+
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: [
|
|
10391
10479
|
problems && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "issue-tag", title: problems.join("\n"), "aria-label": problems.join(". "), children: "!" }),
|
|
10392
10480
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "grip", title: "Select or move the table", onPointerDown: onGrip, children: "⠿" }),
|
|
10393
10481
|
/* @__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)(
|
|
@@ -10517,13 +10605,13 @@ function TableView({ item, scale, drag, setDrag }) {
|
|
|
10517
10605
|
}
|
|
10518
10606
|
|
|
10519
10607
|
// src/designer/Inspector.jsx
|
|
10520
|
-
var
|
|
10608
|
+
var import_react12 = __toESM(require_react(), 1);
|
|
10521
10609
|
|
|
10522
10610
|
// src/designer/ExpressionEditor.jsx
|
|
10523
|
-
var
|
|
10611
|
+
var import_react10 = __toESM(require_react(), 1);
|
|
10524
10612
|
|
|
10525
10613
|
// src/designer/ExprCode.jsx
|
|
10526
|
-
var
|
|
10614
|
+
var import_react9 = __toESM(require_react(), 1);
|
|
10527
10615
|
|
|
10528
10616
|
// node_modules/@marijn/find-cluster-break/src/index.js
|
|
10529
10617
|
var rangeFrom = [];
|
|
@@ -12267,8 +12355,8 @@ var StateField = class _StateField {
|
|
|
12267
12355
|
way it is initialized. Can be useful when you need to provide a
|
|
12268
12356
|
non-default starting value for the field.
|
|
12269
12357
|
*/
|
|
12270
|
-
init(
|
|
12271
|
-
return [this, initField.of({ field: this, create
|
|
12358
|
+
init(create) {
|
|
12359
|
+
return [this, initField.of({ field: this, create })];
|
|
12272
12360
|
}
|
|
12273
12361
|
/**
|
|
12274
12362
|
State field instances can be used as
|
|
@@ -13496,10 +13584,10 @@ var RangeSet = class _RangeSet {
|
|
|
13496
13584
|
for (; ; ) {
|
|
13497
13585
|
let curTo = Math.min(cursor.to, to);
|
|
13498
13586
|
if (cursor.point) {
|
|
13499
|
-
let
|
|
13500
|
-
let openCount = cursor.pointFrom < from ?
|
|
13501
|
-
iterator.point(pos, curTo, cursor.point,
|
|
13502
|
-
openRanges = Math.min(cursor.openEnd(curTo),
|
|
13587
|
+
let active2 = cursor.activeForPoint(cursor.to);
|
|
13588
|
+
let openCount = cursor.pointFrom < from ? active2.length + 1 : cursor.point.startSide < 0 ? active2.length : Math.min(active2.length, openRanges);
|
|
13589
|
+
iterator.point(pos, curTo, cursor.point, active2, openCount, cursor.pointRank);
|
|
13590
|
+
openRanges = Math.min(cursor.openEnd(curTo), active2.length);
|
|
13503
13591
|
} else if (curTo > pos) {
|
|
13504
13592
|
iterator.span(pos, curTo, cursor.active, openRanges);
|
|
13505
13593
|
openRanges = cursor.openEnd(curTo);
|
|
@@ -13913,14 +14001,14 @@ var SpanCursor = class {
|
|
|
13913
14001
|
activeForPoint(to) {
|
|
13914
14002
|
if (!this.active.length)
|
|
13915
14003
|
return this.active;
|
|
13916
|
-
let
|
|
14004
|
+
let active2 = [];
|
|
13917
14005
|
for (let i2 = this.active.length - 1; i2 >= 0; i2--) {
|
|
13918
14006
|
if (this.activeRank[i2] < this.pointRank)
|
|
13919
14007
|
break;
|
|
13920
14008
|
if (this.activeTo[i2] > to || this.activeTo[i2] == to && this.active[i2].endSide >= this.point.endSide)
|
|
13921
|
-
|
|
14009
|
+
active2.push(this.active[i2]);
|
|
13922
14010
|
}
|
|
13923
|
-
return
|
|
14011
|
+
return active2.reverse();
|
|
13924
14012
|
}
|
|
13925
14013
|
openEnd(to) {
|
|
13926
14014
|
let open = 0;
|
|
@@ -15439,9 +15527,9 @@ var viewPlugin = /* @__PURE__ */ Facet.define({
|
|
|
15439
15527
|
}
|
|
15440
15528
|
});
|
|
15441
15529
|
var ViewPlugin = class _ViewPlugin {
|
|
15442
|
-
constructor(id,
|
|
15530
|
+
constructor(id, create, domEventHandlers, domEventObservers, buildExtensions) {
|
|
15443
15531
|
this.id = id;
|
|
15444
|
-
this.create =
|
|
15532
|
+
this.create = create;
|
|
15445
15533
|
this.domEventHandlers = domEventHandlers;
|
|
15446
15534
|
this.domEventObservers = domEventObservers;
|
|
15447
15535
|
this.baseExtensions = buildExtensions(this);
|
|
@@ -15457,9 +15545,9 @@ var ViewPlugin = class _ViewPlugin {
|
|
|
15457
15545
|
Define a plugin from a constructor function that creates the
|
|
15458
15546
|
plugin's value, given an editor view.
|
|
15459
15547
|
*/
|
|
15460
|
-
static define(
|
|
15548
|
+
static define(create, spec) {
|
|
15461
15549
|
const { eventHandlers, eventObservers, provide, decorations: deco } = spec || {};
|
|
15462
|
-
return new _ViewPlugin(nextPluginID++,
|
|
15550
|
+
return new _ViewPlugin(nextPluginID++, create, eventHandlers, eventObservers, (plugin) => {
|
|
15463
15551
|
let ext = [];
|
|
15464
15552
|
if (deco)
|
|
15465
15553
|
ext.push(decorations.of((view) => {
|
|
@@ -15547,11 +15635,11 @@ function getIsolatedRanges(view, line2) {
|
|
|
15547
15635
|
RangeSet.spans(sets, line2.from, line2.to, {
|
|
15548
15636
|
point() {
|
|
15549
15637
|
},
|
|
15550
|
-
span(fromDoc, toDoc,
|
|
15638
|
+
span(fromDoc, toDoc, active2, open) {
|
|
15551
15639
|
let from = fromDoc - line2.from, to = toDoc - line2.from;
|
|
15552
15640
|
let level = result;
|
|
15553
|
-
for (let i2 =
|
|
15554
|
-
let direction =
|
|
15641
|
+
for (let i2 = active2.length - 1; i2 >= 0; i2--, open--) {
|
|
15642
|
+
let direction = active2[i2].spec.bidiIsolate, update;
|
|
15555
15643
|
if (direction == null)
|
|
15556
15644
|
direction = autoDirection(line2.text, from, to);
|
|
15557
15645
|
if (open > 0 && level.length && (update = level[level.length - 1]).to == from && update.direction == direction) {
|
|
@@ -16781,7 +16869,7 @@ var TileUpdate = class {
|
|
|
16781
16869
|
let pendingLineAttrs = null;
|
|
16782
16870
|
let b = this.builder, markCount = -1;
|
|
16783
16871
|
let openEnd = RangeSet.spans(this.decorations, from, to, {
|
|
16784
|
-
point: (from2, to2, deco,
|
|
16872
|
+
point: (from2, to2, deco, active2, openStart, index) => {
|
|
16785
16873
|
if (deco instanceof PointDecoration) {
|
|
16786
16874
|
if (this.disallowBlockEffectsFor[index]) {
|
|
16787
16875
|
if (deco.block)
|
|
@@ -16789,8 +16877,8 @@ var TileUpdate = class {
|
|
|
16789
16877
|
if (to2 > this.view.state.doc.lineAt(from2).to)
|
|
16790
16878
|
throw new RangeError("Decorations that replace line breaks may not be specified via plugins");
|
|
16791
16879
|
}
|
|
16792
|
-
markCount =
|
|
16793
|
-
if (openStart >
|
|
16880
|
+
markCount = active2.length;
|
|
16881
|
+
if (openStart > active2.length) {
|
|
16794
16882
|
b.continueWidget(to2 - from2);
|
|
16795
16883
|
} else {
|
|
16796
16884
|
let widget = deco.widget || (deco.block ? NullWidget.block : NullWidget.inline);
|
|
@@ -16802,7 +16890,7 @@ var TileUpdate = class {
|
|
|
16802
16890
|
b.addBlockWidget(tile);
|
|
16803
16891
|
} else {
|
|
16804
16892
|
b.ensureLine(pendingLineAttrs);
|
|
16805
|
-
b.addInlineWidget(tile,
|
|
16893
|
+
b.addInlineWidget(tile, active2, openStart);
|
|
16806
16894
|
}
|
|
16807
16895
|
}
|
|
16808
16896
|
pendingLineAttrs = null;
|
|
@@ -16812,7 +16900,7 @@ var TileUpdate = class {
|
|
|
16812
16900
|
if (to2 > from2)
|
|
16813
16901
|
this.text.skip(to2 - from2);
|
|
16814
16902
|
},
|
|
16815
|
-
span: (from2, to2,
|
|
16903
|
+
span: (from2, to2, active2, openStart) => {
|
|
16816
16904
|
for (let pos = from2; pos < to2; ) {
|
|
16817
16905
|
let chars = this.text.next(Math.min(512, to2 - pos));
|
|
16818
16906
|
if (chars == null) {
|
|
@@ -16821,12 +16909,12 @@ var TileUpdate = class {
|
|
|
16821
16909
|
pos++;
|
|
16822
16910
|
} else {
|
|
16823
16911
|
b.ensureLine(pendingLineAttrs);
|
|
16824
|
-
b.addText(chars,
|
|
16912
|
+
b.addText(chars, active2, pos == from2 ? openStart : active2.length);
|
|
16825
16913
|
pos += chars.length;
|
|
16826
16914
|
}
|
|
16827
16915
|
pendingLineAttrs = null;
|
|
16828
16916
|
}
|
|
16829
|
-
markCount =
|
|
16917
|
+
markCount = active2.length;
|
|
16830
16918
|
}
|
|
16831
16919
|
});
|
|
16832
16920
|
if (markCount > -1)
|
|
@@ -18815,9 +18903,9 @@ handlers.mousedown = (view, event) => {
|
|
|
18815
18903
|
if (mustFocus)
|
|
18816
18904
|
view.observer.ignore(() => {
|
|
18817
18905
|
focusPreventScroll(view.contentDOM);
|
|
18818
|
-
let
|
|
18819
|
-
if (
|
|
18820
|
-
|
|
18906
|
+
let active2 = view.root.activeElement;
|
|
18907
|
+
if (active2 && !active2.contains(view.contentDOM))
|
|
18908
|
+
active2.blur();
|
|
18821
18909
|
});
|
|
18822
18910
|
let mouseSel = view.inputState.mouseSelection;
|
|
18823
18911
|
if (mouseSel) {
|
|
@@ -28860,7 +28948,7 @@ function scrollIntoView2(container2, element) {
|
|
|
28860
28948
|
function score(option) {
|
|
28861
28949
|
return (option.boost || 0) * 100 + (option.apply ? 10 : 0) + (option.info ? 5 : 0) + (option.type ? 1 : 0);
|
|
28862
28950
|
}
|
|
28863
|
-
function sortOptions(
|
|
28951
|
+
function sortOptions(active2, state) {
|
|
28864
28952
|
let options = [];
|
|
28865
28953
|
let sections = null, dynamicSectionScore = null;
|
|
28866
28954
|
let addOption = (option) => {
|
|
@@ -28875,7 +28963,7 @@ function sortOptions(active, state) {
|
|
|
28875
28963
|
}
|
|
28876
28964
|
};
|
|
28877
28965
|
let conf = state.facet(completionConfig);
|
|
28878
|
-
for (let a of
|
|
28966
|
+
for (let a of active2)
|
|
28879
28967
|
if (a.hasResult()) {
|
|
28880
28968
|
let getMatch = a.result.getMatch;
|
|
28881
28969
|
if (a.result.filter === false) {
|
|
@@ -28938,12 +29026,12 @@ var CompletionDialog = class _CompletionDialog {
|
|
|
28938
29026
|
setSelected(selected, id) {
|
|
28939
29027
|
return selected == this.selected || selected >= this.options.length ? this : new _CompletionDialog(this.options, makeAttrs(id, selected), this.tooltip, this.timestamp, selected, this.disabled);
|
|
28940
29028
|
}
|
|
28941
|
-
static build(
|
|
28942
|
-
if (prev && !didSetActive &&
|
|
29029
|
+
static build(active2, state, id, prev, conf, didSetActive) {
|
|
29030
|
+
if (prev && !didSetActive && active2.some((s) => s.isPending))
|
|
28943
29031
|
return prev.setDisabled();
|
|
28944
|
-
let options = sortOptions(
|
|
29032
|
+
let options = sortOptions(active2, state);
|
|
28945
29033
|
if (!options.length)
|
|
28946
|
-
return prev &&
|
|
29034
|
+
return prev && active2.some((a) => a.isPending) ? prev.setDisabled() : null;
|
|
28947
29035
|
let selected = state.facet(completionConfig).selectOnOpen ? 0 : -1;
|
|
28948
29036
|
if (prev && prev.selected != selected && prev.selected != -1) {
|
|
28949
29037
|
let selectedValue = prev.options[prev.selected].completion;
|
|
@@ -28954,7 +29042,7 @@ var CompletionDialog = class _CompletionDialog {
|
|
|
28954
29042
|
}
|
|
28955
29043
|
}
|
|
28956
29044
|
return new _CompletionDialog(options, makeAttrs(id, selected), {
|
|
28957
|
-
pos:
|
|
29045
|
+
pos: active2.reduce((a, b) => b.hasResult() ? Math.min(a, b.from) : a, 1e8),
|
|
28958
29046
|
create: createTooltip,
|
|
28959
29047
|
above: conf.aboveCursor
|
|
28960
29048
|
}, prev ? prev.timestamp : Date.now(), selected, false);
|
|
@@ -28967,8 +29055,8 @@ var CompletionDialog = class _CompletionDialog {
|
|
|
28967
29055
|
}
|
|
28968
29056
|
};
|
|
28969
29057
|
var CompletionState = class _CompletionState {
|
|
28970
|
-
constructor(
|
|
28971
|
-
this.active =
|
|
29058
|
+
constructor(active2, id, open) {
|
|
29059
|
+
this.active = active2;
|
|
28972
29060
|
this.id = id;
|
|
28973
29061
|
this.open = open;
|
|
28974
29062
|
}
|
|
@@ -28978,7 +29066,7 @@ var CompletionState = class _CompletionState {
|
|
|
28978
29066
|
update(tr) {
|
|
28979
29067
|
let { state } = tr, conf = state.facet(completionConfig);
|
|
28980
29068
|
let sources = conf.override || state.languageDataAt("autocomplete", cur(state)).map(asSource);
|
|
28981
|
-
let
|
|
29069
|
+
let active2 = sources.map((source) => {
|
|
28982
29070
|
let value = this.active.find((s) => s.source == source) || new ActiveSource(
|
|
28983
29071
|
source,
|
|
28984
29072
|
this.active.some(
|
|
@@ -28989,17 +29077,17 @@ var CompletionState = class _CompletionState {
|
|
|
28989
29077
|
);
|
|
28990
29078
|
return value.update(tr, conf);
|
|
28991
29079
|
});
|
|
28992
|
-
if (
|
|
28993
|
-
|
|
29080
|
+
if (active2.length == this.active.length && active2.every((a, i2) => a == this.active[i2]))
|
|
29081
|
+
active2 = this.active;
|
|
28994
29082
|
let open = this.open, didSet = tr.effects.some((e) => e.is(setActiveEffect));
|
|
28995
29083
|
if (open && tr.docChanged)
|
|
28996
29084
|
open = open.map(tr.changes);
|
|
28997
|
-
if (tr.selection ||
|
|
28998
|
-
open = CompletionDialog.build(
|
|
28999
|
-
else if (open && open.disabled && !
|
|
29085
|
+
if (tr.selection || active2.some((a) => a.hasResult() && tr.changes.touchesRange(a.from, a.to)) || !sameResults(active2, this.active) || didSet)
|
|
29086
|
+
open = CompletionDialog.build(active2, state, this.id, open, conf, didSet);
|
|
29087
|
+
else if (open && open.disabled && !active2.some((a) => a.isPending))
|
|
29000
29088
|
open = null;
|
|
29001
|
-
if (!open &&
|
|
29002
|
-
|
|
29089
|
+
if (!open && active2.every((a) => !a.isPending) && active2.some((a) => a.hasResult()))
|
|
29090
|
+
active2 = active2.map((a) => a.hasResult() ? new ActiveSource(
|
|
29003
29091
|
a.source,
|
|
29004
29092
|
0
|
|
29005
29093
|
/* State.Inactive */
|
|
@@ -29007,7 +29095,7 @@ var CompletionState = class _CompletionState {
|
|
|
29007
29095
|
for (let effect of tr.effects)
|
|
29008
29096
|
if (effect.is(setSelectedEffect))
|
|
29009
29097
|
open = open && open.setSelected(effect.value, this.id);
|
|
29010
|
-
return
|
|
29098
|
+
return active2 == this.active && open == this.open ? this : new _CompletionState(active2, this.id, open);
|
|
29011
29099
|
}
|
|
29012
29100
|
get tooltip() {
|
|
29013
29101
|
return this.open ? this.open.tooltip : null;
|
|
@@ -29092,9 +29180,9 @@ var ActiveSource = class _ActiveSource {
|
|
|
29092
29180
|
/* State.Inactive */
|
|
29093
29181
|
);
|
|
29094
29182
|
else if (effect.is(setActiveEffect)) {
|
|
29095
|
-
for (let
|
|
29096
|
-
if (
|
|
29097
|
-
value =
|
|
29183
|
+
for (let active2 of effect.value)
|
|
29184
|
+
if (active2.source == value.source)
|
|
29185
|
+
value = active2;
|
|
29098
29186
|
}
|
|
29099
29187
|
}
|
|
29100
29188
|
return value;
|
|
@@ -29238,8 +29326,8 @@ var closeCompletion = (view) => {
|
|
|
29238
29326
|
return true;
|
|
29239
29327
|
};
|
|
29240
29328
|
var RunningQuery = class {
|
|
29241
|
-
constructor(
|
|
29242
|
-
this.active =
|
|
29329
|
+
constructor(active2, context) {
|
|
29330
|
+
this.active = active2;
|
|
29243
29331
|
this.context = context;
|
|
29244
29332
|
this.time = Date.now();
|
|
29245
29333
|
this.updates = [];
|
|
@@ -29256,9 +29344,9 @@ var completionPlugin = /* @__PURE__ */ ViewPlugin.fromClass(class {
|
|
|
29256
29344
|
this.debounceAccept = -1;
|
|
29257
29345
|
this.pendingStart = false;
|
|
29258
29346
|
this.composing = 0;
|
|
29259
|
-
for (let
|
|
29260
|
-
if (
|
|
29261
|
-
this.startQuery(
|
|
29347
|
+
for (let active2 of view.state.field(completionState).active)
|
|
29348
|
+
if (active2.isPending)
|
|
29349
|
+
this.startQuery(active2);
|
|
29262
29350
|
}
|
|
29263
29351
|
update(update) {
|
|
29264
29352
|
let cState = update.state.field(completionState);
|
|
@@ -29303,19 +29391,19 @@ var completionPlugin = /* @__PURE__ */ ViewPlugin.fromClass(class {
|
|
|
29303
29391
|
this.debounceUpdate = -1;
|
|
29304
29392
|
this.pendingStart = false;
|
|
29305
29393
|
let { state } = this.view, cState = state.field(completionState);
|
|
29306
|
-
for (let
|
|
29307
|
-
if (
|
|
29308
|
-
this.startQuery(
|
|
29394
|
+
for (let active2 of cState.active) {
|
|
29395
|
+
if (active2.isPending && !this.running.some((r) => r.active.source == active2.source))
|
|
29396
|
+
this.startQuery(active2);
|
|
29309
29397
|
}
|
|
29310
29398
|
if (this.running.length && cState.open && cState.open.disabled)
|
|
29311
29399
|
this.debounceAccept = setTimeout(() => this.accept(), this.view.state.facet(completionConfig).updateSyncTime);
|
|
29312
29400
|
}
|
|
29313
|
-
startQuery(
|
|
29401
|
+
startQuery(active2) {
|
|
29314
29402
|
let { state } = this.view, pos = cur(state);
|
|
29315
|
-
let context = new CompletionContext(state, pos,
|
|
29316
|
-
let pending2 = new RunningQuery(
|
|
29403
|
+
let context = new CompletionContext(state, pos, active2.explicit, this.view);
|
|
29404
|
+
let pending2 = new RunningQuery(active2, context);
|
|
29317
29405
|
this.running.push(pending2);
|
|
29318
|
-
Promise.resolve(
|
|
29406
|
+
Promise.resolve(active2.source(context)).then((result) => {
|
|
29319
29407
|
if (!pending2.context.aborted) {
|
|
29320
29408
|
pending2.done = result || null;
|
|
29321
29409
|
this.scheduleAccept();
|
|
@@ -29348,26 +29436,26 @@ var completionPlugin = /* @__PURE__ */ ViewPlugin.fromClass(class {
|
|
|
29348
29436
|
if (query.done) {
|
|
29349
29437
|
let pos = cur(query.updates.length ? query.updates[0].startState : this.view.state);
|
|
29350
29438
|
let limit = Math.min(pos, query.done.from + (query.active.explicit ? 0 : 1));
|
|
29351
|
-
let
|
|
29439
|
+
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);
|
|
29352
29440
|
for (let tr of query.updates)
|
|
29353
|
-
|
|
29354
|
-
if (
|
|
29355
|
-
updated.push(
|
|
29441
|
+
active2 = active2.update(tr, conf);
|
|
29442
|
+
if (active2.hasResult()) {
|
|
29443
|
+
updated.push(active2);
|
|
29356
29444
|
continue;
|
|
29357
29445
|
}
|
|
29358
29446
|
}
|
|
29359
29447
|
let current2 = cState.active.find((a) => a.source == query.active.source);
|
|
29360
29448
|
if (current2 && current2.isPending) {
|
|
29361
29449
|
if (query.done == null) {
|
|
29362
|
-
let
|
|
29450
|
+
let active2 = new ActiveSource(
|
|
29363
29451
|
query.active.source,
|
|
29364
29452
|
0
|
|
29365
29453
|
/* State.Inactive */
|
|
29366
29454
|
);
|
|
29367
29455
|
for (let tr of query.updates)
|
|
29368
|
-
|
|
29369
|
-
if (!
|
|
29370
|
-
updated.push(
|
|
29456
|
+
active2 = active2.update(tr, conf);
|
|
29457
|
+
if (!active2.isPending)
|
|
29458
|
+
updated.push(active2);
|
|
29371
29459
|
} else {
|
|
29372
29460
|
this.startQuery(current2);
|
|
29373
29461
|
}
|
|
@@ -29824,12 +29912,12 @@ var theme2 = EditorView.theme({
|
|
|
29824
29912
|
"&.cm-focused .cm-selectionBackground, .cm-selectionBackground": { background: "var(--accent-soft)" }
|
|
29825
29913
|
});
|
|
29826
29914
|
var UNKNOWN = Decoration.mark({ class: "cm-unknown-field" });
|
|
29827
|
-
var ExprCode = (0,
|
|
29828
|
-
const host = (0,
|
|
29829
|
-
const view = (0,
|
|
29830
|
-
const latest2 = (0,
|
|
29915
|
+
var ExprCode = (0, import_react9.forwardRef)(function ExprCode2({ value, onChange, fields, parameters, invalid, check }, ref) {
|
|
29916
|
+
const host = (0, import_react9.useRef)(null);
|
|
29917
|
+
const view = (0, import_react9.useRef)(null);
|
|
29918
|
+
const latest2 = (0, import_react9.useRef)({ onChange, fields, parameters, check });
|
|
29831
29919
|
latest2.current = { onChange, fields, parameters, check };
|
|
29832
|
-
(0,
|
|
29920
|
+
(0, import_react9.useImperativeHandle)(ref, () => ({
|
|
29833
29921
|
insert(text) {
|
|
29834
29922
|
const v = view.current;
|
|
29835
29923
|
if (!v) return;
|
|
@@ -29843,7 +29931,7 @@ var ExprCode = (0, import_react8.forwardRef)(function ExprCode2({ value, onChang
|
|
|
29843
29931
|
view.current?.focus();
|
|
29844
29932
|
}
|
|
29845
29933
|
}));
|
|
29846
|
-
(0,
|
|
29934
|
+
(0, import_react9.useEffect)(() => {
|
|
29847
29935
|
const complete = (ctx) => {
|
|
29848
29936
|
const m = ctx.matchBefore(/(Fields|Parameters|Globals)\.\w*$/);
|
|
29849
29937
|
if (m) {
|
|
@@ -29932,8 +30020,8 @@ var SNIPPETS = {
|
|
|
29932
30020
|
function ExpressionEditor({ value, dataSet, onSave, onClose, title }) {
|
|
29933
30021
|
const def = useDesigner((s) => s.def);
|
|
29934
30022
|
const sample = useDesigner((s) => s.sample);
|
|
29935
|
-
const [text, setText] = (0,
|
|
29936
|
-
const ta = (0,
|
|
30023
|
+
const [text, setText] = (0, import_react10.useState)(value ?? "");
|
|
30024
|
+
const ta = (0, import_react10.useRef)(null);
|
|
29937
30025
|
const dsName = dataSet || def.dataSets?.[0]?.name;
|
|
29938
30026
|
const ds = def.dataSets?.find((d) => d.name === dsName);
|
|
29939
30027
|
const fields = fieldNames(ds).filter((n) => !(ds?.fields || []).some((f) => f.name === n && f.type === "object"));
|
|
@@ -29943,7 +30031,7 @@ function ExpressionEditor({ value, dataSet, onSave, onClose, title }) {
|
|
|
29943
30031
|
const insert2 = (s) => ta.current?.insert(s);
|
|
29944
30032
|
const err = checkValue(text);
|
|
29945
30033
|
const issues = err ? [] : check(text);
|
|
29946
|
-
const preview = (0,
|
|
30034
|
+
const preview = (0, import_react10.useMemo)(() => {
|
|
29947
30035
|
if (err || !sample?.dataSets) return null;
|
|
29948
30036
|
const rows = sample.dataSets[dsName] || [];
|
|
29949
30037
|
const params = Object.fromEntries((def.parameters || []).map((p) => [p.name, p.default ?? null]));
|
|
@@ -30016,7 +30104,7 @@ function ExpressionEditor({ value, dataSet, onSave, onClose, title }) {
|
|
|
30016
30104
|
}
|
|
30017
30105
|
|
|
30018
30106
|
// src/designer/CondFormat.jsx
|
|
30019
|
-
var
|
|
30107
|
+
var import_react11 = __toESM(require_react(), 1);
|
|
30020
30108
|
|
|
30021
30109
|
// src/designer/cfRules.js
|
|
30022
30110
|
var CF_OPS = ["eq", "ne", "lt", "le", "gt", "ge", "between", "top", "bottom", "aboveAvg", "belowAvg", "contains", "startsWith", "empty", "notEmpty"];
|
|
@@ -30136,7 +30224,7 @@ function CondFormat({ title, cf: start, fields, thisValue, kind, custom, onApply
|
|
|
30136
30224
|
const lang2 = useDesigner((s) => s.lang);
|
|
30137
30225
|
const T = (k, v) => t(lang2, k, v);
|
|
30138
30226
|
const blank = () => ({ field: thisValue ? void 0 : fields[0], op: "gt", value: "", format: kind === "chart" ? { backgroundColor: "#dc2626" } : { color: "#b42318", fontWeight: "bold" } });
|
|
30139
|
-
const [cf, setCf] = (0,
|
|
30227
|
+
const [cf, setCf] = (0, import_react11.useState)(() => JSON.parse(JSON.stringify(start || { mode: "first", rules: [blank()] })));
|
|
30140
30228
|
const rules = cf.rules || [];
|
|
30141
30229
|
const setRule = (i2, patch) => setCf((c) => ({ ...c, rules: c.rules.map((r, j) => j === i2 ? { ...r, ...patch } : r) }));
|
|
30142
30230
|
const setFmt = (i2, k, v) => setCf((c) => ({ ...c, rules: c.rules.map((r, j) => {
|
|
@@ -30227,7 +30315,7 @@ var catLabel = (tk, cat) => tk(`cat_${cat}`, cat);
|
|
|
30227
30315
|
function Inspector() {
|
|
30228
30316
|
const sel = useDesigner((s) => s.sel);
|
|
30229
30317
|
const def = useDesigner((s) => s.def);
|
|
30230
|
-
const [expr, setExpr] = (0,
|
|
30318
|
+
const [expr, setExpr] = (0, import_react12.useState)(null);
|
|
30231
30319
|
const openExpr = (cfg) => setExpr(cfg);
|
|
30232
30320
|
let body;
|
|
30233
30321
|
if (sel.kind === "items" && sel.ids.length > 1) body = /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Multi, { ids: sel.ids });
|
|
@@ -30242,13 +30330,13 @@ function Inspector() {
|
|
|
30242
30330
|
const one = sel.kind === "items" && sel.ids.length === 1 ? findItem(def, sel.ids[0])?.item : sel.kind === "cell" ? findItem(def, sel.id)?.item : null;
|
|
30243
30331
|
const scope = one ? one.dataSet || def.dataSets?.[0]?.name || null : void 0;
|
|
30244
30332
|
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 || ""}`;
|
|
30245
|
-
const ref = (0,
|
|
30246
|
-
(0,
|
|
30333
|
+
const ref = (0, import_react12.useRef)(null);
|
|
30334
|
+
(0, import_react12.useLayoutEffect)(() => {
|
|
30247
30335
|
const pane = ref.current?.closest(".dright");
|
|
30248
30336
|
if (pane) pane.scrollTop = 0;
|
|
30249
30337
|
}, [selKey]);
|
|
30250
|
-
const [closed, setClosed] = (0,
|
|
30251
|
-
(0,
|
|
30338
|
+
const [closed, setClosed] = (0, import_react12.useState)(() => /* @__PURE__ */ new Set());
|
|
30339
|
+
(0, import_react12.useLayoutEffect)(() => {
|
|
30252
30340
|
for (const h of ref.current?.querySelectorAll(".cat > h5") || []) {
|
|
30253
30341
|
const shut = closed.has(h.textContent);
|
|
30254
30342
|
h.querySelector("button")?.setAttribute("aria-expanded", String(!shut));
|
|
@@ -30267,13 +30355,13 @@ function Inspector() {
|
|
|
30267
30355
|
});
|
|
30268
30356
|
};
|
|
30269
30357
|
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { "data-testid": "inspector", ref, onClick: toggle, children: [
|
|
30270
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(FieldScope.Provider, { value: scope, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
30358
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(FieldScope.Provider, { value: scope, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react12.Fragment, { children: body }, selKey) }),
|
|
30271
30359
|
expr && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ExpressionEditor, { ...expr, onClose: () => setExpr(null) })
|
|
30272
30360
|
] });
|
|
30273
30361
|
}
|
|
30274
|
-
function Geo({ label, value, onChange }) {
|
|
30362
|
+
function Geo({ label, value, onChange, min }) {
|
|
30275
30363
|
const unit = useDesigner((s) => s.unit);
|
|
30276
|
-
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))) }) });
|
|
30364
|
+
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))) }) });
|
|
30277
30365
|
}
|
|
30278
30366
|
function PropEditor({ p: spec, value, onChange, openExpr, dataSet, item }) {
|
|
30279
30367
|
const T = useT3();
|
|
@@ -30338,7 +30426,7 @@ function OverflowTarget({ value, onChange, self }) {
|
|
|
30338
30426
|
}
|
|
30339
30427
|
function ExprOr({ p, value, onChange, openExpr, dataSet, children }) {
|
|
30340
30428
|
const T = useT3();
|
|
30341
|
-
const [on, setOn] = (0,
|
|
30429
|
+
const [on, setOn] = (0, import_react12.useState)(isDynamic(value));
|
|
30342
30430
|
const label = T(on ? "useFixed" : "useExpr");
|
|
30343
30431
|
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Field, { label: p.label, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "expr-row", children: [
|
|
30344
30432
|
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,
|
|
@@ -30351,7 +30439,7 @@ function ExprOr({ p, value, onChange, openExpr, dataSet, children }) {
|
|
|
30351
30439
|
function PaletteEditor({ label, value, onChange }) {
|
|
30352
30440
|
const T = useT3();
|
|
30353
30441
|
const custom = Array.isArray(value);
|
|
30354
|
-
const [text, setText] = (0,
|
|
30442
|
+
const [text, setText] = (0, import_react12.useState)(custom ? value.join(", ") : "");
|
|
30355
30443
|
const parse2 = (t3) => t3.split(/[\s,;]+/).map((x) => x.trim()).filter((x) => /^#[0-9a-f]{6}$/i.test(x));
|
|
30356
30444
|
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: { display: "grid", gap: 6 }, children: [
|
|
30357
30445
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Field, { label, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
@@ -30378,17 +30466,18 @@ function PaletteEditor({ label, value, onChange }) {
|
|
|
30378
30466
|
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)) })
|
|
30379
30467
|
] });
|
|
30380
30468
|
}
|
|
30381
|
-
var
|
|
30469
|
+
var reportLists = /* @__PURE__ */ new Map();
|
|
30382
30470
|
function ReportPicker({ value, onChange }) {
|
|
30383
|
-
const [list2, setList] = (0,
|
|
30384
|
-
const listId = (0,
|
|
30385
|
-
(0,
|
|
30471
|
+
const [list2, setList] = (0, import_react12.useState)(() => reportLists.get(useDesigner.getState().embed?.server || "") || []);
|
|
30472
|
+
const listId = (0, import_react12.useState)(() => `reports-${Math.random().toString(36).slice(2, 8)}`)[0];
|
|
30473
|
+
(0, import_react12.useEffect)(() => {
|
|
30386
30474
|
const embed = useDesigner.getState().embed;
|
|
30387
|
-
if (reportList || embed && !embed.server) return;
|
|
30388
30475
|
const server2 = embed?.server || "";
|
|
30476
|
+
if (reportLists.has(server2) || embed && !embed.server) return;
|
|
30389
30477
|
fetch(`${server2}/api/reports`).then((r) => r.ok ? r.json() : []).then((l) => {
|
|
30390
|
-
|
|
30391
|
-
|
|
30478
|
+
const v = Array.isArray(l) ? l : [];
|
|
30479
|
+
reportLists.set(server2, v);
|
|
30480
|
+
setList(v);
|
|
30392
30481
|
}).catch(() => {
|
|
30393
30482
|
});
|
|
30394
30483
|
}, []);
|
|
@@ -30422,8 +30511,8 @@ function ItemProps({ item, section, openExpr }) {
|
|
|
30422
30511
|
const tk = useTk();
|
|
30423
30512
|
const def = useDesigner((s) => s.def);
|
|
30424
30513
|
const spec = ITEMS[item.type];
|
|
30425
|
-
const [nameErr, setNameErr] = (0,
|
|
30426
|
-
const [find2, setFind] = (0,
|
|
30514
|
+
const [nameErr, setNameErr] = (0, import_react12.useState)(null);
|
|
30515
|
+
const [find2, setFind] = (0, import_react12.useState)("");
|
|
30427
30516
|
const q2 = find2.trim().toLowerCase();
|
|
30428
30517
|
const hit = (p, type) => !q2 || propLabel(tk, p, type).toLowerCase().includes(q2) || p.key.toLowerCase().includes(q2);
|
|
30429
30518
|
const props = (spec?.props || []).filter((p) => (!p.showIf || p.showIf(item)) && hit(p, item.type));
|
|
@@ -30475,8 +30564,8 @@ function ItemProps({ item, section, openExpr }) {
|
|
|
30475
30564
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "grid2", children: [
|
|
30476
30565
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Geo, { label: "X", value: item.x, onChange: (v) => setGeo("x", Math.max(0, v)) }),
|
|
30477
30566
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Geo, { label: "Y", value: item.y, onChange: (v) => setGeo("y", Math.max(0, v)) }),
|
|
30478
|
-
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)) }),
|
|
30479
|
-
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)) }),
|
|
30567
|
+
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)) }),
|
|
30568
|
+
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)) }),
|
|
30480
30569
|
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" }) })
|
|
30481
30570
|
] }),
|
|
30482
30571
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "hint", children: (() => {
|
|
@@ -30567,7 +30656,7 @@ function PivotEditor({ item, openExpr }) {
|
|
|
30567
30656
|
const def = useDesigner((s) => s.def);
|
|
30568
30657
|
const fields = fieldsOf2(def, item.dataSet);
|
|
30569
30658
|
const spec = normalizeMatrix(item);
|
|
30570
|
-
const [pick, setPick] = (0,
|
|
30659
|
+
const [pick, setPick] = (0, import_react12.useState)({ rowGroups: "", columnGroups: "", values: "" });
|
|
30571
30660
|
const edit = (fn3, key2) => updateItem(item.id, (it) => {
|
|
30572
30661
|
if (!isTablix(it)) {
|
|
30573
30662
|
const n = normalizeMatrix(it);
|
|
@@ -30646,7 +30735,17 @@ function PivotEditor({ item, openExpr }) {
|
|
|
30646
30735
|
/* @__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) }) })
|
|
30647
30736
|
] })
|
|
30648
30737
|
] }),
|
|
30649
|
-
(i2 < spec[list2].length - 1 || list2 === "rowGroups" && g.parent) && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Check, { label: T("pivotCollapsible"), checked: g.collapsible, onChange: (v) =>
|
|
30738
|
+
(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) => {
|
|
30739
|
+
const o = it[list2][i2];
|
|
30740
|
+
if (v) {
|
|
30741
|
+
o.collapsible = true;
|
|
30742
|
+
o.initiallyCollapsed = true;
|
|
30743
|
+
} else {
|
|
30744
|
+
delete o.collapsible;
|
|
30745
|
+
delete o.initiallyCollapsed;
|
|
30746
|
+
}
|
|
30747
|
+
}, `${item.id}.${list2}${i2}.collapsible`) }),
|
|
30748
|
+
" ",
|
|
30650
30749
|
g.collapsible && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Check, { label: T("pivotStartCollapsed"), checked: g.initiallyCollapsed, onChange: (v) => setK(list2, i2, "initiallyCollapsed", v) }),
|
|
30651
30750
|
/* @__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 }) }),
|
|
30652
30751
|
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 }) })
|
|
@@ -30672,7 +30771,7 @@ function PivotEditor({ item, openExpr }) {
|
|
|
30672
30771
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "grid2", children: [
|
|
30673
30772
|
/* @__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) }) }),
|
|
30674
30773
|
/* @__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" }) }),
|
|
30675
|
-
/* @__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) =>
|
|
30774
|
+
/* @__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`) }) })
|
|
30676
30775
|
] }),
|
|
30677
30776
|
/* @__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 }) }),
|
|
30678
30777
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Field, { label: T("cellBookmark"), children: exprField("values", i2, "bookmark", v.bookmark, T("cellBookmark")) })
|
|
@@ -30714,8 +30813,8 @@ function GroupsEditor({ table: table2, openExpr }) {
|
|
|
30714
30813
|
const T = useT3();
|
|
30715
30814
|
const def = useDesigner((s) => s.def);
|
|
30716
30815
|
const fields = fieldsOf2(def, table2.dataSet);
|
|
30717
|
-
const [pick, setPick] = (0,
|
|
30718
|
-
const [drill, setDrill] = (0,
|
|
30816
|
+
const [pick, setPick] = (0, import_react12.useState)("");
|
|
30817
|
+
const [drill, setDrill] = (0, import_react12.useState)(false);
|
|
30719
30818
|
const setG = (i2, k, v) => updateItem(table2.id, (t3) => {
|
|
30720
30819
|
if (v === void 0 || v === "" || v === false) delete t3.groups[i2][k];
|
|
30721
30820
|
else t3.groups[i2][k] = v;
|
|
@@ -30957,7 +31056,7 @@ rimary" ? void 0 : v), "aria-label": `${T("overlayAxis")} ${i2 + 1}` }) }),
|
|
|
30957
31056
|
}
|
|
30958
31057
|
function CfButton({ label, title, target, at: at2, kind, fields, apply: apply2, testid }) {
|
|
30959
31058
|
const T = useT3();
|
|
30960
|
-
const [open, setOpen] = (0,
|
|
31059
|
+
const [open, setOpen] = (0, import_react12.useState)(false);
|
|
30961
31060
|
const n = target?.cf?.rules?.length || 0;
|
|
30962
31061
|
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
30963
31062
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("button", { type: "button", className: "btn sm", onClick: () => setOpen(true), "data-testid": testid, children: [
|
|
@@ -31024,14 +31123,16 @@ function VisualEditor({ cell, setCell, openExpr, dataSet }) {
|
|
|
31024
31123
|
}
|
|
31025
31124
|
var reportParams = /* @__PURE__ */ new Map();
|
|
31026
31125
|
function useReportParams(id) {
|
|
31027
|
-
const
|
|
31028
|
-
(0,
|
|
31126
|
+
const srv = () => useDesigner.getState().embed?.server || "";
|
|
31127
|
+
const [list2, setList] = (0, import_react12.useState)(() => reportParams.get(`${srv()} ${id}`) ?? null);
|
|
31128
|
+
(0, import_react12.useEffect)(() => {
|
|
31029
31129
|
if (!id || isDynamic(id)) {
|
|
31030
31130
|
setList(null);
|
|
31031
31131
|
return;
|
|
31032
31132
|
}
|
|
31033
|
-
|
|
31034
|
-
|
|
31133
|
+
const key2 = `${srv()} ${id}`;
|
|
31134
|
+
if (reportParams.has(key2)) {
|
|
31135
|
+
setList(reportParams.get(key2));
|
|
31035
31136
|
return;
|
|
31036
31137
|
}
|
|
31037
31138
|
let alive = true;
|
|
@@ -31044,7 +31145,7 @@ function useReportParams(id) {
|
|
|
31044
31145
|
fetch(`${server2}/api/reports/${encodeURIComponent(id)}`).then((r) => r.ok ? r.json() : null).then((r) => {
|
|
31045
31146
|
const d = r?.definition || r;
|
|
31046
31147
|
const ps = d && typeof d === "object" ? (d.parameters || []).map((p) => ({ name: p.name, required: !!p.required && p.default == null, prompt: p.prompt })) : null;
|
|
31047
|
-
if (ps) reportParams.set(
|
|
31148
|
+
if (ps) reportParams.set(key2, ps);
|
|
31048
31149
|
if (alive) setList(ps);
|
|
31049
31150
|
}).catch(() => {
|
|
31050
31151
|
if (alive) setList(null);
|
|
@@ -31058,7 +31159,7 @@ function useReportParams(id) {
|
|
|
31058
31159
|
function ParamMap({ value, onChange, known, openExpr, dataSet, testid }) {
|
|
31059
31160
|
const T = useT3();
|
|
31060
31161
|
const map = value || {};
|
|
31061
|
-
const [extra, setExtra] = (0,
|
|
31162
|
+
const [extra, setExtra] = (0, import_react12.useState)("");
|
|
31062
31163
|
const knownNames = new Set((known || []).map((p) => p.name));
|
|
31063
31164
|
const names = [...(known || []).map((p) => p.name), ...Object.keys(map).filter((k) => !knownNames.has(k))];
|
|
31064
31165
|
const set2 = (k, v, keep) => {
|
|
@@ -31477,7 +31578,7 @@ function ReportProps() {
|
|
|
31477
31578
|
const T = useT3();
|
|
31478
31579
|
const def = useDesigner((s) => s.def);
|
|
31479
31580
|
const families = useFontFamilies();
|
|
31480
|
-
const [fontsOpen, setFontsOpen] = (0,
|
|
31581
|
+
const [fontsOpen, setFontsOpen] = (0, import_react12.useState)(false);
|
|
31481
31582
|
const set2 = (fn3, key2) => useDesigner.getState().apply(fn3, key2);
|
|
31482
31583
|
const m = Array.isArray(def.page?.margins) ? def.page.margins : [36, 36, 36, 36];
|
|
31483
31584
|
const base2 = def.styles?.base || {};
|
|
@@ -31556,7 +31657,7 @@ function ReportProps() {
|
|
|
31556
31657
|
function ReportImages() {
|
|
31557
31658
|
const T = useT3();
|
|
31558
31659
|
const images = useDesigner((s) => s.def.images) || {};
|
|
31559
|
-
const [err, setErr] = (0,
|
|
31660
|
+
const [err, setErr] = (0, import_react12.useState)(null);
|
|
31560
31661
|
const set2 = (fn3) => useDesigner.getState().apply((d) => {
|
|
31561
31662
|
d.images || (d.images = {});
|
|
31562
31663
|
fn3(d.images);
|
|
@@ -31595,7 +31696,7 @@ function EmbeddedPicker({ item, onPick }) {
|
|
|
31595
31696
|
const images = useDesigner((s) => s.def.images) || {};
|
|
31596
31697
|
const names = Object.keys(images);
|
|
31597
31698
|
const cur2 = /^embedded:(.+)$/.exec(String(item.src || ""))?.[1];
|
|
31598
|
-
const [err, setErr] = (0,
|
|
31699
|
+
const [err, setErr] = (0, import_react12.useState)(null);
|
|
31599
31700
|
const upload = async (files) => {
|
|
31600
31701
|
setErr(null);
|
|
31601
31702
|
const r = await uploadImages(files, T);
|
|
@@ -31680,7 +31781,7 @@ function NamedStyles() {
|
|
|
31680
31781
|
const styleNames = useStyleNames();
|
|
31681
31782
|
const def = useDesigner((s) => s.def);
|
|
31682
31783
|
const named = def.styles?.named || {};
|
|
31683
|
-
const [newName, setNewName] = (0,
|
|
31784
|
+
const [newName, setNewName] = (0, import_react12.useState)("");
|
|
31684
31785
|
const setS = (name2, k, v) => useDesigner.getState().apply((d) => {
|
|
31685
31786
|
var _a2, _b;
|
|
31686
31787
|
d.styles || (d.styles = {});
|
|
@@ -31715,7 +31816,7 @@ function NamedStyles() {
|
|
|
31715
31816
|
}
|
|
31716
31817
|
|
|
31717
31818
|
// src/designer/DataPanel.jsx
|
|
31718
|
-
var
|
|
31819
|
+
var import_react15 = __toESM(require_react(), 1);
|
|
31719
31820
|
|
|
31720
31821
|
// src/designer/explore.js
|
|
31721
31822
|
var key = (k) => /^[A-Za-z_$][\w$]*$/.test(k) ? `.${k}` : `['${k}']`;
|
|
@@ -31751,7 +31852,7 @@ function bestRows(root) {
|
|
|
31751
31852
|
}
|
|
31752
31853
|
|
|
31753
31854
|
// src/designer/ODataEditor.jsx
|
|
31754
|
-
var
|
|
31855
|
+
var import_react13 = __toESM(require_react(), 1);
|
|
31755
31856
|
var import_jsx_runtime11 = __toESM(require_jsx_runtime(), 1);
|
|
31756
31857
|
var OPS3 = ["eq", "ne", "gt", "ge", "lt", "le", "contains", "startswith", "endswith"];
|
|
31757
31858
|
var OP_LABEL = { eq: "=", ne: "≠", gt: ">", ge: "≥", lt: "<", le: "≤" };
|
|
@@ -31766,7 +31867,7 @@ async function readMetadata(s) {
|
|
|
31766
31867
|
return odataMetadata(await res.text());
|
|
31767
31868
|
}
|
|
31768
31869
|
function ODataEditor({ s, setS, T }) {
|
|
31769
|
-
const [meta2, setMeta] = (0,
|
|
31870
|
+
const [meta2, setMeta] = (0, import_react13.useState)(null);
|
|
31770
31871
|
const sets = meta2?.sets || [];
|
|
31771
31872
|
const set2 = sets.find((x) => x.name === s.entitySet);
|
|
31772
31873
|
const props = set2 ? set2.properties : (s.select || []).map((name2) => ({ name: name2, type: s.types?.[name2] || "" }));
|
|
@@ -31857,7 +31958,7 @@ function ODataEditor({ s, setS, T }) {
|
|
|
31857
31958
|
}
|
|
31858
31959
|
|
|
31859
31960
|
// src/designer/SqlBuilder.jsx
|
|
31860
|
-
var
|
|
31961
|
+
var import_react14 = __toESM(require_react(), 1);
|
|
31861
31962
|
|
|
31862
31963
|
// src/designer/sqlBuild.js
|
|
31863
31964
|
var FILTER_OPS2 = ["=", "<>", "<", "<=", ">", ">=", "like", "in", "is null", "is not null"];
|
|
@@ -31930,8 +32031,8 @@ function normalizeSchema(body) {
|
|
|
31930
32031
|
return tables;
|
|
31931
32032
|
}
|
|
31932
32033
|
function useSchema(connection) {
|
|
31933
|
-
const [st, setSt] = (0,
|
|
31934
|
-
(0,
|
|
32034
|
+
const [st, setSt] = (0, import_react14.useState)(() => schemas.has(connection) ? { tables: schemas.get(connection) } : { loading: !!connection });
|
|
32035
|
+
(0, import_react14.useEffect)(() => {
|
|
31935
32036
|
if (!connection) {
|
|
31936
32037
|
setSt({});
|
|
31937
32038
|
return void 0;
|
|
@@ -31965,8 +32066,8 @@ function SqlBuilder({ s, setS, T, kind, onManual }) {
|
|
|
31965
32066
|
const nb = { ...b, ...patch };
|
|
31966
32067
|
setS({ ...s, builder: nb, query: buildSql(nb, kind) });
|
|
31967
32068
|
};
|
|
31968
|
-
const [find2, setFind] = (0,
|
|
31969
|
-
const [preview, setPreview] = (0,
|
|
32069
|
+
const [find2, setFind] = (0, import_react14.useState)("");
|
|
32070
|
+
const [preview, setPreview] = (0, import_react14.useState)(null);
|
|
31970
32071
|
const sql = buildSql(b, kind);
|
|
31971
32072
|
const tableOf2 = (name2) => (schema.tables || []).find((t3) => t3.name === name2);
|
|
31972
32073
|
const colsOf = (alias) => tableOf2(b.tables.find((t3) => t3.alias === alias)?.name)?.columns || [];
|
|
@@ -31995,7 +32096,7 @@ function SqlBuilder({ s, setS, T, kind, onManual }) {
|
|
|
31995
32096
|
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;
|
|
31996
32097
|
set2({ joins: [...b.joins, { type: "inner", from, to }] });
|
|
31997
32098
|
};
|
|
31998
|
-
const offered = (0,
|
|
32099
|
+
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]);
|
|
31999
32100
|
const runPreview = async () => {
|
|
32000
32101
|
setPreview({ loading: true });
|
|
32001
32102
|
try {
|
|
@@ -32158,7 +32259,7 @@ function SqlBuilder({ s, setS, T, kind, onManual }) {
|
|
|
32158
32259
|
] });
|
|
32159
32260
|
}
|
|
32160
32261
|
function JoinAdder({ allCols, split, onAdd, T }) {
|
|
32161
|
-
const [a, setA] = (0,
|
|
32262
|
+
const [a, setA] = (0, import_react14.useState)(""), [z, setZ] = (0, import_react14.useState)("");
|
|
32162
32263
|
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "qb-row", children: [
|
|
32163
32264
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Select, { value: a, allowEmpty: true, options: allCols, onChange: (v) => setA(v || ""), "aria-label": T("qb_joinFrom") }),
|
|
32164
32265
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: "=" }),
|
|
@@ -32175,17 +32276,18 @@ function JoinAdder({ allCols, split, onAdd, T }) {
|
|
|
32175
32276
|
var import_jsx_runtime13 = __toESM(require_jsx_runtime(), 1);
|
|
32176
32277
|
var NAME2 = /^[A-Za-z_][\w]*$/;
|
|
32177
32278
|
var noSourceKey = (def) => (def?.dataSources || []).length ? null : "r4_noDataSource";
|
|
32178
|
-
async function loadSample() {
|
|
32179
|
-
const
|
|
32180
|
-
|
|
32279
|
+
async function loadSample(store) {
|
|
32280
|
+
const api = store?.getState ? store : activeStore();
|
|
32281
|
+
const { def } = api.getState();
|
|
32282
|
+
api.setState({ sample: { loading: true } });
|
|
32181
32283
|
try {
|
|
32182
32284
|
const params = resolveParameters(def, {});
|
|
32183
32285
|
const sources = await loadSources(def, { params, baseUrl: origin(), sqlPreview: true, fetch: reportFetch(origin(), void 0, { sqlPreview: true }) });
|
|
32184
32286
|
const ctx = { params, globals: { ExecutionTime: /* @__PURE__ */ new Date() }, dataSets: {}, fields: null, locale: def.locale, currency: def.currency, functions: functionTable(def) };
|
|
32185
32287
|
const dataSets = buildDataSets(def, sources, ctx);
|
|
32186
|
-
|
|
32288
|
+
api.setState({ sample: { dataSets, sources, at: Date.now() } });
|
|
32187
32289
|
} catch (e) {
|
|
32188
|
-
|
|
32290
|
+
api.setState({ sample: { error: e.message } });
|
|
32189
32291
|
}
|
|
32190
32292
|
}
|
|
32191
32293
|
function DataPanel() {
|
|
@@ -32193,8 +32295,8 @@ function DataPanel() {
|
|
|
32193
32295
|
const lang2 = useDesigner((s) => s.lang);
|
|
32194
32296
|
const T = (k, v) => t(lang2, k, v);
|
|
32195
32297
|
const sample = useDesigner((s) => s.sample);
|
|
32196
|
-
const [dlg, setDlg] = (0,
|
|
32197
|
-
const [open, setOpen] = (0,
|
|
32298
|
+
const [dlg, setDlg] = (0, import_react15.useState)(null);
|
|
32299
|
+
const [open, setOpen] = (0, import_react15.useState)(() => new Set((def.dataSets || []).map((d) => d.name)));
|
|
32198
32300
|
const toggle = (n) => setOpen((s) => {
|
|
32199
32301
|
const x = new Set(s);
|
|
32200
32302
|
x.has(n) ? x.delete(n) : x.add(n);
|
|
@@ -32343,10 +32445,10 @@ function ParamDialog({ index, onClose }) {
|
|
|
32343
32445
|
const lang2 = useDesigner((s) => s.lang);
|
|
32344
32446
|
const T = (k, v) => t(lang2, k, v);
|
|
32345
32447
|
const orig = index != null ? def.parameters[index] : null;
|
|
32346
|
-
const [p, setP] = (0,
|
|
32347
|
-
const [columns, setColumns] = (0,
|
|
32348
|
-
const [live, setLive] = (0,
|
|
32349
|
-
const [choicesText, setChoicesText] = (0,
|
|
32448
|
+
const [p, setP] = (0, import_react15.useState)(orig || { name: "", type: "string", prompt: "", default: "", required: false });
|
|
32449
|
+
const [columns, setColumns] = (0, import_react15.useState)(String(def.parameterLayout?.columns || 1));
|
|
32450
|
+
const [live, setLive] = (0, import_react15.useState)(def.liveParameters !== false);
|
|
32451
|
+
const [choicesText, setChoicesText] = (0, import_react15.useState)(() => (p.options || []).map(optionLine).join("\n"));
|
|
32350
32452
|
const fromFields = (def.dataSets?.find((d) => d.name === p.optionsFrom?.dataSet)?.fields || []).map((f) => f.name);
|
|
32351
32453
|
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 }] : []];
|
|
32352
32454
|
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;
|
|
@@ -32493,7 +32595,7 @@ function SourceDialog({ index, onClose }) {
|
|
|
32493
32595
|
const lang2 = useDesigner((s2) => s2.lang);
|
|
32494
32596
|
const T = (k, v) => t(lang2, k, v);
|
|
32495
32597
|
const orig = index != null ? def.dataSources[index] : null;
|
|
32496
|
-
const [s, setS] = (0,
|
|
32598
|
+
const [s, setS] = (0, import_react15.useState)(() => ({
|
|
32497
32599
|
name: "",
|
|
32498
32600
|
type: "rest",
|
|
32499
32601
|
method: "GET",
|
|
@@ -32557,11 +32659,11 @@ function SourceDialog({ index, onClose }) {
|
|
|
32557
32659
|
if (!err && s.type === "sql" && !s.connection) err = "Pick a connection";
|
|
32558
32660
|
if (!err && s.type === "sql" && s.procedure != null && !s.procedure) err = "Pick a stored procedure";
|
|
32559
32661
|
if (!err && s.type === "sql" && s.procedure == null && !/^\s*(select|with)\b/i.test(s.query || "")) err = "Write a SELECT query";
|
|
32560
|
-
const [conns, setConns] = (0,
|
|
32662
|
+
const [conns, setConns] = (0, import_react15.useState)(null);
|
|
32561
32663
|
const procs = (conns || []).find((c) => c.name === s.connection)?.procs || [];
|
|
32562
32664
|
const sqlKind = (conns || []).find((c) => c.name === s.connection)?.kind || "sqlite";
|
|
32563
|
-
const [probe, setProbe] = (0,
|
|
32564
|
-
(0,
|
|
32665
|
+
const [probe, setProbe] = (0, import_react15.useState)(null);
|
|
32666
|
+
(0, import_react15.useEffect)(() => {
|
|
32565
32667
|
if (s.type !== "sql" || conns) return;
|
|
32566
32668
|
fetch("/api/data/sql/connections").then((r) => r.ok ? r.json() : []).then(setConns).catch(() => setConns([]));
|
|
32567
32669
|
}, [s.type, conns]);
|
|
@@ -32754,13 +32856,13 @@ function DataSetDialog({ index, onClose, onSaved }) {
|
|
|
32754
32856
|
const lang2 = useDesigner((s) => s.lang);
|
|
32755
32857
|
const T = (k, v) => t(lang2, k, v);
|
|
32756
32858
|
const orig = index != null ? def.dataSets[index] : null;
|
|
32757
|
-
const [d, setD] = (0,
|
|
32758
|
-
const [detect, setDetect] = (0,
|
|
32759
|
-
const [pathTyped, setPathTyped] = (0,
|
|
32859
|
+
const [d, setD] = (0, import_react15.useState)(() => ({ name: "", source: def.dataSources?.[0]?.name, path: "$", fields: [], sort: [], ...orig ? JSON.parse(JSON.stringify(orig)) : {} }));
|
|
32860
|
+
const [detect, setDetect] = (0, import_react15.useState)({ state: "idle" });
|
|
32861
|
+
const [pathTyped, setPathTyped] = (0, import_react15.useState)(!!orig);
|
|
32760
32862
|
const nested = !!d.relation;
|
|
32761
32863
|
const parents = (def.dataSets || []).filter((x, i2) => i2 !== index && x.name !== d.name);
|
|
32762
32864
|
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;
|
|
32763
|
-
const [explore, setExplore] = (0,
|
|
32865
|
+
const [explore, setExplore] = (0, import_react15.useState)(null);
|
|
32764
32866
|
const loadSourceRaw = async (name2) => {
|
|
32765
32867
|
const params = resolveParameters(useDesigner.getState().def, {});
|
|
32766
32868
|
const src = useDesigner.getState().def.dataSources.find((s) => s.name === name2);
|
|
@@ -33010,7 +33112,7 @@ function DataSetDialog({ index, onClose, onSaved }) {
|
|
|
33010
33112
|
}
|
|
33011
33113
|
|
|
33012
33114
|
// src/designer/Outline.jsx
|
|
33013
|
-
var
|
|
33115
|
+
var import_react16 = __toESM(require_react(), 1);
|
|
33014
33116
|
var import_jsx_runtime14 = __toESM(require_jsx_runtime(), 1);
|
|
33015
33117
|
var MIME = "application/x-pw-outline";
|
|
33016
33118
|
function Outline() {
|
|
@@ -33019,11 +33121,32 @@ function Outline() {
|
|
|
33019
33121
|
const lang2 = useDesigner((s) => s.lang);
|
|
33020
33122
|
const readOnly2 = useDesigner((s) => s.readOnly);
|
|
33021
33123
|
const T = (k, v) => t(lang2, k, v);
|
|
33022
|
-
const [drop, setDrop] = (0,
|
|
33023
|
-
const [said, setSaid] = (0,
|
|
33024
|
-
const
|
|
33025
|
-
const
|
|
33124
|
+
const [drop, setDrop] = (0, import_react16.useState)(null);
|
|
33125
|
+
const [said, setSaid] = (0, import_react16.useState)("");
|
|
33126
|
+
const [cur2, setCur] = (0, import_react16.useState)(null);
|
|
33127
|
+
const dragged = (0, import_react16.useRef)(null);
|
|
33128
|
+
const body = (0, import_react16.useRef)(null);
|
|
33026
33129
|
const chosen = new Set(sel.kind === "items" ? sel.ids : sel.kind === "cell" ? [sel.id] : []);
|
|
33130
|
+
const keys = sectionList(def).flatMap(({ key: key2 }) => {
|
|
33131
|
+
const out = [`band:${key2}`];
|
|
33132
|
+
const go = (l) => l.forEach((it) => {
|
|
33133
|
+
out.push(it.id);
|
|
33134
|
+
if (NESTING.has(it.type)) go(it.items || []);
|
|
33135
|
+
});
|
|
33136
|
+
go(secOf(def, key2)?.items || []);
|
|
33137
|
+
return out;
|
|
33138
|
+
});
|
|
33139
|
+
const stop = keys.includes(cur2) ? cur2 : keys.find((k) => chosen.has(k) || sel.kind === "section" && k === `band:${sel.section}`) || keys[0];
|
|
33140
|
+
const roving = (k) => ({ tabIndex: k === stop ? 0 : -1, onFocus: () => setCur(k) });
|
|
33141
|
+
const nav2 = (e) => {
|
|
33142
|
+
if (e.defaultPrevented || e.altKey || e.metaKey || e.ctrlKey || !e.target.hasAttribute("data-opt")) return;
|
|
33143
|
+
const all = [...e.currentTarget.querySelectorAll("[data-opt]")];
|
|
33144
|
+
const i2 = all.indexOf(e.target);
|
|
33145
|
+
const j = e.key === "ArrowDown" ? i2 + 1 : e.key === "ArrowUp" ? i2 - 1 : e.key === "Home" ? 0 : e.key === "End" ? all.length - 1 : null;
|
|
33146
|
+
if (j == null) return;
|
|
33147
|
+
e.preventDefault();
|
|
33148
|
+
all[Math.max(0, Math.min(all.length - 1, j))]?.focus();
|
|
33149
|
+
};
|
|
33027
33150
|
const pick = (e, id) => {
|
|
33028
33151
|
const st = useDesigner.getState();
|
|
33029
33152
|
if (e.shiftKey && st.sel.kind === "items") {
|
|
@@ -33135,30 +33258,32 @@ function Outline() {
|
|
|
33135
33258
|
};
|
|
33136
33259
|
const rows = (list2, parent, depth, section) => list2.map((it, i2) => {
|
|
33137
33260
|
const mark = drop && drop.id != null && drop.id === it.id ? ` drop-${drop.where}` : "";
|
|
33138
|
-
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("li", { children: [
|
|
33261
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("li", { role: "none", children: [
|
|
33139
33262
|
/* @__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: [
|
|
33140
33263
|
!readOnly2 && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "grip", "aria-hidden": "true", children: "⠿" }),
|
|
33141
|
-
/* @__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-pressed": chosen.has(it.id), "aria-describedby": readOnly2 ?
|
|
33264
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", "data-opt": "", className: "linklike nm", onClick: (e) => pick(e, it.id), onKeyDown: (e) => onKey(e, it, list2, i2, parent), "aria-pressed": chosen.has(it.id), "aria-describedby": readOnly2 ? "outline-nav" : "outline-nav outline-keys", ...roving(it.id), children: it.name }),
|
|
33142
33265
|
/* @__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}`) }),
|
|
33143
33266
|
!readOnly2 && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "act", style: { display: "inline-flex", gap: 2 }, children: [
|
|
33144
|
-
/* @__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: "↑" }),
|
|
33145
|
-
/* @__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: "↓" }),
|
|
33146
|
-
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: "⇱" })
|
|
33267
|
+
/* @__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: "↑" }),
|
|
33268
|
+
/* @__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: "↓" }),
|
|
33269
|
+
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: "⇱" })
|
|
33147
33270
|
] })
|
|
33148
33271
|
] }),
|
|
33149
|
-
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) })
|
|
33272
|
+
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) })
|
|
33150
33273
|
] }, it.id);
|
|
33151
33274
|
});
|
|
33152
33275
|
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "pane", "data-testid": "outline", children: [
|
|
33153
33276
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h4", { children: T("outline") }),
|
|
33154
33277
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "pane-body", ref: body, children: [
|
|
33155
|
-
sectionList(def).map(({ key: key2, label }) => {
|
|
33278
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { role: "group", "aria-label": T("outline"), onKeyDown: nav2, children: sectionList(def).map(({ key: key2, label }) => {
|
|
33156
33279
|
const items = secOf(def, key2)?.items || [];
|
|
33157
|
-
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: `outline-sec${drop?.band === key2 ? " drop-band" : ""}`, "data-outline-band": key2, ...bandDrop(key2), children: [
|
|
33158
|
-
/* @__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 }),
|
|
33159
|
-
|
|
33280
|
+
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: [
|
|
33281
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", "data-opt": "", "aria-pressed": 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}`),
|
|
33282
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("b", { children: label }) }),
|
|
33283
|
+
/* @__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") }) })
|
|
33160
33284
|
] }, key2);
|
|
33161
|
-
}),
|
|
33285
|
+
}) }),
|
|
33286
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "sr-only", id: "outline-nav", children: T("b9_outlineKeys") }),
|
|
33162
33287
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "hint", children: T("outlineHint") }),
|
|
33163
33288
|
!readOnly2 && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "hint", id: "outline-keys", children: T("outlineKeys") }),
|
|
33164
33289
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "sr-only", role: "status", "aria-live": "polite", children: said })
|
|
@@ -33167,7 +33292,7 @@ function Outline() {
|
|
|
33167
33292
|
}
|
|
33168
33293
|
|
|
33169
33294
|
// src/theme/ThemeToggle.jsx
|
|
33170
|
-
var
|
|
33295
|
+
var import_react17 = __toESM(require_react(), 1);
|
|
33171
33296
|
|
|
33172
33297
|
// src/theme/theme.js
|
|
33173
33298
|
var THEME_KEY = "pw-theme";
|
|
@@ -33209,8 +33334,8 @@ function Icon2({ pref }) {
|
|
|
33209
33334
|
] });
|
|
33210
33335
|
}
|
|
33211
33336
|
function ThemeToggle({ className = "btn sm ghost icon" }) {
|
|
33212
|
-
const [pref, setPref] = (0,
|
|
33213
|
-
(0,
|
|
33337
|
+
const [pref, setPref] = (0, import_react17.useState)("system");
|
|
33338
|
+
(0, import_react17.useEffect)(() => {
|
|
33214
33339
|
setPref(readPreference());
|
|
33215
33340
|
const mq = window.matchMedia("(prefers-color-scheme: dark)");
|
|
33216
33341
|
const onChange = () => {
|
|
@@ -33228,7 +33353,7 @@ function ThemeToggle({ className = "btn sm ghost icon" }) {
|
|
|
33228
33353
|
}
|
|
33229
33354
|
|
|
33230
33355
|
// src/designer/ChartWizard.jsx
|
|
33231
|
-
var
|
|
33356
|
+
var import_react18 = __toESM(require_react(), 1);
|
|
33232
33357
|
var import_jsx_runtime16 = __toESM(require_jsx_runtime(), 1);
|
|
33233
33358
|
var TYPES = ["column", "bar", "line", "area", "pie", "donut", "scatter", "bubble", "radar", "funnel", "gauge", "treemap", "histogram", "boxplot", "waterfall", "gantt"];
|
|
33234
33359
|
var PER_ROW = /* @__PURE__ */ new Set(["scatter", "bubble"]);
|
|
@@ -33344,14 +33469,14 @@ function ChartWizard() {
|
|
|
33344
33469
|
const close = () => useDesigner.getState().setUi({ wizard: null });
|
|
33345
33470
|
const lang2 = useDesigner((s) => s.lang);
|
|
33346
33471
|
const tr = (k, v) => t(lang2, `cw_${k}`, v);
|
|
33347
|
-
const [c, setC] = (0,
|
|
33472
|
+
const [c, setC] = (0, import_react18.useState)(() => {
|
|
33348
33473
|
if (editing) return configFromChart(editing);
|
|
33349
33474
|
const score2 = (d) => ((d.fields || []).some((f) => f.type === "number") ? 1e6 : 0) + (sample?.dataSets?.[d.name]?.length || 0);
|
|
33350
33475
|
const ds2 = [...def.dataSets || []].sort((a, b) => score2(b) - score2(a))[0];
|
|
33351
33476
|
return { title: "", split: "", stacked: false, format: "N0", ...guess(ds2, sample?.dataSets?.[ds2?.name] || []) };
|
|
33352
33477
|
});
|
|
33353
33478
|
const set2 = (patch) => setC((x) => ({ ...x, ...patch, custom: false }));
|
|
33354
|
-
(0,
|
|
33479
|
+
(0, import_react18.useEffect)(() => {
|
|
33355
33480
|
if (!sample?.dataSets && !sample?.loading) loadSample();
|
|
33356
33481
|
}, []);
|
|
33357
33482
|
const ds = (def.dataSets || []).find((d) => d.name === c.dataSet);
|
|
@@ -33362,7 +33487,7 @@ function ChartWizard() {
|
|
|
33362
33487
|
const good = suggested(c, rows, fields);
|
|
33363
33488
|
const dateCategory = fields.find((f) => f.name === c.category)?.type === "date";
|
|
33364
33489
|
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);
|
|
33365
|
-
const compact = (0,
|
|
33490
|
+
const compact = (0, import_react18.useMemo)(() => {
|
|
33366
33491
|
if (!c.value || c.agg === "Count" || c.format === "P1") return null;
|
|
33367
33492
|
const per = /* @__PURE__ */ new Map();
|
|
33368
33493
|
for (const r of rows) {
|
|
@@ -33378,14 +33503,14 @@ function ChartWizard() {
|
|
|
33378
33503
|
const d = def.dataSets.find((x) => x.name === name2);
|
|
33379
33504
|
setC((x) => ({ ...x, split: "", ...guess(d, sample?.dataSets?.[name2] || []) }));
|
|
33380
33505
|
};
|
|
33381
|
-
(0,
|
|
33506
|
+
(0, import_react18.useEffect)(() => {
|
|
33382
33507
|
if (editing || !rows.length || c.touched) return;
|
|
33383
33508
|
setC((x) => ({ ...x, ...guess(ds, rows), touched: true }));
|
|
33384
33509
|
}, [rows.length]);
|
|
33385
|
-
const [thumbs, setThumbs] = (0,
|
|
33386
|
-
const [big, setBig] = (0,
|
|
33510
|
+
const [thumbs, setThumbs] = (0, import_react18.useState)({});
|
|
33511
|
+
const [big, setBig] = (0, import_react18.useState)(null);
|
|
33387
33512
|
const cfgKey = JSON.stringify({ ...c, touched: void 0 });
|
|
33388
|
-
(0,
|
|
33513
|
+
(0, import_react18.useEffect)(() => {
|
|
33389
33514
|
if (!sample?.dataSets || !c.dataSet) return;
|
|
33390
33515
|
let alive = true;
|
|
33391
33516
|
const t3 = setTimeout(async () => {
|
|
@@ -33573,7 +33698,7 @@ function rawText(raw) {
|
|
|
33573
33698
|
}
|
|
33574
33699
|
|
|
33575
33700
|
// src/designer/TableWizard.jsx
|
|
33576
|
-
var
|
|
33701
|
+
var import_react19 = __toESM(require_react(), 1);
|
|
33577
33702
|
var import_jsx_runtime17 = __toESM(require_jsx_runtime(), 1);
|
|
33578
33703
|
var LAYOUTS = [
|
|
33579
33704
|
{ id: "list", label: "List", when: "Every row, with totals" },
|
|
@@ -33586,12 +33711,13 @@ function TableWizard() {
|
|
|
33586
33711
|
const wiz = useDesigner((s) => s.tableWizard);
|
|
33587
33712
|
const def = useDesigner((s) => s.def);
|
|
33588
33713
|
const sample = useDesigner((s) => s.sample);
|
|
33714
|
+
const lang2 = useDesigner((s) => s.lang);
|
|
33589
33715
|
const close = () => useDesigner.getState().setUi({ tableWizard: null });
|
|
33590
33716
|
const parent = wiz?.parentId ? findItem(def, wiz.parentId)?.item : null;
|
|
33591
33717
|
const width = Math.max(120, Math.round((parent ? parent.w : bodyWidth(def, wiz?.section || "body")) - (wiz?.x || 0)));
|
|
33592
|
-
const [c, setC] = (0,
|
|
33718
|
+
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: "" }));
|
|
33593
33719
|
const set2 = (patch) => setC((x) => ({ ...x, ...patch }));
|
|
33594
|
-
(0,
|
|
33720
|
+
(0, import_react19.useEffect)(() => {
|
|
33595
33721
|
if (!sample?.dataSets && !sample?.loading) loadSample();
|
|
33596
33722
|
}, []);
|
|
33597
33723
|
const ds = (def.dataSets || []).find((d) => d.name === c.dataSet);
|
|
@@ -33605,9 +33731,9 @@ function TableWizard() {
|
|
|
33605
33731
|
const groupBy2 = c.groupBy || groupGuess;
|
|
33606
33732
|
const mRows = c.mRows || groupBy2, mCols = c.mCols || text.find((f) => f.name !== mRows)?.name || "", mValue = c.mValue || nums[0]?.name || "";
|
|
33607
33733
|
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 });
|
|
33608
|
-
const [thumbs, setThumbs] = (0,
|
|
33734
|
+
const [thumbs, setThumbs] = (0, import_react19.useState)({});
|
|
33609
33735
|
const key2 = JSON.stringify([c, groupBy2, mRows, mCols, mValue, chosen]);
|
|
33610
|
-
(0,
|
|
33736
|
+
(0, import_react19.useEffect)(() => {
|
|
33611
33737
|
if (!ds || !sample?.dataSets) return;
|
|
33612
33738
|
let alive = true;
|
|
33613
33739
|
const t3 = setTimeout(async () => {
|
|
@@ -33652,7 +33778,7 @@ function TableWizard() {
|
|
|
33652
33778
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("button", { className: "btn ghost", onClick: () => {
|
|
33653
33779
|
useDesigner.getState().setUi({ tableWizard: null, pivotWizard: { section: wiz.section, x: wiz.x, y: wiz.y, parentId: wiz.parentId, dataSet: c.dataSet } });
|
|
33654
33780
|
}, "data-testid": "open-pivot-wizard", children: [
|
|
33655
|
-
t(
|
|
33781
|
+
t(lang2, "pivotWizard"),
|
|
33656
33782
|
"…"
|
|
33657
33783
|
] }),
|
|
33658
33784
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("button", { className: "btn", onClick: close, children: "Cancel" }),
|
|
@@ -33665,7 +33791,7 @@ function TableWizard() {
|
|
|
33665
33791
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("section", { className: "cw-side", "aria-label": "Data for the table", children: [
|
|
33666
33792
|
/* @__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: "" }) }) }),
|
|
33667
33793
|
sample?.loading && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "hint", children: "Calling the API…" }),
|
|
33668
|
-
noSourceKey(def) && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "hint", role: "status", "data-testid": "no-source", children: t(
|
|
33794
|
+
noSourceKey(def) && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "hint", role: "status", "data-testid": "no-source", children: t(lang2, noSourceKey(def)) }),
|
|
33669
33795
|
sample?.error && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "err", children: sample.error }),
|
|
33670
33796
|
c.layout !== "matrix" && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
|
|
33671
33797
|
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 }) }) }),
|
|
@@ -33695,7 +33821,7 @@ function TableWizard() {
|
|
|
33695
33821
|
}
|
|
33696
33822
|
|
|
33697
33823
|
// src/designer/AskAi.jsx
|
|
33698
|
-
var
|
|
33824
|
+
var import_react20 = __toESM(require_react(), 1);
|
|
33699
33825
|
var import_jsx_runtime18 = __toESM(require_jsx_runtime(), 1);
|
|
33700
33826
|
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;
|
|
33701
33827
|
function changes(before, after) {
|
|
@@ -33711,9 +33837,9 @@ function changes(before, after) {
|
|
|
33711
33837
|
function AskAi({ onClose }) {
|
|
33712
33838
|
const def = useDesigner((s) => s.def);
|
|
33713
33839
|
const sample = useDesigner((s) => s.sample);
|
|
33714
|
-
const [prompt, setPrompt] = (0,
|
|
33715
|
-
const [st, setSt] = (0,
|
|
33716
|
-
(0,
|
|
33840
|
+
const [prompt, setPrompt] = (0, import_react20.useState)("");
|
|
33841
|
+
const [st, setSt] = (0, import_react20.useState)({ state: "idle" });
|
|
33842
|
+
(0, import_react20.useEffect)(() => {
|
|
33717
33843
|
if (!sample?.dataSets && !sample?.loading) loadSample();
|
|
33718
33844
|
}, []);
|
|
33719
33845
|
const ask = async () => {
|
|
@@ -33727,7 +33853,7 @@ function AskAi({ onClose }) {
|
|
|
33727
33853
|
let preview = null;
|
|
33728
33854
|
try {
|
|
33729
33855
|
const params = resolveParameters(out.definition, {}, { lenient: true });
|
|
33730
|
-
const model = await render(out.definition, { fontStore:
|
|
33856
|
+
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()) });
|
|
33731
33857
|
preview = { html: pageToSvg(model.pages[0], model.width, model.height), pages: model.pages.length };
|
|
33732
33858
|
} catch (e) {
|
|
33733
33859
|
preview = { error: e.message };
|
|
@@ -33798,7 +33924,7 @@ function AskAi({ onClose }) {
|
|
|
33798
33924
|
}
|
|
33799
33925
|
|
|
33800
33926
|
// src/designer/PivotWizard.jsx
|
|
33801
|
-
var
|
|
33927
|
+
var import_react21 = __toESM(require_react(), 1);
|
|
33802
33928
|
var import_jsx_runtime19 = __toESM(require_jsx_runtime(), 1);
|
|
33803
33929
|
var MIME_PF = "application/x-pw-pivot-field";
|
|
33804
33930
|
var AGGS2 = ["Sum", "Avg", "Count", "Min", "Max"];
|
|
@@ -33830,9 +33956,9 @@ function Thumb({ item }) {
|
|
|
33830
33956
|
const T = useT2();
|
|
33831
33957
|
const def = useDesigner((s) => s.def);
|
|
33832
33958
|
const sample = useDesigner((s) => s.sample);
|
|
33833
|
-
const [svg, setSvg] = (0,
|
|
33959
|
+
const [svg, setSvg] = (0, import_react21.useState)(null);
|
|
33834
33960
|
const key2 = JSON.stringify(item);
|
|
33835
|
-
(0,
|
|
33961
|
+
(0, import_react21.useEffect)(() => {
|
|
33836
33962
|
if (!item || !sample?.dataSets) return void 0;
|
|
33837
33963
|
let alive = true;
|
|
33838
33964
|
const t3 = setTimeout(() => {
|
|
@@ -33854,7 +33980,7 @@ function Thumb({ item }) {
|
|
|
33854
33980
|
function useData(name2) {
|
|
33855
33981
|
const def = useDesigner((s) => s.def);
|
|
33856
33982
|
const sample = useDesigner((s) => s.sample);
|
|
33857
|
-
(0,
|
|
33983
|
+
(0, import_react21.useEffect)(() => {
|
|
33858
33984
|
if (!sample?.dataSets && !sample?.loading) loadSample();
|
|
33859
33985
|
}, []);
|
|
33860
33986
|
const ds = (def.dataSets || []).find((d) => d.name === name2);
|
|
@@ -33869,10 +33995,10 @@ function placeOf(w, def) {
|
|
|
33869
33995
|
function PivotWizard() {
|
|
33870
33996
|
const T = useT2();
|
|
33871
33997
|
const w = useDesigner((s) => s.pivotWizard);
|
|
33872
|
-
const [dsName, setDs] = (0,
|
|
33998
|
+
const [dsName, setDs] = (0, import_react21.useState)(() => w?.dataSet || useDesigner.getState().def.dataSets?.[0]?.name);
|
|
33873
33999
|
const { def, ds, fields, rows } = useData(dsName);
|
|
33874
|
-
const [lay, setLay] = (0,
|
|
33875
|
-
const [totals, setTotals] = (0,
|
|
34000
|
+
const [lay, setLay] = (0, import_react21.useState)({ rows: [], columns: [], values: [] });
|
|
34001
|
+
const [totals, setTotals] = (0, import_react21.useState)(true);
|
|
33876
34002
|
const close = () => useDesigner.getState().setUi({ pivotWizard: null });
|
|
33877
34003
|
const width = Math.round(bodyWidth(def, w?.section || "body") - (w?.x || 0));
|
|
33878
34004
|
const add = (zone2, f) => setLay((l) => {
|
|
@@ -33993,13 +34119,13 @@ function InstantVisuals() {
|
|
|
33993
34119
|
const T = useT2();
|
|
33994
34120
|
const w = useDesigner((s) => s.instantVisuals);
|
|
33995
34121
|
const { def, ds, fields, rows } = useData(w?.dataSet);
|
|
33996
|
-
const [picked, setPickedRaw] = (0,
|
|
33997
|
-
const [touched, setTouched] = (0,
|
|
34122
|
+
const [picked, setPickedRaw] = (0, import_react21.useState)(() => instantPicks(ds?.fields || [], rows));
|
|
34123
|
+
const [touched, setTouched] = (0, import_react21.useState)(false);
|
|
33998
34124
|
const setPicked = (fn3) => {
|
|
33999
34125
|
setTouched(true);
|
|
34000
34126
|
setPickedRaw(fn3);
|
|
34001
34127
|
};
|
|
34002
|
-
(0,
|
|
34128
|
+
(0, import_react21.useEffect)(() => {
|
|
34003
34129
|
if (!touched) setPickedRaw(instantPicks(ds?.fields || [], rows));
|
|
34004
34130
|
}, [rows.length, ds]);
|
|
34005
34131
|
const close = () => useDesigner.getState().setUi({ instantVisuals: null });
|
|
@@ -34199,9 +34325,10 @@ var TOOLS = [
|
|
|
34199
34325
|
] }) }
|
|
34200
34326
|
];
|
|
34201
34327
|
function Toolbox({ T, hide = [] }) {
|
|
34328
|
+
const api = useDesignerStore();
|
|
34202
34329
|
const name2 = (type) => T(`item_${type}`) === `item_${type}` ? ITEMS[type].label : T(`item_${type}`);
|
|
34203
34330
|
const add = (type) => {
|
|
34204
|
-
const s =
|
|
34331
|
+
const s = api.getState();
|
|
34205
34332
|
const at2 = insertSpot(s.def, s.sel);
|
|
34206
34333
|
insertItem(type, at2.section, 0, at2.y, {}, at2.parentId);
|
|
34207
34334
|
};
|
|
@@ -34250,12 +34377,15 @@ var TbGroup = ({ label, children }) => /* @__PURE__ */ (0, import_jsx_runtime20.
|
|
|
34250
34377
|
] });
|
|
34251
34378
|
var QUICK = [["textbox", "text"], ["table", "table"], ["chart", "chart"], ["image", "image"]];
|
|
34252
34379
|
function LeftRail({ T, readOnly: readOnly2, embed }) {
|
|
34253
|
-
const body = (0,
|
|
34254
|
-
const [at2, setAt] = (0,
|
|
34380
|
+
const body = (0, import_react22.useRef)(null);
|
|
34381
|
+
const [at2, setAt] = (0, import_react22.useState)("tools");
|
|
34255
34382
|
const tabs = [!readOnly2 && ["tools", "b2_toolbox", "tools"], embed?.panels?.data !== false && ["data", "b2_data", "data"], ["outline", "b2_outline", "outline"]].filter(Boolean);
|
|
34256
34383
|
const go = (id) => {
|
|
34257
34384
|
const el = body.current?.querySelector(`[data-rail="${id}"]`);
|
|
34258
|
-
if (el)
|
|
34385
|
+
if (el) {
|
|
34386
|
+
body.current.scrollTo({ top: el.offsetTop - body.current.offsetTop, behavior: "smooth" });
|
|
34387
|
+
(el.querySelector('[data-opt][tabindex="0"]') || el.querySelector("button, input, select, textarea"))?.focus({ preventScroll: true });
|
|
34388
|
+
}
|
|
34259
34389
|
setAt(id);
|
|
34260
34390
|
};
|
|
34261
34391
|
const spy = () => {
|
|
@@ -34357,8 +34487,9 @@ var framed = () => {
|
|
|
34357
34487
|
}
|
|
34358
34488
|
};
|
|
34359
34489
|
function useAutosave(id, T, lang2, user) {
|
|
34360
|
-
const
|
|
34361
|
-
(0,
|
|
34490
|
+
const api = useDesignerStore();
|
|
34491
|
+
const [offer, setOffer] = (0, import_react22.useState)(null);
|
|
34492
|
+
(0, import_react22.useEffect)(() => {
|
|
34362
34493
|
if (!id || user == null || framed()) return void 0;
|
|
34363
34494
|
let store;
|
|
34364
34495
|
try {
|
|
@@ -34368,10 +34499,10 @@ function useAutosave(id, T, lang2, user) {
|
|
|
34368
34499
|
}
|
|
34369
34500
|
clearDrafts(store, user);
|
|
34370
34501
|
const d = readDraft(store, user, id);
|
|
34371
|
-
if (d && plain(mergeDraft(d.def,
|
|
34502
|
+
if (d && plain(mergeDraft(d.def, api.getState().def)) !== plain(api.getState().def)) setOffer(d);
|
|
34372
34503
|
else if (d) clearDraft(store, user, id);
|
|
34373
34504
|
const keep = () => {
|
|
34374
|
-
const s =
|
|
34505
|
+
const s = api.getState();
|
|
34375
34506
|
if (!s.saved && !s.readOnly) writeDraft(store, user, id, s.def, Date.now(), s.rev || null);
|
|
34376
34507
|
};
|
|
34377
34508
|
const t3 = setInterval(keep, AUTOSAVE_MS);
|
|
@@ -34380,7 +34511,7 @@ function useAutosave(id, T, lang2, user) {
|
|
|
34380
34511
|
};
|
|
34381
34512
|
window.addEventListener("pagehide", keep);
|
|
34382
34513
|
document.addEventListener("visibilitychange", hide);
|
|
34383
|
-
const unsub =
|
|
34514
|
+
const unsub = api.subscribe((s, prev) => {
|
|
34384
34515
|
if (s.saved && !prev.saved) clearDraft(store, user, id);
|
|
34385
34516
|
});
|
|
34386
34517
|
return () => {
|
|
@@ -34392,13 +34523,13 @@ function useAutosave(id, T, lang2, user) {
|
|
|
34392
34523
|
}, [id, user]);
|
|
34393
34524
|
if (!offer) return null;
|
|
34394
34525
|
const when = new Date(offer.at).toLocaleString(lang2 === "en" ? "en-IN" : lang2, { dateStyle: "medium", timeStyle: "short" });
|
|
34395
|
-
const stale = staleDraft(offer,
|
|
34526
|
+
const stale = staleDraft(offer, api.getState().rev);
|
|
34396
34527
|
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "draft-bar", role: "alert", "data-testid": "draft-offer", "data-stale": stale || void 0, children: [
|
|
34397
34528
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { children: T(stale ? "ux_draftStale" : "ux_draftFound", { when }) }),
|
|
34398
34529
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { className: `btn sm${stale ? "" : " primary"}`, "data-testid": "draft-restore", onClick: () => {
|
|
34399
|
-
const d = mergeDraft(offer.def,
|
|
34400
|
-
|
|
34401
|
-
|
|
34530
|
+
const d = mergeDraft(offer.def, api.getState().def);
|
|
34531
|
+
api.getState().apply(() => JSON.parse(JSON.stringify(d)));
|
|
34532
|
+
api.getState().fixSelection();
|
|
34402
34533
|
setOffer(null);
|
|
34403
34534
|
}, children: T(stale ? "ux_draftRestoreAnyway" : "ux_draftRestore") }),
|
|
34404
34535
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { className: "btn sm", "data-testid": "draft-discard", onClick: () => {
|
|
@@ -34411,12 +34542,13 @@ function useAutosave(id, T, lang2, user) {
|
|
|
34411
34542
|
] });
|
|
34412
34543
|
}
|
|
34413
34544
|
function ConflictBar({ T }) {
|
|
34545
|
+
const api = useDesignerStore();
|
|
34414
34546
|
const conflict = useDesigner((s) => s.conflict);
|
|
34415
34547
|
if (!conflict) return null;
|
|
34416
34548
|
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "draft-bar", role: "alert", "data-testid": "save-conflict", children: [
|
|
34417
34549
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { children: T("ux_conflict") }),
|
|
34418
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { className: "btn sm", "data-testid": "conflict-mine", onClick: () =>
|
|
34419
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { className: "btn sm", "data-testid": "conflict-theirs", onClick: () =>
|
|
34550
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { className: "btn sm", "data-testid": "conflict-mine", onClick: () => api.getState().save({ overwrite: true }), children: T("ux_conflictMine") }),
|
|
34551
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { className: "btn sm", "data-testid": "conflict-theirs", onClick: () => api.getState().takeTheirs(), children: T("ux_conflictTheirs") })
|
|
34420
34552
|
] });
|
|
34421
34553
|
}
|
|
34422
34554
|
var AL = (d) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("svg", { width: "16", height: "14", viewBox: "0 0 16 14", "aria-hidden": "true", children: d });
|
|
@@ -34466,7 +34598,7 @@ var ALIGN2 = [
|
|
|
34466
34598
|
];
|
|
34467
34599
|
function AlignBar({ T }) {
|
|
34468
34600
|
const sel = useDesigner((s) => s.sel);
|
|
34469
|
-
const [toPage, setToPage] = (0,
|
|
34601
|
+
const [toPage, setToPage] = (0, import_react22.useState)(false);
|
|
34470
34602
|
if (sel.kind !== "items" || !sel.ids.length) return null;
|
|
34471
34603
|
const n = sel.ids.length;
|
|
34472
34604
|
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { className: "align-bar", role: "toolbar", "aria-label": T("ux_alignBar"), "data-testid": "align-bar", children: [
|
|
@@ -34481,13 +34613,14 @@ function AlignBar({ T }) {
|
|
|
34481
34613
|
] });
|
|
34482
34614
|
}
|
|
34483
34615
|
function IssuesButton({ T }) {
|
|
34616
|
+
const api = useDesignerStore();
|
|
34484
34617
|
const issues = useDesignIssues();
|
|
34485
|
-
const [open, setOpen] = (0,
|
|
34486
|
-
(0,
|
|
34618
|
+
const [open, setOpen] = (0, import_react22.useState)(false);
|
|
34619
|
+
(0, import_react22.useEffect)(() => {
|
|
34487
34620
|
if (!issues.length) setOpen(false);
|
|
34488
34621
|
}, [issues.length]);
|
|
34489
|
-
const listRef = (0,
|
|
34490
|
-
(0,
|
|
34622
|
+
const listRef = (0, import_react22.useRef)(null);
|
|
34623
|
+
(0, import_react22.useLayoutEffect)(() => {
|
|
34491
34624
|
const el = listRef.current;
|
|
34492
34625
|
if (!el) return void 0;
|
|
34493
34626
|
const place = () => {
|
|
@@ -34504,7 +34637,7 @@ function IssuesButton({ T }) {
|
|
|
34504
34637
|
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { className: "issues-wrap", children: [
|
|
34505
34638
|
/* @__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 }) }),
|
|
34506
34639
|
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: () => {
|
|
34507
|
-
if (i2.id)
|
|
34640
|
+
if (i2.id) api.getState().select({ kind: "items", ids: [i2.id] });
|
|
34508
34641
|
}, children: issueLine(T, i2) }) }, k)) })
|
|
34509
34642
|
] });
|
|
34510
34643
|
}
|
|
@@ -34528,9 +34661,10 @@ var SHORTCUTS = [
|
|
|
34528
34661
|
["?", "sc_help"]
|
|
34529
34662
|
];
|
|
34530
34663
|
function HistoryDialog({ id, onClose, T, lang: lang2 }) {
|
|
34531
|
-
const
|
|
34532
|
-
const [
|
|
34533
|
-
(0,
|
|
34664
|
+
const api = useDesignerStore();
|
|
34665
|
+
const [list2, setList] = (0, import_react22.useState)(null);
|
|
34666
|
+
const [err, setErr] = (0, import_react22.useState)(null);
|
|
34667
|
+
(0, import_react22.useEffect)(() => {
|
|
34534
34668
|
fetch(`/api/reports/${id}/versions`).then((r) => r.json()).then(setList).catch((e) => setErr(e.message));
|
|
34535
34669
|
}, [id]);
|
|
34536
34670
|
const restore = async (v) => {
|
|
@@ -34540,7 +34674,7 @@ function HistoryDialog({ id, onClose, T, lang: lang2 }) {
|
|
|
34540
34674
|
return;
|
|
34541
34675
|
}
|
|
34542
34676
|
const def = await res.json();
|
|
34543
|
-
|
|
34677
|
+
api.getState().init(id, def);
|
|
34544
34678
|
onClose();
|
|
34545
34679
|
};
|
|
34546
34680
|
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: [
|
|
@@ -34562,18 +34696,48 @@ function HistoryDialog({ id, onClose, T, lang: lang2 }) {
|
|
|
34562
34696
|
] }, v.version))
|
|
34563
34697
|
] });
|
|
34564
34698
|
}
|
|
34565
|
-
function Designer({
|
|
34699
|
+
function Designer({ store: storeIn = null, ...props }) {
|
|
34700
|
+
const [store] = (0, import_react22.useState)(() => {
|
|
34701
|
+
const s = storeIn || newDesignerStore();
|
|
34702
|
+
activateStore(s);
|
|
34703
|
+
return s;
|
|
34704
|
+
});
|
|
34705
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DesignerStore.Provider, { value: store, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DesignerIn, { ...props }) });
|
|
34706
|
+
}
|
|
34707
|
+
var ACTIVATE = [
|
|
34708
|
+
"onPointerDownCapture",
|
|
34709
|
+
"onMouseDownCapture",
|
|
34710
|
+
"onKeyDownCapture",
|
|
34711
|
+
"onFocusCapture",
|
|
34712
|
+
"onClickCapture",
|
|
34713
|
+
"onInputCapture",
|
|
34714
|
+
"onChangeCapture",
|
|
34715
|
+
"onDragStartCapture",
|
|
34716
|
+
"onDragOverCapture",
|
|
34717
|
+
"onDropCapture",
|
|
34718
|
+
"onPasteCapture",
|
|
34719
|
+
"onWheelCapture",
|
|
34720
|
+
"onContextMenuCapture",
|
|
34721
|
+
"onDoubleClickCapture",
|
|
34722
|
+
"onSubmitCapture"
|
|
34723
|
+
];
|
|
34724
|
+
function DesignerIn({ id, initial, rev = null, lang: langIn, embed = null, user = null, ai = false }) {
|
|
34725
|
+
const api = useDesignerStore();
|
|
34726
|
+
const activators = (0, import_react22.useMemo)(() => {
|
|
34727
|
+
const on = () => activateStore(api);
|
|
34728
|
+
return Object.fromEntries(ACTIVATE.map((k) => [k, on]));
|
|
34729
|
+
}, [api]);
|
|
34566
34730
|
const lang2 = pickLang(langIn);
|
|
34567
34731
|
const T = (k, v) => t(lang2, k, v);
|
|
34568
34732
|
const q2 = lang2 === "en" ? "" : `?lang=${encodeURIComponent(lang2)}`;
|
|
34569
|
-
const ready = (0,
|
|
34733
|
+
const ready = (0, import_react22.useRef)(false);
|
|
34570
34734
|
if (!ready.current && typeof window !== "undefined") {
|
|
34571
|
-
|
|
34572
|
-
|
|
34735
|
+
api.getState().init(id, initial);
|
|
34736
|
+
api.getState().setUi({ lang: lang2, embed, readOnly: !!embed?.readOnly, rev, conflict: null });
|
|
34573
34737
|
ready.current = true;
|
|
34574
34738
|
}
|
|
34575
34739
|
const readOnly2 = !!embed?.readOnly;
|
|
34576
|
-
const rootRef = (0,
|
|
34740
|
+
const rootRef = (0, import_react22.useRef)(null);
|
|
34577
34741
|
const def = useDesigner((s) => s.def);
|
|
34578
34742
|
const tab = useDesigner((s) => s.tab);
|
|
34579
34743
|
const saved = useDesigner((s) => s.saved);
|
|
@@ -34583,23 +34747,23 @@ function Designer({ id, initial, rev = null, lang: langIn, embed = null, user =
|
|
|
34583
34747
|
const snap = useDesigner((s) => s.snap);
|
|
34584
34748
|
const unit = useDesigner((s) => s.unit);
|
|
34585
34749
|
const fonts = useDesigner((s) => s.fonts);
|
|
34586
|
-
const fontCss = (0,
|
|
34587
|
-
(0,
|
|
34750
|
+
const fontCss = (0, import_react22.useMemo)(() => fontFaceCss(allFontKeys(), fontsBase().replace(/\/$/, "")), [fonts]);
|
|
34751
|
+
(0, import_react22.useEffect)(() => {
|
|
34588
34752
|
if (embed) declareDocumentStyles("pw-designer-fonts", fontCss);
|
|
34589
34753
|
}, [embed, fontCss]);
|
|
34590
|
-
(0,
|
|
34591
|
-
customFonts().then((list2) =>
|
|
34754
|
+
(0, import_react22.useEffect)(() => {
|
|
34755
|
+
customFonts().then((list2) => api.getState().setUi({ fonts: list2 }));
|
|
34592
34756
|
}, []);
|
|
34593
|
-
(0,
|
|
34757
|
+
(0, import_react22.useEffect)(() => {
|
|
34594
34758
|
const z = savedZoom();
|
|
34595
|
-
if (z != null)
|
|
34759
|
+
if (z != null) api.getState().setUi({ zoom: z });
|
|
34596
34760
|
}, []);
|
|
34597
34761
|
const canUndo = useDesigner((s) => s.past.length > 0);
|
|
34598
34762
|
const canRedo = useDesigner((s) => s.future.length > 0);
|
|
34599
|
-
const st =
|
|
34600
|
-
const [dialog, setDialog] = (0,
|
|
34601
|
-
const [showLeft, setShowLeft] = (0,
|
|
34602
|
-
const [showRight, setShowRight] = (0,
|
|
34763
|
+
const st = api.getState;
|
|
34764
|
+
const [dialog, setDialog] = (0, import_react22.useState)(null);
|
|
34765
|
+
const [showLeft, setShowLeft] = (0, import_react22.useState)(true);
|
|
34766
|
+
const [showRight, setShowRight] = (0, import_react22.useState)(true);
|
|
34603
34767
|
const selKind = useDesigner((s) => s.sel.kind);
|
|
34604
34768
|
const wizard = useDesigner((s) => s.wizard);
|
|
34605
34769
|
const tableWizard = useDesigner((s) => s.tableWizard);
|
|
@@ -34608,12 +34772,18 @@ function Designer({ id, initial, rev = null, lang: langIn, embed = null, user =
|
|
|
34608
34772
|
const cells = useDesigner((s) => s.cells);
|
|
34609
34773
|
const cellSize = useDesigner((s) => s.cellSize);
|
|
34610
34774
|
const dataKey = useDesigner((s) => `${(s.def?.dataSources || []).map((x) => x.name)}|${(s.def?.dataSets || []).map((x) => x.name)}`);
|
|
34611
|
-
(0,
|
|
34612
|
-
loadSample();
|
|
34775
|
+
(0, import_react22.useEffect)(() => {
|
|
34776
|
+
loadSample(api);
|
|
34613
34777
|
}, [dataKey]);
|
|
34614
|
-
(0,
|
|
34778
|
+
(0, import_react22.useEffect)(() => {
|
|
34779
|
+
let lastInside = false;
|
|
34780
|
+
const inside = (e) => (e.composedPath?.() || []).includes(rootRef.current);
|
|
34781
|
+
const onDown = (e) => {
|
|
34782
|
+
lastInside = inside(e);
|
|
34783
|
+
};
|
|
34784
|
+
const ours = (e) => inside(e) || lastInside && (e.target === document.body || e.target === document.documentElement);
|
|
34615
34785
|
const onKey = (e) => {
|
|
34616
|
-
if (embed && !(e
|
|
34786
|
+
if (embed && !ours(e)) return;
|
|
34617
34787
|
const mod = e.metaKey || e.ctrlKey;
|
|
34618
34788
|
if (mod && e.key.toLowerCase() === "s") {
|
|
34619
34789
|
e.preventDefault();
|
|
@@ -34632,7 +34802,7 @@ function Designer({ id, initial, rev = null, lang: langIn, embed = null, user =
|
|
|
34632
34802
|
st().save();
|
|
34633
34803
|
return;
|
|
34634
34804
|
}
|
|
34635
|
-
if (isTyping(e) || st().tab !== "design") return;
|
|
34805
|
+
if (isTyping(e) || st().tab !== "design" || e.defaultPrevented) return;
|
|
34636
34806
|
if (mod && e.key.toLowerCase() === "z") {
|
|
34637
34807
|
e.preventDefault();
|
|
34638
34808
|
e.shiftKey ? st().redo() : st().undo();
|
|
@@ -34655,11 +34825,7 @@ function Designer({ id, initial, rev = null, lang: langIn, embed = null, user =
|
|
|
34655
34825
|
}
|
|
34656
34826
|
return;
|
|
34657
34827
|
}
|
|
34658
|
-
if (mod && e.key.toLowerCase() === "v")
|
|
34659
|
-
e.preventDefault();
|
|
34660
|
-
pasteItems(st().sel.kind === "section" ? st().sel.section : "body");
|
|
34661
|
-
return;
|
|
34662
|
-
}
|
|
34828
|
+
if (mod && e.key.toLowerCase() === "v") return;
|
|
34663
34829
|
if (e.key === "Delete" || e.key === "Backspace") {
|
|
34664
34830
|
if (st().sel.kind === "items") {
|
|
34665
34831
|
e.preventDefault();
|
|
@@ -34691,10 +34857,24 @@ function Designer({ id, initial, rev = null, lang: langIn, embed = null, user =
|
|
|
34691
34857
|
e.returnValue = "";
|
|
34692
34858
|
}
|
|
34693
34859
|
};
|
|
34860
|
+
const onPaste = (e) => {
|
|
34861
|
+
if (embed && !ours(e) || isTyping(e) || st().tab !== "design") return;
|
|
34862
|
+
e.preventDefault();
|
|
34863
|
+
if (!pasteItems(st().sel.kind === "section" ? st().sel.section : "body", e.clipboardData?.getData("text/plain"))) {
|
|
34864
|
+
st().setUi({ saveError: t(lang2, "b9_nothingToPaste") });
|
|
34865
|
+
setTimeout(() => st().setUi({ saveError: null }), 3e3);
|
|
34866
|
+
}
|
|
34867
|
+
};
|
|
34694
34868
|
window.addEventListener("keydown", onKey);
|
|
34869
|
+
window.addEventListener("paste", onPaste);
|
|
34870
|
+
window.addEventListener("pointerdown", onDown, true);
|
|
34871
|
+
window.addEventListener("focusin", onDown, true);
|
|
34695
34872
|
if (!embed) window.addEventListener("beforeunload", onLeave);
|
|
34696
34873
|
return () => {
|
|
34697
34874
|
window.removeEventListener("keydown", onKey);
|
|
34875
|
+
window.removeEventListener("paste", onPaste);
|
|
34876
|
+
window.removeEventListener("pointerdown", onDown, true);
|
|
34877
|
+
window.removeEventListener("focusin", onDown, true);
|
|
34698
34878
|
window.removeEventListener("beforeunload", onLeave);
|
|
34699
34879
|
};
|
|
34700
34880
|
}, [st, embed]);
|
|
@@ -34713,17 +34893,17 @@ function Designer({ id, initial, rev = null, lang: langIn, embed = null, user =
|
|
|
34713
34893
|
const d = await embed.onOpen();
|
|
34714
34894
|
if (d && typeof d === "object") {
|
|
34715
34895
|
st().init(id, d);
|
|
34716
|
-
loadSample();
|
|
34896
|
+
loadSample(api);
|
|
34717
34897
|
}
|
|
34718
34898
|
};
|
|
34719
|
-
const importInput = (0,
|
|
34720
|
-
const [imported, setImported] = (0,
|
|
34899
|
+
const importInput = (0, import_react22.useRef)(null);
|
|
34900
|
+
const [imported, setImported] = (0, import_react22.useState)(null);
|
|
34721
34901
|
const importFile = async (file) => {
|
|
34722
34902
|
if (!file) return;
|
|
34723
34903
|
const r = readReportFile(file.name, await file.text());
|
|
34724
34904
|
if (r.definition) {
|
|
34725
34905
|
st().init(id, r.definition);
|
|
34726
|
-
loadSample();
|
|
34906
|
+
loadSample(api);
|
|
34727
34907
|
}
|
|
34728
34908
|
setImported({ name: file.name, ok: !!r.definition, warnings: r.warnings || [], error: r.error });
|
|
34729
34909
|
};
|
|
@@ -34737,7 +34917,7 @@ function Designer({ id, initial, rev = null, lang: langIn, embed = null, user =
|
|
|
34737
34917
|
] }),
|
|
34738
34918
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "hint", children: T("loadingDesigner") })
|
|
34739
34919
|
] }) });
|
|
34740
|
-
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: [
|
|
34920
|
+
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: [
|
|
34741
34921
|
!embed && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("style", { children: fontCss }),
|
|
34742
34922
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("header", { className: "dtop dbar", children: [
|
|
34743
34923
|
embed ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { className: "brand", children: [
|
|
@@ -34844,7 +35024,7 @@ function Designer({ id, initial, rev = null, lang: langIn, embed = null, user =
|
|
|
34844
35024
|
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)) })
|
|
34845
35025
|
] }),
|
|
34846
35026
|
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)(
|
|
34847
|
-
|
|
35027
|
+
import_react22.Fragment, { children: [
|
|
34848
35028
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "kbd", children: k }),
|
|
34849
35029
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { children: T(d) })
|
|
34850
35030
|
] }, d)) }) }),
|
|
@@ -34926,6 +35106,7 @@ var CSS2 = true ? `/* Layout: a drafting table. Cool grey workspace, white paper
|
|
|
34926
35106
|
--ink: #16202a;
|
|
34927
35107
|
--muted: #5f6b77;
|
|
34928
35108
|
--faint: #64717e; /* 5:1 on panel (was #8e99a4, 2.9:1) */
|
|
35109
|
+
--faint-desk: #5a6672; /* small text on the desk: 4.85:1 on #e6eaee (--faint is 4.13:1 there) */
|
|
34929
35110
|
--line-strong: #848f9b; /* control borders, 3:1 */
|
|
34930
35111
|
--accent: #0e7490;
|
|
34931
35112
|
--accent-ink: #ffffff;
|
|
@@ -34979,6 +35160,7 @@ var CSS2 = true ? `/* Layout: a drafting table. Cool grey workspace, white paper
|
|
|
34979
35160
|
--ink: #e6edf3;
|
|
34980
35161
|
--muted: #a3afbb;
|
|
34981
35162
|
--faint: #8693a0;
|
|
35163
|
+
--faint-desk: #8693a0;
|
|
34982
35164
|
--accent: #3cbfd4;
|
|
34983
35165
|
--accent-ink: #03222a;
|
|
34984
35166
|
--accent-soft: #123a44;
|
|
@@ -35276,6 +35458,7 @@ a.cell-name:hover { color: var(--accent); }
|
|
|
35276
35458
|
.outline-row.sel { background: var(--accent-soft); }
|
|
35277
35459
|
.outline-row .linklike.nm, .outline-band { text-decoration: none; color: var(--ink); text-align: start; }
|
|
35278
35460
|
.outline-row.sel .linklike.nm, .outline-band.sel { color: var(--accent); }
|
|
35461
|
+
.outline-row.sel .ty { color: var(--muted); } /* --faint is 4.38:1 on --accent-soft; --muted passes in both themes */
|
|
35279
35462
|
.outline-row.sel .act, .outline-row:focus-within .act { opacity: 1; }
|
|
35280
35463
|
.outline-row[draggable="true"] { cursor: grab; }
|
|
35281
35464
|
.outline-row .grip { color: var(--faint); font-size: 10px; line-height: 1; margin-inline-start: -2px; opacity: .55; }
|
|
@@ -35317,7 +35500,7 @@ a.cell-name:hover { color: var(--accent); }
|
|
|
35317
35500
|
.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); }
|
|
35318
35501
|
.tbl.sel .grip { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
|
|
35319
35502
|
.tbl .row { position: relative; display: flex; }
|
|
35320
|
-
.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%; }
|
|
35503
|
+
.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%; }
|
|
35321
35504
|
.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; }
|
|
35322
35505
|
.tbl .cell:first-child { border-left: 1px dashed rgba(95,107,119,.3); }
|
|
35323
35506
|
.tbl .row:first-child .cell { border-top: 1px dashed rgba(95,107,119,.3); }
|
|
@@ -35837,7 +36020,7 @@ input[type=checkbox], input[type=radio] { width: 16px; height: 16px; accent-colo
|
|
|
35837
36020
|
|
|
35838
36021
|
.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}
|
|
35839
36022
|
` : "";
|
|
35840
|
-
var BLANK = { $schema: "pagewright/report@1", name: "
|
|
36023
|
+
var BLANK = { $schema: "pagewright/report@1", name: "Untitled report", page: { size: "A4", margins: [36, 36, 36, 36] }, dataSources: [], dataSets: [], sections: { body: { items: [] } } };
|
|
35841
36024
|
function mountDesigner(target, opts = {}) {
|
|
35842
36025
|
const el = typeof target === "string" ? document.querySelector(target) : target;
|
|
35843
36026
|
if (!el) throw new Error(`mountDesigner: no element for ${target}`);
|
|
@@ -35855,18 +36038,43 @@ function mountDesigner(target, opts = {}) {
|
|
|
35855
36038
|
);
|
|
35856
36039
|
box.style.height = opts.height || "760px";
|
|
35857
36040
|
const root = (0, import_client.createRoot)(box);
|
|
36041
|
+
const store = newDesignerStore();
|
|
35858
36042
|
const embed = { onSave: opts.onSave, onOpen: opts.onOpen, readOnly: !!opts.readOnly, toolbox: opts.toolbox, panels: opts.panels, dataSourceTemplates: opts.dataSourceTemplates, server: server2 };
|
|
35859
36043
|
const show = (definition) => loadLanguage(opts.lang).catch(() => {
|
|
35860
|
-
}).then(() => root.render((0,
|
|
36044
|
+
}).then(() => root.render((0, import_react23.createElement)(Designer, { id: opts.report, initial: definition, lang: opts.lang, embed, store })));
|
|
35861
36045
|
if (opts.definition || !opts.report) show(opts.definition || BLANK);
|
|
35862
36046
|
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) => {
|
|
35863
36047
|
box.innerHTML = `<div class="vmsg error">The report did not load: ${String(e.message).replace(/</g, "<")}</div>`;
|
|
35864
36048
|
});
|
|
36049
|
+
const onLeave = (e) => {
|
|
36050
|
+
e.preventDefault();
|
|
36051
|
+
e.returnValue = "";
|
|
36052
|
+
};
|
|
36053
|
+
let dirty = false;
|
|
36054
|
+
const unsub = store.subscribe((s) => {
|
|
36055
|
+
if (!s.saved === dirty) return;
|
|
36056
|
+
dirty = !s.saved;
|
|
36057
|
+
if (opts.warnOnLeave !== false) {
|
|
36058
|
+
if (dirty) window.addEventListener("beforeunload", onLeave);
|
|
36059
|
+
else window.removeEventListener("beforeunload", onLeave);
|
|
36060
|
+
}
|
|
36061
|
+
try {
|
|
36062
|
+
opts.onDirtyChange?.(dirty);
|
|
36063
|
+
} catch (e) {
|
|
36064
|
+
console.error(e);
|
|
36065
|
+
}
|
|
36066
|
+
});
|
|
35865
36067
|
return {
|
|
35866
|
-
unmount: () =>
|
|
36068
|
+
unmount: () => {
|
|
36069
|
+
unsub();
|
|
36070
|
+
window.removeEventListener("beforeunload", onLeave);
|
|
36071
|
+
root.unmount();
|
|
36072
|
+
},
|
|
36073
|
+
/** whether there are changes not saved yet */
|
|
36074
|
+
isDirty: () => !store.getState().saved,
|
|
35867
36075
|
/** the definition as it is now (a plain copy) */
|
|
35868
|
-
getDefinition: () => JSON.parse(JSON.stringify(
|
|
35869
|
-
save: () =>
|
|
36076
|
+
getDefinition: () => JSON.parse(JSON.stringify(store.getState().def)),
|
|
36077
|
+
save: () => store.getState().save()
|
|
35870
36078
|
};
|
|
35871
36079
|
}
|
|
35872
36080
|
export {
|