@svgrid/enterprise 3.1.7 → 3.1.9

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 (270) hide show
  1. package/README.md +1 -0
  2. package/dist/SvAlertRuleEditor.svelte +16 -5
  3. package/dist/SvGridAlerts.svelte +8 -0
  4. package/dist/SvGridAlerts.svelte.d.ts +4 -0
  5. package/dist/SvGridBoard.svelte +69 -10
  6. package/dist/SvGridBulkEditDrawer.svelte +13 -5
  7. package/dist/SvGridGallery.svelte +286 -0
  8. package/dist/SvGridGallery.svelte.d.ts +30 -0
  9. package/dist/SvGridScheduler.svelte +33 -11
  10. package/dist/SvGridSelectionBar.svelte +47 -0
  11. package/dist/advanced-filter/expr-columns-from-grid.d.ts +1 -0
  12. package/dist/advanced-filter/expr-columns-from-grid.js +11 -7
  13. package/dist/advanced-filter-enable.d.ts +6 -0
  14. package/dist/advanced-filter-enable.js +8 -0
  15. package/dist/alerts/alert-engine.d.ts +7 -0
  16. package/dist/alerts/alert-engine.js +5 -2
  17. package/dist/alerts/condition-editor.d.ts +26 -0
  18. package/dist/alerts/condition-editor.js +17 -0
  19. package/dist/base/index.d.ts +20 -0
  20. package/dist/base/index.js +20 -0
  21. package/dist/bulk-edit.d.ts +11 -0
  22. package/dist/bulk-edit.js +18 -1
  23. package/dist/cdn/svgrid-enterprise.svelte-external.js +11375 -10805
  24. package/dist/designer/assets/GridFooter-Cu8_yBlQ.js +2 -0
  25. package/dist/designer/assets/GridMenus-BUjkkAU2.js +6 -0
  26. package/dist/designer/assets/PinSplitter-BgTpgh1d.css +1 -0
  27. package/dist/designer/assets/PinSplitter-C5AwA1xV.js +1 -0
  28. package/dist/designer/assets/SvGrid.helpers-CIrmIo9U.js +1 -0
  29. package/dist/designer/assets/SvGridCellEditor-CJxThKL_.js +4 -0
  30. package/dist/designer/assets/SvListBox-CS7oUAiX.js +2 -0
  31. package/dist/designer/assets/conditional-formatting-MDWbF8_Y.js +1 -0
  32. package/dist/designer/assets/grid-extension.svelte-BZ7AqyJI.js +1 -0
  33. package/dist/designer/assets/{index-DtBIaQno.js → index-BPU2KNc5.js} +396 -395
  34. package/dist/designer/assets/index-BmvG99kR.css +1 -0
  35. package/dist/designer/assets/sparkline-C-NcnB2i.js +1 -0
  36. package/dist/designer/assets/src-C_U1NKOY.js +58 -0
  37. package/dist/designer/assets/sv-grid-scrollbar-B9N6Wuj0.js +109 -0
  38. package/dist/designer/assets/validate-H5u2HEQh.js +1 -0
  39. package/dist/designer/index.html +11 -7
  40. package/dist/expressions/compile.js +10 -0
  41. package/dist/expressions/evaluate.js +18 -0
  42. package/dist/expressions/expression-types.d.ts +10 -0
  43. package/dist/expressions/kinds.d.ts +28 -0
  44. package/dist/expressions/kinds.js +19 -0
  45. package/dist/expressions/parse.js +9 -1
  46. package/dist/fields/AttachmentCell.svelte +242 -0
  47. package/dist/fields/AttachmentCell.svelte.d.ts +5 -0
  48. package/dist/fields/AttachmentDialog.svelte +357 -0
  49. package/dist/fields/AttachmentDialog.svelte.d.ts +13 -0
  50. package/dist/fields/AttachmentEditor.svelte +41 -0
  51. package/dist/fields/AttachmentEditor.svelte.d.ts +11 -0
  52. package/dist/fields/AttachmentPreview.svelte +72 -0
  53. package/dist/fields/AttachmentPreview.svelte.d.ts +8 -0
  54. package/dist/fields/BarcodeCell.svelte +20 -0
  55. package/dist/fields/BarcodeCell.svelte.d.ts +5 -0
  56. package/dist/fields/BaseAutomations.svelte +558 -0
  57. package/dist/fields/BaseAutomations.svelte.d.ts +18 -0
  58. package/dist/fields/BaseChartView.svelte +47 -0
  59. package/dist/fields/BaseChartView.svelte.d.ts +8 -0
  60. package/dist/fields/BaseTableView.svelte +185 -0
  61. package/dist/fields/BaseTableView.svelte.d.ts +37 -0
  62. package/dist/fields/BaseTabs.svelte +308 -0
  63. package/dist/fields/BaseTabs.svelte.d.ts +21 -0
  64. package/dist/fields/ButtonCell.svelte +47 -0
  65. package/dist/fields/ButtonCell.svelte.d.ts +20 -0
  66. package/dist/fields/CheckboxCell.svelte +46 -0
  67. package/dist/fields/CheckboxCell.svelte.d.ts +14 -0
  68. package/dist/fields/DeleteFieldConfirm.svelte +80 -0
  69. package/dist/fields/DeleteFieldConfirm.svelte.d.ts +8 -0
  70. package/dist/fields/DeleteRecordConfirm.svelte +48 -0
  71. package/dist/fields/DeleteRecordConfirm.svelte.d.ts +9 -0
  72. package/dist/fields/FieldCell.svelte +80 -0
  73. package/dist/fields/FieldCell.svelte.d.ts +9 -0
  74. package/dist/fields/FieldEditor.svelte +321 -0
  75. package/dist/fields/FieldEditor.svelte.d.ts +10 -0
  76. package/dist/fields/FieldInput.svelte +188 -0
  77. package/dist/fields/FieldInput.svelte.d.ts +29 -0
  78. package/dist/fields/FieldsHeaderEnd.svelte +146 -0
  79. package/dist/fields/FieldsHeaderEnd.svelte.d.ts +6 -0
  80. package/dist/fields/FootRowAdder.svelte +8 -0
  81. package/dist/fields/FootRowAdder.svelte.d.ts +6 -0
  82. package/dist/fields/GroupHeader.svelte +127 -0
  83. package/dist/fields/GroupHeader.svelte.d.ts +24 -0
  84. package/dist/fields/LinkCell.svelte +46 -0
  85. package/dist/fields/LinkCell.svelte.d.ts +9 -0
  86. package/dist/fields/LinkPickerEditor.svelte +172 -0
  87. package/dist/fields/LinkPickerEditor.svelte.d.ts +9 -0
  88. package/dist/fields/LinkPreview.svelte +60 -0
  89. package/dist/fields/LinkPreview.svelte.d.ts +7 -0
  90. package/dist/fields/LinkedRecordView.svelte +94 -0
  91. package/dist/fields/LinkedRecordView.svelte.d.ts +9 -0
  92. package/dist/fields/LinkedRecordsCell.svelte +59 -0
  93. package/dist/fields/LinkedRecordsCell.svelte.d.ts +11 -0
  94. package/dist/fields/LongTextEditor.svelte +157 -0
  95. package/dist/fields/LongTextEditor.svelte.d.ts +11 -0
  96. package/dist/fields/NumberEditor.svelte +309 -0
  97. package/dist/fields/NumberEditor.svelte.d.ts +12 -0
  98. package/dist/fields/OptionsEditor.svelte +117 -0
  99. package/dist/fields/OptionsEditor.svelte.d.ts +11 -0
  100. package/dist/fields/PercentCell.svelte +21 -0
  101. package/dist/fields/PercentCell.svelte.d.ts +8 -0
  102. package/dist/fields/PropertyInput.svelte +204 -0
  103. package/dist/fields/PropertyInput.svelte.d.ts +11 -0
  104. package/dist/fields/RatingCell.svelte +75 -0
  105. package/dist/fields/RatingCell.svelte.d.ts +16 -0
  106. package/dist/fields/RatingEditor.svelte +82 -0
  107. package/dist/fields/RatingEditor.svelte.d.ts +9 -0
  108. package/dist/fields/RecordView.svelte +310 -0
  109. package/dist/fields/RecordView.svelte.d.ts +11 -0
  110. package/dist/fields/RichTextCell.svelte +30 -0
  111. package/dist/fields/RichTextCell.svelte.d.ts +5 -0
  112. package/dist/fields/RowAdder.svelte +93 -0
  113. package/dist/fields/RowAdder.svelte.d.ts +7 -0
  114. package/dist/fields/RowHeader.svelte +99 -0
  115. package/dist/fields/RowHeader.svelte.d.ts +11 -0
  116. package/dist/fields/SelectCell.svelte +35 -0
  117. package/dist/fields/SelectCell.svelte.d.ts +15 -0
  118. package/dist/fields/SelectEditor.svelte +350 -0
  119. package/dist/fields/SelectEditor.svelte.d.ts +17 -0
  120. package/dist/fields/SummaryCell.svelte +160 -0
  121. package/dist/fields/SummaryCell.svelte.d.ts +11 -0
  122. package/dist/fields/SvBase.svelte +545 -0
  123. package/dist/fields/SvBase.svelte.d.ts +30 -0
  124. package/dist/fields/SvBaseForm.svelte +295 -0
  125. package/dist/fields/SvBaseForm.svelte.d.ts +22 -0
  126. package/dist/fields/SvBaseViewBar.svelte +644 -0
  127. package/dist/fields/SvBaseViewBar.svelte.d.ts +26 -0
  128. package/dist/fields/UserCell.svelte +39 -0
  129. package/dist/fields/UserCell.svelte.d.ts +9 -0
  130. package/dist/fields/UserFace.svelte +30 -0
  131. package/dist/fields/UserFace.svelte.d.ts +12 -0
  132. package/dist/fields/activity.svelte.d.ts +50 -0
  133. package/dist/fields/activity.svelte.js +110 -0
  134. package/dist/fields/attachments.d.ts +95 -0
  135. package/dist/fields/attachments.js +145 -0
  136. package/dist/fields/automation-outbound.d.ts +46 -0
  137. package/dist/fields/automation-outbound.js +61 -0
  138. package/dist/fields/automation-server.d.ts +53 -0
  139. package/dist/fields/automation-server.js +333 -0
  140. package/dist/fields/automations.svelte.d.ts +208 -0
  141. package/dist/fields/automations.svelte.js +437 -0
  142. package/dist/fields/bar-request.svelte.d.ts +16 -0
  143. package/dist/fields/bar-request.svelte.js +15 -0
  144. package/dist/fields/base-alerts.d.ts +24 -0
  145. package/dist/fields/base-alerts.js +64 -0
  146. package/dist/fields/base-connect.d.ts +82 -0
  147. package/dist/fields/base-connect.js +271 -0
  148. package/dist/fields/base-schema.d.ts +104 -0
  149. package/dist/fields/base-schema.js +266 -0
  150. package/dist/fields/base-sql.d.ts +62 -0
  151. package/dist/fields/base-sql.js +251 -0
  152. package/dist/fields/base-sync.d.ts +142 -0
  153. package/dist/fields/base-sync.js +499 -0
  154. package/dist/fields/base-tables.d.ts +89 -0
  155. package/dist/fields/base-tables.js +349 -0
  156. package/dist/fields/builtin-types.d.ts +13 -0
  157. package/dist/fields/builtin-types.js +773 -0
  158. package/dist/fields/button.d.ts +2 -0
  159. package/dist/fields/button.js +17 -0
  160. package/dist/fields/chart-view.d.ts +35 -0
  161. package/dist/fields/chart-view.js +154 -0
  162. package/dist/fields/column-order.d.ts +6 -0
  163. package/dist/fields/column-order.js +12 -0
  164. package/dist/fields/convert.d.ts +16 -0
  165. package/dist/fields/convert.js +176 -0
  166. package/dist/fields/copy-text.d.ts +13 -0
  167. package/dist/fields/copy-text.js +45 -0
  168. package/dist/fields/editor-request.svelte.d.ts +71 -0
  169. package/dist/fields/editor-request.svelte.js +52 -0
  170. package/dist/fields/field-ops.d.ts +72 -0
  171. package/dist/fields/field-ops.js +334 -0
  172. package/dist/fields/filter-model.d.ts +84 -0
  173. package/dist/fields/filter-model.js +446 -0
  174. package/dist/fields/format.d.ts +109 -0
  175. package/dist/fields/format.js +288 -0
  176. package/dist/fields/formula.d.ts +50 -0
  177. package/dist/fields/formula.js +530 -0
  178. package/dist/fields/grid-access.d.ts +60 -0
  179. package/dist/fields/grid-access.js +120 -0
  180. package/dist/fields/index.d.ts +34 -0
  181. package/dist/fields/index.js +312 -0
  182. package/dist/fields/linked-fields.d.ts +8 -0
  183. package/dist/fields/linked-fields.js +40 -0
  184. package/dist/fields/links.d.ts +10 -0
  185. package/dist/fields/links.js +46 -0
  186. package/dist/fields/name-list.d.ts +16 -0
  187. package/dist/fields/name-list.js +49 -0
  188. package/dist/fields/palette.d.ts +47 -0
  189. package/dist/fields/palette.js +69 -0
  190. package/dist/fields/record-delete.svelte.d.ts +12 -0
  191. package/dist/fields/record-delete.svelte.js +5 -0
  192. package/dist/fields/record-menu.d.ts +9 -0
  193. package/dist/fields/record-menu.js +78 -0
  194. package/dist/fields/registry.svelte.d.ts +176 -0
  195. package/dist/fields/registry.svelte.js +51 -0
  196. package/dist/fields/rich-text.d.ts +23 -0
  197. package/dist/fields/rich-text.js +48 -0
  198. package/dist/fields/row-color-choice.svelte.d.ts +31 -0
  199. package/dist/fields/row-color-choice.svelte.js +25 -0
  200. package/dist/fields/row-colors.d.ts +36 -0
  201. package/dist/fields/row-colors.js +90 -0
  202. package/dist/fields/row-height.d.ts +28 -0
  203. package/dist/fields/row-height.js +50 -0
  204. package/dist/fields/sources.svelte.d.ts +80 -0
  205. package/dist/fields/sources.svelte.js +131 -0
  206. package/dist/fields/summaries.d.ts +18 -0
  207. package/dist/fields/summaries.js +138 -0
  208. package/dist/fields/view-model.d.ts +129 -0
  209. package/dist/fields/view-model.js +492 -0
  210. package/dist/fields/viewbar/ChartPanel.svelte +61 -0
  211. package/dist/fields/viewbar/ChartPanel.svelte.d.ts +9 -0
  212. package/dist/fields/viewbar/ColorPanel.svelte +112 -0
  213. package/dist/fields/viewbar/ColorPanel.svelte.d.ts +9 -0
  214. package/dist/fields/viewbar/ConditionValue.svelte +153 -0
  215. package/dist/fields/viewbar/ConditionValue.svelte.d.ts +15 -0
  216. package/dist/fields/viewbar/FieldIcon.svelte +18 -0
  217. package/dist/fields/viewbar/FieldIcon.svelte.d.ts +9 -0
  218. package/dist/fields/viewbar/FilterPanel.svelte +192 -0
  219. package/dist/fields/viewbar/FilterPanel.svelte.d.ts +13 -0
  220. package/dist/fields/viewbar/GanttPanel.svelte +60 -0
  221. package/dist/fields/viewbar/GanttPanel.svelte.d.ts +10 -0
  222. package/dist/fields/viewbar/HideFieldsPanel.svelte +104 -0
  223. package/dist/fields/viewbar/HideFieldsPanel.svelte.d.ts +7 -0
  224. package/dist/fields/viewbar/SortPanel.svelte +85 -0
  225. package/dist/fields/viewbar/SortPanel.svelte.d.ts +8 -0
  226. package/dist/fields/viewbar/ViewsMenu.svelte +250 -0
  227. package/dist/fields/viewbar/ViewsMenu.svelte.d.ts +15 -0
  228. package/dist/fields/viewbar/panel-focus.d.ts +3 -0
  229. package/dist/fields/viewbar/panel-focus.js +22 -0
  230. package/dist/fields/viewbar/sort-state.d.ts +20 -0
  231. package/dist/fields/viewbar/sort-state.js +24 -0
  232. package/dist/gallery.d.ts +7 -0
  233. package/dist/gallery.js +36 -0
  234. package/dist/gantt/SvGridGantt.svelte +88 -16
  235. package/dist/gantt/gantt-config.d.ts +28 -0
  236. package/dist/index.d.ts +3 -0
  237. package/dist/index.js +6 -0
  238. package/dist/install.js +3 -0
  239. package/dist/license-core.d.ts +3 -3
  240. package/dist/license.js +1 -0
  241. package/dist/node/studio.js +141 -20
  242. package/dist/scheduler-config.d.ts +11 -0
  243. package/dist/sources/introspect-supabase.js +4 -1
  244. package/dist/sources/rest.js +6 -2
  245. package/dist/studio/emit-project.js +25 -6
  246. package/dist/studio/sveltekit3.js +13 -7
  247. package/dist/studio/ui-components.generated.js +94 -2
  248. package/dist/upgrade-prompt.d.ts +1 -1
  249. package/dist/version.d.ts +2 -2
  250. package/dist/version.js +2 -2
  251. package/dist/wc/GridFooter-f5K0aLe_.js +145 -0
  252. package/dist/wc/GridMenus-FtSN_8t9.js +1369 -0
  253. package/dist/wc/PinSplitter-D-qtDhSM.js +132 -0
  254. package/dist/wc/{SvGrid.helpers-zBkDTryR.js → SvGrid.helpers-B2GEKrxS.js} +84 -36
  255. package/dist/wc/{SvGridCellEditor-CzUKEbkI.js → SvGridCellEditor-B_cLJrsp.js} +20 -9
  256. package/dist/wc/conditional-formatting-BXis_oP1.js +189 -0
  257. package/dist/wc/grid-extension.svelte-Bufq4B4C.js +20 -0
  258. package/dist/wc/sv-sheet-element.js +7561 -7618
  259. package/dist/wc/svelte-virtualizer.svelte-ehwOupl-.js +360 -0
  260. package/dist/wc/{validate-43C03DLP.js → validate-BaMO8UPE.js} +1 -1
  261. package/package.json +14 -3
  262. package/dist/designer/assets/GridMenus-CvcASlKv.js +0 -8
  263. package/dist/designer/assets/SvGrid.helpers-DE5mmORW.js +0 -1
  264. package/dist/designer/assets/SvGridCellEditor-C7NWcnNC.js +0 -4
  265. package/dist/designer/assets/SvListBox-BlmmzYcU.js +0 -110
  266. package/dist/designer/assets/index-KmSEY7Lb.css +0 -1
  267. package/dist/designer/assets/src-DqHCqori.js +0 -58
  268. package/dist/designer/assets/validate-B71dE1Cs.js +0 -1
  269. package/dist/wc/GridMenus-fWbBUiRH.js +0 -1088
  270. package/dist/wc/svelte-virtualizer.svelte-Dntdh8Ms.js +0 -581
