react-os-shell 0.6.4 → 0.6.7
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.d.ts +52 -1
- package/dist/index.js +309 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -298,6 +298,57 @@ declare function GlobalSearch({ providers, typeIcons, placeholder }?: GlobalSear
|
|
|
298
298
|
|
|
299
299
|
declare function ShortcutHelp(): react_jsx_runtime.JSX.Element;
|
|
300
300
|
|
|
301
|
+
/**
|
|
302
|
+
* One help article. Generic shape — the consuming portal maps its own
|
|
303
|
+
* help-doc records onto this before passing them in.
|
|
304
|
+
*/
|
|
305
|
+
interface HelpCenterDoc {
|
|
306
|
+
id: string;
|
|
307
|
+
slug: string;
|
|
308
|
+
title: string;
|
|
309
|
+
body: string;
|
|
310
|
+
/** Grouping key (e.g. `'getting_started'`). */
|
|
311
|
+
category: string;
|
|
312
|
+
/** Group header text (e.g. "Getting Started"). */
|
|
313
|
+
category_label: string;
|
|
314
|
+
/** When `false`, a "Draft" badge is shown. Omit for always-published docs. */
|
|
315
|
+
is_published?: boolean;
|
|
316
|
+
}
|
|
317
|
+
interface HelpCenterProps {
|
|
318
|
+
docs: HelpCenterDoc[];
|
|
319
|
+
loading?: boolean;
|
|
320
|
+
/**
|
|
321
|
+
* Category keys in display order. Categories not listed fall to the end in
|
|
322
|
+
* first-seen order. Without it, groups follow first-seen order.
|
|
323
|
+
*/
|
|
324
|
+
categoryOrder?: string[];
|
|
325
|
+
/** Show the New/Edit affordances (consumer gates this on write permission). */
|
|
326
|
+
canEdit?: boolean;
|
|
327
|
+
onNew?: () => void;
|
|
328
|
+
onEdit?: (doc: HelpCenterDoc) => void;
|
|
329
|
+
/** Custom body renderer; defaults to preformatted text. */
|
|
330
|
+
renderBody?: (doc: HelpCenterDoc) => ReactNode;
|
|
331
|
+
emptyMessage?: string;
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* In-app help / documentation viewer. Two panes: a searchable, collapsible
|
|
335
|
+
* category tree on the left, the selected article's body on the right.
|
|
336
|
+
*
|
|
337
|
+
* Presentational only — it holds no API or permission knowledge. The consumer
|
|
338
|
+
* fetches its own help docs, maps them to `HelpCenterDoc`, and (for editors)
|
|
339
|
+
* wires `canEdit` + `onNew`/`onEdit` to its own create/edit UI.
|
|
340
|
+
*
|
|
341
|
+
* Search is client-side: a case-insensitive substring match over title, body
|
|
342
|
+
* and category label. While searching, matching groups auto-expand.
|
|
343
|
+
*/
|
|
344
|
+
declare function HelpCenter({ docs, loading, categoryOrder, canEdit, onNew, onEdit, renderBody, emptyMessage, }: HelpCenterProps): react_jsx_runtime.JSX.Element;
|
|
345
|
+
|
|
346
|
+
interface MarkdownProps {
|
|
347
|
+
children: string;
|
|
348
|
+
className?: string;
|
|
349
|
+
}
|
|
350
|
+
declare function Markdown({ children, className }: MarkdownProps): react_jsx_runtime.JSX.Element;
|
|
351
|
+
|
|
301
352
|
declare const isMac: boolean;
|
|
302
353
|
/** Platform-aware modifier symbols */
|
|
303
354
|
declare const MOD: string;
|
|
@@ -1217,4 +1268,4 @@ declare function useNewHotkey(callback: () => void): void;
|
|
|
1217
1268
|
*/
|
|
1218
1269
|
declare function useEditHotkey(callback: (() => void) | null): void;
|
|
1219
1270
|
|
|
1220
|
-
export { ALT, ALT_SHIFT_D, ALT_SHIFT_E, ALT_SHIFT_N, BehaviorPanel, type BugReport, type BugReportConfig, BugReportConfigProvider, BugReportDetail, type BugReportExtraField, type BugReportExtraSelectField, BugReportProvider, type BugReportSubmission, type BugReportSubmitPayload, CMD_A, CMD_DOT, CMD_ENTER, CMD_K, CMD_S, CancelButton, type CellStyle, type ChangelogEntry, type ColumnDef, ConfirmProvider, CopyButton, Customization, type CustomizationOmitSection, type CustomizationProps, Desktop, type DesktopHostConfig, DesktopHostProvider, DocFavStar, ENTER, EditableGrid, type EditableGridProps, type EntityFetcher, EntityList, type EntityListColumn, type EntityListProps, GLASS_DIVIDER, GLASS_INPUT_BG, GlobalSearch, type GridColumn, Layout, type LayoutProps, ListFooter, type LoginPayload, MOD, type MailCapabilities, MailConnectModal, type MailUser, Modal, ModalActions, NotificationBell, type NotificationsConfig, type PaginatedResponse, PopupMenu, PopupMenuDivider, PopupMenuItem, PopupMenuLabel, type ReportType, ResizableTable, SHIFT, type SearchConfig, type SearchProvider, type SearchResult, type SemanticGroup, type ShellAuth, ShellAuthProvider, ShellEntityFetcherProvider, type ShellNotification, type ShellPrefsAdapter, ShellPrefsProvider, ShortcutHelp, type SortState, SoundsPanel, StartMenu, StatusBadge, StatusBadgeProvider, type StickyEntityRef, type StickyResolver, SystemPreferences, type SystemPreferencesProps, type SystemPreferencesSection, VERSION, WindowManagerProvider, WindowRegistry, WindowTitle, commitExposeHighlight, confirm, confirmDestructive, createWindowRegistry, exitExposeMode, formatDate, getActiveWindowRoute, getExposeHighlight, glassStyle, isMac, openBugReportDialog, prompt, reportBug, setExposeHighlight, setShellApiClient, setShellAuthBridge, setShellMailServer, setShellNavIcons, setWindowDefaultPosition, subscribeExposeHighlight, toast, toggleExposeMode, useBugReport, useClickOutside, useColumnConfig, useDesktopHost, useEditHotkey, useInfiniteScroll, useLocalStoragePrefs, useMailAuth, useModalActive, useNewHotkey, useShellAuth, useShellEntityFetcher, useShellPrefs, useSort, useTableNav, useWidgetSettings, useWindowManager, useWindowMenuItem, useWindowTitle };
|
|
1271
|
+
export { ALT, ALT_SHIFT_D, ALT_SHIFT_E, ALT_SHIFT_N, BehaviorPanel, type BugReport, type BugReportConfig, BugReportConfigProvider, BugReportDetail, type BugReportExtraField, type BugReportExtraSelectField, BugReportProvider, type BugReportSubmission, type BugReportSubmitPayload, CMD_A, CMD_DOT, CMD_ENTER, CMD_K, CMD_S, CancelButton, type CellStyle, type ChangelogEntry, type ColumnDef, ConfirmProvider, CopyButton, Customization, type CustomizationOmitSection, type CustomizationProps, Desktop, type DesktopHostConfig, DesktopHostProvider, DocFavStar, ENTER, EditableGrid, type EditableGridProps, type EntityFetcher, EntityList, type EntityListColumn, type EntityListProps, GLASS_DIVIDER, GLASS_INPUT_BG, GlobalSearch, type GridColumn, HelpCenter, type HelpCenterDoc, type HelpCenterProps, Layout, type LayoutProps, ListFooter, type LoginPayload, MOD, type MailCapabilities, MailConnectModal, type MailUser, Markdown, type MarkdownProps, Modal, ModalActions, NotificationBell, type NotificationsConfig, type PaginatedResponse, PopupMenu, PopupMenuDivider, PopupMenuItem, PopupMenuLabel, type ReportType, ResizableTable, SHIFT, type SearchConfig, type SearchProvider, type SearchResult, type SemanticGroup, type ShellAuth, ShellAuthProvider, ShellEntityFetcherProvider, type ShellNotification, type ShellPrefsAdapter, ShellPrefsProvider, ShortcutHelp, type SortState, SoundsPanel, StartMenu, StatusBadge, StatusBadgeProvider, type StickyEntityRef, type StickyResolver, SystemPreferences, type SystemPreferencesProps, type SystemPreferencesSection, VERSION, WindowManagerProvider, WindowRegistry, WindowTitle, commitExposeHighlight, confirm, confirmDestructive, createWindowRegistry, exitExposeMode, formatDate, getActiveWindowRoute, getExposeHighlight, glassStyle, isMac, openBugReportDialog, prompt, reportBug, setExposeHighlight, setShellApiClient, setShellAuthBridge, setShellMailServer, setShellNavIcons, setWindowDefaultPosition, subscribeExposeHighlight, toast, toggleExposeMode, useBugReport, useClickOutside, useColumnConfig, useDesktopHost, useEditHotkey, useInfiniteScroll, useLocalStoragePrefs, useMailAuth, useModalActive, useNewHotkey, useShellAuth, useShellEntityFetcher, useShellPrefs, useSort, useTableNav, useWidgetSettings, useWindowManager, useWindowMenuItem, useWindowTitle };
|
package/dist/index.js
CHANGED
|
@@ -21,7 +21,7 @@ import { useAuth, useShellAuth } from './chunk-ADJ3CERD.js';
|
|
|
21
21
|
export { ShellAuthProvider, setShellAuthBridge, useShellAuth } from './chunk-ADJ3CERD.js';
|
|
22
22
|
import { glassStyle, startMenuCategories, navSections, isSection, GLASS_INPUT_BG, navIcons, sectionIcons } from './chunk-ZF6AYO4G.js';
|
|
23
23
|
export { GLASS_DIVIDER, GLASS_INPUT_BG, glassStyle, setShellNavIcons } from './chunk-ZF6AYO4G.js';
|
|
24
|
-
import { createContext, lazy, useState, useRef, useEffect, useCallback, useLayoutEffect, useContext, Suspense, isValidElement, cloneElement,
|
|
24
|
+
import { createContext, lazy, useState, useRef, useEffect, useCallback, useMemo, useLayoutEffect, useContext, Suspense, isValidElement, cloneElement, useSyncExternalStore } from 'react';
|
|
25
25
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
26
26
|
import { Dialog, DialogBackdrop, DialogPanel, DialogTitle } from '@headlessui/react';
|
|
27
27
|
import { createPortal } from 'react-dom';
|
|
@@ -256,6 +256,312 @@ function ShortcutHelp() {
|
|
|
256
256
|
] }) })
|
|
257
257
|
] });
|
|
258
258
|
}
|
|
259
|
+
var INLINE_RE = /!\[([^\]]*)\]\(([^)]+)\)|\[([^\]]+)\]\(([^)]+)\)|\*\*([^*]+)\*\*|`([^`]+)`|\*([^*]+)\*/g;
|
|
260
|
+
function renderInline(text) {
|
|
261
|
+
const out = [];
|
|
262
|
+
let last = 0;
|
|
263
|
+
let key = 0;
|
|
264
|
+
let m;
|
|
265
|
+
INLINE_RE.lastIndex = 0;
|
|
266
|
+
while ((m = INLINE_RE.exec(text)) !== null) {
|
|
267
|
+
if (m.index > last) out.push(text.slice(last, m.index));
|
|
268
|
+
if (m[1] !== void 0) {
|
|
269
|
+
out.push(
|
|
270
|
+
/* @__PURE__ */ jsxs("span", { className: "text-gray-400", children: [
|
|
271
|
+
"[",
|
|
272
|
+
m[1],
|
|
273
|
+
"]"
|
|
274
|
+
] }, key++)
|
|
275
|
+
);
|
|
276
|
+
} else if (m[3] !== void 0) {
|
|
277
|
+
out.push(
|
|
278
|
+
/* @__PURE__ */ jsx(
|
|
279
|
+
"a",
|
|
280
|
+
{
|
|
281
|
+
href: m[4],
|
|
282
|
+
target: "_blank",
|
|
283
|
+
rel: "noreferrer",
|
|
284
|
+
className: "text-blue-600 hover:underline",
|
|
285
|
+
children: m[3]
|
|
286
|
+
},
|
|
287
|
+
key++
|
|
288
|
+
)
|
|
289
|
+
);
|
|
290
|
+
} else if (m[5] !== void 0) {
|
|
291
|
+
out.push(
|
|
292
|
+
/* @__PURE__ */ jsx("strong", { className: "font-semibold text-gray-900", children: m[5] }, key++)
|
|
293
|
+
);
|
|
294
|
+
} else if (m[6] !== void 0) {
|
|
295
|
+
out.push(
|
|
296
|
+
/* @__PURE__ */ jsx(
|
|
297
|
+
"code",
|
|
298
|
+
{
|
|
299
|
+
className: "rounded bg-gray-100 px-1 py-0.5 font-mono text-[0.85em] text-gray-800",
|
|
300
|
+
children: m[6]
|
|
301
|
+
},
|
|
302
|
+
key++
|
|
303
|
+
)
|
|
304
|
+
);
|
|
305
|
+
} else if (m[7] !== void 0) {
|
|
306
|
+
out.push(/* @__PURE__ */ jsx("em", { children: m[7] }, key++));
|
|
307
|
+
}
|
|
308
|
+
last = INLINE_RE.lastIndex;
|
|
309
|
+
}
|
|
310
|
+
if (last < text.length) out.push(text.slice(last));
|
|
311
|
+
return out;
|
|
312
|
+
}
|
|
313
|
+
function ScreenshotPlaceholder({ alt }) {
|
|
314
|
+
const label = alt.replace(/^screenshot:\s*/i, "");
|
|
315
|
+
return /* @__PURE__ */ jsxs("div", { className: "my-1 flex items-start gap-2 rounded-lg border border-dashed border-gray-300 bg-gray-50 px-3 py-2.5", children: [
|
|
316
|
+
/* @__PURE__ */ jsx(
|
|
317
|
+
"svg",
|
|
318
|
+
{
|
|
319
|
+
className: "mt-0.5 h-4 w-4 shrink-0 text-gray-400",
|
|
320
|
+
viewBox: "0 0 20 20",
|
|
321
|
+
fill: "currentColor",
|
|
322
|
+
"aria-hidden": "true",
|
|
323
|
+
children: /* @__PURE__ */ jsx("path", { d: "M3 6a1.5 1.5 0 0 1 1.5-1.5h1.1l.4-.9a1 1 0 0 1 .9-.6h6.2a1 1 0 0 1 .9.6l.4.9h1.1A1.5 1.5 0 0 1 18 6v8.5A1.5 1.5 0 0 1 16.5 16h-13A1.5 1.5 0 0 1 2 14.5V6Zm7.5 1.5a3.25 3.25 0 1 0 0 6.5 3.25 3.25 0 0 0 0-6.5Z" })
|
|
324
|
+
}
|
|
325
|
+
),
|
|
326
|
+
/* @__PURE__ */ jsxs("span", { className: "text-xs text-gray-500", children: [
|
|
327
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium text-gray-600", children: "Screenshot \u2014 " }),
|
|
328
|
+
label
|
|
329
|
+
] })
|
|
330
|
+
] });
|
|
331
|
+
}
|
|
332
|
+
function collectItems(lines, itemRe) {
|
|
333
|
+
const items = [];
|
|
334
|
+
for (const line of lines) {
|
|
335
|
+
const m = itemRe.exec(line);
|
|
336
|
+
if (m) {
|
|
337
|
+
items.push(m[1]);
|
|
338
|
+
} else if (items.length) {
|
|
339
|
+
items[items.length - 1] += " " + line.trim();
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
return items;
|
|
343
|
+
}
|
|
344
|
+
var splitCells = (line) => line.replace(/^\s*\|/, "").replace(/\|\s*$/, "").split("|").map((c) => c.trim());
|
|
345
|
+
function isTable(lines) {
|
|
346
|
+
return lines.length >= 2 && lines[0].includes("|") && /^\s*\|?[\s:|-]*-[\s:|-]*\|?\s*$/.test(lines[1]) && lines[1].includes("-");
|
|
347
|
+
}
|
|
348
|
+
function renderTable(lines, key) {
|
|
349
|
+
const header = splitCells(lines[0]);
|
|
350
|
+
const rows = lines.slice(2).map(splitCells);
|
|
351
|
+
return /* @__PURE__ */ jsx("div", { className: "my-1 overflow-x-auto rounded-lg border border-gray-200", children: /* @__PURE__ */ jsxs("table", { className: "w-full border-collapse text-sm", children: [
|
|
352
|
+
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsx("tr", { className: "bg-gray-50", children: header.map((h, i) => /* @__PURE__ */ jsx(
|
|
353
|
+
"th",
|
|
354
|
+
{
|
|
355
|
+
className: "border-b border-gray-200 px-3 py-1.5 text-left font-semibold text-gray-700",
|
|
356
|
+
children: renderInline(h)
|
|
357
|
+
},
|
|
358
|
+
i
|
|
359
|
+
)) }) }),
|
|
360
|
+
/* @__PURE__ */ jsx("tbody", { children: rows.map((row, r) => /* @__PURE__ */ jsx("tr", { className: "even:bg-gray-50/50", children: row.map((c, i) => /* @__PURE__ */ jsx("td", { className: "border-t border-gray-100 px-3 py-1.5 align-top text-gray-700", children: renderInline(c) }, i)) }, r)) })
|
|
361
|
+
] }) }, key);
|
|
362
|
+
}
|
|
363
|
+
function renderBlock(block, key) {
|
|
364
|
+
const lines = block.split("\n");
|
|
365
|
+
const first = lines[0];
|
|
366
|
+
const heading = /^(#{2,4})\s+(.*)$/.exec(first);
|
|
367
|
+
if (heading && lines.length === 1) {
|
|
368
|
+
const level = heading[1].length;
|
|
369
|
+
const Tag = `h${level}`;
|
|
370
|
+
const cls = level === 2 ? "mt-2 text-[13px] font-semibold uppercase tracking-wide text-gray-500" : level === 3 ? "mt-1 text-base font-semibold text-gray-900" : "mt-1 text-sm font-semibold text-gray-900";
|
|
371
|
+
return /* @__PURE__ */ jsx(Tag, { className: cls, children: renderInline(heading[2]) }, key);
|
|
372
|
+
}
|
|
373
|
+
if (lines.length === 1 && /^---+$/.test(first)) {
|
|
374
|
+
return /* @__PURE__ */ jsx("hr", { className: "border-gray-200" }, key);
|
|
375
|
+
}
|
|
376
|
+
if (isTable(lines)) {
|
|
377
|
+
return renderTable(lines, key);
|
|
378
|
+
}
|
|
379
|
+
if (/^>\s?/.test(first)) {
|
|
380
|
+
const text = lines.map((l) => l.replace(/^>\s?/, "")).join(" ");
|
|
381
|
+
return /* @__PURE__ */ jsx(
|
|
382
|
+
"div",
|
|
383
|
+
{
|
|
384
|
+
className: "my-1 rounded-r-lg border-l-4 border-blue-300 bg-blue-50/60 px-3 py-2 text-gray-700",
|
|
385
|
+
children: renderInline(text)
|
|
386
|
+
},
|
|
387
|
+
key
|
|
388
|
+
);
|
|
389
|
+
}
|
|
390
|
+
const img = /^!\[([^\]]*)\]\(([^)]+)\)$/.exec(first);
|
|
391
|
+
if (img && lines.length === 1) {
|
|
392
|
+
return /* @__PURE__ */ jsx(ScreenshotPlaceholder, { alt: img[1] }, key);
|
|
393
|
+
}
|
|
394
|
+
if (/^[-*]\s+/.test(first)) {
|
|
395
|
+
const items = collectItems(lines, /^[-*]\s+(.*)$/);
|
|
396
|
+
return /* @__PURE__ */ jsx("ul", { className: "list-disc space-y-1 pl-5 marker:text-gray-400", children: items.map((it, j) => /* @__PURE__ */ jsx("li", { children: renderInline(it) }, j)) }, key);
|
|
397
|
+
}
|
|
398
|
+
const ordered = /^(\d+)\.\s+/.exec(first);
|
|
399
|
+
if (ordered) {
|
|
400
|
+
const items = collectItems(lines, /^\d+\.\s+(.*)$/);
|
|
401
|
+
return /* @__PURE__ */ jsx(
|
|
402
|
+
"ol",
|
|
403
|
+
{
|
|
404
|
+
start: Number(ordered[1]),
|
|
405
|
+
className: "list-decimal space-y-1 pl-5 marker:text-gray-400",
|
|
406
|
+
children: items.map((it, j) => /* @__PURE__ */ jsx("li", { className: "pl-1", children: renderInline(it) }, j))
|
|
407
|
+
},
|
|
408
|
+
key
|
|
409
|
+
);
|
|
410
|
+
}
|
|
411
|
+
return /* @__PURE__ */ jsx("p", { children: renderInline(lines.join(" ")) }, key);
|
|
412
|
+
}
|
|
413
|
+
function Markdown({ children, className }) {
|
|
414
|
+
const blocks = (children ?? "").replace(/\r\n/g, "\n").split(/\n{2,}/).map((b) => b.replace(/\s+$/, "")).filter((b) => b.trim() !== "");
|
|
415
|
+
return /* @__PURE__ */ jsx("div", { className: `space-y-3 text-sm leading-relaxed text-gray-700 ${className ?? ""}`.trim(), children: blocks.map((block, i) => renderBlock(block, i)) });
|
|
416
|
+
}
|
|
417
|
+
var Chevron = ({ open }) => /* @__PURE__ */ jsx(
|
|
418
|
+
"svg",
|
|
419
|
+
{
|
|
420
|
+
className: `h-3.5 w-3.5 shrink-0 text-gray-400 transition-transform ${open ? "rotate-90" : ""}`,
|
|
421
|
+
viewBox: "0 0 20 20",
|
|
422
|
+
fill: "currentColor",
|
|
423
|
+
"aria-hidden": "true",
|
|
424
|
+
children: /* @__PURE__ */ jsx(
|
|
425
|
+
"path",
|
|
426
|
+
{
|
|
427
|
+
fillRule: "evenodd",
|
|
428
|
+
d: "M7.21 14.77a.75.75 0 0 1 .02-1.06L11.168 10 7.23 6.29a.75.75 0 1 1 1.04-1.08l4.5 4.25a.75.75 0 0 1 0 1.08l-4.5 4.25a.75.75 0 0 1-1.06-.02Z",
|
|
429
|
+
clipRule: "evenodd"
|
|
430
|
+
}
|
|
431
|
+
)
|
|
432
|
+
}
|
|
433
|
+
);
|
|
434
|
+
function HelpCenter({
|
|
435
|
+
docs,
|
|
436
|
+
loading = false,
|
|
437
|
+
categoryOrder,
|
|
438
|
+
canEdit = false,
|
|
439
|
+
onNew,
|
|
440
|
+
onEdit,
|
|
441
|
+
renderBody,
|
|
442
|
+
emptyMessage = "No help articles yet."
|
|
443
|
+
}) {
|
|
444
|
+
const [query, setQuery] = useState("");
|
|
445
|
+
const [selectedSlug, setSelectedSlug] = useState(null);
|
|
446
|
+
const [expanded, setExpanded] = useState({});
|
|
447
|
+
const q = query.trim().toLowerCase();
|
|
448
|
+
const groups = useMemo(() => {
|
|
449
|
+
const map = /* @__PURE__ */ new Map();
|
|
450
|
+
for (const doc of docs) {
|
|
451
|
+
let g = map.get(doc.category);
|
|
452
|
+
if (!g) {
|
|
453
|
+
g = { key: doc.category, label: doc.category_label || doc.category, docs: [] };
|
|
454
|
+
map.set(doc.category, g);
|
|
455
|
+
}
|
|
456
|
+
g.docs.push(doc);
|
|
457
|
+
}
|
|
458
|
+
if (!categoryOrder?.length) return [...map.values()];
|
|
459
|
+
const rank = new Map(categoryOrder.map((k, i) => [k, i]));
|
|
460
|
+
return [...map.values()].sort(
|
|
461
|
+
(a, b) => (rank.get(a.key) ?? Infinity) - (rank.get(b.key) ?? Infinity)
|
|
462
|
+
);
|
|
463
|
+
}, [docs, categoryOrder]);
|
|
464
|
+
const matches = (doc) => !q || doc.title.toLowerCase().includes(q) || doc.body.toLowerCase().includes(q) || doc.category_label.toLowerCase().includes(q);
|
|
465
|
+
const visibleGroups = useMemo(
|
|
466
|
+
() => groups.map((g) => ({ ...g, docs: g.docs.filter(matches) })).filter((g) => g.docs.length > 0),
|
|
467
|
+
[groups, q]
|
|
468
|
+
);
|
|
469
|
+
const visibleDocs = useMemo(() => visibleGroups.flatMap((g) => g.docs), [visibleGroups]);
|
|
470
|
+
const selected = (selectedSlug ? visibleDocs.find((d) => d.slug === selectedSlug) : void 0) ?? visibleDocs[0] ?? null;
|
|
471
|
+
const isGroupOpen = (key) => q ? true : expanded[key] ?? key === selected?.category;
|
|
472
|
+
const toggleGroup = (key) => setExpanded((prev) => ({ ...prev, [key]: !isGroupOpen(key) }));
|
|
473
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex h-full gap-4 px-4 py-3 min-h-0", children: [
|
|
474
|
+
/* @__PURE__ */ jsxs("aside", { className: "w-64 shrink-0 flex flex-col bg-white rounded-lg shadow overflow-hidden", children: [
|
|
475
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 px-3 py-2 border-b border-gray-200 bg-gray-50 shrink-0", children: [
|
|
476
|
+
/* @__PURE__ */ jsx("h2", { className: "text-sm font-semibold text-gray-900", children: "Help" }),
|
|
477
|
+
canEdit && onNew && /* @__PURE__ */ jsx("button", { type: "button", onClick: onNew, className: "text-xs text-blue-600 hover:underline", children: "+ New" })
|
|
478
|
+
] }),
|
|
479
|
+
/* @__PURE__ */ jsx("div", { className: "px-2.5 py-2 border-b border-gray-100 shrink-0", children: /* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
480
|
+
/* @__PURE__ */ jsx(
|
|
481
|
+
"svg",
|
|
482
|
+
{
|
|
483
|
+
className: "pointer-events-none absolute left-2.5 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400",
|
|
484
|
+
viewBox: "0 0 20 20",
|
|
485
|
+
fill: "currentColor",
|
|
486
|
+
"aria-hidden": "true",
|
|
487
|
+
children: /* @__PURE__ */ jsx(
|
|
488
|
+
"path",
|
|
489
|
+
{
|
|
490
|
+
fillRule: "evenodd",
|
|
491
|
+
d: "M9 3.5a5.5 5.5 0 1 0 3.36 9.85l3.14 3.15a.75.75 0 1 0 1.06-1.06l-3.15-3.14A5.5 5.5 0 0 0 9 3.5ZM5 9a4 4 0 1 1 8 0 4 4 0 0 1-8 0Z",
|
|
492
|
+
clipRule: "evenodd"
|
|
493
|
+
}
|
|
494
|
+
)
|
|
495
|
+
}
|
|
496
|
+
),
|
|
497
|
+
/* @__PURE__ */ jsx(
|
|
498
|
+
"input",
|
|
499
|
+
{
|
|
500
|
+
type: "text",
|
|
501
|
+
value: query,
|
|
502
|
+
onChange: (e) => setQuery(e.target.value),
|
|
503
|
+
placeholder: "Search help\u2026",
|
|
504
|
+
className: "w-full rounded-md border border-gray-300 bg-white py-1.5 pl-8 pr-2 text-sm shadow-sm focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500"
|
|
505
|
+
}
|
|
506
|
+
)
|
|
507
|
+
] }) }),
|
|
508
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 overflow-y-auto py-1", children: loading ? /* @__PURE__ */ jsx("p", { className: "px-3 py-6 text-center text-xs text-gray-400", children: "Loading\u2026" }) : visibleGroups.length === 0 ? /* @__PURE__ */ jsx("p", { className: "px-3 py-6 text-center text-xs text-gray-500", children: q ? "No articles match your search." : emptyMessage }) : visibleGroups.map((group) => {
|
|
509
|
+
const open = isGroupOpen(group.key);
|
|
510
|
+
return /* @__PURE__ */ jsxs("div", { className: "py-0.5", children: [
|
|
511
|
+
/* @__PURE__ */ jsxs(
|
|
512
|
+
"button",
|
|
513
|
+
{
|
|
514
|
+
type: "button",
|
|
515
|
+
onClick: () => toggleGroup(group.key),
|
|
516
|
+
className: "w-full flex items-center gap-1.5 px-3 py-1.5 text-left text-[10px] font-semibold uppercase tracking-wide text-gray-400 hover:text-gray-600",
|
|
517
|
+
children: [
|
|
518
|
+
/* @__PURE__ */ jsx(Chevron, { open }),
|
|
519
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: group.label })
|
|
520
|
+
]
|
|
521
|
+
}
|
|
522
|
+
),
|
|
523
|
+
open && group.docs.map((doc) => {
|
|
524
|
+
const active = selected?.slug === doc.slug;
|
|
525
|
+
return /* @__PURE__ */ jsxs(
|
|
526
|
+
"button",
|
|
527
|
+
{
|
|
528
|
+
type: "button",
|
|
529
|
+
onClick: () => setSelectedSlug(doc.slug),
|
|
530
|
+
className: `w-full text-left pl-8 pr-3 py-1.5 text-sm flex items-center gap-1.5 transition-colors ${active ? "bg-blue-50 text-blue-700 font-medium" : "text-gray-700 hover:bg-gray-50"}`,
|
|
531
|
+
children: [
|
|
532
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: doc.title }),
|
|
533
|
+
doc.is_published === false && /* @__PURE__ */ jsx("span", { className: "ml-auto shrink-0 text-[10px] text-amber-600", children: "Draft" })
|
|
534
|
+
]
|
|
535
|
+
},
|
|
536
|
+
doc.slug
|
|
537
|
+
);
|
|
538
|
+
})
|
|
539
|
+
] }, group.key);
|
|
540
|
+
}) })
|
|
541
|
+
] }),
|
|
542
|
+
/* @__PURE__ */ jsx("main", { className: "flex-1 min-w-0 bg-white rounded-lg shadow overflow-hidden flex flex-col", children: selected ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
543
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-4 px-5 py-3 border-b border-gray-200 bg-gray-50 shrink-0", children: [
|
|
544
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
545
|
+
/* @__PURE__ */ jsx("h1", { className: "text-lg font-semibold text-gray-900 truncate", children: selected.title }),
|
|
546
|
+
/* @__PURE__ */ jsxs("p", { className: "text-xs text-gray-500 mt-0.5", children: [
|
|
547
|
+
selected.category_label,
|
|
548
|
+
selected.is_published === false && /* @__PURE__ */ jsx("span", { className: "ml-2 text-amber-600", children: "\xB7 Draft" })
|
|
549
|
+
] })
|
|
550
|
+
] }),
|
|
551
|
+
canEdit && onEdit && /* @__PURE__ */ jsx(
|
|
552
|
+
"button",
|
|
553
|
+
{
|
|
554
|
+
type: "button",
|
|
555
|
+
onClick: () => onEdit(selected),
|
|
556
|
+
className: "shrink-0 text-sm text-blue-600 hover:underline",
|
|
557
|
+
children: "Edit"
|
|
558
|
+
}
|
|
559
|
+
)
|
|
560
|
+
] }),
|
|
561
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 overflow-auto px-5 py-4", children: renderBody ? renderBody(selected) : selected.body ? /* @__PURE__ */ jsx(Markdown, { children: selected.body }) : /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500 italic", children: "This article has no body yet." }) })
|
|
562
|
+
] }) : /* @__PURE__ */ jsx("div", { className: "flex-1 flex items-center justify-center px-6 text-center", children: /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500", children: loading ? "Loading\u2026" : "Pick a help article from the left." }) }) })
|
|
563
|
+
] });
|
|
564
|
+
}
|
|
259
565
|
function timeAgo(dateStr) {
|
|
260
566
|
const diff = Date.now() - new Date(dateStr).getTime();
|
|
261
567
|
const mins = Math.floor(diff / 6e4);
|
|
@@ -915,7 +1221,7 @@ function StatusBadge({ status }) {
|
|
|
915
1221
|
}
|
|
916
1222
|
|
|
917
1223
|
// src/version.ts
|
|
918
|
-
var VERSION = "0.6.
|
|
1224
|
+
var VERSION = "0.6.7" ;
|
|
919
1225
|
var APP_VERSION = VERSION;
|
|
920
1226
|
|
|
921
1227
|
// src/changelog.ts
|
|
@@ -6123,6 +6429,6 @@ function useEditHotkey(callback) {
|
|
|
6123
6429
|
}, [callback, isActive]);
|
|
6124
6430
|
}
|
|
6125
6431
|
|
|
6126
|
-
export { ALT, ALT_SHIFT_D, ALT_SHIFT_E, ALT_SHIFT_N, BehaviorPanel, BugReportConfigProvider, BugReportDetail, BugReportProvider, CMD_A, CMD_DOT, CMD_ENTER, CMD_K, CMD_S, Customization, Desktop, DesktopHostProvider, ENTER, EntityList, GlobalSearch, Layout, ListFooter, MOD, MailConnectModal, NotificationBell, ResizableTable, SHIFT, ShellEntityFetcherProvider, ShortcutHelp, SoundsPanel, StartMenu, StatusBadge, StatusBadgeProvider, SystemPreferences, VERSION, createWindowRegistry, isMac, openBugReportDialog, reportBug, useBugReport, useClickOutside, useColumnConfig, useDesktopHost, useEditHotkey, useInfiniteScroll, useNewHotkey, useShellEntityFetcher, useSort, useTableNav };
|
|
6432
|
+
export { ALT, ALT_SHIFT_D, ALT_SHIFT_E, ALT_SHIFT_N, BehaviorPanel, BugReportConfigProvider, BugReportDetail, BugReportProvider, CMD_A, CMD_DOT, CMD_ENTER, CMD_K, CMD_S, Customization, Desktop, DesktopHostProvider, ENTER, EntityList, GlobalSearch, HelpCenter, Layout, ListFooter, MOD, MailConnectModal, Markdown, NotificationBell, ResizableTable, SHIFT, ShellEntityFetcherProvider, ShortcutHelp, SoundsPanel, StartMenu, StatusBadge, StatusBadgeProvider, SystemPreferences, VERSION, createWindowRegistry, isMac, openBugReportDialog, reportBug, useBugReport, useClickOutside, useColumnConfig, useDesktopHost, useEditHotkey, useInfiniteScroll, useNewHotkey, useShellEntityFetcher, useSort, useTableNav };
|
|
6127
6433
|
//# sourceMappingURL=index.js.map
|
|
6128
6434
|
//# sourceMappingURL=index.js.map
|