@svgrid/enterprise 3.1.8 → 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.
- package/README.md +1 -0
- package/dist/SvAlertRuleEditor.svelte +16 -5
- package/dist/SvGridAlerts.svelte +8 -0
- package/dist/SvGridAlerts.svelte.d.ts +4 -0
- package/dist/SvGridBoard.svelte +69 -10
- package/dist/SvGridBulkEditDrawer.svelte +13 -5
- package/dist/SvGridGallery.svelte +286 -0
- package/dist/SvGridGallery.svelte.d.ts +30 -0
- package/dist/SvGridScheduler.svelte +33 -11
- package/dist/SvGridSelectionBar.svelte +47 -0
- package/dist/advanced-filter/expr-columns-from-grid.d.ts +1 -0
- package/dist/advanced-filter/expr-columns-from-grid.js +11 -7
- package/dist/advanced-filter-enable.d.ts +6 -0
- package/dist/advanced-filter-enable.js +8 -0
- package/dist/alerts/alert-engine.d.ts +7 -0
- package/dist/alerts/alert-engine.js +5 -2
- package/dist/alerts/condition-editor.d.ts +26 -0
- package/dist/alerts/condition-editor.js +17 -0
- package/dist/base/index.d.ts +20 -0
- package/dist/base/index.js +20 -0
- package/dist/bulk-edit.d.ts +11 -0
- package/dist/bulk-edit.js +18 -1
- package/dist/cdn/svgrid-enterprise.svelte-external.js +11197 -10639
- package/dist/designer/assets/GridFooter-Cu8_yBlQ.js +2 -0
- package/dist/designer/assets/GridMenus-BUjkkAU2.js +6 -0
- package/dist/designer/assets/PinSplitter-BgTpgh1d.css +1 -0
- package/dist/designer/assets/PinSplitter-C5AwA1xV.js +1 -0
- package/dist/designer/assets/SvGrid.helpers-CIrmIo9U.js +1 -0
- package/dist/designer/assets/SvGridCellEditor-CJxThKL_.js +4 -0
- package/dist/designer/assets/SvListBox-CS7oUAiX.js +2 -0
- package/dist/designer/assets/conditional-formatting-MDWbF8_Y.js +1 -0
- package/dist/designer/assets/grid-extension.svelte-BZ7AqyJI.js +1 -0
- package/dist/designer/assets/{index-Obk8sI77.js → index-BPU2KNc5.js} +307 -307
- package/dist/designer/assets/index-BmvG99kR.css +1 -0
- package/dist/designer/assets/sparkline-C-NcnB2i.js +1 -0
- package/dist/designer/assets/src-C_U1NKOY.js +58 -0
- package/dist/designer/assets/sv-grid-scrollbar-B9N6Wuj0.js +109 -0
- package/dist/designer/assets/validate-H5u2HEQh.js +1 -0
- package/dist/designer/index.html +11 -7
- package/dist/expressions/compile.js +10 -0
- package/dist/expressions/evaluate.js +18 -0
- package/dist/expressions/expression-types.d.ts +10 -0
- package/dist/expressions/kinds.d.ts +28 -0
- package/dist/expressions/kinds.js +19 -0
- package/dist/expressions/parse.js +9 -1
- package/dist/fields/AttachmentCell.svelte +242 -0
- package/dist/fields/AttachmentCell.svelte.d.ts +5 -0
- package/dist/fields/AttachmentDialog.svelte +357 -0
- package/dist/fields/AttachmentDialog.svelte.d.ts +13 -0
- package/dist/fields/AttachmentEditor.svelte +41 -0
- package/dist/fields/AttachmentEditor.svelte.d.ts +11 -0
- package/dist/fields/AttachmentPreview.svelte +72 -0
- package/dist/fields/AttachmentPreview.svelte.d.ts +8 -0
- package/dist/fields/BarcodeCell.svelte +20 -0
- package/dist/fields/BarcodeCell.svelte.d.ts +5 -0
- package/dist/fields/BaseAutomations.svelte +558 -0
- package/dist/fields/BaseAutomations.svelte.d.ts +18 -0
- package/dist/fields/BaseChartView.svelte +47 -0
- package/dist/fields/BaseChartView.svelte.d.ts +8 -0
- package/dist/fields/BaseTableView.svelte +185 -0
- package/dist/fields/BaseTableView.svelte.d.ts +37 -0
- package/dist/fields/BaseTabs.svelte +308 -0
- package/dist/fields/BaseTabs.svelte.d.ts +21 -0
- package/dist/fields/ButtonCell.svelte +47 -0
- package/dist/fields/ButtonCell.svelte.d.ts +20 -0
- package/dist/fields/CheckboxCell.svelte +46 -0
- package/dist/fields/CheckboxCell.svelte.d.ts +14 -0
- package/dist/fields/DeleteFieldConfirm.svelte +80 -0
- package/dist/fields/DeleteFieldConfirm.svelte.d.ts +8 -0
- package/dist/fields/DeleteRecordConfirm.svelte +48 -0
- package/dist/fields/DeleteRecordConfirm.svelte.d.ts +9 -0
- package/dist/fields/FieldCell.svelte +80 -0
- package/dist/fields/FieldCell.svelte.d.ts +9 -0
- package/dist/fields/FieldEditor.svelte +321 -0
- package/dist/fields/FieldEditor.svelte.d.ts +10 -0
- package/dist/fields/FieldInput.svelte +188 -0
- package/dist/fields/FieldInput.svelte.d.ts +29 -0
- package/dist/fields/FieldsHeaderEnd.svelte +146 -0
- package/dist/fields/FieldsHeaderEnd.svelte.d.ts +6 -0
- package/dist/fields/FootRowAdder.svelte +8 -0
- package/dist/fields/FootRowAdder.svelte.d.ts +6 -0
- package/dist/fields/GroupHeader.svelte +127 -0
- package/dist/fields/GroupHeader.svelte.d.ts +24 -0
- package/dist/fields/LinkCell.svelte +46 -0
- package/dist/fields/LinkCell.svelte.d.ts +9 -0
- package/dist/fields/LinkPickerEditor.svelte +172 -0
- package/dist/fields/LinkPickerEditor.svelte.d.ts +9 -0
- package/dist/fields/LinkPreview.svelte +60 -0
- package/dist/fields/LinkPreview.svelte.d.ts +7 -0
- package/dist/fields/LinkedRecordView.svelte +94 -0
- package/dist/fields/LinkedRecordView.svelte.d.ts +9 -0
- package/dist/fields/LinkedRecordsCell.svelte +59 -0
- package/dist/fields/LinkedRecordsCell.svelte.d.ts +11 -0
- package/dist/fields/LongTextEditor.svelte +157 -0
- package/dist/fields/LongTextEditor.svelte.d.ts +11 -0
- package/dist/fields/NumberEditor.svelte +309 -0
- package/dist/fields/NumberEditor.svelte.d.ts +12 -0
- package/dist/fields/OptionsEditor.svelte +117 -0
- package/dist/fields/OptionsEditor.svelte.d.ts +11 -0
- package/dist/fields/PercentCell.svelte +21 -0
- package/dist/fields/PercentCell.svelte.d.ts +8 -0
- package/dist/fields/PropertyInput.svelte +204 -0
- package/dist/fields/PropertyInput.svelte.d.ts +11 -0
- package/dist/fields/RatingCell.svelte +75 -0
- package/dist/fields/RatingCell.svelte.d.ts +16 -0
- package/dist/fields/RatingEditor.svelte +82 -0
- package/dist/fields/RatingEditor.svelte.d.ts +9 -0
- package/dist/fields/RecordView.svelte +310 -0
- package/dist/fields/RecordView.svelte.d.ts +11 -0
- package/dist/fields/RichTextCell.svelte +30 -0
- package/dist/fields/RichTextCell.svelte.d.ts +5 -0
- package/dist/fields/RowAdder.svelte +93 -0
- package/dist/fields/RowAdder.svelte.d.ts +7 -0
- package/dist/fields/RowHeader.svelte +99 -0
- package/dist/fields/RowHeader.svelte.d.ts +11 -0
- package/dist/fields/SelectCell.svelte +35 -0
- package/dist/fields/SelectCell.svelte.d.ts +15 -0
- package/dist/fields/SelectEditor.svelte +350 -0
- package/dist/fields/SelectEditor.svelte.d.ts +17 -0
- package/dist/fields/SummaryCell.svelte +160 -0
- package/dist/fields/SummaryCell.svelte.d.ts +11 -0
- package/dist/fields/SvBase.svelte +545 -0
- package/dist/fields/SvBase.svelte.d.ts +30 -0
- package/dist/fields/SvBaseForm.svelte +295 -0
- package/dist/fields/SvBaseForm.svelte.d.ts +22 -0
- package/dist/fields/SvBaseViewBar.svelte +644 -0
- package/dist/fields/SvBaseViewBar.svelte.d.ts +26 -0
- package/dist/fields/UserCell.svelte +39 -0
- package/dist/fields/UserCell.svelte.d.ts +9 -0
- package/dist/fields/UserFace.svelte +30 -0
- package/dist/fields/UserFace.svelte.d.ts +12 -0
- package/dist/fields/activity.svelte.d.ts +50 -0
- package/dist/fields/activity.svelte.js +110 -0
- package/dist/fields/attachments.d.ts +95 -0
- package/dist/fields/attachments.js +145 -0
- package/dist/fields/automation-outbound.d.ts +46 -0
- package/dist/fields/automation-outbound.js +61 -0
- package/dist/fields/automation-server.d.ts +53 -0
- package/dist/fields/automation-server.js +333 -0
- package/dist/fields/automations.svelte.d.ts +208 -0
- package/dist/fields/automations.svelte.js +437 -0
- package/dist/fields/bar-request.svelte.d.ts +16 -0
- package/dist/fields/bar-request.svelte.js +15 -0
- package/dist/fields/base-alerts.d.ts +24 -0
- package/dist/fields/base-alerts.js +64 -0
- package/dist/fields/base-connect.d.ts +82 -0
- package/dist/fields/base-connect.js +271 -0
- package/dist/fields/base-schema.d.ts +104 -0
- package/dist/fields/base-schema.js +266 -0
- package/dist/fields/base-sql.d.ts +62 -0
- package/dist/fields/base-sql.js +251 -0
- package/dist/fields/base-sync.d.ts +142 -0
- package/dist/fields/base-sync.js +499 -0
- package/dist/fields/base-tables.d.ts +89 -0
- package/dist/fields/base-tables.js +349 -0
- package/dist/fields/builtin-types.d.ts +13 -0
- package/dist/fields/builtin-types.js +773 -0
- package/dist/fields/button.d.ts +2 -0
- package/dist/fields/button.js +17 -0
- package/dist/fields/chart-view.d.ts +35 -0
- package/dist/fields/chart-view.js +154 -0
- package/dist/fields/column-order.d.ts +6 -0
- package/dist/fields/column-order.js +12 -0
- package/dist/fields/convert.d.ts +16 -0
- package/dist/fields/convert.js +176 -0
- package/dist/fields/copy-text.d.ts +13 -0
- package/dist/fields/copy-text.js +45 -0
- package/dist/fields/editor-request.svelte.d.ts +71 -0
- package/dist/fields/editor-request.svelte.js +52 -0
- package/dist/fields/field-ops.d.ts +72 -0
- package/dist/fields/field-ops.js +334 -0
- package/dist/fields/filter-model.d.ts +84 -0
- package/dist/fields/filter-model.js +446 -0
- package/dist/fields/format.d.ts +109 -0
- package/dist/fields/format.js +288 -0
- package/dist/fields/formula.d.ts +50 -0
- package/dist/fields/formula.js +530 -0
- package/dist/fields/grid-access.d.ts +60 -0
- package/dist/fields/grid-access.js +120 -0
- package/dist/fields/index.d.ts +34 -0
- package/dist/fields/index.js +312 -0
- package/dist/fields/linked-fields.d.ts +8 -0
- package/dist/fields/linked-fields.js +40 -0
- package/dist/fields/links.d.ts +10 -0
- package/dist/fields/links.js +46 -0
- package/dist/fields/name-list.d.ts +16 -0
- package/dist/fields/name-list.js +49 -0
- package/dist/fields/palette.d.ts +47 -0
- package/dist/fields/palette.js +69 -0
- package/dist/fields/record-delete.svelte.d.ts +12 -0
- package/dist/fields/record-delete.svelte.js +5 -0
- package/dist/fields/record-menu.d.ts +9 -0
- package/dist/fields/record-menu.js +78 -0
- package/dist/fields/registry.svelte.d.ts +176 -0
- package/dist/fields/registry.svelte.js +51 -0
- package/dist/fields/rich-text.d.ts +23 -0
- package/dist/fields/rich-text.js +48 -0
- package/dist/fields/row-color-choice.svelte.d.ts +31 -0
- package/dist/fields/row-color-choice.svelte.js +25 -0
- package/dist/fields/row-colors.d.ts +36 -0
- package/dist/fields/row-colors.js +90 -0
- package/dist/fields/row-height.d.ts +28 -0
- package/dist/fields/row-height.js +50 -0
- package/dist/fields/sources.svelte.d.ts +80 -0
- package/dist/fields/sources.svelte.js +131 -0
- package/dist/fields/summaries.d.ts +18 -0
- package/dist/fields/summaries.js +138 -0
- package/dist/fields/view-model.d.ts +129 -0
- package/dist/fields/view-model.js +492 -0
- package/dist/fields/viewbar/ChartPanel.svelte +61 -0
- package/dist/fields/viewbar/ChartPanel.svelte.d.ts +9 -0
- package/dist/fields/viewbar/ColorPanel.svelte +112 -0
- package/dist/fields/viewbar/ColorPanel.svelte.d.ts +9 -0
- package/dist/fields/viewbar/ConditionValue.svelte +153 -0
- package/dist/fields/viewbar/ConditionValue.svelte.d.ts +15 -0
- package/dist/fields/viewbar/FieldIcon.svelte +18 -0
- package/dist/fields/viewbar/FieldIcon.svelte.d.ts +9 -0
- package/dist/fields/viewbar/FilterPanel.svelte +192 -0
- package/dist/fields/viewbar/FilterPanel.svelte.d.ts +13 -0
- package/dist/fields/viewbar/GanttPanel.svelte +60 -0
- package/dist/fields/viewbar/GanttPanel.svelte.d.ts +10 -0
- package/dist/fields/viewbar/HideFieldsPanel.svelte +104 -0
- package/dist/fields/viewbar/HideFieldsPanel.svelte.d.ts +7 -0
- package/dist/fields/viewbar/SortPanel.svelte +85 -0
- package/dist/fields/viewbar/SortPanel.svelte.d.ts +8 -0
- package/dist/fields/viewbar/ViewsMenu.svelte +250 -0
- package/dist/fields/viewbar/ViewsMenu.svelte.d.ts +15 -0
- package/dist/fields/viewbar/panel-focus.d.ts +3 -0
- package/dist/fields/viewbar/panel-focus.js +22 -0
- package/dist/fields/viewbar/sort-state.d.ts +20 -0
- package/dist/fields/viewbar/sort-state.js +24 -0
- package/dist/gallery.d.ts +7 -0
- package/dist/gallery.js +36 -0
- package/dist/gantt/SvGridGantt.svelte +88 -16
- package/dist/gantt/gantt-config.d.ts +28 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +6 -0
- package/dist/install.js +3 -0
- package/dist/license-core.d.ts +3 -3
- package/dist/license.js +1 -0
- package/dist/node/studio.js +105 -4
- package/dist/scheduler-config.d.ts +11 -0
- package/dist/sources/introspect-supabase.js +4 -1
- package/dist/sources/rest.js +6 -2
- package/dist/studio/ui-components.generated.js +93 -1
- package/dist/upgrade-prompt.d.ts +1 -1
- package/dist/version.d.ts +2 -2
- package/dist/version.js +2 -2
- package/dist/wc/GridFooter-f5K0aLe_.js +145 -0
- package/dist/wc/GridMenus-FtSN_8t9.js +1369 -0
- package/dist/wc/PinSplitter-D-qtDhSM.js +132 -0
- package/dist/wc/{SvGrid.helpers-zBkDTryR.js → SvGrid.helpers-B2GEKrxS.js} +84 -36
- package/dist/wc/{SvGridCellEditor-CzUKEbkI.js → SvGridCellEditor-B_cLJrsp.js} +20 -9
- package/dist/wc/conditional-formatting-BXis_oP1.js +189 -0
- package/dist/wc/grid-extension.svelte-Bufq4B4C.js +20 -0
- package/dist/wc/sv-sheet-element.js +7556 -7617
- package/dist/wc/svelte-virtualizer.svelte-ehwOupl-.js +360 -0
- package/dist/wc/{validate-43C03DLP.js → validate-BaMO8UPE.js} +1 -1
- package/package.json +14 -3
- package/dist/designer/assets/GridMenus-CvcASlKv.js +0 -8
- package/dist/designer/assets/SvGrid.helpers-DE5mmORW.js +0 -1
- package/dist/designer/assets/SvGridCellEditor-C7NWcnNC.js +0 -4
- package/dist/designer/assets/SvListBox-BlmmzYcU.js +0 -110
- package/dist/designer/assets/index-KmSEY7Lb.css +0 -1
- package/dist/designer/assets/src-DqHCqori.js +0 -58
- package/dist/designer/assets/validate-B71dE1Cs.js +0 -1
- package/dist/wc/GridMenus-fWbBUiRH.js +0 -1088
- package/dist/wc/svelte-virtualizer.svelte-Dntdh8Ms.js +0 -581
|
@@ -132,6 +132,21 @@
|
|
|
132
132
|
return d ? toZonedLocal(d, tz) : undefined;
|
|
133
133
|
};
|
|
134
134
|
const fromZ = (d: Date): Date => fromZonedLocal(d, tz);
|
|
135
|
+
// `allDay`: a value is a day. A bare 'YYYY-MM-DD' is that local day (new Date()
|
|
136
|
+
// reads it as midnight UTC, the evening before west of Greenwich).
|
|
137
|
+
const toDay = (v: unknown): Date | undefined => {
|
|
138
|
+
const m = typeof v === "string" ? /^(\d{4})-(\d{2})-(\d{2})$/.exec(v) : null;
|
|
139
|
+
if (m) return new Date(Number(m[1]), Number(m[2]) - 1, Number(m[3]));
|
|
140
|
+
const d = toZ(v);
|
|
141
|
+
return d ? new Date(d.getFullYear(), d.getMonth(), d.getDate()) : undefined;
|
|
142
|
+
};
|
|
143
|
+
const readDate = (v: unknown): Date | undefined => (scheduler.allDay ? toDay(v) : toZ(v));
|
|
144
|
+
// An all-day end written as a day ('2026-10-14') is the event's LAST day; the
|
|
145
|
+
// calendar's ends are exclusive, so it ends at the next midnight.
|
|
146
|
+
const readEnd = (v: unknown): Date | undefined => {
|
|
147
|
+
const d = readDate(v);
|
|
148
|
+
return d && scheduler.allDay && typeof v === "string" && /^\d{4}-\d{2}-\d{2}$/.test(v) ? addDays(d, 1) : d;
|
|
149
|
+
};
|
|
135
150
|
// Emit boundary: user edits are computed in pseudo-local time; convert their
|
|
136
151
|
// start/end back to real instants before handing them to consumer callbacks.
|
|
137
152
|
type MoveEv = Parameters<NonNullable<typeof scheduler.onEventMove>>[0];
|
|
@@ -232,12 +247,12 @@
|
|
|
232
247
|
void tz; // re-resolve events (their positions) when the display zone changes
|
|
233
248
|
return {
|
|
234
249
|
getKey: (r) => key(r),
|
|
235
|
-
getStart: (r) => startOfE[key(r)] ?? (
|
|
250
|
+
getStart: (r) => startOfE[key(r)] ?? (readDate(fieldValue(r, scheduler.startField)) as never),
|
|
236
251
|
getEnd: (r) =>
|
|
237
252
|
endOfE[key(r)] ??
|
|
238
|
-
(scheduler.endField ? (
|
|
253
|
+
(scheduler.endField ? (readEnd(fieldValue(r, scheduler.endField)) as never) : undefined),
|
|
239
254
|
getAllDay: (r) =>
|
|
240
|
-
allDayOf[key(r)] ?? (scheduler.allDayField ? !!fieldValue(r, scheduler.allDayField) : false),
|
|
255
|
+
allDayOf[key(r)] ?? (scheduler.allDay ? true : scheduler.allDayField ? !!fieldValue(r, scheduler.allDayField) : false),
|
|
241
256
|
getTitle: (r) => (titleField ? String(fieldValue(r, titleField) ?? "") : ""),
|
|
242
257
|
getColor: (r) =>
|
|
243
258
|
scheduler.colorField
|
|
@@ -306,6 +321,8 @@
|
|
|
306
321
|
// derivations below read it, and a `const` used above its declaration is a type
|
|
307
322
|
// error even though `$derived` is lazy enough to work at runtime.
|
|
308
323
|
const pcfg = $derived(scheduler as unknown as SchedulerProConfig<TFeatures, TData>);
|
|
324
|
+
// Off, events move but keep their length: no edge grips (a record with one date has none to change).
|
|
325
|
+
const resizable = $derived(pcfg.resizable !== false);
|
|
309
326
|
// --- multi-calendar overlay ---
|
|
310
327
|
const calendars = $derived(pcfg.calendars ?? []);
|
|
311
328
|
const calField = $derived(pcfg.calendarField);
|
|
@@ -2404,6 +2421,11 @@
|
|
|
2404
2421
|
rangeSel = null; // opening an event dismisses any pending cell selection
|
|
2405
2422
|
tlRangeSel = null;
|
|
2406
2423
|
monthRangeSel = null;
|
|
2424
|
+
// The app opens events itself (a record view): that wins over the drawer.
|
|
2425
|
+
if (pcfg.onEventOpen) {
|
|
2426
|
+
pcfg.onEventOpen(ev.row);
|
|
2427
|
+
return;
|
|
2428
|
+
}
|
|
2407
2429
|
if (scheduler.drawer) {
|
|
2408
2430
|
const row = ev.row;
|
|
2409
2431
|
const next: Record<string, unknown> = {};
|
|
@@ -3364,7 +3386,7 @@
|
|
|
3364
3386
|
onmouseleave={onEventLeave}
|
|
3365
3387
|
title={s.event.title}
|
|
3366
3388
|
>
|
|
3367
|
-
{#if canEditBar && !s.continuesLeft}
|
|
3389
|
+
{#if canEditBar && resizable && !s.continuesLeft}
|
|
3368
3390
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
3369
3391
|
<span
|
|
3370
3392
|
class="sv-sched-chip-resize sv-sched-chip-resize-start"
|
|
@@ -3373,7 +3395,7 @@
|
|
|
3373
3395
|
></span>
|
|
3374
3396
|
{/if}
|
|
3375
3397
|
{#if scheduler.event}{@render scheduler.event(s.event.row)}{:else}{#if !s.event.allDay && !s.continuesLeft}<span class="sv-sched-dot"></span><span class="sv-sched-bar-time">{fmtTime(s.event.start)}</span>{/if}<span class="sv-sched-bar-title">{s.event.title}</span>{/if}
|
|
3376
|
-
{#if canEditBar && !s.continuesRight}
|
|
3398
|
+
{#if canEditBar && resizable && !s.continuesRight}
|
|
3377
3399
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
3378
3400
|
<span
|
|
3379
3401
|
class="sv-sched-chip-resize sv-sched-chip-resize-end"
|
|
@@ -3569,14 +3591,14 @@
|
|
|
3569
3591
|
onmouseleave={onEventLeave}
|
|
3570
3592
|
title={it.event.title}
|
|
3571
3593
|
>
|
|
3572
|
-
{#if canEdit && !g.continuesLeft}
|
|
3594
|
+
{#if canEdit && resizable && !g.continuesLeft}
|
|
3573
3595
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
3574
3596
|
<span class="sv-sched-chip-resize sv-sched-chip-resize-start" aria-hidden="true" onpointerdown={(e) => startTlDrag(e, it.event, "resize-start")}></span>
|
|
3575
3597
|
{/if}
|
|
3576
3598
|
{#if wpx >= 22}
|
|
3577
3599
|
{#if scheduler.event}{@render scheduler.event(it.event.row)}{:else}{#if view === "timelineDay" && !it.event.allDay && !g.continuesLeft}<span class="sv-sched-bar-time">{fmtTime(it.event.start)}</span>{/if}<span class="sv-sched-bar-title">{it.event.title}</span>{/if}
|
|
3578
3600
|
{/if}
|
|
3579
|
-
{#if canEdit && !g.continuesRight}
|
|
3601
|
+
{#if canEdit && resizable && !g.continuesRight}
|
|
3580
3602
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
3581
3603
|
<span class="sv-sched-chip-resize sv-sched-chip-resize-end" aria-hidden="true" onpointerdown={(e) => startTlDrag(e, it.event, "resize-end")}></span>
|
|
3582
3604
|
{/if}
|
|
@@ -3709,7 +3731,7 @@
|
|
|
3709
3731
|
onmouseleave={onEventLeave}
|
|
3710
3732
|
title={s.event.title}
|
|
3711
3733
|
>
|
|
3712
|
-
{#if canEditBar && !s.continuesLeft}
|
|
3734
|
+
{#if canEditBar && resizable && !s.continuesLeft}
|
|
3713
3735
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
3714
3736
|
<span
|
|
3715
3737
|
class="sv-sched-chip-resize sv-sched-chip-resize-start"
|
|
@@ -3718,7 +3740,7 @@
|
|
|
3718
3740
|
></span>
|
|
3719
3741
|
{/if}
|
|
3720
3742
|
{#if scheduler.event}{@render scheduler.event(s.event.row)}{:else}<span class="sv-sched-bar-title">{s.event.title}</span>{/if}
|
|
3721
|
-
{#if canEditBar && !s.continuesRight}
|
|
3743
|
+
{#if canEditBar && resizable && !s.continuesRight}
|
|
3722
3744
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
3723
3745
|
<span
|
|
3724
3746
|
class="sv-sched-chip-resize sv-sched-chip-resize-end"
|
|
@@ -3825,7 +3847,7 @@
|
|
|
3825
3847
|
onmouseenter={(e) => onEventEnter(e, p.event)}
|
|
3826
3848
|
onmouseleave={onEventLeave}
|
|
3827
3849
|
>
|
|
3828
|
-
{#if canEdit}
|
|
3850
|
+
{#if canEdit && resizable}
|
|
3829
3851
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
3830
3852
|
<span
|
|
3831
3853
|
class="sv-sched-resize sv-sched-resize-top"
|
|
@@ -3834,7 +3856,7 @@
|
|
|
3834
3856
|
></span>
|
|
3835
3857
|
{/if}
|
|
3836
3858
|
{#if scheduler.event}{@render scheduler.event(p.event.row)}{:else}<span class="sv-sched-event-time">{fmtTime(isResize ? drag!.previewStart : p.event.start)}{isResize ? ` - ${fmtTime(drag!.previewEnd)}` : ""}</span><span class="sv-sched-event-title">{p.event.title}</span>{/if}
|
|
3837
|
-
{#if canEdit}
|
|
3859
|
+
{#if canEdit && resizable}
|
|
3838
3860
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
3839
3861
|
<span
|
|
3840
3862
|
class="sv-sched-resize sv-sched-resize-bottom"
|
|
@@ -45,6 +45,23 @@
|
|
|
45
45
|
const ICON = {
|
|
46
46
|
selectAll: 'M9 11l3 3L22 4M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11',
|
|
47
47
|
editFields: 'M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7M18.5 2.5a2.1 2.1 0 0 1 3 3L12 15l-4 1 1-4Z',
|
|
48
|
+
deleteRows: 'M3 6h18M8 6V4h8v2M19 6l-1 14H6L5 6M10 11v6M14 11v6',
|
|
49
|
+
}
|
|
50
|
+
// Delete asks first, on the bar itself: "Delete 3 rows?" Delete / Cancel.
|
|
51
|
+
let confirming = $state(false)
|
|
52
|
+
let confirmButton = $state<HTMLButtonElement | null>(null)
|
|
53
|
+
$effect(() => {
|
|
54
|
+
if (confirming) confirmButton?.focus()
|
|
55
|
+
})
|
|
56
|
+
function deleteSelected() {
|
|
57
|
+
const rows = target.rows
|
|
58
|
+
const ids = target.ids
|
|
59
|
+
const drop = new Set(rows)
|
|
60
|
+
const data = (ctrl.internalData as unknown[]).filter((r) => !drop.has(r))
|
|
61
|
+
confirming = false
|
|
62
|
+
clearSelection()
|
|
63
|
+
ctrl.internalData = data
|
|
64
|
+
ctrl.props?.onRowsDelete?.({ rows, ids, data })
|
|
48
65
|
}
|
|
49
66
|
|
|
50
67
|
/** Turn the built-in string keys into real actions. */
|
|
@@ -69,6 +86,16 @@
|
|
|
69
86
|
action: () => (bulkEditOpen = true),
|
|
70
87
|
}
|
|
71
88
|
}
|
|
89
|
+
if (entry === 'deleteRows') {
|
|
90
|
+
return {
|
|
91
|
+
key: 'deleteRows',
|
|
92
|
+
label: messages.selectionBarDelete,
|
|
93
|
+
icon: ICON.deleteRows,
|
|
94
|
+
// Rows a server row model never loaded cannot be deleted here.
|
|
95
|
+
hidden: () => !!ctrl.props?.rowModel,
|
|
96
|
+
action: () => (confirming = true),
|
|
97
|
+
}
|
|
98
|
+
}
|
|
72
99
|
return null
|
|
73
100
|
}
|
|
74
101
|
|
|
@@ -107,6 +134,11 @@
|
|
|
107
134
|
*/
|
|
108
135
|
function onKeydown(event: KeyboardEvent) {
|
|
109
136
|
if (event.key === 'Escape') {
|
|
137
|
+
if (confirming) {
|
|
138
|
+
confirming = false
|
|
139
|
+
event.stopPropagation()
|
|
140
|
+
return
|
|
141
|
+
}
|
|
110
142
|
if (overflowOpen) {
|
|
111
143
|
overflowOpen = false
|
|
112
144
|
event.stopPropagation()
|
|
@@ -154,6 +186,16 @@
|
|
|
154
186
|
<span class="sv-selbar-count-label">{messages.selectionBarCount}</span>
|
|
155
187
|
</span>
|
|
156
188
|
|
|
189
|
+
{#if confirming}
|
|
190
|
+
<span class="sv-selbar-sep" aria-hidden="true"></span>
|
|
191
|
+
<span class="sv-selbar-confirm" role="alert">{fill(messages.selectionBarDeleteConfirm, count)}</span>
|
|
192
|
+
<button type="button" class="sv-selbar-btn is-danger is-solid" bind:this={confirmButton} onclick={deleteSelected}>
|
|
193
|
+
<span>{messages.selectionBarDelete}</span>
|
|
194
|
+
</button>
|
|
195
|
+
<button type="button" class="sv-selbar-btn" onclick={() => (confirming = false)}>
|
|
196
|
+
<span>{messages.selectionBarCancel}</span>
|
|
197
|
+
</button>
|
|
198
|
+
{:else}
|
|
157
199
|
{#if inline.length}
|
|
158
200
|
<span class="sv-selbar-sep" aria-hidden="true"></span>
|
|
159
201
|
{/if}
|
|
@@ -222,6 +264,7 @@
|
|
|
222
264
|
{/if}
|
|
223
265
|
</div>
|
|
224
266
|
{/if}
|
|
267
|
+
{/if}
|
|
225
268
|
|
|
226
269
|
{#if !hideClear}
|
|
227
270
|
<span class="sv-selbar-sep" aria-hidden="true"></span>
|
|
@@ -366,6 +409,10 @@
|
|
|
366
409
|
.sv-selbar-btn.is-danger:hover:not(:disabled) {
|
|
367
410
|
background: color-mix(in srgb, var(--sg-danger, #dc2626) 12%, transparent 88%);
|
|
368
411
|
}
|
|
412
|
+
/* The confirm is the one red, solid button: the choice that cannot be undone. */
|
|
413
|
+
.sv-selbar-btn.is-solid { background: var(--sg-danger, #dc2626); color: #fff; }
|
|
414
|
+
.sv-selbar-btn.is-solid:hover:not(:disabled) { background: color-mix(in srgb, var(--sg-danger, #dc2626) 88%, #000 12%); }
|
|
415
|
+
.sv-selbar-confirm { flex: none; padding: 0 4px; font-weight: 600; white-space: nowrap; }
|
|
369
416
|
.sv-selbar-more-btn { padding: 5px 7px; flex: none; }
|
|
370
417
|
.sv-selbar-btn > span {
|
|
371
418
|
overflow: hidden;
|
|
@@ -3,16 +3,20 @@
|
|
|
3
3
|
* structural (a checkbox gutter, a row-number gutter) rather than data.
|
|
4
4
|
*/
|
|
5
5
|
const NON_DATA_IDS = new Set(['__select', '__selection', '__rowNumber', '__autoGroup', '__actions']);
|
|
6
|
-
/**
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
/**
|
|
7
|
+
* The coarse type the operator catalogue uses, from the column's data type
|
|
8
|
+
* (whatever edits it). A datetime editor keeps the time in the filter.
|
|
9
|
+
*/
|
|
10
|
+
function toExprType(col) {
|
|
11
|
+
if (col.editorType === 'datetime')
|
|
12
|
+
return 'datetime';
|
|
13
|
+
switch (col.cellDataType) {
|
|
9
14
|
case 'number':
|
|
10
15
|
return 'number';
|
|
11
16
|
case 'date':
|
|
17
|
+
case 'dateString':
|
|
12
18
|
return 'date';
|
|
13
|
-
case '
|
|
14
|
-
return 'datetime';
|
|
15
|
-
case 'checkbox':
|
|
19
|
+
case 'boolean':
|
|
16
20
|
return 'boolean';
|
|
17
21
|
default:
|
|
18
22
|
return 'text';
|
|
@@ -37,7 +41,7 @@ export function exprColumnsFromGrid(api, options = {}) {
|
|
|
37
41
|
// Fall back to the id so a column with no header is still addressable
|
|
38
42
|
// in the `[Bracketed Name]` reference syntax.
|
|
39
43
|
name: col.header || col.id,
|
|
40
|
-
type: toExprType(col
|
|
44
|
+
type: toExprType(col),
|
|
41
45
|
});
|
|
42
46
|
}
|
|
43
47
|
return out;
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/** Compiles an expression kind of another Enterprise module (the fields view bar's `fieldFilter`). */
|
|
2
|
+
export type FilterKindCompiler = (expr: any, ctx: {
|
|
3
|
+
getValue: (row: any, columnId: string) => unknown;
|
|
4
|
+
}) => ((row: any) => boolean) | null;
|
|
5
|
+
/** Teach the advanced filter an expression kind of its own (one per kind). */
|
|
6
|
+
export declare function registerFilterKind(kind: string, compile: FilterKindCompiler): void;
|
|
1
7
|
/**
|
|
2
8
|
* Enable the advanced filter. Call once (installEnterprise does it for you),
|
|
3
9
|
* after which `api.setAdvancedFilter(expr)` actually filters rows.
|
|
@@ -10,11 +10,19 @@ import { hasValidLicense } from './license.js';
|
|
|
10
10
|
import { emitUnlicensedNudge } from './watermark.js';
|
|
11
11
|
import { compilePredicate } from './expressions/compile.js';
|
|
12
12
|
let enabled = false;
|
|
13
|
+
const kinds = new Map();
|
|
14
|
+
/** Teach the advanced filter an expression kind of its own (one per kind). */
|
|
15
|
+
export function registerFilterKind(kind, compile) {
|
|
16
|
+
kinds.set(kind, compile);
|
|
17
|
+
}
|
|
13
18
|
const advancedFilterEngine = (expr, ctx) => {
|
|
14
19
|
// The grid treats null as "do not filter" and never surfaces a partially
|
|
15
20
|
// applied predicate, so swallowing here is safe and is the fail-open half of
|
|
16
21
|
// the contract documented on AdvancedFilterEngine.
|
|
17
22
|
try {
|
|
23
|
+
const own = kinds.get(expr.kind ?? '');
|
|
24
|
+
if (own)
|
|
25
|
+
return own(expr, ctx);
|
|
18
26
|
return compilePredicate(expr, ctx);
|
|
19
27
|
}
|
|
20
28
|
catch {
|
|
@@ -5,6 +5,12 @@ export type AlertEngineOptions<TData> = {
|
|
|
5
5
|
/** Resolve a column id to a value (defaults to `row[id]`). */
|
|
6
6
|
getValue?: (row: TData, columnId: string) => unknown;
|
|
7
7
|
locale?: string | ReadonlyArray<string>;
|
|
8
|
+
/**
|
|
9
|
+
* A message token the built-in ones do not cover, as text: SvGrid Base reads
|
|
10
|
+
* `{Due date}` as the field of that name, formatted as its cell shows it.
|
|
11
|
+
* Undefined leaves the token as it was.
|
|
12
|
+
*/
|
|
13
|
+
token?: (row: TData, name: string) => string | undefined;
|
|
8
14
|
/** Clock for `firedAt` (injectable for deterministic tests). */
|
|
9
15
|
now?: () => number;
|
|
10
16
|
};
|
|
@@ -44,5 +50,6 @@ export declare function renderTemplate(template: string, ctx: {
|
|
|
44
50
|
row?: Record<string, unknown>;
|
|
45
51
|
columnId?: string;
|
|
46
52
|
value?: unknown;
|
|
53
|
+
token?: (row: Record<string, unknown>, name: string) => string | undefined;
|
|
47
54
|
}): string;
|
|
48
55
|
export declare function createAlertEngine<TData = Record<string, unknown>>(options: AlertEngineOptions<TData>): AlertEngine<TData>;
|
|
@@ -9,14 +9,16 @@ import { collectColumnRefs } from '../expressions/parse.js';
|
|
|
9
9
|
const AGG_ROW_KEY = '*';
|
|
10
10
|
/** Fill message-template tokens from the firing context. */
|
|
11
11
|
export function renderTemplate(template, ctx) {
|
|
12
|
-
const { rule, row, columnId, value } = ctx;
|
|
13
|
-
|
|
12
|
+
const { rule, row, columnId, value, token } = ctx;
|
|
13
|
+
const out = template
|
|
14
14
|
.replace(/\{rule\}/g, rule.name)
|
|
15
15
|
.replace(/\{severity\}/g, rule.severity)
|
|
16
16
|
.replace(/\{column\}/g, columnId ?? '')
|
|
17
17
|
.replace(/\{value\}/g, value == null ? '' : String(value))
|
|
18
18
|
.replace(/\{row\.([\w$]+)\}/g, (_m, key) => fmt(row?.[key]))
|
|
19
19
|
.replace(/\{([\w$]+)\}/g, (m, key) => (row && key in row ? fmt(row[key]) : m));
|
|
20
|
+
// Names with spaces ("{Due date}") only mean something to a resolver.
|
|
21
|
+
return token && row ? out.replace(/\{([^{}\n]+)\}/g, (m, name) => token(row, name.trim()) ?? m) : out;
|
|
20
22
|
}
|
|
21
23
|
function fmt(v) {
|
|
22
24
|
return v == null ? '' : String(v);
|
|
@@ -55,6 +57,7 @@ export function createAlertEngine(options) {
|
|
|
55
57
|
row: opts.row,
|
|
56
58
|
columnId: opts.columnId,
|
|
57
59
|
value: opts.value,
|
|
60
|
+
token: options.token,
|
|
58
61
|
});
|
|
59
62
|
return {
|
|
60
63
|
ruleId: rule.id,
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The condition editor an alert rule shows, when a module brings its own.
|
|
3
|
+
*
|
|
4
|
+
* `SvAlertRuleEditor` edits a rule's predicate with the expression editor.
|
|
5
|
+
* SvGrid Base sets this context around its grid so a rule there is written
|
|
6
|
+
* with the view bar's filter ("Where Status is Done and Due date is before
|
|
7
|
+
* today"), stored as an `ext` node, and read with the field types' meaning.
|
|
8
|
+
*/
|
|
9
|
+
import { type Component } from 'svelte';
|
|
10
|
+
import type { PredicateExpr } from '../expressions/expression-types.js';
|
|
11
|
+
export type AlertConditionEditor = {
|
|
12
|
+
/** Draws a predicate and reports each change. */
|
|
13
|
+
component: Component<{
|
|
14
|
+
value: PredicateExpr;
|
|
15
|
+
onChange: (next: PredicateExpr) => void;
|
|
16
|
+
}>;
|
|
17
|
+
/** The predicate a new rule starts with. */
|
|
18
|
+
initial: () => PredicateExpr;
|
|
19
|
+
/** Whether it can show this predicate; one it cannot goes to the expression editor. */
|
|
20
|
+
accepts: (expr: PredicateExpr) => boolean;
|
|
21
|
+
/** The tokens a message can name, for the hint under the message box. */
|
|
22
|
+
tokens?: () => string[];
|
|
23
|
+
};
|
|
24
|
+
/** Call during a component's init: rules authored under it use this editor. */
|
|
25
|
+
export declare function setAlertConditionEditor(editor: AlertConditionEditor): void;
|
|
26
|
+
export declare function getAlertConditionEditor(): AlertConditionEditor | undefined;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The condition editor an alert rule shows, when a module brings its own.
|
|
3
|
+
*
|
|
4
|
+
* `SvAlertRuleEditor` edits a rule's predicate with the expression editor.
|
|
5
|
+
* SvGrid Base sets this context around its grid so a rule there is written
|
|
6
|
+
* with the view bar's filter ("Where Status is Done and Due date is before
|
|
7
|
+
* today"), stored as an `ext` node, and read with the field types' meaning.
|
|
8
|
+
*/
|
|
9
|
+
import { getContext, setContext } from 'svelte';
|
|
10
|
+
const KEY = Symbol('sv-alert-condition-editor');
|
|
11
|
+
/** Call during a component's init: rules authored under it use this editor. */
|
|
12
|
+
export function setAlertConditionEditor(editor) {
|
|
13
|
+
setContext(KEY, editor);
|
|
14
|
+
}
|
|
15
|
+
export function getAlertConditionEditor() {
|
|
16
|
+
return getContext(KEY);
|
|
17
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @svgrid/enterprise/base - SvGrid Base: a table database in the browser, the
|
|
3
|
+
* way a team runs a project tracker, a CRM or a content calendar. Fields of
|
|
4
|
+
* many types, saved views (grid, Kanban, calendar, gallery, form), filters,
|
|
5
|
+
* groups, colors, linked records and expanded records with comments.
|
|
6
|
+
*
|
|
7
|
+
* ```svelte
|
|
8
|
+
* <script lang="ts">
|
|
9
|
+
* import { SvBase, enableBase } from '@svgrid/enterprise/base'
|
|
10
|
+
* enableBase()
|
|
11
|
+
* </script>
|
|
12
|
+
*
|
|
13
|
+
* <SvBase {data} {columns} primaryField="name" bind:views editable />
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* A Suite product. It is the fields module (`@svgrid/enterprise/fields`) with
|
|
17
|
+
* the product's own entry: everything that module exports is here too.
|
|
18
|
+
*/
|
|
19
|
+
export * from '../fields/index.js';
|
|
20
|
+
export { enableFields as enableBase } from '../fields/index.js';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @svgrid/enterprise/base - SvGrid Base: a table database in the browser, the
|
|
3
|
+
* way a team runs a project tracker, a CRM or a content calendar. Fields of
|
|
4
|
+
* many types, saved views (grid, Kanban, calendar, gallery, form), filters,
|
|
5
|
+
* groups, colors, linked records and expanded records with comments.
|
|
6
|
+
*
|
|
7
|
+
* ```svelte
|
|
8
|
+
* <script lang="ts">
|
|
9
|
+
* import { SvBase, enableBase } from '@svgrid/enterprise/base'
|
|
10
|
+
* enableBase()
|
|
11
|
+
* </script>
|
|
12
|
+
*
|
|
13
|
+
* <SvBase {data} {columns} primaryField="name" bind:views editable />
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* A Suite product. It is the fields module (`@svgrid/enterprise/fields`) with
|
|
17
|
+
* the product's own entry: everything that module exports is here too.
|
|
18
|
+
*/
|
|
19
|
+
export * from '../fields/index.js';
|
|
20
|
+
export { enableFields as enableBase } from '../fields/index.js';
|
package/dist/bulk-edit.d.ts
CHANGED
|
@@ -19,6 +19,17 @@ export type BulkEditField = {
|
|
|
19
19
|
value: unknown;
|
|
20
20
|
label: string;
|
|
21
21
|
}>;
|
|
22
|
+
/** A field column's type (`@svgrid/enterprise/fields`), for its form control. */
|
|
23
|
+
fieldType?: string;
|
|
24
|
+
/** The column holds several values (a multiple select, several people). */
|
|
25
|
+
multiple?: boolean;
|
|
26
|
+
/** A rating's maximum. */
|
|
27
|
+
max?: number;
|
|
28
|
+
/**
|
|
29
|
+
* The column's own reading of a typed value (its `valueParser`): "$1,200"
|
|
30
|
+
* to 1200 for an amount, "42" to 0.42 for a percent of fractions.
|
|
31
|
+
*/
|
|
32
|
+
parse?: (raw: unknown) => unknown;
|
|
22
33
|
};
|
|
23
34
|
/**
|
|
24
35
|
* The columns a bulk edit can target.
|
package/dist/bulk-edit.js
CHANGED
|
@@ -33,7 +33,24 @@ export function bulkEditableFields(ctx) {
|
|
|
33
33
|
? { value: o.value, label: String(o.label ?? o.value) }
|
|
34
34
|
: { value: o, label: String(o) })
|
|
35
35
|
: undefined;
|
|
36
|
-
|
|
36
|
+
// A file list or a link to other records is not one value to set on
|
|
37
|
+
// every row from a form field.
|
|
38
|
+
if (def.editorType === 'attachment' || def.editorType === 'fieldLink')
|
|
39
|
+
continue;
|
|
40
|
+
const parser = typeof def.valueParser === 'function' ? def.valueParser : null;
|
|
41
|
+
out.push({
|
|
42
|
+
id: column.id,
|
|
43
|
+
field: String(def.field),
|
|
44
|
+
label,
|
|
45
|
+
editorType: String(def.editorType ?? 'text'),
|
|
46
|
+
options,
|
|
47
|
+
...(def.fieldType ? { fieldType: String(def.fieldType) } : {}),
|
|
48
|
+
...(def.editorMultiple ? { multiple: true } : {}),
|
|
49
|
+
...(def.fieldType === 'rating' ? { max: Number(def.fieldProps?.max) || 5 } : {}),
|
|
50
|
+
...(parser
|
|
51
|
+
? { parse: (raw) => parser({ newValue: raw, rawInput: typeof raw === 'string' ? raw : undefined, oldValue: undefined }) }
|
|
52
|
+
: {}),
|
|
53
|
+
});
|
|
37
54
|
}
|
|
38
55
|
return out;
|
|
39
56
|
}
|