@svgrid/enterprise 3.0.2 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +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-BSjv6Qec.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
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ColumnDef, GanttConfig, RowData, TableFeatures } from "@svgrid/grid";
|
|
2
|
+
declare function $$render<TFeatures extends TableFeatures = TableFeatures, TData extends RowData = RowData>(): {
|
|
3
|
+
props: {
|
|
4
|
+
data: ReadonlyArray<TData>;
|
|
5
|
+
columns: Array<ColumnDef<TFeatures, TData>>;
|
|
6
|
+
gantt: GanttConfig<TFeatures, TData>;
|
|
7
|
+
getRowId?: (row: TData, index: number) => string;
|
|
8
|
+
};
|
|
9
|
+
exports: {};
|
|
10
|
+
bindings: "";
|
|
11
|
+
slots: {};
|
|
12
|
+
events: {};
|
|
13
|
+
};
|
|
14
|
+
declare class __sveltets_Render<TFeatures extends TableFeatures = TableFeatures, TData extends RowData = RowData> {
|
|
15
|
+
props(): ReturnType<typeof $$render<TFeatures, TData>>['props'];
|
|
16
|
+
events(): ReturnType<typeof $$render<TFeatures, TData>>['events'];
|
|
17
|
+
slots(): ReturnType<typeof $$render<TFeatures, TData>>['slots'];
|
|
18
|
+
bindings(): "";
|
|
19
|
+
exports(): {};
|
|
20
|
+
}
|
|
21
|
+
interface $$IsomorphicComponent {
|
|
22
|
+
new <TFeatures extends TableFeatures = TableFeatures, TData extends RowData = RowData>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<TFeatures, TData>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<TFeatures, TData>['props']>, ReturnType<__sveltets_Render<TFeatures, TData>['events']>, ReturnType<__sveltets_Render<TFeatures, TData>['slots']>> & {
|
|
23
|
+
$$bindings?: ReturnType<__sveltets_Render<TFeatures, TData>['bindings']>;
|
|
24
|
+
} & ReturnType<__sveltets_Render<TFeatures, TData>['exports']>;
|
|
25
|
+
<TFeatures extends TableFeatures = TableFeatures, TData extends RowData = RowData>(internal: unknown, props: ReturnType<__sveltets_Render<TFeatures, TData>['props']> & {}): ReturnType<__sveltets_Render<TFeatures, TData>['exports']>;
|
|
26
|
+
z_$$bindings?: ReturnType<__sveltets_Render<any, any>['bindings']>;
|
|
27
|
+
}
|
|
28
|
+
declare const SvGridGantt: $$IsomorphicComponent;
|
|
29
|
+
type SvGridGantt<TFeatures extends TableFeatures = TableFeatures, TData extends RowData = RowData> = InstanceType<typeof SvGridGantt<TFeatures, TData>>;
|
|
30
|
+
export default SvGridGantt;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GanttProConfig - the Enterprise superset of the free grid {@link GanttConfig}.
|
|
3
|
+
* The `gantt` prop and its base config type ship in `@svgrid/grid`; the Pro
|
|
4
|
+
* renderer (SvGridGantt) reads these extra fields at runtime through a cast
|
|
5
|
+
* (the renderer is registered untyped, so nothing in the free grid needs to
|
|
6
|
+
* know about them). Consumers using Pro features type their config as
|
|
7
|
+
* `GanttProConfig` - it is structurally assignable to the `gantt` prop.
|
|
8
|
+
*
|
|
9
|
+
* Mirrors `scheduler-config.ts`, which does the same for the calendar.
|
|
10
|
+
*/
|
|
11
|
+
import type { GanttConfig, RowData, SchedulerResource, TableFeatures } from '@svgrid/grid';
|
|
12
|
+
/**
|
|
13
|
+
* How a task's dates are pinned, in the classic planning vocabulary:
|
|
14
|
+
* `ASAP` (the default - schedule as early as links allow), `ALAP` (as late as
|
|
15
|
+
* possible), `MSO` / `MFO` (must start / finish on the constraint date),
|
|
16
|
+
* `SNET` / `SNLT` (start no earlier / later than), `FNET` / `FNLT` (finish no
|
|
17
|
+
* earlier / later than).
|
|
18
|
+
*/
|
|
19
|
+
export type GanttConstraint = 'ASAP' | 'ALAP' | 'MSO' | 'MFO' | 'SNET' | 'SNLT' | 'FNET' | 'FNLT';
|
|
20
|
+
export type GanttProConfig<TFeatures extends TableFeatures = TableFeatures, TData extends RowData = RowData> = GanttConfig<TFeatures, TData> & {
|
|
21
|
+
/**
|
|
22
|
+
* Highlight the critical path: the chain of linked tasks with no slack,
|
|
23
|
+
* where any slip moves the project's finish. Needs `dependencies`.
|
|
24
|
+
*/
|
|
25
|
+
criticalPath?: boolean;
|
|
26
|
+
/** Fired with the critical task ids whenever the path is recomputed. */
|
|
27
|
+
onCriticalPathChange?: (keys: string[]) => void;
|
|
28
|
+
/**
|
|
29
|
+
* Fields holding the BASELINE (originally agreed) dates, drawn as a ghost bar
|
|
30
|
+
* under each task so drift from the plan is visible.
|
|
31
|
+
*/
|
|
32
|
+
baselineStartField?: keyof TData & string;
|
|
33
|
+
baselineEndField?: keyof TData & string;
|
|
34
|
+
/**
|
|
35
|
+
* Per-row scheduling constraint (see {@link GanttConstraint}) and the date it
|
|
36
|
+
* refers to. A cascade that would violate one stops at the constraint and the
|
|
37
|
+
* bar is flagged rather than moved past it.
|
|
38
|
+
*/
|
|
39
|
+
constraintField?: keyof TData & string;
|
|
40
|
+
constraintDateField?: keyof TData & string;
|
|
41
|
+
/**
|
|
42
|
+
* Fold whole non-working days out of the axis: a weekend shrinks to a narrow
|
|
43
|
+
* hatched gap instead of two empty columns, so a year of plan fits in the
|
|
44
|
+
* width a season used to take. Bars that do run over a folded weekend still
|
|
45
|
+
* draw across it.
|
|
46
|
+
*
|
|
47
|
+
* Only the day-granular presets (`day`, `week`) have weekend columns to fold;
|
|
48
|
+
* at `month` and coarser a tick is never wholly non-working, so this is
|
|
49
|
+
* ignored rather than shrinking a week by part of itself.
|
|
50
|
+
*/
|
|
51
|
+
collapseWeekends?: boolean;
|
|
52
|
+
/** Width (px) of one folded run's marker. Default 12; `0` removes it outright. */
|
|
53
|
+
collapsedGapPx?: number;
|
|
54
|
+
/**
|
|
55
|
+
* Field naming the resource (person, crew, machine) a task is assigned to,
|
|
56
|
+
* plus the ordered resource list. Shown in the tooltip and, with
|
|
57
|
+
* `resourceHistogram`, summed into a load strip under the chart. Omit
|
|
58
|
+
* `resources` and the strip's rows come from the data, in first-seen order.
|
|
59
|
+
*/
|
|
60
|
+
resourceField?: keyof TData & string;
|
|
61
|
+
resources?: ReadonlyArray<SchedulerResource>;
|
|
62
|
+
/**
|
|
63
|
+
* Show a per-resource load histogram below the chart: one row per resource,
|
|
64
|
+
* one bar per axis column, counting the tasks that touch it, with anything
|
|
65
|
+
* past capacity in red. `true` uses the defaults (capacity 1, 88px tall);
|
|
66
|
+
* the object form names a field on each {@link SchedulerResource} holding its
|
|
67
|
+
* capacity, and the strip's total height in px.
|
|
68
|
+
*/
|
|
69
|
+
resourceHistogram?: boolean | {
|
|
70
|
+
capacityField?: string;
|
|
71
|
+
height?: number;
|
|
72
|
+
};
|
|
73
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* gantt-critical-path - the critical path method (CPM) over a Gantt's tasks and
|
|
3
|
+
* their dependency links. Pure and framework-free, like every model in this
|
|
4
|
+
* package: a map of task times in, slack and the critical set out.
|
|
5
|
+
*
|
|
6
|
+
* Two passes over the dependency graph in topological order:
|
|
7
|
+
*
|
|
8
|
+
* - **Forward** gives each task its EARLIEST start and finish: the later of
|
|
9
|
+
* its own start and whatever its predecessors allow.
|
|
10
|
+
* - **Backward** gives each task its LATEST start and finish: the earliest of
|
|
11
|
+
* the project finish and whatever its successors need.
|
|
12
|
+
*
|
|
13
|
+
* `slack` is the gap between the two. A task with none cannot slip by a day
|
|
14
|
+
* without moving the project's finish, and the chain of those tasks is the
|
|
15
|
+
* critical path.
|
|
16
|
+
*
|
|
17
|
+
* Two rules worth stating, because both are judgement calls rather than
|
|
18
|
+
* arithmetic:
|
|
19
|
+
*
|
|
20
|
+
* 1. **An unlinked task is never critical.** A task in no dependency at all
|
|
21
|
+
* is not on any path, so calling it critical would point at something the
|
|
22
|
+
* schedule does not actually depend on. It still gets a slack figure - the
|
|
23
|
+
* room it has before the project finish - for a Slack column to show.
|
|
24
|
+
* 2. **Cyclic links are ignored**, exactly as `cascade` ignores them: a cycle
|
|
25
|
+
* has no legal schedule, so there is no earliest or latest to compute
|
|
26
|
+
* through it.
|
|
27
|
+
*
|
|
28
|
+
* With a {@link WorkingCalendar} the passes run in WORKING time: a task's
|
|
29
|
+
* length is its working days, a latest start is counted back over working
|
|
30
|
+
* days, and slack is the working days a task could slip. Without one they
|
|
31
|
+
* run in calendar time, which is what a plan with no weekends is. The
|
|
32
|
+
* difference is not cosmetic: a five-day task ending Friday whose successor
|
|
33
|
+
* starts Monday has two calendar days of slack and none at all in working
|
|
34
|
+
* time - it is critical, and only the working-time pass says so.
|
|
35
|
+
*
|
|
36
|
+
* Nothing here reads the clock.
|
|
37
|
+
*/
|
|
38
|
+
import { type EventTimes, type SchedulerDependency } from '../scheduler-dependencies.js';
|
|
39
|
+
import { type WorkingCalendar } from './gantt-model.js';
|
|
40
|
+
export type CpmResult = {
|
|
41
|
+
/** Keys with no slack, and at least one link. See rule 1 in the header. */
|
|
42
|
+
critical: Set<string>;
|
|
43
|
+
/** Room each task has before it would move the project finish, in calendar ms. */
|
|
44
|
+
slackMs: Map<string, number>;
|
|
45
|
+
/**
|
|
46
|
+
* The same room in whole days: WORKING days when the pass was given a
|
|
47
|
+
* calendar, calendar days otherwise. The number a Slack column shows.
|
|
48
|
+
*/
|
|
49
|
+
slackDays: Map<string, number>;
|
|
50
|
+
earliest: Map<string, EventTimes>;
|
|
51
|
+
latest: Map<string, EventTimes>;
|
|
52
|
+
/** The earliest the whole project can finish. */
|
|
53
|
+
finish: Date;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Run the two passes. `times` is every task the plan draws, keyed by row key -
|
|
57
|
+
* for a parent, pass the span its summary bar shows, so a link to a phase means
|
|
58
|
+
* "after the whole phase" without any special case here. Give `cal` for a
|
|
59
|
+
* working-time pass (see the header); omit it for calendar time.
|
|
60
|
+
*/
|
|
61
|
+
export declare function criticalPath(times: ReadonlyMap<string, EventTimes>, deps: ReadonlyArray<SchedulerDependency>, cal?: WorkingCalendar): CpmResult;
|
|
62
|
+
/**
|
|
63
|
+
* A task's slack in whole days, for a table column: working days when the
|
|
64
|
+
* pass ran with a calendar, calendar days otherwise. Rounds toward zero, so
|
|
65
|
+
* "2" means two full days of room rather than anything up to three.
|
|
66
|
+
*/
|
|
67
|
+
export declare function slackDays(result: CpmResult, key: string): number;
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* gantt-critical-path - the critical path method (CPM) over a Gantt's tasks and
|
|
3
|
+
* their dependency links. Pure and framework-free, like every model in this
|
|
4
|
+
* package: a map of task times in, slack and the critical set out.
|
|
5
|
+
*
|
|
6
|
+
* Two passes over the dependency graph in topological order:
|
|
7
|
+
*
|
|
8
|
+
* - **Forward** gives each task its EARLIEST start and finish: the later of
|
|
9
|
+
* its own start and whatever its predecessors allow.
|
|
10
|
+
* - **Backward** gives each task its LATEST start and finish: the earliest of
|
|
11
|
+
* the project finish and whatever its successors need.
|
|
12
|
+
*
|
|
13
|
+
* `slack` is the gap between the two. A task with none cannot slip by a day
|
|
14
|
+
* without moving the project's finish, and the chain of those tasks is the
|
|
15
|
+
* critical path.
|
|
16
|
+
*
|
|
17
|
+
* Two rules worth stating, because both are judgement calls rather than
|
|
18
|
+
* arithmetic:
|
|
19
|
+
*
|
|
20
|
+
* 1. **An unlinked task is never critical.** A task in no dependency at all
|
|
21
|
+
* is not on any path, so calling it critical would point at something the
|
|
22
|
+
* schedule does not actually depend on. It still gets a slack figure - the
|
|
23
|
+
* room it has before the project finish - for a Slack column to show.
|
|
24
|
+
* 2. **Cyclic links are ignored**, exactly as `cascade` ignores them: a cycle
|
|
25
|
+
* has no legal schedule, so there is no earliest or latest to compute
|
|
26
|
+
* through it.
|
|
27
|
+
*
|
|
28
|
+
* With a {@link WorkingCalendar} the passes run in WORKING time: a task's
|
|
29
|
+
* length is its working days, a latest start is counted back over working
|
|
30
|
+
* days, and slack is the working days a task could slip. Without one they
|
|
31
|
+
* run in calendar time, which is what a plan with no weekends is. The
|
|
32
|
+
* difference is not cosmetic: a five-day task ending Friday whose successor
|
|
33
|
+
* starts Monday has two calendar days of slack and none at all in working
|
|
34
|
+
* time - it is critical, and only the working-time pass says so.
|
|
35
|
+
*
|
|
36
|
+
* Nothing here reads the clock.
|
|
37
|
+
*/
|
|
38
|
+
import { buildDependencyGraph, requiredStart, topoOrder, } from '../scheduler-dependencies.js';
|
|
39
|
+
import { moveWorkingSpan, snapToWorkingDay, startForWorkingDays, workingDays, } from './gantt-model.js';
|
|
40
|
+
const MS_MIN = 60000;
|
|
41
|
+
const MS_DAY = 86400000;
|
|
42
|
+
/** Below this, a slack is rounding noise rather than real room. */
|
|
43
|
+
const CRITICAL_EPS_MS = MS_MIN;
|
|
44
|
+
const durMs = (t) => Math.max(0, t.end.getTime() - t.start.getTime());
|
|
45
|
+
const calendarArith = {
|
|
46
|
+
reqStart: (pred, dep, self) => requiredStart(pred, dep, durMs(self)),
|
|
47
|
+
capFinish: (succ, dep, self) => latestPredecessorFinish(succ, dep, durMs(self)),
|
|
48
|
+
endOf: (start, self) => new Date(start.getTime() + durMs(self)),
|
|
49
|
+
startOf: (end, self) => new Date(end.getTime() - durMs(self)),
|
|
50
|
+
slackDays: (es, ls) => Math.trunc((ls.getTime() - es.getTime()) / MS_DAY),
|
|
51
|
+
isCritical: (es, ls) => ls.getTime() - es.getTime() < CRITICAL_EPS_MS,
|
|
52
|
+
};
|
|
53
|
+
function workingArith(cal) {
|
|
54
|
+
const endOf = (start, self) => moveWorkingSpan(start, self, cal).end;
|
|
55
|
+
const startOf = (end, self) => {
|
|
56
|
+
const days = workingDays(self.start, self.end, cal);
|
|
57
|
+
return days > 0 ? startForWorkingDays(end, days, cal) : new Date(end.getTime() - durMs(self));
|
|
58
|
+
};
|
|
59
|
+
const lagOf = (dep) => (dep.lag ?? 0) * MS_MIN;
|
|
60
|
+
const snap = (d) => snapToWorkingDay(d, 1, cal);
|
|
61
|
+
return {
|
|
62
|
+
// What a link asks of the successor, landed on a working day - the same
|
|
63
|
+
// snap the cascade applies to a pushed task.
|
|
64
|
+
reqStart: (pred, dep, self) => {
|
|
65
|
+
const lag = lagOf(dep);
|
|
66
|
+
switch (dep.type ?? 'FS') {
|
|
67
|
+
case 'FS': return snap(new Date(pred.end.getTime() + lag));
|
|
68
|
+
case 'SS': return snap(new Date(pred.start.getTime() + lag));
|
|
69
|
+
case 'FF': return snap(startOf(new Date(pred.end.getTime() + lag), self));
|
|
70
|
+
case 'SF': return snap(startOf(new Date(pred.start.getTime() + lag), self));
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
// What a link allows of the predecessor's finish. An end that lands after
|
|
74
|
+
// a weekend is fine as it is: counting the start back over working days
|
|
75
|
+
// skips the weekend, so nothing has to be snapped here.
|
|
76
|
+
capFinish: (succ, dep, self) => {
|
|
77
|
+
const lag = lagOf(dep);
|
|
78
|
+
switch (dep.type ?? 'FS') {
|
|
79
|
+
case 'FS': return new Date(succ.start.getTime() - lag);
|
|
80
|
+
case 'SS': return endOf(new Date(succ.start.getTime() - lag), self);
|
|
81
|
+
case 'FF': return new Date(succ.end.getTime() - lag);
|
|
82
|
+
case 'SF': return endOf(new Date(succ.end.getTime() - lag), self);
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
endOf,
|
|
86
|
+
startOf,
|
|
87
|
+
slackDays: (es, ls) => (ls.getTime() > es.getTime() ? workingDays(es, ls, cal) : 0),
|
|
88
|
+
// No working day between the earliest and latest start: it cannot slip.
|
|
89
|
+
isCritical: (es, ls) => ls.getTime() <= es.getTime() || workingDays(es, ls, cal) === 0,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* The LATEST finish a predecessor may have, given what its successor's latest
|
|
94
|
+
* times allow. The mirror of {@link requiredStart}, which answers the same
|
|
95
|
+
* question forwards.
|
|
96
|
+
*/
|
|
97
|
+
function latestPredecessorFinish(succLatest, dep, predDurationMs) {
|
|
98
|
+
const lagMs = (dep.lag ?? 0) * MS_MIN;
|
|
99
|
+
switch (dep.type ?? 'FS') {
|
|
100
|
+
// succ.start >= pred.end + lag -> pred.end <= succ.start - lag
|
|
101
|
+
case 'FS':
|
|
102
|
+
return new Date(succLatest.start.getTime() - lagMs);
|
|
103
|
+
// succ.start >= pred.start + lag -> pred.start <= succ.start - lag
|
|
104
|
+
case 'SS':
|
|
105
|
+
return new Date(succLatest.start.getTime() - lagMs + predDurationMs);
|
|
106
|
+
// succ.end >= pred.end + lag -> pred.end <= succ.end - lag
|
|
107
|
+
case 'FF':
|
|
108
|
+
return new Date(succLatest.end.getTime() - lagMs);
|
|
109
|
+
// succ.end >= pred.start + lag -> pred.start <= succ.end - lag
|
|
110
|
+
case 'SF':
|
|
111
|
+
return new Date(succLatest.end.getTime() - lagMs + predDurationMs);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Run the two passes. `times` is every task the plan draws, keyed by row key -
|
|
116
|
+
* for a parent, pass the span its summary bar shows, so a link to a phase means
|
|
117
|
+
* "after the whole phase" without any special case here. Give `cal` for a
|
|
118
|
+
* working-time pass (see the header); omit it for calendar time.
|
|
119
|
+
*/
|
|
120
|
+
export function criticalPath(times, deps, cal) {
|
|
121
|
+
const arith = cal ? workingArith(cal) : calendarArith;
|
|
122
|
+
const graph = buildDependencyGraph(deps);
|
|
123
|
+
const { order, cyclicIds } = topoOrder(graph);
|
|
124
|
+
const live = graph.deps.filter((d) => !cyclicIds.has(d.id));
|
|
125
|
+
/** Keys that take part in at least one usable link. */
|
|
126
|
+
const linked = new Set();
|
|
127
|
+
for (const d of live) {
|
|
128
|
+
if (times.has(d.from) && times.has(d.to)) {
|
|
129
|
+
linked.add(d.from);
|
|
130
|
+
linked.add(d.to);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
// --- forward: earliest start / finish ------------------------------------
|
|
134
|
+
const earliest = new Map();
|
|
135
|
+
for (const [k, t] of times)
|
|
136
|
+
earliest.set(k, { start: t.start, end: t.end });
|
|
137
|
+
// Only the graph's nodes need relaxing, and only in topological order; a key
|
|
138
|
+
// outside the graph keeps its own dates.
|
|
139
|
+
for (const key of order) {
|
|
140
|
+
const self = times.get(key);
|
|
141
|
+
if (!self)
|
|
142
|
+
continue;
|
|
143
|
+
let es = self.start;
|
|
144
|
+
for (const dep of graph.pred.get(key) ?? []) {
|
|
145
|
+
if (cyclicIds.has(dep.id))
|
|
146
|
+
continue;
|
|
147
|
+
const pred = earliest.get(dep.from);
|
|
148
|
+
if (!pred)
|
|
149
|
+
continue;
|
|
150
|
+
const req = arith.reqStart(pred, dep, self);
|
|
151
|
+
if (req.getTime() > es.getTime())
|
|
152
|
+
es = req;
|
|
153
|
+
}
|
|
154
|
+
earliest.set(key, { start: es, end: arith.endOf(es, self) });
|
|
155
|
+
}
|
|
156
|
+
// The project finishes when its last task does.
|
|
157
|
+
let finishMs = -Infinity;
|
|
158
|
+
for (const t of earliest.values())
|
|
159
|
+
finishMs = Math.max(finishMs, t.end.getTime());
|
|
160
|
+
if (!Number.isFinite(finishMs))
|
|
161
|
+
finishMs = 0;
|
|
162
|
+
const finish = new Date(finishMs);
|
|
163
|
+
// --- backward: latest start / finish --------------------------------------
|
|
164
|
+
const latest = new Map();
|
|
165
|
+
for (const [k, self] of times) {
|
|
166
|
+
latest.set(k, { start: arith.startOf(finish, self), end: finish });
|
|
167
|
+
}
|
|
168
|
+
for (let i = order.length - 1; i >= 0; i--) {
|
|
169
|
+
const key = order[i];
|
|
170
|
+
const self = times.get(key);
|
|
171
|
+
if (!self)
|
|
172
|
+
continue;
|
|
173
|
+
let lf = finish;
|
|
174
|
+
for (const dep of graph.succ.get(key) ?? []) {
|
|
175
|
+
if (cyclicIds.has(dep.id))
|
|
176
|
+
continue;
|
|
177
|
+
const succ = latest.get(dep.to);
|
|
178
|
+
if (!succ)
|
|
179
|
+
continue;
|
|
180
|
+
const cap = arith.capFinish(succ, dep, self);
|
|
181
|
+
if (cap.getTime() < lf.getTime())
|
|
182
|
+
lf = cap;
|
|
183
|
+
}
|
|
184
|
+
latest.set(key, { start: arith.startOf(lf, self), end: lf });
|
|
185
|
+
}
|
|
186
|
+
// --- slack ----------------------------------------------------------------
|
|
187
|
+
const slackMs = new Map();
|
|
188
|
+
const slackDaysOf = new Map();
|
|
189
|
+
const critical = new Set();
|
|
190
|
+
for (const [k] of times) {
|
|
191
|
+
const e = earliest.get(k);
|
|
192
|
+
const l = latest.get(k);
|
|
193
|
+
slackMs.set(k, l.start.getTime() - e.start.getTime());
|
|
194
|
+
slackDaysOf.set(k, arith.slackDays(e.start, l.start));
|
|
195
|
+
if (linked.has(k) && arith.isCritical(e.start, l.start))
|
|
196
|
+
critical.add(k);
|
|
197
|
+
}
|
|
198
|
+
return { critical, slackMs, slackDays: slackDaysOf, earliest, latest, finish };
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* A task's slack in whole days, for a table column: working days when the
|
|
202
|
+
* pass ran with a calendar, calendar days otherwise. Rounds toward zero, so
|
|
203
|
+
* "2" means two full days of room rather than anything up to three.
|
|
204
|
+
*/
|
|
205
|
+
export function slackDays(result, key) {
|
|
206
|
+
return result.slackDays.get(key) ?? 0;
|
|
207
|
+
}
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* gantt-model - the pure, framework-free core behind the Gantt view. No Svelte,
|
|
3
|
+
* no DOM: rows in, resolved tasks / a work-breakdown tree / an axis out, so
|
|
4
|
+
* every rule here is unit-tested directly (mirrors scheduler-model.ts in
|
|
5
|
+
* @svgrid/grid).
|
|
6
|
+
*
|
|
7
|
+
* Three conventions this file owns, because getting them wrong is silent:
|
|
8
|
+
*
|
|
9
|
+
* 1. **Days are LOCAL.** A date-only string (`'2026-09-14'`) is parsed as
|
|
10
|
+
* local midnight, not UTC. `new Date('2026-09-14')` is UTC midnight, which
|
|
11
|
+
* in any negative-offset zone is the 13th locally - a bar a day early, on
|
|
12
|
+
* every task, visible only to people west of Greenwich.
|
|
13
|
+
* 2. **`end` is exclusive, except a date-only string is inclusive of its day.**
|
|
14
|
+
* A task from the 14th to the 16th is three days long, which is what every
|
|
15
|
+
* planning tool means and what a person typing those dates expects. A
|
|
16
|
+
* value carrying a time (a `Date`, epoch-ms, or an ISO string with `T`) is
|
|
17
|
+
* taken literally.
|
|
18
|
+
* 3. **Duration counts WORKING days.** A 3-day task starting Friday ends
|
|
19
|
+
* Wednesday, not Monday.
|
|
20
|
+
*
|
|
21
|
+
* Nothing here reads the clock: `projectRange` and `ganttAxis` take `today` as
|
|
22
|
+
* an argument so their output is testable without wall-clock flakiness.
|
|
23
|
+
*/
|
|
24
|
+
import type { DateLike, GanttZoom, TimelineAxis } from '@svgrid/grid';
|
|
25
|
+
/** A new Date at local midnight of the same calendar day. */
|
|
26
|
+
export declare function startOfDay(d: Date): Date;
|
|
27
|
+
/** `n` days after `d` (negative to go back), preserving the time of day. */
|
|
28
|
+
export declare function addDays(d: Date, n: number): Date;
|
|
29
|
+
/**
|
|
30
|
+
* Parse a task date. A bare `YYYY-MM-DD` becomes LOCAL midnight of that day
|
|
31
|
+
* (see the header); anything else goes through the grid's `toDate`.
|
|
32
|
+
*/
|
|
33
|
+
export declare function parseDay(value: DateLike | null | undefined): Date | null;
|
|
34
|
+
/** Which days are off: weekdays by number, plus specific dates. */
|
|
35
|
+
export type WorkingCalendar = {
|
|
36
|
+
/** Weekday numbers, 0 = Sun .. 6 = Sat. */
|
|
37
|
+
nonWorkingDays: ReadonlyArray<number>;
|
|
38
|
+
/** `startOfDay(date).getTime()` for each holiday. */
|
|
39
|
+
holidays: ReadonlySet<number>;
|
|
40
|
+
};
|
|
41
|
+
/** Build a {@link WorkingCalendar}. Weekends (`[0, 6]`) are the default. */
|
|
42
|
+
export declare function makeCalendar(nonWorkingDays?: ReadonlyArray<number>, holidays?: ReadonlyArray<DateLike>): WorkingCalendar;
|
|
43
|
+
/** True when work happens on `d`'s calendar day. */
|
|
44
|
+
export declare function isWorkingDay(d: Date, cal: WorkingCalendar): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Working days in `[start, end)`. A task from Monday to the following Monday
|
|
47
|
+
* with weekends off is 5. Returns 0 when the range is empty or inverted.
|
|
48
|
+
*/
|
|
49
|
+
export declare function workingDays(start: Date, end: Date, cal: WorkingCalendar): number;
|
|
50
|
+
/**
|
|
51
|
+
* The exclusive end of a task that starts on `start` and lasts `days` WORKING
|
|
52
|
+
* days: the midnight after its last working day. A zero or negative length
|
|
53
|
+
* gives `start` back (a milestone).
|
|
54
|
+
*/
|
|
55
|
+
export declare function addWorkingDays(start: Date, days: number, cal: WorkingCalendar): Date;
|
|
56
|
+
/**
|
|
57
|
+
* The start of a task that lasts `days` WORKING days and ends (exclusively) at
|
|
58
|
+
* `end`: the inverse of {@link addWorkingDays}. Walks back from the day before
|
|
59
|
+
* `end` counting working days, so a five-day task ending Saturday 00:00
|
|
60
|
+
* started the Monday before. Zero days gives `end`'s own midnight.
|
|
61
|
+
*/
|
|
62
|
+
export declare function startForWorkingDays(end: Date, days: number, cal: WorkingCalendar): Date;
|
|
63
|
+
/**
|
|
64
|
+
* The span a task keeps when it is moved to `start`: its WORKING days laid
|
|
65
|
+
* out from there, so a Monday-to-Friday task dragged to Wednesday ends the
|
|
66
|
+
* Tuesday after, not the Sunday. A task with no working day in it (a
|
|
67
|
+
* milestone, or one parked on a weekend) keeps its calendar length instead,
|
|
68
|
+
* so nothing collapses to zero.
|
|
69
|
+
*/
|
|
70
|
+
export declare function moveWorkingSpan(start: Date, original: {
|
|
71
|
+
start: Date;
|
|
72
|
+
end: Date;
|
|
73
|
+
}, cal: WorkingCalendar): {
|
|
74
|
+
start: Date;
|
|
75
|
+
end: Date;
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* The nearest working day at or after `d` (`dir` 1) or at or before it
|
|
79
|
+
* (`dir` -1), at local midnight. A calendar with no working day at all returns
|
|
80
|
+
* `d`'s own midnight rather than spinning.
|
|
81
|
+
*/
|
|
82
|
+
export declare function snapToWorkingDay(d: Date, dir: 1 | -1, cal: WorkingCalendar): Date;
|
|
83
|
+
/**
|
|
84
|
+
* Field accessors the model uses to read a task off a row. The renderer builds
|
|
85
|
+
* this from `GanttConfig`, applying its drag overlay first so a dragged bar
|
|
86
|
+
* resolves at its new dates without mutating the source row.
|
|
87
|
+
*/
|
|
88
|
+
export type GanttTaskSpec<TData> = {
|
|
89
|
+
getKey: (row: TData) => string;
|
|
90
|
+
getStart: (row: TData) => DateLike | null | undefined;
|
|
91
|
+
getEnd?: (row: TData) => DateLike | null | undefined;
|
|
92
|
+
/** Length in WORKING days, used when `getEnd` yields nothing. */
|
|
93
|
+
getDuration?: (row: TData) => number | null | undefined;
|
|
94
|
+
getTitle?: (row: TData) => string;
|
|
95
|
+
getProgress?: (row: TData) => number | null | undefined;
|
|
96
|
+
getParent?: (row: TData) => string | null | undefined;
|
|
97
|
+
getMilestone?: (row: TData) => boolean;
|
|
98
|
+
getColor?: (row: TData) => string | undefined;
|
|
99
|
+
};
|
|
100
|
+
/** One row resolved to a bar: local-midnight dates, `end` exclusive. */
|
|
101
|
+
export type ResolvedTask<TData = unknown> = {
|
|
102
|
+
key: string;
|
|
103
|
+
row: TData;
|
|
104
|
+
title: string;
|
|
105
|
+
start: Date;
|
|
106
|
+
/** Exclusive. Equal to `start` for a milestone. */
|
|
107
|
+
end: Date;
|
|
108
|
+
/** 0-100, clamped. */
|
|
109
|
+
progress: number;
|
|
110
|
+
milestone: boolean;
|
|
111
|
+
parentKey: string | null;
|
|
112
|
+
color?: string;
|
|
113
|
+
};
|
|
114
|
+
/**
|
|
115
|
+
* Resolve `rows` into bars. A row with no readable start is SKIPPED - a
|
|
116
|
+
* backlog item with no date is not a bar, and dropping it is better than
|
|
117
|
+
* inventing a date for it.
|
|
118
|
+
*
|
|
119
|
+
* End wins over duration; duration counts working days from the start; with
|
|
120
|
+
* neither the task is a milestone (`end === start`). A date-only end string is
|
|
121
|
+
* inclusive of its day (see the file header).
|
|
122
|
+
*/
|
|
123
|
+
export declare function resolveTasks<TData>(rows: ReadonlyArray<TData>, spec: GanttTaskSpec<TData>, cal: WorkingCalendar): ResolvedTask<TData>[];
|
|
124
|
+
/** One row of the Gantt, in display order. */
|
|
125
|
+
export type GanttNode<TData = unknown> = {
|
|
126
|
+
task: ResolvedTask<TData>;
|
|
127
|
+
/** 0 for a root. */
|
|
128
|
+
depth: number;
|
|
129
|
+
hasChildren: boolean;
|
|
130
|
+
collapsed: boolean;
|
|
131
|
+
/**
|
|
132
|
+
* Present only on a parent: the span and percent rolled up from EVERY
|
|
133
|
+
* descendant, collapsed ones included.
|
|
134
|
+
*/
|
|
135
|
+
summary?: {
|
|
136
|
+
start: Date;
|
|
137
|
+
end: Date;
|
|
138
|
+
progress: number;
|
|
139
|
+
};
|
|
140
|
+
};
|
|
141
|
+
/**
|
|
142
|
+
* Order tasks as a work-breakdown tree: roots in input order, each parent's
|
|
143
|
+
* children directly under it in input order. Rows whose parent id matches no
|
|
144
|
+
* task become roots rather than vanishing - the same rule the grid's tree data
|
|
145
|
+
* uses for a missing parent, and the one that keeps a filtered-out phase from
|
|
146
|
+
* hiding its tasks.
|
|
147
|
+
*
|
|
148
|
+
* Descendants of a collapsed node are left out of the returned list but still
|
|
149
|
+
* feed that node's summary, which is why this walks the full task set rather
|
|
150
|
+
* than the visible rows.
|
|
151
|
+
*
|
|
152
|
+
* A cycle in the parent links (a -> b -> a) is broken at the first repeat and
|
|
153
|
+
* the rows involved are treated as roots, so bad data cannot hang the render.
|
|
154
|
+
*
|
|
155
|
+
* Summary progress is the duration-weighted mean of the LEAF descendants: a
|
|
156
|
+
* two-day task at 100% beside a six-day task at 0% is 25% done, not 50%. A
|
|
157
|
+
* milestone weighs nothing (it has no duration), so a parent holding only
|
|
158
|
+
* milestones falls back to their plain mean.
|
|
159
|
+
*/
|
|
160
|
+
export declare function ganttTree<TData>(tasks: ReadonlyArray<ResolvedTask<TData>>, collapsed?: ReadonlySet<string>): GanttNode<TData>[];
|
|
161
|
+
/** Each visible node's row index, for arrow geometry. */
|
|
162
|
+
export declare function nodeIndex<TData>(nodes: ReadonlyArray<GanttNode<TData>>): Map<string, number>;
|
|
163
|
+
/**
|
|
164
|
+
* Map every task key to the key of the visible row that stands for it: itself
|
|
165
|
+
* when it is on screen, else its nearest visible ancestor. A dependency
|
|
166
|
+
* pointing into a collapsed phase draws to that phase's summary bar instead of
|
|
167
|
+
* vanishing. Keys with no visible ancestor are left out.
|
|
168
|
+
*/
|
|
169
|
+
export declare function visibleAnchor<TData>(nodes: ReadonlyArray<GanttNode<TData>>, tasks: ReadonlyArray<ResolvedTask<TData>>): Map<string, string>;
|
|
170
|
+
/**
|
|
171
|
+
* The date window the chart spans: the earliest start to the latest end, plus
|
|
172
|
+
* `paddingDays` of slack each side, clamped to `minDate` / `maxDate`.
|
|
173
|
+
*
|
|
174
|
+
* Never returns an empty window: with no tasks it centres on `today`, so an
|
|
175
|
+
* empty plan still renders an axis rather than dividing by zero.
|
|
176
|
+
*/
|
|
177
|
+
export declare function projectRange(tasks: ReadonlyArray<ResolvedTask<unknown>>, opts: {
|
|
178
|
+
paddingDays: number;
|
|
179
|
+
today: Date;
|
|
180
|
+
minDate?: DateLike | null;
|
|
181
|
+
maxDate?: DateLike | null;
|
|
182
|
+
}): {
|
|
183
|
+
start: Date;
|
|
184
|
+
end: Date;
|
|
185
|
+
};
|
|
186
|
+
/**
|
|
187
|
+
* Target pixel width of ONE tick per preset. The chart's total width is
|
|
188
|
+
* `ticks.length * ganttTickWidth[zoom]`; individual ticks keep their true
|
|
189
|
+
* proportion of the window (February is narrower than March), so bars and
|
|
190
|
+
* header cells always line up.
|
|
191
|
+
*/
|
|
192
|
+
export declare const ganttTickWidth: Record<GanttZoom, number>;
|
|
193
|
+
/**
|
|
194
|
+
* Build the Gantt's two-row header over `[start, end)` for a zoom preset. The
|
|
195
|
+
* window is snapped OUT to whole tick boundaries so the ticks tile it exactly -
|
|
196
|
+
* a half-drawn first column is where a header and its bars start disagreeing.
|
|
197
|
+
*
|
|
198
|
+
* Returns the scheduler's {@link TimelineAxis} shape (percentages, not pixels)
|
|
199
|
+
* so the Gantt and the scheduler timeline share `timelineGeom` and the same
|
|
200
|
+
* header markup:
|
|
201
|
+
*
|
|
202
|
+
* ```
|
|
203
|
+
* day ticks: days majors: weeks ("14 - 20 Sep")
|
|
204
|
+
* week ticks: days majors: months ("September 2026") <- the default
|
|
205
|
+
* month ticks: weeks majors: months
|
|
206
|
+
* quarter ticks: months majors: quarters ("Q3 2026")
|
|
207
|
+
* year ticks: months majors: years ("2026")
|
|
208
|
+
* ```
|
|
209
|
+
*/
|
|
210
|
+
export declare function ganttAxis(start: Date, end: Date, zoom: GanttZoom, opts?: {
|
|
211
|
+
weekStartsOn?: number;
|
|
212
|
+
today?: Date | null;
|
|
213
|
+
}): TimelineAxis;
|
|
214
|
+
/**
|
|
215
|
+
* One run of the axis at a single density: either drawn at the chart's normal
|
|
216
|
+
* rate, or folded down to a fixed-width gap.
|
|
217
|
+
*/
|
|
218
|
+
export type GanttSegment = {
|
|
219
|
+
start: Date;
|
|
220
|
+
/** Exclusive, like every end in this file. */
|
|
221
|
+
end: Date;
|
|
222
|
+
/** Left edge of this run, in px from the chart's left. */
|
|
223
|
+
x: number;
|
|
224
|
+
/** How wide the run is drawn. */
|
|
225
|
+
px: number;
|
|
226
|
+
collapsed: boolean;
|
|
227
|
+
};
|
|
228
|
+
/**
|
|
229
|
+
* The chart's date <-> pixel mapping, and the one place either direction is
|
|
230
|
+
* computed. Uniform by default; piecewise once whole days are folded out.
|
|
231
|
+
*/
|
|
232
|
+
export type GanttScale = {
|
|
233
|
+
totalPx: number;
|
|
234
|
+
segments: GanttSegment[];
|
|
235
|
+
/** A date's x offset (px) in the chart body. */
|
|
236
|
+
xOf: (d: Date) => number;
|
|
237
|
+
/** The inverse: which date an x offset lands on. */
|
|
238
|
+
dateAt: (x: number) => Date;
|
|
239
|
+
};
|
|
240
|
+
/**
|
|
241
|
+
* Build the scale over `[start, end)`.
|
|
242
|
+
*
|
|
243
|
+
* With no `collapsed` predicate this is the plain linear mapping - one segment,
|
|
244
|
+
* `totalPx` exactly as asked - which is what every chart without the Pro axis
|
|
245
|
+
* uses. Pass one and each run of days it answers true for folds to `gapPx`
|
|
246
|
+
* instead of its real width, so a year of weekends stops eating two sevenths of
|
|
247
|
+
* the chart. Within a gap the mapping stays proportional, so a task that does
|
|
248
|
+
* run over a folded weekend still draws across it rather than collapsing to a
|
|
249
|
+
* line.
|
|
250
|
+
*
|
|
251
|
+
* `gapPx` of 0 removes the folded days outright: Friday's finish and Monday's
|
|
252
|
+
* start land on the same pixel.
|
|
253
|
+
*/
|
|
254
|
+
export declare function ganttScale(start: Date, end: Date, totalPx: number, opts?: {
|
|
255
|
+
collapsed?: ((day: Date) => boolean) | null;
|
|
256
|
+
gapPx?: number;
|
|
257
|
+
}): GanttScale;
|