@parhelia/core 0.1.11151 → 0.1.11180

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.
Files changed (224) hide show
  1. package/dist/agents-view/AgentsInbox.d.ts +2 -1
  2. package/dist/agents-view/AgentsInbox.js +2 -2
  3. package/dist/agents-view/AgentsInbox.js.map +1 -1
  4. package/dist/agents-view/AgentsView.js +30 -1
  5. package/dist/agents-view/AgentsView.js.map +1 -1
  6. package/dist/components/ui/card.d.ts +1 -1
  7. package/dist/components/ui/card.js +1 -1
  8. package/dist/components/ui/card.js.map +1 -1
  9. package/dist/components/ui/paste-button.d.ts +1 -1
  10. package/dist/components/ui/paste-button.js +79 -22
  11. package/dist/components/ui/paste-button.js.map +1 -1
  12. package/dist/config/config.js +83 -51
  13. package/dist/config/config.js.map +1 -1
  14. package/dist/config/types.d.ts +29 -4
  15. package/dist/editor/ContentTree.js +92 -22
  16. package/dist/editor/ContentTree.js.map +1 -1
  17. package/dist/editor/FieldActionsOverlay.d.ts +1 -0
  18. package/dist/editor/FieldActionsOverlay.js +17 -1
  19. package/dist/editor/FieldActionsOverlay.js.map +1 -1
  20. package/dist/editor/FieldListField.js +1 -1
  21. package/dist/editor/FieldListField.js.map +1 -1
  22. package/dist/editor/LinkEditorDialog.js +33 -24
  23. package/dist/editor/LinkEditorDialog.js.map +1 -1
  24. package/dist/editor/MainLayout.js +2 -2
  25. package/dist/editor/MainLayout.js.map +1 -1
  26. package/dist/editor/PictureEditor.js +1 -1
  27. package/dist/editor/PictureEditor.js.map +1 -1
  28. package/dist/editor/ai/AgentTerminal.js +63 -26
  29. package/dist/editor/ai/AgentTerminal.js.map +1 -1
  30. package/dist/editor/ai/Agents.js +7 -2
  31. package/dist/editor/ai/Agents.js.map +1 -1
  32. package/dist/editor/client/EditorShell.js +178 -79
  33. package/dist/editor/client/EditorShell.js.map +1 -1
  34. package/dist/editor/client/OperationDialogContent.d.ts +13 -0
  35. package/dist/editor/client/OperationDialogContent.js +13 -0
  36. package/dist/editor/client/OperationDialogContent.js.map +1 -0
  37. package/dist/editor/client/editContext.d.ts +2 -0
  38. package/dist/editor/client/editContext.js.map +1 -1
  39. package/dist/editor/client/hooks/useGlobalEditorKeyDown.js +5 -2
  40. package/dist/editor/client/hooks/useGlobalEditorKeyDown.js.map +1 -1
  41. package/dist/editor/client/hooks/useQuota.d.ts +4 -0
  42. package/dist/editor/client/hooks/useQuota.js.map +1 -1
  43. package/dist/editor/client/hooks/useSocketMessageHandler.d.ts +2 -2
  44. package/dist/editor/client/hooks/useSocketMessageHandler.js +5 -7
  45. package/dist/editor/client/hooks/useSocketMessageHandler.js.map +1 -1
  46. package/dist/editor/client/operations.d.ts +1 -0
  47. package/dist/editor/client/operations.js +332 -8
  48. package/dist/editor/client/operations.js.map +1 -1
  49. package/dist/editor/client/ui/EditorChrome.js +1 -1
  50. package/dist/editor/client/ui/EditorChrome.js.map +1 -1
  51. package/dist/editor/commands/itemCommands.d.ts +0 -1
  52. package/dist/editor/commands/itemCommands.js +1 -16
  53. package/dist/editor/commands/itemCommands.js.map +1 -1
  54. package/dist/editor/commands/undo.js +6 -2
  55. package/dist/editor/commands/undo.js.map +1 -1
  56. package/dist/editor/menubar/toolbar-sections/ViewportControls.js +1 -1
  57. package/dist/editor/menubar/toolbar-sections/ViewportControls.js.map +1 -1
  58. package/dist/editor/page-editor-chrome/FieldActionIndicator.js +56 -2
  59. package/dist/editor/page-editor-chrome/FieldActionIndicator.js.map +1 -1
  60. package/dist/editor/page-editor-chrome/FrameMenu.js +5 -4
  61. package/dist/editor/page-editor-chrome/FrameMenu.js.map +1 -1
  62. package/dist/editor/page-editor-chrome/PlaceholderDropZones.js +5 -1
  63. package/dist/editor/page-editor-chrome/PlaceholderDropZones.js.map +1 -1
  64. package/dist/editor/page-viewer/PageViewerFrame.js +118 -13
  65. package/dist/editor/page-viewer/PageViewerFrame.js.map +1 -1
  66. package/dist/editor/reviews/CreateReviewDialog.js +1 -1
  67. package/dist/editor/reviews/CreateReviewDialog.js.map +1 -1
  68. package/dist/editor/reviews/DecisionsMatrix.js +1 -1
  69. package/dist/editor/reviews/DecisionsMatrix.js.map +1 -1
  70. package/dist/editor/reviews/ReviewsList.js +1 -1
  71. package/dist/editor/reviews/ReviewsList.js.map +1 -1
  72. package/dist/editor/services/editService.d.ts +20 -3
  73. package/dist/editor/services/editService.js +17 -17
  74. package/dist/editor/services/editService.js.map +1 -1
  75. package/dist/editor/services/indexService.d.ts +4 -1
  76. package/dist/editor/services/indexService.js +12 -0
  77. package/dist/editor/services/indexService.js.map +1 -1
  78. package/dist/editor/services/serviceHelper.js +1 -0
  79. package/dist/editor/services/serviceHelper.js.map +1 -1
  80. package/dist/editor/settings/About.d.ts +1 -0
  81. package/dist/editor/settings/About.js +9 -0
  82. package/dist/editor/settings/About.js.map +1 -0
  83. package/dist/editor/settings/AllAgentsPanel.d.ts +5 -0
  84. package/dist/editor/settings/AllAgentsPanel.js +126 -0
  85. package/dist/editor/settings/AllAgentsPanel.js.map +1 -0
  86. package/dist/editor/settings/IndexOverview.d.ts +1 -0
  87. package/dist/editor/settings/IndexOverview.js +471 -0
  88. package/dist/editor/settings/IndexOverview.js.map +1 -0
  89. package/dist/editor/settings/Info.d.ts +1 -0
  90. package/dist/editor/settings/Info.js +11 -0
  91. package/dist/editor/settings/Info.js.map +1 -0
  92. package/dist/editor/settings/LatestFeedback.d.ts +1 -0
  93. package/dist/editor/settings/LatestFeedback.js +136 -0
  94. package/dist/editor/settings/LatestFeedback.js.map +1 -0
  95. package/dist/editor/settings/QuotaInfo.d.ts +1 -0
  96. package/dist/editor/settings/QuotaInfo.js +102 -0
  97. package/dist/editor/settings/QuotaInfo.js.map +1 -0
  98. package/dist/editor/settings/SettingsMenu.d.ts +1 -0
  99. package/dist/editor/settings/SettingsMenu.js +74 -0
  100. package/dist/editor/settings/SettingsMenu.js.map +1 -0
  101. package/dist/editor/settings/SettingsView.d.ts +1 -0
  102. package/dist/editor/settings/SettingsView.js +85 -0
  103. package/dist/editor/settings/SettingsView.js.map +1 -0
  104. package/dist/editor/settings/Setup.d.ts +1 -0
  105. package/dist/editor/settings/Setup.js +211 -0
  106. package/dist/editor/settings/Setup.js.map +1 -0
  107. package/dist/editor/settings/Status.d.ts +1 -0
  108. package/dist/editor/settings/Status.js +85 -0
  109. package/dist/editor/settings/Status.js.map +1 -0
  110. package/dist/editor/settings/WebSocketMessages.d.ts +1 -0
  111. package/dist/editor/settings/WebSocketMessages.js +71 -0
  112. package/dist/editor/settings/WebSocketMessages.js.map +1 -0
  113. package/dist/editor/settings/panels/AgentsPanel.d.ts +6 -0
  114. package/dist/editor/settings/panels/AgentsPanel.js +186 -0
  115. package/dist/editor/settings/panels/AgentsPanel.js.map +1 -0
  116. package/dist/editor/settings/panels/DatabasePanel.d.ts +6 -0
  117. package/dist/editor/settings/panels/DatabasePanel.js +50 -0
  118. package/dist/editor/settings/panels/DatabasePanel.js.map +1 -0
  119. package/dist/editor/settings/panels/ItemConfigPanel.d.ts +13 -0
  120. package/dist/editor/settings/panels/ItemConfigPanel.js +52 -0
  121. package/dist/editor/settings/panels/ItemConfigPanel.js.map +1 -0
  122. package/dist/editor/settings/panels/ModelsPanel.d.ts +6 -0
  123. package/dist/editor/settings/panels/ModelsPanel.js +269 -0
  124. package/dist/editor/settings/panels/ModelsPanel.js.map +1 -0
  125. package/dist/editor/settings/panels/ProvidersPanel.d.ts +6 -0
  126. package/dist/editor/settings/panels/ProvidersPanel.js +206 -0
  127. package/dist/editor/settings/panels/ProvidersPanel.js.map +1 -0
  128. package/dist/editor/settings/panels/SearchConfigPanel.d.ts +6 -0
  129. package/dist/editor/settings/panels/SearchConfigPanel.js +134 -0
  130. package/dist/editor/settings/panels/SearchConfigPanel.js.map +1 -0
  131. package/dist/editor/settings/panels/SettingsPanel.d.ts +6 -0
  132. package/dist/editor/settings/panels/SettingsPanel.js +39 -0
  133. package/dist/editor/settings/panels/SettingsPanel.js.map +1 -0
  134. package/dist/editor/settings/panels/StatusPanel.d.ts +6 -0
  135. package/dist/editor/settings/panels/StatusPanel.js +141 -0
  136. package/dist/editor/settings/panels/StatusPanel.js.map +1 -0
  137. package/dist/editor/settings/panels/ToolsPanel.d.ts +6 -0
  138. package/dist/editor/settings/panels/ToolsPanel.js +192 -0
  139. package/dist/editor/settings/panels/ToolsPanel.js.map +1 -0
  140. package/dist/editor/settings/panels/index.d.ts +14 -0
  141. package/dist/editor/settings/panels/index.js +15 -0
  142. package/dist/editor/settings/panels/index.js.map +1 -0
  143. package/dist/editor/settings/panels/useSidebarEditor.d.ts +15 -0
  144. package/dist/editor/settings/panels/useSidebarEditor.js +24 -0
  145. package/dist/editor/settings/panels/useSidebarEditor.js.map +1 -0
  146. package/dist/editor/settings/setup-steps/AiSetupStep/EmbeddingsModelSection.d.ts +2 -0
  147. package/dist/editor/settings/setup-steps/AiSetupStep/EmbeddingsModelSection.js +195 -0
  148. package/dist/editor/settings/setup-steps/AiSetupStep/EmbeddingsModelSection.js.map +1 -0
  149. package/dist/editor/settings/setup-steps/AiSetupStep/index.d.ts +2 -0
  150. package/dist/editor/settings/setup-steps/AiSetupStep/index.js +22 -0
  151. package/dist/editor/settings/setup-steps/AiSetupStep/index.js.map +1 -0
  152. package/dist/editor/settings/setup-steps/AiSetupStep/provider/ProviderSection.d.ts +1 -0
  153. package/dist/editor/settings/setup-steps/AiSetupStep/provider/ProviderSection.js +233 -0
  154. package/dist/editor/settings/setup-steps/AiSetupStep/provider/ProviderSection.js.map +1 -0
  155. package/dist/editor/settings/setup-steps/AiSetupStep/required-containers/RequiredContainersList.d.ts +15 -0
  156. package/dist/editor/settings/setup-steps/AiSetupStep/required-containers/RequiredContainersList.js +14 -0
  157. package/dist/editor/settings/setup-steps/AiSetupStep/required-containers/RequiredContainersList.js.map +1 -0
  158. package/dist/editor/settings/setup-steps/AiSetupStep/required-containers/RequiredContainersSection.d.ts +1 -0
  159. package/dist/editor/settings/setup-steps/AiSetupStep/required-containers/RequiredContainersSection.js +94 -0
  160. package/dist/editor/settings/setup-steps/AiSetupStep/required-containers/RequiredContainersSection.js.map +1 -0
  161. package/dist/editor/settings/setup-steps/AiSetupStep/tools/GenerateToolsSection.d.ts +1 -0
  162. package/dist/editor/settings/setup-steps/AiSetupStep/tools/GenerateToolsSection.js +367 -0
  163. package/dist/editor/settings/setup-steps/AiSetupStep/tools/GenerateToolsSection.js.map +1 -0
  164. package/dist/editor/settings/setup-steps/AiSetupStep/types.d.ts +1 -0
  165. package/dist/editor/settings/setup-steps/AiSetupStep/types.js +2 -0
  166. package/dist/editor/settings/setup-steps/AiSetupStep/types.js.map +1 -0
  167. package/dist/editor/settings/setup-steps/AiSetupStep/utils.d.ts +5 -0
  168. package/dist/editor/settings/setup-steps/AiSetupStep/utils.js +44 -0
  169. package/dist/editor/settings/setup-steps/AiSetupStep/utils.js.map +1 -0
  170. package/dist/editor/settings/setup-steps/IndexSetupStep.d.ts +2 -0
  171. package/dist/editor/settings/setup-steps/IndexSetupStep.js +36 -0
  172. package/dist/editor/settings/setup-steps/IndexSetupStep.js.map +1 -0
  173. package/dist/editor/settings/setup-steps/SettingsSetupStep.d.ts +2 -0
  174. package/dist/editor/settings/setup-steps/SettingsSetupStep.js +111 -0
  175. package/dist/editor/settings/setup-steps/SettingsSetupStep.js.map +1 -0
  176. package/dist/editor/settings/setup-steps/SetupOverview.d.ts +14 -0
  177. package/dist/editor/settings/setup-steps/SetupOverview.js +38 -0
  178. package/dist/editor/settings/setup-steps/SetupOverview.js.map +1 -0
  179. package/dist/editor/settings/status/coreStatusChecks.d.ts +25 -0
  180. package/dist/editor/settings/status/coreStatusChecks.js +231 -0
  181. package/dist/editor/settings/status/coreStatusChecks.js.map +1 -0
  182. package/dist/editor/settings/status/index.d.ts +3 -0
  183. package/dist/editor/settings/status/index.js +3 -0
  184. package/dist/editor/settings/status/index.js.map +1 -0
  185. package/dist/editor/settings/status/useStartupChecks.d.ts +17 -0
  186. package/dist/editor/settings/status/useStartupChecks.js +54 -0
  187. package/dist/editor/settings/status/useStartupChecks.js.map +1 -0
  188. package/dist/editor/sidebar/EditHistory.js +18 -14
  189. package/dist/editor/sidebar/EditHistory.js.map +1 -1
  190. package/dist/editor/sidebar/MainContentTree.js +0 -1
  191. package/dist/editor/sidebar/MainContentTree.js.map +1 -1
  192. package/dist/editor/sidebar/OperationItem.js +4 -3
  193. package/dist/editor/sidebar/OperationItem.js.map +1 -1
  194. package/dist/editor/ui/PerfectTree.js +1 -1
  195. package/dist/editor/ui/PerfectTree.js.map +1 -1
  196. package/dist/editor/ui/Section.js +3 -3
  197. package/dist/editor/ui/Section.js.map +1 -1
  198. package/dist/editor/ui/SimpleMenu.js +13 -4
  199. package/dist/editor/ui/SimpleMenu.js.map +1 -1
  200. package/dist/editor/ui/SimpleToolbar.js +1 -1
  201. package/dist/editor/ui/SimpleToolbar.js.map +1 -1
  202. package/dist/editor/utils/keyboardNavigation.js +89 -27
  203. package/dist/editor/utils/keyboardNavigation.js.map +1 -1
  204. package/dist/revision.d.ts +2 -2
  205. package/dist/revision.js +2 -2
  206. package/dist/setup/SetupWizardPage.js +2 -2
  207. package/dist/setup/SetupWizardPage.js.map +1 -1
  208. package/dist/setup/services/setupWizardService.d.ts +132 -12
  209. package/dist/setup/services/setupWizardService.js +82 -6
  210. package/dist/setup/services/setupWizardService.js.map +1 -1
  211. package/dist/setup/wizard/index.d.ts +5 -4
  212. package/dist/setup/wizard/index.js +6 -4
  213. package/dist/setup/wizard/index.js.map +1 -1
  214. package/dist/setup/wizard/steps/AddModelDialog.d.ts +10 -0
  215. package/dist/setup/wizard/steps/AddModelDialog.js +119 -0
  216. package/dist/setup/wizard/steps/AddModelDialog.js.map +1 -0
  217. package/dist/setup/wizard/steps/ImportModelDialog.d.ts +10 -0
  218. package/dist/setup/wizard/steps/ImportModelDialog.js +351 -0
  219. package/dist/setup/wizard/steps/ImportModelDialog.js.map +1 -0
  220. package/dist/splash-screen/ModernSplashScreen.js +1 -1
  221. package/dist/splash-screen/ModernSplashScreen.js.map +1 -1
  222. package/dist/styles.css +183 -10
  223. package/dist/types.d.ts +36 -1
  224. package/package.json +4 -4
