@alpaca-editor/core 1.0.4026 → 1.0.4030

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/components/ActionButton.js +2 -2
  2. package/dist/components/ActionButton.js.map +1 -1
  3. package/dist/components/SimpleLanguageSelector.js +3 -1
  4. package/dist/components/SimpleLanguageSelector.js.map +1 -1
  5. package/dist/components/ui/button.d.ts +1 -1
  6. package/dist/config/config.js +1 -1
  7. package/dist/config/config.js.map +1 -1
  8. package/dist/config/types.d.ts +1 -1
  9. package/dist/editor/ContextMenu.js +0 -1
  10. package/dist/editor/ContextMenu.js.map +1 -1
  11. package/dist/editor/Editor.js +9 -3
  12. package/dist/editor/Editor.js.map +1 -1
  13. package/dist/editor/FieldListField.js +16 -24
  14. package/dist/editor/FieldListField.js.map +1 -1
  15. package/dist/editor/ImageEditButton.js +1 -1
  16. package/dist/editor/ImageEditButton.js.map +1 -1
  17. package/dist/editor/ImageEditor.js +1 -1
  18. package/dist/editor/ImageEditor.js.map +1 -1
  19. package/dist/editor/MainLayout.js +2 -2
  20. package/dist/editor/MainLayout.js.map +1 -1
  21. package/dist/editor/Terminal.js +1 -1
  22. package/dist/editor/Terminal.js.map +1 -1
  23. package/dist/editor/Titlebar.js +0 -1
  24. package/dist/editor/Titlebar.js.map +1 -1
  25. package/dist/editor/ai/AgentCostDisplay.d.ts +26 -0
  26. package/dist/editor/ai/AgentCostDisplay.js +65 -0
  27. package/dist/editor/ai/AgentCostDisplay.js.map +1 -0
  28. package/dist/editor/ai/Agents.js +83 -29
  29. package/dist/editor/ai/Agents.js.map +1 -1
  30. package/dist/editor/ai/AiPromptPopover.d.ts +7 -0
  31. package/dist/editor/ai/AiPromptPopover.js +111 -0
  32. package/dist/editor/ai/AiPromptPopover.js.map +1 -0
  33. package/dist/editor/ai/AiResponseMessage.d.ts +1 -0
  34. package/dist/editor/ai/AiResponseMessage.js +104 -18
  35. package/dist/editor/ai/AiResponseMessage.js.map +1 -1
  36. package/dist/editor/ai/AiTerminal.d.ts +18 -2
  37. package/dist/editor/ai/AiTerminal.js +423 -63
  38. package/dist/editor/ai/AiTerminal.js.map +1 -1
  39. package/dist/editor/ai/EditorAiTerminal.d.ts +2 -1
  40. package/dist/editor/ai/EditorAiTerminal.js +2 -2
  41. package/dist/editor/ai/EditorAiTerminal.js.map +1 -1
  42. package/dist/editor/ai/editorAiContext.d.ts +0 -1
  43. package/dist/editor/ai/editorAiContext.js +0 -2
  44. package/dist/editor/ai/editorAiContext.js.map +1 -1
  45. package/dist/editor/client/EditorClient.d.ts +3 -2
  46. package/dist/editor/client/EditorClient.js +326 -68
  47. package/dist/editor/client/EditorClient.js.map +1 -1
  48. package/dist/editor/client/editContext.d.ts +6 -4
  49. package/dist/editor/client/editContext.js.map +1 -1
  50. package/dist/editor/client/fieldModificationStore.d.ts +19 -0
  51. package/dist/editor/client/fieldModificationStore.js +125 -0
  52. package/dist/editor/client/fieldModificationStore.js.map +1 -0
  53. package/dist/editor/client/itemsRepository.d.ts +1 -1
  54. package/dist/editor/client/itemsRepository.js +38 -28
  55. package/dist/editor/client/itemsRepository.js.map +1 -1
  56. package/dist/editor/client/operations.d.ts +1 -0
  57. package/dist/editor/client/operations.js +39 -31
  58. package/dist/editor/client/operations.js.map +1 -1
  59. package/dist/editor/commands/componentCommands.js +5 -3
  60. package/dist/editor/commands/componentCommands.js.map +1 -1
  61. package/dist/editor/commands/itemCommands.js.map +1 -1
  62. package/dist/editor/component-designer/aiContext.js +0 -2
  63. package/dist/editor/component-designer/aiContext.js.map +1 -1
  64. package/dist/editor/field-types/DropLinkEditor.js +1 -1
  65. package/dist/editor/field-types/DropLinkEditor.js.map +1 -1
  66. package/dist/editor/field-types/MultiLineText.js +5 -7
  67. package/dist/editor/field-types/MultiLineText.js.map +1 -1
  68. package/dist/editor/field-types/RichTextEditorComponent.js +5 -7
  69. package/dist/editor/field-types/RichTextEditorComponent.js.map +1 -1
  70. package/dist/editor/field-types/SingleLineText.js +5 -7
  71. package/dist/editor/field-types/SingleLineText.js.map +1 -1
  72. package/dist/editor/hooks/useEditorSettings.d.ts +17 -0
  73. package/dist/editor/hooks/useEditorSettings.js +61 -0
  74. package/dist/editor/hooks/useEditorSettings.js.map +1 -0
  75. package/dist/editor/menubar/ItemActionsMenu.js +2 -2
  76. package/dist/editor/menubar/ItemActionsMenu.js.map +1 -1
  77. package/dist/editor/menubar/PageSelector.js +1 -1
  78. package/dist/editor/menubar/PageSelector.js.map +1 -1
  79. package/dist/editor/menubar/toolbar-sections/EditControls.js +1 -1
  80. package/dist/editor/menubar/toolbar-sections/EditControls.js.map +1 -1
  81. package/dist/editor/menubar/toolbar-sections/InsertControls.js +1 -1
  82. package/dist/editor/menubar/toolbar-sections/InsertControls.js.map +1 -1
  83. package/dist/editor/menubar/toolbar-sections/UtilityControls.js +1 -1
  84. package/dist/editor/menubar/toolbar-sections/UtilityControls.js.map +1 -1
  85. package/dist/editor/menubar/toolbar-sections/ViewportControls.js +1 -1
  86. package/dist/editor/menubar/toolbar-sections/ViewportControls.js.map +1 -1
  87. package/dist/editor/page-editor-chrome/FieldEditedIndicators.js +4 -3
  88. package/dist/editor/page-editor-chrome/FieldEditedIndicators.js.map +1 -1
  89. package/dist/editor/page-editor-chrome/FrameMenu.js +9 -1
  90. package/dist/editor/page-editor-chrome/FrameMenu.js.map +1 -1
  91. package/dist/editor/page-editor-chrome/useInlineAICompletion.js +0 -1
  92. package/dist/editor/page-editor-chrome/useInlineAICompletion.js.map +1 -1
  93. package/dist/editor/page-viewer/EditorForm.js +1 -1
  94. package/dist/editor/page-viewer/EditorForm.js.map +1 -1
  95. package/dist/editor/page-viewer/PageViewer.js +9 -8
  96. package/dist/editor/page-viewer/PageViewer.js.map +1 -1
  97. package/dist/editor/page-viewer/PageViewerFrame.js +7 -1
  98. package/dist/editor/page-viewer/PageViewerFrame.js.map +1 -1
  99. package/dist/editor/page-viewer/pageViewContext.js +40 -6
  100. package/dist/editor/page-viewer/pageViewContext.js.map +1 -1
  101. package/dist/editor/reviews/Comment.js +7 -6
  102. package/dist/editor/reviews/Comment.js.map +1 -1
  103. package/dist/editor/services/agentService.d.ts +84 -12
  104. package/dist/editor/services/agentService.js +256 -15
  105. package/dist/editor/services/agentService.js.map +1 -1
  106. package/dist/editor/services/aiService.d.ts +18 -3
  107. package/dist/editor/services/aiService.js +5 -3
  108. package/dist/editor/services/aiService.js.map +1 -1
  109. package/dist/editor/services/contextService.js +0 -1
  110. package/dist/editor/services/contextService.js.map +1 -1
  111. package/dist/editor/services/systemService.d.ts +2 -1
  112. package/dist/editor/services/systemService.js +3 -0
  113. package/dist/editor/services/systemService.js.map +1 -1
  114. package/dist/editor/sidebar/ComponentPalette.js +1 -1
  115. package/dist/editor/sidebar/ComponentPalette.js.map +1 -1
  116. package/dist/editor/sidebar/EditHistory.js +2 -2
  117. package/dist/editor/sidebar/EditHistory.js.map +1 -1
  118. package/dist/editor/sidebar/GraphQL.d.ts +1 -0
  119. package/dist/editor/sidebar/GraphQL.js +8 -2
  120. package/dist/editor/sidebar/GraphQL.js.map +1 -1
  121. package/dist/editor/sidebar/MainContentTree.js +1 -1
  122. package/dist/editor/sidebar/MainContentTree.js.map +1 -1
  123. package/dist/editor/sidebar/SEOInfo.js +1 -1
  124. package/dist/editor/sidebar/SEOInfo.js.map +1 -1
  125. package/dist/editor/sidebar/ViewSelector.d.ts +4 -1
  126. package/dist/editor/sidebar/ViewSelector.js +64 -48
  127. package/dist/editor/sidebar/ViewSelector.js.map +1 -1
  128. package/dist/editor/ui/PerfectTree.js +2 -11
  129. package/dist/editor/ui/PerfectTree.js.map +1 -1
  130. package/dist/editor/ui/SimpleIconButton.d.ts +2 -0
  131. package/dist/editor/ui/SimpleIconButton.js +8 -4
  132. package/dist/editor/ui/SimpleIconButton.js.map +1 -1
  133. package/dist/index.d.ts +2 -0
  134. package/dist/index.js +2 -0
  135. package/dist/index.js.map +1 -1
  136. package/dist/page-wizard/steps/CollectStep.js +1 -1
  137. package/dist/page-wizard/steps/CollectStep.js.map +1 -1
  138. package/dist/page-wizard/steps/StructureStep.js +1 -1
  139. package/dist/page-wizard/steps/StructureStep.js.map +1 -1
  140. package/dist/page-wizard/steps/TranslateStep.js +233 -18
  141. package/dist/page-wizard/steps/TranslateStep.js.map +1 -1
  142. package/dist/revision.d.ts +2 -2
  143. package/dist/revision.js +2 -2
  144. package/dist/splash-screen/RecentPages.js +1 -13
  145. package/dist/splash-screen/RecentPages.js.map +1 -1
  146. package/dist/splash-screen/SplashScreen.js +1 -1
  147. package/dist/splash-screen/SplashScreen.js.map +1 -1
  148. package/dist/styles.css +88 -3
  149. package/dist/types.d.ts +6 -0
  150. package/package.json +2 -2
  151. package/src/components/ActionButton.tsx +3 -2
  152. package/src/components/SimpleLanguageSelector.tsx +6 -1
  153. package/src/config/config.tsx +1 -1
  154. package/src/config/types.ts +1 -1
  155. package/src/editor/ContextMenu.tsx +0 -3
  156. package/src/editor/Editor.tsx +11 -3
  157. package/src/editor/FieldListField.tsx +22 -31
  158. package/src/editor/ImageEditButton.tsx +1 -0
  159. package/src/editor/ImageEditor.tsx +1 -0
  160. package/src/editor/MainLayout.tsx +2 -2
  161. package/src/editor/Terminal.tsx +1 -1
  162. package/src/editor/Titlebar.tsx +0 -2
  163. package/src/editor/ai/AgentCostDisplay.tsx +237 -0
  164. package/src/editor/ai/Agents.tsx +147 -65
  165. package/src/editor/ai/AiPromptPopover.tsx +209 -0
  166. package/src/editor/ai/AiResponseMessage.tsx +232 -45
  167. package/src/editor/ai/AiTerminal.tsx +559 -88
  168. package/src/editor/ai/EditorAiTerminal.tsx +3 -0
  169. package/src/editor/ai/editorAiContext.ts +0 -3
  170. package/src/editor/client/EditorClient.tsx +409 -117
  171. package/src/editor/client/editContext.ts +7 -5
  172. package/src/editor/client/fieldModificationStore.ts +196 -0
  173. package/src/editor/client/itemsRepository.ts +41 -31
  174. package/src/editor/client/operations.ts +95 -76
  175. package/src/editor/commands/componentCommands.tsx +9 -3
  176. package/src/editor/commands/itemCommands.tsx +0 -1
  177. package/src/editor/component-designer/aiContext.ts +0 -2
  178. package/src/editor/field-types/DropLinkEditor.tsx +1 -1
  179. package/src/editor/field-types/MultiLineText.tsx +9 -9
  180. package/src/editor/field-types/RichTextEditorComponent.tsx +8 -8
  181. package/src/editor/field-types/SingleLineText.tsx +9 -9
  182. package/src/editor/hooks/useEditorSettings.ts +68 -0
  183. package/src/editor/menubar/ItemActionsMenu.tsx +3 -2
  184. package/src/editor/menubar/PageSelector.tsx +1 -1
  185. package/src/editor/menubar/toolbar-sections/EditControls.tsx +1 -0
  186. package/src/editor/menubar/toolbar-sections/InsertControls.tsx +1 -0
  187. package/src/editor/menubar/toolbar-sections/UtilityControls.tsx +2 -0
  188. package/src/editor/menubar/toolbar-sections/ViewportControls.tsx +2 -0
  189. package/src/editor/page-editor-chrome/FieldEditedIndicators.tsx +4 -3
  190. package/src/editor/page-editor-chrome/FrameMenu.tsx +10 -1
  191. package/src/editor/page-editor-chrome/useInlineAICompletion.tsx +0 -1
  192. package/src/editor/page-viewer/EditorForm.tsx +1 -0
  193. package/src/editor/page-viewer/PageViewer.tsx +9 -8
  194. package/src/editor/page-viewer/PageViewerFrame.tsx +7 -1
  195. package/src/editor/page-viewer/pageViewContext.ts +40 -5
  196. package/src/editor/reviews/Comment.tsx +7 -7
  197. package/src/editor/services/agentService.ts +405 -31
  198. package/src/editor/services/aiService.ts +24 -5
  199. package/src/editor/services/contextService.ts +0 -1
  200. package/src/editor/services/systemService.ts +7 -1
  201. package/src/editor/sidebar/ComponentPalette.tsx +4 -1
  202. package/src/editor/sidebar/EditHistory.tsx +2 -0
  203. package/src/editor/sidebar/GraphQL.tsx +19 -7
  204. package/src/editor/sidebar/MainContentTree.tsx +1 -1
  205. package/src/editor/sidebar/SEOInfo.tsx +1 -1
  206. package/src/editor/sidebar/ViewSelector.tsx +80 -64
  207. package/src/editor/ui/PerfectTree.tsx +2 -18
  208. package/src/editor/ui/SimpleIconButton.tsx +56 -38
  209. package/src/index.ts +2 -0
  210. package/src/page-wizard/steps/CollectStep.tsx +0 -2
  211. package/src/page-wizard/steps/StructureStep.tsx +3 -0
  212. package/src/page-wizard/steps/TranslateStep.tsx +473 -62
  213. package/src/revision.ts +2 -2
  214. package/src/splash-screen/RecentPages.tsx +0 -14
  215. package/src/splash-screen/SplashScreen.tsx +3 -2
  216. package/src/types.ts +7 -0
  217. package/dist/editor/ai/AiPopup.d.ts +0 -10
  218. package/dist/editor/ai/AiPopup.js +0 -23
  219. package/dist/editor/ai/AiPopup.js.map +0 -1
  220. package/dist/editor/ai/AiToolCall.d.ts +0 -5
  221. package/dist/editor/ai/AiToolCall.js +0 -28
  222. package/dist/editor/ai/AiToolCall.js.map +0 -1
  223. package/src/editor/ai/AiPopup.tsx +0 -59
  224. package/src/editor/ai/AiToolCall.tsx +0 -71
