@ai-matrx/vault 0.1.35 → 0.1.37
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/CHANGELOG.md +15 -1
- package/dist/index.cjs +416 -323
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +389 -296
- package/dist/index.js.map +1 -1
- package/package.json +8 -29
package/dist/index.js
CHANGED
|
@@ -58,7 +58,7 @@ import {
|
|
|
58
58
|
} from "./chunk-B5TOAIY6.js";
|
|
59
59
|
|
|
60
60
|
// src/VaultApp.tsx
|
|
61
|
-
import { useCallback as useCallback4, useEffect as
|
|
61
|
+
import { useCallback as useCallback4, useEffect as useEffect22, useMemo as useMemo6, useRef as useRef18, useState as useState40, useSyncExternalStore as useSyncExternalStore5 } from "react";
|
|
62
62
|
import { DropdownMenu as DropdownMenu5, DropdownMenuContent as DropdownMenuContent5, DropdownMenuItem as DropdownMenuItem5, DropdownMenuTrigger as DropdownMenuTrigger5, LookScope } from "@ai-matrx/design-system";
|
|
63
63
|
import { Button as Button33, SearchField as SearchField4, Select as Select12 } from "@ai-matrx/design-system/controls";
|
|
64
64
|
import { confirm as confirm14 } from "@ai-matrx/kit/confirm-opener";
|
|
@@ -881,11 +881,11 @@ function whenInDay(iso, now = /* @__PURE__ */ new Date()) {
|
|
|
881
881
|
if (dayKey(d) === dayKey(now)) return formatRelativeTime(iso, { now: now.getTime() });
|
|
882
882
|
return d.toLocaleTimeString(void 0, { hour: "numeric", minute: "2-digit" });
|
|
883
883
|
}
|
|
884
|
-
function collapseRuns(rows,
|
|
884
|
+
function collapseRuns(rows, keyOf2) {
|
|
885
885
|
const out = [];
|
|
886
886
|
const at = /* @__PURE__ */ new Map();
|
|
887
887
|
for (const row of rows) {
|
|
888
|
-
const k =
|
|
888
|
+
const k = keyOf2(row);
|
|
889
889
|
const seen = at.get(k);
|
|
890
890
|
if (seen) seen.times += 1;
|
|
891
891
|
else {
|
|
@@ -1293,14 +1293,12 @@ function CodeButton({ live, digits, size = "md", label }) {
|
|
|
1293
1293
|
disabled: !live.code,
|
|
1294
1294
|
onClick: () => live.code && void copy(live.code),
|
|
1295
1295
|
"aria-label": live.code ? `Copy ${label} code` : `Getting ${label} code`,
|
|
1296
|
+
...live.code ? { tooltip: "Copy code" } : {},
|
|
1296
1297
|
variant: "quiet",
|
|
1297
1298
|
layout: "row",
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
copied ? /* @__PURE__ */ jsx6("span", { className: "inline-flex size-6 items-center justify-center text-success", role: "status", "aria-label": "Copied", children: /* @__PURE__ */ jsx6(CheckGlyph, { className: "size-4" }) }) : /* @__PURE__ */ jsx6(CountdownRing, { remaining: live.remaining, period: live.period, loading: !live.code })
|
|
1302
|
-
] }),
|
|
1303
|
-
className: "max-w-full shrink-0"
|
|
1299
|
+
fit: true,
|
|
1300
|
+
title: /* @__PURE__ */ jsx6("span", { className: cn5("whitespace-nowrap font-mono font-medium tabular-nums tracking-[0.08em]", size === "lg" ? "text-2xl" : "text-[1.0625rem]", live.code ? "text-foreground" : "text-disabled-foreground"), children: shown }),
|
|
1301
|
+
end: copied ? /* @__PURE__ */ jsx6("span", { className: "inline-flex size-6 items-center justify-center text-success", role: "status", "aria-label": "Copied", children: /* @__PURE__ */ jsx6(CheckGlyph, { className: "size-4" }) }) : /* @__PURE__ */ jsx6(CountdownRing, { remaining: live.remaining, period: live.period, loading: !live.code })
|
|
1304
1302
|
}
|
|
1305
1303
|
);
|
|
1306
1304
|
}
|
|
@@ -1410,6 +1408,14 @@ function canDecodeQrLocally() {
|
|
|
1410
1408
|
function hasCamera() {
|
|
1411
1409
|
return typeof navigator !== "undefined" && typeof navigator.mediaDevices?.getUserMedia === "function";
|
|
1412
1410
|
}
|
|
1411
|
+
async function hasCameraDevice() {
|
|
1412
|
+
if (!hasCamera() || typeof navigator.mediaDevices?.enumerateDevices !== "function") return false;
|
|
1413
|
+
try {
|
|
1414
|
+
return (await navigator.mediaDevices.enumerateDevices()).some((d) => d.kind === "videoinput");
|
|
1415
|
+
} catch {
|
|
1416
|
+
return false;
|
|
1417
|
+
}
|
|
1418
|
+
}
|
|
1413
1419
|
async function decodeQr(source) {
|
|
1414
1420
|
return decodeQrFromElement(source);
|
|
1415
1421
|
}
|
|
@@ -1441,17 +1447,15 @@ function useCanScan() {
|
|
|
1441
1447
|
}, []);
|
|
1442
1448
|
return ok;
|
|
1443
1449
|
}
|
|
1444
|
-
function
|
|
1450
|
+
function QrScanInline({ onResult, onClose }) {
|
|
1445
1451
|
const video = useRef6(null);
|
|
1446
1452
|
const [error, setError] = useState8(null);
|
|
1447
1453
|
const done = useRef6(onResult);
|
|
1448
1454
|
done.current = onResult;
|
|
1449
1455
|
useEffect8(() => {
|
|
1450
|
-
if (!open) return;
|
|
1451
1456
|
let stream = null;
|
|
1452
1457
|
let live = true;
|
|
1453
1458
|
let timer2 = null;
|
|
1454
|
-
setError(null);
|
|
1455
1459
|
const stop = () => {
|
|
1456
1460
|
if (timer2) clearTimeout(timer2);
|
|
1457
1461
|
stream?.getTracks().forEach((t) => t.stop());
|
|
@@ -1494,13 +1498,26 @@ function QrScanPanel({ open, onResult, onClose }) {
|
|
|
1494
1498
|
live = false;
|
|
1495
1499
|
stop();
|
|
1496
1500
|
};
|
|
1497
|
-
}, [
|
|
1498
|
-
|
|
1499
|
-
/* @__PURE__ */ jsxs6("
|
|
1501
|
+
}, []);
|
|
1502
|
+
if (error) {
|
|
1503
|
+
return /* @__PURE__ */ jsxs6("p", { className: "flex items-center gap-2 px-1 pt-1 text-xs text-muted-foreground", role: "status", "data-camera-note": "", children: [
|
|
1504
|
+
/* @__PURE__ */ jsx7(CameraGlyph, { className: "size-3.5 shrink-0", "aria-hidden": true }),
|
|
1505
|
+
/* @__PURE__ */ jsxs6("span", { className: "min-w-0 flex-1 truncate", children: [
|
|
1506
|
+
error,
|
|
1507
|
+
" Paste the setup key or choose a QR image."
|
|
1508
|
+
] }),
|
|
1509
|
+
/* @__PURE__ */ jsx7(Button5, { variant: "quiet", onClick: onClose, children: "Dismiss" })
|
|
1510
|
+
] });
|
|
1511
|
+
}
|
|
1512
|
+
return /* @__PURE__ */ jsxs6("div", { className: "flex flex-col items-center gap-1.5 pt-2", role: "region", "aria-label": "Scan QR code", "data-camera-preview": "", children: [
|
|
1513
|
+
/* @__PURE__ */ jsxs6("div", { className: "relative aspect-square w-full max-w-56 overflow-hidden rounded-xl bg-muted", children: [
|
|
1500
1514
|
/* @__PURE__ */ jsx7("video", { ref: video, className: "size-full object-cover", playsInline: true, muted: true, "aria-label": "Camera" }),
|
|
1501
|
-
|
|
1515
|
+
/* @__PURE__ */ jsx7("div", { className: "pointer-events-none absolute inset-[18%] rounded-lg border-2 border-primary", "aria-hidden": true })
|
|
1502
1516
|
] }),
|
|
1503
|
-
/* @__PURE__ */
|
|
1517
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2", children: [
|
|
1518
|
+
/* @__PURE__ */ jsx7("span", { className: "text-xs text-muted-foreground", children: "Point at the site's QR code" }),
|
|
1519
|
+
/* @__PURE__ */ jsx7(Button5, { variant: "quiet", onClick: onClose, children: "Stop camera" })
|
|
1520
|
+
] })
|
|
1504
1521
|
] });
|
|
1505
1522
|
}
|
|
1506
1523
|
function OtpSetupRow({ value, onChange, label = "Authenticator", placeholder = "Paste setup key or otpauth link", disabled = false, autoFocus = false, onImage, onRecognized, status, autoStartCamera = false }) {
|
|
@@ -1510,8 +1527,15 @@ function OtpSetupRow({ value, onChange, label = "Authenticator", placeholder = "
|
|
|
1510
1527
|
const autoStarted = useRef6(false);
|
|
1511
1528
|
useEffect8(() => {
|
|
1512
1529
|
if (!autoStartCamera || !canScan || disabled || autoStarted.current || value) return;
|
|
1513
|
-
|
|
1514
|
-
|
|
1530
|
+
let live = true;
|
|
1531
|
+
void hasCameraDevice().then((has) => {
|
|
1532
|
+
if (!live || !has || autoStarted.current) return;
|
|
1533
|
+
autoStarted.current = true;
|
|
1534
|
+
setScanning(true);
|
|
1535
|
+
});
|
|
1536
|
+
return () => {
|
|
1537
|
+
live = false;
|
|
1538
|
+
};
|
|
1515
1539
|
}, [autoStartCamera, canScan, disabled, value]);
|
|
1516
1540
|
const [reading, setReading] = useState8(false);
|
|
1517
1541
|
const [imageError, setImageError] = useState8(null);
|
|
@@ -1613,10 +1637,9 @@ function OtpSetupRow({ value, onChange, label = "Authenticator", placeholder = "
|
|
|
1613
1637
|
]
|
|
1614
1638
|
}
|
|
1615
1639
|
),
|
|
1616
|
-
canScan ? /* @__PURE__ */ jsx7(
|
|
1617
|
-
|
|
1640
|
+
canScan && scanning ? /* @__PURE__ */ jsx7(
|
|
1641
|
+
QrScanInline,
|
|
1618
1642
|
{
|
|
1619
|
-
open: scanning,
|
|
1620
1643
|
onClose: () => setScanning(false),
|
|
1621
1644
|
onResult: (text) => {
|
|
1622
1645
|
setScanning(false);
|
|
@@ -2102,7 +2125,7 @@ function OtpListRow({ port, item, family, entry, onOpen, onOpenInNewTab, onRenam
|
|
|
2102
2125
|
const canManage = item.capabilities.canManage || item.capabilities.canEdit;
|
|
2103
2126
|
if (a.removed) return null;
|
|
2104
2127
|
const sub = a.error ?? [entry?.account, loginSiteOf(item) || entry?.issuer].filter((v, i, all) => Boolean(v) && all.indexOf(v) === i).join(" \xB7 ");
|
|
2105
|
-
return /* @__PURE__ */ jsxs9("div", { className: "grid min-h-14 grid-cols-[2rem_minmax(0,1fr)_auto_auto] items-center gap-x-
|
|
2128
|
+
return /* @__PURE__ */ jsxs9("div", { className: "grid min-h-14 grid-cols-[2rem_minmax(0,1fr)_auto_auto] items-center gap-x-1 rounded-lg px-2 py-1.5 transition-colors hover:bg-accent/50", children: [
|
|
2106
2129
|
/* @__PURE__ */ jsx10(
|
|
2107
2130
|
Button8,
|
|
2108
2131
|
{
|
|
@@ -2123,6 +2146,7 @@ function OtpListRow({ port, item, family, entry, onOpen, onOpenInNewTab, onRenam
|
|
|
2123
2146
|
onClick: onOpen,
|
|
2124
2147
|
title: /* @__PURE__ */ jsx10("span", { className: a.enabled ? "text-foreground" : "text-muted-foreground", children: item.name }),
|
|
2125
2148
|
line: sub ? /* @__PURE__ */ jsx10("span", { className: a.error ? "text-destructive" : "text-muted-foreground", title: sub, children: sub }) : void 0,
|
|
2149
|
+
oneLine: true,
|
|
2126
2150
|
className: "min-w-0"
|
|
2127
2151
|
}
|
|
2128
2152
|
),
|
|
@@ -2729,12 +2753,56 @@ function createVaultKnobs(client, address) {
|
|
|
2729
2753
|
}
|
|
2730
2754
|
var REVEAL_SECONDS_KNOB = "desktop.vault.reveal_hide_seconds";
|
|
2731
2755
|
var BACKUP_PASSPHRASE_MIN_KNOB = "desktop.vault.backup_passphrase_min_length";
|
|
2756
|
+
var ORGANIZATION_SEARCH_AT_KNOB = "vault.organization_search_at";
|
|
2757
|
+
var ORGANIZATION_SEARCH_AT_UNREAD = 8;
|
|
2732
2758
|
function positiveKnob(resolved, key) {
|
|
2733
2759
|
const v = resolved[key];
|
|
2734
2760
|
const n = typeof v === "string" && v.trim() !== "" ? Number(v) : v;
|
|
2735
2761
|
return typeof n === "number" && Number.isFinite(n) && n > 0 ? Math.floor(n) : null;
|
|
2736
2762
|
}
|
|
2737
2763
|
|
|
2764
|
+
// src/organizations.ts
|
|
2765
|
+
import { shortUuid } from "@ai-matrx/design-system/record-id-format";
|
|
2766
|
+
function orderOrganizations(orgs, items, recentItemIds) {
|
|
2767
|
+
const counts = /* @__PURE__ */ new Map();
|
|
2768
|
+
for (const i of items) if (i.owner.organizationId) counts.set(i.owner.organizationId, (counts.get(i.owner.organizationId) ?? 0) + 1);
|
|
2769
|
+
const byId = new Map(items.map((i) => [i.id, i]));
|
|
2770
|
+
const recent = /* @__PURE__ */ new Map();
|
|
2771
|
+
for (const id of recentItemIds ?? []) {
|
|
2772
|
+
const org = byId.get(id)?.owner.organizationId;
|
|
2773
|
+
if (org && !recent.has(org)) recent.set(org, recent.size);
|
|
2774
|
+
}
|
|
2775
|
+
const group = (o) => recent.has(o.id) ? 0 : (counts.get(o.id) ?? 0) > 0 ? 1 : 2;
|
|
2776
|
+
return [...orgs].sort((a, b) => group(a) - group(b) || (recent.get(a.id) ?? 0) - (recent.get(b.id) ?? 0) || a.name.localeCompare(b.name, void 0, { sensitivity: "base" }) || a.id.localeCompare(b.id));
|
|
2777
|
+
}
|
|
2778
|
+
function organizationHints(orgs) {
|
|
2779
|
+
const seen = /* @__PURE__ */ new Map();
|
|
2780
|
+
for (const o of orgs) seen.set(o.name.trim().toLowerCase(), (seen.get(o.name.trim().toLowerCase()) ?? 0) + 1);
|
|
2781
|
+
return new Map(orgs.filter((o) => (seen.get(o.name.trim().toLowerCase()) ?? 0) > 1).map((o) => [o.id, shortUuid(o.id)]));
|
|
2782
|
+
}
|
|
2783
|
+
|
|
2784
|
+
// src/shown-until-move.ts
|
|
2785
|
+
import { useEffect as useEffect11, useRef as useRef9, useState as useState14 } from "react";
|
|
2786
|
+
var keyOf = (loc) => `${String(loc.vault)}|${loc.view}|${loc.itemId ?? ""}|${loc.mode}|${loc.panel ?? ""}|${loc.kind ?? ""}`;
|
|
2787
|
+
function useShownUntilMove(loc) {
|
|
2788
|
+
const [shown, setShown] = useState14(null);
|
|
2789
|
+
const home = useRef9(null);
|
|
2790
|
+
const key = keyOf(loc);
|
|
2791
|
+
useEffect11(() => {
|
|
2792
|
+
if (!shown) {
|
|
2793
|
+
home.current = null;
|
|
2794
|
+
return;
|
|
2795
|
+
}
|
|
2796
|
+
if (home.current?.id !== shown.id) home.current = { id: shown.id, key: null };
|
|
2797
|
+
if (home.current.key === null) {
|
|
2798
|
+
if (loc.itemId === shown.id && loc.mode === "view") home.current.key = key;
|
|
2799
|
+
return;
|
|
2800
|
+
}
|
|
2801
|
+
if (key !== home.current.key) setShown(null);
|
|
2802
|
+
}, [shown, key, loc.itemId, loc.mode]);
|
|
2803
|
+
return [shown, setShown];
|
|
2804
|
+
}
|
|
2805
|
+
|
|
2738
2806
|
// src/lock.ts
|
|
2739
2807
|
import { useSyncExternalStore as useSyncExternalStore2 } from "react";
|
|
2740
2808
|
var LOCKED_MESSAGE = "The vault is locked. Unlock it first.";
|
|
@@ -2776,7 +2844,7 @@ function useLocked(lock) {
|
|
|
2776
2844
|
|
|
2777
2845
|
// src/io/BackupPanel.tsx
|
|
2778
2846
|
import { formatFileSize } from "@ai-matrx/kit/format";
|
|
2779
|
-
import { useEffect as
|
|
2847
|
+
import { useEffect as useEffect12, useRef as useRef10, useState as useState16 } from "react";
|
|
2780
2848
|
import { Button as Button12, Field as Field5, SegmentedControl as SegmentedControl3, Switch as Switch3 } from "@ai-matrx/design-system/controls";
|
|
2781
2849
|
import { downloadFile } from "@ai-matrx/kit/download";
|
|
2782
2850
|
import { confirm as confirm4 } from "@ai-matrx/kit/confirm-opener";
|
|
@@ -2869,7 +2937,7 @@ function startNewRestoreRun(preview) {
|
|
|
2869
2937
|
}
|
|
2870
2938
|
|
|
2871
2939
|
// src/io/lines.tsx
|
|
2872
|
-
import { useState as
|
|
2940
|
+
import { useState as useState15 } from "react";
|
|
2873
2941
|
import { Checkbox } from "@ai-matrx/design-system";
|
|
2874
2942
|
import { Badge as Badge4, Button as Button11, DisclosureHeader as DisclosureHeader2 } from "@ai-matrx/design-system/controls";
|
|
2875
2943
|
import { Fragment as Fragment8, jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
@@ -2882,7 +2950,7 @@ function PickLine({ checked, onChange, disabled = false, title, detail, badge, t
|
|
|
2882
2950
|
] });
|
|
2883
2951
|
}
|
|
2884
2952
|
function Windowed({ items, size = 150, render }) {
|
|
2885
|
-
const [all, setAll] =
|
|
2953
|
+
const [all, setAll] = useState15(false);
|
|
2886
2954
|
const shown = all ? items : items.slice(0, size);
|
|
2887
2955
|
return /* @__PURE__ */ jsxs12(Fragment8, { children: [
|
|
2888
2956
|
shown.map(render),
|
|
@@ -2893,7 +2961,7 @@ function Windowed({ items, size = 150, render }) {
|
|
|
2893
2961
|
] });
|
|
2894
2962
|
}
|
|
2895
2963
|
function More({ title = "More", children }) {
|
|
2896
|
-
const [open, setOpen] =
|
|
2964
|
+
const [open, setOpen] = useState15(false);
|
|
2897
2965
|
return /* @__PURE__ */ jsxs12("div", { className: "flex flex-col gap-2", children: [
|
|
2898
2966
|
/* @__PURE__ */ jsx13(DisclosureHeader2, { open, title, onClick: () => setOpen((o) => !o) }),
|
|
2899
2967
|
open ? children : null
|
|
@@ -2933,21 +3001,21 @@ function Omissions({ omissions, accepted, onAccepted, verb }) {
|
|
|
2933
3001
|
function BackupPanel({ port, host, items, onClose, onChanged }) {
|
|
2934
3002
|
const minLength = passphraseMinimum(host.backupPassphraseMinLength);
|
|
2935
3003
|
const confirmed = useConfirmed();
|
|
2936
|
-
const fileInput =
|
|
2937
|
-
const abort =
|
|
2938
|
-
const [mode, setMode] =
|
|
2939
|
-
const [busy, setBusy] =
|
|
2940
|
-
const [error, setError] =
|
|
2941
|
-
const [passphrase, setPassphrase] =
|
|
2942
|
-
const [repeat, setRepeat] =
|
|
2943
|
-
const [accepted, setAccepted] =
|
|
2944
|
-
const [selected, setSelected] =
|
|
2945
|
-
const [backup, setBackup] =
|
|
2946
|
-
const [file, setFile] =
|
|
2947
|
-
const [restorePreview, setRestorePreview] =
|
|
2948
|
-
const [runId, setRunId] =
|
|
2949
|
-
const [result, setResult] =
|
|
2950
|
-
|
|
3004
|
+
const fileInput = useRef10(null);
|
|
3005
|
+
const abort = useRef10(null);
|
|
3006
|
+
const [mode, setMode] = useState16("backup");
|
|
3007
|
+
const [busy, setBusy] = useState16(false);
|
|
3008
|
+
const [error, setError] = useState16(null);
|
|
3009
|
+
const [passphrase, setPassphrase] = useState16("");
|
|
3010
|
+
const [repeat, setRepeat] = useState16("");
|
|
3011
|
+
const [accepted, setAccepted] = useState16(false);
|
|
3012
|
+
const [selected, setSelected] = useState16(/* @__PURE__ */ new Set());
|
|
3013
|
+
const [backup, setBackup] = useState16(null);
|
|
3014
|
+
const [file, setFile] = useState16(null);
|
|
3015
|
+
const [restorePreview, setRestorePreview] = useState16(null);
|
|
3016
|
+
const [runId, setRunId] = useState16(null);
|
|
3017
|
+
const [result, setResult] = useState16(null);
|
|
3018
|
+
useEffect12(() => () => abort.current?.abort(), []);
|
|
2951
3019
|
const switchMode = (next) => {
|
|
2952
3020
|
abort.current?.abort();
|
|
2953
3021
|
setMode(next);
|
|
@@ -3084,7 +3152,7 @@ function BackupPanel({ port, host, items, onClose, onChanged }) {
|
|
|
3084
3152
|
/* @__PURE__ */ jsx14(Summary, { value: backup }),
|
|
3085
3153
|
/* @__PURE__ */ jsx14(Omissions, { omissions: backup.omissions, accepted, onAccepted: setAccepted, verb: "Back up" }),
|
|
3086
3154
|
/* @__PURE__ */ jsxs13(VaultSection, { children: [
|
|
3087
|
-
/* @__PURE__ */ jsx14(VaultRow, { label: "Passphrase", hint: minLength ? `At least ${minLength} characters. Not saved.` : "Not saved. It can't be recovered.", children: /* @__PURE__ */ jsx14(Field5, { type: "password", value: passphrase, autoComplete: "new-password", "aria-label": "Backup passphrase", "aria-invalid": short || void 0, onChange: (e) => setPassphrase(e.target.value) }) }),
|
|
3155
|
+
/* @__PURE__ */ jsx14(VaultRow, { label: "Passphrase", hint: minLength ? `At least ${minLength} characters. Not saved. It can't be recovered.` : "Not saved. It can't be recovered.", children: /* @__PURE__ */ jsx14(Field5, { type: "password", value: passphrase, autoComplete: "new-password", "aria-label": "Backup passphrase", "aria-invalid": short || void 0, onChange: (e) => setPassphrase(e.target.value) }) }),
|
|
3088
3156
|
short ? /* @__PURE__ */ jsxs13("p", { role: "alert", className: "px-1 text-xs text-destructive", "data-passphrase-too-short": "", children: [
|
|
3089
3157
|
"Use at least ",
|
|
3090
3158
|
minLength,
|
|
@@ -3132,7 +3200,7 @@ function tooShort(passphrase, minLength) {
|
|
|
3132
3200
|
}
|
|
3133
3201
|
|
|
3134
3202
|
// src/io/ExportPanel.tsx
|
|
3135
|
-
import { useMemo, useState as
|
|
3203
|
+
import { useMemo, useState as useState17 } from "react";
|
|
3136
3204
|
import { Button as Button13, Select as Select5 } from "@ai-matrx/design-system/controls";
|
|
3137
3205
|
import { downloadFile as downloadFile2 } from "@ai-matrx/kit/download";
|
|
3138
3206
|
import { confirm as confirm5 } from "@ai-matrx/kit/confirm-opener";
|
|
@@ -3157,11 +3225,11 @@ function omissionText2(omissions) {
|
|
|
3157
3225
|
function ExportPanel({ port, items, onClose }) {
|
|
3158
3226
|
const confirmed = useConfirmed();
|
|
3159
3227
|
const logins = useMemo(() => items.filter((i) => i.definitionKey === WEBSITE_LOGIN), [items]);
|
|
3160
|
-
const [profile, setProfile] =
|
|
3161
|
-
const [selected, setSelected] =
|
|
3162
|
-
const [preview, setPreview] =
|
|
3163
|
-
const [busy, setBusy] =
|
|
3164
|
-
const [error, setError] =
|
|
3228
|
+
const [profile, setProfile] = useState17("matrx_login_csv_v1");
|
|
3229
|
+
const [selected, setSelected] = useState17(/* @__PURE__ */ new Set());
|
|
3230
|
+
const [preview, setPreview] = useState17(null);
|
|
3231
|
+
const [busy, setBusy] = useState17(false);
|
|
3232
|
+
const [error, setError] = useState17(null);
|
|
3165
3233
|
const format = FORMATS.find((f) => f.value === profile);
|
|
3166
3234
|
const reasons = new Map(preview?.items.map((p) => [p.item_id, p]) ?? []);
|
|
3167
3235
|
const eligible = preview?.items.filter((p) => p.eligible).length ?? 0;
|
|
@@ -3286,7 +3354,7 @@ function ExportPanel({ port, items, onClose }) {
|
|
|
3286
3354
|
}
|
|
3287
3355
|
|
|
3288
3356
|
// src/io/ImportPanel.tsx
|
|
3289
|
-
import { useEffect as
|
|
3357
|
+
import { useEffect as useEffect13, useMemo as useMemo2, useRef as useRef11, useState as useState18 } from "react";
|
|
3290
3358
|
import { Button as Button14, Select as Select6, Switch as Switch4, Textarea as Textarea2 } from "@ai-matrx/design-system/controls";
|
|
3291
3359
|
|
|
3292
3360
|
// src/io/csv-import.ts
|
|
@@ -4148,25 +4216,25 @@ var STATE_BADGE = {
|
|
|
4148
4216
|
var ME = "me";
|
|
4149
4217
|
function ImportPanel({ port, host, items, definitions, organizations, onClose, onChanged, limits }) {
|
|
4150
4218
|
const confirmed = useConfirmed();
|
|
4151
|
-
const [otpFor, setOtpFor] =
|
|
4152
|
-
const fileInput =
|
|
4153
|
-
const abort =
|
|
4154
|
-
const stop =
|
|
4155
|
-
const keys =
|
|
4156
|
-
const [source, setSource] =
|
|
4157
|
-
const [envText, setEnvText] =
|
|
4158
|
-
const [injectSandbox, setInjectSandbox] =
|
|
4159
|
-
const [fileName, setFileName] =
|
|
4160
|
-
const [reading, setReading] =
|
|
4161
|
-
const [draft, setDraft] =
|
|
4162
|
-
const [destination, setDestination] =
|
|
4163
|
-
const [browserFill, setBrowserFill] =
|
|
4164
|
-
const [approvedVisible, setApprovedVisible] =
|
|
4165
|
-
const [selected, setSelected] =
|
|
4166
|
-
const [running, setRunning] =
|
|
4167
|
-
const [done, setDone] =
|
|
4168
|
-
const [error, setError] =
|
|
4169
|
-
|
|
4219
|
+
const [otpFor, setOtpFor] = useState18(null);
|
|
4220
|
+
const fileInput = useRef11(null);
|
|
4221
|
+
const abort = useRef11(null);
|
|
4222
|
+
const stop = useRef11(false);
|
|
4223
|
+
const keys = useRef11(/* @__PURE__ */ new Map());
|
|
4224
|
+
const [source, setSource] = useState18("auto");
|
|
4225
|
+
const [envText, setEnvText] = useState18("");
|
|
4226
|
+
const [injectSandbox, setInjectSandbox] = useState18(false);
|
|
4227
|
+
const [fileName, setFileName] = useState18(null);
|
|
4228
|
+
const [reading, setReading] = useState18(false);
|
|
4229
|
+
const [draft, setDraft] = useState18(null);
|
|
4230
|
+
const [destination, setDestination] = useState18(ME);
|
|
4231
|
+
const [browserFill, setBrowserFill] = useState18(false);
|
|
4232
|
+
const [approvedVisible, setApprovedVisible] = useState18(false);
|
|
4233
|
+
const [selected, setSelected] = useState18(/* @__PURE__ */ new Set());
|
|
4234
|
+
const [running, setRunning] = useState18(null);
|
|
4235
|
+
const [done, setDone] = useState18(null);
|
|
4236
|
+
const [error, setError] = useState18(null);
|
|
4237
|
+
useEffect13(
|
|
4170
4238
|
() => () => {
|
|
4171
4239
|
abort.current?.abort();
|
|
4172
4240
|
stop.current = true;
|
|
@@ -4453,14 +4521,14 @@ function Notices({ draft }) {
|
|
|
4453
4521
|
}
|
|
4454
4522
|
|
|
4455
4523
|
// src/ItemList.tsx
|
|
4456
|
-
import { useEffect as
|
|
4524
|
+
import { useEffect as useEffect16, useRef as useRef14, useState as useState27 } from "react";
|
|
4457
4525
|
import { DropdownMenu as DropdownMenu4, DropdownMenuContent as DropdownMenuContent4, DropdownMenuItem as DropdownMenuItem4, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator as DropdownMenuSeparator4, DropdownMenuTrigger as DropdownMenuTrigger4 } from "@ai-matrx/design-system";
|
|
4458
4526
|
import { cn as cn11 } from "@ai-matrx/design-system";
|
|
4459
4527
|
import { Button as Button22, SearchField, Tile as Tile3 } from "@ai-matrx/design-system/controls";
|
|
4460
4528
|
import { CopyIcon as CopyIcon7 } from "@ai-matrx/design-system/icons";
|
|
4461
4529
|
|
|
4462
4530
|
// src/ItemPane.tsx
|
|
4463
|
-
import { Fragment as Fragment16, useEffect as
|
|
4531
|
+
import { Fragment as Fragment16, useEffect as useEffect15, useMemo as useMemo3, useRef as useRef13, useState as useState26 } from "react";
|
|
4464
4532
|
import { DropdownMenu as DropdownMenu3, DropdownMenuContent as DropdownMenuContent3, DropdownMenuItem as DropdownMenuItem3, DropdownMenuSeparator as DropdownMenuSeparator3, DropdownMenuTrigger as DropdownMenuTrigger3 } from "@ai-matrx/design-system";
|
|
4465
4533
|
import { cn as cn10 } from "@ai-matrx/design-system";
|
|
4466
4534
|
import { Badge as Badge7, Button as Button21, CONTROLS_CONTAINER_CLASS, OptionCombobox, Switch as Switch6 } from "@ai-matrx/design-system/controls";
|
|
@@ -4468,7 +4536,7 @@ import { confirm as confirm10 } from "@ai-matrx/kit/confirm-opener";
|
|
|
4468
4536
|
|
|
4469
4537
|
// src/activity/FilesSection.tsx
|
|
4470
4538
|
import { formatFileSize as formatFileSize2 } from "@ai-matrx/kit/format";
|
|
4471
|
-
import { useRef as
|
|
4539
|
+
import { useRef as useRef12, useState as useState19 } from "react";
|
|
4472
4540
|
import { Badge as Badge5, Button as Button15, Field as Field6, SegmentedControl as SegmentedControl4 } from "@ai-matrx/design-system/controls";
|
|
4473
4541
|
import { cn as cn7 } from "@ai-matrx/design-system";
|
|
4474
4542
|
import { confirm as confirm6 } from "@ai-matrx/kit/confirm-opener";
|
|
@@ -4486,11 +4554,11 @@ function FilesSection({ item, port, editing, onChanged }) {
|
|
|
4486
4554
|
const confirmed = useConfirmed();
|
|
4487
4555
|
const canEdit = editing && item.capabilities.canEdit;
|
|
4488
4556
|
const canAdd = item.capabilities.canEdit;
|
|
4489
|
-
const [busy, setBusy] =
|
|
4490
|
-
const [error, setError] =
|
|
4491
|
-
const [pending, setPending] =
|
|
4492
|
-
const [dragging, setDragging] =
|
|
4493
|
-
const picker =
|
|
4557
|
+
const [busy, setBusy] = useState19(null);
|
|
4558
|
+
const [error, setError] = useState19(null);
|
|
4559
|
+
const [pending, setPending] = useState19(null);
|
|
4560
|
+
const [dragging, setDragging] = useState19(false);
|
|
4561
|
+
const picker = useRef12(null);
|
|
4494
4562
|
if (!canAdd && item.attachments.length === 0) return null;
|
|
4495
4563
|
async function run(key, work, fallback) {
|
|
4496
4564
|
setBusy(key);
|
|
@@ -4567,8 +4635,8 @@ function FilesSection({ item, port, editing, onChanged }) {
|
|
|
4567
4635
|
);
|
|
4568
4636
|
}
|
|
4569
4637
|
function EditableFile({ port, item: it, file: a, busy: b, run: go, onDownload, onTooBig }) {
|
|
4570
|
-
const [open, setOpen] =
|
|
4571
|
-
const replacer =
|
|
4638
|
+
const [open, setOpen] = useState19(false);
|
|
4639
|
+
const replacer = useRef12(null);
|
|
4572
4640
|
async function remove() {
|
|
4573
4641
|
const yes = await confirm6({ title: `Delete ${a.label}?`, description: "The encrypted file is removed from this item.", confirmLabel: "Delete", variant: "destructive" });
|
|
4574
4642
|
if (yes) await go(`delete:${a.id}`, () => port.activity.deleteFile(it, a.id), "The file could not be deleted.");
|
|
@@ -4626,9 +4694,9 @@ function Protection({ value, locked, onChange }) {
|
|
|
4626
4694
|
);
|
|
4627
4695
|
}
|
|
4628
4696
|
function NewFile({ file, busy, onAdd, onCancel }) {
|
|
4629
|
-
const [label, setLabel] =
|
|
4630
|
-
const [description, setDescription] =
|
|
4631
|
-
const [handling, setHandling] =
|
|
4697
|
+
const [label, setLabel] = useState19(file.name);
|
|
4698
|
+
const [description, setDescription] = useState19("");
|
|
4699
|
+
const [handling, setHandling] = useState19("revealable");
|
|
4632
4700
|
async function add() {
|
|
4633
4701
|
if (handling === "sealed" && !await confirmSeal(label)) return;
|
|
4634
4702
|
await onAdd({ label: label.trim(), description: description.trim() || null, handling });
|
|
@@ -4648,10 +4716,10 @@ function NewFile({ file, busy, onAdd, onCancel }) {
|
|
|
4648
4716
|
] });
|
|
4649
4717
|
}
|
|
4650
4718
|
function FileDetailsRows({ file, busy, onSave, onCancel }) {
|
|
4651
|
-
const [label, setLabel] =
|
|
4652
|
-
const [description, setDescription] =
|
|
4653
|
-
const [fileName, setFileName] =
|
|
4654
|
-
const [handling, setHandling] =
|
|
4719
|
+
const [label, setLabel] = useState19(file.label);
|
|
4720
|
+
const [description, setDescription] = useState19(file.description);
|
|
4721
|
+
const [fileName, setFileName] = useState19(file.fileName);
|
|
4722
|
+
const [handling, setHandling] = useState19(file.handling);
|
|
4655
4723
|
const changed = label !== file.label || description !== file.description || fileName !== file.fileName || handling !== file.handling;
|
|
4656
4724
|
async function save() {
|
|
4657
4725
|
if (handling === "sealed" && file.handling !== "sealed" && !await confirmSeal(label)) return;
|
|
@@ -4677,10 +4745,10 @@ function confirmSeal(label) {
|
|
|
4677
4745
|
});
|
|
4678
4746
|
}
|
|
4679
4747
|
function DraftFilesSection({ files, onFiles }) {
|
|
4680
|
-
const [pending, setPending] =
|
|
4681
|
-
const [error, setError] =
|
|
4682
|
-
const [dragging, setDragging] =
|
|
4683
|
-
const picker =
|
|
4748
|
+
const [pending, setPending] = useState19(null);
|
|
4749
|
+
const [error, setError] = useState19(null);
|
|
4750
|
+
const [dragging, setDragging] = useState19(false);
|
|
4751
|
+
const picker = useRef12(null);
|
|
4684
4752
|
const choose = (file) => {
|
|
4685
4753
|
if (!file) return;
|
|
4686
4754
|
if (fileTooBig(file.size)) return setError(TOO_BIG);
|
|
@@ -4729,7 +4797,7 @@ function DraftFilesSection({ files, onFiles }) {
|
|
|
4729
4797
|
}
|
|
4730
4798
|
|
|
4731
4799
|
// src/fields/RecoveryCodesRow.tsx
|
|
4732
|
-
import { useState as
|
|
4800
|
+
import { useState as useState20 } from "react";
|
|
4733
4801
|
import { Badge as Badge6, Button as Button16, Textarea as Textarea3 } from "@ai-matrx/design-system/controls";
|
|
4734
4802
|
import { CopyIcon as CopyIcon6 } from "@ai-matrx/design-system/icons";
|
|
4735
4803
|
import { Fragment as Fragment13, jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
@@ -4739,9 +4807,9 @@ function RecoveryCodesRow({ item, field, port, onChanged }) {
|
|
|
4739
4807
|
const confirmed = useConfirmed();
|
|
4740
4808
|
const copyValue2 = useCopy();
|
|
4741
4809
|
const secret = useTransientSecret();
|
|
4742
|
-
const [busy, setBusy] =
|
|
4743
|
-
const [error, setError] =
|
|
4744
|
-
const [draft, setDraft] =
|
|
4810
|
+
const [busy, setBusy] = useState20(false);
|
|
4811
|
+
const [error, setError] = useState20(null);
|
|
4812
|
+
const [draft, setDraft] = useState20(null);
|
|
4745
4813
|
const canEdit = item.capabilities.canEdit;
|
|
4746
4814
|
const run = async (step) => {
|
|
4747
4815
|
setBusy(true);
|
|
@@ -4836,7 +4904,7 @@ function RecoveryCodesRow({ item, field, port, onChanged }) {
|
|
|
4836
4904
|
}
|
|
4837
4905
|
|
|
4838
4906
|
// src/fields/DraftRows.tsx
|
|
4839
|
-
import { useState as
|
|
4907
|
+
import { useState as useState21 } from "react";
|
|
4840
4908
|
import { Button as Button17, Field as Field7, SegmentedControl as SegmentedControl5, Select as Select7, Switch as Switch5 } from "@ai-matrx/design-system/controls";
|
|
4841
4909
|
import { RecordId } from "@ai-matrx/design-system";
|
|
4842
4910
|
import { confirm as confirm7 } from "@ai-matrx/kit/confirm-opener";
|
|
@@ -4891,7 +4959,7 @@ function FieldSettingsRows({ name, value, defaultHandling = "revealable", onChan
|
|
|
4891
4959
|
var hasSecretSettings = (s) => saysMore(s, "revealable");
|
|
4892
4960
|
var hasDeclaredSettings = (s, defaultHandling) => Boolean(s && saysMore(s, defaultHandling));
|
|
4893
4961
|
function SecretBuilderRow({ field, onChange, onRemove }) {
|
|
4894
|
-
const [open, setOpen] =
|
|
4962
|
+
const [open, setOpen] = useState21(hasSecretSettings(field));
|
|
4895
4963
|
const handling = field.handling ?? "revealable";
|
|
4896
4964
|
const name = field.label.trim() || "Secret";
|
|
4897
4965
|
return /* @__PURE__ */ jsxs18(Fragment14, { children: [
|
|
@@ -5132,7 +5200,7 @@ function targetLabel(t) {
|
|
|
5132
5200
|
}
|
|
5133
5201
|
|
|
5134
5202
|
// src/extension/UseOnSiteButton.tsx
|
|
5135
|
-
import { useState as
|
|
5203
|
+
import { useState as useState22 } from "react";
|
|
5136
5204
|
import { Button as Button18 } from "@ai-matrx/design-system/controls";
|
|
5137
5205
|
import { jsx as jsx20 } from "react/jsx-runtime";
|
|
5138
5206
|
function canUseOnSite(item, pageUrl) {
|
|
@@ -5140,7 +5208,7 @@ function canUseOnSite(item, pageUrl) {
|
|
|
5140
5208
|
}
|
|
5141
5209
|
function UseOnSiteButton({ port, item, pageUrl, onChanged }) {
|
|
5142
5210
|
const notify = useNotify();
|
|
5143
|
-
const [busy, setBusy] =
|
|
5211
|
+
const [busy, setBusy] = useState22(false);
|
|
5144
5212
|
if (!canUseOnSite(item, pageUrl)) return null;
|
|
5145
5213
|
const site = pageSite(pageUrl);
|
|
5146
5214
|
const run = async () => {
|
|
@@ -5159,7 +5227,7 @@ function UseOnSiteButton({ port, item, pageUrl, onChanged }) {
|
|
|
5159
5227
|
}
|
|
5160
5228
|
|
|
5161
5229
|
// src/sharing/SharePanel.tsx
|
|
5162
|
-
import { useEffect as
|
|
5230
|
+
import { useEffect as useEffect14, useState as useState25 } from "react";
|
|
5163
5231
|
import { confirm as confirm9 } from "@ai-matrx/kit/confirm-opener";
|
|
5164
5232
|
import { Button as Button20, DisclosureHeader as DisclosureHeader3, Field as Field9, RegionSkeleton, Select as Select9 } from "@ai-matrx/design-system/controls";
|
|
5165
5233
|
import { cn as cn9 } from "@ai-matrx/design-system";
|
|
@@ -5182,14 +5250,17 @@ function isEmail(value) {
|
|
|
5182
5250
|
}
|
|
5183
5251
|
var PERSONAL = "personal";
|
|
5184
5252
|
var destinationOf = (key) => key === PERSONAL ? null : key;
|
|
5253
|
+
var orgChoice = (o, hints) => ({ value: o.id, label: o.name, ...hints.has(o.id) ? { hint: hints.get(o.id) } : {} });
|
|
5185
5254
|
function moveDestinations(item, orgs) {
|
|
5186
5255
|
if (item.owner.kind === "shared") return [];
|
|
5187
5256
|
const here = item.owner.organizationId;
|
|
5188
|
-
|
|
5257
|
+
const hints = organizationHints(orgs);
|
|
5258
|
+
return [...here ? [{ value: PERSONAL, label: "Personal" }] : [], ...orgs.filter((o) => o.id !== here).map((o) => orgChoice(o, hints))];
|
|
5189
5259
|
}
|
|
5190
5260
|
function copyDestinations(orgs, item) {
|
|
5191
5261
|
const here = item ? item.owner.kind === "me" ? PERSONAL : item.owner.organizationId : void 0;
|
|
5192
|
-
|
|
5262
|
+
const hints = organizationHints(orgs);
|
|
5263
|
+
return [{ value: PERSONAL, label: "Personal" }, ...orgs.map((o) => orgChoice(o, hints))].filter((d) => d.value !== here);
|
|
5193
5264
|
}
|
|
5194
5265
|
function copyRefusal(message2) {
|
|
5195
5266
|
return /duplicate/i.test(message2) ? "There is already a copy of this item there." : null;
|
|
@@ -5217,7 +5288,7 @@ function shareSummary(grants) {
|
|
|
5217
5288
|
var MEMBER_CHOICE_DEFAULT = "default";
|
|
5218
5289
|
|
|
5219
5290
|
// src/sharing/parts.tsx
|
|
5220
|
-
import { useState as
|
|
5291
|
+
import { useState as useState23 } from "react";
|
|
5221
5292
|
import { cn as cn8 } from "@ai-matrx/design-system";
|
|
5222
5293
|
import { jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
5223
5294
|
var message = (e, fallback) => {
|
|
@@ -5226,9 +5297,9 @@ var message = (e, fallback) => {
|
|
|
5226
5297
|
};
|
|
5227
5298
|
function useConfirmedChange() {
|
|
5228
5299
|
const confirmed = useConfirmed();
|
|
5229
|
-
const [busy, setBusy] =
|
|
5230
|
-
const [error, setError] =
|
|
5231
|
-
const [notice, setNotice] =
|
|
5300
|
+
const [busy, setBusy] = useState23(null);
|
|
5301
|
+
const [error, setError] = useState23(null);
|
|
5302
|
+
const [notice, setNotice] = useState23(null);
|
|
5232
5303
|
async function run(key, fn, done) {
|
|
5233
5304
|
setBusy(key);
|
|
5234
5305
|
setError(null);
|
|
@@ -5262,18 +5333,20 @@ function StatusLine({ error, notice }) {
|
|
|
5262
5333
|
}
|
|
5263
5334
|
|
|
5264
5335
|
// src/sharing/MovePanel.tsx
|
|
5265
|
-
import { useState as
|
|
5336
|
+
import { useState as useState24 } from "react";
|
|
5266
5337
|
import { confirm as confirm8 } from "@ai-matrx/kit/confirm-opener";
|
|
5267
5338
|
import { Button as Button19, Field as Field8, Select as Select8 } from "@ai-matrx/design-system/controls";
|
|
5268
5339
|
import { jsx as jsx22, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
5269
5340
|
var NONE = "__none__";
|
|
5270
|
-
function MovePanel({ item, port, organizations, onClose, onChanged }) {
|
|
5341
|
+
function MovePanel({ item, port, host, organizations, onClose, onChanged, onOpenItem }) {
|
|
5271
5342
|
const { busy, error, notice, run, setNotice } = useConfirmedChange();
|
|
5272
5343
|
const moves = moveDestinations(item, organizations);
|
|
5273
5344
|
const copies = copyDestinations(organizations, item);
|
|
5274
|
-
const [moveTo, setMoveTo] =
|
|
5275
|
-
const [copyTo, setCopyTo] =
|
|
5276
|
-
const [email, setEmail] =
|
|
5345
|
+
const [moveTo, setMoveTo] = useState24("");
|
|
5346
|
+
const [copyTo, setCopyTo] = useState24("");
|
|
5347
|
+
const [email, setEmail] = useState24("");
|
|
5348
|
+
const [made, setMade] = useState24(null);
|
|
5349
|
+
const searchAt = host.organizationSearchAt ?? ORGANIZATION_SEARCH_AT_UNREAD;
|
|
5277
5350
|
const passkey = isPasskey(item);
|
|
5278
5351
|
const canMove = item.capabilities.canManage && !passkey && moves.length > 0;
|
|
5279
5352
|
const canGive = item.capabilities.canManage && item.owner.kind === "me" && !passkey;
|
|
@@ -5307,8 +5380,10 @@ function MovePanel({ item, port, organizations, onClose, onChanged }) {
|
|
|
5307
5380
|
};
|
|
5308
5381
|
const copy = async () => {
|
|
5309
5382
|
if (!copyChoice) return;
|
|
5310
|
-
const
|
|
5311
|
-
if (
|
|
5383
|
+
const copied = await run("copy", () => port.sharing.copy(item, destinationOf(copyChoice.value)), `Copy made in ${copyChoice.label}`);
|
|
5384
|
+
if (!copied) return;
|
|
5385
|
+
setMade(copied);
|
|
5386
|
+
onChanged();
|
|
5312
5387
|
};
|
|
5313
5388
|
const nothing = !canMove && !canGive && !canCopy;
|
|
5314
5389
|
return /* @__PURE__ */ jsx22(
|
|
@@ -5317,7 +5392,10 @@ function MovePanel({ item, port, organizations, onClose, onChanged }) {
|
|
|
5317
5392
|
title: "Move or copy",
|
|
5318
5393
|
size: "md",
|
|
5319
5394
|
onClose,
|
|
5320
|
-
footer: /* @__PURE__ */
|
|
5395
|
+
footer: /* @__PURE__ */ jsxs20(PanelFooter, { status: error || notice ? /* @__PURE__ */ jsx22(StatusLine, { error, notice }) : null, children: [
|
|
5396
|
+
made && onOpenItem ? /* @__PURE__ */ jsx22(Button19, { variant: "outline", onClick: () => onOpenItem(made), children: "Open copy" }) : null,
|
|
5397
|
+
/* @__PURE__ */ jsx22(Button19, { variant: "primary", onClick: onClose, children: "Done" })
|
|
5398
|
+
] }),
|
|
5321
5399
|
children: nothing ? /* @__PURE__ */ jsx22(VaultSection, { children: /* @__PURE__ */ jsx22(Empty, { children: passkey ? "A passkey stays where it was created." : "Only the owner can move or give this item." }) }) : /* @__PURE__ */ jsxs20(VaultSection, { children: [
|
|
5322
5400
|
canMove && moves.length > 0 ? /* @__PURE__ */ jsx22(
|
|
5323
5401
|
VaultRow,
|
|
@@ -5325,7 +5403,7 @@ function MovePanel({ item, port, organizations, onClose, onChanged }) {
|
|
|
5325
5403
|
label: "Move to",
|
|
5326
5404
|
hint: moveChoice ? itemMoveConsequence(item, destinationOf(moveChoice.value)) : void 0,
|
|
5327
5405
|
actions: /* @__PURE__ */ jsx22(Button19, { variant: "outline", disabled: busy !== null || !moveChoice, onClick: () => void move(), children: "Move" }),
|
|
5328
|
-
children: /* @__PURE__ */ jsx22(Select8, { className: "w-full", "aria-label": "Move to", value: moveTo || NONE, onValueChange: (v) => setMoveTo(v === NONE ? "" : v), options: [{ value: NONE, label: "Choose where" }, ...moves] })
|
|
5406
|
+
children: /* @__PURE__ */ jsx22(Select8, { className: "w-full", "aria-label": "Move to", searchAt, value: moveTo || NONE, onValueChange: (v) => setMoveTo(v === NONE ? "" : v), options: [{ value: NONE, label: "Choose where" }, ...moves] })
|
|
5329
5407
|
}
|
|
5330
5408
|
) : null,
|
|
5331
5409
|
canGive ? /* @__PURE__ */ jsx22(VaultRow, { label: "Give to", hint: "You lose all access; your shares end", actions: /* @__PURE__ */ jsx22(Button19, { variant: "danger", disabled: busy !== null || !isEmail(email), onClick: () => void give(), children: "Give" }), children: /* @__PURE__ */ jsx22(
|
|
@@ -5342,7 +5420,7 @@ function MovePanel({ item, port, organizations, onClose, onChanged }) {
|
|
|
5342
5420
|
onChange: (e) => setEmail(e.target.value)
|
|
5343
5421
|
}
|
|
5344
5422
|
) }) : null,
|
|
5345
|
-
canCopy && copies.length > 0 ? /* @__PURE__ */ jsx22(VaultRow, { label: "Copy to", hint: "A separate item; edits no longer sync", actions: /* @__PURE__ */ jsx22(Button19, { variant: "outline", disabled: busy !== null || !copyChoice, onClick: () => void copy(), children: "Copy" }), children: /* @__PURE__ */ jsx22(Select8, { className: "w-full", "aria-label": "Copy to", value: copyTo || NONE, onValueChange: (v) => setCopyTo(v === NONE ? "" : v), options: [{ value: NONE, label: "Choose where" }, ...copies] }) }) : null
|
|
5423
|
+
canCopy && copies.length > 0 ? /* @__PURE__ */ jsx22(VaultRow, { label: "Copy to", hint: "A separate item; edits no longer sync", actions: /* @__PURE__ */ jsx22(Button19, { variant: "outline", disabled: busy !== null || !copyChoice, onClick: () => void copy(), children: "Copy" }), children: /* @__PURE__ */ jsx22(Select8, { className: "w-full", "aria-label": "Copy to", searchAt, value: copyTo || NONE, onValueChange: (v) => setCopyTo(v === NONE ? "" : v), options: [{ value: NONE, label: "Choose where" }, ...copies] }) }) : null
|
|
5346
5424
|
] })
|
|
5347
5425
|
}
|
|
5348
5426
|
);
|
|
@@ -5351,11 +5429,11 @@ function MovePanel({ item, port, organizations, onClose, onChanged }) {
|
|
|
5351
5429
|
// src/sharing/SharePanel.tsx
|
|
5352
5430
|
import { Fragment as Fragment15, jsx as jsx23, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
5353
5431
|
function useGrants(port, item) {
|
|
5354
|
-
const [grants, setGrants] =
|
|
5355
|
-
const [loadError, setLoadError] =
|
|
5356
|
-
const [nonce, setNonce] =
|
|
5432
|
+
const [grants, setGrants] = useState25(null);
|
|
5433
|
+
const [loadError, setLoadError] = useState25(null);
|
|
5434
|
+
const [nonce, setNonce] = useState25(0);
|
|
5357
5435
|
const allowed = item.capabilities.canManage;
|
|
5358
|
-
|
|
5436
|
+
useEffect14(() => {
|
|
5359
5437
|
if (!allowed) return;
|
|
5360
5438
|
let live = true;
|
|
5361
5439
|
setLoadError(null);
|
|
@@ -5372,9 +5450,9 @@ function useGrants(port, item) {
|
|
|
5372
5450
|
function SharePanel({ item, port, organizations, onClose, onChanged }) {
|
|
5373
5451
|
const { grants, setGrants, loadError, reload } = useGrants(port, item);
|
|
5374
5452
|
const { busy, error, notice, run } = useConfirmedChange();
|
|
5375
|
-
const [email, setEmail] =
|
|
5376
|
-
const [level, setLevel] =
|
|
5377
|
-
const [more, setMore] =
|
|
5453
|
+
const [email, setEmail] = useState25("");
|
|
5454
|
+
const [level, setLevel] = useState25("use");
|
|
5455
|
+
const [more, setMore] = useState25(false);
|
|
5378
5456
|
const isOrg = item.owner.kind === "organization" && item.owner.organizationId !== null;
|
|
5379
5457
|
const orgName = item.owner.label;
|
|
5380
5458
|
const people = (grants ?? []).filter((g) => g.kind === "person");
|
|
@@ -5493,8 +5571,8 @@ function SharePanel({ item, port, organizations, onClose, onChanged }) {
|
|
|
5493
5571
|
function IntoOrganization({ item, port, organizations, grants, onShared }) {
|
|
5494
5572
|
const { busy, error, notice, run } = useConfirmedChange();
|
|
5495
5573
|
const open = organizations.filter((o) => !grants.some((g) => g.organizationId === o.id));
|
|
5496
|
-
const [target, setTarget] =
|
|
5497
|
-
const [level, setLevel] =
|
|
5574
|
+
const [target, setTarget] = useState25("");
|
|
5575
|
+
const [level, setLevel] = useState25("use");
|
|
5498
5576
|
const chosen = open.find((o) => o.id === target);
|
|
5499
5577
|
if (item.owner.kind !== "me") return null;
|
|
5500
5578
|
return /* @__PURE__ */ jsx23(VaultSection, { title: "Share into organization", children: open.length > 0 ? /* @__PURE__ */ jsxs21(Fragment15, { children: [
|
|
@@ -5529,10 +5607,10 @@ var CHOICES = [
|
|
|
5529
5607
|
{ value: "editor", label: "Can edit", meta: "See and change" }
|
|
5530
5608
|
];
|
|
5531
5609
|
function MemberAccess({ port, organizationId, organizationName }) {
|
|
5532
|
-
const [list, setList] =
|
|
5533
|
-
const [loadError, setLoadError] =
|
|
5610
|
+
const [list, setList] = useState25(null);
|
|
5611
|
+
const [loadError, setLoadError] = useState25(null);
|
|
5534
5612
|
const { busy, error, run } = useConfirmedChange();
|
|
5535
|
-
|
|
5613
|
+
useEffect14(() => {
|
|
5536
5614
|
let live = true;
|
|
5537
5615
|
port.sharing.memberAccess(organizationId).then(
|
|
5538
5616
|
(l) => live && setList(l),
|
|
@@ -5564,9 +5642,9 @@ function MemberAccess({ port, organizationId, organizationName }) {
|
|
|
5564
5642
|
] });
|
|
5565
5643
|
}
|
|
5566
5644
|
function SharingSummary({ item, port, className }) {
|
|
5567
|
-
const [text, setText] =
|
|
5645
|
+
const [text, setText] = useState25("");
|
|
5568
5646
|
const allowed = item.capabilities.canManage;
|
|
5569
|
-
|
|
5647
|
+
useEffect14(() => {
|
|
5570
5648
|
if (!allowed) return;
|
|
5571
5649
|
let live = true;
|
|
5572
5650
|
port.sharing.grants(item).then(
|
|
@@ -5597,7 +5675,7 @@ function ItemPane(props) {
|
|
|
5597
5675
|
const editing = mode !== "view";
|
|
5598
5676
|
const seedName = seed?.name ?? "";
|
|
5599
5677
|
const seedUrl = seed?.url ?? "";
|
|
5600
|
-
const [loaded, setLoaded] =
|
|
5678
|
+
const [loaded, setLoaded] = useState26({});
|
|
5601
5679
|
const base = useMemo3(() => {
|
|
5602
5680
|
const b = draftOf(item);
|
|
5603
5681
|
if (!item) {
|
|
@@ -5607,28 +5685,28 @@ function ItemPane(props) {
|
|
|
5607
5685
|
b.values = { ...loaded };
|
|
5608
5686
|
return b;
|
|
5609
5687
|
}, [item, seedName, seedUrl, loaded]);
|
|
5610
|
-
const [draft, setDraft] =
|
|
5611
|
-
const [tagsText, setTagsText] =
|
|
5612
|
-
const [showTags, setShowTags] =
|
|
5613
|
-
const [showDescription, setShowDescription] =
|
|
5614
|
-
const [showRecovery, setShowRecovery] =
|
|
5615
|
-
const [settingUpOtp, setSettingUpOtp] =
|
|
5616
|
-
const [owner, setOwner] =
|
|
5617
|
-
const [recipient, setRecipient] =
|
|
5618
|
-
const [generatePrivately, setGeneratePrivately] =
|
|
5619
|
-
const [busy, setBusy] =
|
|
5620
|
-
const [sent, setSent] =
|
|
5621
|
-
const [queuedFiles, setQueuedFiles] =
|
|
5622
|
-
const [showBrowser, setShowBrowser] =
|
|
5623
|
-
const [error, setError] =
|
|
5624
|
-
const [destinations, setDestinations] =
|
|
5625
|
-
const [savedNew, setSavedNew] =
|
|
5688
|
+
const [draft, setDraft] = useState26(base);
|
|
5689
|
+
const [tagsText, setTagsText] = useState26(base.tags.join(", "));
|
|
5690
|
+
const [showTags, setShowTags] = useState26(false);
|
|
5691
|
+
const [showDescription, setShowDescription] = useState26(false);
|
|
5692
|
+
const [showRecovery, setShowRecovery] = useState26(false);
|
|
5693
|
+
const [settingUpOtp, setSettingUpOtp] = useState26(false);
|
|
5694
|
+
const [owner, setOwner] = useState26(defaultOwner ?? "me");
|
|
5695
|
+
const [recipient, setRecipient] = useState26("");
|
|
5696
|
+
const [generatePrivately, setGeneratePrivately] = useState26(false);
|
|
5697
|
+
const [busy, setBusy] = useState26(false);
|
|
5698
|
+
const [sent, setSent] = useState26(null);
|
|
5699
|
+
const [queuedFiles, setQueuedFiles] = useState26([]);
|
|
5700
|
+
const [showBrowser, setShowBrowser] = useState26(false);
|
|
5701
|
+
const [error, setError] = useState26(null);
|
|
5702
|
+
const [destinations, setDestinations] = useState26({});
|
|
5703
|
+
const [savedNew, setSavedNew] = useState26(false);
|
|
5626
5704
|
const dirty = editing && !savedNew && isDirty(base, draft);
|
|
5627
5705
|
const declared = definition?.fields ?? [];
|
|
5628
|
-
const prev =
|
|
5629
|
-
const paneRef =
|
|
5706
|
+
const prev = useRef13(null);
|
|
5707
|
+
const paneRef = useRef13(null);
|
|
5630
5708
|
const room = useRoomOf(paneRef);
|
|
5631
|
-
|
|
5709
|
+
useEffect15(() => {
|
|
5632
5710
|
const was = prev.current;
|
|
5633
5711
|
const id = item?.id ?? null;
|
|
5634
5712
|
if (was && was.id === id && was.mode === mode && editing) {
|
|
@@ -5641,22 +5719,22 @@ function ItemPane(props) {
|
|
|
5641
5719
|
}
|
|
5642
5720
|
prev.current = { base, id, mode };
|
|
5643
5721
|
}, [base, mode, item?.id, editing]);
|
|
5644
|
-
|
|
5722
|
+
useEffect15(() => {
|
|
5645
5723
|
setLoaded({});
|
|
5646
5724
|
setShowTags(false);
|
|
5647
5725
|
setShowDescription(false);
|
|
5648
5726
|
setShowRecovery(false);
|
|
5649
5727
|
setSavedNew(false);
|
|
5650
5728
|
}, [item?.id, mode]);
|
|
5651
|
-
const onDirtyRef =
|
|
5729
|
+
const onDirtyRef = useRef13(onDirty);
|
|
5652
5730
|
onDirtyRef.current = onDirty;
|
|
5653
|
-
|
|
5731
|
+
useEffect15(() => onDirtyRef.current(dirty), [dirty]);
|
|
5654
5732
|
const keepKey = draftKey(item?.id ?? null, definition?.key ?? item?.definitionKey ?? null);
|
|
5655
|
-
|
|
5733
|
+
useEffect15(() => {
|
|
5656
5734
|
if (editing && dirty) keepDraft(keepKey, keptFieldsOf(draft), { basedOn: item?.updatedAt ?? "new" });
|
|
5657
5735
|
else if (!editing) dropKeptDraft(keepKey);
|
|
5658
5736
|
}, [editing, dirty, draft, keepKey, item?.updatedAt]);
|
|
5659
|
-
|
|
5737
|
+
useEffect15(() => {
|
|
5660
5738
|
if (!editing || !item) return;
|
|
5661
5739
|
let live = true;
|
|
5662
5740
|
for (const f of item.fields) {
|
|
@@ -5781,7 +5859,7 @@ function ItemPane(props) {
|
|
|
5781
5859
|
const turnOnOne = canTurnOn ? (f) => () => turnOn([f]) : () => void 0;
|
|
5782
5860
|
const declaredKeys = new Set(declared.map((f) => f.key));
|
|
5783
5861
|
const hasSecureNote = declaredKeys.has(SECURE_NOTE_KEY) || Boolean(item?.fields.some((f) => f.key === SECURE_NOTE_KEY)) || draft.secrets.some((x) => x.key === SECURE_NOTE_KEY);
|
|
5784
|
-
const [settingsToggled, setSettingsToggled] =
|
|
5862
|
+
const [settingsToggled, setSettingsToggled] = useState26(/* @__PURE__ */ new Set());
|
|
5785
5863
|
const settingsOpen = (f) => settingsToggled.has(f.key) !== (definition?.key === ENV_VALUE_KEY || hasDeclaredSettings(draft.fieldSettings?.[f.key], f.handling));
|
|
5786
5864
|
const toggleSettings = (key) => setSettingsToggled((cur) => {
|
|
5787
5865
|
const next = new Set(cur);
|
|
@@ -6158,8 +6236,8 @@ function ItemList({ title, items, definitions, port, selectedId, onSelect, query
|
|
|
6158
6236
|
const pinned = matchingIds ? items.filter((i) => matchingIds.has(i.id)) : [];
|
|
6159
6237
|
const rest = matchingIds ? items.filter((i) => !matchingIds.has(i.id)) : items;
|
|
6160
6238
|
const ordered = [...pinned, ...rest];
|
|
6161
|
-
const listRef =
|
|
6162
|
-
|
|
6239
|
+
const listRef = useRef14(null);
|
|
6240
|
+
useEffect16(() => {
|
|
6163
6241
|
if (selectedId) listRef.current?.querySelector(`[data-item="${selectedId}"]`)?.scrollIntoView({ block: "nearest" });
|
|
6164
6242
|
}, [selectedId, items.length]);
|
|
6165
6243
|
const familyOf2 = (key) => definitions.find((d) => d.key === key)?.family ?? "generic";
|
|
@@ -6222,8 +6300,8 @@ function ListRow({ item, family, port, on, onSelect, withOwner, ownContextMenu,
|
|
|
6222
6300
|
const confirmed = useConfirmed();
|
|
6223
6301
|
const copy = useCopy();
|
|
6224
6302
|
const notify = useNotify();
|
|
6225
|
-
const [busy, setBusy] =
|
|
6226
|
-
const [menuOpen, setMenuOpen] =
|
|
6303
|
+
const [busy, setBusy] = useState27(false);
|
|
6304
|
+
const [menuOpen, setMenuOpen] = useState27(false);
|
|
6227
6305
|
const canUse = item.capabilities.canUse;
|
|
6228
6306
|
const user = canUse ? item.fields.find((f) => USERNAME_KEYS.test(f.key) && f.handling !== "sealed" && f.active !== false) : void 0;
|
|
6229
6307
|
const secret = canUse && item.capabilities.canReveal ? item.fields.find((f) => f.key === "password" && f.handling === "revealable" && f.active !== false) : void 0;
|
|
@@ -6262,7 +6340,7 @@ function ListRow({ item, family, port, on, onSelect, withOwner, ownContextMenu,
|
|
|
6262
6340
|
...manageEntries(item, onAction),
|
|
6263
6341
|
...hostEntries.map((h) => ({ ...h, kind: h.kind ?? "host" }))
|
|
6264
6342
|
];
|
|
6265
|
-
const entriesRef =
|
|
6343
|
+
const entriesRef = useRef14(entries);
|
|
6266
6344
|
entriesRef.current = entries;
|
|
6267
6345
|
const glyphOf = (e) => e.id === "copy:username" ? /* @__PURE__ */ jsx25(UserGlyph, { className: "size-4" }) : e.id === "copy:password" ? /* @__PURE__ */ jsx25(KeyGlyph, { className: "size-4" }) : e.id === "copy:code" ? /* @__PURE__ */ jsx25(ClockGlyph, { className: "size-4" }) : e.kind === "favorite" ? /* @__PURE__ */ jsx25(StarGlyph, { className: cn11("size-4", favorite?.on && "fill-current text-warning") }) : e.kind === "open" ? /* @__PURE__ */ jsx25(ChevronRightGlyph, { className: "size-4" }) : e.kind === "host" || e.kind === "manage" ? null : /* @__PURE__ */ jsx25(CopyIcon7, { className: "size-4" });
|
|
6268
6346
|
const menuItem = (e) => /* @__PURE__ */ jsxs23(DropdownMenuItem4, { disabled: e.disabled ?? false, onSelect: e.onSelect, children: [
|
|
@@ -6285,21 +6363,25 @@ function ListRow({ item, family, port, on, onSelect, withOwner, ownContextMenu,
|
|
|
6285
6363
|
{
|
|
6286
6364
|
type: "button",
|
|
6287
6365
|
"aria-current": on ? "true" : void 0,
|
|
6288
|
-
|
|
6366
|
+
selected: on,
|
|
6367
|
+
selectedStyle: "primary",
|
|
6289
6368
|
onClick: () => onSelect(item.id),
|
|
6290
6369
|
layout: "row",
|
|
6291
6370
|
variant: "quiet",
|
|
6371
|
+
endInset: "control",
|
|
6372
|
+
oneLine: true,
|
|
6292
6373
|
icon: /* @__PURE__ */ jsx25(ItemIcon, { definitionKey: item.definitionKey, family, site: loginSiteOf(item), inverted: on }),
|
|
6293
6374
|
title: item.name,
|
|
6294
6375
|
line: subtitleOf(item, withOwner),
|
|
6295
|
-
className: "w-full
|
|
6376
|
+
className: "w-full"
|
|
6296
6377
|
}
|
|
6297
6378
|
),
|
|
6298
6379
|
/* @__PURE__ */ jsxs23("div", { className: "absolute right-1.5 top-1/2 flex -translate-y-1/2 items-center gap-0.5", "data-surface": on ? "primary" : void 0, children: [
|
|
6299
|
-
user || secret || favorite ? /* @__PURE__ */ jsxs23("div", { className: cn11("hidden items-center gap-0.5 rounded-md pl-2 [@media(hover:hover)]:group-hover:flex [@media(hover:hover)]:group-focus-within:flex", on ? "bg-primary" : "bg-accent"), "data-row-quick": "", children: [
|
|
6380
|
+
user || secret || code || favorite ? /* @__PURE__ */ jsxs23("div", { className: cn11("hidden items-center gap-0.5 rounded-md pl-2 [@media(hover:hover)]:group-hover:flex [@media(hover:hover)]:group-focus-within:flex", on ? "bg-primary" : "bg-accent"), "data-row-quick": "", children: [
|
|
6300
6381
|
favorite ? /* @__PURE__ */ jsx25(Button22, { variant: "quiet", icon: /* @__PURE__ */ jsx25(StarGlyph, { className: favorite.on ? "fill-current text-warning" : "" }), "aria-label": favorite.on ? "Remove from favorites" : "Add to favorites", "aria-pressed": favorite.on, onClick: favorite.toggle }) : null,
|
|
6301
6382
|
user ? /* @__PURE__ */ jsx25(Button22, { variant: "quiet", icon: /* @__PURE__ */ jsx25(UserGlyph, {}), "aria-label": `Copy ${user.label}`, disabled: busy, onClick: copyUser }) : null,
|
|
6302
|
-
secret ? /* @__PURE__ */ jsx25(Button22, { variant: "quiet", icon: /* @__PURE__ */ jsx25(KeyGlyph, {}), "aria-label": "Copy password", disabled: busy, onClick: copyPassword }) : null
|
|
6383
|
+
secret ? /* @__PURE__ */ jsx25(Button22, { variant: "quiet", icon: /* @__PURE__ */ jsx25(KeyGlyph, {}), "aria-label": "Copy password", disabled: busy, onClick: copyPassword }) : null,
|
|
6384
|
+
code ? /* @__PURE__ */ jsx25(Button22, { variant: "quiet", icon: /* @__PURE__ */ jsx25(ClockGlyph, {}), "aria-label": "Copy one-time code", disabled: busy, onClick: copyCode }) : null
|
|
6303
6385
|
] }) : null,
|
|
6304
6386
|
/* @__PURE__ */ jsxs23(DropdownMenu4, { open: menuOpen, onOpenChange: setMenuOpen, children: [
|
|
6305
6387
|
/* @__PURE__ */ jsx25(DropdownMenuTrigger4, { asChild: true, children: /* @__PURE__ */ jsx25(
|
|
@@ -6340,7 +6422,7 @@ function manageEntries(item, onAction) {
|
|
|
6340
6422
|
}
|
|
6341
6423
|
|
|
6342
6424
|
// src/lists/TrashView.tsx
|
|
6343
|
-
import { useState as
|
|
6425
|
+
import { useState as useState29 } from "react";
|
|
6344
6426
|
import { Button as Button24 } from "@ai-matrx/design-system/controls";
|
|
6345
6427
|
import { formatAbsoluteDate as formatAbsoluteDate4 } from "@ai-matrx/kit/format";
|
|
6346
6428
|
|
|
@@ -6414,7 +6496,7 @@ function refusalText(reason) {
|
|
|
6414
6496
|
}
|
|
6415
6497
|
|
|
6416
6498
|
// src/lists/RestorePanel.tsx
|
|
6417
|
-
import { useEffect as
|
|
6499
|
+
import { useEffect as useEffect17, useState as useState28 } from "react";
|
|
6418
6500
|
import { Button as Button23 } from "@ai-matrx/design-system/controls";
|
|
6419
6501
|
import { Fragment as Fragment18, jsx as jsx26, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
6420
6502
|
var count = (n, one) => `${n} ${one}${n === 1 ? "" : "s"}`;
|
|
@@ -6425,13 +6507,13 @@ function RestorePanel({
|
|
|
6425
6507
|
turnOn,
|
|
6426
6508
|
onClose
|
|
6427
6509
|
}) {
|
|
6428
|
-
const [preview, setPreview] =
|
|
6429
|
-
const [restored, setRestored] =
|
|
6430
|
-
const [turnedOn, setTurnedOn] =
|
|
6431
|
-
const [error, setError] =
|
|
6432
|
-
const [busy, setBusy] =
|
|
6433
|
-
const [loading, setLoading] =
|
|
6434
|
-
|
|
6510
|
+
const [preview, setPreview] = useState28(null);
|
|
6511
|
+
const [restored, setRestored] = useState28(null);
|
|
6512
|
+
const [turnedOn, setTurnedOn] = useState28(null);
|
|
6513
|
+
const [error, setError] = useState28(null);
|
|
6514
|
+
const [busy, setBusy] = useState28(false);
|
|
6515
|
+
const [loading, setLoading] = useState28(Boolean(lists.preview));
|
|
6516
|
+
useEffect17(() => {
|
|
6435
6517
|
if (!lists.preview) return;
|
|
6436
6518
|
let live = true;
|
|
6437
6519
|
lists.preview(item).then(
|
|
@@ -6535,10 +6617,10 @@ function trashLineOf(item) {
|
|
|
6535
6617
|
}
|
|
6536
6618
|
function TrashView({ port, deleted, query, header, onChanged }) {
|
|
6537
6619
|
const confirmed = useConfirmed();
|
|
6538
|
-
const [busyId, setBusyId] =
|
|
6539
|
-
const [message2, setMessage] =
|
|
6620
|
+
const [busyId, setBusyId] = useState29(null);
|
|
6621
|
+
const [message2, setMessage] = useState29(null);
|
|
6540
6622
|
const shown = deleted.filter((i) => trashItemMatchesQuery(i, query));
|
|
6541
|
-
const [restoring, setRestoring] =
|
|
6623
|
+
const [restoring, setRestoring] = useState29(null);
|
|
6542
6624
|
const restore = async (item, deletionId) => {
|
|
6543
6625
|
setBusyId(item.id);
|
|
6544
6626
|
setMessage(null);
|
|
@@ -6586,12 +6668,12 @@ function TrashView({ port, deleted, query, header, onChanged }) {
|
|
|
6586
6668
|
}
|
|
6587
6669
|
|
|
6588
6670
|
// src/NewItemFlow.tsx
|
|
6589
|
-
import { useMemo as useMemo4, useState as
|
|
6671
|
+
import { useMemo as useMemo4, useState as useState30 } from "react";
|
|
6590
6672
|
import { Button as Button25, Field as Field10, SearchField as SearchField2, Tile as Tile4 } from "@ai-matrx/design-system/controls";
|
|
6591
6673
|
import { GlobeIcon as GlobeIcon2 } from "@ai-matrx/design-system/icons";
|
|
6592
6674
|
import { jsx as jsx28, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
6593
6675
|
function NewItemFlow({ definitions, url, onUrl, onChoose, onCancel }) {
|
|
6594
|
-
const [search, setSearch] =
|
|
6676
|
+
const [search, setSearch] = useState30("");
|
|
6595
6677
|
const guess = useMemo4(() => inferFromUrl(url, definitions), [url, definitions]);
|
|
6596
6678
|
const common = COMMON_DEFINITION_KEYS.map((k) => definitions.find((d) => d.key === k)).filter((d) => d !== void 0);
|
|
6597
6679
|
const matches = useMemo4(() => {
|
|
@@ -6665,7 +6747,7 @@ function NewItemFlow({ definitions, url, onUrl, onChoose, onCancel }) {
|
|
|
6665
6747
|
}
|
|
6666
6748
|
|
|
6667
6749
|
// src/sharing/SecureLinkPanel.tsx
|
|
6668
|
-
import { useEffect as
|
|
6750
|
+
import { useEffect as useEffect18, useRef as useRef15, useState as useState31 } from "react";
|
|
6669
6751
|
import { confirm as confirm11 } from "@ai-matrx/kit/confirm-opener";
|
|
6670
6752
|
import { Checkbox as Checkbox2 } from "@ai-matrx/design-system";
|
|
6671
6753
|
import { Badge as Badge8, Button as Button26, Field as Field11, RegionSkeleton as RegionSkeleton2, SegmentedControl as SegmentedControl6, Textarea as Textarea4 } from "@ai-matrx/design-system/controls";
|
|
@@ -6748,20 +6830,20 @@ import { jsx as jsx29, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
|
6748
6830
|
function SecureLinkPanel({ item, port, onClose }) {
|
|
6749
6831
|
const sharing = port.sharing;
|
|
6750
6832
|
const { busy, error, notice, run, setNotice } = useConfirmedChange();
|
|
6751
|
-
const [remedy, setRemedy] =
|
|
6752
|
-
const [options, setOptions] =
|
|
6753
|
-
const [optionsError, setOptionsError] =
|
|
6754
|
-
const [sent, setSent] =
|
|
6755
|
-
const [sentError, setSentError] =
|
|
6756
|
-
const [nonce, setNonce] =
|
|
6757
|
-
const [email, setEmail] =
|
|
6758
|
-
const [phone, setPhone] =
|
|
6759
|
-
const [name, setName] =
|
|
6760
|
-
const [linkBy, setLinkBy] =
|
|
6761
|
-
const [fields, setFields] =
|
|
6762
|
-
const [note, setNote] =
|
|
6763
|
-
const [sameChannelSent, setSameChannelSent] =
|
|
6764
|
-
|
|
6833
|
+
const [remedy, setRemedy] = useState31(null);
|
|
6834
|
+
const [options, setOptions] = useState31(null);
|
|
6835
|
+
const [optionsError, setOptionsError] = useState31(null);
|
|
6836
|
+
const [sent, setSent] = useState31(null);
|
|
6837
|
+
const [sentError, setSentError] = useState31(null);
|
|
6838
|
+
const [nonce, setNonce] = useState31(0);
|
|
6839
|
+
const [email, setEmail] = useState31("");
|
|
6840
|
+
const [phone, setPhone] = useState31("");
|
|
6841
|
+
const [name, setName] = useState31("");
|
|
6842
|
+
const [linkBy, setLinkBy] = useState31("email");
|
|
6843
|
+
const [fields, setFields] = useState31([]);
|
|
6844
|
+
const [note, setNote] = useState31("");
|
|
6845
|
+
const [sameChannelSent, setSameChannelSent] = useState31(false);
|
|
6846
|
+
useEffect18(() => {
|
|
6765
6847
|
let live = true;
|
|
6766
6848
|
setOptionsError(null);
|
|
6767
6849
|
sharing.secureLinkOptions(item).then(
|
|
@@ -6776,7 +6858,7 @@ function SecureLinkPanel({ item, port, onClose }) {
|
|
|
6776
6858
|
live = false;
|
|
6777
6859
|
};
|
|
6778
6860
|
}, [sharing, item]);
|
|
6779
|
-
|
|
6861
|
+
useEffect18(() => {
|
|
6780
6862
|
const list = sharing.sentSecureLinks;
|
|
6781
6863
|
if (!list) return;
|
|
6782
6864
|
let live = true;
|
|
@@ -6789,9 +6871,9 @@ function SecureLinkPanel({ item, port, onClose }) {
|
|
|
6789
6871
|
live = false;
|
|
6790
6872
|
};
|
|
6791
6873
|
}, [sharing, item, nonce]);
|
|
6792
|
-
const [phoneTyped, setPhoneTyped] =
|
|
6793
|
-
const prefilled =
|
|
6794
|
-
|
|
6874
|
+
const [phoneTyped, setPhoneTyped] = useState31(false);
|
|
6875
|
+
const prefilled = useRef15(false);
|
|
6876
|
+
useEffect18(() => {
|
|
6795
6877
|
const lookup = sharing.phoneOnFile;
|
|
6796
6878
|
if (!lookup || phoneTyped) return;
|
|
6797
6879
|
const clear = () => {
|
|
@@ -6944,7 +7026,7 @@ function sentMeta(row, options) {
|
|
|
6944
7026
|
}
|
|
6945
7027
|
|
|
6946
7028
|
// src/devices/DevicesPanel.tsx
|
|
6947
|
-
import { useCallback as useCallback3, useEffect as
|
|
7029
|
+
import { useCallback as useCallback3, useEffect as useEffect19, useState as useState32 } from "react";
|
|
6948
7030
|
import { confirm as confirm12 } from "@ai-matrx/kit/confirm-opener";
|
|
6949
7031
|
import { Button as Button27, RegionSkeleton as RegionSkeleton3 } from "@ai-matrx/design-system/controls";
|
|
6950
7032
|
import { formatAbsoluteDate as formatAbsoluteDate6 } from "@ai-matrx/kit/format";
|
|
@@ -7035,9 +7117,9 @@ function ErrorLine2({ text }) {
|
|
|
7035
7117
|
function DevicesPanel({ port, onClose }) {
|
|
7036
7118
|
const confirmed = useConfirmed();
|
|
7037
7119
|
const notify = useNotify();
|
|
7038
|
-
const [devices, setDevices] =
|
|
7039
|
-
const [error, setError] =
|
|
7040
|
-
const [busyId, setBusyId] =
|
|
7120
|
+
const [devices, setDevices] = useState32(null);
|
|
7121
|
+
const [error, setError] = useState32(null);
|
|
7122
|
+
const [busyId, setBusyId] = useState32(null);
|
|
7041
7123
|
const load = useCallback3(async () => {
|
|
7042
7124
|
setError(null);
|
|
7043
7125
|
try {
|
|
@@ -7046,7 +7128,7 @@ function DevicesPanel({ port, onClose }) {
|
|
|
7046
7128
|
setError(messageOf3(e, "Your browsers could not be read."));
|
|
7047
7129
|
}
|
|
7048
7130
|
}, [port]);
|
|
7049
|
-
|
|
7131
|
+
useEffect19(() => {
|
|
7050
7132
|
void load();
|
|
7051
7133
|
}, [load]);
|
|
7052
7134
|
const revoke = async (device) => {
|
|
@@ -7104,10 +7186,10 @@ function ApprovePanel({ port, host, onClose, approvalKey, label, kind = "browser
|
|
|
7104
7186
|
const where = isMac ? "the Mac app" : "the extension";
|
|
7105
7187
|
const passkeys = port.devices.passkeys;
|
|
7106
7188
|
const here = passkeys?.available() ?? false;
|
|
7107
|
-
const [methods, setMethods] =
|
|
7108
|
-
const [busy, setBusy] =
|
|
7109
|
-
const [error, setError] =
|
|
7110
|
-
const [approvedUntil, setApprovedUntil] =
|
|
7189
|
+
const [methods, setMethods] = useState32(null);
|
|
7190
|
+
const [busy, setBusy] = useState32(null);
|
|
7191
|
+
const [error, setError] = useState32(null);
|
|
7192
|
+
const [approvedUntil, setApprovedUntil] = useState32(null);
|
|
7111
7193
|
const load = useCallback3(async () => {
|
|
7112
7194
|
setError(null);
|
|
7113
7195
|
try {
|
|
@@ -7116,7 +7198,7 @@ function ApprovePanel({ port, host, onClose, approvalKey, label, kind = "browser
|
|
|
7116
7198
|
setError(messageOf3(e, "Your account could not be checked."));
|
|
7117
7199
|
}
|
|
7118
7200
|
}, [port]);
|
|
7119
|
-
|
|
7201
|
+
useEffect19(() => {
|
|
7120
7202
|
if (key && here) void load();
|
|
7121
7203
|
}, [key, here, load]);
|
|
7122
7204
|
const approve = async () => {
|
|
@@ -7204,7 +7286,7 @@ function ApprovePanel({ port, host, onClose, approvalKey, label, kind = "browser
|
|
|
7204
7286
|
}
|
|
7205
7287
|
|
|
7206
7288
|
// src/native/NativeImportPanel.tsx
|
|
7207
|
-
import { useEffect as
|
|
7289
|
+
import { useEffect as useEffect21, useMemo as useMemo5, useState as useState34 } from "react";
|
|
7208
7290
|
import { confirm as confirm13 } from "@ai-matrx/kit/confirm-opener";
|
|
7209
7291
|
import { Badge as Badge9, Button as Button28, Select as Select10 } from "@ai-matrx/design-system/controls";
|
|
7210
7292
|
|
|
@@ -7267,19 +7349,19 @@ async function loadFullPreview(bridge, operationId, current) {
|
|
|
7267
7349
|
}
|
|
7268
7350
|
|
|
7269
7351
|
// src/native/use-native-import.ts
|
|
7270
|
-
import { useEffect as
|
|
7352
|
+
import { useEffect as useEffect20, useRef as useRef16, useState as useState33 } from "react";
|
|
7271
7353
|
var fail = (e, fallback) => e instanceof Error && e.message ? e.message : fallback;
|
|
7272
7354
|
var RESTART = "Your account changed. The import was stopped; start it again.";
|
|
7273
7355
|
function useNativeImport(bridge, stillAllowed, onImported) {
|
|
7274
|
-
const [screen, setScreen] =
|
|
7275
|
-
const [busy, setBusy] =
|
|
7276
|
-
const generation =
|
|
7277
|
-
const mounted =
|
|
7278
|
-
const op =
|
|
7279
|
-
const last =
|
|
7280
|
-
const timer2 =
|
|
7281
|
-
const polls =
|
|
7282
|
-
const refreshRef =
|
|
7356
|
+
const [screen, setScreen] = useState33({ kind: "idle", message: null });
|
|
7357
|
+
const [busy, setBusy] = useState33(false);
|
|
7358
|
+
const generation = useRef16(0);
|
|
7359
|
+
const mounted = useRef16(false);
|
|
7360
|
+
const op = useRef16(null);
|
|
7361
|
+
const last = useRef16(null);
|
|
7362
|
+
const timer2 = useRef16(null);
|
|
7363
|
+
const polls = useRef16(0);
|
|
7364
|
+
const refreshRef = useRef16(async () => void 0);
|
|
7283
7365
|
const current = (g) => mounted.current && g === generation.current;
|
|
7284
7366
|
const stopPolling = () => {
|
|
7285
7367
|
if (timer2.current !== null) clearTimeout(timer2.current);
|
|
@@ -7448,9 +7530,9 @@ function useNativeImport(bridge, stillAllowed, onImported) {
|
|
|
7448
7530
|
setBusy(false);
|
|
7449
7531
|
setScreen({ kind: "idle", message: null });
|
|
7450
7532
|
};
|
|
7451
|
-
const invalidateRef =
|
|
7533
|
+
const invalidateRef = useRef16(invalidate);
|
|
7452
7534
|
invalidateRef.current = invalidate;
|
|
7453
|
-
|
|
7535
|
+
useEffect20(() => {
|
|
7454
7536
|
mounted.current = true;
|
|
7455
7537
|
const off = bridge.subscribe?.(() => {
|
|
7456
7538
|
if (op.current) invalidateRef.current(RESTART);
|
|
@@ -7483,13 +7565,13 @@ function NativeImportPanel({ bridge, readLimits, activeOrganizationId, organizat
|
|
|
7483
7565
|
}
|
|
7484
7566
|
function Importer({ bridge, readLimits, activeOrganizationId, organizations, onClose, onChanged }) {
|
|
7485
7567
|
const options = useMemo5(() => organizations.map((o) => ({ value: o.id, label: o.name })), [organizations]);
|
|
7486
|
-
const [organizationId, setOrganizationId] =
|
|
7487
|
-
const [limits, setLimits] =
|
|
7488
|
-
const [limitError, setLimitError] =
|
|
7568
|
+
const [organizationId, setOrganizationId] = useState34(() => organizations.some((o) => o.id === activeOrganizationId) ? activeOrganizationId : organizations[0]?.id ?? "");
|
|
7569
|
+
const [limits, setLimits] = useState34(null);
|
|
7570
|
+
const [limitError, setLimitError] = useState34(null);
|
|
7489
7571
|
const flow = useNativeImport(bridge, (id) => organizations.some((o) => o.id === id), onChanged);
|
|
7490
7572
|
const { screen, busy } = flow;
|
|
7491
7573
|
const orgName = organizations.find((o) => o.id === organizationId)?.name ?? "this organization";
|
|
7492
|
-
|
|
7574
|
+
useEffect21(() => {
|
|
7493
7575
|
if (!readLimits || !organizationId) return;
|
|
7494
7576
|
let live = true;
|
|
7495
7577
|
setLimits(null);
|
|
@@ -7550,21 +7632,21 @@ function Importer({ bridge, readLimits, activeOrganizationId, organizations, onC
|
|
|
7550
7632
|
}
|
|
7551
7633
|
|
|
7552
7634
|
// src/extension/PageView.tsx
|
|
7553
|
-
import { useState as
|
|
7635
|
+
import { useState as useState38 } from "react";
|
|
7554
7636
|
import { SiteIcon } from "@ai-matrx/design-system";
|
|
7555
7637
|
import { Button as Button32, Tile as Tile5 } from "@ai-matrx/design-system/controls";
|
|
7556
7638
|
import { GlobeIcon as GlobeIcon3 } from "@ai-matrx/design-system/icons";
|
|
7557
7639
|
|
|
7558
7640
|
// src/extension/CaptureCard.tsx
|
|
7559
|
-
import { useState as
|
|
7641
|
+
import { useState as useState35, useSyncExternalStore as useSyncExternalStore3 } from "react";
|
|
7560
7642
|
import { Button as Button29, SearchField as SearchField3 } from "@ai-matrx/design-system/controls";
|
|
7561
7643
|
import { Fragment as Fragment21, jsx as jsx32, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
7562
7644
|
var SEARCH_FROM = 4;
|
|
7563
7645
|
function CaptureCard({ capture, onChanged }) {
|
|
7564
7646
|
const prompt = useSyncExternalStore3(capture.subscribe, capture.get, capture.get);
|
|
7565
7647
|
const notify = useNotify();
|
|
7566
|
-
const [busy, setBusy] =
|
|
7567
|
-
const [q, setQ] =
|
|
7648
|
+
const [busy, setBusy] = useState35(false);
|
|
7649
|
+
const [q, setQ] = useState35("");
|
|
7568
7650
|
if (!prompt) return null;
|
|
7569
7651
|
const decide = async (d) => {
|
|
7570
7652
|
setBusy(true);
|
|
@@ -7620,15 +7702,15 @@ function CaptureCard({ capture, onChanged }) {
|
|
|
7620
7702
|
}
|
|
7621
7703
|
|
|
7622
7704
|
// src/extension/FillSetupCard.tsx
|
|
7623
|
-
import { useRef as
|
|
7705
|
+
import { useRef as useRef17, useState as useState36, useSyncExternalStore as useSyncExternalStore4 } from "react";
|
|
7624
7706
|
import { Button as Button30, Field as Field12 } from "@ai-matrx/design-system/controls";
|
|
7625
7707
|
import { jsx as jsx33, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
7626
7708
|
function FillSetupCard({ fillSetup }) {
|
|
7627
7709
|
const notify = useNotify();
|
|
7628
7710
|
const state = useSyncExternalStore4(fillSetup.subscribe, fillSetup.get, fillSetup.get);
|
|
7629
|
-
const box =
|
|
7630
|
-
const [busy, setBusy] =
|
|
7631
|
-
const [error, setError] =
|
|
7711
|
+
const box = useRef17(null);
|
|
7712
|
+
const [busy, setBusy] = useState36(false);
|
|
7713
|
+
const [error, setError] = useState36(null);
|
|
7632
7714
|
if (state.status !== "off") return null;
|
|
7633
7715
|
const finish = async (run) => {
|
|
7634
7716
|
setBusy(true);
|
|
@@ -7693,7 +7775,7 @@ function FillSetupCard({ fillSetup }) {
|
|
|
7693
7775
|
}
|
|
7694
7776
|
|
|
7695
7777
|
// src/extension/PageGenerator.tsx
|
|
7696
|
-
import { useState as
|
|
7778
|
+
import { useState as useState37 } from "react";
|
|
7697
7779
|
import { Popover as Popover2, PopoverContent as PopoverContent2, PopoverTrigger as PopoverTrigger2 } from "@ai-matrx/design-system";
|
|
7698
7780
|
import { Button as Button31 } from "@ai-matrx/design-system/controls";
|
|
7699
7781
|
import { CopyIcon as CopyIcon8 } from "@ai-matrx/design-system/icons";
|
|
@@ -7703,10 +7785,10 @@ function PageGenerator({ fields }) {
|
|
|
7703
7785
|
const limits = useGeneratorLimitsSource();
|
|
7704
7786
|
const copy = useCopy();
|
|
7705
7787
|
const held = useTransientSecret(HOLD_MS);
|
|
7706
|
-
const [open, setOpen] =
|
|
7707
|
-
const [busy, setBusy] =
|
|
7708
|
-
const [targets, setTargets] =
|
|
7709
|
-
const [said, setSaid] =
|
|
7788
|
+
const [open, setOpen] = useState37(false);
|
|
7789
|
+
const [busy, setBusy] = useState37(false);
|
|
7790
|
+
const [targets, setTargets] = useState37([]);
|
|
7791
|
+
const [said, setSaid] = useState37(null);
|
|
7710
7792
|
if (!limits) return null;
|
|
7711
7793
|
const say3 = setSaid;
|
|
7712
7794
|
const put = async (targetId, value2) => {
|
|
@@ -7770,8 +7852,8 @@ function PageGenerator({ fields }) {
|
|
|
7770
7852
|
// src/extension/PageView.tsx
|
|
7771
7853
|
import { jsx as jsx35, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
7772
7854
|
function PageView({ port, page, fill, capture, fillSetup, newPasswordFields, items, definitions, onOpen, onNewForPage, onBrowse, onChanged, header }) {
|
|
7773
|
-
const [running, setRunning] =
|
|
7774
|
-
const [said, setSaid] =
|
|
7855
|
+
const [running, setRunning] = useState38(null);
|
|
7856
|
+
const [said, setSaid] = useState38(null);
|
|
7775
7857
|
const site = pageSite(page.url);
|
|
7776
7858
|
const state = page.matchState ?? { status: "ready" };
|
|
7777
7859
|
const fillable = new Set(page.fillableItemIds ?? page.matchingItemIds);
|
|
@@ -7780,8 +7862,8 @@ function PageView({ port, page, fill, capture, fillSetup, newPasswordFields, ite
|
|
|
7780
7862
|
const familyOf2 = (key) => definitions.find((d) => d.key === key)?.family ?? "generic";
|
|
7781
7863
|
const canSave = isFillablePage(page.url);
|
|
7782
7864
|
const signIn = page.signIn;
|
|
7783
|
-
const act = async (itemId, run, failed) => {
|
|
7784
|
-
setRunning(itemId);
|
|
7865
|
+
const act = async (itemId, action, run, failed) => {
|
|
7866
|
+
setRunning({ itemId, action });
|
|
7785
7867
|
setSaid(null);
|
|
7786
7868
|
try {
|
|
7787
7869
|
setSaid(await run());
|
|
@@ -7814,10 +7896,10 @@ function PageView({ port, page, fill, capture, fillSetup, newPasswordFields, ite
|
|
|
7814
7896
|
family: item ? familyOf2(item.definitionKey) : "generic",
|
|
7815
7897
|
port,
|
|
7816
7898
|
busy: running !== null,
|
|
7817
|
-
running: running === itemId,
|
|
7899
|
+
running: running?.itemId === itemId ? running.action : null,
|
|
7818
7900
|
onOpen,
|
|
7819
|
-
onFill: fill && !page.blocked && fillable.has(itemId) && item?.capabilities.canUse !== false ? () => void act(itemId, async () => FILL_WORDS[await fill(itemId)], FILL_WORDS.unavailable) : null,
|
|
7820
|
-
onSignIn: signIn ? () => void act(itemId, async () => SIGN_IN_WORDS[await signIn(itemId)], SIGN_IN_WORDS.unknown) : null
|
|
7901
|
+
onFill: fill && !page.blocked && fillable.has(itemId) && item?.capabilities.canUse !== false ? () => void act(itemId, "fill", async () => FILL_WORDS[await fill(itemId)], FILL_WORDS.unavailable) : null,
|
|
7902
|
+
onSignIn: signIn ? () => void act(itemId, "signIn", async () => SIGN_IN_WORDS[await signIn(itemId)], SIGN_IN_WORDS.unknown) : null
|
|
7821
7903
|
},
|
|
7822
7904
|
itemId
|
|
7823
7905
|
)) });
|
|
@@ -7855,7 +7937,7 @@ function MatchRow({ itemId, item, tag, family, port, busy, running, onOpen, onFi
|
|
|
7855
7937
|
const confirmed = useConfirmed();
|
|
7856
7938
|
const copy = useCopy();
|
|
7857
7939
|
const notify = useNotify();
|
|
7858
|
-
const [reading, setReading] =
|
|
7940
|
+
const [reading, setReading] = useState38(false);
|
|
7859
7941
|
const usable = item?.capabilities.canUse ?? false;
|
|
7860
7942
|
const user = usable ? item?.fields.find((f) => USERNAME_KEYS.test(f.key) && f.handling !== "sealed" && f.active) : void 0;
|
|
7861
7943
|
const secret = usable && item?.capabilities.canReveal ? item?.fields.find((f) => f.key === "password" && f.handling === "revealable" && f.active) : void 0;
|
|
@@ -7884,8 +7966,8 @@ function MatchRow({ itemId, item, tag, family, port, busy, running, onOpen, onFi
|
|
|
7884
7966
|
className: "min-w-0 flex-1"
|
|
7885
7967
|
}
|
|
7886
7968
|
),
|
|
7887
|
-
onFill ? /* @__PURE__ */ jsx35(Button32, { variant: "primary", disabled: busy, "aria-busy": running || void 0, onClick: onFill, "aria-label": `Fill ${item?.name ?? "this login"}`, children: running ? "Filling\u2026" : "Fill" }) : null,
|
|
7888
|
-
onSignIn ? /* @__PURE__ */ jsx35(Button32, { variant: onFill ? "outline" : "primary", icon: /* @__PURE__ */ jsx35(ShieldGlyph, {}), disabled: busy, onClick: onSignIn, "aria-label": `Sign me in with ${item?.name ?? "this login"}`, title: "Sign me in", children: "Sign me in" }) : null,
|
|
7969
|
+
onFill ? /* @__PURE__ */ jsx35(Button32, { variant: "primary", disabled: busy, "aria-busy": running === "fill" || void 0, onClick: onFill, "aria-label": `Fill ${item?.name ?? "this login"}`, children: running === "fill" ? "Filling\u2026" : "Fill" }) : null,
|
|
7970
|
+
onSignIn ? /* @__PURE__ */ jsx35(Button32, { variant: onFill ? "outline" : "primary", icon: /* @__PURE__ */ jsx35(ShieldGlyph, {}), disabled: busy, "aria-busy": running === "signIn" || void 0, onClick: onSignIn, "aria-label": `Sign me in with ${item?.name ?? "this login"}`, title: "Sign me in", children: running === "signIn" ? "Signing in\u2026" : "Sign me in" }) : null,
|
|
7889
7971
|
user && item ? /* @__PURE__ */ jsx35(Button32, { variant: "quiet", icon: /* @__PURE__ */ jsx35(UserGlyph, {}), "aria-label": `Copy ${user.label}`, title: `Copy ${user.label}`, disabled: reading, onClick: () => void read(user.label, () => port.reveal(item, user.key)) }) : null,
|
|
7890
7972
|
secret && item ? /* @__PURE__ */ jsx35(Button32, { variant: "quiet", icon: /* @__PURE__ */ jsx35(KeyGlyph, {}), "aria-label": "Copy password", title: "Copy password", disabled: reading, onClick: () => void read("Password", () => port.reveal(item, secret.key)) }) : null,
|
|
7891
7973
|
otp ? /* @__PURE__ */ jsx35(Button32, { variant: "quiet", icon: /* @__PURE__ */ jsx35(ClockGlyph, {}), "aria-label": "Copy one-time code", title: "Copy one-time code", disabled: reading, onClick: () => void read("One-time code", async () => (await port.authenticator.code(otp)).code) }) : null
|
|
@@ -7893,8 +7975,8 @@ function MatchRow({ itemId, item, tag, family, port, busy, running, onOpen, onFi
|
|
|
7893
7975
|
}
|
|
7894
7976
|
|
|
7895
7977
|
// src/Sidebar.tsx
|
|
7896
|
-
import { useState as
|
|
7897
|
-
import { cn as cn12 } from "@ai-matrx/design-system";
|
|
7978
|
+
import { useState as useState39 } from "react";
|
|
7979
|
+
import { cn as cn12, useLook as useLook2 } from "@ai-matrx/design-system";
|
|
7898
7980
|
import { DisclosureHeader as DisclosureHeader4, Select as Select11, Tile as Tile6 } from "@ai-matrx/design-system/controls";
|
|
7899
7981
|
import { GlobeIcon as GlobeIcon4 } from "@ai-matrx/design-system/icons";
|
|
7900
7982
|
import { jsx as jsx36, jsxs as jsxs34 } from "react/jsx-runtime";
|
|
@@ -7902,6 +7984,7 @@ var AUTHENTICATOR_LABEL = "Authenticator";
|
|
|
7902
7984
|
function vaultChoices(items, organizations, _current) {
|
|
7903
7985
|
const n = (f) => items.filter(f).length;
|
|
7904
7986
|
const shared = n((i) => i.owner.kind === "shared");
|
|
7987
|
+
const hints = organizationHints(organizations);
|
|
7905
7988
|
return [
|
|
7906
7989
|
{ value: "all", label: "All items", count: items.length },
|
|
7907
7990
|
{ value: "mine", label: "Personal", count: n((i) => i.owner.kind === "me") },
|
|
@@ -7909,11 +7992,11 @@ function vaultChoices(items, organizations, _current) {
|
|
|
7909
7992
|
// Every organization the person belongs to, empty ones too: an empty vault opens on its own
|
|
7910
7993
|
// "Nothing here yet" with New item, so the first credential can go there. (The organization
|
|
7911
7994
|
// list carries no role, so who may add is the server's answer to the save, said in place.)
|
|
7912
|
-
...organizations.map((o) => ({ value: o.id, label: o.name, count: n((i) => i.owner.organizationId === o.id) }))
|
|
7995
|
+
...organizations.map((o) => ({ value: o.id, label: o.name, count: n((i) => i.owner.organizationId === o.id), ...hints.has(o.id) ? { hint: hints.get(o.id) } : {} }))
|
|
7913
7996
|
];
|
|
7914
7997
|
}
|
|
7915
|
-
function VaultSelect({ value, choices, onChange }) {
|
|
7916
|
-
return /* @__PURE__ */ jsx36(Select11, { value, onValueChange: onChange, "aria-label": "Vault", options: choices.map((c) => ({ value: c.value, label: c.label, meta: String(c.count) })) });
|
|
7998
|
+
function VaultSelect({ value, choices, onChange, searchAt = ORGANIZATION_SEARCH_AT_UNREAD }) {
|
|
7999
|
+
return /* @__PURE__ */ jsx36(Select11, { value, onValueChange: onChange, "aria-label": "Vault", searchAt, options: choices.map((c) => ({ value: c.value, label: c.label, meta: String(c.count), ...c.hint ? { hint: c.hint } : {} })) });
|
|
7917
8000
|
}
|
|
7918
8001
|
var CATEGORY_GLYPHS = { logins: GlobeIcon4, passkeys: ShieldGlyph, api: KeyGlyph, oauth: PlugGlyph, infra: DatabaseGlyph, env: TerminalGlyph, files: FileGlyph, other: NoteGlyph };
|
|
7919
8002
|
var familyOf = (key, definitions) => definitions.find((d) => d.key === key)?.family ?? "generic";
|
|
@@ -7977,12 +8060,14 @@ function viewOptions(views, allCount, deletedCount, hasFavorites, hasRecents, ha
|
|
|
7977
8060
|
];
|
|
7978
8061
|
}
|
|
7979
8062
|
function Entry({ on, glyph: Icon, label, count: count2, onClick, nested = false }) {
|
|
8063
|
+
const desktop = useLook2() === "desktop";
|
|
7980
8064
|
return /* @__PURE__ */ jsx36(
|
|
7981
8065
|
Tile6,
|
|
7982
8066
|
{
|
|
7983
8067
|
type: "button",
|
|
7984
8068
|
"aria-current": on ? "page" : void 0,
|
|
7985
8069
|
selected: on,
|
|
8070
|
+
...desktop ? { selectedStyle: "fill" } : {},
|
|
7986
8071
|
onClick,
|
|
7987
8072
|
layout: "row",
|
|
7988
8073
|
variant: "quiet",
|
|
@@ -7990,8 +8075,9 @@ function Entry({ on, glyph: Icon, label, count: count2, onClick, nested = false
|
|
|
7990
8075
|
icon: nested ? void 0 : /* @__PURE__ */ jsx36(Icon, { className: "size-4 shrink-0" }),
|
|
7991
8076
|
title: label,
|
|
7992
8077
|
...count2 !== void 0 ? { end: /* @__PURE__ */ jsx36("span", { className: "text-xs tabular-nums text-muted-foreground", children: count2 }) } : {},
|
|
8078
|
+
...nested ? { level: 1 } : {},
|
|
7993
8079
|
"data-nested": nested ? "" : void 0,
|
|
7994
|
-
className:
|
|
8080
|
+
className: "w-full"
|
|
7995
8081
|
}
|
|
7996
8082
|
);
|
|
7997
8083
|
}
|
|
@@ -8001,12 +8087,12 @@ function Group({ title, children }) {
|
|
|
8001
8087
|
children
|
|
8002
8088
|
] });
|
|
8003
8089
|
}
|
|
8004
|
-
function VaultSidebar({ vault, choices, onVault, view, allCount, deletedCount, views, hasFavorites, hasRecents, onView, onPanel, nativeProvider, hasNativeImport = false, hasPage = false, onLock, onOpenWeb }) {
|
|
8005
|
-
const [tagsOpen, setTagsOpen] =
|
|
8090
|
+
function VaultSidebar({ vault, choices, onVault, organizationSearchAt, view, allCount, deletedCount, views, hasFavorites, hasRecents, onView, onPanel, nativeProvider, hasNativeImport = false, hasPage = false, onLock, onOpenWeb }) {
|
|
8091
|
+
const [tagsOpen, setTagsOpen] = useState39(view.startsWith("tag:"));
|
|
8006
8092
|
return /* @__PURE__ */ jsxs34("nav", { "aria-label": "Vault", className: "flex h-full min-h-0 flex-col border-r border-sidebar-border bg-sidebar-background text-sidebar-foreground", children: [
|
|
8007
8093
|
/* @__PURE__ */ jsxs34("div", { className: "flex items-center gap-2 px-3 pb-2 pt-3", children: [
|
|
8008
8094
|
/* @__PURE__ */ jsx36(SafeGlyph, { className: "size-5 shrink-0 text-primary" }),
|
|
8009
|
-
/* @__PURE__ */ jsx36("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsx36(VaultSelect, { value: vault, choices, onChange: onVault }) })
|
|
8095
|
+
/* @__PURE__ */ jsx36("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsx36(VaultSelect, { value: vault, choices, onChange: onVault, searchAt: organizationSearchAt }) })
|
|
8010
8096
|
] }),
|
|
8011
8097
|
/* @__PURE__ */ jsxs34("div", { className: "flex min-h-0 flex-1 flex-col gap-5 overflow-y-auto px-2 pb-3 pt-1", children: [
|
|
8012
8098
|
/* @__PURE__ */ jsxs34("div", { className: "flex flex-col gap-0.5", children: [
|
|
@@ -8083,8 +8169,8 @@ var generatorLimitsFrom = (knobs) => knobs ? async () => {
|
|
|
8083
8169
|
} : void 0;
|
|
8084
8170
|
function ImportWithLimits(props) {
|
|
8085
8171
|
const { knobs, ...rest } = props;
|
|
8086
|
-
const [state, setState] =
|
|
8087
|
-
|
|
8172
|
+
const [state, setState] = useState40(null);
|
|
8173
|
+
useEffect22(() => {
|
|
8088
8174
|
if (!knobs) return setState({ error: "Import is not set up for this organization yet." });
|
|
8089
8175
|
knobs().then(
|
|
8090
8176
|
(r) => {
|
|
@@ -8109,13 +8195,13 @@ function VaultApp(given) {
|
|
|
8109
8195
|
}
|
|
8110
8196
|
function useOrganizationSettings(host) {
|
|
8111
8197
|
const knobs = host.knobs;
|
|
8112
|
-
const needs = knobs !== void 0 && (host.revealSeconds === void 0 || host.backupPassphraseMinLength === void 0);
|
|
8113
|
-
const [read, setRead] =
|
|
8114
|
-
|
|
8198
|
+
const needs = knobs !== void 0 && (host.revealSeconds === void 0 || host.backupPassphraseMinLength === void 0 || host.organizationSearchAt === void 0);
|
|
8199
|
+
const [read, setRead] = useState40(null);
|
|
8200
|
+
useEffect22(() => {
|
|
8115
8201
|
if (!needs || !knobs) return;
|
|
8116
8202
|
let live = true;
|
|
8117
8203
|
knobs().then(
|
|
8118
|
-
(r) => live && setRead({ reveal: positiveKnob(r, REVEAL_SECONDS_KNOB), backupMin: positiveKnob(r, BACKUP_PASSPHRASE_MIN_KNOB) }),
|
|
8204
|
+
(r) => live && setRead({ reveal: positiveKnob(r, REVEAL_SECONDS_KNOB), backupMin: positiveKnob(r, BACKUP_PASSPHRASE_MIN_KNOB), searchAt: positiveKnob(r, ORGANIZATION_SEARCH_AT_KNOB) }),
|
|
8119
8205
|
() => void 0
|
|
8120
8206
|
);
|
|
8121
8207
|
return () => {
|
|
@@ -8126,7 +8212,8 @@ function useOrganizationSettings(host) {
|
|
|
8126
8212
|
return {
|
|
8127
8213
|
...host,
|
|
8128
8214
|
...host.revealSeconds === void 0 && read.reveal !== null ? { revealSeconds: read.reveal } : {},
|
|
8129
|
-
...host.backupPassphraseMinLength === void 0 && read.backupMin !== null ? { backupPassphraseMinLength: read.backupMin } : {}
|
|
8215
|
+
...host.backupPassphraseMinLength === void 0 && read.backupMin !== null ? { backupPassphraseMinLength: read.backupMin } : {},
|
|
8216
|
+
...host.organizationSearchAt === void 0 && read.searchAt !== null ? { organizationSearchAt: read.searchAt } : {}
|
|
8130
8217
|
};
|
|
8131
8218
|
}
|
|
8132
8219
|
var NO_STORE = () => () => void 0;
|
|
@@ -8137,8 +8224,8 @@ function useHostPrompts(capture, fillSetup) {
|
|
|
8137
8224
|
return prompt !== null || setup?.status === "off";
|
|
8138
8225
|
}
|
|
8139
8226
|
function LockedScreen({ lock }) {
|
|
8140
|
-
const [busy, setBusy] =
|
|
8141
|
-
const [error, setError] =
|
|
8227
|
+
const [busy, setBusy] = useState40(false);
|
|
8228
|
+
const [error, setError] = useState40(null);
|
|
8142
8229
|
const unlock = async () => {
|
|
8143
8230
|
setBusy(true);
|
|
8144
8231
|
setError(null);
|
|
@@ -8158,21 +8245,21 @@ function LockedScreen({ lock }) {
|
|
|
8158
8245
|
] });
|
|
8159
8246
|
}
|
|
8160
8247
|
function Workspace({ port, host = NO_HOST, layout = "auto", location, onLocationChange, onInventory }) {
|
|
8161
|
-
const rootRef =
|
|
8248
|
+
const rootRef = useRef18(null);
|
|
8162
8249
|
const width = useElementWidth(rootRef);
|
|
8163
8250
|
const mode = layout !== "auto" ? layout : width >= FULL_AT ? "full" : width >= SPLIT_AT ? "split" : "stack";
|
|
8164
8251
|
const notify = useNotify();
|
|
8165
|
-
const [snap, setSnap] =
|
|
8166
|
-
const [items, setItems] =
|
|
8167
|
-
const [deleted, setDeleted] =
|
|
8168
|
-
const [favorites, setFavorites] =
|
|
8169
|
-
const [recents, setRecents] =
|
|
8170
|
-
const [error, setError] =
|
|
8171
|
-
const [inner, setInner] =
|
|
8252
|
+
const [snap, setSnap] = useState40(null);
|
|
8253
|
+
const [items, setItems] = useState40([]);
|
|
8254
|
+
const [deleted, setDeleted] = useState40([]);
|
|
8255
|
+
const [favorites, setFavorites] = useState40(null);
|
|
8256
|
+
const [recents, setRecents] = useState40(null);
|
|
8257
|
+
const [error, setError] = useState40(null);
|
|
8258
|
+
const [inner, setInner] = useState40(DEFAULT_LOCATION);
|
|
8172
8259
|
const loc = location ?? inner;
|
|
8173
|
-
const dirty =
|
|
8174
|
-
const [notice, setNotice] =
|
|
8175
|
-
const [firstCode, setFirstCode] =
|
|
8260
|
+
const dirty = useRef18(false);
|
|
8261
|
+
const [notice, setNotice] = useState40(null);
|
|
8262
|
+
const [firstCode, setFirstCode] = useShownUntilMove(loc);
|
|
8176
8263
|
const move = useCallback4(
|
|
8177
8264
|
(next, how) => {
|
|
8178
8265
|
if (!location) setInner(next);
|
|
@@ -8199,9 +8286,9 @@ function Workspace({ port, host = NO_HOST, layout = "auto", location, onLocation
|
|
|
8199
8286
|
},
|
|
8200
8287
|
[loc, move]
|
|
8201
8288
|
);
|
|
8202
|
-
const keyState =
|
|
8289
|
+
const keyState = useRef18({ loc, go });
|
|
8203
8290
|
keyState.current = { loc, go };
|
|
8204
|
-
|
|
8291
|
+
useEffect22(() => {
|
|
8205
8292
|
const onKey = (e) => {
|
|
8206
8293
|
if (e.defaultPrevented || e.metaKey || e.ctrlKey || e.altKey) return;
|
|
8207
8294
|
const root = rootRef.current;
|
|
@@ -8223,8 +8310,8 @@ function Workspace({ port, host = NO_HOST, layout = "auto", location, onLocation
|
|
|
8223
8310
|
document.addEventListener("keydown", onKey);
|
|
8224
8311
|
return () => document.removeEventListener("keydown", onKey);
|
|
8225
8312
|
}, []);
|
|
8226
|
-
const keepSearchFocus =
|
|
8227
|
-
|
|
8313
|
+
const keepSearchFocus = useRef18(false);
|
|
8314
|
+
useEffect22(() => {
|
|
8228
8315
|
if (!keepSearchFocus.current) return;
|
|
8229
8316
|
keepSearchFocus.current = false;
|
|
8230
8317
|
const search = rootRef.current?.querySelector('input[aria-label^="Search"]');
|
|
@@ -8233,13 +8320,13 @@ function Workspace({ port, host = NO_HOST, layout = "auto", location, onLocation
|
|
|
8233
8320
|
search.setSelectionRange(search.value.length, search.value.length);
|
|
8234
8321
|
}, [loc.q]);
|
|
8235
8322
|
const hasPrompts = useHostPrompts(host.capture, host.fillSetup);
|
|
8236
|
-
const knobsRef =
|
|
8323
|
+
const knobsRef = useRef18(host.knobs);
|
|
8237
8324
|
knobsRef.current = host.knobs;
|
|
8238
|
-
const [signedOut, setSignedOut] =
|
|
8239
|
-
const [refreshError, setRefreshError] =
|
|
8240
|
-
const [refreshing, setRefreshing] =
|
|
8241
|
-
const loadedAt =
|
|
8242
|
-
const inFlight =
|
|
8325
|
+
const [signedOut, setSignedOut] = useState40(false);
|
|
8326
|
+
const [refreshError, setRefreshError] = useState40(null);
|
|
8327
|
+
const [refreshing, setRefreshing] = useState40(false);
|
|
8328
|
+
const loadedAt = useRef18(0);
|
|
8329
|
+
const inFlight = useRef18(false);
|
|
8243
8330
|
const apply = useCallback4(
|
|
8244
8331
|
(s) => {
|
|
8245
8332
|
loadedAt.current = Date.now();
|
|
@@ -8287,11 +8374,11 @@ function Workspace({ port, host = NO_HOST, layout = "auto", location, onLocation
|
|
|
8287
8374
|
knobsRef.current?.().catch(() => void 0);
|
|
8288
8375
|
port.lists.recents?.list().then(setRecents, () => void 0);
|
|
8289
8376
|
}, [port, apply]);
|
|
8290
|
-
|
|
8291
|
-
const quietRef =
|
|
8377
|
+
useEffect22(load, [load]);
|
|
8378
|
+
const quietRef = useRef18({ loc, ready: false });
|
|
8292
8379
|
quietRef.current = { loc, ready: snap !== null && !error };
|
|
8293
|
-
const [knobSeconds, setKnobSeconds] =
|
|
8294
|
-
|
|
8380
|
+
const [knobSeconds, setKnobSeconds] = useState40(null);
|
|
8381
|
+
useEffect22(() => {
|
|
8295
8382
|
if (host.refreshSeconds !== void 0 || !knobsRef.current) return;
|
|
8296
8383
|
let live = true;
|
|
8297
8384
|
knobsRef.current().then(
|
|
@@ -8306,7 +8393,7 @@ function Workspace({ port, host = NO_HOST, layout = "auto", location, onLocation
|
|
|
8306
8393
|
};
|
|
8307
8394
|
}, [host.refreshSeconds]);
|
|
8308
8395
|
const everySeconds = host.refreshSeconds ?? knobSeconds;
|
|
8309
|
-
|
|
8396
|
+
useEffect22(() => {
|
|
8310
8397
|
const quietly = (minGapMs) => {
|
|
8311
8398
|
const { loc: here, ready } = quietRef.current;
|
|
8312
8399
|
if (!ready || document.visibilityState === "hidden" || dirty.current || here.mode !== "view") return;
|
|
@@ -8324,17 +8411,17 @@ function Workspace({ port, host = NO_HOST, layout = "auto", location, onLocation
|
|
|
8324
8411
|
if (timer2) clearInterval(timer2);
|
|
8325
8412
|
};
|
|
8326
8413
|
}, [refresh, everySeconds]);
|
|
8327
|
-
const inventoryRef =
|
|
8414
|
+
const inventoryRef = useRef18(onInventory);
|
|
8328
8415
|
inventoryRef.current = onInventory;
|
|
8329
|
-
|
|
8416
|
+
useEffect22(() => {
|
|
8330
8417
|
if (snap) inventoryRef.current?.({ items, definitions: snap.definitions });
|
|
8331
8418
|
}, [snap, items]);
|
|
8332
|
-
|
|
8419
|
+
useEffect22(() => {
|
|
8333
8420
|
if (!loc.itemId || !port.lists.recents) return;
|
|
8334
8421
|
const id = loc.itemId;
|
|
8335
8422
|
port.lists.recents.record(id).then(() => setRecents((r) => [id, ...(r ?? []).filter((x) => x !== id)]), () => void 0);
|
|
8336
8423
|
}, [loc.itemId, port]);
|
|
8337
|
-
const orgs = snap?.organizations ?? [];
|
|
8424
|
+
const orgs = useMemo6(() => orderOrganizations(snap?.organizations ?? [], items, recents), [snap?.organizations, items, recents]);
|
|
8338
8425
|
const definitions = snap?.definitions ?? [];
|
|
8339
8426
|
const inThisVault = useMemo6(() => items.filter((i) => inVault(i, loc.vault)), [items, loc.vault]);
|
|
8340
8427
|
const vaultMixesOwners = new Set(inThisVault.map((i) => i.owner.organizationId ?? i.owner.kind)).size > 1;
|
|
@@ -8417,7 +8504,7 @@ function Workspace({ port, host = NO_HOST, layout = "auto", location, onLocation
|
|
|
8417
8504
|
const hasFavorites = port.lists.favorites !== void 0;
|
|
8418
8505
|
const title = loc.vault === "all" && loc.view === "all" ? "All items" : viewLabel(loc.view, views);
|
|
8419
8506
|
const compactHeader = mode === "full" ? void 0 : /* @__PURE__ */ jsxs35("div", { className: "grid grid-cols-[repeat(auto-fit,minmax(11rem,1fr))] gap-2", "data-vault-compact-header": "", children: [
|
|
8420
|
-
/* @__PURE__ */ jsx37(VaultSelect, { value: loc.vault, choices, onChange: (vault) => go({ vault, itemId: null, panel: null }) }),
|
|
8507
|
+
/* @__PURE__ */ jsx37(VaultSelect, { value: loc.vault, choices, searchAt: host.organizationSearchAt, onChange: (vault) => go({ vault, itemId: null, panel: null }) }),
|
|
8421
8508
|
/* @__PURE__ */ jsx37(Select12, { value: loc.view, onValueChange: (view) => go({ view, itemId: null, panel: null }), options: viewOptions(views, inThisVault.length, deleted.length, hasFavorites, port.lists.recents !== void 0, host.page !== void 0, loc.view), "aria-label": "Show" })
|
|
8422
8509
|
] });
|
|
8423
8510
|
const compactActions = mode === "full" ? void 0 : /* @__PURE__ */ jsxs35("div", { className: "flex shrink-0 items-center gap-2", "data-vault-compact-actions": "", children: [
|
|
@@ -8654,6 +8741,11 @@ function Workspace({ port, host = NO_HOST, layout = "auto", location, onLocation
|
|
|
8654
8741
|
arg: panelArg ?? null,
|
|
8655
8742
|
onClose: closePanel,
|
|
8656
8743
|
onPanel,
|
|
8744
|
+
onOpenItem: (next) => {
|
|
8745
|
+
replaceItem(next);
|
|
8746
|
+
const holds = loc.vault === "all" || loc.vault === "mine" && next.owner.kind === "me" || loc.vault === next.owner.organizationId;
|
|
8747
|
+
go({ ...holds ? {} : { vault: "all" }, itemId: next.id, mode: "view", panel: null });
|
|
8748
|
+
},
|
|
8657
8749
|
onChanged: (next) => {
|
|
8658
8750
|
if (next) replaceItem(next);
|
|
8659
8751
|
else if (next === null) {
|
|
@@ -8693,6 +8785,7 @@ function Workspace({ port, host = NO_HOST, layout = "auto", location, onLocation
|
|
|
8693
8785
|
vault: loc.vault,
|
|
8694
8786
|
choices,
|
|
8695
8787
|
onVault: (vault) => go({ vault, itemId: null, panel: null }),
|
|
8788
|
+
organizationSearchAt: host.organizationSearchAt,
|
|
8696
8789
|
view: loc.view,
|
|
8697
8790
|
allCount: inThisVault.length,
|
|
8698
8791
|
deletedCount: deleted.length,
|