@powerhousedao/connect 1.0.24-dev.0 → 1.1.0

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 (37) hide show
  1. package/dist/.env +1 -1
  2. package/dist/assets/{app-DWlDE8AF.css → app-Dtx0nq4m.css} +181 -240
  3. package/dist/assets/{app-B5yYl0zv.js → app-SJyv410V.js} +33037 -34663
  4. package/dist/assets/{app-loader-NDVZu4bS.css → app-loader-3ipafc56.css} +228 -238
  5. package/dist/assets/{app-loader-CmEZOj3m.js → app-loader-BsJCIY3v.js} +417 -735
  6. package/dist/assets/{ccip-KtRjx9vh.js → ccip-CWiYf37C.js} +8 -6
  7. package/dist/assets/{content-2lJzkjLx.js → content-DrqtiFBt.js} +456 -1094
  8. package/dist/assets/{index-BVVRVlZN.js → index-CS0mQFrd.js} +3 -4
  9. package/dist/assets/{index-BhHOiwFw.js → index-DFoYtrS6.js} +3693 -3516
  10. package/dist/assets/{index-dSMCpjcQ.js → index-n2OSuQ3g.js} +171 -23
  11. package/dist/assets/{main.DA6nl4Ov.js → main.BcxEuVs0.js} +12 -3
  12. package/dist/assets/{style-CdxGKc2g.css → style-0ej1afQi.css} +95 -39
  13. package/dist/external-packages.js +0 -1
  14. package/dist/hmr.js +0 -1
  15. package/dist/index.html +1 -1
  16. package/dist/service-worker.js +0 -1
  17. package/dist/vite-envs.sh +1 -1
  18. package/package.json +20 -21
  19. package/dist/assets/app-B5yYl0zv.js.map +0 -1
  20. package/dist/assets/app-loader-CmEZOj3m.js.map +0 -1
  21. package/dist/assets/browser-D5LEpLBa.js +0 -27224
  22. package/dist/assets/browser-D5LEpLBa.js.map +0 -1
  23. package/dist/assets/ccip-KtRjx9vh.js.map +0 -1
  24. package/dist/assets/content-2lJzkjLx.js.map +0 -1
  25. package/dist/assets/index-BVVRVlZN.js.map +0 -1
  26. package/dist/assets/index-BhHOiwFw.js.map +0 -1
  27. package/dist/assets/index-DZiF5od7.js +0 -208
  28. package/dist/assets/index-DZiF5od7.js.map +0 -1
  29. package/dist/assets/index-dSMCpjcQ.js.map +0 -1
  30. package/dist/assets/main.DA6nl4Ov.js.map +0 -1
  31. package/dist/assets/reactor-analytics-CF_JKt8H.js +0 -42
  32. package/dist/assets/reactor-analytics-CF_JKt8H.js.map +0 -1
  33. package/dist/assets/router-Ch1WZD-6.js +0 -1585
  34. package/dist/assets/router-Ch1WZD-6.js.map +0 -1
  35. package/dist/external-packages.js.map +0 -1
  36. package/dist/hmr.js.map +0 -1
  37. package/dist/service-worker.js.map +0 -1
@@ -1,11 +1,10 @@
1
1
  import { jsx, jsxs, Fragment as Fragment$1 } from "react/jsx-runtime";
2
- import { t as twMerge, B as Button, aO as mergeClassNameProps, aP as INITIAL_SYNC, aQ as SYNCING, S as SUCCESS, C as CONFLICT, aR as MISSING, x as ERROR, aS as ConnectDropdownMenu, aT as useOnClickOutside, aU as useEventListener, aV as useCopyToClipboard, aW as Select, aX as Provider, aY as Root3, aZ as Trigger, a_ as Portal, a$ as Content2, b0 as validateInitialState, b1 as validateStateSchemaName, b2 as validateModules, b3 as useDocumentDrives, A as useUiNodesContext, b4 as useDriveContext, b5 as FILE$1, F as useUnwrappedReactor, b6 as useConnectDid, b7 as useConnectCrypto, o as useTranslation, G as useModal, b8 as useAtomValue, b9 as themeAtom, ba as useUser, bb as useUserPermissions$1, p as useUiNodes, bc as exportFile, bd as useGetDocumentModelModule, be as addActionContext$1, bf as signOperation$1, e as useDocumentDriveServer, bg as useHotkeys, bh as DriveLayout, bi as DriveContextProvider, bj as SearchBar, N as useAnalyticsStore, bk as useQueryClient, u as useQuery, a3 as AnalyticsPath, bl as useAnalyticsEngine, a4 as DateTime, bm as AnalyticsGranularity, bn as useGetEditor, bo as isSameDocument, n as useNavigate, s as useAsyncReactor, bp as useFilteredDocumentModels, bq as useDriveEditor, br as useDocumentDriveById, z as useParams, q as useDocumentDrives$1, w as toast } from "./app-B5yYl0zv.js";
2
+ import { t as twMerge, B as Button, m as mergeClassNameProps, E as ERROR, M as MISSING, C as CONFLICT, S as SUCCESS, k as SYNCING, I as INITIAL_SYNC, l as ConnectDropdownMenu, u as useOnClickOutside, n as useEventListener, o as useCopyToClipboard, p as Select, q as ENSAvatar, P as Provider, v as Root3, T as Trigger, w as Portal, x as Content2, y as validateInitialState, z as validateStateSchemaName, A as validateModules, D as useDocumentDrives, F as useUiNodesContext, G as useDriveContext, H as FILE$1, J as useUnwrappedReactor, K as useConnectDid, L as useConnectCrypto, N as useTranslation, O as useModal, Q as useAtomValue, U as themeAtom, V as useUser, W as useUserPermissions$1, X as useUiNodes, Y as exportFile, Z as useGetDocumentModelModule, _ as addActionContext$1, $ as signOperation$1, a0 as useDocumentDriveServer, a1 as useHotkeys, a2 as useGetEditor, a3 as isSameDocument, a4 as useNavigate, a5 as ErrorBoundary, a6 as DriveLayout, a7 as DriveContextProvider, a8 as SearchBar, a9 as useAsyncReactor, aa as useFilteredDocumentModels, ab as useDriveEditor, ac as useDocumentDriveById, ad as useParams, ae as useDocumentDrives$1, af as toast } from "./app-SJyv410V.js";
3
3
  import * as React from "react";
4
4
  import React__default, { useState, useCallback, useMemo, useEffect, Fragment, useRef, useLayoutEffect, memo as memo$1, createElement, useSyncExternalStore, Suspense } from "react";
5
- import { $ as Icon, bX as getDimensions, bY as READ, bZ as nodeOptionsMap, b_ as defaultFileOptions, b$ as DUPLICATE, c0 as RENAME, c1 as WRITE, c2 as DELETE, c3 as defaultFolderOptions, c4 as garbageCollect, c5 as sortOperations, c6 as UI_NODE, aQ as DRIVE, aB as FILE, ae as buildSignedOperation, ax as addFolder, at as generateAddNodeAction, ay as isFolderNode, au as isFileNode, az as deleteNode, aA as updateNode, aC as moveNode, aD as generateNodesCopy, aE as copyNode, aq as generateId$1, c7 as undo, c8 as redo, _ as logger, aR as FOLDER, c9 as useDocumentDispatch$1, an as driveDocumentModelModule, ah as connectConfig } from "./app-loader-CmEZOj3m.js";
6
- import { E as ENSAvatar, a as ErrorBoundary } from "./router-Ch1WZD-6.js";
5
+ import { _ as Icon, aX as getDimensions, aY as READ, aZ as nodeOptionsMap, a_ as defaultFileOptions, a$ as DELETE, b0 as RENAME, b1 as WRITE, b2 as DUPLICATE, b3 as defaultFolderOptions, b4 as garbageCollect, b5 as sortOperations, b6 as UI_NODE, aP as DRIVE, az as FILE, ae as buildSignedOperation, b7 as generateId$1, aw as isFolderNode, aB as generateNodesCopy, aC as copyNode, aA as moveNode, ay as updateNode, ax as deleteNode, ar as generateAddNodeAction, as as isFileNode, av as addFolder, b8 as undo, b9 as redo, ac as logger, ba as useDocumentDispatch$1, aQ as FOLDER, al as driveDocumentModelModule } from "./app-loader-BsJCIY3v.js";
7
6
  import { flushSync } from "react-dom";