@@ -8,7 +8,7 @@ import { useRouter, useSearchParams, usePathname } from "next/navigation";
8
8
  import { findComponent, getComponentById } from "../componentTreeHelper";
9
9
  import { getOperationsContext } from "./operations";
10
10
  import { handleErrorResult } from "./helpers";
11
- import { executeFieldAction as executeFieldServerAction, connectSocket, getEditHistory, getSessionHistory, getAllHistory, releaseFieldLocks, validateItems, } from "../services/editService";
11
+ import { executeFieldAction as executeFieldServerAction, connectSocket, getEditHistory, releaseFieldLocks, validateItems, } from "../services/editService";
12
12
  import { useEditorWebSocket } from "./hooks/useEditorWebSocket";
13
13
  import { useSocketMessageHandler } from "./hooks/useSocketMessageHandler";
14
14
  import "react-json-view-lite/dist/index.css";
@@ -45,6 +45,7 @@ import { DevModeIndicator } from "./ui/DevModeIndicator";
45
45
  import { useWorkbox } from "./hooks/useWorkbox";
46
46
  import { useMediaSelector } from "./hooks/useMediaSelector";
47
47
  import { useGlobalEditorKeyDown } from "./hooks/useGlobalEditorKeyDown";
48
+ import { useStartupChecks } from "../settings/status/index";
48
49
  export function EditorShell({ configuration, className, item: loadItemDescriptor, sessionId, userInfo, userPreferences, parheliaSettings, setUserPreferences, children, }) {
49
50
  const router = useRouter();
50
51
  const pathname = usePathname();
@@ -76,6 +77,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
76
77
  const [validationResult, setValidationResult] = useState();
77
78
  const [editHistory, setEditHistory] = useState([]);
78
79
  const [historyMode, setHistoryMode] = useState("global");
80
+ const [showOnlyMyChanges, setShowOnlyMyChanges] = useState(true);
79
81
  const [recentEdits, setRecentEdits] = useState([]);
80
82
  const addRecentEdit = useCallback((edit) => {
81
83
  setRecentEdits((prevEditedFields) => {
@@ -107,6 +109,10 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
107
109
  searchParams.get("view") ??
108
110
  configuration.editor.views[0]?.name ??
109
111
  "splash-screen");
112
+ const viewNameRef = useRef(viewName);
113
+ useEffect(() => {
114
+ viewNameRef.current = viewName;
115
+ }, [viewName]);
110
116
  const [previousViewName, setPreviousViewName] = useState(undefined);
111
117
  const [compareMode, setCompareMode] = useState(false);
112
118
  const [compareTo, setCompareTo] = useState();
@@ -222,6 +228,25 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
222
228
  const [isInitialLoad, setIsInitialLoad] = useState(true);
223
229
  // Wizard state - managed centrally instead of reading URL directly
224
230
  const [currentWizardId, setCurrentWizardId] = useState(null);
231
+ // Startup checks - run blocking checks on app startup
232
+ const startupChecks = useStartupChecks(configuration.statusChecks);
233
+ // Redirect to status panel if blocking issues are found
234
+ useEffect(() => {
235
+ if (startupChecks.state !== "complete")
236
+ return;
237
+ if (!startupChecks.hasBlockingIssues)
238
+ return;
239
+ // Don't redirect if already on the status panel
240
+ const currentView = searchParams.get("view");
241
+ const currentPanel = searchParams.get("ccpanel");
242
+ if (currentView === "settings" && currentPanel === "status")
243
+ return;
244
+ // Redirect to the status panel
245
+ const url = new URL(window.location.href);
246
+ url.searchParams.set("view", "settings");
247
+ url.searchParams.set("ccpanel", "status");
248
+ router.push(url.toString(), { scroll: false });
249
+ }, [startupChecks.state, startupChecks.hasBlockingIssues, searchParams, router]);
225
250
  // Handle initial mode setup from URL (only on initial load)
226
251
  useEffect(() => {
227
252
  if (!isInitialLoad)
@@ -481,7 +506,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
481
506
  const urlParams = new URLSearchParams(window.location.search);
482
507
  // Handle view changes
483
508
  const urlView = urlParams.get("view");
484
- if (urlView && urlView !== viewName) {
509
+ if (urlView && urlView !== viewNameRef.current) {
485
510
  setViewName(urlView);
486
511
  }
487
512
  // Handle wizard ID changes
@@ -521,26 +546,18 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
521
546
  version,
522
547
  }, {
523
548
  addToBrowseHistory: false, // Don't add to history since this is navigation
549
+ skipViewChange: true, // View is already set by popstate handler above
524
550
  });
525
551
  }
526
552
  }
527
553
  }
528
554
  };
529
- // Also track any other URL changes with a MutationObserver fallback
530
- const checkUrlChange = () => {
531
- const currentUrl = window.location.href;
532
- if (currentUrl !== lastUrl) {
533
- lastUrl = currentUrl;
534
- }
535
- };
536
- const urlCheckInterval = setInterval(checkUrlChange, 100);
537
555
  window.addEventListener("message", handleMessage);
538
556
  window.addEventListener("popstate", handlePopState);
539
557
  return () => {
540
558
  window.removeEventListener("message", handleMessage);
541
559
  window.removeEventListener("popstate", handlePopState);
542
560
  clearInterval(interval);
543
- clearInterval(urlCheckInterval);
544
561
  };
545
562
  }, []);
