@svgrid/enterprise 3.0.2 → 3.0.3
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 +94 -24
- package/README.md +36 -4
- package/dist/SvAdvancedFilter.svelte +1 -1
- package/dist/SvAlertsManager.svelte +2 -1
- package/dist/SvBoard.svelte +2 -1
- package/dist/SvExportMenu.svelte +4 -1
- package/dist/SvExportMenu.svelte.d.ts +0 -13
- package/dist/SvExpressionEditor.svelte +3 -3
- package/dist/SvFormulaBar.svelte +94 -20
- package/dist/SvFormulaBar.svelte.d.ts +7 -0
- package/dist/SvGridAlerts.svelte +49 -9
- package/dist/SvGridBoard.svelte +13 -8
- package/dist/SvGridBulkEditDrawer.svelte +26 -2
- package/dist/SvGridEditPanel.svelte +3 -0
- package/dist/SvGridScheduler.svelte +69 -40
- package/dist/SvGridSelectionBar.svelte +10 -3
- package/dist/SvPivotDesigner.svelte +198 -40
- package/dist/SvPivotDesigner.svelte.d.ts +27 -20
- package/dist/SvSheet.svelte +4043 -243
- package/dist/SvSheet.svelte.d.ts +76 -3
- package/dist/SvSheetChartSetup.svelte +151 -0
- package/dist/SvSheetChartSetup.svelte.d.ts +18 -0
- package/dist/SvSheetComment.svelte +216 -31
- package/dist/SvSheetComment.svelte.d.ts +11 -11
- package/dist/SvSheetConditionalFormat.svelte +28 -31
- package/dist/SvSheetDataValidation.svelte +66 -42
- package/dist/SvSheetEditRanges.svelte +217 -0
- package/dist/SvSheetEditRanges.svelte.d.ts +15 -0
- package/dist/SvSheetErrors.svelte +125 -0
- package/dist/SvSheetErrors.svelte.d.ts +20 -0
- package/dist/SvSheetEvaluate.svelte +133 -0
- package/dist/SvSheetEvaluate.svelte.d.ts +15 -0
- package/dist/SvSheetFilterMenu.svelte +137 -34
- package/dist/SvSheetFilterMenu.svelte.d.ts +5 -0
- package/dist/SvSheetFindReplace.svelte +19 -19
- package/dist/SvSheetFormatCells.svelte +125 -81
- package/dist/SvSheetGoalSeek.svelte +17 -16
- package/dist/SvSheetInsertFunction.svelte +15 -13
- package/dist/SvSheetIteration.svelte +81 -0
- package/dist/SvSheetIteration.svelte.d.ts +10 -0
- package/dist/SvSheetLink.svelte +99 -0
- package/dist/SvSheetLink.svelte.d.ts +17 -0
- package/dist/SvSheetListPicker.svelte +4 -2
- package/dist/SvSheetListPicker.svelte.d.ts +0 -6
- package/dist/SvSheetManageRules.svelte +20 -18
- package/dist/SvSheetNameManager.svelte +17 -15
- package/dist/SvSheetPageSetup.svelte +159 -0
- package/dist/SvSheetPageSetup.svelte.d.ts +13 -0
- package/dist/SvSheetPasteSpecial.svelte +22 -20
- package/dist/SvSheetPivot.svelte +220 -0
- package/dist/SvSheetPivot.svelte.d.ts +21 -0
- package/dist/SvSheetProtectSheet.svelte +81 -0
- package/dist/SvSheetProtectSheet.svelte.d.ts +11 -0
- package/dist/SvSheetRemoveDuplicates.svelte +13 -10
- package/dist/SvSheetRibbon.svelte +104 -51
- package/dist/SvSheetSizeDialog.svelte +4 -2
- package/dist/SvSheetSort.svelte +218 -0
- package/dist/SvSheetSort.svelte.d.ts +28 -0
- package/dist/SvSheetSparklines.svelte +135 -0
- package/dist/SvSheetSparklines.svelte.d.ts +14 -0
- package/dist/SvSheetTable.svelte +160 -0
- package/dist/SvSheetTable.svelte.d.ts +24 -0
- package/dist/SvSheetTabs.svelte +161 -31
- package/dist/SvSheetTabs.svelte.d.ts +22 -8
- package/dist/SvSheetTextToColumns.svelte +20 -20
- package/dist/SvSheetValidationAlert.svelte +8 -6
- package/dist/advanced-filter-enable.js +1 -1
- package/dist/alerts/alert-engine.d.ts +6 -0
- package/dist/alerts/alert-engine.js +21 -4
- package/dist/alerts/alert-formats.js +2 -0
- package/dist/alerts/alert-types.d.ts +1 -1
- package/dist/alerts.d.ts +1 -1
- package/dist/alerts.js +2 -2
- package/dist/board.js +2 -2
- package/dist/bulk-edit.d.ts +3 -1
- package/dist/bulk-edit.js +1 -1
- package/dist/cdn/svgrid-enterprise.svelte-external.js +39827 -16429
- package/dist/designer/assets/GridMenus-8gTNssgV.js +8 -0
- package/dist/designer/assets/{SvChartMenu-D9hEeHar.js → SvChartMenu-BDoeqGz6.js} +1 -1
- package/dist/designer/assets/{SvDateTimePicker-DARvKUL2.js → SvDateTimePicker-DCPg7WGN.js} +1 -1
- package/dist/designer/assets/SvGridCellEditor-DMoWJjEI.js +4 -0
- package/dist/designer/assets/{SvGridChart-B8j1SSy3.js → SvGridChart-Cy1ATrWh.js} +2 -2
- package/dist/designer/assets/SvGridChartBuilder-eQ3mn0L9.js +1 -0
- package/dist/designer/assets/{SvGridChartPanel-pT6ITc2P.js → SvGridChartPanel-CATdVc9X.js} +3 -3
- package/dist/designer/assets/{SvGridChartView-bg281UA1.js → SvGridChartView-CmsZtCED.js} +1 -1
- package/dist/designer/assets/SvGridDropdown-Cjz0H-fI.js +1 -0
- package/dist/designer/assets/{SvTabs-UFCMTHXS.js → SvTabs-2mHC6oaz.js} +1 -1
- package/dist/designer/assets/cell-formatting-BbubJTVz.js +1 -0
- package/dist/designer/assets/{chart-cIPUsbM5.js → chart-Cn7MnNqA.js} +1 -1
- package/dist/designer/assets/{chart-panel-messages-DtTxpBUU.js → chart-panel-messages-Dz7PTIqT.js} +1 -1
- package/dist/designer/assets/{chart-summary-Czu_5epb.js → chart-summary-BD1qYB2R.js} +1 -1
- package/dist/designer/assets/{chart-trend-D5I5VEe8.js → chart-trend-B8xr5LuD.js} +1 -1
- package/dist/designer/assets/{dismissable-BO547MH9.js → dismissable-ChWRPkoa.js} +1 -1
- package/dist/designer/assets/{export-format-D-eP4b2l.js → export-format-DGckmgKr.js} +1 -1
- package/dist/designer/assets/{focus-trap-CAreAhlU.js → focus-trap-V2-6Fy9I.js} +1 -1
- package/dist/designer/assets/{index-DwU7CAMm.js → index-D5bVbuzI.js} +317 -315
- package/dist/designer/assets/index-_JVFxt02.css +1 -0
- package/dist/designer/assets/row-resize-BInFWCpr.js +1 -0
- package/dist/designer/assets/server-block-cache-CXJKkJpy.js +1 -0
- package/dist/designer/assets/src-DUQ4xE3x.js +58 -0
- package/dist/designer/assets/validate-C3B8QKsM.js +1 -0
- package/dist/designer/index.html +17 -16
- package/dist/export-pdf.d.ts +75 -0
- package/dist/export-pdf.js +216 -15
- package/dist/export.js +10 -2
- package/dist/gantt/SvGridGantt.svelte +2890 -0
- package/dist/gantt/SvGridGantt.svelte.d.ts +30 -0
- package/dist/gantt/gantt-config.d.ts +73 -0
- package/dist/gantt/gantt-config.js +1 -0
- package/dist/gantt/gantt-critical-path.d.ts +67 -0
- package/dist/gantt/gantt-critical-path.js +207 -0
- package/dist/gantt/gantt-model.d.ts +257 -0
- package/dist/gantt/gantt-model.js +651 -0
- package/dist/gantt/gantt-resources.d.ts +59 -0
- package/dist/gantt/gantt-resources.js +71 -0
- package/dist/gantt/gantt.d.ts +7 -0
- package/dist/gantt/gantt.js +36 -0
- package/dist/gantt/index.d.ts +15 -0
- package/dist/gantt/index.js +22 -0
- package/dist/gantt/timeline-arrows.d.ts +102 -0
- package/dist/gantt/timeline-arrows.js +181 -0
- package/dist/import.d.ts +2 -2
- package/dist/import.js +1 -1
- package/dist/index.d.ts +34 -7
- package/dist/index.js +44 -7
- package/dist/install.js +8 -1
- package/dist/license-core.d.ts +17 -1
- package/dist/license-core.js +16 -5
- package/dist/license.d.ts +18 -2
- package/dist/license.js +71 -6
- package/dist/node/studio.js +140 -8
- package/dist/pivot-enable.js +2 -2
- package/dist/scheduler-dependencies.d.ts +35 -0
- package/dist/scheduler-dependencies.js +36 -1
- package/dist/scheduler.js +2 -2
- package/dist/selection-bar.js +2 -2
- package/dist/server/SvGroupCell.svelte +213 -0
- package/dist/server/SvGroupCell.svelte.d.ts +62 -0
- package/dist/server/SvRowGroupPanel.svelte +322 -0
- package/dist/server/SvRowGroupPanel.svelte.d.ts +37 -0
- package/dist/server/enable.d.ts +17 -0
- package/dist/server/enable.js +49 -0
- package/dist/server/index.d.ts +22 -0
- package/dist/server/index.js +24 -0
- package/dist/server/messages.d.ts +45 -0
- package/dist/server/messages.js +35 -0
- package/dist/server/server-group-model.d.ts +104 -0
- package/dist/server/server-group-model.js +272 -0
- package/dist/server/server-pivot.d.ts +46 -0
- package/dist/server/server-pivot.js +57 -0
- package/dist/server/server-row-model.d.ts +547 -0
- package/dist/server/server-row-model.js +1551 -0
- package/dist/server/server-selection.d.ts +99 -0
- package/dist/server/server-selection.js +215 -0
- package/dist/server/svgrid-adapter.d.ts +155 -0
- package/dist/server/svgrid-adapter.js +202 -0
- package/dist/sheet/ast.d.ts +45 -1
- package/dist/sheet/ast.js +14 -0
- package/dist/sheet/auto-filter.d.ts +58 -4
- package/dist/sheet/auto-filter.js +159 -11
- package/dist/sheet/autocomplete.d.ts +9 -0
- package/dist/sheet/autocomplete.js +90 -4
- package/dist/sheet/cell-images.d.ts +39 -0
- package/dist/sheet/cell-images.js +90 -0
- package/dist/sheet/cell-types.d.ts +58 -0
- package/dist/sheet/cell-types.js +96 -0
- package/dist/sheet/coerce.d.ts +40 -0
- package/dist/sheet/coerce.js +170 -3
- package/dist/sheet/comments.d.ts +43 -9
- package/dist/sheet/comments.js +85 -27
- package/dist/sheet/conditional-formats.d.ts +29 -6
- package/dist/sheet/conditional-formats.js +37 -12
- package/dist/sheet/csv.d.ts +32 -0
- package/dist/sheet/csv.js +158 -0
- package/dist/sheet/culture.d.ts +87 -0
- package/dist/sheet/culture.js +247 -0
- package/dist/sheet/delta.d.ts +102 -0
- package/dist/sheet/delta.js +203 -0
- package/dist/sheet/deps.d.ts +45 -1
- package/dist/sheet/deps.js +77 -2
- package/dist/sheet/document.d.ts +106 -4
- package/dist/sheet/document.js +204 -3
- package/dist/sheet/engine.d.ts +67 -0
- package/dist/sheet/engine.js +19 -0
- package/dist/sheet/entry.d.ts +8 -4
- package/dist/sheet/entry.js +171 -21
- package/dist/sheet/error-check.d.ts +49 -0
- package/dist/sheet/error-check.js +83 -0
- package/dist/sheet/evaluate-steps.d.ts +48 -0
- package/dist/sheet/evaluate-steps.js +196 -0
- package/dist/sheet/evaluate.d.ts +67 -0
- package/dist/sheet/evaluate.js +725 -13
- package/dist/sheet/filter-files.d.ts +37 -0
- package/dist/sheet/filter-files.js +465 -0
- package/dist/sheet/format-store.d.ts +15 -0
- package/dist/sheet/format-store.js +11 -1
- package/dist/sheet/from-rows.d.ts +14 -0
- package/dist/sheet/from-rows.js +50 -0
- package/dist/sheet/function-catalog.d.ts +1 -1
- package/dist/sheet/function-catalog.js +296 -5
- package/dist/sheet/functions.js +363 -91
- package/dist/sheet/index.d.ts +35 -8
- package/dist/sheet/index.js +35 -8
- package/dist/sheet/links.d.ts +57 -0
- package/dist/sheet/links.js +174 -0
- package/dist/sheet/messages.d.ts +778 -0
- package/dist/sheet/messages.js +806 -0
- package/dist/sheet/number-format.d.ts +52 -5
- package/dist/sheet/number-format.js +465 -68
- package/dist/sheet/objects.d.ts +106 -0
- package/dist/sheet/objects.js +149 -0
- package/dist/sheet/ods-document.d.ts +44 -0
- package/dist/sheet/ods-document.js +1275 -0
- package/dist/sheet/open-file.d.ts +26 -0
- package/dist/sheet/open-file.js +56 -0
- package/dist/sheet/outline.d.ts +82 -0
- package/dist/sheet/outline.js +228 -0
- package/dist/sheet/packs/array.d.ts +16 -0
- package/dist/sheet/packs/array.js +172 -0
- package/dist/sheet/packs/database.d.ts +42 -0
- package/dist/sheet/packs/database.js +142 -0
- package/dist/sheet/packs/engineering.d.ts +2 -0
- package/dist/sheet/packs/engineering.js +296 -0
- package/dist/sheet/packs/financial.d.ts +5 -0
- package/dist/sheet/packs/financial.js +220 -0
- package/dist/sheet/packs/math-stats.d.ts +2 -0
- package/dist/sheet/packs/math-stats.js +372 -0
- package/dist/sheet/packs/special.d.ts +44 -0
- package/dist/sheet/packs/special.js +187 -0
- package/dist/sheet/packs/stats-dist.d.ts +2 -0
- package/dist/sheet/packs/stats-dist.js +785 -0
- package/dist/sheet/packs/text-date.d.ts +2 -0
- package/dist/sheet/packs/text-date.js +332 -0
- package/dist/sheet/packs/trig.d.ts +2 -0
- package/dist/sheet/packs/trig.js +73 -0
- package/dist/sheet/page-setup.d.ts +73 -0
- package/dist/sheet/page-setup.js +73 -0
- package/dist/sheet/parse.js +42 -10
- package/dist/sheet/paste-special.d.ts +22 -0
- package/dist/sheet/paste-special.js +14 -5
- package/dist/sheet/pivot-range.d.ts +160 -0
- package/dist/sheet/pivot-range.js +333 -0
- package/dist/sheet/presence.d.ts +73 -0
- package/dist/sheet/presence.js +79 -0
- package/dist/sheet/print.d.ts +104 -0
- package/dist/sheet/print.js +169 -0
- package/dist/sheet/protection.d.ts +55 -1
- package/dist/sheet/protection.js +55 -2
- package/dist/sheet/rects.d.ts +1 -1
- package/dist/sheet/refs.d.ts +48 -0
- package/dist/sheet/refs.js +155 -8
- package/dist/sheet/ribbon-icons.d.ts +1 -1
- package/dist/sheet/ribbon-icons.js +186 -0
- package/dist/sheet/ribbon.d.ts +1 -1
- package/dist/sheet/ribbon.js +324 -23
- package/dist/sheet/sheet-kinds.d.ts +74 -0
- package/dist/sheet/sheet-kinds.js +91 -0
- package/dist/sheet/shortcuts.d.ts +13 -3
- package/dist/sheet/shortcuts.js +63 -12
- package/dist/sheet/sort.d.ts +51 -0
- package/dist/sheet/sort.js +107 -0
- package/dist/sheet/sparklines.d.ts +111 -0
- package/dist/sheet/sparklines.js +204 -0
- package/dist/sheet/table-styles.d.ts +74 -0
- package/dist/sheet/table-styles.js +152 -0
- package/dist/sheet/tables.d.ts +19 -0
- package/dist/sheet/tables.js +31 -0
- package/dist/sheet/tokenize.d.ts +18 -1
- package/dist/sheet/tokenize.js +60 -9
- package/dist/sheet/validation.d.ts +16 -0
- package/dist/sheet/validation.js +37 -0
- package/dist/sheet/workbook.d.ts +148 -3
- package/dist/sheet/workbook.js +742 -31
- package/dist/sheet/xls-cfb.d.ts +32 -0
- package/dist/sheet/xls-cfb.js +290 -0
- package/dist/sheet/xls-document.d.ts +10 -0
- package/dist/sheet/xls-document.js +1243 -0
- package/dist/sheet/xls-formula.d.ts +40 -0
- package/dist/sheet/xls-formula.js +569 -0
- package/dist/sheet/xlsx-document.d.ts +108 -0
- package/dist/sheet/xlsx-document.js +1849 -0
- package/dist/sheet/xlsx-drawing.d.ts +99 -0
- package/dist/sheet/xlsx-drawing.js +420 -0
- package/dist/sheet-enable.js +6 -7
- package/dist/sheet-text.d.ts +7 -0
- package/dist/sheet-text.js +29 -0
- package/dist/sources/auth-supabase.js +2 -2
- package/dist/sources/realtime-supabase.js +2 -2
- package/dist/sources/rest.d.ts +6 -2
- package/dist/sources/rest.js +42 -7
- package/dist/sources/supabase.d.ts +10 -1
- package/dist/sources/supabase.js +73 -40
- package/dist/studio/emit-project.js +14 -1
- package/dist/studio/index.js +1 -1
- package/dist/studio/project.d.ts +11 -2
- package/dist/studio/project.js +5 -2
- package/dist/studio/ui-components.generated.js +107 -2
- package/dist/sveltekit/in-memory.d.ts +2 -2
- package/dist/sveltekit/in-memory.js +125 -4
- package/dist/sveltekit/index.d.ts +1 -1
- package/dist/sveltekit/index.js +1 -1
- package/dist/sveltekit/query-plan.d.ts +50 -4
- package/dist/sveltekit/query-plan.js +25 -3
- package/dist/sveltekit/sql-source.d.ts +6 -0
- package/dist/sveltekit/sql-source.js +34 -6
- package/dist/sveltekit/sql.d.ts +31 -0
- package/dist/sveltekit/sql.js +135 -25
- package/dist/sveltekit/transport.d.ts +10 -2
- package/dist/sveltekit/transport.js +30 -6
- package/dist/upgrade-prompt.d.ts +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/watermark.js +35 -2
- package/dist/wc/GridMenus-By9vPuq0.js +1088 -0
- package/dist/wc/SvChartMenu-CQNrQGT2.js +308 -0
- package/dist/wc/SvDateRangeInput-DR6m7bSM.js +199 -0
- package/dist/wc/SvDateTimePicker-D-vRnaMo.js +771 -0
- package/dist/wc/SvField-B_kurx_P.js +149 -0
- package/dist/wc/SvGrid.helpers-BdVDtjUm.js +135 -0
- package/dist/wc/SvGridCellEditor-Bnf1Kr5C.js +560 -0
- package/dist/wc/SvGridChart-BqUJh2pG.js +3572 -0
- package/dist/wc/SvGridChartBuilder-CGycC5cn.js +988 -0
- package/dist/wc/SvGridChartPanel-CRnizsHD.js +1746 -0
- package/dist/wc/SvGridChartView-D1pa_xMy.js +47 -0
- package/dist/wc/SvGridDropdown-45WsObLL.js +259 -0
- package/dist/wc/SvModal-DrfOYYyX.js +189 -0
- package/dist/wc/cell-formatting-CBfgahv1.js +86 -0
- package/dist/wc/chart-6OXlybVT.js +4341 -0
- package/dist/wc/chart-export-CeSADGfi.js +135 -0
- package/dist/wc/chart-export-pdf-BGko7MER.js +104 -0
- package/dist/wc/chart-summary-2m3ia1-n.js +137 -0
- package/dist/wc/chart-trend-CQOQtTMl.js +50 -0
- package/dist/wc/chart-validate-CD6ptiwg.js +180 -0
- package/dist/wc/client-DQIzjDBG.js +3064 -0
- package/dist/wc/column-resize-DUPgynvc.js +101 -0
- package/dist/wc/date-format-DS-z_h9v.js +1130 -0
- package/dist/wc/dismissable-CQ6XFXsk.js +45 -0
- package/dist/wc/editor-contract-peBDxir_.js +22 -0
- package/dist/wc/editor-registry-DxGKqcvx.js +24 -0
- package/dist/wc/focus-trap-Dbb2tJxb.js +65 -0
- package/dist/wc/list-option-DrRyivWp.js +82 -0
- package/dist/wc/popover-WsGlvtQv.js +69 -0
- package/dist/wc/positioning-BiKLfu1E.js +112 -0
- package/dist/wc/react.d.ts +41 -0
- package/dist/wc/react.js +90 -0
- package/dist/wc/rolldown-runtime-Dy4uBu1J.js +11 -0
- package/dist/wc/row-drag-touch-CycRR65n.js +93 -0
- package/dist/wc/row-resize-limG_N1z.js +111 -0
- package/dist/wc/sv-sheet-element.d.ts +97 -0
- package/dist/wc/sv-sheet-element.js +44213 -0
- package/dist/wc/svelte-virtualizer.svelte-CXtQy2TQ.js +530 -0
- package/dist/wc/validate-BqDthkNr.js +88 -0
- package/dist/wc/vue.d.ts +31 -0
- package/dist/wc/vue.js +75 -0
- package/package.json +30 -5
- package/dist/designer/assets/GridMenus-BlsvL_aU.js +0 -8
- package/dist/designer/assets/SvGridCellEditor-C7uQXYds.js +0 -4
- package/dist/designer/assets/SvGridChartBuilder-kvyIU_Rl.js +0 -1
- package/dist/designer/assets/SvGridDropdown-Bb3HH2Aj.js +0 -1
- package/dist/designer/assets/cell-formatting-wr5wm7US.js +0 -1
- package/dist/designer/assets/index-CMFgAoVV.css +0 -1
- package/dist/designer/assets/row-resize-DLktcqUK.js +0 -1
- package/dist/designer/assets/src-EdI3Xqds.js +0 -58
- package/dist/designer/assets/validate-h-aslRV9.js +0 -1
package/dist/SvGridAlerts.svelte
CHANGED
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
import { applyAlertEvents, type FlashTarget } from './alerts/alert-engine-attach'
|
|
25
25
|
import { rulesToConditionalFormats } from './alerts/alert-formats'
|
|
26
26
|
import { alertStore } from './alerts/alert-store.svelte'
|
|
27
|
+
import { createScheduler, type Schedule } from './scheduling'
|
|
27
28
|
import {
|
|
28
29
|
createAlertRules,
|
|
29
30
|
localStorageAlertRules,
|
|
@@ -100,19 +101,37 @@
|
|
|
100
101
|
onJump,
|
|
101
102
|
}: Props = $props()
|
|
102
103
|
|
|
103
|
-
|
|
104
|
-
|
|
104
|
+
// The store is chosen and seeded once, from the props' first values: a
|
|
105
|
+
// storage key does not move at runtime and the seed is only for an empty
|
|
106
|
+
// store.
|
|
107
|
+
const manager: AlertRulesManager = untrack(() =>
|
|
108
|
+
createAlertRules(storageKey ? localStorageAlertRules(storageKey) : memoryAlertRules()),
|
|
105
109
|
)
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
+
untrack(() => {
|
|
111
|
+
if (initialRules.length && manager.list().length === 0) {
|
|
112
|
+
for (const r of initialRules) manager.save(r)
|
|
113
|
+
}
|
|
114
|
+
})
|
|
110
115
|
|
|
111
116
|
let rules = $state<AlertRule[]>(manager.list())
|
|
112
117
|
let rulesVersion = $state(0)
|
|
113
|
-
|
|
118
|
+
// Raw on purpose: a flash is removed by identity 900 ms later, and a deep
|
|
119
|
+
// proxy never equals the object that was pushed, so the flashes never went.
|
|
120
|
+
let flashFormats = $state.raw<ConditionalFormat<TRow>[]>([])
|
|
114
121
|
|
|
115
|
-
|
|
122
|
+
// The engine and the observer are built once; `getRowId`, `getValue` and
|
|
123
|
+
// `locale` are props that may change after mount, so they go in as
|
|
124
|
+
// closures and getters that read the current value rather than a copy of
|
|
125
|
+
// the first one.
|
|
126
|
+
const rowIdOf = (row: TRow) => getRowId(row)
|
|
127
|
+
const engine = createAlertEngine<TRow>({
|
|
128
|
+
// The first list; later lists reach the observer through the
|
|
129
|
+
// rulesVersion effect below.
|
|
130
|
+
rules: untrack(() => rules),
|
|
131
|
+
getRowId: rowIdOf,
|
|
132
|
+
get getValue() { return getValue },
|
|
133
|
+
get locale() { return locale },
|
|
134
|
+
})
|
|
116
135
|
|
|
117
136
|
// The observer owns all scheduling + change tracking. It runs evaluation on a
|
|
118
137
|
// post-paint frame (never inside the grid's render flush) and only clones prev
|
|
@@ -132,7 +151,7 @@
|
|
|
132
151
|
|
|
133
152
|
const observer = createAlertObserver<TRow>({
|
|
134
153
|
engine,
|
|
135
|
-
getRowId,
|
|
154
|
+
getRowId: rowIdOf,
|
|
136
155
|
schedule: 'raf',
|
|
137
156
|
onEvents: (events) => {
|
|
138
157
|
const { flashes } = applyAlertEvents(events, getRowId, { shouldToast: allowToast })
|
|
@@ -142,6 +161,27 @@
|
|
|
142
161
|
|
|
143
162
|
let seededVersion = -1
|
|
144
163
|
|
|
164
|
+
// A `scheduled` rule is re-checked on its cron by the enterprise scheduler
|
|
165
|
+
// rather than on a data change: on each fire the pass lists every row the
|
|
166
|
+
// predicate matches at that moment, whether or not anything moved. The
|
|
167
|
+
// scheduler is rebuilt when the rules change, and stopped with the overlay.
|
|
168
|
+
$effect(() => {
|
|
169
|
+
void rulesVersion
|
|
170
|
+
const scheduled = rules.filter((r): r is AlertRule & { trigger: { type: 'scheduled'; schedule: Schedule } } => r.enabled && r.trigger.type === 'scheduled')
|
|
171
|
+
if (scheduled.length === 0) return
|
|
172
|
+
const scheduler = createScheduler({
|
|
173
|
+
schedules: scheduled.map((r) => ({ ...r.trigger.schedule, id: r.id })),
|
|
174
|
+
onFire: (schedule) => {
|
|
175
|
+
const events = engine.evaluateScheduled(schedule.id, untrack(() => data))
|
|
176
|
+
if (events.length === 0) return
|
|
177
|
+
const { flashes } = applyAlertEvents(events, getRowId, { shouldToast: allowToast })
|
|
178
|
+
for (const f of flashes) addFlash(f)
|
|
179
|
+
},
|
|
180
|
+
})
|
|
181
|
+
scheduler.start()
|
|
182
|
+
return () => scheduler.stop()
|
|
183
|
+
})
|
|
184
|
+
|
|
145
185
|
function addFlash(target: FlashTarget) {
|
|
146
186
|
const fmt: ConditionalFormat<TRow> = {
|
|
147
187
|
type: 'rule',
|
package/dist/SvGridBoard.svelte
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
// as a per-row overlay keyed by row id, so consumers write no move code;
|
|
13
13
|
// `onCardMove` fires purely as a notification for persistence / mirroring
|
|
14
14
|
// Themes entirely from the grid's `--sg-*` tokens.
|
|
15
|
-
import { tick } from "svelte";
|
|
15
|
+
import { tick, untrack } from "svelte";
|
|
16
16
|
import type {
|
|
17
17
|
ColumnDef,
|
|
18
18
|
RowData,
|
|
@@ -165,10 +165,11 @@
|
|
|
165
165
|
collapsedSwim: { ...collapsedSwim },
|
|
166
166
|
};
|
|
167
167
|
}
|
|
168
|
-
// Restore once at init (before first paint).
|
|
169
|
-
|
|
168
|
+
// Restore once at init (before first paint), from the first persistKey.
|
|
169
|
+
const persistKey = untrack(() => (getRowId ? board.persistKey : undefined));
|
|
170
|
+
if (persistKey && typeof localStorage !== "undefined") {
|
|
170
171
|
try {
|
|
171
|
-
const raw = localStorage.getItem(
|
|
172
|
+
const raw = localStorage.getItem(persistKey);
|
|
172
173
|
if (raw) {
|
|
173
174
|
const s = JSON.parse(raw);
|
|
174
175
|
laneOf = s.laneOf ?? {};
|
|
@@ -1264,6 +1265,8 @@
|
|
|
1264
1265
|
style={lane.color ? `--sv-board-accent: ${lane.color};` : undefined}
|
|
1265
1266
|
aria-label={laneTitle(lane)}
|
|
1266
1267
|
>
|
|
1268
|
+
<!-- A reorderable lane header is a keyboard handle (Ctrl+arrows move the lane). -->
|
|
1269
|
+
<!-- svelte-ignore a11y_no_noninteractive_tabindex -->
|
|
1267
1270
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
1268
1271
|
<header
|
|
1269
1272
|
class="sv-board-lane-head"
|
|
@@ -1344,7 +1347,9 @@
|
|
|
1344
1347
|
<div
|
|
1345
1348
|
class="sv-board-lane-body"
|
|
1346
1349
|
class:is-virtual={virtualized}
|
|
1347
|
-
role="
|
|
1350
|
+
role="listbox"
|
|
1351
|
+
tabindex="-1"
|
|
1352
|
+
aria-multiselectable={board.selectable ? true : undefined}
|
|
1348
1353
|
class:is-dropover={overLane === lane.id && overSwim === swimId}
|
|
1349
1354
|
use:trackLane={cellKey(lane.id, swimId)}
|
|
1350
1355
|
ondragover={(e) => onLaneDragOver(e, lane.id, swimId)}
|
|
@@ -1359,7 +1364,7 @@
|
|
|
1359
1364
|
<div class="sv-board-drop-marker" aria-hidden="true"></div>
|
|
1360
1365
|
{/if}
|
|
1361
1366
|
{@const isEditing = editingKey === key(row)}
|
|
1362
|
-
<
|
|
1367
|
+
<div
|
|
1363
1368
|
class="sv-board-card"
|
|
1364
1369
|
class:is-dragging={dragRow === row}
|
|
1365
1370
|
class:is-grabbed={grabbed === row}
|
|
@@ -1367,7 +1372,7 @@
|
|
|
1367
1372
|
class:is-flagged={isFlagged(row)}
|
|
1368
1373
|
class:is-locked={!movable(row)}
|
|
1369
1374
|
class:is-selected={board.selectable && selected[key(row)]}
|
|
1370
|
-
role="
|
|
1375
|
+
role="option"
|
|
1371
1376
|
tabindex="0"
|
|
1372
1377
|
data-card-key={key(row)}
|
|
1373
1378
|
aria-roledescription="Draggable card"
|
|
@@ -1531,7 +1536,7 @@
|
|
|
1531
1536
|
{@render commentThread(row)}
|
|
1532
1537
|
</div>
|
|
1533
1538
|
{/if}
|
|
1534
|
-
</
|
|
1539
|
+
</div>
|
|
1535
1540
|
{/each}
|
|
1536
1541
|
{#if win.bottom > 0}
|
|
1537
1542
|
<div style={`height:${win.bottom}px`} aria-hidden="true"></div>
|
|
@@ -35,7 +35,17 @@
|
|
|
35
35
|
|
|
36
36
|
const messages = $derived(ctrl.messages)
|
|
37
37
|
const columns = $derived(bulkEditableFields(ctrl) as BulkEditField[])
|
|
38
|
-
const count = $derived(
|
|
38
|
+
const count = $derived(
|
|
39
|
+
((ctrl.selectionBarCount as number | undefined) ?? (ctrl.selectionBarTarget?.ids ?? []).length) as number,
|
|
40
|
+
)
|
|
41
|
+
// A selection model with `bulkUpdate` owns the write: the rule it stores
|
|
42
|
+
// covers rows this grid never loaded, which writing the loaded cells
|
|
43
|
+
// would silently miss.
|
|
44
|
+
const remoteUpdate = $derived(
|
|
45
|
+
(ctrl.props?.rowSelectionModel?.bulkUpdate ?? null) as
|
|
46
|
+
| ((patch: Record<string, unknown>) => Promise<number>)
|
|
47
|
+
| null,
|
|
48
|
+
)
|
|
39
49
|
|
|
40
50
|
/** A column's editor type mapped onto the form's control vocabulary. */
|
|
41
51
|
function controlFor(editorType: string, hasOptions: boolean): FormFieldType {
|
|
@@ -85,7 +95,8 @@
|
|
|
85
95
|
})),
|
|
86
96
|
)
|
|
87
97
|
|
|
88
|
-
const
|
|
98
|
+
const locale = $derived(ctrl.props?.localization?.locale as string | string[] | undefined)
|
|
99
|
+
const fill = (t: string, n: number) => t.replace(/\{count\}/g, n.toLocaleString(locale))
|
|
89
100
|
|
|
90
101
|
function submit(values: Record<string, unknown>) {
|
|
91
102
|
const byId = new Map(columns.map((c) => [c.id, c]))
|
|
@@ -100,6 +111,19 @@
|
|
|
100
111
|
if (mixed.has(name) && (raw === '' || raw == null)) continue
|
|
101
112
|
edits[name] = next
|
|
102
113
|
}
|
|
114
|
+
if (remoteUpdate) {
|
|
115
|
+
// Keyed by field, not column id: the write goes to the datasource.
|
|
116
|
+
const byField: Record<string, unknown> = {}
|
|
117
|
+
for (const [columnId, value] of Object.entries(edits)) {
|
|
118
|
+
const field = byId.get(columnId)?.field
|
|
119
|
+
if (field) byField[field] = value
|
|
120
|
+
}
|
|
121
|
+
open = false
|
|
122
|
+
void remoteUpdate(byField).then((changed) =>
|
|
123
|
+
onApplied?.({ changed, skipped: 0, fields: Object.keys(byField).length }),
|
|
124
|
+
)
|
|
125
|
+
return
|
|
126
|
+
}
|
|
103
127
|
const result = applyBulkEdit(ctrl, edits)
|
|
104
128
|
open = false
|
|
105
129
|
onApplied?.(result)
|
|
@@ -715,6 +715,9 @@
|
|
|
715
715
|
(no scrollbar), unlike an in-flow popup. -->
|
|
716
716
|
<div class="sv-ep-field__dropdown">
|
|
717
717
|
<SvGridDropdown
|
|
718
|
+
id={`sv-ef-${f.field}`}
|
|
719
|
+
invalid={!!err}
|
|
720
|
+
{describedBy}
|
|
718
721
|
options={selectOptions(f)}
|
|
719
722
|
value={values[f.field]}
|
|
720
723
|
autoOpen={false}
|
|
@@ -78,6 +78,7 @@
|
|
|
78
78
|
} from "@svgrid/grid";
|
|
79
79
|
// Scheduler Pro feature models (this package).
|
|
80
80
|
import { cascade, violations, type SchedulerDependency } from "./scheduler-dependencies";
|
|
81
|
+
import { arrowHeadPath, dependencyArrows, type Arrow } from "./gantt/timeline-arrows";
|
|
81
82
|
import { expandAssignments, resourceLoad, type SchedulerAssignment } from "./scheduler-assignments";
|
|
82
83
|
import { columnSummaries } from "./scheduler-summary";
|
|
83
84
|
import { buildAxis, timeToX, xToTime, resolveZoom, zoomPresets, type Axis, type ZoomLevel } from "./scheduler-axis";
|
|
@@ -568,33 +569,18 @@
|
|
|
568
569
|
}
|
|
569
570
|
return { byKey, height: top };
|
|
570
571
|
});
|
|
571
|
-
// SVG path + state for each dependency arrow (elbow connector, pred finish ->
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
const x1 = type === "SS" || type === "SF" ? a.left : a.right;
|
|
583
|
-
const x2 = type === "FF" || type === "SF" ? b.right : b.left;
|
|
584
|
-
out.push({ id: dep.id, d: depElbow(x1, a.midY, x2, b.midY), bad: bad.has(dep.id), hx: x2, hy: b.midY });
|
|
585
|
-
}
|
|
586
|
-
return out;
|
|
572
|
+
// SVG path + state for each dependency arrow (elbow connector, pred finish ->
|
|
573
|
+
// succ start). The geometry lives in ./gantt/timeline-arrows, shared with the
|
|
574
|
+
// Gantt chart so the two views draw the same link the same way.
|
|
575
|
+
const tlDepArrows = $derived.by<Arrow[]>(() => {
|
|
576
|
+
if (!isTimeline || !hasDeps) return [];
|
|
577
|
+
return dependencyArrows(
|
|
578
|
+
tlBarRects.byKey,
|
|
579
|
+
depList,
|
|
580
|
+
new Set(depViolations.map((d) => d.id)),
|
|
581
|
+
tlLaneH,
|
|
582
|
+
);
|
|
587
583
|
});
|
|
588
|
-
// Orthogonal elbow connector between two anchor points; loops around when the
|
|
589
|
-
// successor sits left of the predecessor (a backward / violating link).
|
|
590
|
-
function depElbow(x1: number, y1: number, x2: number, y2: number): string {
|
|
591
|
-
const s = 10;
|
|
592
|
-
const p = x1 + s;
|
|
593
|
-
if (x2 >= p) return `M${x1},${y1} L${p},${y1} L${p},${y2} L${x2},${y2}`;
|
|
594
|
-
const q = x2 - s;
|
|
595
|
-
const midY = y2 >= y1 ? y1 + tlLaneH : y1 - tlLaneH;
|
|
596
|
-
return `M${x1},${y1} L${p},${y1} L${p},${midY} L${q},${midY} L${q},${y2} L${x2},${y2}`;
|
|
597
|
-
}
|
|
598
584
|
// Cascade successors forward after a move / resize, writing the shifts into the
|
|
599
585
|
// overlay and reporting them (never mutating source rows).
|
|
600
586
|
function cascadeDeps(movedKey: string, ns: Date, ne: Date) {
|
|
@@ -602,7 +588,9 @@
|
|
|
602
588
|
const times = new Map<string, { start: Date; end: Date }>();
|
|
603
589
|
for (const [k, v] of depTimes) times.set(k, v);
|
|
604
590
|
times.set(movedKey, { start: ns, end: ne });
|
|
605
|
-
|
|
591
|
+
// Successors only: the moved event stays where it was dropped, and a link
|
|
592
|
+
// it now breaks is drawn as violated rather than the drop being undone.
|
|
593
|
+
const shifts = cascade(times, depList, { from: [movedKey], snapForward: depSnapForward });
|
|
606
594
|
if (!shifts.size) return;
|
|
607
595
|
const moves: Array<{ id: string; start: Date; end: Date }> = [];
|
|
608
596
|
for (const [k, t] of shifts) {
|
|
@@ -882,16 +870,45 @@
|
|
|
882
870
|
return monthWeekSegments(rowEvents, gridDays[0] ?? anchor);
|
|
883
871
|
});
|
|
884
872
|
|
|
885
|
-
|
|
873
|
+
// `monthMatrix` returns exactly the rows it is asked for, because the date
|
|
874
|
+
// picker wants a grid that keeps its height as you page through the months.
|
|
875
|
+
// A full-page calendar wants the opposite: September 2026 spans five weeks,
|
|
876
|
+
// and a sixth row of October dates only takes height away from the five that
|
|
877
|
+
// carry the month - enough, at this demo's size, to cost every cell a lane.
|
|
878
|
+
// So trailing rows that are entirely outside the month are dropped. Only
|
|
879
|
+
// trailing rows can be: the first row always holds the 1st.
|
|
880
|
+
const monthWeeks = $derived.by(() => {
|
|
881
|
+
const weeks = monthMatrix(anchor, weekStartsOn, 6);
|
|
882
|
+
let used = weeks.length;
|
|
883
|
+
while (used > 1 && weeks[used - 1]!.every((cell) => !cell.inMonth)) used--;
|
|
884
|
+
return used === weeks.length ? weeks : weeks.slice(0, used);
|
|
885
|
+
});
|
|
886
886
|
const agenda = $derived(agendaGroups(viewEvents));
|
|
887
887
|
|
|
888
888
|
// --- month spanning-bar layout ---
|
|
889
889
|
const MONTH_DAYNUM_H = 22; // px reserved at the top of each cell for the date
|
|
890
890
|
const MONTH_LANE_H = 20; // px per event-bar lane
|
|
891
891
|
const MONTH_MORE_H = 16; // px reserved for the "+N more" row
|
|
892
|
+
// The floor a week row never shrinks past, fed to the CSS below so the two
|
|
893
|
+
// cannot drift apart. It is the sum above rather than a round number on
|
|
894
|
+
// purpose: it is exactly the height that still shows the date, one lane and
|
|
895
|
+
// the "+N more" that reaches the rest, so every event stays reachable at the
|
|
896
|
+
// floor. It used to be a flat 84, which is taller than six rows of a short
|
|
897
|
+
// body can be - so a month that needs six (August 2026, say) pushed its last
|
|
898
|
+
// row past the bottom of a `overflow: visible` box, and the 31st could not
|
|
899
|
+
// be seen or scrolled to. Rows shrink to fit now, and the body scrolls only
|
|
900
|
+
// if even the floor does not.
|
|
901
|
+
const MONTH_WEEK_MIN_H = MONTH_DAYNUM_H + MONTH_LANE_H + MONTH_MORE_H;
|
|
892
902
|
let monthBodyH = $state(0);
|
|
893
903
|
const visibleMonthLanes = $derived.by(() => {
|
|
894
|
-
|
|
904
|
+
// A week row is `flex: 1 1 0` with that min-height, so its real height is
|
|
905
|
+
// the larger of the two - the rows only divide the body evenly while the
|
|
906
|
+
// body is tall enough for all of them. Dividing unconditionally
|
|
907
|
+
// under-counts the lanes and puts a "+N more" in cells with a whole lane
|
|
908
|
+
// of empty space below it. September 2026 did exactly that: 418px over
|
|
909
|
+
// six rows reads as 69px and one lane, while every row really was 84px
|
|
910
|
+
// and fit two.
|
|
911
|
+
const weekH = Math.max(MONTH_WEEK_MIN_H, monthBodyH / Math.max(1, monthWeeks.length));
|
|
895
912
|
return Math.max(1, Math.floor((weekH - MONTH_DAYNUM_H - MONTH_MORE_H) / MONTH_LANE_H));
|
|
896
913
|
});
|
|
897
914
|
// Events hidden (beyond the visible lanes) that cover a given day column.
|
|
@@ -1971,6 +1988,9 @@
|
|
|
1971
1988
|
e.preventDefault();
|
|
1972
1989
|
const s = new Date(ev.start.getTime() + dDay * 86400000 + dMin * 60000);
|
|
1973
1990
|
const en = new Date(ev.end.getTime() + dDay * 86400000 + dMin * 60000);
|
|
1991
|
+
// The same booking rules as a drag: an arrow key must not land an event
|
|
1992
|
+
// on another one, outside the working hours or on a blocked day.
|
|
1993
|
+
if (bookingBlocked(s, en, ev.resourceId, ev.rowKey, ev.row)) return;
|
|
1974
1994
|
startOfE[ev.rowKey] = s;
|
|
1975
1995
|
endOfE[ev.rowKey] = en;
|
|
1976
1996
|
emitMove({ row: ev.row, start: s, end: en, allDay: ev.allDay, toResource: ev.resourceId });
|
|
@@ -3191,9 +3211,9 @@
|
|
|
3191
3211
|
{/if}
|
|
3192
3212
|
{#if zoomOn && proAxisData}
|
|
3193
3213
|
<div class="sv-sched-slots sv-sched-zoom" role="group" aria-label="Zoom">
|
|
3194
|
-
<button type="button" class="sv-sched-btn sv-sched-btn-slot" onclick={() => stepZoom(
|
|
3214
|
+
<button type="button" class="sv-sched-btn sv-sched-btn-slot" onclick={() => stepZoom(1)} aria-label="Zoom out">-</button>
|
|
3195
3215
|
<span class="sv-sched-zoom-label">{proAxisData.level?.label ?? "Zoom"}</span>
|
|
3196
|
-
<button type="button" class="sv-sched-btn sv-sched-btn-slot" onclick={() => stepZoom(1)} aria-label="Zoom
|
|
3216
|
+
<button type="button" class="sv-sched-btn sv-sched-btn-slot" onclick={() => stepZoom(-1)} aria-label="Zoom in">+</button>
|
|
3197
3217
|
</div>
|
|
3198
3218
|
{/if}
|
|
3199
3219
|
{#each views as v (v)}
|
|
@@ -3266,7 +3286,7 @@
|
|
|
3266
3286
|
<div class="sv-sched-dow">{wd(dowIdx)}</div>
|
|
3267
3287
|
{/each}
|
|
3268
3288
|
</div>
|
|
3269
|
-
<div class="sv-sched-monthbody" bind:clientHeight={monthBodyH}>
|
|
3289
|
+
<div class="sv-sched-monthbody" style={`--sv-sched-week-min-h:${MONTH_WEEK_MIN_H}px`} bind:clientHeight={monthBodyH}>
|
|
3270
3290
|
{#each monthWeeks as week, wi (wi)}
|
|
3271
3291
|
{@const weekStart = week[0]!.date}
|
|
3272
3292
|
{@const seg = monthWeekSegments(viewEvents, weekStart)}
|
|
@@ -3428,7 +3448,7 @@
|
|
|
3428
3448
|
<path
|
|
3429
3449
|
class="sv-sched-dep-arrow"
|
|
3430
3450
|
class:sv-sched-dep-bad={arr.bad}
|
|
3431
|
-
d={
|
|
3451
|
+
d={arrowHeadPath(arr.hx, arr.hy, arr.dir)}
|
|
3432
3452
|
/>
|
|
3433
3453
|
{/each}
|
|
3434
3454
|
</svg>
|
|
@@ -4272,8 +4292,16 @@
|
|
|
4272
4292
|
border-bottom: 1px solid var(--sg-border, #e5e7eb);
|
|
4273
4293
|
text-align: right;
|
|
4274
4294
|
}
|
|
4275
|
-
|
|
4276
|
-
|
|
4295
|
+
/* `auto`, not `visible`: the rows shrink to fit, so this only ever engages
|
|
4296
|
+
when the body is shorter than the rows' own floor - and then a scrollbar
|
|
4297
|
+
is the difference between a day you can reach and one that is simply
|
|
4298
|
+
painted outside the box. */
|
|
4299
|
+
.sv-sched-monthbody { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; overflow-y: auto; }
|
|
4300
|
+
/* min-height comes from MONTH_WEEK_MIN_H: the lane count reads the same
|
|
4301
|
+
floor, so a change here that did not reach the script would put "+N more"
|
|
4302
|
+
in cells that have room for the bar. The rows are `flex: 1 1 0`, so they
|
|
4303
|
+
grow to fill a tall body and shrink to this floor in a short one. */
|
|
4304
|
+
.sv-sched-week { position: relative; display: grid; grid-template-columns: repeat(7, 1fr); flex: 1 1 0; min-height: var(--sv-sched-week-min-h, 58px); }
|
|
4277
4305
|
.sv-sched-daycell {
|
|
4278
4306
|
position: relative;
|
|
4279
4307
|
border-right: 1px solid var(--sg-border, #e5e7eb);
|
|
@@ -5149,14 +5177,15 @@
|
|
|
5149
5177
|
.sv-sched-dep-arrow {
|
|
5150
5178
|
fill: var(--sv-sched-dep, color-mix(in srgb, var(--sg-fg, #1f2937) 45%, transparent));
|
|
5151
5179
|
}
|
|
5152
|
-
|
|
5153
|
-
|
|
5154
|
-
stroke: var(--sv-sched-dep-bad, #dc2626);
|
|
5155
|
-
fill: var(--sv-sched-dep-bad, #dc2626);
|
|
5156
|
-
}
|
|
5180
|
+
/* The line keeps `fill: none` - a fill on the elbow path paints the polygon
|
|
5181
|
+
it encloses, and a violated link showed up as a solid red slab. */
|
|
5157
5182
|
.sv-sched-dep-line.sv-sched-dep-bad {
|
|
5183
|
+
stroke: var(--sv-sched-dep-bad, #dc2626);
|
|
5158
5184
|
stroke-dasharray: 4 3;
|
|
5159
5185
|
}
|
|
5186
|
+
.sv-sched-dep-arrow.sv-sched-dep-bad {
|
|
5187
|
+
fill: var(--sv-sched-dep-bad, #dc2626);
|
|
5188
|
+
}
|
|
5160
5189
|
/* Resource utilization histogram (Scheduler Pro) - a subtle meter strip at the
|
|
5161
5190
|
bottom of each resource row, clearly separated from the event lanes above. */
|
|
5162
5191
|
.sv-sched-hist {
|
|
@@ -27,7 +27,13 @@
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
const target = $derived(ctrl.selectionBarTarget as Target)
|
|
30
|
-
|
|
30
|
+
// The count the controller resolved: a selection model that stores the
|
|
31
|
+
// rule knows about rows the grid never loaded, so "1,000,000 selected"
|
|
32
|
+
// is honest even with twenty rows on screen.
|
|
33
|
+
const count = $derived((ctrl.selectionBarCount as number | undefined) ?? target.ids.length)
|
|
34
|
+
// Grouped the way the grid's own numbers are: 1,000,000, not 1000000.
|
|
35
|
+
const locale = $derived(ctrl.props?.localization?.locale as string | string[] | undefined)
|
|
36
|
+
const countText = $derived(count.toLocaleString(locale))
|
|
31
37
|
const messages = $derived(ctrl.messages)
|
|
32
38
|
const position = $derived(ctrl.selectionBarPosition as 'top' | 'bottom')
|
|
33
39
|
const maxVisible = $derived(ctrl.selectionBarMaxVisible as number)
|
|
@@ -85,7 +91,7 @@
|
|
|
85
91
|
let overflowOpen = $state(false)
|
|
86
92
|
let barEl = $state<HTMLElement | null>(null)
|
|
87
93
|
|
|
88
|
-
const fill = (template: string, n: number) => template.replace(/\{count\}/g,
|
|
94
|
+
const fill = (template: string, n: number) => template.replace(/\{count\}/g, n.toLocaleString(locale))
|
|
89
95
|
const clearSelection = () => ctrl.grid.setRowSelection(() => ({}))
|
|
90
96
|
|
|
91
97
|
function run(a: Action) {
|
|
@@ -138,12 +144,13 @@
|
|
|
138
144
|
class="sv-selbar"
|
|
139
145
|
data-position={position}
|
|
140
146
|
role="toolbar"
|
|
147
|
+
tabindex="-1"
|
|
141
148
|
aria-label={messages.selectionBarLabel}
|
|
142
149
|
aria-orientation="horizontal"
|
|
143
150
|
onkeydown={onKeydown}
|
|
144
151
|
>
|
|
145
152
|
<span class="sv-selbar-count" aria-live="polite">
|
|
146
|
-
<span class="sv-selbar-chip">{
|
|
153
|
+
<span class="sv-selbar-chip">{countText}</span>
|
|
147
154
|
<span class="sv-selbar-count-label">{messages.selectionBarCount}</span>
|
|
148
155
|
</span>
|
|
149
156
|
|