@powerhousedao/connect 1.0.24-dev.0 → 1.1.1
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.
- package/dist/.env +1 -1
- package/dist/assets/{app-B5yYl0zv.js → app-CZSKsD-w.js} +11239 -12745
- package/dist/assets/{app-DWlDE8AF.css → app-W_mH4m8_.css} +182 -241
- package/dist/assets/{app-loader-NDVZu4bS.css → app-loader-4GyeoNTc.css} +229 -239
- package/dist/assets/{app-loader-CmEZOj3m.js → app-loader-CyUyHxMC.js} +436 -745
- package/dist/assets/{ccip-KtRjx9vh.js → ccip-BPO0EeBI.js} +8 -6
- package/dist/assets/{content-2lJzkjLx.js → content-fzZoyU8t.js} +466 -1103
- package/dist/assets/{index-BVVRVlZN.js → index-C3PlmBGF.js} +3 -4
- package/dist/assets/{index-dSMCpjcQ.js → index-DFiZ2Eug.js} +171 -23
- package/dist/assets/{index-BhHOiwFw.js → index-D_CfC9G5.js} +3702 -3517
- package/dist/assets/{main.DA6nl4Ov.js → main.8RNzWcZO.js} +12 -3
- package/dist/assets/{style-CdxGKc2g.css → style-U7Kx3_hE.css} +95 -39
- package/dist/external-packages.js +0 -1
- package/dist/hmr.js +0 -1
- package/dist/index.html +1 -1
- package/dist/service-worker.js +0 -1
- package/dist/vite-envs.sh +1 -1
- package/package.json +20 -21
- package/dist/assets/app-B5yYl0zv.js.map +0 -1
- package/dist/assets/app-loader-CmEZOj3m.js.map +0 -1
- package/dist/assets/browser-D5LEpLBa.js +0 -27224
- package/dist/assets/browser-D5LEpLBa.js.map +0 -1
- package/dist/assets/ccip-KtRjx9vh.js.map +0 -1
- package/dist/assets/content-2lJzkjLx.js.map +0 -1
- package/dist/assets/index-BVVRVlZN.js.map +0 -1
- package/dist/assets/index-BhHOiwFw.js.map +0 -1
- package/dist/assets/index-DZiF5od7.js +0 -208
- package/dist/assets/index-DZiF5od7.js.map +0 -1
- package/dist/assets/index-dSMCpjcQ.js.map +0 -1
- package/dist/assets/main.DA6nl4Ov.js.map +0 -1
- package/dist/assets/reactor-analytics-CF_JKt8H.js +0 -42
- package/dist/assets/reactor-analytics-CF_JKt8H.js.map +0 -1
- package/dist/assets/router-Ch1WZD-6.js +0 -1585
- package/dist/assets/router-Ch1WZD-6.js.map +0 -1
- package/dist/external-packages.js.map +0 -1
- package/dist/hmr.js.map +0 -1
- 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,
|
|
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-CZSKsD-w.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 {
|
|
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-CyUyHxMC.js";
|
|
7
6
|
import { flushSync } from "react-dom";
|
|
8
|
-
import "./main.
|
|
7
|
+
import "./main.8RNzWcZO.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
|
-
|
|
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
|
|
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
|
|
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
|
|
1723
|
-
const
|
|
1724
|
-
const
|
|
1725
|
-
const
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
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
|
|
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
|
|
1926
|
-
|
|
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
|
|
1929
|
-
|
|
1930
|
-
const
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
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
|
|
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
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
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
|
|
1968
|
-
|
|
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
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
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) {
|
|
@@ -2324,7 +1874,7 @@ function notUndefined(value, msg) {
|
|
|
2324
1874
|
return value;
|
|
2325
1875
|
}
|
|
2326
1876
|
}
|
|
2327
|
-
const approxEqual = (a, b) => Math.abs(a - b)
|
|
1877
|
+
const approxEqual = (a, b) => Math.abs(a - b) <= 1;
|
|
2328
1878
|
const debounce = (targetWindow, fn, ms) => {
|
|
2329
1879
|
let timeoutId;
|
|
2330
1880
|
return function(...args) {
|
|
@@ -2332,6 +1882,10 @@ const debounce = (targetWindow, fn, ms) => {
|
|
|
2332
1882
|
timeoutId = targetWindow.setTimeout(() => fn.apply(this, args), ms);
|
|
2333
1883
|
};
|
|
2334
1884
|
};
|
|
1885
|
+
const getRect = (element) => {
|
|
1886
|
+
const { offsetWidth, offsetHeight } = element;
|
|
1887
|
+
return { width: offsetWidth, height: offsetHeight };
|
|
1888
|
+
};
|
|
2335
1889
|
const defaultKeyExtractor = (index) => index;
|
|
2336
1890
|
const defaultRangeExtractor = (range) => {
|
|
2337
1891
|
const start = Math.max(range.startIndex - range.overscan, 0);
|
|
@@ -2355,21 +1909,24 @@ const observeElementRect = (instance, cb) => {
|
|
|
2355
1909
|
const { width, height } = rect;
|
|
2356
1910
|
cb({ width: Math.round(width), height: Math.round(height) });
|
|
2357
1911
|
};
|
|
2358
|
-
handler(element
|
|
1912
|
+
handler(getRect(element));
|
|
2359
1913
|
if (!targetWindow.ResizeObserver) {
|
|
2360
1914
|
return () => {
|
|
2361
1915
|
};
|
|
2362
1916
|
}
|
|
2363
1917
|
const observer = new targetWindow.ResizeObserver((entries) => {
|
|
2364
|
-
const
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
1918
|
+
const run = () => {
|
|
1919
|
+
const entry = entries[0];
|
|
1920
|
+
if (entry == null ? void 0 : entry.borderBoxSize) {
|
|
1921
|
+
const box = entry.borderBoxSize[0];
|
|
1922
|
+
if (box) {
|
|
1923
|
+
handler({ width: box.inlineSize, height: box.blockSize });
|
|
1924
|
+
return;
|
|
1925
|
+
}
|
|
2370
1926
|
}
|
|
2371
|
-
|
|
2372
|
-
|
|
1927
|
+
handler(getRect(element));
|
|
1928
|
+
};
|
|
1929
|
+
instance.options.useAnimationFrameWithResizeObserver ? requestAnimationFrame(run) : run();
|
|
2373
1930
|
});
|
|
2374
1931
|
observer.observe(element, { box: "border-box" });
|
|
2375
1932
|
return () => {
|
|
@@ -2407,10 +1964,15 @@ const observeElementOffset = (instance, cb) => {
|
|
|
2407
1964
|
const endHandler = createHandler(false);
|
|
2408
1965
|
endHandler();
|
|
2409
1966
|
element.addEventListener("scroll", handler, addEventListenerOptions);
|
|
2410
|
-
|
|
1967
|
+
const registerScrollendEvent = instance.options.useScrollendEvent && supportsScrollend;
|
|
1968
|
+
if (registerScrollendEvent) {
|
|
1969
|
+
element.addEventListener("scrollend", endHandler, addEventListenerOptions);
|
|
1970
|
+
}
|
|
2411
1971
|
return () => {
|
|
2412
1972
|
element.removeEventListener("scroll", handler);
|
|
2413
|
-
|
|
1973
|
+
if (registerScrollendEvent) {
|
|
1974
|
+
element.removeEventListener("scrollend", endHandler);
|
|
1975
|
+
}
|
|
2414
1976
|
};
|
|
2415
1977
|
};
|
|
2416
1978
|
const measureElement = (element, entry, instance) => {
|
|
@@ -2423,9 +1985,7 @@ const measureElement = (element, entry, instance) => {
|
|
|
2423
1985
|
return size;
|
|
2424
1986
|
}
|
|
2425
1987
|
}
|
|
2426
|
-
return
|
|
2427
|
-
element.getBoundingClientRect()[instance.options.horizontal ? "width" : "height"]
|
|
2428
|
-
);
|
|
1988
|
+
return element[instance.options.horizontal ? "offsetWidth" : "offsetHeight"];
|
|
2429
1989
|
};
|
|
2430
1990
|
const elementScroll = (offset, {
|
|
2431
1991
|
adjustments = 0,
|
|
@@ -2464,7 +2024,10 @@ class Virtualizer {
|
|
|
2464
2024
|
}
|
|
2465
2025
|
return _ro = new this.targetWindow.ResizeObserver((entries) => {
|
|
2466
2026
|
entries.forEach((entry) => {
|
|
2467
|
-
|
|
2027
|
+
const run = () => {
|
|
2028
|
+
this._measureElement(entry.target, entry);
|
|
2029
|
+
};
|
|
2030
|
+
this.options.useAnimationFrameWithResizeObserver ? requestAnimationFrame(run) : run();
|
|
2468
2031
|
});
|
|
2469
2032
|
});
|
|
2470
2033
|
};
|
|
@@ -2512,7 +2075,8 @@ class Virtualizer {
|
|
|
2512
2075
|
isScrollingResetDelay: 150,
|
|
2513
2076
|
enabled: true,
|
|
2514
2077
|
isRtl: false,
|
|
2515
|
-
useScrollendEvent:
|
|
2078
|
+
useScrollendEvent: false,
|
|
2079
|
+
useAnimationFrameWithResizeObserver: false,
|
|
2516
2080
|
...opts2
|
|
2517
2081
|
};
|
|
2518
2082
|
};
|
|
@@ -2701,12 +2265,18 @@ class Virtualizer {
|
|
|
2701
2265
|
}
|
|
2702
2266
|
);
|
|
2703
2267
|
this.calculateRange = memo(
|
|
2704
|
-
() => [
|
|
2705
|
-
|
|
2268
|
+
() => [
|
|
2269
|
+
this.getMeasurements(),
|
|
2270
|
+
this.getSize(),
|
|
2271
|
+
this.getScrollOffset(),
|
|
2272
|
+
this.options.lanes
|
|
2273
|
+
],
|
|
2274
|
+
(measurements, outerSize, scrollOffset, lanes) => {
|
|
2706
2275
|
return this.range = measurements.length > 0 && outerSize > 0 ? calculateRange({
|
|
2707
2276
|
measurements,
|
|
2708
2277
|
outerSize,
|
|
2709
|
-
scrollOffset
|
|
2278
|
+
scrollOffset,
|
|
2279
|
+
lanes
|
|
2710
2280
|
}) : null;
|
|
2711
2281
|
},
|
|
2712
2282
|
{
|
|
@@ -2714,7 +2284,7 @@ class Virtualizer {
|
|
|
2714
2284
|
debug: () => this.options.debug
|
|
2715
2285
|
}
|
|
2716
2286
|
);
|
|
2717
|
-
this.
|
|
2287
|
+
this.getVirtualIndexes = memo(
|
|
2718
2288
|
() => {
|
|
2719
2289
|
let startIndex = null;
|
|
2720
2290
|
let endIndex = null;
|
|
@@ -2723,6 +2293,7 @@ class Virtualizer {
|
|
|
2723
2293
|
startIndex = range.startIndex;
|
|
2724
2294
|
endIndex = range.endIndex;
|
|
2725
2295
|
}
|
|
2296
|
+
this.maybeNotify.updateDeps([this.isScrolling, startIndex, endIndex]);
|
|
2726
2297
|
return [
|
|
2727
2298
|
this.options.rangeExtractor,
|
|
2728
2299
|
this.options.overscan,
|
|
@@ -2806,7 +2377,7 @@ class Virtualizer {
|
|
|
2806
2377
|
this._measureElement(node, void 0);
|
|
2807
2378
|
};
|
|
2808
2379
|
this.getVirtualItems = memo(
|
|
2809
|
-
() => [this.
|
|
2380
|
+
() => [this.getVirtualIndexes(), this.getMeasurements()],
|
|
2810
2381
|
(indexes, measurements) => {
|
|
2811
2382
|
const virtualItems = [];
|
|
2812
2383
|
for (let k = 0, len = indexes.length; k < len; k++) {
|
|
@@ -2835,20 +2406,18 @@ class Virtualizer {
|
|
|
2835
2406
|
)]
|
|
2836
2407
|
);
|
|
2837
2408
|
};
|
|
2838
|
-
this.getOffsetForAlignment = (toOffset, align) => {
|
|
2409
|
+
this.getOffsetForAlignment = (toOffset, align, itemSize = 0) => {
|
|
2839
2410
|
const size = this.getSize();
|
|
2840
2411
|
const scrollOffset = this.getScrollOffset();
|
|
2841
2412
|
if (align === "auto") {
|
|
2842
|
-
|
|
2843
|
-
align = "end";
|
|
2844
|
-
}
|
|
2413
|
+
align = toOffset >= scrollOffset + size ? "end" : "start";
|
|
2845
2414
|
}
|
|
2846
|
-
if (align === "
|
|
2415
|
+
if (align === "center") {
|
|
2416
|
+
toOffset += (itemSize - size) / 2;
|
|
2417
|
+
} else if (align === "end") {
|
|
2847
2418
|
toOffset -= size;
|
|
2848
2419
|
}
|
|
2849
|
-
const
|
|
2850
|
-
const scrollSize = this.scrollElement ? "document" in this.scrollElement ? this.scrollElement.document.documentElement[scrollSizeProp] : this.scrollElement[scrollSizeProp] : 0;
|
|
2851
|
-
const maxOffset = scrollSize - size;
|
|
2420
|
+
const maxOffset = this.getTotalSize() - size;
|
|
2852
2421
|
return Math.max(Math.min(maxOffset, toOffset), 0);
|
|
2853
2422
|
};
|
|
2854
2423
|
this.getOffsetForIndex = (index, align = "auto") => {
|
|
@@ -2868,27 +2437,11 @@ class Virtualizer {
|
|
|
2868
2437
|
return [scrollOffset, align];
|
|
2869
2438
|
}
|
|
2870
2439
|
}
|
|
2871
|
-
const
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
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 = () => {
|
|
@@ -2931,7 +2484,8 @@ class Virtualizer {
|
|
|
2931
2484
|
const [latestOffset] = notUndefined(
|
|
2932
2485
|
this.getOffsetForIndex(index, align)
|
|
2933
2486
|
);
|
|
2934
|
-
|
|
2487
|
+
const currentScrollOffset = this.getScrollOffset();
|
|
2488
|
+
if (!approxEqual(latestOffset, currentScrollOffset)) {
|
|
2935
2489
|
this.scrollToIndex(index, { align, behavior });
|
|
2936
2490
|
}
|
|
2937
2491
|
} else {
|
|
@@ -2958,10 +2512,19 @@ class Virtualizer {
|
|
|
2958
2512
|
let end;
|
|
2959
2513
|
if (measurements.length === 0) {
|
|
2960
2514
|
end = this.options.paddingStart;
|
|
2515
|
+
} else if (this.options.lanes === 1) {
|
|
2516
|
+
end = ((_a = measurements[measurements.length - 1]) == null ? void 0 : _a.end) ?? 0;
|
|
2961
2517
|
} else {
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
)
|
|
2518
|
+
const endByLane = Array(this.options.lanes).fill(null);
|
|
2519
|
+
let endIndex = measurements.length - 1;
|
|
2520
|
+
while (endIndex >= 0 && endByLane.some((val) => val === null)) {
|
|
2521
|
+
const item = measurements[endIndex];
|
|
2522
|
+
if (endByLane[item.lane] === null) {
|
|
2523
|
+
endByLane[item.lane] = item.end;
|
|
2524
|
+
}
|
|
2525
|
+
endIndex--;
|
|
2526
|
+
}
|
|
2527
|
+
end = Math.max(...endByLane.filter((val) => val !== null));
|
|
2965
2528
|
}
|
|
2966
2529
|
return Math.max(
|
|
2967
2530
|
end - this.options.scrollMargin + this.options.paddingEnd,
|
|
@@ -3002,14 +2565,43 @@ const findNearestBinarySearch = (low, high, getCurrentValue, value) => {
|
|
|
3002
2565
|
function calculateRange({
|
|
3003
2566
|
measurements,
|
|
3004
2567
|
outerSize,
|
|
3005
|
-
scrollOffset
|
|
2568
|
+
scrollOffset,
|
|
2569
|
+
lanes
|
|
3006
2570
|
}) {
|
|
3007
|
-
const
|
|
2571
|
+
const lastIndex = measurements.length - 1;
|
|
3008
2572
|
const getOffset = (index) => measurements[index].start;
|
|
3009
|
-
|
|
2573
|
+
if (measurements.length <= lanes) {
|
|
2574
|
+
return {
|
|
2575
|
+
startIndex: 0,
|
|
2576
|
+
endIndex: lastIndex
|
|
2577
|
+
};
|
|
2578
|
+
}
|
|
2579
|
+
let startIndex = findNearestBinarySearch(
|
|
2580
|
+
0,
|
|
2581
|
+
lastIndex,
|
|
2582
|
+
getOffset,
|
|
2583
|
+
scrollOffset
|
|
2584
|
+
);
|
|
3010
2585
|
let endIndex = startIndex;
|
|
3011
|
-
|
|
3012
|
-
endIndex
|
|
2586
|
+
if (lanes === 1) {
|
|
2587
|
+
while (endIndex < lastIndex && measurements[endIndex].end < scrollOffset + outerSize) {
|
|
2588
|
+
endIndex++;
|
|
2589
|
+
}
|
|
2590
|
+
} else if (lanes > 1) {
|
|
2591
|
+
const endPerLane = Array(lanes).fill(0);
|
|
2592
|
+
while (endIndex < lastIndex && endPerLane.some((pos) => pos < scrollOffset + outerSize)) {
|
|
2593
|
+
const item = measurements[endIndex];
|
|
2594
|
+
endPerLane[item.lane] = item.end;
|
|
2595
|
+
endIndex++;
|
|
2596
|
+
}
|
|
2597
|
+
const startPerLane = Array(lanes).fill(scrollOffset + outerSize);
|
|
2598
|
+
while (startIndex >= 0 && startPerLane.some((pos) => pos >= scrollOffset)) {
|
|
2599
|
+
const item = measurements[startIndex];
|
|
2600
|
+
startPerLane[item.lane] = item.start;
|
|
2601
|
+
startIndex--;
|
|
2602
|
+
}
|
|
2603
|
+
startIndex = Math.max(0, startIndex - startIndex % lanes);
|
|
2604
|
+
endIndex = Math.min(lastIndex, endIndex + (lanes - 1 - endIndex % lanes));
|
|
3013
2605
|
}
|
|
3014
2606
|
return { startIndex, endIndex };
|
|
3015
2607
|
}
|
|
@@ -3266,8 +2858,8 @@ function RevisionHistory(props) {
|
|
|
3266
2858
|
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
2859
|
}
|
|
3268
2860
|
function Tooltip(props) {
|
|
3269
|
-
const { children, content, open, defaultOpen, onOpenChange, className,
|
|
3270
|
-
return jsxs(Root3, { defaultOpen, delayDuration: 0, onOpenChange, open, children: [jsx(Trigger, { asChild: true, children }), jsx(Portal, { children: jsx(Content2, { ...rest,
|
|
2861
|
+
const { children, content, open, defaultOpen, onOpenChange, className, ...rest } = props;
|
|
2862
|
+
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
2863
|
}
|
|
3272
2864
|
const TooltipProvider = Provider;
|
|
3273
2865
|
const BUDGET = "powerhouse/budget-statement";
|
|
@@ -3515,7 +3107,9 @@ function useAddDebouncedOperations(reactor, props) {
|
|
|
3515
3107
|
const { driveId, documentId } = props;
|
|
3516
3108
|
const [documentDrives] = useDocumentDrives(reactor);
|
|
3517
3109
|
const documentDrivesRef = useRef(documentDrives);
|
|
3518
|
-
const { isAllowedToEditDocuments } = useUserPermissions()
|
|
3110
|
+
const { isAllowedToEditDocuments } = useUserPermissions() || {
|
|
3111
|
+
isAllowedToEditDocuments: false
|
|
3112
|
+
};
|
|
3519
3113
|
useEffect(() => {
|
|
3520
3114
|
documentDrivesRef.current = documentDrives;
|
|
3521
3115
|
}, [documentDrives]);
|
|
@@ -3526,7 +3120,7 @@ function useAddDebouncedOperations(reactor, props) {
|
|
|
3526
3120
|
if (!reactor) {
|
|
3527
3121
|
throw new Error("Reactor is not loaded");
|
|
3528
3122
|
}
|
|
3529
|
-
const drive = documentDrivesRef.current.find((drive2) => drive2.id === driveId2);
|
|
3123
|
+
const drive = documentDrivesRef.current.find((drive2) => drive2.state.global.id === driveId2);
|
|
3530
3124
|
if (!drive) {
|
|
3531
3125
|
throw new Error(`Drive with id ${driveId2} not found`);
|
|
3532
3126
|
}
|
|
@@ -3605,7 +3199,7 @@ function getNode(id, drive) {
|
|
|
3605
3199
|
}
|
|
3606
3200
|
function createDriveActions(document2, dispatch, context) {
|
|
3607
3201
|
const drive = document2;
|
|
3608
|
-
const driveId = drive.
|
|
3202
|
+
const { id: driveId } = drive.state.global;
|
|
3609
3203
|
const { selectedNode } = context;
|
|
3610
3204
|
const handleAddFolder = async (name, parentFolder, id = generateId()) => {
|
|
3611
3205
|
dispatch(addFolder({
|
|
@@ -3895,17 +3489,6 @@ function useEditorProps(document2, node, documentDispatch, onAddOperation) {
|
|
|
3895
3489
|
isAllowedToEditDocuments: (userPermissions == null ? void 0 : userPermissions.isAllowedToEditDocuments) ?? false
|
|
3896
3490
|
};
|
|
3897
3491
|
}
|
|
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
3492
|
function useSyncStatus(driveId, documentId) {
|
|
3910
3493
|
const { getSyncStatusSync, onSyncStatus, documentDrives } = useDocumentDriveServer();
|
|
3911
3494
|
const syncStatus = useSyncExternalStore(
|
|
@@ -3915,7 +3498,9 @@ function useSyncStatus(driveId, documentId) {
|
|
|
3915
3498
|
},
|
|
3916
3499
|
() => {
|
|
3917
3500
|
var _a;
|
|
3918
|
-
const drive = documentDrives.find(
|
|
3501
|
+
const drive = documentDrives.find(
|
|
3502
|
+
(_drive) => _drive.state.global.id === driveId
|
|
3503
|
+
);
|
|
3919
3504
|
if (!drive) return;
|
|
3920
3505
|
const isReadDrive = "readContext" in drive;
|
|
3921
3506
|
const _sharingType = !isReadDrive ? (_a = drive.state.local.sharingType) == null ? void 0 : _a.toUpperCase() : "PUBLIC";
|
|
@@ -3974,338 +3559,6 @@ const useUndoRedoShortcuts = (props) => {
|
|
|
3974
3559
|
[canRedo, redo2]
|
|
3975
3560
|
);
|
|
3976
3561
|
};
|
|
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
3562
|
function EditorLoader(props) {
|
|
4310
3563
|
const [showLoading, setShowLoading] = useState(false);
|
|
4311
3564
|
useEffect(() => {
|
|
@@ -4333,11 +3586,9 @@ const DocumentEditor = (props) => {
|
|
|
4333
3586
|
onChange,
|
|
4334
3587
|
onExport,
|
|
4335
3588
|
onAddOperation,
|
|
4336
|
-
onGetDocumentRevision,
|
|
4337
3589
|
onOpenSwitchboardLink
|
|
4338
3590
|
} = props;
|
|
4339
3591
|
const documentId = fileNodeDocument == null ? void 0 : fileNodeDocument.documentId;
|
|
4340
|
-
const [selectedTimelineItem, setSelectedTimelineItem] = useState(null);
|
|
4341
3592
|
const [revisionHistoryVisible, setRevisionHistoryVisible] = useState(false);
|
|
4342
3593
|
const theme = useAtomValue(themeAtom);
|
|
4343
3594
|
const user = useUser() || void 0;
|
|
@@ -4363,10 +3614,6 @@ const DocumentEditor = (props) => {
|
|
|
4363
3614
|
[theme, user]
|
|
4364
3615
|
);
|
|
4365
3616
|
const userPermissions = useUserPermissions$1();
|
|
4366
|
-
const timelineItems = useTimelineItems(
|
|
4367
|
-
documentId,
|
|
4368
|
-
initialDocument == null ? void 0 : initialDocument.created
|
|
4369
|
-
);
|
|
4370
3617
|
const currentDocument = useRef({ ...fileNodeDocument, document: document2 });
|
|
4371
3618
|
useEffect(() => {
|
|
4372
3619
|
var _a;
|
|
@@ -4543,8 +3790,7 @@ const DocumentEditor = (props) => {
|
|
|
4543
3790
|
const {
|
|
4544
3791
|
disableExternalControls,
|
|
4545
3792
|
documentToolbarEnabled,
|
|
4546
|
-
showSwitchboardLink
|
|
4547
|
-
timelineEnabled
|
|
3793
|
+
showSwitchboardLink
|
|
4548
3794
|
} = editor.config || {};
|
|
4549
3795
|
const handleSwitchboardLinkClick = showSwitchboardLink !== false ? onOpenSwitchboardLink : void 0;
|
|
4550
3796
|
return /* @__PURE__ */ jsxs("div", { className: "relative h-full", id: "document-editor-context", children: [
|
|
@@ -4555,10 +3801,7 @@ const DocumentEditor = (props) => {
|
|
|
4555
3801
|
onExport,
|
|
4556
3802
|
onShowRevisionHistory: showRevisionHistory,
|
|
4557
3803
|
title: fileNodeDocument.name || document2.name,
|
|
4558
|
-
onSwitchboardLinkClick: handleSwitchboardLinkClick
|
|
4559
|
-
timelineButtonVisible: timelineEnabled,
|
|
4560
|
-
timelineItems: timelineItems.data,
|
|
4561
|
-
onTimelineItemClick: setSelectedTimelineItem
|
|
3804
|
+
onSwitchboardLinkClick: handleSwitchboardLinkClick
|
|
4562
3805
|
}
|
|
4563
3806
|
),
|
|
4564
3807
|
!disableExternalControls && /* @__PURE__ */ jsxs("div", { className: "mb-4 flex justify-end gap-10", children: [
|
|
@@ -4588,16 +3831,7 @@ const DocumentEditor = (props) => {
|
|
|
4588
3831
|
EditorComponent,
|
|
4589
3832
|
{
|
|
4590
3833
|
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
|
-
},
|
|
3834
|
+
context,
|
|
4601
3835
|
document: document2,
|
|
4602
3836
|
documentNodeName: fileNodeDocument.name,
|
|
4603
3837
|
dispatch,
|
|
@@ -4635,7 +3869,6 @@ function DocumentEditorContainer() {
|
|
|
4635
3869
|
renameNode,
|
|
4636
3870
|
getDocumentModelModule
|
|
4637
3871
|
} = useUiNodes();
|
|
4638
|
-
const getDocument = useGetDocument();
|
|
4639
3872
|
const handleAddOperationToSelectedDocument = useCallback(
|
|
4640
3873
|
async (operation) => {
|
|
4641
3874
|
if (!selectedDocument) {
|
|
@@ -4698,20 +3931,6 @@ function DocumentEditorContainer() {
|
|
|
4698
3931
|
},
|
|
4699
3932
|
[getDocumentModelModule, showModal, t]
|
|
4700
3933
|
);
|
|
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
3934
|
const onExport = useCallback(() => {
|
|
4716
3935
|
if (selectedDocument) {
|
|
4717
3936
|
return exportDocument(selectedDocument);
|
|
@@ -4733,7 +3952,6 @@ function DocumentEditorContainer() {
|
|
|
4733
3952
|
onChange: onDocumentChangeHandler,
|
|
4734
3953
|
onClose,
|
|
4735
3954
|
onExport,
|
|
4736
|
-
onGetDocumentRevision,
|
|
4737
3955
|
onAddOperation: handleAddOperationToSelectedDocument,
|
|
4738
3956
|
onOpenSwitchboardLink
|
|
4739
3957
|
}
|
|
@@ -4742,6 +3960,165 @@ function DocumentEditorContainer() {
|
|
|
4742
3960
|
fileNodeDocument.documentId
|
|
4743
3961
|
);
|
|
4744
3962
|
}
|
|
3963
|
+
function getDocumentSpec(doc) {
|
|
3964
|
+
if ("documentModelState" in doc) {
|
|
3965
|
+
return doc.documentModelState;
|
|
3966
|
+
}
|
|
3967
|
+
return doc.documentModel;
|
|
3968
|
+
}
|
|
3969
|
+
const CreateDocument = ({ documentModels, createDocument }) => {
|
|
3970
|
+
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) => {
|
|
3971
|
+
const spec = getDocumentSpec(doc);
|
|
3972
|
+
return jsx(Button, { color: "light", "aria-details": spec.description, onClick: () => createDocument(doc), children: jsx("span", { className: "text-sm", children: spec.name }) }, spec.id);
|
|
3973
|
+
}) })] });
|
|
3974
|
+
};
|
|
3975
|
+
function sortUiNodesByName(a, b) {
|
|
3976
|
+
return a.name.localeCompare(b.name);
|
|
3977
|
+
}
|
|
3978
|
+
const GAP = 8;
|
|
3979
|
+
const ITEM_WIDTH = 256;
|
|
3980
|
+
const ITEM_HEIGHT = 48;
|
|
3981
|
+
const USED_SPACE = 420;
|
|
3982
|
+
function FileContentView(props) {
|
|
3983
|
+
const parentRef = useRef(null);
|
|
3984
|
+
const { t } = useTranslation();
|
|
3985
|
+
const windowSize = useWindowSize();
|
|
3986
|
+
const { fileNodes, ...fileProps } = props;
|
|
3987
|
+
const availableWidth = windowSize.innerWidth - USED_SPACE;
|
|
3988
|
+
const columnCount = Math.floor(availableWidth / (ITEM_WIDTH + GAP)) || 1;
|
|
3989
|
+
const rowCount = Math.ceil(fileNodes.length / columnCount);
|
|
3990
|
+
const rowVirtualizer = useVirtualizer({
|
|
3991
|
+
count: rowCount,
|
|
3992
|
+
getScrollElement: () => parentRef.current,
|
|
3993
|
+
estimateSize: (index) => {
|
|
3994
|
+
if (index > 0) {
|
|
3995
|
+
return ITEM_HEIGHT + GAP;
|
|
3996
|
+
}
|
|
3997
|
+
return ITEM_HEIGHT;
|
|
3998
|
+
},
|
|
3999
|
+
overscan: 5
|
|
4000
|
+
});
|
|
4001
|
+
const columnVirtualizer = useVirtualizer({
|
|
4002
|
+
horizontal: true,
|
|
4003
|
+
count: columnCount,
|
|
4004
|
+
getScrollElement: () => parentRef.current,
|
|
4005
|
+
estimateSize: (index) => {
|
|
4006
|
+
if (index > 0) {
|
|
4007
|
+
return ITEM_WIDTH + GAP;
|
|
4008
|
+
}
|
|
4009
|
+
return ITEM_WIDTH;
|
|
4010
|
+
},
|
|
4011
|
+
overscan: 5
|
|
4012
|
+
});
|
|
4013
|
+
const getItemIndex = (rowIndex, columnIndex) => rowIndex * columnCount + columnIndex;
|
|
4014
|
+
const getItem = (rowIndex, columnIndex) => {
|
|
4015
|
+
const index = getItemIndex(rowIndex, columnIndex);
|
|
4016
|
+
return fileNodes[index] || null;
|
|
4017
|
+
};
|
|
4018
|
+
if (fileNodes.length === 0) {
|
|
4019
|
+
return jsx("div", { className: "mb-8 text-sm text-gray-400", children: t("folderView.sections.documents.empty", {
|
|
4020
|
+
defaultValue: "No documents or files 📄"
|
|
4021
|
+
}) });
|
|
4022
|
+
}
|
|
4023
|
+
const renderItem = (rowIndex, columnIndex) => {
|
|
4024
|
+
const fileNode = getItem(rowIndex, columnIndex);
|
|
4025
|
+
if (!fileNode) {
|
|
4026
|
+
return null;
|
|
4027
|
+
}
|
|
4028
|
+
return jsx("div", { style: {
|
|
4029
|
+
marginLeft: columnIndex === 0 ? 0 : GAP
|
|
4030
|
+
}, children: jsx(FileItem, { uiNode: fileNode, ...fileProps }, fileNode.id) });
|
|
4031
|
+
};
|
|
4032
|
+
return jsx("div", { ref: parentRef, style: {
|
|
4033
|
+
height: `400px`,
|
|
4034
|
+
width: `100%`,
|
|
4035
|
+
overflow: "auto"
|
|
4036
|
+
}, children: jsx("div", { style: {
|
|
4037
|
+
height: `${rowVirtualizer.getTotalSize()}px`,
|
|
4038
|
+
width: `${columnVirtualizer.getTotalSize()}px`,
|
|
4039
|
+
position: "relative"
|
|
4040
|
+
}, children: rowVirtualizer.getVirtualItems().map((virtualRow) => jsx(React__default.Fragment, { children: columnVirtualizer.getVirtualItems().map((virtualColumn) => jsx("div", { style: {
|
|
4041
|
+
position: "absolute",
|
|
4042
|
+
top: 0,
|
|
4043
|
+
left: 0,
|
|
4044
|
+
marginTop: virtualRow.index === 0 ? 0 : GAP,
|
|
4045
|
+
width: `${virtualColumn.size}px`,
|
|
4046
|
+
height: `${virtualRow.size}px`,
|
|
4047
|
+
transform: `translateX(${virtualColumn.start}px) translateY(${virtualRow.start}px)`
|
|
4048
|
+
}, children: renderItem(virtualRow.index, virtualColumn.index) }, virtualColumn.key)) }, virtualRow.key)) }) });
|
|
4049
|
+
}
|
|
4050
|
+
function FolderView(props) {
|
|
4051
|
+
const { node, className, isDropTarget, containerProps, ...nodeProps } = props;
|
|
4052
|
+
const { t } = useTranslation();
|
|
4053
|
+
const folderNodes = node.children.filter((node2) => node2.kind === FOLDER).sort(sortUiNodesByName);
|
|
4054
|
+
const fileNodes = node.children.filter((node2) => node2.kind === FILE).sort(sortUiNodesByName);
|
|
4055
|
+
const folderCallbacks = {
|
|
4056
|
+
onSelectNode: (node2) => nodeProps.onSelectNode(node2),
|
|
4057
|
+
onRenameNode: (name, node2) => nodeProps.onRenameNode(name, node2),
|
|
4058
|
+
onDuplicateNode: (node2) => nodeProps.onDuplicateNode(node2),
|
|
4059
|
+
onDeleteNode: (node2) => nodeProps.onDeleteNode(node2)
|
|
4060
|
+
};
|
|
4061
|
+
const fileCallbacks = {
|
|
4062
|
+
onSelectNode: (node2) => nodeProps.onSelectNode(node2),
|
|
4063
|
+
onRenameNode: (name, node2) => nodeProps.onRenameNode(name, node2),
|
|
4064
|
+
onDuplicateNode: (node2) => nodeProps.onDuplicateNode(node2),
|
|
4065
|
+
onDeleteNode: (node2) => nodeProps.onDeleteNode(node2)
|
|
4066
|
+
};
|
|
4067
|
+
const baseNodeCallbacks = {
|
|
4068
|
+
onAddFile: async (file, parentNode) => {
|
|
4069
|
+
await nodeProps.onAddFile(file, parentNode);
|
|
4070
|
+
},
|
|
4071
|
+
onCopyNode: async (uiNode, targetNode) => {
|
|
4072
|
+
await nodeProps.onCopyNode(uiNode, targetNode);
|
|
4073
|
+
},
|
|
4074
|
+
onMoveNode: async (uiNode, targetNode) => {
|
|
4075
|
+
await nodeProps.onMoveNode(uiNode, targetNode);
|
|
4076
|
+
}
|
|
4077
|
+
};
|
|
4078
|
+
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", {
|
|
4079
|
+
defaultValue: "Folders"
|
|
4080
|
+
}), 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", {
|
|
4081
|
+
defaultValue: "No documents or files 📄"
|
|
4082
|
+
}) }) }), jsx(DriveLayout.ContentSection, { title: t("folderView.sections.documents.title", {
|
|
4083
|
+
defaultValue: "Documents and files"
|
|
4084
|
+
}), children: jsx("div", { className: twMerge("w-full", fileNodes.length > 0 ? "min-h-[400px]" : "min-h-14"), children: jsx(FileContentView, { fileNodes, ...fileCallbacks, isAllowedToCreateDocuments: nodeProps.isAllowedToCreateDocuments }) }) })] });
|
|
4085
|
+
}
|
|
4086
|
+
function BaseEditor(props) {
|
|
4087
|
+
const { document: document2, dispatch, className, children } = props;
|
|
4088
|
+
const { state: { global: { id: driveId } } } = document2;
|
|
4089
|
+
const { showSearchBar, isAllowedToCreateDocuments, documentModels, showCreateDocumentModal } = useDriveContext();
|
|
4090
|
+
const { driveNodes, selectedNode, selectedNodePath, getNodeById, setSelectedNode } = useUiNodesContext();
|
|
4091
|
+
const driveNode = useMemo(() => driveNodes.find((n) => n.id === driveId), [driveNodes, driveId]);
|
|
4092
|
+
const { addDocument, addFile, addFolder: addFolder2, renameNode, deleteNode: deleteNode2, moveNode: moveNode2, copyNode: copyNode2, duplicateNode } = useDriveActionsWithUiNodes(document2, dispatch);
|
|
4093
|
+
const onCreateDocument = useCallback(async (documentModel) => {
|
|
4094
|
+
const { name } = await showCreateDocumentModal(documentModel);
|
|
4095
|
+
const document3 = documentModel.utils.createDocument();
|
|
4096
|
+
await addDocument(name, documentModel.documentModel.name, document3, selectedNode == null ? void 0 : selectedNode.id);
|
|
4097
|
+
}, [addDocument, showCreateDocumentModal, selectedNode == null ? void 0 : selectedNode.id]);
|
|
4098
|
+
const { isDropTarget, dropProps } = useDrop({
|
|
4099
|
+
uiNode: selectedNode,
|
|
4100
|
+
onAddFile: addFile,
|
|
4101
|
+
onCopyNode: copyNode2,
|
|
4102
|
+
onMoveNode: moveNode2
|
|
4103
|
+
});
|
|
4104
|
+
const { breadcrumbs, onBreadcrumbSelected } = useBreadcrumbs({
|
|
4105
|
+
selectedNodePath,
|
|
4106
|
+
getNodeById,
|
|
4107
|
+
setSelectedNode
|
|
4108
|
+
});
|
|
4109
|
+
if (!driveNode) {
|
|
4110
|
+
return jsx("div", { children: "Drive not found" });
|
|
4111
|
+
} else if ((selectedNode == null ? void 0 : selectedNode.kind) === FILE$1) {
|
|
4112
|
+
return jsx(Fragment$1, {});
|
|
4113
|
+
}
|
|
4114
|
+
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 }) })] });
|
|
4115
|
+
}
|
|
4116
|
+
function Editor(props) {
|
|
4117
|
+
return jsx(DriveContextProvider, { value: props.context, children: jsx(BaseEditor, { ...props }) });
|
|
4118
|
+
}
|
|
4119
|
+
const GenericDriveExplorer = {
|
|
4120
|
+
Component: Editor
|
|
4121
|
+
};
|
|
4745
4122
|
function useDocumentsState(args) {
|
|
4746
4123
|
const { reactor, driveId, documentIds, options } = args;
|
|
4747
4124
|
const [statesByDocumentId, setStatesByDocumentId] = useState({});
|
|
@@ -4928,19 +4305,8 @@ function DriveEditorContainer() {
|
|
|
4928
4305
|
const { addFile, addDocument } = useDocumentDriveServer();
|
|
4929
4306
|
const documentModels = useFilteredDocumentModels();
|
|
4930
4307
|
const useDriveDocumentState = makeDriveDocumentStateHook(reactor);
|
|
4931
|
-
const getDocument = useGetDocument();
|
|
4932
4308
|
const getDocumentModelModule = useGetDocumentModelModule();
|
|
4933
4309
|
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
4310
|
const driveContext = useMemo(
|
|
4945
4311
|
() => ({
|
|
4946
4312
|
showSearchBar: false,
|
|
@@ -4984,8 +4350,6 @@ function DriveEditorContainer() {
|
|
|
4984
4350
|
context: {
|
|
4985
4351
|
...editorProps.context,
|
|
4986
4352
|
...driveContext,
|
|
4987
|
-
analyticsDatabaseName: connectConfig.analyticsDatabaseName,
|
|
4988
|
-
getDocumentRevision: onGetDocumentRevision,
|
|
4989
4353
|
getDocumentModelModule,
|
|
4990
4354
|
getEditor
|
|
4991
4355
|
},
|
|
@@ -5021,7 +4385,7 @@ function Content() {
|
|
|
5021
4385
|
}, [selectedDriveNode, selectedNode, addFile]);
|
|
5022
4386
|
useEffect(() => {
|
|
5023
4387
|
if ((status === "LOADED" || status === "ERROR") && !documentDrives.find(
|
|
5024
|
-
(d) => d.id === driveId || d.slug === driveId || d.state.global.name === driveId
|
|
4388
|
+
(d) => d.state.global.id === driveId || d.state.global.slug === driveId || d.state.global.name === driveId
|
|
5025
4389
|
)) {
|
|
5026
4390
|
toast(/* @__PURE__ */ jsxs("p", { children: [
|
|
5027
4391
|
"Drive ",
|
|
@@ -5036,4 +4400,3 @@ function Content() {
|
|
|
5036
4400
|
export {
|
|
5037
4401
|
Content as default
|
|
5038
4402
|
};
|
|
5039
|
-
//# sourceMappingURL=content-2lJzkjLx.js.map
|