8
- import "./main.DA6nl4Ov.js";
7
+ import "./main.BcxEuVs0.js";
9
8
  const PaginationButton = ({ active = false, ...props }) => {
10
9
  const className = twMerge("h-8 min-w-8 border border-solid border-gray-300 bg-white px-3 py-1 text-xs text-gray-900 hover:bg-gray-100", !active && "border-0");
11
10
  return jsx(Button, { color: "light", size: "small", ...mergeClassNameProps(props, className), children: props.children });
@@ -15,7 +14,7 @@ const Pagination = (props) => {
15
14
  return jsxs("div", { className: "flex gap-x-1", children: [firstPageLabel ? jsx(PaginationButton, { disabled: !isPreviousPageAvailable, onClick: () => goToFirstPage(), children: firstPageLabel }) : null, previousPageLabel ? jsxs(PaginationButton, { disabled: !isPreviousPageAvailable, onClick: () => goToPreviousPage(), children: [jsx(Icon, { className: "rotate-90", name: "ChevronDown", size: 16 }), previousPageLabel] }) : null, pages.map((page) => jsx(PaginationButton, { active: page.active, onClick: () => goToPage(page.index), children: page.number }, page.index)), hiddenNextPages ? jsx("span", { className: "flex items-center justify-center px-2", children: "..." }) : null, nextPageLabel ? jsxs(PaginationButton, { disabled: !isNextPageAvailable, onClick: () => goToNextPage(), children: [nextPageLabel, jsx(Icon, { className: "-rotate-90", name: "ChevronDown", size: 16 })] }) : null, lastPageLabel ? jsx(PaginationButton, { disabled: !isNextPageAvailable, onClick: () => goToLastPage(), children: lastPageLabel }) : null] });
16
15
  };
17
16
  function usePagination(items, options) {
18
- const { itemsPerPage = 20, initialPage = 0, pageRange = 3 } = options;
17
+ const { itemsPerPage = 20, initialPage = 0, pageRange = 3 } = options || {};
19
18
  const [currentPage, setCurrentPage] = useState(initialPage);
20
19
  const pageCount = Math.ceil(items.length / itemsPerPage);
21
20
  const isNextPageAvailable = currentPage < pageCount - 1;
@@ -152,12 +151,131 @@ function DefaultEditorLoader(props) {
152
151
  const { message: message2 = "Loading editor", ...divProps } = props;
153
152
  return jsx("div", { className: "grid h-full place-items-center", ...divProps, children: jsxs("div", { className: "-mt-20 grid place-items-center", children: [jsx("h3", { className: "mb-4 text-xl", children: message2 }), jsx(AnimatedLoader, {})] }) });
154
153
  }
154
+ const DocumentToolbar = (props) => {
155
+ const { undo: undo2, canUndo, redo: redo2, canRedo, title, onClose, onExport, className, onShowRevisionHistory, onSwitchboardLinkClick, onShowTimeline } = props;
156
+ const isUndoDisabled = !canUndo || !undo2;
157
+ const isRedoDisabled = !canRedo || !redo2;
158
+ const isExportDisabled = !onExport;
159
+ const isSwitchboardLinkDisabled = !onSwitchboardLinkClick;
160
+ const isRevisionHistoryDisabled = !onShowRevisionHistory;
161
+ const isTimelineDisabled = !onShowTimeline;
162
+ return jsxs("div", { className: twMerge("flex h-12 w-full items-center justify-between rounded-xl border border-gray-200 bg-slate-50 px-4", className), children: [jsxs("div", { className: "flex items-center gap-x-2", children: [jsx("button", { className: twMerge("grid size-8 place-items-center rounded-lg border border-gray-200 bg-white", isUndoDisabled ? "cursor-not-allowed" : "cursor-pointer active:opacity-70"), onClick: undo2, disabled: isUndoDisabled, children: jsx(Icon, { name: "ArrowCouterclockwise", size: 16, className: isUndoDisabled ? "text-gray-500" : "text-gray-900" }) }), jsx("button", { className: twMerge("grid size-8 place-items-center rounded-lg border border-gray-200 bg-white", isRedoDisabled ? "cursor-not-allowed" : "cursor-pointer active:opacity-70"), onClick: redo2, disabled: isRedoDisabled, children: jsx("div", { className: "-scale-x-100", children: jsx(Icon, { name: "ArrowCouterclockwise", size: 16, className: isRedoDisabled ? "text-gray-500" : "text-gray-900" }) }) }), jsx("button", { className: twMerge("flex h-8 items-center rounded-lg border border-gray-200 bg-white px-3 text-sm", isExportDisabled ? "cursor-not-allowed" : "cursor-pointer active:opacity-70"), onClick: onExport, disabled: isExportDisabled, children: jsx("span", { className: isExportDisabled ? "text-gray-500" : "text-gray-900", children: "Export" }) })] }), jsx("div", { className: "flex items-center", children: jsx("h1", { className: "text-sm font-medium text-gray-500", children: title }) }), jsxs("div", { className: "flex items-center gap-x-2", children: [jsx("button", { className: twMerge("grid size-8 place-items-center rounded-lg border border-gray-200 bg-white", isSwitchboardLinkDisabled ? "cursor-not-allowed" : "cursor-pointer active:opacity-70"), onClick: onSwitchboardLinkClick, disabled: isSwitchboardLinkDisabled, children: jsx(Icon, { name: "Drive", size: 16, className: isSwitchboardLinkDisabled ? "text-gray-500" : "text-gray-900" }) }), jsx("button", { className: twMerge("grid size-8 place-items-center rounded-lg border border-gray-200 bg-white", isRevisionHistoryDisabled ? "cursor-not-allowed" : "cursor-pointer active:opacity-70"), onClick: onShowRevisionHistory, disabled: isRevisionHistoryDisabled, children: jsx(Icon, { name: "History", size: 16, className: isRevisionHistoryDisabled ? "text-gray-500" : "text-gray-900" }) }), jsx("button", { className: twMerge("grid size-8 place-items-center rounded-lg border border-gray-200 bg-white", isTimelineDisabled ? "cursor-not-allowed" : "cursor-pointer active:opacity-70"), onClick: onShowTimeline, disabled: isTimelineDisabled, children: jsx(Icon, { name: "Timeline", size: 16, className: twMerge("text-gray-900", isTimelineDisabled && "opacity-50") }) }), jsx("button", { className: "grid size-8 cursor-pointer place-items-center rounded-lg border border-gray-200 bg-white active:opacity-70", onClick: onClose, children: jsx(Icon, { name: "XmarkLight", size: 16, className: "text-gray-900" }) })] })] });
163
+ };
164
+ const syncIcons = {
165
+ SYNCING: "Syncing",
166
+ SUCCESS: "Synced",
167
+ CONFLICT: "Error",
168
+ MISSING: "Circle",
169
+ ERROR: "Error",
170
+ INITIAL_SYNC: "Syncing"
171
+ };
172
+ function SyncStatusIcon(props) {
173
+ const { syncStatus, className, overrideSyncIcons = {}, ...iconProps } = props;
174
+ const icons = { ...syncIcons, ...overrideSyncIcons };
175
+ const syncStatusIcons = {
176
+ [INITIAL_SYNC]: jsx(Icon, { size: 16, ...iconProps, className: twMerge("text-blue-900", className), name: icons[INITIAL_SYNC] }),
177
+ [SYNCING]: jsx(Icon, { size: 16, ...iconProps, className: twMerge("text-blue-900", className), name: icons[SYNCING] }),
178
+ [SUCCESS]: jsx(Icon, { size: 16, ...iconProps, className: twMerge("text-green-900", className), name: icons[SUCCESS] }),
179
+ [CONFLICT]: jsx(Icon, { size: 16, ...iconProps, className: twMerge("text-orange-900", className), name: icons[CONFLICT] }),
180
+ [MISSING]: jsx(Icon, { size: 16, ...iconProps, className: twMerge("text-red-900", className), name: icons[MISSING] }),
181
+ [ERROR]: jsx(Icon, { size: 16, ...iconProps, className: twMerge("text-red-900", className), name: icons[ERROR] })
182
+ };
183
+ return syncStatusIcons[syncStatus];
184
+ }
185
+ function FileItem(props) {
186
+ const { uiNode, className, customDocumentIconSrc, onSelectNode, onRenameNode, onDuplicateNode, onDeleteNode, isAllowedToCreateDocuments } = props;
187
+ const [mode, setMode] = useState(READ);
188
+ const [isDropdownMenuOpen, setIsDropdownMenuOpen] = useState(false);
189
+ const { dragProps } = useDrag({ uiNode });
190
+ const isReadMode = mode === READ;
191
+ const dropdownMenuHandlers = {
192
+ [DUPLICATE]: () => onDuplicateNode(uiNode),
193
+ [RENAME]: () => setMode(WRITE),
194
+ [DELETE]: () => onDeleteNode(uiNode)
195
+ };
196
+ const dropdownMenuOptions = Object.entries(nodeOptionsMap).map(([id, option]) => ({
197
+ ...option,
198
+ id
199
+ })).filter((option) => defaultFileOptions.includes(option.id));
200
+ function onSubmit(name) {
201
+ onRenameNode(name, uiNode);
202
+ setMode(READ);
203
+ }
204
+ function onCancel() {
205
+ setMode(READ);
206
+ }
207
+ function onClick() {
208
+ onSelectNode(uiNode);
209
+ }
210
+ function onDropdownMenuOptionClick(itemId) {
211
+ const handler = dropdownMenuHandlers[itemId];
212
+ if (!handler) {
213
+ console.error(`No handler found for dropdown menu item: ${itemId}`);
214
+ return;
215
+ }
216
+ handler();
217
+ setIsDropdownMenuOpen(false);
218
+ }
219
+ const iconSrc = getDocumentIconSrc(uiNode.documentType, customDocumentIconSrc);
220
+ const iconNode = jsxs("div", { className: "relative", children: [jsx("img", { alt: "file icon", className: "max-w-none", height: 34, src: iconSrc, width: 32 }), isReadMode && uiNode.syncStatus && jsx("div", { className: "absolute bottom-[-2px] right-0 size-3 rounded-full bg-white", children: jsx("div", { className: "absolute left-[-2px] top-[-2px]", children: jsx(SyncStatusIcon, { overrideSyncIcons: { SUCCESS: "CheckCircleFill" }, syncStatus: uiNode.syncStatus }) }) })] });
221
+ const containerStyles = twMerge("group flex h-12 cursor-pointer select-none items-center rounded-lg bg-gray-200 px-2 text-gray-600 hover:text-gray-800", className);
222
+ const content = isReadMode ? jsxs("div", { className: "flex w-52 items-center justify-between", children: [jsxs("div", { className: "mr-2 truncate group-hover:mr-0", children: [jsx("div", { className: "max-h-6 truncate text-sm font-medium group-hover:text-gray-800", children: uiNode.name }), jsx("div", { className: "max-h-6 truncate text-xs font-medium text-gray-600 group-hover:text-gray-800", children: uiNode.documentType })] }), isAllowedToCreateDocuments ? jsx(ConnectDropdownMenu, { items: dropdownMenuOptions, onItemClick: onDropdownMenuOptionClick, onOpenChange: setIsDropdownMenuOpen, open: isDropdownMenuOpen, children: jsx("button", { className: twMerge("hidden group-hover:block", isDropdownMenuOpen && "block"), onClick: (e) => {
223
+ e.stopPropagation();
224
+ setIsDropdownMenuOpen(true);
225
+ }, children: jsx(Icon, { className: "text-gray-600", name: "VerticalDots" }) }) }) : null] }) : jsx(NodeInput, { className: "ml-3 flex-1 font-medium", defaultValue: uiNode.name, onCancel, onSubmit });
226
+ return jsx("div", { className: "relative w-64", onClick, children: jsx("div", { ...dragProps, className: containerStyles, children: jsxs("div", { className: "flex items-center", children: [jsx("div", { className: "mr-1.5", children: iconNode }), content] }) }) });
227
+ }
228
+ function FolderItem(props) {
229
+ const { uiNode, isAllowedToCreateDocuments, className, onRenameNode, onDuplicateNode, onDeleteNode, onSelectNode, onAddFile, onCopyNode, onMoveNode } = props;
230
+ const [mode, setMode] = useState(READ);
231
+ const [isDropdownMenuOpen, setIsDropdownMenuOpen] = useState(false);
232
+ const { dragProps } = useDrag({ ...props, uiNode });
233
+ const { isDropTarget, dropProps } = useDrop({
234
+ uiNode,
235
+ onAddFile,
236
+ onCopyNode,
237
+ onMoveNode
238
+ });
239
+ const isReadMode = mode === READ;
240
+ function onCancel() {
241
+ setMode(READ);
242
+ }
243
+ function onSubmit(name) {
244
+ onRenameNode(name, uiNode);
245
+ setMode(READ);
246
+ }
247
+ function onClick() {
248
+ onSelectNode(uiNode);
249
+ }
250
+ const dropdownMenuHandlers = {
251
+ [DUPLICATE]: () => onDuplicateNode(uiNode),
252
+ [RENAME]: () => setMode(WRITE),
253
+ [DELETE]: () => onDeleteNode(uiNode)
254
+ };
255
+ const dropdownMenuOptions = Object.entries(nodeOptionsMap).map(([id, option]) => ({
256
+ ...option,
257
+ id
258
+ })).filter((option) => defaultFolderOptions.includes(option.id));
259
+ function onDropdownMenuOptionClick(itemId) {
260
+ const handler = dropdownMenuHandlers[itemId];
261
+ if (!handler) {
262
+ console.error(`No handler found for dropdown menu item: ${itemId}`);
263
+ return;
264
+ }
265
+ handler();
266
+ setIsDropdownMenuOpen(false);
267
+ }
268
+ const content = isReadMode || !isAllowedToCreateDocuments ? jsx("div", { className: "ml-3 max-h-6 truncate font-medium text-gray-600 group-hover:text-gray-800", children: uiNode.name }) : jsx(NodeInput, { className: "ml-3 font-medium", defaultValue: uiNode.name, onCancel, onSubmit });
269
+ const containerStyles = twMerge("group flex h-12 cursor-pointer select-none items-center rounded-lg bg-gray-200 px-2", className, isDropTarget && "bg-blue-100");
270
+ return jsx("div", { className: "relative w-64", onClick, children: jsxs("div", { ...dragProps, ...dropProps, className: containerStyles, children: [jsxs("div", { className: "flex items-center overflow-hidden", children: [jsx("div", { className: "p-1", children: jsxs("div", { className: "relative", children: [jsx(Icon, { name: "FolderClose", size: 24 }), isReadMode && uiNode.syncStatus ? jsx("div", { className: "absolute bottom-[-3px] right-[-2px] size-3 rounded-full bg-white", children: jsx("div", { className: "absolute left-[-2px] top-[-2px]", children: jsx(SyncStatusIcon, { overrideSyncIcons: {
271
+ SUCCESS: "CheckCircleFill"
272
+ }, syncStatus: uiNode.syncStatus }) }) }) : null] }) }), content] }), isReadMode && isAllowedToCreateDocuments ? jsx(ConnectDropdownMenu, { items: dropdownMenuOptions, onItemClick: onDropdownMenuOptionClick, onOpenChange: setIsDropdownMenuOpen, open: isDropdownMenuOpen, children: jsx("button", { className: twMerge("ml-auto hidden group-hover:block", isDropdownMenuOpen && "block"), onClick: (e) => {
273
+ e.stopPropagation();
274
+ setIsDropdownMenuOpen(true);
275
+ }, children: jsx(Icon, { className: "text-gray-600", name: "VerticalDots" }) }) }) : null] }) });
276
+ }
155
277
  const millisecondsInWeek = 6048e5;
156
278
  const millisecondsInDay = 864e5;
157
- const millisecondsInMinute = 6e4;
158
- const millisecondsInHour = 36e5;
159
- const minutesInMonth = 43200;
160
- const minutesInDay = 1440;
161
279
  const constructFromSymbol = Symbol.for("constructDateFrom");
162
280
  function constructFrom(date, value) {
163
281
  if (typeof date === "function") return date(value);
@@ -225,7 +343,7 @@ function getTimezoneOffsetInMilliseconds(date) {
225
343
  function normalizeDates(context, ...dates) {
226
344
  const normalize = constructFrom.bind(
227
345
  null,
228
- context || dates.find((date) => typeof date === "object")
346
+ dates.find((date) => typeof date === "object")
229
347
  );
230
348
  return dates.map(normalize);
231
349
  }
@@ -253,83 +371,12 @@ function startOfISOWeekYear(date, options) {
253
371
  fourthOfJanuary.setHours(0, 0, 0, 0);
254
372
  return startOfISOWeek(fourthOfJanuary);
255
373
  }
256
- function compareAsc(dateLeft, dateRight) {
257
- const diff = +toDate(dateLeft) - +toDate(dateRight);
258
- if (diff < 0) return -1;
259
- else if (diff > 0) return 1;
260
- return diff;
261
- }
262
- function constructNow(date) {
263
- return constructFrom(date, Date.now());
264
- }
265
374
  function isDate(value) {
266
375
  return value instanceof Date || typeof value === "object" && Object.prototype.toString.call(value) === "[object Date]";
267
376
  }
268
377
  function isValid(date) {
269
378
  return !(!isDate(date) && typeof date !== "number" || isNaN(+toDate(date)));
270
379
  }
271
- function differenceInCalendarMonths(laterDate, earlierDate, options) {
272
- const [laterDate_, earlierDate_] = normalizeDates(
273
- options == null ? void 0 : options.in,
274
- laterDate,
275
- earlierDate
276
- );
277
- const yearsDiff = laterDate_.getFullYear() - earlierDate_.getFullYear();
278
- const monthsDiff = laterDate_.getMonth() - earlierDate_.getMonth();
279
- return yearsDiff * 12 + monthsDiff;
280
- }
281
- function getRoundingMethod(method) {
282
- return (number) => {
283
- const round = method ? Math[method] : Math.trunc;
284
- const result = round(number);
285
- return result === 0 ? 0 : result;
286
- };
287
- }
288
- function differenceInMilliseconds(laterDate, earlierDate) {
289
- return +toDate(laterDate) - +toDate(earlierDate);
290
- }
291
- function endOfDay(date, options) {
292
- const _date = toDate(date, options == null ? void 0 : options.in);
293
- _date.setHours(23, 59, 59, 999);
294
- return _date;
295
- }
296
- function endOfMonth(date, options) {
297
- const _date = toDate(date, options == null ? void 0 : options.in);
298
- const month = _date.getMonth();
299
- _date.setFullYear(_date.getFullYear(), month + 1, 0);
300
- _date.setHours(23, 59, 59, 999);
301
- return _date;
302
- }
303
- function isLastDayOfMonth(date, options) {
304
- const _date = toDate(date, options == null ? void 0 : options.in);
305
- return +endOfDay(_date, options) === +endOfMonth(_date, options);
306
- }
307
- function differenceInMonths(laterDate, earlierDate, options) {
308
- const [laterDate_, workingLaterDate, earlierDate_] = normalizeDates(
309
- options == null ? void 0 : options.in,
310
- laterDate,
311
- laterDate,
312
- earlierDate
313
- );
314
- const sign = compareAsc(workingLaterDate, earlierDate_);
315
- const difference = Math.abs(
316
- differenceInCalendarMonths(workingLaterDate, earlierDate_)
317
- );
318
- if (difference < 1) return 0;
319
- if (workingLaterDate.getMonth() === 1 && workingLaterDate.getDate() > 27)
320
- workingLaterDate.setDate(30);
321
- workingLaterDate.setMonth(workingLaterDate.getMonth() - sign * difference);
322
- let isLastMonthNotFull = compareAsc(workingLaterDate, earlierDate_) === -sign;
323
- if (isLastDayOfMonth(laterDate_) && difference === 1 && compareAsc(laterDate_, earlierDate_) === 1) {
324
- isLastMonthNotFull = false;
325
- }
326
- const result = sign * (difference - +isLastMonthNotFull);
327
- return result === 0 ? 0 : result;
328
- }
329
- function differenceInSeconds(laterDate, earlierDate, options) {
330
- const diff = differenceInMilliseconds(laterDate, earlierDate) / 1e3;
331
- return getRoundingMethod(options == null ? void 0 : options.roundingMethod)(diff);
332
- }
333
380
  function startOfYear(date, options) {
334
381
  const date_ = toDate(date, options == null ? void 0 : options.in);
335
382
  date_.setFullYear(date_.getFullYear(), 0, 1);
@@ -399,7 +446,7 @@ const formatDistanceLocale = {
399
446
  other: "almost {{count}} years"
400
447
  }
401
448
  };
402
- const formatDistance$1 = (token, count, options) => {
449
+ const formatDistance = (token, count, options) => {
403
450
  let result;
404
451
  const tokenValue = formatDistanceLocale[token];
405
452
  if (typeof tokenValue === "string") {
@@ -815,7 +862,7 @@ const match = {
815
862
  };
816
863
  const enUS = {
817
864
  code: "en-US",
818
- formatDistance: formatDistance$1,
865
+ formatDistance,
819
866
  formatLong,
820
867
  formatRelative,
821
868
  localize,
@@ -938,8 +985,6 @@ const lightFormatters = {
938
985
  }
939
986
  };
940
987
  const dayPeriodEnum = {
941
- am: "am",
942
- pm: "pm",
943
988
  midnight: "midnight",
944
989
  noon: "noon",
945
990
  morning: "morning",
@@ -1719,572 +1764,73 @@ function cleanEscapedString(input) {
1719
1764
  }
1720
1765
  return matched[1].replace(doubleQuoteRegExp, "'");
1721
1766
  }
1722
- function formatDistance(laterDate, earlierDate, options) {
1723
- const defaultOptions2 = getDefaultOptions();
1724
- const locale = (options == null ? void 0 : options.locale) ?? defaultOptions2.locale ?? enUS;
1725
- const minutesInAlmostTwoDays = 2520;
1726
- const comparison = compareAsc(laterDate, earlierDate);
1727
- if (isNaN(comparison)) throw new RangeError("Invalid time value");
1728
- const localizeOptions = Object.assign({}, options, {
1729
- addSuffix: options == null ? void 0 : options.addSuffix,
1730
- comparison
1731
- });
1732
- const [laterDate_, earlierDate_] = normalizeDates(
1733
- options == null ? void 0 : options.in,
1734
- ...comparison > 0 ? [earlierDate, laterDate] : [laterDate, earlierDate]
1735
- );
1736
- const seconds = differenceInSeconds(earlierDate_, laterDate_);
1737
- const offsetInSeconds = (getTimezoneOffsetInMilliseconds(earlierDate_) - getTimezoneOffsetInMilliseconds(laterDate_)) / 1e3;
1738
- const minutes = Math.round((seconds - offsetInSeconds) / 60);
1739
- let months;
1740
- if (minutes < 2) {
1741
- if (options == null ? void 0 : options.includeSeconds) {
1742
- if (seconds < 5) {
1743
- return locale.formatDistance("lessThanXSeconds", 5, localizeOptions);
1744
- } else if (seconds < 10) {
1745
- return locale.formatDistance("lessThanXSeconds", 10, localizeOptions);
1746
- } else if (seconds < 20) {
1747
- return locale.formatDistance("lessThanXSeconds", 20, localizeOptions);
1748
- } else if (seconds < 40) {
1749
- return locale.formatDistance("halfAMinute", 0, localizeOptions);
1750
- } else if (seconds < 60) {
1751
- return locale.formatDistance("lessThanXMinutes", 1, localizeOptions);
1752
- } else {
1753
- return locale.formatDistance("xMinutes", 1, localizeOptions);
1754
- }
1755
- } else {
1756
- if (minutes === 0) {
1757
- return locale.formatDistance("lessThanXMinutes", 1, localizeOptions);
1758
- } else {
1759
- return locale.formatDistance("xMinutes", minutes, localizeOptions);
1760
- }
1761
- }
1762
- } else if (minutes < 45) {
1763
- return locale.formatDistance("xMinutes", minutes, localizeOptions);
1764
- } else if (minutes < 90) {
1765
- return locale.formatDistance("aboutXHours", 1, localizeOptions);
1766
- } else if (minutes < minutesInDay) {
1767
- const hours = Math.round(minutes / 60);
1768
- return locale.formatDistance("aboutXHours", hours, localizeOptions);
1769
- } else if (minutes < minutesInAlmostTwoDays) {
1770
- return locale.formatDistance("xDays", 1, localizeOptions);
1771
- } else if (minutes < minutesInMonth) {
1772
- const days = Math.round(minutes / minutesInDay);
1773
- return locale.formatDistance("xDays", days, localizeOptions);
1774
- } else if (minutes < minutesInMonth * 2) {
1775
- months = Math.round(minutes / minutesInMonth);
1776
- return locale.formatDistance("aboutXMonths", months, localizeOptions);
1777
- }
1778
- months = differenceInMonths(earlierDate_, laterDate_);
1779
- if (months < 12) {
1780
- const nearestMonth = Math.round(minutes / minutesInMonth);
1781
- return locale.formatDistance("xMonths", nearestMonth, localizeOptions);
1782
- } else {
1783
- const monthsSinceStartOfYear = months % 12;
1784
- const years = Math.trunc(months / 12);
1785
- if (monthsSinceStartOfYear < 3) {
1786
- return locale.formatDistance("aboutXYears", years, localizeOptions);
1787
- } else if (monthsSinceStartOfYear < 9) {
1788
- return locale.formatDistance("overXYears", years, localizeOptions);
1789
- } else {
1790
- return locale.formatDistance("almostXYears", years + 1, localizeOptions);
1791
- }
1792
- }
1793
- }
1794
- function formatDistanceToNow(date, options) {
1795
- return formatDistance(date, constructNow(date), options);
1796
- }
1797
- function parseISO(argument, options) {
1798
- const invalidDate = () => constructFrom(options == null ? void 0 : options.in, NaN);
1799
- const additionalDigits = 2;
1800
- const dateStrings = splitDateString(argument);
1801
- let date;
1802
- if (dateStrings.date) {
1803
- const parseYearResult = parseYear(dateStrings.date, additionalDigits);
1804
- date = parseDate(parseYearResult.restDateString, parseYearResult.year);
1805
- }
1806
- if (!date || isNaN(+date)) return invalidDate();
1807
- const timestamp = +date;
1808
- let time = 0;
1809
- let offset;
1810
- if (dateStrings.time) {
1811
- time = parseTime(dateStrings.time);
1812
- if (isNaN(time)) return invalidDate();
1813
- }
1814
- if (dateStrings.timezone) {
1815
- offset = parseTimezone(dateStrings.timezone);
1816
- if (isNaN(offset)) return invalidDate();
1817
- } else {
1818
- const tmpDate = new Date(timestamp + time);
1819
- const result = toDate(0, options == null ? void 0 : options.in);
1820
- result.setFullYear(
1821
- tmpDate.getUTCFullYear(),
1822
- tmpDate.getUTCMonth(),
1823
- tmpDate.getUTCDate()
1824
- );
1825
- result.setHours(
1826
- tmpDate.getUTCHours(),
1827
- tmpDate.getUTCMinutes(),
1828
- tmpDate.getUTCSeconds(),
1829
- tmpDate.getUTCMilliseconds()
1830
- );
1831
- return result;
1832
- }
1833
- return toDate(timestamp + time + offset, options == null ? void 0 : options.in);
1834
- }
1835
- const patterns = {
1836
- dateTimeDelimiter: /[T ]/,
1837
- timeZoneDelimiter: /[Z ]/i,
1838
- timezone: /([Z+-].*)$/
1839
- };
1840
- const dateRegex = /^-?(?:(\d{3})|(\d{2})(?:-?(\d{2}))?|W(\d{2})(?:-?(\d{1}))?|)$/;
1841
- const timeRegex = /^(\d{2}(?:[.,]\d*)?)(?::?(\d{2}(?:[.,]\d*)?))?(?::?(\d{2}(?:[.,]\d*)?))?$/;
1842
- const timezoneRegex = /^([+-])(\d{2})(?::?(\d{2}))?$/;
1843
- function splitDateString(dateString) {
1844
- const dateStrings = {};
1845
- const array = dateString.split(patterns.dateTimeDelimiter);
1846
- let timeString;
1847
- if (array.length > 2) {
1848
- return dateStrings;
1849
- }
1850
- if (/:/.test(array[0])) {
1851
- timeString = array[0];
1852
- } else {
1853
- dateStrings.date = array[0];
1854
- timeString = array[1];
1855
- if (patterns.timeZoneDelimiter.test(dateStrings.date)) {
1856
- dateStrings.date = dateString.split(patterns.timeZoneDelimiter)[0];
1857
- timeString = dateString.substr(
1858
- dateStrings.date.length,
1859
- dateString.length
1860
- );
1861
- }
1862
- }
1863
- if (timeString) {
1864
- const token = patterns.timezone.exec(timeString);
1865
- if (token) {
1866
- dateStrings.time = timeString.replace(token[1], "");
1867
- dateStrings.timezone = token[1];
1868
- } else {
1869
- dateStrings.time = timeString;
1767
+ function NodeInput(props) {
1768
+ const { onSubmit, onCancel, defaultValue, className, minLength = 1, ...inputProps } = props;
1769
+ const [value, setValue] = useState(defaultValue ?? "");
1770
+ const ref = useRef(null);
1771
+ useOnClickOutside(ref, handleSubmit);
1772
+ useEventListener("keyup", (e) => {
1773
+ if (e.key === "Enter") {
1774
+ handleSubmit();
1870
1775
  }
1871
- }
1872
- return dateStrings;
1873
- }
1874
- function parseYear(dateString, additionalDigits) {
1875
- const regex = new RegExp(
1876
- "^(?:(\\d{4}|[+-]\\d{" + (4 + additionalDigits) + "})|(\\d{2}|[+-]\\d{" + (2 + additionalDigits) + "})$)"
1877
- );
1878
- const captures = dateString.match(regex);
1879
- if (!captures) return { year: NaN, restDateString: "" };
1880
- const year = captures[1] ? parseInt(captures[1]) : null;
1881
- const century = captures[2] ? parseInt(captures[2]) : null;
1882
- return {
1883
- year: century === null ? year : century * 100,
1884
- restDateString: dateString.slice((captures[1] || captures[2]).length)
1885
- };
1886
- }
1887
- function parseDate(dateString, year) {
1888
- if (year === null) return /* @__PURE__ */ new Date(NaN);
1889
- const captures = dateString.match(dateRegex);
1890
- if (!captures) return /* @__PURE__ */ new Date(NaN);
1891
- const isWeekDate = !!captures[4];
1892
- const dayOfYear = parseDateUnit(captures[1]);
1893
- const month = parseDateUnit(captures[2]) - 1;
1894
- const day = parseDateUnit(captures[3]);
1895
- const week = parseDateUnit(captures[4]);
1896
- const dayOfWeek = parseDateUnit(captures[5]) - 1;
1897
- if (isWeekDate) {
1898
- if (!validateWeekDate(year, week, dayOfWeek)) {
1899
- return /* @__PURE__ */ new Date(NaN);
1776
+ if (e.key === "Escape") {
1777
+ onCancel();
1900
1778
  }
1901
- return dayOfISOWeekYear(year, week, dayOfWeek);
1902
- } else {
1903
- const date = /* @__PURE__ */ new Date(0);
1904
- if (!validateDate(year, month, day) || !validateDayOfYearDate(year, dayOfYear)) {
1905
- return /* @__PURE__ */ new Date(NaN);
1779
+ });
1780
+ useLayoutEffect(() => {
1781
+ setTimeout(() => {
1782
+ var _a, _b, _c;
1783
+ (_a = ref.current) == null ? void 0 : _a.focus();
1784
+ (_b = ref.current) == null ? void 0 : _b.select();
1785
+ (_c = ref.current) == null ? void 0 : _c.scroll({ left: 9999 });
1786
+ }, 100);
1787
+ }, []);
1788
+ function handleSubmit() {
1789
+ if (value.length >= minLength) {
1790
+ onSubmit(value);
1906
1791
  }
1907
- date.setUTCFullYear(year, month, Math.max(dayOfYear, day));
1908
- return date;
1909
- }
1910
- }
1911
- function parseDateUnit(value) {
1912
- return value ? parseInt(value) : 1;
1913
- }
1914
- function parseTime(timeString) {
1915
- const captures = timeString.match(timeRegex);
1916
- if (!captures) return NaN;
1917
- const hours = parseTimeUnit(captures[1]);
1918
- const minutes = parseTimeUnit(captures[2]);
1919
- const seconds = parseTimeUnit(captures[3]);
1920
- if (!validateTime(hours, minutes, seconds)) {
1921
- return NaN;
1922
1792
  }
1923
- return hours * millisecondsInHour + minutes * millisecondsInMinute + seconds * 1e3;
1793
+ return jsx("input", { ...inputProps, autoFocus: true, className: twMerge("bg-inherit text-inherit outline-none", className), minLength, onChange: (e) => setValue(e.target.value), ref, required: true, type: "text", value });
1924
1794
  }
1925
- function parseTimeUnit(value) {
1926
- return value && parseFloat(value.replace(",", ".")) || 0;
1795
+ function Branch(props) {
1796
+ const { branch = "main" } = props;
1797
+ return jsxs("button", { className: "flex h-8 items-center gap-1 rounded-lg bg-slate-50 pl-1 pr-2 text-xs text-slate-100", children: [jsx(Icon, { name: "Branch" }), jsx("span", { children: "BRANCH" }), jsx("span", { className: "text-gray-900", children: branch })] });
1927
1798
  }
1928
- function parseTimezone(timezoneString) {
1929
- if (timezoneString === "Z") return 0;
1930
- const captures = timezoneString.match(timezoneRegex);
1931
- if (!captures) return 0;
1932
- const sign = captures[1] === "+" ? -1 : 1;
1933
- const hours = parseInt(captures[2]);
1934
- const minutes = captures[3] && parseInt(captures[3]) || 0;
1935
- if (!validateTimezone(hours, minutes)) {
1936
- return NaN;
1799
+ function DocId(props) {
1800
+ const { docId } = props;
1801
+ const [, copy] = useCopyToClipboard();
1802
+ function handleCopy(text) {
1803
+ return () => {
1804
+ copy(text).catch((error) => {
1805
+ console.error("Failed to copy!", error);
1806
+ });
1807
+ };
1937
1808
  }
1938
- return sign * (hours * millisecondsInHour + minutes * millisecondsInMinute);
1939
- }
1940
- function dayOfISOWeekYear(isoWeekYear, week, day) {
1941
- const date = /* @__PURE__ */ new Date(0);
1942
- date.setUTCFullYear(isoWeekYear, 0, 4);
1943
- const fourthOfJanuaryDay = date.getUTCDay() || 7;
1944
- const diff = (week - 1) * 7 + day + 1 - fourthOfJanuaryDay;
1945
- date.setUTCDate(date.getUTCDate() + diff);
1946
- return date;
1947
- }
1948
- const daysInMonths = [31, null, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
1949
- function isLeapYearIndex(year) {
1950
- return year % 400 === 0 || year % 4 === 0 && year % 100 !== 0;
1951
- }
1952
- function validateDate(year, month, date) {
1953
- return month >= 0 && month <= 11 && date >= 1 && date <= (daysInMonths[month] || (isLeapYearIndex(year) ? 29 : 28));
1954
- }
1955
- function validateDayOfYearDate(year, dayOfYear) {
1956
- return dayOfYear >= 1 && dayOfYear <= (isLeapYearIndex(year) ? 366 : 365);
1957
- }
1958
- function validateWeekDate(_year, week, day) {
1959
- return week >= 1 && week <= 53 && day >= 0 && day <= 6;
1809
+ return jsxs("button", { className: "flex h-8 items-center gap-1 rounded-lg bg-slate-50 pl-1 pr-2 text-xs text-slate-100", onClick: handleCopy(docId), children: [jsx(Icon, { name: "Link" }), "DOC ID", jsx("span", { className: "text-gray-900", children: docId })] });
1960
1810
  }
1961
- function validateTime(hours, minutes, seconds) {
1962
- if (hours === 24) {
1963
- return minutes === 0 && seconds === 0;
1964
- }
1965
- return seconds >= 0 && seconds < 60 && minutes >= 0 && minutes < 60 && hours >= 0 && hours < 25;
1811
+ function Scope(props) {
1812
+ const { value, onChange } = props;
1813
+ const items = [
1814
+ { displayValue: "Global scope", value: "global" },
1815
+ { displayValue: "Local scope", value: "local" }
1816
+ ];
1817
+ return jsx(Select, { absolutePositionMenu: true, containerClassName: "bg-slate-50 text-gray-500 rounded-lg w-fit text-xs z-10", id: "scope select", itemClassName: "py-2 text-gray-500 grid grid-cols-[auto,auto] gap-1", items, menuClassName: "min-w-0 text-gray-500", onChange, value });
1966
1818
  }
1967
- function validateTimezone(_hours, minutes) {
1968
- return minutes >= 0 && minutes <= 59;
1819
+ function Header(props) {
1820
+ const { title, docId, scope, onChangeScope, onClose, className, ...divProps } = props;
1821
+ return jsxs("header", { className: twMerge("flex items-center justify-between bg-transparent", className), ...divProps, children: [jsxs("div", { className: "flex items-center gap-3", children: [jsx("button", { className: "shadow-button rounded-lg bg-gray-50 p-1 text-slate-100", onClick: onClose, children: jsx(Icon, { name: "VariantArrowLeft" }) }), jsx("h1", { className: "text-xs", children: title })] }), jsxs("div", { className: "flex items-center gap-2", children: [jsx(DocId, { docId }), jsx(Branch, {}), jsx(Scope, { onChange: onChangeScope, value: scope })] })] });
1969
1822
  }
1970
- const HDivider = (props) => {
1971
- const { className, timestamp, title, subtitle, onClick, isSelected = false } = props;
1972
- const [open, setOpen] = useState(false);
1973
- const hasContent = !!title || !!subtitle || !!timestamp;
1974
- useEffect(() => {
1975
- if (open) {
1976
- setOpen(false);
1977
- setTimeout(() => hasContent && setOpen(true), 50);
1978
- }
1979
- }, [title, subtitle, timestamp, hasContent]);
1980
- const formatTimestamp2 = (isoString) => {
1981
- if (!isoString)
1982
- return "";
1983
- try {
1984
- return formatDistanceToNow(new Date(isoString), { addSuffix: true });
1985
- } catch {
1986
- return isoString;
1987
- }
1988
- };
1989
- const tooltipContent = jsxs("div", { className: "flex flex-col text-xs", children: [!!title && jsx("div", { children: title }), !!subtitle && jsx("div", { className: "text-gray-300", children: subtitle }), !!timestamp && jsx("div", { children: formatTimestamp2(timestamp) })] });
1990
- const handleMouseEnter = () => {
1991
- if (hasContent) {
1992
- setOpen(true);
1993
- }
1994
- };
1995
- const handleMouseLeave = () => {
1996
- setOpen(false);
1997
- };
1998
- return jsxs("div", { className: "relative", onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, children: [isSelected && jsx(Icon, { name: "TimelineCaret", color: "#4EA9FF", size: 10, className: "absolute top-[-11px] z-40" }), jsx(Tooltip, { className: "rounded-md bg-gray-900 text-white", content: tooltipContent, open: open && hasContent, onOpenChange: setOpen, delayDuration: 0, side: "bottom", sideOffset: 5, children: jsx("div", { className: twMerge("mx-0.5 flex h-[25px] w-1.5 cursor-pointer flex-col items-center justify-center rounded-[2px] hover:bg-blue-300", isSelected && "bg-blue-300", className), onClick, "data-title": title, "data-subtitle": subtitle, "data-timestamp": timestamp, children: jsx("div", { className: "h-0.5 w-1 rounded-full bg-gray-500" }) }) })] });
1999
- };
2000
- const getBarHeight = (size = 0) => {
2001
- switch (true) {
2002
- case size <= 0:
2003
- return "h-[1px]";
2004
- case size === 1:
2005
- return "h-[3px]";
2006
- case size === 2:
2007
- return "h-[6px]";
2008
- case size === 3:
2009
- return "h-[9px]";
2010
- case size >= 4:
2011
- return "h-[12px]";
2012
- default:
2013
- return "h-[1px]";
2014
- }
2015
- };
2016
- const formatTimestamp = (isoString) => {
2017
- if (!isoString)
2018
- return "";
2019
- try {
2020
- const date = parseISO(isoString);
2021
- return format(date, "HH:mm, dd, MMMM");
2022
- } catch {
2023
- return isoString;
2024
- }
2025
- };
2026
- const TimelineBar = ({ onClick, className, timestamp, additions, deletions, addSize = 0, delSize = 0, isSelected = false }) => {
2027
- const [open, setOpen] = useState(false);
2028
- const noChanges = addSize === 0 && delSize === 0;
2029
- const addBarHeight = getBarHeight(addSize);
2030
- const delBarHeight = getBarHeight(delSize);
2031
- const tooltipContent = jsxs("div", { className: "flex flex-col text-xs", children: [jsx("div", { children: formatTimestamp(timestamp) }), jsx("div", { className: "text-green-900", children: `${additions} additions +` }), jsx("div", { className: "text-red-700", children: `${deletions} deletions -` })] });
2032
- const handleMouseEnter = () => {
2033
- if (!noChanges) {
2034
- setOpen(true);
2035
- }
2036
- };
2037
- const handleMouseLeave = () => {
2038
- setOpen(false);
2039
- };
2040
- return jsxs("div", { className: "relative", onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, children: [isSelected && jsx(Icon, { name: "TimelineCaret", color: "#4EA9FF", size: 10, className: "absolute left-[-2px] top-[-11px] z-40" }), noChanges ? jsx("div", { className: twMerge("flex h-[25px] w-1.5 cursor-pointer flex-col items-center justify-center rounded-[2px] hover:bg-blue-300", className), "data-timestamp": timestamp, onClick, children: jsx("div", { className: "size-[3px] rounded-full bg-gray-500" }) }) : jsx(Tooltip, { className: "rounded-md bg-gray-900 text-white", content: tooltipContent, open, onOpenChange: setOpen, delayDuration: 0, side: "bottom", sideOffset: 5, children: jsxs("div", { className: twMerge("flex h-[25px] w-1.5 cursor-pointer flex-col items-center justify-center rounded-[2px] hover:bg-blue-300", className, isSelected && "bg-blue-300"), "data-timestamp": timestamp, onClick, children: [jsx("div", { className: "flex h-3 w-0.5 items-end", children: jsx("div", { className: twMerge("h-3 w-0.5 rounded-t-full bg-green-600", addBarHeight) }) }), jsx("div", { className: "flex h-3 w-0.5 items-start", children: jsx("div", { className: twMerge("h-3 w-0.5 rounded-b-full bg-red-600", delBarHeight) }) })] }) })] });
2041
- };
2042
- const defaultTimeLineItem = {
2043
- id: "default",
2044
- type: "bar",
2045
- addSize: 0,
2046
- delSize: 0
2047
- };
2048
- const DocumentTimeline = (props) => {
2049
- const { timeline = [], onItemClick } = props;
2050
- const [selectedItem, setSelectedItem] = useState(null);
2051
- const scrollContainerRef = useRef(null);
2052
- const handleClick = (item) => {
2053
- if (item.id === selectedItem || item.id === defaultTimeLineItem.id) {
2054
- onItemClick == null ? void 0 : onItemClick(null);
2055
- setSelectedItem(null);
2056
- } else {
2057
- onItemClick == null ? void 0 : onItemClick(item);
2058
- setSelectedItem(item.id);
2059
- }
2060
- };
2061
- const mergedTimelineItems = [...timeline, defaultTimeLineItem];
2062
- const [unselectedItems, selectedItems] = useMemo(() => {
2063
- const indexSelected = mergedTimelineItems.findIndex((item) => item.id === selectedItem);
2064
- return indexSelected === -1 ? [mergedTimelineItems, []] : [
2065
- mergedTimelineItems.slice(0, indexSelected),
2066
- mergedTimelineItems.slice(indexSelected)
2067
- ];
2068
- }, [mergedTimelineItems, selectedItem]);
2069
- const renderTimelineItems = useCallback((items) => {
2070
- return items.map((item) => {
2071
- if (item.type === "divider") {
2072
- const { timestamp, title, subtitle } = item;
2073
- return jsx(HDivider, { timestamp, title, subtitle, onClick: () => handleClick(item), isSelected: item.id === selectedItem }, item.id);
2074
- }
2075
- return jsx(TimelineBar, { timestamp: item.timestamp, addSize: item.addSize, delSize: item.delSize, additions: item.additions, deletions: item.deletions, isSelected: item.id === selectedItem, onClick: () => handleClick(item) }, item.id);
2076
- });
2077
- }, [handleClick, selectedItem]);
2078
- const unselectedContent = useMemo(() => renderTimelineItems(unselectedItems), [unselectedItems, renderTimelineItems]);
2079
- const selectedContent = useMemo(() => renderTimelineItems(selectedItems), [selectedItems, renderTimelineItems]);
2080
- useEffect(() => {
2081
- if (scrollContainerRef.current) {
2082
- scrollContainerRef.current.scrollLeft = scrollContainerRef.current.scrollWidth;
2083
- }
2084
- }, []);
2085
- return jsx(TooltipProvider, { delayDuration: 0, skipDelayDuration: 0, children: jsxs("div", { className: "relative h-[36px] w-full", children: [jsx("div", { className: "absolute left-[0px] z-[20] h-[17px] w-[6px] bg-white", children: jsx("div", { className: "mt-[11px] h-[6px] w-[6px] rounded-tl-md bg-slate-50" }) }), jsx("div", { className: "absolute right-[0px] top-[11px] z-[20] h-[6px] w-[6px] bg-white", children: jsx("div", { className: "h-[6px] w-[6px] rounded-tr-md bg-slate-50" }) }), jsx("div", { className: "absolute inset-x-0 bottom-0 h-[25px] rounded-md bg-slate-50" }), jsx("div", { className: "absolute inset-x-0 bottom-0 h-[36px]", children: jsx("div", { ref: scrollContainerRef, className: "h-full overflow-x-auto rounded-md", children: jsxs("div", { className: "ml-auto flex h-[36px] w-max items-end px-2 pb-0", children: [jsx("div", { className: "flex", children: unselectedContent }), jsx("div", { className: "flex rounded-sm bg-blue-200", children: selectedContent })] }) }) }), jsx("div", { className: "pointer-events-none absolute bottom-0 left-0 z-10 h-[25px] w-2 rounded-l-md bg-slate-50" }), jsx("div", { className: "pointer-events-none absolute bottom-0 right-0 z-10 h-[25px] w-2 rounded-r-md bg-slate-50" })] }) });
2086
- };
2087
- const DocumentToolbar = (props) => {
2088
- const { undo: undo2, canUndo, redo: redo2, canRedo, title, onClose, onExport, className, onShowRevisionHistory, onSwitchboardLinkClick, timelineItems = [], onTimelineItemClick, initialTimelineVisible = false, timelineButtonVisible = false } = props;
2089
- const [showTimeline, setShowTimeline] = useState(initialTimelineVisible);
2090
- const isUndoDisabled = !canUndo || !undo2;
2091
- const isRedoDisabled = !canRedo || !redo2;
2092
- const isExportDisabled = !onExport;
2093
- const isSwitchboardLinkDisabled = !onSwitchboardLinkClick;
2094
- const isRevisionHistoryDisabled = !onShowRevisionHistory;
2095
- const isTimelineDisabled = timelineItems.length === 0;
2096
- useEffect(() => {
2097
- if (initialTimelineVisible) {
2098
- setShowTimeline(true);
2099
- }
2100
- }, [initialTimelineVisible]);
2101
- const handleTimelineToggle = () => {
2102
- if (isTimelineDisabled)
2103
- return;
2104
- setShowTimeline(!showTimeline);
2105
- };
2106
- return jsxs("div", { className: "flex w-full flex-col", children: [jsxs("div", { className: twMerge("flex h-12 w-full items-center justify-between rounded-xl border border-gray-200 bg-slate-50 px-4", className), children: [jsxs("div", { className: "flex items-center gap-x-2", children: [jsx("button", { className: twMerge("grid size-8 place-items-center rounded-lg border border-gray-200 bg-white", isUndoDisabled ? "cursor-not-allowed" : "cursor-pointer active:opacity-70"), onClick: undo2, disabled: isUndoDisabled, children: jsx(Icon, { name: "ArrowCouterclockwise", size: 16, className: isUndoDisabled ? "text-gray-500" : "text-gray-900" }) }), jsx("button", { className: twMerge("grid size-8 place-items-center rounded-lg border border-gray-200 bg-white", isRedoDisabled ? "cursor-not-allowed" : "cursor-pointer active:opacity-70"), onClick: redo2, disabled: isRedoDisabled, children: jsx("div", { className: "-scale-x-100", children: jsx(Icon, { name: "ArrowCouterclockwise", size: 16, className: isRedoDisabled ? "text-gray-500" : "text-gray-900" }) }) }), jsx("button", { className: twMerge("flex h-8 items-center rounded-lg border border-gray-200 bg-white px-3 text-sm", isExportDisabled ? "cursor-not-allowed" : "cursor-pointer active:opacity-70"), onClick: onExport, disabled: isExportDisabled, children: jsx("span", { className: isExportDisabled ? "text-gray-500" : "text-gray-900", children: "Export" }) })] }), jsx("div", { className: "flex items-center", children: jsx("h1", { className: "text-sm font-medium text-gray-500", children: title }) }), jsxs("div", { className: "flex items-center gap-x-2", children: [jsx("button", { className: twMerge("grid size-8 place-items-center rounded-lg border border-gray-200 bg-white", isSwitchboardLinkDisabled ? "cursor-not-allowed" : "cursor-pointer active:opacity-70"), onClick: onSwitchboardLinkClick, disabled: isSwitchboardLinkDisabled, children: jsx(Icon, { name: "Drive", size: 16, className: isSwitchboardLinkDisabled ? "text-gray-500" : "text-gray-900" }) }), jsx("button", { className: twMerge("grid size-8 place-items-center rounded-lg border border-gray-200 bg-white", isRevisionHistoryDisabled ? "cursor-not-allowed" : "cursor-pointer active:opacity-70"), onClick: onShowRevisionHistory, disabled: isRevisionHistoryDisabled, children: jsx(Icon, { name: "History", size: 16, className: isRevisionHistoryDisabled ? "text-gray-500" : "text-gray-900" }) }), timelineButtonVisible && jsx("button", { className: twMerge("grid size-8 place-items-center rounded-lg border border-gray-200 bg-white", isTimelineDisabled ? "cursor-not-allowed" : "cursor-pointer active:opacity-70"), onClick: handleTimelineToggle, disabled: isTimelineDisabled, "aria-pressed": showTimeline, children: jsx(Icon, { name: "Timeline", size: 16, className: twMerge("text-gray-900", isTimelineDisabled && "opacity-50", showTimeline && "text-blue-600") }) }), jsx("button", { className: "grid size-8 cursor-pointer place-items-center rounded-lg border border-gray-200 bg-white active:opacity-70", onClick: onClose, children: jsx(Icon, { name: "XmarkLight", size: 16, className: "text-gray-900" }) })] })] }), showTimeline && jsx("div", { className: "mt-2 w-full", children: jsx(DocumentTimeline, { timeline: timelineItems, onItemClick: onTimelineItemClick }) })] });
2107
- };
2108
- const syncIcons = {
2109
- SYNCING: "Syncing",
2110
- SUCCESS: "Synced",
2111
- CONFLICT: "Error",
2112
- MISSING: "Circle",
2113
- ERROR: "Error",
2114
- INITIAL_SYNC: "Syncing"
2115
- };
2116
- function SyncStatusIcon(props) {
2117
- const { syncStatus, className, overrideSyncIcons = {}, ...iconProps } = props;
2118
- const icons = { ...syncIcons, ...overrideSyncIcons };
2119
- const syncStatusIcons = {
2120
- [INITIAL_SYNC]: jsx(Icon, { size: 16, ...iconProps, className: twMerge("text-blue-900", className), name: icons[INITIAL_SYNC] }),
2121
- [SYNCING]: jsx(Icon, { size: 16, ...iconProps, className: twMerge("text-blue-900", className), name: icons[SYNCING] }),
2122
- [SUCCESS]: jsx(Icon, { size: 16, ...iconProps, className: twMerge("text-green-900", className), name: icons[SUCCESS] }),
2123
- [CONFLICT]: jsx(Icon, { size: 16, ...iconProps, className: twMerge("text-orange-900", className), name: icons[CONFLICT] }),
2124
- [MISSING]: jsx(Icon, { size: 16, ...iconProps, className: twMerge("text-red-900", className), name: icons[MISSING] }),
2125
- [ERROR]: jsx(Icon, { size: 16, ...iconProps, className: twMerge("text-red-900", className), name: icons[ERROR] })
2126
- };
2127
- return syncStatusIcons[syncStatus];
2128
- }
2129
- function FileItem(props) {
2130
- const { uiNode, className, customDocumentIconSrc, onSelectNode, onRenameNode, onDuplicateNode, onDeleteNode, isAllowedToCreateDocuments } = props;
2131
- const [mode, setMode] = useState(READ);
2132
- const [isDropdownMenuOpen, setIsDropdownMenuOpen] = useState(false);
2133
- const { dragProps } = useDrag({ uiNode });
2134
- const isReadMode = mode === READ;
2135
- const dropdownMenuHandlers = {
2136
- [DUPLICATE]: () => onDuplicateNode(uiNode),
2137
- [RENAME]: () => setMode(WRITE),
2138
- [DELETE]: () => onDeleteNode(uiNode)
2139
- };
2140
- const dropdownMenuOptions = Object.entries(nodeOptionsMap).map(([id, option]) => ({
2141
- ...option,
2142
- id
2143
- })).filter((option) => defaultFileOptions.includes(option.id));
2144
- function onSubmit(name) {
2145
- onRenameNode(name, uiNode);
2146
- setMode(READ);
2147
- }
2148
- function onCancel() {
2149
- setMode(READ);
2150
- }
2151
- function onClick() {
2152
- onSelectNode(uiNode);
2153
- }
2154
- function onDropdownMenuOptionClick(itemId) {
2155
- const handler = dropdownMenuHandlers[itemId];
2156
- if (!handler) {
2157
- console.error(`No handler found for dropdown menu item: ${itemId}`);
2158
- return;
2159
- }
2160
- handler();
2161
- setIsDropdownMenuOpen(false);
2162
- }
2163
- const iconSrc = getDocumentIconSrc(uiNode.documentType, customDocumentIconSrc);
2164
- const iconNode = jsxs("div", { className: "relative", children: [jsx("img", { alt: "file icon", className: "max-w-none", height: 34, src: iconSrc, width: 32 }), isReadMode && uiNode.syncStatus && jsx("div", { className: "absolute bottom-[-2px] right-0 size-3 rounded-full bg-white", children: jsx("div", { className: "absolute left-[-2px] top-[-2px]", children: jsx(SyncStatusIcon, { overrideSyncIcons: { SUCCESS: "CheckCircleFill" }, syncStatus: uiNode.syncStatus }) }) })] });
2165
- const containerStyles = twMerge("group flex h-12 cursor-pointer select-none items-center rounded-lg bg-gray-200 px-2 text-gray-600 hover:text-gray-800", className);
2166
- const content = isReadMode ? jsxs("div", { className: "flex w-52 items-center justify-between", children: [jsxs("div", { className: "mr-2 truncate group-hover:mr-0", children: [jsx("div", { className: "max-h-6 truncate text-sm font-medium group-hover:text-gray-800", children: uiNode.name }), jsx("div", { className: "max-h-6 truncate text-xs font-medium text-gray-600 group-hover:text-gray-800", children: uiNode.documentType })] }), isAllowedToCreateDocuments ? jsx(ConnectDropdownMenu, { items: dropdownMenuOptions, onItemClick: onDropdownMenuOptionClick, onOpenChange: setIsDropdownMenuOpen, open: isDropdownMenuOpen, children: jsx("button", { className: twMerge("hidden group-hover:block", isDropdownMenuOpen && "block"), onClick: (e) => {
2167
- e.stopPropagation();
2168
- setIsDropdownMenuOpen(true);
2169
- }, children: jsx(Icon, { className: "text-gray-600", name: "VerticalDots" }) }) }) : null] }) : jsx(NodeInput, { className: "ml-3 flex-1 font-medium", defaultValue: uiNode.name, onCancel, onSubmit });
2170
- return jsx("div", { className: "relative w-64", onClick, children: jsx("div", { ...dragProps, className: containerStyles, children: jsxs("div", { className: "flex items-center", children: [jsx("div", { className: "mr-1.5", children: iconNode }), content] }) }) });
2171
- }
2172
- function FolderItem(props) {
2173
- const { uiNode, isAllowedToCreateDocuments, className, onRenameNode, onDuplicateNode, onDeleteNode, onSelectNode, onAddFile, onCopyNode, onMoveNode } = props;
2174
- const [mode, setMode] = useState(READ);
2175
- const [isDropdownMenuOpen, setIsDropdownMenuOpen] = useState(false);
2176
- const { dragProps } = useDrag({ ...props, uiNode });
2177
- const { isDropTarget, dropProps } = useDrop({
2178
- uiNode,
2179
- onAddFile,
2180
- onCopyNode,
2181
- onMoveNode
2182
- });
2183
- const isReadMode = mode === READ;
2184
- function onCancel() {
2185
- setMode(READ);
2186
- }
2187
- function onSubmit(name) {
2188
- onRenameNode(name, uiNode);
2189
- setMode(READ);
2190
- }
2191
- function onClick() {
2192
- onSelectNode(uiNode);
2193
- }
2194
- const dropdownMenuHandlers = {
2195
- [DUPLICATE]: () => onDuplicateNode(uiNode),
2196
- [RENAME]: () => setMode(WRITE),
2197
- [DELETE]: () => onDeleteNode(uiNode)
2198
- };
2199
- const dropdownMenuOptions = Object.entries(nodeOptionsMap).map(([id, option]) => ({
2200
- ...option,
2201
- id
2202
- })).filter((option) => defaultFolderOptions.includes(option.id));
2203
- function onDropdownMenuOptionClick(itemId) {
2204
- const handler = dropdownMenuHandlers[itemId];
2205
- if (!handler) {
2206
- console.error(`No handler found for dropdown menu item: ${itemId}`);
2207
- return;
2208
- }
2209
- handler();
2210
- setIsDropdownMenuOpen(false);
2211
- }
2212
- const content = isReadMode || !isAllowedToCreateDocuments ? jsx("div", { className: "ml-3 max-h-6 truncate font-medium text-gray-600 group-hover:text-gray-800", children: uiNode.name }) : jsx(NodeInput, { className: "ml-3 font-medium", defaultValue: uiNode.name, onCancel, onSubmit });
2213
- const containerStyles = twMerge("group flex h-12 cursor-pointer select-none items-center rounded-lg bg-gray-200 px-2", className, isDropTarget && "bg-blue-100");
2214
- return jsx("div", { className: "relative w-64", onClick, children: jsxs("div", { ...dragProps, ...dropProps, className: containerStyles, children: [jsxs("div", { className: "flex items-center overflow-hidden", children: [jsx("div", { className: "p-1", children: jsxs("div", { className: "relative", children: [jsx(Icon, { name: "FolderClose", size: 24 }), isReadMode && uiNode.syncStatus ? jsx("div", { className: "absolute bottom-[-3px] right-[-2px] size-3 rounded-full bg-white", children: jsx("div", { className: "absolute left-[-2px] top-[-2px]", children: jsx(SyncStatusIcon, { overrideSyncIcons: {
2215
- SUCCESS: "CheckCircleFill"
2216
- }, syncStatus: uiNode.syncStatus }) }) }) : null] }) }), content] }), isReadMode && isAllowedToCreateDocuments ? jsx(ConnectDropdownMenu, { items: dropdownMenuOptions, onItemClick: onDropdownMenuOptionClick, onOpenChange: setIsDropdownMenuOpen, open: isDropdownMenuOpen, children: jsx("button", { className: twMerge("ml-auto hidden group-hover:block", isDropdownMenuOpen && "block"), onClick: (e) => {
2217
- e.stopPropagation();
2218
- setIsDropdownMenuOpen(true);
2219
- }, children: jsx(Icon, { className: "text-gray-600", name: "VerticalDots" }) }) }) : null] }) });
2220
- }
2221
- function NodeInput(props) {
2222
- const { onSubmit, onCancel, defaultValue, className, minLength = 1, ...inputProps } = props;
2223
- const [value, setValue] = useState(defaultValue ?? "");
2224
- const ref = useRef(null);
2225
- useOnClickOutside(ref, handleSubmit);
2226
- useEventListener("keyup", (e) => {
2227
- if (e.key === "Enter") {
2228
- handleSubmit();
2229
- }
2230
- if (e.key === "Escape") {
2231
- onCancel();
2232
- }
2233
- });
2234
- useLayoutEffect(() => {
2235
- setTimeout(() => {
2236
- var _a, _b, _c;
2237
- (_a = ref.current) == null ? void 0 : _a.focus();
2238
- (_b = ref.current) == null ? void 0 : _b.select();
2239
- (_c = ref.current) == null ? void 0 : _c.scroll({ left: 9999 });
2240
- }, 100);
2241
- }, []);
2242
- function handleSubmit() {
2243
- if (value.length >= minLength) {
2244
- onSubmit(value);
2245
- }
2246
- }
2247
- return jsx("input", { ...inputProps, autoFocus: true, className: twMerge("bg-inherit text-inherit outline-none", className), minLength, onChange: (e) => setValue(e.target.value), ref, required: true, type: "text", value });
2248
- }
2249
- function Branch(props) {
2250
- const { branch = "main" } = props;
2251
- return jsxs("button", { className: "flex h-8 items-center gap-1 rounded-lg bg-slate-50 pl-1 pr-2 text-xs text-slate-100", children: [jsx(Icon, { name: "Branch" }), jsx("span", { children: "BRANCH" }), jsx("span", { className: "text-gray-900", children: branch })] });
2252
- }
2253
- function DocId(props) {
2254
- const { docId } = props;
2255
- const [, copy] = useCopyToClipboard();
2256
- function handleCopy(text) {
2257
- return () => {
2258
- copy(text).catch((error) => {
2259
- console.error("Failed to copy!", error);
2260
- });
2261
- };
2262
- }
2263
- return jsxs("button", { className: "flex h-8 items-center gap-1 rounded-lg bg-slate-50 pl-1 pr-2 text-xs text-slate-100", onClick: handleCopy(docId), children: [jsx(Icon, { name: "Link" }), "DOC ID", jsx("span", { className: "text-gray-900", children: docId })] });
2264
- }
2265
- function Scope(props) {
2266
- const { value, onChange } = props;
2267
- const items = [
2268
- { displayValue: "Global scope", value: "global" },
2269
- { displayValue: "Local scope", value: "local" }
2270
- ];
2271
- return jsx(Select, { absolutePositionMenu: true, containerClassName: "bg-slate-50 text-gray-500 rounded-lg w-fit text-xs z-10", id: "scope select", itemClassName: "py-2 text-gray-500 grid grid-cols-[auto,auto] gap-1", items, menuClassName: "min-w-0 text-gray-500", onChange, value });
2272
- }
2273
- function Header(props) {
2274
- const { title, docId, scope, onChangeScope, onClose, className, ...divProps } = props;
2275
- return jsxs("header", { className: twMerge("flex items-center justify-between bg-transparent", className), ...divProps, children: [jsxs("div", { className: "flex items-center gap-3", children: [jsx("button", { className: "shadow-button rounded-lg bg-gray-50 p-1 text-slate-100", onClick: onClose, children: jsx(Icon, { name: "VariantArrowLeft" }) }), jsx("h1", { className: "text-xs", children: title })] }), jsxs("div", { className: "flex items-center gap-2", children: [jsx(DocId, { docId }), jsx(Branch, {}), jsx(Scope, { onChange: onChangeScope, value: scope })] })] });
2276
- }
2277
- function memo(getDeps, fn, opts) {
2278
- let deps = opts.initialDeps ?? [];
2279
- let result;
2280
- return () => {
2281
- var _a, _b, _c, _d;
2282
- let depTime;
2283
- if (opts.key && ((_a = opts.debug) == null ? void 0 : _a.call(opts))) depTime = Date.now();
2284
- const newDeps = getDeps();
2285
- const depsChanged = newDeps.length !== deps.length || newDeps.some((dep, index) => deps[index] !== dep);
2286
- if (!depsChanged) {
2287
- return result;
1823
+ function memo(getDeps, fn, opts) {
1824
+ let deps = opts.initialDeps ?? [];
1825
+ let result;
1826
+ function memoizedFunction() {
1827
+ var _a, _b, _c, _d;
1828
+ let depTime;
1829
+ if (opts.key && ((_a = opts.debug) == null ? void 0 : _a.call(opts))) depTime = Date.now();
1830
+ const newDeps = getDeps();
1831
+ const depsChanged = newDeps.length !== deps.length || newDeps.some((dep, index) => deps[index] !== dep);
1832
+ if (!depsChanged) {
1833
+ return result;
2288
1834
  }
2289
1835
  deps = newDeps;
2290
1836
  let resultTime;
@@ -2315,7 +1861,11 @@ function memo(getDeps, fn, opts) {
2315
1861
  }
2316
1862
  (_d = opts == null ? void 0 : opts.onChange) == null ? void 0 : _d.call(opts, result);
2317
1863
  return result;
1864
+ }
1865
+ memoizedFunction.updateDeps = (newDeps) => {
1866
+ deps = newDeps;
2318
1867
  };
1868
+ return memoizedFunction;
2319
1869
  }
2320
1870
  function notUndefined(value, msg) {
2321
1871
  if (value === void 0) {
@@ -2361,15 +1911,18 @@ const observeElementRect = (instance, cb) => {
2361
1911
  };
2362
1912
  }
2363
1913
  const observer = new targetWindow.ResizeObserver((entries) => {
2364
- const entry = entries[0];
2365
- if (entry == null ? void 0 : entry.borderBoxSize) {
2366
- const box = entry.borderBoxSize[0];
2367
- if (box) {
2368
- handler({ width: box.inlineSize, height: box.blockSize });
2369
- return;
1914
+ const run = () => {
1915
+ const entry = entries[0];
1916
+ if (entry == null ? void 0 : entry.borderBoxSize) {
1917
+ const box = entry.borderBoxSize[0];
1918
+ if (box) {
1919
+ handler({ width: box.inlineSize, height: box.blockSize });
1920
+ return;
1921
+ }
2370
1922
  }
2371
- }
2372
- handler(element.getBoundingClientRect());
1923
+ handler(element.getBoundingClientRect());
1924
+ };
1925
+ instance.options.useAnimationFrameWithResizeObserver ? requestAnimationFrame(run) : run();
2373
1926
  });
2374
1927
  observer.observe(element, { box: "border-box" });
2375
1928
  return () => {
@@ -2407,10 +1960,15 @@ const observeElementOffset = (instance, cb) => {
2407
1960
  const endHandler = createHandler(false);
2408
1961
  endHandler();
2409
1962
  element.addEventListener("scroll", handler, addEventListenerOptions);
2410
- element.addEventListener("scrollend", endHandler, addEventListenerOptions);
1963
+ const registerScrollendEvent = instance.options.useScrollendEvent && supportsScrollend;
1964
+ if (registerScrollendEvent) {
1965
+ element.addEventListener("scrollend", endHandler, addEventListenerOptions);
1966
+ }
2411
1967
  return () => {
2412
1968
  element.removeEventListener("scroll", handler);
2413
- element.removeEventListener("scrollend", endHandler);
1969
+ if (registerScrollendEvent) {
1970
+ element.removeEventListener("scrollend", endHandler);
1971
+ }
2414
1972
  };
2415
1973
  };
2416
1974
  const measureElement = (element, entry, instance) => {
@@ -2464,7 +2022,10 @@ class Virtualizer {
2464
2022
  }
2465
2023
  return _ro = new this.targetWindow.ResizeObserver((entries) => {
2466
2024
  entries.forEach((entry) => {
2467
- this._measureElement(entry.target, entry);
2025
+ const run = () => {
2026
+ this._measureElement(entry.target, entry);
2027
+ };
2028
+ this.options.useAnimationFrameWithResizeObserver ? requestAnimationFrame(run) : run();
2468
2029
  });
2469
2030
  });
2470
2031
  };
@@ -2512,7 +2073,8 @@ class Virtualizer {
2512
2073
  isScrollingResetDelay: 150,
2513
2074
  enabled: true,
2514
2075
  isRtl: false,
2515
- useScrollendEvent: true,
2076
+ useScrollendEvent: false,
2077
+ useAnimationFrameWithResizeObserver: false,
2516
2078
  ...opts2
2517
2079
  };
2518
2080
  };
@@ -2701,12 +2263,18 @@ class Virtualizer {
2701
2263
  }
2702
2264
  );
2703
2265
  this.calculateRange = memo(
2704
- () => [this.getMeasurements(), this.getSize(), this.getScrollOffset()],
2705
- (measurements, outerSize, scrollOffset) => {
2266
+ () => [
2267
+ this.getMeasurements(),
2268
+ this.getSize(),
2269
+ this.getScrollOffset(),
2270
+ this.options.lanes
2271
+ ],
2272
+ (measurements, outerSize, scrollOffset, lanes) => {
2706
2273
  return this.range = measurements.length > 0 && outerSize > 0 ? calculateRange({
2707
2274
  measurements,
2708
2275
  outerSize,
2709
- scrollOffset
2276
+ scrollOffset,
2277
+ lanes
2710
2278
  }) : null;
2711
2279
  },
2712
2280
  {
@@ -2714,7 +2282,7 @@ class Virtualizer {
2714
2282
  debug: () => this.options.debug
2715
2283
  }
2716
2284
  );
2717
- this.getIndexes = memo(
2285
+ this.getVirtualIndexes = memo(
2718
2286
  () => {
2719
2287
  let startIndex = null;
2720
2288
  let endIndex = null;
@@ -2723,6 +2291,7 @@ class Virtualizer {
2723
2291
  startIndex = range.startIndex;
2724
2292
  endIndex = range.endIndex;
2725
2293
  }
2294
+ this.maybeNotify.updateDeps([this.isScrolling, startIndex, endIndex]);
2726
2295
  return [
2727
2296
  this.options.rangeExtractor,
2728
2297
  this.options.overscan,
@@ -2806,7 +2375,7 @@ class Virtualizer {
2806
2375
  this._measureElement(node, void 0);
2807
2376
  };
2808
2377
  this.getVirtualItems = memo(
2809
- () => [this.getIndexes(), this.getMeasurements()],
2378
+ () => [this.getVirtualIndexes(), this.getMeasurements()],
2810
2379
  (indexes, measurements) => {
2811
2380
  const virtualItems = [];
2812
2381
  for (let k = 0, len = indexes.length; k < len; k++) {
@@ -2835,15 +2404,15 @@ class Virtualizer {
2835
2404
  )]
2836
2405
  );
2837
2406
  };
2838
- this.getOffsetForAlignment = (toOffset, align) => {
2407
+ this.getOffsetForAlignment = (toOffset, align, itemSize = 0) => {
2839
2408
  const size = this.getSize();
2840
2409
  const scrollOffset = this.getScrollOffset();
2841
2410
  if (align === "auto") {
2842
- if (toOffset >= scrollOffset + size) {
2843
- align = "end";
2844
- }
2411
+ align = toOffset >= scrollOffset + size ? "end" : "start";
2845
2412
  }
2846
- if (align === "end") {
2413
+ if (align === "center") {
2414
+ toOffset += (itemSize - size) / 2;
2415
+ } else if (align === "end") {
2847
2416
  toOffset -= size;
2848
2417
  }
2849
2418
  const scrollSizeProp = this.options.horizontal ? "scrollWidth" : "scrollHeight";
@@ -2868,27 +2437,11 @@ class Virtualizer {
2868
2437
  return [scrollOffset, align];
2869
2438
  }
2870
2439
  }
2871
- const centerOffset = item.start - this.options.scrollPaddingStart + (item.size - size) / 2;
2872
- switch (align) {
2873
- case "center":
2874
- return [this.getOffsetForAlignment(centerOffset, align), align];
2875
- case "end":
2876
- return [
2877
- this.getOffsetForAlignment(
2878
- item.end + this.options.scrollPaddingEnd,
2879
- align
2880
- ),
2881
- align
2882
- ];
2883
- default:
2884
- return [
2885
- this.getOffsetForAlignment(
2886
- item.start - this.options.scrollPaddingStart,
2887
- align
2888
- ),
2889
- align
2890
- ];
2891
- }
2440
+ const toOffset = align === "end" ? item.end + this.options.scrollPaddingEnd : item.start - this.options.scrollPaddingStart;
2441
+ return [
2442
+ this.getOffsetForAlignment(toOffset, align, item.size),
2443
+ align
2444
+ ];
2892
2445
  };
2893
2446
  this.isDynamicMode = () => this.elementsCache.size > 0;
2894
2447
  this.cancelScrollToIndex = () => {
@@ -2958,10 +2511,19 @@ class Virtualizer {
2958
2511
  let end;
2959
2512
  if (measurements.length === 0) {
2960
2513
  end = this.options.paddingStart;
2514
+ } else if (this.options.lanes === 1) {
2515
+ end = ((_a = measurements[measurements.length - 1]) == null ? void 0 : _a.end) ?? 0;
2961
2516
  } else {
2962
- end = this.options.lanes === 1 ? ((_a = measurements[measurements.length - 1]) == null ? void 0 : _a.end) ?? 0 : Math.max(
2963
- ...measurements.slice(-this.options.lanes).map((m) => m.end)
2964
- );
2517
+ const endByLane = Array(this.options.lanes).fill(null);
2518
+ let endIndex = measurements.length - 1;
2519
+ while (endIndex >= 0 && endByLane.some((val) => val === null)) {
2520
+ const item = measurements[endIndex];
2521
+ if (endByLane[item.lane] === null) {
2522
+ endByLane[item.lane] = item.end;
2523
+ }
2524
+ endIndex--;
2525
+ }
2526
+ end = Math.max(...endByLane.filter((val) => val !== null));
2965
2527
  }
2966
2528
  return Math.max(
2967
2529
  end - this.options.scrollMargin + this.options.paddingEnd,
@@ -3002,14 +2564,43 @@ const findNearestBinarySearch = (low, high, getCurrentValue, value) => {
3002
2564
  function calculateRange({
3003
2565
  measurements,
3004
2566
  outerSize,
3005
- scrollOffset
2567
+ scrollOffset,
2568
+ lanes
3006
2569
  }) {
3007
- const count = measurements.length - 1;
2570
+ const lastIndex = measurements.length - 1;
3008
2571
  const getOffset = (index) => measurements[index].start;
3009
- const startIndex = findNearestBinarySearch(0, count, getOffset, scrollOffset);
2572
+ if (measurements.length <= lanes) {
2573
+ return {
2574
+ startIndex: 0,
2575
+ endIndex: lastIndex
2576
+ };
2577
+ }
2578
+ let startIndex = findNearestBinarySearch(
2579
+ 0,
2580
+ lastIndex,
2581
+ getOffset,
2582
+ scrollOffset
2583
+ );
3010
2584
  let endIndex = startIndex;
3011
- while (endIndex < count && measurements[endIndex].end < scrollOffset + outerSize) {
3012
- endIndex++;
2585
+ if (lanes === 1) {
2586
+ while (endIndex < lastIndex && measurements[endIndex].end < scrollOffset + outerSize) {
2587
+ endIndex++;
2588
+ }
2589
+ } else if (lanes > 1) {
2590
+ const endPerLane = Array(lanes).fill(0);
2591
+ while (endIndex < lastIndex && endPerLane.some((pos) => pos < scrollOffset + outerSize)) {
2592
+ const item = measurements[endIndex];
2593
+ endPerLane[item.lane] = item.end;
2594
+ endIndex++;
2595
+ }
2596
+ const startPerLane = Array(lanes).fill(scrollOffset + outerSize);
2597
+ while (startIndex >= 0 && startPerLane.some((pos) => pos >= scrollOffset)) {
2598
+ const item = measurements[startIndex];
2599
+ startPerLane[item.lane] = item.start;
2600
+ startIndex--;
2601
+ }
2602
+ startIndex = Math.max(0, startIndex - startIndex % lanes);
2603
+ endIndex = Math.min(lastIndex, endIndex + (lanes - 1 - endIndex % lanes));
3013
2604
  }
3014
2605
  return { startIndex, endIndex };
3015
2606
  }
@@ -3266,8 +2857,8 @@ function RevisionHistory(props) {
3266
2857
  return jsxs(TooltipProvider, { children: [jsx(Header, { docId: documentId, onChangeScope, onClose, scope, title: documentTitle }), PaginationComponent, jsx("div", { className: "mt-4 flex justify-center rounded-md bg-slate-50 p-4", children: visibleOperations.length > 0 ? jsx("div", { className: "grid grid-cols-[minmax(min-content,1018px)]", children: jsx(Timeline, { globalOperations: scope === "global" ? pageItems : [], localOperations: scope === "local" ? pageItems : [], scope }) }) : jsx("h3", { className: "my-40 text-gray-600", children: "This document has no recorded operations yet." }) }), PaginationComponent] });
3267
2858
  }
3268
2859
  function Tooltip(props) {
3269
- const { children, content, open, defaultOpen, onOpenChange, className, side = "top", sideOffset = 5, ...rest } = props;
3270
- return jsxs(Root3, { defaultOpen, delayDuration: 0, onOpenChange, open, children: [jsx(Trigger, { asChild: true, children }), jsx(Portal, { children: jsx(Content2, { ...rest, side, sideOffset, className: twMerge("shadow-tooltip rounded-lg border border-gray-200 bg-white p-2 text-xs", className), children: content }) })] });
2860
+ const { children, content, open, defaultOpen, onOpenChange, className, ...rest } = props;
2861
+ return jsxs(Root3, { defaultOpen, delayDuration: 0, onOpenChange, open, children: [jsx(Trigger, { asChild: true, children }), jsx(Portal, { children: jsx(Content2, { ...rest, className: twMerge("shadow-tooltip rounded-lg border border-gray-200 bg-white p-2 text-xs", className), children: content }) })] });
3271
2862
  }
3272
2863
  const TooltipProvider = Provider;
3273
2864
  const BUDGET = "powerhouse/budget-statement";
@@ -3515,7 +3106,9 @@ function useAddDebouncedOperations(reactor, props) {
3515
3106
  const { driveId, documentId } = props;
3516
3107
  const [documentDrives] = useDocumentDrives(reactor);
3517
3108
  const documentDrivesRef = useRef(documentDrives);
3518
- const { isAllowedToEditDocuments } = useUserPermissions();
3109
+ const { isAllowedToEditDocuments } = useUserPermissions() || {
3110
+ isAllowedToEditDocuments: false
3111
+ };
3519
3112
  useEffect(() => {
3520
3113
  documentDrivesRef.current = documentDrives;
3521
3114
  }, [documentDrives]);
@@ -3526,7 +3119,7 @@ function useAddDebouncedOperations(reactor, props) {
3526
3119
  if (!reactor) {
3527
3120
  throw new Error("Reactor is not loaded");
3528
3121
  }
3529
- const drive = documentDrivesRef.current.find((drive2) => drive2.id === driveId2);
3122
+ const drive = documentDrivesRef.current.find((drive2) => drive2.state.global.id === driveId2);
3530
3123
  if (!drive) {
3531
3124
  throw new Error(`Drive with id ${driveId2} not found`);
3532
3125
  }
@@ -3605,7 +3198,7 @@ function getNode(id, drive) {
3605
3198
  }
3606
3199
  function createDriveActions(document2, dispatch, context) {
3607
3200
  const drive = document2;
3608
- const driveId = drive.id;
3201
+ const { id: driveId } = drive.state.global;
3609
3202
  const { selectedNode } = context;
3610
3203
  const handleAddFolder = async (name, parentFolder, id = generateId()) => {
3611
3204
  dispatch(addFolder({
@@ -3895,17 +3488,6 @@ function useEditorProps(document2, node, documentDispatch, onAddOperation) {
3895
3488
  isAllowedToEditDocuments: (userPermissions == null ? void 0 : userPermissions.isAllowedToEditDocuments) ?? false
3896
3489
  };
3897
3490
  }
3898
- function useGetDocument() {
3899
- const { openFile } = useDocumentDriveServer();
3900
- const getDocument = useCallback(
3901
- async (driveId, documentId, options) => {
3902
- const document2 = await openFile(driveId, documentId, options);
3903
- return document2;
3904
- },
3905
- [openFile]
3906
- );
3907
- return getDocument;
3908
- }
3909
3491
  function useSyncStatus(driveId, documentId) {
3910
3492
  const { getSyncStatusSync, onSyncStatus, documentDrives } = useDocumentDriveServer();
3911
3493
  const syncStatus = useSyncExternalStore(
@@ -3915,7 +3497,9 @@ function useSyncStatus(driveId, documentId) {
3915
3497
  },
3916
3498
  () => {
3917
3499
  var _a;
3918
- const drive = documentDrives.find((_drive) => _drive.id === driveId);
3500
+ const drive = documentDrives.find(
3501
+ (_drive) => _drive.state.global.id === driveId
3502
+ );
3919
3503
  if (!drive) return;
3920
3504
  const isReadDrive = "readContext" in drive;
3921
3505
  const _sharingType = !isReadDrive ? (_a = drive.state.local.sharingType) == null ? void 0 : _a.toUpperCase() : "PUBLIC";
@@ -3974,338 +3558,6 @@ const useUndoRedoShortcuts = (props) => {
3974
3558
  [canRedo, redo2]
3975
3559
  );
3976
3560
  };
3977
- function getDocumentSpec(doc) {
3978
- if ("documentModelState" in doc) {
3979
- return doc.documentModelState;
3980
- }
3981
- return doc.documentModel;
3982
- }
3983
- const CreateDocument = ({ documentModels, createDocument }) => {
3984
- return jsxs("div", { className: "px-6", children: [jsx("h3", { className: "mb-3 mt-4 text-xl font-bold text-gray-600", children: "New document" }), jsx("div", { className: "flex w-full flex-wrap gap-4", children: documentModels == null ? void 0 : documentModels.map((doc) => {
3985
- const spec = getDocumentSpec(doc);
3986
- return jsx(Button, { color: "light", "aria-details": spec.description, onClick: () => createDocument(doc), children: jsx("span", { className: "text-sm", children: spec.name }) }, spec.id);
3987
- }) })] });
3988
- };
3989
- function sortUiNodesByName(a, b) {
3990
- return a.name.localeCompare(b.name);
3991
- }
3992
- const GAP = 8;
3993
- const ITEM_WIDTH = 256;
3994
- const ITEM_HEIGHT = 48;
3995
- const USED_SPACE = 420;
3996
- function FileContentView(props) {
3997
- const parentRef = useRef(null);
3998
- const { t } = useTranslation();
3999
- const windowSize = useWindowSize();
4000
- const { fileNodes, ...fileProps } = props;
4001
- const availableWidth = windowSize.innerWidth - USED_SPACE;
4002
- const columnCount = Math.floor(availableWidth / (ITEM_WIDTH + GAP)) || 1;
4003
- const rowCount = Math.ceil(fileNodes.length / columnCount);
4004
- const rowVirtualizer = useVirtualizer({
4005
- count: rowCount,
4006
- getScrollElement: () => parentRef.current,
4007
- estimateSize: (index) => {
4008
- if (index > 0) {
4009
- return ITEM_HEIGHT + GAP;
4010
- }
4011
- return ITEM_HEIGHT;
4012
- },
4013
- overscan: 5
4014
- });
4015
- const columnVirtualizer = useVirtualizer({
4016
- horizontal: true,
4017
- count: columnCount,
4018
- getScrollElement: () => parentRef.current,
4019
- estimateSize: (index) => {
4020
- if (index > 0) {
4021
- return ITEM_WIDTH + GAP;
4022
- }
4023
- return ITEM_WIDTH;
4024
- },
4025
- overscan: 5
4026
- });
4027
- const getItemIndex = (rowIndex, columnIndex) => rowIndex * columnCount + columnIndex;
4028
- const getItem = (rowIndex, columnIndex) => {
4029
- const index = getItemIndex(rowIndex, columnIndex);
4030
- return fileNodes[index] || null;
4031
- };
4032
- if (fileNodes.length === 0) {
4033
- return jsx("div", { className: "mb-8 text-sm text-gray-400", children: t("folderView.sections.documents.empty", {
4034
- defaultValue: "No documents or files 📄"
4035
- }) });
4036
- }
4037
- const renderItem = (rowIndex, columnIndex) => {
4038
- const fileNode = getItem(rowIndex, columnIndex);
4039
- if (!fileNode) {
4040
- return null;
4041
- }
4042
- return jsx("div", { style: {
4043
- marginLeft: columnIndex === 0 ? 0 : GAP
4044
- }, children: jsx(FileItem, { uiNode: fileNode, ...fileProps }, fileNode.id) });
4045
- };
4046
- return jsx("div", { ref: parentRef, style: {
4047
- height: `400px`,
4048
- width: `100%`,
4049
- overflow: "auto"
4050
- }, children: jsx("div", { style: {
4051
- height: `${rowVirtualizer.getTotalSize()}px`,
4052
- width: `${columnVirtualizer.getTotalSize()}px`,
4053
- position: "relative"
4054
- }, children: rowVirtualizer.getVirtualItems().map((virtualRow) => jsx(React__default.Fragment, { children: columnVirtualizer.getVirtualItems().map((virtualColumn) => jsx("div", { style: {
4055
- position: "absolute",
4056
- top: 0,
4057
- left: 0,
4058
- marginTop: virtualRow.index === 0 ? 0 : GAP,
4059
- width: `${virtualColumn.size}px`,
4060
- height: `${virtualRow.size}px`,
4061
- transform: `translateX(${virtualColumn.start}px) translateY(${virtualRow.start}px)`
4062
- }, children: renderItem(virtualRow.index, virtualColumn.index) }, virtualColumn.key)) }, virtualRow.key)) }) });
4063
- }
4064
- function FolderView(props) {
4065
- const { node, className, isDropTarget, containerProps, ...nodeProps } = props;
4066
- const { t } = useTranslation();
4067
- const folderNodes = node.children.filter((node2) => node2.kind === FOLDER).sort(sortUiNodesByName);
4068
- const fileNodes = node.children.filter((node2) => node2.kind === FILE).sort(sortUiNodesByName);
4069
- const folderCallbacks = {
4070
- onSelectNode: (node2) => nodeProps.onSelectNode(node2),
4071
- onRenameNode: (name, node2) => nodeProps.onRenameNode(name, node2),
4072
- onDuplicateNode: (node2) => nodeProps.onDuplicateNode(node2),
4073
- onDeleteNode: (node2) => nodeProps.onDeleteNode(node2)
4074
- };
4075
- const fileCallbacks = {
4076
- onSelectNode: (node2) => nodeProps.onSelectNode(node2),
4077
- onRenameNode: (name, node2) => nodeProps.onRenameNode(name, node2),
4078
- onDuplicateNode: (node2) => nodeProps.onDuplicateNode(node2),
4079
- onDeleteNode: (node2) => nodeProps.onDeleteNode(node2)
4080
- };
4081
- const baseNodeCallbacks = {
4082
- onAddFile: async (file, parentNode) => {
4083
- await nodeProps.onAddFile(file, parentNode);
4084
- },
4085
- onCopyNode: async (uiNode, targetNode) => {
4086
- await nodeProps.onCopyNode(uiNode, targetNode);
4087
- },
4088
- onMoveNode: async (uiNode, targetNode) => {
4089
- await nodeProps.onMoveNode(uiNode, targetNode);
4090
- }
4091
- };
4092
- return jsxs("div", { className: twMerge("rounded-md border-2 border-transparent p-2", isDropTarget && "border-dashed border-blue-100", className), ...containerProps, children: [jsx(DriveLayout.ContentSection, { title: t("folderView.sections.folders.title", {
4093
- defaultValue: "Folders"
4094
- }), className: "mb-4", children: folderNodes.length > 0 ? folderNodes.map((folderNode) => jsx(FolderItem, { uiNode: folderNode, ...baseNodeCallbacks, ...folderCallbacks, isAllowedToCreateDocuments: nodeProps.isAllowedToCreateDocuments }, folderNode.id)) : jsx("div", { className: "mb-8 text-sm text-gray-400", children: t("folderView.sections.folders.empty", {
4095
- defaultValue: "No documents or files 📄"
4096
- }) }) }), jsx(DriveLayout.ContentSection, { title: t("folderView.sections.documents.title", {
4097
- defaultValue: "Documents and files"
4098
- }), children: jsx("div", { className: twMerge("w-full", fileNodes.length > 0 ? "min-h-[400px]" : "min-h-14"), children: jsx(FileContentView, { fileNodes, ...fileCallbacks, isAllowedToCreateDocuments: nodeProps.isAllowedToCreateDocuments }) }) })] });
4099
- }
4100
- function BaseEditor(props) {
4101
- const { document: document2, dispatch, className, children } = props;
4102
- const { id: driveId } = document2;
4103
- const { showSearchBar, isAllowedToCreateDocuments, documentModels, showCreateDocumentModal } = useDriveContext();
4104
- const { driveNodes, selectedNode, selectedNodePath, getNodeById, setSelectedNode } = useUiNodesContext();
4105
- const driveNode = useMemo(() => driveNodes.find((n) => n.id === driveId), [driveNodes, driveId]);
4106
- const { addDocument, addFile, addFolder: addFolder2, renameNode, deleteNode: deleteNode2, moveNode: moveNode2, copyNode: copyNode2, duplicateNode } = useDriveActionsWithUiNodes(document2, dispatch);
4107
- const onCreateDocument = useCallback(async (documentModel) => {
4108
- const { name } = await showCreateDocumentModal(documentModel);
4109
- const document3 = documentModel.utils.createDocument();
4110
- await addDocument(name, documentModel.documentModel.name, document3, selectedNode == null ? void 0 : selectedNode.id);
4111
- }, [addDocument, showCreateDocumentModal, selectedNode == null ? void 0 : selectedNode.id]);
4112
- const { isDropTarget, dropProps } = useDrop({
4113
- uiNode: selectedNode,
4114
- onAddFile: addFile,
4115
- onCopyNode: copyNode2,
4116
- onMoveNode: moveNode2
4117
- });
4118
- const { breadcrumbs, onBreadcrumbSelected } = useBreadcrumbs({
4119
- selectedNodePath,
4120
- getNodeById,
4121
- setSelectedNode
4122
- });
4123
- if (!driveNode) {
4124
- return jsx("div", { children: "Drive not found" });
4125
- } else if ((selectedNode == null ? void 0 : selectedNode.kind) === FILE$1) {
4126
- return jsx(Fragment$1, {});
4127
- }
4128
- return jsxs(DriveLayout, { className, children: [children, jsxs(DriveLayout.Header, { children: [jsx(Breadcrumbs, { breadcrumbs, createEnabled: isAllowedToCreateDocuments, onCreate: addFolder2, onBreadcrumbSelected }), showSearchBar && jsx(SearchBar, {})] }), jsx(DriveLayout.Content, { children: jsx(FolderView, { node: selectedNode || driveNode, onSelectNode: setSelectedNode, onRenameNode: renameNode, onDuplicateNode: duplicateNode, onDeleteNode: deleteNode2, onAddFile: addFile, onCopyNode: copyNode2, onMoveNode: moveNode2, isDropTarget, isAllowedToCreateDocuments }) }), jsx(DriveLayout.Footer, { children: isAllowedToCreateDocuments && jsx(CreateDocument, { documentModels, createDocument: onCreateDocument }) })] });
4129
- }
4130
- function Editor(props) {
4131
- return jsx(DriveContextProvider, { value: props.context, children: jsx(BaseEditor, { ...props }) });
4132
- }
4133
- const GenericDriveExplorer = {
4134
- Component: Editor,
4135
- documentTypes: ["powerhouse/document-drive"],
4136
- config: {
4137
- id: "GenericDriveExplorer",
4138
- disableExternalControls: true,
4139
- documentToolbarEnabled: true,
4140
- showSwitchboardLink: true
4141
- }
4142
- };
4143
- function useAnalyticsQueryWrapper(options) {
4144
- const { queryFn, ...queryOptions } = options;
4145
- const store = useAnalyticsStore();
4146
- const engine = useAnalyticsEngine();
4147
- return useQuery({
4148
- ...queryOptions,
4149
- queryFn: () => {
4150
- if (!store || !engine) {
4151
- throw new Error("No analytics store available. Use within an AnalyticsProvider.");
4152
- }
4153
- return queryFn({ store, engine });
4154
- }
4155
- });
4156
- }
4157
- function useAnalyticsQuery(query, options) {
4158
- const store = useAnalyticsStore();
4159
- const { data: querySources } = useQuerySources(query);
4160
- const queryClient = useQueryClient();
4161
- const subscriptions = useRef([]);
4162
- const result = useAnalyticsQueryWrapper({
4163
- queryKey: ["analytics", "query", query],
4164
- queryFn: ({ engine }) => engine.execute(query),
4165
- ...options
4166
- });
4167
- useEffect(() => {
4168
- if (!(querySources == null ? void 0 : querySources.length) || !store) {
4169
- return;
4170
- }
4171
- querySources.forEach((source) => {
4172
- const unsub = store.subscribeToSource(source, () => {
4173
- return queryClient.invalidateQueries({
4174
- queryKey: ["analytics", "query", query]
4175
- });
4176
- });
4177
- subscriptions.current.push(unsub);
4178
- });
4179
- return () => {
4180
- subscriptions.current.forEach((unsub) => unsub());
4181
- subscriptions.current = [];
4182
- };
4183
- }, [querySources]);
4184
- return result;
4185
- }
4186
- function useMatchingSeries(query, options) {
4187
- const result = useAnalyticsQueryWrapper({
4188
- queryKey: ["analytics", "matchingSeries", query],
4189
- queryFn: ({ store }) => store.getMatchingSeries(query),
4190
- ...options
4191
- });
4192
- return result;
4193
- }
4194
- function useQuerySources(query, options) {
4195
- const { data: matchingSeries } = useMatchingSeries(query);
4196
- return useQuery({
4197
- queryKey: ["analytics", "sources", query],
4198
- queryFn: () => {
4199
- if (!(matchingSeries == null ? void 0 : matchingSeries.length)) {
4200
- return [];
4201
- }
4202
- const uniqueSources = [
4203
- ...new Set(matchingSeries.map((s) => s.source.toString()))
4204
- ];
4205
- return uniqueSources.map((source) => AnalyticsPath.fromString(source));
4206
- },
4207
- enabled: !!matchingSeries,
4208
- ...options
4209
- });
4210
- }
4211
- const getBarSize = (value) => {
4212
- if (value <= 0)
4213
- return 0;
4214
- if (value > 0 && value <= 50)
4215
- return 1;
4216
- if (value > 50 && value <= 100)
4217
- return 2;
4218
- if (value > 100 && value <= 250)
4219
- return 3;
4220
- return 4;
4221
- };
4222
- const useTimelineItems = (documentId, startTimestamp) => {
4223
- const start = startTimestamp ? DateTime.fromISO(startTimestamp) : DateTime.now().startOf("day");
4224
- const { data: diffResult, isLoading } = useAnalyticsQuery({
4225
- start,
4226
- end: DateTime.now().endOf("day"),
4227
- granularity: AnalyticsGranularity.Hourly,
4228
- metrics: ["Count"],
4229
- select: {
4230
- changes: [AnalyticsPath.fromString(`changes`)],
4231
- document: [AnalyticsPath.fromString(`document/${documentId}`)]
4232
- },
4233
- lod: {
4234
- changes: 2
4235
- },
4236
- currency: AnalyticsPath.fromString("")
4237
- });
4238
- const mappedResult = useMemo(() => {
4239
- if (!diffResult)
4240
- return [];
4241
- return diffResult.sort((a, b) => {
4242
- const aDate = new Date(a.start);
4243
- const bDate = new Date(b.start);
4244
- return aDate.getTime() - bDate.getTime();
4245
- }).filter((result) => {
4246
- return result.rows.every((row) => row.value > 0);
4247
- }).map((result) => {
4248
- const { additions, deletions } = result.rows.reduce((acc, row) => {
4249
- if (row.dimensions.changes.path === "changes/add") {
4250
- acc.additions += row.value;
4251
- } else if (row.dimensions.changes.path === "changes/remove") {
4252
- acc.deletions += row.value;
4253
- }
4254
- return acc;
4255
- }, { additions: 0, deletions: 0 });
4256
- const startDate = new Date(result.start);
4257
- return {
4258
- id: startDate.toISOString(),
4259
- type: "bar",
4260
- addSize: getBarSize(additions),
4261
- delSize: getBarSize(deletions),
4262
- additions,
4263
- deletions,
4264
- timestamp: startDate.toISOString(),
4265
- startDate,
4266
- endDate: new Date(result.end),
4267
- revision: 0
4268
- };
4269
- });
4270
- }, [diffResult]);
4271
- const resultWithDividers = useMemo(() => {
4272
- if (!mappedResult.length)
4273
- return [];
4274
- const result = [];
4275
- mappedResult.forEach((item, index) => {
4276
- result.push(item);
4277
- if (index < mappedResult.length - 1) {
4278
- const currentDate = new Date(item.startDate);
4279
- const nextDate = new Date(mappedResult[index + 1].startDate);
4280
- const currentHour = currentDate.getHours();
4281
- const nextHour = nextDate.getHours();
4282
- const currentDay = currentDate.toDateString();
4283
- const nextDay = nextDate.toDateString();
4284
- if (currentDay !== nextDay || currentDay === nextDay && Math.abs(nextHour - currentHour) > 1) {
4285
- result.push({
4286
- id: `divider-${item.id}-${mappedResult[index + 1].id}`,
4287
- type: "divider",
4288
- revision: 0
4289
- });
4290
- }
4291
- }
4292
- });
4293
- return result;
4294
- }, [mappedResult]);
4295
- return {
4296
- isLoading,
4297
- data: resultWithDividers
4298
- };
4299
- };
4300
- const getRevisionFromDate = (startDate, endDate, operations = []) => {
4301
- if (!startDate || !endDate)
4302
- return 0;
4303
- const operation = operations.find((operation2) => {
4304
- const operationDate = new Date(operation2.timestamp);
4305
- return operationDate >= startDate && operationDate <= endDate;
4306
- });
4307
- return operation ? operation.index : 0;
4308
- };
4309
3561
  function EditorLoader(props) {
4310
3562
  const [showLoading, setShowLoading] = useState(false);
4311
3563
  useEffect(() => {
@@ -4333,11 +3585,9 @@ const DocumentEditor = (props) => {
4333
3585
  onChange,
4334
3586
  onExport,
4335
3587
  onAddOperation,
4336
- onGetDocumentRevision,
4337
3588
  onOpenSwitchboardLink
4338
3589
  } = props;
4339
3590
  const documentId = fileNodeDocument == null ? void 0 : fileNodeDocument.documentId;
4340
- const [selectedTimelineItem, setSelectedTimelineItem] = useState(null);
4341
3591
  const [revisionHistoryVisible, setRevisionHistoryVisible] = useState(false);
4342
3592
  const theme = useAtomValue(themeAtom);
4343
3593
  const user = useUser() || void 0;
@@ -4363,10 +3613,6 @@ const DocumentEditor = (props) => {
4363
3613
  [theme, user]
4364
3614
  );
4365
3615
  const userPermissions = useUserPermissions$1();
4366
- const timelineItems = useTimelineItems(
4367
- documentId,
4368
- initialDocument == null ? void 0 : initialDocument.created
4369
- );
4370
3616
  const currentDocument = useRef({ ...fileNodeDocument, document: document2 });
4371
3617
  useEffect(() => {
4372
3618
  var _a;
@@ -4543,8 +3789,7 @@ const DocumentEditor = (props) => {
4543
3789
  const {
4544
3790
  disableExternalControls,
4545
3791
  documentToolbarEnabled,
4546
- showSwitchboardLink,
4547
- timelineEnabled
3792
+ showSwitchboardLink
4548
3793
  } = editor.config || {};
4549
3794
  const handleSwitchboardLinkClick = showSwitchboardLink !== false ? onOpenSwitchboardLink : void 0;
4550
3795
  return /* @__PURE__ */ jsxs("div", { className: "relative h-full", id: "document-editor-context", children: [
@@ -4555,10 +3800,7 @@ const DocumentEditor = (props) => {
4555
3800
  onExport,
4556
3801
  onShowRevisionHistory: showRevisionHistory,
4557
3802
  title: fileNodeDocument.name || document2.name,
4558
- onSwitchboardLinkClick: handleSwitchboardLinkClick,
4559
- timelineButtonVisible: timelineEnabled,
4560
- timelineItems: timelineItems.data,
4561
- onTimelineItemClick: setSelectedTimelineItem
3803
+ onSwitchboardLinkClick: handleSwitchboardLinkClick
4562
3804
  }
4563
3805
  ),
4564
3806
  !disableExternalControls && /* @__PURE__ */ jsxs("div", { className: "mb-4 flex justify-end gap-10", children: [
@@ -4588,16 +3830,7 @@ const DocumentEditor = (props) => {
4588
3830
  EditorComponent,
4589
3831
  {
4590
3832
  error,
4591
- context: {
4592
- ...context,
4593
- getDocumentRevision: onGetDocumentRevision,
4594
- readMode: !!selectedTimelineItem,
4595
- selectedTimelineRevision: getRevisionFromDate(
4596
- selectedTimelineItem == null ? void 0 : selectedTimelineItem.startDate,
4597
- selectedTimelineItem == null ? void 0 : selectedTimelineItem.endDate,
4598
- document2.operations.global
4599
- )
4600
- },
3833
+ context,
4601
3834
  document: document2,
4602
3835
  documentNodeName: fileNodeDocument.name,
4603
3836
  dispatch,
@@ -4635,7 +3868,6 @@ function DocumentEditorContainer() {
4635
3868
  renameNode,
4636
3869
  getDocumentModelModule
4637
3870
  } = useUiNodes();
4638
- const getDocument = useGetDocument();
4639
3871
  const handleAddOperationToSelectedDocument = useCallback(
4640
3872
  async (operation) => {
4641
3873
  if (!selectedDocument) {
@@ -4698,20 +3930,6 @@ function DocumentEditorContainer() {
4698
3930
  },
4699
3931
  [getDocumentModelModule, showModal, t]
4700
3932
  );
4701
- const onGetDocumentRevision = useCallback(
4702
- (options) => {
4703
- if (!selectedNode) {
4704
- console.error("No selected node");
4705
- return Promise.reject(new Error("No selected node"));
4706
- }
4707
- return getDocument(
4708
- selectedNode.driveId,
4709
- selectedNode.id,
4710
- options
4711
- );
4712
- },
4713
- [getDocument, selectedNode]
4714
- );
4715
3933
  const onExport = useCallback(() => {
4716
3934
  if (selectedDocument) {
4717
3935
  return exportDocument(selectedDocument);
@@ -4733,7 +3951,6 @@ function DocumentEditorContainer() {
4733
3951
  onChange: onDocumentChangeHandler,
4734
3952
  onClose,
4735
3953
  onExport,
4736
- onGetDocumentRevision,
4737
3954
  onAddOperation: handleAddOperationToSelectedDocument,
4738
3955
  onOpenSwitchboardLink
4739
3956
  }
@@ -4742,6 +3959,165 @@ function DocumentEditorContainer() {
4742
3959
  fileNodeDocument.documentId
4743
3960
  );
4744
3961
  }
3962
+ function getDocumentSpec(doc) {
3963
+ if ("documentModelState" in doc) {
3964
+ return doc.documentModelState;
3965
+ }
3966
+ return doc.documentModel;
3967
+ }
3968
+ const CreateDocument = ({ documentModels, createDocument }) => {
3969
+ return jsxs("div", { className: "px-6", children: [jsx("h3", { className: "mb-3 mt-4 text-xl font-bold text-gray-600", children: "New document" }), jsx("div", { className: "flex w-full flex-wrap gap-4", children: documentModels == null ? void 0 : documentModels.map((doc) => {
3970
+ const spec = getDocumentSpec(doc);
3971
+ return jsx(Button, { color: "light", "aria-details": spec.description, onClick: () => createDocument(doc), children: jsx("span", { className: "text-sm", children: spec.name }) }, spec.id);
3972
+ }) })] });
3973
+ };
3974
+ function sortUiNodesByName(a, b) {
3975
+ return a.name.localeCompare(b.name);
3976
+ }
3977
+ const GAP = 8;
3978
+ const ITEM_WIDTH = 256;
3979
+ const ITEM_HEIGHT = 48;
3980
+ const USED_SPACE = 420;
3981
+ function FileContentView(props) {
3982
+ const parentRef = useRef(null);
3983
+ const { t } = useTranslation();
3984
+ const windowSize = useWindowSize();
3985
+ const { fileNodes, ...fileProps } = props;
3986
+ const availableWidth = windowSize.innerWidth - USED_SPACE;
3987
+ const columnCount = Math.floor(availableWidth / (ITEM_WIDTH + GAP)) || 1;
3988
+ const rowCount = Math.ceil(fileNodes.length / columnCount);
3989
+ const rowVirtualizer = useVirtualizer({
3990
+ count: rowCount,
3991
+ getScrollElement: () => parentRef.current,
3992
+ estimateSize: (index) => {
3993
+ if (index > 0) {
3994
+ return ITEM_HEIGHT + GAP;
3995
+ }
3996
+ return ITEM_HEIGHT;
3997
+ },
3998
+ overscan: 5
3999
+ });
4000
+ const columnVirtualizer = useVirtualizer({
4001
+ horizontal: true,
4002
+ count: columnCount,
4003
+ getScrollElement: () => parentRef.current,
4004
+ estimateSize: (index) => {
4005
+ if (index > 0) {
4006
+ return ITEM_WIDTH + GAP;
4007
+ }
4008
+ return ITEM_WIDTH;
4009
+ },
4010
+ overscan: 5
4011
+ });
4012
+ const getItemIndex = (rowIndex, columnIndex) => rowIndex * columnCount + columnIndex;
4013
+ const getItem = (rowIndex, columnIndex) => {
4014
+ const index = getItemIndex(rowIndex, columnIndex);
4015
+ return fileNodes[index] || null;
4016
+ };
4017
+ if (fileNodes.length === 0) {
4018
+ return jsx("div", { className: "mb-8 text-sm text-gray-400", children: t("folderView.sections.documents.empty", {
4019
+ defaultValue: "No documents or files 📄"
4020
+ }) });
4021
+ }
4022
+ const renderItem = (rowIndex, columnIndex) => {
4023
+ const fileNode = getItem(rowIndex, columnIndex);
4024
+ if (!fileNode) {
4025
+ return null;
4026
+ }
4027
+ return jsx("div", { style: {
4028
+ marginLeft: columnIndex === 0 ? 0 : GAP
4029
+ }, children: jsx(FileItem, { uiNode: fileNode, ...fileProps }, fileNode.id) });
4030
+ };
4031
+ return jsx("div", { ref: parentRef, style: {
4032
+ height: `400px`,
4033
+ width: `100%`,
4034
+ overflow: "auto"
4035
+ }, children: jsx("div", { style: {
4036
+ height: `${rowVirtualizer.getTotalSize()}px`,
4037
+ width: `${columnVirtualizer.getTotalSize()}px`,
4038
+ position: "relative"
4039
+ }, children: rowVirtualizer.getVirtualItems().map((virtualRow) => jsx(React__default.Fragment, { children: columnVirtualizer.getVirtualItems().map((virtualColumn) => jsx("div", { style: {
4040
+ position: "absolute",
4041
+ top: 0,
4042
+ left: 0,
4043
+ marginTop: virtualRow.index === 0 ? 0 : GAP,
4044
+ width: `${virtualColumn.size}px`,
4045
+ height: `${virtualRow.size}px`,
4046
+ transform: `translateX(${virtualColumn.start}px) translateY(${virtualRow.start}px)`
4047
+ }, children: renderItem(virtualRow.index, virtualColumn.index) }, virtualColumn.key)) }, virtualRow.key)) }) });
4048
+ }
4049
+ function FolderView(props) {
4050
+ const { node, className, isDropTarget, containerProps, ...nodeProps } = props;
4051
+ const { t } = useTranslation();
4052
+ const folderNodes = node.children.filter((node2) => node2.kind === FOLDER).sort(sortUiNodesByName);
4053
+ const fileNodes = node.children.filter((node2) => node2.kind === FILE).sort(sortUiNodesByName);
4054
+ const folderCallbacks = {
4055
+ onSelectNode: (node2) => nodeProps.onSelectNode(node2),
4056
+ onRenameNode: (name, node2) => nodeProps.onRenameNode(name, node2),
4057
+ onDuplicateNode: (node2) => nodeProps.onDuplicateNode(node2),
4058
+ onDeleteNode: (node2) => nodeProps.onDeleteNode(node2)
4059
+ };
4060
+ const fileCallbacks = {
4061
+ onSelectNode: (node2) => nodeProps.onSelectNode(node2),
4062
+ onRenameNode: (name, node2) => nodeProps.onRenameNode(name, node2),
4063
+ onDuplicateNode: (node2) => nodeProps.onDuplicateNode(node2),
4064
+ onDeleteNode: (node2) => nodeProps.onDeleteNode(node2)
4065
+ };
4066
+ const baseNodeCallbacks = {
4067
+ onAddFile: async (file, parentNode) => {
4068
+ await nodeProps.onAddFile(file, parentNode);
4069
+ },
4070
+ onCopyNode: async (uiNode, targetNode) => {
4071
+ await nodeProps.onCopyNode(uiNode, targetNode);
4072
+ },
4073
+ onMoveNode: async (uiNode, targetNode) => {
4074
+ await nodeProps.onMoveNode(uiNode, targetNode);
4075
+ }
4076
+ };
4077
+ return jsxs("div", { className: twMerge("rounded-md border-2 border-transparent p-2", isDropTarget && "border-dashed border-blue-100", className), ...containerProps, children: [jsx(DriveLayout.ContentSection, { title: t("folderView.sections.folders.title", {
4078
+ defaultValue: "Folders"
4079
+ }), className: "mb-4", children: folderNodes.length > 0 ? folderNodes.map((folderNode) => jsx(FolderItem, { uiNode: folderNode, ...baseNodeCallbacks, ...folderCallbacks, isAllowedToCreateDocuments: nodeProps.isAllowedToCreateDocuments }, folderNode.id)) : jsx("div", { className: "mb-8 text-sm text-gray-400", children: t("folderView.sections.folders.empty", {
4080
+ defaultValue: "No documents or files 📄"
4081
+ }) }) }), jsx(DriveLayout.ContentSection, { title: t("folderView.sections.documents.title", {
4082
+ defaultValue: "Documents and files"
4083
+ }), children: jsx("div", { className: twMerge("w-full", fileNodes.length > 0 ? "min-h-[400px]" : "min-h-14"), children: jsx(FileContentView, { fileNodes, ...fileCallbacks, isAllowedToCreateDocuments: nodeProps.isAllowedToCreateDocuments }) }) })] });
4084
+ }
4085
+ function BaseEditor(props) {
4086
+ const { document: document2, dispatch, className, children } = props;
4087
+ const { state: { global: { id: driveId } } } = document2;
4088
+ const { showSearchBar, isAllowedToCreateDocuments, documentModels, showCreateDocumentModal } = useDriveContext();
4089
+ const { driveNodes, selectedNode, selectedNodePath, getNodeById, setSelectedNode } = useUiNodesContext();
4090
+ const driveNode = useMemo(() => driveNodes.find((n) => n.id === driveId), [driveNodes, driveId]);
4091
+ const { addDocument, addFile, addFolder: addFolder2, renameNode, deleteNode: deleteNode2, moveNode: moveNode2, copyNode: copyNode2, duplicateNode } = useDriveActionsWithUiNodes(document2, dispatch);
4092
+ const onCreateDocument = useCallback(async (documentModel) => {
4093
+ const { name } = await showCreateDocumentModal(documentModel);
4094
+ const document3 = documentModel.utils.createDocument();
4095
+ await addDocument(name, documentModel.documentModel.name, document3, selectedNode == null ? void 0 : selectedNode.id);
4096
+ }, [addDocument, showCreateDocumentModal, selectedNode == null ? void 0 : selectedNode.id]);
4097
+ const { isDropTarget, dropProps } = useDrop({
4098
+ uiNode: selectedNode,
4099
+ onAddFile: addFile,
4100
+ onCopyNode: copyNode2,
4101
+ onMoveNode: moveNode2
4102
+ });
4103
+ const { breadcrumbs, onBreadcrumbSelected } = useBreadcrumbs({
4104
+ selectedNodePath,
4105
+ getNodeById,
4106
+ setSelectedNode
4107
+ });
4108
+ if (!driveNode) {
4109
+ return jsx("div", { children: "Drive not found" });
4110
+ } else if ((selectedNode == null ? void 0 : selectedNode.kind) === FILE$1) {
4111
+ return jsx(Fragment$1, {});
4112
+ }
4113
+ return jsxs(DriveLayout, { className, children: [children, jsxs(DriveLayout.Header, { children: [jsx(Breadcrumbs, { breadcrumbs, createEnabled: isAllowedToCreateDocuments, onCreate: addFolder2, onBreadcrumbSelected }), showSearchBar && jsx(SearchBar, {})] }), jsx(DriveLayout.Content, { children: jsx(FolderView, { node: selectedNode || driveNode, onSelectNode: setSelectedNode, onRenameNode: renameNode, onDuplicateNode: duplicateNode, onDeleteNode: deleteNode2, onAddFile: addFile, onCopyNode: copyNode2, onMoveNode: moveNode2, isDropTarget, isAllowedToCreateDocuments }) }), jsx(DriveLayout.Footer, { children: isAllowedToCreateDocuments && jsx(CreateDocument, { documentModels, createDocument: onCreateDocument }) })] });
4114
+ }
4115
+ function Editor(props) {
4116
+ return jsx(DriveContextProvider, { value: props.context, children: jsx(BaseEditor, { ...props }) });
4117
+ }
4118
+ const GenericDriveExplorer = {
4119
+ Component: Editor
4120
+ };
4745
4121
  function useDocumentsState(args) {
4746
4122
  const { reactor, driveId, documentIds, options } = args;
4747
4123
  const [statesByDocumentId, setStatesByDocumentId] = useState({});
@@ -4928,19 +4304,8 @@ function DriveEditorContainer() {
4928
4304
  const { addFile, addDocument } = useDocumentDriveServer();
4929
4305
  const documentModels = useFilteredDocumentModels();
4930
4306
  const useDriveDocumentState = makeDriveDocumentStateHook(reactor);
4931
- const getDocument = useGetDocument();
4932
4307
  const getDocumentModelModule = useGetDocumentModelModule();
4933
4308
  const getEditor = useGetEditor();
4934
- const onGetDocumentRevision = useCallback(
4935
- (documentId, options) => {
4936
- if (!selectedNode) {
4937
- console.error("No selected node");
4938
- return Promise.reject(new Error("No selected node"));
4939
- }
4940
- return getDocument(selectedNode.driveId, documentId, options);
4941
- },
4942
- [getDocument, selectedNode]
4943
- );
4944
4309
  const driveContext = useMemo(
4945
4310
  () => ({
4946
4311
  showSearchBar: false,
@@ -4984,8 +4349,6 @@ function DriveEditorContainer() {
4984
4349
  context: {
4985
4350
  ...editorProps.context,
4986
4351
  ...driveContext,
4987
- analyticsDatabaseName: connectConfig.analyticsDatabaseName,
4988
- getDocumentRevision: onGetDocumentRevision,
4989
4352
  getDocumentModelModule,
4990
4353
  getEditor
4991
4354
  },
@@ -5021,7 +4384,7 @@ function Content() {
5021
4384
  }, [selectedDriveNode, selectedNode, addFile]);
5022
4385
  useEffect(() => {
5023
4386
  if ((status === "LOADED" || status === "ERROR") && !documentDrives.find(
5024
- (d) => d.id === driveId || d.slug === driveId || d.state.global.name === driveId
4387
+ (d) => d.state.global.id === driveId || d.state.global.slug === driveId || d.state.global.name === driveId
5025
4388
  )) {
5026
4389
  toast(/* @__PURE__ */ jsxs("p", { children: [
5027
4390
  "Drive ",
@@ -5036,4 +4399,3 @@ function Content() {
5036
4399
  export {
5037
4400
  Content as default
5038
4401
  };
5039
- //# sourceMappingURL=content-2lJzkjLx.js.map