@parhelia/core 0.1.12909 → 0.1.12911
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/editor/ai/Agents.js +17 -23
- package/dist/editor/ai/Agents.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/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/client/EditorShell.js +177 -19
- package/dist/editor/client/EditorShell.js.map +1 -1
- package/dist/editor/client/editContext.d.ts +5 -1
- package/dist/editor/client/editContext.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/page-editor-chrome/BridgeInlineFormatOverlay.js +6 -5
- package/dist/editor/page-editor-chrome/BridgeInlineFormatOverlay.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 +2 -2
- package/dist/editor/page-viewer/PageViewerFrame.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/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/sidebar/EditHistory.js +11 -3
- package/dist/editor/sidebar/EditHistory.js.map +1 -1
- package/dist/editor/ui/LoadingState.js +4 -4
- package/dist/editor/ui/LoadingState.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/package.json +1 -1
|
@@ -22,6 +22,7 @@ import "react-json-view-lite/dist/index.css";
|
|
|
22
22
|
import { MediaSelector, } from "../media-selector/MediaSelector";
|
|
23
23
|
import { getComponentCommands } from "../commands/componentCommands";
|
|
24
24
|
import { getLanguagesAndVersions, } from "../services/contentService";
|
|
25
|
+
import { getEditorSettings } from "../services/systemService";
|
|
25
26
|
import { getAllFavorites } from "../services/favouritesService";
|
|
26
27
|
import ConfirmationDialog from "../ConfirmationDialog";
|
|
27
28
|
import { getItemDescriptor } from "../utils";
|
|
@@ -67,12 +68,37 @@ import { useGlobalEditorKeyDown } from "./hooks/useGlobalEditorKeyDown";
|
|
|
67
68
|
import { useStartupChecks } from "../settings/status/index";
|
|
68
69
|
import { EditorLoadingOverlay } from "../EditorLoadingOverlay";
|
|
69
70
|
import { FeatureGate, LicenseFeatures, LicenseProvider, LicenseOverlay, } from "../../licensing";
|
|
71
|
+
const GLOBAL_SESSION_HISTORY_LIMIT = 200;
|
|
72
|
+
const GLOBAL_HISTORY_LIMIT = 200;
|
|
73
|
+
const GLOBAL_SESSION_HISTORY_LOAD_MORE_INCREMENT = 50;
|
|
74
|
+
const GLOBAL_HISTORY_LOAD_MORE_INCREMENT = 100;
|
|
75
|
+
function getInitialGlobalHistoryLimit(filterBySession) {
|
|
76
|
+
return filterBySession ? GLOBAL_SESSION_HISTORY_LIMIT : GLOBAL_HISTORY_LIMIT;
|
|
77
|
+
}
|
|
78
|
+
function getGlobalHistoryLoadMoreIncrement(filterBySession) {
|
|
79
|
+
return filterBySession
|
|
80
|
+
? GLOBAL_SESSION_HISTORY_LOAD_MORE_INCREMENT
|
|
81
|
+
: GLOBAL_HISTORY_LOAD_MORE_INCREMENT;
|
|
82
|
+
}
|
|
70
83
|
// Sentinel written to the `sidebar` URL param when the user has explicitly closed
|
|
71
84
|
// every sidebar. Distinguishes "no preference yet" (param absent) from "user wants
|
|
72
85
|
// nothing open" (param present with this value) so reload can honor the user's intent.
|
|
73
86
|
const SIDEBAR_NONE_SENTINEL = "none";
|
|
87
|
+
const PARHELIA_SETTINGS_ITEM_ID = "a2f3c168bb2841ff9673ee7f3cc624af";
|
|
88
|
+
const PARHELIA_SETTINGS_ITEM_PATH = "/sitecore/system/parhelia/settings";
|
|
89
|
+
const PARHELIA_SHOW_MINIMAP_FIELD_ID = "e75976d2179e4578b4140147b7525fa5";
|
|
74
90
|
const sidebarUrlValue = (ids) => ids.length ? ids.join(",") : SIDEBAR_NONE_SENTINEL;
|
|
75
91
|
// moved to hooks/useQuota
|
|
92
|
+
function isParheliaSettingsSnapshotChange(changes) {
|
|
93
|
+
return changes.some((change) => {
|
|
94
|
+
const changedItemId = cleanId(change.item?.id);
|
|
95
|
+
const changedItemPath = change.item?.path?.toLowerCase();
|
|
96
|
+
const changedFieldIds = change.changes.fields?.map((fieldId) => cleanId(fieldId));
|
|
97
|
+
return (changedItemId === PARHELIA_SETTINGS_ITEM_ID ||
|
|
98
|
+
changedItemPath === PARHELIA_SETTINGS_ITEM_PATH ||
|
|
99
|
+
changedFieldIds?.includes(PARHELIA_SHOW_MINIMAP_FIELD_ID));
|
|
100
|
+
});
|
|
101
|
+
}
|
|
76
102
|
function getInitialOpenSidebars(configuration, workspaceId) {
|
|
77
103
|
const workspace = configuration.editor.workspaces?.find((candidate) => candidate.id === workspaceId);
|
|
78
104
|
if (workspace?.supportsSidebars && workspace.defaultSidebars?.length) {
|
|
@@ -143,6 +169,10 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
143
169
|
const router = useRouter();
|
|
144
170
|
const pathname = usePathname();
|
|
145
171
|
const searchParams = useSearchParams();
|
|
172
|
+
const [effectiveParheliaSettings, setEffectiveParheliaSettings] = useState(parheliaSettings);
|
|
173
|
+
const [effectiveParheliaSettingsLoaded, setEffectiveParheliaSettingsLoaded] = useState(parheliaSettingsLoaded === true);
|
|
174
|
+
const parheliaSettingsRefreshInFlightRef = useRef(null);
|
|
175
|
+
const minimapEnabledInSettings = effectiveParheliaSettings?.showMinimap !== false;
|
|
146
176
|
const [selection, setSelection] = useState([]);
|
|
147
177
|
const [contentTreeSelection, setContentTreeSelection] = useState([]);
|
|
148
178
|
const [selectedForInsertion, setSelectedForInsertion] = useState("");
|
|
@@ -159,6 +189,34 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
159
189
|
const confirmationDialogRef = useRef(null);
|
|
160
190
|
const contextMenuRef = useRef(null);
|
|
161
191
|
const editContextRef = useRef(undefined);
|
|
192
|
+
useEffect(() => {
|
|
193
|
+
setEffectiveParheliaSettings(parheliaSettings);
|
|
194
|
+
setEffectiveParheliaSettingsLoaded(parheliaSettingsLoaded === true);
|
|
195
|
+
}, [parheliaSettings, parheliaSettingsLoaded]);
|
|
196
|
+
const refreshParheliaSettings = useCallback(async () => {
|
|
197
|
+
if (parheliaSettingsRefreshInFlightRef.current) {
|
|
198
|
+
return parheliaSettingsRefreshInFlightRef.current;
|
|
199
|
+
}
|
|
200
|
+
const refresh = getEditorSettings()
|
|
201
|
+
.then((result) => {
|
|
202
|
+
if (result.type === "success" && result.data) {
|
|
203
|
+
setEffectiveParheliaSettings(result.data);
|
|
204
|
+
setEffectiveParheliaSettingsLoaded(true);
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
console.warn("Failed to refresh Parhelia settings:", result.summary || result.details);
|
|
208
|
+
})
|
|
209
|
+
.catch((error) => {
|
|
210
|
+
console.error("Failed to refresh Parhelia settings:", error);
|
|
211
|
+
});
|
|
212
|
+
parheliaSettingsRefreshInFlightRef.current = refresh;
|
|
213
|
+
void refresh.finally(() => {
|
|
214
|
+
if (parheliaSettingsRefreshInFlightRef.current === refresh) {
|
|
215
|
+
parheliaSettingsRefreshInFlightRef.current = null;
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
return refresh;
|
|
219
|
+
}, []);
|
|
162
220
|
const [currentOverlay, setCurrentOverlay] = useState();
|
|
163
221
|
const [contextMenuSource, setContextMenuSource] = useState();
|
|
164
222
|
const [item, setItem] = useState();
|
|
@@ -192,6 +250,12 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
192
250
|
const [showOnlyMyChanges, setShowOnlyMyChanges] = useState(true);
|
|
193
251
|
const [filterByCurrentLanguage, setFilterByCurrentLanguage] = useState(true);
|
|
194
252
|
const [historySearchQuery, setHistorySearchQuery] = useState("");
|
|
253
|
+
const [isHistoryLoading, setIsHistoryLoading] = useState(false);
|
|
254
|
+
const [isHistoryLoadingMore, setIsHistoryLoadingMore] = useState(false);
|
|
255
|
+
const [canLoadMoreHistory, setCanLoadMoreHistory] = useState(false);
|
|
256
|
+
const [globalHistoryLimit, setGlobalHistoryLimit] = useState(GLOBAL_SESSION_HISTORY_LIMIT);
|
|
257
|
+
const historyLoadingRequestCountRef = useRef(0);
|
|
258
|
+
const historyLoadingMoreRequestCountRef = useRef(0);
|
|
195
259
|
const [recentEdits, setRecentEdits] = useState([]);
|
|
196
260
|
const addRecentEdit = useCallback((edit) => {
|
|
197
261
|
setRecentEdits((prevEditedFields) => {
|
|
@@ -696,6 +760,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
696
760
|
const [editorFormHintVisible, setEditorFormHintVisible] = useState(false);
|
|
697
761
|
const editorFormToggleButtonRef = useRef(null);
|
|
698
762
|
const [showMinimap, setShowMinimap] = useState(userPreferences.showMinimap ?? true);
|
|
763
|
+
const effectiveShowMinimap = minimapEnabledInSettings && showMinimap;
|
|
699
764
|
const [showHelpTerminal, setShowHelpTerminal] = useState(false);
|
|
700
765
|
const [helpTerminalInitialPrompt, setHelpTerminalInitialPrompt] = useState(undefined);
|
|
701
766
|
const [helpTerminalProfileName, setHelpTerminalProfileName] = useState(undefined);
|
|
@@ -803,13 +868,29 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
803
868
|
const [currentPageItem, setCurrentPageItem] = useState();
|
|
804
869
|
// Create itemsRepository with current page item (will be updated when page loads)
|
|
805
870
|
const itemsRepository = useItemsRepository(addRecentEdit, currentPageItem, getFieldModificationStores);
|
|
871
|
+
// The fallback is a null-object: it backs activePageViewContext only when no slot
|
|
872
|
+
// context is registered (the startup gap, or all slots closed). Its *resolved page* is
|
|
873
|
+
// rendered on screen ONLY by the fullscreen branch (the <PageViewerFrame> in the
|
|
874
|
+
// `fullscreen ? (...)` render); in non-fullscreen the visible iframe comes from the
|
|
875
|
+
// slot's own primaryPageViewContext. So only feed it a descriptor when it is actually
|
|
876
|
+
// the render source — otherwise it pointlessly re-resolves the page the slot already
|
|
877
|
+
// resolves, producing a duplicate /parhelia/resolve at startup.
|
|
878
|
+
const hasActiveSlotContext = !!(activeSlotId && slotContexts.get(activeSlotId));
|
|
806
879
|
const fallbackPageViewContext = usePageViewContext({
|
|
807
|
-
pageItemDescriptor: currentItemDescriptor,
|
|
880
|
+
pageItemDescriptor: fullscreen && !hasActiveSlotContext ? currentItemDescriptor : undefined,
|
|
808
881
|
itemsRepository,
|
|
809
882
|
configuration,
|
|
810
|
-
parheliaSettings,
|
|
883
|
+
parheliaSettings: effectiveParheliaSettings,
|
|
811
884
|
layoutMode,
|
|
812
885
|
});
|
|
886
|
+
useEffect(() => {
|
|
887
|
+
return itemsRepository.subscribeItemsChanged((changes) => {
|
|
888
|
+
const persistedChanges = changes.filter((change) => change.source !== "local-field-update");
|
|
889
|
+
if (isParheliaSettingsSnapshotChange(persistedChanges)) {
|
|
890
|
+
void refreshParheliaSettings();
|
|
891
|
+
}
|
|
892
|
+
});
|
|
893
|
+
}, [itemsRepository, refreshParheliaSettings]);
|
|
813
894
|
const registerSlotContext = useCallback((slotId, ctx) => {
|
|
814
895
|
setSlotContexts((prev) => {
|
|
815
896
|
if (prev.get(slotId) === ctx)
|
|
@@ -1929,6 +2010,34 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
1929
2010
|
}
|
|
1930
2011
|
return [];
|
|
1931
2012
|
}, []);
|
|
2013
|
+
const getEditHistoryWithLoading = useCallback(async (options, loadingMode = "initial") => {
|
|
2014
|
+
const loadingMore = loadingMode === "more";
|
|
2015
|
+
if (loadingMore) {
|
|
2016
|
+
historyLoadingMoreRequestCountRef.current += 1;
|
|
2017
|
+
setIsHistoryLoadingMore(true);
|
|
2018
|
+
}
|
|
2019
|
+
else {
|
|
2020
|
+
historyLoadingRequestCountRef.current += 1;
|
|
2021
|
+
setIsHistoryLoading(true);
|
|
2022
|
+
}
|
|
2023
|
+
try {
|
|
2024
|
+
return await getEditHistory(options);
|
|
2025
|
+
}
|
|
2026
|
+
finally {
|
|
2027
|
+
if (loadingMore) {
|
|
2028
|
+
historyLoadingMoreRequestCountRef.current = Math.max(0, historyLoadingMoreRequestCountRef.current - 1);
|
|
2029
|
+
if (historyLoadingMoreRequestCountRef.current === 0) {
|
|
2030
|
+
setIsHistoryLoadingMore(false);
|
|
2031
|
+
}
|
|
2032
|
+
}
|
|
2033
|
+
else {
|
|
2034
|
+
historyLoadingRequestCountRef.current = Math.max(0, historyLoadingRequestCountRef.current - 1);
|
|
2035
|
+
if (historyLoadingRequestCountRef.current === 0) {
|
|
2036
|
+
setIsHistoryLoading(false);
|
|
2037
|
+
}
|
|
2038
|
+
}
|
|
2039
|
+
}
|
|
2040
|
+
}, []);
|
|
1932
2041
|
useEffect(() => {
|
|
1933
2042
|
// Read fresh page from the mutable slot context ref chain.
|
|
1934
2043
|
// The slot context uses a stable ref that is mutated in-place (see editorSlotContext.ts),
|
|
@@ -1949,11 +2058,19 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
1949
2058
|
const loadHistory = useDebouncedCallback(async () => {
|
|
1950
2059
|
if (!sessionId)
|
|
1951
2060
|
return;
|
|
1952
|
-
const
|
|
2061
|
+
const requestedLimit = GLOBAL_SESSION_HISTORY_LIMIT;
|
|
2062
|
+
const result = await getEditHistoryWithLoading({
|
|
2063
|
+
sessionId,
|
|
2064
|
+
limit: requestedLimit + 1,
|
|
2065
|
+
});
|
|
1953
2066
|
if (handleErrorResult(result, ui, state))
|
|
1954
2067
|
return;
|
|
2068
|
+
const nextOperations = normalizeEditHistoryPayload(result.data);
|
|
2069
|
+
const limitedOperations = nextOperations.slice(0, requestedLimit);
|
|
2070
|
+
setGlobalHistoryLimit(requestedLimit);
|
|
2071
|
+
setCanLoadMoreHistory(nextOperations.length > requestedLimit);
|
|
1955
2072
|
setEditHistory((prev) => {
|
|
1956
|
-
const next =
|
|
2073
|
+
const next = limitedOperations;
|
|
1957
2074
|
if (!prev.length)
|
|
1958
2075
|
return sortEditHistoryByDateDesc(next);
|
|
1959
2076
|
if (!next.length)
|
|
@@ -2004,7 +2121,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
2004
2121
|
return sortEditHistoryByDateDesc(merged);
|
|
2005
2122
|
});
|
|
2006
2123
|
}, 600);
|
|
2007
|
-
const refreshHistory = useCallback(async (mode, filterBySession, filterByLanguage) => {
|
|
2124
|
+
const refreshHistory = useCallback(async (mode, filterBySession, filterByLanguage, historyLimitOverride, loadingMode = "initial") => {
|
|
2008
2125
|
const currentMode = mode || historyMode;
|
|
2009
2126
|
// Use showOnlyMyChanges state if filterBySession not explicitly provided
|
|
2010
2127
|
const shouldFilterBySession = filterBySession !== undefined ? filterBySession : showOnlyMyChanges;
|
|
@@ -2045,14 +2162,16 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
2045
2162
|
if (currentMode === "global") {
|
|
2046
2163
|
// Global mode: optionally filter by session and/or language
|
|
2047
2164
|
const currentLanguage = item?.descriptor?.language || currentItemDescriptor?.language;
|
|
2048
|
-
const
|
|
2165
|
+
const requestedLimit = historyLimitOverride ??
|
|
2166
|
+
getInitialGlobalHistoryLimit(shouldFilterBySession);
|
|
2167
|
+
const result = await getEditHistoryWithLoading({
|
|
2049
2168
|
sessionId: shouldFilterBySession ? sessionId : undefined,
|
|
2050
|
-
limit:
|
|
2169
|
+
limit: requestedLimit + 1,
|
|
2051
2170
|
language: shouldFilterByLanguage && currentLanguage
|
|
2052
2171
|
? currentLanguage
|
|
2053
2172
|
: undefined,
|
|
2054
2173
|
query: historyQuery,
|
|
2055
|
-
});
|
|
2174
|
+
}, loadingMode);
|
|
2056
2175
|
if (handleErrorResult(result, ui, state)) {
|
|
2057
2176
|
console.error("[EditorShell] Failed to load history:", result);
|
|
2058
2177
|
return;
|
|
@@ -2060,8 +2179,12 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
2060
2179
|
if (isStaleHistoryResponse()) {
|
|
2061
2180
|
return;
|
|
2062
2181
|
}
|
|
2182
|
+
const nextOperations = normalizeEditHistoryPayload(result.data);
|
|
2183
|
+
const limitedOperations = nextOperations.slice(0, requestedLimit);
|
|
2184
|
+
setGlobalHistoryLimit(requestedLimit);
|
|
2185
|
+
setCanLoadMoreHistory(nextOperations.length > requestedLimit);
|
|
2063
2186
|
setEditHistory((prev) => {
|
|
2064
|
-
const next =
|
|
2187
|
+
const next = limitedOperations;
|
|
2065
2188
|
const scope = {
|
|
2066
2189
|
mode: currentMode,
|
|
2067
2190
|
filterBySession: shouldFilterBySession,
|
|
@@ -2130,19 +2253,24 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
2130
2253
|
if (!currentItem) {
|
|
2131
2254
|
console.warn(`[EditorShell] Cannot load ${currentMode} history: no item loaded`);
|
|
2132
2255
|
setEditHistory([]);
|
|
2256
|
+
setCanLoadMoreHistory(false);
|
|
2133
2257
|
return;
|
|
2134
2258
|
}
|
|
2135
2259
|
// For page-centric/timeline: fetch all versions (itemId + language only)
|
|
2136
2260
|
// For current-version: fetch specific version (itemId + language + version)
|
|
2137
2261
|
const itemFilter = currentMode === "page-centric" || currentMode === "timeline"
|
|
2138
|
-
? {
|
|
2262
|
+
? {
|
|
2263
|
+
id: currentItem.id,
|
|
2264
|
+
language: currentItem.language,
|
|
2265
|
+
version: 0,
|
|
2266
|
+
} // version 0 signals "all versions" to backend
|
|
2139
2267
|
: currentItem;
|
|
2140
2268
|
// Request item-scoped history, optionally filtered by session
|
|
2141
|
-
const result = await
|
|
2269
|
+
const result = await getEditHistoryWithLoading({
|
|
2142
2270
|
item: itemFilter,
|
|
2143
2271
|
sessionId: shouldFilterBySession ? sessionId : undefined,
|
|
2144
2272
|
query: historyQuery,
|
|
2145
|
-
});
|
|
2273
|
+
}, loadingMode);
|
|
2146
2274
|
if (handleErrorResult(result, ui, state)) {
|
|
2147
2275
|
console.error("[EditorShell] Failed to load item history:", result);
|
|
2148
2276
|
return;
|
|
@@ -2150,6 +2278,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
2150
2278
|
if (isStaleHistoryResponse()) {
|
|
2151
2279
|
return;
|
|
2152
2280
|
}
|
|
2281
|
+
setCanLoadMoreHistory(false);
|
|
2153
2282
|
let operations = normalizeEditHistoryPayload(result.data);
|
|
2154
2283
|
// Client-side version filtering for current-version mode
|
|
2155
2284
|
if (currentMode === "current-version") {
|
|
@@ -2232,10 +2361,26 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
2232
2361
|
historySearchQuery,
|
|
2233
2362
|
item,
|
|
2234
2363
|
currentItemDescriptor,
|
|
2364
|
+
getEditHistoryWithLoading,
|
|
2235
2365
|
matchesHistoryScope,
|
|
2236
2366
|
normalizeEditHistoryPayload,
|
|
2237
2367
|
sortEditHistoryByDateDesc,
|
|
2238
2368
|
]);
|
|
2369
|
+
const loadMoreHistory = useCallback(async () => {
|
|
2370
|
+
if (historyMode !== "global" || isHistoryLoading || isHistoryLoadingMore) {
|
|
2371
|
+
return;
|
|
2372
|
+
}
|
|
2373
|
+
const nextLimit = globalHistoryLimit + getGlobalHistoryLoadMoreIncrement(showOnlyMyChanges);
|
|
2374
|
+
await refreshHistory("global", showOnlyMyChanges, filterByCurrentLanguage, nextLimit, "more");
|
|
2375
|
+
}, [
|
|
2376
|
+
filterByCurrentLanguage,
|
|
2377
|
+
globalHistoryLimit,
|
|
2378
|
+
historyMode,
|
|
2379
|
+
isHistoryLoading,
|
|
2380
|
+
isHistoryLoadingMore,
|
|
2381
|
+
refreshHistory,
|
|
2382
|
+
showOnlyMyChanges,
|
|
2383
|
+
]);
|
|
2239
2384
|
// Debounced history refresh to avoid hammering `/parhelia/editHistory` on rapid UI changes.
|
|
2240
2385
|
const debouncedRefreshHistory = useDebouncedCallback((mode) => {
|
|
2241
2386
|
void refreshHistory(mode);
|
|
@@ -2289,11 +2434,14 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
2289
2434
|
// from being displayed while the new data is loading
|
|
2290
2435
|
if (prevHistoryModeRef.current !== historyMode) {
|
|
2291
2436
|
setEditHistory([]);
|
|
2437
|
+
setCanLoadMoreHistory(false);
|
|
2292
2438
|
prevHistoryModeRef.current = historyMode;
|
|
2293
2439
|
}
|
|
2294
2440
|
// Cancel any in-flight scheduled refresh before deciding what to do next.
|
|
2295
2441
|
debouncedRefreshHistoryRef.current.cancel();
|
|
2296
2442
|
if (historyMode === "global" && sessionId) {
|
|
2443
|
+
setGlobalHistoryLimit(getInitialGlobalHistoryLimit(showOnlyMyChanges));
|
|
2444
|
+
setCanLoadMoreHistory(false);
|
|
2297
2445
|
// Use refreshHistory for immediate load on first initialization; debounce thereafter.
|
|
2298
2446
|
if (!historyInitialLoadDoneRef.current) {
|
|
2299
2447
|
historyInitialLoadDoneRef.current = true;
|
|
@@ -2304,6 +2452,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
2304
2452
|
}
|
|
2305
2453
|
}
|
|
2306
2454
|
else if (historyMode !== "global" && currentItemDescriptor) {
|
|
2455
|
+
setCanLoadMoreHistory(false);
|
|
2307
2456
|
// Always load immediately for page-centric/current-version/timeline so we don't show
|
|
2308
2457
|
// an empty history list for the debounce window (e.g. 600ms). The effect only runs on
|
|
2309
2458
|
// mode or item id/lang/version change, not on every keystroke, so this avoids flaky
|
|
@@ -2316,6 +2465,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
2316
2465
|
else if (historyMode !== "global" && !currentItemDescriptor) {
|
|
2317
2466
|
// Clear history if no item loaded in page-centric modes
|
|
2318
2467
|
setEditHistory([]);
|
|
2468
|
+
setCanLoadMoreHistory(false);
|
|
2319
2469
|
}
|
|
2320
2470
|
// Note: refreshHistory and debouncedRefreshHistory are accessed via refs to avoid
|
|
2321
2471
|
// re-running this effect when contentEditorItem changes (which would happen on every keystroke).
|
|
@@ -3150,9 +3300,9 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
3150
3300
|
requestQuota: requestQuotaAndUpdate,
|
|
3151
3301
|
sendClientInfo,
|
|
3152
3302
|
setSocketDiagnostics,
|
|
3153
|
-
enableWebSocketTransport:
|
|
3154
|
-
enableSseFallback:
|
|
3155
|
-
transportSettingsReady:
|
|
3303
|
+
enableWebSocketTransport: effectiveParheliaSettings?.enableWebSocketTransport ?? true,
|
|
3304
|
+
enableSseFallback: effectiveParheliaSettings?.enableSseFallback ?? true,
|
|
3305
|
+
transportSettingsReady: effectiveParheliaSettingsLoaded === true,
|
|
3156
3306
|
});
|
|
3157
3307
|
useEffect(() => {
|
|
3158
3308
|
const hasMySession = activeSessions.some((s) => s.sessionId === sessionId);
|
|
@@ -4692,6 +4842,10 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
4692
4842
|
setHistorySearchQuery,
|
|
4693
4843
|
refreshHistory,
|
|
4694
4844
|
isRefreshing,
|
|
4845
|
+
isHistoryLoading,
|
|
4846
|
+
canLoadMoreHistory,
|
|
4847
|
+
isHistoryLoadingMore,
|
|
4848
|
+
loadMoreHistory,
|
|
4695
4849
|
activeSessions,
|
|
4696
4850
|
remoteCarets,
|
|
4697
4851
|
unlockField: async () => {
|
|
@@ -4950,7 +5104,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
4950
5104
|
showEditorFormHint,
|
|
4951
5105
|
dismissEditorFormHint,
|
|
4952
5106
|
editorFormToggleButtonRef,
|
|
4953
|
-
showMinimap,
|
|
5107
|
+
showMinimap: effectiveShowMinimap,
|
|
4954
5108
|
setShowMinimap: handleSetShowMinimap,
|
|
4955
5109
|
showHelpTerminal,
|
|
4956
5110
|
setShowHelpTerminal: handleSetShowHelpTerminal,
|
|
@@ -4979,7 +5133,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
4979
5133
|
webSocketMessages,
|
|
4980
5134
|
clearWebSocketMessages: () => setWebSocketMessages([]),
|
|
4981
5135
|
userInfo: userInfo,
|
|
4982
|
-
parheliaSettings,
|
|
5136
|
+
parheliaSettings: effectiveParheliaSettings,
|
|
4983
5137
|
setUserPreferences,
|
|
4984
5138
|
currentWizardId,
|
|
4985
5139
|
setCurrentWizardId,
|
|
@@ -5094,9 +5248,13 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
5094
5248
|
showResolvedComments,
|
|
5095
5249
|
reviews,
|
|
5096
5250
|
userInfo,
|
|
5097
|
-
|
|
5251
|
+
effectiveParheliaSettings,
|
|
5098
5252
|
setUserPreferences,
|
|
5099
5253
|
isRefreshing,
|
|
5254
|
+
isHistoryLoading,
|
|
5255
|
+
canLoadMoreHistory,
|
|
5256
|
+
isHistoryLoadingMore,
|
|
5257
|
+
loadMoreHistory,
|
|
5100
5258
|
favorites,
|
|
5101
5259
|
loadFavorites,
|
|
5102
5260
|
refreshFavorites,
|
|
@@ -5143,7 +5301,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
|
|
|
5143
5301
|
showEditorFormHint,
|
|
5144
5302
|
dismissEditorFormHint,
|
|
5145
5303
|
editorFormToggleButtonRef,
|
|
5146
|
-
|
|
5304
|
+
effectiveShowMinimap,
|
|
5147
5305
|
handleSetShowMinimap,
|
|
5148
5306
|
showHelpTerminal,
|
|
5149
5307
|
toggleHelpTerminal,
|