@alpaca-editor/core 1.0.3956 → 1.0.3960

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 (247) hide show
  1. package/build.css +1 -1
  2. package/dist/components/ui/badge.d.ts +9 -0
  3. package/dist/components/ui/badge.js +23 -0
  4. package/dist/components/ui/badge.js.map +1 -0
  5. package/dist/components/ui/button.js +3 -3
  6. package/dist/components/ui/button.js.map +1 -1
  7. package/dist/components/ui/command.d.ts +18 -0
  8. package/dist/components/ui/command.js +35 -0
  9. package/dist/components/ui/command.js.map +1 -0
  10. package/dist/components/ui/dialog.d.ts +15 -0
  11. package/dist/components/ui/dialog.js +37 -0
  12. package/dist/components/ui/dialog.js.map +1 -0
  13. package/dist/components/ui/dropdown-menu.d.ts +25 -0
  14. package/dist/components/ui/dropdown-menu.js +52 -0
  15. package/dist/components/ui/dropdown-menu.js.map +1 -0
  16. package/dist/components/ui/input.d.ts +3 -0
  17. package/dist/components/ui/input.js +7 -0
  18. package/dist/components/ui/input.js.map +1 -0
  19. package/dist/components/ui/menubar.d.ts +26 -0
  20. package/dist/components/ui/menubar.js +55 -0
  21. package/dist/components/ui/menubar.js.map +1 -0
  22. package/dist/components/ui/popover.d.ts +9 -0
  23. package/dist/components/ui/popover.js +63 -0
  24. package/dist/components/ui/popover.js.map +1 -0
  25. package/dist/components/ui/switch.d.ts +4 -0
  26. package/dist/components/ui/switch.js +9 -0
  27. package/dist/components/ui/switch.js.map +1 -0
  28. package/dist/components/ui/tooltip.d.ts +7 -0
  29. package/dist/components/ui/tooltip.js +18 -0
  30. package/dist/components/ui/tooltip.js.map +1 -0
  31. package/dist/config/config.js +79 -63
  32. package/dist/config/config.js.map +1 -1
  33. package/dist/config/types.d.ts +3 -3
  34. package/dist/editor/ContentTree.js +1 -1
  35. package/dist/editor/ContentTree.js.map +1 -1
  36. package/dist/editor/Editor.js +6 -2
  37. package/dist/editor/Editor.js.map +1 -1
  38. package/dist/editor/FieldList.js +1 -1
  39. package/dist/editor/FieldList.js.map +1 -1
  40. package/dist/editor/FieldListField.js +1 -1
  41. package/dist/editor/FieldListField.js.map +1 -1
  42. package/dist/editor/ImageEditor.js +16 -6
  43. package/dist/editor/ImageEditor.js.map +1 -1
  44. package/dist/editor/MainLayout.js +4 -4
  45. package/dist/editor/MainLayout.js.map +1 -1
  46. package/dist/editor/MobileLayout.js +3 -3
  47. package/dist/editor/MobileLayout.js.map +1 -1
  48. package/dist/editor/PictureEditor.js +29 -15
  49. package/dist/editor/PictureEditor.js.map +1 -1
  50. package/dist/editor/Titlebar.js +6 -11
  51. package/dist/editor/Titlebar.js.map +1 -1
  52. package/dist/editor/ai/GhostWriter.js +1 -1
  53. package/dist/editor/ai/GhostWriter.js.map +1 -1
  54. package/dist/editor/client/EditorClient.d.ts +4 -2
  55. package/dist/editor/client/EditorClient.js +32 -11
  56. package/dist/editor/client/EditorClient.js.map +1 -1
  57. package/dist/editor/client/editContext.d.ts +4 -1
  58. package/dist/editor/client/editContext.js.map +1 -1
  59. package/dist/editor/client/operations.js +2 -2
  60. package/dist/editor/client/pageModelBuilder.js +3 -6
  61. package/dist/editor/client/pageModelBuilder.js.map +1 -1
  62. package/dist/editor/commands/itemCommands.d.ts +2 -0
  63. package/dist/editor/commands/itemCommands.js +180 -0
  64. package/dist/editor/commands/itemCommands.js.map +1 -1
  65. package/dist/editor/field-types/MultiLineText.js +1 -1
  66. package/dist/editor/field-types/MultiLineText.js.map +1 -1
  67. package/dist/editor/field-types/SingleLineText.js +1 -1
  68. package/dist/editor/field-types/SingleLineText.js.map +1 -1
  69. package/dist/editor/menubar/ActiveUsers.js +98 -4
  70. package/dist/editor/menubar/ActiveUsers.js.map +1 -1
  71. package/dist/editor/menubar/{ActionsMenu.d.ts → ItemActionsMenu.d.ts} +1 -1
  72. package/dist/editor/menubar/ItemActionsMenu.js +23 -0
  73. package/dist/editor/menubar/ItemActionsMenu.js.map +1 -0
  74. package/dist/editor/menubar/ItemLanguageVersion.js +2 -2
  75. package/dist/editor/menubar/ItemLanguageVersion.js.map +1 -1
  76. package/dist/editor/menubar/LanguageSelector.d.ts +1 -2
  77. package/dist/editor/menubar/LanguageSelector.js +23 -23
  78. package/dist/editor/menubar/LanguageSelector.js.map +1 -1
  79. package/dist/editor/menubar/PageSelector.js +7 -8
  80. package/dist/editor/menubar/PageSelector.js.map +1 -1
  81. package/dist/editor/menubar/PageViewerControls.js +22 -19
  82. package/dist/editor/menubar/PageViewerControls.js.map +1 -1
  83. package/dist/editor/menubar/PreviewSecondaryControls.js +2 -3
  84. package/dist/editor/menubar/PreviewSecondaryControls.js.map +1 -1
  85. package/dist/editor/menubar/User.js +1 -1
  86. package/dist/editor/menubar/User.js.map +1 -1
  87. package/dist/editor/menubar/VersionSelector.js +36 -31
  88. package/dist/editor/menubar/VersionSelector.js.map +1 -1
  89. package/dist/editor/menubar/WorkflowButton.d.ts +1 -0
  90. package/dist/editor/menubar/WorkflowButton.js +41 -0
  91. package/dist/editor/menubar/WorkflowButton.js.map +1 -0
  92. package/dist/editor/page-editor-chrome/FrameMenu.js +5 -5
  93. package/dist/editor/page-editor-chrome/FrameMenu.js.map +1 -1
  94. package/dist/editor/page-editor-chrome/SuggestionHighlightings.js +2 -2
  95. package/dist/editor/page-editor-chrome/SuggestionHighlightings.js.map +1 -1
  96. package/dist/editor/page-viewer/EditorForm.d.ts +2 -1
  97. package/dist/editor/page-viewer/EditorForm.js +61 -49
  98. package/dist/editor/page-viewer/EditorForm.js.map +1 -1
  99. package/dist/editor/page-viewer/PageViewer.d.ts +2 -1
  100. package/dist/editor/page-viewer/PageViewer.js +28 -44
  101. package/dist/editor/page-viewer/PageViewer.js.map +1 -1
  102. package/dist/editor/page-viewer/PageViewerFrame.js +1 -1
  103. package/dist/editor/page-viewer/PageViewerFrame.js.map +1 -1
  104. package/dist/editor/reviews/Comments.js +9 -9
  105. package/dist/editor/reviews/Comments.js.map +1 -1
  106. package/dist/editor/reviews/SuggestedEdit.js +3 -3
  107. package/dist/editor/services/contentService.d.ts +18 -0
  108. package/dist/editor/services/contentService.js +6 -0
  109. package/dist/editor/services/contentService.js.map +1 -1
  110. package/dist/editor/services/editService.d.ts +5 -0
  111. package/dist/editor/services/editService.js +4 -0
  112. package/dist/editor/services/editService.js.map +1 -1
  113. package/dist/editor/services/systemService.d.ts +2 -1
  114. package/dist/editor/services/systemService.js +4 -1
  115. package/dist/editor/services/systemService.js.map +1 -1
  116. package/dist/editor/sidebar/ComponentTree.js +26 -10
  117. package/dist/editor/sidebar/ComponentTree.js.map +1 -1
  118. package/dist/editor/sidebar/Divider.d.ts +6 -0
  119. package/dist/editor/sidebar/Divider.js +6 -0
  120. package/dist/editor/sidebar/Divider.js.map +1 -0
  121. package/dist/editor/sidebar/LeftToolbar.d.ts +1 -0
  122. package/dist/editor/sidebar/LeftToolbar.js +16 -0
  123. package/dist/editor/sidebar/LeftToolbar.js.map +1 -0
  124. package/dist/editor/sidebar/SEOInfo.d.ts +1 -0
  125. package/dist/editor/sidebar/SEOInfo.js +169 -0
  126. package/dist/editor/sidebar/SEOInfo.js.map +1 -0
  127. package/dist/editor/sidebar/Sidebar.js +1 -1
  128. package/dist/editor/sidebar/Sidebar.js.map +1 -1
  129. package/dist/editor/sidebar/SidebarView.d.ts +3 -2
  130. package/dist/editor/sidebar/SidebarView.js +22 -60
  131. package/dist/editor/sidebar/SidebarView.js.map +1 -1
  132. package/dist/editor/sidebar/ViewSelector.js +66 -20
  133. package/dist/editor/sidebar/ViewSelector.js.map +1 -1
  134. package/dist/editor/ui/Icons.d.ts +4 -0
  135. package/dist/editor/ui/Icons.js +15 -3
  136. package/dist/editor/ui/Icons.js.map +1 -1
  137. package/dist/editor/ui/Section.js +1 -1
  138. package/dist/editor/ui/Section.js.map +1 -1
  139. package/dist/editor/ui/SimpleIconButton.d.ts +1 -2
  140. package/dist/editor/ui/SimpleIconButton.js +8 -13
  141. package/dist/editor/ui/SimpleIconButton.js.map +1 -1
  142. package/dist/editor/ui/SimpleTabs.js +2 -2
  143. package/dist/editor/ui/SimpleTabs.js.map +1 -1
  144. package/dist/editor/ui/SimpleToolbar.js +1 -1
  145. package/dist/editor/ui/SimpleToolbar.js.map +1 -1
  146. package/dist/editor/ui/Splitter.d.ts +4 -0
  147. package/dist/editor/ui/Splitter.js +6 -7
  148. package/dist/editor/ui/Splitter.js.map +1 -1
  149. package/dist/editor/views/CompareView.js +16 -4
  150. package/dist/editor/views/CompareView.js.map +1 -1
  151. package/dist/editor/views/SingleEditView.d.ts +2 -1
  152. package/dist/editor/views/SingleEditView.js +2 -2
  153. package/dist/editor/views/SingleEditView.js.map +1 -1
  154. package/dist/page-wizard/steps/ContentStep.js +1 -1
  155. package/dist/page-wizard/steps/ContentStep.js.map +1 -1
  156. package/dist/revision.d.ts +2 -2
  157. package/dist/revision.js +2 -2
  158. package/dist/splash-screen/NewPage.js +8 -6
  159. package/dist/splash-screen/NewPage.js.map +1 -1
  160. package/dist/splash-screen/RecentPages.js +3 -8
  161. package/dist/splash-screen/RecentPages.js.map +1 -1
  162. package/dist/styles.css +1519 -543
  163. package/dist/tour/Tour.js +79 -10
  164. package/dist/tour/Tour.js.map +1 -1
  165. package/dist/tour/default-tour.js +55 -45
  166. package/dist/tour/default-tour.js.map +1 -1
  167. package/dist/types.d.ts +19 -1
  168. package/package.json +13 -5
  169. package/src/components/ui/badge.tsx +46 -0
  170. package/src/components/ui/button.tsx +3 -3
  171. package/src/components/ui/command.tsx +184 -0
  172. package/src/components/ui/dialog.tsx +143 -0
  173. package/src/components/ui/dropdown-menu.tsx +257 -0
  174. package/src/components/ui/input.tsx +21 -0
  175. package/src/components/ui/menubar.tsx +276 -0
  176. package/src/components/ui/popover.tsx +113 -0
  177. package/src/components/ui/switch.tsx +31 -0
  178. package/src/components/ui/tooltip.tsx +61 -0
  179. package/src/config/config.tsx +102 -65
  180. package/src/config/types.ts +3 -3
  181. package/src/editor/ContentTree.tsx +1 -1
  182. package/src/editor/Editor.tsx +8 -2
  183. package/src/editor/FieldList.tsx +2 -2
  184. package/src/editor/FieldListField.tsx +1 -1
  185. package/src/editor/ImageEditor.tsx +44 -21
  186. package/src/editor/MainLayout.tsx +21 -16
  187. package/src/editor/MobileLayout.tsx +3 -2
  188. package/src/editor/PictureEditor.tsx +74 -45
  189. package/src/editor/Titlebar.tsx +12 -24
  190. package/src/editor/ai/GhostWriter.tsx +1 -1
  191. package/src/editor/client/EditorClient.tsx +55 -13
  192. package/src/editor/client/editContext.ts +5 -0
  193. package/src/editor/client/operations.ts +2 -2
  194. package/src/editor/client/pageModelBuilder.ts +3 -7
  195. package/src/editor/commands/itemCommands.tsx +272 -0
  196. package/src/editor/field-types/MultiLineText.tsx +1 -1
  197. package/src/editor/field-types/SingleLineText.tsx +1 -1
  198. package/src/editor/menubar/ActiveUsers.tsx +271 -5
  199. package/src/editor/menubar/ItemActionsMenu.tsx +89 -0
  200. package/src/editor/menubar/ItemLanguageVersion.tsx +7 -5
  201. package/src/editor/menubar/LanguageSelector.tsx +105 -134
  202. package/src/editor/menubar/PageSelector.tsx +25 -27
  203. package/src/editor/menubar/PageViewerControls.tsx +126 -78
  204. package/src/editor/menubar/PreviewSecondaryControls.tsx +0 -2
  205. package/src/editor/menubar/User.tsx +2 -2
  206. package/src/editor/menubar/VersionSelector.tsx +124 -99
  207. package/src/editor/menubar/WorkflowButton.tsx +115 -0
  208. package/src/editor/page-editor-chrome/FrameMenu.tsx +5 -5
  209. package/src/editor/page-editor-chrome/SuggestionHighlightings.tsx +2 -2
  210. package/src/editor/page-viewer/EditorForm.tsx +112 -87
  211. package/src/editor/page-viewer/PageViewer.tsx +75 -92
  212. package/src/editor/page-viewer/PageViewerFrame.tsx +1 -1
  213. package/src/editor/reviews/Comments.tsx +19 -20
  214. package/src/editor/reviews/SuggestedEdit.tsx +3 -3
  215. package/src/editor/services/contentService.ts +28 -0
  216. package/src/editor/services/editService.ts +12 -0
  217. package/src/editor/services/systemService.ts +5 -2
  218. package/src/editor/sidebar/ComponentTree.tsx +34 -12
  219. package/src/editor/sidebar/Divider.tsx +22 -0
  220. package/src/editor/sidebar/LeftToolbar.tsx +36 -0
  221. package/src/editor/sidebar/SEOInfo.tsx +265 -0
  222. package/src/editor/sidebar/Sidebar.tsx +1 -0
  223. package/src/editor/sidebar/SidebarView.tsx +77 -111
  224. package/src/editor/sidebar/ViewSelector.tsx +211 -43
  225. package/src/editor/ui/Icons.tsx +155 -10
  226. package/src/editor/ui/Section.tsx +1 -1
  227. package/src/editor/ui/SimpleIconButton.tsx +30 -28
  228. package/src/editor/ui/SimpleTabs.tsx +3 -3
  229. package/src/editor/ui/SimpleToolbar.tsx +1 -1
  230. package/src/editor/ui/Splitter.tsx +14 -7
  231. package/src/editor/views/CompareView.tsx +23 -11
  232. package/src/editor/views/SingleEditView.tsx +3 -0
  233. package/src/page-wizard/steps/ContentStep.tsx +0 -1
  234. package/src/revision.ts +2 -2
  235. package/src/splash-screen/NewPage.tsx +18 -13
  236. package/src/splash-screen/RecentPages.tsx +4 -10
  237. package/src/tour/Tour.tsx +125 -34
  238. package/src/tour/default-tour.tsx +55 -45
  239. package/src/types.ts +21 -1
  240. package/styles.css +301 -1
  241. package/dist/editor/menubar/ActionsMenu.js +0 -49
  242. package/dist/editor/menubar/ActionsMenu.js.map +0 -1
  243. package/dist/editor/menubar/SecondaryControls.d.ts +0 -1
  244. package/dist/editor/menubar/SecondaryControls.js +0 -17
  245. package/dist/editor/menubar/SecondaryControls.js.map +0 -1
  246. package/src/editor/menubar/ActionsMenu.tsx +0 -94
  247. package/src/editor/menubar/SecondaryControls.tsx +0 -45
