@parhelia/core 0.1.12910 → 0.1.12912
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/AgentGalleryView.d.ts +1 -1
- package/dist/agents-view/AgentGalleryView.js +3 -2
- package/dist/agents-view/AgentGalleryView.js.map +1 -1
- package/dist/agents-view/AgentsView.js +1 -1
- package/dist/agents-view/AgentsView.js.map +1 -1
- package/dist/components/PageHeader.d.ts +7 -2
- package/dist/components/PageHeader.js +8 -3
- package/dist/components/PageHeader.js.map +1 -1
- package/dist/components/ui/UserPicker.d.ts +5 -1
- package/dist/components/ui/UserPicker.js +17 -3
- package/dist/components/ui/UserPicker.js.map +1 -1
- package/dist/components/ui/button.js +1 -1
- package/dist/components/ui/button.js.map +1 -1
- package/dist/components/ui/command.js +1 -1
- package/dist/components/ui/delete-button.d.ts +1 -1
- package/dist/components/ui/delete-button.js +2 -2
- package/dist/components/ui/delete-button.js.map +1 -1
- package/dist/components/ui/dropdown-menu.js +3 -3
- package/dist/components/ui/input.js +1 -1
- package/dist/components/ui/input.js.map +1 -1
- package/dist/components/ui/label.js +1 -1
- package/dist/components/ui/select.d.ts +2 -0
- package/dist/components/ui/select.js +8 -6
- package/dist/components/ui/select.js.map +1 -1
- package/dist/components/ui/textarea.js +1 -3
- package/dist/components/ui/textarea.js.map +1 -1
- package/dist/config/config.js +5 -0
- package/dist/config/config.js.map +1 -1
- package/dist/editor/ContentTree.d.ts +3 -2
- package/dist/editor/ContentTree.js +4 -4
- package/dist/editor/ContentTree.js.map +1 -1
- package/dist/editor/EditorWarning.js +1 -1
- package/dist/editor/EditorWarning.js.map +1 -1
- package/dist/editor/FieldHistory.js +6 -4
- package/dist/editor/FieldHistory.js.map +1 -1
- package/dist/editor/ai/Agents.js +17 -23
- package/dist/editor/ai/Agents.js.map +1 -1
- package/dist/editor/ai/ContentInspectorPopover.js +2 -1
- package/dist/editor/ai/ContentInspectorPopover.js.map +1 -1
- package/dist/editor/ai/agentCollection.d.ts +2 -0
- package/dist/editor/ai/agentCollection.js +8 -0
- package/dist/editor/ai/agentCollection.js.map +1 -0
- package/dist/editor/ai/agentMessageHelpers.d.ts +1 -0
- package/dist/editor/ai/agentMessageHelpers.js +4 -1
- package/dist/editor/ai/agentMessageHelpers.js.map +1 -1
- package/dist/editor/ai/terminal/agentSessionSnapshot.js +4 -1
- package/dist/editor/ai/terminal/agentSessionSnapshot.js.map +1 -1
- package/dist/editor/ai/terminal/components/AgentLoadingContent.js +2 -2
- package/dist/editor/ai/terminal/components/AgentLoadingContent.js.map +1 -1
- package/dist/editor/ai/terminal/components/AiResponseMessage.js +9 -3
- package/dist/editor/ai/terminal/components/AiResponseMessage.js.map +1 -1
- package/dist/editor/ai/terminal/components/EditOperationsPanel.js +3 -3
- package/dist/editor/ai/terminal/components/EditOperationsPanel.js.map +1 -1
- package/dist/editor/ai/terminal/useAgentDraftInitializer.js +3 -1
- package/dist/editor/ai/terminal/useAgentDraftInitializer.js.map +1 -1
- package/dist/editor/ai/terminal/useAgentLoadErrorHandler.js +3 -1
- package/dist/editor/ai/terminal/useAgentLoadErrorHandler.js.map +1 -1
- package/dist/editor/ai/terminal/useAgentSessionFacade.js +7 -3
- package/dist/editor/ai/terminal/useAgentSessionFacade.js.map +1 -1
- package/dist/editor/bridge/protocol.d.ts +13 -0
- package/dist/editor/bridge/protocol.js +2 -1
- package/dist/editor/bridge/protocol.js.map +1 -1
- package/dist/editor/client/EditorShell.js +179 -30
- package/dist/editor/client/EditorShell.js.map +1 -1
- package/dist/editor/client/editContext.d.ts +7 -5
- package/dist/editor/client/editContext.js.map +1 -1
- package/dist/editor/client/errorToast.d.ts +12 -0
- package/dist/editor/client/errorToast.js +67 -0
- package/dist/editor/client/errorToast.js.map +1 -0
- package/dist/editor/client/helpers.d.ts +2 -4
- package/dist/editor/client/helpers.js +3 -2
- package/dist/editor/client/helpers.js.map +1 -1
- package/dist/editor/client/hooks/useSocketMessageHandler.js +5 -3
- package/dist/editor/client/hooks/useSocketMessageHandler.js.map +1 -1
- package/dist/editor/client/operations.d.ts +2 -4
- package/dist/editor/client/operations.js +11 -2
- package/dist/editor/client/operations.js.map +1 -1
- package/dist/editor/client/ui/FullscreenControls.d.ts +0 -1
- package/dist/editor/client/ui/FullscreenControls.js +4 -17
- package/dist/editor/client/ui/FullscreenControls.js.map +1 -1
- package/dist/editor/field-types/DateFieldEditor.js +1 -1
- package/dist/editor/field-types/DateFieldEditor.js.map +1 -1
- package/dist/editor/field-types/DateTimeFieldEditor.js +1 -1
- package/dist/editor/field-types/DateTimeFieldEditor.js.map +1 -1
- package/dist/editor/field-types/useTextCompletion.js +12 -43
- package/dist/editor/field-types/useTextCompletion.js.map +1 -1
- package/dist/editor/media-selector/AiImageSearchPrompt.js +8 -17
- package/dist/editor/media-selector/AiImageSearchPrompt.js.map +1 -1
- package/dist/editor/menubar/toolbar-sections/DeviceSwitchToolbar.d.ts +6 -1
- package/dist/editor/menubar/toolbar-sections/DeviceSwitchToolbar.js +21 -13
- package/dist/editor/menubar/toolbar-sections/DeviceSwitchToolbar.js.map +1 -1
- package/dist/editor/page-editor-chrome/BridgeInlineFormatOverlay.js +6 -5
- package/dist/editor/page-editor-chrome/BridgeInlineFormatOverlay.js.map +1 -1
- package/dist/editor/page-editor-chrome/FrameMenu.js +8 -2
- package/dist/editor/page-editor-chrome/FrameMenu.js.map +1 -1
- package/dist/editor/page-editor-chrome/InsertComponentMenu.js +1 -1
- package/dist/editor/page-editor-chrome/InsertComponentMenu.js.map +1 -1
- package/dist/editor/page-editor-chrome/overlay/IframeOverlayProvider.d.ts +3 -1
- package/dist/editor/page-editor-chrome/overlay/IframeOverlayProvider.js +34 -2
- package/dist/editor/page-editor-chrome/overlay/IframeOverlayProvider.js.map +1 -1
- package/dist/editor/page-viewer/MiniMap.d.ts +5 -1
- package/dist/editor/page-viewer/MiniMap.js +21 -9
- package/dist/editor/page-viewer/MiniMap.js.map +1 -1
- package/dist/editor/page-viewer/PageViewerFrame.js +291 -4
- package/dist/editor/page-viewer/PageViewerFrame.js.map +1 -1
- package/dist/editor/page-viewer/RenderingParametersSection.js +1 -1
- package/dist/editor/page-viewer/RenderingParametersSection.js.map +1 -1
- package/dist/editor/page-viewer/bridgeFieldPatch.js +2 -1
- package/dist/editor/page-viewer/bridgeFieldPatch.js.map +1 -1
- package/dist/editor/reviews/CreateReviewConfirmStep.d.ts +1 -2
- package/dist/editor/reviews/CreateReviewConfirmStep.js +3 -3
- package/dist/editor/reviews/CreateReviewConfirmStep.js.map +1 -1
- package/dist/editor/reviews/CreateReviewDialog.js +27 -3
- package/dist/editor/reviews/CreateReviewDialog.js.map +1 -1
- package/dist/editor/reviews/DecisionsMatrix.js +1 -1
- package/dist/editor/reviews/DecisionsMatrix.js.map +1 -1
- package/dist/editor/services/contentService.d.ts +3 -2
- package/dist/editor/services/contentService.js +19 -5
- package/dist/editor/services/contentService.js.map +1 -1
- package/dist/editor/services/contextService.d.ts +8 -0
- package/dist/editor/services/contextService.js +19 -0
- package/dist/editor/services/contextService.js.map +1 -1
- package/dist/editor/services/textCompletionService.d.ts +14 -0
- package/dist/editor/services/textCompletionService.js +45 -0
- package/dist/editor/services/textCompletionService.js.map +1 -0
- package/dist/editor/settings/About.js +40 -263
- package/dist/editor/settings/About.js.map +1 -1
- package/dist/editor/settings/SettingsBreadcrumb.js +5 -1
- package/dist/editor/settings/SettingsBreadcrumb.js.map +1 -1
- package/dist/editor/settings/panels/AgentToolsPanel.js +3 -7
- package/dist/editor/settings/panels/AgentToolsPanel.js.map +1 -1
- package/dist/editor/settings/panels/AgentsPanel.js +2 -3
- package/dist/editor/settings/panels/AgentsPanel.js.map +1 -1
- package/dist/editor/settings/panels/ClusterInstancesPanel.js +2 -3
- package/dist/editor/settings/panels/ClusterInstancesPanel.js.map +1 -1
- package/dist/editor/settings/panels/FieldTypeSerializersPanel.js +2 -4
- package/dist/editor/settings/panels/FieldTypeSerializersPanel.js.map +1 -1
- package/dist/editor/settings/panels/JavaScriptToolsPanel.js +2 -3
- package/dist/editor/settings/panels/JavaScriptToolsPanel.js.map +1 -1
- package/dist/editor/settings/panels/McpToolsPanel.js +3 -4
- package/dist/editor/settings/panels/McpToolsPanel.js.map +1 -1
- package/dist/editor/settings/panels/ProjectTemplatesPanel.js +2 -3
- package/dist/editor/settings/panels/ProjectTemplatesPanel.js.map +1 -1
- package/dist/editor/setup-wizard/steps/LicenseActivationStep.d.ts +3 -1
- package/dist/editor/setup-wizard/steps/LicenseActivationStep.js +9 -5
- package/dist/editor/setup-wizard/steps/LicenseActivationStep.js.map +1 -1
- package/dist/editor/setup-wizard/steps/LicenseEmailStep.d.ts +2 -1
- package/dist/editor/setup-wizard/steps/LicenseEmailStep.js +6 -3
- package/dist/editor/setup-wizard/steps/LicenseEmailStep.js.map +1 -1
- package/dist/editor/sidebar/EditHistory.js +11 -3
- package/dist/editor/sidebar/EditHistory.js.map +1 -1
- package/dist/editor/sidebar/WorkspaceRailMobile.js +1 -3
- package/dist/editor/sidebar/WorkspaceRailMobile.js.map +1 -1
- package/dist/editor/ui/ItemCollectionEditor.d.ts +6 -2
- package/dist/editor/ui/ItemCollectionEditor.js +163 -84
- package/dist/editor/ui/ItemCollectionEditor.js.map +1 -1
- package/dist/editor/ui/LoadingState.js +4 -4
- package/dist/editor/ui/LoadingState.js.map +1 -1
- package/dist/editor/ui/PerfectTree.d.ts +5 -1
- package/dist/editor/ui/PerfectTree.js +10 -6
- package/dist/editor/ui/PerfectTree.js.map +1 -1
- package/dist/editor/ui/SimpleIconButton.js +1 -1
- package/dist/editor/ui/TreeListSelector.d.ts +6 -2
- package/dist/editor/ui/TreeListSelector.js +2 -2
- package/dist/editor/ui/TreeListSelector.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/revision.d.ts +2 -2
- package/dist/revision.js +2 -2
- package/dist/splash-screen/ModernSplashScreen.d.ts +2 -0
- package/dist/splash-screen/ModernSplashScreen.js +8 -3
- package/dist/splash-screen/ModernSplashScreen.js.map +1 -1
- package/dist/task-board/components/ProjectDashboard.js +2 -1
- package/dist/task-board/components/ProjectDashboard.js.map +1 -1
- package/dist/task-board/components/ProjectPropertiesPanel.js +1 -1
- package/dist/task-board/components/ProjectPropertiesPanel.js.map +1 -1
- package/dist/task-board/components/TaskAssigneeBadge.d.ts +1 -1
- package/dist/task-board/components/TaskAssigneeBadge.js +1 -1
- package/dist/task-board/components/TaskAssigneeBadge.js.map +1 -1
- package/dist/task-board/components/TaskAssigneePicker.js +1 -1
- package/dist/task-board/components/TaskAssigneePicker.js.map +1 -1
- package/dist/task-board/components/TaskRow.js +1 -1
- package/dist/task-board/components/TaskRow.js.map +1 -1
- package/package.json +1 -1
|
@@ -9,6 +9,7 @@ import { useRouter, useSearchParams, usePathname } from "./navigation";
|
|
|
9
9
|
import { findComponent, getComponentById } from "../componentTreeHelper";
|
|
10
10
|
import { getOperationsContext } from "./operations";
|
|
11
11
|
import { handleErrorResult } from "./helpers";
|
|
12
|
+
import { showExpandableErrorToast, } from "./errorToast";
|
|
12
13
|
import { isManualShowMeFocusTransfer, isManualShowMeTarget, } from "./manualShowMeFocus";
|
|
13
14
|
import { executeFieldAction as executeFieldServerAction, connectSocket, getEditHistory, getRunningOperations, reconnectSession, releaseFieldLocks, validateItems, } from "../services/editService";
|
|
14
15
|
import { emitAgentDocumentsChanged } from "../services/agentService";
|
|
@@ -22,6 +23,7 @@ import "react-json-view-lite/dist/index.css";
|
|
|
22
23
|
import { MediaSelector, } from "../media-selector/MediaSelector";
|
|
23
24
|
import { getComponentCommands } from "../commands/componentCommands";
|
|
24
25
|
import { getLanguagesAndVersions, } from "../services/contentService";
|
|
26
|
+
import { getEditorSettings } from "../services/systemService";
|
|
25
27
|
import { getAllFavorites } from "../services/favouritesService";
|
|
26
28
|
import ConfirmationDialog from "../ConfirmationDialog";
|
|
27
29
|
import { getItemDescriptor } from "../utils";
|
|
@@ -67,12 +69,37 @@ import { useGlobalEditorKeyDown } from "./hooks/useGlobalEditorKeyDown";
|
|
|
67
69
|
import { useStartupChecks } from "../settings/status/index";
|
|
68
70
|
import { EditorLoadingOverlay } from "../EditorLoadingOverlay";
|
|
69
71
|
import { FeatureGate, LicenseFeatures, LicenseProvider, LicenseOverlay, } from "../../licensing";
|
|
72
|
+
const GLOBAL_SESSION_HISTORY_LIMIT = 200;
|
|
73
|
+
const GLOBAL_HISTORY_LIMIT = 200;
|
|
74
|
+
const GLOBAL_SESSION_HISTORY_LOAD_MORE_INCREMENT = 50;
|
|
75
|
+
const GLOBAL_HISTORY_LOAD_MORE_INCREMENT = 100;
|
|
76
|
+
function getInitialGlobalHistoryLimit(filterBySession) {
|
|
77
|
+
return filterBySession ? GLOBAL_SESSION_HISTORY_LIMIT : GLOBAL_HISTORY_LIMIT;
|
|
78
|
+
}
|
|
79
|
+
function getGlobalHistoryLoadMoreIncrement(filterBySession) {
|
|
80
|
+
return filterBySession
|
|
81
|
+
? GLOBAL_SESSION_HISTORY_LOAD_MORE_INCREMENT
|
|
82
|
+
: GLOBAL_HISTORY_LOAD_MORE_INCREMENT;
|
|
83
|
+
}
|
|
70
84
|
// Sentinel written to the `sidebar` URL param when the user has explicitly closed
|
|
71
85
|
// every sidebar. Distinguishes "no preference yet" (param absent) from "user wants
|
|
72
86
|
// nothing open" (param present with this value) so reload can honor the user's intent.
|
|
73
87
|
const SIDEBAR_NONE_SENTINEL = "none";
|
|
88
|
+
const PARHELIA_SETTINGS_ITEM_ID = "a2f3c168bb2841ff9673ee7f3cc624af";
|
|
89
|
+
const PARHELIA_SETTINGS_ITEM_PATH = "/sitecore/system/parhelia/settings";
|
|
90
|
+
const PARHELIA_SHOW_MINIMAP_FIELD_ID = "e75976d2179e4578b4140147b7525fa5";
|
|
74
91
|
const sidebarUrlValue = (ids) => ids.length ? ids.join(",") : SIDEBAR_NONE_SENTINEL;
|
|
75
92
|
// moved to hooks/useQuota
|
|
93
|
+
function isParheliaSettingsSnapshotChange(changes) {
|
|
94
|
+
return changes.some((change) => {
|
|
95
|
+
const changedItemId = cleanId(change.item?.id);
|
|
96
|
+
const changedItemPath = change.item?.path?.toLowerCase();
|
|
97
|
+
const changedFieldIds = change.changes.fields?.map((fieldId) => cleanId(fieldId));
|
|
98
|
+
return (changedItemId === PARHELIA_SETTINGS_ITEM_ID ||
|
|
99
|
+
changedItemPath === PARHELIA_SETTINGS_ITEM_PATH ||
|
|
100
|
+
changedFieldIds?.includes(PARHELIA_SHOW_MINIMAP_FIELD_ID));
|
|
101
|
+
});
|
|
102
|
+
}
|
|
76
103
|
function getInitialOpenSidebars(configuration, workspaceId) {
|
|
77
104
|
const workspace = configuration.editor.workspaces?.find((candidate) => candidate.id === workspaceId);
|
|
78
105
|
if (workspace?.supportsSidebars && workspace.defaultSidebars?.length) {
|
|
@@ -143,6 +170,10 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
143
170
|
const router = useRouter();
|
|
144
171
|
const pathname = usePathname();
|
|
145
172
|
const searchParams = useSearchParams();
|
|
173
|
+
const [effectiveParheliaSettings, setEffectiveParheliaSettings] = useState(parheliaSettings);
|
|
174
|
+
const [effectiveParheliaSettingsLoaded, setEffectiveParheliaSettingsLoaded] = useState(parheliaSettingsLoaded === true);
|
|
175
|
+
const parheliaSettingsRefreshInFlightRef = useRef(null);
|
|
176
|
+
const minimapEnabledInSettings = effectiveParheliaSettings?.showMinimap !== false;
|
|
146
177
|
const [selection, setSelection] = useState([]);
|
|
147
178
|
const [contentTreeSelection, setContentTreeSelection] = useState([]);
|
|
148
179
|
const [selectedForInsertion, setSelectedForInsertion] = useState("");
|
|
@@ -159,6 +190,34 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
159
190
|
const confirmationDialogRef = useRef(null);
|
|
160
191
|
const contextMenuRef = useRef(null);
|
|
161
192
|
const editContextRef = useRef(undefined);
|
|
193
|
+
useEffect(() => {
|
|
194
|
+
setEffectiveParheliaSettings(parheliaSettings);
|
|
195
|
+
setEffectiveParheliaSettingsLoaded(parheliaSettingsLoaded === true);
|
|
196
|
+
}, [parheliaSettings, parheliaSettingsLoaded]);
|
|
197
|
+
const refreshParheliaSettings = useCallback(async () => {
|
|
198
|
+
if (parheliaSettingsRefreshInFlightRef.current) {
|
|
199
|
+
return parheliaSettingsRefreshInFlightRef.current;
|
|
200
|
+
}
|
|
201
|
+
const refresh = getEditorSettings()
|
|
202
|
+
.then((result) => {
|
|
203
|
+
if (result.type === "success" && result.data) {
|
|
204
|
+
setEffectiveParheliaSettings(result.data);
|
|
205
|
+
setEffectiveParheliaSettingsLoaded(true);
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
console.warn("Failed to refresh Parhelia settings:", result.summary || result.details);
|
|
209
|
+
})
|
|
210
|
+
.catch((error) => {
|
|
211
|
+
console.error("Failed to refresh Parhelia settings:", error);
|
|
212
|
+
});
|
|
213
|
+
parheliaSettingsRefreshInFlightRef.current = refresh;
|
|
214
|
+
void refresh.finally(() => {
|
|
215
|
+
if (parheliaSettingsRefreshInFlightRef.current === refresh) {
|
|
216
|
+
parheliaSettingsRefreshInFlightRef.current = null;
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
return refresh;
|
|
220
|
+
}, []);
|
|
162
221
|
const [currentOverlay, setCurrentOverlay] = useState();
|
|
163
222
|
const [contextMenuSource, setContextMenuSource] = useState();
|
|
164
223
|
const [item, setItem] = useState();
|
|
@@ -192,6 +251,12 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
192
251
|
const [showOnlyMyChanges, setShowOnlyMyChanges] = useState(true);
|
|
193
252
|
const [filterByCurrentLanguage, setFilterByCurrentLanguage] = useState(true);
|
|
194
253
|
const [historySearchQuery, setHistorySearchQuery] = useState("");
|
|
254
|
+
const [isHistoryLoading, setIsHistoryLoading] = useState(false);
|
|
255
|
+
const [isHistoryLoadingMore, setIsHistoryLoadingMore] = useState(false);
|
|
256
|
+
const [canLoadMoreHistory, setCanLoadMoreHistory] = useState(false);
|
|
257
|
+
const [globalHistoryLimit, setGlobalHistoryLimit] = useState(GLOBAL_SESSION_HISTORY_LIMIT);
|
|
258
|
+
const historyLoadingRequestCountRef = useRef(0);
|
|
259
|
+
const historyLoadingMoreRequestCountRef = useRef(0);
|
|
195
260
|
const [recentEdits, setRecentEdits] = useState([]);
|
|
196
261
|
const addRecentEdit = useCallback((edit) => {
|
|
197
262
|
setRecentEdits((prevEditedFields) => {
|
|
@@ -696,6 +761,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
696
761
|
const [editorFormHintVisible, setEditorFormHintVisible] = useState(false);
|
|
697
762
|
const editorFormToggleButtonRef = useRef(null);
|
|
698
763
|
const [showMinimap, setShowMinimap] = useState(userPreferences.showMinimap ?? true);
|
|
764
|
+
const effectiveShowMinimap = minimapEnabledInSettings && showMinimap;
|
|
699
765
|
const [showHelpTerminal, setShowHelpTerminal] = useState(false);
|
|
700
766
|
const [helpTerminalInitialPrompt, setHelpTerminalInitialPrompt] = useState(undefined);
|
|
701
767
|
const [helpTerminalProfileName, setHelpTerminalProfileName] = useState(undefined);
|
|
@@ -803,13 +869,29 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
803
869
|
const [currentPageItem, setCurrentPageItem] = useState();
|
|
804
870
|
// Create itemsRepository with current page item (will be updated when page loads)
|
|
805
871
|
const itemsRepository = useItemsRepository(addRecentEdit, currentPageItem, getFieldModificationStores);
|
|
872
|
+
// The fallback is a null-object: it backs activePageViewContext only when no slot
|
|
873
|
+
// context is registered (the startup gap, or all slots closed). Its *resolved page* is
|
|
874
|
+
// rendered on screen ONLY by the fullscreen branch (the <PageViewerFrame> in the
|
|
875
|
+
// `fullscreen ? (...)` render); in non-fullscreen the visible iframe comes from the
|
|
876
|
+
// slot's own primaryPageViewContext. So only feed it a descriptor when it is actually
|
|
877
|
+
// the render source — otherwise it pointlessly re-resolves the page the slot already
|
|
878
|
+
// resolves, producing a duplicate /parhelia/resolve at startup.
|
|
879
|
+
const hasActiveSlotContext = !!(activeSlotId && slotContexts.get(activeSlotId));
|
|
806
880
|
const fallbackPageViewContext = usePageViewContext({
|
|
807
|
-
pageItemDescriptor: currentItemDescriptor,
|
|
881
|
+
pageItemDescriptor: fullscreen && !hasActiveSlotContext ? currentItemDescriptor : undefined,
|
|
808
882
|
itemsRepository,
|
|
809
883
|
configuration,
|
|
810
|
-
parheliaSettings,
|
|
884
|
+
parheliaSettings: effectiveParheliaSettings,
|
|
811
885
|
layoutMode,
|
|
812
886
|
});
|
|
887
|
+
useEffect(() => {
|
|
888
|
+
return itemsRepository.subscribeItemsChanged((changes) => {
|
|
889
|
+
const persistedChanges = changes.filter((change) => change.source !== "local-field-update");
|
|
890
|
+
if (isParheliaSettingsSnapshotChange(persistedChanges)) {
|
|
891
|
+
void refreshParheliaSettings();
|
|
892
|
+
}
|
|
893
|
+
});
|
|
894
|
+
}, [itemsRepository, refreshParheliaSettings]);
|
|
813
895
|
const registerSlotContext = useCallback((slotId, ctx) => {
|
|
814
896
|
setSlotContexts((prev) => {
|
|
815
897
|
if (prev.get(slotId) === ctx)
|
|
@@ -1929,6 +2011,34 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
1929
2011
|
}
|
|
1930
2012
|
return [];
|
|
1931
2013
|
}, []);
|
|
2014
|
+
const getEditHistoryWithLoading = useCallback(async (options, loadingMode = "initial") => {
|
|
2015
|
+
const loadingMore = loadingMode === "more";
|
|
2016
|
+
if (loadingMore) {
|
|
2017
|
+
historyLoadingMoreRequestCountRef.current += 1;
|
|
2018
|
+
setIsHistoryLoadingMore(true);
|
|
2019
|
+
}
|
|
2020
|
+
else {
|
|
2021
|
+
historyLoadingRequestCountRef.current += 1;
|
|
2022
|
+
setIsHistoryLoading(true);
|
|
2023
|
+
}
|
|
2024
|
+
try {
|
|
2025
|
+
return await getEditHistory(options);
|
|
2026
|
+
}
|
|
2027
|
+
finally {
|
|
2028
|
+
if (loadingMore) {
|
|
2029
|
+
historyLoadingMoreRequestCountRef.current = Math.max(0, historyLoadingMoreRequestCountRef.current - 1);
|
|
2030
|
+
if (historyLoadingMoreRequestCountRef.current === 0) {
|
|
2031
|
+
setIsHistoryLoadingMore(false);
|
|
2032
|
+
}
|
|
2033
|
+
}
|
|
2034
|
+
else {
|
|
2035
|
+
historyLoadingRequestCountRef.current = Math.max(0, historyLoadingRequestCountRef.current - 1);
|
|
2036
|
+
if (historyLoadingRequestCountRef.current === 0) {
|
|
2037
|
+
setIsHistoryLoading(false);
|
|
2038
|
+
}
|
|
2039
|
+
}
|
|
2040
|
+
}
|
|
2041
|
+
}, []);
|
|
1932
2042
|
useEffect(() => {
|
|
1933
2043
|
// Read fresh page from the mutable slot context ref chain.
|
|
1934
2044
|
// The slot context uses a stable ref that is mutated in-place (see editorSlotContext.ts),
|
|
@@ -1949,11 +2059,19 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
1949
2059
|
const loadHistory = useDebouncedCallback(async () => {
|
|
1950
2060
|
if (!sessionId)
|
|
1951
2061
|
return;
|
|
1952
|
-
const
|
|
2062
|
+
const requestedLimit = GLOBAL_SESSION_HISTORY_LIMIT;
|
|
2063
|
+
const result = await getEditHistoryWithLoading({
|
|
2064
|
+
sessionId,
|
|
2065
|
+
limit: requestedLimit + 1,
|
|
2066
|
+
});
|
|
1953
2067
|
if (handleErrorResult(result, ui, state))
|
|
1954
2068
|
return;
|
|
2069
|
+
const nextOperations = normalizeEditHistoryPayload(result.data);
|
|
2070
|
+
const limitedOperations = nextOperations.slice(0, requestedLimit);
|
|
2071
|
+
setGlobalHistoryLimit(requestedLimit);
|
|
2072
|
+
setCanLoadMoreHistory(nextOperations.length > requestedLimit);
|
|
1955
2073
|
setEditHistory((prev) => {
|
|
1956
|
-
const next =
|
|
2074
|
+
const next = limitedOperations;
|
|
1957
2075
|
if (!prev.length)
|
|
1958
2076
|
return sortEditHistoryByDateDesc(next);
|
|
1959
2077
|
if (!next.length)
|
|
@@ -2004,7 +2122,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
2004
2122
|
return sortEditHistoryByDateDesc(merged);
|
|
2005
2123
|
});
|
|
2006
2124
|
}, 600);
|
|
2007
|
-
const refreshHistory = useCallback(async (mode, filterBySession, filterByLanguage) => {
|
|
2125
|
+
const refreshHistory = useCallback(async (mode, filterBySession, filterByLanguage, historyLimitOverride, loadingMode = "initial") => {
|
|
2008
2126
|
const currentMode = mode || historyMode;
|
|
2009
2127
|
// Use showOnlyMyChanges state if filterBySession not explicitly provided
|
|
2010
2128
|
const shouldFilterBySession = filterBySession !== undefined ? filterBySession : showOnlyMyChanges;
|
|
@@ -2045,14 +2163,16 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
2045
2163
|
if (currentMode === "global") {
|
|
2046
2164
|
// Global mode: optionally filter by session and/or language
|
|
2047
2165
|
const currentLanguage = item?.descriptor?.language || currentItemDescriptor?.language;
|
|
2048
|
-
const
|
|
2166
|
+
const requestedLimit = historyLimitOverride ??
|
|
2167
|
+
getInitialGlobalHistoryLimit(shouldFilterBySession);
|
|
2168
|
+
const result = await getEditHistoryWithLoading({
|
|
2049
2169
|
sessionId: shouldFilterBySession ? sessionId : undefined,
|
|
2050
|
-
limit:
|
|
2170
|
+
limit: requestedLimit + 1,
|
|
2051
2171
|
language: shouldFilterByLanguage && currentLanguage
|
|
2052
2172
|
? currentLanguage
|
|
2053
2173
|
: undefined,
|
|
2054
2174
|
query: historyQuery,
|
|
2055
|
-
});
|
|
2175
|
+
}, loadingMode);
|
|
2056
2176
|
if (handleErrorResult(result, ui, state)) {
|
|
2057
2177
|
console.error("[EditorShell] Failed to load history:", result);
|
|
2058
2178
|
return;
|
|
@@ -2060,8 +2180,12 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
2060
2180
|
if (isStaleHistoryResponse()) {
|
|
2061
2181
|
return;
|
|
2062
2182
|
}
|
|
2183
|
+
const nextOperations = normalizeEditHistoryPayload(result.data);
|
|
2184
|
+
const limitedOperations = nextOperations.slice(0, requestedLimit);
|
|
2185
|
+
setGlobalHistoryLimit(requestedLimit);
|
|
2186
|
+
setCanLoadMoreHistory(nextOperations.length > requestedLimit);
|
|
2063
2187
|
setEditHistory((prev) => {
|
|
2064
|
-
const next =
|
|
2188
|
+
const next = limitedOperations;
|
|
2065
2189
|
const scope = {
|
|
2066
2190
|
mode: currentMode,
|
|
2067
2191
|
filterBySession: shouldFilterBySession,
|
|
@@ -2130,19 +2254,24 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
2130
2254
|
if (!currentItem) {
|
|
2131
2255
|
console.warn(`[EditorShell] Cannot load ${currentMode} history: no item loaded`);
|
|
2132
2256
|
setEditHistory([]);
|
|
2257
|
+
setCanLoadMoreHistory(false);
|
|
2133
2258
|
return;
|
|
2134
2259
|
}
|
|
2135
2260
|
// For page-centric/timeline: fetch all versions (itemId + language only)
|
|
2136
2261
|
// For current-version: fetch specific version (itemId + language + version)
|
|
2137
2262
|
const itemFilter = currentMode === "page-centric" || currentMode === "timeline"
|
|
2138
|
-
? {
|
|
2263
|
+
? {
|
|
2264
|
+
id: currentItem.id,
|
|
2265
|
+
language: currentItem.language,
|
|
2266
|
+
version: 0,
|
|
2267
|
+
} // version 0 signals "all versions" to backend
|
|
2139
2268
|
: currentItem;
|
|
2140
2269
|
// Request item-scoped history, optionally filtered by session
|
|
2141
|
-
const result = await
|
|
2270
|
+
const result = await getEditHistoryWithLoading({
|
|
2142
2271
|
item: itemFilter,
|
|
2143
2272
|
sessionId: shouldFilterBySession ? sessionId : undefined,
|
|
2144
2273
|
query: historyQuery,
|
|
2145
|
-
});
|
|
2274
|
+
}, loadingMode);
|
|
2146
2275
|
if (handleErrorResult(result, ui, state)) {
|
|
2147
2276
|
console.error("[EditorShell] Failed to load item history:", result);
|
|
2148
2277
|
return;
|
|
@@ -2150,6 +2279,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
2150
2279
|
if (isStaleHistoryResponse()) {
|
|
2151
2280
|
return;
|
|
2152
2281
|
}
|
|
2282
|
+
setCanLoadMoreHistory(false);
|
|
2153
2283
|
let operations = normalizeEditHistoryPayload(result.data);
|
|
2154
2284
|
// Client-side version filtering for current-version mode
|
|
2155
2285
|
if (currentMode === "current-version") {
|
|
@@ -2232,10 +2362,26 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
2232
2362
|
historySearchQuery,
|
|
2233
2363
|
item,
|
|
2234
2364
|
currentItemDescriptor,
|
|
2365
|
+
getEditHistoryWithLoading,
|
|
2235
2366
|
matchesHistoryScope,
|
|
2236
2367
|
normalizeEditHistoryPayload,
|
|
2237
2368
|
sortEditHistoryByDateDesc,
|
|
2238
2369
|
]);
|
|
2370
|
+
const loadMoreHistory = useCallback(async () => {
|
|
2371
|
+
if (historyMode !== "global" || isHistoryLoading || isHistoryLoadingMore) {
|
|
2372
|
+
return;
|
|
2373
|
+
}
|
|
2374
|
+
const nextLimit = globalHistoryLimit + getGlobalHistoryLoadMoreIncrement(showOnlyMyChanges);
|
|
2375
|
+
await refreshHistory("global", showOnlyMyChanges, filterByCurrentLanguage, nextLimit, "more");
|
|
2376
|
+
}, [
|
|
2377
|
+
filterByCurrentLanguage,
|
|
2378
|
+
globalHistoryLimit,
|
|
2379
|
+
historyMode,
|
|
2380
|
+
isHistoryLoading,
|
|
2381
|
+
isHistoryLoadingMore,
|
|
2382
|
+
refreshHistory,
|
|
2383
|
+
showOnlyMyChanges,
|
|
2384
|
+
]);
|
|
2239
2385
|
// Debounced history refresh to avoid hammering `/parhelia/editHistory` on rapid UI changes.
|
|
2240
2386
|
const debouncedRefreshHistory = useDebouncedCallback((mode) => {
|
|
2241
2387
|
void refreshHistory(mode);
|
|
@@ -2289,11 +2435,14 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
2289
2435
|
// from being displayed while the new data is loading
|
|
2290
2436
|
if (prevHistoryModeRef.current !== historyMode) {
|
|
2291
2437
|
setEditHistory([]);
|
|
2438
|
+
setCanLoadMoreHistory(false);
|
|
2292
2439
|
prevHistoryModeRef.current = historyMode;
|
|
2293
2440
|
}
|
|
2294
2441
|
// Cancel any in-flight scheduled refresh before deciding what to do next.
|
|
2295
2442
|
debouncedRefreshHistoryRef.current.cancel();
|
|
2296
2443
|
if (historyMode === "global" && sessionId) {
|
|
2444
|
+
setGlobalHistoryLimit(getInitialGlobalHistoryLimit(showOnlyMyChanges));
|
|
2445
|
+
setCanLoadMoreHistory(false);
|
|
2297
2446
|
// Use refreshHistory for immediate load on first initialization; debounce thereafter.
|
|
2298
2447
|
if (!historyInitialLoadDoneRef.current) {
|
|
2299
2448
|
historyInitialLoadDoneRef.current = true;
|
|
@@ -2304,6 +2453,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
2304
2453
|
}
|
|
2305
2454
|
}
|
|
2306
2455
|
else if (historyMode !== "global" && currentItemDescriptor) {
|
|
2456
|
+
setCanLoadMoreHistory(false);
|
|
2307
2457
|
// Always load immediately for page-centric/current-version/timeline so we don't show
|
|
2308
2458
|
// an empty history list for the debounce window (e.g. 600ms). The effect only runs on
|
|
2309
2459
|
// mode or item id/lang/version change, not on every keystroke, so this avoids flaky
|
|
@@ -2316,6 +2466,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
2316
2466
|
else if (historyMode !== "global" && !currentItemDescriptor) {
|
|
2317
2467
|
// Clear history if no item loaded in page-centric modes
|
|
2318
2468
|
setEditHistory([]);
|
|
2469
|
+
setCanLoadMoreHistory(false);
|
|
2319
2470
|
}
|
|
2320
2471
|
// Note: refreshHistory and debouncedRefreshHistory are accessed via refs to avoid
|
|
2321
2472
|
// re-running this effect when contentEditorItem changes (which would happen on every keystroke).
|
|
@@ -2947,17 +3098,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
2947
3098
|
}
|
|
2948
3099
|
}, [currentItemDescriptorRef.current, setItemVersions, setItemLanguages]);
|
|
2949
3100
|
const showErrorToast = useCallback((error) => {
|
|
2950
|
-
|
|
2951
|
-
if (error &&
|
|
2952
|
-
typeof error === "object" &&
|
|
2953
|
-
("summary" in error || "details" in error)) {
|
|
2954
|
-
const { summary, details } = error;
|
|
2955
|
-
toast.error(details || summary || "An error occurred");
|
|
2956
|
-
}
|
|
2957
|
-
else {
|
|
2958
|
-
console.warn("showErrorToast called with unexpected value:", error);
|
|
2959
|
-
toast.error("An error occurred");
|
|
2960
|
-
}
|
|
3101
|
+
showExpandableErrorToast(error);
|
|
2961
3102
|
}, []);
|
|
2962
3103
|
const showInfoToast = useCallback(({ summary, details }) => {
|
|
2963
3104
|
toast.info(details || summary || "Information");
|
|
@@ -3150,9 +3291,9 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
3150
3291
|
requestQuota: requestQuotaAndUpdate,
|
|
3151
3292
|
sendClientInfo,
|
|
3152
3293
|
setSocketDiagnostics,
|
|
3153
|
-
enableWebSocketTransport:
|
|
3154
|
-
enableSseFallback:
|
|
3155
|
-
transportSettingsReady:
|
|
3294
|
+
enableWebSocketTransport: effectiveParheliaSettings?.enableWebSocketTransport ?? true,
|
|
3295
|
+
enableSseFallback: effectiveParheliaSettings?.enableSseFallback ?? true,
|
|
3296
|
+
transportSettingsReady: effectiveParheliaSettingsLoaded === true,
|
|
3156
3297
|
});
|
|
3157
3298
|
useEffect(() => {
|
|
3158
3299
|
const hasMySession = activeSessions.some((s) => s.sessionId === sessionId);
|
|
@@ -4692,6 +4833,10 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
4692
4833
|
setHistorySearchQuery,
|
|
4693
4834
|
refreshHistory,
|
|
4694
4835
|
isRefreshing,
|
|
4836
|
+
isHistoryLoading,
|
|
4837
|
+
canLoadMoreHistory,
|
|
4838
|
+
isHistoryLoadingMore,
|
|
4839
|
+
loadMoreHistory,
|
|
4695
4840
|
activeSessions,
|
|
4696
4841
|
remoteCarets,
|
|
4697
4842
|
unlockField: async () => {
|
|
@@ -4950,7 +5095,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
4950
5095
|
showEditorFormHint,
|
|
4951
5096
|
dismissEditorFormHint,
|
|
4952
5097
|
editorFormToggleButtonRef,
|
|
4953
|
-
showMinimap,
|
|
5098
|
+
showMinimap: effectiveShowMinimap,
|
|
4954
5099
|
setShowMinimap: handleSetShowMinimap,
|
|
4955
5100
|
showHelpTerminal,
|
|
4956
5101
|
setShowHelpTerminal: handleSetShowHelpTerminal,
|
|
@@ -4979,7 +5124,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
4979
5124
|
webSocketMessages,
|
|
4980
5125
|
clearWebSocketMessages: () => setWebSocketMessages([]),
|
|
4981
5126
|
userInfo: userInfo,
|
|
4982
|
-
parheliaSettings,
|
|
5127
|
+
parheliaSettings: effectiveParheliaSettings,
|
|
4983
5128
|
setUserPreferences,
|
|
4984
5129
|
currentWizardId,
|
|
4985
5130
|
setCurrentWizardId,
|
|
@@ -5094,9 +5239,13 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
5094
5239
|
showResolvedComments,
|
|
5095
5240
|
reviews,
|
|
5096
5241
|
userInfo,
|
|
5097
|
-
|
|
5242
|
+
effectiveParheliaSettings,
|
|
5098
5243
|
setUserPreferences,
|
|
5099
5244
|
isRefreshing,
|
|
5245
|
+
isHistoryLoading,
|
|
5246
|
+
canLoadMoreHistory,
|
|
5247
|
+
isHistoryLoadingMore,
|
|
5248
|
+
loadMoreHistory,
|
|
5100
5249
|
favorites,
|
|
5101
5250
|
loadFavorites,
|
|
5102
5251
|
refreshFavorites,
|
|
@@ -5143,7 +5292,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
5143
5292
|
showEditorFormHint,
|
|
5144
5293
|
dismissEditorFormHint,
|
|
5145
5294
|
editorFormToggleButtonRef,
|
|
5146
|
-
|
|
5295
|
+
effectiveShowMinimap,
|
|
5147
5296
|
handleSetShowMinimap,
|
|
5148
5297
|
showHelpTerminal,
|
|
5149
5298
|
toggleHelpTerminal,
|