546
563
  const isMobile = useMediaQuery("(max-width: 768px)");
@@ -701,67 +718,120 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
701
718
  const loadHistory = useDebouncedCallback(async () => {
702
719
  if (!sessionId)
703
720
  return;
704
- const result = await getSessionHistory(sessionId);
721
+ const result = await getEditHistory({ sessionId });
705
722
  if (handleErrorResult(result, ui, state))
706
723
  return;
707
- setEditHistory(result.data || []);
724
+ setEditHistory((prev) => {
725
+ const next = result.data || [];
726
+ if (!prev.length)
727
+ return next;
728
+ if (!next.length)
729
+ return next;
730
+ const prevById = new Map(prev.map((x) => [x.id, x]));
731
+ return next.map((op) => {
732
+ const prior = prevById.get(op.id);
733
+ if (!prior)
734
+ return op;
735
+ // Preserve client/websocket-populated fields if the server response omits them.
736
+ return {
737
+ ...op,
738
+ description: op.description ?? prior.description,
739
+ focus: op.focus ?? prior.focus,
740
+ user: op.user ?? prior.user,
741
+ };
742
+ });
743
+ });
708
744
  }, 200);
709
- const refreshHistory = useCallback(async (mode, filterBySession = true) => {
745
+ const refreshHistory = useCallback(async (mode, filterBySession) => {
710
746
  const currentMode = mode || historyMode;
747
+ // Use showOnlyMyChanges state if filterBySession not explicitly provided
748
+ const shouldFilterBySession = filterBySession !== undefined ? filterBySession : showOnlyMyChanges;
711
749
  if (currentMode === "global") {
712
- if (!filterBySession) {
713
- // Show all operations globally (across all sessions) with limit of 500
714
- console.log("[EditorShell] Loading all operations globally (all sessions)");
715
- const result = await getAllHistory(500);
716
- if (handleErrorResult(result, ui, state)) {
717
- console.error("[EditorShell] Failed to load all history:", result);
718
- return;
719
- }
720
- console.log("[EditorShell] Loaded", result.data?.length || 0, "operations (all sessions)");
721
- setEditHistory(result.data || []);
722
- return;
723
- }
724
- // Filter by session
725
- if (!sessionId) {
726
- console.warn("[EditorShell] Cannot load history: sessionId is not available");
727
- return;
728
- }
729
- console.log("[EditorShell] Loading session history for sessionId:", sessionId);
730
- const result = await getSessionHistory(sessionId);
750
+ // Global mode: optionally filter by session
751
+ const result = await getEditHistory({
752
+ sessionId: shouldFilterBySession ? sessionId : undefined,
753
+ limit: shouldFilterBySession ? 100 : 500,
754
+ });
731
755
  if (handleErrorResult(result, ui, state)) {
732
- console.error("[EditorShell] Failed to load session history:", result);
756
+ console.error("[EditorShell] Failed to load history:", result);
733
757
  return;
734
758
  }
735
- console.log("[EditorShell] Loaded", result.data?.length || 0, "operations");
736
- setEditHistory(result.data || []);
759
+ setEditHistory((prev) => {
760
+ const next = result.data || [];
761
+ if (!prev.length)
762
+ return next;
763
+ if (!next.length)
764
+ return next;
765
+ const prevById = new Map(prev.map((x) => [x.id, x]));
766
+ return next.map((op) => {
767
+ const prior = prevById.get(op.id);
768
+ if (!prior)
769
+ return op;
770
+ // Preserve client/websocket-populated fields if the server response omits them.
771
+ return {
772
+ ...op,
773
+ description: op.description ?? prior.description,
774
+ focus: op.focus ?? prior.focus,
775
+ user: op.user ?? prior.user,
776
+ };
777
+ });
778
+ });
737
779
  }
738
780
  else {
739
781
  // Page-centric or current-version mode - need current item
740
782
  const currentItem = contentEditorItem?.descriptor;
741
783
  if (!currentItem) {
742
- console.warn("[EditorShell] Cannot load page-centric history: no item loaded");
784
+ console.warn("[EditorShell] Cannot load page-centric/current-version history: no item loaded");
743
785
  setEditHistory([]);
744
786
  return;
745
787
  }
746
- console.log("[EditorShell] Loading item history for:", currentItem.id, "mode:", currentMode, "filterBySession:", filterBySession);
747
- const result = await getEditHistory(currentItem);
788
+ // For page-centric: fetch all versions (itemId + language only)
789
+ // For current-version: fetch specific version (itemId + language + version)
790
+ const itemFilter = currentMode === "page-centric"
791
+ ? { id: currentItem.id, language: currentItem.language, version: 0 } // version 0 signals "all versions" to backend
792
+ : currentItem;
793
+ // Request item-scoped history, optionally filtered by session
794
+ const result = await getEditHistory({
795
+ item: itemFilter,
796
+ sessionId: shouldFilterBySession ? sessionId : undefined,
797
+ });
748
798
  if (handleErrorResult(result, ui, state)) {
749
799
  console.error("[EditorShell] Failed to load item history:", result);
750
800
  return;
751
801
  }
752
802
  let operations = result.data || [];
753
- // Filter by session if requested
754
- if (filterBySession) {
755
- operations = operations.filter((op) => op.sessionId === sessionId);
756
- }
757
- // Filter by version if current-version mode
803
+ // Client-side version filtering for current-version mode
758
804
  if (currentMode === "current-version") {
759
- operations = operations.filter((op) => op.mainItem?.version === currentItem.version);
805
+ // Defensive filter: only include operations for the current version
806
+ operations = operations.filter((op) => {
807
+ // If mainItem is missing, exclude the operation
808
+ if (!op.mainItem) {
809
+ return false;
810
+ }
811
+ return op.mainItem.version === currentItem.version;
812
+ });
760
813
  }
761
- console.log("[EditorShell] Loaded", operations.length, "operations");
762
- setEditHistory(operations);
814
+ setEditHistory((prev) => {
815
+ if (!prev.length)
816
+ return operations;
817
+ if (!operations.length)
818
+ return operations;
819
+ const prevById = new Map(prev.map((x) => [x.id, x]));
820
+ return operations.map((op) => {
821
+ const prior = prevById.get(op.id);
822
+ if (!prior)
823
+ return op;
824
+ // Preserve client/websocket-populated fields if the server response omits them.
825
+ return {
826
+ ...op,
827
+ description: op.description ?? prior.description,
828
+ focus: op.focus ?? prior.focus,
829
+ user: op.user ?? prior.user,
830
+ };
831
+ });
832
+ });
763
833
  }
764
- }, [sessionId, historyMode, contentEditorItem]);
834
+ }, [sessionId, historyMode, showOnlyMyChanges, contentEditorItem]);
765
835
  // defined below after loadItem/loadItemVersions/requestRefresh