@@ -27,6 +27,7 @@
27
27
  portalToBody,
28
28
  popIn,
29
29
  createDismissableLayer,
30
+ getGridExtension,
30
31
  onScrollOutside,
31
32
  SvDrawer,
32
33
  SvForm,
@@ -161,7 +162,16 @@
161
162
  }
162
163
 
163
164
  // --- columns lookup + default title field ---
164
- const fieldColumns = $derived(columns.filter((c) => typeof c.field === "string"));
165
+ // Columns declared by field type are filled in as the grid fills them
166
+ // (formatter, computed value), so the task table shows what the grid shows.
167
+ const fieldColumns = $derived.by(() => {
168
+ const own = columns.filter((c) => typeof c.field === "string");
169
+ const fill = getGridExtension()?.column;
170
+ if (!fill) return own;
171
+ type Def = Record<string, unknown>;
172
+ const defs = own as unknown as Def[];
173
+ return defs.map((c) => (c.fieldType ? fill(c, defs) : c)) as unknown as typeof own;
174
+ });
165
175
  const titleField = $derived(
166
176
  gantt.titleField ?? (fieldColumns[0]?.field as string | undefined),
167
177
  );
@@ -178,7 +188,11 @@
178
188
  getTitle: (r) => (titleField ? String(fieldValue(r, titleField) ?? "") : ""),
