@svgrid/enterprise 3.1.24 → 3.1.26

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.
Files changed (44) hide show
  1. package/dist/cdn/svgrid-enterprise.svelte-external.js +13664 -13646
  2. package/dist/designer/assets/{GridMenus-DWDghydL.js → GridMenus-C8WqB-To.js} +2 -2
  3. package/dist/designer/assets/{SvDateRangeInput-DbfmXqJj.js → SvDateRangeInput-y8PkioQk.js} +1 -1
  4. package/dist/designer/assets/SvGridCellEditor-CC9UMdVq.js +4 -0
  5. package/dist/designer/assets/{SvGridChart-DYtGHM3F.js → SvGridChart-DzCeEdlb.js} +3 -3
  6. package/dist/designer/assets/{SvGridChartBuilder-BjdQrnz5.js → SvGridChartBuilder-CsXVVKvA.js} +1 -1
  7. package/dist/designer/assets/SvGridChartPanel-Dj3IxTS2.js +4 -0
  8. package/dist/designer/assets/{SvGridChartView-Bfs0bvDb.js → SvGridChartView-Dwm4hxbW.js} +1 -1
  9. package/dist/designer/assets/{chart-export-B6bkQ3X8.js → chart-export-Dqq_eHRq.js} +4 -4
  10. package/dist/designer/assets/{chart-export-pdf-BbA28-gt.js → chart-export-pdf-Gw22jkxa.js} +1 -1
  11. package/dist/designer/assets/csv-injection-C4a0uulO.js +1 -0
  12. package/dist/designer/assets/export-format-NYxEY-0Y.js +6 -0
  13. package/dist/designer/assets/index-BU3ieI05.css +1 -0
  14. package/dist/designer/assets/{index-BB1G1RTR.js → index-PEFkd-5C.js} +341 -331
  15. package/dist/designer/assets/src-D23PPsK1.js +1 -0
  16. package/dist/designer/assets/{src-fddEt37f.js → src-DC5nN4Q7.js} +3 -3
  17. package/dist/designer/index.html +9 -8
  18. package/dist/import.js +11 -1
  19. package/dist/node/studio.js +20 -12
  20. package/dist/review/model.svelte.d.ts +65 -140
  21. package/dist/sheet/xlsx-document.js +15 -0
  22. package/dist/studio/emit-schema.js +18 -10
  23. package/dist/version.d.ts +2 -2
  24. package/dist/version.js +2 -2
  25. package/dist/wc/{GridMenus-h7RsvcmI.js → GridMenus-BIQXB6a7.js} +1 -1
  26. package/dist/wc/{SvDateRangeInput-CJZohgBe.js → SvDateRangeInput-DHYuAJeY.js} +1 -0
  27. package/dist/wc/SvGridCellEditor-CZwhQx0a.js +584 -0
  28. package/dist/wc/{SvGridChart-DWRqlhCV.js → SvGridChart-DcfmVvzB.js} +3 -3
  29. package/dist/wc/{SvGridChartBuilder-BXW3yUR0.js → SvGridChartBuilder-1Z69mxbM.js} +2 -2
  30. package/dist/wc/{SvGridChartPanel-28n4tomx.js → SvGridChartPanel-BaVsa-T-.js} +5 -5
  31. package/dist/wc/{SvGridChartView-CbG_WrU-.js → SvGridChartView-LEC8ZNeU.js} +1 -1
  32. package/dist/wc/{chart-export-CeSADGfi.js → chart-export-C1KSVdMU.js} +29 -28
  33. package/dist/wc/{chart-export-pdf-BGko7MER.js → chart-export-pdf-CmEd365D.js} +1 -1
  34. package/dist/wc/csv-injection-Ce26_TOb.js +8 -0
  35. package/dist/wc/sv-sheet-element.js +6234 -6211
  36. package/dist/xlsx-limits.d.ts +17 -0
  37. package/dist/xlsx-limits.js +21 -0
  38. package/package.json +3 -3
  39. package/dist/designer/assets/SvGridCellEditor-od4VbndV.js +0 -4
  40. package/dist/designer/assets/SvGridChartPanel-Cm9_K7BV.js +0 -4
  41. package/dist/designer/assets/export-format-BCuqcexA.js +0 -6
  42. package/dist/designer/assets/index-CHx3F4Ij.css +0 -1
  43. package/dist/designer/assets/src-CITpcm6b.js +0 -1
  44. package/dist/wc/SvGridCellEditor-C7ios4i_.js +0 -582