766
836
  const requestRefresh = useCallback((mode) => {
767
837
  const refreshTimer = globalThis.editorRefreshTimer;
@@ -789,7 +859,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
789
859
  loadComments();
790
860
  loadSuggestedEdits();
791
861
  }, [currentItemDescriptor]);
792
- // Load history on initialization or when mode/item changes
862
+ // Load history on initialization or when mode/item/filter changes
793
863
  useEffect(() => {
794
864
  if (historyMode === "global" && sessionId) {
795
865
  // Use refreshHistory for immediate load on initialization
@@ -805,6 +875,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
805
875
  }, [
806
876
  sessionId,
807
877
  historyMode,
878
+ showOnlyMyChanges,
808
879
  currentItemDescriptor?.id,
809
880
  currentItemDescriptor?.language,
810
881
  currentItemDescriptor?.version,
@@ -1039,8 +1110,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1039
1110
  }
1040
1111
  if (!options?.skipViewChange &&
1041
1112
  ((!item.hasLayout && viewName === "page-editor") ||
1042
- viewName == "splash-screen" ||
1043
- viewName == "control-center")) {
1113
+ viewName == "splash-screen")) {
1044
1114
  setViewName("content-tree");
1045
1115
  }
1046
1116
  // ensure this is object has no additional properties
@@ -1049,8 +1119,8 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1049
1119
  setCurrentItemDescriptor(itemToLoad);
1050
1120
  setContentEditorItem(item);
1051
1121
  setSelection([]);
1052
- // Load history (session-based) and add to browse history
1053
- loadHistory();
1122
+ // History will be refreshed automatically by the useEffect watching currentItemDescriptor
1123
+ // Don't call loadHistory() here as it would override mode-aware history loading
1054
1124
  if (options?.addToBrowseHistory ||
1055
1125
  options?.addToBrowseHistory === undefined) {
1056
1126
  addToBrowseHistory(item);
@@ -1064,7 +1134,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1064
1134
  itemsRepository,
1065
1135
  setContentEditorItem,
1066
1136
  viewName,
1067
- loadHistory,
1068
1137
  addToBrowseHistory,
1069
1138
  addNavigationEntry,
1070
1139
  ]);