179
189
  getProgress: (r) =>
180
190
  progressOf[key(r)] ??
181
- (gantt.progressField ? (fieldValue(r, gantt.progressField) as never) : undefined),
191
+ (pcfg.progressValue
192
+ ? (pcfg.progressValue(r) as never)
193
+ : gantt.progressField
194
+ ? (fieldValue(r, gantt.progressField) as never)
195
+ : undefined),
182
196
  getParent: (r) =>
183
197
  gantt.parentField
184
198
  ? (fieldValue(r, gantt.parentField) as string | null | undefined)
@@ -186,9 +200,10 @@
186
200
  getMilestone: (r) =>
187
201
  gantt.milestoneField ? !!fieldValue(r, gantt.milestoneField) : false,
188
202
  getColor: (r) =>
189
- gantt.colorField
203
+ pcfg.colorOf?.(r) ??
204
+ (gantt.colorField
190
205
  ? ((fieldValue(r, gantt.colorField) as string | undefined) ?? gantt.color)
191
- : gantt.color,
206
+ : gantt.color),
192
207
  }));
193
208
 
194
209
  const tasks = $derived(resolveTasks(data, spec, cal));
@@ -323,6 +338,9 @@
323
338
  (pct: number) => new Date(axis.start.getTime() + (pct / 100) * axis.totalMs),
