@w100n/documents 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -6,8 +6,29 @@ import {
6
6
  } from "./chunk-KEV4R7W5.js";
7
7
 
8
8
  // src/DocumentsWorkspace.tsx
9
- import { useLayoutEffect as useLayoutEffect3, useRef as useRef4, useState as useState4 } from "react";
10
- import { ChevronDown, FileSpreadsheet, FileText, FileType, Files, History, Info, ListTree, PanelLeftClose, PanelLeftOpen, Presentation, RotateCcw, Search } from "lucide-react";
9
+ import { useLayoutEffect as useLayoutEffect3, useRef as useRef5, useState as useState5 } from "react";
10
+ import {
11
+ Check,
12
+ ChevronDown,
13
+ ChevronRight,
14
+ FileSpreadsheet,
15
+ FileText,
16
+ FileType,
17
+ Files,
18
+ History,
19
+ Info,
20
+ LayoutGrid,
21
+ ListTree,
22
+ Maximize2,
23
+ Minus,
24
+ PanelLeftOpen,
25
+ PanelRightOpen,
26
+ Plus,
27
+ Presentation,
28
+ RotateCcw,
29
+ Search,
30
+ X
31
+ } from "lucide-react";
11
32
 
12
33
  // src/text.ts
13
34
  var en = {
@@ -41,6 +62,12 @@ var en = {
41
62
  unsupported: "This file cannot be shown yet",
42
63
  restore: "Restore this version",
43
64
  restoreFailed: "Could not restore",
65
+ allProjects: "All projects",
66
+ closePanel: "Hide the panel",
67
+ openPanel: "Show the panel",
68
+ zoomIn: "Zoom in",
69
+ zoomOut: "Zoom out",
70
+ fit: "Actual size",
44
71
  kinds: { docx: "DOCX", markdown: "Markdown", pdf: "PDF", sheet: "Sheets", slides: "Slides" }
45
72
  };
46
73
  var pl = {
@@ -74,6 +101,12 @@ var pl = {
74
101
  unsupported: "Tego pliku nie da si\u0119 jeszcze pokaza\u0107",
75
102
  restore: "Przywr\xF3\u0107 t\u0119 wersj\u0119",
76
103
  restoreFailed: "Nie uda\u0142o si\u0119 przywr\xF3ci\u0107",
104
+ allProjects: "Wszystkie projekty",
105
+ closePanel: "Ukryj panel",
106
+ openPanel: "Poka\u017C panel",
107
+ zoomIn: "Powi\u0119ksz",
108
+ zoomOut: "Pomniejsz",
109
+ fit: "Rzeczywisty rozmiar",
77
110
  kinds: { docx: "DOCX", markdown: "Markdown", pdf: "PDF", sheet: "Arkusze", slides: "Slajdy" }
78
111
  };
79
112
  var uk = {
@@ -107,16 +140,117 @@ var uk = {
107
140
  unsupported: "\u0426\u0435\u0439 \u0444\u0430\u0439\u043B \u043F\u043E\u043A\u0438 \u043D\u0435 \u043F\u043E\u043A\u0430\u0437\u0443\u0454\u0442\u044C\u0441\u044F",
108
141
  restore: "\u0412\u0456\u0434\u043D\u043E\u0432\u0438\u0442\u0438 \u0446\u044E \u0432\u0435\u0440\u0441\u0456\u044E",
109
142
  restoreFailed: "\u041D\u0435 \u0432\u0434\u0430\u043B\u043E\u0441\u044F \u0432\u0456\u0434\u043D\u043E\u0432\u0438\u0442\u0438",
143
+ allProjects: "\u0423\u0441\u0456 \u043F\u0440\u043E\u0454\u043A\u0442\u0438",
144
+ closePanel: "\u0421\u0445\u043E\u0432\u0430\u0442\u0438 \u043F\u0430\u043D\u0435\u043B\u044C",
145
+ openPanel: "\u041F\u043E\u043A\u0430\u0437\u0430\u0442\u0438 \u043F\u0430\u043D\u0435\u043B\u044C",
146
+ zoomIn: "\u0417\u0431\u0456\u043B\u044C\u0448\u0438\u0442\u0438",
147
+ zoomOut: "\u0417\u043C\u0435\u043D\u0448\u0438\u0442\u0438",
148
+ fit: "\u0421\u043F\u0440\u0430\u0432\u0436\u043D\u0456\u0439 \u0440\u043E\u0437\u043C\u0456\u0440",
110
149
  kinds: { docx: "DOCX", markdown: "Markdown", pdf: "PDF", sheet: "\u0422\u0430\u0431\u043B\u0438\u0446\u0456", slides: "\u0421\u043B\u0430\u0439\u0434\u0438" }
111
150
  };
112
151
  var texts = { en, pl, uk };
113
152
 
153
+ // src/Thumb.tsx
154
+ import { useEffect, useRef, useState } from "react";
155
+
156
+ // src/preview.ts
157
+ var cache = /* @__PURE__ */ new Map();
158
+ var waiting = [];
159
+ var running = 0;
160
+ async function turn(work) {
161
+ if (running >= 2) await new Promise((go) => waiting.push(go));
162
+ running++;
163
+ try {
164
+ return await work();
165
+ } finally {
166
+ running--;
167
+ waiting.shift()?.();
168
+ }
169
+ }
170
+ async function make(host, doc) {
171
+ if (doc.size > 3e6 || !["markdown", "docx", "pdf"].includes(doc.kind)) return null;
172
+ return turn(async () => {
173
+ var _a;
174
+ const bytes = await host.content(doc.id, null);
175
+ if (doc.kind === "markdown") return { text: new TextDecoder().decode(bytes.slice(0, 2400)) };
176
+ if (doc.kind === "docx") {
177
+ const { renderAsync } = await import("docx-preview");
178
+ const box = document.createElement("div");
179
+ await renderAsync(bytes, box, void 0, { inWrapper: false, ignoreLastRenderedPageBreak: true });
180
+ return { text: [...box.querySelectorAll("p, h1, h2, h3, li")].map((node) => node.textContent?.trim()).filter(Boolean).join("\n").slice(0, 800) };
181
+ }
182
+ const pdfjs = await import("pdfjs-dist");
183
+ if (host.pdfWorker) (_a = pdfjs.GlobalWorkerOptions).workerPort ?? (_a.workerPort = host.pdfWorker());
184
+ const task = pdfjs.getDocument({ data: new Uint8Array(bytes.slice(0)) });
185
+ const pdf = await task.promise;
186
+ const page = await pdf.getPage(1);
187
+ const viewport = page.getViewport({ scale: 320 / page.getViewport({ scale: 1 }).width });
188
+ const canvas = document.createElement("canvas");
189
+ canvas.width = viewport.width;
190
+ canvas.height = viewport.height;
191
+ await page.render({ canvas, canvasContext: canvas.getContext("2d"), viewport }).promise;
192
+ void task.destroy();
193
+ return { image: canvas.toDataURL("image/png") };
194
+ });
195
+ }
196
+ function preview(host, doc) {
197
+ const key = `${doc.id}:${doc.updatedAt}`;
198
+ let found = cache.get(key);
199
+ if (!found) {
200
+ found = make(host, doc).catch(() => null);
201
+ cache.set(key, found);
202
+ }
203
+ return found;
204
+ }
205
+
206
+ // src/Thumb.tsx
207
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
208
+ function Thumb({ host, item, label }) {
209
+ const box = useRef(null);
210
+ const [seen, setSeen] = useState(false);
211
+ const [shot, setShot] = useState(null);
212
+ useEffect(() => {
213
+ if (item.thumbnailUrl || item.excerpt || typeof IntersectionObserver === "undefined") return;
214
+ const watch = new IntersectionObserver((entries) => {
215
+ if (entries.some((entry) => entry.isIntersecting)) setSeen(true);
216
+ }, { rootMargin: "200px" });
217
+ watch.observe(box.current);
218
+ return () => watch.disconnect();
219
+ }, [item.thumbnailUrl, item.excerpt]);
220
+ useEffect(() => {
221
+ if (!seen) return;
222
+ let live = true;
223
+ void preview(host, item).then((found) => {
224
+ if (live) setShot(found);
225
+ });
226
+ return () => {
227
+ live = false;
228
+ };
229
+ }, [seen, host, item.id, item.updatedAt]);
230
+ const text = item.excerpt ?? shot?.text ?? "";
231
+ const lines = text.split("\n").filter((line) => !line.trim().startsWith("```")).map((line) => line.replace(/^#+\s*/, "").replace(/[*_`>|]/g, "").trim()).filter(Boolean);
232
+ const image = item.thumbnailUrl ?? shot?.image;
233
+ return /* @__PURE__ */ jsxs("span", { ref: box, className: "w100n-docs-thumb", "data-kind": item.kind, children: [
234
+ image ? /* @__PURE__ */ jsx("img", { src: image, alt: "" }) : /* @__PURE__ */ jsx("span", { className: "w100n-docs-paper", "aria-hidden": true, children: lines.length ? /* @__PURE__ */ jsxs(Fragment, { children: [
235
+ /* @__PURE__ */ jsx("b", { children: lines[0] }),
236
+ lines.slice(1, 14).join(" ")
237
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
238
+ /* @__PURE__ */ jsx("i", {}),
239
+ /* @__PURE__ */ jsx("i", {}),
240
+ /* @__PURE__ */ jsx("i", {}),
241
+ /* @__PURE__ */ jsx("i", {}),
242
+ /* @__PURE__ */ jsx("i", {})
243
+ ] }) }),
244
+ /* @__PURE__ */ jsx("span", { className: "w100n-docs-kind", "data-kind": item.kind, children: label })
245
+ ] });
246
+ }
247
+
114
248
  // src/useLoad.ts
115
- import { useEffect, useState } from "react";
249
+ import { useEffect as useEffect2, useState as useState2 } from "react";
116
250
  function useLoad(load, key) {
117
- const [state, setState] = useState({ data: null, error: null, loading: true });
118
- const [attempt, setAttempt] = useState(0);
119
- useEffect(() => {
251
+ const [state, setState] = useState2({ data: null, error: null, loading: true });
252
+ const [attempt, setAttempt] = useState2(0);
253
+ useEffect2(() => {
120
254
  const controller = new AbortController();
121
255
  setState((current) => ({ ...current, loading: true, error: null }));
122
256
  load(controller.signal).then(
@@ -133,7 +267,7 @@ function useLoad(load, key) {
133
267
  }
134
268
 
135
269
  // src/viewers/DocxView.tsx
136
- import { useLayoutEffect, useRef, useState as useState2 } from "react";
270
+ import { useLayoutEffect, useRef as useRef2, useState as useState3 } from "react";
137
271
 
138
272
  // src/viewers/headings.ts
139
273
  var last = 0;
@@ -147,10 +281,10 @@ function collect(root, selector, level = (el) => Number(el.tagName.slice(1))) {
147
281
  }
148
282
 
149
283
  // src/viewers/DocxView.tsx
150
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
284
+ import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
151
285
  function DocxView({ bytes, onOutline, failed }) {
152
- const box = useRef(null);
153
- const [error, setError] = useState2(false);
286
+ const box = useRef2(null);
287
+ const [error, setError] = useState3(false);
154
288
  useLayoutEffect(() => {
155
289
  let live = true;
156
290
  let width = 0;
@@ -176,35 +310,35 @@ function DocxView({ bytes, onOutline, failed }) {
176
310
  watch.disconnect();
177
311
  };
178
312
  }, [bytes, onOutline]);
179
- return /* @__PURE__ */ jsxs(Fragment, { children: [
180
- error && /* @__PURE__ */ jsx("p", { className: "w100n-docs-note", children: failed }),
181
- /* @__PURE__ */ jsx("div", { ref: box, className: "w100n-docs-docx" })
313
+ return /* @__PURE__ */ jsxs2(Fragment2, { children: [
314
+ error && /* @__PURE__ */ jsx2("p", { className: "w100n-docs-note", children: failed }),
315
+ /* @__PURE__ */ jsx2("div", { ref: box, className: "w100n-docs-docx" })
182
316
  ] });
183
317
  }
184
318
 
185
319
  // src/viewers/MarkdownView.tsx
186
320
  import DOMPurify from "dompurify";
187
321
  import { marked } from "marked";
188
- import { useLayoutEffect as useLayoutEffect2, useRef as useRef2 } from "react";
189
- import { jsx as jsx2 } from "react/jsx-runtime";
322
+ import { useLayoutEffect as useLayoutEffect2, useRef as useRef3 } from "react";
323
+ import { jsx as jsx3 } from "react/jsx-runtime";
190
324
  function MarkdownView({ bytes, onOutline }) {
191
- const box = useRef2(null);
325
+ const box = useRef3(null);
192
326
  useLayoutEffect2(() => {
193
327
  const root = box.current;
194
328
  root.innerHTML = DOMPurify.sanitize(marked.parse(new TextDecoder().decode(bytes), { async: false }));
195
329
  onOutline(collect(root, "h1, h2, h3"));
196
330
  }, [bytes, onOutline]);
197
- return /* @__PURE__ */ jsx2("article", { ref: box, className: "w100n-docs-page w100n-docs-prose" });
331
+ return /* @__PURE__ */ jsx3("article", { ref: box, className: "w100n-docs-page w100n-docs-prose" });
198
332
  }
199
333
 
200
334
  // src/viewers/PdfView.tsx
201
- import { useEffect as useEffect2, useRef as useRef3, useState as useState3 } from "react";
202
- import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
335
+ import { useEffect as useEffect3, useRef as useRef4, useState as useState4 } from "react";
336
+ import { Fragment as Fragment3, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
203
337
  var last2 = 0;
204
338
  function PdfView({ bytes, worker, onOutline, failed }) {
205
- const box = useRef3(null);
206
- const [error, setError] = useState3(false);
207
- useEffect2(() => {
339
+ const box = useRef4(null);
340
+ const [error, setError] = useState4(false);
341
+ useEffect3(() => {
208
342
  const root = box.current;
209
343
  const prefix = `w100n-docs-p${++last2}`;
210
344
  let stop = false;
@@ -251,64 +385,90 @@ function PdfView({ bytes, worker, onOutline, failed }) {
251
385
  close();
252
386
  };
253
387
  }, [bytes, worker, onOutline]);
254
- return /* @__PURE__ */ jsxs2(Fragment2, { children: [
255
- error && /* @__PURE__ */ jsx3("p", { className: "w100n-docs-note", children: failed }),
256
- /* @__PURE__ */ jsx3("div", { ref: box, className: "w100n-docs-pdf" })
388
+ return /* @__PURE__ */ jsxs3(Fragment3, { children: [
389
+ error && /* @__PURE__ */ jsx4("p", { className: "w100n-docs-note", children: failed }),
390
+ /* @__PURE__ */ jsx4("div", { ref: box, className: "w100n-docs-pdf" })
257
391
  ] });
258
392
  }
259
393
 
260
394
  // src/viewers/SlidesView.tsx
261
- import { jsx as jsx4 } from "react/jsx-runtime";
395
+ import { jsx as jsx5 } from "react/jsx-runtime";
262
396
  function SlidesView({ bytes, title }) {
263
- return /* @__PURE__ */ jsx4("iframe", { className: "w100n-docs-slides", sandbox: "allow-scripts", title, srcDoc: new TextDecoder().decode(bytes) });
397
+ return /* @__PURE__ */ jsx5("iframe", { className: "w100n-docs-slides", sandbox: "allow-scripts", title, srcDoc: new TextDecoder().decode(bytes) });
264
398
  }
265
399
 
266
400
  // src/DocumentsWorkspace.tsx
267
- import { Fragment as Fragment3, jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
401
+ import { Fragment as Fragment4, jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
268
402
  var icons = { docx: FileText, markdown: FileType, pdf: Files, sheet: FileSpreadsheet, slides: Presentation };
269
- function DocumentsWorkspace({ host, language = "en", theme = "light", place, onPlace, start, end, aside }) {
403
+ function DocumentsWorkspace({ host, language = "en", theme = "light", place, onPlace, start, end, aside, actions }) {
270
404
  const t = texts[language];
271
- const [own, setOwn] = useState4({ spaceId: null, documentId: null });
405
+ const [own, setOwn] = useState5({ spaceId: null, documentId: null });
272
406
  const here = place ?? own;
273
407
  const go = (next) => {
274
408
  setOwn(next);
275
409
  onPlace?.(next);
276
410
  };
277
- const [query, setQuery] = useState4("");
278
- const [kind, setKind] = useState4("all");
279
- const [listOpen, setListOpen] = useState4(true);
280
- const listRef = useRef4(null);
281
- const overlays = () => listRef.current !== null && getComputedStyle(listRef.current).position === "absolute";
411
+ const [query, setQuery] = useState5("");
412
+ const [kind, setKind] = useState5("all");
413
+ const [listOpen, setListOpen] = useState5(true);
414
+ const [panelOpen, setPanelOpen] = useState5(true);
415
+ const root = useRef5(null);
416
+ const narrow = () => root.current !== null && getComputedStyle(root.current).getPropertyValue("--docs-narrow").trim() === "1";
282
417
  useLayoutEffect3(() => {
283
- if (here.documentId && overlays()) setListOpen(false);
418
+ if (here.documentId && narrow()) setListOpen(false);
284
419
  }, []);
285
- const [picking, setPicking] = useState4(false);
286
- const [tab, setTab] = useState4("outline");
287
- const [outline, setOutline] = useState4([]);
288
- const [version, setVersion] = useState4({ documentId: null, id: null });
420
+ const [picking, setPicking] = useState5(false);
421
+ const [tab, setTab] = useState5("outline");
422
+ const [zoom, setZoom] = useState5(100);
423
+ const [outline, setOutline] = useState5([]);
424
+ const [version, setVersion] = useState5({ documentId: null, id: null });
289
425
  const versionId = version.documentId === here.documentId ? version.id : null;
290
- const [restoring, setRestoring] = useState4("idle");
426
+ const [restoring, setRestoring] = useState5("idle");
291
427
  const spaces = useLoad((signal) => host.spaces({ signal }), [host]);
292
- const spaceId = here.spaceId ?? spaces.data?.[0]?.id ?? null;
428
+ const single = spaces.data?.length === 1 ? spaces.data[0].id : null;
429
+ const spaceId = here.spaceId ?? single;
293
430
  const space = spaces.data?.find((item) => item.id === spaceId);
294
- const list = useLoad((signal) => spaceId ? host.documents(spaceId, { signal }) : Promise.resolve([]), [host, spaceId]);
431
+ const list = useLoad(async (signal) => {
432
+ if (spaceId) return host.documents(spaceId, { signal });
433
+ if (host.everything) return host.everything({ signal });
434
+ const all2 = await host.spaces({ signal });
435
+ return (await Promise.all(all2.map((item) => host.documents(item.id, { signal })))).flat();
436
+ }, [host, spaceId]);
295
437
  const doc = useLoad((signal) => here.documentId ? host.document(here.documentId, { signal }) : Promise.resolve(null), [host, here.documentId]);
296
438
  const versions = useLoad((signal) => here.documentId ? host.versions(here.documentId, { signal }) : Promise.resolve([]), [host, here.documentId]);
297
439
  const content = useLoad((signal) => here.documentId ? host.content(here.documentId, versionId, { signal }) : Promise.resolve(null), [host, here.documentId, versionId]);
298
- const shown = (list.data ?? []).filter((item) => matches(item, query, kind));
299
- const present = kinds.filter((item) => list.data?.some((doc2) => doc2.kind === item));
300
- const folders = [.../* @__PURE__ */ new Set(["", ...shown.map((item) => item.folder ?? "")])].filter((folder) => shown.some((item) => (item.folder ?? "") === folder));
440
+ const all = list.data ?? [];
441
+ const shown = all.filter((item) => matches(item, query, kind));
442
+ const present = kinds.filter((item) => all.some((doc2) => doc2.kind === item));
443
+ const folders = spaceId ? [.../* @__PURE__ */ new Set(["", ...shown.map((item) => item.folder ?? "")])].filter((folder) => shown.some((item) => (item.folder ?? "") === folder)) : [""];
444
+ const names = new Map((spaces.data ?? []).map((item) => [item.id, item.name]));
445
+ const counts = /* @__PURE__ */ new Map();
446
+ for (const item of all) counts.set(item.spaceId, (counts.get(item.spaceId) ?? 0) + 1);
447
+ const groups = [...new Set((spaces.data ?? []).map((item) => item.group ?? ""))];
301
448
  const date = (iso) => new Intl.DateTimeFormat(language, { day: "numeric", month: "short", year: "numeric", hour: "2-digit", minute: "2-digit" }).format(new Date(iso));
449
+ const ago = (iso) => {
450
+ const minutes = Math.round((Date.parse(iso) - Date.now()) / 6e4);
451
+ const rtf = new Intl.RelativeTimeFormat(language, { numeric: "auto", style: "short" });
452
+ if (Math.abs(minutes) < 60) return rtf.format(minutes, "minute");
453
+ if (Math.abs(minutes) < 1440) return rtf.format(Math.round(minutes / 60), "hour");
454
+ if (Math.abs(minutes) < 43200) return rtf.format(Math.round(minutes / 1440), "day");
455
+ return new Intl.DateTimeFormat(language, { day: "numeric", month: "short", year: "numeric" }).format(new Date(iso));
456
+ };
302
457
  const size = (bytes) => bytes < 1024 ? `${bytes} B` : bytes < 1048576 ? `${(bytes / 1024).toFixed(0)} KB` : `${(bytes / 1048576).toFixed(1)} MB`;
303
- const failed = (retry) => /* @__PURE__ */ jsxs3("div", { className: "w100n-docs-note", children: [
458
+ const failed = (retry) => /* @__PURE__ */ jsxs4("div", { className: "w100n-docs-note", children: [
304
459
  t.failed,
305
- /* @__PURE__ */ jsx5("button", { type: "button", onClick: retry, children: t.retry })
460
+ /* @__PURE__ */ jsx6("button", { type: "button", onClick: retry, children: t.retry })
306
461
  ] });
307
- const open = (documentId) => {
462
+ const open = (item) => {
308
463
  setOutline([]);
309
464
  setTab("outline");
310
- go({ spaceId, documentId });
311
- if (overlays()) setListOpen(false);
465
+ go({ spaceId: here.spaceId, documentId: item.id });
466
+ if (narrow()) setListOpen(false);
467
+ };
468
+ const pick = (next) => {
469
+ setPicking(false);
470
+ setKind("all");
471
+ go({ spaceId: next, documentId: null });
312
472
  };
313
473
  const restore = async (documentId, versionId2) => {
314
474
  setRestoring("busy");
@@ -324,8 +484,8 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place, onP
324
484
  doc.retry();
325
485
  list.retry();
326
486
  };
327
- let stage = /* @__PURE__ */ jsxs3("div", { className: "w100n-docs-empty", children: [
328
- /* @__PURE__ */ jsx5(FileText, { "aria-hidden": true }),
487
+ let stage = /* @__PURE__ */ jsxs4("div", { className: "w100n-docs-empty", children: [
488
+ /* @__PURE__ */ jsx6(FileText, { "aria-hidden": true }),
329
489
  t.pick
330
490
  ] });
331
491
  if (here.documentId) {
@@ -333,116 +493,158 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place, onP
333
493
  doc.retry();
334
494
  content.retry();
335
495
  });
336
- else if (!doc.data || !content.data) stage = /* @__PURE__ */ jsx5("div", { className: "w100n-docs-empty", children: t.loading });
337
- else if (doc.data.kind === "markdown") stage = /* @__PURE__ */ jsx5(MarkdownView, { bytes: content.data, onOutline: setOutline });
338
- else if (doc.data.kind === "docx") stage = /* @__PURE__ */ jsx5(DocxView, { bytes: content.data, onOutline: setOutline, failed: t.failed });
339
- else if (doc.data.kind === "pdf") stage = /* @__PURE__ */ jsx5(PdfView, { bytes: content.data, worker: host.pdfWorker, onOutline: setOutline, failed: t.failed });
340
- else if (doc.data.kind === "slides") stage = /* @__PURE__ */ jsx5(SlidesView, { bytes: content.data, title: doc.data.name });
341
- else stage = /* @__PURE__ */ jsx5("div", { className: "w100n-docs-empty", children: t.unsupported });
496
+ else if (!doc.data || !content.data) stage = /* @__PURE__ */ jsx6("div", { className: "w100n-docs-empty", children: t.loading });
497
+ else if (doc.data.kind === "markdown") stage = /* @__PURE__ */ jsx6(MarkdownView, { bytes: content.data, onOutline: setOutline });
498
+ else if (doc.data.kind === "docx") stage = /* @__PURE__ */ jsx6(DocxView, { bytes: content.data, onOutline: setOutline, failed: t.failed });
499
+ else if (doc.data.kind === "pdf") stage = /* @__PURE__ */ jsx6(PdfView, { bytes: content.data, worker: host.pdfWorker, onOutline: setOutline, failed: t.failed });
500
+ else if (doc.data.kind === "slides") stage = /* @__PURE__ */ jsx6(SlidesView, { bytes: content.data, title: doc.data.name });
501
+ else stage = /* @__PURE__ */ jsx6("div", { className: "w100n-docs-empty", children: t.unsupported });
342
502
  }
503
+ const Kind = doc.data ? icons[doc.data.kind] : FileText;
504
+ const crumbs = doc.data ? [names.get(doc.data.spaceId), doc.data.folder].filter(Boolean) : space ? [space.name] : [];
343
505
  const panelTabs = [["outline", ListTree, t.outline], ["versions", History, t.versions], ["details", Info, t.details]];
344
- return /* @__PURE__ */ jsxs3("div", { className: "w100n-docs", "data-theme": theme, children: [
345
- /* @__PURE__ */ jsxs3("header", { className: "w100n-docs-bar w100n-docs-island", children: [
506
+ return /* @__PURE__ */ jsxs4("div", { ref: root, className: "w100n-docs", "data-theme": theme, children: [
507
+ /* @__PURE__ */ jsxs4("header", { className: "w100n-docs-bar", children: [
346
508
  start,
347
- /* @__PURE__ */ jsx5("button", { type: "button", className: "w100n-docs-icon", onClick: () => setListOpen(!listOpen), "aria-label": listOpen ? t.closeList : t.openList, title: listOpen ? t.closeList : t.openList, children: listOpen ? /* @__PURE__ */ jsx5(PanelLeftClose, {}) : /* @__PURE__ */ jsx5(PanelLeftOpen, {}) }),
348
- /* @__PURE__ */ jsx5("strong", { className: "w100n-docs-title", children: doc.data?.name ?? t.documents }),
349
- doc.data && /* @__PURE__ */ jsx5("span", { className: "w100n-docs-badge", "data-kind": doc.data.kind, children: t.kinds[doc.data.kind] }),
350
- versionId && /* @__PURE__ */ jsx5("span", { className: "w100n-docs-badge", children: versions.data?.find((v) => v.id === versionId) && date(versions.data.find((v) => v.id === versionId).createdAt) }),
351
- versionId && here.documentId && host.restore && doc.data?.rights.edit && /* @__PURE__ */ jsxs3("button", { type: "button", className: "w100n-docs-action", disabled: restoring === "busy", onClick: () => void restore(here.documentId, versionId), children: [
352
- /* @__PURE__ */ jsx5(RotateCcw, { "aria-hidden": true }),
509
+ /* @__PURE__ */ jsx6("span", { className: "w100n-docs-tile", "data-kind": doc.data?.kind, children: /* @__PURE__ */ jsx6(Kind, { "aria-hidden": true }) }),
510
+ /* @__PURE__ */ jsxs4("div", { className: "w100n-docs-heading", children: [
511
+ /* @__PURE__ */ jsx6("strong", { className: "w100n-docs-title", children: doc.data?.name ?? t.documents }),
512
+ crumbs.length > 0 && /* @__PURE__ */ jsx6("span", { className: "w100n-docs-crumbs", children: crumbs.map((item, i) => /* @__PURE__ */ jsxs4("span", { children: [
513
+ i > 0 && /* @__PURE__ */ jsx6(ChevronRight, { "aria-hidden": true }),
514
+ item
515
+ ] }, i)) })
516
+ ] }),
517
+ doc.data && /* @__PURE__ */ jsx6("span", { className: "w100n-docs-badge", "data-kind": doc.data.kind, children: t.kinds[doc.data.kind] }),
518
+ versionId && /* @__PURE__ */ jsx6("span", { className: "w100n-docs-badge", children: versions.data?.find((v) => v.id === versionId) && date(versions.data.find((v) => v.id === versionId).createdAt) }),
519
+ versionId && here.documentId && host.restore && doc.data?.rights.edit && /* @__PURE__ */ jsxs4("button", { type: "button", className: "w100n-docs-action", disabled: restoring === "busy", onClick: () => void restore(here.documentId, versionId), children: [
520
+ /* @__PURE__ */ jsx6(RotateCcw, { "aria-hidden": true }),
353
521
  t.restore
354
522
  ] }),
355
- restoring === "failed" && /* @__PURE__ */ jsx5("span", { className: "w100n-docs-muted", children: t.restoreFailed }),
356
- end && /* @__PURE__ */ jsx5("div", { className: "w100n-docs-end", children: end })
523
+ restoring === "failed" && /* @__PURE__ */ jsx6("span", { className: "w100n-docs-muted", children: t.restoreFailed }),
524
+ doc.data && !versionId && actions?.(doc.data),
525
+ end && /* @__PURE__ */ jsx6("div", { className: "w100n-docs-end", children: end })
357
526
  ] }),
358
- /* @__PURE__ */ jsxs3("div", { className: "w100n-docs-body", children: [
359
- listOpen && /* @__PURE__ */ jsxs3("aside", { ref: listRef, className: "w100n-docs-list w100n-docs-island", "aria-label": t.documents, children: [
360
- (spaces.data?.length ?? 0) > 1 && /* @__PURE__ */ jsxs3("div", { className: "w100n-docs-picker", children: [
361
- /* @__PURE__ */ jsxs3("button", { type: "button", className: "w100n-docs-field", "aria-haspopup": "listbox", "aria-expanded": picking, onClick: () => setPicking(!picking), children: [
362
- /* @__PURE__ */ jsx5("span", { className: "w100n-docs-dot", style: { background: space?.color ?? void 0 } }),
363
- space?.name ?? t.space,
364
- /* @__PURE__ */ jsx5(ChevronDown, { "aria-hidden": true })
527
+ /* @__PURE__ */ jsxs4("div", { className: "w100n-docs-body", children: [
528
+ listOpen ? /* @__PURE__ */ jsxs4("aside", { className: "w100n-docs-side w100n-docs-list", "aria-label": t.documents, children: [
529
+ /* @__PURE__ */ jsxs4("div", { className: "w100n-docs-head", children: [
530
+ /* @__PURE__ */ jsxs4("div", { className: "w100n-docs-row", children: [
531
+ /* @__PURE__ */ jsxs4("p", { className: "w100n-docs-caption", children: [
532
+ /* @__PURE__ */ jsx6(Files, { "aria-hidden": true }),
533
+ t.documents,
534
+ /* @__PURE__ */ jsx6("span", { children: all.length })
535
+ ] }),
536
+ /* @__PURE__ */ jsx6("button", { type: "button", className: "w100n-docs-close", onClick: () => setListOpen(false), "aria-label": t.closeList, title: t.closeList, children: /* @__PURE__ */ jsx6(X, { "aria-hidden": true }) })
365
537
  ] }),
366
- picking && /* @__PURE__ */ jsx5("ul", { role: "listbox", className: "w100n-docs-menu", children: (spaces.data ?? []).map((item) => /* @__PURE__ */ jsx5("li", { children: /* @__PURE__ */ jsxs3("button", { type: "button", role: "option", "aria-selected": item.id === spaceId, onClick: () => {
367
- setPicking(false);
368
- go({ spaceId: item.id, documentId: null });
369
- }, children: [
370
- /* @__PURE__ */ jsx5("span", { className: "w100n-docs-dot", style: { background: item.color ?? void 0 } }),
371
- item.name
372
- ] }) }, item.id)) })
373
- ] }),
374
- /* @__PURE__ */ jsxs3("label", { className: "w100n-docs-field w100n-docs-search", children: [
375
- /* @__PURE__ */ jsx5(Search, { "aria-hidden": true }),
376
- /* @__PURE__ */ jsx5("input", { value: query, onChange: (event) => setQuery(event.target.value), placeholder: t.search, "aria-label": t.search })
538
+ (spaces.data?.length ?? 0) > 1 && /* @__PURE__ */ jsxs4("div", { className: "w100n-docs-picker", children: [
539
+ /* @__PURE__ */ jsxs4("button", { type: "button", className: "w100n-docs-field", "aria-haspopup": "listbox", "aria-expanded": picking, onClick: () => setPicking(!picking), children: [
540
+ space ? /* @__PURE__ */ jsx6("span", { className: "w100n-docs-dot", style: { background: space.color ?? void 0 } }) : /* @__PURE__ */ jsx6("span", { className: "w100n-docs-all", children: /* @__PURE__ */ jsx6(LayoutGrid, { "aria-hidden": true }) }),
541
+ /* @__PURE__ */ jsx6("b", { children: space?.name ?? t.allProjects }),
542
+ !space && /* @__PURE__ */ jsx6("span", { className: "w100n-docs-count", children: all.length }),
543
+ /* @__PURE__ */ jsx6(ChevronDown, { "aria-hidden": true })
544
+ ] }),
545
+ picking && /* @__PURE__ */ jsxs4("div", { role: "listbox", className: "w100n-docs-menu", children: [
546
+ /* @__PURE__ */ jsxs4("button", { type: "button", role: "option", "aria-selected": !spaceId, onClick: () => pick(null), children: [
547
+ /* @__PURE__ */ jsx6("span", { className: "w100n-docs-all", children: /* @__PURE__ */ jsx6(LayoutGrid, { "aria-hidden": true }) }),
548
+ /* @__PURE__ */ jsx6("b", { children: t.allProjects }),
549
+ !spaceId && /* @__PURE__ */ jsx6(Check, { "aria-hidden": true })
550
+ ] }),
551
+ groups.map((group) => /* @__PURE__ */ jsxs4("div", { role: "group", "aria-label": group || void 0, children: [
552
+ group && /* @__PURE__ */ jsx6("p", { className: "w100n-docs-menu-caption", children: group }),
553
+ (spaces.data ?? []).filter((item) => (item.group ?? "") === group).map((item) => /* @__PURE__ */ jsxs4("button", { type: "button", role: "option", "aria-selected": item.id === spaceId, onClick: () => pick(item.id), children: [
554
+ /* @__PURE__ */ jsx6("span", { className: "w100n-docs-dot", style: { background: item.color ?? void 0 } }),
555
+ /* @__PURE__ */ jsx6("b", { children: item.name }),
556
+ !spaceId && counts.get(item.id) ? /* @__PURE__ */ jsx6("span", { className: "w100n-docs-count", children: counts.get(item.id) }) : null,
557
+ item.id === spaceId && /* @__PURE__ */ jsx6(Check, { "aria-hidden": true })
558
+ ] }, item.id))
559
+ ] }, group))
560
+ ] })
561
+ ] }),
562
+ /* @__PURE__ */ jsxs4("label", { className: "w100n-docs-field w100n-docs-search", children: [
563
+ /* @__PURE__ */ jsx6(Search, { "aria-hidden": true }),
564
+ /* @__PURE__ */ jsx6("input", { value: query, onChange: (event) => setQuery(event.target.value), placeholder: t.search, "aria-label": t.search })
565
+ ] }),
566
+ present.length > 1 && /* @__PURE__ */ jsx6("div", { className: "w100n-docs-chips", role: "group", children: ["all", ...present].map((item) => /* @__PURE__ */ jsxs4("button", { type: "button", "aria-pressed": kind === item, onClick: () => setKind(item), children: [
567
+ item === "all" ? t.all : t.kinds[item],
568
+ /* @__PURE__ */ jsx6("span", { "aria-hidden": true, children: item === "all" ? all.length : all.filter((doc2) => doc2.kind === item).length })
569
+ ] }, item)) })
377
570
  ] }),
378
- present.length > 1 && /* @__PURE__ */ jsx5("div", { className: "w100n-docs-chips", role: "group", children: ["all", ...present].map((item) => /* @__PURE__ */ jsx5("button", { type: "button", "aria-pressed": kind === item, onClick: () => setKind(item), children: item === "all" ? t.all : t.kinds[item] }, item)) }),
379
- /* @__PURE__ */ jsxs3("div", { className: "w100n-docs-cards", children: [
571
+ /* @__PURE__ */ jsxs4("div", { className: "w100n-docs-cards", children: [
380
572
  list.error && failed(list.retry),
381
- list.loading && !list.data && /* @__PURE__ */ jsx5("p", { className: "w100n-docs-muted", children: t.loading }),
382
- list.data && !shown.length && /* @__PURE__ */ jsx5("p", { className: "w100n-docs-muted", children: list.data.length ? t.nothing : t.empty }),
383
- folders.map((folder) => /* @__PURE__ */ jsxs3("div", { className: "w100n-docs-folder", role: "group", "aria-label": folder || t.loose, children: [
384
- folders.length > 1 && /* @__PURE__ */ jsx5("p", { className: "w100n-docs-group", children: folder || t.loose }),
385
- shown.filter((item) => (item.folder ?? "") === folder).map((item) => {
386
- const Icon = icons[item.kind];
387
- return /* @__PURE__ */ jsxs3("button", { type: "button", className: "w100n-docs-card", "aria-current": item.id === here.documentId, onClick: () => open(item.id), children: [
388
- item.thumbnailUrl ? /* @__PURE__ */ jsx5("img", { src: item.thumbnailUrl, alt: "", className: "w100n-docs-thumb" }) : /* @__PURE__ */ jsx5("span", { className: "w100n-docs-thumb", "data-kind": item.kind, children: /* @__PURE__ */ jsx5(Icon, { "aria-hidden": true }) }),
389
- /* @__PURE__ */ jsxs3("span", { className: "w100n-docs-card-text", children: [
390
- /* @__PURE__ */ jsx5("b", { children: item.name }),
391
- /* @__PURE__ */ jsxs3("small", { children: [
392
- t.kinds[item.kind],
393
- " \xB7 ",
394
- date(item.updatedAt)
395
- ] })
396
- ] })
397
- ] }, item.id);
398
- })
573
+ list.loading && !list.data && /* @__PURE__ */ jsx6("p", { className: "w100n-docs-muted", children: t.loading }),
574
+ list.data && !shown.length && /* @__PURE__ */ jsx6("p", { className: "w100n-docs-muted", children: all.length ? t.nothing : t.empty }),
575
+ folders.map((folder) => /* @__PURE__ */ jsxs4("div", { className: "w100n-docs-folder", role: "group", "aria-label": folder || t.loose, children: [
576
+ folders.length > 1 && /* @__PURE__ */ jsx6("p", { className: "w100n-docs-group", children: folder || t.loose }),
577
+ /* @__PURE__ */ jsx6("div", { className: "w100n-docs-grid", children: shown.filter((item) => !spaceId || (item.folder ?? "") === folder).map((item) => /* @__PURE__ */ jsxs4("button", { type: "button", className: "w100n-docs-card", "aria-current": item.id === here.documentId, onClick: () => open(item), title: item.name, children: [
578
+ /* @__PURE__ */ jsx6(Thumb, { host, item, label: t.kinds[item.kind] }),
579
+ /* @__PURE__ */ jsxs4("span", { className: "w100n-docs-card-text", children: [
580
+ /* @__PURE__ */ jsx6("b", { children: item.name }),
581
+ /* @__PURE__ */ jsx6("small", { children: [!spaceId && names.get(item.spaceId), ago(item.updatedAt)].filter(Boolean).join(" \xB7 ") })
582
+ ] })
583
+ ] }, item.id)) })
399
584
  ] }, folder))
400
585
  ] })
586
+ ] }) : /* @__PURE__ */ jsx6("button", { type: "button", className: "w100n-docs-reopen", onClick: () => setListOpen(true), "aria-label": t.openList, title: t.openList, children: /* @__PURE__ */ jsx6(PanelLeftOpen, { "aria-hidden": true }) }),
587
+ /* @__PURE__ */ jsxs4("main", { className: "w100n-docs-stage", children: [
588
+ doc.data && /* @__PURE__ */ jsxs4("div", { className: "w100n-docs-zoom", role: "group", children: [
589
+ /* @__PURE__ */ jsx6("button", { type: "button", onClick: () => setZoom(Math.max(50, zoom - 10)), "aria-label": t.zoomOut, title: t.zoomOut, children: /* @__PURE__ */ jsx6(Minus, { "aria-hidden": true }) }),
590
+ /* @__PURE__ */ jsxs4("span", { children: [
591
+ zoom,
592
+ "%"
593
+ ] }),
594
+ /* @__PURE__ */ jsx6("button", { type: "button", onClick: () => setZoom(Math.min(200, zoom + 10)), "aria-label": t.zoomIn, title: t.zoomIn, children: /* @__PURE__ */ jsx6(Plus, { "aria-hidden": true }) }),
595
+ /* @__PURE__ */ jsx6("button", { type: "button", onClick: () => setZoom(100), "aria-label": t.fit, title: t.fit, children: /* @__PURE__ */ jsx6(Maximize2, { "aria-hidden": true }) })
596
+ ] }),
597
+ doc.data && !panelOpen && /* @__PURE__ */ jsx6("button", { type: "button", className: "w100n-docs-reopen w100n-docs-reopen-right", onClick: () => setPanelOpen(true), "aria-label": t.openPanel, title: t.openPanel, children: /* @__PURE__ */ jsx6(PanelRightOpen, { "aria-hidden": true }) }),
598
+ /* @__PURE__ */ jsx6("div", { className: "w100n-docs-scroll", children: /* @__PURE__ */ jsx6("div", { className: "w100n-docs-zoomed", style: { zoom: zoom / 100 }, children: stage }) })
401
599
  ] }),
402
- /* @__PURE__ */ jsx5("main", { className: "w100n-docs-stage", children: stage }),
403
- doc.data && /* @__PURE__ */ jsxs3("aside", { className: "w100n-docs-panel w100n-docs-island", children: [
404
- /* @__PURE__ */ jsx5("div", { className: "w100n-docs-tabs", role: "tablist", children: panelTabs.map(([key, Icon, label]) => /* @__PURE__ */ jsxs3("button", { type: "button", role: "tab", "aria-selected": tab === key, onClick: () => setTab(key), children: [
405
- /* @__PURE__ */ jsx5(Icon, { "aria-hidden": true }),
406
- label
407
- ] }, key)) }),
408
- tab === "outline" && (outline.length ? /* @__PURE__ */ jsx5("nav", { className: "w100n-docs-outline", children: outline.map((item) => /* @__PURE__ */ jsx5("button", { type: "button", "data-level": item.level, onClick: () => document.getElementById(item.id)?.scrollIntoView({ behavior: "smooth", block: "start" }), children: item.text }, item.id)) }) : /* @__PURE__ */ jsx5("p", { className: "w100n-docs-muted", children: t.noOutline })),
409
- tab === "versions" && /* @__PURE__ */ jsxs3("div", { className: "w100n-docs-versions", children: [
410
- versions.error && failed(versions.retry),
411
- (versions.data ?? []).map((item) => /* @__PURE__ */ jsxs3(
412
- "button",
413
- {
414
- type: "button",
415
- "aria-pressed": (versionId ?? "current") === item.id || !versionId && item.current,
416
- onClick: () => {
417
- setRestoring("idle");
418
- setVersion({ documentId: here.documentId, id: item.current ? null : item.id });
600
+ doc.data && panelOpen && /* @__PURE__ */ jsxs4("aside", { className: "w100n-docs-side w100n-docs-panel", "aria-label": t.details, children: [
601
+ /* @__PURE__ */ jsx6("div", { className: "w100n-docs-head", children: /* @__PURE__ */ jsxs4("div", { className: "w100n-docs-row", children: [
602
+ /* @__PURE__ */ jsx6("div", { className: "w100n-docs-tabs", role: "tablist", children: panelTabs.map(([key, Icon, label]) => /* @__PURE__ */ jsxs4("button", { type: "button", role: "tab", "aria-selected": tab === key, onClick: () => setTab(key), children: [
603
+ /* @__PURE__ */ jsx6(Icon, { "aria-hidden": true }),
604
+ label
605
+ ] }, key)) }),
606
+ /* @__PURE__ */ jsx6("button", { type: "button", className: "w100n-docs-close", onClick: () => setPanelOpen(false), "aria-label": t.closePanel, title: t.closePanel, children: /* @__PURE__ */ jsx6(X, { "aria-hidden": true }) })
607
+ ] }) }),
608
+ /* @__PURE__ */ jsxs4("div", { className: "w100n-docs-panel-body", children: [
609
+ tab === "outline" && (outline.length ? /* @__PURE__ */ jsx6("nav", { className: "w100n-docs-outline", children: outline.map((item) => /* @__PURE__ */ jsx6("button", { type: "button", "data-level": item.level, onClick: () => document.getElementById(item.id)?.scrollIntoView({ behavior: "smooth", block: "start" }), children: item.text }, item.id)) }) : /* @__PURE__ */ jsx6("p", { className: "w100n-docs-muted", children: t.noOutline })),
610
+ tab === "versions" && /* @__PURE__ */ jsxs4("div", { className: "w100n-docs-versions", children: [
611
+ versions.error && failed(versions.retry),
612
+ (versions.data ?? []).map((item) => /* @__PURE__ */ jsxs4(
613
+ "button",
614
+ {
615
+ type: "button",
616
+ "aria-pressed": (versionId ?? "current") === item.id || !versionId && item.current,
617
+ onClick: () => {
618
+ setRestoring("idle");
619
+ setVersion({ documentId: here.documentId, id: item.current ? null : item.id });
620
+ },
621
+ children: [
622
+ /* @__PURE__ */ jsxs4("b", { children: [
623
+ date(item.createdAt),
624
+ item.current && /* @__PURE__ */ jsx6("span", { className: "w100n-docs-badge", children: t.current })
625
+ ] }),
626
+ /* @__PURE__ */ jsx6("small", { children: [item.author?.name, size(item.size), item.note].filter(Boolean).join(" \xB7 ") })
627
+ ]
419
628
  },
420
- children: [
421
- /* @__PURE__ */ jsxs3("b", { children: [
422
- date(item.createdAt),
423
- item.current && /* @__PURE__ */ jsx5("span", { className: "w100n-docs-badge", children: t.current })
424
- ] }),
425
- /* @__PURE__ */ jsx5("small", { children: [item.author?.name, size(item.size), item.note].filter(Boolean).join(" \xB7 ") })
426
- ]
427
- },
428
- item.id
429
- ))
430
- ] }),
431
- tab === "details" && /* @__PURE__ */ jsxs3("dl", { className: "w100n-docs-details", children: [
432
- /* @__PURE__ */ jsx5("dt", { children: t.kind }),
433
- /* @__PURE__ */ jsx5("dd", { children: t.kinds[doc.data.kind] }),
434
- /* @__PURE__ */ jsx5("dt", { children: t.size }),
435
- /* @__PURE__ */ jsx5("dd", { children: size(doc.data.size) }),
436
- /* @__PURE__ */ jsx5("dt", { children: t.updated }),
437
- /* @__PURE__ */ jsx5("dd", { children: date(doc.data.updatedAt) }),
438
- doc.data.updatedBy && /* @__PURE__ */ jsxs3(Fragment3, { children: [
439
- /* @__PURE__ */ jsx5("dt", { children: t.by }),
440
- /* @__PURE__ */ jsx5("dd", { children: doc.data.updatedBy.name })
629
+ item.id
630
+ ))
441
631
  ] }),
442
- /* @__PURE__ */ jsx5("dt", { children: t.rights }),
443
- /* @__PURE__ */ jsx5("dd", { children: [doc.data.rights.view && t.view, doc.data.rights.comment && t.comment, doc.data.rights.edit && t.edit].filter(Boolean).join(", ") })
444
- ] }),
445
- aside?.(doc.data)
632
+ tab === "details" && /* @__PURE__ */ jsxs4("dl", { className: "w100n-docs-details", children: [
633
+ /* @__PURE__ */ jsx6("dt", { children: t.kind }),
634
+ /* @__PURE__ */ jsx6("dd", { children: t.kinds[doc.data.kind] }),
635
+ /* @__PURE__ */ jsx6("dt", { children: t.size }),
636
+ /* @__PURE__ */ jsx6("dd", { children: size(doc.data.size) }),
637
+ /* @__PURE__ */ jsx6("dt", { children: t.updated }),
638
+ /* @__PURE__ */ jsx6("dd", { children: date(doc.data.updatedAt) }),
639
+ doc.data.updatedBy && /* @__PURE__ */ jsxs4(Fragment4, { children: [
640
+ /* @__PURE__ */ jsx6("dt", { children: t.by }),
641
+ /* @__PURE__ */ jsx6("dd", { children: doc.data.updatedBy.name })
642
+ ] }),
643
+ /* @__PURE__ */ jsx6("dt", { children: t.rights }),
644
+ /* @__PURE__ */ jsx6("dd", { children: [doc.data.rights.view && t.view, doc.data.rights.comment && t.comment, doc.data.rights.edit && t.edit].filter(Boolean).join(", ") })
645
+ ] }),
646
+ aside?.(doc.data)
647
+ ] })
446
648
  ] })
447
649
  ] })
448
650
  ] });