@@ -1103,6 +1172,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1103
1172
  itemsRepository,
1104
1173
  user,
1105
1174
  editHistory,
1175
+ showOnlyMyChanges,
1106
1176
  refreshHistory,
1107
1177
  suggestedEdits,
1108
1178
  setSuggestedEdits,
@@ -1161,9 +1231,11 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1161
1231
  contentEditorItem?.version === op.mainItem?.version) {
1162
1232
  setInsertMode(false);
1163
1233
  }
1164
- // Refresh history from server to ensure consistency
1165
- refreshHistory();
1166
- }, [contentEditorItem, setEditHistory, setInsertMode, refreshHistory]);
1234
+ // Note: We intentionally do NOT call refreshHistory() here.
1235
+ // The websocket 'edit-operation' handler updates the operation directly in history.
1236
+ // Calling refreshHistory here causes a race condition where stale server data
1237
+ // arrives before the server has processed the redo, causing UI flicker.
1238
+ }, [contentEditorItem, setEditHistory, setInsertMode]);
1167
1239
  const ui = {
1168
1240
  showErrorToast,
1169
1241
  confirmationDialogRef,
@@ -1175,6 +1247,52 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1175
1247
  currentItemDescriptor,
1176
1248
  validate,
1177
1249
  });
1250
+ // Function to update a single operation in history directly (used by websocket handler)
1251
+ // Only updates operations that match the current history mode/filter scope
1252
+ const updateOperationInHistory = useCallback((op) => {
1253
+ // Check if operation matches current history scope
1254
+ const matchesScope = () => {
1255
+ // Session filter
1256
+ if (showOnlyMyChanges && op.sessionId !== sessionId) {
1257
+ return false;
1258
+ }
1259
+ // Mode-specific filtering
1260
+ if (historyMode === "global") {
1261
+ // Global mode: accept all operations (session filter already applied above)
1262
+ return true;
1263
+ }
1264
+ else if (historyMode === "page-centric") {
1265
+ // Page-centric: must match current item id + language (any version)
1266
+ if (!contentEditorItem || !op.mainItem)
1267
+ return false;
1268
+ return (op.mainItem.id === contentEditorItem.id &&
1269
+ op.mainItem.language === contentEditorItem.language);
1270
+ }
1271
+ else if (historyMode === "current-version") {
1272
+ // Current-version: must match current item id + language + version
1273
+ if (!contentEditorItem || !op.mainItem)
1274
+ return false;
1275
+ return (op.mainItem.id === contentEditorItem.id &&
1276
+ op.mainItem.language === contentEditorItem.language &&
1277
+ op.mainItem.version === contentEditorItem.version);
1278
+ }
1279
+ return false;
1280
+ };
1281
+ if (!matchesScope()) {
1282
+ // Operation doesn't match current scope, don't update history
1283
+ return;
1284
+ }
1285
+ setEditHistory((prev) => {
1286
+ const existingOpIndex = prev.findIndex((x) => x.id === op.id);
1287
+ if (existingOpIndex >= 0) {
1288
+ const next = [...prev];
1289
+ next[existingOpIndex] = op;
1290
+ return next;
1291
+ }
1292
+ // If operation doesn't exist and matches scope, add it
1293
+ return [op, ...prev];
1294
+ });
1295
+ }, [historyMode, showOnlyMyChanges, sessionId, contentEditorItem]);
1178
1296
  // WebSocket message handler and connection