324
339
  );
325
340
  const bodyH = $derived(Math.max(rowH, nodes.length * rowH));
341
+ // The chart fills the pane below the last row too: the weekend shading runs
342
+ // to the bottom, and a double-click there adds a task.
343
+ let axisH = $state(0);
326
344
 
327
345
  // Non-working columns, as day bands. Under a day-granular axis these are
328
346
  // whole days; a tick coarser than a day (week / month) is never wholly
@@ -419,6 +437,16 @@
419
437
  });
420
438
  };
421
439
  for (const d of gantt.dependencies ?? []) push(d);
440
+ // Predecessors listed on the task that waits for them.
441
+ const pf = pcfg.predecessorField;
442
+ if (pf) {
443
+ for (const row of data) {
444
+ const raw = fieldValue(row, pf);
445
+ const ids = Array.isArray(raw) ? raw : raw == null || raw === "" ? [] : [raw];
446
+ const to = key(row);
447
+ for (const from of ids) push({ id: `${String(from)}->${to}`, from: String(from), to });
448
+ }
449
+ }
422
450
  const f = gantt.dependencyField;
423
451
  if (f) {
424
452
  for (const row of data) {
@@ -780,7 +808,7 @@
780
808
  // The hover card describes the bar as it was grabbed; after a move it
781
809
  // would go on showing those dates until the pointer left the bar.
782
810
  clearTimeout(tipTimer);
783
- tipBar = null;
811
+ tipKey = null;
784
812
  window.addEventListener("pointermove", onDragMove);
785
813
  window.addEventListener("pointerup", onDragEnd, { once: true });
786
814
  window.addEventListener("pointercancel", onDragCancel, { once: true });
@@ -1332,6 +1360,8 @@
1332
1360
  kind: "field" | "duration" | "progress" | "slack";
1333
1361
  field?: string;
1334
1362
  numeric?: boolean;
1363
+ /** The column itself, so a cell reads its value and shows it as the grid does. */
1364
+ def?: ColumnDef<TFeatures, TData>;
1335
1365
  };
1336
1366
  /** Two columns a consumer can name in `tableColumns` without defining them. */
1337
1367
  const BUILT_IN: Record<string, TableCol> = {
@@ -1346,9 +1376,10 @@
1346
1376
  const fromDef = (c: ColumnDef<TFeatures, TData>): TableCol => ({
1347
1377
  id: colId(c),
1348
1378
  label: typeof c.header === "string" ? c.header : ((c.field as string) ?? ""),
1349
- width: c.width ?? 140,
1379
+ width: pcfg.tableColumnWidths?.[colId(c)] ?? c.width ?? 140,
1350
1380
  kind: "field",
1351
1381
  field: c.field as string | undefined,
1382
+ def: c,
1352
1383
  });
1353
1384
  const want = gantt.tableColumns;
1354
1385
  if (!want) return fieldColumns.map(fromDef);
@@ -1397,7 +1428,9 @@
1397
1428
  if (tableWFitted || tableWTouched || gantt.tableWidth != null || viewportW <= 0) return;
1398
1429
  tableWFitted = true;
1399
1430
  const trailing = tableColsWidth - (tableCols[0]?.width ?? 0);
1400
- tableW = Math.max(180, trailing + 120, Math.min(tableW, Math.floor(viewportW * 0.4)));
1431
+ // Never more than 60% of the container either: with many columns the
1432
+ // trailing ones clip (the splitter shows them), the chart keeps its room.
1433
+ tableW = Math.min(Math.floor(viewportW * 0.6), Math.max(180, trailing + 120, Math.min(tableW, Math.floor(viewportW * 0.4))));
1401
1434
  });