@@ -13,6 +13,7 @@ import { drawingPartsFor, objectsFromDrawing, rectOfRef, REL_DRAWING } from './x
13
13
  import { objectId } from './objects.js';
14
14
  import { sparklineLines, sparklineId } from './sparklines.js';
15
15
  import { autoFilterXlsx, filteredRows, filtersFromXlsx } from './filter-files.js';
16
+ import { XLSX_MAX_COLS, XLSX_MAX_FILL, XLSX_MAX_ROWS, xlsxFillError } from '../xlsx-limits.js';
16
17
  // ---------------------------------------------------------------------------
17
18
  // Shared pieces
18
19
  // ---------------------------------------------------------------------------
@@ -1282,10 +1283,24 @@ export function documentFromXlsxParts(parts) {
1282
1283
  const outlineCols = emptyOutline();
1283
1284
  if (xml) {
1284
1285
  const root = parseXml(xml, path).documentElement;
1286
+ // Rows and lines are filled up to the cell, so a reference from the
1287
+ // file decides how much is allocated: a cell outside the sheet is
1288
+ // skipped, as other malformed parts are, and the blanks are budgeted
1289
+ // (xlsx-limits.ts).
1290
+ let filled = 0;
1285
1291
  const put = (r, c, text) => {
1292
+ if (r >= XLSX_MAX_ROWS || c >= XLSX_MAX_COLS)
1293
+ return;
1294
+ if (r > cells.length)
1295
+ filled += r - cells.length;
1286
1296
  while (cells.length <= r)
1287
1297
  cells.push([]);
1288
1298
  const line = cells[r];
1299
+ if (c >= line.length) {
1300
+ filled += c - line.length;
1301
+ if (filled > XLSX_MAX_FILL)
1302
+ throw xlsxFillError();
1303
+ }
1289
1304
  while (line.length <= c)
1290
1305
  line.push('');
1291
1306
  line[c] = text;
@@ -834,8 +834,8 @@ export function layoutFile(nav, opts = {}) {
834
834
  ? `<div class="sv-app__toolbar">
835
835
  <div class="sv-app__search">
836
836
  <svg class="sv-app__search-ic" viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><circle cx="11" cy="11" r="7"/><path d="M21 21l-4.35-4.35"/></svg>
837
- <input class="sv-app__search-in" type="search" placeholder="Search {brand}…" bind:value={q} bind:this={searchEl} aria-label="Search screens" />
838
- <kbd class="sv-app__kbd" aria-hidden="true">⌘K</kbd>
837
+ <input class="sv-app__search-in" type="search" placeholder="Search {brand}…" bind:value={q} aria-label="Search screens" />
838
+ <button type="button" class="sv-app__kbd" title="Command palette (⌘K / Ctrl+K)" aria-label="Open the command palette" onclick={() => (paletteOpen = true)}>⌘K</button>
839
839
  {#if results.length}
840
840
  <div class="sv-app__results">
841
841
  {#each results as r (r.href)}
@@ -881,6 +881,7 @@ export function layoutFile(nav, opts = {}) {
881
881
  </div>
882
882
  </div>
883
883
  {#if bellOpen || menuOpen}<button type="button" class="sv-app__scrim" tabindex="-1" aria-label="Close menus" onclick={() => { bellOpen = false; menuOpen = false }}></button>{/if}
884
+ <SvCommand bind:open={paletteOpen} {commands} placeholder="Go to a screen or run an action…" emptyText="No matching screen" />
884
885
  </div>\n `
885
886
  : '';
886
887
  // Supabase Auth: gate the whole app behind a client-side sign-in. SvAuthGate shows
@@ -987,7 +988,7 @@ export function layoutFile(nav, opts = {}) {
987
988
  import '../app.css'
988
989
  import '../custom.css'
989
990
  import { page } from '$app/state'
990
- import { setLicenseKey } from '@svgrid/enterprise'${opts.access ? `\n import { currentRole, canScreen } from '../lib/access'` : ''}${opts.i18n ? `\n import { t, currentLocale, locales } from '../lib/i18n'` : ''}${opts.auth ? `\n import type { LayoutData } from './$types'` : ''}${opts.supabaseAuth ? `\n import { SvAuthGate, type SupabaseAuthClientLike } from '@svgrid/enterprise'\n import { supabaseClient } from '../lib/connections'` : ''}
991
+ import { setLicenseKey } from '@svgrid/enterprise'${toolbarOn ? `\n import { goto } from '$app/navigation'\n import { SvCommand, type CommandItem } from '@svgrid/grid'` : ''}${opts.access ? `\n import { currentRole, canScreen } from '../lib/access'` : ''}${opts.i18n ? `\n import { t, currentLocale, locales } from '../lib/i18n'` : ''}${opts.auth ? `\n import type { LayoutData } from './$types'` : ''}${opts.supabaseAuth ? `\n import { SvAuthGate, type SupabaseAuthClientLike } from '@svgrid/enterprise'\n import { supabaseClient } from '../lib/connections'` : ''}
991
992
 
992
993
  // VITE_SVPRO_KEY in .env is your SvGrid license key; it removes the unlicensed watermark.
993
994
  if (import.meta.env.VITE_SVPRO_KEY) setLicenseKey(import.meta.env.VITE_SVPRO_KEY)
@@ -1013,24 +1014,30 @@ export function layoutFile(nav, opts = {}) {
1013
1014
  try { const s = localStorage.getItem('svapp:theme'); if (s === 'light' || s === 'dark') t = s } catch (_) { /* storage blocked */ }
1014
1015
  applyTheme(t)
1015
1016
  })` : ''}${sideState}${toolbarOn ? `
1016
- // App-chrome quick-search: filter the screens by label as you type.
1017
+ // App-chrome quick-search: filter the screens by label as you type. Only the
1018
+ // screens the sidebar would show${opts.access ? ' to this role' : ''}.
1017
1019
  const initials = ${JSON.stringify(initials)}
1018
1020
  const acctEmail = ${JSON.stringify(`admin@${brandSlug}.com`)}
1021
+ const visibleNav = ${opts.access ? '$derived(nav.filter((n) => !n.id || canScreen($currentRole, n.id)))' : 'nav'}
1019
1022
  let q = $state('')
1020
- const results = $derived(q.trim() ? nav.filter((n) => n.label.toLowerCase().includes(q.trim().toLowerCase())).slice(0, 6) : [])
1023
+ const results = $derived(q.trim() ? visibleNav.filter((n) => n.label.toLowerCase().includes(q.trim().toLowerCase())).slice(0, 6) : [])
1024
+ // Cmd/Ctrl+K: a palette over the same screens. SvCommand binds the key itself.
1025
+ let paletteOpen = $state(false)
1026
+ const commands: CommandItem[] = $derived([
1027
+ ...visibleNav.map((n) => ({ id: 'go:' + n.href, label: ${opts.i18n ? "n.id ? $t('nav.' + n.id, n.label) : n.label" : 'n.label'}, group: 'Go to', onRun: () => goto(n.href) })),${hasSwitch ? `
1028
+ { id: 'theme', label: theme === 'dark' ? 'Switch to light mode' : 'Switch to dark mode', group: 'Actions', onRun: toggleTheme },` : ''}
1029
+ ])
1021
1030
  let bellOpen = $state(false)
1022
1031
  let menuOpen = $state(false)
1023
- let searchEl: HTMLInputElement | null = $state(null)
1024
1032
  const notifications = [
1025
1033
  { title: 'Welcome to ' + brand, time: 'just now', color: 'var(--sg-accent, #6366f1)' },
1026
1034
  { title: 'Your workspace is ready', time: '2m ago', color: '#10b981' },
1027
1035
  { title: 'Sample data loaded', time: '5m ago', color: '#f59e0b' },
1028
1036
  ]
1029
- // Cmd/Ctrl+K focuses search; Escape closes the menus.
1037
+ // Escape closes the menus.
1030
1038
  $effect(() => {
1031
1039
  function onKey(e: KeyboardEvent) {
1032
- if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 'k') { e.preventDefault(); searchEl?.focus() }
1033
- else if (e.key === 'Escape') { bellOpen = false; menuOpen = false }
1040
+ if (e.key === 'Escape') { bellOpen = false; menuOpen = false }
1034
1041
  }
1035
1042
  window.addEventListener('keydown', onKey)
1036
1043
  return () => window.removeEventListener('keydown', onKey)
@@ -1069,7 +1076,8 @@ ${styles}
1069
1076
  .sv-app__tool:hover { color: var(--sg-fg, #0f172a); border-color: color-mix(in srgb, var(--sg-fg, #0f172a) 20%, var(--sg-border, #e6e8ec)); }
1070
1077
  .sv-app__dot { position: absolute; top: 5px; right: 5px; width: 6px; height: 6px; border-radius: 50%; background: var(--sg-accent, #6366f1); box-shadow: 0 0 0 2px var(--sg-bg, #fff); }
1071
1078
  .sv-app__avatar { display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; padding: 0; border: none; border-radius: 50%; font: inherit; font-size: 12px; font-weight: 700; color: #fff; background: var(--sg-accent, #6366f1); letter-spacing: 0.02em; cursor: pointer; }
1072
- .sv-app__kbd { position: absolute; right: 8px; font-size: 10.5px; font-weight: 600; color: var(--sg-muted, #94a3b8); background: color-mix(in srgb, var(--sg-fg, #0f172a) 6%, transparent); border: 1px solid var(--sg-border, #e6e8ec); border-radius: 5px; padding: 1px 5px; pointer-events: none; }
1079
+ .sv-app__kbd { position: absolute; right: 8px; font-size: 10.5px; font-weight: 600; color: var(--sg-muted, #94a3b8); background: color-mix(in srgb, var(--sg-fg, #0f172a) 6%, transparent); border: 1px solid var(--sg-border, #e6e8ec); border-radius: 5px; padding: 1px 5px; font-family: inherit; line-height: inherit; cursor: pointer; }
1080
+ .sv-app__kbd:hover { color: var(--sg-fg, #0f172a); }
1073
1081
  .sv-app__pop { position: relative; }
1074
1082
  .sv-app__scrim { position: fixed; inset: 0; z-index: 44; border: 0; padding: 0; background: transparent; cursor: default; }
1075
1083
  .sv-app__menu { position: absolute; top: calc(100% + 8px); right: 0; z-index: 46; min-width: 232px; padding: 6px; background: var(--sg-bg, #fff); border: 1px solid var(--sg-border, #e6e8ec); border-radius: 11px; box-shadow: 0 16px 40px -10px rgba(15, 23, 42, 0.3); }
package/dist/version.d.ts CHANGED
@@ -10,7 +10,7 @@
10
10
  *
11
11
  * `version.test.ts` asserts this matches `package.json`, so the two cannot drift.
12
12
  */
13
- export declare const SVGRID_VERSION = "3.1.24";
13
+ export declare const SVGRID_VERSION = "3.1.26";
14
14
  /**
15
15
  * The version of `@svgrid/grid`, which releases on its own line: enterprise is
16
16
  * on 3.1.x while the grid is on 3.0.x.
@@ -23,4 +23,4 @@ export declare const SVGRID_VERSION = "3.1.24";
23
23
  *
24
24
  * `version.test.ts` asserts this matches packages/grid/package.json.
25
25
  */
26
- export declare const GRID_VERSION = "3.0.22";
26
+ export declare const GRID_VERSION = "3.0.23";
package/dist/version.js CHANGED
@@ -10,7 +10,7 @@
10
10
  *
11
11
  * `version.test.ts` asserts this matches `package.json`, so the two cannot drift.
12
12
  */
13
- export const SVGRID_VERSION = '3.1.24';
13
+ export const SVGRID_VERSION = '3.1.26';
14
14
  /**
15
15
  * The version of `@svgrid/grid`, which releases on its own line: enterprise is
16
16
  * on 3.1.x while the grid is on 3.0.x.
@@ -23,4 +23,4 @@ export const SVGRID_VERSION = '3.1.24';
23
23
  *
24
24
  * `version.test.ts` asserts this matches packages/grid/package.json.
25
25
  */
26
- export const GRID_VERSION = '3.0.22';
26
+ export const GRID_VERSION = '3.0.23';
@@ -988,7 +988,7 @@ function Mt(r, u) {
988
988
  let e = n(Y) ?? n(J);
989
989
  if (!e) return;
990
990
  let t = n(Q).find((t) => t.id === e);
991
- ue(t?.columnDef) && (n(Kt) || import("./SvDateTimePicker-DmK_QkkU.js").then((e) => y(Kt, e.default, !0)), n(qt) || import("./SvDateRangeInput-CJZohgBe.js").then((e) => y(qt, e.default, !0)));
991
+ ue(t?.columnDef) && (n(Kt) || import("./SvDateTimePicker-DmK_QkkU.js").then((e) => y(Kt, e.default, !0)), n(qt) || import("./SvDateRangeInput-DHYuAJeY.js").then((e) => y(qt, e.default, !0)));
992
992
  });
993
993
  function Jt(e, t) {
994
994
  let n = () => {
@@ -107,6 +107,7 @@ function A(t, r) {
107
107
  value: e(Se),
108
108
  disabled: L(),
109
109
  ...t,
110
+ role: "combobox",
110
111
  "aria-haspopup": "dialog",
111
112
  "aria-expanded": e(K),
112
113
  onkeydown: De