@svgrid/enterprise 3.0.2 → 3.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +94 -24
- package/README.md +36 -4
- package/dist/SvAdvancedFilter.svelte +1 -1
- package/dist/SvAlertsManager.svelte +2 -1
- package/dist/SvBoard.svelte +2 -1
- package/dist/SvExportMenu.svelte +4 -1
- package/dist/SvExportMenu.svelte.d.ts +0 -13
- package/dist/SvExpressionEditor.svelte +3 -3
- package/dist/SvFormulaBar.svelte +94 -20
- package/dist/SvFormulaBar.svelte.d.ts +7 -0
- package/dist/SvGridAlerts.svelte +49 -9
- package/dist/SvGridBoard.svelte +13 -8
- package/dist/SvGridBulkEditDrawer.svelte +26 -2
- package/dist/SvGridEditPanel.svelte +3 -0
- package/dist/SvGridScheduler.svelte +69 -40
- package/dist/SvGridSelectionBar.svelte +10 -3
- package/dist/SvPivotDesigner.svelte +198 -40
- package/dist/SvPivotDesigner.svelte.d.ts +27 -20
- package/dist/SvSheet.svelte +4043 -243
- package/dist/SvSheet.svelte.d.ts +76 -3
- package/dist/SvSheetChartSetup.svelte +151 -0
- package/dist/SvSheetChartSetup.svelte.d.ts +18 -0
- package/dist/SvSheetComment.svelte +216 -31
- package/dist/SvSheetComment.svelte.d.ts +11 -11
- package/dist/SvSheetConditionalFormat.svelte +28 -31
- package/dist/SvSheetDataValidation.svelte +66 -42
- package/dist/SvSheetEditRanges.svelte +217 -0
- package/dist/SvSheetEditRanges.svelte.d.ts +15 -0
- package/dist/SvSheetErrors.svelte +125 -0
- package/dist/SvSheetErrors.svelte.d.ts +20 -0
- package/dist/SvSheetEvaluate.svelte +133 -0
- package/dist/SvSheetEvaluate.svelte.d.ts +15 -0
- package/dist/SvSheetFilterMenu.svelte +137 -34
- package/dist/SvSheetFilterMenu.svelte.d.ts +5 -0
- package/dist/SvSheetFindReplace.svelte +19 -19
- package/dist/SvSheetFormatCells.svelte +125 -81
- package/dist/SvSheetGoalSeek.svelte +17 -16
- package/dist/SvSheetInsertFunction.svelte +15 -13
- package/dist/SvSheetIteration.svelte +81 -0
- package/dist/SvSheetIteration.svelte.d.ts +10 -0
- package/dist/SvSheetLink.svelte +99 -0
- package/dist/SvSheetLink.svelte.d.ts +17 -0
- package/dist/SvSheetListPicker.svelte +4 -2
- package/dist/SvSheetListPicker.svelte.d.ts +0 -6
- package/dist/SvSheetManageRules.svelte +20 -18
- package/dist/SvSheetNameManager.svelte +17 -15
- package/dist/SvSheetPageSetup.svelte +159 -0
- package/dist/SvSheetPageSetup.svelte.d.ts +13 -0
- package/dist/SvSheetPasteSpecial.svelte +22 -20
- package/dist/SvSheetPivot.svelte +220 -0
- package/dist/SvSheetPivot.svelte.d.ts +21 -0
- package/dist/SvSheetProtectSheet.svelte +81 -0
- package/dist/SvSheetProtectSheet.svelte.d.ts +11 -0
- package/dist/SvSheetRemoveDuplicates.svelte +13 -10
- package/dist/SvSheetRibbon.svelte +104 -51
- package/dist/SvSheetSizeDialog.svelte +4 -2
- package/dist/SvSheetSort.svelte +218 -0
- package/dist/SvSheetSort.svelte.d.ts +28 -0
- package/dist/SvSheetSparklines.svelte +135 -0
- package/dist/SvSheetSparklines.svelte.d.ts +14 -0
- package/dist/SvSheetTable.svelte +160 -0
- package/dist/SvSheetTable.svelte.d.ts +24 -0
- package/dist/SvSheetTabs.svelte +161 -31
- package/dist/SvSheetTabs.svelte.d.ts +22 -8
- package/dist/SvSheetTextToColumns.svelte +20 -20
- package/dist/SvSheetValidationAlert.svelte +8 -6
- package/dist/advanced-filter-enable.js +1 -1
- package/dist/alerts/alert-engine.d.ts +6 -0
- package/dist/alerts/alert-engine.js +21 -4
- package/dist/alerts/alert-formats.js +2 -0
- package/dist/alerts/alert-types.d.ts +1 -1
- package/dist/alerts.d.ts +1 -1
- package/dist/alerts.js +2 -2
- package/dist/board.js +2 -2
- package/dist/bulk-edit.d.ts +3 -1
- package/dist/bulk-edit.js +1 -1
- package/dist/cdn/svgrid-enterprise.svelte-external.js +39827 -16429
- package/dist/designer/assets/GridMenus-8gTNssgV.js +8 -0
- package/dist/designer/assets/{SvChartMenu-D9hEeHar.js → SvChartMenu-BDoeqGz6.js} +1 -1
- package/dist/designer/assets/{SvDateTimePicker-DARvKUL2.js → SvDateTimePicker-DCPg7WGN.js} +1 -1
- package/dist/designer/assets/SvGridCellEditor-DMoWJjEI.js +4 -0
- package/dist/designer/assets/{SvGridChart-B8j1SSy3.js → SvGridChart-Cy1ATrWh.js} +2 -2
- package/dist/designer/assets/SvGridChartBuilder-eQ3mn0L9.js +1 -0
- package/dist/designer/assets/{SvGridChartPanel-pT6ITc2P.js → SvGridChartPanel-CATdVc9X.js} +3 -3
- package/dist/designer/assets/{SvGridChartView-bg281UA1.js → SvGridChartView-CmsZtCED.js} +1 -1
- package/dist/designer/assets/SvGridDropdown-Cjz0H-fI.js +1 -0
- package/dist/designer/assets/{SvTabs-UFCMTHXS.js → SvTabs-2mHC6oaz.js} +1 -1
- package/dist/designer/assets/cell-formatting-BbubJTVz.js +1 -0
- package/dist/designer/assets/{chart-cIPUsbM5.js → chart-Cn7MnNqA.js} +1 -1
- package/dist/designer/assets/{chart-panel-messages-DtTxpBUU.js → chart-panel-messages-Dz7PTIqT.js} +1 -1
- package/dist/designer/assets/{chart-summary-Czu_5epb.js → chart-summary-BD1qYB2R.js} +1 -1
- package/dist/designer/assets/{chart-trend-D5I5VEe8.js → chart-trend-B8xr5LuD.js} +1 -1
- package/dist/designer/assets/{dismissable-BO547MH9.js → dismissable-ChWRPkoa.js} +1 -1
- package/dist/designer/assets/{export-format-D-eP4b2l.js → export-format-DGckmgKr.js} +1 -1
- package/dist/designer/assets/{focus-trap-CAreAhlU.js → focus-trap-V2-6Fy9I.js} +1 -1
- package/dist/designer/assets/{index-DwU7CAMm.js → index-D5bVbuzI.js} +317 -315
- package/dist/designer/assets/index-_JVFxt02.css +1 -0
- package/dist/designer/assets/row-resize-BInFWCpr.js +1 -0
- package/dist/designer/assets/server-block-cache-CXJKkJpy.js +1 -0
- package/dist/designer/assets/src-DUQ4xE3x.js +58 -0
- package/dist/designer/assets/validate-C3B8QKsM.js +1 -0
- package/dist/designer/index.html +17 -16
- package/dist/export-pdf.d.ts +75 -0
- package/dist/export-pdf.js +216 -15
- package/dist/export.js +10 -2
- package/dist/gantt/SvGridGantt.svelte +2890 -0
- package/dist/gantt/SvGridGantt.svelte.d.ts +30 -0
- package/dist/gantt/gantt-config.d.ts +73 -0
- package/dist/gantt/gantt-config.js +1 -0
- package/dist/gantt/gantt-critical-path.d.ts +67 -0
- package/dist/gantt/gantt-critical-path.js +207 -0
- package/dist/gantt/gantt-model.d.ts +257 -0
- package/dist/gantt/gantt-model.js +651 -0
- package/dist/gantt/gantt-resources.d.ts +59 -0
- package/dist/gantt/gantt-resources.js +71 -0
- package/dist/gantt/gantt.d.ts +7 -0
- package/dist/gantt/gantt.js +36 -0
- package/dist/gantt/index.d.ts +15 -0
- package/dist/gantt/index.js +22 -0
- package/dist/gantt/timeline-arrows.d.ts +102 -0
- package/dist/gantt/timeline-arrows.js +181 -0
- package/dist/import.d.ts +2 -2
- package/dist/import.js +1 -1
- package/dist/index.d.ts +34 -7
- package/dist/index.js +44 -7
- package/dist/install.js +8 -1
- package/dist/license-core.d.ts +17 -1
- package/dist/license-core.js +16 -5
- package/dist/license.d.ts +18 -2
- package/dist/license.js +71 -6
- package/dist/node/studio.js +140 -8
- package/dist/pivot-enable.js +2 -2
- package/dist/scheduler-dependencies.d.ts +35 -0
- package/dist/scheduler-dependencies.js +36 -1
- package/dist/scheduler.js +2 -2
- package/dist/selection-bar.js +2 -2
- package/dist/server/SvGroupCell.svelte +213 -0
- package/dist/server/SvGroupCell.svelte.d.ts +62 -0
- package/dist/server/SvRowGroupPanel.svelte +322 -0
- package/dist/server/SvRowGroupPanel.svelte.d.ts +37 -0
- package/dist/server/enable.d.ts +17 -0
- package/dist/server/enable.js +49 -0
- package/dist/server/index.d.ts +22 -0
- package/dist/server/index.js +24 -0
- package/dist/server/messages.d.ts +45 -0
- package/dist/server/messages.js +35 -0
- package/dist/server/server-group-model.d.ts +104 -0
- package/dist/server/server-group-model.js +272 -0
- package/dist/server/server-pivot.d.ts +46 -0
- package/dist/server/server-pivot.js +57 -0
- package/dist/server/server-row-model.d.ts +547 -0
- package/dist/server/server-row-model.js +1551 -0
- package/dist/server/server-selection.d.ts +99 -0
- package/dist/server/server-selection.js +215 -0
- package/dist/server/svgrid-adapter.d.ts +155 -0
- package/dist/server/svgrid-adapter.js +202 -0
- package/dist/sheet/ast.d.ts +45 -1
- package/dist/sheet/ast.js +14 -0
- package/dist/sheet/auto-filter.d.ts +58 -4
- package/dist/sheet/auto-filter.js +159 -11
- package/dist/sheet/autocomplete.d.ts +9 -0
- package/dist/sheet/autocomplete.js +90 -4
- package/dist/sheet/cell-images.d.ts +39 -0
- package/dist/sheet/cell-images.js +90 -0
- package/dist/sheet/cell-types.d.ts +58 -0
- package/dist/sheet/cell-types.js +96 -0
- package/dist/sheet/coerce.d.ts +40 -0
- package/dist/sheet/coerce.js +170 -3
- package/dist/sheet/comments.d.ts +43 -9
- package/dist/sheet/comments.js +85 -27
- package/dist/sheet/conditional-formats.d.ts +29 -6
- package/dist/sheet/conditional-formats.js +37 -12
- package/dist/sheet/csv.d.ts +32 -0
- package/dist/sheet/csv.js +158 -0
- package/dist/sheet/culture.d.ts +87 -0
- package/dist/sheet/culture.js +247 -0
- package/dist/sheet/delta.d.ts +102 -0
- package/dist/sheet/delta.js +203 -0
- package/dist/sheet/deps.d.ts +45 -1
- package/dist/sheet/deps.js +77 -2
- package/dist/sheet/document.d.ts +106 -4
- package/dist/sheet/document.js +204 -3
- package/dist/sheet/engine.d.ts +67 -0
- package/dist/sheet/engine.js +19 -0
- package/dist/sheet/entry.d.ts +8 -4
- package/dist/sheet/entry.js +171 -21
- package/dist/sheet/error-check.d.ts +49 -0
- package/dist/sheet/error-check.js +83 -0
- package/dist/sheet/evaluate-steps.d.ts +48 -0
- package/dist/sheet/evaluate-steps.js +196 -0
- package/dist/sheet/evaluate.d.ts +67 -0
- package/dist/sheet/evaluate.js +725 -13
- package/dist/sheet/filter-files.d.ts +37 -0
- package/dist/sheet/filter-files.js +465 -0
- package/dist/sheet/format-store.d.ts +15 -0
- package/dist/sheet/format-store.js +11 -1
- package/dist/sheet/from-rows.d.ts +14 -0
- package/dist/sheet/from-rows.js +50 -0
- package/dist/sheet/function-catalog.d.ts +1 -1
- package/dist/sheet/function-catalog.js +296 -5
- package/dist/sheet/functions.js +363 -91
- package/dist/sheet/index.d.ts +35 -8
- package/dist/sheet/index.js +35 -8
- package/dist/sheet/links.d.ts +57 -0
- package/dist/sheet/links.js +174 -0
- package/dist/sheet/messages.d.ts +778 -0
- package/dist/sheet/messages.js +806 -0
- package/dist/sheet/number-format.d.ts +52 -5
- package/dist/sheet/number-format.js +465 -68
- package/dist/sheet/objects.d.ts +106 -0
- package/dist/sheet/objects.js +149 -0
- package/dist/sheet/ods-document.d.ts +44 -0
- package/dist/sheet/ods-document.js +1275 -0
- package/dist/sheet/open-file.d.ts +26 -0
- package/dist/sheet/open-file.js +56 -0
- package/dist/sheet/outline.d.ts +82 -0
- package/dist/sheet/outline.js +228 -0
- package/dist/sheet/packs/array.d.ts +16 -0
- package/dist/sheet/packs/array.js +172 -0
- package/dist/sheet/packs/database.d.ts +42 -0
- package/dist/sheet/packs/database.js +142 -0
- package/dist/sheet/packs/engineering.d.ts +2 -0
- package/dist/sheet/packs/engineering.js +296 -0
- package/dist/sheet/packs/financial.d.ts +5 -0
- package/dist/sheet/packs/financial.js +220 -0
- package/dist/sheet/packs/math-stats.d.ts +2 -0
- package/dist/sheet/packs/math-stats.js +372 -0
- package/dist/sheet/packs/special.d.ts +44 -0
- package/dist/sheet/packs/special.js +187 -0
- package/dist/sheet/packs/stats-dist.d.ts +2 -0
- package/dist/sheet/packs/stats-dist.js +785 -0
- package/dist/sheet/packs/text-date.d.ts +2 -0
- package/dist/sheet/packs/text-date.js +332 -0
- package/dist/sheet/packs/trig.d.ts +2 -0
- package/dist/sheet/packs/trig.js +73 -0
- package/dist/sheet/page-setup.d.ts +73 -0
- package/dist/sheet/page-setup.js +73 -0
- package/dist/sheet/parse.js +42 -10
- package/dist/sheet/paste-special.d.ts +22 -0
- package/dist/sheet/paste-special.js +14 -5
- package/dist/sheet/pivot-range.d.ts +160 -0
- package/dist/sheet/pivot-range.js +333 -0
- package/dist/sheet/presence.d.ts +73 -0
- package/dist/sheet/presence.js +79 -0
- package/dist/sheet/print.d.ts +104 -0
- package/dist/sheet/print.js +169 -0
- package/dist/sheet/protection.d.ts +55 -1
- package/dist/sheet/protection.js +55 -2
- package/dist/sheet/rects.d.ts +1 -1
- package/dist/sheet/refs.d.ts +48 -0
- package/dist/sheet/refs.js +155 -8
- package/dist/sheet/ribbon-icons.d.ts +1 -1
- package/dist/sheet/ribbon-icons.js +186 -0
- package/dist/sheet/ribbon.d.ts +1 -1
- package/dist/sheet/ribbon.js +324 -23
- package/dist/sheet/sheet-kinds.d.ts +74 -0
- package/dist/sheet/sheet-kinds.js +91 -0
- package/dist/sheet/shortcuts.d.ts +13 -3
- package/dist/sheet/shortcuts.js +63 -12
- package/dist/sheet/sort.d.ts +51 -0
- package/dist/sheet/sort.js +107 -0
- package/dist/sheet/sparklines.d.ts +111 -0
- package/dist/sheet/sparklines.js +204 -0
- package/dist/sheet/table-styles.d.ts +74 -0
- package/dist/sheet/table-styles.js +152 -0
- package/dist/sheet/tables.d.ts +19 -0
- package/dist/sheet/tables.js +31 -0
- package/dist/sheet/tokenize.d.ts +18 -1
- package/dist/sheet/tokenize.js +60 -9
- package/dist/sheet/validation.d.ts +16 -0
- package/dist/sheet/validation.js +37 -0
- package/dist/sheet/workbook.d.ts +148 -3
- package/dist/sheet/workbook.js +742 -31
- package/dist/sheet/xls-cfb.d.ts +32 -0
- package/dist/sheet/xls-cfb.js +290 -0
- package/dist/sheet/xls-document.d.ts +10 -0
- package/dist/sheet/xls-document.js +1243 -0
- package/dist/sheet/xls-formula.d.ts +40 -0
- package/dist/sheet/xls-formula.js +569 -0
- package/dist/sheet/xlsx-document.d.ts +108 -0
- package/dist/sheet/xlsx-document.js +1849 -0
- package/dist/sheet/xlsx-drawing.d.ts +99 -0
- package/dist/sheet/xlsx-drawing.js +420 -0
- package/dist/sheet-enable.js +6 -7
- package/dist/sheet-text.d.ts +7 -0
- package/dist/sheet-text.js +29 -0
- package/dist/sources/auth-supabase.js +2 -2
- package/dist/sources/realtime-supabase.js +2 -2
- package/dist/sources/rest.d.ts +6 -2
- package/dist/sources/rest.js +42 -7
- package/dist/sources/supabase.d.ts +10 -1
- package/dist/sources/supabase.js +73 -40
- package/dist/studio/emit-project.js +14 -1
- package/dist/studio/index.js +1 -1
- package/dist/studio/project.d.ts +11 -2
- package/dist/studio/project.js +5 -2
- package/dist/studio/ui-components.generated.js +107 -2
- package/dist/sveltekit/in-memory.d.ts +2 -2
- package/dist/sveltekit/in-memory.js +125 -4
- package/dist/sveltekit/index.d.ts +1 -1
- package/dist/sveltekit/index.js +1 -1
- package/dist/sveltekit/query-plan.d.ts +50 -4
- package/dist/sveltekit/query-plan.js +25 -3
- package/dist/sveltekit/sql-source.d.ts +6 -0
- package/dist/sveltekit/sql-source.js +34 -6
- package/dist/sveltekit/sql.d.ts +31 -0
- package/dist/sveltekit/sql.js +135 -25
- package/dist/sveltekit/transport.d.ts +10 -2
- package/dist/sveltekit/transport.js +30 -6
- package/dist/upgrade-prompt.d.ts +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/watermark.js +35 -2
- package/dist/wc/GridMenus-By9vPuq0.js +1088 -0
- package/dist/wc/SvChartMenu-CQNrQGT2.js +308 -0
- package/dist/wc/SvDateRangeInput-DR6m7bSM.js +199 -0
- package/dist/wc/SvDateTimePicker-D-vRnaMo.js +771 -0
- package/dist/wc/SvField-B_kurx_P.js +149 -0
- package/dist/wc/SvGrid.helpers-BdVDtjUm.js +135 -0
- package/dist/wc/SvGridCellEditor-Bnf1Kr5C.js +560 -0
- package/dist/wc/SvGridChart-BqUJh2pG.js +3572 -0
- package/dist/wc/SvGridChartBuilder-CGycC5cn.js +988 -0
- package/dist/wc/SvGridChartPanel-CRnizsHD.js +1746 -0
- package/dist/wc/SvGridChartView-D1pa_xMy.js +47 -0
- package/dist/wc/SvGridDropdown-45WsObLL.js +259 -0
- package/dist/wc/SvModal-DrfOYYyX.js +189 -0
- package/dist/wc/cell-formatting-CBfgahv1.js +86 -0
- package/dist/wc/chart-6OXlybVT.js +4341 -0
- package/dist/wc/chart-export-CeSADGfi.js +135 -0
- package/dist/wc/chart-export-pdf-BGko7MER.js +104 -0
- package/dist/wc/chart-summary-2m3ia1-n.js +137 -0
- package/dist/wc/chart-trend-CQOQtTMl.js +50 -0
- package/dist/wc/chart-validate-CD6ptiwg.js +180 -0
- package/dist/wc/client-DQIzjDBG.js +3064 -0
- package/dist/wc/column-resize-DUPgynvc.js +101 -0
- package/dist/wc/date-format-DS-z_h9v.js +1130 -0
- package/dist/wc/dismissable-CQ6XFXsk.js +45 -0
- package/dist/wc/editor-contract-peBDxir_.js +22 -0
- package/dist/wc/editor-registry-DxGKqcvx.js +24 -0
- package/dist/wc/focus-trap-Dbb2tJxb.js +65 -0
- package/dist/wc/list-option-DrRyivWp.js +82 -0
- package/dist/wc/popover-WsGlvtQv.js +69 -0
- package/dist/wc/positioning-BiKLfu1E.js +112 -0
- package/dist/wc/react.d.ts +41 -0
- package/dist/wc/react.js +90 -0
- package/dist/wc/rolldown-runtime-Dy4uBu1J.js +11 -0
- package/dist/wc/row-drag-touch-CycRR65n.js +93 -0
- package/dist/wc/row-resize-limG_N1z.js +111 -0
- package/dist/wc/sv-sheet-element.d.ts +97 -0
- package/dist/wc/sv-sheet-element.js +44213 -0
- package/dist/wc/svelte-virtualizer.svelte-CXtQy2TQ.js +530 -0
- package/dist/wc/validate-BqDthkNr.js +88 -0
- package/dist/wc/vue.d.ts +31 -0
- package/dist/wc/vue.js +75 -0
- package/package.json +30 -5
- package/dist/designer/assets/GridMenus-BlsvL_aU.js +0 -8
- package/dist/designer/assets/SvGridCellEditor-C7uQXYds.js +0 -4
- package/dist/designer/assets/SvGridChartBuilder-kvyIU_Rl.js +0 -1
- package/dist/designer/assets/SvGridDropdown-Bb3HH2Aj.js +0 -1
- package/dist/designer/assets/cell-formatting-wr5wm7US.js +0 -1
- package/dist/designer/assets/index-CMFgAoVV.css +0 -1
- package/dist/designer/assets/row-resize-DLktcqUK.js +0 -1
- package/dist/designer/assets/src-EdI3Xqds.js +0 -58
- package/dist/designer/assets/validate-h-aslRV9.js +0 -1
|
@@ -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,28 +548,97 @@
|
|
|
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
644
|
let chartStacked100 = $state(false)
|
|
@@ -832,13 +950,27 @@
|
|
|
832
950
|
{/if}
|
|
833
951
|
</div>
|
|
834
952
|
{/if}
|
|
835
|
-
|
|
836
|
-
<
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
<
|
|
840
|
-
|
|
841
|
-
|
|
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}
|
|
842
974
|
<div class="pvd-viewswitch" role="group" aria-label="View">
|
|
843
975
|
<button type="button" class="pvd-view-btn" class:is-active={view === 'table'} onclick={() => (view = 'table')}>{@render ic('table')} Table</button>
|
|
844
976
|
<button type="button" class="pvd-view-btn" class:is-active={view === 'chart'} onclick={() => (view = 'chart')}>{@render ic('chart')} Chart</button>
|
|
@@ -903,7 +1035,7 @@
|
|
|
903
1035
|
{/if}
|
|
904
1036
|
<div class="pvd-main">
|
|
905
1037
|
{#if showPivotToggle}<div class="pvd-topbar">{@render pivotToggle()}</div>{/if}
|
|
906
|
-
<div class="pvd-wells" class:two={!
|
|
1038
|
+
<div class="pvd-wells" class:two={!filtersWell}>{@render wellsBlock()}</div>
|
|
907
1039
|
{@render gridBlock()}
|
|
908
1040
|
</div>
|
|
909
1041
|
{/if}
|
|
@@ -1097,18 +1229,18 @@
|
|
|
1097
1229
|
|
|
1098
1230
|
{#snippet wellsBlock()}
|
|
1099
1231
|
<!-- Filters -->
|
|
1100
|
-
{#if
|
|
1101
|
-
<div class="pvd-well"
|
|
1232
|
+
{#if filtersWell}
|
|
1233
|
+
<div class="pvd-well" data-well="filters" role="group" aria-label="Filters"
|
|
1102
1234
|
class:drag-over={dragOver === 'filters'}
|
|
1103
1235
|
ondragover={(e) => onDragOver(e, 'filters')}
|
|
1104
1236
|
ondragleave={onDragLeave}
|
|
1105
1237
|
ondrop={(e) => onDrop(e, 'filters')}
|
|
1106
1238
|
oncontextmenu={(e) => openCtx(e, wellMenu('filters'))}>
|
|
1107
1239
|
<div class="pvd-well-head">{@render ic('filter')} Filters</div>
|
|
1108
|
-
<div class="pvd-well-body">
|
|
1240
|
+
<div class="pvd-well-body" role="list">
|
|
1109
1241
|
{#each layout.filters as f (f.field)}
|
|
1110
1242
|
{@const fd = fieldsByName.get(f.field)}
|
|
1111
|
-
<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))}>
|
|
1112
1244
|
<span class="pvd-chip-grip" aria-hidden="true">{@render ic('grip')}</span>
|
|
1113
1245
|
<button type="button" class="pvd-chip-label" title="Choose which values pass" onclick={() => toggleFilterMenu(f.field)}>
|
|
1114
1246
|
{fd?.label ?? f.field}{f.allowed ? `: ${f.allowed.length}` : ''} <span class="pvd-chip-caret">▾</span>
|
|
@@ -1145,17 +1277,17 @@
|
|
|
1145
1277
|
{/if}
|
|
1146
1278
|
|
|
1147
1279
|
<!-- Columns -->
|
|
1148
|
-
<div class="pvd-well"
|
|
1280
|
+
<div class="pvd-well" data-well="cols" role="group" aria-label="Cols"
|
|
1149
1281
|
class:drag-over={dragOver === 'cols'}
|
|
1150
1282
|
ondragover={(e) => onDragOver(e, 'cols')}
|
|
1151
1283
|
ondragleave={onDragLeave}
|
|
1152
1284
|
ondrop={(e) => onDrop(e, 'cols')}
|
|
1153
1285
|
oncontextmenu={(e) => openCtx(e, wellMenu('cols'))}>
|
|
1154
1286
|
<div class="pvd-well-head">{@render ic('columns')} Columns</div>
|
|
1155
|
-
<div class="pvd-well-body">
|
|
1287
|
+
<div class="pvd-well-body" role="list">
|
|
1156
1288
|
{#each layout.cols as field (field)}
|
|
1157
1289
|
{@const fd = fieldsByName.get(field)}
|
|
1158
|
-
<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))}>
|
|
1159
1291
|
<span class="pvd-chip-grip" aria-hidden="true">{@render ic('grip')}</span>
|
|
1160
1292
|
<span class="pvd-chip-label">{fd?.label ?? field}</span>
|
|
1161
1293
|
<button type="button" class="pvd-chip-x" onclick={() => removeFromWell(field, 'cols')} aria-label="Remove">×</button>
|
|
@@ -1166,17 +1298,17 @@
|
|
|
1166
1298
|
</div>
|
|
1167
1299
|
|
|
1168
1300
|
<!-- Rows -->
|
|
1169
|
-
<div class="pvd-well"
|
|
1301
|
+
<div class="pvd-well" data-well="rows" role="group" aria-label="Rows"
|
|
1170
1302
|
class:drag-over={dragOver === 'rows'}
|
|
1171
1303
|
ondragover={(e) => onDragOver(e, 'rows')}
|
|
1172
1304
|
ondragleave={onDragLeave}
|
|
1173
1305
|
ondrop={(e) => onDrop(e, 'rows')}
|
|
1174
1306
|
oncontextmenu={(e) => openCtx(e, wellMenu('rows'))}>
|
|
1175
1307
|
<div class="pvd-well-head">{@render ic('rows')} Rows</div>
|
|
1176
|
-
<div class="pvd-well-body">
|
|
1308
|
+
<div class="pvd-well-body" role="list">
|
|
1177
1309
|
{#each layout.rows as field (field)}
|
|
1178
1310
|
{@const fd = fieldsByName.get(field)}
|
|
1179
|
-
<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))}>
|
|
1180
1312
|
<span class="pvd-chip-grip" aria-hidden="true">{@render ic('grip')}</span>
|
|
1181
1313
|
<span class="pvd-chip-label">{fd?.label ?? field}</span>
|
|
1182
1314
|
<button type="button" class="pvd-chip-x" onclick={() => removeFromWell(field, 'rows')} aria-label="Remove">×</button>
|
|
@@ -1187,17 +1319,17 @@
|
|
|
1187
1319
|
</div>
|
|
1188
1320
|
|
|
1189
1321
|
<!-- Values -->
|
|
1190
|
-
<div class="pvd-well"
|
|
1322
|
+
<div class="pvd-well" data-well="values" role="group" aria-label="Values"
|
|
1191
1323
|
class:drag-over={dragOver === 'values'}
|
|
1192
1324
|
ondragover={(e) => onDragOver(e, 'values')}
|
|
1193
1325
|
ondragleave={onDragLeave}
|
|
1194
1326
|
ondrop={(e) => onDrop(e, 'values')}
|
|
1195
1327
|
oncontextmenu={(e) => openCtx(e, wellMenu('values'))}>
|
|
1196
1328
|
<div class="pvd-well-head">{@render ic('sigma')} Values</div>
|
|
1197
|
-
<div class="pvd-well-body">
|
|
1329
|
+
<div class="pvd-well-body" role="list">
|
|
1198
1330
|
{#each layout.values as v, vi (v.field + '|' + v.agg + '|' + vi)}
|
|
1199
1331
|
{@const fd = fieldsByName.get(v.field)}
|
|
1200
|
-
<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))}>
|
|
1201
1333
|
<span class="pvd-chip-grip" aria-hidden="true">{@render ic('grip')}</span>
|
|
1202
1334
|
<button type="button" class="pvd-chip-label" onclick={() => toggleAggMenu(vi)}>
|
|
1203
1335
|
<span class="pvd-chip-agg">{AGG_LABEL[v.agg]}</span>
|
|
@@ -1230,7 +1362,7 @@
|
|
|
1230
1362
|
{#snippet columnsPanel()}
|
|
1231
1363
|
{#if showPivotToggle}{@render pivotToggle()}{/if}
|
|
1232
1364
|
{#if showFieldList}<div class="pvd-panel-rail">{@render railBlock()}</div>{/if}
|
|
1233
|
-
<div class="pvd-wells pvd-wells--vertical" class:two={!
|
|
1365
|
+
<div class="pvd-wells pvd-wells--vertical" class:two={!filtersWell}>{@render wellsBlock()}</div>
|
|
1234
1366
|
{/snippet}
|
|
1235
1367
|
|
|
1236
1368
|
<!-- The Filters tab body: AG-style set filters. Each active column filter is a
|
|
@@ -1296,8 +1428,25 @@
|
|
|
1296
1428
|
|
|
1297
1429
|
{#snippet gridBlock()}
|
|
1298
1430
|
{#if embedGrid}
|
|
1299
|
-
<div class="pvd-grid" style={`height:${typeof gridHeight === 'number' ? gridHeight + 'px' : gridHeight}`} oncontextmenu={(e) => openCtx(e, gridMenu())}>
|
|
1300
|
-
{#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}
|
|
1301
1450
|
<SvGrid
|
|
1302
1451
|
data={filteredData}
|
|
1303
1452
|
columns={visibleFlatColumns!}
|
|
@@ -1426,6 +1575,15 @@
|
|
|
1426
1575
|
border-color: var(--sg-accent, #2563eb);
|
|
1427
1576
|
}
|
|
1428
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; }
|
|
1429
1587
|
.pvd-toggle {
|
|
1430
1588
|
display: inline-flex;
|
|
1431
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";
|