1402
1435
  const showTable = $derived(tableCols.length > 0 && tableW > 0);
1403
1436
 
@@ -1428,10 +1461,29 @@
1428
1461
  }
1429
1462
  return String(slackDays(cpm, n.task.key));
1430
1463
  }
1431
- if (col.kind === "field" && col.field) return fmt(fieldValue(n.task.row, col.field));
1464
+ if (col.kind === "field" && col.field) return fieldText(col, n.task.row);
1432
1465
  return "";
1433
1466
  }
1434
1467
 
1468
+ /**
1469
+ * A field cell as the grid shows it: the column's computed value
1470
+ * (`fieldFn`) through its `formatter` (a select's label, a person's name, a
1471
+ * date in the column's format), else the plain value.
1472
+ */
1473
+ function fieldText(col: TableCol, row: TData): string {
1474
+ const def = col.def as { fieldFn?: (r: TData) => unknown; formatter?: (c: { value: unknown; row: TData; column: unknown }) => unknown } | undefined;
1475
+ const value = def?.fieldFn ? def.fieldFn(row) : fieldValue(row, col.field!);
1476
+ if (def?.formatter) {
1477
+ try {
1478
+ return String(def.formatter({ value, row, column: { id: col.id, columnDef: def } }) ?? "");
1479
+ } catch {
1480
+ return fmt(value);
1481
+ }
1482
+ }
1483
+ if (Array.isArray(value)) return value.map(fmt).join(", ");
1484
+ return fmt(value);
1485
+ }
1486
+
1435
1487
  // --- splitter -------------------------------------------------------------
