@svgrid/enterprise 3.0.1 → 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 +680 -0
- package/dist/SvFormulaBar.svelte.d.ts +69 -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 +263 -54
- package/dist/SvPivotDesigner.svelte.d.ts +27 -20
- package/dist/SvRibbonIcon.svelte +46 -0
- package/dist/SvRibbonIcon.svelte.d.ts +17 -0
- package/dist/SvSchemaChart.svelte +4 -2
- package/dist/SvSheet.svelte +7914 -0
- package/dist/SvSheet.svelte.d.ts +215 -0
- package/dist/SvSheetChartSetup.svelte +151 -0
- package/dist/SvSheetChartSetup.svelte.d.ts +18 -0
- package/dist/SvSheetComment.svelte +283 -0
- package/dist/SvSheetComment.svelte.d.ts +22 -0
- package/dist/SvSheetConditionalFormat.svelte +159 -0
- package/dist/SvSheetConditionalFormat.svelte.d.ts +14 -0
- package/dist/SvSheetDataValidation.svelte +273 -0
- package/dist/SvSheetDataValidation.svelte.d.ts +14 -0
- 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 +320 -0
- package/dist/SvSheetFilterMenu.svelte.d.ts +22 -0
- package/dist/SvSheetFindReplace.svelte +132 -0
- package/dist/SvSheetFindReplace.svelte.d.ts +10 -0
- package/dist/SvSheetFormatCells.svelte +465 -0
- package/dist/SvSheetFormatCells.svelte.d.ts +17 -0
- package/dist/SvSheetGoalSeek.svelte +145 -0
- package/dist/SvSheetGoalSeek.svelte.d.ts +12 -0
- package/dist/SvSheetInsertFunction.svelte +149 -0
- package/dist/SvSheetInsertFunction.svelte.d.ts +8 -0
- 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 +91 -0
- package/dist/SvSheetListPicker.svelte.d.ts +10 -0
- package/dist/SvSheetManageRules.svelte +187 -0
- package/dist/SvSheetManageRules.svelte.d.ts +16 -0
- package/dist/SvSheetNameManager.svelte +227 -0
- package/dist/SvSheetNameManager.svelte.d.ts +11 -0
- package/dist/SvSheetPageSetup.svelte +159 -0
- package/dist/SvSheetPageSetup.svelte.d.ts +13 -0
- package/dist/SvSheetPasteSpecial.svelte +107 -0
- package/dist/SvSheetPasteSpecial.svelte.d.ts +12 -0
- 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 +152 -0
- package/dist/SvSheetRemoveDuplicates.svelte.d.ts +12 -0
- package/dist/SvSheetRibbon.svelte +1254 -0
- package/dist/SvSheetRibbon.svelte.d.ts +34 -0
- package/dist/SvSheetSizeDialog.svelte +60 -0
- package/dist/SvSheetSizeDialog.svelte.d.ts +11 -0
- 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 +571 -0
- package/dist/SvSheetTabs.svelte.d.ts +50 -0
- package/dist/SvSheetTabs.test-harness.svelte.d.ts +17 -0
- package/dist/SvSheetTabs.test-harness.svelte.js +22 -0
- package/dist/SvSheetTextToColumns.svelte +172 -0
- package/dist/SvSheetTextToColumns.svelte.d.ts +13 -0
- package/dist/SvSheetValidationAlert.svelte +85 -0
- package/dist/SvSheetValidationAlert.svelte.d.ts +15 -0
- 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 +43538 -6539
- package/dist/designer/assets/GridMenus-8gTNssgV.js +8 -0
- package/dist/designer/assets/SvChartMenu-BDoeqGz6.js +1 -0
- package/dist/designer/assets/SvChartMenu-BYO9cYdy.css +1 -0
- package/dist/designer/assets/SvDateRangeInput-BBRzrQeg.js +1 -0
- package/dist/designer/assets/SvDateTimePicker-DCPg7WGN.js +1 -0
- package/dist/designer/assets/SvGridCellEditor-DMoWJjEI.js +4 -0
- package/dist/designer/assets/SvGridChart-BgLuPO7I.css +1 -0
- package/dist/designer/assets/SvGridChart-Cy1ATrWh.js +3 -0
- package/dist/designer/assets/SvGridChartBuilder-08YWWeqY.css +1 -0
- package/dist/designer/assets/SvGridChartBuilder-eQ3mn0L9.js +1 -0
- package/dist/designer/assets/SvGridChartPanel-4Pc8y5yO.css +1 -0
- package/dist/designer/assets/SvGridChartPanel-CATdVc9X.js +4 -0
- package/dist/designer/assets/{SvGridChartView-DUc-1RUf.css → SvGridChartView-7msfnWZT.css} +1 -1
- package/dist/designer/assets/SvGridChartView-CmsZtCED.js +1 -0
- package/dist/designer/assets/SvGridDropdown-Cjz0H-fI.js +1 -0
- package/dist/designer/assets/SvListBox-BDS66lmZ.js +110 -0
- package/dist/designer/assets/SvMenuList-DJ47ba1h.css +1 -0
- package/dist/designer/assets/SvMenuList-Dgq2D5VN.js +1 -0
- package/dist/designer/assets/SvTabs-2mHC6oaz.js +1 -0
- package/dist/designer/assets/SvTabs-DKmwb5p1.css +1 -0
- package/dist/designer/assets/cell-formatting-BbubJTVz.js +1 -0
- package/dist/designer/assets/chart-Cn7MnNqA.js +1 -0
- package/dist/designer/assets/chart-export-B6bkQ3X8.js +11 -0
- package/dist/designer/assets/chart-export-pdf-BbA28-gt.js +11 -0
- package/dist/designer/assets/chart-panel-messages-Dz7PTIqT.js +1 -0
- package/dist/designer/assets/chart-summary-BD1qYB2R.js +1 -0
- package/dist/designer/assets/chart-trend-B8xr5LuD.js +1 -0
- package/dist/designer/assets/chart-validate-BMqM-qkF.js +1 -0
- package/dist/designer/assets/column-resize-BYDzR1Ve.js +1 -0
- package/dist/designer/assets/date-format-B8JbEtIG.js +1 -0
- package/dist/designer/assets/date-format-DKS-z0xS.css +1 -0
- package/dist/designer/assets/{dismissable-BO547MH9.js → dismissable-ChWRPkoa.js} +1 -1
- package/dist/designer/assets/editor-contract-Bpoa7A5g.js +1 -0
- package/dist/designer/assets/{export-format-D-eP4b2l.js → export-format-DGckmgKr.js} +1 -1
- package/dist/designer/assets/focus-trap-V2-6Fy9I.js +1 -0
- package/dist/designer/assets/{index-C_a9Cj8Y.js → index-D5bVbuzI.js} +318 -315
- package/dist/designer/assets/index-_JVFxt02.css +1 -0
- package/dist/designer/assets/list-option-BP_dWS66.js +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-CITpcm6b.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 +29 -19
- package/dist/export-pdf.d.ts +164 -0
- package/dist/export-pdf.js +346 -15
- package/dist/export.js +25 -10
- 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 +93 -3
- package/dist/index.js +107 -3
- package/dist/install.js +13 -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 +203 -9
- package/dist/pivot-chart.d.ts +25 -1
- package/dist/pivot-chart.js +25 -69
- 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/address.d.ts +43 -0
- package/dist/sheet/address.js +81 -0
- package/dist/sheet/ast.d.ts +138 -0
- package/dist/sheet/ast.js +70 -0
- package/dist/sheet/auto-filter.d.ts +120 -0
- package/dist/sheet/auto-filter.js +295 -0
- package/dist/sheet/autocomplete.d.ts +51 -0
- package/dist/sheet/autocomplete.js +248 -0
- 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 +71 -0
- package/dist/sheet/coerce.js +289 -0
- package/dist/sheet/commands.d.ts +89 -0
- package/dist/sheet/commands.js +230 -0
- package/dist/sheet/comments.d.ts +63 -0
- package/dist/sheet/comments.js +131 -0
- package/dist/sheet/conditional-formats.d.ts +167 -0
- package/dist/sheet/conditional-formats.js +341 -0
- 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 +104 -0
- package/dist/sheet/deps.js +274 -0
- package/dist/sheet/document.d.ts +252 -0
- package/dist/sheet/document.js +465 -0
- package/dist/sheet/edit-keys.d.ts +14 -0
- package/dist/sheet/edit-keys.js +40 -0
- package/dist/sheet/engine.d.ts +67 -0
- package/dist/sheet/engine.js +19 -0
- package/dist/sheet/entry.d.ts +35 -0
- package/dist/sheet/entry.js +226 -0
- 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 +128 -0
- package/dist/sheet/evaluate.js +1049 -0
- package/dist/sheet/filter-files.d.ts +37 -0
- package/dist/sheet/filter-files.js +465 -0
- package/dist/sheet/find-replace.d.ts +62 -0
- package/dist/sheet/find-replace.js +152 -0
- package/dist/sheet/format-store.d.ts +114 -0
- package/dist/sheet/format-store.js +243 -0
- package/dist/sheet/freeze.d.ts +54 -0
- package/dist/sheet/freeze.js +58 -0
- package/dist/sheet/from-rows.d.ts +14 -0
- package/dist/sheet/from-rows.js +50 -0
- package/dist/sheet/function-catalog.d.ts +10 -0
- package/dist/sheet/function-catalog.js +385 -0
- package/dist/sheet/functions.d.ts +28 -0
- package/dist/sheet/functions.js +634 -0
- package/dist/sheet/goal-seek.d.ts +73 -0
- package/dist/sheet/goal-seek.js +153 -0
- package/dist/sheet/index.d.ts +80 -0
- package/dist/sheet/index.js +80 -0
- package/dist/sheet/links.d.ts +57 -0
- package/dist/sheet/links.js +174 -0
- package/dist/sheet/merges.d.ts +71 -0
- package/dist/sheet/merges.js +137 -0
- package/dist/sheet/messages.d.ts +778 -0
- package/dist/sheet/messages.js +806 -0
- package/dist/sheet/names.d.ts +31 -0
- package/dist/sheet/names.js +87 -0
- package/dist/sheet/navigate.d.ts +52 -0
- package/dist/sheet/navigate.js +135 -0
- package/dist/sheet/number-format.d.ts +110 -0
- package/dist/sheet/number-format.js +905 -0
- 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/palette.d.ts +19 -0
- package/dist/sheet/palette.js +84 -0
- package/dist/sheet/parse.d.ts +13 -0
- package/dist/sheet/parse.js +140 -0
- package/dist/sheet/paste-special.d.ts +186 -0
- package/dist/sheet/paste-special.js +601 -0
- 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 +75 -0
- package/dist/sheet/protection.js +101 -0
- package/dist/sheet/rects.d.ts +45 -0
- package/dist/sheet/rects.js +112 -0
- package/dist/sheet/refs.d.ts +130 -0
- package/dist/sheet/refs.js +413 -0
- package/dist/sheet/ribbon-icons.d.ts +31 -0
- package/dist/sheet/ribbon-icons.js +536 -0
- package/dist/sheet/ribbon.d.ts +173 -0
- package/dist/sheet/ribbon.js +1054 -0
- package/dist/sheet/sheet-kinds.d.ts +74 -0
- package/dist/sheet/sheet-kinds.js +91 -0
- package/dist/sheet/shortcuts.d.ts +174 -0
- package/dist/sheet/shortcuts.js +674 -0
- 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/structure.d.ts +87 -0
- package/dist/sheet/structure.js +166 -0
- package/dist/sheet/table-styles.d.ts +74 -0
- package/dist/sheet/table-styles.js +152 -0
- package/dist/sheet/tables.d.ts +89 -0
- package/dist/sheet/tables.js +178 -0
- package/dist/sheet/tokenize.d.ts +71 -0
- package/dist/sheet/tokenize.js +355 -0
- package/dist/sheet/transforms.d.ts +76 -0
- package/dist/sheet/transforms.js +154 -0
- package/dist/sheet/validation.d.ts +108 -0
- package/dist/sheet/validation.js +278 -0
- package/dist/sheet/workbook.d.ts +217 -0
- package/dist/sheet/workbook.js +1120 -0
- 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.d.ts +6 -0
- package/dist/sheet-enable.js +45 -0
- 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 +170 -3
- 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 +36 -6
- package/dist/designer/assets/GridMenus-B1JtIN21.js +0 -8
- package/dist/designer/assets/SvDateRangeInput-CjO7nn_x.js +0 -1
- package/dist/designer/assets/SvDateTimePicker-ByBD_ov6.js +0 -1
- package/dist/designer/assets/SvField-YDLipR6O.css +0 -1
- package/dist/designer/assets/SvField-cj1PFNgZ.js +0 -1
- package/dist/designer/assets/SvGridCellEditor-0W1L2hJ1.js +0 -2
- package/dist/designer/assets/SvGridChart-DBOR4xcz.js +0 -2
- package/dist/designer/assets/SvGridChart-fkMWeh1J.css +0 -1
- package/dist/designer/assets/SvGridChartPanel-symrhNnR.js +0 -11
- package/dist/designer/assets/SvGridChartView-BmRxq6mU.js +0 -1
- package/dist/designer/assets/SvGridDropdown-Bb3HH2Aj.js +0 -1
- package/dist/designer/assets/SvListBox-1oUF6Iav.js +0 -110
- package/dist/designer/assets/cell-formatting-wr5wm7US.js +0 -1
- package/dist/designer/assets/chart-DXFganU8.js +0 -1
- package/dist/designer/assets/column-resize-C_inr5zT.js +0 -1
- package/dist/designer/assets/date-format-DGagAqRc.css +0 -1
- package/dist/designer/assets/date-format-onlYDsrY.js +0 -1
- package/dist/designer/assets/easing-zaypKrr0.js +0 -3
- package/dist/designer/assets/index-k2stW6L8.css +0 -1
- package/dist/designer/assets/row-resize-B0FWHcNr.js +0 -1
- package/dist/designer/assets/src-D9p27OGC.js +0 -58
- package/dist/designer/assets/validate-h-aslRV9.js +0 -1
|
@@ -19,6 +19,8 @@
|
|
|
19
19
|
*
|
|
20
20
|
* SvPivotDesigner {data} {fields} bind:layout
|
|
21
21
|
*/
|
|
22
|
+
import { untrack } from 'svelte'
|
|
23
|
+
|
|
22
24
|
import {
|
|
23
25
|
SvGrid,
|
|
24
26
|
SvGridChart,
|
|
@@ -26,6 +28,7 @@
|
|
|
26
28
|
tableFeatures,
|
|
27
29
|
rowSortingFeature,
|
|
28
30
|
columnFilteringFeature,
|
|
31
|
+
renderComponent,
|
|
29
32
|
renderSnippet,
|
|
30
33
|
portalToBody,
|
|
31
34
|
popIn,
|
|
@@ -35,7 +38,10 @@
|
|
|
35
38
|
type ColumnDef,
|
|
36
39
|
type ChartType,
|
|
37
40
|
type MenuItem,
|
|
41
|
+
type ServerAggregation,
|
|
38
42
|
} from '@svgrid/grid'
|
|
43
|
+
import SvGroupCell from './server/SvGroupCell.svelte'
|
|
44
|
+
import { serverGroupText, type ServerRowModel, type ServerRowModelGridRow } from './server/server-row-model'
|
|
39
45
|
import { createPivotModel, filterCollapsedPivotRows, type PivotRow, type PivotAggregatorId } from './pivot'
|
|
40
46
|
import { pivotToChartSpec } from './pivot-chart'
|
|
41
47
|
import {
|
|
@@ -44,8 +50,8 @@
|
|
|
44
50
|
} from './pivot-designer'
|
|
45
51
|
|
|
46
52
|
type Props = {
|
|
47
|
-
/** Flat input rows. */
|
|
48
|
-
data
|
|
53
|
+
/** Flat input rows. Not read in server mode. */
|
|
54
|
+
data?: T[]
|
|
49
55
|
/** All fields the user can pick from the rail. */
|
|
50
56
|
fields: PivotField<T>[]
|
|
51
57
|
/** The current pivot layout. Bindable so the consumer can persist it. */
|
|
@@ -87,7 +93,8 @@
|
|
|
87
93
|
layout: PivotLayout,
|
|
88
94
|
) => ColumnDef<typeof features, PivotRow>[]
|
|
89
95
|
/** Click handler forwarded to the embedded SvGrid - typically used
|
|
90
|
-
* to drive a drill-through side panel.
|
|
96
|
+
* to drive a drill-through side panel. In server mode `row` is the
|
|
97
|
+
* model's grid row (its `__group` says which group or leaf it is). */
|
|
91
98
|
onCellClick?: (ctx: { columnId: string; row: PivotRow; value: unknown }) => void
|
|
92
99
|
/** Offer a Table <-> Chart view toggle (same layout as a live chart). Default true. */
|
|
93
100
|
chartable?: boolean
|
|
@@ -149,9 +156,29 @@
|
|
|
149
156
|
* narrow the source rows (they drive `layout.filters`). Default false.
|
|
150
157
|
*/
|
|
151
158
|
toolTabs?: boolean
|
|
159
|
+
|
|
160
|
+
// ---- Server mode ----------------------------------------------------
|
|
161
|
+
/**
|
|
162
|
+
* A `createServerRowModel` controller. The designer then drives it
|
|
163
|
+
* instead of pivoting in the browser - Rows become `groupBy`, Columns
|
|
164
|
+
* `pivotBy`, Values `aggregations` - and the embedded grid mounts it
|
|
165
|
+
* through `rowModel`, showing the columns the backend's
|
|
166
|
+
* `pivotResultFields` describe. `data` is not read. The Filters well,
|
|
167
|
+
* the subtotal switches and the chart view are off: filters belong to
|
|
168
|
+
* the grid's own filter UI, footers and totals to the model's options.
|
|
169
|
+
*/
|
|
170
|
+
server?: ServerRowModel<T>
|
|
171
|
+
/** The group column the designer adds in server mode. */
|
|
172
|
+
groupColumn?: { header?: string; width?: number; leafField?: string }
|
|
173
|
+
/**
|
|
174
|
+
* `'immediate'` (default) sends every drag to `onLayoutChange` and the
|
|
175
|
+
* server. `'deferred'` collects edits and shows Apply / Cancel, so one
|
|
176
|
+
* slice-and-dice session is one request.
|
|
177
|
+
*/
|
|
178
|
+
applyMode?: 'immediate' | 'deferred'
|
|
152
179
|
}
|
|
153
180
|
let {
|
|
154
|
-
data,
|
|
181
|
+
data = [],
|
|
155
182
|
fields,
|
|
156
183
|
layout = $bindable<PivotLayout>(defaultLayoutFor([])),
|
|
157
184
|
onLayoutChange,
|
|
@@ -181,8 +208,27 @@
|
|
|
181
208
|
hiddenFields = $bindable<string[]>([]),
|
|
182
209
|
onHiddenFieldsChange,
|
|
183
210
|
toolTabs = false,
|
|
211
|
+
server,
|
|
212
|
+
groupColumn,
|
|
213
|
+
applyMode = 'immediate',
|
|
184
214
|
}: Props = $props()
|
|
185
215
|
|
|
216
|
+
// ---- Deferred apply -------------------------------------------------
|
|
217
|
+
// `layout` is what the wells show; `committed` is what the pivot (or the
|
|
218
|
+
// server) runs. They differ only in deferred mode, between an edit and
|
|
219
|
+
// Apply.
|
|
220
|
+
let committed = $state<PivotLayout>(layout)
|
|
221
|
+
const deferred = $derived(applyMode === 'deferred')
|
|
222
|
+
const applied = $derived(deferred ? committed : layout)
|
|
223
|
+
const dirty = $derived(deferred && JSON.stringify(layout) !== JSON.stringify(committed))
|
|
224
|
+
function applyLayout() {
|
|
225
|
+
committed = layout
|
|
226
|
+
onLayoutChange?.(layout)
|
|
227
|
+
}
|
|
228
|
+
function cancelLayout() {
|
|
229
|
+
layout = committed
|
|
230
|
+
}
|
|
231
|
+
|
|
186
232
|
// ---- Columns / Filters tab rail ----------------------------------
|
|
187
233
|
let activeTab = $state<'columns' | 'filters'>('columns')
|
|
188
234
|
let filterCollapsed = $state<Set<string>>(new Set())
|
|
@@ -224,7 +270,7 @@
|
|
|
224
270
|
return () => window.removeEventListener('mousedown', on)
|
|
225
271
|
})
|
|
226
272
|
|
|
227
|
-
const showPivotToggle = $derived(!!flatColumns)
|
|
273
|
+
const showPivotToggle = $derived(!!flatColumns || !!server)
|
|
228
274
|
function setPivotMode(on: boolean) {
|
|
229
275
|
pivotMode = on
|
|
230
276
|
onPivotModeChange?.(on)
|
|
@@ -236,10 +282,12 @@
|
|
|
236
282
|
$effect.pre(() => {
|
|
237
283
|
if (!layout || (!layout.rows.length && !layout.cols.length && !layout.values.length && !layout.filters.length)) {
|
|
238
284
|
layout = defaultLayoutFor(fields)
|
|
285
|
+
committed = layout
|
|
239
286
|
}
|
|
240
287
|
})
|
|
241
288
|
|
|
242
289
|
const features = tableFeatures({ rowSortingFeature, columnFilteringFeature })
|
|
290
|
+
const filtersWell = $derived(showFiltersWell && !server)
|
|
243
291
|
const uid = `pvd-${Math.random().toString(36).slice(2, 8)}`
|
|
244
292
|
|
|
245
293
|
// Lookup helpers -----------------------------------------------------
|
|
@@ -331,6 +379,7 @@
|
|
|
331
379
|
// ---- Mutation helpers ---------------------------------------------
|
|
332
380
|
function emit(next: PivotLayout) {
|
|
333
381
|
layout = next
|
|
382
|
+
if (deferred) return
|
|
334
383
|
onLayoutChange?.(next)
|
|
335
384
|
}
|
|
336
385
|
function defaultWellFor(field: PivotField<T>): Well {
|
|
@@ -484,9 +533,9 @@
|
|
|
484
533
|
// The pivot model itself has no filtering, but the well clearly should:
|
|
485
534
|
// a Filters chip with `allowed` restricts which rows reach the model.
|
|
486
535
|
const filteredData = $derived.by(() => {
|
|
487
|
-
if (!
|
|
536
|
+
if (!applied.filters.length) return data
|
|
488
537
|
return data.filter((row) => {
|
|
489
|
-
for (const f of
|
|
538
|
+
for (const f of applied.filters) {
|
|
490
539
|
if (f.allowed == null) continue
|
|
491
540
|
const v = row[f.field]
|
|
492
541
|
if (!f.allowed.includes(String(v))) return false
|
|
@@ -499,41 +548,145 @@
|
|
|
499
548
|
// Whenever the layout or data changes, re-run the pivot. Empty layouts
|
|
500
549
|
// are tolerated: the grid will show a friendly empty state.
|
|
501
550
|
const pivot = $derived.by(() => {
|
|
502
|
-
if (
|
|
503
|
-
if (!
|
|
551
|
+
if (server) return null
|
|
552
|
+
if (!applied.values.length && !applied.rows.length && !applied.cols.length) return null
|
|
553
|
+
if (!applied.values.length) return null
|
|
504
554
|
return createPivotModel(filteredData, {
|
|
505
|
-
rows:
|
|
506
|
-
cols:
|
|
507
|
-
values:
|
|
555
|
+
rows: applied.rows as Array<keyof T & string>,
|
|
556
|
+
cols: applied.cols as Array<keyof T & string>,
|
|
557
|
+
values: applied.values.map((v) => ({
|
|
508
558
|
field: v.field as keyof T & string,
|
|
509
559
|
agg: v.agg,
|
|
510
560
|
label: v.label,
|
|
511
561
|
format: v.format,
|
|
512
562
|
})),
|
|
513
|
-
grandTotalRow: !
|
|
514
|
-
grandTotalCol: !
|
|
515
|
-
rowSubtotals: !
|
|
563
|
+
grandTotalRow: !applied.hideGrandTotals,
|
|
564
|
+
grandTotalCol: !applied.hideGrandTotals,
|
|
565
|
+
rowSubtotals: !applied.hideSubtotals,
|
|
516
566
|
})
|
|
517
567
|
})
|
|
518
568
|
$effect(() => {
|
|
519
569
|
if (pivot) onPivot?.(pivot.rows, pivot.columns)
|
|
520
570
|
})
|
|
521
571
|
|
|
572
|
+
// ---- Server mode ----------------------------------------------------
|
|
573
|
+
// The applied layout drives the model in one call, so a designer edit is
|
|
574
|
+
// one reload. Aggregators the contract has no word for are left out.
|
|
575
|
+
const SERVER_FN: Partial<Record<PivotAggregatorId, ServerAggregation['fn']>> = {
|
|
576
|
+
sum: 'sum',
|
|
577
|
+
avg: 'avg',
|
|
578
|
+
min: 'min',
|
|
579
|
+
max: 'max',
|
|
580
|
+
count: 'count',
|
|
581
|
+
}
|
|
582
|
+
$effect(() => {
|
|
583
|
+
if (!server) return
|
|
584
|
+
const l = applied
|
|
585
|
+
server.setLayout({
|
|
586
|
+
groupBy: [...l.rows],
|
|
587
|
+
pivotBy: [...l.cols],
|
|
588
|
+
pivotMode: pivotMode && l.cols.length > 0,
|
|
589
|
+
aggregations: l.values.flatMap((v) => {
|
|
590
|
+
const fn = SERVER_FN[v.agg]
|
|
591
|
+
return fn ? [{ col: v.field, fn }] : []
|
|
592
|
+
}),
|
|
593
|
+
// The same switch the client pivot reads as its total column.
|
|
594
|
+
pivotRowTotals: !l.hideGrandTotals,
|
|
595
|
+
})
|
|
596
|
+
})
|
|
597
|
+
// The model is plain; a version bump re-reads its pivot columns.
|
|
598
|
+
let serverVersion = $state(0)
|
|
599
|
+
$effect(() => {
|
|
600
|
+
if (!server) return
|
|
601
|
+
return server.subscribe(() => {
|
|
602
|
+
serverVersion += 1
|
|
603
|
+
})
|
|
604
|
+
})
|
|
605
|
+
type ServerCol = ColumnDef<typeof features, ServerRowModelGridRow<T>>
|
|
606
|
+
const serverGroupColumn = $derived.by((): ServerCol | null => {
|
|
607
|
+
if (!server) return null
|
|
608
|
+
const model = server
|
|
609
|
+
return {
|
|
610
|
+
id: 'sv-group',
|
|
611
|
+
header: groupColumn?.header ?? 'Group',
|
|
612
|
+
width: groupColumn?.width ?? 260,
|
|
613
|
+
sortable: false,
|
|
614
|
+
filterable: false,
|
|
615
|
+
fieldFn: (row) => serverGroupText(row, groupColumn?.leafField as (keyof T & string) | undefined),
|
|
616
|
+
cell: (ctx) =>
|
|
617
|
+
renderComponent(SvGroupCell, {
|
|
618
|
+
row: ctx.row.original,
|
|
619
|
+
onToggle: () => model.group?.onToggle(ctx.row.original),
|
|
620
|
+
leafField: groupColumn?.leafField,
|
|
621
|
+
}),
|
|
622
|
+
} as ServerCol
|
|
623
|
+
})
|
|
624
|
+
// Pivot off: the group column (when grouping) and the app's own columns.
|
|
625
|
+
const serverColumns = $derived.by((): ServerCol[] => {
|
|
626
|
+
const own = (flatColumns ?? []) as unknown as ServerCol[]
|
|
627
|
+
return applied.rows.length && serverGroupColumn ? [serverGroupColumn, ...own] : own
|
|
628
|
+
})
|
|
629
|
+
// Pivot on: the group column, then the columns the model built from the
|
|
630
|
+
// backend's `pivotResultFields`. Undefined before the first pivoted
|
|
631
|
+
// response, so the grid keeps `serverColumns` until then.
|
|
632
|
+
const serverPivotColumns = $derived.by((): ServerCol[] | undefined => {
|
|
633
|
+
void serverVersion
|
|
634
|
+
if (!server) return undefined
|
|
635
|
+
const cols = server.pivotResultColumns as ServerCol[] | null
|
|
636
|
+
if (!cols) return undefined
|
|
637
|
+
return serverGroupColumn ? [serverGroupColumn, ...cols] : cols
|
|
638
|
+
})
|
|
639
|
+
|
|
522
640
|
// ---- Table <-> Chart view (the same layout as a live pivot chart) ----
|
|
523
|
-
let view = $state<'table' | 'chart'>(defaultView === 'chart' && chartable ? 'chart' : 'table')
|
|
641
|
+
let view = $state<'table' | 'chart'>(untrack(() => (defaultView === 'chart' && chartable ? 'chart' : 'table')))
|
|
524
642
|
let chartType = $state<ChartType>('bar')
|
|
525
643
|
let chartStacked = $state(false)
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
644
|
+
let chartStacked100 = $state(false)
|
|
645
|
+
let chartHorizontal = $state(false)
|
|
646
|
+
// Every shape a pivot's categories + series can take, grouped the way the
|
|
647
|
+
// grid panel groups them. The ones missing (scatter, gauge, box plot,
|
|
648
|
+
// histogram, ranges, bullet, candles) read rows one by one.
|
|
649
|
+
const CHART_TYPES: Array<{ value: ChartType; label: string; group: string }> = [
|
|
650
|
+
{ value: 'bar', label: 'Bar', group: 'Compare' },
|
|
651
|
+
{ value: 'line', label: 'Line', group: 'Compare' },
|
|
652
|
+
{ value: 'area', label: 'Area', group: 'Compare' },
|
|
653
|
+
{ value: 'lollipop', label: 'Lollipop', group: 'Compare' },
|
|
654
|
+
{ value: 'pareto', label: 'Pareto', group: 'Compare' },
|
|
655
|
+
{ value: 'radial-column', label: 'Radial column', group: 'Compare' },
|
|
656
|
+
{ value: 'radial-bar', label: 'Radial bar', group: 'Compare' },
|
|
657
|
+
{ value: 'nightingale', label: 'Nightingale', group: 'Compare' },
|
|
658
|
+
{ value: 'pie', label: 'Pie', group: 'Part of a whole' },
|
|
659
|
+
{ value: 'funnel', label: 'Funnel', group: 'Flow' },
|
|
660
|
+
{ value: 'waterfall', label: 'Waterfall', group: 'Flow' },
|
|
661
|
+
{ value: 'radar', label: 'Radar', group: 'Distribution' },
|
|
662
|
+
{ value: 'heatmap', label: 'Heat map', group: 'Distribution' },
|
|
663
|
+
{ value: 'stream', label: 'Stream', group: 'Over time' },
|
|
531
664
|
]
|
|
532
|
-
const
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
665
|
+
const CHART_GROUPS = [...new Set(CHART_TYPES.map((t) => t.group))]
|
|
666
|
+
const STACKABLE: ChartType[] = ['bar', 'line', 'area', 'radial-column']
|
|
667
|
+
// The measures' formats travel to the chart when they agree; a layout
|
|
668
|
+
// mixing a currency and a count formats plainly rather than putting a "$"
|
|
669
|
+
// on the count. The chip's own format wins over the field's.
|
|
670
|
+
const chartFormat = $derived.by(() => {
|
|
671
|
+
const formats = layout.values.map((v) => v.format ?? fields.find((f) => f.field === v.field)?.format)
|
|
672
|
+
const first = formats[0]
|
|
673
|
+
if (!first) return undefined
|
|
674
|
+
const same = formats.every((f) => f && f.type === first.type && (f.type !== 'currency' || (f as { currency?: string }).currency === (first as { currency?: string }).currency))
|
|
675
|
+
return same ? first : undefined
|
|
676
|
+
})
|
|
677
|
+
const chartSpec = $derived.by(() => {
|
|
678
|
+
if (!pivot || !chartable || view !== 'chart') return null
|
|
679
|
+
const spec = pivotToChartSpec(pivot, {
|
|
680
|
+
type: chartType,
|
|
681
|
+
stacked: chartStacked && STACKABLE.includes(chartType),
|
|
682
|
+
stacked100: chartStacked100 && (chartType === 'bar' || chartType === 'area'),
|
|
683
|
+
format: chartFormat,
|
|
684
|
+
})
|
|
685
|
+
if (chartHorizontal && chartType === 'bar') spec.orientation = 'horizontal'
|
|
686
|
+
// A stream is a stacked area on a wiggle baseline; the box has nothing to add.
|
|
687
|
+
if (chartType === 'stream') { spec.stacked = true; spec.stackOffset = 'wiggle' }
|
|
688
|
+
return spec
|
|
689
|
+
})
|
|
537
690
|
|
|
538
691
|
// ---- Expand / collapse (when `expandable` is on) ------------------
|
|
539
692
|
// We hold a `collapsed` set of pivot row ids; descendants of a
|
|
@@ -797,28 +950,56 @@
|
|
|
797
950
|
{/if}
|
|
798
951
|
</div>
|
|
799
952
|
{/if}
|
|
800
|
-
|
|
801
|
-
<
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
<
|
|
805
|
-
|
|
806
|
-
|
|
953
|
+
{#if !server}
|
|
954
|
+
<label class="pvd-toggle">
|
|
955
|
+
<input type="checkbox" checked={!layout.hideSubtotals} onchange={toggleHideSubtotals} /> Subtotals
|
|
956
|
+
</label>
|
|
957
|
+
<label class="pvd-toggle">
|
|
958
|
+
<input type="checkbox" checked={!layout.hideGrandTotals} onchange={toggleHideGrandTotals} /> Grand totals
|
|
959
|
+
</label>
|
|
960
|
+
{:else}
|
|
961
|
+
<!-- The server model owns its grand-total row (a construction option);
|
|
962
|
+
the switch here is the Total column group, built without a request. -->
|
|
963
|
+
<label class="pvd-toggle">
|
|
964
|
+
<input type="checkbox" checked={!layout.hideGrandTotals} onchange={toggleHideGrandTotals} /> Row totals
|
|
965
|
+
</label>
|
|
966
|
+
{/if}
|
|
967
|
+
{#if deferred}
|
|
968
|
+
<div class="pvd-apply" role="group" aria-label="Apply layout">
|
|
969
|
+
<button type="button" class="pvd-btn pvd-btn-primary" disabled={!dirty} onclick={applyLayout}>Apply</button>
|
|
970
|
+
<button type="button" class="pvd-btn" disabled={!dirty} onclick={cancelLayout}>Cancel</button>
|
|
971
|
+
</div>
|
|
972
|
+
{/if}
|
|
973
|
+
{#if chartable && !server}
|
|
807
974
|
<div class="pvd-viewswitch" role="group" aria-label="View">
|
|
808
975
|
<button type="button" class="pvd-view-btn" class:is-active={view === 'table'} onclick={() => (view = 'table')}>{@render ic('table')} Table</button>
|
|
809
976
|
<button type="button" class="pvd-view-btn" class:is-active={view === 'chart'} onclick={() => (view = 'chart')}>{@render ic('chart')} Chart</button>
|
|
810
977
|
</div>
|
|
811
978
|
{#if view === 'chart'}
|
|
812
979
|
<label class="pvd-toggle">
|
|
813
|
-
<select class="pvd-select" value={chartType} onchange={(e) => (chartType = e.currentTarget.value as ChartType)}>
|
|
814
|
-
{#each
|
|
980
|
+
<select class="pvd-select" aria-label="Chart type" value={chartType} onchange={(e) => (chartType = e.currentTarget.value as ChartType)}>
|
|
981
|
+
{#each CHART_GROUPS as g (g)}
|
|
982
|
+
<optgroup label={g}>
|
|
983
|
+
{#each CHART_TYPES.filter((t) => t.group === g) as t (t.value)}<option value={t.value}>{t.label}</option>{/each}
|
|
984
|
+
</optgroup>
|
|
985
|
+
{/each}
|
|
815
986
|
</select>
|
|
816
987
|
</label>
|
|
817
|
-
{#if chartType
|
|
988
|
+
{#if STACKABLE.includes(chartType)}
|
|
818
989
|
<label class="pvd-toggle">
|
|
819
990
|
<input type="checkbox" checked={chartStacked} onchange={(e) => (chartStacked = e.currentTarget.checked)} /> Stacked
|
|
820
991
|
</label>
|
|
821
992
|
{/if}
|
|
993
|
+
{#if chartType === 'bar' || chartType === 'area'}
|
|
994
|
+
<label class="pvd-toggle">
|
|
995
|
+
<input type="checkbox" checked={chartStacked100} onchange={(e) => (chartStacked100 = e.currentTarget.checked)} /> 100%
|
|
996
|
+
</label>
|
|
997
|
+
{/if}
|
|
998
|
+
{#if chartType === 'bar'}
|
|
999
|
+
<label class="pvd-toggle">
|
|
1000
|
+
<input type="checkbox" checked={chartHorizontal} onchange={(e) => (chartHorizontal = e.currentTarget.checked)} /> Horizontal
|
|
1001
|
+
</label>
|
|
1002
|
+
{/if}
|
|
822
1003
|
{/if}
|
|
823
1004
|
{/if}
|
|
824
1005
|
<div class="pvd-spacer"></div>
|
|
@@ -854,7 +1035,7 @@
|
|
|
854
1035
|
{/if}
|
|
855
1036
|
<div class="pvd-main">
|
|
856
1037
|
{#if showPivotToggle}<div class="pvd-topbar">{@render pivotToggle()}</div>{/if}
|
|
857
|
-
<div class="pvd-wells" class:two={!
|
|
1038
|
+
<div class="pvd-wells" class:two={!filtersWell}>{@render wellsBlock()}</div>
|
|
858
1039
|
{@render gridBlock()}
|
|
859
1040
|
</div>
|
|
860
1041
|
{/if}
|
|
@@ -1048,18 +1229,18 @@
|
|
|
1048
1229
|
|
|
1049
1230
|
{#snippet wellsBlock()}
|
|
1050
1231
|
<!-- Filters -->
|
|
1051
|
-
{#if
|
|
1052
|
-
<div class="pvd-well"
|
|
1232
|
+
{#if filtersWell}
|
|
1233
|
+
<div class="pvd-well" data-well="filters" role="group" aria-label="Filters"
|
|
1053
1234
|
class:drag-over={dragOver === 'filters'}
|
|
1054
1235
|
ondragover={(e) => onDragOver(e, 'filters')}
|
|
1055
1236
|
ondragleave={onDragLeave}
|
|
1056
1237
|
ondrop={(e) => onDrop(e, 'filters')}
|
|
1057
1238
|
oncontextmenu={(e) => openCtx(e, wellMenu('filters'))}>
|
|
1058
1239
|
<div class="pvd-well-head">{@render ic('filter')} Filters</div>
|
|
1059
|
-
<div class="pvd-well-body">
|
|
1240
|
+
<div class="pvd-well-body" role="list">
|
|
1060
1241
|
{#each layout.filters as f (f.field)}
|
|
1061
1242
|
{@const fd = fieldsByName.get(f.field)}
|
|
1062
|
-
<div class="pvd-chip" draggable="true" ondragstart={(e) => onDragStart(e, f.field, 'filters')} oncontextmenu={(e) => openCtx(e, chipMenu('filters', f.field))}>
|
|
1243
|
+
<div class="pvd-chip" role="listitem" draggable="true" ondragstart={(e) => onDragStart(e, f.field, 'filters')} oncontextmenu={(e) => openCtx(e, chipMenu('filters', f.field))}>
|
|
1063
1244
|
<span class="pvd-chip-grip" aria-hidden="true">{@render ic('grip')}</span>
|
|
1064
1245
|
<button type="button" class="pvd-chip-label" title="Choose which values pass" onclick={() => toggleFilterMenu(f.field)}>
|
|
1065
1246
|
{fd?.label ?? f.field}{f.allowed ? `: ${f.allowed.length}` : ''} <span class="pvd-chip-caret">▾</span>
|
|
@@ -1096,17 +1277,17 @@
|
|
|
1096
1277
|
{/if}
|
|
1097
1278
|
|
|
1098
1279
|
<!-- Columns -->
|
|
1099
|
-
<div class="pvd-well"
|
|
1280
|
+
<div class="pvd-well" data-well="cols" role="group" aria-label="Cols"
|
|
1100
1281
|
class:drag-over={dragOver === 'cols'}
|
|
1101
1282
|
ondragover={(e) => onDragOver(e, 'cols')}
|
|
1102
1283
|
ondragleave={onDragLeave}
|
|
1103
1284
|
ondrop={(e) => onDrop(e, 'cols')}
|
|
1104
1285
|
oncontextmenu={(e) => openCtx(e, wellMenu('cols'))}>
|
|
1105
1286
|
<div class="pvd-well-head">{@render ic('columns')} Columns</div>
|
|
1106
|
-
<div class="pvd-well-body">
|
|
1287
|
+
<div class="pvd-well-body" role="list">
|
|
1107
1288
|
{#each layout.cols as field (field)}
|
|
1108
1289
|
{@const fd = fieldsByName.get(field)}
|
|
1109
|
-
<div class="pvd-chip" draggable="true" ondragstart={(e) => onDragStart(e, field, 'cols')} oncontextmenu={(e) => openCtx(e, chipMenu('cols', field))}>
|
|
1290
|
+
<div class="pvd-chip" role="listitem" draggable="true" ondragstart={(e) => onDragStart(e, field, 'cols')} oncontextmenu={(e) => openCtx(e, chipMenu('cols', field))}>
|
|
1110
1291
|
<span class="pvd-chip-grip" aria-hidden="true">{@render ic('grip')}</span>
|
|
1111
1292
|
<span class="pvd-chip-label">{fd?.label ?? field}</span>
|
|
1112
1293
|
<button type="button" class="pvd-chip-x" onclick={() => removeFromWell(field, 'cols')} aria-label="Remove">×</button>
|
|
@@ -1117,17 +1298,17 @@
|
|
|
1117
1298
|
</div>
|
|
1118
1299
|
|
|
1119
1300
|
<!-- Rows -->
|
|
1120
|
-
<div class="pvd-well"
|
|
1301
|
+
<div class="pvd-well" data-well="rows" role="group" aria-label="Rows"
|
|
1121
1302
|
class:drag-over={dragOver === 'rows'}
|
|
1122
1303
|
ondragover={(e) => onDragOver(e, 'rows')}
|
|
1123
1304
|
ondragleave={onDragLeave}
|
|
1124
1305
|
ondrop={(e) => onDrop(e, 'rows')}
|
|
1125
1306
|
oncontextmenu={(e) => openCtx(e, wellMenu('rows'))}>
|
|
1126
1307
|
<div class="pvd-well-head">{@render ic('rows')} Rows</div>
|
|
1127
|
-
<div class="pvd-well-body">
|
|
1308
|
+
<div class="pvd-well-body" role="list">
|
|
1128
1309
|
{#each layout.rows as field (field)}
|
|
1129
1310
|
{@const fd = fieldsByName.get(field)}
|
|
1130
|
-
<div class="pvd-chip" draggable="true" ondragstart={(e) => onDragStart(e, field, 'rows')} oncontextmenu={(e) => openCtx(e, chipMenu('rows', field))}>
|
|
1311
|
+
<div class="pvd-chip" role="listitem" draggable="true" ondragstart={(e) => onDragStart(e, field, 'rows')} oncontextmenu={(e) => openCtx(e, chipMenu('rows', field))}>
|
|
1131
1312
|
<span class="pvd-chip-grip" aria-hidden="true">{@render ic('grip')}</span>
|
|
1132
1313
|
<span class="pvd-chip-label">{fd?.label ?? field}</span>
|
|
1133
1314
|
<button type="button" class="pvd-chip-x" onclick={() => removeFromWell(field, 'rows')} aria-label="Remove">×</button>
|
|
@@ -1138,17 +1319,17 @@
|
|
|
1138
1319
|
</div>
|
|
1139
1320
|
|
|
1140
1321
|
<!-- Values -->
|
|
1141
|
-
<div class="pvd-well"
|
|
1322
|
+
<div class="pvd-well" data-well="values" role="group" aria-label="Values"
|
|
1142
1323
|
class:drag-over={dragOver === 'values'}
|
|
1143
1324
|
ondragover={(e) => onDragOver(e, 'values')}
|
|
1144
1325
|
ondragleave={onDragLeave}
|
|
1145
1326
|
ondrop={(e) => onDrop(e, 'values')}
|
|
1146
1327
|
oncontextmenu={(e) => openCtx(e, wellMenu('values'))}>
|
|
1147
1328
|
<div class="pvd-well-head">{@render ic('sigma')} Values</div>
|
|
1148
|
-
<div class="pvd-well-body">
|
|
1329
|
+
<div class="pvd-well-body" role="list">
|
|
1149
1330
|
{#each layout.values as v, vi (v.field + '|' + v.agg + '|' + vi)}
|
|
1150
1331
|
{@const fd = fieldsByName.get(v.field)}
|
|
1151
|
-
<div class="pvd-chip pvd-chip-value" draggable="true" ondragstart={(e) => onDragStart(e, v.field, 'values', vi)} oncontextmenu={(e) => openCtx(e, chipMenu('values', v.field, vi))}>
|
|
1332
|
+
<div class="pvd-chip pvd-chip-value" role="listitem" draggable="true" ondragstart={(e) => onDragStart(e, v.field, 'values', vi)} oncontextmenu={(e) => openCtx(e, chipMenu('values', v.field, vi))}>
|
|
1152
1333
|
<span class="pvd-chip-grip" aria-hidden="true">{@render ic('grip')}</span>
|
|
1153
1334
|
<button type="button" class="pvd-chip-label" onclick={() => toggleAggMenu(vi)}>
|
|
1154
1335
|
<span class="pvd-chip-agg">{AGG_LABEL[v.agg]}</span>
|
|
@@ -1181,7 +1362,7 @@
|
|
|
1181
1362
|
{#snippet columnsPanel()}
|
|
1182
1363
|
{#if showPivotToggle}{@render pivotToggle()}{/if}
|
|
1183
1364
|
{#if showFieldList}<div class="pvd-panel-rail">{@render railBlock()}</div>{/if}
|
|
1184
|
-
<div class="pvd-wells pvd-wells--vertical" class:two={!
|
|
1365
|
+
<div class="pvd-wells pvd-wells--vertical" class:two={!filtersWell}>{@render wellsBlock()}</div>
|
|
1185
1366
|
{/snippet}
|
|
1186
1367
|
|
|
1187
1368
|
<!-- The Filters tab body: AG-style set filters. Each active column filter is a
|
|
@@ -1247,8 +1428,25 @@
|
|
|
1247
1428
|
|
|
1248
1429
|
{#snippet gridBlock()}
|
|
1249
1430
|
{#if embedGrid}
|
|
1250
|
-
<div class="pvd-grid" style={`height:${typeof gridHeight === 'number' ? gridHeight + 'px' : gridHeight}`} oncontextmenu={(e) => openCtx(e, gridMenu())}>
|
|
1251
|
-
{#if
|
|
1431
|
+
<div class="pvd-grid" role="region" aria-label="Pivot" style={`height:${typeof gridHeight === 'number' ? gridHeight + 'px' : gridHeight}`} oncontextmenu={(e) => openCtx(e, gridMenu())}>
|
|
1432
|
+
{#if server}
|
|
1433
|
+
<SvGrid
|
|
1434
|
+
rowModel={server}
|
|
1435
|
+
columns={serverColumns}
|
|
1436
|
+
pivotResultColumns={pivotMode ? serverPivotColumns : undefined}
|
|
1437
|
+
features={features}
|
|
1438
|
+
sortable
|
|
1439
|
+
selectionMode="none"
|
|
1440
|
+
rowHeight={32}
|
|
1441
|
+
containerHeight="100%"
|
|
1442
|
+
fitColumns={gridFitColumns}
|
|
1443
|
+
columnVirtualization={columnVirtualization}
|
|
1444
|
+
enableRowSummaries={false}
|
|
1445
|
+
onCellClick={onCellClick
|
|
1446
|
+
? (e) => onCellClick({ columnId: e.columnId, row: e.row as unknown as PivotRow, value: e.value })
|
|
1447
|
+
: undefined}
|
|
1448
|
+
/>
|
|
1449
|
+
{:else if showPivotToggle && !pivotMode}
|
|
1252
1450
|
<SvGrid
|
|
1253
1451
|
data={filteredData}
|
|
1254
1452
|
columns={visibleFlatColumns!}
|
|
@@ -1264,7 +1462,9 @@
|
|
|
1264
1462
|
/>
|
|
1265
1463
|
{:else if pivot && chartable && view === 'chart'}
|
|
1266
1464
|
{#if chartSpec && chartSpec.series.length}
|
|
1267
|
-
|
|
1465
|
+
<!-- The chart's own toolbar (PNG / SVG / PDF / print / copy) and the
|
|
1466
|
+
spoken summary, at the pane's size. -->
|
|
1467
|
+
<div class="pvd-chart"><SvGridChart spec={chartSpec} interactive legend="bottom" toolbar describe autosize /></div>
|
|
1268
1468
|
{:else}
|
|
1269
1469
|
<div class="pvd-empty pvd-grid-empty">Add a measure and a row / column field to chart the pivot.</div>
|
|
1270
1470
|
{/if}
|
|
@@ -1375,6 +1575,15 @@
|
|
|
1375
1575
|
border-color: var(--sg-accent, #2563eb);
|
|
1376
1576
|
}
|
|
1377
1577
|
.pvd-btn-primary:hover { opacity: 0.9; }
|
|
1578
|
+
.pvd-btn:disabled { opacity: 0.5; cursor: default; }
|
|
1579
|
+
/* Apply with nothing to apply reads as off, not as a paler Apply. */
|
|
1580
|
+
.pvd-btn-primary:disabled {
|
|
1581
|
+
opacity: 1;
|
|
1582
|
+
background: var(--sg-header-bg, #f1f5f9);
|
|
1583
|
+
border-color: var(--sg-border, #e2e8f0);
|
|
1584
|
+
color: var(--sg-muted, #64748b);
|
|
1585
|
+
}
|
|
1586
|
+
.pvd-apply { display: inline-flex; gap: 6px; }
|
|
1378
1587
|
.pvd-toggle {
|
|
1379
1588
|
display: inline-flex;
|
|
1380
1589
|
align-items: center;
|
|
@@ -1,28 +1,12 @@
|
|
|
1
1
|
type PivotInputRow = Record<string, unknown>;
|
|
2
|
-
/**
|
|
3
|
-
* SvPivotDesigner - Excel-style pivot table designer.
|
|
4
|
-
*
|
|
5
|
-
* Self-contained, controlled component. The consumer holds the data
|
|
6
|
-
* + the field list + the layout state; everything else (drag-and-drop,
|
|
7
|
-
* chip menus, search, presets, the inline pivot grid) is built in.
|
|
8
|
-
*
|
|
9
|
-
* Minimal wire-up (in a .svelte file):
|
|
10
|
-
* const fields = [
|
|
11
|
-
* { field: 'region', label: 'Region', kind: 'dimension' },
|
|
12
|
-
* { field: 'quarter', label: 'Quarter', kind: 'dimension' },
|
|
13
|
-
* { field: 'amount', label: 'Revenue', kind: 'measure', defaultAgg: 'sum' },
|
|
14
|
-
* ]
|
|
15
|
-
* let layout = $state(defaultLayoutFor(fields))
|
|
16
|
-
*
|
|
17
|
-
* SvPivotDesigner {data} {fields} bind:layout
|
|
18
|
-
*/
|
|
19
2
|
import { type ColumnDef } from '@svgrid/grid';
|
|
3
|
+
import { type ServerRowModel } from './server/server-row-model.js';
|
|
20
4
|
import { type PivotRow, type PivotAggregatorId } from './pivot.js';
|
|
21
5
|
import { type PivotField, type PivotLayout, type PivotPreset } from './pivot-designer.js';
|
|
22
6
|
declare function $$render<T extends PivotInputRow>(): {
|
|
23
7
|
props: {
|
|
24
|
-
/** Flat input rows. */
|
|
25
|
-
data
|
|
8
|
+
/** Flat input rows. Not read in server mode. */
|
|
9
|
+
data?: T[];
|
|
26
10
|
/** All fields the user can pick from the rail. */
|
|
27
11
|
fields: PivotField<T>[];
|
|
28
12
|
/** The current pivot layout. Bindable so the consumer can persist it. */
|
|
@@ -80,7 +64,8 @@ declare function $$render<T extends PivotInputRow>(): {
|
|
|
80
64
|
};
|
|
81
65
|
}, PivotRow>[];
|
|
82
66
|
/** Click handler forwarded to the embedded SvGrid - typically used
|
|
83
|
-
* to drive a drill-through side panel.
|
|
67
|
+
* to drive a drill-through side panel. In server mode `row` is the
|
|
68
|
+
* model's grid row (its `__group` says which group or leaf it is). */
|
|
84
69
|
onCellClick?: (ctx: {
|
|
85
70
|
columnId: string;
|
|
86
71
|
row: PivotRow;
|
|
@@ -151,6 +136,28 @@ declare function $$render<T extends PivotInputRow>(): {
|
|
|
151
136
|
* narrow the source rows (they drive `layout.filters`). Default false.
|
|
152
137
|
*/
|
|
153
138
|
toolTabs?: boolean;
|
|
139
|
+
/**
|
|
140
|
+
* A `createServerRowModel` controller. The designer then drives it
|
|
141
|
+
* instead of pivoting in the browser - Rows become `groupBy`, Columns
|
|
142
|
+
* `pivotBy`, Values `aggregations` - and the embedded grid mounts it
|
|
143
|
+
* through `rowModel`, showing the columns the backend's
|
|
144
|
+
* `pivotResultFields` describe. `data` is not read. The Filters well,
|
|
145
|
+
* the subtotal switches and the chart view are off: filters belong to
|
|
146
|
+
* the grid's own filter UI, footers and totals to the model's options.
|
|
147
|
+
*/
|
|
148
|
+
server?: ServerRowModel<T>;
|
|
149
|
+
/** The group column the designer adds in server mode. */
|
|
150
|
+
groupColumn?: {
|
|
151
|
+
header?: string;
|
|
152
|
+
width?: number;
|
|
153
|
+
leafField?: string;
|
|
154
|
+
};
|
|
155
|
+
/**
|
|
156
|
+
* `'immediate'` (default) sends every drag to `onLayoutChange` and the
|
|
157
|
+
* server. `'deferred'` collects edits and shows Apply / Cancel, so one
|
|
158
|
+
* slice-and-dice session is one request.
|
|
159
|
+
*/
|
|
160
|
+
applyMode?: "immediate" | "deferred";
|
|
154
161
|
};
|
|
155
162
|
exports: {};
|
|
156
163
|
bindings: "pivotMode" | "layout" | "hiddenFields";
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* One ribbon icon, by name, at any size.
|
|
4
|
+
*
|
|
5
|
+
* The paths live in `sheet/ribbon-icons.ts` on a 16-unit grid; the SVG
|
|
6
|
+
* scales them, so a large button gets the same drawing at 32px without a
|
|
7
|
+
* second set. Everything is drawn in `currentColor`: the icon is the
|
|
8
|
+
* colour of the text around it, black on a light ribbon and white on a
|
|
9
|
+
* dark one, and nothing in the set carries a colour of its own.
|
|
10
|
+
*/
|
|
11
|
+
import { RIBBON_ICONS, type RibbonIconName } from './sheet/ribbon-icons'
|
|
12
|
+
|
|
13
|
+
let { name, size = 16 }: { name: RibbonIconName; size?: number } = $props()
|
|
14
|
+
|
|
15
|
+
const paths = $derived(RIBBON_ICONS[name] ?? [])
|
|
16
|
+
</script>
|
|
17
|
+
|
|
18
|
+
<svg
|
|
19
|
+
class="sv-ribbon-icon"
|
|
20
|
+
width={size}
|
|
21
|
+
height={size}
|
|
22
|
+
viewBox="0 0 16 16"
|
|
23
|
+
fill="none"
|
|
24
|
+
stroke="currentColor"
|
|
25
|
+
stroke-width="1.4"
|
|
26
|
+
stroke-linecap="round"
|
|
27
|
+
stroke-linejoin="round"
|
|
28
|
+
aria-hidden="true"
|
|
29
|
+
focusable="false"
|
|
30
|
+
>
|
|
31
|
+
{#each paths as path, i (i)}
|
|
32
|
+
<path
|
|
33
|
+
d={path.d}
|
|
34
|
+
fill={path.fill ? 'currentColor' : 'none'}
|
|
35
|
+
stroke-width={path.width}
|
|
36
|
+
stroke-dasharray={path.dash}
|
|
37
|
+
/>
|
|
38
|
+
{/each}
|
|
39
|
+
</svg>
|
|
40
|
+
|
|
41
|
+
<style>
|
|
42
|
+
.sv-ribbon-icon {
|
|
43
|
+
display: block;
|
|
44
|
+
flex: 0 0 auto;
|
|
45
|
+
}
|
|
46
|
+
</style>
|