@parhelia/core 0.1.12927 → 0.1.12931
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.js +4 -1
- package/dist/agents-view/AgentCard.js.map +1 -1
- package/dist/agents-view/AgentProfileIcon.js +8 -8
- package/dist/agents-view/AgentProfileIcon.js.map +1 -1
- package/dist/agents-view/AgentsView.js +1 -1
- package/dist/client-components/index.d.ts +1 -1
- package/dist/client-components/index.js +1 -1
- package/dist/client-components/index.js.map +1 -1
- package/dist/components/WorkspaceHomeView.d.ts +13 -0
- package/dist/components/WorkspaceHomeView.js +13 -0
- package/dist/components/WorkspaceHomeView.js.map +1 -0
- package/dist/components/ui/styled-dialog-title.d.ts +3 -1
- package/dist/components/ui/styled-dialog-title.js +2 -2
- package/dist/components/ui/styled-dialog-title.js.map +1 -1
- package/dist/config/config.js +7 -19
- package/dist/config/config.js.map +1 -1
- package/dist/config/notificationRoutes.js +1 -1
- package/dist/config/notificationRoutes.js.map +1 -1
- package/dist/editor/ConfirmationDialog.js +1 -1
- package/dist/editor/ConfirmationDialog.js.map +1 -1
- package/dist/editor/FieldListField.js +8 -0
- package/dist/editor/FieldListField.js.map +1 -1
- package/dist/editor/ImageEditButton.js +14 -2
- package/dist/editor/ImageEditButton.js.map +1 -1
- package/dist/editor/ImageEditor.js +1 -1
- package/dist/editor/ImageEditor.js.map +1 -1
- package/dist/editor/MainLayout.js +2 -1
- package/dist/editor/MainLayout.js.map +1 -1
- package/dist/editor/PerfProfiler.d.ts +11 -0
- package/dist/editor/PerfProfiler.js +29 -0
- package/dist/editor/PerfProfiler.js.map +1 -0
- package/dist/editor/PictureEditor.js +1 -1
- package/dist/editor/PictureEditor.js.map +1 -1
- package/dist/editor/ai/Agents.js +15 -79
- package/dist/editor/ai/Agents.js.map +1 -1
- package/dist/editor/ai/GuidanceOverlay.js +4 -9
- package/dist/editor/ai/GuidanceOverlay.js.map +1 -1
- package/dist/editor/ai/InlineAiDialog.js +2 -2
- package/dist/editor/ai/InlineAiDialog.js.map +1 -1
- package/dist/editor/ai/dialogs/capturePageScreenshot.js +1 -1
- package/dist/editor/ai/dialogs/capturePageScreenshot.js.map +1 -1
- package/dist/editor/ai/terminal/components/AgentMemoryPanel.d.ts +12 -0
- package/dist/editor/ai/terminal/components/AgentMemoryPanel.js +131 -0
- package/dist/editor/ai/terminal/components/AgentMemoryPanel.js.map +1 -0
- package/dist/editor/ai/terminal/components/AgentPromptTrayPopovers.js +10 -2
- package/dist/editor/ai/terminal/components/AgentPromptTrayPopovers.js.map +1 -1
- package/dist/editor/ai/terminal/components/AgentSettingsContent.d.ts +2 -1
- package/dist/editor/ai/terminal/components/AgentSettingsContent.js.map +1 -1
- package/dist/editor/ai/terminal/components/AgentSettingsSections.d.ts +2 -1
- package/dist/editor/ai/terminal/components/AgentSettingsSections.js +9 -2
- package/dist/editor/ai/terminal/components/AgentSettingsSections.js.map +1 -1
- package/dist/editor/ai/terminal/components/AgentTerminalContextPanels.js +11 -0
- package/dist/editor/ai/terminal/components/AgentTerminalContextPanels.js.map +1 -1
- package/dist/editor/ai/terminal/components/AgentTerminalStatusBar.js +27 -20
- package/dist/editor/ai/terminal/components/AgentTerminalStatusBar.js.map +1 -1
- package/dist/editor/ai/terminal/components/ContextInfoBar.js +4 -3
- package/dist/editor/ai/terminal/components/ContextInfoBar.js.map +1 -1
- package/dist/editor/ai/terminal/useAgentSettingsData.d.ts +8 -1
- package/dist/editor/ai/terminal/useAgentSettingsData.js +44 -5
- package/dist/editor/ai/terminal/useAgentSettingsData.js.map +1 -1
- package/dist/editor/ai/terminal/useAgentSettingsPanel.d.ts +1 -1
- package/dist/editor/bridge/BridgeClient.js +9 -1
- package/dist/editor/bridge/BridgeClient.js.map +1 -1
- package/dist/editor/bridge/protocol.d.ts +19 -0
- package/dist/editor/bridge/protocol.js +1 -1
- package/dist/editor/bridge/protocol.js.map +1 -1
- package/dist/editor/client/EditorShell.js +163 -67
- package/dist/editor/client/EditorShell.js.map +1 -1
- package/dist/editor/client/editContext.d.ts +35 -2
- package/dist/editor/client/editContext.js +8 -0
- package/dist/editor/client/editContext.js.map +1 -1
- package/dist/editor/client/fieldModificationStore.js +64 -0
- package/dist/editor/client/fieldModificationStore.js.map +1 -1
- package/dist/editor/client/itemsRepository.js +95 -3
- package/dist/editor/client/itemsRepository.js.map +1 -1
- package/dist/editor/client/operations.d.ts +1 -0
- package/dist/editor/client/operations.js +166 -13
- package/dist/editor/client/operations.js.map +1 -1
- package/dist/editor/client/ui/EditorChrome.js +6 -5
- package/dist/editor/client/ui/EditorChrome.js.map +1 -1
- package/dist/editor/commands/componentCommands.js +2 -1
- package/dist/editor/commands/componentCommands.js.map +1 -1
- package/dist/editor/commands/keyboardCommands.js +1 -1
- package/dist/editor/commands/keyboardCommands.js.map +1 -1
- package/dist/editor/componentTreeHelper.js +15 -5
- package/dist/editor/componentTreeHelper.js.map +1 -1
- package/dist/editor/context-menu/InsertMenu.js +1 -1
- package/dist/editor/context-menu/InsertMenu.js.map +1 -1
- package/dist/editor/field-types/SingleLineText.js +79 -9
- package/dist/editor/field-types/SingleLineText.js.map +1 -1
- package/dist/editor/fieldValueDiagnostics.d.ts +79 -0
- package/dist/editor/fieldValueDiagnostics.js +133 -0
- package/dist/editor/fieldValueDiagnostics.js.map +1 -0
- package/dist/editor/menubar/PageSelector.js +1 -1
- package/dist/editor/menubar/PageSelector.js.map +1 -1
- package/dist/editor/menubar/toolbar-sections/EditControls.js +1 -2
- package/dist/editor/menubar/toolbar-sections/EditControls.js.map +1 -1
- package/dist/editor/menubar/toolbar-sections/ManualBrowser.js +6 -0
- package/dist/editor/menubar/toolbar-sections/ManualBrowser.js.map +1 -1
- package/dist/editor/menubar/toolbar-sections/UtilityControls.js +5 -5
- package/dist/editor/menubar/toolbar-sections/UtilityControls.js.map +1 -1
- package/dist/editor/page-editor-chrome/DragInsertionOverlay.d.ts +8 -1
- package/dist/editor/page-editor-chrome/DragInsertionOverlay.js +203 -51
- package/dist/editor/page-editor-chrome/DragInsertionOverlay.js.map +1 -1
- package/dist/editor/page-editor-chrome/EmptyImageFieldIndicators.d.ts +10 -0
- package/dist/editor/page-editor-chrome/EmptyImageFieldIndicators.js +236 -0
- package/dist/editor/page-editor-chrome/EmptyImageFieldIndicators.js.map +1 -0
- package/dist/editor/page-editor-chrome/FrameMenu.d.ts +2 -0
- package/dist/editor/page-editor-chrome/FrameMenu.js +8 -6
- package/dist/editor/page-editor-chrome/FrameMenu.js.map +1 -1
- package/dist/editor/page-editor-chrome/FrameMenus.d.ts +3 -1
- package/dist/editor/page-editor-chrome/FrameMenus.js +4 -4
- package/dist/editor/page-editor-chrome/FrameMenus.js.map +1 -1
- package/dist/editor/page-editor-chrome/PageEditorChrome.js +18 -4
- package/dist/editor/page-editor-chrome/PageEditorChrome.js.map +1 -1
- package/dist/editor/page-editor-chrome/PictureEditorOverlay.d.ts +3 -0
- package/dist/editor/page-editor-chrome/PictureEditorOverlay.js +5 -8
- package/dist/editor/page-editor-chrome/PictureEditorOverlay.js.map +1 -1
- package/dist/editor/page-editor-chrome/PlaceholderDropZone.d.ts +8 -1
- package/dist/editor/page-editor-chrome/PlaceholderDropZone.js +20 -5
- package/dist/editor/page-editor-chrome/PlaceholderDropZone.js.map +1 -1
- package/dist/editor/page-editor-chrome/PlaceholderDropZones.d.ts +3 -1
- package/dist/editor/page-editor-chrome/PlaceholderDropZones.js +2 -2
- package/dist/editor/page-editor-chrome/PlaceholderDropZones.js.map +1 -1
- package/dist/editor/page-editor-chrome/overlay/placeholderZones.d.ts +10 -0
- package/dist/editor/page-editor-chrome/overlay/placeholderZones.js +61 -1
- package/dist/editor/page-editor-chrome/overlay/placeholderZones.js.map +1 -1
- package/dist/editor/page-editor-chrome/useBridgeInlineEditing.js +121 -48
- package/dist/editor/page-editor-chrome/useBridgeInlineEditing.js.map +1 -1
- package/dist/editor/page-viewer/EditorForm.js +94 -7
- package/dist/editor/page-viewer/EditorForm.js.map +1 -1
- package/dist/editor/page-viewer/MiniMap.js +74 -9
- package/dist/editor/page-viewer/MiniMap.js.map +1 -1
- package/dist/editor/page-viewer/PageViewer.js +9 -7
- package/dist/editor/page-viewer/PageViewer.js.map +1 -1
- package/dist/editor/page-viewer/PageViewerFrame.js +390 -54
- package/dist/editor/page-viewer/PageViewerFrame.js.map +1 -1
- package/dist/editor/page-viewer/bridgeFieldPatch.js +49 -2
- package/dist/editor/page-viewer/bridgeFieldPatch.js.map +1 -1
- package/dist/editor/page-viewer/minimapVisibility.d.ts +33 -0
- package/dist/editor/page-viewer/minimapVisibility.js +72 -0
- package/dist/editor/page-viewer/minimapVisibility.js.map +1 -0
- package/dist/editor/page-viewer/pageViewContext.d.ts +1 -0
- package/dist/editor/page-viewer/pageViewContext.js +7 -0
- package/dist/editor/page-viewer/pageViewContext.js.map +1 -1
- package/dist/editor/page-viewer/renderUrl.js +29 -7
- package/dist/editor/page-viewer/renderUrl.js.map +1 -1
- package/dist/editor/perfTrace.d.ts +46 -0
- package/dist/editor/perfTrace.js +213 -0
- package/dist/editor/perfTrace.js.map +1 -0
- package/dist/editor/reviews/CommentPopover.js +2 -3
- package/dist/editor/reviews/CommentPopover.js.map +1 -1
- package/dist/editor/reviews/CreateReviewConfirmStep.js +5 -4
- package/dist/editor/reviews/CreateReviewConfirmStep.js.map +1 -1
- package/dist/editor/reviews/CreateReviewDialog.js +120 -202
- package/dist/editor/reviews/CreateReviewDialog.js.map +1 -1
- package/dist/editor/reviews/CreateReviewItemsStep.d.ts +18 -0
- package/dist/editor/reviews/CreateReviewItemsStep.js +6 -0
- package/dist/editor/reviews/CreateReviewItemsStep.js.map +1 -0
- package/dist/editor/reviews/CreateReviewLanguagesStep.d.ts +9 -0
- package/dist/editor/reviews/CreateReviewLanguagesStep.js +36 -0
- package/dist/editor/reviews/CreateReviewLanguagesStep.js.map +1 -0
- package/dist/editor/reviews/CreateReviewReviewersStep.d.ts +17 -0
- package/dist/editor/reviews/CreateReviewReviewersStep.js +33 -0
- package/dist/editor/reviews/CreateReviewReviewersStep.js.map +1 -0
- package/dist/editor/reviews/CreateReviewSettingsStep.d.ts +21 -0
- package/dist/editor/reviews/CreateReviewSettingsStep.js +33 -0
- package/dist/editor/reviews/CreateReviewSettingsStep.js.map +1 -0
- package/dist/editor/reviews/MultiReviewManager.js +1 -4
- package/dist/editor/reviews/MultiReviewManager.js.map +1 -1
- package/dist/editor/reviews/commentAi.js +1 -1
- package/dist/editor/reviews/commentAi.js.map +1 -1
- package/dist/editor/reviews/openCommentsFeedback.d.ts +2 -6
- package/dist/editor/reviews/openCommentsFeedback.js +3 -11
- package/dist/editor/reviews/openCommentsFeedback.js.map +1 -1
- package/dist/editor/services/agentService.d.ts +38 -0
- package/dist/editor/services/agentService.js +42 -0
- package/dist/editor/services/agentService.js.map +1 -1
- package/dist/editor/services/aiService.d.ts +4 -1
- package/dist/editor/services/aiService.js.map +1 -1
- package/dist/editor/services/editService.d.ts +1 -1
- package/dist/editor/services/editService.js +2 -2
- package/dist/editor/services/editService.js.map +1 -1
- package/dist/editor/services/reviewsService.d.ts +6 -0
- package/dist/editor/services/reviewsService.js +15 -0
- package/dist/editor/services/reviewsService.js.map +1 -1
- package/dist/editor/settings/panels/AgentProfileConfigPanel.js +2 -1
- package/dist/editor/settings/panels/AgentProfileConfigPanel.js.map +1 -1
- package/dist/editor/sidebar/ComponentTree.js +31 -10
- package/dist/editor/sidebar/ComponentTree.js.map +1 -1
- package/dist/editor/sidebar/ContentTreePanel.d.ts +2 -2
- package/dist/editor/sidebar/ContentTreePanel.js +6 -2
- package/dist/editor/sidebar/ContentTreePanel.js.map +1 -1
- package/dist/editor/sidebar/MainContentTree.js +3 -2
- package/dist/editor/sidebar/MainContentTree.js.map +1 -1
- package/dist/editor/tree-indicators/GutterColumns.js +24 -6
- package/dist/editor/tree-indicators/GutterColumns.js.map +1 -1
- package/dist/editor/ui/ItemCollectionEditor.js +4 -4
- package/dist/editor/ui/ItemCollectionEditor.js.map +1 -1
- package/dist/editor/ui/PerfectTree.js +5 -5
- package/dist/editor/ui/PerfectTree.js.map +1 -1
- package/dist/editor/ui/PublishItemDialog.js +1 -1
- package/dist/editor/ui/PublishItemDialog.js.map +1 -1
- package/dist/editor/ui/PublishRestrictionsDialog.js +179 -148
- package/dist/editor/ui/PublishRestrictionsDialog.js.map +1 -1
- package/dist/editor/utils/keyboardNavigation.js +9 -2
- package/dist/editor/utils/keyboardNavigation.js.map +1 -1
- package/dist/editor/views/SingleEditView.js +32 -2
- package/dist/editor/views/SingleEditView.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/revision.d.ts +2 -2
- package/dist/revision.js +2 -2
- package/dist/task-board/components/TaskBoardHomeView.js +3 -6
- package/dist/task-board/components/TaskBoardHomeView.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import React, { useState, useEffect, useRef, useCallback, useMemo, startTransition, } from "react";
|
|
3
|
+
import React, { useState, useEffect, useLayoutEffect, useRef, useCallback, useMemo, startTransition, } from "react";
|
|
4
4
|
import { toast } from "sonner";
|
|
5
|
-
import {
|
|
5
|
+
import { isPerfTraceActive, perfTracePaintStep, perfTraceStep, } from "../perfTrace";
|
|
6
|
+
import { EditContextProvider, FieldsEditContextProvider, OperationsContextProvider, SelectionContextProvider, useEditContext, } from "./editContext";
|
|
6
7
|
import { aggregateModifiedFieldsFromStores, areModifiedFieldSnapshotsEqual, FieldModificationStore, } from "./fieldModificationStore";
|
|
7
8
|
import { SplashScreenAgentProvider } from "../../splash-screen/SplashScreenAgentContext";
|
|
8
9
|
import { useRouter, useSearchParams, usePathname } from "./navigation";
|
|
9
10
|
import { findComponent, getComponentById } from "../componentTreeHelper";
|
|
10
11
|
import { getOperationsContext } from "./operations";
|
|
11
12
|
import { handleErrorResult } from "./helpers";
|
|
12
|
-
import { showExpandableErrorToast
|
|
13
|
+
import { showExpandableErrorToast } from "./errorToast";
|
|
13
14
|
import { isManualShowMeFocusTransfer, isManualShowMeTarget, } from "./manualShowMeFocus";
|
|
14
15
|
import { executeFieldAction as executeFieldServerAction, connectSocket, getEditHistory, getRunningOperations, reconnectSession, releaseFieldLocks, validateItems, } from "../services/editService";
|
|
15
16
|
import { emitAgentDocumentsChanged } from "../services/agentService";
|
|
@@ -37,6 +38,7 @@ import { post } from "../services/serviceHelper";
|
|
|
37
38
|
import { CONTENT_TREE_SIDEBAR_ID } from "../sidebar/contentTreeConstants";
|
|
38
39
|
import { PageViewerFrame } from "../page-viewer/PageViewerFrame";
|
|
39
40
|
import { useItemsRepository } from "./itemsRepository";
|
|
41
|
+
import { logFieldValueDiagnostic, summarizeFieldDescriptor, } from "../fieldValueDiagnostics";
|
|
40
42
|
import { Spinner } from "../ui/Spinner";
|
|
41
43
|
import { createSettleRegistry } from "../ui/animationSettle";
|
|
42
44
|
import { cleanId } from "../utils/id-helper";
|
|
@@ -47,7 +49,7 @@ import { Tour } from "../../tour/Tour";
|
|
|
47
49
|
import { GuidanceOverlay } from "../ai/GuidanceOverlay";
|
|
48
50
|
import { AgentDialogHandler } from "../ai/dialogs";
|
|
49
51
|
import { setActiveAgentConversation } from "../ai/useActiveAgentConversation";
|
|
50
|
-
import { usePageViewContext, } from "../page-viewer/pageViewContext";
|
|
52
|
+
import { CANVAS_REFRESH_COMPLETED_EVENT, usePageViewContext, } from "../page-viewer/pageViewContext";
|
|
51
53
|
import { QuickItemSwitcher } from "../QuickItemSwitcher";
|
|
52
54
|
import { useEditorSlotContext, } from "../views/editorSlotContext";
|
|
53
55
|
import { getComments, getAvailableCommentTags, } from "../services/reviewsService";
|
|
@@ -176,6 +178,10 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
176
178
|
const parheliaSettingsRefreshInFlightRef = useRef(null);
|
|
177
179
|
const minimapEnabledInSettings = effectiveParheliaSettings?.showMinimap !== false;
|
|
178
180
|
const [selection, setSelection] = useState([]);
|
|
181
|
+
// Current selection for event-time reads (select() early-bail, getSelection)
|
|
182
|
+
// without making callers depend on the reactive value.
|
|
183
|
+
const selectionRef = useRef(selection);
|
|
184
|
+
selectionRef.current = selection;
|
|
179
185
|
const [contentTreeSelection, setContentTreeSelection] = useState([]);
|
|
180
186
|
const [selectedForInsertion, setSelectedForInsertion] = useState("");
|
|
181
187
|
const [refreshCompletedFlag, setRefreshCompletedFlag] = useState(false);
|
|
@@ -230,6 +236,51 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
230
236
|
const [inserting, setInserting] = useState();
|
|
231
237
|
const [removingComponentIds, setRemovingComponentIds] = useState([]);
|
|
232
238
|
const insertingSequenceRef = useRef(0);
|
|
239
|
+
// Armed by selectWithoutAutoScroll for programmatic selections (drop
|
|
240
|
+
// target's parent, post-operation focus): the canvas selection-scroll
|
|
241
|
+
// effect consumes it and skips exactly that change. Deterministic — unlike
|
|
242
|
+
// a time window, it cannot expire while a slow operation or a frozen host
|
|
243
|
+
// delays the effect flush.
|
|
244
|
+
const suppressNextSelectionAutoScrollRef = useRef(false);
|
|
245
|
+
const selectWithoutAutoScroll = useCallback((ids) => {
|
|
246
|
+
const current = selectionRef.current;
|
|
247
|
+
if (ids.length === current.length &&
|
|
248
|
+
ids.every((id, index) => id === current[index])) {
|
|
249
|
+
// No state change: nothing renders, so don't leave the suppression
|
|
250
|
+
// armed for an unrelated later selection.
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
suppressNextSelectionAutoScrollRef.current = true;
|
|
254
|
+
setSelection(ids);
|
|
255
|
+
}, []);
|
|
256
|
+
const consumeNextSelectionAutoScrollSuppression = useCallback(() => {
|
|
257
|
+
const suppressed = suppressNextSelectionAutoScrollRef.current;
|
|
258
|
+
suppressNextSelectionAutoScrollRef.current = false;
|
|
259
|
+
return suppressed;
|
|
260
|
+
}, []);
|
|
261
|
+
const insertingHoldCleanupRef = useRef(null);
|
|
262
|
+
// The drop operation's HTTP resolve only means the server accepted it — the
|
|
263
|
+
// canvas re-render (fetch + DOM patch) lands seconds later. Keep the
|
|
264
|
+
// inserting indicator up until the first canvas refresh after the operation
|
|
265
|
+
// completes, so it visually hands off to the component actually appearing,
|
|
266
|
+
// with a timeout backstop for hosts that never report a refresh.
|
|
267
|
+
const holdInsertingUntilCanvasRefresh = useCallback((sequence) => {
|
|
268
|
+
insertingHoldCleanupRef.current?.();
|
|
269
|
+
const finish = () => {
|
|
270
|
+
insertingHoldCleanupRef.current = null;
|
|
271
|
+
window.removeEventListener(CANVAS_REFRESH_COMPLETED_EVENT, finish);
|
|
272
|
+
window.clearTimeout(timeoutId);
|
|
273
|
+
if (insertingSequenceRef.current === sequence) {
|
|
274
|
+
setInserting(undefined);
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
const timeoutId = window.setTimeout(finish, 15000);
|
|
278
|
+
window.addEventListener(CANVAS_REFRESH_COMPLETED_EVENT, finish);
|
|
279
|
+
insertingHoldCleanupRef.current = finish;
|
|
280
|
+
}, []);
|
|
281
|
+
useEffect(() => () => {
|
|
282
|
+
insertingHoldCleanupRef.current?.();
|
|
283
|
+
}, []);
|
|
233
284
|
const [showFullscreenHint, setShowFullscreenHint] = useState(false);
|
|
234
285
|
// Fullscreen is a shell-level UI mode. Keep it in EditorShell state so the shell can rerender
|
|
235
286
|
// immediately when toggled, while still syncing the active slot's PageViewContext.fullscreen.
|
|
@@ -709,43 +760,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
709
760
|
const resolvedMode = typeof nextMode === "function" ? nextMode(modeRef.current) : nextMode;
|
|
710
761
|
void changeMode(resolvedMode);
|
|
711
762
|
}, [changeMode]);
|
|
712
|
-
const closeFeedbackSuggestionsMode = useCallback(() => {
|
|
713
|
-
setShowComments(false);
|
|
714
|
-
setShowSuggestedEdits(false);
|
|
715
|
-
setShowSuggestedEditsDiff(false);
|
|
716
|
-
if (modeRef.current === "suggestions") {
|
|
717
|
-
void changeMode("edit", { reason: "feedback-sidebar-close" });
|
|
718
|
-
}
|
|
719
|
-
}, [changeMode]);
|
|
720
|
-
const feedbackSidebarOpenRef = useRef(openSidebars.includes("feedback"));
|
|
721
|
-
const feedbackSidebarSuggestionsLoadedRef = useRef(false);
|
|
722
|
-
useEffect(() => {
|
|
723
|
-
const feedbackSidebarOpen = openSidebars.includes("feedback");
|
|
724
|
-
const wasFeedbackSidebarOpen = feedbackSidebarOpenRef.current;
|
|
725
|
-
feedbackSidebarOpenRef.current = feedbackSidebarOpen;
|
|
726
|
-
if (!feedbackSidebarOpen) {
|
|
727
|
-
feedbackSidebarSuggestionsLoadedRef.current = false;
|
|
728
|
-
if (wasFeedbackSidebarOpen) {
|
|
729
|
-
closeFeedbackSuggestionsMode();
|
|
730
|
-
}
|
|
731
|
-
return;
|
|
732
|
-
}
|
|
733
|
-
if (!showComments) {
|
|
734
|
-
setShowComments(true);
|
|
735
|
-
}
|
|
736
|
-
if (!showSuggestedEdits) {
|
|
737
|
-
setShowSuggestedEdits(true);
|
|
738
|
-
}
|
|
739
|
-
if (!feedbackSidebarSuggestionsLoadedRef.current) {
|
|
740
|
-
feedbackSidebarSuggestionsLoadedRef.current = true;
|
|
741
|
-
void loadSuggestedEditsRef.current();
|
|
742
|
-
}
|
|
743
|
-
}, [
|
|
744
|
-
closeFeedbackSuggestionsMode,
|
|
745
|
-
openSidebars,
|
|
746
|
-
showComments,
|
|
747
|
-
showSuggestedEdits,
|
|
748
|
-
]);
|
|
749
763
|
const activateCommentsModeForWriting = useCallback(async (reason) => {
|
|
750
764
|
setShowComments(true);
|
|
751
765
|
setShowSuggestedEdits(false);
|
|
@@ -873,6 +887,15 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
873
887
|
setSelectedHelpSectionId(helpParam === "contents" || helpParam === "true" ? null : helpParam);
|
|
874
888
|
}
|
|
875
889
|
}, [searchParams, isInitialLoad]);
|
|
890
|
+
// Perf probe: the gap between shell:setSelection-state-update and
|
|
891
|
+
// shell:selection-render-committed is the React render of the entire shell
|
|
892
|
+
// tree (every editContext consumer); the paint step adds compositor time.
|
|
893
|
+
useLayoutEffect(() => {
|
|
894
|
+
if (!isPerfTraceActive())
|
|
895
|
+
return;
|
|
896
|
+
perfTraceStep("shell:selection-render-committed", { ids: selection });
|
|
897
|
+
perfTracePaintStep("shell:selection-painted");
|
|
898
|
+
}, [selection]);
|
|
876
899
|
useEffect(() => {
|
|
877
900
|
if (focusedField &&
|
|
878
901
|
selection.length > 0 &&
|
|
@@ -3054,6 +3077,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
3054
3077
|
configuration,
|
|
3055
3078
|
selection,
|
|
3056
3079
|
setSelection,
|
|
3080
|
+
selectWithoutAutoScroll,
|
|
3057
3081
|
loadItem,
|
|
3058
3082
|
addToEditHistory,
|
|
3059
3083
|
setLockedField,
|
|
@@ -3515,9 +3539,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
3515
3539
|
if (sidebarId === "agents-panel") {
|
|
3516
3540
|
setUserPreferences({ showAgentsPanel: false });
|
|
3517
3541
|
}
|
|
3518
|
-
if (sidebarId === "feedback") {
|
|
3519
|
-
closeFeedbackSuggestionsMode();
|
|
3520
|
-
}
|
|
3521
3542
|
startTransition(() => {
|
|
3522
3543
|
updateUrl({ sidebar: sidebarUrlValue(newSidebars) });
|
|
3523
3544
|
});
|
|
@@ -3553,7 +3574,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
3553
3574
|
ensureSidebarPinned,
|
|
3554
3575
|
setUserPreferences,
|
|
3555
3576
|
isMobile,
|
|
3556
|
-
closeFeedbackSuggestionsMode,
|
|
3557
3577
|
]);
|
|
3558
3578
|
// Ensure a sidebar is open (without toggling it closed if already open)
|
|
3559
3579
|
const openSidebar = useCallback((sidebarId, options) => {
|
|
@@ -4030,6 +4050,13 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
4030
4050
|
}, [operationsContext.cleanup]);
|
|
4031
4051
|
// Shared focused field setter with lock handling (used in both contexts)
|
|
4032
4052
|
const setFocusedFieldWithLock = useCallback(async (field, requestLock) => {
|
|
4053
|
+
logFieldValueDiagnostic("focused-field", "setFocusedField requested", {
|
|
4054
|
+
field: summarizeFieldDescriptor(field),
|
|
4055
|
+
requestLock,
|
|
4056
|
+
ignoreBlur,
|
|
4057
|
+
currentFocusedField: summarizeFieldDescriptor(focusedFieldRef.current),
|
|
4058
|
+
lockedField: summarizeFieldDescriptor(lockedField),
|
|
4059
|
+
});
|
|
4033
4060
|
if (field) {
|
|
4034
4061
|
setIgnoreBlur(true);
|
|
4035
4062
|
setTimeout(() => {
|
|
@@ -4038,12 +4065,25 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
4038
4065
|
if (requestLock) {
|
|
4039
4066
|
const lockResult = (await operations.ensureLock(field)) || false;
|
|
4040
4067
|
if (!lockResult) {
|
|
4068
|
+
logFieldValueDiagnostic("focused-field", "lock failed", {
|
|
4069
|
+
field: summarizeFieldDescriptor(field),
|
|
4070
|
+
requestLock,
|
|
4071
|
+
});
|
|
4041
4072
|
return false;
|
|
4042
4073
|
}
|
|
4043
4074
|
setFocusedField({ ...field });
|
|
4075
|
+
logFieldValueDiagnostic("focused-field", "focused field set", {
|
|
4076
|
+
field: summarizeFieldDescriptor(field),
|
|
4077
|
+
requestLock,
|
|
4078
|
+
lockResult,
|
|
4079
|
+
});
|
|
4044
4080
|
return true;
|
|
4045
4081
|
}
|
|
4046
4082
|
setFocusedField({ ...field });
|
|
4083
|
+
logFieldValueDiagnostic("focused-field", "focused field set", {
|
|
4084
|
+
field: summarizeFieldDescriptor(field),
|
|
4085
|
+
requestLock,
|
|
4086
|
+
});
|
|
4047
4087
|
}
|
|
4048
4088
|
else {
|
|
4049
4089
|
// Keep the field selected when the blur was caused by clicking a User
|
|
@@ -4060,13 +4100,25 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
4060
4100
|
now: Date.now(),
|
|
4061
4101
|
});
|
|
4062
4102
|
if (!ignoreBlur && !focusMovedToShowMe) {
|
|
4103
|
+
logFieldValueDiagnostic("focused-field", "clearing focused field", {
|
|
4104
|
+
previousFocusedField: summarizeFieldDescriptor(focusedFieldRef.current),
|
|
4105
|
+
lockedField: summarizeFieldDescriptor(lockedField),
|
|
4106
|
+
sessionId,
|
|
4107
|
+
});
|
|
4063
4108
|
setFocusedField(undefined);
|
|
4064
4109
|
setLockedField(undefined); // Clear client-side lock state
|
|
4065
4110
|
releaseFieldLocks(sessionId);
|
|
4066
4111
|
}
|
|
4112
|
+
else {
|
|
4113
|
+
logFieldValueDiagnostic("focused-field", "clear skipped", {
|
|
4114
|
+
reason: ignoreBlur ? "ignoreBlur" : "manual show-me focus transfer",
|
|
4115
|
+
previousFocusedField: summarizeFieldDescriptor(focusedFieldRef.current),
|
|
4116
|
+
focusMovedToShowMe,
|
|
4117
|
+
});
|
|
4118
|
+
}
|
|
4067
4119
|
}
|
|
4068
4120
|
return true;
|
|
4069
|
-
}, [operations, ignoreBlur, sessionId]);
|
|
4121
|
+
}, [operations, ignoreBlur, sessionId, lockedField]);
|
|
4070
4122
|
const quickSwitcherEntries = useMemo(() => {
|
|
4071
4123
|
const entries = [];
|
|
4072
4124
|
const seen = new Set();
|
|
@@ -4552,10 +4604,21 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
4552
4604
|
loadItemVersions,
|
|
4553
4605
|
sessionId: sessionId,
|
|
4554
4606
|
readonly: isReadOnly,
|
|
4555
|
-
|
|
4607
|
+
getSelection: () => selectionRef.current,
|
|
4556
4608
|
select: (ids) => {
|
|
4609
|
+
// Re-selecting the same components is a no-op: without this bail a
|
|
4610
|
+
// fresh array identity re-renders every selection consumer.
|
|
4611
|
+
const current = selectionRef.current;
|
|
4612
|
+
if (ids.length === current.length &&
|
|
4613
|
+
ids.every((id, index) => id === current[index])) {
|
|
4614
|
+
perfTraceStep("shell:setSelection-bailed (unchanged)", { ids });
|
|
4615
|
+
return;
|
|
4616
|
+
}
|
|
4617
|
+
perfTraceStep("shell:setSelection-state-update", { ids });
|
|
4557
4618
|
setSelection(ids);
|
|
4558
4619
|
},
|
|
4620
|
+
selectWithoutAutoScroll,
|
|
4621
|
+
consumeNextSelectionAutoScrollSuppression,
|
|
4559
4622
|
contentTreeSelection,
|
|
4560
4623
|
setContentTreeSelection,
|
|
4561
4624
|
selectedForInsertion,
|
|
@@ -4597,6 +4660,10 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
4597
4660
|
return await getComponentCommands(components, editContext, providerContext);
|
|
4598
4661
|
},
|
|
4599
4662
|
dragStart: (dragObject) => {
|
|
4663
|
+
// A drag supersedes any unresolved scroll request (e.g. a comment
|
|
4664
|
+
// target still waiting for geometry). Left pending, it would replay
|
|
4665
|
+
// against the post-drop refresh and yank the canvas to a stale spot.
|
|
4666
|
+
setScrollIntoView(undefined);
|
|
4600
4667
|
setDragObject(dragObject);
|
|
4601
4668
|
},
|
|
4602
4669
|
dragEnd: () => {
|
|
@@ -4604,18 +4671,21 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
4604
4671
|
},
|
|
4605
4672
|
droppedInPlaceholder: async (placeholderKey, index, spotPositionElement, spotPositionAnchor, insertOption, spotPosition, color) => {
|
|
4606
4673
|
const droppedDragObject = dragObject;
|
|
4607
|
-
if ((!droppedDragObject && !insertOption) || !page)
|
|
4608
|
-
return;
|
|
4674
|
+
if ((!droppedDragObject && !insertOption) || !page) {
|
|
4675
|
+
return { committed: false };
|
|
4676
|
+
}
|
|
4609
4677
|
setDragObject(undefined);
|
|
4610
4678
|
const placeholderKeyComponents = placeholderKey.split("_");
|
|
4611
4679
|
const parentId = placeholderKeyComponents.length === 1
|
|
4612
4680
|
? undefined
|
|
4613
4681
|
: placeholderKeyComponents[1];
|
|
4614
|
-
|
|
4615
|
-
|
|
4682
|
+
// Selection is left alone at drop. The server response's focus id
|
|
4683
|
+
// selects the moved/added component (executeEditOperation); selecting
|
|
4684
|
+
// the drop target's parent here made the single-selection frame
|
|
4685
|
+
// FLIP-animate component -> parent -> component around every drop.
|
|
4616
4686
|
let op;
|
|
4617
4687
|
if (!currentItemDescriptorRef.current)
|
|
4618
|
-
return;
|
|
4688
|
+
return { committed: false };
|
|
4619
4689
|
let insertionSequence;
|
|
4620
4690
|
if ((spotPosition || spotPositionElement) && spotPositionAnchor) {
|
|
4621
4691
|
insertionSequence = ++insertingSequenceRef.current;
|
|
@@ -4687,20 +4757,34 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
4687
4757
|
insertingSequenceRef.current === insertionSequence) {
|
|
4688
4758
|
setInserting(undefined);
|
|
4689
4759
|
}
|
|
4690
|
-
return;
|
|
4760
|
+
return { committed: false };
|
|
4691
4761
|
}
|
|
4762
|
+
let operationFailed = false;
|
|
4692
4763
|
try {
|
|
4693
|
-
|
|
4764
|
+
// executeOp resolves (instead of throwing) with a failed status when
|
|
4765
|
+
// the server rejects the operation — no refresh follows then.
|
|
4766
|
+
const result = (await operationPromise);
|
|
4767
|
+
operationFailed = result?.executionStatus === "failed";
|
|
4694
4768
|
}
|
|
4695
4769
|
catch (err) {
|
|
4770
|
+
operationFailed = true;
|
|
4696
4771
|
console.error("Failed to drop component in placeholder", err);
|
|
4697
4772
|
}
|
|
4698
4773
|
finally {
|
|
4699
4774
|
if (insertionSequence !== undefined &&
|
|
4700
4775
|
insertingSequenceRef.current === insertionSequence) {
|
|
4701
|
-
|
|
4776
|
+
if (operationFailed) {
|
|
4777
|
+
setInserting(undefined);
|
|
4778
|
+
}
|
|
4779
|
+
else {
|
|
4780
|
+
// The server accepted the drop; the canvas has not repainted
|
|
4781
|
+
// yet. Hold the indicator until the refresh lands so it stops
|
|
4782
|
+
// when the component actually appears, not seconds earlier.
|
|
4783
|
+
holdInsertingUntilCanvasRefresh(insertionSequence);
|
|
4784
|
+
}
|
|
4702
4785
|
}
|
|
4703
4786
|
}
|
|
4787
|
+
return { committed: !operationFailed };
|
|
4704
4788
|
},
|
|
4705
4789
|
page,
|
|
4706
4790
|
triggerFieldAction: async (fieldDescriptor, actionButton, parameters, event) => {
|
|
@@ -5200,7 +5284,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
5200
5284
|
loadItemVersions,
|
|
5201
5285
|
sessionId,
|
|
5202
5286
|
isReadOnly,
|
|
5203
|
-
selection,
|
|
5204
5287
|
contentTreeSelection,
|
|
5205
5288
|
selectedForInsertion,
|
|
5206
5289
|
dragObject,
|
|
@@ -5348,7 +5431,13 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
5348
5431
|
// This ensures editContextRef.current always has the latest value when executeCommand is called
|
|
5349
5432
|
// Using useEffect would create a timing window where the ref is stale
|
|
5350
5433
|
editContextRef.current = editContext;
|
|
5351
|
-
|
|
5434
|
+
// Selection is deliberately NOT part of editContext (see SelectionContext):
|
|
5435
|
+
// a canvas click would otherwise rebuild the context and re-render every
|
|
5436
|
+
// consumer. Only SelectionContext subscribers re-render on selection change.
|
|
5437
|
+
const selectionContextValue = useMemo(() => ({ selection }), [selection]);
|
|
5438
|
+
// Memoized: a fresh identity here re-renders every FieldsEditContext
|
|
5439
|
+
// consumer on every shell render (same churn class as SelectionContext).
|
|
5440
|
+
const fieldsEditContext = useMemo(() => ({
|
|
5352
5441
|
modifiedFields,
|
|
5353
5442
|
recentEdits,
|
|
5354
5443
|
clearRecentEdits: () => {
|
|
@@ -5361,7 +5450,14 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
5361
5450
|
setLockedField(undefined); // Clear client-side lock state
|
|
5362
5451
|
await releaseFieldLocks(sessionId);
|
|
5363
5452
|
},
|
|
5364
|
-
}
|
|
5453
|
+
}), [
|
|
5454
|
+
modifiedFields,
|
|
5455
|
+
recentEdits,
|
|
5456
|
+
addRecentEdit,
|
|
5457
|
+
focusedField,
|
|
5458
|
+
setFocusedFieldWithLock,
|
|
5459
|
+
sessionId,
|
|
5460
|
+
]);
|
|
5365
5461
|
// Debug: Track editContext changes
|
|
5366
5462
|
// const prevDependencies = useRef<any[]>([]);
|
|
5367
5463
|
// useEffect(() => {
|
|
@@ -5598,7 +5694,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
5598
5694
|
]);
|
|
5599
5695
|
if (!currentWorkspace)
|
|
5600
5696
|
return null;
|
|
5601
|
-
const editorUi = fullscreen ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "fixed inset-0 flex", children: _jsx(PageViewerFrame, { compareView: compareMode, pageViewContext: activePageViewContext }) }), showFullscreenHint && !configuration.forceFullscreen && !isMobile && (_jsx("div", { className: "fixed inset-0 z-10000", onMouseMoveCapture: () => {
|
|
5697
|
+
const editorUi = fullscreen ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "bg-neutral-grey-5 fixed inset-0 flex", "data-testid": "fullscreen-root", children: _jsx(PageViewerFrame, { compareView: compareMode, pageViewContext: activePageViewContext }) }), showFullscreenHint && !configuration.forceFullscreen && !isMobile && (_jsx("div", { className: "fixed inset-0 z-10000", onMouseMoveCapture: () => {
|
|
5602
5698
|
setTimeout(() => {
|
|
5603
5699
|
setShowFullscreenHint(false);
|
|
5604
5700
|
}, 600);
|
|
@@ -5615,13 +5711,13 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
5615
5711
|
window.history.replaceState(getCurrentHistoryState(), "", newUrl);
|
|
5616
5712
|
}, configuration: configuration, restoredFromUrl: tourRestoredRef.current })), _jsx(FeatureGate, { feature: LicenseFeatures.AI, children: _jsx(GuidanceOverlay, {}) }), _jsx(FeatureGate, { feature: LicenseFeatures.AI, children: _jsx(AgentDialogHandler, {}) })] }));
|
|
5617
5713
|
const showRefreshSpinner = editContext.isRefreshing && !activePageViewContext.iframeSupportsRefresh;
|
|
5618
|
-
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" ||
|
|
5619
|
-
|
|
5620
|
-
|
|
5621
|
-
|
|
5622
|
-
|
|
5623
|
-
|
|
5624
|
-
|
|
5625
|
-
|
|
5714
|
+
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: _jsx(SelectionContextProvider, { value: selectionContextValue, 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" ||
|
|
5715
|
+
currentWorkspace.id === "taskboard" ||
|
|
5716
|
+
currentWorkspace.id === "translation-management") &&
|
|
5717
|
+
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) => {
|
|
5718
|
+
if (!open) {
|
|
5719
|
+
setConcurrentUserLimitError(null);
|
|
5720
|
+
}
|
|
5721
|
+
}, sessionId: sessionId, currentUsers: concurrentUserLimitError?.currentUsers ?? 0, maxUsers: concurrentUserLimitError?.maxUsers ?? 0, message: concurrentUserLimitError?.message ?? "", onRetry: handleRetryConnection, isAdministrator: userInfo.user.isAdministrator === true }), _jsx(QuickItemSwitcher, { visible: quickSwitcherVisible, entries: quickSwitcherEntries.slice(0, 5), selectedIndex: quickSwitcherSelectedIndex, onSelect: handleQuickSwitcherSelect, onClose: () => setQuickSwitcherVisible(false) }), _jsx(EditContextMenu, { ref: contextMenuRef, onOpenChange: handleContextMenuOpenChange }), _jsx(EditorFormHintPopover, {}), _jsx(FeatureGate, { feature: LicenseFeatures.AI, children: _jsx(InlineAiTrigger, {}) }), media.mediaSelectorVisible && (_jsx(MediaSelector, { language: editContext.currentItemDescriptor.language, visible: media.mediaSelectorVisible, onHide: media.handleHide, onMediaSelected: media.onMediaSelect, selectedIdPath: media.selectedMediaIdPath, mode: media.mediaSelectorMode, initialSearchTerm: media.initialSearchTerm })), _jsx(FieldEditorPopup, { ref: fieldEditorPopupRef }), _jsx(LicenseOverlay, {}), _jsx(SessionExpiredOverlay, {})] }) }) }) }) }) }) }));
|
|
5626
5722
|
}
|
|
5627
5723
|
//# sourceMappingURL=EditorShell.js.map
|