1436
1488
  let splitDrag: { startX: number; startW: number } | null = null;
1437
1489
  function startSplit(e: PointerEvent) {
@@ -1460,6 +1512,8 @@
1460
1512
  let scrollEl = $state<HTMLElement | null>(null);
1461
1513
  let scrollTop = $state(0);
1462
1514
  let viewportH = $state(0);
1515
+ // Below viewportH, which it reads (see axisH above).
1516
+ const fillH = $derived(Math.max(bodyH, viewportH - axisH - 1));
1463
1517
  function onScroll() {
1464
1518
  if (scrollEl) scrollTop = scrollEl.scrollTop;
1465
1519
  }
@@ -1573,22 +1627,25 @@
1573
1627
  const tooltipCfg = $derived(gantt.tooltip);
1574
1628
  const hasTooltip = $derived(!!tooltipCfg);
1575
1629
  const tooltipSnippet = $derived(typeof tooltipCfg === "function" ? tooltipCfg : undefined);
1576
- let tipBar = $state<Bar | null>(null);
1630
+ // The hovered bar by key, read from the bars as drawn now: a bar object
1631
+ // kept from the hover would show the dates it had then (mid-drag, say).
1632
+ let tipKey = $state<string | null>(null);
1633
+ const tipBar = $derived(tipKey ? (bars.find((b) => b.key === tipKey) ?? null) : null);
1577
1634
  let tipPos = $state({ x: 0, y: 0 });
1578
1635
  let tipTimer: ReturnType<typeof setTimeout> | undefined;
1579
1636
  function onBarEnter(e: MouseEvent, bar: Bar) {
1580
- if (!hasTooltip) return;
1637
+ if (!hasTooltip || drag) return;
1581
1638
  clearTimeout(tipTimer);
1582
1639
  const target = e.currentTarget as HTMLElement;
1583
1640
  tipTimer = setTimeout(() => {
1584
1641
  const r = target.getBoundingClientRect();
1585
1642
  tipPos = { x: Math.round(r.left + r.width / 2), y: Math.round(r.top) };
1586
- tipBar = bar;
1643
+ tipKey = bar.key;
1587
1644
  }, gantt.tooltipDelay ?? 400);
1588
1645
  }
1589
1646
  function onBarLeave() {
1590
1647
  clearTimeout(tipTimer);
1591
- tipBar = null;
1648
+ tipKey = null;
1592
1649
  }
1593
1650
  $effect(() => () => clearTimeout(tipTimer));
1594
1651
 
@@ -1682,6 +1739,11 @@
1682
1739
  suppressClick = false;
1683
1740
  return;
1684
1741
  }
1742
+ // The app opens tasks itself (a record view): that wins over the drawer.
1743
+ if (pcfg.onTaskOpen) {
1744
+ pcfg.onTaskOpen(bar.row);
1745
+ return;
1746
+ }
1685
1747
  if (!hasDrawer) return;
