@parhelia/core 0.1.12880 → 0.1.12881
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/components/ui/card.d.ts +3 -1
- package/dist/components/ui/card.js +2 -2
- package/dist/components/ui/card.js.map +1 -1
- package/dist/components/ui/context-menu.js +2 -2
- package/dist/config/config.js +6 -5
- package/dist/config/config.js.map +1 -1
- package/dist/config/types.d.ts +0 -7
- package/dist/config/types.js.map +1 -1
- package/dist/editor/FieldActionsOverlay.d.ts +0 -1
- package/dist/editor/FieldActionsOverlay.js +1 -45
- package/dist/editor/FieldActionsOverlay.js.map +1 -1
- package/dist/editor/FieldListField.d.ts +1 -1
- package/dist/editor/FieldListField.js +20 -18
- package/dist/editor/FieldListField.js.map +1 -1
- package/dist/editor/ImageEditor.d.ts +6 -1
- package/dist/editor/ImageEditor.js +19 -3
- package/dist/editor/ImageEditor.js.map +1 -1
- package/dist/editor/PictureEditor.d.ts +2 -1
- package/dist/editor/PictureEditor.js +5 -14
- package/dist/editor/PictureEditor.js.map +1 -1
- package/dist/editor/ai/Agents.js +2 -2
- package/dist/editor/ai/Agents.js.map +1 -1
- package/dist/editor/ai/GuidanceOverlay.js +1 -11
- package/dist/editor/ai/GuidanceOverlay.js.map +1 -1
- package/dist/editor/ai/InlineAiDialog.js +22 -11
- package/dist/editor/ai/InlineAiDialog.js.map +1 -1
- package/dist/editor/ai/InlineAiTrigger.js +17 -57
- package/dist/editor/ai/InlineAiTrigger.js.map +1 -1
- package/dist/editor/ai/dialogs/capturePageDom.js +66 -36
- package/dist/editor/ai/dialogs/capturePageDom.js.map +1 -1
- package/dist/editor/ai/dialogs/capturePageScreenshot.js +281 -162
- package/dist/editor/ai/dialogs/capturePageScreenshot.js.map +1 -1
- package/dist/editor/ai/terminal/agentSessionState.d.ts +3 -0
- package/dist/editor/ai/terminal/agentSessionState.js +3 -1
- package/dist/editor/ai/terminal/agentSessionState.js.map +1 -1
- package/dist/editor/ai/terminal/agentStartRequest.d.ts +2 -1
- package/dist/editor/ai/terminal/agentStartRequest.js +2 -1
- package/dist/editor/ai/terminal/agentStartRequest.js.map +1 -1
- package/dist/editor/ai/terminal/components/AgentCostDisplay.js +1 -1
- package/dist/editor/ai/terminal/components/AgentCostDisplay.js.map +1 -1
- package/dist/editor/ai/terminal/components/AgentDocumentList.d.ts +7 -0
- package/dist/editor/ai/terminal/components/AgentDocumentList.js +55 -13
- package/dist/editor/ai/terminal/components/AgentDocumentList.js.map +1 -1
- package/dist/editor/ai/terminal/components/AgentEditHistoryButton.d.ts +5 -0
- package/dist/editor/ai/terminal/components/AgentEditHistoryButton.js +12 -0
- package/dist/editor/ai/terminal/components/AgentEditHistoryButton.js.map +1 -0
- package/dist/editor/ai/terminal/components/AgentFullPromptControls.d.ts +3 -1
- package/dist/editor/ai/terminal/components/AgentFullPromptControls.js +22 -14
- package/dist/editor/ai/terminal/components/AgentFullPromptControls.js.map +1 -1
- package/dist/editor/ai/terminal/components/AgentModeSelector.js +4 -4
- package/dist/editor/ai/terminal/components/AgentModeSelector.js.map +1 -1
- package/dist/editor/ai/terminal/components/AgentPromptActionButtons.js +4 -4
- package/dist/editor/ai/terminal/components/AgentPromptActionButtons.js.map +1 -1
- package/dist/editor/ai/terminal/components/AgentPromptComposer.js +1 -1
- package/dist/editor/ai/terminal/components/AgentPromptComposer.js.map +1 -1
- package/dist/editor/ai/terminal/components/AgentPromptInputArea.d.ts +2 -1
- package/dist/editor/ai/terminal/components/AgentPromptInputArea.js +8 -11
- package/dist/editor/ai/terminal/components/AgentPromptInputArea.js.map +1 -1
- package/dist/editor/ai/terminal/components/AgentPromptTrayPopovers.d.ts +1 -4
- package/dist/editor/ai/terminal/components/AgentPromptTrayPopovers.js +31 -14
- package/dist/editor/ai/terminal/components/AgentPromptTrayPopovers.js.map +1 -1
- package/dist/editor/ai/terminal/components/AgentSettingsPopover.js +1 -1
- package/dist/editor/ai/terminal/components/AgentSettingsPopover.js.map +1 -1
- package/dist/editor/ai/terminal/components/AgentTerminalFullLayout.d.ts +2 -1
- package/dist/editor/ai/terminal/components/AgentTerminalFullLayout.js +2 -4
- package/dist/editor/ai/terminal/components/AgentTerminalFullLayout.js.map +1 -1
- package/dist/editor/ai/terminal/components/AgentTerminalMessageGroups.js +1 -1
- package/dist/editor/ai/terminal/components/AgentTerminalMessageGroups.js.map +1 -1
- package/dist/editor/ai/terminal/components/AgentTerminalView.js +13 -2
- package/dist/editor/ai/terminal/components/AgentTerminalView.js.map +1 -1
- package/dist/editor/ai/terminal/components/AiResponseMessage.js +16 -14
- package/dist/editor/ai/terminal/components/AiResponseMessage.js.map +1 -1
- package/dist/editor/ai/terminal/components/ContextInfoBar.js +22 -2
- package/dist/editor/ai/terminal/components/ContextInfoBar.js.map +1 -1
- package/dist/editor/ai/terminal/components/QueuedPromptsPanel.js +37 -26
- package/dist/editor/ai/terminal/components/QueuedPromptsPanel.js.map +1 -1
- package/dist/editor/ai/terminal/components/UserMessage.d.ts +2 -1
- package/dist/editor/ai/terminal/components/UserMessage.js +144 -8
- package/dist/editor/ai/terminal/components/UserMessage.js.map +1 -1
- package/dist/editor/ai/terminal/useAgentPromptComposerHandlers.js +1 -1
- package/dist/editor/ai/terminal/useAgentPromptComposerHandlers.js.map +1 -1
- package/dist/editor/ai/terminal/useAgentSessionSync.d.ts +1 -0
- package/dist/editor/ai/terminal/useAgentSubmitHandlers.d.ts +3 -1
- package/dist/editor/ai/terminal/useAgentSubmitHandlers.js +9 -3
- package/dist/editor/ai/terminal/useAgentSubmitHandlers.js.map +1 -1
- package/dist/editor/ai/terminal/useAgentTerminalController.js +7 -0
- package/dist/editor/ai/terminal/useAgentTerminalController.js.map +1 -1
- package/dist/editor/ai/terminal/useAgentTerminalUiState.js +1 -1
- package/dist/editor/ai/terminal/useAgentTerminalUiState.js.map +1 -1
- package/dist/editor/ai/terminal/useAgentUserMessageSocketHandler.js +3 -1
- package/dist/editor/ai/terminal/useAgentUserMessageSocketHandler.js.map +1 -1
- package/dist/editor/ai/useInlineAiPosition.d.ts +1 -1
- package/dist/editor/ai/useInlineAiPosition.js +22 -52
- package/dist/editor/ai/useInlineAiPosition.js.map +1 -1
- package/dist/editor/ai-image-editor/AiImageResultOverlay.js +30 -62
- package/dist/editor/ai-image-editor/AiImageResultOverlay.js.map +1 -1
- package/dist/editor/bridge/BridgeClient.d.ts +80 -0
- package/dist/editor/bridge/BridgeClient.js +417 -0
- package/dist/editor/bridge/BridgeClient.js.map +1 -0
- package/dist/editor/client/EditorShell.d.ts +5 -1
- package/dist/editor/client/EditorShell.js +282 -126
- package/dist/editor/client/EditorShell.js.map +1 -1
- package/dist/editor/client/editContext.d.ts +33 -5
- package/dist/editor/client/editContext.js.map +1 -1
- package/dist/editor/client/hooks/useSocketMessageHandler.js +14 -17
- package/dist/editor/client/hooks/useSocketMessageHandler.js.map +1 -1
- package/dist/editor/client/itemsRepository.d.ts +2 -0
- package/dist/editor/client/itemsRepository.js +15 -8
- package/dist/editor/client/itemsRepository.js.map +1 -1
- package/dist/editor/client/operations.d.ts +1 -1
- package/dist/editor/client/operations.js +41 -17
- package/dist/editor/client/operations.js.map +1 -1
- package/dist/editor/client/pageModelBuilder.js +24 -7
- package/dist/editor/client/pageModelBuilder.js.map +1 -1
- package/dist/editor/field-types/MultiLineText.js +10 -3
- package/dist/editor/field-types/MultiLineText.js.map +1 -1
- package/dist/editor/field-types/RawEditor.js +8 -1
- package/dist/editor/field-types/RawEditor.js.map +1 -1
- package/dist/editor/field-types/RichTextEditorComponent.js +156 -45
- package/dist/editor/field-types/RichTextEditorComponent.js.map +1 -1
- package/dist/editor/field-types/SingleLineText.js +10 -3
- package/dist/editor/field-types/SingleLineText.js.map +1 -1
- package/dist/editor/field-types/richtext/components/ReactSlate.js +8 -2
- package/dist/editor/field-types/richtext/components/ReactSlate.js.map +1 -1
- package/dist/editor/field-types/richtext/contextMenuFactory.d.ts +1 -2
- package/dist/editor/field-types/richtext/contextMenuFactory.js +100 -303
- 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/useFormFieldCaretPresence.d.ts +13 -0
- package/dist/editor/field-types/useFormFieldCaretPresence.js +92 -0
- package/dist/editor/field-types/useFormFieldCaretPresence.js.map +1 -0
- package/dist/editor/media-selector/TreeSelector.js +15 -15
- package/dist/editor/media-selector/TreeSelector.js.map +1 -1
- package/dist/editor/menubar/PageSelector.js +8 -2
- package/dist/editor/menubar/PageSelector.js.map +1 -1
- package/dist/editor/menubar/VersionPreviewCard.js +4 -249
- package/dist/editor/menubar/VersionPreviewCard.js.map +1 -1
- package/dist/editor/menubar/toolbar-sections/EditControls.js +2 -2
- package/dist/editor/menubar/toolbar-sections/EditControls.js.map +1 -1
- package/dist/editor/menubar/toolbar-sections/ManualBrowser.d.ts +0 -10
- package/dist/editor/menubar/toolbar-sections/ManualBrowser.js +63 -462
- package/dist/editor/menubar/toolbar-sections/ManualBrowser.js.map +1 -1
- package/dist/editor/menubar/toolbar-sections/ViewportControls.js +1 -1
- package/dist/editor/page-editor-chrome/BridgeInlineFormatOverlay.d.ts +6 -0
- package/dist/editor/page-editor-chrome/BridgeInlineFormatOverlay.js +123 -0
- package/dist/editor/page-editor-chrome/BridgeInlineFormatOverlay.js.map +1 -0
- package/dist/editor/page-editor-chrome/CommentHighlightings.d.ts +5 -2
- package/dist/editor/page-editor-chrome/CommentHighlightings.js +340 -215
- package/dist/editor/page-editor-chrome/CommentHighlightings.js.map +1 -1
- package/dist/editor/page-editor-chrome/FeedbackHighlightBadge.d.ts +5 -1
- package/dist/editor/page-editor-chrome/FeedbackHighlightBadge.js +11 -4
- package/dist/editor/page-editor-chrome/FeedbackHighlightBadge.js.map +1 -1
- package/dist/editor/page-editor-chrome/FieldActionIndicator.js +21 -13
- package/dist/editor/page-editor-chrome/FieldActionIndicator.js.map +1 -1
- package/dist/editor/page-editor-chrome/FieldEditedIndicator.js +23 -29
- package/dist/editor/page-editor-chrome/FieldEditedIndicator.js.map +1 -1
- package/dist/editor/page-editor-chrome/FrameMenu.js +110 -19
- package/dist/editor/page-editor-chrome/FrameMenu.js.map +1 -1
- package/dist/editor/page-editor-chrome/LockedFieldIndicator.d.ts +3 -2
- package/dist/editor/page-editor-chrome/LockedFieldIndicator.js +148 -45
- package/dist/editor/page-editor-chrome/LockedFieldIndicator.js.map +1 -1
- package/dist/editor/page-editor-chrome/PageEditorChrome.d.ts +2 -0
- package/dist/editor/page-editor-chrome/PageEditorChrome.js +25 -21
- package/dist/editor/page-editor-chrome/PageEditorChrome.js.map +1 -1
- package/dist/editor/page-editor-chrome/PictureEditorOverlay.js +163 -128
- package/dist/editor/page-editor-chrome/PictureEditorOverlay.js.map +1 -1
- package/dist/editor/page-editor-chrome/PlaceholderDropZone.d.ts +1 -1
- package/dist/editor/page-editor-chrome/PlaceholderDropZone.js +6 -3
- package/dist/editor/page-editor-chrome/PlaceholderDropZone.js.map +1 -1
- package/dist/editor/page-editor-chrome/PlaceholderDropZones.d.ts +1 -2
- package/dist/editor/page-editor-chrome/PlaceholderDropZones.js +83 -146
- package/dist/editor/page-editor-chrome/PlaceholderDropZones.js.map +1 -1
- package/dist/editor/page-editor-chrome/SuggestionHighlightings.d.ts +5 -2
- package/dist/editor/page-editor-chrome/SuggestionHighlightings.js +144 -63
- package/dist/editor/page-editor-chrome/SuggestionHighlightings.js.map +1 -1
- package/dist/editor/page-editor-chrome/VersionDiffHighlightings.d.ts +1 -2
- package/dist/editor/page-editor-chrome/VersionDiffHighlightings.js +101 -30
- package/dist/editor/page-editor-chrome/VersionDiffHighlightings.js.map +1 -1
- package/dist/editor/page-editor-chrome/overlay/IframeOverlayProvider.d.ts +10 -1
- package/dist/editor/page-editor-chrome/overlay/IframeOverlayProvider.js +105 -122
- package/dist/editor/page-editor-chrome/overlay/IframeOverlayProvider.js.map +1 -1
- package/dist/editor/page-editor-chrome/overlay/geometry.d.ts +11 -4
- package/dist/editor/page-editor-chrome/overlay/geometry.js +139 -36
- package/dist/editor/page-editor-chrome/overlay/geometry.js.map +1 -1
- package/dist/editor/page-editor-chrome/useBridgeInlineEditing.d.ts +26 -0
- package/dist/editor/page-editor-chrome/useBridgeInlineEditing.js +222 -0
- package/dist/editor/page-editor-chrome/useBridgeInlineEditing.js.map +1 -0
- package/dist/editor/page-viewer/EditorForm.js +17 -1
- package/dist/editor/page-viewer/EditorForm.js.map +1 -1
- package/dist/editor/page-viewer/MiniMap.d.ts +2 -2
- package/dist/editor/page-viewer/MiniMap.js +176 -364
- package/dist/editor/page-viewer/MiniMap.js.map +1 -1
- package/dist/editor/page-viewer/PageViewer.js +40 -13
- package/dist/editor/page-viewer/PageViewer.js.map +1 -1
- package/dist/editor/page-viewer/PageViewerFrame.d.ts +0 -5
- package/dist/editor/page-viewer/PageViewerFrame.js +1529 -1511
- package/dist/editor/page-viewer/PageViewerFrame.js.map +1 -1
- package/dist/editor/page-viewer/bridgeFieldPatch.d.ts +20 -0
- package/dist/editor/page-viewer/bridgeFieldPatch.js +33 -0
- package/dist/editor/page-viewer/bridgeFieldPatch.js.map +1 -0
- package/dist/editor/page-viewer/pageViewContext.d.ts +32 -0
- package/dist/editor/page-viewer/pageViewContext.js +37 -6
- package/dist/editor/page-viewer/pageViewContext.js.map +1 -1
- package/dist/editor/reviews/Comment.d.ts +2 -1
- package/dist/editor/reviews/Comment.js +9 -4
- package/dist/editor/reviews/Comment.js.map +1 -1
- package/dist/editor/reviews/CommentEditor.js +1 -1
- package/dist/editor/reviews/CommentEditor.js.map +1 -1
- package/dist/editor/reviews/CommentPopover.js +68 -9
- package/dist/editor/reviews/CommentPopover.js.map +1 -1
- package/dist/editor/reviews/CommentView.js +24 -4
- package/dist/editor/reviews/CommentView.js.map +1 -1
- package/dist/editor/reviews/Comments.d.ts +0 -2
- package/dist/editor/reviews/Comments.js +29 -30
- package/dist/editor/reviews/Comments.js.map +1 -1
- package/dist/editor/reviews/FeedbackCard.d.ts +4 -2
- package/dist/editor/reviews/FeedbackCard.js +5 -5
- package/dist/editor/reviews/FeedbackCard.js.map +1 -1
- package/dist/editor/reviews/SuggestedEdit.js +4 -6
- package/dist/editor/reviews/SuggestedEdit.js.map +1 -1
- package/dist/editor/reviews/SuggestionDisplayPopover.js +3 -2
- package/dist/editor/reviews/SuggestionDisplayPopover.js.map +1 -1
- package/dist/editor/reviews/commentAi.js +96 -27
- package/dist/editor/reviews/commentAi.js.map +1 -1
- package/dist/editor/reviews/commentTransientSelection.d.ts +23 -0
- package/dist/editor/reviews/commentTransientSelection.js +7 -0
- package/dist/editor/reviews/commentTransientSelection.js.map +1 -0
- package/dist/editor/reviews/feedbackOrdering.d.ts +5 -0
- package/dist/editor/reviews/feedbackOrdering.js +27 -0
- package/dist/editor/reviews/feedbackOrdering.js.map +1 -0
- package/dist/editor/reviews/feedbackSelection.js +32 -4
- package/dist/editor/reviews/feedbackSelection.js.map +1 -1
- package/dist/editor/reviews/suggestedEditState.d.ts +12 -0
- package/dist/editor/reviews/suggestedEditState.js +90 -0
- package/dist/editor/reviews/suggestedEditState.js.map +1 -0
- package/dist/editor/reviews/suggestionDisplayValue.d.ts +43 -0
- package/dist/editor/reviews/suggestionDisplayValue.js +93 -0
- package/dist/editor/reviews/suggestionDisplayValue.js.map +1 -0
- package/dist/editor/services/agentService.d.ts +15 -0
- package/dist/editor/services/agentService.js +11 -1
- package/dist/editor/services/agentService.js.map +1 -1
- package/dist/editor/services/reviewsService.d.ts +2 -2
- package/dist/editor/services/reviewsService.js.map +1 -1
- package/dist/editor/settings/SettingsView.js +2 -2
- package/dist/editor/settings/SettingsView.js.map +1 -1
- package/dist/editor/settings/panels/ProjectTemplatesPanel.js +1 -1
- package/dist/editor/settings/panels/ProjectTemplatesPanel.js.map +1 -1
- package/dist/editor/settings/panels/ProvidersPanel.js +2 -3
- package/dist/editor/settings/panels/ProvidersPanel.js.map +1 -1
- package/dist/editor/sidebar/MorePanelsButton.js +1 -1
- package/dist/editor/sidebar/MorePanelsButton.js.map +1 -1
- package/dist/editor/sidebar/Workbox.js +1 -1
- package/dist/editor/sidebar/Workbox.js.map +1 -1
- package/dist/editor/ui/IconSelectorDialog.js +1 -1
- package/dist/editor/ui/IconSelectorDialog.js.map +1 -1
- package/dist/editor/ui/SimpleIconButton.d.ts +2 -2
- package/dist/editor/ui/SimpleIconButton.js +1 -1
- package/dist/editor/ui/SimpleIconButton.js.map +1 -1
- package/dist/editor/utils.d.ts +1 -17
- package/dist/editor/utils.js +0 -143
- package/dist/editor/utils.js.map +1 -1
- package/dist/editor/version-diff/versionDiffTargets.d.ts +3 -8
- package/dist/editor/version-diff/versionDiffTargets.js +37 -94
- package/dist/editor/version-diff/versionDiffTargets.js.map +1 -1
- package/dist/revision.d.ts +2 -2
- package/dist/revision.js +2 -2
- package/dist/splash-screen/DialogWrappers.js +2 -2
- package/dist/splash-screen/DialogWrappers.js.map +1 -1
- package/dist/splash-screen/ModernSplashScreen.js +11 -3
- package/dist/splash-screen/ModernSplashScreen.js.map +1 -1
- package/dist/splash-screen/NewPage.js +7 -5
- package/dist/splash-screen/NewPage.js.map +1 -1
- package/dist/splash-screen/OpenPage.js +5 -3
- package/dist/splash-screen/OpenPage.js.map +1 -1
- package/dist/splash-screen/RecentPages.js +3 -3
- package/dist/splash-screen/RecentPages.js.map +1 -1
- package/package.json +2 -1
- package/styles.css +49 -0
- package/dist/editor/page-editor-chrome/InlineEditor.d.ts +0 -7
- package/dist/editor/page-editor-chrome/InlineEditor.js +0 -1719
- package/dist/editor/page-editor-chrome/InlineEditor.js.map +0 -1
- package/dist/editor/page-editor-chrome/overlay/iframeAccess.d.ts +0 -2
- package/dist/editor/page-editor-chrome/overlay/iframeAccess.js +0 -21
- package/dist/editor/page-editor-chrome/overlay/iframeAccess.js.map +0 -1
- package/dist/editor/page-editor-chrome/useInlineAICompletion.d.ts +0 -7
- package/dist/editor/page-editor-chrome/useInlineAICompletion.js +0 -758
- package/dist/editor/page-editor-chrome/useInlineAICompletion.js.map +0 -1
- package/dist/editor/page-viewer/pageModelSkeletonBuilder.d.ts +0 -3
- package/dist/editor/page-viewer/pageModelSkeletonBuilder.js +0 -796
- package/dist/editor/page-viewer/pageModelSkeletonBuilder.js.map +0 -1
|
@@ -46,6 +46,7 @@ import { QuickItemSwitcher } from "../QuickItemSwitcher";
|
|
|
46
46
|
import { useEditorSlotContext, } from "../views/editorSlotContext";
|
|
47
47
|
import { getComments, getAvailableCommentTags, } from "../services/reviewsService";
|
|
48
48
|
import { useReviews } from "../reviews/useReviews";
|
|
49
|
+
import { COMMENT_TRANSIENT_ELEMENT_KEY, COMMENT_TRANSIENT_SELECTION_RECT, } from "../reviews/commentTransientSelection";
|
|
49
50
|
import uuid from "react-uuid";
|
|
50
51
|
import { flushSync } from "react-dom";
|
|
51
52
|
import { getSuggestedEdits } from "../services/suggestedEditsService";
|
|
@@ -67,6 +68,24 @@ import { FeatureGate, LicenseFeatures, LicenseProvider, LicenseOverlay, } from "
|
|
|
67
68
|
// nothing open" (param present with this value) so reload can honor the user's intent.
|
|
68
69
|
const SIDEBAR_NONE_SENTINEL = "none";
|
|
69
70
|
const sidebarUrlValue = (ids) => ids.length ? ids.join(",") : SIDEBAR_NONE_SENTINEL;
|
|
71
|
+
// moved to hooks/useQuota
|
|
72
|
+
function isUsableTextSelectionRange(range) {
|
|
73
|
+
return !!(range &&
|
|
74
|
+
range.text?.trim() &&
|
|
75
|
+
typeof range.startOffset === "number" &&
|
|
76
|
+
typeof range.endOffset === "number" &&
|
|
77
|
+
range.startOffset !== range.endOffset &&
|
|
78
|
+
range.fieldId &&
|
|
79
|
+
range.itemId);
|
|
80
|
+
}
|
|
81
|
+
function selectionRangeMatchesField(range, field) {
|
|
82
|
+
if (!range || !field)
|
|
83
|
+
return false;
|
|
84
|
+
return (cleanId(range.fieldId) === cleanId(field.fieldId) &&
|
|
85
|
+
cleanId(range.itemId) === cleanId(field.item.id) &&
|
|
86
|
+
(!range.language || range.language === field.item.language) &&
|
|
87
|
+
(typeof range.version !== "number" || range.version === field.item.version));
|
|
88
|
+
}
|
|
70
89
|
function reconcileSlotSettingsState(previous, slots, defaults) {
|
|
71
90
|
const next = {};
|
|
72
91
|
let changed = false;
|
|
@@ -134,8 +153,10 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
134
153
|
const [focusedField, setFocusedField] = useState();
|
|
135
154
|
const focusedFieldRef = useRef(undefined);
|
|
136
155
|
const [selectedRange, setSelectedRange] = useState();
|
|
156
|
+
const lastTextSelectionRangeRef = useRef(undefined);
|
|
137
157
|
const [validating, setValidating] = useState(false);
|
|
138
158
|
const [inserting, setInserting] = useState();
|
|
159
|
+
const insertingSequenceRef = useRef(0);
|
|
139
160
|
const [showFullscreenHint, setShowFullscreenHint] = useState(false);
|
|
140
161
|
// Fullscreen is a shell-level UI mode. Keep it in EditorShell state so the shell can rerender
|
|
141
162
|
// immediately when toggled, while still syncing the active slot's PageViewContext.fullscreen.
|
|
@@ -465,7 +486,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
465
486
|
// The very first URL sync after initial load should replaceState (not pushState)
|
|
466
487
|
// so the initial bare URL isn't left as a dead-end history entry.
|
|
467
488
|
const isFirstUrlSyncRef = useRef(true);
|
|
468
|
-
const [inlineEditingFieldElement, setInlineEditingFieldElement] = useState();
|
|
469
489
|
const [lockedField, setLockedField] = useState();
|
|
470
490
|
const [itemLanguages, setItemLanguages] = useState([]);
|
|
471
491
|
const [itemVersions, setItemVersions] = useState([]);
|
|
@@ -555,9 +575,67 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
555
575
|
const [isTourActive, setIsTourActive] = useState(tourRestoredFromUrl);
|
|
556
576
|
// Track if tour was restored from URL to skip prepareAction on initial render
|
|
557
577
|
const tourRestoredRef = useRef(tourRestoredFromUrl);
|
|
558
|
-
const [mode,
|
|
578
|
+
const [mode, setModeState] = useState("edit");
|
|
579
|
+
const modeRef = useRef("edit");
|
|
580
|
+
modeRef.current = mode;
|
|
581
|
+
const modeChangeParticipantsRef = useRef(new Set());
|
|
582
|
+
const loadSuggestedEditsRef = useRef(async () => { });
|
|
583
|
+
const [modeTransitionRevision, setModeTransitionRevision] = useState(0);
|
|
559
584
|
const [previewDate, setPreviewDate] = useState();
|
|
560
585
|
const [layoutMode, setLayoutMode] = useState("final");
|
|
586
|
+
const registerModeChangeParticipant = useCallback((participant) => {
|
|
587
|
+
modeChangeParticipantsRef.current.add(participant);
|
|
588
|
+
return () => {
|
|
589
|
+
modeChangeParticipantsRef.current.delete(participant);
|
|
590
|
+
};
|
|
591
|
+
}, []);
|
|
592
|
+
const changeMode = useCallback(async (nextMode, options) => {
|
|
593
|
+
const previousMode = modeRef.current;
|
|
594
|
+
if (nextMode === previousMode)
|
|
595
|
+
return;
|
|
596
|
+
const participants = Array.from(modeChangeParticipantsRef.current);
|
|
597
|
+
for (const participant of participants) {
|
|
598
|
+
await participant.beforeModeChange?.(nextMode, previousMode, options);
|
|
599
|
+
}
|
|
600
|
+
for (const participant of participants) {
|
|
601
|
+
participant.clearInlineDedupe?.(nextMode, previousMode, options);
|
|
602
|
+
}
|
|
603
|
+
flushSync(() => {
|
|
604
|
+
modeRef.current = nextMode;
|
|
605
|
+
setModeState(nextMode);
|
|
606
|
+
setModeTransitionRevision((revision) => revision + 1);
|
|
607
|
+
if (nextMode !== "preview") {
|
|
608
|
+
setPreviewDate(undefined);
|
|
609
|
+
}
|
|
610
|
+
if (nextMode === "suggestions") {
|
|
611
|
+
setShowSuggestedEdits(true);
|
|
612
|
+
setWorkspaceId("editor");
|
|
613
|
+
setOpenSidebars((prev) => {
|
|
614
|
+
if (prev.includes("feedback"))
|
|
615
|
+
return prev;
|
|
616
|
+
const next = [...prev, "feedback"];
|
|
617
|
+
openSidebarsRef.current = next;
|
|
618
|
+
return next;
|
|
619
|
+
});
|
|
620
|
+
}
|
|
621
|
+
else {
|
|
622
|
+
setShowSuggestedEdits(false);
|
|
623
|
+
}
|
|
624
|
+
});
|
|
625
|
+
if (nextMode === "suggestions") {
|
|
626
|
+
void loadSuggestedEditsRef.current();
|
|
627
|
+
}
|
|
628
|
+
}, []);
|
|
629
|
+
const setMode = useCallback((nextMode) => {
|
|
630
|
+
const resolvedMode = typeof nextMode === "function" ? nextMode(modeRef.current) : nextMode;
|
|
631
|
+
void changeMode(resolvedMode);
|
|
632
|
+
}, [changeMode]);
|
|
633
|
+
const workspaceShowsModeControls = !!configuration.editor.workspaces?.find((workspace) => workspace.id === workspaceId)?.toolbarFactory;
|
|
634
|
+
useEffect(() => {
|
|
635
|
+
if (workspaceShowsModeControls || mode !== "suggestions")
|
|
636
|
+
return;
|
|
637
|
+
void changeMode("edit", { reason: "mode-controls-hidden" });
|
|
638
|
+
}, [changeMode, mode, workspaceId, workspaceShowsModeControls]);
|
|
561
639
|
useEffect(() => {
|
|
562
640
|
if (mode !== "preview") {
|
|
563
641
|
setPreviewDate(undefined);
|
|
@@ -663,19 +741,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
663
741
|
setSelectedHelpSectionId(helpParam === "contents" || helpParam === "true" ? null : helpParam);
|
|
664
742
|
}
|
|
665
743
|
}, [searchParams, isInitialLoad]);
|
|
666
|
-
useEffect(() => {
|
|
667
|
-
if (mode === "suggestions") {
|
|
668
|
-
// Ensure we're in the editor workspace and open the feedback sidebar
|
|
669
|
-
setWorkspaceId("editor");
|
|
670
|
-
// Open the feedback sidebar if not already open
|
|
671
|
-
setOpenSidebars((prev) => {
|
|
672
|
-
if (!prev.includes("comments")) {
|
|
673
|
-
return [...prev, "comments"];
|
|
674
|
-
}
|
|
675
|
-
return prev;
|
|
676
|
-
});
|
|
677
|
-
}
|
|
678
|
-
}, [mode]);
|
|
679
744
|
useEffect(() => {
|
|
680
745
|
if (focusedField &&
|
|
681
746
|
selection.length > 0 &&
|
|
@@ -685,7 +750,19 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
685
750
|
}, [selection]);
|
|
686
751
|
useEffect(() => {
|
|
687
752
|
focusedFieldRef.current = focusedField;
|
|
753
|
+
const lastTextSelection = lastTextSelectionRangeRef.current;
|
|
754
|
+
if (focusedField &&
|
|
755
|
+
lastTextSelection &&
|
|
756
|
+
(focusedField.fieldId !== lastTextSelection.fieldId ||
|
|
757
|
+
focusedField.item.id !== lastTextSelection.itemId)) {
|
|
758
|
+
lastTextSelectionRangeRef.current = undefined;
|
|
759
|
+
}
|
|
688
760
|
}, [focusedField]);
|
|
761
|
+
useEffect(() => {
|
|
762
|
+
if (isUsableTextSelectionRange(selectedRange)) {
|
|
763
|
+
lastTextSelectionRangeRef.current = selectedRange;
|
|
764
|
+
}
|
|
765
|
+
}, [selectedRange]);
|
|
689
766
|
// Track the current page item descriptor for itemsRepository
|
|
690
767
|
const [currentPageItem, setCurrentPageItem] = useState();
|
|
691
768
|
// Create itemsRepository with current page item (will be updated when page loads)
|
|
@@ -1216,7 +1293,8 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
1216
1293
|
const toggleHelpTerminal = useCallback((options) => {
|
|
1217
1294
|
const isCurrentlyOpen = showHelpTerminal;
|
|
1218
1295
|
const requestedTab = options?.activeTab;
|
|
1219
|
-
if (isCurrentlyOpen &&
|
|
1296
|
+
if (isCurrentlyOpen &&
|
|
1297
|
+
(!requestedTab || requestedTab === helpTerminalActiveTab)) {
|
|
1220
1298
|
// Close when toggling the currently active help view.
|
|
1221
1299
|
handleSetShowHelpTerminal(false);
|
|
1222
1300
|
}
|
|
@@ -1419,9 +1497,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
1419
1497
|
}
|
|
1420
1498
|
// Handle mode changes — always set to avoid stale-closure mismatch
|
|
1421
1499
|
const urlMode = urlParams.get("mode");
|
|
1422
|
-
|
|
1423
|
-
setMode(urlMode);
|
|
1424
|
-
}
|
|
1500
|
+
setMode(urlMode ?? "edit");
|
|
1425
1501
|
// Handle fullscreen changes (shell-level state)
|
|
1426
1502
|
const isFullscreen = urlParams.get("fullscreen") === "true";
|
|
1427
1503
|
if (configuration.forceFullscreen) {
|
|
@@ -1698,6 +1774,9 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
1698
1774
|
const edits = result.data || [];
|
|
1699
1775
|
setSuggestedEdits(edits);
|
|
1700
1776
|
}, [item, searchParams]);
|
|
1777
|
+
useEffect(() => {
|
|
1778
|
+
loadSuggestedEditsRef.current = loadSuggestedEdits;
|
|
1779
|
+
}, [loadSuggestedEdits]);
|
|
1701
1780
|
const loadFavorites = useCallback(async () => {
|
|
1702
1781
|
try {
|
|
1703
1782
|
const result = await getAllFavorites();
|
|
@@ -1710,6 +1789,9 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
1710
1789
|
setFavorites([]);
|
|
1711
1790
|
}
|
|
1712
1791
|
}, []);
|
|
1792
|
+
const refreshFavorites = useCallback(async (opts) => {
|
|
1793
|
+
await loadFavorites();
|
|
1794
|
+
}, [loadFavorites]);
|
|
1713
1795
|
const page = activePageViewContext.page;
|
|
1714
1796
|
const currentHistoryScope = useMemo(() => {
|
|
1715
1797
|
const currentItem = item?.descriptor;
|
|
@@ -2106,6 +2188,9 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
2106
2188
|
globalThis.editorRefreshTimer = undefined;
|
|
2107
2189
|
};
|
|
2108
2190
|
if (mode === "immediate") {
|
|
2191
|
+
if (refreshTimer) {
|
|
2192
|
+
clearTimeout(refreshTimer);
|
|
2193
|
+
}
|
|
2109
2194
|
doRefresh();
|
|
2110
2195
|
return;
|
|
2111
2196
|
}
|
|
@@ -2299,7 +2384,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
2299
2384
|
else {
|
|
2300
2385
|
current.set("compare", "true");
|
|
2301
2386
|
}
|
|
2302
|
-
current.set("mode", mode);
|
|
2387
|
+
current.set("mode", workspaceShowsModeControls ? mode : "edit");
|
|
2303
2388
|
// Handle fullscreen parameter
|
|
2304
2389
|
if (fullscreen) {
|
|
2305
2390
|
current.set("fullscreen", "true");
|
|
@@ -3004,9 +3089,35 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
3004
3089
|
};
|
|
3005
3090
|
}, [promptSessionReconnect]);
|
|
3006
3091
|
const sendSocketMessage = useCallback((message) => {
|
|
3092
|
+
if (message.type === "caret-position" &&
|
|
3093
|
+
message.payload?.source === "form-field") {
|
|
3094
|
+
const payload = message.payload;
|
|
3095
|
+
setRemoteCarets((current) => {
|
|
3096
|
+
if (payload.offset == null) {
|
|
3097
|
+
if (!current[sessionId])
|
|
3098
|
+
return current;
|
|
3099
|
+
const next = { ...current };
|
|
3100
|
+
delete next[sessionId];
|
|
3101
|
+
return next;
|
|
3102
|
+
}
|
|
3103
|
+
if (!payload.fieldId || !payload.item) {
|
|
3104
|
+
return current;
|
|
3105
|
+
}
|
|
3106
|
+
return {
|
|
3107
|
+
...current,
|
|
3108
|
+
[sessionId]: {
|
|
3109
|
+
sessionId,
|
|
3110
|
+
fieldId: payload.fieldId,
|
|
3111
|
+
item: payload.item,
|
|
3112
|
+
offset: payload.offset,
|
|
3113
|
+
value: payload.value,
|
|
3114
|
+
},
|
|
3115
|
+
};
|
|
3116
|
+
});
|
|
3117
|
+
}
|
|
3007
3118
|
// Routes over whichever transport is active (WebSocket preferred, SSE fallback).
|
|
3008
3119
|
getEditorRealtime().send(message);
|
|
3009
|
-
}, []);
|
|
3120
|
+
}, [sessionId]);
|
|
3010
3121
|
// URL update helper - defined early so it can be used by workspace/sidebar functions
|
|
3011
3122
|
const updateUrl = useCallback((params) => {
|
|
3012
3123
|
// Use the actual browser pathname (including any basePath like /parhelia)
|
|
@@ -3484,34 +3595,51 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
3484
3595
|
operationsContext.context.markOperationComplete;
|
|
3485
3596
|
}, [operationsContext.context.markOperationComplete]);
|
|
3486
3597
|
// Replace selected text with new content (for inline AI editing)
|
|
3487
|
-
const replaceSelectedText = useCallback(async (newText) => {
|
|
3488
|
-
|
|
3489
|
-
return;
|
|
3598
|
+
const replaceSelectedText = useCallback(async (newText, selectionOverride) => {
|
|
3599
|
+
const rangeToReplace = selectionOverride ?? selectedRange ?? lastTextSelectionRangeRef.current;
|
|
3490
3600
|
try {
|
|
3491
3601
|
// If we have selected text and a replaceText callback, use it
|
|
3492
|
-
if (
|
|
3493
|
-
|
|
3602
|
+
if (rangeToReplace?.text && rangeToReplace.replaceText) {
|
|
3603
|
+
rangeToReplace.replaceText(newText);
|
|
3494
3604
|
setSelectedRange(undefined);
|
|
3605
|
+
lastTextSelectionRangeRef.current = undefined;
|
|
3495
3606
|
return;
|
|
3496
3607
|
}
|
|
3497
3608
|
// If no selection but we have a replaceText callback, try to use it for insertion
|
|
3498
3609
|
// (some editors might support insertion via the same callback)
|
|
3499
|
-
if (!
|
|
3500
|
-
|
|
3610
|
+
if (!rangeToReplace?.text && rangeToReplace?.replaceText) {
|
|
3611
|
+
rangeToReplace.replaceText(newText);
|
|
3501
3612
|
setSelectedRange(undefined);
|
|
3613
|
+
lastTextSelectionRangeRef.current = undefined;
|
|
3502
3614
|
return;
|
|
3503
3615
|
}
|
|
3616
|
+
const fieldToReplace = focusedField ??
|
|
3617
|
+
(rangeToReplace?.fieldId &&
|
|
3618
|
+
rangeToReplace.itemId &&
|
|
3619
|
+
rangeToReplace.language &&
|
|
3620
|
+
typeof rangeToReplace.version === "number"
|
|
3621
|
+
? {
|
|
3622
|
+
fieldId: rangeToReplace.fieldId,
|
|
3623
|
+
item: {
|
|
3624
|
+
id: rangeToReplace.itemId,
|
|
3625
|
+
language: rangeToReplace.language,
|
|
3626
|
+
version: rangeToReplace.version,
|
|
3627
|
+
},
|
|
3628
|
+
}
|
|
3629
|
+
: undefined);
|
|
3630
|
+
if (!fieldToReplace)
|
|
3631
|
+
return;
|
|
3504
3632
|
// Fallback: indexOf-based replacement/insertion for plain text fields
|
|
3505
|
-
const { fieldId, item } =
|
|
3633
|
+
const { fieldId, item } = fieldToReplace;
|
|
3506
3634
|
const modifiedField = getActiveSlotContext()?.fieldModificationStore.getField(fieldId, item.id, item.language, item.version);
|
|
3507
3635
|
const currentValue = modifiedField
|
|
3508
3636
|
? modifiedField.value || ""
|
|
3509
|
-
: (await itemsRepository.getField(
|
|
3510
|
-
"";
|
|
3637
|
+
: (await itemsRepository.getField(fieldToReplace))
|
|
3638
|
+
?.value || "";
|
|
3511
3639
|
let newValue;
|
|
3512
|
-
if (
|
|
3640
|
+
if (rangeToReplace?.text) {
|
|
3513
3641
|
// Replace selected text
|
|
3514
|
-
const { text: originalSelectedText } =
|
|
3642
|
+
const { text: originalSelectedText } = rangeToReplace;
|
|
3515
3643
|
const actualPosition = currentValue.indexOf(originalSelectedText);
|
|
3516
3644
|
if (actualPosition === -1) {
|
|
3517
3645
|
console.error("Failed to find selected text in field value");
|
|
@@ -3524,7 +3652,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
3524
3652
|
}
|
|
3525
3653
|
else {
|
|
3526
3654
|
// Insert at cursor position (use startOffset if available, otherwise append)
|
|
3527
|
-
const insertPosition =
|
|
3655
|
+
const insertPosition = rangeToReplace?.startOffset ?? currentValue.length;
|
|
3528
3656
|
newValue =
|
|
3529
3657
|
currentValue.slice(0, insertPosition) +
|
|
3530
3658
|
newText +
|
|
@@ -3532,12 +3660,13 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
3532
3660
|
}
|
|
3533
3661
|
// Update the field
|
|
3534
3662
|
await operations.editField({
|
|
3535
|
-
field:
|
|
3663
|
+
field: fieldToReplace,
|
|
3536
3664
|
value: newValue,
|
|
3537
3665
|
refresh: "immediate",
|
|
3538
3666
|
});
|
|
3539
3667
|
// Clear the selection after replacement/insertion
|
|
3540
3668
|
setSelectedRange(undefined);
|
|
3669
|
+
lastTextSelectionRangeRef.current = undefined;
|
|
3541
3670
|
}
|
|
3542
3671
|
catch (error) {
|
|
3543
3672
|
console.error("Failed to replace/insert text:", error);
|
|
@@ -4014,18 +4143,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
4014
4143
|
};
|
|
4015
4144
|
}
|
|
4016
4145
|
}, [operations.onFieldBlur]);
|
|
4017
|
-
useEffect(() => {
|
|
4018
|
-
if (mode === "suggestions") {
|
|
4019
|
-
setShowSuggestedEdits(true);
|
|
4020
|
-
// Refresh from the server to recover from any missed
|
|
4021
|
-
// `suggested-edit-updated` WebSocket events (e.g. created by an
|
|
4022
|
-
// agent tool while another tab was focused).
|
|
4023
|
-
loadSuggestedEdits();
|
|
4024
|
-
}
|
|
4025
|
-
else {
|
|
4026
|
-
setShowSuggestedEdits(false);
|
|
4027
|
-
}
|
|
4028
|
-
}, [mode, loadSuggestedEdits]);
|
|
4029
4146
|
const isReadOnly = !item ||
|
|
4030
4147
|
!item.canWriteItem ||
|
|
4031
4148
|
!item.canWriteLanguage ||
|
|
@@ -4044,15 +4161,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
4044
4161
|
// Otherwise, only show workspaces that are in the settings
|
|
4045
4162
|
return workspaceIdsFromSettings.includes(w.id) && !w.visible;
|
|
4046
4163
|
});
|
|
4047
|
-
// Handle initial mode setup from URL (only on initial load)
|
|
4048
|
-
useEffect(() => {
|
|
4049
|
-
if (!isInitialLoad)
|
|
4050
|
-
return;
|
|
4051
|
-
const queryMode = searchParams.get("mode");
|
|
4052
|
-
if (queryMode) {
|
|
4053
|
-
setMode(queryMode);
|
|
4054
|
-
}
|
|
4055
|
-
}, [searchParams, isInitialLoad]);
|
|
4056
4164
|
// Add this new effect for initial fullscreen setup
|
|
4057
4165
|
useEffect(() => {
|
|
4058
4166
|
if (!isInitialLoad)
|
|
@@ -4180,16 +4288,11 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
4180
4288
|
dragEnd: () => {
|
|
4181
4289
|
setDragObject(undefined);
|
|
4182
4290
|
},
|
|
4183
|
-
droppedInPlaceholder: async (placeholderKey, index, spotPositionElement, spotPositionAnchor, insertOption) => {
|
|
4184
|
-
|
|
4291
|
+
droppedInPlaceholder: async (placeholderKey, index, spotPositionElement, spotPositionAnchor, insertOption, spotPosition) => {
|
|
4292
|
+
const droppedDragObject = dragObject;
|
|
4293
|
+
if ((!droppedDragObject && !insertOption) || !page)
|
|
4185
4294
|
return;
|
|
4186
4295
|
setDragObject(undefined);
|
|
4187
|
-
if (spotPositionElement && spotPositionAnchor) {
|
|
4188
|
-
setInserting({
|
|
4189
|
-
positionElement: spotPositionElement,
|
|
4190
|
-
positionAnchor: spotPositionAnchor,
|
|
4191
|
-
});
|
|
4192
|
-
}
|
|
4193
4296
|
const placeholderKeyComponents = placeholderKey.split("_");
|
|
4194
4297
|
const parentId = placeholderKeyComponents.length === 1
|
|
4195
4298
|
? undefined
|
|
@@ -4199,39 +4302,31 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
4199
4302
|
let op;
|
|
4200
4303
|
if (!currentItemDescriptorRef.current)
|
|
4201
4304
|
return;
|
|
4305
|
+
let insertionSequence;
|
|
4306
|
+
if ((spotPosition || spotPositionElement) && spotPositionAnchor) {
|
|
4307
|
+
insertionSequence = ++insertingSequenceRef.current;
|
|
4308
|
+
setInserting({
|
|
4309
|
+
position: spotPosition,
|
|
4310
|
+
positionElement: spotPositionElement,
|
|
4311
|
+
positionAnchor: spotPositionAnchor,
|
|
4312
|
+
});
|
|
4313
|
+
}
|
|
4314
|
+
let operationPromise;
|
|
4202
4315
|
if (insertOption) {
|
|
4203
4316
|
// Clear any selected component type for insertion once the component
|
|
4204
4317
|
// has been dropped into a placeholder. This ensures that insert mode
|
|
4205
4318
|
// can exit cleanly and the editor header updates from "Add Component"
|
|
4206
4319
|
// to the actual component name after the operation completes.
|
|
4207
4320
|
setSelectedForInsertion("");
|
|
4208
|
-
operations
|
|
4209
|
-
.addComponent(insertOption.typeId, placeholderKey, index, currentItemDescriptorRef.current)
|
|
4210
|
-
.then((result) => {
|
|
4211
|
-
setInserting(undefined);
|
|
4212
|
-
})
|
|
4213
|
-
.catch((err) => {
|
|
4214
|
-
setInserting(undefined);
|
|
4215
|
-
});
|
|
4216
|
-
return;
|
|
4321
|
+
operationPromise = operations.addComponent(insertOption.typeId, placeholderKey, index, currentItemDescriptorRef.current);
|
|
4217
4322
|
}
|
|
4218
|
-
if (
|
|
4219
|
-
|
|
4220
|
-
if (dragObject && dragObject.type == "template") {
|
|
4221
|
-
operations
|
|
4222
|
-
.addComponent(dragObject.typeId, placeholderKey, index, currentItemDescriptorRef.current)
|
|
4223
|
-
.then((result) => {
|
|
4224
|
-
setInserting(undefined);
|
|
4225
|
-
})
|
|
4226
|
-
.catch((err) => {
|
|
4227
|
-
setInserting(undefined);
|
|
4228
|
-
});
|
|
4229
|
-
return;
|
|
4323
|
+
else if (droppedDragObject?.type == "template") {
|
|
4324
|
+
operationPromise = operations.addComponent(droppedDragObject.typeId, placeholderKey, index, currentItemDescriptorRef.current);
|
|
4230
4325
|
}
|
|
4231
|
-
if (
|
|
4232
|
-
(
|
|
4326
|
+
else if (droppedDragObject?.type == "component" ||
|
|
4327
|
+
(droppedDragObject?.type == "items" && droppedDragObject.items)) {
|
|
4233
4328
|
const parentComponent = parentId && page ? getComponentById(parentId, page) : null;
|
|
4234
|
-
if (
|
|
4329
|
+
if (droppedDragObject.type == "items" && droppedDragObject.items) {
|
|
4235
4330
|
op = {
|
|
4236
4331
|
type: "link-component",
|
|
4237
4332
|
mainItem: page.item.descriptor,
|
|
@@ -4245,33 +4340,52 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
4245
4340
|
placeholderIndex: index,
|
|
4246
4341
|
date: new Date().toISOString(),
|
|
4247
4342
|
id: uuid(),
|
|
4248
|
-
linkedComponentItem:
|
|
4343
|
+
linkedComponentItem: droppedDragObject.items[0],
|
|
4249
4344
|
title: "Link component",
|
|
4250
4345
|
};
|
|
4251
4346
|
}
|
|
4252
4347
|
else {
|
|
4253
|
-
const componentIds =
|
|
4254
|
-
if (componentIds.length
|
|
4255
|
-
|
|
4256
|
-
|
|
4257
|
-
|
|
4258
|
-
|
|
4259
|
-
|
|
4260
|
-
|
|
4261
|
-
|
|
4262
|
-
|
|
4263
|
-
|
|
4264
|
-
|
|
4265
|
-
|
|
4266
|
-
|
|
4267
|
-
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
}
|
|
4348
|
+
const componentIds = droppedDragObject.components?.map((c) => c.id) ?? [];
|
|
4349
|
+
if (componentIds.length > 0) {
|
|
4350
|
+
op = {
|
|
4351
|
+
type: "move-component",
|
|
4352
|
+
mainItem: page.item.descriptor,
|
|
4353
|
+
parent: parentId && {
|
|
4354
|
+
id: parentId,
|
|
4355
|
+
language: page.item.descriptor.language,
|
|
4356
|
+
version: page.item.descriptor.version,
|
|
4357
|
+
},
|
|
4358
|
+
placeholderKey,
|
|
4359
|
+
placeholderIndex: index,
|
|
4360
|
+
componentIds,
|
|
4361
|
+
date: new Date().toISOString(),
|
|
4362
|
+
id: uuid(),
|
|
4363
|
+
title: "Move component",
|
|
4364
|
+
};
|
|
4365
|
+
}
|
|
4271
4366
|
}
|
|
4272
4367
|
}
|
|
4273
4368
|
if (op)
|
|
4274
|
-
operations.executeEditOperation(op);
|
|
4369
|
+
operationPromise = operations.executeEditOperation(op);
|
|
4370
|
+
if (!operationPromise) {
|
|
4371
|
+
if (insertionSequence !== undefined &&
|
|
4372
|
+
insertingSequenceRef.current === insertionSequence) {
|
|
4373
|
+
setInserting(undefined);
|
|
4374
|
+
}
|
|
4375
|
+
return;
|
|
4376
|
+
}
|
|
4377
|
+
try {
|
|
4378
|
+
await operationPromise;
|
|
4379
|
+
}
|
|
4380
|
+
catch (err) {
|
|
4381
|
+
console.error("Failed to drop component in placeholder", err);
|
|
4382
|
+
}
|
|
4383
|
+
finally {
|
|
4384
|
+
if (insertionSequence !== undefined &&
|
|
4385
|
+
insertingSequenceRef.current === insertionSequence) {
|
|
4386
|
+
setInserting(undefined);
|
|
4387
|
+
}
|
|
4388
|
+
}
|
|
4275
4389
|
},
|
|
4276
4390
|
page,
|
|
4277
4391
|
triggerFieldAction: async (fieldDescriptor, actionButton, parameters, event) => {
|
|
@@ -4550,27 +4664,50 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
4550
4664
|
setShowComments,
|
|
4551
4665
|
showResolvedComments,
|
|
4552
4666
|
setShowResolvedComments,
|
|
4553
|
-
addComment: async () => {
|
|
4667
|
+
addComment: async (options) => {
|
|
4554
4668
|
const descriptor = item?.descriptor;
|
|
4555
4669
|
if (!descriptor)
|
|
4556
4670
|
return;
|
|
4557
4671
|
// Snapshot selection context up-front so switching views doesn't change what we comment on.
|
|
4672
|
+
const hintedFieldSnapshot = options?.field;
|
|
4558
4673
|
const focusedFieldSnapshot = focusedFieldRef.current;
|
|
4559
|
-
const
|
|
4560
|
-
|
|
4561
|
-
|
|
4562
|
-
|
|
4674
|
+
const selectedRangeCandidate = isUsableTextSelectionRange(selectedRange)
|
|
4675
|
+
? selectedRange
|
|
4676
|
+
: lastTextSelectionRangeRef.current;
|
|
4677
|
+
const selectedRangeSnapshot = !hintedFieldSnapshot ||
|
|
4678
|
+
selectionRangeMatchesField(selectedRangeCandidate, hintedFieldSnapshot)
|
|
4679
|
+
? selectedRangeCandidate
|
|
4680
|
+
: undefined;
|
|
4681
|
+
const selectedRangeFieldSnapshot = isUsableTextSelectionRange(selectedRangeSnapshot)
|
|
4682
|
+
? {
|
|
4683
|
+
fieldId: selectedRangeSnapshot.fieldId,
|
|
4684
|
+
item: {
|
|
4685
|
+
id: selectedRangeSnapshot.itemId,
|
|
4686
|
+
language: selectedRangeSnapshot.language || descriptor.language,
|
|
4687
|
+
version: typeof selectedRangeSnapshot.version === "number"
|
|
4688
|
+
? selectedRangeSnapshot.version
|
|
4689
|
+
: descriptor.version,
|
|
4690
|
+
},
|
|
4691
|
+
}
|
|
4692
|
+
: undefined;
|
|
4693
|
+
const commentFieldSnapshot = selectedRangeFieldSnapshot ??
|
|
4694
|
+
hintedFieldSnapshot ??
|
|
4695
|
+
focusedFieldSnapshot;
|
|
4696
|
+
const itemId = commentFieldSnapshot?.item.id ||
|
|
4697
|
+
(selection.length > 0 ? selection[0] : undefined) ||
|
|
4563
4698
|
descriptor.id;
|
|
4564
4699
|
if (!itemId)
|
|
4565
4700
|
return;
|
|
4566
4701
|
// Ensure the feedback sidebar is open when adding a comment (e.g. command palette / toolbar button).
|
|
4567
4702
|
openSidebar("feedback");
|
|
4568
|
-
const language = descriptor.language;
|
|
4569
|
-
const version =
|
|
4703
|
+
const language = commentFieldSnapshot?.item.language || descriptor.language;
|
|
4704
|
+
const version = typeof commentFieldSnapshot?.item.version === "number"
|
|
4705
|
+
? commentFieldSnapshot.item.version
|
|
4706
|
+
: descriptor.version;
|
|
4570
4707
|
const getFieldName = async () => {
|
|
4571
|
-
if (!
|
|
4708
|
+
if (!commentFieldSnapshot)
|
|
4572
4709
|
return "";
|
|
4573
|
-
const field = await itemsRepository.getField(
|
|
4710
|
+
const field = await itemsRepository.getField(commentFieldSnapshot);
|
|
4574
4711
|
return field?.name;
|
|
4575
4712
|
};
|
|
4576
4713
|
const getItemName = async () => {
|
|
@@ -4586,24 +4723,40 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
4586
4723
|
isNew: true,
|
|
4587
4724
|
itemId,
|
|
4588
4725
|
itemName: await getItemName(),
|
|
4589
|
-
fieldId:
|
|
4726
|
+
fieldId: commentFieldSnapshot?.fieldId,
|
|
4590
4727
|
fieldName: await getFieldName(),
|
|
4591
4728
|
mainItemId: descriptor.id,
|
|
4592
4729
|
language,
|
|
4593
4730
|
version,
|
|
4594
4731
|
position: 0,
|
|
4595
|
-
rangeStart: selectedRangeSnapshot
|
|
4596
|
-
|
|
4732
|
+
rangeStart: isUsableTextSelectionRange(selectedRangeSnapshot)
|
|
4733
|
+
? selectedRangeSnapshot.startOffset
|
|
4734
|
+
: 0,
|
|
4735
|
+
rangeEnd: isUsableTextSelectionRange(selectedRangeSnapshot)
|
|
4736
|
+
? selectedRangeSnapshot.endOffset
|
|
4737
|
+
: 0,
|
|
4597
4738
|
author: user?.name,
|
|
4598
4739
|
authorDisplayName: user?.fullName,
|
|
4599
|
-
|
|
4740
|
+
created: new Date().toISOString(),
|
|
4600
4741
|
};
|
|
4742
|
+
if (selectedRangeSnapshot?.clientRect) {
|
|
4743
|
+
newComment[COMMENT_TRANSIENT_SELECTION_RECT] =
|
|
4744
|
+
selectedRangeSnapshot.clientRect;
|
|
4745
|
+
}
|
|
4746
|
+
if (selectedRangeSnapshot?.elementKey) {
|
|
4747
|
+
newComment[COMMENT_TRANSIENT_ELEMENT_KEY] =
|
|
4748
|
+
selectedRangeSnapshot.elementKey;
|
|
4749
|
+
}
|
|
4601
4750
|
setComments([newComment, ...comments]);
|
|
4602
4751
|
setSelectedComment(newComment);
|
|
4603
4752
|
setShowComments(true);
|
|
4753
|
+
lastTextSelectionRangeRef.current = undefined;
|
|
4604
4754
|
},
|
|
4605
4755
|
mode,
|
|
4756
|
+
changeMode,
|
|
4606
4757
|
setMode,
|
|
4758
|
+
registerModeChangeParticipant,
|
|
4759
|
+
modeTransitionRevision,
|
|
4607
4760
|
previewDate,
|
|
4608
4761
|
setPreviewDate,
|
|
4609
4762
|
layoutMode,
|
|
@@ -4671,6 +4824,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
4671
4824
|
setCurrentWizardId,
|
|
4672
4825
|
favorites,
|
|
4673
4826
|
loadFavorites,
|
|
4827
|
+
refreshFavorites,
|
|
4674
4828
|
isQuickSwitcherVisible: quickSwitcherVisible,
|
|
4675
4829
|
// Context factory registry methods
|
|
4676
4830
|
registerContextFactory: (name, factory) => {
|
|
@@ -4779,6 +4933,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
4779
4933
|
isRefreshing,
|
|
4780
4934
|
favorites,
|
|
4781
4935
|
loadFavorites,
|
|
4936
|
+
refreshFavorites,
|
|
4782
4937
|
currentWizardId,
|
|
4783
4938
|
quickSwitcherVisible,
|
|
4784
4939
|
quickSwitcherSelectedIndex,
|
|
@@ -4789,6 +4944,10 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
4789
4944
|
factoriesRef,
|
|
4790
4945
|
user,
|
|
4791
4946
|
statusMessage,
|
|
4947
|
+
changeMode,
|
|
4948
|
+
setMode,
|
|
4949
|
+
registerModeChangeParticipant,
|
|
4950
|
+
modeTransitionRevision,
|
|
4792
4951
|
previewDate,
|
|
4793
4952
|
layoutMode,
|
|
4794
4953
|
enableCompletions,
|
|
@@ -4854,8 +5013,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
4854
5013
|
setLockedField(undefined); // Clear client-side lock state
|
|
4855
5014
|
await releaseFieldLocks(sessionId);
|
|
4856
5015
|
},
|
|
4857
|
-
inlineEditingFieldElement,
|
|
4858
|
-
setInlineEditingFieldElement,
|
|
4859
5016
|
};
|
|
4860
5017
|
// Debug: Track editContext changes
|
|
4861
5018
|
// const prevDependencies = useRef<any[]>([]);
|
|
@@ -4894,7 +5051,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
4894
5051
|
// componentDesignerRendering,
|
|
4895
5052
|
// insertMode,
|
|
4896
5053
|
// currentOverlay,
|
|
4897
|
-
// inlineEditingFieldElement,
|
|
4898
5054
|
// lockedField,
|
|
4899
5055
|
// selectedRange,
|
|
4900
5056
|
// pageViewContext,
|
|
@@ -4982,7 +5138,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
4982
5138
|
// 'componentDesignerRendering',
|
|
4983
5139
|
// 'insertMode',
|
|
4984
5140
|
// 'currentOverlay',
|
|
4985
|
-
// 'inlineEditingFieldElement',
|
|
4986
5141
|
// 'lockedField',
|
|
4987
5142
|
// 'selectedRange',
|
|
4988
5143
|
// 'pageViewContext',
|
|
@@ -5110,7 +5265,8 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
5110
5265
|
: window.location.pathname;
|
|
5111
5266
|
window.history.replaceState(getCurrentHistoryState(), "", newUrl);
|
|
5112
5267
|
}, configuration: configuration, restoredFromUrl: tourRestoredRef.current })), _jsx(FeatureGate, { feature: LicenseFeatures.AI, children: _jsx(GuidanceOverlay, {}) }), _jsx(FeatureGate, { feature: LicenseFeatures.AI, children: _jsx(AgentDialogHandler, {}) })] }));
|
|
5113
|
-
|
|
5268
|
+
const showRefreshSpinner = editContext.isRefreshing && !activePageViewContext.iframeSupportsRefresh;
|
|
5269
|
+
return (_jsx(LicenseProvider, { initialLicenseStatus: initialLicenseStatus, initialStatusLoaded: initialLicenseStatusLoaded, children: _jsx("div", { className: `editor h-full w-full`, children: _jsx(OperationsContextProvider, { value: operationsContext.context, children: _jsx(FieldsEditContextProvider, { value: fieldsEditContext, children: _jsx(EditContextProvider, { value: editContext, children: _jsxs(SplashScreenAgentProvider, { children: [_jsx(DevModeIndicator, {}), startupChecks.state === "loading" && _jsx(EditorLoadingOverlay, {}), showRefreshSpinner && (_jsx("div", { className: "text-neutral-grey-50 pointer-events-none fixed right-0 bottom-0 flex h-24 w-24 items-center justify-center opacity-50 select-none", children: _jsx(Spinner, {}) })), (currentWorkspace.id === "agents" ||
|
|
5114
5270
|
currentWorkspace.id === "taskboard" ||
|
|
5115
5271
|
currentWorkspace.id === "translation-management") &&
|
|
5116
5272
|
showAgentsWorkspaceEditor && (_jsx(AgentsSlotContextBridgeHost, { slots: editorSlots })), startupChecks.state !== "loading" && (children || editorUi), startupChecks.state !== "loading" && dialog, _jsx(Toaster, { position: "top-center" }), " ", _jsx(ConfirmationDialog, { ref: confirmationDialogRef }), _jsx(ConcurrentUserLimitDialog, { open: concurrentUserLimitError !== null, onOpenChange: (open) => {
|