1179
1297
  const messageHandler = useSocketMessageHandler({
1180
1298
  sessionId,
@@ -1191,16 +1309,15 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1191
1309
  setQuotaInfo,
1192
1310
  requestRefresh,
1193
1311
  currentItemRef,
1194
- loadHistory,
1195
1312
  addRecentEdit,
1196
1313
  socketMessageListeners,
1197
1314
  isItemUsedInCurrentPage,
1315
+ updateOperationInHistory,
1198
1316
  });
1199
1317
  const { socketRef: socketInstanceRef } = useEditorWebSocket({
1200
1318
  sessionId,
1201
1319
  onMessage: messageHandler,
1202
1320
  onOpen: () => {
1203
- console.log("Connected!");
1204
1321
  // Increment socket connection version to trigger re-subscriptions
1205
1322
  setSocketConnectionVersion((v) => v + 1);
1206
1323
  },
@@ -1317,21 +1434,16 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1317
1434
  }, [operations, ignoreBlur, sessionId]);
1318
1435
  // Quick switcher handlers
1319
1436
  const showQuickSwitcher = useCallback((show) => {
1320
- console.log(`[QuickSwitcher] showQuickSwitcher called: show=${show}, historyLength=${navigationHistory.length}`);
1321
1437
  if (show && navigationHistory.length > 1) {
1322
1438
  setQuickSwitcherVisible(true);
1323
1439
  // Start with index 1 (second entry - previous entry) for quick switching
1324
1440
  setQuickSwitcherSelectedIndex(1);
1325
- console.log("[QuickSwitcher] Switcher opened, selected index: 1");
1326
- console.log("[QuickSwitcher] Navigation history:", navigationHistory.map((h, i) => `[${i}] ${h.displayName}`));
1327
1441
  }
1328
1442
  else {
1329
1443
  setQuickSwitcherVisible(false);
1330
- console.log("[QuickSwitcher] Switcher closed");
1331
1444
  }
1332
1445
  }, [navigationHistory]);
