@docyrus/ui-pro-ai-assistant 0.0.2 → 0.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/package.json +2 -3
- package/src/components/assistant-animations.tsx +0 -29
- package/src/components/assistant-dialogs.tsx +0 -235
- package/src/components/code-view.tsx +0 -278
- package/src/components/create-agent-task.tsx +0 -104
- package/src/components/create-new-work-version.tsx +0 -30
- package/src/components/extract-web.tsx +0 -160
- package/src/components/forward-to-agent.tsx +0 -90
- package/src/components/generate-chart.tsx +0 -101
- package/src/components/generative-action-button.tsx +0 -122
- package/src/components/generative-tool.tsx +0 -685
- package/src/components/generative-ui-object.tsx +0 -210
- package/src/components/input-area.tsx +0 -1209
- package/src/components/json-schema-layout.tsx +0 -326
- package/src/components/list-item-card.tsx +0 -92
- package/src/components/mermaid-diagram.tsx +0 -192
- package/src/components/preview-image.tsx +0 -47
- package/src/components/request-approval.tsx +0 -48
- package/src/components/request-user-input.tsx +0 -270
- package/src/components/search-web.tsx +0 -319
- package/src/components/sheet-command.tsx +0 -88
- package/src/components/shell-canvas.tsx +0 -122
- package/src/components/show-advanced-data-table.tsx +0 -352
- package/src/components/show-generated-content-options.tsx +0 -93
- package/src/components/show-people-cards.tsx +0 -180
- package/src/components/subagent-tool.tsx +0 -180
- package/src/components/text-editor-tool.tsx +0 -328
- package/src/components/work-canvas.tsx +0 -88
- package/src/components/work-card.tsx +0 -42
- package/src/declarations.d.ts +0 -1
- package/src/docy-assistant.tsx +0 -1962
- package/src/hooks/index.ts +0 -7
- package/src/hooks/use-assistant-api.ts +0 -507
- package/src/hooks/use-deployment-data.ts +0 -162
- package/src/hooks/use-project-state.ts +0 -347
- package/src/hooks/use-session-state.ts +0 -207
- package/src/hooks/use-speech-recognition.ts +0 -137
- package/src/hooks/use-ui-state.ts +0 -185
- package/src/hooks/use-works-state.ts +0 -146
- package/src/i18n/context.tsx +0 -253
- package/src/i18n/index.ts +0 -19
- package/src/i18n/locales/de.json +0 -198
- package/src/i18n/locales/el.json +0 -198
- package/src/i18n/locales/en.json +0 -226
- package/src/i18n/locales/es.json +0 -198
- package/src/i18n/locales/fr.json +0 -198
- package/src/i18n/locales/it.json +0 -198
- package/src/i18n/locales/pt.json +0 -198
- package/src/i18n/locales/sl.json +0 -198
- package/src/i18n/locales/tr.json +0 -211
- package/src/i18n/types.ts +0 -23
- package/src/i18n/use-translation.ts +0 -17
- package/src/index.ts +0 -18
- package/src/internal/plate-editor/editor/auth-context.ts +0 -11
- package/src/internal/plate-editor/editor/editor-base-kit.tsx +0 -39
- package/src/internal/plate-editor/editor/editor-kit.tsx +0 -89
- package/src/internal/plate-editor/editor/plate-editor.tsx +0 -75
- package/src/internal/plate-editor/editor/plate-types.ts +0 -126
- package/src/internal/plate-editor/editor/plugins/ai-kit.tsx +0 -172
- package/src/internal/plate-editor/editor/plugins/autoformat-kit.tsx +0 -211
- package/src/internal/plate-editor/editor/plugins/basic-blocks-base-kit.tsx +0 -26
- package/src/internal/plate-editor/editor/plugins/basic-blocks-kit.tsx +0 -51
- package/src/internal/plate-editor/editor/plugins/basic-marks-base-kit.tsx +0 -24
- package/src/internal/plate-editor/editor/plugins/basic-marks-kit.tsx +0 -38
- package/src/internal/plate-editor/editor/plugins/basic-nodes-kit.tsx +0 -6
- package/src/internal/plate-editor/editor/plugins/block-menu-kit.tsx +0 -14
- package/src/internal/plate-editor/editor/plugins/block-placeholder-kit.tsx +0 -17
- package/src/internal/plate-editor/editor/plugins/block-selection-kit.tsx +0 -31
- package/src/internal/plate-editor/editor/plugins/callout-base-kit.tsx +0 -5
- package/src/internal/plate-editor/editor/plugins/callout-kit.tsx +0 -7
- package/src/internal/plate-editor/editor/plugins/code-block-base-kit.tsx +0 -23
- package/src/internal/plate-editor/editor/plugins/code-block-kit.tsx +0 -26
- package/src/internal/plate-editor/editor/plugins/column-base-kit.tsx +0 -8
- package/src/internal/plate-editor/editor/plugins/column-kit.tsx +0 -7
- package/src/internal/plate-editor/editor/plugins/comment-base-kit.tsx +0 -5
- package/src/internal/plate-editor/editor/plugins/comment-kit.tsx +0 -174
- package/src/internal/plate-editor/editor/plugins/copilot-kit.tsx +0 -68
- package/src/internal/plate-editor/editor/plugins/cursor-overlay-kit.tsx +0 -13
- package/src/internal/plate-editor/editor/plugins/date-base-kit.tsx +0 -5
- package/src/internal/plate-editor/editor/plugins/date-kit.tsx +0 -7
- package/src/internal/plate-editor/editor/plugins/discussion-kit.tsx +0 -36
- package/src/internal/plate-editor/editor/plugins/dnd-kit.tsx +0 -27
- package/src/internal/plate-editor/editor/plugins/docx-export-kit.tsx +0 -43
- package/src/internal/plate-editor/editor/plugins/docx-kit.tsx +0 -6
- package/src/internal/plate-editor/editor/plugins/emoji-kit.tsx +0 -15
- package/src/internal/plate-editor/editor/plugins/exit-break-kit.tsx +0 -12
- package/src/internal/plate-editor/editor/plugins/floating-toolbar-kit.tsx +0 -19
- package/src/internal/plate-editor/editor/plugins/font-base-kit.tsx +0 -36
- package/src/internal/plate-editor/editor/plugins/font-kit.tsx +0 -47
- package/src/internal/plate-editor/editor/plugins/indent-base-kit.tsx +0 -19
- package/src/internal/plate-editor/editor/plugins/indent-kit.tsx +0 -22
- package/src/internal/plate-editor/editor/plugins/link-base-kit.tsx +0 -5
- package/src/internal/plate-editor/editor/plugins/link-kit.tsx +0 -35
- package/src/internal/plate-editor/editor/plugins/list-base-kit.tsx +0 -24
- package/src/internal/plate-editor/editor/plugins/list-kit.tsx +0 -27
- package/src/internal/plate-editor/editor/plugins/markdown-kit.tsx +0 -18
- package/src/internal/plate-editor/editor/plugins/math-base-kit.tsx +0 -8
- package/src/internal/plate-editor/editor/plugins/math-kit.tsx +0 -10
- package/src/internal/plate-editor/editor/plugins/media-base-kit.tsx +0 -37
- package/src/internal/plate-editor/editor/plugins/media-kit.tsx +0 -53
- package/src/internal/plate-editor/editor/plugins/mention-base-kit.tsx +0 -5
- package/src/internal/plate-editor/editor/plugins/mention-kit.tsx +0 -36
- package/src/internal/plate-editor/editor/plugins/slash-kit.tsx +0 -17
- package/src/internal/plate-editor/editor/plugins/suggestion-base-kit.tsx +0 -5
- package/src/internal/plate-editor/editor/plugins/suggestion-kit.tsx +0 -95
- package/src/internal/plate-editor/editor/plugins/table-base-kit.tsx +0 -20
- package/src/internal/plate-editor/editor/plugins/table-kit.tsx +0 -22
- package/src/internal/plate-editor/editor/plugins/toc-base-kit.tsx +0 -5
- package/src/internal/plate-editor/editor/plugins/toc-kit.tsx +0 -14
- package/src/internal/plate-editor/editor/plugins/toggle-base-kit.tsx +0 -5
- package/src/internal/plate-editor/editor/plugins/toggle-kit.tsx +0 -9
- package/src/internal/plate-editor/editor/transforms.ts +0 -165
- package/src/internal/plate-editor/editor/use-chat.ts +0 -152
- package/src/internal/plate-editor/hooks/index.ts +0 -3
- package/src/internal/plate-editor/hooks/use-copy-to-clipboard.ts +0 -31
- package/src/internal/plate-editor/hooks/use-is-touch-device.ts +0 -26
- package/src/internal/plate-editor/hooks/use-lock-scroll.ts +0 -21
- package/src/internal/plate-editor/hooks/use-media-query.ts +0 -44
- package/src/internal/plate-editor/hooks/use-mounted.ts +0 -18
- package/src/internal/plate-editor/hooks/use-on-click-outside.ts +0 -114
- package/src/internal/plate-editor/hooks/use-upload-file.ts +0 -81
- package/src/internal/plate-editor/i18n/context.tsx +0 -58
- package/src/internal/plate-editor/i18n/index.ts +0 -3
- package/src/internal/plate-editor/i18n/locales/de.json +0 -57
- package/src/internal/plate-editor/i18n/locales/el.json +0 -57
- package/src/internal/plate-editor/i18n/locales/en.json +0 -57
- package/src/internal/plate-editor/i18n/locales/es.json +0 -57
- package/src/internal/plate-editor/i18n/locales/fr.json +0 -57
- package/src/internal/plate-editor/i18n/locales/it.json +0 -57
- package/src/internal/plate-editor/i18n/locales/pt.json +0 -57
- package/src/internal/plate-editor/i18n/locales/sl.json +0 -57
- package/src/internal/plate-editor/i18n/locales/tr.json +0 -57
- package/src/internal/plate-editor/i18n/types.ts +0 -59
- package/src/internal/plate-editor/i18n/use-translation.ts +0 -22
- package/src/internal/plate-editor/index.ts +0 -39
- package/src/internal/plate-editor/lib/ai-output-converter.ts +0 -153
- package/src/internal/plate-editor/lib/download-file.ts +0 -17
- package/src/internal/plate-editor/plate-ui/ai-chat-editor.tsx +0 -24
- package/src/internal/plate-editor/plate-ui/ai-menu.tsx +0 -828
- package/src/internal/plate-editor/plate-ui/ai-node.tsx +0 -41
- package/src/internal/plate-editor/plate-ui/ai-toolbar-button.tsx +0 -25
- package/src/internal/plate-editor/plate-ui/alert-dialog.tsx +0 -145
- package/src/internal/plate-editor/plate-ui/align-toolbar-button.tsx +0 -88
- package/src/internal/plate-editor/plate-ui/avatar.tsx +0 -3
- package/src/internal/plate-editor/plate-ui/block-context-menu.tsx +0 -104
- package/src/internal/plate-editor/plate-ui/block-discussion.tsx +0 -364
- package/src/internal/plate-editor/plate-ui/block-draggable.tsx +0 -557
- package/src/internal/plate-editor/plate-ui/block-list-static.tsx +0 -77
- package/src/internal/plate-editor/plate-ui/block-list.tsx +0 -85
- package/src/internal/plate-editor/plate-ui/block-menu.tsx +0 -555
- package/src/internal/plate-editor/plate-ui/block-selection.tsx +0 -47
- package/src/internal/plate-editor/plate-ui/block-suggestion.tsx +0 -469
- package/src/internal/plate-editor/plate-ui/blockquote-node-static.tsx +0 -10
- package/src/internal/plate-editor/plate-ui/blockquote-node.tsx +0 -11
- package/src/internal/plate-editor/plate-ui/button.tsx +0 -201
- package/src/internal/plate-editor/plate-ui/calendar.tsx +0 -3
- package/src/internal/plate-editor/plate-ui/callout-node-static.tsx +0 -76
- package/src/internal/plate-editor/plate-ui/callout-node.tsx +0 -54
- package/src/internal/plate-editor/plate-ui/caption.tsx +0 -47
- package/src/internal/plate-editor/plate-ui/checkbox.tsx +0 -3
- package/src/internal/plate-editor/plate-ui/code-block-node-static.tsx +0 -172
- package/src/internal/plate-editor/plate-ui/code-block-node.tsx +0 -226
- package/src/internal/plate-editor/plate-ui/code-node-static.tsx +0 -11
- package/src/internal/plate-editor/plate-ui/code-node.tsx +0 -12
- package/src/internal/plate-editor/plate-ui/column-node-static.tsx +0 -65
- package/src/internal/plate-editor/plate-ui/column-node.tsx +0 -24
- package/src/internal/plate-editor/plate-ui/command.tsx +0 -202
- package/src/internal/plate-editor/plate-ui/comment-node-static.tsx +0 -12
- package/src/internal/plate-editor/plate-ui/comment-node.tsx +0 -45
- package/src/internal/plate-editor/plate-ui/comment-toolbar-button.tsx +0 -24
- package/src/internal/plate-editor/plate-ui/comment.tsx +0 -619
- package/src/internal/plate-editor/plate-ui/cursor-overlay.tsx +0 -85
- package/src/internal/plate-editor/plate-ui/date-node-static.tsx +0 -43
- package/src/internal/plate-editor/plate-ui/date-node.tsx +0 -54
- package/src/internal/plate-editor/plate-ui/dialog.tsx +0 -445
- package/src/internal/plate-editor/plate-ui/dropdown-menu.tsx +0 -264
- package/src/internal/plate-editor/plate-ui/editor-static.tsx +0 -40
- package/src/internal/plate-editor/plate-ui/editor.tsx +0 -146
- package/src/internal/plate-editor/plate-ui/emoji-node.tsx +0 -48
- package/src/internal/plate-editor/plate-ui/emoji-toolbar-button.tsx +0 -626
- package/src/internal/plate-editor/plate-ui/equation-node-static.tsx +0 -155
- package/src/internal/plate-editor/plate-ui/equation-node.tsx +0 -226
- package/src/internal/plate-editor/plate-ui/equation-toolbar-button.tsx +0 -26
- package/src/internal/plate-editor/plate-ui/export-toolbar-button.tsx +0 -206
- package/src/internal/plate-editor/plate-ui/fixed-toolbar-buttons.tsx +0 -157
- package/src/internal/plate-editor/plate-ui/fixed-toolbar.tsx +0 -25
- package/src/internal/plate-editor/plate-ui/floating-discussion.tsx +0 -1129
- package/src/internal/plate-editor/plate-ui/floating-toolbar-buttons.tsx +0 -129
- package/src/internal/plate-editor/plate-ui/floating-toolbar.tsx +0 -97
- package/src/internal/plate-editor/plate-ui/font-color-toolbar-button.tsx +0 -209
- package/src/internal/plate-editor/plate-ui/font-size-toolbar-button.tsx +0 -152
- package/src/internal/plate-editor/plate-ui/ghost-text.tsx +0 -20
- package/src/internal/plate-editor/plate-ui/heading-node-static.tsx +0 -52
- package/src/internal/plate-editor/plate-ui/heading-node.tsx +0 -56
- package/src/internal/plate-editor/plate-ui/highlight-node-static.tsx +0 -9
- package/src/internal/plate-editor/plate-ui/highlight-node.tsx +0 -11
- package/src/internal/plate-editor/plate-ui/history-toolbar-button.tsx +0 -50
- package/src/internal/plate-editor/plate-ui/hover-card.tsx +0 -7
- package/src/internal/plate-editor/plate-ui/hr-node-static.tsx +0 -18
- package/src/internal/plate-editor/plate-ui/hr-node.tsx +0 -28
- package/src/internal/plate-editor/plate-ui/import-toolbar-button.tsx +0 -122
- package/src/internal/plate-editor/plate-ui/indent-toolbar-button.tsx +0 -32
- package/src/internal/plate-editor/plate-ui/inline-combobox.tsx +0 -409
- package/src/internal/plate-editor/plate-ui/input.tsx +0 -37
- package/src/internal/plate-editor/plate-ui/insert-toolbar-button.tsx +0 -258
- package/src/internal/plate-editor/plate-ui/label.tsx +0 -1
- package/src/internal/plate-editor/plate-ui/line-height-toolbar-button.tsx +0 -69
- package/src/internal/plate-editor/plate-ui/link-node-static.tsx +0 -15
- package/src/internal/plate-editor/plate-ui/link-node.tsx +0 -33
- package/src/internal/plate-editor/plate-ui/link-toolbar-button.tsx +0 -28
- package/src/internal/plate-editor/plate-ui/link-toolbar.tsx +0 -147
- package/src/internal/plate-editor/plate-ui/list-toolbar-button.tsx +0 -177
- package/src/internal/plate-editor/plate-ui/mark-toolbar-button.tsx +0 -34
- package/src/internal/plate-editor/plate-ui/media-audio-node-static.tsx +0 -21
- package/src/internal/plate-editor/plate-ui/media-audio-node.tsx +0 -32
- package/src/internal/plate-editor/plate-ui/media-embed-node.tsx +0 -103
- package/src/internal/plate-editor/plate-ui/media-file-node-static.tsx +0 -30
- package/src/internal/plate-editor/plate-ui/media-file-node.tsx +0 -52
- package/src/internal/plate-editor/plate-ui/media-image-node-static.tsx +0 -37
- package/src/internal/plate-editor/plate-ui/media-image-node.tsx +0 -183
- package/src/internal/plate-editor/plate-ui/media-placeholder-node.tsx +0 -441
- package/src/internal/plate-editor/plate-ui/media-preview-dialog.tsx +0 -127
- package/src/internal/plate-editor/plate-ui/media-toolbar-button.tsx +0 -227
- package/src/internal/plate-editor/plate-ui/media-toolbar.tsx +0 -214
- package/src/internal/plate-editor/plate-ui/media-upload-toast.tsx +0 -73
- package/src/internal/plate-editor/plate-ui/media-video-node-static.tsx +0 -35
- package/src/internal/plate-editor/plate-ui/media-video-node.tsx +0 -119
- package/src/internal/plate-editor/plate-ui/mention-node-static.tsx +0 -46
- package/src/internal/plate-editor/plate-ui/mention-node.tsx +0 -79
- package/src/internal/plate-editor/plate-ui/menu.tsx +0 -539
- package/src/internal/plate-editor/plate-ui/mode-toolbar-button.tsx +0 -124
- package/src/internal/plate-editor/plate-ui/more-toolbar-button.tsx +0 -34
- package/src/internal/plate-editor/plate-ui/paragraph-node-static.tsx +0 -15
- package/src/internal/plate-editor/plate-ui/paragraph-node.tsx +0 -16
- package/src/internal/plate-editor/plate-ui/popover.tsx +0 -75
- package/src/internal/plate-editor/plate-ui/progress.tsx +0 -1
- package/src/internal/plate-editor/plate-ui/remote-cursor-overlay.tsx +0 -79
- package/src/internal/plate-editor/plate-ui/resize-handle.tsx +0 -86
- package/src/internal/plate-editor/plate-ui/separator.tsx +0 -41
- package/src/internal/plate-editor/plate-ui/slash-node.tsx +0 -433
- package/src/internal/plate-editor/plate-ui/spinner.tsx +0 -1
- package/src/internal/plate-editor/plate-ui/suggestion-node-static.tsx +0 -35
- package/src/internal/plate-editor/plate-ui/suggestion-node.tsx +0 -166
- package/src/internal/plate-editor/plate-ui/suggestion-toolbar-button.tsx +0 -24
- package/src/internal/plate-editor/plate-ui/table-node-static.tsx +0 -84
- package/src/internal/plate-editor/plate-ui/table-node.tsx +0 -283
- package/src/internal/plate-editor/plate-ui/table-toolbar-button.tsx +0 -252
- package/src/internal/plate-editor/plate-ui/tabs.tsx +0 -3
- package/src/internal/plate-editor/plate-ui/textarea.tsx +0 -57
- package/src/internal/plate-editor/plate-ui/toc-node-static.tsx +0 -142
- package/src/internal/plate-editor/plate-ui/toc-node.tsx +0 -57
- package/src/internal/plate-editor/plate-ui/toc-sidebar.tsx +0 -48
- package/src/internal/plate-editor/plate-ui/toggle-node-static.tsx +0 -18
- package/src/internal/plate-editor/plate-ui/toggle-node.tsx +0 -33
- package/src/internal/plate-editor/plate-ui/toggle-toolbar-button.tsx +0 -24
- package/src/internal/plate-editor/plate-ui/toggle.tsx +0 -3
- package/src/internal/plate-editor/plate-ui/toolbar.tsx +0 -378
- package/src/internal/plate-editor/plate-ui/tooltip.tsx +0 -148
- package/src/internal/plate-editor/plate-ui/turn-into-toolbar-button.tsx +0 -175
- package/src/internal/plate-editor/types/index.ts +0 -22
- package/src/internal/plate-editor/vite.ts +0 -284
- package/src/internal/sheets/components/univer-sheets.tsx +0 -1104
- package/src/internal/sheets/i18n/context.tsx +0 -183
- package/src/internal/sheets/i18n/index.ts +0 -19
- package/src/internal/sheets/i18n/locales/de.json +0 -21
- package/src/internal/sheets/i18n/locales/el.json +0 -21
- package/src/internal/sheets/i18n/locales/en.json +0 -21
- package/src/internal/sheets/i18n/locales/es.json +0 -21
- package/src/internal/sheets/i18n/locales/fr.json +0 -21
- package/src/internal/sheets/i18n/locales/it.json +0 -21
- package/src/internal/sheets/i18n/locales/pt.json +0 -21
- package/src/internal/sheets/i18n/locales/sl.json +0 -21
- package/src/internal/sheets/i18n/locales/tr.json +0 -21
- package/src/internal/sheets/i18n/types.ts +0 -23
- package/src/internal/sheets/i18n/use-translation.ts +0 -17
- package/src/internal/sheets/index.ts +0 -14
- package/src/internal/sheets/types/css.d.ts +0 -11
- package/src/internal/sheets/types/index.ts +0 -260
- package/src/internal/sheets/xlsx.ts +0 -1169
- package/src/lib/api-client.ts +0 -77
- package/src/lib/assistant-api-actions.ts +0 -549
- package/src/lib/assistant-config.tsx +0 -75
- package/src/lib/class-utils.ts +0 -40
- package/src/lib/index.ts +0 -7
- package/src/lib/message-utils.ts +0 -131
- package/src/tools/tools-schema.json +0 -512
- package/src/types/index.ts +0 -235
- package/src/views/assistant-view.tsx +0 -1137
- package/src/views/canvas-app.tsx +0 -839
- package/src/views/canvas-code.tsx +0 -93
- package/src/views/canvas-deep-research.tsx +0 -44
- package/src/views/canvas-image.tsx +0 -25
- package/src/views/canvas-record-view.tsx +0 -285
- package/src/views/canvas-spreadsheet.tsx +0 -125
- package/src/views/canvas-text.tsx +0 -52
- package/src/views/canvas.tsx +0 -274
- package/src/views/chat-panel.tsx +0 -149
- package/src/views/index.ts +0 -20
- package/src/views/memories-panel.tsx +0 -365
- package/src/views/message-list.tsx +0 -370
- package/src/views/project-detail.tsx +0 -257
- package/src/views/projects-panel.tsx +0 -131
- package/src/views/sessions-list.tsx +0 -98
- package/src/views/sidebar-content.tsx +0 -256
- package/src/views/work-detail.tsx +0 -98
- package/src/vite.ts +0 -64
- package/src/worker.ts +0 -203
|
@@ -1,1104 +0,0 @@
|
|
|
1
|
-
// Univer Plugin Mode imports - Core
|
|
2
|
-
import {
|
|
3
|
-
useCallback, useEffect, useRef, useState, type ChangeEvent
|
|
4
|
-
} from 'react';
|
|
5
|
-
|
|
6
|
-
import {
|
|
7
|
-
CommandType,
|
|
8
|
-
ICommandService,
|
|
9
|
-
LocaleType,
|
|
10
|
-
Univer,
|
|
11
|
-
UniverInstanceType,
|
|
12
|
-
type ICommand
|
|
13
|
-
} from '@univerjs/core';
|
|
14
|
-
import { defaultTheme } from '@univerjs/design';
|
|
15
|
-
// ==== LOCALE IMPORTS - English (en-US) ====
|
|
16
|
-
import DesignEnUS from '@univerjs/design/locale/en-US';
|
|
17
|
-
// ==== LOCALE IMPORTS - Spanish (es-ES) ====
|
|
18
|
-
import DesignEsES from '@univerjs/design/locale/es-ES';
|
|
19
|
-
// ==== LOCALE IMPORTS - French (fr-FR) ====
|
|
20
|
-
import DesignFrFR from '@univerjs/design/locale/fr-FR';
|
|
21
|
-
import { UniverDocsPlugin } from '@univerjs/docs';
|
|
22
|
-
import { UniverDocsUIPlugin } from '@univerjs/docs-ui';
|
|
23
|
-
import DocsUIEnUS from '@univerjs/docs-ui/locale/en-US';
|
|
24
|
-
import DocsUIEsES from '@univerjs/docs-ui/locale/es-ES';
|
|
25
|
-
import DocsUIFrFR from '@univerjs/docs-ui/locale/fr-FR';
|
|
26
|
-
// Drawing plugins (required for images)
|
|
27
|
-
import { UniverDrawingPlugin } from '@univerjs/drawing';
|
|
28
|
-
import { UniverDrawingUIPlugin } from '@univerjs/drawing-ui';
|
|
29
|
-
import DrawingUIEnUS from '@univerjs/drawing-ui/locale/en-US';
|
|
30
|
-
import DrawingUIEsES from '@univerjs/drawing-ui/locale/es-ES';
|
|
31
|
-
import DrawingUIFrFR from '@univerjs/drawing-ui/locale/fr-FR';
|
|
32
|
-
import { UniverFormulaEnginePlugin } from '@univerjs/engine-formula';
|
|
33
|
-
import { UniverRenderEnginePlugin } from '@univerjs/engine-render';
|
|
34
|
-
// Find & Replace plugin
|
|
35
|
-
import FindReplaceEnUS from '@univerjs/find-replace/locale/en-US';
|
|
36
|
-
import FindReplaceEsES from '@univerjs/find-replace/locale/es-ES';
|
|
37
|
-
import FindReplaceFrFR from '@univerjs/find-replace/locale/fr-FR';
|
|
38
|
-
import { UniverSheetsPlugin } from '@univerjs/sheets';
|
|
39
|
-
import SheetsEnUS from '@univerjs/sheets/locale/en-US';
|
|
40
|
-
import SheetsEsES from '@univerjs/sheets/locale/es-ES';
|
|
41
|
-
import SheetsFrFR from '@univerjs/sheets/locale/fr-FR';
|
|
42
|
-
// Conditional Formatting plugins
|
|
43
|
-
import { UniverSheetsConditionalFormattingPlugin } from '@univerjs/sheets-conditional-formatting';
|
|
44
|
-
import { UniverSheetsConditionalFormattingUIPlugin } from '@univerjs/sheets-conditional-formatting-ui';
|
|
45
|
-
import SheetsConditionalFormattingUIEnUS from '@univerjs/sheets-conditional-formatting-ui/locale/en-US';
|
|
46
|
-
import SheetsConditionalFormattingUIEsES from '@univerjs/sheets-conditional-formatting-ui/locale/es-ES';
|
|
47
|
-
import SheetsConditionalFormattingUIFrFR from '@univerjs/sheets-conditional-formatting-ui/locale/fr-FR';
|
|
48
|
-
// Crosshair Highlight plugin
|
|
49
|
-
import { UniverSheetsCrosshairHighlightPlugin } from '@univerjs/sheets-crosshair-highlight';
|
|
50
|
-
import SheetsCrosshairHighlightEnUS from '@univerjs/sheets-crosshair-highlight/locale/en-US';
|
|
51
|
-
import SheetsCrosshairHighlightEsES from '@univerjs/sheets-crosshair-highlight/locale/es-ES';
|
|
52
|
-
import SheetsCrosshairHighlightFrFR from '@univerjs/sheets-crosshair-highlight/locale/fr-FR';
|
|
53
|
-
// Data Validation plugins
|
|
54
|
-
import { UniverSheetsDataValidationPlugin } from '@univerjs/sheets-data-validation';
|
|
55
|
-
import { UniverSheetsDataValidationUIPlugin } from '@univerjs/sheets-data-validation-ui';
|
|
56
|
-
import SheetsDataValidationUIEnUS from '@univerjs/sheets-data-validation-ui/locale/en-US';
|
|
57
|
-
import SheetsDataValidationUIEsES from '@univerjs/sheets-data-validation-ui/locale/es-ES';
|
|
58
|
-
import SheetsDataValidationUIFrFR from '@univerjs/sheets-data-validation-ui/locale/fr-FR';
|
|
59
|
-
import { UniverSheetsDrawingPlugin } from '@univerjs/sheets-drawing';
|
|
60
|
-
import { UniverSheetsDrawingUIPlugin } from '@univerjs/sheets-drawing-ui';
|
|
61
|
-
import SheetsDrawingUIEnUS from '@univerjs/sheets-drawing-ui/locale/en-US';
|
|
62
|
-
import SheetsDrawingUIEsES from '@univerjs/sheets-drawing-ui/locale/es-ES';
|
|
63
|
-
import SheetsDrawingUIFrFR from '@univerjs/sheets-drawing-ui/locale/fr-FR';
|
|
64
|
-
// Filter plugins
|
|
65
|
-
import { UniverSheetsFilterPlugin } from '@univerjs/sheets-filter';
|
|
66
|
-
import { UniverSheetsFilterUIPlugin } from '@univerjs/sheets-filter-ui';
|
|
67
|
-
import SheetsFilterUIEnUS from '@univerjs/sheets-filter-ui/locale/en-US';
|
|
68
|
-
import SheetsFilterUIEsES from '@univerjs/sheets-filter-ui/locale/es-ES';
|
|
69
|
-
import SheetsFilterUIFrFR from '@univerjs/sheets-filter-ui/locale/fr-FR';
|
|
70
|
-
import { UniverSheetsFindReplacePlugin } from '@univerjs/sheets-find-replace';
|
|
71
|
-
import SheetsFindReplaceEnUS from '@univerjs/sheets-find-replace/locale/en-US';
|
|
72
|
-
import SheetsFindReplaceEsES from '@univerjs/sheets-find-replace/locale/es-ES';
|
|
73
|
-
import SheetsFindReplaceFrFR from '@univerjs/sheets-find-replace/locale/fr-FR';
|
|
74
|
-
import { UniverSheetsFormulaPlugin } from '@univerjs/sheets-formula';
|
|
75
|
-
import { UniverSheetsFormulaUIPlugin } from '@univerjs/sheets-formula-ui';
|
|
76
|
-
import SheetsFormulaUIEnUS from '@univerjs/sheets-formula-ui/locale/en-US';
|
|
77
|
-
import SheetsFormulaUIEsES from '@univerjs/sheets-formula-ui/locale/es-ES';
|
|
78
|
-
import SheetsFormulaUIFrFR from '@univerjs/sheets-formula-ui/locale/fr-FR';
|
|
79
|
-
// Hyperlink plugins
|
|
80
|
-
import { UniverSheetsHyperLinkPlugin } from '@univerjs/sheets-hyper-link';
|
|
81
|
-
import { UniverSheetsHyperLinkUIPlugin } from '@univerjs/sheets-hyper-link-ui';
|
|
82
|
-
import SheetsHyperLinkUIEnUS from '@univerjs/sheets-hyper-link-ui/locale/en-US';
|
|
83
|
-
import SheetsHyperLinkUIEsES from '@univerjs/sheets-hyper-link-ui/locale/es-ES';
|
|
84
|
-
import SheetsHyperLinkUIFrFR from '@univerjs/sheets-hyper-link-ui/locale/fr-FR';
|
|
85
|
-
import { UniverSheetsNumfmtPlugin } from '@univerjs/sheets-numfmt';
|
|
86
|
-
import { UniverSheetsNumfmtUIPlugin } from '@univerjs/sheets-numfmt-ui';
|
|
87
|
-
import SheetsNumfmtUIEnUS from '@univerjs/sheets-numfmt-ui/locale/en-US';
|
|
88
|
-
import SheetsNumfmtUIEsES from '@univerjs/sheets-numfmt-ui/locale/es-ES';
|
|
89
|
-
import SheetsNumfmtUIFrFR from '@univerjs/sheets-numfmt-ui/locale/fr-FR';
|
|
90
|
-
// Sort plugins
|
|
91
|
-
import { UniverSheetsSortPlugin } from '@univerjs/sheets-sort';
|
|
92
|
-
import { UniverSheetsSortUIPlugin } from '@univerjs/sheets-sort-ui';
|
|
93
|
-
import SheetsSortUIEnUS from '@univerjs/sheets-sort-ui/locale/en-US';
|
|
94
|
-
import SheetsSortUIEsES from '@univerjs/sheets-sort-ui/locale/es-ES';
|
|
95
|
-
import SheetsSortUIFrFR from '@univerjs/sheets-sort-ui/locale/fr-FR';
|
|
96
|
-
// Thread Comment plugins
|
|
97
|
-
import { UniverSheetsThreadCommentPlugin } from '@univerjs/sheets-thread-comment';
|
|
98
|
-
import { UniverSheetsThreadCommentUIPlugin } from '@univerjs/sheets-thread-comment-ui';
|
|
99
|
-
import SheetsThreadCommentUIEnUS from '@univerjs/sheets-thread-comment-ui/locale/en-US';
|
|
100
|
-
import SheetsThreadCommentUIEsES from '@univerjs/sheets-thread-comment-ui/locale/es-ES';
|
|
101
|
-
import SheetsThreadCommentUIFrFR from '@univerjs/sheets-thread-comment-ui/locale/fr-FR';
|
|
102
|
-
import { UniverSheetsUIPlugin } from '@univerjs/sheets-ui';
|
|
103
|
-
import SheetsUIEnUS from '@univerjs/sheets-ui/locale/en-US';
|
|
104
|
-
import SheetsUIEsES from '@univerjs/sheets-ui/locale/es-ES';
|
|
105
|
-
import SheetsUIFrFR from '@univerjs/sheets-ui/locale/fr-FR';
|
|
106
|
-
import ThreadCommentUIEnUS from '@univerjs/thread-comment-ui/locale/en-US';
|
|
107
|
-
import ThreadCommentUIEsES from '@univerjs/thread-comment-ui/locale/es-ES';
|
|
108
|
-
import ThreadCommentUIFrFR from '@univerjs/thread-comment-ui/locale/fr-FR';
|
|
109
|
-
import {
|
|
110
|
-
ComponentManager,
|
|
111
|
-
IMenuManagerService,
|
|
112
|
-
MenuItemType,
|
|
113
|
-
RibbonStartGroup,
|
|
114
|
-
UniverUIPlugin,
|
|
115
|
-
type IFontConfig
|
|
116
|
-
} from '@univerjs/ui';
|
|
117
|
-
import UIEnUS from '@univerjs/ui/locale/en-US';
|
|
118
|
-
import UIEsES from '@univerjs/ui/locale/es-ES';
|
|
119
|
-
import UIFrFR from '@univerjs/ui/locale/fr-FR';
|
|
120
|
-
// Watermark plugin
|
|
121
|
-
import { UniverWatermarkPlugin } from '@univerjs/watermark';
|
|
122
|
-
import { FUniver } from '@univerjs/core/facade';
|
|
123
|
-
|
|
124
|
-
// Facade API imports - Core
|
|
125
|
-
import '@univerjs/sheets/facade';
|
|
126
|
-
import '@univerjs/sheets-ui/facade';
|
|
127
|
-
import '@univerjs/sheets-numfmt/facade';
|
|
128
|
-
|
|
129
|
-
// Facade API imports - Feature plugins
|
|
130
|
-
import '@univerjs/sheets-data-validation/facade';
|
|
131
|
-
import '@univerjs/sheets-conditional-formatting/facade';
|
|
132
|
-
import '@univerjs/sheets-filter/facade';
|
|
133
|
-
import '@univerjs/sheets-sort/facade';
|
|
134
|
-
import '@univerjs/sheets-hyper-link/facade';
|
|
135
|
-
import '@univerjs/sheets-find-replace/facade';
|
|
136
|
-
import '@univerjs/sheets-thread-comment/facade';
|
|
137
|
-
import '@univerjs/sheets-drawing-ui/facade';
|
|
138
|
-
import '@univerjs/watermark/facade';
|
|
139
|
-
import '@univerjs/sheets-crosshair-highlight/facade';
|
|
140
|
-
// CSS imports - order matters!
|
|
141
|
-
import '@univerjs/design/lib/index.css';
|
|
142
|
-
import '@univerjs/ui/lib/index.css';
|
|
143
|
-
import '@univerjs/docs-ui/lib/index.css';
|
|
144
|
-
import '@univerjs/sheets-ui/lib/index.css';
|
|
145
|
-
import '@univerjs/sheets-formula-ui/lib/index.css';
|
|
146
|
-
import '@univerjs/sheets-numfmt-ui/lib/index.css';
|
|
147
|
-
|
|
148
|
-
// CSS imports - Feature plugins
|
|
149
|
-
import '@univerjs/drawing-ui/lib/index.css';
|
|
150
|
-
import '@univerjs/sheets-drawing-ui/lib/index.css';
|
|
151
|
-
import '@univerjs/sheets-data-validation-ui/lib/index.css';
|
|
152
|
-
import '@univerjs/sheets-conditional-formatting-ui/lib/index.css';
|
|
153
|
-
import '@univerjs/sheets-filter-ui/lib/index.css';
|
|
154
|
-
import '@univerjs/sheets-sort-ui/lib/index.css';
|
|
155
|
-
import '@univerjs/sheets-hyper-link-ui/lib/index.css';
|
|
156
|
-
import '@univerjs/sheets-thread-comment-ui/lib/index.css';
|
|
157
|
-
import '@univerjs/sheets-crosshair-highlight/lib/index.css';
|
|
158
|
-
|
|
159
|
-
import { type Locale } from '../i18n/types';
|
|
160
|
-
|
|
161
|
-
import { type IWorkbookData as XlsxWorkbookData } from '../types';
|
|
162
|
-
|
|
163
|
-
import { csvToUniver, downloadWorkbook, xlsxToUniver } from '../xlsx';
|
|
164
|
-
|
|
165
|
-
// Custom font list - only common fonts, excluding Chinese-specific fonts
|
|
166
|
-
const CUSTOM_FONT_LIST: IFontConfig[] = [
|
|
167
|
-
{ value: 'Arial', label: 'fontFamily.arial', category: 'sans-serif' },
|
|
168
|
-
{ value: 'Times New Roman', label: 'fontFamily.times-new-roman', category: 'serif' },
|
|
169
|
-
{ value: 'Tahoma', label: 'fontFamily.tahoma', category: 'sans-serif' },
|
|
170
|
-
{ value: 'Verdana', label: 'fontFamily.verdana', category: 'sans-serif' },
|
|
171
|
-
{ value: 'Georgia', label: 'fontFamily.georgia', category: 'serif' },
|
|
172
|
-
{ value: 'Courier New', label: 'fontFamily.courier-new', category: 'monospace' },
|
|
173
|
-
{ value: 'Trebuchet MS', label: 'fontFamily.trebuchet-ms', category: 'sans-serif' },
|
|
174
|
-
{ value: 'Comic Sans MS', label: 'fontFamily.comic-sans-ms', category: 'handwriting' }
|
|
175
|
-
];
|
|
176
|
-
|
|
177
|
-
// Deep merge utility for locale objects
|
|
178
|
-
function deepMerge(...objects: unknown[]): Record<string, unknown> {
|
|
179
|
-
const result: Record<string, unknown> = {};
|
|
180
|
-
|
|
181
|
-
for (const obj of objects) {
|
|
182
|
-
if (obj && typeof obj === 'object') {
|
|
183
|
-
for (const key of Object.keys(obj)) {
|
|
184
|
-
const value = (obj as Record<string, unknown>)[key];
|
|
185
|
-
|
|
186
|
-
if (
|
|
187
|
-
typeof value === 'object'
|
|
188
|
-
&& value !== null
|
|
189
|
-
&& !Array.isArray(value)
|
|
190
|
-
&& typeof result[key] === 'object'
|
|
191
|
-
&& result[key] !== null
|
|
192
|
-
&& !Array.isArray(result[key])
|
|
193
|
-
) {
|
|
194
|
-
result[key] = deepMerge(result[key] as Record<string, unknown>, value as Record<string, unknown>);
|
|
195
|
-
} else {
|
|
196
|
-
result[key] = value;
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
return result;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
// Additional font family translations for custom fonts not in Univer defaults
|
|
206
|
-
const CUSTOM_FONT_TRANSLATIONS = {
|
|
207
|
-
fontFamily: {
|
|
208
|
-
georgia: 'Georgia',
|
|
209
|
-
'courier-new': 'Courier New',
|
|
210
|
-
'trebuchet-ms': 'Trebuchet MS',
|
|
211
|
-
'comic-sans-ms': 'Comic Sans MS'
|
|
212
|
-
}
|
|
213
|
-
};
|
|
214
|
-
|
|
215
|
-
// Pre-merged locale data for each supported Univer locale
|
|
216
|
-
const UNIVER_LOCALES = {
|
|
217
|
-
'en-US': deepMerge(
|
|
218
|
-
DesignEnUS,
|
|
219
|
-
UIEnUS,
|
|
220
|
-
DocsUIEnUS,
|
|
221
|
-
SheetsEnUS,
|
|
222
|
-
SheetsUIEnUS,
|
|
223
|
-
SheetsFormulaUIEnUS,
|
|
224
|
-
SheetsNumfmtUIEnUS,
|
|
225
|
-
DrawingUIEnUS,
|
|
226
|
-
SheetsDrawingUIEnUS,
|
|
227
|
-
SheetsDataValidationUIEnUS,
|
|
228
|
-
SheetsConditionalFormattingUIEnUS,
|
|
229
|
-
SheetsFilterUIEnUS,
|
|
230
|
-
SheetsSortUIEnUS,
|
|
231
|
-
SheetsHyperLinkUIEnUS,
|
|
232
|
-
FindReplaceEnUS,
|
|
233
|
-
SheetsFindReplaceEnUS,
|
|
234
|
-
ThreadCommentUIEnUS,
|
|
235
|
-
SheetsThreadCommentUIEnUS,
|
|
236
|
-
SheetsCrosshairHighlightEnUS,
|
|
237
|
-
CUSTOM_FONT_TRANSLATIONS
|
|
238
|
-
),
|
|
239
|
-
'es-ES': deepMerge(
|
|
240
|
-
DesignEsES,
|
|
241
|
-
UIEsES,
|
|
242
|
-
DocsUIEsES,
|
|
243
|
-
SheetsEsES,
|
|
244
|
-
SheetsUIEsES,
|
|
245
|
-
SheetsFormulaUIEsES,
|
|
246
|
-
SheetsNumfmtUIEsES,
|
|
247
|
-
DrawingUIEsES,
|
|
248
|
-
SheetsDrawingUIEsES,
|
|
249
|
-
SheetsDataValidationUIEsES,
|
|
250
|
-
SheetsConditionalFormattingUIEsES,
|
|
251
|
-
SheetsFilterUIEsES,
|
|
252
|
-
SheetsSortUIEsES,
|
|
253
|
-
SheetsHyperLinkUIEsES,
|
|
254
|
-
FindReplaceEsES,
|
|
255
|
-
SheetsFindReplaceEsES,
|
|
256
|
-
ThreadCommentUIEsES,
|
|
257
|
-
SheetsThreadCommentUIEsES,
|
|
258
|
-
SheetsCrosshairHighlightEsES,
|
|
259
|
-
CUSTOM_FONT_TRANSLATIONS
|
|
260
|
-
),
|
|
261
|
-
'fr-FR': deepMerge(
|
|
262
|
-
DesignFrFR,
|
|
263
|
-
UIFrFR,
|
|
264
|
-
DocsUIFrFR,
|
|
265
|
-
SheetsFrFR,
|
|
266
|
-
SheetsUIFrFR,
|
|
267
|
-
SheetsFormulaUIFrFR,
|
|
268
|
-
SheetsNumfmtUIFrFR,
|
|
269
|
-
DrawingUIFrFR,
|
|
270
|
-
SheetsDrawingUIFrFR,
|
|
271
|
-
SheetsDataValidationUIFrFR,
|
|
272
|
-
SheetsConditionalFormattingUIFrFR,
|
|
273
|
-
SheetsFilterUIFrFR,
|
|
274
|
-
SheetsSortUIFrFR,
|
|
275
|
-
SheetsHyperLinkUIFrFR,
|
|
276
|
-
FindReplaceFrFR,
|
|
277
|
-
SheetsFindReplaceFrFR,
|
|
278
|
-
ThreadCommentUIFrFR,
|
|
279
|
-
SheetsThreadCommentUIFrFR,
|
|
280
|
-
SheetsCrosshairHighlightFrFR,
|
|
281
|
-
CUSTOM_FONT_TRANSLATIONS
|
|
282
|
-
)
|
|
283
|
-
} as const;
|
|
284
|
-
|
|
285
|
-
type UniverLocaleCode = keyof typeof UNIVER_LOCALES;
|
|
286
|
-
|
|
287
|
-
// Map app locale to Univer locale
|
|
288
|
-
function getUniverLocale(appLocale: Locale): {
|
|
289
|
-
code: UniverLocaleCode;
|
|
290
|
-
type: LocaleType;
|
|
291
|
-
data: Record<string, unknown>;
|
|
292
|
-
} {
|
|
293
|
-
const mapping: Record<Locale, { code: UniverLocaleCode; type: LocaleType }> = {
|
|
294
|
-
en: { code: 'en-US', type: LocaleType.EN_US },
|
|
295
|
-
es: { code: 'es-ES', type: LocaleType.ES_ES },
|
|
296
|
-
fr: { code: 'fr-FR', type: LocaleType.FR_FR },
|
|
297
|
-
de: { code: 'en-US', type: LocaleType.EN_US }, // Fallback - German not supported by Univer
|
|
298
|
-
el: { code: 'en-US', type: LocaleType.EN_US }, // Fallback - Greek not supported by Univer
|
|
299
|
-
it: { code: 'en-US', type: LocaleType.EN_US }, // Fallback - Italian not supported by Univer
|
|
300
|
-
pt: { code: 'en-US', type: LocaleType.EN_US }, // Fallback - Portuguese not supported by Univer
|
|
301
|
-
sl: { code: 'en-US', type: LocaleType.EN_US }, // Fallback - Slovenian not supported by Univer
|
|
302
|
-
tr: { code: 'en-US', type: LocaleType.EN_US } // Fallback - Turkish not supported by Univer
|
|
303
|
-
};
|
|
304
|
-
const localeInfo = mapping[appLocale] || mapping.en;
|
|
305
|
-
|
|
306
|
-
return {
|
|
307
|
-
...localeInfo,
|
|
308
|
-
data: UNIVER_LOCALES[localeInfo.code]
|
|
309
|
-
};
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
/**
|
|
313
|
-
* Map app locale to numfmt locale for decimal/thousands separator
|
|
314
|
-
* This affects how numbers are displayed (e.g., 1,234.56 vs 1.234,56)
|
|
315
|
-
*/
|
|
316
|
-
function getNumfmtLocale(appLocale: Locale): string {
|
|
317
|
-
const mapping: Record<Locale, string> = {
|
|
318
|
-
en: 'en_US',
|
|
319
|
-
es: 'es_ES',
|
|
320
|
-
fr: 'fr_FR',
|
|
321
|
-
de: 'de_DE',
|
|
322
|
-
el: 'el_GR',
|
|
323
|
-
it: 'it_IT',
|
|
324
|
-
pt: 'pt_PT',
|
|
325
|
-
sl: 'sl_SI',
|
|
326
|
-
tr: 'tr_TR'
|
|
327
|
-
};
|
|
328
|
-
|
|
329
|
-
return mapping[appLocale] || 'en_US';
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
/*
|
|
333
|
-
* ============================================================================
|
|
334
|
-
* Import/Export Toolbar Setup
|
|
335
|
-
* ============================================================================
|
|
336
|
-
*/
|
|
337
|
-
|
|
338
|
-
// Command IDs
|
|
339
|
-
const IMPORT_XLSX_COMMAND_ID = 'docyrus.sheets.import-xlsx';
|
|
340
|
-
const EXPORT_XLSX_COMMAND_ID = 'docyrus.sheets.export-xlsx';
|
|
341
|
-
const EXPORT_CSV_COMMAND_ID = 'docyrus.sheets.export-csv';
|
|
342
|
-
|
|
343
|
-
// Import/Export command handlers - will be set by the component
|
|
344
|
-
const importExportHandlers = {
|
|
345
|
-
import: null as (() => void) | null,
|
|
346
|
-
exportXlsx: null as (() => void) | null,
|
|
347
|
-
exportCsv: null as (() => void) | null
|
|
348
|
-
};
|
|
349
|
-
|
|
350
|
-
// Setup import/export toolbar buttons after Univer is initialized
|
|
351
|
-
function setupImportExportToolbar(univer: Univer): void {
|
|
352
|
-
const injector = (univer as any).__injector || (univer as any)._injector;
|
|
353
|
-
|
|
354
|
-
if (!injector) {
|
|
355
|
-
console.warn('[UniverSheets] Could not access injector for toolbar setup');
|
|
356
|
-
|
|
357
|
-
return;
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
try {
|
|
361
|
-
const commandService = injector.get(ICommandService);
|
|
362
|
-
const menuManagerService = injector.get(IMenuManagerService);
|
|
363
|
-
const componentManager = injector.get(ComponentManager);
|
|
364
|
-
|
|
365
|
-
// Register icons
|
|
366
|
-
componentManager.register('ImportIcon', () => (
|
|
367
|
-
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
|
|
368
|
-
<polyline points="17 8 12 3 7 8" />
|
|
369
|
-
<line x1="12" y1="3" x2="12" y2="15" />
|
|
370
|
-
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
|
|
371
|
-
</svg>
|
|
372
|
-
));
|
|
373
|
-
|
|
374
|
-
componentManager.register('ExportXlsxIcon', () => (
|
|
375
|
-
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#217346" strokeWidth="2">
|
|
376
|
-
<polyline points="7 10 12 15 17 10" />
|
|
377
|
-
<line x1="12" y1="15" x2="12" y2="3" />
|
|
378
|
-
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
|
|
379
|
-
</svg>
|
|
380
|
-
));
|
|
381
|
-
|
|
382
|
-
componentManager.register('ExportCsvIcon', () => (
|
|
383
|
-
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#666" strokeWidth="2">
|
|
384
|
-
<polyline points="7 10 12 15 17 10" />
|
|
385
|
-
<line x1="12" y1="15" x2="12" y2="3" />
|
|
386
|
-
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
|
|
387
|
-
</svg>
|
|
388
|
-
));
|
|
389
|
-
|
|
390
|
-
// Register commands
|
|
391
|
-
const importCommand: ICommand = {
|
|
392
|
-
id: IMPORT_XLSX_COMMAND_ID,
|
|
393
|
-
type: CommandType.COMMAND,
|
|
394
|
-
handler: async () => {
|
|
395
|
-
importExportHandlers.import?.();
|
|
396
|
-
|
|
397
|
-
return true;
|
|
398
|
-
}
|
|
399
|
-
};
|
|
400
|
-
|
|
401
|
-
const exportXlsxCommand: ICommand = {
|
|
402
|
-
id: EXPORT_XLSX_COMMAND_ID,
|
|
403
|
-
type: CommandType.COMMAND,
|
|
404
|
-
handler: async () => {
|
|
405
|
-
importExportHandlers.exportXlsx?.();
|
|
406
|
-
|
|
407
|
-
return true;
|
|
408
|
-
}
|
|
409
|
-
};
|
|
410
|
-
|
|
411
|
-
const exportCsvCommand: ICommand = {
|
|
412
|
-
id: EXPORT_CSV_COMMAND_ID,
|
|
413
|
-
type: CommandType.COMMAND,
|
|
414
|
-
handler: async () => {
|
|
415
|
-
importExportHandlers.exportCsv?.();
|
|
416
|
-
|
|
417
|
-
return true;
|
|
418
|
-
}
|
|
419
|
-
};
|
|
420
|
-
|
|
421
|
-
commandService.registerCommand(importCommand);
|
|
422
|
-
commandService.registerCommand(exportXlsxCommand);
|
|
423
|
-
commandService.registerCommand(exportCsvCommand);
|
|
424
|
-
|
|
425
|
-
// Add menu items to toolbar ribbon
|
|
426
|
-
menuManagerService.mergeMenu({
|
|
427
|
-
[RibbonStartGroup.OTHERS]: {
|
|
428
|
-
[IMPORT_XLSX_COMMAND_ID]: {
|
|
429
|
-
order: 0,
|
|
430
|
-
menuItemFactory: () => ({
|
|
431
|
-
id: IMPORT_XLSX_COMMAND_ID,
|
|
432
|
-
title: 'Import',
|
|
433
|
-
tooltip: 'Import XLSX/CSV',
|
|
434
|
-
icon: 'ImportIcon',
|
|
435
|
-
type: MenuItemType.BUTTON
|
|
436
|
-
})
|
|
437
|
-
},
|
|
438
|
-
[EXPORT_XLSX_COMMAND_ID]: {
|
|
439
|
-
order: 1,
|
|
440
|
-
menuItemFactory: () => ({
|
|
441
|
-
id: EXPORT_XLSX_COMMAND_ID,
|
|
442
|
-
title: 'XLSX',
|
|
443
|
-
tooltip: 'Export as XLSX',
|
|
444
|
-
icon: 'ExportXlsxIcon',
|
|
445
|
-
type: MenuItemType.BUTTON
|
|
446
|
-
})
|
|
447
|
-
},
|
|
448
|
-
[EXPORT_CSV_COMMAND_ID]: {
|
|
449
|
-
order: 2,
|
|
450
|
-
menuItemFactory: () => ({
|
|
451
|
-
id: EXPORT_CSV_COMMAND_ID,
|
|
452
|
-
title: 'CSV',
|
|
453
|
-
tooltip: 'Export as CSV',
|
|
454
|
-
icon: 'ExportCsvIcon',
|
|
455
|
-
type: MenuItemType.BUTTON
|
|
456
|
-
})
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
});
|
|
460
|
-
|
|
461
|
-
console.info('[UniverSheets] Import/Export toolbar buttons registered');
|
|
462
|
-
} catch (err) {
|
|
463
|
-
console.warn('[UniverSheets] Failed to setup import/export toolbar:', err);
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
// Type definitions
|
|
468
|
-
export interface SheetsPayload {
|
|
469
|
-
workbookData?: Record<string, unknown>;
|
|
470
|
-
user?: {
|
|
471
|
-
tenantId?: string;
|
|
472
|
-
name?: string;
|
|
473
|
-
};
|
|
474
|
-
recordId?: string;
|
|
475
|
-
versionId?: string;
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
export interface IApiCallPayload {
|
|
479
|
-
id?: string;
|
|
480
|
-
method: string;
|
|
481
|
-
args?: unknown[];
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
export interface UniverSheetsProps {
|
|
485
|
-
/** Initial workbook data to load */
|
|
486
|
-
initialData?: unknown;
|
|
487
|
-
/** Locale for UI translations (default: "en") */
|
|
488
|
-
locale?: Locale;
|
|
489
|
-
/** Commands to execute after the workbook loads */
|
|
490
|
-
commands?: IApiCallPayload[];
|
|
491
|
-
onReady?: () => void;
|
|
492
|
-
onData?: (data: { workbook: unknown; workbookJson: string }) => void;
|
|
493
|
-
onLoaded?: (data: { workbookId: string }) => void;
|
|
494
|
-
onError?: (error: string) => void;
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
const SAMPLE_WORKBOOK_DATA = {};
|
|
498
|
-
|
|
499
|
-
type RangeObj = any;
|
|
500
|
-
type SheetObj = any;
|
|
501
|
-
|
|
502
|
-
const RANGE_ACTIONS: Record<string, (r: RangeObj, a: unknown[]) => void> = {
|
|
503
|
-
setValue: (r, a) => r.setValue(a[0]),
|
|
504
|
-
setValues: (r, a) => r.setValues(a[0]),
|
|
505
|
-
getValue: r => r.getValue(),
|
|
506
|
-
getValues: r => r.getValues(),
|
|
507
|
-
setBackgroundColor: (r, a) => r.setBackgroundColor(a[0]),
|
|
508
|
-
setFontColor: (r, a) => r.setFontColor(a[0]),
|
|
509
|
-
setFontWeight: (r, a) => r.setFontWeight(a[0]),
|
|
510
|
-
setFontStyle: (r, a) => r.setFontStyle(a[0]),
|
|
511
|
-
setFontSize: (r, a) => r.setFontSize(a[0]),
|
|
512
|
-
setFontFamily: (r, a) => r.setFontFamily(a[0]),
|
|
513
|
-
setHorizontalAlignment: (r, a) => r.setHorizontalAlignment(a[0]),
|
|
514
|
-
setVerticalAlignment: (r, a) => r.setVerticalAlignment(a[0]),
|
|
515
|
-
setNumberFormat: (r, a) => r.setNumberFormat(a[0]),
|
|
516
|
-
setWrap: (r, a) => r.setWrap(a[0]),
|
|
517
|
-
setBorder: (r, a) => r.setBorder(a[0], a[1], a[2], a[3], a[4], a[5]),
|
|
518
|
-
setNote: (r, a) => r.setNote(a[0]),
|
|
519
|
-
getNote: r => r.getNote(),
|
|
520
|
-
clearNote: r => r.clearNote(),
|
|
521
|
-
merge: r => r.merge(),
|
|
522
|
-
unmerge: r => r.breakApart(),
|
|
523
|
-
clearFormat: r => r.clearFormat(),
|
|
524
|
-
clearContent: r => r.clearContent(),
|
|
525
|
-
clear: r => r.clear(),
|
|
526
|
-
activate: r => r.activate(),
|
|
527
|
-
isMerged: r => r.isMerged(),
|
|
528
|
-
copyTo: (r, a) => r.copyTo(a[0]),
|
|
529
|
-
sort: (r, a) => r.sort(a[0])
|
|
530
|
-
};
|
|
531
|
-
|
|
532
|
-
const SHEET_ACTIONS: Record<string, (s: SheetObj, a: unknown[]) => void> = {
|
|
533
|
-
insertRowsAfter: (s, a) => s.insertRowsAfter(a[0], a[1]),
|
|
534
|
-
insertRowsBefore: (s, a) => s.insertRowsBefore(a[0], a[1]),
|
|
535
|
-
deleteRows: (s, a) => s.deleteRows(a[0], a[1]),
|
|
536
|
-
insertColumnsAfter: (s, a) => s.insertColumnsAfter(a[0], a[1]),
|
|
537
|
-
insertColumnsBefore: (s, a) => s.insertColumnsBefore(a[0], a[1]),
|
|
538
|
-
deleteColumns: (s, a) => s.deleteColumns(a[0], a[1]),
|
|
539
|
-
setRowHeight: (s, a) => s.setRowHeight(a[0], a[1]),
|
|
540
|
-
setColumnWidth: (s, a) => s.setColumnWidth(a[0], a[1]),
|
|
541
|
-
setFrozenRows: (s, a) => s.setFrozenRows(a[0]),
|
|
542
|
-
setFrozenColumns: (s, a) => s.setFrozenColumns(a[0]),
|
|
543
|
-
setName: (s, a) => s.setName(a[0]),
|
|
544
|
-
activate: s => s.activate(),
|
|
545
|
-
hideRows: (s, a) => s.hideRows(a[0], a[1]),
|
|
546
|
-
showRows: (s, a) => s.showRows(a[0], a[1]),
|
|
547
|
-
hideColumns: (s, a) => s.hideColumns(a[0], a[1]),
|
|
548
|
-
showColumns: (s, a) => s.showColumns(a[0], a[1]),
|
|
549
|
-
zoom: (s, a) => s.zoom(a[0]),
|
|
550
|
-
getMaxRows: s => s.getMaxRows(),
|
|
551
|
-
getMaxColumns: s => s.getMaxColumns()
|
|
552
|
-
};
|
|
553
|
-
|
|
554
|
-
// Instance generation counter to handle React Strict Mode cleanup timing
|
|
555
|
-
let instanceGeneration = 0;
|
|
556
|
-
|
|
557
|
-
export function UniverSheets({
|
|
558
|
-
initialData,
|
|
559
|
-
locale = 'en',
|
|
560
|
-
commands,
|
|
561
|
-
onReady,
|
|
562
|
-
onData,
|
|
563
|
-
onLoaded,
|
|
564
|
-
onError: _onError
|
|
565
|
-
}: UniverSheetsProps) {
|
|
566
|
-
const containerRef = useRef<HTMLDivElement>(null);
|
|
567
|
-
const univerRef = useRef<Univer | null>(null);
|
|
568
|
-
const univerAPIRef = useRef<FUniver | null>(null);
|
|
569
|
-
const instanceGenerationRef = useRef<number>(0);
|
|
570
|
-
const pendingDataRef = useRef<unknown>(null);
|
|
571
|
-
const fileInputRef = useRef<HTMLInputElement>(null);
|
|
572
|
-
const workbookNameRef = useRef<string>('');
|
|
573
|
-
const [isClient, setIsClient] = useState(false);
|
|
574
|
-
|
|
575
|
-
// Store callbacks in refs to avoid effect re-runs when they change
|
|
576
|
-
const onReadyRef = useRef(onReady);
|
|
577
|
-
const onDataRef = useRef(onData);
|
|
578
|
-
const onLoadedRef = useRef(onLoaded);
|
|
579
|
-
// Store initial data in ref - only used on first load
|
|
580
|
-
const initialDataRef = useRef(initialData);
|
|
581
|
-
// Store commands in ref so they're accessible inside the initialization effect
|
|
582
|
-
const commandsRef = useRef(commands);
|
|
583
|
-
// True while the initial createUnit is pending its async doc.command-replace-snapshot
|
|
584
|
-
const isInitializingRef = useRef(false);
|
|
585
|
-
// Skip first-mount run of the commands effect (init effect already handles it)
|
|
586
|
-
const isCommandsInitialMountRef = useRef(true);
|
|
587
|
-
|
|
588
|
-
// Update refs when callbacks change
|
|
589
|
-
useEffect(() => {
|
|
590
|
-
onReadyRef.current = onReady;
|
|
591
|
-
onDataRef.current = onData;
|
|
592
|
-
onLoadedRef.current = onLoaded;
|
|
593
|
-
}, [onReady, onData, onLoaded]);
|
|
594
|
-
|
|
595
|
-
/*
|
|
596
|
-
* Execute an api:call payload directly against the Univer API.
|
|
597
|
-
* Method format: 'range:A1:setValue' | 'sheet:methodName' | 'undo' | 'redo'
|
|
598
|
-
*/
|
|
599
|
-
const executeApiCommand = useCallback(async (payload: IApiCallPayload) => {
|
|
600
|
-
if (!univerAPIRef.current) {
|
|
601
|
-
console.warn('[Sheets] executeApiCommand called but Univer not ready:', payload.method);
|
|
602
|
-
|
|
603
|
-
return;
|
|
604
|
-
}
|
|
605
|
-
|
|
606
|
-
const { method, args = [] } = payload;
|
|
607
|
-
const parts = method.split(':');
|
|
608
|
-
const target = parts[0];
|
|
609
|
-
const action = parts[parts.length - 1];
|
|
610
|
-
|
|
611
|
-
try {
|
|
612
|
-
const workbook = univerAPIRef.current.getActiveWorkbook();
|
|
613
|
-
const sheet = workbook?.getActiveSheet();
|
|
614
|
-
|
|
615
|
-
if (target === 'undo') {
|
|
616
|
-
await univerAPIRef.current.executeCommand('univer.command.undo');
|
|
617
|
-
} else if (target === 'redo') {
|
|
618
|
-
await univerAPIRef.current.executeCommand('univer.command.redo');
|
|
619
|
-
} else if (target === 'range') {
|
|
620
|
-
if (!sheet) throw new Error('No active sheet');
|
|
621
|
-
|
|
622
|
-
const selector = parts.slice(1, -1).join(':');
|
|
623
|
-
const range = sheet.getRange(selector);
|
|
624
|
-
const fn = RANGE_ACTIONS[action];
|
|
625
|
-
|
|
626
|
-
if (fn) {
|
|
627
|
-
fn(range, args);
|
|
628
|
-
} else {
|
|
629
|
-
console.warn('[Sheets] Unknown range action:', action);
|
|
630
|
-
}
|
|
631
|
-
} else if (target === 'sheet') {
|
|
632
|
-
if (!sheet) throw new Error('No active sheet');
|
|
633
|
-
|
|
634
|
-
const fn = SHEET_ACTIONS[action];
|
|
635
|
-
|
|
636
|
-
if (fn) {
|
|
637
|
-
fn(sheet, args);
|
|
638
|
-
} else {
|
|
639
|
-
console.warn('[Sheets] Unknown sheet action:', action);
|
|
640
|
-
}
|
|
641
|
-
} else {
|
|
642
|
-
console.warn('[Sheets] Unknown api:call target:', target);
|
|
643
|
-
}
|
|
644
|
-
} catch (err) {
|
|
645
|
-
console.error('[Sheets] api:call failed:', method, err);
|
|
646
|
-
}
|
|
647
|
-
}, []);
|
|
648
|
-
|
|
649
|
-
/*
|
|
650
|
-
* Handle api:call postMessages from parent
|
|
651
|
-
* Format: { type: 'event', eventName: 'api:call', payload: { id, method, args } }
|
|
652
|
-
*/
|
|
653
|
-
useEffect(() => {
|
|
654
|
-
const handleApiCall = (event: MessageEvent) => {
|
|
655
|
-
if (!event.data || typeof event.data !== 'object') return;
|
|
656
|
-
|
|
657
|
-
const { type, eventName, payload } = event.data;
|
|
658
|
-
|
|
659
|
-
if (type !== 'event' || eventName !== 'api:call' || !payload?.method) return;
|
|
660
|
-
|
|
661
|
-
void executeApiCommand(payload as IApiCallPayload);
|
|
662
|
-
};
|
|
663
|
-
|
|
664
|
-
window.addEventListener('message', handleApiCall);
|
|
665
|
-
|
|
666
|
-
return () => window.removeEventListener('message', handleApiCall);
|
|
667
|
-
}, [executeApiCommand]);
|
|
668
|
-
|
|
669
|
-
// Execute new commands whenever the commands prop changes after initial mount
|
|
670
|
-
useEffect(() => {
|
|
671
|
-
commandsRef.current = commands;
|
|
672
|
-
|
|
673
|
-
if (isCommandsInitialMountRef.current) {
|
|
674
|
-
isCommandsInitialMountRef.current = false;
|
|
675
|
-
|
|
676
|
-
return;
|
|
677
|
-
}
|
|
678
|
-
|
|
679
|
-
if (!commands?.length || !univerAPIRef.current) return;
|
|
680
|
-
|
|
681
|
-
for (const cmd of commands) {
|
|
682
|
-
void executeApiCommand(cmd);
|
|
683
|
-
}
|
|
684
|
-
}, [commands, executeApiCommand]);
|
|
685
|
-
|
|
686
|
-
// Handle file import
|
|
687
|
-
const handleImport = () => {
|
|
688
|
-
fileInputRef.current?.click();
|
|
689
|
-
};
|
|
690
|
-
|
|
691
|
-
const handleFileChange = async (e: ChangeEvent<HTMLInputElement>) => {
|
|
692
|
-
const file = e.target.files?.[0];
|
|
693
|
-
|
|
694
|
-
if (!file) return;
|
|
695
|
-
|
|
696
|
-
try {
|
|
697
|
-
const arrayBuffer = await file.arrayBuffer();
|
|
698
|
-
const bytes = new Uint8Array(arrayBuffer);
|
|
699
|
-
const filename = file.name.toLowerCase();
|
|
700
|
-
const isCSV = filename.endsWith('.csv');
|
|
701
|
-
|
|
702
|
-
let workbookData: XlsxWorkbookData;
|
|
703
|
-
|
|
704
|
-
const workbookName = file.name.replace(/\.[^.]+$/, '');
|
|
705
|
-
|
|
706
|
-
if (isCSV) {
|
|
707
|
-
const text = new TextDecoder().decode(bytes);
|
|
708
|
-
|
|
709
|
-
workbookData = csvToUniver(text, {
|
|
710
|
-
workbookName,
|
|
711
|
-
firstRowIsHeader: true
|
|
712
|
-
});
|
|
713
|
-
} else {
|
|
714
|
-
workbookData = xlsxToUniver(arrayBuffer, {
|
|
715
|
-
workbookName
|
|
716
|
-
});
|
|
717
|
-
}
|
|
718
|
-
|
|
719
|
-
// Track the workbook name for export
|
|
720
|
-
workbookNameRef.current = workbookName;
|
|
721
|
-
|
|
722
|
-
if (univerRef.current) {
|
|
723
|
-
univerRef.current.createUnit(UniverInstanceType.UNIVER_SHEET, workbookData as any);
|
|
724
|
-
}
|
|
725
|
-
} catch (err) {
|
|
726
|
-
console.error('Import error:', err);
|
|
727
|
-
}
|
|
728
|
-
|
|
729
|
-
e.target.value = '';
|
|
730
|
-
};
|
|
731
|
-
|
|
732
|
-
// Get workbook name for export (fallback to ref, sheet name, ID, or timestamp)
|
|
733
|
-
const getExportFileName = useCallback((workbookData: XlsxWorkbookData): string => {
|
|
734
|
-
// Use workbook name from data if available and not empty
|
|
735
|
-
if (workbookData.name && workbookData.name.trim()) {
|
|
736
|
-
return workbookData.name.trim();
|
|
737
|
-
}
|
|
738
|
-
|
|
739
|
-
// Fallback to tracked workbook name (from import or initial load)
|
|
740
|
-
if (workbookNameRef.current && workbookNameRef.current.trim()) {
|
|
741
|
-
return workbookNameRef.current.trim();
|
|
742
|
-
}
|
|
743
|
-
|
|
744
|
-
// Fallback to first sheet name
|
|
745
|
-
if (workbookData.sheets) {
|
|
746
|
-
const sheetOrder = workbookData.sheetOrder || Object.keys(workbookData.sheets);
|
|
747
|
-
const firstSheetId = sheetOrder[0];
|
|
748
|
-
|
|
749
|
-
if (firstSheetId && workbookData.sheets[firstSheetId]?.name) {
|
|
750
|
-
const sheetName = workbookData.sheets[firstSheetId].name.trim();
|
|
751
|
-
|
|
752
|
-
if (sheetName) {
|
|
753
|
-
return sheetName;
|
|
754
|
-
}
|
|
755
|
-
}
|
|
756
|
-
}
|
|
757
|
-
|
|
758
|
-
// Fallback to workbook ID
|
|
759
|
-
if (workbookData.id) {
|
|
760
|
-
return `Spreadsheet_${workbookData.id}`;
|
|
761
|
-
}
|
|
762
|
-
|
|
763
|
-
// Last resort: timestamp
|
|
764
|
-
return `Spreadsheet_${new Date().toISOString().slice(0, 10)}`;
|
|
765
|
-
}, []);
|
|
766
|
-
|
|
767
|
-
// Handle file export using SheetJS
|
|
768
|
-
const handleExportXlsx = useCallback(() => {
|
|
769
|
-
try {
|
|
770
|
-
const workbook = univerAPIRef.current?.getActiveWorkbook();
|
|
771
|
-
|
|
772
|
-
if (!workbook) return;
|
|
773
|
-
|
|
774
|
-
const workbookData = workbook.save() as unknown as XlsxWorkbookData;
|
|
775
|
-
const name = getExportFileName(workbookData);
|
|
776
|
-
|
|
777
|
-
downloadWorkbook(workbookData, name, 'xlsx');
|
|
778
|
-
} catch (err) {
|
|
779
|
-
console.error('XLSX Export error:', err);
|
|
780
|
-
}
|
|
781
|
-
}, [getExportFileName]);
|
|
782
|
-
|
|
783
|
-
// Handle CSV export (uses SheetJS - simpler format)
|
|
784
|
-
const handleExportCsv = useCallback(() => {
|
|
785
|
-
try {
|
|
786
|
-
const workbook = univerAPIRef.current?.getActiveWorkbook();
|
|
787
|
-
|
|
788
|
-
if (!workbook) return;
|
|
789
|
-
|
|
790
|
-
const workbookData = workbook.save() as unknown as XlsxWorkbookData;
|
|
791
|
-
const name = getExportFileName(workbookData);
|
|
792
|
-
|
|
793
|
-
downloadWorkbook(workbookData, name, 'csv');
|
|
794
|
-
} catch (err) {
|
|
795
|
-
console.error('CSV Export error:', err);
|
|
796
|
-
}
|
|
797
|
-
}, [getExportFileName]);
|
|
798
|
-
|
|
799
|
-
// Client-side only check
|
|
800
|
-
useEffect(() => {
|
|
801
|
-
setIsClient(true);
|
|
802
|
-
}, []);
|
|
803
|
-
|
|
804
|
-
// Initialize Univer
|
|
805
|
-
useEffect(() => {
|
|
806
|
-
if (!isClient || !containerRef.current) return;
|
|
807
|
-
|
|
808
|
-
// Get locale data synchronously
|
|
809
|
-
const univerLocale = getUniverLocale(locale);
|
|
810
|
-
|
|
811
|
-
// Increment generation and capture for this effect instance
|
|
812
|
-
instanceGeneration++;
|
|
813
|
-
const currentGeneration = instanceGeneration;
|
|
814
|
-
|
|
815
|
-
instanceGenerationRef.current = currentGeneration;
|
|
816
|
-
|
|
817
|
-
// Always dispose existing instance first (handles React Strict Mode)
|
|
818
|
-
if (univerRef.current) {
|
|
819
|
-
univerRef.current.dispose();
|
|
820
|
-
univerRef.current = null;
|
|
821
|
-
univerAPIRef.current = null;
|
|
822
|
-
}
|
|
823
|
-
|
|
824
|
-
const container = containerRef.current;
|
|
825
|
-
const rect = container.getBoundingClientRect();
|
|
826
|
-
|
|
827
|
-
// If container has no dimensions, wait for next frame
|
|
828
|
-
if (rect.width === 0 || rect.height === 0) {
|
|
829
|
-
const timerId = setTimeout(() => {
|
|
830
|
-
// Force re-render by updating isClient (already true, but React will re-run effect)
|
|
831
|
-
setIsClient(true);
|
|
832
|
-
}, 50);
|
|
833
|
-
|
|
834
|
-
return () => clearTimeout(timerId);
|
|
835
|
-
}
|
|
836
|
-
|
|
837
|
-
const univer = new Univer({
|
|
838
|
-
theme: defaultTheme,
|
|
839
|
-
locale: univerLocale.type,
|
|
840
|
-
locales: {
|
|
841
|
-
[univerLocale.type]: univerLocale.data
|
|
842
|
-
} as any
|
|
843
|
-
});
|
|
844
|
-
|
|
845
|
-
// Register core plugins in order
|
|
846
|
-
univer.registerPlugin(UniverRenderEnginePlugin as any);
|
|
847
|
-
univer.registerPlugin(UniverFormulaEnginePlugin as any);
|
|
848
|
-
univer.registerPlugin(UniverUIPlugin as any, {
|
|
849
|
-
container: containerRef.current,
|
|
850
|
-
customFontFamily: {
|
|
851
|
-
override: true,
|
|
852
|
-
list: CUSTOM_FONT_LIST
|
|
853
|
-
}
|
|
854
|
-
});
|
|
855
|
-
|
|
856
|
-
univer.registerPlugin(UniverDocsPlugin as any);
|
|
857
|
-
univer.registerPlugin(UniverDocsUIPlugin as any);
|
|
858
|
-
|
|
859
|
-
univer.registerPlugin(UniverSheetsPlugin as any);
|
|
860
|
-
univer.registerPlugin(UniverSheetsUIPlugin as any);
|
|
861
|
-
univer.registerPlugin(UniverSheetsFormulaPlugin as any);
|
|
862
|
-
univer.registerPlugin(UniverSheetsFormulaUIPlugin as any);
|
|
863
|
-
univer.registerPlugin(UniverSheetsNumfmtPlugin as any);
|
|
864
|
-
univer.registerPlugin(UniverSheetsNumfmtUIPlugin as any);
|
|
865
|
-
|
|
866
|
-
// Register Drawing plugins
|
|
867
|
-
univer.registerPlugin(UniverDrawingPlugin as any);
|
|
868
|
-
univer.registerPlugin(UniverDrawingUIPlugin as any);
|
|
869
|
-
univer.registerPlugin(UniverSheetsDrawingPlugin as any);
|
|
870
|
-
univer.registerPlugin(UniverSheetsDrawingUIPlugin as any);
|
|
871
|
-
|
|
872
|
-
// Register feature plugins
|
|
873
|
-
univer.registerPlugin(UniverSheetsDataValidationPlugin as any);
|
|
874
|
-
univer.registerPlugin(UniverSheetsDataValidationUIPlugin as any);
|
|
875
|
-
univer.registerPlugin(UniverSheetsConditionalFormattingPlugin as any);
|
|
876
|
-
univer.registerPlugin(UniverSheetsConditionalFormattingUIPlugin as any);
|
|
877
|
-
univer.registerPlugin(UniverSheetsFilterPlugin as any);
|
|
878
|
-
univer.registerPlugin(UniverSheetsFilterUIPlugin as any);
|
|
879
|
-
univer.registerPlugin(UniverSheetsSortPlugin as any);
|
|
880
|
-
univer.registerPlugin(UniverSheetsSortUIPlugin as any);
|
|
881
|
-
univer.registerPlugin(UniverSheetsHyperLinkPlugin as any);
|
|
882
|
-
univer.registerPlugin(UniverSheetsHyperLinkUIPlugin as any);
|
|
883
|
-
univer.registerPlugin(UniverSheetsFindReplacePlugin as any);
|
|
884
|
-
univer.registerPlugin(UniverSheetsThreadCommentPlugin as any);
|
|
885
|
-
univer.registerPlugin(UniverSheetsThreadCommentUIPlugin as any);
|
|
886
|
-
univer.registerPlugin(UniverWatermarkPlugin as any);
|
|
887
|
-
univer.registerPlugin(UniverSheetsCrosshairHighlightPlugin as any);
|
|
888
|
-
|
|
889
|
-
univerRef.current = univer;
|
|
890
|
-
univerAPIRef.current = FUniver.newAPI(univer);
|
|
891
|
-
|
|
892
|
-
// Listen for workbook changes
|
|
893
|
-
let debounceTimer: ReturnType<typeof setTimeout> | null = null;
|
|
894
|
-
const univerAPI = univerAPIRef.current;
|
|
895
|
-
|
|
896
|
-
univerAPI.addEvent(univerAPI.Event.CommandExecuted, (event) => {
|
|
897
|
-
/*
|
|
898
|
-
* Only react to user-level commands (CommandType.COMMAND = 0).
|
|
899
|
-
* System plugins such as SHEET_FILTER_PLUGIN fire CommandType.MUTATION (2)
|
|
900
|
-
* directly without a command wrapper, which must not trigger a save.
|
|
901
|
-
* All user actions (typing, paste, API calls via FUniver) go through
|
|
902
|
-
* CommandType.COMMAND first, so this is the correct layer to listen on.
|
|
903
|
-
*/
|
|
904
|
-
if (event.type !== CommandType.COMMAND) return;
|
|
905
|
-
|
|
906
|
-
const cmd = event.id || '';
|
|
907
|
-
|
|
908
|
-
/*
|
|
909
|
-
* Skip the async snapshot-replace fired by createUnit during initialization.
|
|
910
|
-
* Once it fires, clear the flag so subsequent calls (e.g. file import) are saved.
|
|
911
|
-
*/
|
|
912
|
-
if (cmd === 'doc.command-replace-snapshot') {
|
|
913
|
-
isInitializingRef.current = false;
|
|
914
|
-
|
|
915
|
-
return;
|
|
916
|
-
}
|
|
917
|
-
|
|
918
|
-
// Skip UI-only commands that don't change workbook data
|
|
919
|
-
const isUICommand
|
|
920
|
-
= cmd.includes('select')
|
|
921
|
-
|| cmd.includes('scroll')
|
|
922
|
-
|| cmd.includes('focus')
|
|
923
|
-
|| cmd.includes('hover')
|
|
924
|
-
|| cmd.includes('click')
|
|
925
|
-
|| cmd.includes('cursor')
|
|
926
|
-
|| cmd.includes('highlight')
|
|
927
|
-
|| cmd.includes('zoom')
|
|
928
|
-
|| cmd.includes('view')
|
|
929
|
-
|| cmd.includes('activate')
|
|
930
|
-
|| cmd.includes('editor')
|
|
931
|
-
|| cmd.includes('operation');
|
|
932
|
-
|
|
933
|
-
if (isUICommand) return;
|
|
934
|
-
|
|
935
|
-
const isMutation
|
|
936
|
-
= cmd.includes('set-range-values')
|
|
937
|
-
|| cmd.includes('set-cell')
|
|
938
|
-
|| cmd.includes('insert-row')
|
|
939
|
-
|| cmd.includes('insert-col')
|
|
940
|
-
|| cmd.includes('delete-row')
|
|
941
|
-
|| cmd.includes('delete-col')
|
|
942
|
-
|| cmd.includes('remove-row')
|
|
943
|
-
|| cmd.includes('remove-col')
|
|
944
|
-
|| cmd.includes('move-row')
|
|
945
|
-
|| cmd.includes('move-col')
|
|
946
|
-
|| cmd.includes('add-merge')
|
|
947
|
-
|| cmd.includes('remove-merge')
|
|
948
|
-
|| cmd.includes('clear-selection')
|
|
949
|
-
|| cmd.includes('set-worksheet-name')
|
|
950
|
-
|| cmd.includes('paste')
|
|
951
|
-
|| cmd.includes('cut')
|
|
952
|
-
|| cmd.includes('set-style')
|
|
953
|
-
|| cmd.includes('set-format')
|
|
954
|
-
|| cmd.includes('undo')
|
|
955
|
-
|| cmd.includes('redo');
|
|
956
|
-
|
|
957
|
-
if (!isMutation) return;
|
|
958
|
-
|
|
959
|
-
if (debounceTimer) clearTimeout(debounceTimer);
|
|
960
|
-
debounceTimer = setTimeout(() => {
|
|
961
|
-
const workbook = univerAPIRef.current?.getActiveWorkbook();
|
|
962
|
-
|
|
963
|
-
if (!workbook) return;
|
|
964
|
-
|
|
965
|
-
const snapshot = workbook.save();
|
|
966
|
-
|
|
967
|
-
onDataRef.current?.({
|
|
968
|
-
workbook: snapshot,
|
|
969
|
-
workbookJson: JSON.stringify(snapshot)
|
|
970
|
-
});
|
|
971
|
-
}, 300);
|
|
972
|
-
});
|
|
973
|
-
|
|
974
|
-
onReadyRef.current?.();
|
|
975
|
-
|
|
976
|
-
// Set up toolbar command handlers
|
|
977
|
-
importExportHandlers.import = handleImport;
|
|
978
|
-
importExportHandlers.exportXlsx = handleExportXlsx;
|
|
979
|
-
importExportHandlers.exportCsv = handleExportCsv;
|
|
980
|
-
|
|
981
|
-
// Setup import/export toolbar buttons
|
|
982
|
-
setupImportExportToolbar(univer);
|
|
983
|
-
|
|
984
|
-
// Use initialData prop or pendingDataRef or empty workbook
|
|
985
|
-
const workbookData = initialDataRef.current || pendingDataRef.current;
|
|
986
|
-
|
|
987
|
-
if (workbookData) {
|
|
988
|
-
console.info('[UniverSheets] Loading workbook data:', workbookData);
|
|
989
|
-
|
|
990
|
-
// Track workbook name from loaded data
|
|
991
|
-
const loadedName = (workbookData as any).name;
|
|
992
|
-
|
|
993
|
-
if (loadedName && loadedName.trim()) {
|
|
994
|
-
workbookNameRef.current = loadedName.trim();
|
|
995
|
-
}
|
|
996
|
-
|
|
997
|
-
isInitializingRef.current = true;
|
|
998
|
-
univer.createUnit(UniverInstanceType.UNIVER_SHEET, workbookData as any);
|
|
999
|
-
onLoadedRef.current?.({ workbookId: (workbookData as any).id });
|
|
1000
|
-
pendingDataRef.current = null;
|
|
1001
|
-
} else {
|
|
1002
|
-
console.info('[UniverSheets] Creating empty workbook');
|
|
1003
|
-
univer.createUnit(UniverInstanceType.UNIVER_SHEET, SAMPLE_WORKBOOK_DATA);
|
|
1004
|
-
}
|
|
1005
|
-
|
|
1006
|
-
// Execute initial commands after the workbook is fully initialized
|
|
1007
|
-
const pendingCommands = commandsRef.current;
|
|
1008
|
-
|
|
1009
|
-
if (pendingCommands && pendingCommands.length > 0) {
|
|
1010
|
-
for (const cmd of pendingCommands) {
|
|
1011
|
-
void executeApiCommand(cmd);
|
|
1012
|
-
}
|
|
1013
|
-
}
|
|
1014
|
-
|
|
1015
|
-
// Set numfmt locale for decimal/thousands separator based on app locale
|
|
1016
|
-
const numfmtLocale = getNumfmtLocale(locale);
|
|
1017
|
-
const activeWorkbook = univerAPIRef.current?.getActiveWorkbook();
|
|
1018
|
-
|
|
1019
|
-
if (activeWorkbook) {
|
|
1020
|
-
try {
|
|
1021
|
-
(activeWorkbook as any).setNumfmtLocal(numfmtLocale);
|
|
1022
|
-
console.info('[UniverSheets] Set numfmt locale to:', numfmtLocale);
|
|
1023
|
-
} catch (e) {
|
|
1024
|
-
console.warn('[UniverSheets] Failed to set numfmt locale:', e);
|
|
1025
|
-
}
|
|
1026
|
-
}
|
|
1027
|
-
|
|
1028
|
-
return () => {
|
|
1029
|
-
/*
|
|
1030
|
-
* Only dispose if this cleanup is for the current generation
|
|
1031
|
-
* This prevents React Strict Mode's first cleanup from disposing
|
|
1032
|
-
* the instance created by the second render
|
|
1033
|
-
*/
|
|
1034
|
-
if (instanceGenerationRef.current === currentGeneration) {
|
|
1035
|
-
console.info('[UniverSheets] Cleanup - disposing generation:', currentGeneration);
|
|
1036
|
-
|
|
1037
|
-
// Defer dispose to next tick to avoid React concurrent rendering conflicts
|
|
1038
|
-
queueMicrotask(() => {
|
|
1039
|
-
try {
|
|
1040
|
-
univer.dispose();
|
|
1041
|
-
} catch (e) {
|
|
1042
|
-
/*
|
|
1043
|
-
* Ignore errors during dispose - can happen when navigating away
|
|
1044
|
-
* while Univer's internal callbacks are still running
|
|
1045
|
-
*/
|
|
1046
|
-
console.warn('[UniverSheets] Error during dispose (safe to ignore):', e);
|
|
1047
|
-
}
|
|
1048
|
-
});
|
|
1049
|
-
|
|
1050
|
-
univerRef.current = null;
|
|
1051
|
-
univerAPIRef.current = null;
|
|
1052
|
-
} else {
|
|
1053
|
-
console.info(
|
|
1054
|
-
'[UniverSheets] Cleanup - skipping stale generation:',
|
|
1055
|
-
currentGeneration,
|
|
1056
|
-
'current:',
|
|
1057
|
-
instanceGenerationRef.current
|
|
1058
|
-
);
|
|
1059
|
-
}
|
|
1060
|
-
};
|
|
1061
|
-
}, [
|
|
1062
|
-
isClient,
|
|
1063
|
-
locale,
|
|
1064
|
-
handleExportXlsx,
|
|
1065
|
-
handleExportCsv,
|
|
1066
|
-
executeApiCommand
|
|
1067
|
-
]);
|
|
1068
|
-
|
|
1069
|
-
if (!isClient) {
|
|
1070
|
-
return (
|
|
1071
|
-
<div
|
|
1072
|
-
style={{
|
|
1073
|
-
width: '100%',
|
|
1074
|
-
height: '100%',
|
|
1075
|
-
display: 'flex',
|
|
1076
|
-
alignItems: 'center',
|
|
1077
|
-
justifyContent: 'center',
|
|
1078
|
-
background: '#f5f5f5'
|
|
1079
|
-
}}>
|
|
1080
|
-
<span>Loading...</span>
|
|
1081
|
-
</div>
|
|
1082
|
-
);
|
|
1083
|
-
}
|
|
1084
|
-
|
|
1085
|
-
return (
|
|
1086
|
-
<div style={{ position: 'absolute', inset: 0 }}>
|
|
1087
|
-
{/* Hidden file input for import - triggered by toolbar button */}
|
|
1088
|
-
<input
|
|
1089
|
-
ref={fileInputRef}
|
|
1090
|
-
type="file"
|
|
1091
|
-
accept=".xlsx,.xls,.csv"
|
|
1092
|
-
onChange={handleFileChange}
|
|
1093
|
-
style={{ display: 'none' }} />
|
|
1094
|
-
|
|
1095
|
-
<div
|
|
1096
|
-
ref={containerRef}
|
|
1097
|
-
style={{
|
|
1098
|
-
position: 'absolute',
|
|
1099
|
-
inset: 0,
|
|
1100
|
-
overflow: 'hidden'
|
|
1101
|
-
}} />
|
|
1102
|
-
</div>
|
|
1103
|
-
);
|
|
1104
|
-
}
|