@alpaca-editor/core 1.0.3955 → 1.0.3959

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
@@ -1,9 +1,18 @@
1
- import { classNames } from "primereact/utils";
2
1
  import { useEditContext } from "../client/editContext";
3
2
  import { Separator } from "./Separator";
4
3
  import { CompareIcon, FormEditIcon } from "../ui/Icons";
5
4
  import { SimpleIconButton } from "../ui/SimpleIconButton";
6
- import { Route, SquarePen, UserRoundPen, EyeIcon, Pencil } from "lucide-react";
5
+ import {
6
+ EyeIcon,
7
+ MessagesSquare,
8
+ Pencil,
9
+ Monitor,
10
+ Smartphone,
11
+ Table,
12
+ Plus,
13
+ Layers,
14
+ } from "lucide-react";
15
+ import { EnterFullScreenIcon } from "@radix-ui/react-icons";
7
16
 
8
17
  export function PageViewerControls() {
9
18
  const editContext = useEditContext();
@@ -17,104 +26,143 @@ export function PageViewerControls() {
17
26
  const device = pageViewContext.device;
18
27
  const setDevice = pageViewContext.setDevice;
19
28
 
29
+ // Insert mode logic
30
+ const insertMode = editContext.insertMode;
31
+
32
+ const toggleInsertMode = () => {
33
+ editContext.setInsertMode(true);
34
+ };
35
+
36
+ // Calculate total count of comments and suggestions
37
+ const commentsCount =
38
+ editContext.comments?.filter((x) => !x.isResolved).length || 0;
39
+ const suggestionsCount =
40
+ editContext.suggestedEdits?.filter((x) => x.status === "pending").length ||
41
+ 0;
42
+ const totalCount = commentsCount + suggestionsCount;
43
+
20
44
  return (
21
- <div className="flex items-center gap-2">
45
+ <div className="flex items-center justify-between gap-2 border-b px-4 py-2">
22
46
  {hasLayout && (
23
47
  <>
24
- {!editContext.user?.isLimitedPreviewUser && (
48
+ <div className="flex items-center gap-2">
49
+ {!editContext.user?.isLimitedPreviewUser && (
50
+ <SimpleIconButton
51
+ icon={<Pencil className="h-6 w-6 p-1" strokeWidth={1} />}
52
+ label="Edit"
53
+ size="large"
54
+ selected={editContext.mode === "edit"}
55
+ onClick={() => editContext.setMode("edit")}
56
+ />
57
+ )}
58
+
25
59
  <SimpleIconButton
26
- icon={<Pencil className="h-6 w-6 p-1" />}
27
- label="Edit"
28
- dark={true}
60
+ icon={<EyeIcon className="h-6 w-6 p-1" strokeWidth={1} />}
61
+ label="Preview"
29
62
  size="large"
30
- selected={editContext.mode === "edit"}
31
- onClick={() => editContext.setMode("edit")}
63
+ selected={editContext.mode === "preview"}
64
+ onClick={() => editContext.setMode("preview")}
32
65
  />
33
- )}
34
-
35
- <SimpleIconButton
36
- icon={<EyeIcon className="h-6 w-6 p-1" />}
37
- label="Preview"
38
- dark={true}
39
- size="large"
40
- selected={editContext.mode === "preview"}
41
- onClick={() => editContext.setMode("preview")}
42
- />
43
66
 
44
- <SimpleIconButton
45
- selected={editContext?.mode === "suggestions"}
46
- icon={<UserRoundPen size={24} className="p-0.5" />}
47
- label="Write suggestions"
48
- dark={true}
49
- size="large"
50
- onClick={() => editContext?.setMode("suggestions")}
51
- />
52
- <Separator size="large" />
67
+ <div className="relative">
68
+ <SimpleIconButton
69
+ selected={editContext?.mode === "suggestions"}
70
+ icon={
71
+ <MessagesSquare strokeWidth={1} className="h-6 w-6 p-1" />
72
+ }
73
+ label="Write suggestions"
74
+ size="large"
75
+ onClick={() => editContext?.setMode("suggestions")}
76
+ />
77
+ {totalCount > 0 && (
78
+ <div className="bg-theme-secondary text-3xs absolute -top-1 -right-1 flex h-[16px] min-w-[16px] items-center justify-center rounded-full px-1 text-white">
79
+ {totalCount > 99 ? "99+" : totalCount}
80
+ </div>
81
+ )}
82
+ </div>
83
+ <Separator size="large" />
84
+ <SimpleIconButton
85
+ icon={<Plus className="h-6 w-6 p-1" strokeWidth={1} />}
86
+ label="Add Component"
87
+ size="large"
88
+ selected={insertMode}
89
+ onClick={toggleInsertMode}
90
+ disabled={
91
+ !editContext.page?.item.canWriteItem ||
92
+ editContext.mode !== "edit"
93
+ }
94
+ />
95
+ </div>
53
96
  {!editContext.isMobile && (
54
- <>
55
- <i
56
- className={classNames(
57
- device === "desktop"
58
- ? "bg-gray-200"
59
- : "text-gray-400 hover:bg-gray-200 hover:text-gray-800",
60
- "pi pi-desktop cursor-pointer rounded-full p-2",
61
- )}
62
- title="Desktop"
63
- onClick={() => {
64
- setDevice("desktop");
65
- }}
97
+ <div className="flex items-center gap-2">
98
+ <SimpleIconButton
99
+ icon={<Monitor className="h-6 w-6 p-1" strokeWidth={1} />}
100
+ label="Desktop"
101
+ size="large"
102
+ selected={device === "desktop"}
103
+ onClick={() => setDevice("desktop")}
66
104
  />
67
- <i
68
- className={classNames(
69
- device && device !== "desktop"
70
- ? "bg-gray-200"
71
- : "text-gray-400 hover:bg-gray-200 hover:text-gray-800",
72
- "pi pi-mobile cursor-pointer rounded-full p-2",
73
- )}
74
- title="Mobile"
105
+ <SimpleIconButton
106
+ icon={<Smartphone className="h-6 w-6 p-1" strokeWidth={1} />}
107
+ label="Mobile"
108
+ size="large"
109
+ selected={Boolean(device && device !== "desktop")}
75
110
  onClick={() => {
76
111
  if (editContext.configuration.devices[0]) {
77
112
  setDevice(editContext.configuration.devices[0].name);
78
113
  }
79
114
  }}
80
115
  />
81
- <i
82
- className={classNames(
83
- !device
84
- ? "bg-gray-200"
85
- : "text-gray-400 hover:bg-gray-200 hover:text-gray-800",
86
- "h-8 w-8 cursor-pointer rounded-full p-1",
87
- )}
88
- title="Form"
89
- onClick={() => {
90
- setDevice("");
91
- }}
92
- >
93
- <FormEditIcon />
94
- </i>
116
+ <SimpleIconButton
117
+ icon={<Table className="h-6 w-6 p-1" strokeWidth={1} />}
118
+ label="Form"
119
+ size="large"
120
+ selected={!device}
121
+ onClick={() => setDevice("")}
122
+ />
95
123
  <Separator size="large" />
96
- </>
124
+ {!editContext.isMobile && (
125
+ <SimpleIconButton
126
+ icon={<CompareIcon className="h-6 w-6 p-1" />}
127
+ label="Compare"
128
+ size="large"
129
+ className={
130
+ editContext.compareMode
131
+ ? "text-gray-600"
132
+ : "hover:text-gray-600"
133
+ }
134
+ selected={editContext.compareMode}
135
+ onClick={() =>
136
+ editContext.setCompareMode(!editContext.compareMode)
137
+ }
138
+ />
139
+ )}
140
+ </div>
97
141
  )}
98
- <i
142
+ {/* <i
99
143
  className="pi pi-external-link cursor-pointer rounded-full p-2 text-gray-400 hover:bg-gray-200 hover:text-gray-800"
100
144
  title="Fullscreen"
101
145
  onClick={() => pageViewContext.setFullscreen(true)}
102
- />
146
+ /> */}
147
+ <div className="flex items-center gap-2">
148
+ <SimpleIconButton
149
+ icon={<EnterFullScreenIcon className="h-6 w-6 p-1" />}
150
+ label="Fullscreen"
151
+ size="large"
152
+ onClick={() => pageViewContext.setFullscreen(true)}
153
+ />
154
+ <SimpleIconButton
155
+ icon={<Layers className="h-6 w-6 p-1" strokeWidth={1} />}
156
+ label="Component Navigator"
157
+ size="large"
158
+ selected={editContext.showRightSidebar}
159
+ onClick={() =>
160
+ editContext.setShowRightSidebar(!editContext.showRightSidebar)
161
+ }
162
+ />
163
+ </div>
103
164
  </>
104
165
  )}
105
- {!editContext.isMobile && (
106
- <SimpleIconButton
107
- icon={<CompareIcon className="h-6 w-6 p-1" />}
108
- label="Compare"
109
- size="large"
110
- dark={true}
111
- className={
112
- editContext.compareMode ? "text-gray-600" : "hover:text-gray-600"
113
- }
114
- selected={editContext.compareMode}
115
- onClick={() => editContext.setCompareMode(!editContext.compareMode)}
116
- />
117
- )}
118
166
  </div>
119
167
  );
120
168
  }
@@ -1,6 +1,5 @@
1
1
  import { useEditContext } from "../client/editContext";
2
2
  import { PreviewInfo } from "../reviews/PreviewInfo";
3
- import { ActionsMenu } from "./ActionsMenu";
4
3
 
5
4
  export const PreviewSecondaryControls = () => {
6
5
  const editContext = useEditContext();
@@ -12,7 +11,6 @@ export const PreviewSecondaryControls = () => {
12
11
  }`}
13
12
  >
14
13
  <PreviewInfo />
15
- <ActionsMenu isMobile={editContext.isMobile} />
16
14
  </div>
17
15
  );
18
16
  };
@@ -17,11 +17,11 @@ export function User({ session }: { session: EditSession }) {
17
17
 
18
18
  return (
19
19
  <div
20
- className="rounded-full w-8 h-8 grid items-center justify-center text-white"
20
+ className="grid h-7 w-7 items-center justify-center rounded-full text-xs font-normal text-white"
21
21
  style={{ background: session.color }}
22
22
  title={userName + " (" + session.user.email + ")"}
23
23
  >
24
- {letter}
24
+ {letter?.toUpperCase()}
25
25
  </div>
26
26
  );
27
27
  }
@@ -1,13 +1,26 @@
1
1
  "use client";
2
2
 
3
- import { ArrowDownIcon } from "../ui/Icons";
4
- import { useRef } from "react";
5
- import { OverlayPanel } from "primereact/overlaypanel";
6
- import { Button } from "primereact/button";
3
+ import * as React from "react";
4
+ import { Check, ChevronsUpDown, Plus, X } from "lucide-react";
7
5
  import { useEditContext } from "../client/editContext";
8
6
  import { getCreateAndSwitchToNewVersionCommand } from "../commands/createVersionCommand";
9
7
  import { getDeleteVersionCommand } from "../commands/deleteVersionCommand";
10
8
  import { ItemDescriptor, Version } from "../pageModel";
9
+ import { cn } from "../../lib/utils";
10
+ import { Button } from "../../components/ui/button";
11
+ import {
12
+ Command,
13
+ CommandEmpty,
14
+ CommandGroup,
15
+ CommandItem,
16
+ CommandList,
17
+ CommandSeparator,
18
+ } from "../../components/ui/command";
19
+ import {
20
+ Popover,
21
+ PopoverContent,
22
+ PopoverTrigger,
23
+ } from "../../components/ui/popover";
11
24
 
12
25
  export function VersionSelector({
13
26
  itemDescriptor,
@@ -24,119 +37,131 @@ export function VersionSelector({
24
37
  darkMode?: boolean;
25
38
  versions: Version[];
26
39
  }) {
40
+ const [open, setOpen] = React.useState(false);
27
41
  const editContext = useEditContext();
28
- const overlaypanel = useRef<OverlayPanel>(null);
29
42
 
30
43
  if (itemDescriptor == null) return;
31
44
 
32
45
  const getVersionLabel = () => {
33
46
  if (versions.length === 0) return "No versions";
34
47
  if (itemDescriptor.version === 0)
35
- return "Latest" + (actualVersion ? " (" + actualVersion + ")" : "");
36
- return itemDescriptor.version;
48
+ return (
49
+ "Latest version" + (actualVersion ? " (" + actualVersion + ")" : "")
50
+ );
51
+ return "Version (" + itemDescriptor.version + ")";
52
+ };
53
+
54
+ const selectVersion = async (version: number) => {
55
+ onVersionSelected(version);
56
+ setOpen(false);
57
+ };
58
+
59
+ const handleCreateVersion = async () => {
60
+ await editContext?.executeCommand({
61
+ command: getCreateAndSwitchToNewVersionCommand({}),
62
+ event: new Event("click") as any,
63
+ });
64
+ setOpen(false);
65
+ onVersionSelected(0);
66
+ };
67
+
68
+ const handleDeleteVersion = async () => {
69
+ await editContext?.executeCommand({
70
+ command: getDeleteVersionCommand({}),
71
+ event: new Event("click") as any,
72
+ });
73
+ setOpen(false);
74
+ onVersionSelected(0);
37
75
  };
38
76
 
39
77
  return (
40
- <>
41
- <div
42
- data-testid="version-selector"
43
- className={`flex cursor-pointer items-center gap-3 p-[7px] py-[5px] text-sm ${
44
- darkMode
45
- ? "text-gray-500 hover:bg-gray-200"
46
- : "text-gray-200 hover:bg-gray-500"
47
- } a rounded-md`}
48
- onClick={(ev) => overlaypanel.current?.toggle(ev, ev.currentTarget)}
49
- >
50
- <div className="flex gap-2">{getVersionLabel()}</div>
51
- <div
52
- className={`p-dropdown-trigger ${
53
- darkMode ? "text-gray-500" : "text-gray-200"
54
- }`}
55
- role="button"
56
- aria-haspopup="listbox"
57
- aria-expanded="false"
58
- aria-label="Select a version"
59
- data-pc-section="trigger"
78
+ <Popover open={open} onOpenChange={setOpen}>
79
+ <PopoverTrigger asChild>
80
+ <Button
81
+ variant="outline"
82
+ role="combobox"
83
+ aria-expanded={open}
84
+ className={cn(
85
+ "text-dark border-gray-3 flex h-8 w-auto min-w-[120px] cursor-pointer items-center justify-between gap-3 rounded-md border p-[7px] py-[11px] text-xs font-medium hover:bg-gray-50",
86
+ )}
87
+ data-testid="version-selector"
60
88
  >
61
- <ArrowDownIcon />
62
- </div>
63
- </div>
64
- <OverlayPanel dismissable={true} ref={overlaypanel} closeOnEscape>
65
- <div className="flex max-h-[50vh] min-w-20 flex-col">
66
- <div className="flex-1 overflow-auto">
67
- <div className="flex flex-col text-sm">
68
- {versions.length === 0 && <div className="p-2">No versions</div>}
89
+ <div className="flex gap-2">{getVersionLabel()}</div>
90
+ <ChevronsUpDown className="h-4 w-4 shrink-0 opacity-50" />
91
+ </Button>
92
+ </PopoverTrigger>
93
+ <PopoverContent className="w-64 p-0" align="start">
94
+ <Command>
95
+ <CommandList className="max-h-[50vh]">
96
+ <CommandEmpty>No versions available</CommandEmpty>
97
+ <CommandGroup>
69
98
  {versions.length > 0 && (
70
- <div
99
+ <CommandItem
71
100
  key="latest"
72
- className="flex cursor-pointer gap-2 p-2 hover:bg-gray-200"
73
- onClick={() => {
74
- onVersionSelected(0);
75
- overlaypanel.current?.hide();
76
- }}
101
+ value="latest"
102
+ onSelect={() => selectVersion(0)}
103
+ className="flex items-center gap-2 px-2 py-2 text-xs"
77
104
  >
78
- Latest
79
- </div>
105
+ <span className="flex-1">Latest</span>
106
+ <Check
107
+ className={cn(
108
+ "h-4 w-4",
109
+ itemDescriptor.version === 0
110
+ ? "opacity-100"
111
+ : "opacity-0",
112
+ )}
113
+ />
114
+ </CommandItem>
80
115
  )}
81
116
  {versions.map((x) => (
82
- <div
117
+ <CommandItem
83
118
  key={x.version}
84
- className="flex cursor-pointer gap-2 p-2 hover:bg-gray-200"
85
- onClick={() => {
86
- onVersionSelected(x.version);
87
- overlaypanel.current?.hide();
88
- }}
119
+ value={x.version.toString()}
120
+ onSelect={() => selectVersion(x.version)}
121
+ className="flex items-center gap-2 px-2 py-2 text-xs"
89
122
  >
90
- {itemDescriptor.version === x.version && (
91
- <i className="pi pi-check" style={{ fontSize: "1rem" }}></i>
92
- )}{" "}
93
- {x.version}
94
- </div>
123
+ <span className="flex-1">Version {x.version}</span>
124
+ <Check
125
+ className={cn(
126
+ "h-4 w-4",
127
+ itemDescriptor.version === x.version
128
+ ? "opacity-100"
129
+ : "opacity-0",
130
+ )}
131
+ />
132
+ </CommandItem>
95
133
  ))}
96
- </div>
97
- </div>
98
- </div>
99
- {!readOnly && (
100
- <div className="flex flex-col border-t p-2">
101
- <div className="mb-2 flex items-center gap-1 text-xs text-gray-500">
102
- <ArrowDownIcon /> Actions
103
- </div>
104
- <div className="flex gap-2">
105
- <Button
106
- text
107
- size="small"
108
- icon="pi pi-plus"
109
- label="Add Version"
110
- onClick={async (ev) => {
111
- await editContext?.executeCommand({
112
- command: getCreateAndSwitchToNewVersionCommand({}),
113
- event: ev,
114
- });
115
- overlaypanel.current?.hide();
116
- onVersionSelected(0);
117
- }}
118
- />
119
- <Button
120
- text
121
- size="small"
122
- icon="pi pi-times"
123
- label="Delete Version"
124
- severity="danger"
125
- disabled={versions.length === 0}
126
- onClick={async (ev) => {
127
- editContext;
128
- await editContext?.executeCommand({
129
- command: getDeleteVersionCommand({}),
130
- event: ev,
131
- });
132
- overlaypanel.current?.hide();
133
- onVersionSelected(0);
134
- }}
135
- />{" "}
136
- </div>
137
- </div>
138
- )}
139
- </OverlayPanel>
140
- </>
134
+ </CommandGroup>
135
+ {!readOnly && (
136
+ <>
137
+ <CommandSeparator />
138
+ <CommandGroup>
139
+ <CommandItem
140
+ onSelect={handleCreateVersion}
141
+ className="flex items-center gap-2 px-2 py-2"
142
+ >
143
+ <Plus className="h-4 w-4" />
144
+ <span>Add Version</span>
145
+ </CommandItem>
146
+ <CommandItem
147
+ onSelect={handleDeleteVersion}
148
+ disabled={versions.length === 0}
149
+ className={cn(
150
+ "flex items-center gap-2 px-2 py-2",
151
+ versions.length === 0
152
+ ? "cursor-not-allowed opacity-50"
153
+ : "text-red-600 hover:text-red-700",
154
+ )}
155
+ >
156
+ <X className="h-4 w-4" />
157
+ <span>Delete Version</span>
158
+ </CommandItem>
159
+ </CommandGroup>
160
+ </>
161
+ )}
162
+ </CommandList>
163
+ </Command>
164
+ </PopoverContent>
165
+ </Popover>
141
166
  );
142
167
  }
@@ -0,0 +1,115 @@
1
+ import { useEditContext } from "../client/editContext";
2
+ import { Button } from "../../components/ui/button";
3
+ import {
4
+ DropdownMenu,
5
+ DropdownMenuContent,
6
+ DropdownMenuItem,
7
+ DropdownMenuTrigger,
8
+ } from "../../components/ui/dropdown-menu";
9
+
10
+ export function WorkflowButton() {
11
+ const editContext = useEditContext();
12
+
13
+ if (!editContext?.currentItemDescriptor) return null;
14
+
15
+ // Find the current item in workboxItems to get its workflow commands
16
+ const currentWorkboxItem = editContext.workboxItems?.find(
17
+ (item) =>
18
+ item.item.id === editContext.currentItemDescriptor?.id &&
19
+ item.item.language === editContext.currentItemDescriptor?.language &&
20
+ item.item.version === editContext.currentItemDescriptor?.version,
21
+ );
22
+
23
+ const workflowCommands = currentWorkboxItem?.workflowCommands || [];
24
+
25
+ // If no workflow commands, show simple publish button
26
+ if (workflowCommands.length === 0) {
27
+ return (
28
+ <Button
29
+ size="sm"
30
+ onClick={() => {
31
+ const publishView = editContext?.configuration.editor.views.find(
32
+ (x) => x.name === "publish",
33
+ );
34
+
35
+ if (publishView) editContext?.switchView(publishView.name);
36
+ }}
37
+ >
38
+ Publish
39
+ </Button>
40
+ );
41
+ }
42
+
43
+ // If only one workflow command, show it as a simple button
44
+ if (workflowCommands.length === 1) {
45
+ const command = workflowCommands[0];
46
+ if (!command) return null;
47
+ return (
48
+ <Button
49
+ size="sm"
50
+ onClick={() => {
51
+ editContext.operations.executeWorkflowCommand(
52
+ editContext.currentItemDescriptor!,
53
+ command.id,
54
+ );
55
+ }}
56
+ >
57
+ {command.name}
58
+ </Button>
59
+ );
60
+ }
61
+
62
+ // Multiple workflow commands - show as dropdown
63
+ const firstCommand = workflowCommands[0];
64
+ if (!firstCommand) return null;
65
+
66
+ return (
67
+ <div className="flex">
68
+ <Button
69
+ size="sm"
70
+ onClick={() => {
71
+ editContext.operations.executeWorkflowCommand(
72
+ editContext.currentItemDescriptor!,
73
+ firstCommand.id,
74
+ );
75
+ }}
76
+ >
77
+ {firstCommand.name}
78
+ </Button>
79
+ <DropdownMenu>
80
+ <DropdownMenuTrigger asChild>
81
+ <Button variant="outline" size="sm" className="ml-0.5 px-2">
82
+ <svg
83
+ className="h-4 w-4"
84
+ fill="none"
85
+ stroke="currentColor"
86
+ viewBox="0 0 24 24"
87
+ >
88
+ <path
89
+ strokeLinecap="round"
90
+ strokeLinejoin="round"
91
+ strokeWidth={2}
92
+ d="M19 9l-7 7-7-7"
93
+ />
94
+ </svg>
95
+ </Button>
96
+ </DropdownMenuTrigger>
97
+ <DropdownMenuContent>
98
+ {workflowCommands.map((command) => (
99
+ <DropdownMenuItem
100
+ key={command.id}
101
+ onClick={() => {
102
+ editContext.operations.executeWorkflowCommand(
103
+ editContext.currentItemDescriptor!,
104
+ command.id,
105
+ );
106
+ }}
107
+ >
108
+ {command.name}
109
+ </DropdownMenuItem>
110
+ ))}
111
+ </DropdownMenuContent>
112
+ </DropdownMenu>
113
+ </div>
114
+ );
115
+ }