@freegridjs/core 1.8.0 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +63 -29
- package/README.md +19 -4
- package/dist/cdn/freegrid.esm.js +16 -14
- package/dist/cdn/freegrid.min.js +21 -19
- package/dist/index.d.ts +8 -4
- package/dist/index.js +219 -64
- package/dist/locales/de.d.ts +1 -1
- package/dist/locales/en.d.ts +1 -1
- package/dist/locales/es.d.ts +1 -1
- package/dist/locales/fr.d.ts +1 -1
- package/dist/locales/id.d.ts +1 -1
- package/dist/locales/it.d.ts +1 -1
- package/dist/locales/ja.d.ts +1 -1
- package/dist/locales/ko.d.ts +1 -1
- package/dist/locales/pt-BR.d.ts +1 -1
- package/dist/locales/ru.d.ts +1 -1
- package/dist/locales/th.d.ts +1 -1
- package/dist/locales/vi.d.ts +1 -1
- package/dist/locales/zh-CN.d.ts +1 -1
- package/dist/locales/zh-TW.d.ts +1 -1
- package/dist/{types-Cda4EHUz.d.ts → types-Du3F8mqD.d.ts} +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1296,6 +1296,7 @@ function columnFormulaValue(def, row) {
|
|
|
1296
1296
|
if (scope) return valueIn(scope, cacheOf(scope), row, def.field);
|
|
1297
1297
|
return run(row[def.field], { row, scope, seen: /* @__PURE__ */ new Set([def.field]), depth: 0, memo: /* @__PURE__ */ new Map() });
|
|
1298
1298
|
}
|
|
1299
|
+
var formulasOff = (def) => !!scopes.get(def)?.off?.();
|
|
1299
1300
|
var isFormula = (v) => typeof v === "string" && v.length > 1 && v.startsWith("=");
|
|
1300
1301
|
function formulaRefs(formula) {
|
|
1301
1302
|
let n;
|
|
@@ -1327,10 +1328,10 @@ function getCellValue(def, row) {
|
|
|
1327
1328
|
return void 0;
|
|
1328
1329
|
}
|
|
1329
1330
|
}
|
|
1330
|
-
if (typeof def.formula === "string" && isFormula(def.formula)) return columnFormulaValue(def, row);
|
|
1331
|
+
if (typeof def.formula === "string" && isFormula(def.formula) && !formulasOff(def)) return columnFormulaValue(def, row);
|
|
1331
1332
|
if (def.field == null) return void 0;
|
|
1332
1333
|
const raw = row[def.field];
|
|
1333
|
-
return def.formulas && isFormula(raw) ? columnFormulaValue(def, row) : raw;
|
|
1334
|
+
return def.formulas && isFormula(raw) && !formulasOff(def) ? columnFormulaValue(def, row) : raw;
|
|
1334
1335
|
}
|
|
1335
1336
|
|
|
1336
1337
|
// src/interactions/filterRow.ts
|
|
@@ -3416,6 +3417,8 @@ function nextFocus(key, mods, p, s) {
|
|
|
3416
3417
|
|
|
3417
3418
|
// src/registry.ts
|
|
3418
3419
|
var liveGrids = /* @__PURE__ */ new Map();
|
|
3420
|
+
var apiGrids = /* @__PURE__ */ new WeakMap();
|
|
3421
|
+
var gridOfApi = (api) => api ? apiGrids.get(api) : void 0;
|
|
3419
3422
|
var gridOfRoot = (root) => root ? liveGrids.get(root) : void 0;
|
|
3420
3423
|
|
|
3421
3424
|
// src/interactions/body.ts
|
|
@@ -3492,7 +3495,7 @@ function attachBody(grid) {
|
|
|
3492
3495
|
const data = grid.columns.displayed().filter((c) => !isSystemCol(c.id));
|
|
3493
3496
|
if (data.length) {
|
|
3494
3497
|
grid.setFocus(ev.rowIndex, data[0].id);
|
|
3495
|
-
grid.setRange({ start: { rowIndex: ev.rowIndex, colId: data[0].id }, end: { rowIndex: ev.rowIndex, colId: data[data.length - 1].id } });
|
|
3498
|
+
if (grid.rangesOn()) grid.setRange({ start: { rowIndex: ev.rowIndex, colId: data[0].id }, end: { rowIndex: ev.rowIndex, colId: data[data.length - 1].id } });
|
|
3496
3499
|
}
|
|
3497
3500
|
return;
|
|
3498
3501
|
}
|
|
@@ -3501,9 +3504,9 @@ function attachBody(grid) {
|
|
|
3501
3504
|
const prev = grid.store.state.focus;
|
|
3502
3505
|
const onBox = ev.colId === SELECT_COL_ID;
|
|
3503
3506
|
if (dragged) {
|
|
3504
|
-
} else if (e.shiftKey && prev && !onBox && !isSystemCol(prev.colId) && grid.
|
|
3507
|
+
} else if (e.shiftKey && prev && !onBox && !isSystemCol(prev.colId) && grid.rangesOn()) {
|
|
3505
3508
|
grid.setRange({ start: prev, end: { rowIndex: ev.rowIndex, colId: ev.colId } }, true);
|
|
3506
|
-
} else if ((e.ctrlKey || e.metaKey) && !onBox && !isSystemCol(ev.colId) && grid.
|
|
3509
|
+
} else if ((e.ctrlKey || e.metaKey) && !onBox && !isSystemCol(ev.colId) && grid.rangesOn()) {
|
|
3507
3510
|
const at = { rowIndex: ev.rowIndex, colId: ev.colId };
|
|
3508
3511
|
grid.addRange({ start: at, end: at });
|
|
3509
3512
|
grid.setFocus(ev.rowIndex, ev.colId);
|
|
@@ -3569,7 +3572,7 @@ function attachBody(grid) {
|
|
|
3569
3572
|
grid.selectAllCells();
|
|
3570
3573
|
return true;
|
|
3571
3574
|
case "find":
|
|
3572
|
-
if (grid.options.findBar === false) return false;
|
|
3575
|
+
if (grid.options.findBar === false || !grid.paid) return false;
|
|
3573
3576
|
grid.finder.openBar();
|
|
3574
3577
|
return true;
|
|
3575
3578
|
case "paste":
|
|
@@ -3679,7 +3682,7 @@ function attachBody(grid) {
|
|
|
3679
3682
|
clearTimeout(pressTimer);
|
|
3680
3683
|
pressTimer = window.setTimeout(() => {
|
|
3681
3684
|
cancel();
|
|
3682
|
-
if (grid.
|
|
3685
|
+
if (!grid.contextMenu.enabled()) return;
|
|
3683
3686
|
suppressClick = true;
|
|
3684
3687
|
if (!isSystemCol(hit.colId)) {
|
|
3685
3688
|
grid.setFocus(hit.rowIndex, hit.colId);
|
|
@@ -3698,7 +3701,7 @@ function attachBody(grid) {
|
|
|
3698
3701
|
return;
|
|
3699
3702
|
}
|
|
3700
3703
|
if (e.button === 0 && onHandleDown(e)) return;
|
|
3701
|
-
if (grid.
|
|
3704
|
+
if (!grid.rangesOn()) return;
|
|
3702
3705
|
if (e.button !== 0 || e.shiftKey || e.target.closest("input, a, button")) return;
|
|
3703
3706
|
const start = renderer.cellAt(e.target);
|
|
3704
3707
|
if (!start || isSystemCol(start.colId)) return;
|
|
@@ -3746,7 +3749,7 @@ function attachBody(grid) {
|
|
|
3746
3749
|
grid.setRange(null);
|
|
3747
3750
|
return;
|
|
3748
3751
|
}
|
|
3749
|
-
if (ctrl && e.key.toLowerCase() === "a" && grid.
|
|
3752
|
+
if (ctrl && e.key.toLowerCase() === "a" && grid.rangesOn()) {
|
|
3750
3753
|
e.preventDefault();
|
|
3751
3754
|
grid.selectAllCells();
|
|
3752
3755
|
return;
|
|
@@ -3763,7 +3766,7 @@ function attachBody(grid) {
|
|
|
3763
3766
|
}
|
|
3764
3767
|
const size = { rows: count, cols: cols.length, pageRows: renderer.pageRows() };
|
|
3765
3768
|
const firstData = cols.findIndex((c) => !isSystemCol(c.id));
|
|
3766
|
-
const ranges = grid.
|
|
3769
|
+
const ranges = grid.rangesOn();
|
|
3767
3770
|
if (ranges && e.shiftKey && e.key !== "Tab" && NAV_KEYS.has(e.key)) {
|
|
3768
3771
|
const anchor = f ?? { rowIndex: 0, colId: cols[firstData].id };
|
|
3769
3772
|
const range = grid.store.state.range;
|
|
@@ -4264,6 +4267,10 @@ var ContextMenu = class {
|
|
|
4264
4267
|
this.close();
|
|
4265
4268
|
this.detach();
|
|
4266
4269
|
}
|
|
4270
|
+
/** The cell menu is on: not switched off and the paid feature allowed (closed: the browser's menu shows). */
|
|
4271
|
+
enabled() {
|
|
4272
|
+
return this.grid.options.contextMenu !== false && this.grid.allow("contextMenu");
|
|
4273
|
+
}
|
|
4267
4274
|
onContextMenu(e) {
|
|
4268
4275
|
const { grid } = this;
|
|
4269
4276
|
if (grid.options.contextMenu === false) return;
|
|
@@ -4278,7 +4285,7 @@ var ContextMenu = class {
|
|
|
4278
4285
|
return;
|
|
4279
4286
|
}
|
|
4280
4287
|
const hit = grid.renderer.cellAt(target);
|
|
4281
|
-
if (!hit) return;
|
|
4288
|
+
if (!hit || !this.enabled()) return;
|
|
4282
4289
|
e.preventDefault();
|
|
4283
4290
|
grid.renderer.gridEl.focus({ preventScroll: true });
|
|
4284
4291
|
if (!isSystemCol(hit.colId) && !grid.rangeContains(hit.rowIndex, hit.colId)) {
|
|
@@ -4290,7 +4297,7 @@ var ContextMenu = class {
|
|
|
4290
4297
|
/** Keyboard: Shift+F10 or the ContextMenu key. */
|
|
4291
4298
|
openAtFocus() {
|
|
4292
4299
|
const f = this.grid.store.state.focus;
|
|
4293
|
-
if (!f || this.
|
|
4300
|
+
if (!f || !this.enabled()) return;
|
|
4294
4301
|
const r = this.grid.renderer.root.getBoundingClientRect();
|
|
4295
4302
|
const cell = this.grid.renderer.root.querySelector(`.fg-row[data-row="${f.rowIndex}"] .fg-cell[data-col="${CSS.escape(f.colId)}"]`);
|
|
4296
4303
|
const box = cell?.getBoundingClientRect() ?? r;
|
|
@@ -4333,7 +4340,7 @@ var ContextMenu = class {
|
|
|
4333
4340
|
if (grid.options.rowSelection === "multiple") items.push({ label: loc.selectAllRows, action: () => grid.api.selectAll() });
|
|
4334
4341
|
items.push({ label: loc.chooseColumns, action: () => grid.chooser.open() });
|
|
4335
4342
|
const b = grid.rangeBounds();
|
|
4336
|
-
if (b && (b.r2 > b.r1 || b.c2 > b.c1)) {
|
|
4343
|
+
if (b && (b.r2 > b.r1 || b.c2 > b.c1) && grid.paid) {
|
|
4337
4344
|
items.push(
|
|
4338
4345
|
"separator",
|
|
4339
4346
|
{ label: loc.chartBar, action: () => grid.api.createChart({ type: "bar" }) },
|
|
@@ -4344,12 +4351,12 @@ var ContextMenu = class {
|
|
|
4344
4351
|
items.push(
|
|
4345
4352
|
"separator",
|
|
4346
4353
|
{ label: loc.exportCsv, action: () => grid.api.exportCsv() },
|
|
4347
|
-
{ label: loc.exportExcel, action: () => grid.api.exportXlsx() },
|
|
4354
|
+
...grid.paid ? [{ label: loc.exportExcel, action: () => grid.api.exportXlsx() }] : [],
|
|
4348
4355
|
{ label: loc.exportJson, action: () => grid.api.exportJson() },
|
|
4349
|
-
...grid.options.assistant?.url ? [{ label: `${loc.ai.title}\u2026`, action: () => grid.api.openAssistant() }] : [],
|
|
4350
|
-
{ label: loc.exportPdf, action: () => grid.api.exportPdf() }
|
|
4356
|
+
...grid.options.assistant?.url && grid.paid ? [{ label: `${loc.ai.title}\u2026`, action: () => grid.api.openAssistant() }] : [],
|
|
4357
|
+
...grid.paid ? [{ label: loc.exportPdf, action: () => grid.api.exportPdf() }] : []
|
|
4351
4358
|
);
|
|
4352
|
-
if (grid.options.advancedFilter !== false && !grid.options.pivot) items.push("separator", { label: `${loc.advancedFilter}\u2026`, action: () => grid.filterBuilder.open() });
|
|
4359
|
+
if (grid.options.advancedFilter !== false && !grid.options.pivot && grid.paid) items.push("separator", { label: `${loc.advancedFilter}\u2026`, action: () => grid.filterBuilder.open() });
|
|
4353
4360
|
items.push("separator", { label: loc.print, action: () => grid.api.print() });
|
|
4354
4361
|
return items;
|
|
4355
4362
|
}
|
|
@@ -4492,8 +4499,7 @@ var FillHandle = class {
|
|
|
4492
4499
|
this.handle.addEventListener("pointerdown", this.onDown);
|
|
4493
4500
|
}
|
|
4494
4501
|
enabled() {
|
|
4495
|
-
|
|
4496
|
-
return o.fillHandle !== false && o.rangeSelection !== false;
|
|
4502
|
+
return this.grid.options.fillHandle !== false && this.grid.rangesOn();
|
|
4497
4503
|
}
|
|
4498
4504
|
/** Current source block: the range, or the focused cell. */
|
|
4499
4505
|
source() {
|
|
@@ -4670,7 +4676,7 @@ var Finder = class {
|
|
|
4670
4676
|
this.countEl.textContent = !this.query ? "" : this.matches.length ? `${this.index + 1}/${this.matches.length}` : loc.noMatches;
|
|
4671
4677
|
}
|
|
4672
4678
|
openBar() {
|
|
4673
|
-
if (this.grid.options.findBar === false) return;
|
|
4679
|
+
if (this.grid.options.findBar === false || !this.grid.paid) return;
|
|
4674
4680
|
if (this.bar) {
|
|
4675
4681
|
this.bar.querySelector("input").focus();
|
|
4676
4682
|
return;
|
|
@@ -7603,12 +7609,36 @@ function buildPivot(source, config, defOf, labels, locale) {
|
|
|
7603
7609
|
return { columns: [...rowColumns, ...valueColumns], rows, groupBy: cfg.rows.slice(0, -1) };
|
|
7604
7610
|
}
|
|
7605
7611
|
|
|
7612
|
+
// src/features.ts
|
|
7613
|
+
var PAID_FEATURES = {
|
|
7614
|
+
grouping: { en: "Row grouping and aggregation", ko: "\uD589 \uADF8\uB8F9\xB7\uC9D1\uACC4" },
|
|
7615
|
+
pivot: { en: "Pivot", ko: "\uD53C\uBC97" },
|
|
7616
|
+
charts: { en: "Charts", ko: "\uCC28\uD2B8" },
|
|
7617
|
+
range: { en: "Cell range selection", ko: "\uC140 \uBC94\uC704 \uC120\uD0DD" },
|
|
7618
|
+
clipboard: { en: "Range copy and paste", ko: "\uBC94\uC704 \uBCF5\uC0AC\xB7\uBD99\uC5EC\uB123\uAE30" },
|
|
7619
|
+
fill: { en: "Fill handle", ko: "\uCC44\uC6B0\uAE30 \uD578\uB4E4" },
|
|
7620
|
+
excel: { en: "Excel export", ko: "\uC5D1\uC140 \uB0B4\uBCF4\uB0B4\uAE30" },
|
|
7621
|
+
pdf: { en: "PDF export", ko: "PDF \uB0B4\uBCF4\uB0B4\uAE30" },
|
|
7622
|
+
serverGroups: { en: "Server-side groups", ko: "\uC11C\uBC84 \uADF8\uB8F9" },
|
|
7623
|
+
advancedFilter: { en: "Advanced filter", ko: "\uACE0\uAE09 \uD544\uD130" },
|
|
7624
|
+
sideBar: { en: "Side bar panels", ko: "\uC0AC\uC774\uB4DC\uBC14 \uD328\uB110" },
|
|
7625
|
+
contextMenu: { en: "Context menu", ko: "\uCEE8\uD14D\uC2A4\uD2B8 \uBA54\uB274" },
|
|
7626
|
+
summary: { en: "Summary rows", ko: "\uD569\uACC4 \uD589" },
|
|
7627
|
+
formulas: { en: "Formulas", ko: "\uC218\uC2DD" },
|
|
7628
|
+
find: { en: "Find", ko: "\uCC3E\uAE30" },
|
|
7629
|
+
conditional: { en: "Conditional formatting", ko: "\uC870\uAC74\uBD80 \uC11C\uC2DD" },
|
|
7630
|
+
assistant: { en: "AI assistant", ko: "AI \uC5B4\uC2DC\uC2A4\uD134\uD2B8" },
|
|
7631
|
+
merge: { en: "Merged cells", ko: "\uC140 \uBCD1\uD569" },
|
|
7632
|
+
workbook: { en: "Workbook", ko: "\uC6CC\uD06C\uBD81" }
|
|
7633
|
+
};
|
|
7634
|
+
|
|
7606
7635
|
// src/version.ts
|
|
7607
|
-
var version = "1.
|
|
7636
|
+
var version = "1.9.0";
|
|
7608
7637
|
|
|
7609
7638
|
// src/license.ts
|
|
7610
7639
|
var PUBLIC_KEY = { kty: "EC", crv: "P-256", x: "sUTKkglZmk-HMKPNub8p7AeLBKesHCU8irIkw9rJlbE", y: "j0U_aKRDR7iApY9UpaD3hUemhBLZJwDv9-QiT_hUyw8" };
|
|
7611
7640
|
var PRICING_URL = "https://freegrid.app/pricing/";
|
|
7641
|
+
var PERSONAL_URL = "https://freegrid.app/license/personal/";
|
|
7612
7642
|
var USAGE_URL = "https://freegrid.app/api/usage";
|
|
7613
7643
|
var STATUS_URL = "https://freegrid.app/api/domain-status";
|
|
7614
7644
|
var majorOf = (v) => Number.parseInt(String(v).split(".")[0], 10);
|
|
@@ -7624,11 +7654,9 @@ function domainMatches(host, domains) {
|
|
|
7624
7654
|
const h = host.toLowerCase().replace(/\.$/, "");
|
|
7625
7655
|
return domains.some((d) => {
|
|
7626
7656
|
const raw = d.toLowerCase().replace(/\.$/, "");
|
|
7627
|
-
const
|
|
7628
|
-
const dom = wildcard ? raw.slice(2) : raw;
|
|
7657
|
+
const dom = raw.startsWith("*.") ? raw.slice(2) : raw;
|
|
7629
7658
|
if (!dom) return false;
|
|
7630
|
-
|
|
7631
|
-
return wildcard && h.endsWith(`.${dom}`);
|
|
7659
|
+
return h === dom || h.endsWith(`.${dom}`);
|
|
7632
7660
|
});
|
|
7633
7661
|
}
|
|
7634
7662
|
var isDay = (s) => {
|
|
@@ -7646,6 +7674,7 @@ async function verifyLicense(key, host, opts = {}) {
|
|
|
7646
7674
|
info = JSON.parse(new TextDecoder().decode(b64urlDecode(parts[1])));
|
|
7647
7675
|
if (!Array.isArray(info.domains) || !isDay(info.expires)) return { ok: false, reason: "format" };
|
|
7648
7676
|
if (info.major !== void 0 && !(Number.isInteger(info.major) && info.major > 0)) return { ok: false, reason: "format" };
|
|
7677
|
+
if (info.plan !== void 0 && info.plan !== "company" && info.plan !== "personal") return { ok: false, reason: "format" };
|
|
7649
7678
|
} catch {
|
|
7650
7679
|
return { ok: false, reason: "format" };
|
|
7651
7680
|
}
|
|
@@ -7666,13 +7695,18 @@ async function verifyLicense(key, host, opts = {}) {
|
|
|
7666
7695
|
}
|
|
7667
7696
|
var globalKey;
|
|
7668
7697
|
var statuses = /* @__PURE__ */ new Map();
|
|
7669
|
-
var
|
|
7698
|
+
var statusChecks = /* @__PURE__ */ new Map();
|
|
7699
|
+
var gateNotices = /* @__PURE__ */ new Set();
|
|
7700
|
+
var blockedWarned = /* @__PURE__ */ new Set();
|
|
7670
7701
|
function setLicenseKey(key) {
|
|
7671
7702
|
globalKey = key;
|
|
7672
7703
|
}
|
|
7673
7704
|
var NOTICE = {
|
|
7674
|
-
missing: `FreeGrid is free for
|
|
7675
|
-
FreeGrid
|
|
7705
|
+
missing: `FreeGrid: every feature is free for 30 days on a domain. After that, paid features need a free personal key (${PERSONAL_URL}) or a company key: ${PRICING_URL}
|
|
7706
|
+
FreeGrid: \uB3C4\uBA54\uC778\uB9C8\uB2E4 30\uC77C \uB3D9\uC548 \uBAA8\uB4E0 \uAE30\uB2A5\uC744 \uBB34\uB8CC\uB85C \uC4F8 \uC218 \uC788\uC2B5\uB2C8\uB2E4. \uADF8 \uB4A4 \uC720\uB8CC \uAE30\uB2A5\uC5D0\uB294 \uBB34\uB8CC \uAC1C\uC778 \uD0A4(${PERSONAL_URL}) \uB610\uB294 \uD68C\uC0AC \uD0A4\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4: ${PRICING_URL}`,
|
|
7707
|
+
trial: (ends) => `FreeGrid: the 30-day trial of paid features on this domain ends ${ends}. / \uC774 \uB3C4\uBA54\uC778\uC758 \uC720\uB8CC \uAE30\uB2A5 30\uC77C \uCCB4\uD5D8\uC740 ${ends}\uC5D0 \uB05D\uB0A9\uB2C8\uB2E4.`,
|
|
7708
|
+
ended: `FreeGrid: the 30-day trial on this domain has ended, so paid features are now off. Get a free personal key (${PERSONAL_URL}) or a company key: ${PRICING_URL}
|
|
7709
|
+
FreeGrid: \uC774 \uB3C4\uBA54\uC778\uC758 30\uC77C \uCCB4\uD5D8\uC774 \uB05D\uB098 \uC720\uB8CC \uAE30\uB2A5\uC774 \uAEBC\uC84C\uC2B5\uB2C8\uB2E4. \uBB34\uB8CC \uAC1C\uC778 \uD0A4(${PERSONAL_URL}) \uB610\uB294 \uD68C\uC0AC \uD0A4\uB97C \uBC1B\uC73C\uC138\uC694: ${PRICING_URL}`,
|
|
7676
7710
|
format: "FreeGrid: the license key is not in the right format. / \uB77C\uC774\uC120\uC2A4 \uD0A4 \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
|
|
7677
7711
|
signature: "FreeGrid: the license key could not be verified. / \uB77C\uC774\uC120\uC2A4 \uD0A4\uB97C \uD655\uC778\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.",
|
|
7678
7712
|
expired: "FreeGrid: the license key has expired. / \uB77C\uC774\uC120\uC2A4 \uAE30\uAC04\uC774 \uB05D\uB0AC\uC2B5\uB2C8\uB2E4.",
|
|
@@ -7716,31 +7750,98 @@ ${PRICING_URL}`);
|
|
|
7716
7750
|
statuses.set(id, status);
|
|
7717
7751
|
return status;
|
|
7718
7752
|
}
|
|
7719
|
-
|
|
7720
|
-
|
|
7721
|
-
|
|
7753
|
+
var gateHost;
|
|
7754
|
+
var currentHost = () => gateHost ?? (typeof location !== "undefined" ? location.hostname : "");
|
|
7755
|
+
var parseStatus = (d) => {
|
|
7756
|
+
if (!d || typeof d !== "object") return null;
|
|
7757
|
+
const { badge, trial } = d;
|
|
7758
|
+
const valid = !!trial && typeof trial === "object" && isDay(trial.started) && isDay(trial.ends) && typeof trial.active === "boolean";
|
|
7759
|
+
return { badge: badge === true, trial: valid ? { started: trial.started, ends: trial.ends, active: trial.active } : null };
|
|
7760
|
+
};
|
|
7761
|
+
function fetchDomainStatus(host = currentHost()) {
|
|
7762
|
+
if (isDevHost(host) || typeof fetch !== "function") return Promise.resolve(null);
|
|
7763
|
+
const pending = statusChecks.get(host);
|
|
7764
|
+
if (pending) return pending;
|
|
7722
7765
|
const day = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
7723
7766
|
let store = null;
|
|
7724
7767
|
try {
|
|
7725
7768
|
store = typeof localStorage !== "undefined" ? localStorage : null;
|
|
7726
|
-
const cached = JSON.parse(store?.getItem("freegrid:
|
|
7727
|
-
|
|
7769
|
+
const cached = JSON.parse(store?.getItem("freegrid:status") ?? "null");
|
|
7770
|
+
const status = cached && cached.host === host && cached.day === day ? parseStatus(cached.status) : null;
|
|
7771
|
+
if (status) {
|
|
7772
|
+
const hit = Promise.resolve(status);
|
|
7773
|
+
statusChecks.set(host, hit);
|
|
7774
|
+
return hit;
|
|
7775
|
+
}
|
|
7728
7776
|
} catch {
|
|
7729
7777
|
}
|
|
7730
|
-
|
|
7731
|
-
const
|
|
7732
|
-
|
|
7733
|
-
|
|
7734
|
-
|
|
7778
|
+
const check = fetch(STATUS_URL, { mode: "cors", credentials: "omit" }).then((r) => r.ok ? r.json() : null).then((d) => {
|
|
7779
|
+
const status = parseStatus(d);
|
|
7780
|
+
if (status) {
|
|
7781
|
+
try {
|
|
7782
|
+
store?.setItem("freegrid:status", JSON.stringify({ host, day, status }));
|
|
7783
|
+
} catch {
|
|
7784
|
+
}
|
|
7735
7785
|
}
|
|
7736
|
-
return
|
|
7737
|
-
}
|
|
7738
|
-
|
|
7786
|
+
return status;
|
|
7787
|
+
}).catch(() => null);
|
|
7788
|
+
statusChecks.set(host, check);
|
|
7789
|
+
return check;
|
|
7739
7790
|
}
|
|
7740
|
-
|
|
7791
|
+
function badgeRequested(host = currentHost()) {
|
|
7792
|
+
return fetchDomainStatus(host).then((s) => s?.badge === true);
|
|
7793
|
+
}
|
|
7794
|
+
async function needsFreeBadge(key, host = currentHost()) {
|
|
7741
7795
|
if (await checkLicense(key, host)) return false;
|
|
7742
7796
|
return badgeRequested(host);
|
|
7743
7797
|
}
|
|
7798
|
+
var GATE_KEY = "freegrid:gate";
|
|
7799
|
+
var keyIdOf = (key) => {
|
|
7800
|
+
if (!key) return "";
|
|
7801
|
+
const parts = key.trim().split(".");
|
|
7802
|
+
return parts[parts.length - 1].slice(-16);
|
|
7803
|
+
};
|
|
7804
|
+
function paidAllowed(key, host = currentHost()) {
|
|
7805
|
+
if (isDevHost(host)) return true;
|
|
7806
|
+
try {
|
|
7807
|
+
const cache2 = JSON.parse(localStorage.getItem(GATE_KEY) ?? "null");
|
|
7808
|
+
if (!cache2 || cache2.host !== host || cache2.keyId !== keyIdOf(key ?? globalKey)) return true;
|
|
7809
|
+
return cache2.paid !== false;
|
|
7810
|
+
} catch {
|
|
7811
|
+
return true;
|
|
7812
|
+
}
|
|
7813
|
+
}
|
|
7814
|
+
var writeGate = (cache2) => {
|
|
7815
|
+
try {
|
|
7816
|
+
localStorage.setItem(GATE_KEY, JSON.stringify(cache2));
|
|
7817
|
+
} catch {
|
|
7818
|
+
}
|
|
7819
|
+
};
|
|
7820
|
+
async function resolveGate(key, host = currentHost()) {
|
|
7821
|
+
const k = key ?? globalKey;
|
|
7822
|
+
const keyId = keyIdOf(k);
|
|
7823
|
+
if (await checkLicense(k, host)) {
|
|
7824
|
+
writeGate({ host, keyId, paid: true });
|
|
7825
|
+
return true;
|
|
7826
|
+
}
|
|
7827
|
+
const trial = (await fetchDomainStatus(host))?.trial;
|
|
7828
|
+
if (!trial) return true;
|
|
7829
|
+
writeGate({ host, keyId, paid: trial.active, trialEnds: trial.ends });
|
|
7830
|
+
const notice = `${trial.active ? "trial" : "ended"}@${host}`;
|
|
7831
|
+
if (!gateNotices.has(notice)) {
|
|
7832
|
+
gateNotices.add(notice);
|
|
7833
|
+
if (trial.active) console.info(NOTICE.trial(trial.ends));
|
|
7834
|
+
else console.warn(NOTICE.ended);
|
|
7835
|
+
}
|
|
7836
|
+
return trial.active;
|
|
7837
|
+
}
|
|
7838
|
+
function paidBlocked(feature) {
|
|
7839
|
+
if (blockedWarned.has(feature)) return;
|
|
7840
|
+
blockedWarned.add(feature);
|
|
7841
|
+
const name = PAID_FEATURES[feature] ?? { en: feature, ko: feature };
|
|
7842
|
+
console.warn(`FreeGrid: ${name.en} is a paid feature and is off on this domain. Get a free personal key (${PERSONAL_URL}) or a company key: ${PRICING_URL}
|
|
7843
|
+
FreeGrid: ${name.ko}\uC740(\uB294) \uC720\uB8CC \uAE30\uB2A5\uC774\uB77C \uC774 \uB3C4\uBA54\uC778\uC5D0\uC11C \uAEBC\uC838 \uC788\uC2B5\uB2C8\uB2E4. \uBB34\uB8CC \uAC1C\uC778 \uD0A4(${PERSONAL_URL}) \uB610\uB294 \uD68C\uC0AC \uD0A4\uB97C \uBC1B\uC73C\uC138\uC694: ${PRICING_URL}`);
|
|
7844
|
+
}
|
|
7744
7845
|
|
|
7745
7846
|
// src/interactions/menu.ts
|
|
7746
7847
|
var OPS = {
|
|
@@ -7785,7 +7886,7 @@ var ColumnMenu = class {
|
|
|
7785
7886
|
[loc.unpin, () => this.grid.setPinned(colId, null)]
|
|
7786
7887
|
]));
|
|
7787
7888
|
const grouped = this.grid.getGroupBy();
|
|
7788
|
-
if (!this.grid.options.treeData && (this.grid.options.groupPanel || grouped.length)) {
|
|
7889
|
+
if (!this.grid.options.treeData && this.grid.paid && (this.grid.options.groupPanel || grouped.length)) {
|
|
7789
7890
|
const g = grouped.includes(colId) ? [[loc.ungroup, () => this.grid.setGroupBy(grouped.filter((x) => x !== colId))]] : [[loc.groupByThis, () => this.grid.setGroupBy([...grouped, colId])]];
|
|
7790
7891
|
if (grouped.length) g.push([loc.expandAll, () => this.grid.expandAll(true)], [loc.collapseAll, () => this.grid.expandAll(false)]);
|
|
7791
7892
|
popup.append(this.section(g));
|
|
@@ -7796,7 +7897,7 @@ var ColumnMenu = class {
|
|
|
7796
7897
|
];
|
|
7797
7898
|
if (!def.lockVisible) items.push([loc.hideColumn, () => this.grid.setColumnsVisible([colId], false)]);
|
|
7798
7899
|
items.push([loc.chooseColumns, () => this.grid.chooser.open()], [loc.resetColumns, () => this.grid.resetColumns()]);
|
|
7799
|
-
if (this.grid.options.conditionalFormatMenu !== false) items.push([`${loc.cf.title}\u2026`, () => this.grid.formatDialog.open(colId)]);
|
|
7900
|
+
if (this.grid.options.conditionalFormatMenu !== false && this.grid.paid) items.push([`${loc.cf.title}\u2026`, () => this.grid.formatDialog.open(colId)]);
|
|
7800
7901
|
popup.append(this.section(items));
|
|
7801
7902
|
const filter = this.filterSection(colId, () => this.close());
|
|
7802
7903
|
if (filter) popup.append(filter);
|
|
@@ -9704,6 +9805,7 @@ var Grid = class {
|
|
|
9704
9805
|
this.pageSize = DEFAULT_PAGE_SIZE;
|
|
9705
9806
|
/** What formulas see: every source row, and computed columns by id. */
|
|
9706
9807
|
this.formulaScope = {
|
|
9808
|
+
off: () => !this.allow("formulas"),
|
|
9707
9809
|
rows: () => this.store.state.data,
|
|
9708
9810
|
version: () => this.editVersion,
|
|
9709
9811
|
computed: (name) => {
|
|
@@ -9768,6 +9870,7 @@ var Grid = class {
|
|
|
9768
9870
|
this.selectionVersion = 0;
|
|
9769
9871
|
/** Rows select-all acts on: displayed data rows that are selectable. */
|
|
9770
9872
|
this.selectableCache = null;
|
|
9873
|
+
this.paid = paidAllowed(options.licenseKey);
|
|
9771
9874
|
if (!Array.isArray(options.columns)) warn("options.columns must be an array");
|
|
9772
9875
|
if (options.data != null && !Array.isArray(options.data)) warn("options.data must be an array");
|
|
9773
9876
|
this.store = new Store({
|
|
@@ -9809,12 +9912,12 @@ var Grid = class {
|
|
|
9809
9912
|
collator: () => this.collator(),
|
|
9810
9913
|
textVersion: () => `${this.store.state.locale.code}|${this.editVersion}`
|
|
9811
9914
|
});
|
|
9812
|
-
this.groupBy = this.validGroupBy(options.groupBy
|
|
9813
|
-
if (Array.isArray(options.conditionalFormats)) this.cfRules = options.conditionalFormats.filter((r) => r && typeof r === "object" && Array.isArray(r.columns)).map((r) => ({ ...r, columns: [...r.columns] }));
|
|
9814
|
-
this.defaultExpanded = options.groupDefaultExpanded ?? 0;
|
|
9915
|
+
if (options.groupBy?.length && this.allow(this.rowModel.server ? "serverGroups" : "grouping")) this.groupBy = this.validGroupBy(options.groupBy);
|
|
9916
|
+
if (Array.isArray(options.conditionalFormats) && options.conditionalFormats.length && this.allow("conditional")) this.cfRules = options.conditionalFormats.filter((r) => r && typeof r === "object" && Array.isArray(r.columns)).map((r) => ({ ...r, columns: [...r.columns] }));
|
|
9917
|
+
this.defaultExpanded = options.treeData || this.paid ? options.groupDefaultExpanded ?? 0 : 0;
|
|
9815
9918
|
if (options.treeData && !options.getRowId) warn("treeData needs getRowId so parent ids can be matched");
|
|
9816
9919
|
this.updateRows();
|
|
9817
|
-
this.summaryOpts = options.summary
|
|
9920
|
+
this.summaryOpts = options.summary && this.allow("summary") ? options.summary : null;
|
|
9818
9921
|
this.summarySnapshot = snapshot(this.summaryOpts);
|
|
9819
9922
|
this.refreshSummary();
|
|
9820
9923
|
const explicit = options.fontSize != null && options.fontSize > 0 ? options.fontSize : null;
|
|
@@ -9835,9 +9938,9 @@ var Grid = class {
|
|
|
9835
9938
|
this.editor = new CellEditor(this);
|
|
9836
9939
|
this.finder = new Finder(this);
|
|
9837
9940
|
this.fillHandle = new FillHandle(this);
|
|
9838
|
-
this.groupPanel = options.groupPanel ? new GroupPanel(this) : null;
|
|
9941
|
+
this.groupPanel = options.groupPanel && this.allow("grouping") ? new GroupPanel(this) : null;
|
|
9839
9942
|
this.pinnedRows = { top: cleanRows(options.pinnedTopRows ?? []), bottom: cleanRows(options.pinnedBottomRows ?? []) };
|
|
9840
|
-
this.sideBar = options.sideBar ? new SideBar(
|
|
9943
|
+
this.sideBar = options.sideBar && this.allow("sideBar") ? new SideBar(
|
|
9841
9944
|
this,
|
|
9842
9945
|
typeof options.sideBar === "object" && !!options.sideBar.open,
|
|
9843
9946
|
(typeof options.sideBar === "object" ? options.sideBar.panels : void 0) ?? (options.pivot || options.pivotPanel ? ["columns", "filters", "pivot"] : void 0)
|
|
@@ -9870,11 +9973,23 @@ var Grid = class {
|
|
|
9870
9973
|
this.renderer.render();
|
|
9871
9974
|
this.api = this.createApi();
|
|
9872
9975
|
liveGrids.set(this.renderer.root, this);
|
|
9976
|
+
apiGrids.set(this.api, this);
|
|
9977
|
+
void resolveGate(options.licenseKey);
|
|
9873
9978
|
}
|
|
9874
9979
|
/** Bumped whenever cell values change (edits, transactions, undo). */
|
|
9875
9980
|
get valuesVersion() {
|
|
9876
9981
|
return this.editVersion;
|
|
9877
9982
|
}
|
|
9983
|
+
/** Cell ranges are on: not switched off and paid features allowed. Closed behaves exactly like `rangeSelection: false`. */
|
|
9984
|
+
rangesOn() {
|
|
9985
|
+
return this.options.rangeSelection !== false && this.paid;
|
|
9986
|
+
}
|
|
9987
|
+
/** Whether a paid feature may run; warns once per feature when it may not. */
|
|
9988
|
+
allow(feature) {
|
|
9989
|
+
if (this.paid) return true;
|
|
9990
|
+
paidBlocked(feature);
|
|
9991
|
+
return false;
|
|
9992
|
+
}
|
|
9878
9993
|
/** The column definitions as given (setColumns), without the system columns. */
|
|
9879
9994
|
columnDefs() {
|
|
9880
9995
|
return [...this.sourceDefs];
|
|
@@ -9887,6 +10002,7 @@ var Grid = class {
|
|
|
9887
10002
|
warn("setConditionalFormats: formats must be an array");
|
|
9888
10003
|
return;
|
|
9889
10004
|
}
|
|
10005
|
+
if (list.length && !this.allow("conditional")) return;
|
|
9890
10006
|
this.cfRules = list.filter((r) => r && typeof r === "object" && Array.isArray(r.columns)).map((r) => ({ ...r, columns: [...r.columns] }));
|
|
9891
10007
|
this.renderer.invalidate({ rows: true });
|
|
9892
10008
|
this.events.emit("conditionalFormatsChange", { formats: this.getConditionalFormats() });
|
|
@@ -9984,6 +10100,7 @@ var Grid = class {
|
|
|
9984
10100
|
return out;
|
|
9985
10101
|
}
|
|
9986
10102
|
setPivot(cfg) {
|
|
10103
|
+
if (cfg && !this.allow("pivot")) return;
|
|
9987
10104
|
if (cfg && this.clientOnly("pivot")) return;
|
|
9988
10105
|
if (cfg && (typeof cfg !== "object" || !Array.isArray(cfg.rows) || !Array.isArray(cfg.values))) {
|
|
9989
10106
|
warn("setPivot: expected { rows: string[], values: [...] }");
|
|
@@ -10239,6 +10356,7 @@ var Grid = class {
|
|
|
10239
10356
|
}
|
|
10240
10357
|
setAdvancedFilter(filter) {
|
|
10241
10358
|
const next = filter && typeof filter === "object" && Array.isArray(filter.conditions) && filter.conditions.length ? filter : null;
|
|
10359
|
+
if (next && !this.allow("advancedFilter")) return;
|
|
10242
10360
|
if (next === this.store.state.advancedFilter) return;
|
|
10243
10361
|
this.store.set({ advancedFilter: next });
|
|
10244
10362
|
this.events.emit("advancedFilterChange", { advancedFilter: next });
|
|
@@ -10450,6 +10568,7 @@ var Grid = class {
|
|
|
10450
10568
|
return [...this.groupBy];
|
|
10451
10569
|
}
|
|
10452
10570
|
setGroupBy(ids) {
|
|
10571
|
+
if (Array.isArray(ids) && ids.length && !this.allow(this.rowModel.server ? "serverGroups" : "grouping")) return;
|
|
10453
10572
|
const next = this.validGroupBy(ids);
|
|
10454
10573
|
if (next.join("") === this.groupBy.join("")) return;
|
|
10455
10574
|
this.groupBy = next;
|
|
@@ -10735,6 +10854,7 @@ var Grid = class {
|
|
|
10735
10854
|
warn("setSummary: summary.rows must be an array");
|
|
10736
10855
|
return;
|
|
10737
10856
|
}
|
|
10857
|
+
if (opts && !this.allow("summary")) return;
|
|
10738
10858
|
if (same2(opts, this.summarySnapshot)) {
|
|
10739
10859
|
this.summaryOpts = opts;
|
|
10740
10860
|
return;
|
|
@@ -10759,13 +10879,14 @@ var Grid = class {
|
|
|
10759
10879
|
return this.columns.displayed().filter((c) => !isSystemCol(c.id));
|
|
10760
10880
|
}
|
|
10761
10881
|
validRange(range) {
|
|
10762
|
-
if (!range || this.
|
|
10882
|
+
if (!range || !this.rangesOn()) return null;
|
|
10763
10883
|
const count = this.rowModel.getRowCount();
|
|
10764
10884
|
const ok = (p) => !!p && !isSystemCol(p.colId) && !!this.columns.getColumn(p.colId) && p.rowIndex >= 0 && p.rowIndex < count;
|
|
10765
10885
|
return ok(range.start) && ok(range.end) ? { start: { ...range.start }, end: { ...range.end } } : null;
|
|
10766
10886
|
}
|
|
10767
10887
|
/** Set the active range. Earlier Ctrl ranges are dropped unless `keepOthers`. */
|
|
10768
10888
|
setRange(range, keepOthers = false) {
|
|
10889
|
+
if (range && (range.start?.rowIndex !== range.end?.rowIndex || range.start?.colId !== range.end?.colId) && !this.allow("range")) return;
|
|
10769
10890
|
const next = this.validRange(range);
|
|
10770
10891
|
const extras = keepOthers || !this.store.state.extraRanges.length ? this.store.state.extraRanges : [];
|
|
10771
10892
|
const cur = this.store.state.range;
|
|
@@ -10775,6 +10896,7 @@ var Grid = class {
|
|
|
10775
10896
|
}
|
|
10776
10897
|
/** Ctrl+click / Ctrl+drag: keep what is selected (the focused cell when there is no range) and start a new range. */
|
|
10777
10898
|
addRange(range) {
|
|
10899
|
+
if (!this.allow("range")) return;
|
|
10778
10900
|
const { range: active, focus } = this.store.state;
|
|
10779
10901
|
const keep = this.validRange(active ?? (focus ? { start: focus, end: focus } : null));
|
|
10780
10902
|
if (keep) this.store.set({ extraRanges: [...this.store.state.extraRanges, keep] });
|
|
@@ -10786,6 +10908,7 @@ var Grid = class {
|
|
|
10786
10908
|
return all2.map((r) => ({ start: { ...r.start }, end: { ...r.end } }));
|
|
10787
10909
|
}
|
|
10788
10910
|
setRanges(ranges) {
|
|
10911
|
+
if (Array.isArray(ranges) && ranges.length && !this.allow("range")) return;
|
|
10789
10912
|
const list = (Array.isArray(ranges) ? ranges : []).map((r) => this.validRange(r)).filter((r) => !!r);
|
|
10790
10913
|
this.store.set({ extraRanges: list.slice(0, -1) });
|
|
10791
10914
|
this.setRange(list[list.length - 1] ?? null, true);
|
|
@@ -10809,6 +10932,7 @@ var Grid = class {
|
|
|
10809
10932
|
return !!col && this.allRangeBounds().some((b) => rangeContains(b, rowIndex, col.index));
|
|
10810
10933
|
}
|
|
10811
10934
|
selectAllCells() {
|
|
10935
|
+
if (!this.allow("range")) return;
|
|
10812
10936
|
const cols = this.dataColumns();
|
|
10813
10937
|
const count = this.rowModel.getRowCount();
|
|
10814
10938
|
if (!cols.length || !count) return;
|
|
@@ -10818,6 +10942,7 @@ var Grid = class {
|
|
|
10818
10942
|
// ── clipboard ───────────────────────────────────────────────
|
|
10819
10943
|
/** TSV for the range, else the focused cell; `rows` copies the checked rows instead. */
|
|
10820
10944
|
selectionTSV(headers, rows = false) {
|
|
10945
|
+
if (!rows && this.multiCell() && !this.allow("clipboard")) return "";
|
|
10821
10946
|
const code = this.store.state.locale.code;
|
|
10822
10947
|
const displayed = this.columns.displayed();
|
|
10823
10948
|
const b = rows ? null : this.rangeBounds();
|
|
@@ -10859,6 +10984,11 @@ var Grid = class {
|
|
|
10859
10984
|
if (headers) matrix.unshift(cols.map((c) => c.def.header ?? c.def.field ?? c.id));
|
|
10860
10985
|
return toTSV(matrix);
|
|
10861
10986
|
}
|
|
10987
|
+
/** The selection covers more than one cell (several ranges, or one range wider than a cell). */
|
|
10988
|
+
multiCell() {
|
|
10989
|
+
const all2 = this.allRangeBounds();
|
|
10990
|
+
return all2.length > 1 || all2.some((b) => b.r1 !== b.r2 || b.c1 !== b.c2);
|
|
10991
|
+
}
|
|
10862
10992
|
/** Like Excel: ranges stack when they share columns or rows; otherwise only the active one is copied. */
|
|
10863
10993
|
rangesStack(all2) {
|
|
10864
10994
|
return all2.length > 1 && (all2.every((x) => x.c1 === all2[0].c1 && x.c2 === all2[0].c2) || all2.every((x) => x.r1 === all2[0].r1 && x.r2 === all2[0].r2));
|
|
@@ -10909,6 +11039,7 @@ var Grid = class {
|
|
|
10909
11039
|
const matrix = parseTSV(text2);
|
|
10910
11040
|
const result = { changed: 0, skipped: 0 };
|
|
10911
11041
|
if (!matrix.length) return result;
|
|
11042
|
+
if ((matrix.length > 1 || matrix[0].length > 1) && !this.allow("clipboard")) return result;
|
|
10912
11043
|
const displayed = this.columns.displayed();
|
|
10913
11044
|
const count = this.rowModel.getRowCount();
|
|
10914
11045
|
const b = this.rangeBounds();
|
|
@@ -11017,6 +11148,7 @@ var Grid = class {
|
|
|
11017
11148
|
/** Merge blocks for every `merge` column over the displayed rows (memoized). */
|
|
11018
11149
|
mergeSpans() {
|
|
11019
11150
|
if (this.rowModel.server || !this.columns.displayed().some((c) => c.def.merge || c.def.rowSpan)) return NO_SPANS;
|
|
11151
|
+
if (!this.allow("merge")) return NO_SPANS;
|
|
11020
11152
|
const rows = this.rowModel.rows();
|
|
11021
11153
|
const ver = this.editVersion * 1e6 + this.columns.displayed().length;
|
|
11022
11154
|
if (this.spanCache && this.spanCache.rows === rows && this.spanCache.ver === ver) return this.spanCache.spans;
|
|
@@ -11031,7 +11163,7 @@ var Grid = class {
|
|
|
11031
11163
|
}
|
|
11032
11164
|
rangeAggregates() {
|
|
11033
11165
|
const all2 = this.allRangeBounds();
|
|
11034
|
-
if (!all2.length) return null;
|
|
11166
|
+
if (!all2.length || !this.paid) return null;
|
|
11035
11167
|
const displayed = this.columns.displayed();
|
|
11036
11168
|
const key = [JSON.stringify(all2), this.rowModel.rows(), this.editVersion, ...displayed.map((c) => c.def)];
|
|
11037
11169
|
const memo = this.aggMemo;
|
|
@@ -11070,6 +11202,7 @@ var Grid = class {
|
|
|
11070
11202
|
}
|
|
11071
11203
|
/** Fill from the current selection into `target`, Excel-style (one undo step). */
|
|
11072
11204
|
fillRange(target) {
|
|
11205
|
+
if (!this.allow("fill")) return;
|
|
11073
11206
|
const src = this.rangeBounds() ?? (() => {
|
|
11074
11207
|
const f = this.store.state.focus;
|
|
11075
11208
|
const col = f && this.columns.getColumn(f.colId);
|
|
@@ -11655,11 +11788,13 @@ var Grid = class {
|
|
|
11655
11788
|
this.forcedOverlay = kind === "loading" || kind === "noRows" ? kind : null;
|
|
11656
11789
|
this.renderer.invalidate();
|
|
11657
11790
|
}),
|
|
11658
|
-
|
|
11791
|
+
// closed: an empty sheet, so writeXlsx([api.getXlsxSheet()]) is not an Excel export
|
|
11792
|
+
getXlsxSheet: guard((o) => this.allow("excel") ? buildXlsxSheet(this, o) : { name: o?.sheetName ?? "Sheet1", rows: [] }),
|
|
11659
11793
|
print: guard((o) => printHtml(buildPrintHtml(this, o))),
|
|
11660
11794
|
getPrintHtml: guard((o) => buildPrintHtml(this, o)),
|
|
11661
|
-
getPdf: guard((o) => renderPdf(printModel(this, o), browserSurface, { scale: o?.resolution, quality: o?.quality })),
|
|
11795
|
+
getPdf: guard((o) => this.allow("pdf") ? renderPdf(printModel(this, o), browserSurface, { scale: o?.resolution, quality: o?.quality }) : null),
|
|
11662
11796
|
exportPdf: guard((name = "export.pdf", o) => {
|
|
11797
|
+
if (!this.allow("pdf")) return;
|
|
11663
11798
|
const bytes = renderPdf(printModel(this, o), browserSurface, { scale: o?.resolution, quality: o?.quality });
|
|
11664
11799
|
if (bytes) download(name, [bytes], "application/pdf");
|
|
11665
11800
|
else warn("exportPdf: this browser cannot draw on a canvas");
|
|
@@ -11667,16 +11802,26 @@ var Grid = class {
|
|
|
11667
11802
|
setColumnGroupOpened: guard((id, open) => this.setColumnGroupOpened(id, open)),
|
|
11668
11803
|
setAdvancedFilter: guard((f) => this.setAdvancedFilter(f)),
|
|
11669
11804
|
getAdvancedFilter: guard(() => this.store.state.advancedFilter ? JSON.parse(JSON.stringify(this.store.state.advancedFilter)) : null),
|
|
11670
|
-
openFilterBuilder: guard(() =>
|
|
11805
|
+
openFilterBuilder: guard(() => {
|
|
11806
|
+
if (!this.allow("advancedFilter")) return;
|
|
11807
|
+
this.filterBuilder.open();
|
|
11808
|
+
}),
|
|
11671
11809
|
isColumnGroupOpened: guard((id) => !!this.columns.getNode(id)?.open),
|
|
11672
11810
|
applyTransaction: guard((tx) => this.applyTransaction(tx)),
|
|
11673
11811
|
applyTransactionAsync: guard((tx) => this.applyTransactionAsync(tx)),
|
|
11674
11812
|
flushAsyncTransactions: guard(() => this.flushAsyncTransactions()),
|
|
11675
11813
|
setConditionalFormats: guard((f) => this.setConditionalFormats(f)),
|
|
11676
11814
|
getConditionalFormats: guard(() => this.getConditionalFormats()),
|
|
11677
|
-
openConditionalFormats: guard((colId) =>
|
|
11678
|
-
|
|
11679
|
-
|
|
11815
|
+
openConditionalFormats: guard((colId) => {
|
|
11816
|
+
if (!this.allow("conditional")) return;
|
|
11817
|
+
this.formatDialog.open(colId);
|
|
11818
|
+
}),
|
|
11819
|
+
// closed: as if `assistant` were not set
|
|
11820
|
+
askAssistant: guard((prompt) => askAssistant(this, prompt, this.allow("assistant") ? this.options.assistant : void 0)),
|
|
11821
|
+
openAssistant: guard(() => {
|
|
11822
|
+
if (!this.allow("assistant")) return;
|
|
11823
|
+
this.assistantPanel.open();
|
|
11824
|
+
}),
|
|
11680
11825
|
getState: guard(() => this.getState()),
|
|
11681
11826
|
setState: guard((s, o) => this.setState(s, o)),
|
|
11682
11827
|
getScrollPosition: guard(() => this.renderer.getScroll()),
|
|
@@ -11690,7 +11835,10 @@ var Grid = class {
|
|
|
11690
11835
|
resetColumnState: guard(() => this.resetColumns()),
|
|
11691
11836
|
openColumnChooser: guard(() => this.chooser.open()),
|
|
11692
11837
|
closeColumnChooser: guard(() => this.chooser.close()),
|
|
11693
|
-
toggleSideBar: guard((open, panel) =>
|
|
11838
|
+
toggleSideBar: guard((open, panel) => {
|
|
11839
|
+
if (!this.allow("sideBar")) return;
|
|
11840
|
+
this.sideBar?.toggle(open, panel);
|
|
11841
|
+
}),
|
|
11694
11842
|
setSummary: guard((s) => this.setSummary(s)),
|
|
11695
11843
|
getSummaryValues: guard(() => this.summaryValues.map((v) => ({ ...v }))),
|
|
11696
11844
|
getRange: guard(() => {
|
|
@@ -11720,7 +11868,7 @@ var Grid = class {
|
|
|
11720
11868
|
canRedo: guard(() => this.history.canRedo()),
|
|
11721
11869
|
fillRange: guard((t) => this.fillRange(t)),
|
|
11722
11870
|
setPinnedRows: guard((r) => this.setPinnedRows(r)),
|
|
11723
|
-
find: guard((text2) => this.finder.find(text2)),
|
|
11871
|
+
find: guard((text2) => this.allow("find") ? this.finder.find(text2) : 0),
|
|
11724
11872
|
findNext: guard(() => this.finder.next()),
|
|
11725
11873
|
findPrevious: guard(() => this.finder.previous()),
|
|
11726
11874
|
clearFind: guard(() => this.finder.clear()),
|
|
@@ -11741,13 +11889,17 @@ var Grid = class {
|
|
|
11741
11889
|
refreshRows: guard(() => this.refreshRows()),
|
|
11742
11890
|
setPivot: guard((p) => this.setPivot(p)),
|
|
11743
11891
|
getPivot: guard(() => this.getPivot()),
|
|
11744
|
-
|
|
11892
|
+
// closed: an inert handle whose methods do nothing
|
|
11893
|
+
createChart: guard((o) => this.allow("charts") ? this.charts.create(o) : { el: el("div", "fg-chart-body"), setType: () => void 0, update: () => void 0, destroy: () => void 0 }),
|
|
11745
11894
|
getCsv: guard((o) => buildCsv(this, o)),
|
|
11746
11895
|
getJson: guard((o) => buildJson(this, o)),
|
|
11747
11896
|
exportJson: guard((name = "export.json", o) => download(name, [buildJson(this, o)], "application/json;charset=utf-8")),
|
|
11748
11897
|
exportCsv: guard((name = "export.csv", o) => download(name, ["\uFEFF", buildCsv(this, o)], "text/csv;charset=utf-8")),
|
|
11749
|
-
getXlsx: guard((o) => buildXlsx(this, o)),
|
|
11750
|
-
exportXlsx: guard((name = "export.xlsx", o) =>
|
|
11898
|
+
getXlsx: guard((o) => this.allow("excel") ? buildXlsx(this, o) : new Uint8Array(0)),
|
|
11899
|
+
exportXlsx: guard((name = "export.xlsx", o) => {
|
|
11900
|
+
if (!this.allow("excel")) return;
|
|
11901
|
+
download(name, [buildXlsx(this, o)], "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
|
11902
|
+
}),
|
|
11751
11903
|
importFile: guard((file, o) => importInto(this, file, o)),
|
|
11752
11904
|
on: guard((type, fn) => this.events.on(type, fn)),
|
|
11753
11905
|
destroy: () => this.destroy()
|
|
@@ -11775,10 +11927,13 @@ function buildWorkbook(sheets) {
|
|
|
11775
11927
|
warn("buildWorkbook: no grids given; the file has one empty sheet");
|
|
11776
11928
|
return writeXlsx([{ name: "Sheet1", rows: [] }]);
|
|
11777
11929
|
}
|
|
11930
|
+
if (list.some((s) => gridOfApi(s.grid)?.allow("workbook") === false)) return new Uint8Array(0);
|
|
11778
11931
|
return writeXlsx(list.map((s, i) => s.grid.getXlsxSheet({ ...s.options, sheetName: s.sheetName ?? s.options?.sheetName ?? `Sheet${i + 1}` })));
|
|
11779
11932
|
}
|
|
11780
11933
|
function exportWorkbook(filename, sheets) {
|
|
11781
|
-
|
|
11934
|
+
const bytes = buildWorkbook(sheets);
|
|
11935
|
+
if (!bytes.length) return;
|
|
11936
|
+
download(filename || "export.xlsx", [bytes], "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
|
11782
11937
|
}
|
|
11783
11938
|
|
|
11784
11939
|
// src/rest.ts
|