1686
1748
  const next: Record<string, unknown> = {
1687
1749
  __start: dayInput(bar.start),
@@ -1743,8 +1805,11 @@
1743
1805
  let menuPanel = $state<HTMLElement | null>(null);
1744
1806
  function openMenu(e: MouseEvent, bar: Bar) {
1745
1807
  const items: MenuItem[] = [];
1746
- if (hasDrawer) items.push({ label: "Edit", onSelect: () => openDrawer(bar) });
1747
- if (editable && gantt.onTaskAdd) {
1808
+ if (pcfg.onTaskOpen) items.push({ label: "Open", onSelect: () => pcfg.onTaskOpen?.(bar.row) });
1809
+ else if (hasDrawer) items.push({ label: "Edit", onSelect: () => openDrawer(bar) });
1810
+ // A subtask needs a tree to hang in: without parentField it would be
1811
+ // just another task.
1812
+ if (editable && gantt.onTaskAdd && gantt.parentField) {
1748
1813
  items.push({
1749
1814
  label: "Add subtask",
1750
1815
  onSelect: () => gantt.onTaskAdd?.(bar.start, addDays(bar.start, 1), bar.key),
@@ -1937,6 +2002,8 @@
1937
2002
  ></span>
1938
2003
  </span>
1939
2004
  <span class="sv-gantt-meter-pct">{Math.round(drawnSpan(node).progress)}%</span>
2005
+ {:else if ci === 0 && pcfg.onTaskOpen}
2006
+ <button type="button" class="sv-gantt-cell-text sv-gantt-open" title={`Open ${node.task.title}`} onclick={() => pcfg.onTaskOpen?.(node.task.row)}>{cellText(col, node)}</button>
1940
2007
  {:else}
1941
2008
  <span class="sv-gantt-cell-text">{cellText(col, node)}</span>
1942
2009
  {/if}
@@ -1957,7 +2024,7 @@
1957
2024
  {/if}
1958
2025
 
1959
2026
  <div class="sv-gantt-chart" style={`width:${axisPx}px`}>
1960
- <div class="sv-gantt-axis" style={`width:${axisPx}px`}>
2027
+ <div class="sv-gantt-axis" style={`width:${axisPx}px`} bind:clientHeight={axisH}>
1961
2028
  <div class="sv-gantt-majors">
1962
2029
  {#each axis.majors as m (m.leftPct)}
1963
2030
  <div
@@ -1982,7 +2049,7 @@
1982
2049
  <div
1983
2050
  class="sv-gantt-body"
1984
2051
  bind:this={bodyEl}
1985
- style={`width:${axisPx}px; height:${bodyH}px`}
2052
+ style={`width:${axisPx}px; height:${fillH}px`}
1986
2053
  ondblclick={onBodyDblClick}
1987
2054
  oncontextmenu={onBodyContextMenu}
1988
2055
  >
@@ -2400,6 +2467,11 @@
2400
2467
  }
2401
2468
  .sv-gantt-parent { font-weight: 600; }
2402
2469
  .sv-gantt-cell-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
2470
+ .sv-gantt-open {
2471
+ min-width: 0; padding: 0; border: 0; background: none; font: inherit; color: inherit; text-align: start; cursor: pointer;
2472
+ }
2473
+ .sv-gantt-open:hover { text-decoration: underline; text-underline-offset: 2px; }
2474
+ .sv-gantt-open:focus-visible { outline: 2px solid var(--sg-focus, var(--sg-accent, #2563eb)); outline-offset: 1px; border-radius: 3px; }
2403
2475
  .sv-gantt-chevron {
2404
2476
  flex: none;
2405
2477
  width: 16px;
@@ -18,6 +18,34 @@ import type { GanttConfig, RowData, SchedulerResource, TableFeatures } from '@sv
18
18
  */
19
19
  export type GanttConstraint = 'ASAP' | 'ALAP' | 'MSO' | 'MFO' | 'SNET' | 'SNLT' | 'FNET' | 'FNLT';
20
20
  export type GanttProConfig<TFeatures extends TableFeatures = TableFeatures, TData extends RowData = RowData> = GanttConfig<TFeatures, TData> & {
21
+ /**
22
+ * A bar's color from its row (a status option's color, say). Wins over
23
+ * `colorField` and `color`; return nothing to fall back to them.
24
+ */
25
+ colorOf?: (row: TData) => string | null | undefined;
26
+ /**
27
+ * Open a task where the app keeps it (a record view, a page) instead of
28
+ * the built-in drawer: a click or Enter on a bar, the task's name in the
29
+ * table, and "Open" in the bar's menu call it.
30
+ */
31
+ onTaskOpen?: (row: TData) => void;
32
+ /**
33
+ * Field holding the ids of the tasks this one DEPENDS ON (its predecessors),
34
+ * drawn as finish-to-start arrows into it. The other direction from
35
+ * `dependencyField`, which lists a task's successors.
36
+ */
37
+ predecessorField?: keyof TData & string;
38
+ /**
39
+ * A task's progress, 0 to 100, from its row: for a field that holds
40
+ * something else (a fraction, a status). Wins over `progressField` when
41
+ * drawing; the grip still reports 0 to 100 through `onProgressChange`.
42
+ */
43
+ progressValue?: (row: TData) => number | null | undefined;
44
+ /**
45
+ * Widths (px) of task-table columns by id, over the columns' own `width`:
46
+ * a grid column sized for a wide table can sit narrower beside the bars.
47
+ */
48
+ tableColumnWidths?: Record<string, number>;
21
49
  /**
22
50
  * Highlight the critical path: the chain of linked tasks with no slack,
23
51
  * where any slip moves the project's finish. Needs `dependencies`.
package/dist/index.d.ts CHANGED
@@ -9,6 +9,7 @@ export { default as SvImportDialog } from './SvImportDialog.svelte';
9
9
  export { installEnterprise, type EnterpriseGridApi, type EnterpriseAIApi, type EnterprisePivotApi } from './install.js';
10
10
  export { enableSchedulerView, SvGridScheduler } from './scheduler.js';
11
11
  export { enableBoardView, SvGridBoard } from './board.js';
12
+ export { enableGalleryView, SvGridGallery } from './gallery.js';
12
13
  export * from './gantt/index.js';
13
14
  export { enableSelectionBar, SvGridSelectionBar } from './selection-bar.js';
14
15
  export { applyBulkEdit, bulkEditableFields, bulkEditInitialValues, coerceBulkValue, type BulkEditField, type BulkEditResult } from './bulk-edit.js';
@@ -147,6 +148,8 @@ export { evaluatePredicate, evaluateScalar, evaluateChange, BUILTIN_FUNCTION_NAM
147
148
  export { parsePredicate, stringifyPredicate, stringifyScalar, validateExpression, collectColumnRefs, ExpressionParseError, } from './expressions/parse.js';
148
149
  export { OPERATORS, operatorMeta, operatorsForType, isValueless, isSetOperator, isRangeOperator, columnById, resolveColumnRef, columnLabel, columnRefText, type ExprColumn, type ExprColumnType, type OperatorMeta, } from './expressions/expression-columns.js';
149
150
  export type { ScalarExpr, PredicateExpr, ChangeExpr, ComparisonOp, ArithmeticOp, AggFn, EvalContext, ExprRow, } from './expressions/expression-types.js';
151
+ export { registerPredicateKind, getPredicateKind, type PredicateKind, type PredicateKindContext } from './expressions/kinds.js';
152
+ export { setAlertConditionEditor, type AlertConditionEditor } from './alerts/condition-editor.js';
150
153
  export { default as SvExpressionEditor } from './SvExpressionEditor.svelte';
151
154
  export { enableAlerts } from './alerts.js';
152
155
  export { createAlertEngine, renderTemplate, type AlertEngine, type AlertEngineOptions, type ValidateEditResult, } from './alerts/alert-engine.js';
package/dist/index.js CHANGED
@@ -20,6 +20,9 @@ export { enableSchedulerView, SvGridScheduler } from './scheduler.js';
20
20
  // Kanban board view (Pro). `enableBoardView()` registers the renderer so
21
21
  // `<SvGrid board={...}>` shows lanes of cards. Config types live in @svgrid/grid.
22
22
  export { enableBoardView, SvGridBoard } from './board.js';
23
+ // Gallery view (Pro). `enableGalleryView()` registers the renderer so
24
+ // `<SvGrid gallery={...}>` shows rows as cards. Config types live in @svgrid/grid.
25
+ export { enableGalleryView, SvGridGallery } from './gallery.js';
23
26
  // Gantt view (Pro). `enableGanttView()` registers the renderer so
24
27
  // `<SvGrid gantt={...}>` shows a task table beside a time chart. The `gantt`
25
28
  // prop and its config types live in @svgrid/grid; the layout model, the
@@ -188,6 +191,9 @@ export { pivotToChartSpec } from './pivot-chart.js';
188
191
  export { evaluatePredicate, evaluateScalar, evaluateChange, BUILTIN_FUNCTION_NAMES, isBuiltinFunction, } from './expressions/evaluate.js';
189
192
  export { parsePredicate, stringifyPredicate, stringifyScalar, validateExpression, collectColumnRefs, ExpressionParseError, } from './expressions/parse.js';
190
193
  export { OPERATORS, operatorMeta, operatorsForType, isValueless, isSetOperator, isRangeOperator, columnById, resolveColumnRef, columnLabel, columnRefText, } from './expressions/expression-columns.js';
194
+ // A module's own condition kind: the `ext` node (SvGrid Base's field filter).
195
+ export { registerPredicateKind, getPredicateKind } from './expressions/kinds.js';
196
+ export { setAlertConditionEditor } from './alerts/condition-editor.js';
191
197
  export { default as SvExpressionEditor } from './SvExpressionEditor.svelte';
192
198
  // Alert Rules engine (Pro). Declarative "when this holds / this moves -> toast /
193
199
  // badge / highlight / flash / prevent-edit / log". Authored at runtime,
package/dist/install.js CHANGED
@@ -9,6 +9,7 @@ import { aiFilter, aiSmartFill, aiSummarize, aiClassify, aiExport, aiFindAnomali
9
9
  import { createPivotModel, } from './pivot.js';
10
10
  import { enableSchedulerView } from './scheduler.js';
11
11
  import { enableBoardView } from './board.js';
12
+ import { enableGalleryView } from './gallery.js';
12
13
  import { enableGanttView } from './gantt/gantt.js';
13
14
  import { enableSelectionBar } from './selection-bar.js';
14
15
  import { enableAdvancedFilter } from './advanced-filter-enable.js';
@@ -46,6 +47,8 @@ export function installEnterprise(api) {
46
47
  enableSchedulerView();
47
48
  // Register the Kanban board view (no-op without the `board` prop).
48
49
  enableBoardView();
50
+ // Register the gallery view (no-op without the `gallery` prop).
51
+ enableGalleryView();
49
52
  // Register the Gantt view (no-op without the `gantt` prop).
50
53
  enableGanttView();
51
54
  enableSelectionBar();
@@ -2,13 +2,13 @@
2
2
  export declare const VALID_PREFIX = "SVENTERPRISE-";
3
3
  /**
4
4
  * What an order bought. `grid` is the enterprise grid on its own; `suite` adds
5
- * the spreadsheet and the Studio. Keys issued before editions existed carry no
5
+ * the spreadsheet, SvGrid Base (the table database) and the Studio. Keys issued before editions existed carry no
6
6
  * edition segment and read as `suite`, so nothing an existing customer already
7
7
  * ships changes when this lands.
8
8
  */
9
9
  export type LicenseEdition = 'grid' | 'suite';
10
- /** The three things an edition can gate. */
11
- export type LicensedProduct = 'grid' | 'spreadsheet' | 'studio';
10
+ /** The things an edition can gate. */
11
+ export type LicensedProduct = 'grid' | 'spreadsheet' | 'base' | 'studio';
12
12
  /** Does `edition` cover `product`? Pure, and the only place the answer lives. */
13
13
  export declare function editionCovers(edition: LicenseEdition, product: LicensedProduct): boolean;
14
14
  export type LicenseStatus = 'unset' | 'invalid' | 'revoked' | 'dev' | 'eval' | 'licensed';
package/dist/license.js CHANGED
@@ -139,6 +139,7 @@ export function nudgeEnterprise(feature) {
139
139
  const PRODUCT_LABEL = {
140
140
  grid: 'the enterprise grid',
141
141
  spreadsheet: 'the spreadsheet',
142
+ base: 'SvGrid Base',
142
143
  studio: 'the Studio',
143
144
  };
144
145
  /** One-time console notice for a feature the current edition does not cover.