@@ -3,6 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
3
3
  import React, { useState, useEffect, useRef, useCallback, useMemo, } from "react";
4
4
  import { toast } from "sonner";
5
5
  import { EditContextProvider, ModifiedFieldsContextProvider, OperationsContextProvider, } from "./editContext";
6
+ import { fieldModificationStore } from "./fieldModificationStore";
6
7
  import { useRouter, useSearchParams, usePathname } from "next/navigation";
7
8
  import { findComponent, getComponentById } from "../componentTreeHelper";
8
9
  import { getOperationsContext } from "./operations";
@@ -19,7 +20,6 @@ import MainLayout from "../MainLayout";
19
20
  import { getItemDescriptor, useEventListenerExt } from "../utils";
20
21
  import { EditContextMenu } from "../ContextMenu";
21
22
  import { FieldEditorPopup } from "../FieldEditorPopup";
22
- import { AiPopup } from "../ai/AiPopup";
23
23
  import { EditorFormPopup, } from "../page-viewer/EditorFormPopup";
24
24
  import { post } from "../services/serviceHelper";
25
25
  import { SidebarView } from "../sidebar/SidebarView";
@@ -40,7 +40,7 @@ import { getSuggestedEdits } from "../services/suggestedEditsService";
40
40
  import { usePageWizard } from "../../page-wizard/usePageWizard";