@@ -222,7 +222,7 @@ export function FrameMenu({
222
222
  shared: "border-orange-400",
223
223
  readonly: "border-gray-400",
224
224
  layout: "border-purple-400",
225
- default: "border-sky-400",
225
+ default: "border-component-blue",
226
226
  nonMovable: "border-red-400",
227
227
  suggestions: "border-teal-400",
228
228
  };
@@ -231,7 +231,7 @@ export function FrameMenu({
231
231
  shared: "bg-orange-400",
232
232
  readonly: "bg-gray-400",
233
233
  layout: "bg-purple-400",
234
- default: "bg-sky-400",
234
+ default: "bg-component-blue",
235
235
  nonMovable: "bg-red-400",
236
236
  suggestions: "bg-teal-400",
237
237
  };
@@ -254,7 +254,7 @@ export function FrameMenu({
254
254
  className={cn(
255
255
  "pointer-events-none absolute inset-0 rounded-b-sm border-2",
256
256
  colorVariants[color],
257
- "tour-frame-menu opacity-50 hover:opacity-100",
257
+ "tour-frame-menu opacity-70 hover:opacity-100",
258
258
  !isMultiSelected && isHeaderWiderThanComponent && "border-t-0",
259
259
  !isMultiSelected && !isHeaderWiderThanComponent && "rounded-tl-sm",
260
260
  isMultiSelected && "rounded-t-sm",
@@ -273,8 +273,8 @@ export function FrameMenu({
273
273
  ref={headerRef}
274
274
  className={
275
275
  `editframe-menu pointer-events-auto absolute z-1000 flex items-center pr-4 text-base text-white ${bgColorVariants[color]} ` +
276
- (componentRect.y - 36 < 0 ? "rounded-bl-lg" : "rounded-t-lg") +
277
- (isHeaderWiderThanComponent ? " rounded-bl-lg" : "")
276
+ (componentRect.y - 36 < 0 ? "rounded-bl" : "rounded-t") +
277
+ (isHeaderWiderThanComponent ? " rounded-bl" : "")
278
278
  }
279
279
  style={{
280
280
  right: "-2px",
@@ -18,7 +18,7 @@ export function SuggestionHighlightings({
18
18
 
19
19
  useEffect(() => {
20
20
  setSuggestions(
21
- editContext?.suggestedEdits.filter((x) => x.status === "Pending") || [],
21
+ editContext?.suggestedEdits.filter((x) => x.status === "pending") || [],
22
22
  );
23
23
  }, [editContext?.comments, editContext?.suggestedEdits]);
24
24
 
@@ -26,7 +26,7 @@ export function SuggestionHighlightings({
26
26
  <>
27
27
  {editContext?.showSuggestedEdits &&
28
28
  suggestions
29
- .filter((x) => x.status !== "approved" && x.status !== "rejected")
29
+ .filter((x) => x.status !== "applied" && x.status !== "rejected")
30
30
  .map((suggestion) => (
31
31
  <SuggestionHighlighting
32
32
  iframe={iframe}
@@ -11,47 +11,38 @@ import { Component, Field, FullItem, RenderedItem } from "../pageModel";
11
11
  import { Spinner } from "../ui/Spinner";
12
12
  import { PageViewContext } from "./pageViewContext";
13
13
  import { SimpleTabs, Tab } from "../ui/SimpleTabs";
14
+ import { ChevronLeft, X } from "lucide-react";
14
15
 
15
16
  export function EditorForm({
16
17
  pageViewContext,
17
18
  readonly,
18
19
  compareView,
20
+ onCollapse,
19
21
  }: {
20
22
  pageViewContext?: PageViewContext;
21
23
  readonly?: boolean;
22
24
  compareView: boolean;
25
+ onCollapse?: () => void;
23
26
  }) {
24
27
  const editContext = useEditContext()!;
25
28
  if (!pageViewContext) pageViewContext = editContext.pageView;
26
29
 
27
- const setInsertMode = editContext.setInsertMode;
28
30
  const insertMode =
29
31
  editContext.insertMode && editContext.mode === "edit" && !compareView;
30
32
  const [activeTabKey, setActiveTabKey] = useState("content");
31
33
  const [item, setItem] = useState<RenderedItem>();
32
34
  const [component, setComponent] = useState<Component>();
33
35
  const [fullItem, setFullItem] = useState<FullItem>();
34
-
35
- const toggleInsertMode = () => {
36
- if (insertMode) {
37
- setInsertMode(false);
38
- } else {
39
- setInsertMode(true);
40
- }
41
- };
36
+ const [hasDatasource, setHasDatasource] = useState(true);
42
37
 
43
38
  useEffect(() => {
44
39
  async function loadFullItem() {
45
- if (!item) return;
40
+ if (!item || !hasDatasource) return;
46
41
  const fullItem = await editContext!.itemsRepository.getItem(item);
47
42
  setFullItem(fullItem);
48
43
  }
49
44
  loadFullItem();
50
- }, [item]);
51
-
52
- useEffect(() => {
53
- if (editContext.selectedForInsertion) setInsertMode(true);
54
- }, [editContext.selectedForInsertion]);
45
+ }, [item, hasDatasource]);
55
46
 
56
47
  let isShared = false;
57
48
 
@@ -59,38 +50,50 @@ export function EditorForm({
59
50
  if (!pageViewContext.page) {
60
51
  setComponent(undefined);
61
52
  setItem(undefined);
53
+ setHasDatasource(true);
62
54
  return;
63
55
  }
64
56
  let newSelectedItem;
57
+ let selectedComponent;
65
58
 
66
59
  if (editContext.selection.length === 1) {
67
- const component = getComponentById(
60
+ selectedComponent = getComponentById(
68
61
  editContext.selection[0]!,
69
62
  pageViewContext.page,
70
63
  );
71
64
 
72
- setComponent(component);
73
- newSelectedItem = component?.datasourceItem;
65
+ setComponent(selectedComponent);
66
+ newSelectedItem = selectedComponent?.datasourceItem;
74
67
  if (
75
- component?.datasourceItem &&
76
- component?.datasourceItem?.id !== component?.id
68
+ selectedComponent?.datasourceItem &&
69
+ selectedComponent?.datasourceItem?.id !== selectedComponent?.id
77
70
  )
78
71
  isShared = true;
79
72
  } else {
80
73
  newSelectedItem = pageViewContext.page.rootComponent.datasourceItem;
81
- setComponent(pageViewContext.page.rootComponent);
74
+ selectedComponent = pageViewContext.page.rootComponent;
75
+ setComponent(selectedComponent);
82
76
  }
83
77
 
84
- setItem(
85
- newSelectedItem || pageViewContext.page.rootComponent.datasourceItem,
86
- );
78
+ // Check if we have a datasource item
79
+ const hasItemDatasource = !!newSelectedItem;
80
+ setHasDatasource(hasItemDatasource);
81
+
82
+ if (hasItemDatasource) {
83
+ setItem(newSelectedItem);
84
+ } else {
85
+ // No datasource item, clear the item state
86
+ setItem(undefined);
87
+ setFullItem(undefined);
88
+ }
87
89
  }, [
88
90
  editContext.selection,
89
91
  pageViewContext.page,
90
92
  pageViewContext.pageItemDescriptor,
91
93
  ]);
92
94
 
93
- if (!fullItem || !item)
95
+ // Show spinner only when we have a datasource but haven't loaded the full item yet
96
+ if (hasDatasource && (!fullItem || !item))
94
97
  return (
95
98
  <div className="grid h-full w-full items-center justify-center">
96
99
  <Spinner />
@@ -123,28 +126,32 @@ export function EditorForm({
123
126
 
124
127
  const itemFields: ItemFields[] = [];
125
128
 
126
- const contentFields = Object.values(fullItem?.fields || []).filter(
127
- (x) =>
128
- ((editorFields && editorFields["Content"]?.addFields.includes(x.name!)) ||
129
- item.renderedFieldIds.indexOf(x.id) >= 0) &&
130
- !(
131
- editorFields && editorFields["Content"]?.removeFields.includes(x.name!)
132
- ),
133
- );
134
- if (contentFields.length > 0) itemFields.push({ fields: contentFields });
129
+ if (item) {
130
+ const contentFields = Object.values(fullItem?.fields || []).filter(
131
+ (x) =>
132
+ ((editorFields &&
133
+ editorFields["Content"]?.addFields.includes(x.name!)) ||
134
+ item.renderedFieldIds.indexOf(x.id) >= 0) &&
135
+ !(
136
+ editorFields &&
137
+ editorFields["Content"]?.removeFields.includes(x.name!)
138
+ ),
139
+ );
140
+ if (contentFields.length > 0) itemFields.push({ fields: contentFields });
135
141
 
136
- component?.items
137
- .filter((x) => x.id !== item.id)
138
- .forEach((i) => {
139
- const fields: Field[] = [];
140
- i.renderedFieldIds.forEach((id) => {
141
- const field = Object.values(fullItem?.fields || []).find(
142
- (x) => x.id === id,
143
- );
144
- if (field) fields.push(field);
142
+ component?.items
143
+ .filter((x) => x.id !== item.id)
144
+ .forEach((i) => {
145
+ const fields: Field[] = [];
146
+ i.renderedFieldIds.forEach((id) => {
147
+ const field = Object.values(fullItem?.fields || []).find(
148
+ (x) => x.id === id,
149
+ );
150
+ if (field) fields.push(field);
151
+ });
152
+ if (fields.length > 0) itemFields.push({ headline: i.name, fields });
145
153
  });
146
- if (fields.length > 0) itemFields.push({ headline: i.name, fields });
147
- });
154
+ }
148
155
 
149
156
  const getFieldsTab = (fields: ItemFields[], headline: string, id: string) => {
150
157
  return {
@@ -187,33 +194,31 @@ export function EditorForm({
187
194
  getFieldsTab([{ fields: designFields }], "Design", "design"),
188
195
  );
189
196
 
190
- tabPanels.push({
191
- label: "Advanced",
192
- content: (
193
- <div className="relative h-full">
194
- <div className="absolute inset-0 overflow-auto">
195
- <ItemInfo item={fullItem} />
196
- <FieldList
197
- fields={[{ fields: fullItem?.fields || [] }]}
198
- validators={validators}
199
- showStandardFieldsEnabled={true}
200
- readonly={readonly}
201
- />
197
+ if (hasDatasource)
198
+ tabPanels.push({
199
+ label: "Advanced",
200
+ content: (
201
+ <div className="relative h-full">
202
+ <div className="absolute inset-0 overflow-auto">
203
+ {fullItem && <ItemInfo item={fullItem} />}
204
+ <FieldList
205
+ fields={[{ fields: fullItem?.fields || [] }]}
206
+ validators={validators}
207
+ showStandardFieldsEnabled={true}
208
+ readonly={readonly}
209
+ />
210
+ </div>
202
211
  </div>
203
- </div>
204
- ),
205
- id: "advanced",
206
- });
212
+ ),
213
+ id: "advanced",
214
+ });
207
215
 
208
216
  return (
209
- <div
210
- className="flex h-full flex-col bg-gray-50"
211
- data-testid="editor-sidepanel"
212
- >
213
- <h1 className="flex h-12 items-center justify-center border-b border-gray-200 p-2">
217
+ <div className="flex h-full flex-col" data-testid="editor-sidepanel">
218
+ <h1 className="border-gray-3 flex h-12 items-center justify-center border-b p-2">
214
219
  {component && component !== pageViewContext.page?.rootComponent && (
215
220
  <SimpleIconButton
216
- icon="pi pi-angle-left"
221
+ icon={<ChevronLeft className="h-6 w-6" strokeWidth={1} />}
217
222
  onClick={() => editContext.select([])}
218
223
  label="Back to page"
219
224
  size="large"
@@ -221,41 +226,61 @@ export function EditorForm({
221
226
  )}
222
227
  {editContext.selection.length === 0 && <div className="w-12" />}
223
228
  <div
224
- className="flex-1 text-center text-gray-800"
229
+ className="text-dark flex-1 text-center text-sm font-medium"
225
230
  id="item-name"
226
231
  data-testid="component-name"
227
232
  >
228
- {item?.name}
229
- {isShared && (
233
+ {insertMode ? "Add Component" : component?.name}
234
+ {!insertMode && isShared && (
230
235
  <span className="ml-2 rounded-md bg-orange-400 p-2 text-sm text-black">
231
236
  Shared
232
237
  </span>
233
238
  )}
234
239
  </div>
235
240
  <SimpleIconButton
236
- id="insert-component-button"
237
- icon={insertMode ? "pi pi-pencil" : "pi pi-plus"}
238
- onClick={() => toggleInsertMode()}
239
- label={insertMode ? "Continue editing" : "Insert component"}
241
+ icon={<X className="h-6 w-6 p-1" strokeWidth={1} />}
242
+ onClick={() => {
243
+ if (insertMode) {
244
+ editContext.setInsertMode(false);
245
+ } else {
246
+ onCollapse?.();
247
+ }
248
+ }}
249
+ label="Close"
240
250
  size="large"
241
- disabled={
242
- !editContext.page?.item.canWriteItem ||
243
- !fullItem?.canWriteItem ||
244
- editContext.mode !== "edit" ||
245
- compareView
246
- }
247
251
  />
248
252
  </h1>
249
253
 
250
254
  {insertMode && <Insert />}
251
255
  {!insertMode && (
252
- <SimpleTabs
253
- key="editor-tabs"
254
- tabs={tabPanels}
255
- className="flex flex-1 items-center justify-center border-b border-gray-200 bg-gray-50 py-2.5 text-sm"
256
- activeTab={tabPanels.findIndex((x) => x.id === activeTabKey) || 0}
257
- setActiveTab={(index) => setActiveTabKey(tabPanels[index]?.id!)}
258
- ></SimpleTabs>
256
+ <div className="flex flex-1 flex-col">
257
+ {/* <div className="border-b border-gray-200 bg-gray-50 px-4 py-3">
258
+ <div className="flex flex-wrap gap-2 text-sm">
259
+ {component?.isShared && (
260
+ <Badge variant="outline">Shared Component</Badge>
261
+ )}
262
+ {component?.layoutId && (
263
+ <Badge variant="outline">Layout Component</Badge>
264
+ )}
265
+ {component?.isInheritedFromMasterLanguage && (
266
+ <Badge variant="outline">Inherited</Badge>
267
+ )}
268
+ {component?.isRemovedFromMasterLanguage && (
269
+ <Badge variant="outline">Removed from Master</Badge>
270
+ )}
271
+ {!component?.visible && <Badge variant="outline">Hidden</Badge>}
272
+ <Badge variant="outline">{component?.type}</Badge>
273
+ {!hasDatasource && <Badge variant="outline">No Datasource</Badge>}
274
+ </div>
275
+ </div> */}
276
+ <SimpleTabs
277
+ key="editor-tabs"
278
+ tabs={tabPanels}
279
+ className="flex flex-1 items-center justify-center border-b border-gray-200 pt-4 text-xs"
280
+ activeTab={tabPanels.findIndex((x) => x.id === activeTabKey) || 0}
281
+ setActiveTab={(index) => setActiveTabKey(tabPanels[index]?.id!)}
282
+ ></SimpleTabs>
283
+ </div>
259
284
  )}
260
285
  </div>
261
286
  );
@@ -1,4 +1,3 @@
1
- import { Allotment, AllotmentHandle } from "allotment";
2
1
  import { PageViewContext } from "./pageViewContext";
3
2
  import { EditorForm } from "./EditorForm";
4
3
  import { PageViewerFrame } from "./PageViewerFrame";
@@ -8,6 +7,8 @@ import { SimpleIconButton } from "../ui/SimpleIconButton";
8
7
  import { useEditContext } from "../client/editContext";
9
8
  import { useDebouncedCallback } from "use-debounce";
10
9
  import { Ellipsis, PanelLeftClose, PanelLeftOpen } from "lucide-react";
10
+ import { cn } from "../../lib/utils";
11
+ import { Splitter, SplitterPanel } from "../ui/Splitter";
11
12
 
12
13
  export function PageViewer({
13
14
  pageViewContext,
@@ -15,49 +16,22 @@ export function PageViewer({
15
16
  compareView,
16
17
  name,
17
18
  followEditsDefault,
19
+ className,
18
20
  }: {
19
21
  pageViewContext?: PageViewContext;
20
22
  showFormEditor: boolean;
21
23
  compareView?: boolean;
22
24
  name: string;
23
25
  followEditsDefault?: boolean;
26
+ className?: string;
24
27
  }) {
25
- const panels = [];
26
-
27
28
  const editContext = useEditContext();
28
29
 
29
30
  const [followEdits, setFollowEdits] = useState(followEditsDefault);
30
-
31
- const allotmentRef = useRef<AllotmentHandle>(null);
32
- const [formEditorWidth, setFormEditorWidth] = useState(0);
33
31
  const [formEditorCollapsed, setFormEditorCollapsed] = useState(false);
34
32
 
35
33
  if (!pageViewContext) return null;
36
34
 
37
- useEffect(() => {
38
- const width = localStorage.getItem("editor.editFormWidth." + name)
39
- ? parseInt(localStorage.getItem("editor.editFormWidth." + name)!)
40
- : 300;
41
-
42
- setFormEditorWidth(width);
43
- resizePanels(width);
44
- }, []);
45
-
46
- const resizePanels = useDebouncedCallback((width: number) => {
47
- if (!allotmentRef.current) return;
48
- const newsizes: number[] = [];
49
- if (showFormEditor) newsizes.push(width);
50
- allotmentRef.current?.resize(newsizes);
51
- }, 140);
52
-
53
- useEffect(() => {
54
- if (formEditorWidth > 0)
55
- localStorage.setItem(
56
- "editor.editFormWidth." + name,
57
- formEditorWidth.toString(),
58
- );
59
- }, [formEditorWidth]);
60
-
61
35
  useEffect(() => {
62
36
  if (
63
37
  followEdits &&
@@ -79,7 +53,7 @@ export function PageViewer({
79
53
  }
80
54
 
81
55
  const element =
82
- pageViewContext.editorIframeRef.current?.contentWindow?.document.querySelector(
56
+ pageViewContext?.editorIframeRef.current?.contentWindow?.document.querySelector(
83
57
  `[data-fieldid="${lastEdit.fieldId}"][data-itemid="${lastEdit.item.id}"][data-language="${lastEdit.item.language}"][data-version="${lastEdit.item.version}"]`,
84
58
  );
85
59
 
@@ -87,74 +61,83 @@ export function PageViewer({
87
61
  element.scrollIntoView({ behavior: "smooth", block: "center" });
88
62
  }
89
63
  }
90
- }, [editContext?.lastEditedFields]);
64
+ }, [
65
+ editContext?.lastEditedFields,
66
+ editContext,
67
+ followEdits,
68
+ pageViewContext,
69
+ ]);
91
70
 
92
- if (showFormEditor) {
93
- if (!formEditorCollapsed) {
94
- panels.push(
95
- <div key="form" className="flex h-full w-full flex-col">
96
- <div className="flex-1">
97
- <EditorForm
98
- pageViewContext={pageViewContext}
99
- readonly={editContext?.mode !== "edit"}
100
- compareView={compareView || false}
101
- />
102
- </div>
103
- <div className="flex items-center justify-between gap-1 bg-gray-50 p-1">
104
- <div className="p-1 text-xs text-gray-500">
105
- {editContext?.statusMessage}
106
- </div>
107
- <div className="flex gap-1">
108
- <SimpleIconButton
109
- icon=<Ellipsis size={12} />
110
- selected={editContext?.enableCompletions}
111
- label="Enable Completions"
112
- onClick={() => editContext?.setEnableCompletions((c) => !c)}
113
- />
114
- <SimpleIconButton
115
- icon="pi pi-step-forward"
116
- selected={followEdits}
117
- label="Follow"
118
- onClick={() => setFollowEdits((f) => !f)}
119
- />
120
- <SimpleIconButton
121
- icon={<PanelLeftClose size={12} />}
122
- label="Collapse"
123
- onClick={() => setFormEditorCollapsed(true)}
71
+ if (!pageViewContext) return null;
72
+
73
+ // Create panels array for the Splitter component
74
+ const panels: SplitterPanel[] = [];
75
+
76
+ if (showFormEditor && !formEditorCollapsed) {
77
+ panels.push({
78
+ name: "form",
79
+ defaultSize: 300,
80
+ collapsible: true,
81
+ content: (
82
+ <div className="h-full w-full p-2 pl-1">
83
+ <div className="border-gray-3 flex h-full w-full flex-col rounded-2xl border bg-white">
84
+ <div className="flex-1">
85
+ <EditorForm
86
+ pageViewContext={pageViewContext}
87
+ readonly={editContext?.mode !== "edit"}
88
+ compareView={compareView || false}
89
+ onCollapse={() => setFormEditorCollapsed(true)}
124
90
  />
125
91
  </div>
92
+ <div className="flex items-center justify-between gap-1 p-1">
93
+ <div className="p-1 text-xs text-gray-500">
94
+ {editContext?.statusMessage}
95
+ </div>
96
+ <div className="flex gap-1">
97
+ <SimpleIconButton
98
+ icon=<Ellipsis size={12} />
99
+ selected={editContext?.enableCompletions}
100
+ label="Enable Completions"
101
+ onClick={() => editContext?.setEnableCompletions((c) => !c)}
102
+ />
103
+ <SimpleIconButton
104
+ icon="pi pi-step-forward"
105
+ selected={followEdits}
106
+ label="Follow"
107
+ onClick={() => setFollowEdits((f) => !f)}
108
+ />
109
+ <SimpleIconButton
110
+ icon={<PanelLeftClose size={12} />}
111
+ label="Collapse"
112
+ onClick={() => setFormEditorCollapsed(true)}
113
+ />
114
+ </div>
115
+ </div>
126
116
  </div>
127
- </div>,
128
- );
129
- }
117
+ </div>
118
+ ),
119
+ });
130
120
  }
131
121
 
132
- panels.push(
133
- <PageViewerFrame
134
- compareView={compareView || false}
135
- pageViewContext={pageViewContext}
136
- key="frame"
137
- />,
138
- );
139
-
140
- if (editContext?.isMobile) {
141
- panels.reverse();
142
- }
122
+ panels.push({
123
+ name: "frame",
124
+ defaultSize: "auto",
125
+ content: (
126
+ <PageViewerFrame
127
+ compareView={compareView || false}
128
+ pageViewContext={pageViewContext}
129
+ />
130
+ ),
131
+ });
143
132
 
144
133
  return (
145
- <>
146
- <Allotment
147
- proportionalLayout={false}
148
- ref={allotmentRef}
149
- vertical={editContext?.isMobile}
150
- onChange={(newSizes) => {
151
- if (!newSizes || newSizes.length === 0) return;
152
- if (showFormEditor && newSizes[0]) {
153
- setFormEditorWidth(newSizes[0]);
154
- }
155
- }}
156
- children={panels}
157
- ></Allotment>
134
+ <div className={cn("h-full w-full", className)}>
135
+ <Splitter
136
+ panels={panels}
137
+ splitterClassName="bg-transparent -ml-1"
138
+ direction={editContext?.isMobile ? "vertical" : "horizontal"}
139
+ localStorageKey={`editor.pageViewer.${name}`}
140
+ />
158
141
  {formEditorCollapsed && (
159
142
  <div className="absolute bottom-0 left-0 z-10 flex items-center justify-center">
160
143
  <SimpleIconButton
@@ -164,6 +147,6 @@ export function PageViewer({
164
147
  />
165
148
  </div>
166
149
  )}
167
- </>
150
+ </div>
168
151
  );
169
152
  }
@@ -803,7 +803,7 @@ export function PageViewerFrame({
803
803
  : pageViewContext.deviceHeight || 640;
804
804
 
805
805
  return (
806
- <div className="relative flex h-full w-full flex-col items-center bg-slate-100 select-none">
806
+ <div className="relative mt-2 flex h-full w-full flex-col items-center select-none">
807
807
  {!editContext.pageView.fullscreen && (
808
808
  <EditorWarnings item={pageViewContext.page?.item} />
809
809
  )}
@@ -30,7 +30,7 @@ export function Comments() {
30
30
 
31
31
  // Filter out applied suggestions if hideAppliedSuggestions is true
32
32
  const filteredSuggestedEdits = hideAppliedSuggestions
33
- ? suggestedEdits.filter((edit) => edit.status !== "Applied")
33
+ ? suggestedEdits.filter((edit) => edit.status !== "applied")
34
34
  : suggestedEdits;
35
35
 
36
36
  const combined: FeedbackItem[] = [...comments, ...filteredSuggestedEdits];
@@ -47,6 +47,24 @@ export function Comments() {
47
47
 
48
48
  return (
49
49
  <div className="flex h-full flex-col">
50
+ <div className="border-gray-3 flex-1 overflow-auto border-b">
51
+ <div className="h-fill-available p-4">
52
+ {feedbackItems.map((item) => {
53
+ // Use a discriminator check. Here we assume suggested edits have the properties oldValue and newValue.
54
+ if ("oldValue" in item && "newValue" in item) {
55
+ return (
56
+ <SuggestedEditComponent
57
+ key={item.id}
58
+ edit={item as SuggestedEdit}
59
+ />
60
+ );
61
+ }
62
+ return (
63
+ <CommentComponent key={item.id} comment={item as CommentType} />
64
+ );
65
+ })}
66
+ </div>
67
+ </div>
50
68
  <SimpleToolbar>
51
69
  <SimpleIconButton
52
70
  id="add-comment"
@@ -101,25 +119,6 @@ export function Comments() {
101
119
  }}
102
120
  />
103
121
  </SimpleToolbar>
104
-
105
- <div className="flex-1 overflow-auto">
106
- <div className="h-fill-available border-l border-gray-200 bg-gray-50 p-4">
107
- {feedbackItems.map((item) => {
108
- // Use a discriminator check. Here we assume suggested edits have the properties oldValue and newValue.
109
- if ("oldValue" in item && "newValue" in item) {
110
- return (
111
- <SuggestedEditComponent
112
- key={item.id}
113
- edit={item as SuggestedEdit}
114
- />
115
- );
116
- }
117
- return (
118
- <CommentComponent key={item.id} comment={item as CommentType} />
119
- );
120
- })}
121
- </div>
122
- </div>
123
122
  </div>
124
123
  );
125
124
  }