@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
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* took and applies the choice through `planPaste` / `resolvePasteCell`;
|
|
7
7
|
* this component only asks the question.
|
|
8
8
|
*/
|
|
9
|
+
import { useSheetText } from './sheet-text'
|
|
9
10
|
import { SvModal } from '@svgrid/grid'
|
|
10
11
|
import type { PasteSpecialOptions, PasteWhat, PasteOperation } from './sheet/paste-special'
|
|
11
12
|
|
|
@@ -19,6 +20,7 @@
|
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
let { open = $bindable(false), hasClipboard, onPaste, onClose }: Props = $props()
|
|
23
|
+
const t = useSheetText()
|
|
22
24
|
|
|
23
25
|
let what = $state<PasteWhat>('all')
|
|
24
26
|
let operation = $state<PasteOperation>('none')
|
|
@@ -26,17 +28,17 @@
|
|
|
26
28
|
let transpose = $state(false)
|
|
27
29
|
|
|
28
30
|
const WHAT: ReadonlyArray<{ value: PasteWhat; label: string }> = [
|
|
29
|
-
{ value: 'all', label: '
|
|
30
|
-
{ value: 'formulas', label: '
|
|
31
|
-
{ value: 'values', label: '
|
|
32
|
-
{ value: 'formats', label: '
|
|
31
|
+
{ value: 'all', label: 'pasteSpecial.all' },
|
|
32
|
+
{ value: 'formulas', label: 'pasteSpecial.formulas' },
|
|
33
|
+
{ value: 'values', label: 'pasteSpecial.values' },
|
|
34
|
+
{ value: 'formats', label: 'pasteSpecial.formats' },
|
|
33
35
|
]
|
|
34
36
|
const OPERATIONS: ReadonlyArray<{ value: PasteOperation; label: string }> = [
|
|
35
|
-
{ value: 'none', label: '
|
|
36
|
-
{ value: 'add', label: '
|
|
37
|
-
{ value: 'subtract', label: '
|
|
38
|
-
{ value: 'multiply', label: '
|
|
39
|
-
{ value: 'divide', label: '
|
|
37
|
+
{ value: 'none', label: 'pasteSpecial.none' },
|
|
38
|
+
{ value: 'add', label: 'pasteSpecial.add' },
|
|
39
|
+
{ value: 'subtract', label: 'pasteSpecial.subtract' },
|
|
40
|
+
{ value: 'multiply', label: 'pasteSpecial.multiply' },
|
|
41
|
+
{ value: 'divide', label: 'pasteSpecial.divide' },
|
|
40
42
|
]
|
|
41
43
|
|
|
42
44
|
function ok() {
|
|
@@ -51,34 +53,34 @@
|
|
|
51
53
|
}
|
|
52
54
|
</script>
|
|
53
55
|
|
|
54
|
-
<SvModal bind:open onClose={onClose} title=
|
|
55
|
-
<div class="sv-sheet-dialog" role="group" aria-label=
|
|
56
|
+
<SvModal bind:open onClose={onClose} title={t('pasteSpecial.title')} size="sm">
|
|
57
|
+
<div class="sv-sheet-dialog" role="group" aria-label={t('pasteSpecial.title')}>
|
|
56
58
|
{#if !hasClipboard}
|
|
57
|
-
<p class="status">
|
|
59
|
+
<p class="status">{t('pasteSpecial.empty')}</p>
|
|
58
60
|
{/if}
|
|
59
61
|
<div class="columns">
|
|
60
62
|
<fieldset class="group">
|
|
61
|
-
<legend>
|
|
63
|
+
<legend>{t('pasteSpecial.paste')}</legend>
|
|
62
64
|
{#each WHAT as choice (choice.value)}
|
|
63
|
-
<label class="check"><input type="radio" name="sheet-paste-what" value={choice.value} bind:group={what} /> {choice.label}</label>
|
|
65
|
+
<label class="check"><input type="radio" name="sheet-paste-what" value={choice.value} bind:group={what} /> {t(choice.label)}</label>
|
|
64
66
|
{/each}
|
|
65
67
|
</fieldset>
|
|
66
68
|
<fieldset class="group">
|
|
67
|
-
<legend>
|
|
69
|
+
<legend>{t('pasteSpecial.operation')}</legend>
|
|
68
70
|
{#each OPERATIONS as choice (choice.value)}
|
|
69
|
-
<label class="check"><input type="radio" name="sheet-paste-op" value={choice.value} bind:group={operation} /> {choice.label}</label>
|
|
71
|
+
<label class="check"><input type="radio" name="sheet-paste-op" value={choice.value} bind:group={operation} /> {t(choice.label)}</label>
|
|
70
72
|
{/each}
|
|
71
73
|
</fieldset>
|
|
72
74
|
</div>
|
|
73
75
|
<div class="checks">
|
|
74
|
-
<label class="check"><input type="checkbox" bind:checked={skipBlanks} />
|
|
75
|
-
<label class="check"><input type="checkbox" bind:checked={transpose} />
|
|
76
|
+
<label class="check"><input type="checkbox" bind:checked={skipBlanks} /> {t('pasteSpecial.skipBlanks')}</label>
|
|
77
|
+
<label class="check"><input type="checkbox" bind:checked={transpose} /> {t('pasteSpecial.transpose')}</label>
|
|
76
78
|
</div>
|
|
77
79
|
</div>
|
|
78
80
|
{#snippet footer()}
|
|
79
81
|
<div class="sv-sheet-dialog-buttons">
|
|
80
|
-
<button type="button" class="btn primary" onclick={ok} disabled={!hasClipboard}>
|
|
81
|
-
<button type="button" class="btn" onclick={close}>
|
|
82
|
+
<button type="button" class="btn primary" onclick={ok} disabled={!hasClipboard}>{t('ok')}</button>
|
|
83
|
+
<button type="button" class="btn" onclick={close}>{t('cancel')}</button>
|
|
82
84
|
</div>
|
|
83
85
|
{/snippet}
|
|
84
86
|
</SvModal>
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* Excel's Create PivotTable dialog with its field list folded in: the
|
|
4
|
+
* source block, where the result goes, and which field is a row, a column
|
|
5
|
+
* or a measure. Opened by Insert > PivotTable, and again by Refresh on a
|
|
6
|
+
* cell inside a pivot, which is how one is changed.
|
|
7
|
+
*/
|
|
8
|
+
import { SvModal } from '@svgrid/grid'
|
|
9
|
+
import { useSheetText } from './sheet-text'
|
|
10
|
+
import { parseRangeText, rangeText } from './sheet/protection'
|
|
11
|
+
import { parseA1, formatA1 } from './sheet/address'
|
|
12
|
+
import {
|
|
13
|
+
SHEET_PIVOT_AGGS, ALL_VALUES,
|
|
14
|
+
type SheetPivot, type SheetPivotAgg, type SheetPivotValue, type SheetPivotFilter,
|
|
15
|
+
} from './sheet/pivot-range'
|
|
16
|
+
import type { Rect } from './sheet/format-store'
|
|
17
|
+
|
|
18
|
+
type Props = {
|
|
19
|
+
open?: boolean
|
|
20
|
+
/** The pivot as it stands, new or being edited. */
|
|
21
|
+
pivot: SheetPivot
|
|
22
|
+
/** The source's field names, read from its header row. */
|
|
23
|
+
fields: ReadonlyArray<string>
|
|
24
|
+
/**
|
|
25
|
+
* The values each field carries, for the Filters area's value list.
|
|
26
|
+
* The dialog has the definition, not the cells, so the shell reads
|
|
27
|
+
* them off the source.
|
|
28
|
+
*/
|
|
29
|
+
valuesOf?: (field: string) => ReadonlyArray<string>
|
|
30
|
+
existing?: boolean
|
|
31
|
+
onApply: (pivot: SheetPivot) => void
|
|
32
|
+
onDelete?: () => void
|
|
33
|
+
onClose?: () => void
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
let { open = $bindable(false), pivot, fields, valuesOf, existing = false, onApply, onDelete, onClose }: Props = $props()
|
|
37
|
+
const t = useSheetText()
|
|
38
|
+
|
|
39
|
+
let source = $state('')
|
|
40
|
+
let target = $state('')
|
|
41
|
+
let rows = $state<string[]>([])
|
|
42
|
+
let cols = $state<string[]>([])
|
|
43
|
+
let values = $state<SheetPivotValue[]>([])
|
|
44
|
+
let filters = $state<SheetPivotFilter[]>([])
|
|
45
|
+
let grandTotalRow = $state(true)
|
|
46
|
+
let rowSubtotals = $state(true)
|
|
47
|
+
let error = $state('')
|
|
48
|
+
let first = $state<HTMLInputElement | null>(null)
|
|
49
|
+
|
|
50
|
+
$effect(() => {
|
|
51
|
+
if (!open) return
|
|
52
|
+
source = rangeText([pivot.source])
|
|
53
|
+
target = formatA1({ sheet: null, row: pivot.target.row, col: pivot.target.col, rowAbs: false, colAbs: false })
|
|
54
|
+
rows = [...pivot.rows]
|
|
55
|
+
cols = [...pivot.cols]
|
|
56
|
+
values = pivot.values.map((v) => ({ ...v }))
|
|
57
|
+
filters = (pivot.filters ?? []).map((f) => ({ ...f }))
|
|
58
|
+
grandTotalRow = pivot.grandTotalRow !== false
|
|
59
|
+
rowSubtotals = pivot.rowSubtotals !== false
|
|
60
|
+
error = ''
|
|
61
|
+
queueMicrotask(() => first?.focus())
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
/** Where a field sits now: down the rows, across the columns, or a measure. */
|
|
65
|
+
function placeOf(field: string): Placement {
|
|
66
|
+
if (rows.includes(field)) return 'rows'
|
|
67
|
+
if (cols.includes(field)) return 'cols'
|
|
68
|
+
if (values.some((v) => v.field === field)) return 'values'
|
|
69
|
+
if (filters.some((f) => f.field === field)) return 'filters'
|
|
70
|
+
return 'none'
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
type Placement = 'none' | 'rows' | 'cols' | 'values' | 'filters'
|
|
74
|
+
|
|
75
|
+
function place(field: string, to: Placement) {
|
|
76
|
+
rows = rows.filter((f) => f !== field)
|
|
77
|
+
cols = cols.filter((f) => f !== field)
|
|
78
|
+
values = values.filter((v) => v.field !== field)
|
|
79
|
+
filters = filters.filter((f) => f.field !== field)
|
|
80
|
+
if (to === 'rows') rows = [...rows, field]
|
|
81
|
+
else if (to === 'cols') cols = [...cols, field]
|
|
82
|
+
else if (to === 'values') values = [...values, { field, agg: 'sum' }]
|
|
83
|
+
else if (to === 'filters') filters = [...filters, { field, value: '' }]
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function setFilter(field: string, value: string) {
|
|
87
|
+
filters = filters.map((f) => (f.field === field ? { ...f, value } : f))
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function setAgg(field: string, agg: SheetPivotAgg) {
|
|
91
|
+
values = values.map((v) => (v.field === field ? { ...v, agg } : v))
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function ok() {
|
|
95
|
+
const rects = parseRangeText(source)
|
|
96
|
+
const block = rects && rects.length === 1 ? rects[0]! : null
|
|
97
|
+
const at = parseA1(target.trim())
|
|
98
|
+
if (!block || !at || at.row === null) { error = t('pivot.badRange'); return }
|
|
99
|
+
if (!values.length) { error = t('pivot.needValue'); return }
|
|
100
|
+
const next: SheetPivot = {
|
|
101
|
+
...pivot,
|
|
102
|
+
source: block as Rect,
|
|
103
|
+
target: { row: at.row, col: at.col },
|
|
104
|
+
rows: [...rows],
|
|
105
|
+
cols: [...cols],
|
|
106
|
+
values: values.map((v) => ({ ...v })),
|
|
107
|
+
...(filters.length ? { filters: filters.map((f) => ({ ...f })) } : { filters: [] }),
|
|
108
|
+
grandTotalRow,
|
|
109
|
+
rowSubtotals,
|
|
110
|
+
}
|
|
111
|
+
if (!next.filters?.length) delete next.filters
|
|
112
|
+
open = false
|
|
113
|
+
onApply(next)
|
|
114
|
+
onClose?.()
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function close() {
|
|
118
|
+
open = false
|
|
119
|
+
onClose?.()
|
|
120
|
+
}
|
|
121
|
+
</script>
|
|
122
|
+
|
|
123
|
+
<SvModal bind:open onClose={onClose} title={t('pivot.title')} size="md">
|
|
124
|
+
<form class="sv-sheet-dialog" onsubmit={(e) => { e.preventDefault(); ok() }}>
|
|
125
|
+
<label class="field">
|
|
126
|
+
<span>{t('pivot.source')}</span>
|
|
127
|
+
<input type="text" bind:this={first} bind:value={source} spellcheck="false" placeholder={t('pivot.sourcePlaceholder')} />
|
|
128
|
+
</label>
|
|
129
|
+
<label class="field">
|
|
130
|
+
<span>{t('pivot.target')}</span>
|
|
131
|
+
<input type="text" bind:value={target} spellcheck="false" placeholder={t('pivot.targetPlaceholder')} />
|
|
132
|
+
</label>
|
|
133
|
+
<div class="fields">
|
|
134
|
+
<div class="head">
|
|
135
|
+
<span>{t('pivot.field')}</span>
|
|
136
|
+
<span>{t('pivot.place')}</span>
|
|
137
|
+
<span>{t('pivot.summarise')}</span>
|
|
138
|
+
</div>
|
|
139
|
+
{#each fields as field (field)}
|
|
140
|
+
{@const place_ = placeOf(field)}
|
|
141
|
+
<div class="row">
|
|
142
|
+
<span class="name" title={field}>{field}</span>
|
|
143
|
+
<select value={place_} onchange={(e) => place(field, e.currentTarget.value as Placement)}>
|
|
144
|
+
<option value="none">{t('pivot.place.none')}</option>
|
|
145
|
+
<option value="rows">{t('pivot.place.rows')}</option>
|
|
146
|
+
<option value="cols">{t('pivot.place.cols')}</option>
|
|
147
|
+
<option value="values">{t('pivot.place.values')}</option>
|
|
148
|
+
<option value="filters">{t('pivot.place.filters')}</option>
|
|
149
|
+
</select>
|
|
150
|
+
{#if place_ === 'values'}
|
|
151
|
+
{@const agg = values.find((v) => v.field === field)?.agg ?? 'sum'}
|
|
152
|
+
<select value={agg} onchange={(e) => setAgg(field, e.currentTarget.value as SheetPivotAgg)}>
|
|
153
|
+
{#each SHEET_PIVOT_AGGS as id (id)}<option value={id}>{t(`pivot.agg.${id}`)}</option>{/each}
|
|
154
|
+
</select>
|
|
155
|
+
{:else if place_ === 'filters'}
|
|
156
|
+
{@const chosen = filters.find((f) => f.field === field)?.value ?? ''}
|
|
157
|
+
<select value={chosen} onchange={(e) => setFilter(field, e.currentTarget.value)} aria-label={t('pivot.filterValue', { field })}>
|
|
158
|
+
<option value="">{ALL_VALUES}</option>
|
|
159
|
+
{#each valuesOf?.(field) ?? [] as value (value)}<option value={value}>{value}</option>{/each}
|
|
160
|
+
</select>
|
|
161
|
+
{:else}
|
|
162
|
+
<span class="dash">—</span>
|
|
163
|
+
{/if}
|
|
164
|
+
</div>
|
|
165
|
+
{/each}
|
|
166
|
+
</div>
|
|
167
|
+
<div class="checks">
|
|
168
|
+
<label class="check"><input type="checkbox" bind:checked={grandTotalRow} /> {t('pivot.grandTotal')}</label>
|
|
169
|
+
<label class="check"><input type="checkbox" bind:checked={rowSubtotals} /> {t('pivot.subtotals')}</label>
|
|
170
|
+
</div>
|
|
171
|
+
{#if error}<p class="error">{error}</p>{/if}
|
|
172
|
+
<p class="hint">{t('pivot.hint')}</p>
|
|
173
|
+
</form>
|
|
174
|
+
{#snippet footer()}
|
|
175
|
+
<div class="sv-sheet-dialog-buttons">
|
|
176
|
+
{#if existing && onDelete}
|
|
177
|
+
<button type="button" class="btn" onclick={() => { open = false; onDelete?.() }}>{t('delete')}</button>
|
|
178
|
+
{/if}
|
|
179
|
+
<span class="spacer"></span>
|
|
180
|
+
<button type="button" class="btn primary" onclick={ok}>{t('ok')}</button>
|
|
181
|
+
<button type="button" class="btn" onclick={close}>{t('cancel')}</button>
|
|
182
|
+
</div>
|
|
183
|
+
{/snippet}
|
|
184
|
+
</SvModal>
|
|
185
|
+
|
|
186
|
+
<style>
|
|
187
|
+
.spacer { flex: 1; }
|
|
188
|
+
.error { margin: 4px 0 0; color: var(--sg-danger, #c42b1c); font-size: 12px; }
|
|
189
|
+
.fields {
|
|
190
|
+
margin-top: 8px;
|
|
191
|
+
max-height: 220px;
|
|
192
|
+
overflow: auto;
|
|
193
|
+
border: 1px solid var(--sg-border, #d1d1d1);
|
|
194
|
+
border-radius: var(--sg-radius, 4px);
|
|
195
|
+
}
|
|
196
|
+
.head,
|
|
197
|
+
.row {
|
|
198
|
+
display: grid;
|
|
199
|
+
grid-template-columns: 1fr 120px 130px;
|
|
200
|
+
gap: 8px;
|
|
201
|
+
align-items: center;
|
|
202
|
+
padding: 4px 8px;
|
|
203
|
+
}
|
|
204
|
+
.head {
|
|
205
|
+
position: sticky;
|
|
206
|
+
top: 0;
|
|
207
|
+
background: var(--sg-header-bg, #f3f3f3);
|
|
208
|
+
color: var(--sg-muted, #616161);
|
|
209
|
+
font-size: 11px;
|
|
210
|
+
text-transform: uppercase;
|
|
211
|
+
letter-spacing: 0.04em;
|
|
212
|
+
}
|
|
213
|
+
.row + .row { border-top: 1px solid var(--sg-border, #ececec); }
|
|
214
|
+
.name {
|
|
215
|
+
overflow: hidden;
|
|
216
|
+
text-overflow: ellipsis;
|
|
217
|
+
white-space: nowrap;
|
|
218
|
+
}
|
|
219
|
+
.dash { color: var(--sg-muted, #9a9a9a); text-align: center; }
|
|
220
|
+
</style>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type SheetPivot } from './sheet/pivot-range.js';
|
|
2
|
+
type Props = {
|
|
3
|
+
open?: boolean;
|
|
4
|
+
/** The pivot as it stands, new or being edited. */
|
|
5
|
+
pivot: SheetPivot;
|
|
6
|
+
/** The source's field names, read from its header row. */
|
|
7
|
+
fields: ReadonlyArray<string>;
|
|
8
|
+
/**
|
|
9
|
+
* The values each field carries, for the Filters area's value list.
|
|
10
|
+
* The dialog has the definition, not the cells, so the shell reads
|
|
11
|
+
* them off the source.
|
|
12
|
+
*/
|
|
13
|
+
valuesOf?: (field: string) => ReadonlyArray<string>;
|
|
14
|
+
existing?: boolean;
|
|
15
|
+
onApply: (pivot: SheetPivot) => void;
|
|
16
|
+
onDelete?: () => void;
|
|
17
|
+
onClose?: () => void;
|
|
18
|
+
};
|
|
19
|
+
declare const SvSheetPivot: import("svelte").Component<Props, {}, "open">;
|
|
20
|
+
type SvSheetPivot = ReturnType<typeof SvSheetPivot>;
|
|
21
|
+
export default SvSheetPivot;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* Excel's Protect Sheet dialog, without the password: the "allow all
|
|
4
|
+
* users of this worksheet to" list, each entry a kind of change that
|
|
5
|
+
* stays open once the sheet is protected. OK protects with what is
|
|
6
|
+
* ticked; the shell keeps the list per sheet, so Unprotect and Protect
|
|
7
|
+
* again offer the same ticks.
|
|
8
|
+
*/
|
|
9
|
+
import { useSheetText } from './sheet-text'
|
|
10
|
+
import { SvModal } from '@svgrid/grid'
|
|
11
|
+
import { PROTECTION_PERMISSIONS, type ProtectionAllow, type ProtectionPermission } from './sheet/protection'
|
|
12
|
+
|
|
13
|
+
type Props = {
|
|
14
|
+
open?: boolean
|
|
15
|
+
/** The sheet's list as it stands, what the ticks open on. */
|
|
16
|
+
allow: ProtectionAllow
|
|
17
|
+
onApply: (allow: ProtectionAllow) => void
|
|
18
|
+
onClose?: () => void
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
let { open = $bindable(false), allow, onApply, onClose }: Props = $props()
|
|
22
|
+
const t = useSheetText()
|
|
23
|
+
|
|
24
|
+
let ticks = $state<Record<ProtectionPermission, boolean>>({} as Record<ProtectionPermission, boolean>)
|
|
25
|
+
let first = $state<HTMLInputElement | null>(null)
|
|
26
|
+
|
|
27
|
+
$effect(() => {
|
|
28
|
+
if (!open) return
|
|
29
|
+
const next = {} as Record<ProtectionPermission, boolean>
|
|
30
|
+
for (const key of PROTECTION_PERMISSIONS) next[key] = Boolean(allow[key])
|
|
31
|
+
ticks = next
|
|
32
|
+
queueMicrotask(() => first?.focus())
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
function ok() {
|
|
36
|
+
const next: ProtectionAllow = {}
|
|
37
|
+
for (const key of PROTECTION_PERMISSIONS) if (ticks[key]) next[key] = true
|
|
38
|
+
open = false
|
|
39
|
+
onApply(next)
|
|
40
|
+
onClose?.()
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function close() {
|
|
44
|
+
open = false
|
|
45
|
+
onClose?.()
|
|
46
|
+
}
|
|
47
|
+
</script>
|
|
48
|
+
|
|
49
|
+
<SvModal bind:open onClose={onClose} title={t('protectSheet.title')} size="sm">
|
|
50
|
+
<form class="sv-sheet-dialog" onsubmit={(e) => { e.preventDefault(); ok() }}>
|
|
51
|
+
<div class="lead">{t('protectSheet.lead')}</div>
|
|
52
|
+
<div class="checks column" role="group" aria-label={t('protectSheet.lead')}>
|
|
53
|
+
{#each PROTECTION_PERMISSIONS as key, i (key)}
|
|
54
|
+
<label class="check">
|
|
55
|
+
{#if i === 0}
|
|
56
|
+
<input bind:this={first} type="checkbox" bind:checked={ticks[key]} />
|
|
57
|
+
{:else}
|
|
58
|
+
<input type="checkbox" bind:checked={ticks[key]} />
|
|
59
|
+
{/if}
|
|
60
|
+
{t(`protectSheet.${key}`)}
|
|
61
|
+
</label>
|
|
62
|
+
{/each}
|
|
63
|
+
</div>
|
|
64
|
+
<p class="hint">{t('protectSheet.hint')}</p>
|
|
65
|
+
</form>
|
|
66
|
+
{#snippet footer()}
|
|
67
|
+
<div class="sv-sheet-dialog-buttons">
|
|
68
|
+
<button type="button" class="btn primary" onclick={ok}>{t('ok')}</button>
|
|
69
|
+
<button type="button" class="btn" onclick={close}>{t('cancel')}</button>
|
|
70
|
+
</div>
|
|
71
|
+
{/snippet}
|
|
72
|
+
</SvModal>
|
|
73
|
+
|
|
74
|
+
<style>
|
|
75
|
+
.checks.column {
|
|
76
|
+
display: flex;
|
|
77
|
+
flex-direction: column;
|
|
78
|
+
gap: 4px;
|
|
79
|
+
padding: 4px 0;
|
|
80
|
+
}
|
|
81
|
+
</style>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type ProtectionAllow } from './sheet/protection.js';
|
|
2
|
+
type Props = {
|
|
3
|
+
open?: boolean;
|
|
4
|
+
/** The sheet's list as it stands, what the ticks open on. */
|
|
5
|
+
allow: ProtectionAllow;
|
|
6
|
+
onApply: (allow: ProtectionAllow) => void;
|
|
7
|
+
onClose?: () => void;
|
|
8
|
+
};
|
|
9
|
+
declare const SvSheetProtectSheet: import("svelte").Component<Props, {}, "open">;
|
|
10
|
+
type SvSheetProtectSheet = ReturnType<typeof SvSheetProtectSheet>;
|
|
11
|
+
export default SvSheetProtectSheet;
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* rows they vacated go blank, in one batch, so it is one Ctrl+Z; the
|
|
7
7
|
* sentence Excel's dialog ends on is handed back for the status bar.
|
|
8
8
|
*/
|
|
9
|
+
import { useSheetText } from './sheet-text'
|
|
9
10
|
import { untrack } from 'svelte'
|
|
10
11
|
import { SvModal } from '@svgrid/grid'
|
|
11
12
|
import type { GridCommandContext } from '@svgrid/grid/shortcuts'
|
|
@@ -22,6 +23,7 @@
|
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
let { open = $bindable(false), workbook, cmd, onDone, onClose }: Props = $props()
|
|
26
|
+
const t = useSheetText()
|
|
25
27
|
|
|
26
28
|
type Block = { top: number; left: number; bottom: number; right: number }
|
|
27
29
|
let block = $state<Block>({ top: 0, left: 0, bottom: 0, right: 0 })
|
|
@@ -33,7 +35,8 @@
|
|
|
33
35
|
const headers = $derived.by(() =>
|
|
34
36
|
Array.from({ length: block.right - block.left + 1 }, (_, i) => {
|
|
35
37
|
const letter = colToLetters(block.left + i)
|
|
36
|
-
|
|
38
|
+
const fallback = t('removeDuplicates.columnLetter', { letter })
|
|
39
|
+
return hasHeaders ? raw(block.top, block.left + i) || fallback : fallback
|
|
37
40
|
}),
|
|
38
41
|
)
|
|
39
42
|
|
|
@@ -98,16 +101,16 @@
|
|
|
98
101
|
}
|
|
99
102
|
</script>
|
|
100
103
|
|
|
101
|
-
<SvModal bind:open onClose={onClose} title=
|
|
102
|
-
<div class="sv-sheet-dialog" role="group" aria-label=
|
|
103
|
-
<p class="lead">
|
|
104
|
+
<SvModal bind:open onClose={onClose} title={t('removeDuplicates.title')} size="sm">
|
|
105
|
+
<div class="sv-sheet-dialog" role="group" aria-label={t('removeDuplicates.title')}>
|
|
106
|
+
<p class="lead">{t('removeDuplicates.lead')}</p>
|
|
104
107
|
<div class="checks">
|
|
105
|
-
<button type="button" class="small" onclick={() => (chosen = chosen.map(() => true))}>
|
|
106
|
-
<button type="button" class="small" onclick={() => (chosen = chosen.map(() => false))}>
|
|
107
|
-
<label class="check"><input type="checkbox" bind:checked={hasHeaders} />
|
|
108
|
+
<button type="button" class="small" onclick={() => (chosen = chosen.map(() => true))}>{t('removeDuplicates.selectAll')}</button>
|
|
109
|
+
<button type="button" class="small" onclick={() => (chosen = chosen.map(() => false))}>{t('removeDuplicates.unselectAll')}</button>
|
|
110
|
+
<label class="check"><input type="checkbox" bind:checked={hasHeaders} /> {t('removeDuplicates.hasHeaders')}</label>
|
|
108
111
|
</div>
|
|
109
112
|
<fieldset class="group">
|
|
110
|
-
<legend>
|
|
113
|
+
<legend>{t('removeDuplicates.columns')}</legend>
|
|
111
114
|
{#each headers as header, i (i)}
|
|
112
115
|
<label class="check"><input type="checkbox" bind:checked={chosen[i]} /> {header}</label>
|
|
113
116
|
{/each}
|
|
@@ -115,8 +118,8 @@
|
|
|
115
118
|
</div>
|
|
116
119
|
{#snippet footer()}
|
|
117
120
|
<div class="sv-sheet-dialog-buttons">
|
|
118
|
-
<button type="button" class="btn primary" onclick={remove} disabled={!chosen.some(Boolean)}>
|
|
119
|
-
<button type="button" class="btn" onclick={close}>
|
|
121
|
+
<button type="button" class="btn primary" onclick={remove} disabled={!chosen.some(Boolean)}>{t('ok')}</button>
|
|
122
|
+
<button type="button" class="btn" onclick={close}>{t('cancel')}</button>
|
|
120
123
|
</div>
|
|
121
124
|
{/snippet}
|
|
122
125
|
</SvModal>
|