41
41
  import { requestQuota } from "../services/aiService";
42
42
  import { Shrink } from "lucide-react";
43
- export function EditorClient({ configuration, className, item: loadItemDescriptor, sessionId, userInfo, userPreferences, setUserPreferences, children, }) {
43
+ export function EditorClient({ configuration, className, item: loadItemDescriptor, sessionId, userInfo, userPreferences, editorSettings, setUserPreferences, children, }) {
44
44
  const router = useRouter();
45
45
  const pathname = usePathname();
46
46
  const searchParams = useSearchParams();
@@ -67,12 +67,23 @@ export function EditorClient({ configuration, className, item: loadItemDescripto
67
67
  // const [showPublishDialog, setShowPublishDialog] = useState(false);
68
68
  const [activeFieldActions, setActiveFieldActions] = useState([]);
69
69
  const [renderedFields, setRenderedFields] = useState([]);
70
- const aiPopupRef = React.useRef(null);
71
70
  const fieldEditorPopupRef = React.useRef(null);
72
71
  const editorFormPopupRef = React.useRef(null);
73
72
  const [validationResult, setValidationResult] = useState();
74
73
  const [editHistory, setEditHistory] = useState([]);
75
- const [lastEditedFields, setLastEditedFields] = useState([]);
74
+ const [recentEdits, setRecentEdits] = useState([]);
75
+ const addRecentEdit = useCallback((edit) => {
76
+ setRecentEdits((prevEditedFields) => {
77
+ return [
78
+ ...prevEditedFields.filter((x) => x.timestamp > Date.now() - 30000 &&
79
+ (x.fieldId !== edit.fieldId ||
80
+ x.item.id !== edit.item.id ||
81
+ x.item.language !== edit.item.language ||
82
+ x.item.version !== edit.item.version)),
83
+ edit,
84
+ ];
85
+ });
86
+ }, []);
76
87
  const [activeSessions, setActiveSessions] = useState([]);
77
88
  if (typeof window !== "undefined")
78
89
  sessionStorage?.setItem("sessionId", sessionId);
@@ -174,17 +185,17 @@ export function EditorClient({ configuration, className, item: loadItemDescripto
174
185
  setFocusedField(undefined);
175
186
  }
176
187
  }, [selection]);
177
- const itemsRepository = useItemsRepository(setModifiedFields, setLastEditedFields);
188
+ const itemsRepository = useItemsRepository(setModifiedFields, addRecentEdit);
178
189
  const pageViewContext = usePageViewContext({
179
190
  pageItemDescriptor: currentItemDescriptor,
180
191
  itemsRepository,
181
192
  configuration,
182
193
  });
183
194
  const socketMessageListeners = useRef(new Set());
184
- const addSocketMessageListener = (callback) => {
195
+ const addSocketMessageListener = useCallback((callback) => {
185
196
  socketMessageListeners.current.add(callback);
186
197
  return () => socketMessageListeners.current.delete(callback);
187
- };
198
+ }, []);
188
199
  const reviews = useReviews({
189
200
  currentItemDescriptor: contentEditorItem?.descriptor,
190
201
  addSocketMessageListener: addSocketMessageListener,
@@ -232,19 +243,23 @@ export function EditorClient({ configuration, className, item: loadItemDescripto
232
243
  // socket.send(JSON.stringify(clientInfoMessage));
233
244
  //}
234
245
  };
235
- const startTour = () => {
246
+ const startTour = useCallback(() => {
236
247
  setIsTourActive(true);
237
- };
238
- const handleSetShowRightSidebar = (value) => {
248
+ }, [setIsTourActive]);
249
+ const handleSetShowRightSidebar = useCallback((value) => {
239
250
  const newValue = typeof value === "function" ? value(showRightSidebar) : value;
240
251
  setShowRightSidebar(newValue);
241
252
  setUserPreferences({ showRightSidebar: newValue });
242
- };
243
- const handleSetHideNonEditableComponents = (value) => {
253
+ }, [showRightSidebar, setShowRightSidebar, setUserPreferences]);
254
+ const handleSetHideNonEditableComponents = useCallback((value) => {
244
255
  const newValue = typeof value === "function" ? value(hideNonEditableComponents) : value;
245
256
  setHideNonEditableComponents(newValue);
246
257
  setUserPreferences({ hideNonEditableComponents: newValue });
247
- };
258
+ }, [
259
+ hideNonEditableComponents,
260
+ setHideNonEditableComponents,
261
+ setUserPreferences,
262
+ ]);
248
263
  const messageHandler = useCallback(async (event) => {
249
264
  if (!event.data.startsWith("{"))
250
265
  return;
@@ -310,7 +325,6 @@ export function EditorClient({ configuration, className, item: loadItemDescripto
310
325
  if (currentItemDescriptorRef.current) {
311
326
  if (currentItemDescriptorRef.current.id === message.payload.item.id)
312
327
  await loadItemVersions();
313
- setCurrentItemDescriptor({ ...currentItemDescriptorRef.current });
314
328
  }
315
329
  }
316
330
  if (message.type === "comment-updated") {
@@ -452,8 +466,8 @@ export function EditorClient({ configuration, className, item: loadItemDescripto
452
466
  }
453
467
  }
454
468
  socketMessageListeners.current.forEach((listener) => listener(message));
455
- }, [currentItemDescriptorRef, setLastEditedFields]);
456
- const user = activeSessions.find((x) => x.sessionId === sessionId)?.user;
469
+ }, [currentItemDescriptorRef, addRecentEdit]);
470
+ const user = useMemo(() => activeSessions.find((x) => x.sessionId === sessionId)?.user, [activeSessions, sessionId]);
457
471
  useEffect(() => {
458
472
  if (typeof window === "undefined")
459
473
  return;
@@ -561,7 +575,7 @@ export function EditorClient({ configuration, className, item: loadItemDescripto
561
575
  const tour = configuration.activeTour;
562
576
  const key = tour === "default" ? "editor.tourShown" : "editor.tourShown." + tour;
563
577
  const tourShown = localStorage.getItem(key);
564
- if (user?.isLimitedPreviewUser && !tourShown) {
578
+ if (!tourShown) {
565
579
  startTour();
566
580
  localStorage.setItem(key, "true");
567
581
  }
@@ -670,7 +684,7 @@ export function EditorClient({ configuration, className, item: loadItemDescripto
670
684
  // Set a small timeout to ensure all initial state setting effects have run
671
685
  const timer = setTimeout(() => {
672
686
  setIsInitialLoad(false);
673
- console.log("🔗 INITIAL LOAD COMPLETE - State now drives URL updates");
687
+ //console.log("🔗 INITIAL LOAD COMPLETE - State now drives URL updates");
674
688
  }, 100);
675
689
  return () => clearTimeout(timer);
676
690
  }
@@ -710,7 +724,7 @@ export function EditorClient({ configuration, className, item: loadItemDescripto
710
724
  useEffect(() => {
711
725
  setRefreshCompletedFlag(!refreshCompletedFlag);
712
726
  setInserting(undefined);
713
- }, [currentItemDescriptor, pageViewContext.page]);
727
+ }, [currentItemDescriptor, pageViewContext.page?.item.id]);
714
728
  useEffect(() => {
715
729
  sendClientInfo();
716
730
  }, [currentItemDescriptor]);
@@ -811,7 +825,7 @@ export function EditorClient({ configuration, className, item: loadItemDescripto
811
825
  doRefresh();
812
826
  }, mode === "waitForQuietPeriod" ? 1200 : 700);
813
827
  }
814
- }, [contentEditorItem, router]);
828
+ }, []);
815
829
  useEffect(() => {
816
830
  if (!currentItemDescriptor)
817
831
  return;
@@ -860,7 +874,6 @@ export function EditorClient({ configuration, className, item: loadItemDescripto
860
874
  current.set("version", currentItemDescriptor.version.toString());
861
875
  }
862
876
  if (current.get("view") !== viewName) {
863
- console.log("EditorClient: Updating view from", current.get("view"), "to", viewName);
864
877
  current.set("view", viewName);
865
878
  }
866
879
  if (!compareMode) {
@@ -990,21 +1003,6 @@ export function EditorClient({ configuration, className, item: loadItemDescripto
990
1003
  if (pageViewContext.fullscreen && !searchParams.get("fullscreen"))
991
1004
  setShowFullscreenHint(true);
992
1005
  }, [pageViewContext.fullscreen]);
993
- const executeCommand = useCallback(async ({ command, event, data, }) => {
994
- if (!editContextRef.current)
995
- return;
996
- const context = {
997
- editContext: editContextRef.current,
998
- pathname,
999
- router,
1000
- searchParams,
1001
- openDialog: openDialog,
1002
- event,
1003
- data,
1004
- };
1005
- const result = await command.execute(context);
1006
- return result;
1007
- }, [editContextRef, pathname, router, searchParams]);
1008
1006
  const state = useMemo(() => ({
1009
1007
  page,
1010
1008
  configuration,
@@ -1025,6 +1023,7 @@ export function EditorClient({ configuration, className, item: loadItemDescripto
1025
1023
  setSuggestedEdits,
1026
1024
  mode,
1027
1025
  setFocusFieldComponentId,
1026
+ setInsertMode,
1028
1027
  }), [
1029
1028
  page,
1030
1029
  configuration,
@@ -1045,10 +1044,9 @@ export function EditorClient({ configuration, className, item: loadItemDescripto
1045
1044
  setSuggestedEdits,
1046
1045
  mode,
1047
1046
  setFocusFieldComponentId,
1047
+ setInsertMode,
1048
1048
  ]);
1049
1049
  useEffect(() => {
1050
- if (currentOverlay !== "ai")
1051
- aiPopupRef.current?.close();
1052
1050
  if (currentOverlay !== "fields")
1053
1051
  fieldEditorPopupRef.current?.close();
1054
1052
  if (currentOverlay !== "context-menu")
@@ -1083,25 +1081,26 @@ export function EditorClient({ configuration, className, item: loadItemDescripto
1083
1081
  const showInfoToast = useCallback(({ summary, details }) => {
1084
1082
  toast.info(details || summary || "Information");
1085
1083
  }, []);
1084
+ const onOperationExecuted = useCallback((op) => {
1085
+ // Replace the operation in edit history with the executed operation
1086
+ setEditHistory((prev) => {
1087
+ const existingOpIndex = prev.findIndex((x) => x.id === op.id);
1088
+ if (existingOpIndex >= 0) {
1089
+ prev[existingOpIndex] = op;
1090
+ }
1091
+ return prev;
1092
+ });
1093
+ if (contentEditorItem?.id === op.mainItem?.id &&
1094
+ contentEditorItem?.language === op.mainItem?.language &&
1095
+ contentEditorItem?.version === op.mainItem?.version) {
1096
+ setInsertMode(false);
1097
+ }
1098
+ }, [contentEditorItem, setEditHistory, setInsertMode]);
1086
1099
  const ui = useMemo(() => ({
1087
1100
  showErrorToast,
1088
1101
  confirmationDialogRef,
1089
- onOperationExecuted: (op) => {
1090
- // Replace the operation in edit history with the executed operation
1091
- setEditHistory((prev) => {
1092
- const existingOpIndex = prev.findIndex((x) => x.id === op.id);
1093
- if (existingOpIndex >= 0) {
1094
- prev[existingOpIndex] = op;
1095
- }
1096
- return prev;
1097
- });
1098
- if (contentEditorItem?.id === op.mainItem?.id &&
1099
- contentEditorItem?.language === op.mainItem?.language &&
1100
- contentEditorItem?.version === op.mainItem?.version) {
1101
- setInsertMode(false);
1102
- }
1103
- },
1104
- }), [showErrorToast, confirmationDialogRef, currentItemDescriptor]);
1102
+ onOperationExecuted,
1103
+ }), [showErrorToast, confirmationDialogRef, onOperationExecuted]);
1105
1104
  const selectMedia = useCallback(({ selectedIdPath, mode, }) => {
1106
1105
  setSelectedMediaIdPath(selectedIdPath);
1107
1106
  setMediaSelectorVisible(true);
@@ -1197,7 +1196,7 @@ export function EditorClient({ configuration, className, item: loadItemDescripto
1197
1196
  switchView();
1198
1197
  };
1199
1198
  const [dialog, setDialog] = useState(null);
1200
- const openDialog = (Component, props) => {
1199
+ const openDialog = useCallback((Component, props) => {
1201
1200
  return new Promise((resolve) => {
1202
1201
  const handleClose = (result) => {
1203
1202
  setDialog(null);
@@ -1205,7 +1204,22 @@ export function EditorClient({ configuration, className, item: loadItemDescripto
1205
1204
  };
1206
1205
  setDialog(_jsx(Component, { ...props, onClose: handleClose }));
1207
1206
  });
1208
- };
1207
+ }, [setDialog]);
1208
+ const executeCommand = useCallback(async ({ command, event, data, }) => {
1209
+ if (!editContextRef.current)
1210
+ return;
1211
+ const context = {
1212
+ editContext: editContextRef.current,
1213
+ pathname,
1214
+ router,
1215
+ searchParams,
1216
+ openDialog: openDialog,
1217
+ event,
1218
+ data,
1219
+ };
1220
+ const result = await command.execute(context);
1221
+ return result;
1222
+ }, [editContextRef, pathname, router, searchParams, openDialog]);
1209
1223
  const operationsContext = getOperationsContext(state, ui);
1210
1224
  const operations = operationsContext.ops;
1211
1225
  const { handleKeyDown } = useKeyboardNavigation({
@@ -1302,8 +1316,34 @@ export function EditorClient({ configuration, className, item: loadItemDescripto
1302
1316
  });
1303
1317
  }
1304
1318
  }, [quotaInfo, getQuotaWarningMessage, isQuotaExceeded, showErrorToast]);
1319
+ // Calculate visible views separately to avoid circular dependency
1320
+ const visibleViews = useMemo(() => {
1321
+ const allViews = configuration.editor.views
1322
+ ?.filter((x) => {
1323
+ // For this calculation, we'll pass null for editContext since we're building it
1324
+ // The visibility check will be recalculated after editContext is available
1325
+ return !x.visible && !x.hidden;
1326
+ })
1327
+ .filter((x) => !userInfo.views ||
1328
+ userInfo.views.map((view) => view.name).includes(x.name)) ?? [];
1329
+ const pinnedViews = userInfo.preferences?.pinnedViews ||
1330
+ configuration.editor.defaultPinnedViews ||
1331
+ [];
1332
+ return allViews.filter((view) =>
1333
+ // Always show selected view
1334
+ view.name === viewName ||
1335
+ // Show pinned views
1336
+ pinnedViews.includes(view.name));
1337
+ }, [
1338
+ configuration.editor.views,
1339
+ userInfo.views,
1340
+ userInfo.preferences?.pinnedViews,
1341
+ configuration.editor.defaultPinnedViews,
1342
+ viewName,
1343
+ ]);
1305
1344
  const editContext = useMemo(() => {
1306
- return {
1345
+ // console.log('🔄 EditContext useMemo is being recalculated');
1346
+ const context = {
1307
1347
  operations: operationsContext.ops,
1308
1348
  itemsRepository,
1309
1349
  configuration,
@@ -1493,10 +1533,6 @@ export function EditorClient({ configuration, className, item: loadItemDescripto
1493
1533
  contextMenuRef.current?.show(event, items);
1494
1534
  setCurrentOverlay("context-menu");
1495
1535
  },
1496
- showAiPopup: (event, aiTerminalOptions) => {
1497
- setCurrentOverlay("ai");
1498
- aiPopupRef.current?.show(event, aiTerminalOptions);
1499
- },
1500
1536
  showFieldEditorPopup: (fields, sections, ev) => {
1501
1537
  setCurrentOverlay("fields");
1502
1538
  fieldEditorPopupRef.current?.show(fields, sections, ev);
@@ -1534,6 +1570,7 @@ export function EditorClient({ configuration, className, item: loadItemDescripto
1534
1570
  compareMode,
1535
1571
  setCompareMode,
1536
1572
  view: currentView,
1573
+ visibleViews,
1537
1574
  pageView: pageViewContext,
1538
1575
  componentDesignerComponent,
1539
1576
  setComponentDesignerComponent,
@@ -1570,7 +1607,6 @@ export function EditorClient({ configuration, className, item: loadItemDescripto
1570
1607
  currentItemDescriptor,
1571
1608
  compareTo,
1572
1609
  setCompareTo,
1573
- lastEditedFields,
1574
1610
  revision,
1575
1611
  selectedComment,
1576
1612
  setSelectedComment,
@@ -1653,6 +1689,7 @@ export function EditorClient({ configuration, className, item: loadItemDescripto
1653
1689
  webSocketMessages,
1654
1690
  clearWebSocketMessages: () => setWebSocketMessages([]),
1655
1691
  userInfo: userInfo,
1692
+ editorSettings,
1656
1693
  userPreferences,
1657
1694
  setUserPreferences,
1658
1695
  currentWizardId,
@@ -1660,6 +1697,7 @@ export function EditorClient({ configuration, className, item: loadItemDescripto
1660
1697
  favorites,
1661
1698
  loadFavorites,
1662
1699
  };
1700
+ return context;
1663
1701
  }, [
1664
1702
  operations,
1665
1703
  itemsRepository,
@@ -1712,7 +1750,6 @@ export function EditorClient({ configuration, className, item: loadItemDescripto
1712
1750
  currentItemDescriptor,
1713
1751
  compareTo,
1714
1752
  setCompareTo,
1715
- lastEditedFields,
1716
1753
  revision,
1717
1754
  comments,
1718
1755
  setComments,
@@ -1748,18 +1785,239 @@ export function EditorClient({ configuration, className, item: loadItemDescripto
1748
1785
  setCurrentWizardId,
1749
1786
  favorites,
1750
1787
  loadFavorites,
1788
+ userInfo,
1789
+ editorSettings,
1790
+ visibleViews,
1751
1791
  ]);
1792
+ // CRITICAL: Assign editContext to ref so keyboard handlers can access it
1793
+ useEffect(() => {
1794
+ editContextRef.current = editContext;
1795
+ }, [editContext]);
1752
1796
  const modifiedFieldsContext = useMemo(() => {
1753
1797
  return {
1754
1798
  modifiedFields,
1799
+ recentEdits,
1755
1800
  clear: () => {
1756
1801
  setModifiedFields([]);
1802
+ fieldModificationStore.clear();
1757
1803
  },
1804
+ clearRecentEdits: () => {
1805
+ setRecentEdits([]);
1806
+ },
1807
+ addRecentEdit,
1758
1808
  };
1759
- }, [modifiedFields, setModifiedFields]);
1760
- useEffect(() => {
1761
- editContextRef.current = editContext;
1762
- }, [editContext]);
1809
+ }, [modifiedFields, recentEdits, addRecentEdit]);
1810
+ // Debug: Track editContext changes
1811
+ const prevDependencies = useRef([]);
1812
+ // useEffect(() => {
1813
+ // // Create current dependencies array to match the useMemo dependency array
1814
+ // const currentDependencies = [
1815
+ // operations,
1816
+ // itemsRepository,
1817
+ // configuration,
1818
+ // contentEditorItem,
1819
+ // page?.item,
1820
+ // itemLanguages,
1821
+ // itemVersions,
1822
+ // sessionId,
1823
+ // isReadOnly,
1824
+ // selection,
1825
+ // selectedForInsertion,
1826
+ // dragObject,
1827
+ // requestRefresh,
1828
+ // refreshCompletedFlag,
1829
+ // searchParams,
1830
+ // pathname,
1831
+ // router,
1832
+ // selectMedia,
1833
+ // scrollIntoView,
1834
+ // focusedField,
1835
+ // renderedFields,
1836
+ // inserting,
1837
+ // page,
1838
+ // activeFieldActions,
1839
+ // editHistory,
1840
+ // isRefreshing,
1841
+ // activeSessions,
1842
+ // currentView,
1843
+ // componentDesignerComponent,
1844
+ // componentDesignerRendering,
1845
+ // insertMode,
1846
+ // currentOverlay,
1847
+ // inlineEditingFieldElement,
1848
+ // lockedField,
1849
+ // selectedRange,
1850
+ // pageViewContext,
1851
+ // browseHistory,
1852
+ // workboxItems,
1853
+ // validating,
1854
+ // setCenterPanelView,
1855
+ // handleKeyDown,
1856
+ // setTimings,
1857
+ // timings,
1858
+ // startTour,
1859
+ // viewName,
1860
+ // compareMode,
1861
+ // setCompareMode,
1862
+ // addSocketMessageListener,
1863
+ // currentItemDescriptor,
1864
+ // compareTo,
1865
+ // setCompareTo,
1866
+ // revision,
1867
+ // comments,
1868
+ // setComments,
1869
+ // selectedComment,
1870
+ // setSelectedComment,
1871
+ // loadComments,
1872
+ // mode,
1873
+ // setMode,
1874
+ // user,
1875
+ // reviews,
1876
+ // statusMessage,
1877
+ // setStatusMessage,
1878
+ // suggestedEdits,
1879
+ // setSuggestedEdits,
1880
+ // showSuggestedEdits,
1881
+ // setShowSuggestedEdits,
1882
+ // showSuggestedEditsDiff,
1883
+ // setShowSuggestedEditsDiff,
1884
+ // showRightSidebar,
1885
+ // handleSetShowRightSidebar,
1886
+ // activeEditorTab,
1887
+ // setActiveEditorTab,
1888
+ // hideNonEditableComponents,
1889
+ // handleSetHideNonEditableComponents,
1890
+ // quotaInfo,
1891
+ // isQuotaExceeded,
1892
+ // getQuotaWarningMessage,
1893
+ // isMobile,
1894
+ // openDialog,
1895
+ // pageWizard,
1896
+ // webSocketMessages,
1897
+ // currentWizardId,
1898
+ // setCurrentWizardId,
1899
+ // favorites,
1900
+ // loadFavorites,
1901
+ // ];
1902
+ // const dependencyNames = [
1903
+ // 'operations',
1904
+ // 'itemsRepository',
1905
+ // 'configuration',
1906
+ // 'contentEditorItem',
1907
+ // 'page?.item',
1908
+ // 'itemLanguages',
1909
+ // 'itemVersions',
1910
+ // 'sessionId',
1911
+ // 'isReadOnly',
1912
+ // 'selection',
1913
+ // 'selectedForInsertion',
1914
+ // 'dragObject',
1915
+ // 'requestRefresh',
1916
+ // 'refreshCompletedFlag',
1917
+ // 'searchParams',
1918
+ // 'pathname',
1919
+ // 'router',
1920
+ // 'selectMedia',
1921
+ // 'scrollIntoView',
1922
+ // 'focusedField',
1923
+ // 'renderedFields',
1924
+ // 'inserting',
1925
+ // 'page',
1926
+ // 'activeFieldActions',
1927
+ // 'editHistory',
1928
+ // 'isRefreshing',
1929
+ // 'activeSessions',
1930
+ // 'currentView',
1931
+ // 'componentDesignerComponent',
1932
+ // 'componentDesignerRendering',
1933
+ // 'insertMode',
1934
+ // 'currentOverlay',
1935
+ // 'inlineEditingFieldElement',
1936
+ // 'lockedField',
1937
+ // 'selectedRange',
1938
+ // 'pageViewContext',
1939
+ // 'browseHistory',
1940
+ // 'workboxItems',
1941
+ // 'validating',
1942
+ // 'setCenterPanelView',
1943
+ // 'handleKeyDown',
1944
+ // 'setTimings',
1945
+ // 'timings',
1946
+ // 'startTour',
1947
+ // 'viewName',
1948
+ // 'compareMode',
1949
+ // 'setCompareMode',
1950
+ // 'addSocketMessageListener',
1951
+ // 'currentItemDescriptor',
1952
+ // 'compareTo',
1953
+ // 'setCompareTo',
1954
+ // 'revision',
1955
+ // 'comments',
1956
+ // 'setComments',
1957
+ // 'selectedComment',
1958
+ // 'setSelectedComment',
1959
+ // 'loadComments',
1960
+ // 'mode',
1961
+ // 'setMode',
1962
+ // 'user',
1963
+ // 'reviews',
1964
+ // 'statusMessage',
1965
+ // 'setStatusMessage',
1966
+ // 'suggestedEdits',
1967
+ // 'setSuggestedEdits',
1968
+ // 'showSuggestedEdits',
1969
+ // 'setShowSuggestedEdits',
1970
+ // 'showSuggestedEditsDiff',
1971
+ // 'setShowSuggestedEditsDiff',
1972
+ // 'showRightSidebar',
1973
+ // 'handleSetShowRightSidebar',
1974
+ // 'activeEditorTab',
1975
+ // 'setActiveEditorTab',
1976
+ // 'hideNonEditableComponents',
1977
+ // 'handleSetHideNonEditableComponents',
1978
+ // 'quotaInfo',
1979
+ // 'isQuotaExceeded',
1980
+ // 'getQuotaWarningMessage',
1981
+ // 'isMobile',
1982
+ // 'openDialog',
1983
+ // 'pageWizard',
1984
+ // 'webSocketMessages',
1985
+ // 'currentWizardId',
1986
+ // 'setCurrentWizardId',
1987
+ // 'favorites',
1988
+ // 'loadFavorites',
1989
+ // ];
1990
+ // // Check which dependencies have changed
1991
+ // const changedDependencies: string[] = [];
1992
+ // currentDependencies.forEach((dep, index) => {
1993
+ // if (prevDependencies.current[index] !== dep) {
1994
+ // const depName = dependencyNames[index];
1995
+ // if (depName) {
1996
+ // changedDependencies.push(depName);
1997
+ // }
1998
+ // }
1999
+ // });
2000
+ // if (changedDependencies.length > 0) {
2001
+ // console.group('🔍 EditContext Changed');
2002
+ // console.log('Changed dependencies:', changedDependencies);
2003
+ // console.log('Total dependencies tracked:', currentDependencies.length);
2004
+ // // Log details about the changed dependencies
2005
+ // changedDependencies.forEach(depName => {
2006
+ // const index = dependencyNames.indexOf(depName);
2007
+ // const oldValue = prevDependencies.current[index];
2008
+ // const newValue = currentDependencies[index];
2009
+ // console.log(`📝 ${depName}:`, {
2010
+ // from: oldValue,
2011
+ // to: newValue,
2012
+ // changed: oldValue !== newValue
2013
+ // });
2014
+ // });
2015
+ // console.groupEnd();
2016
+ // }
2017
+ // // Store current dependencies for next comparison
2018
+ // prevDependencies.current = currentDependencies;
2019
+ // editContextRef.current = editContext;
2020
+ // }, [editContext]);
1763
2021
  useEffect(() => {
1764
2022
  modifiedFieldsContext.clear();
1765
2023
  }, [currentItemDescriptor]);
@@ -1771,6 +2029,6 @@ export function EditorClient({ configuration, className, item: loadItemDescripto
1771
2029
  }, 600);
1772
2030
  }, children: _jsx("div", { className: "fixed top-3 left-1/2 -translate-x-1/2 transform rounded-sm bg-gray-200 p-12", children: "Press Ctrl + F11 to exit fullscreen mode" }) }))] })) : (_jsxs(_Fragment, { children: [_jsx(MainLayout, { className: className, view: currentView, centerPanelView: centerPanelView, rightSidebar: currentView.rightSidebar &&
1773
2031
  showRightSidebar && (_jsx(SidebarView, { sidebar: currentView.rightSidebar, editContext: editContext, active: true, detached: true, onClose: () => handleSetShowRightSidebar(false) })), rightSidebarTitle: currentView.rightSidebar?.title }), isTourActive && _jsx(Tour, { tourStopCallback: () => setIsTourActive(false) })] }));
1774
- return (_jsx("div", { className: `editor h-full`, children: _jsx(OperationsContextProvider, { value: operationsContext.context, children: _jsx(ModifiedFieldsContextProvider, { value: modifiedFieldsContext, children: _jsxs(EditContextProvider, { value: editContext, children: [editContext.isRefreshing && (_jsx("div", { className: "pointer-events-none fixed right-0 bottom-0 flex h-24 w-24 items-center justify-center text-gray-600 opacity-50 select-none", children: _jsx(Spinner, {}) })), children || editorUi, dialog, _jsx(Toaster, { position: "top-center" }), " ", _jsx(ConfirmationDialog, { ref: confirmationDialogRef }), _jsx(EditContextMenu, { ref: contextMenuRef }), mediaSelectorVisible && (_jsx(MediaSelector, { language: editContext.currentItemDescriptor.language, visible: mediaSelectorVisible, onHide: () => setMediaSelectorVisible(false), onMediaSelected: onMediaSelect, selectedIdPath: selectedMediaIdPath, mode: mediaSelectorMode })), _jsx(AiPopup, { ref: aiPopupRef }), _jsx(FieldEditorPopup, { ref: fieldEditorPopupRef }), _jsx(EditorFormPopup, { ref: editorFormPopupRef, pageViewContext: pageViewContext })] }) }) }) }));
2032
+ return (_jsx("div", { className: `editor h-full`, children: _jsx(OperationsContextProvider, { value: operationsContext.context, children: _jsx(ModifiedFieldsContextProvider, { value: modifiedFieldsContext, children: _jsxs(EditContextProvider, { value: editContext, children: [editContext.isRefreshing && (_jsx("div", { className: "pointer-events-none fixed right-0 bottom-0 flex h-24 w-24 items-center justify-center text-gray-600 opacity-50 select-none", children: _jsx(Spinner, {}) })), children || editorUi, dialog, _jsx(Toaster, { position: "top-center" }), " ", _jsx(ConfirmationDialog, { ref: confirmationDialogRef }), _jsx(EditContextMenu, { ref: contextMenuRef }), mediaSelectorVisible && (_jsx(MediaSelector, { language: editContext.currentItemDescriptor.language, visible: mediaSelectorVisible, onHide: () => setMediaSelectorVisible(false), onMediaSelected: onMediaSelect, selectedIdPath: selectedMediaIdPath, mode: mediaSelectorMode })), _jsx(FieldEditorPopup, { ref: fieldEditorPopupRef }), _jsx(EditorFormPopup, { ref: editorFormPopupRef, pageViewContext: pageViewContext })] }) }) }) }));
1775
2033
  }
1776
2034
  //# sourceMappingURL=EditorClient.js.map