@parhelia/core 0.1.12556 → 0.1.12560
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/dist/agents-view/AgentCard.d.ts +6 -4
- package/dist/agents-view/AgentCard.js +143 -24
- package/dist/agents-view/AgentCard.js.map +1 -1
- package/dist/agents-view/AgentsInbox.d.ts +1 -1
- package/dist/agents-view/AgentsInbox.js +7 -92
- package/dist/agents-view/AgentsInbox.js.map +1 -1
- package/dist/agents-view/AgentsTitlebar.js +3 -2
- package/dist/agents-view/AgentsTitlebar.js.map +1 -1
- package/dist/agents-view/AgentsView.d.ts +6 -7
- package/dist/agents-view/AgentsView.js +187 -98
- package/dist/agents-view/AgentsView.js.map +1 -1
- package/dist/agents-view/AgentsWorkspaceView.d.ts +2 -6
- package/dist/agents-view/AgentsWorkspaceView.js +266 -113
- package/dist/agents-view/AgentsWorkspaceView.js.map +1 -1
- package/dist/agents-view/ProfileAgentsGroup.d.ts +2 -1
- package/dist/agents-view/ProfileAgentsGroup.js +4 -3
- package/dist/agents-view/ProfileAgentsGroup.js.map +1 -1
- package/dist/components/ActionButton.d.ts +1 -1
- package/dist/components/ActionButton.js.map +1 -1
- package/dist/components/FilterInput.d.ts +1 -1
- package/dist/components/FilterInput.js +1 -1
- package/dist/components/FilterInput.js.map +1 -1
- package/dist/components/ui/LanguageSelector.js +2 -4
- package/dist/components/ui/LanguageSelector.js.map +1 -1
- package/dist/components/ui/PlaceholderInput.js +3 -3
- package/dist/components/ui/PlaceholderInput.js.map +1 -1
- package/dist/components/ui/PlaceholderInputTypes.js +1 -1
- package/dist/components/ui/PlaceholderInputTypes.js.map +1 -1
- package/dist/components/ui/alert-dialog.d.ts +1 -1
- package/dist/components/ui/alert-dialog.js +6 -10
- package/dist/components/ui/alert-dialog.js.map +1 -1
- package/dist/components/ui/button.d.ts +4 -4
- package/dist/components/ui/button.js +4 -1
- package/dist/components/ui/button.js.map +1 -1
- package/dist/components/ui/context-menu.d.ts +1 -1
- package/dist/components/ui/context-menu.js +12 -4
- package/dist/components/ui/context-menu.js.map +1 -1
- package/dist/components/ui/copy-button.d.ts +2 -1
- package/dist/components/ui/copy-button.js +2 -2
- package/dist/components/ui/copy-button.js.map +1 -1
- package/dist/components/ui/dialog.d.ts +1 -1
- package/dist/components/ui/dialog.js +21 -126
- package/dist/components/ui/dialog.js.map +1 -1
- package/dist/components/ui/input.d.ts +1 -1
- package/dist/components/ui/input.js +5 -3
- package/dist/components/ui/input.js.map +1 -1
- package/dist/components/ui/paste-button.d.ts +2 -1
- package/dist/components/ui/paste-button.js +2 -2
- package/dist/components/ui/paste-button.js.map +1 -1
- package/dist/components/ui/popover.js +1 -9
- package/dist/components/ui/popover.js.map +1 -1
- package/dist/components/ui/select.js +1 -1
- package/dist/components/ui/select.js.map +1 -1
- package/dist/components/ui/styled-dialog-title.js +1 -1
- package/dist/components/ui/styled-dialog-title.js.map +1 -1
- package/dist/components/ui/tabs.d.ts +1 -1
- package/dist/components/ui/tabs.js +4 -11
- package/dist/components/ui/tabs.js.map +1 -1
- package/dist/config/config.d.ts +4 -2
- package/dist/config/config.js +250 -70
- package/dist/config/config.js.map +1 -1
- package/dist/config/notificationRoutes.js +14 -0
- package/dist/config/notificationRoutes.js.map +1 -1
- package/dist/config/types/workspace.d.ts +6 -0
- package/dist/config/types.d.ts +63 -12
- package/dist/config/types.js.map +1 -1
- package/dist/editor/ConfirmationDialog.js +20 -4
- package/dist/editor/ConfirmationDialog.js.map +1 -1
- package/dist/editor/ContentTree.d.ts +2 -1
- package/dist/editor/ContentTree.js +93 -32
- package/dist/editor/ContentTree.js.map +1 -1
- package/dist/editor/Editor.js +87 -22
- package/dist/editor/Editor.js.map +1 -1
- package/dist/editor/FieldHistory.js +84 -36
- package/dist/editor/FieldHistory.js.map +1 -1
- package/dist/editor/FieldListField.js +21 -9
- package/dist/editor/FieldListField.js.map +1 -1
- package/dist/editor/FieldListFieldWithFallbacks.js +23 -2
- package/dist/editor/FieldListFieldWithFallbacks.js.map +1 -1
- package/dist/editor/GlobalMenuBar.js +29 -2
- package/dist/editor/GlobalMenuBar.js.map +1 -1
- package/dist/editor/ImageEditor.js +5 -2
- package/dist/editor/ImageEditor.js.map +1 -1
- package/dist/editor/ItemInfo.js +36 -1
- package/dist/editor/ItemInfo.js.map +1 -1
- package/dist/editor/LinkEditorDialog.js +3 -0
- package/dist/editor/LinkEditorDialog.js.map +1 -1
- package/dist/editor/MainLayout.d.ts +0 -2
- package/dist/editor/MainLayout.js +65 -8
- package/dist/editor/MainLayout.js.map +1 -1
- package/dist/editor/MigrationsView.js +29 -5
- package/dist/editor/MigrationsView.js.map +1 -1
- package/dist/editor/MobileLayout.js +37 -12
- package/dist/editor/MobileLayout.js.map +1 -1
- package/dist/editor/PictureCropper.js +54 -45
- package/dist/editor/PictureCropper.js.map +1 -1
- package/dist/editor/PictureEditor.js +17 -15
- package/dist/editor/PictureEditor.js.map +1 -1
- package/dist/editor/QuickItemSwitcher.js +21 -21
- package/dist/editor/QuickItemSwitcher.js.map +1 -1
- package/dist/editor/SetupWizard.js +52 -12
- package/dist/editor/SetupWizard.js.map +1 -1
- package/dist/editor/Titlebar.js +7 -2
- package/dist/editor/Titlebar.js.map +1 -1
- package/dist/editor/ai/AgentCostDisplay.d.ts +1 -0
- package/dist/editor/ai/AgentCostDisplay.js +1 -1
- package/dist/editor/ai/AgentCostDisplay.js.map +1 -1
- package/dist/editor/ai/AgentDocumentList.js +32 -14
- package/dist/editor/ai/AgentDocumentList.js.map +1 -1
- package/dist/editor/ai/AgentGreeting.js +3 -2
- package/dist/editor/ai/AgentGreeting.js.map +1 -1
- package/dist/editor/ai/AgentProfileSelector.js +2 -1
- package/dist/editor/ai/AgentProfileSelector.js.map +1 -1
- package/dist/editor/ai/AgentStatusBadge.d.ts +0 -5
- package/dist/editor/ai/AgentStatusBadge.js +67 -65
- package/dist/editor/ai/AgentStatusBadge.js.map +1 -1
- package/dist/editor/ai/AgentTerminal.d.ts +14 -2
- package/dist/editor/ai/AgentTerminal.js +2377 -483
- package/dist/editor/ai/AgentTerminal.js.map +1 -1
- package/dist/editor/ai/AgentTerminalStatusBar.d.ts +8 -3
- package/dist/editor/ai/AgentTerminalStatusBar.js +460 -56
- package/dist/editor/ai/AgentTerminalStatusBar.js.map +1 -1
- package/dist/editor/ai/Agents.js +150 -113
- package/dist/editor/ai/Agents.js.map +1 -1
- package/dist/editor/ai/AiResponseMessage.d.ts +10 -1
- package/dist/editor/ai/AiResponseMessage.js +238 -23
- package/dist/editor/ai/AiResponseMessage.js.map +1 -1
- package/dist/editor/ai/ContextInfoBar.d.ts +2 -3
- package/dist/editor/ai/ContextInfoBar.js +64 -7
- package/dist/editor/ai/ContextInfoBar.js.map +1 -1
- package/dist/editor/ai/GuidanceOverlay.js +17 -11
- package/dist/editor/ai/GuidanceOverlay.js.map +1 -1
- package/dist/editor/ai/InlineAiDialog.d.ts +1 -1
- package/dist/editor/ai/InlineAiDialog.js +514 -192
- package/dist/editor/ai/InlineAiDialog.js.map +1 -1
- package/dist/editor/ai/InlineAiTrigger.js +115 -12
- package/dist/editor/ai/InlineAiTrigger.js.map +1 -1
- package/dist/editor/ai/MediaImage.js +40 -8
- package/dist/editor/ai/MediaImage.js.map +1 -1
- package/dist/editor/ai/SpawnedAgentsPanel.js +10 -12
- package/dist/editor/ai/SpawnedAgentsPanel.js.map +1 -1
- package/dist/editor/ai/ToolCallDisplay.d.ts +22 -2
- package/dist/editor/ai/ToolCallDisplay.js +518 -147
- package/dist/editor/ai/ToolCallDisplay.js.map +1 -1
- package/dist/editor/ai/dialogs/AgentDialogHandler.d.ts +1 -8
- package/dist/editor/ai/dialogs/AgentDialogHandler.js +379 -42
- package/dist/editor/ai/dialogs/AgentDialogHandler.js.map +1 -1
- package/dist/editor/ai/dialogs/QuestionnaireInline.d.ts +5 -1
- package/dist/editor/ai/dialogs/QuestionnaireInline.js +628 -60
- package/dist/editor/ai/dialogs/QuestionnaireInline.js.map +1 -1
- package/dist/editor/ai/dialogs/agentDialogTypes.d.ts +115 -0
- package/dist/editor/ai/dialogs/agentDialogTypes.js +2 -0
- package/dist/editor/ai/dialogs/agentDialogTypes.js.map +1 -1
- package/dist/editor/ai/types.d.ts +3 -1
- package/dist/editor/ai/useAgentStatus.d.ts +2 -1
- package/dist/editor/ai/useAgentStatus.js +86 -99
- package/dist/editor/ai/useAgentStatus.js.map +1 -1
- package/dist/editor/ai/useInlineAiPosition.js +45 -5
- package/dist/editor/ai/useInlineAiPosition.js.map +1 -1
- package/dist/editor/client/AboutDialog.js +4 -2
- package/dist/editor/client/AboutDialog.js.map +1 -1
- package/dist/editor/client/EditorShell.d.ts +4 -1
- package/dist/editor/client/EditorShell.js +770 -237
- package/dist/editor/client/EditorShell.js.map +1 -1
- package/dist/editor/client/editContext.d.ts +33 -19
- package/dist/editor/client/editContext.js.map +1 -1
- package/dist/editor/client/helpers.js +6 -0
- package/dist/editor/client/helpers.js.map +1 -1
- package/dist/editor/client/hooks/useEditorUrlSync.js +1 -2
- package/dist/editor/client/hooks/useEditorUrlSync.js.map +1 -1
- package/dist/editor/client/hooks/useEditorWebSocket.d.ts +10 -0
- package/dist/editor/client/hooks/useEditorWebSocket.js +209 -14
- package/dist/editor/client/hooks/useEditorWebSocket.js.map +1 -1
- package/dist/editor/client/hooks/useQuota.d.ts +8 -0
- package/dist/editor/client/hooks/useQuota.js.map +1 -1
- package/dist/editor/client/hooks/useSocketMessageHandler.js +68 -7
- package/dist/editor/client/hooks/useSocketMessageHandler.js.map +1 -1
- package/dist/editor/client/itemsRepository.js +10 -6
- package/dist/editor/client/itemsRepository.js.map +1 -1
- package/dist/editor/client/navigation.js +35 -3
- package/dist/editor/client/navigation.js.map +1 -1
- package/dist/editor/client/operations.d.ts +6 -3
- package/dist/editor/client/operations.js +208 -30
- package/dist/editor/client/operations.js.map +1 -1
- package/dist/editor/client/pageModelBuilder.js +4 -31
- package/dist/editor/client/pageModelBuilder.js.map +1 -1
- package/dist/editor/client/ui/DevModeIndicator.js +2 -2
- package/dist/editor/client/ui/DevModeIndicator.js.map +1 -1
- package/dist/editor/client/ui/EditorChrome.d.ts +0 -6
- package/dist/editor/client/ui/EditorChrome.js +55 -72
- package/dist/editor/client/ui/EditorChrome.js.map +1 -1
- package/dist/editor/client/ui/FullscreenControls.js +5 -3
- package/dist/editor/client/ui/FullscreenControls.js.map +1 -1
- package/dist/editor/commands/commands.d.ts +11 -1
- package/dist/editor/commands/commands.js +12 -1
- package/dist/editor/commands/commands.js.map +1 -1
- package/dist/editor/commands/componentCommands.js +109 -55
- package/dist/editor/commands/componentCommands.js.map +1 -1
- package/dist/editor/commands/customCommandConverter.d.ts +8 -1
- package/dist/editor/commands/customCommandConverter.js +35 -5
- package/dist/editor/commands/customCommandConverter.js.map +1 -1
- package/dist/editor/commands/handlers/agentHandler.js +2 -1
- package/dist/editor/commands/handlers/agentHandler.js.map +1 -1
- package/dist/editor/commands/itemCommands.d.ts +3 -0
- package/dist/editor/commands/itemCommands.js +93 -10
- package/dist/editor/commands/itemCommands.js.map +1 -1
- package/dist/editor/commands/undo.d.ts +9 -15
- package/dist/editor/commands/undo.js +24 -0
- package/dist/editor/commands/undo.js.map +1 -1
- package/dist/editor/context-menu/InsertMenu.js +83 -39
- package/dist/editor/context-menu/InsertMenu.js.map +1 -1
- package/dist/editor/field-types/MultiLineText.js +1 -1
- package/dist/editor/field-types/MultiLineText.js.map +1 -1
- package/dist/editor/field-types/RawEditor.js +1 -1
- package/dist/editor/field-types/RichTextEditor.js +13 -5
- package/dist/editor/field-types/RichTextEditor.js.map +1 -1
- package/dist/editor/field-types/RichTextEditorComponent.js +37 -3
- package/dist/editor/field-types/RichTextEditorComponent.js.map +1 -1
- package/dist/editor/field-types/SingleLineText.js +1 -1
- package/dist/editor/field-types/TreeListEditor.js +3 -2
- package/dist/editor/field-types/TreeListEditor.js.map +1 -1
- package/dist/editor/field-types/richtext/components/ReactSlate.css +23 -5
- package/dist/editor/field-types/richtext/components/ReactSlate.d.ts +2 -0
- package/dist/editor/field-types/richtext/components/ReactSlate.js +28 -4
- package/dist/editor/field-types/richtext/components/ReactSlate.js.map +1 -1
- package/dist/editor/field-types/richtext/components/ToolbarButton.js +4 -2
- package/dist/editor/field-types/richtext/components/ToolbarButton.js.map +1 -1
- package/dist/editor/field-types/richtext/contextMenuFactory.d.ts +13 -0
- package/dist/editor/field-types/richtext/contextMenuFactory.js +181 -24
- package/dist/editor/field-types/richtext/contextMenuFactory.js.map +1 -1
- package/dist/editor/field-types/richtext/types.d.ts +2 -0
- package/dist/editor/field-types/richtext/types.js.map +1 -1
- package/dist/editor/field-types/richtext/utils/plugins.js +4 -0
- package/dist/editor/field-types/richtext/utils/plugins.js.map +1 -1
- package/dist/editor/field-types/textContextMenuFactory.js +3 -2
- package/dist/editor/field-types/textContextMenuFactory.js.map +1 -1
- package/dist/editor/media-selector/AiImageSearchPrompt.js +4 -2
- package/dist/editor/media-selector/AiImageSearchPrompt.js.map +1 -1
- package/dist/editor/media-selector/MediaFolderBrowser.js +1 -1
- package/dist/editor/media-selector/MediaFolderBrowser.js.map +1 -1
- package/dist/editor/media-selector/MediaSelector.js +7 -1
- package/dist/editor/media-selector/MediaSelector.js.map +1 -1
- package/dist/editor/media-selector/TreeSelector.js +40 -35
- package/dist/editor/media-selector/TreeSelector.js.map +1 -1
- package/dist/editor/menubar/ActiveUsers.js +1 -1
- package/dist/editor/menubar/ActiveUsers.js.map +1 -1
- package/dist/editor/menubar/GenericToolbar.js +4 -2
- package/dist/editor/menubar/GenericToolbar.js.map +1 -1
- package/dist/editor/menubar/ItemLanguageVersion.js +2 -2
- package/dist/editor/menubar/ItemLanguageVersion.js.map +1 -1
- package/dist/editor/menubar/PageSelector.js +26 -147
- package/dist/editor/menubar/PageSelector.js.map +1 -1
- package/dist/editor/menubar/Separator.js +1 -1
- package/dist/editor/menubar/VersionSelector.js +2 -4
- package/dist/editor/menubar/VersionSelector.js.map +1 -1
- package/dist/editor/menubar/WorkflowButton.js +39 -12
- package/dist/editor/menubar/WorkflowButton.js.map +1 -1
- package/dist/editor/menubar/toolbar-sections/CustomCommandsToolbar.js +16 -38
- package/dist/editor/menubar/toolbar-sections/CustomCommandsToolbar.js.map +1 -1
- package/dist/editor/menubar/toolbar-sections/EditControls.js +3 -3
- package/dist/editor/menubar/toolbar-sections/EditControls.js.map +1 -1
- package/dist/editor/menubar/toolbar-sections/HelpButton.js +1 -0
- package/dist/editor/menubar/toolbar-sections/HelpButton.js.map +1 -1
- package/dist/editor/menubar/toolbar-sections/ManualBrowser.d.ts +6 -10
- package/dist/editor/menubar/toolbar-sections/ManualBrowser.js +597 -220
- package/dist/editor/menubar/toolbar-sections/ManualBrowser.js.map +1 -1
- package/dist/editor/menubar/toolbar-sections/UtilityControls.js +13 -2
- package/dist/editor/menubar/toolbar-sections/UtilityControls.js.map +1 -1
- package/dist/editor/page-editor-chrome/CommentHighlighting.js +42 -1
- package/dist/editor/page-editor-chrome/CommentHighlighting.js.map +1 -1
- package/dist/editor/page-editor-chrome/FrameMenu.js +1 -1
- package/dist/editor/page-editor-chrome/FrameMenu.js.map +1 -1
- package/dist/editor/page-editor-chrome/InlineEditor.js +97 -48
- package/dist/editor/page-editor-chrome/InlineEditor.js.map +1 -1
- package/dist/editor/page-editor-chrome/PlaceholderDropZone.js +38 -17
- package/dist/editor/page-editor-chrome/PlaceholderDropZone.js.map +1 -1
- package/dist/editor/page-editor-chrome/PlaceholderDropZones.js +17 -11
- package/dist/editor/page-editor-chrome/PlaceholderDropZones.js.map +1 -1
- package/dist/editor/page-editor-chrome/useInlineAICompletion.js +301 -301
- package/dist/editor/page-editor-chrome/useInlineAICompletion.js.map +1 -1
- package/dist/editor/page-viewer/DeviceToolbar.js +1 -1
- package/dist/editor/page-viewer/DeviceToolbar.js.map +1 -1
- package/dist/editor/page-viewer/EditorForm.js +69 -11
- package/dist/editor/page-viewer/EditorForm.js.map +1 -1
- package/dist/editor/page-viewer/MiniMap.d.ts +2 -4
- package/dist/editor/page-viewer/MiniMap.js +91 -28
- package/dist/editor/page-viewer/MiniMap.js.map +1 -1
- package/dist/editor/page-viewer/PageViewer.d.ts +3 -1
- package/dist/editor/page-viewer/PageViewer.js +92 -19
- package/dist/editor/page-viewer/PageViewer.js.map +1 -1
- package/dist/editor/page-viewer/PageViewerFrame.d.ts +2 -1
- package/dist/editor/page-viewer/PageViewerFrame.js +348 -115
- package/dist/editor/page-viewer/PageViewerFrame.js.map +1 -1
- package/dist/editor/page-viewer/pageModelSkeletonBuilder.js +114 -49
- package/dist/editor/page-viewer/pageModelSkeletonBuilder.js.map +1 -1
- package/dist/editor/page-viewer/pageViewContext.d.ts +1 -0
- package/dist/editor/page-viewer/pageViewContext.js +51 -14
- package/dist/editor/page-viewer/pageViewContext.js.map +1 -1
- package/dist/editor/pageModel.d.ts +14 -1
- package/dist/editor/reviews/Comment.js +26 -12
- package/dist/editor/reviews/Comment.js.map +1 -1
- package/dist/editor/reviews/CommentDisplayPopover.js +7 -5
- package/dist/editor/reviews/CommentDisplayPopover.js.map +1 -1
- package/dist/editor/reviews/CommentView.js +19 -4
- package/dist/editor/reviews/CommentView.js.map +1 -1
- package/dist/editor/reviews/Comments.js +89 -72
- package/dist/editor/reviews/Comments.js.map +1 -1
- package/dist/editor/reviews/CreateReviewDialog.js +281 -177
- package/dist/editor/reviews/CreateReviewDialog.js.map +1 -1
- package/dist/editor/reviews/DecisionsMatrix.js +96 -25
- package/dist/editor/reviews/DecisionsMatrix.js.map +1 -1
- package/dist/editor/reviews/DiffView.js +7 -14
- package/dist/editor/reviews/DiffView.js.map +1 -1
- package/dist/editor/reviews/EditReviewSettingsDialog.js +6 -4
- package/dist/editor/reviews/EditReviewSettingsDialog.js.map +1 -1
- package/dist/editor/reviews/MultiReviewManager.js +25 -3
- package/dist/editor/reviews/MultiReviewManager.js.map +1 -1
- package/dist/editor/reviews/PagesPanel.js +31 -15
- package/dist/editor/reviews/PagesPanel.js.map +1 -1
- package/dist/editor/reviews/PreviewInfo.js +1 -4
- package/dist/editor/reviews/PreviewInfo.js.map +1 -1
- package/dist/editor/reviews/ReviewCard.js +13 -7
- package/dist/editor/reviews/ReviewCard.js.map +1 -1
- package/dist/editor/reviews/ReviewDetail.js +3 -2
- package/dist/editor/reviews/ReviewDetail.js.map +1 -1
- package/dist/editor/reviews/ReviewsList.js +7 -3
- package/dist/editor/reviews/ReviewsList.js.map +1 -1
- package/dist/editor/reviews/SuggestedEdit.js +34 -3
- package/dist/editor/reviews/SuggestedEdit.js.map +1 -1
- package/dist/editor/reviews/SuggestionDisplayPopover.js +31 -5
- package/dist/editor/reviews/SuggestionDisplayPopover.js.map +1 -1
- package/dist/editor/reviews/commentAi.js +25 -6
- package/dist/editor/reviews/commentAi.js.map +1 -1
- package/dist/editor/reviews/reviewCommands.js +4 -1
- package/dist/editor/reviews/reviewCommands.js.map +1 -1
- package/dist/editor/reviews/useMultiReview.js +2 -2
- package/dist/editor/reviews/useMultiReview.js.map +1 -1
- package/dist/editor/reviews/useReviews.d.ts +2 -2
- package/dist/editor/reviews/useReviews.js +12 -30
- package/dist/editor/reviews/useReviews.js.map +1 -1
- package/dist/editor/services/agentService.d.ts +229 -5
- package/dist/editor/services/agentService.js +292 -39
- package/dist/editor/services/agentService.js.map +1 -1
- package/dist/editor/services/aiService.d.ts +57 -1
- package/dist/editor/services/aiService.js +79 -6
- package/dist/editor/services/aiService.js.map +1 -1
- package/dist/editor/services/contentService.d.ts +6 -3
- package/dist/editor/services/contentService.js +13 -12
- package/dist/editor/services/contentService.js.map +1 -1
- package/dist/editor/services/editService.d.ts +52 -1
- package/dist/editor/services/editService.js +94 -2
- package/dist/editor/services/editService.js.map +1 -1
- package/dist/editor/services/indexService.js +1 -1
- package/dist/editor/services/indexService.js.map +1 -1
- package/dist/editor/services/reviewsService.d.ts +3 -6
- package/dist/editor/services/reviewsService.js +2 -11
- package/dist/editor/services/reviewsService.js.map +1 -1
- package/dist/editor/services/serviceHelper.d.ts +2 -1
- package/dist/editor/services/serviceHelper.js +112 -20
- package/dist/editor/services/serviceHelper.js.map +1 -1
- package/dist/editor/services/systemService.d.ts +2 -1
- package/dist/editor/services/systemService.js +3 -0
- package/dist/editor/services/systemService.js.map +1 -1
- package/dist/editor/services-server/api.d.ts +1 -2
- package/dist/editor/services-server/api.js +11 -6
- package/dist/editor/services-server/api.js.map +1 -1
- package/dist/editor/settings/About.js +317 -3
- package/dist/editor/settings/About.js.map +1 -1
- package/dist/editor/settings/QuotaInfo.js +210 -4
- package/dist/editor/settings/QuotaInfo.js.map +1 -1
- package/dist/editor/settings/SettingsView.js +25 -23
- package/dist/editor/settings/SettingsView.js.map +1 -1
- package/dist/editor/settings/Status.js +7 -6
- package/dist/editor/settings/Status.js.map +1 -1
- package/dist/editor/settings/index/useIndexStatus.js +20 -22
- package/dist/editor/settings/index/useIndexStatus.js.map +1 -1
- package/dist/editor/settings/panels/AgentsPanel.d.ts +0 -4
- package/dist/editor/settings/panels/AgentsPanel.js +95 -121
- package/dist/editor/settings/panels/AgentsPanel.js.map +1 -1
- package/dist/editor/settings/panels/ModelsPanel.js +329 -108
- package/dist/editor/settings/panels/ModelsPanel.js.map +1 -1
- package/dist/editor/settings/panels/ProvidersPanel.d.ts +1 -1
- package/dist/editor/settings/panels/ProvidersPanel.js +86 -59
- package/dist/editor/settings/panels/ProvidersPanel.js.map +1 -1
- package/dist/editor/settings/panels/SearchConfigPanel.js +4 -4
- package/dist/editor/settings/panels/SearchConfigPanel.js.map +1 -1
- package/dist/editor/settings/panels/index.d.ts +3 -2
- package/dist/editor/settings/panels/index.js +3 -2
- package/dist/editor/settings/panels/index.js.map +1 -1
- package/dist/editor/settings/status/coreStatusChecks.js +124 -19
- package/dist/editor/settings/status/coreStatusChecks.js.map +1 -1
- package/dist/editor/settings/status/useStartupChecks.d.ts +3 -1
- package/dist/editor/settings/status/useStartupChecks.js +9 -5
- package/dist/editor/settings/status/useStartupChecks.js.map +1 -1
- package/dist/editor/setup-wizard/steps/CompleteStep.d.ts +2 -1
- package/dist/editor/setup-wizard/steps/CompleteStep.js +2 -1
- package/dist/editor/setup-wizard/steps/CompleteStep.js.map +1 -1
- package/dist/editor/sidebar/ComponentPalette.js +2 -1
- package/dist/editor/sidebar/ComponentPalette.js.map +1 -1
- package/dist/editor/sidebar/ComponentTree.d.ts +8 -1
- package/dist/editor/sidebar/ComponentTree.js +216 -69
- package/dist/editor/sidebar/ComponentTree.js.map +1 -1
- package/dist/editor/sidebar/EditHistory.js +22 -46
- package/dist/editor/sidebar/EditHistory.js.map +1 -1
- package/dist/editor/sidebar/Favorites.js +4 -8
- package/dist/editor/sidebar/Favorites.js.map +1 -1
- package/dist/editor/sidebar/MainContentTree.js +4 -3
- package/dist/editor/sidebar/MainContentTree.js.map +1 -1
- package/dist/editor/sidebar/OperationItem.js +21 -7
- package/dist/editor/sidebar/OperationItem.js.map +1 -1
- package/dist/editor/sidebar/SidebarPanel.d.ts +3 -1
- package/dist/editor/sidebar/SidebarPanel.js +44 -12
- package/dist/editor/sidebar/SidebarPanel.js.map +1 -1
- package/dist/editor/sidebar/SidebarStack.d.ts +2 -1
- package/dist/editor/sidebar/SidebarStack.js +4 -3
- package/dist/editor/sidebar/SidebarStack.js.map +1 -1
- package/dist/editor/sidebar/Validation.js +22 -12
- package/dist/editor/sidebar/Validation.js.map +1 -1
- package/dist/editor/sidebar/Workbox.js +53 -3
- package/dist/editor/sidebar/Workbox.js.map +1 -1
- package/dist/editor/sidebar/WorkspaceRail.d.ts +0 -1
- package/dist/editor/sidebar/WorkspaceRail.js +56 -167
- package/dist/editor/sidebar/WorkspaceRail.js.map +1 -1
- package/dist/editor/tree-indicators/GutterColumns.d.ts +3 -1
- package/dist/editor/tree-indicators/GutterColumns.js +26 -5
- package/dist/editor/tree-indicators/GutterColumns.js.map +1 -1
- package/dist/editor/tree-indicators/GutterContext.d.ts +4 -0
- package/dist/editor/tree-indicators/GutterContext.js +23 -0
- package/dist/editor/tree-indicators/GutterContext.js.map +1 -1
- package/dist/editor/tree-indicators/index.d.ts +0 -1
- package/dist/editor/tree-indicators/index.js +0 -1
- package/dist/editor/tree-indicators/index.js.map +1 -1
- package/dist/editor/tree-indicators/types.d.ts +12 -1
- package/dist/editor/ui/CopyMoveTargetSelectorDialog.js +1 -1
- package/dist/editor/ui/CopyMoveTargetSelectorDialog.js.map +1 -1
- package/dist/editor/ui/Icons.js +1 -1
- package/dist/editor/ui/Icons.js.map +1 -1
- package/dist/editor/ui/ItemNameDialogNew.d.ts +2 -0
- package/dist/editor/ui/ItemNameDialogNew.js +33 -17
- package/dist/editor/ui/ItemNameDialogNew.js.map +1 -1
- package/dist/editor/ui/ItemSearch.js +7 -11
- package/dist/editor/ui/ItemSearch.js.map +1 -1
- package/dist/editor/ui/SimpleIconButton.js +1 -1
- package/dist/editor/ui/SimpleIconButton.js.map +1 -1
- package/dist/editor/ui/SimpleTabs.d.ts +1 -0
- package/dist/editor/ui/SimpleTabs.js +45 -25
- package/dist/editor/ui/SimpleTabs.js.map +1 -1
- package/dist/editor/ui/Splitter.d.ts +1 -0
- package/dist/editor/ui/Splitter.js +102 -86
- package/dist/editor/ui/Splitter.js.map +1 -1
- package/dist/editor/ui/TemplateSelectorDialog.js +4 -4
- package/dist/editor/ui/TemplateSelectorDialog.js.map +1 -1
- package/dist/editor/ui/TreeListSelector.d.ts +6 -1
- package/dist/editor/ui/TreeListSelector.js +2 -2
- package/dist/editor/ui/TreeListSelector.js.map +1 -1
- package/dist/editor/utils/keyboardNavigation.d.ts +6 -20
- package/dist/editor/utils/keyboardNavigation.js +48 -140
- package/dist/editor/utils/keyboardNavigation.js.map +1 -1
- package/dist/editor/utils.js +19 -9
- package/dist/editor/utils.js.map +1 -1
- package/dist/editor/views/CompareView.d.ts +3 -1
- package/dist/editor/views/CompareView.js +7 -5
- package/dist/editor/views/CompareView.js.map +1 -1
- package/dist/editor/views/EditView.js +1 -1
- package/dist/editor/views/EditView.js.map +1 -1
- package/dist/editor/views/EditorSlot.js +27 -34
- package/dist/editor/views/EditorSlot.js.map +1 -1
- package/dist/editor/views/ItemEditor.js +7 -3
- package/dist/editor/views/ItemEditor.js.map +1 -1
- package/dist/editor/views/MediaFolderEditView.js +1 -1
- package/dist/editor/views/MediaFolderEditView.js.map +1 -1
- package/dist/editor/views/ParheliaView.js +5 -6
- package/dist/editor/views/ParheliaView.js.map +1 -1
- package/dist/editor/views/SingleEditView.d.ts +2 -1
- package/dist/editor/views/SingleEditView.js +10 -8
- package/dist/editor/views/SingleEditView.js.map +1 -1
- package/dist/editor/views/editorSlotContext.js +35 -6
- package/dist/editor/views/editorSlotContext.js.map +1 -1
- package/dist/index.d.ts +16 -2
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -1
- package/dist/revision.d.ts +2 -2
- package/dist/revision.js +2 -2
- package/dist/setup/services/setupWizardService.d.ts +40 -13
- package/dist/setup/services/setupWizardService.js +32 -17
- package/dist/setup/services/setupWizardService.js.map +1 -1
- package/dist/setup/wizard/steps/AddModelDialog.js +12 -3
- package/dist/setup/wizard/steps/AddModelDialog.js.map +1 -1
- package/dist/setup/wizard/steps/ImportModelDialog.js +39 -22
- package/dist/setup/wizard/steps/ImportModelDialog.js.map +1 -1
- package/dist/splash-screen/ModernSplashScreen.js +112 -32
- package/dist/splash-screen/ModernSplashScreen.js.map +1 -1
- package/dist/splash-screen/NewPage.js +33 -50
- package/dist/splash-screen/NewPage.js.map +1 -1
- package/dist/splash-screen/OpenPage.js +2 -6
- package/dist/splash-screen/OpenPage.js.map +1 -1
- package/dist/splash-screen/ParheliaAssistantChat.js +12 -29
- package/dist/splash-screen/ParheliaAssistantChat.js.map +1 -1
- package/dist/splash-screen/ParheliaLogo.js +87 -37
- package/dist/splash-screen/ParheliaLogo.js.map +1 -1
- package/dist/splash-screen/RecentPages.js +3 -3
- package/dist/splash-screen/RecentPages.js.map +1 -1
- package/dist/tour/Tour.d.ts +2 -1
- package/dist/tour/Tour.js +256 -75
- package/dist/tour/Tour.js.map +1 -1
- package/dist/tour/default-tour.js +222 -96
- package/dist/tour/default-tour.js.map +1 -1
- package/dist/types.d.ts +63 -29
- package/package.json +19 -15
- package/styles.css +14 -10
- package/dist/editor/ComponentInfo.d.ts +0 -4
- package/dist/editor/ComponentInfo.js +0 -41
- package/dist/editor/ComponentInfo.js.map +0 -1
- package/dist/editor/ai/HelpTerminal.d.ts +0 -5
- package/dist/editor/ai/HelpTerminal.js +0 -166
- package/dist/editor/ai/HelpTerminal.js.map +0 -1
- package/dist/editor/field-types/ReactQuill.d.ts +0 -125
- package/dist/editor/field-types/ReactQuill.js +0 -385
- package/dist/editor/field-types/ReactQuill.js.map +0 -1
- package/dist/editor/services-server/graphQL.d.ts +0 -29
- package/dist/editor/services-server/graphQL.js +0 -53
- package/dist/editor/services-server/graphQL.js.map +0 -1
- package/dist/editor/settings/AllAgentsPanel.d.ts +0 -5
- package/dist/editor/settings/AllAgentsPanel.js +0 -139
- package/dist/editor/settings/AllAgentsPanel.js.map +0 -1
- package/dist/editor/settings/LatestFeedback.d.ts +0 -1
- package/dist/editor/settings/LatestFeedback.js +0 -136
- package/dist/editor/settings/LatestFeedback.js.map +0 -1
- package/dist/editor/settings/Setup.d.ts +0 -1
- package/dist/editor/settings/Setup.js +0 -211
- package/dist/editor/settings/Setup.js.map +0 -1
- package/dist/editor/settings/panels/DatabasePanel.d.ts +0 -6
- package/dist/editor/settings/panels/DatabasePanel.js +0 -50
- package/dist/editor/settings/panels/DatabasePanel.js.map +0 -1
- package/dist/editor/settings/setup-steps/AiSetupStep/EmbeddingsModelSection.d.ts +0 -2
- package/dist/editor/settings/setup-steps/AiSetupStep/EmbeddingsModelSection.js +0 -195
- package/dist/editor/settings/setup-steps/AiSetupStep/EmbeddingsModelSection.js.map +0 -1
- package/dist/editor/settings/setup-steps/AiSetupStep/index.d.ts +0 -2
- package/dist/editor/settings/setup-steps/AiSetupStep/index.js +0 -21
- package/dist/editor/settings/setup-steps/AiSetupStep/index.js.map +0 -1
- package/dist/editor/settings/setup-steps/AiSetupStep/provider/ProviderSection.d.ts +0 -1
- package/dist/editor/settings/setup-steps/AiSetupStep/provider/ProviderSection.js +0 -233
- package/dist/editor/settings/setup-steps/AiSetupStep/provider/ProviderSection.js.map +0 -1
- package/dist/editor/settings/setup-steps/AiSetupStep/required-containers/RequiredContainersList.d.ts +0 -15
- package/dist/editor/settings/setup-steps/AiSetupStep/required-containers/RequiredContainersList.js +0 -14
- package/dist/editor/settings/setup-steps/AiSetupStep/required-containers/RequiredContainersList.js.map +0 -1
- package/dist/editor/settings/setup-steps/AiSetupStep/required-containers/RequiredContainersSection.d.ts +0 -1
- package/dist/editor/settings/setup-steps/AiSetupStep/required-containers/RequiredContainersSection.js +0 -94
- package/dist/editor/settings/setup-steps/AiSetupStep/required-containers/RequiredContainersSection.js.map +0 -1
- package/dist/editor/settings/setup-steps/AiSetupStep/types.d.ts +0 -1
- package/dist/editor/settings/setup-steps/AiSetupStep/types.js +0 -2
- package/dist/editor/settings/setup-steps/AiSetupStep/types.js.map +0 -1
- package/dist/editor/settings/setup-steps/AiSetupStep/utils.d.ts +0 -5
- package/dist/editor/settings/setup-steps/AiSetupStep/utils.js +0 -44
- package/dist/editor/settings/setup-steps/AiSetupStep/utils.js.map +0 -1
- package/dist/editor/settings/setup-steps/IndexSetupStep.d.ts +0 -2
- package/dist/editor/settings/setup-steps/IndexSetupStep.js +0 -36
- package/dist/editor/settings/setup-steps/IndexSetupStep.js.map +0 -1
- package/dist/editor/settings/setup-steps/SettingsSetupStep.d.ts +0 -2
- package/dist/editor/settings/setup-steps/SettingsSetupStep.js +0 -111
- package/dist/editor/settings/setup-steps/SettingsSetupStep.js.map +0 -1
- package/dist/editor/settings/setup-steps/SetupOverview.d.ts +0 -14
- package/dist/editor/settings/setup-steps/SetupOverview.js +0 -38
- package/dist/editor/settings/setup-steps/SetupOverview.js.map +0 -1
- package/dist/editor/sidebar/Debug.d.ts +0 -1
- package/dist/editor/sidebar/Debug.js +0 -70
- package/dist/editor/sidebar/Debug.js.map +0 -1
- package/dist/editor/sidebar/GraphQL.d.ts +0 -2
- package/dist/editor/sidebar/GraphQL.js +0 -234
- package/dist/editor/sidebar/GraphQL.js.map +0 -1
- package/dist/editor/sidebar/LeftToolbar.d.ts +0 -1
- package/dist/editor/sidebar/LeftToolbar.js +0 -12
- package/dist/editor/sidebar/LeftToolbar.js.map +0 -1
- package/dist/editor/sidebar/NavigationSidebar.d.ts +0 -4
- package/dist/editor/sidebar/NavigationSidebar.js +0 -254
- package/dist/editor/sidebar/NavigationSidebar.js.map +0 -1
- package/dist/editor/tree-indicators/GutterSelector.d.ts +0 -5
- package/dist/editor/tree-indicators/GutterSelector.js +0 -91
- package/dist/editor/tree-indicators/GutterSelector.js.map +0 -1
|
@@ -1,17 +1,29 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
2
|
import { useEffect, useCallback, useState, useMemo, useRef, } from "react";
|
|
2
3
|
import { useDebouncedCallback } from "use-debounce";
|
|
3
4
|
import { useEditContext, useFieldsEditContext } from "../client/editContext";
|
|
4
5
|
import { generatePageContext, getCachedContext, } from "../services/contextService";
|
|
6
|
+
import { WandSparkles } from "lucide-react";
|
|
7
|
+
import { createRoot } from "react-dom/client";
|
|
8
|
+
import { LicenseFeatures, useFeature } from "../../licensing";
|
|
9
|
+
function InlineCompletionHint({ hintText, isMobile, onAccept, positionStyle, }) {
|
|
10
|
+
return (_jsxs("div", { className: "shadow-[0_4px_14px_rgba(15,23,42,0.14),0_0_0_1px_rgba(15,23,42,0.06)]pointer-events-auto fixed z-95 inline-flex max-w-none cursor-pointer items-center gap-2 rounded-md border border-slate-400 bg-slate-100 px-2.5 py-2 text-xs leading-snug font-medium whitespace-nowrap text-slate-900", style: positionStyle, onClick: isMobile ? onAccept : undefined, role: isMobile ? "button" : undefined, children: [_jsx(WandSparkles, { className: "size-3.5 shrink-0 text-violet-600", strokeWidth: 2, "aria-hidden": true }), _jsx("span", { children: hintText })] }));
|
|
11
|
+
}
|
|
5
12
|
export function useInlineAiCompletion({ pageViewContext, cursorSpanId, isUpdatingRef, }) {
|
|
6
13
|
const editContext = useEditContext();
|
|
7
14
|
const fieldsContext = useFieldsEditContext();
|
|
15
|
+
const canUseAi = useFeature(LicenseFeatures.AI);
|
|
8
16
|
const [currentCompletion, setCurrentCompletion] = useState(null);
|
|
9
|
-
const [
|
|
17
|
+
const [, setIsLoading] = useState(false);
|
|
10
18
|
const abortControllerRef = useRef(null);
|
|
11
19
|
const loadingAnimationRef = useRef(null);
|
|
20
|
+
const applyCompletionRef = useRef(null);
|
|
21
|
+
const hintReactRootRef = useRef(null);
|
|
12
22
|
// Clean up hint element on unmount
|
|
13
23
|
useEffect(() => {
|
|
14
24
|
return () => {
|
|
25
|
+
hintReactRootRef.current?.unmount();
|
|
26
|
+
hintReactRootRef.current = null;
|
|
15
27
|
const hintElement = document.getElementById(`${cursorSpanId}-hint`);
|
|
16
28
|
if (hintElement) {
|
|
17
29
|
hintElement.remove();
|
|
@@ -23,7 +35,7 @@ export function useInlineAiCompletion({ pageViewContext, cursorSpanId, isUpdatin
|
|
|
23
35
|
}, [cursorSpanId]);
|
|
24
36
|
const lastCaretPosRef = useRef(null);
|
|
25
37
|
// Simple function to track caret position without inserting spans
|
|
26
|
-
const positionCursorSpan = () => {
|
|
38
|
+
const positionCursorSpan = useCallback(() => {
|
|
27
39
|
if (isUpdatingRef.current)
|
|
28
40
|
return;
|
|
29
41
|
isUpdatingRef.current = true;
|
|
@@ -97,55 +109,14 @@ export function useInlineAiCompletion({ pageViewContext, cursorSpanId, isUpdatin
|
|
|
97
109
|
isUpdatingRef.current = false;
|
|
98
110
|
}, 10);
|
|
99
111
|
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
e.key === "ArrowUp" ||
|
|
107
|
-
e.key === "ArrowDown" ||
|
|
108
|
-
e.key === " " ||
|
|
109
|
-
e.key === "Tab" ||
|
|
110
|
-
e.key === "End" ||
|
|
111
|
-
e.key === "Backspace" ||
|
|
112
|
-
e.key === "Delete" // Add Delete key handling
|
|
113
|
-
) {
|
|
114
|
-
// Clear the completion when arrow keys are used
|
|
115
|
-
setCurrentCompletion(null);
|
|
116
|
-
clearCursorSpan();
|
|
117
|
-
// Let the browser handle the cursor movement/deletion
|
|
118
|
-
// Then update our cursor span after a small delay
|
|
119
|
-
setTimeout(() => {
|
|
120
|
-
if (!isUpdatingRef.current) {
|
|
121
|
-
positionCursorSpan();
|
|
122
|
-
}
|
|
123
|
-
}, 10);
|
|
124
|
-
// Special handling for right arrow and delete which seems to have issues
|
|
125
|
-
if (e.key === "ArrowRight" || e.key === "Delete") {
|
|
126
|
-
// Make sure the cursor span doesn't block the movement/deletion
|
|
127
|
-
const cursorSpan = pageViewContext.editorIframe?.contentWindow?.document.getElementById(cursorSpanId);
|
|
128
|
-
if (cursorSpan) {
|
|
129
|
-
// Temporarily make it display none so it doesn't interfere with selection
|
|
130
|
-
const originalDisplay = cursorSpan.style.display;
|
|
131
|
-
cursorSpan.style.display = "none";
|
|
132
|
-
// Restore after the browser has processed the movement/deletion
|
|
133
|
-
setTimeout(() => {
|
|
134
|
-
if (cursorSpan.parentNode) {
|
|
135
|
-
cursorSpan.style.display = originalDisplay;
|
|
136
|
-
}
|
|
137
|
-
}, 0);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
};
|
|
142
|
-
pageViewContext.editorIframe?.contentWindow?.document.addEventListener("keydown", keyHandler);
|
|
143
|
-
return () => {
|
|
144
|
-
pageViewContext.editorIframe?.contentWindow?.document.removeEventListener("keydown", keyHandler);
|
|
145
|
-
};
|
|
146
|
-
}, [currentCompletion, pageViewContext.page]);
|
|
112
|
+
}, [
|
|
113
|
+
pageViewContext.editorIframe?.contentWindow,
|
|
114
|
+
fieldsContext?.inlineEditingFieldElement,
|
|
115
|
+
cursorSpanId,
|
|
116
|
+
isUpdatingRef,
|
|
117
|
+
]);
|
|
147
118
|
// Extracts the text up to the cursor position in the editable element
|
|
148
|
-
const getContentUpToCursor = (element) => {
|
|
119
|
+
const getContentUpToCursor = useCallback((element) => {
|
|
149
120
|
const iframeWindow = pageViewContext.editorIframe?.contentWindow;
|
|
150
121
|
const selection = iframeWindow?.getSelection();
|
|
151
122
|
if (!element || !selection || selection.rangeCount === 0)
|
|
@@ -168,19 +139,17 @@ export function useInlineAiCompletion({ pageViewContext, cursorSpanId, isUpdatin
|
|
|
168
139
|
contentUpToCursor = tempRange.toString();
|
|
169
140
|
}
|
|
170
141
|
return contentUpToCursor;
|
|
171
|
-
};
|
|
142
|
+
}, [pageViewContext.editorIframe?.contentWindow]);
|
|
172
143
|
// Loading animation with three dots changing color
|
|
173
|
-
const startLoadingAnimation = () => {
|
|
144
|
+
const startLoadingAnimation = useCallback(() => {
|
|
174
145
|
const doc = pageViewContext.editorIframe?.contentWindow?.document;
|
|
175
146
|
const span = doc?.getElementById(cursorSpanId);
|
|
176
147
|
if (!doc || !span)
|
|
177
148
|
return;
|
|
178
|
-
// Create dots container
|
|
179
149
|
span.innerHTML = "";
|
|
180
150
|
span.style.display = "inline-flex";
|
|
181
151
|
span.style.gap = "4px";
|
|
182
152
|
span.style.alignItems = "center";
|
|
183
|
-
// Create three dots
|
|
184
153
|
for (let i = 0; i < 3; i++) {
|
|
185
154
|
const dot = doc.createElement("span");
|
|
186
155
|
dot.textContent = "•";
|
|
@@ -189,7 +158,6 @@ export function useInlineAiCompletion({ pageViewContext, cursorSpanId, isUpdatin
|
|
|
189
158
|
dot.style.fontSize = "16px";
|
|
190
159
|
span.appendChild(dot);
|
|
191
160
|
}
|
|
192
|
-
// Animate dots
|
|
193
161
|
let step = 0;
|
|
194
162
|
const animate = () => {
|
|
195
163
|
const dots = span.querySelectorAll("span");
|
|
@@ -203,7 +171,6 @@ export function useInlineAiCompletion({ pageViewContext, cursorSpanId, isUpdatin
|
|
|
203
171
|
});
|
|
204
172
|
step++;
|
|
205
173
|
loadingAnimationRef.current = requestAnimationFrame(() => {
|
|
206
|
-
// Slow down animation by only updating every 15 frames (~250ms at 60fps)
|
|
207
174
|
if (step % 15 === 0) {
|
|
208
175
|
animate();
|
|
209
176
|
}
|
|
@@ -213,34 +180,27 @@ export function useInlineAiCompletion({ pageViewContext, cursorSpanId, isUpdatin
|
|
|
213
180
|
});
|
|
214
181
|
};
|
|
215
182
|
animate();
|
|
216
|
-
};
|
|
217
|
-
const stopLoadingAnimation = () => {
|
|
183
|
+
}, [pageViewContext.editorIframe?.contentWindow?.document, cursorSpanId]);
|
|
184
|
+
const stopLoadingAnimation = useCallback(() => {
|
|
218
185
|
if (loadingAnimationRef.current) {
|
|
219
186
|
cancelAnimationFrame(loadingAnimationRef.current);
|
|
220
187
|
loadingAnimationRef.current = null;
|
|
221
188
|
}
|
|
222
|
-
};
|
|
223
|
-
const getCompletion = async (element, isManualTrigger = false) => {
|
|
189
|
+
}, []);
|
|
190
|
+
const getCompletion = useCallback(async (element, isManualTrigger = false) => {
|
|
224
191
|
const contentUpToCursor = getContentUpToCursor(element);
|
|
225
192
|
if (!contentUpToCursor?.trim())
|
|
226
193
|
return null;
|
|
227
|
-
// Abort any in-flight request
|
|
228
194
|
if (abortControllerRef.current) {
|
|
229
195
|
abortControllerRef.current.abort();
|
|
230
196
|
}
|
|
231
|
-
// Create a new abort controller for this request
|
|
232
197
|
abortControllerRef.current = new AbortController();
|
|
233
|
-
const signal = abortControllerRef.current.signal;
|
|
234
|
-
// Get field attributes
|
|
235
198
|
const fieldId = element.getAttribute("data-fieldid");
|
|
236
|
-
const fieldName = element.getAttribute("data-fieldname");
|
|
237
199
|
const itemId = element.getAttribute("data-itemid");
|
|
238
200
|
const language = element.getAttribute("data-language");
|
|
239
201
|
const version = element.getAttribute("data-version");
|
|
240
202
|
if (!fieldId || !itemId || !language || !version)
|
|
241
203
|
return null;
|
|
242
|
-
// Only trigger completion after a space for automatic completions
|
|
243
|
-
// Manual triggers (Ctrl+Space) can work anywhere
|
|
244
204
|
if (!isManualTrigger) {
|
|
245
205
|
const lastChar = contentUpToCursor.slice(-1);
|
|
246
206
|
if (lastChar !== " " && lastChar !== "\u00A0") {
|
|
@@ -249,7 +209,6 @@ export function useInlineAiCompletion({ pageViewContext, cursorSpanId, isUpdatin
|
|
|
249
209
|
}
|
|
250
210
|
if (!editContext)
|
|
251
211
|
return null;
|
|
252
|
-
// Get page context for better completions
|
|
253
212
|
let pageContext = getCachedContext(editContext);
|
|
254
213
|
if (!pageContext) {
|
|
255
214
|
try {
|
|
@@ -257,22 +216,20 @@ export function useInlineAiCompletion({ pageViewContext, cursorSpanId, isUpdatin
|
|
|
257
216
|
}
|
|
258
217
|
catch (error) {
|
|
259
218
|
console.warn("Failed to generate page context:", error);
|
|
260
|
-
// Continue without context
|
|
261
219
|
}
|
|
262
220
|
}
|
|
263
221
|
let contextString = "";
|
|
264
222
|
if (pageContext) {
|
|
265
223
|
contextString = `Page Name: ${pageContext.pageTitle} (${pageContext.pageType})\n PageSummary: ${pageContext.abstract}`;
|
|
266
224
|
}
|
|
267
|
-
// Show loading indicator
|
|
268
225
|
setIsLoading(true);
|
|
269
226
|
startLoadingAnimation();
|
|
270
227
|
try {
|
|
271
228
|
const endpoint = `/parhelia/agent/GetTextCompletion`;
|
|
272
229
|
const response = await fetch(endpoint, {
|
|
273
|
-
method:
|
|
230
|
+
method: "POST",
|
|
274
231
|
headers: {
|
|
275
|
-
|
|
232
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
276
233
|
},
|
|
277
234
|
body: new URLSearchParams({
|
|
278
235
|
textToComplete: contentUpToCursor,
|
|
@@ -283,18 +240,22 @@ export function useInlineAiCompletion({ pageViewContext, cursorSpanId, isUpdatin
|
|
|
283
240
|
return data.completion || null;
|
|
284
241
|
}
|
|
285
242
|
catch (error) {
|
|
286
|
-
// Ignore AbortError as it's expected when cancelling
|
|
287
243
|
if (error instanceof Error && error.name !== "AbortError") {
|
|
288
244
|
console.error("Error getting completion:", error);
|
|
289
245
|
}
|
|
290
246
|
return null;
|
|
291
247
|
}
|
|
292
248
|
finally {
|
|
293
|
-
// Hide loading indicator
|
|
294
249
|
setIsLoading(false);
|
|
295
250
|
stopLoadingAnimation();
|
|
296
251
|
}
|
|
297
|
-
}
|
|
252
|
+
}, [
|
|
253
|
+
getContentUpToCursor,
|
|
254
|
+
editContext,
|
|
255
|
+
pageViewContext,
|
|
256
|
+
startLoadingAnimation,
|
|
257
|
+
stopLoadingAnimation,
|
|
258
|
+
]);
|
|
298
259
|
// Debounced AI call: recompute the sentence, call getCompletion, and extract only the "tail" for the ghost text
|
|
299
260
|
const getCompletionDebounced = useDebouncedCallback(async (isManualTrigger = false) => {
|
|
300
261
|
const el = fieldsContext?.inlineEditingFieldElement;
|
|
@@ -317,50 +278,17 @@ export function useInlineAiCompletion({ pageViewContext, cursorSpanId, isUpdatin
|
|
|
317
278
|
setCurrentCompletion(suggestion);
|
|
318
279
|
updateCursorSpan(suggestion.substring(sentence.length));
|
|
319
280
|
}, 250);
|
|
320
|
-
// Manual completion trigger (non-debounced for immediate response)
|
|
321
|
-
const getCompletionManual = async () => {
|
|
322
|
-
const el = fieldsContext?.inlineEditingFieldElement;
|
|
323
|
-
if (!el)
|
|
324
|
-
return;
|
|
325
|
-
// 1) Recompute the exact sentence at this moment
|
|
326
|
-
const full = getContentUpToCursor(el) || "";
|
|
327
|
-
const sentence = full.split(/[.?!]\s*/).pop() || "";
|
|
328
|
-
// 2) Ask AI for a completion
|
|
329
|
-
const rawSuggestion = await getCompletion(el, true);
|
|
330
|
-
if (!rawSuggestion) {
|
|
331
|
-
setCurrentCompletion(null);
|
|
332
|
-
clearCursorSpan();
|
|
333
|
-
return;
|
|
334
|
-
}
|
|
335
|
-
// 3) Strip off the already-typed sentence to leave just the "completion tail"
|
|
336
|
-
const suggestion = rawSuggestion.startsWith(sentence)
|
|
337
|
-
? rawSuggestion
|
|
338
|
-
: sentence + rawSuggestion;
|
|
339
|
-
setCurrentCompletion(suggestion);
|
|
340
|
-
updateCursorSpan(suggestion.substring(sentence.length));
|
|
341
|
-
};
|
|
342
281
|
// Inserts or clears the ghost text inside the cursor span
|
|
343
|
-
const updateCursorSpan = (text) => {
|
|
282
|
+
const updateCursorSpan = useCallback((text) => {
|
|
344
283
|
const doc = pageViewContext.editorIframe?.contentWindow?.document;
|
|
345
284
|
const span = doc?.getElementById(cursorSpanId);
|
|
346
285
|
if (!doc || !span)
|
|
347
286
|
return;
|
|
348
287
|
// Update the completion text
|
|
349
288
|
if (text) {
|
|
350
|
-
// // Create a temporary span to measure the text width
|
|
351
|
-
// const measureSpan = doc.createElement("span");
|
|
352
|
-
// measureSpan.style.visibility = "hidden";
|
|
353
|
-
// measureSpan.style.position = "absolute";
|
|
354
|
-
// measureSpan.style.whiteSpace = "pre"; // Preserve whitespace
|
|
355
|
-
// measureSpan.style.font = window.getComputedStyle(span).font; // Match the font
|
|
356
|
-
// measureSpan.textContent = text;
|
|
357
|
-
// doc.body.appendChild(measureSpan);
|
|
358
|
-
// const textWidth = measureSpan.getBoundingClientRect().width;
|
|
359
|
-
// measureSpan.remove();
|
|
360
289
|
span.textContent = text;
|
|
361
290
|
span.style.color = "#888";
|
|
362
291
|
span.style.fontStyle = "italic";
|
|
363
|
-
//span.innerHTML = "hello";
|
|
364
292
|
// Create or update hint element in the main document
|
|
365
293
|
let hintElement = document.getElementById(`${cursorSpanId}-hint`);
|
|
366
294
|
if (!hintElement) {
|
|
@@ -368,70 +296,274 @@ export function useInlineAiCompletion({ pageViewContext, cursorSpanId, isUpdatin
|
|
|
368
296
|
hintElement.id = `${cursorSpanId}-hint`;
|
|
369
297
|
document.body.appendChild(hintElement);
|
|
370
298
|
}
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
padding: "0.5rem",
|
|
380
|
-
marginLeft: "0.25rem",
|
|
381
|
-
marginRight: "0.25rem",
|
|
382
|
-
borderRadius: "0.25rem",
|
|
383
|
-
border: "1px solid rgb(229, 231, 235)",
|
|
384
|
-
fontStyle: "normal",
|
|
385
|
-
display: "block",
|
|
386
|
-
lineHeight: "1.4",
|
|
387
|
-
zIndex: "95",
|
|
388
|
-
pointerEvents: "none",
|
|
389
|
-
boxShadow: "0 2px 4px rgba(0,0,0,0.1)",
|
|
390
|
-
});
|
|
391
|
-
// Position the hint element relative to the iframe and cursor span
|
|
299
|
+
if (!hintReactRootRef.current) {
|
|
300
|
+
hintElement.replaceChildren();
|
|
301
|
+
hintReactRootRef.current = createRoot(hintElement);
|
|
302
|
+
}
|
|
303
|
+
const hintLabel = editContext?.isMobile
|
|
304
|
+
? "Tap to accept"
|
|
305
|
+
: "Press Tab to accept ⇥";
|
|
306
|
+
const isMobile = editContext?.isMobile ?? false;
|
|
392
307
|
const iframeRect = pageViewContext.editorIframe?.getBoundingClientRect();
|
|
393
308
|
const spanRect = span.getBoundingClientRect();
|
|
309
|
+
let positionStyle = {
|
|
310
|
+
marginLeft: "0.25rem",
|
|
311
|
+
marginRight: "0.25rem",
|
|
312
|
+
};
|
|
394
313
|
if (iframeRect) {
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
const absoluteTop = iframeRect.top + rangeRect.top;
|
|
405
|
-
hintElement.style.left = `${absoluteLeft}px`;
|
|
406
|
-
hintElement.style.top = `${absoluteTop}px`;
|
|
314
|
+
if (isMobile) {
|
|
315
|
+
const centerX = (spanRect.left + spanRect.right) / 2;
|
|
316
|
+
const gap = 6;
|
|
317
|
+
positionStyle = {
|
|
318
|
+
...positionStyle,
|
|
319
|
+
left: centerX,
|
|
320
|
+
top: spanRect.top - gap,
|
|
321
|
+
transform: "translate(-50%, -100%)",
|
|
322
|
+
};
|
|
407
323
|
}
|
|
408
324
|
else {
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
325
|
+
const textLength = span.textContent?.length || 0;
|
|
326
|
+
let left;
|
|
327
|
+
let top;
|
|
328
|
+
if (textLength > 0 && span.firstChild) {
|
|
329
|
+
const range = doc.createRange();
|
|
330
|
+
range.setStart(span.firstChild, Math.max(0, textLength - 1));
|
|
331
|
+
range.setEnd(span.firstChild, textLength);
|
|
332
|
+
const rangeRect = range.getBoundingClientRect();
|
|
333
|
+
left = iframeRect.left + rangeRect.right;
|
|
334
|
+
top = iframeRect.top + rangeRect.top;
|
|
335
|
+
}
|
|
336
|
+
else {
|
|
337
|
+
left = iframeRect.left + spanRect.right;
|
|
338
|
+
top = iframeRect.top + spanRect.top;
|
|
339
|
+
}
|
|
340
|
+
positionStyle = {
|
|
341
|
+
...positionStyle,
|
|
342
|
+
left,
|
|
343
|
+
top,
|
|
344
|
+
transform: undefined,
|
|
345
|
+
};
|
|
414
346
|
}
|
|
415
347
|
}
|
|
348
|
+
hintReactRootRef.current.render(_jsx(InlineCompletionHint, { hintText: hintLabel, isMobile: isMobile, onAccept: () => applyCompletionRef.current?.(), positionStyle: positionStyle }));
|
|
416
349
|
}
|
|
417
350
|
else {
|
|
418
351
|
span.textContent = "";
|
|
419
352
|
// Remove hint element if it exists
|
|
420
353
|
const hintElement = document.getElementById(`${cursorSpanId}-hint`);
|
|
421
354
|
if (hintElement) {
|
|
355
|
+
hintReactRootRef.current?.unmount();
|
|
356
|
+
hintReactRootRef.current = null;
|
|
422
357
|
hintElement.remove();
|
|
423
358
|
}
|
|
424
359
|
}
|
|
425
|
-
};
|
|
426
|
-
const clearCursorSpan = () => {
|
|
360
|
+
}, [pageViewContext.editorIframe, cursorSpanId, editContext?.isMobile]);
|
|
361
|
+
const clearCursorSpan = useCallback(() => {
|
|
427
362
|
const doc = pageViewContext.editorIframe?.contentWindow?.document;
|
|
428
363
|
if (!doc)
|
|
429
364
|
return;
|
|
430
365
|
// Clear the completion text
|
|
431
366
|
updateCursorSpan("");
|
|
432
|
-
};
|
|
367
|
+
}, [pageViewContext.editorIframe?.contentWindow?.document, updateCursorSpan]);
|
|
368
|
+
// Handle keydown events for cursor movement (arrow keys, etc.)
|
|
369
|
+
useEffect(() => {
|
|
370
|
+
const keyHandler = (e) => {
|
|
371
|
+
if (e.key === "ArrowLeft" ||
|
|
372
|
+
e.key === "ArrowRight" ||
|
|
373
|
+
e.key === "ArrowUp" ||
|
|
374
|
+
e.key === "ArrowDown" ||
|
|
375
|
+
e.key === " " ||
|
|
376
|
+
e.key === "Tab" ||
|
|
377
|
+
e.key === "End" ||
|
|
378
|
+
e.key === "Backspace" ||
|
|
379
|
+
e.key === "Delete") {
|
|
380
|
+
setCurrentCompletion(null);
|
|
381
|
+
clearCursorSpan();
|
|
382
|
+
setTimeout(() => {
|
|
383
|
+
if (!isUpdatingRef.current) {
|
|
384
|
+
positionCursorSpan();
|
|
385
|
+
}
|
|
386
|
+
}, 10);
|
|
387
|
+
if (e.key === "ArrowRight" || e.key === "Delete") {
|
|
388
|
+
const cursorSpan = pageViewContext.editorIframe?.contentWindow?.document.getElementById(cursorSpanId);
|
|
389
|
+
if (cursorSpan) {
|
|
390
|
+
const originalDisplay = cursorSpan.style.display;
|
|
391
|
+
cursorSpan.style.display = "none";
|
|
392
|
+
setTimeout(() => {
|
|
393
|
+
if (cursorSpan.parentNode) {
|
|
394
|
+
cursorSpan.style.display = originalDisplay;
|
|
395
|
+
}
|
|
396
|
+
}, 0);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
};
|
|
401
|
+
const doc = pageViewContext.editorIframe?.contentWindow?.document;
|
|
402
|
+
if (!doc)
|
|
403
|
+
return;
|
|
404
|
+
doc.addEventListener("keydown", keyHandler);
|
|
405
|
+
return () => doc.removeEventListener("keydown", keyHandler);
|
|
406
|
+
}, [
|
|
407
|
+
clearCursorSpan,
|
|
408
|
+
cursorSpanId,
|
|
409
|
+
isUpdatingRef,
|
|
410
|
+
pageViewContext.editorIframe?.contentWindow?.document,
|
|
411
|
+
pageViewContext.page,
|
|
412
|
+
positionCursorSpan,
|
|
413
|
+
]);
|
|
414
|
+
// Function to apply the completion (must be before handleInput)
|
|
415
|
+
const applyCompletion = useCallback(() => {
|
|
416
|
+
const iframeWindow = pageViewContext.editorIframe?.contentWindow;
|
|
417
|
+
const iframeDocument = iframeWindow?.document;
|
|
418
|
+
if (!iframeWindow ||
|
|
419
|
+
!iframeDocument ||
|
|
420
|
+
!fieldsContext?.inlineEditingFieldElement)
|
|
421
|
+
return;
|
|
422
|
+
const cursorSpan = iframeDocument.getElementById(cursorSpanId);
|
|
423
|
+
if (!cursorSpan)
|
|
424
|
+
return;
|
|
425
|
+
const completionToApply = cursorSpan.textContent || "";
|
|
426
|
+
if (!completionToApply)
|
|
427
|
+
return;
|
|
428
|
+
const element = fieldsContext.inlineEditingFieldElement;
|
|
429
|
+
const fieldId = element.getAttribute("data-fieldid");
|
|
430
|
+
const fieldName = element.getAttribute("data-fieldname");
|
|
431
|
+
const itemId = element.getAttribute("data-itemid");
|
|
432
|
+
const language = element.getAttribute("data-language");
|
|
433
|
+
const versionStr = element.getAttribute("data-version");
|
|
434
|
+
const isRichText = element.getAttribute("data-is-richtext") === "true";
|
|
435
|
+
const version = versionStr ? parseInt(versionStr, 10) : undefined;
|
|
436
|
+
if (!fieldId || !itemId || !language || !version)
|
|
437
|
+
return;
|
|
438
|
+
const selection = iframeWindow.getSelection();
|
|
439
|
+
if (!selection || selection.rangeCount === 0)
|
|
440
|
+
return;
|
|
441
|
+
const range = selection.getRangeAt(0);
|
|
442
|
+
const tempRange = document.createRange();
|
|
443
|
+
tempRange.selectNodeContents(element);
|
|
444
|
+
tempRange.setEnd(range.startContainer, range.startOffset);
|
|
445
|
+
const textUpToCursor = tempRange.toString();
|
|
446
|
+
const wordBoundaryRegex = /[\s.,;:!?"'()[\]{}<>/|=+\-*&^%$#@~`](?=[^\s.,;:!?"'()[\]{}<>/|=+\-*&^%$#@~`]*$)/;
|
|
447
|
+
const match = textUpToCursor.match(wordBoundaryRegex);
|
|
448
|
+
const lastWordBoundaryIndex = match && match.index !== undefined ? match.index + 1 : 0;
|
|
449
|
+
const currentPartialWord = textUpToCursor
|
|
450
|
+
.substring(lastWordBoundaryIndex)
|
|
451
|
+
.trim();
|
|
452
|
+
const isOverlapping = currentPartialWord.length > 0 &&
|
|
453
|
+
completionToApply
|
|
454
|
+
.toLowerCase()
|
|
455
|
+
.startsWith(currentPartialWord.toLowerCase());
|
|
456
|
+
if (isOverlapping) {
|
|
457
|
+
const wordRange = document.createRange();
|
|
458
|
+
const startContainer = range.startContainer;
|
|
459
|
+
const startOffset = range.startOffset - currentPartialWord.length;
|
|
460
|
+
if (startOffset >= 0 && startContainer.nodeType === Node.TEXT_NODE) {
|
|
461
|
+
wordRange.setStart(startContainer, startOffset);
|
|
462
|
+
wordRange.setEnd(range.startContainer, range.startOffset);
|
|
463
|
+
wordRange.deleteContents();
|
|
464
|
+
}
|
|
465
|
+
else {
|
|
466
|
+
if (textUpToCursor.length > 0 && !textUpToCursor.endsWith(" ")) {
|
|
467
|
+
const spaceNode = document.createTextNode(" ");
|
|
468
|
+
range.insertNode(spaceNode);
|
|
469
|
+
range.setStartAfter(spaceNode);
|
|
470
|
+
range.setEndAfter(spaceNode);
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
else {
|
|
475
|
+
if (textUpToCursor.length > 0 &&
|
|
476
|
+
!textUpToCursor.endsWith(" ") &&
|
|
477
|
+
!textUpToCursor.endsWith("\n") &&
|
|
478
|
+
!/[.!?\-—:;({[\s]$/.test(textUpToCursor)) {
|
|
479
|
+
const spaceNode = document.createTextNode(" ");
|
|
480
|
+
range.insertNode(spaceNode);
|
|
481
|
+
range.setStartAfter(spaceNode);
|
|
482
|
+
range.setEndAfter(spaceNode);
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
const textNode = document.createTextNode(completionToApply);
|
|
486
|
+
range.insertNode(textNode);
|
|
487
|
+
range.setStartAfter(textNode);
|
|
488
|
+
range.setEndAfter(textNode);
|
|
489
|
+
selection.removeAllRanges();
|
|
490
|
+
selection.addRange(range);
|
|
491
|
+
setCurrentCompletion(null);
|
|
492
|
+
clearCursorSpan();
|
|
493
|
+
setTimeout(() => {
|
|
494
|
+
let valueToSave;
|
|
495
|
+
if (isRichText) {
|
|
496
|
+
const clone = element.cloneNode(true);
|
|
497
|
+
const cursorElem = clone.querySelector(`#${cursorSpanId}`);
|
|
498
|
+
if (cursorElem)
|
|
499
|
+
cursorElem.parentNode?.removeChild(cursorElem);
|
|
500
|
+
const ownerDoc = clone.ownerDocument || document;
|
|
501
|
+
const walker = ownerDoc.createTreeWalker(clone, NodeFilter.SHOW_TEXT);
|
|
502
|
+
const toClean = [];
|
|
503
|
+
while (walker.nextNode()) {
|
|
504
|
+
const tn = walker.currentNode;
|
|
505
|
+
if (tn.nodeValue && tn.nodeValue.includes("\u200B"))
|
|
506
|
+
toClean.push(tn);
|
|
507
|
+
}
|
|
508
|
+
toClean.forEach((tn) => (tn.nodeValue = tn.nodeValue?.replaceAll("\u200B", "") || ""));
|
|
509
|
+
valueToSave = clone.innerHTML;
|
|
510
|
+
}
|
|
511
|
+
else {
|
|
512
|
+
valueToSave = (element.innerText || "").replaceAll("\u200B", "");
|
|
513
|
+
}
|
|
514
|
+
editContext?.operations.editField({
|
|
515
|
+
field: {
|
|
516
|
+
fieldId,
|
|
517
|
+
fieldName: fieldName ?? undefined,
|
|
518
|
+
item: { id: itemId, language, version },
|
|
519
|
+
},
|
|
520
|
+
refresh: "none",
|
|
521
|
+
value: valueToSave,
|
|
522
|
+
});
|
|
523
|
+
}, 0);
|
|
524
|
+
}, [
|
|
525
|
+
pageViewContext.editorIframe?.contentWindow,
|
|
526
|
+
fieldsContext?.inlineEditingFieldElement,
|
|
527
|
+
cursorSpanId,
|
|
528
|
+
clearCursorSpan,
|
|
529
|
+
editContext?.operations,
|
|
530
|
+
]);
|
|
531
|
+
applyCompletionRef.current = applyCompletion;
|
|
532
|
+
// Manual completion trigger (non-debounced)
|
|
533
|
+
const getCompletionManual = useCallback(async () => {
|
|
534
|
+
if (!canUseAi)
|
|
535
|
+
return;
|
|
536
|
+
const el = fieldsContext?.inlineEditingFieldElement;
|
|
537
|
+
if (!el)
|
|
538
|
+
return;
|
|
539
|
+
const full = getContentUpToCursor(el) || "";
|
|
540
|
+
const sentence = full.split(/[.?!]\s*/).pop() || "";
|
|
541
|
+
const rawSuggestion = await getCompletion(el, true);
|
|
542
|
+
if (!rawSuggestion) {
|
|
543
|
+
setCurrentCompletion(null);
|
|
544
|
+
clearCursorSpan();
|
|
545
|
+
return;
|
|
546
|
+
}
|
|
547
|
+
const suggestion = rawSuggestion.startsWith(sentence)
|
|
548
|
+
? rawSuggestion
|
|
549
|
+
: sentence + rawSuggestion;
|
|
550
|
+
setCurrentCompletion(suggestion);
|
|
551
|
+
updateCursorSpan(suggestion.substring(sentence.length));
|
|
552
|
+
}, [
|
|
553
|
+
fieldsContext?.inlineEditingFieldElement,
|
|
554
|
+
canUseAi,
|
|
555
|
+
getContentUpToCursor,
|
|
556
|
+
getCompletion,
|
|
557
|
+
clearCursorSpan,
|
|
558
|
+
updateCursorSpan,
|
|
559
|
+
]);
|
|
433
560
|
// On every input: either reuse the existing suggestion or fire a new one
|
|
434
561
|
const handleInput = useCallback((e) => {
|
|
562
|
+
if (!canUseAi) {
|
|
563
|
+
setCurrentCompletion(null);
|
|
564
|
+
clearCursorSpan();
|
|
565
|
+
return;
|
|
566
|
+
}
|
|
435
567
|
const el = fieldsContext?.inlineEditingFieldElement;
|
|
436
568
|
if (!el)
|
|
437
569
|
return;
|
|
@@ -518,13 +650,20 @@ export function useInlineAiCompletion({ pageViewContext, cursorSpanId, isUpdatin
|
|
|
518
650
|
}
|
|
519
651
|
}, [
|
|
520
652
|
fieldsContext?.inlineEditingFieldElement,
|
|
653
|
+
getContentUpToCursor,
|
|
521
654
|
currentCompletion,
|
|
522
|
-
|
|
655
|
+
canUseAi,
|
|
656
|
+
clearCursorSpan,
|
|
523
657
|
getCompletionManual,
|
|
658
|
+
pageViewContext.editorIframe?.contentWindow,
|
|
659
|
+
cursorSpanId,
|
|
660
|
+
applyCompletion,
|
|
661
|
+
updateCursorSpan,
|
|
662
|
+
getCompletionDebounced,
|
|
524
663
|
]);
|
|
525
664
|
// Wire up the input listener
|
|
526
665
|
useEffect(() => {
|
|
527
|
-
if (!editContext?.enableCompletions)
|
|
666
|
+
if (!canUseAi || !editContext?.enableCompletions)
|
|
528
667
|
return;
|
|
529
668
|
const el = fieldsContext?.inlineEditingFieldElement;
|
|
530
669
|
if (!el)
|
|
@@ -534,11 +673,12 @@ export function useInlineAiCompletion({ pageViewContext, cursorSpanId, isUpdatin
|
|
|
534
673
|
}, [
|
|
535
674
|
fieldsContext?.inlineEditingFieldElement,
|
|
536
675
|
handleInput,
|
|
676
|
+
canUseAi,
|
|
537
677
|
editContext?.enableCompletions,
|
|
538
678
|
]);
|
|
539
679
|
// Add mouse click handler to update cursor span position
|
|
540
680
|
useEffect(() => {
|
|
541
|
-
if (!editContext?.enableCompletions)
|
|
681
|
+
if (!canUseAi || !editContext?.enableCompletions)
|
|
542
682
|
return;
|
|
543
683
|
const el = fieldsContext?.inlineEditingFieldElement;
|
|
544
684
|
if (!el)
|
|
@@ -557,7 +697,11 @@ export function useInlineAiCompletion({ pageViewContext, cursorSpanId, isUpdatin
|
|
|
557
697
|
return () => el.removeEventListener("mouseup", handleMouseUp);
|
|
558
698
|
}, [
|
|
559
699
|
fieldsContext?.inlineEditingFieldElement,
|
|
700
|
+
canUseAi,
|
|
560
701
|
editContext?.enableCompletions,
|
|
702
|
+
isUpdatingRef,
|
|
703
|
+
positionCursorSpan,
|
|
704
|
+
clearCursorSpan,
|
|
561
705
|
]);
|
|
562
706
|
// Clean up abort controller on unmount
|
|
563
707
|
useEffect(() => {
|
|
@@ -572,157 +716,13 @@ export function useInlineAiCompletion({ pageViewContext, cursorSpanId, isUpdatin
|
|
|
572
716
|
}
|
|
573
717
|
};
|
|
574
718
|
}, []);
|
|
575
|
-
// Function to apply the completion
|
|
576
|
-
const applyCompletion = () => {
|
|
577
|
-
// Get the cursor span to read the most up-to-date completion
|
|
578
|
-
const iframeWindow = pageViewContext.editorIframe?.contentWindow;
|
|
579
|
-
const iframeDocument = iframeWindow?.document;
|
|
580
|
-
if (!iframeWindow ||
|
|
581
|
-
!iframeDocument ||
|
|
582
|
-
!fieldsContext?.inlineEditingFieldElement)
|
|
583
|
-
return;
|
|
584
|
-
const cursorSpan = iframeDocument.getElementById(cursorSpanId);
|
|
585
|
-
if (!cursorSpan)
|
|
586
|
-
return;
|
|
587
|
-
// Get the completion text directly from the cursor span, which should be the most current
|
|
588
|
-
const completionToApply = cursorSpan.textContent || "";
|
|
589
|
-
if (!completionToApply)
|
|
590
|
-
return;
|
|
591
|
-
const element = fieldsContext?.inlineEditingFieldElement;
|
|
592
|
-
// Get field attributes for saving
|
|
593
|
-
const fieldId = element.getAttribute("data-fieldid");
|
|
594
|
-
const fieldName = element.getAttribute("data-fieldname");
|
|
595
|
-
const itemId = element.getAttribute("data-itemid");
|
|
596
|
-
const language = element.getAttribute("data-language");
|
|
597
|
-
const versionStr = element.getAttribute("data-version");
|
|
598
|
-
const isRichText = element.getAttribute("data-is-richtext") === "true";
|
|
599
|
-
const version = versionStr ? parseInt(versionStr, 10) : undefined;
|
|
600
|
-
if (!fieldId || !itemId || !language || !version)
|
|
601
|
-
return;
|
|
602
|
-
// Get the current selection position
|
|
603
|
-
const selection = iframeWindow.getSelection();
|
|
604
|
-
if (!selection || selection.rangeCount === 0)
|
|
605
|
-
return;
|
|
606
|
-
// Get the text up to the cursor to analyze current word
|
|
607
|
-
const range = selection.getRangeAt(0);
|
|
608
|
-
const tempRange = document.createRange();
|
|
609
|
-
tempRange.selectNodeContents(element);
|
|
610
|
-
tempRange.setEnd(range.startContainer, range.startOffset);
|
|
611
|
-
const textUpToCursor = tempRange.toString();
|
|
612
|
-
// Get the current partial word by finding text from the last word boundary to cursor
|
|
613
|
-
// Look for last word boundary (space, punctuation, etc.)
|
|
614
|
-
const wordBoundaryRegex = /[\s.,;:!?"'()[\]{}<>\/\\|=+\-*&^%$#@~`](?=[^\s.,;:!?"'()[\]{}<>\/\\|=+\-*&^%$#@~`]*$)/;
|
|
615
|
-
const match = textUpToCursor.match(wordBoundaryRegex);
|
|
616
|
-
const lastWordBoundaryIndex = match && match.index !== undefined ? match.index + 1 : 0;
|
|
617
|
-
const currentPartialWord = textUpToCursor
|
|
618
|
-
.substring(lastWordBoundaryIndex)
|
|
619
|
-
.trim();
|
|
620
|
-
// Check if completion overlaps with current partial word
|
|
621
|
-
// (e.g., if user typed "int" and completion is "integer")
|
|
622
|
-
const isOverlapping = currentPartialWord.length > 0 &&
|
|
623
|
-
completionToApply
|
|
624
|
-
.toLowerCase()
|
|
625
|
-
.startsWith(currentPartialWord.toLowerCase());
|
|
626
|
-
console.log("Is overlapping:", isOverlapping);
|
|
627
|
-
// If there's overlap, we need to delete the current partial word
|
|
628
|
-
if (isOverlapping) {
|
|
629
|
-
// Create a range to select the current partial word
|
|
630
|
-
const wordRange = document.createRange();
|
|
631
|
-
// Position where the current word starts
|
|
632
|
-
let startContainer = range.startContainer;
|
|
633
|
-
let startOffset = range.startOffset - currentPartialWord.length;
|
|
634
|
-
// We need to handle the case where the word spans multiple text nodes
|
|
635
|
-
// For simplicity, we'll try to handle the common case first
|
|
636
|
-
if (startOffset >= 0 && startContainer.nodeType === Node.TEXT_NODE) {
|
|
637
|
-
// Simple case: word is in the same text node as cursor
|
|
638
|
-
wordRange.setStart(startContainer, startOffset);
|
|
639
|
-
wordRange.setEnd(range.startContainer, range.startOffset);
|
|
640
|
-
wordRange.deleteContents(); // Delete the partial word
|
|
641
|
-
}
|
|
642
|
-
else {
|
|
643
|
-
// Complex case: use a simpler approach - just insert, user can delete manually if needed
|
|
644
|
-
// This is a fallback for complex DOM structures
|
|
645
|
-
// Add a space if we're in the middle of a sentence
|
|
646
|
-
if (textUpToCursor.length > 0 && !textUpToCursor.endsWith(" ")) {
|
|
647
|
-
const spaceNode = document.createTextNode(" ");
|
|
648
|
-
range.insertNode(spaceNode);
|
|
649
|
-
range.setStartAfter(spaceNode);
|
|
650
|
-
range.setEndAfter(spaceNode);
|
|
651
|
-
}
|
|
652
|
-
}
|
|
653
|
-
}
|
|
654
|
-
else {
|
|
655
|
-
// Not overlapping, add a space if we're in the middle of text
|
|
656
|
-
// and not already at the beginning of text or after a space
|
|
657
|
-
if (textUpToCursor.length > 0 &&
|
|
658
|
-
!textUpToCursor.endsWith(" ") &&
|
|
659
|
-
// Don't add space at the start of a line or after punctuation that shouldn't have a space
|
|
660
|
-
!textUpToCursor.endsWith("\n") &&
|
|
661
|
-
!/[.!?\-—:;({[\s]$/.test(textUpToCursor)) {
|
|
662
|
-
const spaceNode = document.createTextNode(" ");
|
|
663
|
-
range.insertNode(spaceNode);
|
|
664
|
-
range.setStartAfter(spaceNode);
|
|
665
|
-
range.setEndAfter(spaceNode);
|
|
666
|
-
}
|
|
667
|
-
}
|
|
668
|
-
// Now insert the completion text
|
|
669
|
-
const textNode = document.createTextNode(isOverlapping
|
|
670
|
-
? completionToApply // If overlapping, use the full completion
|
|
671
|
-
: completionToApply);
|
|
672
|
-
range.insertNode(textNode);
|
|
673
|
-
// Move the cursor after the inserted text
|
|
674
|
-
range.setStartAfter(textNode);
|
|
675
|
-
range.setEndAfter(textNode);
|
|
676
|
-
selection.removeAllRanges();
|
|
677
|
-
selection.addRange(range);
|
|
678
|
-
setCurrentCompletion(null);
|
|
679
|
-
clearCursorSpan();
|
|
680
|
-
// Explicitly save the field value since the MutationObserver may miss this change
|
|
681
|
-
// when isUpdatingRef is true during cursor positioning
|
|
682
|
-
setTimeout(() => {
|
|
683
|
-
// Get the final value from the element (excluding cursor span content)
|
|
684
|
-
let valueToSave;
|
|
685
|
-
if (isRichText) {
|
|
686
|
-
const clone = element.cloneNode(true);
|
|
687
|
-
const cursorElem = clone.querySelector(`#${cursorSpanId}`);
|
|
688
|
-
if (cursorElem)
|
|
689
|
-
cursorElem.parentNode?.removeChild(cursorElem);
|
|
690
|
-
// Clean up zero-width spaces
|
|
691
|
-
const ownerDoc = clone.ownerDocument || document;
|
|
692
|
-
const walker = ownerDoc.createTreeWalker(clone, NodeFilter.SHOW_TEXT);
|
|
693
|
-
const toClean = [];
|
|
694
|
-
while (walker.nextNode()) {
|
|
695
|
-
const tn = walker.currentNode;
|
|
696
|
-
if (tn.nodeValue && tn.nodeValue.includes("\u200B"))
|
|
697
|
-
toClean.push(tn);
|
|
698
|
-
}
|
|
699
|
-
toClean.forEach((tn) => (tn.nodeValue = tn.nodeValue?.replaceAll("\u200B", "") || ""));
|
|
700
|
-
valueToSave = clone.innerHTML;
|
|
701
|
-
}
|
|
702
|
-
else {
|
|
703
|
-
valueToSave = (element.innerText || "").replaceAll("\u200B", "");
|
|
704
|
-
}
|
|
705
|
-
// Call editField to save the value
|
|
706
|
-
editContext?.operations.editField({
|
|
707
|
-
field: {
|
|
708
|
-
fieldId,
|
|
709
|
-
fieldName: fieldName ?? undefined,
|
|
710
|
-
item: {
|
|
711
|
-
id: itemId,
|
|
712
|
-
language,
|
|
713
|
-
version,
|
|
714
|
-
},
|
|
715
|
-
},
|
|
716
|
-
refresh: "none",
|
|
717
|
-
value: valueToSave,
|
|
718
|
-
});
|
|
719
|
-
}, 0);
|
|
720
|
-
};
|
|
721
719
|
// Exposed manual trigger (if needed)
|
|
722
720
|
return useMemo(() => () => {
|
|
723
721
|
setCurrentCompletion(null);
|
|
724
722
|
clearCursorSpan();
|
|
725
|
-
|
|
726
|
-
|
|
723
|
+
if (canUseAi) {
|
|
724
|
+
getCompletionManual();
|
|
725
|
+
}
|
|
726
|
+
}, [canUseAi, clearCursorSpan, getCompletionManual]);
|
|
727
727
|
}
|
|
728
728
|
//# sourceMappingURL=useInlineAICompletion.js.map
|