1333
1446
  const cycleQuickSwitcher = useCallback((direction) => {
1334
- console.log(`[QuickSwitcher] cycleQuickSwitcher: direction=${direction}, visible=${quickSwitcherVisible}`);
1335
1447
  if (!quickSwitcherVisible)
1336
1448
  return;
1337
1449
  const maxItems = Math.min(5, navigationHistory.length);
@@ -1377,15 +1489,12 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1377
1489
  }
1378
1490
  break;
1379
1491
  }
1380
- console.log(`[QuickSwitcher] Cycling from index ${current} to ${newIndex} (${columns} columns)`);
1381
1492
  return newIndex;
1382
1493
  });
1383
1494
  }, [quickSwitcherVisible, browseHistory]);
1384
1495
  const handleQuickSwitcherSelect = useCallback((index) => {
1385
- console.log(`[QuickSwitcher] Selecting entry at index ${index}`);
1386
1496
  const selectedEntry = navigationHistory[index];
1387
1497
  if (selectedEntry) {
1388
- console.log(`[QuickSwitcher] Navigating to:`, selectedEntry);
1389
1498
  // First switch view
1390
1499
  if (selectedEntry.viewName !== viewName) {
1391
1500
  // Avoid inserting a duplicate navigation entry; we'll explicitly move the
@@ -1402,7 +1511,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1402
1511
  contentEditorItem.language !== selectedEntry.item.language ||
1403
1512
  contentEditorItem.version !== selectedEntry.item.version;
1404
1513
  if (isDifferentItem) {
1405
- console.log(`[QuickSwitcher] Loading different item:`, selectedEntry.item);
1406
1514
  loadItem({
1407
1515
  id: selectedEntry.item.id,
1408
1516
  language: selectedEntry.item.language,
@@ -1414,9 +1522,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1414
1522
  skipNavigationHistory: true,
1415
1523
  });
1416
1524
  }
1417
- else {
1418
- console.log(`[QuickSwitcher] Same item, skipping reload`);
1419
- }
1420
1525
  }
1421
1526
  // Move selected entry to first position in navigation history by identity
1422
1527
  setNavigationHistory((history) => {
@@ -1801,7 +1906,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1801
1906
  operations.addComponent(dragObject.typeId, placeholderKey, index, currentItemDescriptorRef.current);
1802
1907
  return;
1803
1908
  }
1804
- console.log("dragObject", dragObject);
1805
1909
  if (dragObject.type == "component" ||
1806
1910
  (dragObject.type == "items" && dragObject.items)) {
1807
1911
  const parentComponent = parentId && page ? getComponentById(parentId, page) : null;
@@ -1822,7 +1926,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1822
1926
  linkedComponentItem: dragObject.items[0],
1823
1927
  title: "Link component",
1824
1928
  };
1825
- console.log("op", op);
1826
1929
  }
1827
1930
  else {
1828
1931
  const componentIds = dragObject.components?.map((c) => c.id) ?? [];
@@ -1867,7 +1970,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1867
1970
  //dialogContext,
1868
1971
  });
1869
1972
  }
1870
- console.log("Field action before setActiveFieldActions");
1871
1973
  if (actionButton.action) {
1872
1974
  setActiveFieldActions((prevFieldActions) => {
1873
1975
  const isSameField = (x) => x.field.fieldId == fieldDescriptor.fieldId &&
@@ -1887,10 +1989,8 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1887
1989
  : op;
1888
1990
  return [...prevFieldActions.filter((x) => !isSameField(x)), mergedOp];
1889
1991
  });
1890
- console.log("Field action after setActiveFieldActions");
1891
1992
  try {
1892
1993
  await executeFieldServerAction(fieldDescriptor.item, fieldDescriptor.fieldId, contentEditorItem.descriptor, actionButton.action, editContext.sessionId, selectedRange?.text || "", parameters || {}, (data) => {
1893
- console.log("Field action progress", data);
1894
1994
  // Update progress message if available
1895
1995
  if (data?.responseText) {
1896
1996
  op.message = data.responseText;
@@ -1899,7 +1999,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1899
1999
  ]);
1900
2000
  }
1901
2001
  });
1902
- console.log("Field action completed", op);
1903
2002
  itemsRepository.refreshItems([fieldDescriptor.item]);
1904
2003
  // Only mark as success if no websocket error has been reported
1905
2004
  if (op.state === "running") {
@@ -1965,11 +2064,12 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1965
2064
  editHistory,
1966
2065
  historyMode,
1967
2066
  setHistoryMode,
2067
+ showOnlyMyChanges,
2068
+ setShowOnlyMyChanges,
1968
2069
  refreshHistory,
1969
2070
  isRefreshing,
1970
2071
  activeSessions,
1971
2072
  unlockField: async () => {
1972
- console.log("[EditContext.unlockField] Clearing lockedField state");
1973
2073
  setLockedField(undefined); // Clear client-side lock state
1974
2074
  await releaseFieldLocks(sessionId);
1975
2075
  },
@@ -2165,7 +2265,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
2165
2265
  focusedField,
2166
2266
  setFocusedField: setFocusedFieldWithLock,
2167
2267
  unlockField: async () => {
2168
- console.log("[FieldsEditContext.unlockField] Clearing lockedField state");
2169
2268
  setLockedField(undefined); // Clear client-side lock state
2170
2269
  await releaseFieldLocks(sessionId);
2171
2270
  },