@ai-matrx/vault 0.1.9 → 0.1.10
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 +17 -1
- package/dist/index.cjs +240 -263
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -2
- package/dist/index.d.ts +7 -2
- package/dist/index.js +222 -245
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -222,6 +222,7 @@ var import_design_system2 = require("@ai-matrx/design-system");
|
|
|
222
222
|
var import_controls = require("@ai-matrx/design-system/controls");
|
|
223
223
|
|
|
224
224
|
// src/glyphs.tsx
|
|
225
|
+
var import_icons = require("@ai-matrx/design-system/icons");
|
|
225
226
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
226
227
|
function glyph(paths, air = [1, 1]) {
|
|
227
228
|
const style = { "--matrx-glyph-air-l": air[0], "--matrx-glyph-air-r": air[1] };
|
|
@@ -233,10 +234,6 @@ var KeyGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_ru
|
|
|
233
234
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: "7.5", cy: "15.5", r: "5.5" }),
|
|
234
235
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m21 2-9.6 9.6M15.5 7.5l3 3" })
|
|
235
236
|
] }), [1, 2]);
|
|
236
|
-
var GlobeGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
237
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
|
|
238
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M2 12h20M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" })
|
|
239
|
-
] }), [1, 1]);
|
|
240
237
|
var NoteGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
241
238
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" }),
|
|
242
239
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M14 2v4a2 2 0 0 0 2 2h4M16 13H8M16 17H8" })
|
|
@@ -266,10 +263,6 @@ var FileGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_r
|
|
|
266
263
|
var CodeGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m16 18 6-6-6-6M8 6l-6 6 6 6" }) }), [1, 1]);
|
|
267
264
|
var StarGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M12 2l3.1 6.3 6.9 1-5 4.9 1.2 6.8L12 17.8 5.8 21l1.2-6.8-5-4.9 6.9-1z" }), [1, 1]);
|
|
268
265
|
var PlusGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M12 5v14M5 12h14" }), [4, 4]);
|
|
269
|
-
var CopyGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
270
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("rect", { x: "9", y: "9", width: "13", height: "13", rx: "2" }),
|
|
271
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" })
|
|
272
|
-
] }), [1, 1]);
|
|
273
266
|
var EyeGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
274
267
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M2 12s3.6-7 10-7 10 7 10 7-3.6 7-10 7-10-7-10-7z" }),
|
|
275
268
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: "12", cy: "12", r: "3" })
|
|
@@ -294,11 +287,6 @@ var BuildingGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_j
|
|
|
294
287
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("rect", { x: "4", y: "2", width: "16", height: "20", rx: "2" }),
|
|
295
288
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M9 22v-4h6v4M8 6h.01M16 6h.01M12 6h.01M12 10h.01M12 14h.01M16 10h.01M16 14h.01M8 10h.01M8 14h.01" })
|
|
296
289
|
] }), [3, 3]);
|
|
297
|
-
var UsersGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
298
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" }),
|
|
299
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: "9", cy: "7", r: "4" }),
|
|
300
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M22 21v-2a4 4 0 0 0-3-3.9M16 3.1a4 4 0 0 1 0 7.8" })
|
|
301
|
-
] }), [1, 1]);
|
|
302
290
|
var ChevronLeftGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m15 18-6-6 6-6" }), [8, 8]);
|
|
303
291
|
var GridGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
304
292
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("rect", { x: "3", y: "3", width: "7", height: "7", rx: "1" }),
|
|
@@ -317,7 +305,7 @@ var FAMILY_GLYPHS = {
|
|
|
317
305
|
cloud_infrastructure: ServerGlyph
|
|
318
306
|
};
|
|
319
307
|
function definitionGlyph(key, family) {
|
|
320
|
-
if (key === "username_password" || key === "website_login") return
|
|
308
|
+
if (key === "username_password" || key === "website_login") return import_icons.GlobeIcon;
|
|
321
309
|
return FAMILY_GLYPHS[family] ?? KeyGlyph;
|
|
322
310
|
}
|
|
323
311
|
var XGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M18 6 6 18M6 6l12 12" }), [5, 5]);
|
|
@@ -335,15 +323,7 @@ var MoreGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_r
|
|
|
335
323
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: "5", cy: "12", r: "1" })
|
|
336
324
|
] }), [3, 3]);
|
|
337
325
|
var ShareGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8M16 6l-4-4-4 4M12 2v13" }) }), [3, 3]);
|
|
338
|
-
var HistoryGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
339
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" }),
|
|
340
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M3 3v5h5M12 7v5l4 2" })
|
|
341
|
-
] }), [2, 2]);
|
|
342
326
|
var ListGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M8 6h13M8 12h13M8 18h13M3 6h.01M3 12h.01M3 18h.01" }), [2, 2]);
|
|
343
|
-
var SettingsGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
344
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z" }),
|
|
345
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: "12", cy: "12", r: "3" })
|
|
346
|
-
] }), [2, 2]);
|
|
347
327
|
var ImportGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M7 10l5 5 5-5M12 15V3" }), [2, 2]);
|
|
348
328
|
var ExportGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M17 8l-5-5-5 5M12 3v12" }), [2, 2]);
|
|
349
329
|
var ChevronDownGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m6 9 6 6 6-6" }), [5, 5]);
|
|
@@ -384,10 +364,6 @@ var RefreshGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_js
|
|
|
384
364
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M21 3v5h-5M3 21v-5h5" })
|
|
385
365
|
] }), [2, 2]);
|
|
386
366
|
var SlidersGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M4 21v-7M4 10V3M12 21v-9M12 8V3M20 21v-5M20 12V3M1 14h6M9 8h6M17 16h6" }) }), [0, 0]);
|
|
387
|
-
var DownloadGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
388
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
|
|
389
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m7 10 5 5 5-5M12 15V3" })
|
|
390
|
-
] }), [2, 2]);
|
|
391
367
|
var UploadGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
392
368
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
|
|
393
369
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m17 8-5-5-5 5M12 3v12" })
|
|
@@ -469,7 +445,7 @@ var Ctx2 = (0, import_react2.createContext)((run) => run());
|
|
|
469
445
|
function useConfirmed() {
|
|
470
446
|
return (0, import_react2.useContext)(Ctx2);
|
|
471
447
|
}
|
|
472
|
-
var PROVIDER_LABEL = { google: "Google", github: "GitHub", azure: "Microsoft", apple: "Apple", linkedin_oidc: "LinkedIn", slack_oidc: "Slack" };
|
|
448
|
+
var PROVIDER_LABEL = { google: "Google", github: "GitHub", azure: "Microsoft", apple: "Apple", linkedin_oidc: "LinkedIn", slack_oidc: "Slack", browser: "Browser", touch_id: "Touch ID" };
|
|
473
449
|
var providerLabel = (p) => PROVIDER_LABEL[p] ?? p.charAt(0).toUpperCase() + p.slice(1);
|
|
474
450
|
function IdentityGate({ identity, children }) {
|
|
475
451
|
const [asking, setAsking] = (0, import_react2.useState)(false);
|
|
@@ -539,10 +515,21 @@ function ConfirmIdentityDialog({ open, identity, onDone, onCancel }) {
|
|
|
539
515
|
] }),
|
|
540
516
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex flex-col gap-3", children: [
|
|
541
517
|
identity.dev ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_controls.Button, { variant: "primary", disabled: busy, onClick: () => void attempt(() => identity.dev?.() ?? Promise.resolve()), children: "Sign in again (dev)" }) : null,
|
|
542
|
-
account10?.providers.map((p) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
518
|
+
account10?.providers.map((p) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
519
|
+
import_controls.Button,
|
|
520
|
+
{
|
|
521
|
+
variant: identity.dev ? "outline" : "primary",
|
|
522
|
+
disabled: busy,
|
|
523
|
+
onClick: () => void attempt(async () => {
|
|
524
|
+
if (await identity.withProvider(p) === "confirmed") onDone();
|
|
525
|
+
}, false),
|
|
526
|
+
children: [
|
|
527
|
+
"Continue with ",
|
|
528
|
+
providerLabel(p)
|
|
529
|
+
]
|
|
530
|
+
},
|
|
531
|
+
p
|
|
532
|
+
)),
|
|
546
533
|
account10?.hasPassword ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("form", { className: "flex gap-2", onSubmit: (e) => {
|
|
547
534
|
e.preventDefault();
|
|
548
535
|
if (password) void attempt(() => identity.withPassword(password));
|
|
@@ -569,6 +556,7 @@ function ConfirmIdentityDialog({ open, identity, onDone, onCancel }) {
|
|
|
569
556
|
var import_react5 = require("react");
|
|
570
557
|
var import_controls2 = require("@ai-matrx/design-system/controls");
|
|
571
558
|
var import_design_system5 = require("@ai-matrx/design-system");
|
|
559
|
+
var import_icons2 = require("@ai-matrx/design-system/icons");
|
|
572
560
|
|
|
573
561
|
// src/hooks.ts
|
|
574
562
|
var import_react3 = require("react");
|
|
@@ -637,7 +625,7 @@ function useRoomOf(ref) {
|
|
|
637
625
|
return room;
|
|
638
626
|
}
|
|
639
627
|
var RoomProvider = Room.Provider;
|
|
640
|
-
function
|
|
628
|
+
function VaultSection({ title, actions, children, className }) {
|
|
641
629
|
const flat = (0, import_react4.useContext)(InPanel);
|
|
642
630
|
const desktop = (0, import_design_system4.useLook)() === "desktop";
|
|
643
631
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("section", { className: (0, import_design_system4.cn)("flex flex-col gap-1.5", className), children: [
|
|
@@ -653,7 +641,7 @@ var ROW_GRID = {
|
|
|
653
641
|
roomy: "grid-cols-[9rem_minmax(0,1fr)_auto] gap-x-3 px-4",
|
|
654
642
|
viewport: "grid-cols-[5.75rem_minmax(0,1fr)_auto] gap-x-2 px-3 sm:grid-cols-[9rem_minmax(0,1fr)_auto] sm:gap-x-3 sm:px-4"
|
|
655
643
|
};
|
|
656
|
-
function
|
|
644
|
+
function VaultRow({ label, hint, children, actions, top = false, className }) {
|
|
657
645
|
const room = (0, import_react4.useContext)(Room);
|
|
658
646
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: (0, import_design_system4.cn)("grid min-h-11 py-1", ROW_GRID[room ?? "viewport"], top ? "items-start" : "items-center", className), children: [
|
|
659
647
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: (0, import_design_system4.cn)("flex min-w-0 flex-col text-xs leading-tight text-muted-foreground", top && "pt-2.5"), children: [
|
|
@@ -674,11 +662,6 @@ function Panel({ title, open = true, onClose, children, footer, size = "lg" }) {
|
|
|
674
662
|
footer ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system3.DialogFooter, { children: footer }) : null
|
|
675
663
|
] }) });
|
|
676
664
|
}
|
|
677
|
-
function formatBytes(n) {
|
|
678
|
-
if (n < 1024) return `${n} B`;
|
|
679
|
-
if (n < 1024 * 1024) return `${(n / 1024).toFixed(n < 10 * 1024 ? 1 : 0)} KB`;
|
|
680
|
-
return `${(n / 1024 / 1024).toFixed(1)} MB`;
|
|
681
|
-
}
|
|
682
665
|
var DAY_FORMAT = { year: "numeric", month: "short", day: "numeric" };
|
|
683
666
|
|
|
684
667
|
// src/FieldRows.tsx
|
|
@@ -737,14 +720,14 @@ function SecretRow({ port, item, field, extra }) {
|
|
|
737
720
|
const multiline = field.kind === "multiline";
|
|
738
721
|
const shown = visible ? plain : secret.value;
|
|
739
722
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
740
|
-
|
|
723
|
+
VaultRow,
|
|
741
724
|
{
|
|
742
725
|
label: field.label,
|
|
743
726
|
top: multiline && shown !== null,
|
|
744
727
|
actions: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
745
728
|
extra,
|
|
746
729
|
canSee && !visible ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_controls2.Button, { variant: "quiet", icon: secret.value !== null ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(EyeOffGlyph, {}) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(EyeGlyph, {}), "aria-label": secret.value !== null ? `Hide ${field.label}` : `Show ${field.label}`, disabled: busy, onClick: () => void toggle2() }) : null,
|
|
747
|
-
canSee ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_controls2.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
730
|
+
canSee ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_controls2.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_icons2.CopyIcon, {}), "aria-label": `Copy ${field.label}`, disabled: busy, onClick: () => void copy() }) : null
|
|
748
731
|
] }),
|
|
749
732
|
children: sealed ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_controls2.Badge, { icon: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(LockGlyph, {}), children: "Sealed" }) : off ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "text-muted-foreground", children: "Turned off" }) : error ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "truncate text-destructive", title: error, children: error }) : shown !== null ? visible ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: (0, import_design_system5.cn)("block", multiline ? "whitespace-pre-wrap break-words" : "truncate"), children: shown || "\u2014" }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SecretText, { value: shown, multiline }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: (0, import_design_system5.cn)("block truncate text-muted-foreground", !visible && "tracking-widest"), children: visible ? "\u2026" : MASK })
|
|
750
733
|
}
|
|
@@ -754,7 +737,7 @@ function PlainRow({ label, value, hint, openUrl, extra, multiline = false }) {
|
|
|
754
737
|
const copyValue2 = useCopy();
|
|
755
738
|
const isUrl = /^https?:\/\//i.test(value);
|
|
756
739
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
757
|
-
|
|
740
|
+
VaultRow,
|
|
758
741
|
{
|
|
759
742
|
label,
|
|
760
743
|
hint,
|
|
@@ -762,7 +745,7 @@ function PlainRow({ label, value, hint, openUrl, extra, multiline = false }) {
|
|
|
762
745
|
actions: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
763
746
|
extra,
|
|
764
747
|
isUrl && openUrl ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_controls2.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ExternalGlyph, {}), "aria-label": `Open ${value}`, onClick: () => openUrl(value) }) : null,
|
|
765
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_controls2.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
748
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_controls2.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_icons2.CopyIcon, {}), "aria-label": `Copy ${typeof label === "string" ? label : "value"}`, onClick: () => void copyValue2(value, typeof label === "string" && label ? label : "Value", { secret: false }) })
|
|
766
749
|
] }),
|
|
767
750
|
children: isUrl && openUrl ? (
|
|
768
751
|
// A real link (right-click, copy link address, open in a new tab); a click goes through the host's opener.
|
|
@@ -785,12 +768,12 @@ function PlainRow({ label, value, hint, openUrl, extra, multiline = false }) {
|
|
|
785
768
|
);
|
|
786
769
|
}
|
|
787
770
|
function AddRow({ label, onAdd, children = "Add" }) {
|
|
788
|
-
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
771
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(VaultRow, { label, children: onAdd ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: "text-sm text-muted-foreground hover:text-primary", onClick: onAdd, children }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "text-disabled-foreground", children: "\u2014" }) });
|
|
789
772
|
}
|
|
790
773
|
function EditRow({ label, hint, value, onChange, placeholder, secret = false, multiline = false, onRemove, removeLabel, actions, autoFocus, onBlur, inputMode }) {
|
|
791
774
|
const [shown, setShown] = (0, import_react5.useState)(false);
|
|
792
775
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
793
|
-
|
|
776
|
+
VaultRow,
|
|
794
777
|
{
|
|
795
778
|
label,
|
|
796
779
|
hint,
|
|
@@ -807,7 +790,7 @@ function EditRow({ label, hint, value, onChange, placeholder, secret = false, mu
|
|
|
807
790
|
function CustomEditRow({ label, value, onLabel, onValue, secret, onRemove }) {
|
|
808
791
|
const [shown, setShown] = (0, import_react5.useState)(false);
|
|
809
792
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
810
|
-
|
|
793
|
+
VaultRow,
|
|
811
794
|
{
|
|
812
795
|
label: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_controls2.Field, { className: "w-full", value: label, onChange: (e) => onLabel(e.target.value), placeholder: "Name", "aria-label": "Field name" }),
|
|
813
796
|
actions: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
@@ -820,6 +803,7 @@ function CustomEditRow({ label, value, onLabel, onValue, secret, onRemove }) {
|
|
|
820
803
|
}
|
|
821
804
|
|
|
822
805
|
// src/activity/HistoryPanel.tsx
|
|
806
|
+
var import_icons3 = require("@ai-matrx/design-system/icons");
|
|
823
807
|
var import_format3 = require("@ai-matrx/kit/format");
|
|
824
808
|
|
|
825
809
|
// src/activity/logic.ts
|
|
@@ -1312,7 +1296,7 @@ function ActivityPanel({ item, port, onClose }) {
|
|
|
1312
1296
|
footer: hasMore ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_controls3.Button, { variant: "outline", disabled: loading, onClick: () => setLimit((n) => Math.min(MAX, n * 2)), children: loading ? "Loading\u2026" : "Show more" }) : void 0,
|
|
1313
1297
|
children: [
|
|
1314
1298
|
error ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { role: "alert", className: "px-1 text-sm text-destructive", children: error }) : null,
|
|
1315
|
-
entries === null ? loading ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Empty, { children: "Reading activity\u2026" }) : null : entries.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Empty, { children: "Nothing has happened yet." }) : groupByDay(entries, now).map((day) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1299
|
+
entries === null ? loading ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Empty, { children: "Reading activity\u2026" }) : null : entries.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Empty, { children: "Nothing has happened yet." }) : groupByDay(entries, now).map((day) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(VaultSection, { title: day.label, children: collapseRuns(
|
|
1316
1300
|
day.entries.map((entry) => ({ entry, s: auditSentence(entry, item, me) })),
|
|
1317
1301
|
(r) => `${r.s.what}|${r.s.who ?? ""}`
|
|
1318
1302
|
).map(({ row: { entry, s }, times }) => {
|
|
@@ -1335,7 +1319,7 @@ function ActivityPanel({ item, port, onClose }) {
|
|
|
1335
1319
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1336
1320
|
var MASK2 = "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022";
|
|
1337
1321
|
var messageOf = (e, fallback) => wasCancelled(e) ? null : e instanceof Error ? e.message : fallback;
|
|
1338
|
-
function
|
|
1322
|
+
function ItemHistoryPanel({ item, port, arg, onClose, onChanged }) {
|
|
1339
1323
|
const eligible = historyEligible(item);
|
|
1340
1324
|
const [page, setPage] = (0, import_react7.useState)(null);
|
|
1341
1325
|
const [loading, setLoading] = (0, import_react7.useState)(eligible);
|
|
@@ -1397,7 +1381,7 @@ function HistoryPanel({ item, port, arg, onClose, onChanged }) {
|
|
|
1397
1381
|
error ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { role: "alert", className: "px-1 text-sm text-destructive", children: error }) : null,
|
|
1398
1382
|
notice ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { role: "status", className: "px-1 text-sm text-success", children: notice }) : null,
|
|
1399
1383
|
page && groups.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Empty, { children: "No earlier values yet." }) : null,
|
|
1400
|
-
page ? groups.map((g) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1384
|
+
page ? groups.map((g) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(VaultSection, { title: g.label, children: g.entries.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(HistoryRow, { item, port, page, entry, label: g.label, onRestored: restored, onConflict: conflicted, onError: setError }, `${item.id}:${entry.fieldId}:${entry.revision}`)) }, g.fieldId)) : null,
|
|
1401
1385
|
page && (page.captureStartedAt || page.incomplete) ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex flex-wrap gap-x-3 gap-y-1 px-1 text-xs", children: [
|
|
1402
1386
|
page.captureStartedAt ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "text-muted-foreground", children: [
|
|
1403
1387
|
"Kept since ",
|
|
@@ -1458,12 +1442,12 @@ function HistoryRow({ item, port, page, entry, label, onRestored, onConflict, on
|
|
|
1458
1442
|
}
|
|
1459
1443
|
}
|
|
1460
1444
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1461
|
-
|
|
1445
|
+
VaultRow,
|
|
1462
1446
|
{
|
|
1463
1447
|
label: when,
|
|
1464
1448
|
actions: entry.available ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
1465
1449
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_controls4.Button, { variant: "quiet", icon: secret.value !== null ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(EyeOffGlyph, {}) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(EyeGlyph, {}), "aria-label": secret.value !== null ? "Hide" : "Show", disabled: busy, onClick: () => void toggle2() }),
|
|
1466
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_controls4.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1450
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_controls4.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_icons3.CopyIcon, {}), "aria-label": "Copy", disabled: busy, onClick: () => void copy() }),
|
|
1467
1451
|
canRestore(page, entry) ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_controls4.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(RestoreGlyph, {}), "aria-label": "Restore", disabled: busy, onClick: () => void restore() }) : null
|
|
1468
1452
|
] }) : null,
|
|
1469
1453
|
children: !entry.available ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_controls4.Badge, { children: "Not kept" }) : secret.value !== null ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SecretText, { value: secret.value, multiline: false }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "block truncate tracking-widest text-muted-foreground", children: MASK2 })
|
|
@@ -1475,6 +1459,7 @@ function HistoryRow({ item, port, page, entry, label, onRestored, onConflict, on
|
|
|
1475
1459
|
var import_react13 = require("react");
|
|
1476
1460
|
var import_controls9 = require("@ai-matrx/design-system/controls");
|
|
1477
1461
|
var import_design_system9 = require("@ai-matrx/design-system");
|
|
1462
|
+
var import_icons5 = require("@ai-matrx/design-system/icons");
|
|
1478
1463
|
|
|
1479
1464
|
// src/authenticator/AddOtpPanel.tsx
|
|
1480
1465
|
var import_react12 = require("react");
|
|
@@ -1484,8 +1469,11 @@ var import_controls8 = require("@ai-matrx/design-system/controls");
|
|
|
1484
1469
|
var import_react8 = require("react");
|
|
1485
1470
|
var import_controls5 = require("@ai-matrx/design-system/controls");
|
|
1486
1471
|
var import_design_system7 = require("@ai-matrx/design-system");
|
|
1472
|
+
var import_icons4 = require("@ai-matrx/design-system/icons");
|
|
1473
|
+
var import_format5 = require("@ai-matrx/kit/format");
|
|
1487
1474
|
|
|
1488
1475
|
// src/authenticator/otpauth.ts
|
|
1476
|
+
var import_format4 = require("@ai-matrx/kit/format");
|
|
1489
1477
|
var TOTP_DEFAULT_DIGITS = 6;
|
|
1490
1478
|
var TOTP_DEFAULT_PERIOD = 30;
|
|
1491
1479
|
var TOTP_DEFAULT_ALGORITHM = "SHA1";
|
|
@@ -1553,14 +1541,8 @@ function describeEnrollment(parsed) {
|
|
|
1553
1541
|
const parts = [parsed.issuer, parsed.account].filter((p) => Boolean(p));
|
|
1554
1542
|
return parts.length ? parts.join(" \xB7 ") : "Setup key";
|
|
1555
1543
|
}
|
|
1556
|
-
function groupCode(code) {
|
|
1557
|
-
const c = code.replace(/\s/g, "");
|
|
1558
|
-
if (c.length < 6) return c;
|
|
1559
|
-
const head = Math.ceil(c.length / 2);
|
|
1560
|
-
return `${c.slice(0, head)} ${c.slice(head)}`;
|
|
1561
|
-
}
|
|
1562
1544
|
function maskedCode(digits = TOTP_DEFAULT_DIGITS) {
|
|
1563
|
-
return groupCode("\u2022".repeat(Math.max(6, digits)));
|
|
1545
|
+
return (0, import_format4.groupCode)("\u2022".repeat(Math.max(6, digits)));
|
|
1564
1546
|
}
|
|
1565
1547
|
function accountOfLabel(label, issuer) {
|
|
1566
1548
|
const l = label?.trim();
|
|
@@ -1636,7 +1618,7 @@ function useCopied() {
|
|
|
1636
1618
|
}
|
|
1637
1619
|
function CodeButton({ live, digits, size = "md", label }) {
|
|
1638
1620
|
const { copied, copy } = useCopied();
|
|
1639
|
-
const shown = live.code ? groupCode(live.code) : maskedCode(digits);
|
|
1621
|
+
const shown = live.code ? (0, import_format5.groupCode)(live.code) : maskedCode(digits);
|
|
1640
1622
|
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
1641
1623
|
"button",
|
|
1642
1624
|
{
|
|
@@ -1655,7 +1637,7 @@ function CodeButton({ live, digits, size = "md", label }) {
|
|
|
1655
1637
|
}
|
|
1656
1638
|
function CopyCodeButton({ live, label }) {
|
|
1657
1639
|
const { copied, copy } = useCopied();
|
|
1658
|
-
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_controls5.Button, { variant: "quiet", icon: copied ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CheckGlyph, {}) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1640
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_controls5.Button, { variant: "quiet", icon: copied ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CheckGlyph, {}) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_icons4.CopyIcon, {}), ...copied ? { glyphTone: "success" } : {}, "aria-label": `Copy ${label} code`, disabled: !live.code, onClick: () => live.code && void copy(live.code) });
|
|
1659
1641
|
}
|
|
1660
1642
|
|
|
1661
1643
|
// src/authenticator/live-code.ts
|
|
@@ -1927,7 +1909,7 @@ function OtpSetupRow({ value, onChange, label = "One-time password", placeholder
|
|
|
1927
1909
|
className: dragging ? "rounded-lg bg-accent" : void 0,
|
|
1928
1910
|
children: [
|
|
1929
1911
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
1930
|
-
|
|
1912
|
+
VaultRow,
|
|
1931
1913
|
{
|
|
1932
1914
|
label,
|
|
1933
1915
|
actions: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
@@ -2077,7 +2059,7 @@ function TotpRow({ port, item, onChanged }) {
|
|
|
2077
2059
|
] })
|
|
2078
2060
|
] }) : null;
|
|
2079
2061
|
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2080
|
-
|
|
2062
|
+
VaultRow,
|
|
2081
2063
|
{
|
|
2082
2064
|
label: "One-time password",
|
|
2083
2065
|
actions: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
@@ -2136,7 +2118,7 @@ function TwoFactorMethodRow({ port, item, onChanged }) {
|
|
|
2136
2118
|
const [busy, setBusy] = (0, import_react11.useState)(false);
|
|
2137
2119
|
const [error, setError] = (0, import_react11.useState)(null);
|
|
2138
2120
|
const canEdit = item.capabilities.canEdit || item.capabilities.canManage;
|
|
2139
|
-
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2121
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(VaultRow, { label: "Two-factor", hint: error ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-destructive", children: error }) : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2140
2122
|
import_controls7.Select,
|
|
2141
2123
|
{
|
|
2142
2124
|
value: value ?? "none",
|
|
@@ -2251,7 +2233,7 @@ function AddOtpPanel({ port, items, definitions, itemId = null, onClose, onChang
|
|
|
2251
2233
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_controls8.Button, { variant: "primary", disabled: !ready, onClick: () => void save(), children: busy ? "Adding\u2026" : "Add" })
|
|
2252
2234
|
] }),
|
|
2253
2235
|
children: [
|
|
2254
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
2236
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(VaultSection, { children: [
|
|
2255
2237
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2256
2238
|
OtpSetupRow,
|
|
2257
2239
|
{
|
|
@@ -2273,7 +2255,7 @@ function AddOtpPanel({ port, items, definitions, itemId = null, onClose, onChang
|
|
|
2273
2255
|
status: image ? `QR image ready \xB7 ${image.name}` : null
|
|
2274
2256
|
}
|
|
2275
2257
|
),
|
|
2276
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2258
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(VaultRow, { label: "Add to", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2277
2259
|
import_controls8.Select,
|
|
2278
2260
|
{
|
|
2279
2261
|
value: target,
|
|
@@ -2287,7 +2269,7 @@ function AddOtpPanel({ port, items, definitions, itemId = null, onClose, onChang
|
|
|
2287
2269
|
}
|
|
2288
2270
|
) }),
|
|
2289
2271
|
isNew ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
2290
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2272
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(VaultRow, { label: "Name", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2291
2273
|
import_controls8.Field,
|
|
2292
2274
|
{
|
|
2293
2275
|
className: "w-full",
|
|
@@ -2301,7 +2283,7 @@ function AddOtpPanel({ port, items, definitions, itemId = null, onClose, onChang
|
|
|
2301
2283
|
"aria-label": "Name"
|
|
2302
2284
|
}
|
|
2303
2285
|
) }),
|
|
2304
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2286
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(VaultRow, { label: "Website", hint: websiteBad ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-destructive", children: "Not a web address" }) : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_controls8.Field, { className: "w-full", type: "url", value: website, disabled: busy || created !== null, onChange: (e) => setWebsite(e.target.value), placeholder: "example.com", "aria-label": "Website", "aria-invalid": websiteBad || void 0 }) })
|
|
2305
2287
|
] }) : null
|
|
2306
2288
|
] }),
|
|
2307
2289
|
error ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "px-1 text-sm text-destructive", role: "alert", children: error }) : null
|
|
@@ -2369,7 +2351,7 @@ function AuthenticatorView({ port, items, definitions, query, onOpen, onChanged,
|
|
|
2369
2351
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "flex size-12 items-center justify-center rounded-full bg-muted text-muted-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ShieldGlyph, { className: "size-6" }) }),
|
|
2370
2352
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "text-sm font-medium text-foreground", children: "No one-time passwords yet" }),
|
|
2371
2353
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_controls9.Button, { variant: "primary", icon: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(PlusGlyph, {}), onClick: () => setAdding(true), children: "Add one-time password" })
|
|
2372
|
-
] }) : groups.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "px-4 py-10 text-center text-sm text-muted-foreground", children: "Nothing matches." }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "min-h-0 flex-1 overflow-y-auto px-3 pb-6 pt-1 sm:px-4", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "mx-auto flex w-full max-w-3xl flex-col gap-5", children: groups.map((g) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2354
|
+
] }) : groups.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "px-4 py-10 text-center text-sm text-muted-foreground", children: "Nothing matches." }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "min-h-0 flex-1 overflow-y-auto px-3 pb-6 pt-1 sm:px-4", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "mx-auto flex w-full max-w-3xl flex-col gap-5", children: groups.map((g) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(VaultSection, { ...groups.length > 1 ? { title: g.label } : {}, className: "[&>div]:px-1", children: g.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2373
2355
|
OtpListRow,
|
|
2374
2356
|
{
|
|
2375
2357
|
port,
|
|
@@ -2463,7 +2445,7 @@ function OtpListRow({ port, item, family, entry, onOpen, onRename, onChanged, on
|
|
|
2463
2445
|
"Open login"
|
|
2464
2446
|
] }),
|
|
2465
2447
|
live.code ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system9.DropdownMenuItem, { onSelect: () => live.code && void copy(live.code), children: [
|
|
2466
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2448
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_icons5.CopyIcon, { className: "size-4" }),
|
|
2467
2449
|
"Copy code"
|
|
2468
2450
|
] }) : null,
|
|
2469
2451
|
canManage ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
|
|
@@ -2490,6 +2472,7 @@ function OtpListRow({ port, item, family, entry, onOpen, onRename, onChanged, on
|
|
|
2490
2472
|
var import_react14 = require("react");
|
|
2491
2473
|
var import_controls10 = require("@ai-matrx/design-system/controls");
|
|
2492
2474
|
var import_confirm_opener3 = require("@ai-matrx/kit/confirm-opener");
|
|
2475
|
+
var import_icons6 = require("@ai-matrx/design-system/icons");
|
|
2493
2476
|
|
|
2494
2477
|
// src/fields/rules.ts
|
|
2495
2478
|
var ENV_KEY_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
@@ -2639,7 +2622,7 @@ function FieldSettings({ item, port, field, onClose, onChanged }) {
|
|
|
2639
2622
|
const locked = !canEdit || busy !== null;
|
|
2640
2623
|
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Panel, { title: `${field.label} settings`, size: "md", onClose, footer: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_controls10.Button, { variant: "primary", onClick: onClose, children: "Done" }), children: [
|
|
2641
2624
|
!canEdit ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "px-1 text-sm text-muted-foreground", children: "View only: you can\u2019t change these settings." }) : null,
|
|
2642
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2625
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(VaultSection, { title: "Who can see it", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(VaultRow, { label: "Value", hint: quietHint(handling.hint), children: field.handling === "sealed" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_controls10.Badge, { icon: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(LockGlyph, {}), children: "Sealed for good" }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2643
2626
|
import_controls10.SegmentedControl,
|
|
2644
2627
|
{
|
|
2645
2628
|
"aria-label": "Who can see it",
|
|
@@ -2648,8 +2631,8 @@ function FieldSettings({ item, port, field, onClose, onChanged }) {
|
|
|
2648
2631
|
data: handlingChoices(field.handling).map((h) => ({ value: h, label: HANDLING_WORDS[h].label, title: HANDLING_WORDS[h].hint, disabled: locked }))
|
|
2649
2632
|
}
|
|
2650
2633
|
) }) }),
|
|
2651
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
2652
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2634
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(VaultSection, { title: "Automation", children: [
|
|
2635
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(VaultRow, { label: "Env key", hint: envProblem ? quietHint(envProblem, "destructive") : quietHint("The name sandboxes and workflows use"), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2653
2636
|
import_controls10.Field,
|
|
2654
2637
|
{
|
|
2655
2638
|
ref: envRef,
|
|
@@ -2669,10 +2652,10 @@ function FieldSettings({ item, port, field, onClose, onChanged }) {
|
|
|
2669
2652
|
}
|
|
2670
2653
|
}
|
|
2671
2654
|
) }),
|
|
2672
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2655
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(VaultRow, { label: "Use in sandbox", hint: blocker && !field.injectIntoSandbox ? quietHint(blocker) : quietHint("Sandboxes get it as an env variable"), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_controls10.Switch, { "aria-label": "Use in sandbox", checked: field.injectIntoSandbox, disabled: locked, onCheckedChange: (v) => void setSandbox(v) }) })
|
|
2673
2656
|
] }),
|
|
2674
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
2675
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2657
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(VaultSection, { title: "Field", children: [
|
|
2658
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(VaultRow, { label: "Description", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2676
2659
|
import_controls10.Field,
|
|
2677
2660
|
{
|
|
2678
2661
|
className: "w-full",
|
|
@@ -2688,8 +2671,8 @@ function FieldSettings({ item, port, field, onClose, onChanged }) {
|
|
|
2688
2671
|
}
|
|
2689
2672
|
}
|
|
2690
2673
|
) }),
|
|
2691
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2692
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2674
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(VaultRow, { label: "Editable", hint: quietHint(field.editable ? "The value can be changed" : "The value is locked"), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_controls10.Switch, { "aria-label": "Editable", checked: field.editable, disabled: locked, onCheckedChange: (v) => void update("editable", { editable: v }) }) }),
|
|
2675
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(VaultRow, { label: "Active", hint: quietHint(field.active ? "In use" : "Kept, but nothing uses it"), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_controls10.Switch, { "aria-label": "Active", checked: field.active, disabled: locked, onCheckedChange: (v) => void update("active", { active: v }) }) })
|
|
2693
2676
|
] }),
|
|
2694
2677
|
error ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Problem, { children: error }) : null
|
|
2695
2678
|
] });
|
|
@@ -2720,8 +2703,8 @@ function ItemSettingsPanel({ item, port, onClose, onChanged, onPanel }) {
|
|
|
2720
2703
|
const fillHint = !hasWebsite ? "Add a website first" : item.browserFillEnabled ? "Offered on matching pages" : "Never filled automatically";
|
|
2721
2704
|
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Panel, { title: "Item settings", size: "md", onClose, footer: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_controls10.Button, { variant: "primary", onClick: onClose, children: "Done" }), children: [
|
|
2722
2705
|
!canEdit ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "px-1 text-sm text-muted-foreground", children: "View only: you can\u2019t change these settings." }) : null,
|
|
2723
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
2724
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2706
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(VaultSection, { title: "In the browser", children: [
|
|
2707
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(VaultRow, { label: "Website matching", hint: quietHint(MATCH_WORDS[item.uriMatchMode].hint), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2725
2708
|
import_controls10.Select,
|
|
2726
2709
|
{
|
|
2727
2710
|
"aria-label": "Website matching",
|
|
@@ -2731,13 +2714,13 @@ function ItemSettingsPanel({ item, port, onClose, onChanged, onPanel }) {
|
|
|
2731
2714
|
onValueChange: (m) => void save("match", () => port.fields.updateItem(item, { uriMatchMode: m }))
|
|
2732
2715
|
}
|
|
2733
2716
|
) }),
|
|
2734
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2717
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(VaultRow, { label: "Fill in browser", hint: quietHint(fillHint), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_controls10.Switch, { "aria-label": "Fill in browser", checked: hasWebsite && item.browserFillEnabled, disabled: locked || !hasWebsite, onCheckedChange: (v) => void save("fill", () => port.fields.updateItem(item, { browserFillEnabled: v })) }) }),
|
|
2735
2718
|
promotable.map((f) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2736
|
-
|
|
2719
|
+
VaultRow,
|
|
2737
2720
|
{
|
|
2738
2721
|
label: f.label,
|
|
2739
2722
|
hint: quietHint("Encrypted, so the browser can\u2019t match it"),
|
|
2740
|
-
actions: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_controls10.Button, { variant: "outline", icon: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2723
|
+
actions: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_controls10.Button, { variant: "outline", icon: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_icons6.GlobeIcon, {}), disabled: locked, onClick: () => void promote(f), children: "Use as website" }),
|
|
2741
2724
|
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "text-muted-foreground", children: "Not a website yet" })
|
|
2742
2725
|
},
|
|
2743
2726
|
f.id
|
|
@@ -2745,8 +2728,8 @@ function ItemSettingsPanel({ item, port, onClose, onChanged, onPanel }) {
|
|
|
2745
2728
|
] }),
|
|
2746
2729
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-col gap-1.5", children: [
|
|
2747
2730
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_controls10.DisclosureHeader, { open: advanced, title: "Advanced", meta: item.fields.length ? `${item.fields.length} fields` : void 0, onClick: () => setAdvanced((a) => !a) }),
|
|
2748
|
-
advanced ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2749
|
-
|
|
2731
|
+
advanced ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(VaultSection, { children: item.fields.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Empty, { children: "No encrypted fields." }) : item.fields.map((f) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2732
|
+
VaultRow,
|
|
2750
2733
|
{
|
|
2751
2734
|
label: f.label,
|
|
2752
2735
|
actions: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_controls10.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SlidersGlyph, {}), "aria-label": `${f.label} settings`, onClick: () => onPanel(`field:${f.id}`) }),
|
|
@@ -2771,6 +2754,7 @@ function ItemSettingsPanel({ item, port, onClose, onChanged, onPanel }) {
|
|
|
2771
2754
|
var import_react15 = require("react");
|
|
2772
2755
|
var import_design_system10 = require("@ai-matrx/design-system");
|
|
2773
2756
|
var import_controls11 = require("@ai-matrx/design-system/controls");
|
|
2757
|
+
var import_icons7 = require("@ai-matrx/design-system/icons");
|
|
2774
2758
|
|
|
2775
2759
|
// src/generator/generate.ts
|
|
2776
2760
|
var import_credential_generator = require("@ai-matrx/kit/credential-generator");
|
|
@@ -2925,7 +2909,7 @@ function PasswordGenerator({ limits: source, onUse, useLabel = "Use" }) {
|
|
|
2925
2909
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex min-h-7 items-start gap-1", children: [
|
|
2926
2910
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("code", { className: (0, import_design_system10.cn)("min-w-0 flex-1 break-all py-1 font-mono text-sm", candidate ? "text-foreground" : "text-muted-foreground"), "data-testid": "generated-value", children: candidate ? revealed ? candidate.value : MASK3 : "\u2014" }),
|
|
2927
2911
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_controls11.Button, { variant: "quiet", icon: revealed ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(EyeOffGlyph, {}) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(EyeGlyph, {}), "aria-label": revealed ? "Hide" : "Reveal", disabled: !candidate, onClick: () => setRevealed((r) => !r) }),
|
|
2928
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_controls11.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2912
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_controls11.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_icons7.CopyIcon, {}), "aria-label": "Copy", disabled: !candidate, onClick: () => void copy() }),
|
|
2929
2913
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_controls11.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(RefreshGlyph, {}), "aria-label": "Generate another", onClick: () => change(settings) })
|
|
2930
2914
|
] }),
|
|
2931
2915
|
strength && candidate ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("p", { className: "text-xs", children: [
|
|
@@ -3052,6 +3036,7 @@ function useLocked(lock) {
|
|
|
3052
3036
|
}
|
|
3053
3037
|
|
|
3054
3038
|
// src/io/BackupPanel.tsx
|
|
3039
|
+
var import_format6 = require("@ai-matrx/kit/format");
|
|
3055
3040
|
var import_react18 = require("react");
|
|
3056
3041
|
var import_controls13 = require("@ai-matrx/design-system/controls");
|
|
3057
3042
|
var import_download = require("@ai-matrx/kit/download");
|
|
@@ -3193,17 +3178,17 @@ function omissionText(o) {
|
|
|
3193
3178
|
return `${o.count ?? "Some"} ${what}: ${o.reason.replaceAll("_", " ")}`;
|
|
3194
3179
|
}
|
|
3195
3180
|
function Summary({ value }) {
|
|
3196
|
-
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
3197
|
-
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3198
|
-
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3199
|
-
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3181
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(VaultSection, { children: [
|
|
3182
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(VaultRow, { label: "Credentials", children: value.record_count }),
|
|
3183
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(VaultRow, { label: "Protected fields", children: value.field_count }),
|
|
3184
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(VaultRow, { label: "Files", children: value.attachment_count > 0 ? `${value.attachment_count} \xB7 ${(0, import_format6.formatFileSize)(value.attachment_bytes)}` : "0" })
|
|
3200
3185
|
] });
|
|
3201
3186
|
}
|
|
3202
3187
|
function Omissions({ omissions, accepted, onAccepted, verb }) {
|
|
3203
3188
|
if (omissions.length === 0) return null;
|
|
3204
|
-
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
3205
|
-
omissions.map((o, i) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3206
|
-
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3189
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(VaultSection, { title: "Left out", children: [
|
|
3190
|
+
omissions.map((o, i) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(VaultRow, { label: o.component.replaceAll("_", " "), children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "block truncate text-muted-foreground", title: omissionText(o), children: omissionText(o) }) }, `${o.component}-${o.source_item_id ?? i}`)),
|
|
3191
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(VaultRow, { label: "Accept", hint: `${verb} without these`, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_controls13.Switch, { checked: accepted, onCheckedChange: onAccepted, "aria-label": `${verb} without these` }) })
|
|
3207
3192
|
] });
|
|
3208
3193
|
}
|
|
3209
3194
|
function BackupPanel({ port, items, onClose, onChanged }) {
|
|
@@ -3338,7 +3323,7 @@ function BackupPanel({ port, items, onClose, onChanged }) {
|
|
|
3338
3323
|
),
|
|
3339
3324
|
mode === "backup" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
3340
3325
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3341
|
-
|
|
3326
|
+
VaultSection,
|
|
3342
3327
|
{
|
|
3343
3328
|
title: `${selected.size} of ${plural(items.length, "credential")}`,
|
|
3344
3329
|
actions: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
@@ -3357,13 +3342,13 @@ function BackupPanel({ port, items, onClose, onChanged }) {
|
|
|
3357
3342
|
backup ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
3358
3343
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Summary, { value: backup }),
|
|
3359
3344
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Omissions, { omissions: backup.omissions, accepted, onAccepted: setAccepted, verb: "Back up" }),
|
|
3360
|
-
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
3361
|
-
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3362
|
-
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3345
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(VaultSection, { children: [
|
|
3346
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(VaultRow, { label: "Passphrase", hint: "Not saved. It can't be recovered.", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_controls13.Field, { type: "password", value: passphrase, autoComplete: "new-password", "aria-label": "Backup passphrase", onChange: (e) => setPassphrase(e.target.value) }) }),
|
|
3347
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(VaultRow, { label: "Repeat", ...mismatch ? { hint: "Doesn't match" } : {}, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_controls13.Field, { type: "password", value: repeat, autoComplete: "new-password", "aria-label": "Repeat the passphrase", onChange: (e) => setRepeat(e.target.value) }) })
|
|
3363
3348
|
] })
|
|
3364
3349
|
] }) : null
|
|
3365
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_jsx_runtime16.Fragment, { children: !restorePreview ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
3366
|
-
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
3350
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_jsx_runtime16.Fragment, { children: !restorePreview ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(VaultSection, { children: [
|
|
3351
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(VaultRow, { label: "File", ...file ? { hint: file.name } : {}, children: [
|
|
3367
3352
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_controls13.Button, { variant: "outline", disabled: busy, onClick: () => fileInput.current?.click(), children: "Choose a backup" }),
|
|
3368
3353
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3369
3354
|
"input",
|
|
@@ -3379,11 +3364,11 @@ function BackupPanel({ port, items, onClose, onChanged }) {
|
|
|
3379
3364
|
}
|
|
3380
3365
|
)
|
|
3381
3366
|
] }),
|
|
3382
|
-
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3367
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(VaultRow, { label: "Passphrase", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_controls13.Field, { type: "password", value: passphrase, autoComplete: "current-password", "aria-label": "Backup passphrase", onChange: (e) => setPassphrase(e.target.value) }) })
|
|
3383
3368
|
] }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
3384
3369
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Summary, { value: restorePreview }),
|
|
3385
3370
|
!result ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Omissions, { omissions: restorePreview.omissions, accepted, onAccepted: setAccepted, verb: "Restore" }) : null,
|
|
3386
|
-
!result ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "px-1 text-xs text-muted-foreground", children: "Restored items start disabled and restricted." }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3371
|
+
!result ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "px-1 text-xs text-muted-foreground", children: "Restored items start disabled and restricted." }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(VaultSection, { title: `${result.created} restored \xB7 ${result.replayed} already \xB7 ${result.refused} refused \xB7 ${result.retryable_failure} to retry`, children: result.results.map((r) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(VaultRow, { label: names.get(r.source_item_id) ?? "Credential", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: r.status === "refused" || r.status === "retryable_failure" ? "text-destructive" : "text-foreground", children: [
|
|
3387
3372
|
RECORD_STATUS[r.status],
|
|
3388
3373
|
r.reason === "alias_conflict" ? " \xB7 name in use" : ""
|
|
3389
3374
|
] }) }, r.source_item_id)) })
|
|
@@ -3488,7 +3473,7 @@ function ExportPanel({ port, items, onClose }) {
|
|
|
3488
3473
|
] })
|
|
3489
3474
|
] }),
|
|
3490
3475
|
children: [
|
|
3491
|
-
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3476
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(VaultSection, { children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(VaultRow, { label: "Format", hint: format?.hint, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3492
3477
|
import_controls14.Select,
|
|
3493
3478
|
{
|
|
3494
3479
|
value: profile,
|
|
@@ -3501,7 +3486,7 @@ function ExportPanel({ port, items, onClose }) {
|
|
|
3501
3486
|
}
|
|
3502
3487
|
) }) }),
|
|
3503
3488
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3504
|
-
|
|
3489
|
+
VaultSection,
|
|
3505
3490
|
{
|
|
3506
3491
|
title: `${selected.size} of ${plural(logins.length, "login")}`,
|
|
3507
3492
|
actions: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
|
|
@@ -4572,13 +4557,13 @@ function ImportPanel({ port, host, items, organizations, onClose, onChanged, lim
|
|
|
4572
4557
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_controls15.Button, { variant: "primary", onClick: onClose, children: "Done" })
|
|
4573
4558
|
] });
|
|
4574
4559
|
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Panel, { title: "Import", size: "xl", onClose, footer, children: [
|
|
4575
|
-
stage === "choose" ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
4576
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4560
|
+
stage === "choose" ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(VaultSection, { children: [
|
|
4561
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(VaultRow, { label: "Source", actions: help && host.openUrl ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_controls15.Button, { variant: "quiet", onClick: () => host.openUrl?.(help), children: "How to export" }) : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_controls15.Select, { value: source, options: SOURCE_OPTIONS, "aria-label": "Source", onValueChange: (s) => {
|
|
4577
4562
|
setSource(s);
|
|
4578
4563
|
setError(null);
|
|
4579
4564
|
} }) }),
|
|
4580
|
-
source === "env" ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4581
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
4565
|
+
source === "env" ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(VaultRow, { label: ".env text", hint: "Same key updates in place", top: true, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_controls15.Textarea, { mono: true, rows: 7, value: envText, autoComplete: "off", spellCheck: false, "aria-label": ".env text", placeholder: "OPENAI_API_KEY=sk-...\nDATABASE_URL=postgres://...", onChange: (e) => setEnvText(e.target.value) }) }) : null,
|
|
4566
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(VaultRow, { label: "File", hint: fileName ?? void 0, children: [
|
|
4582
4567
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_controls15.Button, { variant: "outline", disabled: reading, onClick: () => fileInput.current?.click(), children: reading ? "Reading\u2026" : source === "env" ? "Load a file" : "Choose a file" }),
|
|
4583
4568
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4584
4569
|
"input",
|
|
@@ -4595,12 +4580,12 @@ function ImportPanel({ port, host, items, organizations, onClose, onChanged, lim
|
|
|
4595
4580
|
}
|
|
4596
4581
|
)
|
|
4597
4582
|
] }),
|
|
4598
|
-
source === "env" ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4583
|
+
source === "env" ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(VaultRow, { label: "Sandboxes", hint: "Pass these values to agent sandboxes", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_controls15.Switch, { checked: injectSandbox, onCheckedChange: setInjectSandbox, "aria-label": "Use in sandboxes" }) }) : null
|
|
4599
4584
|
] }) : null,
|
|
4600
4585
|
stage === "review" && draft ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
|
|
4601
|
-
organizations.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4586
|
+
organizations.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(VaultSection, { children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(VaultRow, { label: "Save to", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_controls15.Select, { value: destination, options: destinationOptions, "aria-label": "Save to", onValueChange: (v) => draft.kind === "file" ? restart({ destination: v }) : setDestination(v) }) }) }) : null,
|
|
4602
4587
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4603
|
-
|
|
4588
|
+
VaultSection,
|
|
4604
4589
|
{
|
|
4605
4590
|
title: draft.kind === "env" ? plural(envKeys.length, "value") : summary(counts, lines.length),
|
|
4606
4591
|
actions: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
|
|
@@ -4628,11 +4613,11 @@ function ImportPanel({ port, host, items, organizations, onClose, onChanged, lim
|
|
|
4628
4613
|
)
|
|
4629
4614
|
}
|
|
4630
4615
|
),
|
|
4631
|
-
draft.kind === "file" && draft.parsed.kind === "structured" ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4616
|
+
draft.kind === "file" && draft.parsed.kind === "structured" ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(VaultSection, { children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(VaultRow, { label: "Visible details", hint: "Approve saving websites and public keys in the clear", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_controls15.Switch, { checked: approvedVisible, disabled: busy, onCheckedChange: setApprovedVisible, "aria-label": "Approve visible details" }) }) }) : null,
|
|
4632
4617
|
draft.kind === "file" ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Notices, { draft }) : null,
|
|
4633
|
-
draft.kind === "file" ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(More, { children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
4634
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4635
|
-
draft.parsed.kind === "csv" ? draft.parsed.preview.headers.map((header, index) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4618
|
+
draft.kind === "file" ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(More, { children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(VaultSection, { children: [
|
|
4619
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(VaultRow, { label: "Browser fill", hint: "Needs username, password and an https address", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_controls15.Switch, { checked: browserFill, disabled: busy, onCheckedChange: (on) => restart({ browserFill: on }), "aria-label": "Browser fill" }) }),
|
|
4620
|
+
draft.parsed.kind === "csv" ? draft.parsed.preview.headers.map((header, index) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(VaultRow, { label: header || `Column ${index + 1}`, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4636
4621
|
import_controls15.Select,
|
|
4637
4622
|
{
|
|
4638
4623
|
value: draft.mapping[index] ?? "keep",
|
|
@@ -4644,16 +4629,16 @@ function ImportPanel({ port, host, items, organizations, onClose, onChanged, lim
|
|
|
4644
4629
|
] }) }) : null,
|
|
4645
4630
|
ambiguous ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ErrorLine, { message: "Each of name, username, password, notes and one-time password can be used by one column." }) : null
|
|
4646
4631
|
] }) : null,
|
|
4647
|
-
stage === "done" && done ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
4648
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4649
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4650
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4651
|
-
done.untried.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4652
|
-
done.withOtp > 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4632
|
+
stage === "done" && done ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(VaultSection, { title: "Result", children: [
|
|
4633
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(VaultRow, { label: "Created", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "text-foreground", children: done.created.length }) }),
|
|
4634
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(VaultRow, { label: "Skipped", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "text-foreground", children: done.skipped }) }),
|
|
4635
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(VaultRow, { label: "Failed", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: done.failed.length > 0 ? "text-destructive" : "text-foreground", children: done.failed.length }) }),
|
|
4636
|
+
done.untried.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(VaultRow, { label: "Not tried", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "text-foreground", children: done.untried.length }) }) : null,
|
|
4637
|
+
done.withOtp > 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(VaultRow, { label: "Codes", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { className: "text-muted-foreground", children: [
|
|
4653
4638
|
plural(done.withOtp, "login"),
|
|
4654
4639
|
" still need the one-time password added."
|
|
4655
4640
|
] }) }) : null,
|
|
4656
|
-
done.failed.map((f) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4641
|
+
done.failed.map((f) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(VaultRow, { label: f.title, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "block truncate text-destructive", title: f.reason, children: f.reason }) }, f.key))
|
|
4657
4642
|
] }) : null,
|
|
4658
4643
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ErrorLine, { message: error })
|
|
4659
4644
|
] });
|
|
@@ -4713,11 +4698,13 @@ var import_controls21 = require("@ai-matrx/design-system/controls");
|
|
|
4713
4698
|
var import_confirm_opener9 = require("@ai-matrx/kit/confirm-opener");
|
|
4714
4699
|
|
|
4715
4700
|
// src/activity/FilesSection.tsx
|
|
4701
|
+
var import_format7 = require("@ai-matrx/kit/format");
|
|
4716
4702
|
var import_react21 = require("react");
|
|
4717
4703
|
var import_controls16 = require("@ai-matrx/design-system/controls");
|
|
4718
4704
|
var import_design_system13 = require("@ai-matrx/design-system");
|
|
4719
4705
|
var import_confirm_opener6 = require("@ai-matrx/kit/confirm-opener");
|
|
4720
4706
|
var import_download3 = require("@ai-matrx/kit/download");
|
|
4707
|
+
var import_icons8 = require("@ai-matrx/design-system/icons");
|
|
4721
4708
|
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
4722
4709
|
var messageOf2 = (e, fallback) => wasCancelled(e) ? null : e instanceof Error ? e.message : fallback;
|
|
4723
4710
|
var TOO_BIG = "Files over 25 MB can't be stored.";
|
|
@@ -4776,7 +4763,7 @@ function FilesSection({ item, port, editing, onChanged }) {
|
|
|
4776
4763
|
onDragLeave: canEdit ? () => setDragging(false) : void 0,
|
|
4777
4764
|
onDrop: canEdit ? drop : void 0,
|
|
4778
4765
|
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
4779
|
-
|
|
4766
|
+
VaultSection,
|
|
4780
4767
|
{
|
|
4781
4768
|
title: "Files",
|
|
4782
4769
|
actions: canEdit ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_controls16.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(PlusGlyph, {}), disabled: busy !== null, onClick: () => picker.current?.click(), children: "Add file" }) : void 0,
|
|
@@ -4787,11 +4774,11 @@ function FilesSection({ item, port, editing, onChanged }) {
|
|
|
4787
4774
|
} }) : null,
|
|
4788
4775
|
item.attachments.map(
|
|
4789
4776
|
(a) => canEdit ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(EditableFile, { port, item, file: a, busy, run, onDownload: () => void download(a), onTooBig: () => setError(TOO_BIG) }, a.id) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
4790
|
-
|
|
4777
|
+
VaultRow,
|
|
4791
4778
|
{
|
|
4792
4779
|
label: a.label,
|
|
4793
4780
|
hint: a.description || void 0,
|
|
4794
|
-
actions: a.handling === "sealed" ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_controls16.Badge, { icon: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(LockGlyph, {}), children: "Sealed" }) : canDownload(item, a) ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_controls16.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
4781
|
+
actions: a.handling === "sealed" ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_controls16.Badge, { icon: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(LockGlyph, {}), children: "Sealed" }) : canDownload(item, a) ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_controls16.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_icons8.DownloadIcon, {}), "aria-label": `Download ${a.fileName}`, disabled: busy !== null, onClick: () => void download(a) }) : null,
|
|
4795
4782
|
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(FileName, { file: a })
|
|
4796
4783
|
},
|
|
4797
4784
|
a.id
|
|
@@ -4817,12 +4804,12 @@ function EditableFile({ port, item: it, file: a, busy: b, run: go, onDownload, o
|
|
|
4817
4804
|
}
|
|
4818
4805
|
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
|
|
4819
4806
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
4820
|
-
|
|
4807
|
+
VaultRow,
|
|
4821
4808
|
{
|
|
4822
4809
|
label: a.label,
|
|
4823
4810
|
hint: a.description || void 0,
|
|
4824
4811
|
actions: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
|
|
4825
|
-
canDownload(it, a) ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_controls16.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
4812
|
+
canDownload(it, a) ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_controls16.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_icons8.DownloadIcon, {}), "aria-label": `Download ${a.fileName}`, disabled: b !== null, onClick: onDownload }) : null,
|
|
4826
4813
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_controls16.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(PencilGlyph, {}), "aria-label": `Edit ${a.label}`, pressed: open, disabled: b !== null, onClick: () => setOpen((o) => !o) }),
|
|
4827
4814
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_controls16.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(UploadGlyph, {}), "aria-label": `Replace ${a.fileName}`, disabled: b !== null, onClick: () => replacer.current?.click() }),
|
|
4828
4815
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_controls16.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TrashGlyph, {}), "aria-label": `Delete ${a.label}`, disabled: b !== null, onClick: () => void remove() }),
|
|
@@ -4853,7 +4840,7 @@ function EditableFile({ port, item: it, file: a, busy: b, run: go, onDownload, o
|
|
|
4853
4840
|
function FileName({ file }) {
|
|
4854
4841
|
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { className: "flex min-w-0 items-center gap-2", children: [
|
|
4855
4842
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "truncate", children: file.fileName }),
|
|
4856
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "shrink-0 text-xs text-muted-foreground", children:
|
|
4843
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "shrink-0 text-xs text-muted-foreground", children: (0, import_format7.formatFileSize)(file.sizeBytes) })
|
|
4857
4844
|
] });
|
|
4858
4845
|
}
|
|
4859
4846
|
function Protection({ value, locked, onChange }) {
|
|
@@ -4876,13 +4863,13 @@ function NewFile({ file, busy, onAdd, onCancel }) {
|
|
|
4876
4863
|
await onAdd({ label: label.trim(), description: description.trim() || null, handling });
|
|
4877
4864
|
}
|
|
4878
4865
|
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
|
|
4879
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
4866
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(VaultRow, { label: "New file", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { className: "flex min-w-0 items-center gap-2", children: [
|
|
4880
4867
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "truncate", children: file.name }),
|
|
4881
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "shrink-0 text-xs text-muted-foreground", children:
|
|
4868
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "shrink-0 text-xs text-muted-foreground", children: (0, import_format7.formatFileSize)(file.size) })
|
|
4882
4869
|
] }) }),
|
|
4883
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
4884
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
4885
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
4870
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(VaultRow, { label: "Name", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_controls16.Field, { "aria-label": "Name", value: label, onChange: (e) => setLabel(e.target.value) }) }),
|
|
4871
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(VaultRow, { label: "Purpose", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_controls16.Field, { "aria-label": "Purpose", placeholder: "What it is for", value: description, onChange: (e) => setDescription(e.target.value) }) }),
|
|
4872
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(VaultRow, { label: "Protection", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Protection, { value: handling, locked: false, onChange: setHandling }) }),
|
|
4886
4873
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex justify-end gap-2 px-3 py-1 sm:px-4", children: [
|
|
4887
4874
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_controls16.Button, { variant: "quiet", disabled: busy, onClick: onCancel, children: "Cancel" }),
|
|
4888
4875
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_controls16.Button, { variant: "primary", disabled: busy || !label.trim(), onClick: () => void add(), children: busy ? "Adding\u2026" : "Add file" })
|
|
@@ -4900,10 +4887,10 @@ function FileDetailsRows({ file, busy, onSave, onCancel }) {
|
|
|
4900
4887
|
await onSave({ label: label.trim(), description: description.trim() || null, fileName: fileName.trim(), handling });
|
|
4901
4888
|
}
|
|
4902
4889
|
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
|
|
4903
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
4904
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
4905
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
4906
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
4890
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(VaultRow, { label: "Name", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_controls16.Field, { "aria-label": "Name", value: label, onChange: (e) => setLabel(e.target.value) }) }),
|
|
4891
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(VaultRow, { label: "Purpose", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_controls16.Field, { "aria-label": "Purpose", placeholder: "What it is for", value: description, onChange: (e) => setDescription(e.target.value) }) }),
|
|
4892
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(VaultRow, { label: "File name", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_controls16.Field, { "aria-label": "File name", value: fileName, onChange: (e) => setFileName(e.target.value) }) }),
|
|
4893
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(VaultRow, { label: "Protection", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Protection, { value: handling, locked: file.handling === "sealed", onChange: setHandling }) }),
|
|
4907
4894
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex justify-end gap-2 px-3 py-1 sm:px-4", children: [
|
|
4908
4895
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_controls16.Button, { variant: "quiet", disabled: busy, onClick: onCancel, children: "Cancel" }),
|
|
4909
4896
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_controls16.Button, { variant: "primary", disabled: busy || !changed || !label.trim() || !fileName.trim(), onClick: () => void save(), children: busy ? "Saving\u2026" : "Save" })
|
|
@@ -4922,6 +4909,7 @@ function confirmSeal(label) {
|
|
|
4922
4909
|
// src/fields/RecoveryCodesRow.tsx
|
|
4923
4910
|
var import_react22 = require("react");
|
|
4924
4911
|
var import_controls17 = require("@ai-matrx/design-system/controls");
|
|
4912
|
+
var import_icons9 = require("@ai-matrx/design-system/icons");
|
|
4925
4913
|
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
4926
4914
|
var MASK4 = "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022";
|
|
4927
4915
|
var say2 = (e, fallback) => e instanceof Error && e.message ? e.message : fallback;
|
|
@@ -4962,7 +4950,7 @@ function RecoveryCodesRow({ item, field, port, onChanged }) {
|
|
|
4962
4950
|
};
|
|
4963
4951
|
if (draft !== null) {
|
|
4964
4952
|
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
4965
|
-
|
|
4953
|
+
VaultRow,
|
|
4966
4954
|
{
|
|
4967
4955
|
label: "Recovery codes",
|
|
4968
4956
|
top: true,
|
|
@@ -4982,7 +4970,7 @@ function RecoveryCodesRow({ item, field, port, onChanged }) {
|
|
|
4982
4970
|
}
|
|
4983
4971
|
if (!field) {
|
|
4984
4972
|
if (!canEdit) return null;
|
|
4985
|
-
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
4973
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(VaultRow, { label: "Recovery codes", actions: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_controls17.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(PlusGlyph, {}), "aria-label": "Add recovery codes", onClick: () => setDraft("") }), children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-muted-foreground", children: "None" }) });
|
|
4986
4974
|
}
|
|
4987
4975
|
const sealed = field.handling === "sealed";
|
|
4988
4976
|
const canSee = !sealed && item.capabilities.canReveal;
|
|
@@ -5004,7 +4992,7 @@ function RecoveryCodesRow({ item, field, port, onChanged }) {
|
|
|
5004
4992
|
});
|
|
5005
4993
|
};
|
|
5006
4994
|
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
5007
|
-
|
|
4995
|
+
VaultRow,
|
|
5008
4996
|
{
|
|
5009
4997
|
label: "Recovery codes",
|
|
5010
4998
|
top: codes !== null,
|
|
@@ -5015,7 +5003,7 @@ function RecoveryCodesRow({ item, field, port, onChanged }) {
|
|
|
5015
5003
|
children: sealed ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_controls17.Badge, { icon: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(LockGlyph, {}), children: "Sealed" }) : codes ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("ul", { className: "flex flex-col gap-0.5", "aria-label": "Recovery codes", children: [
|
|
5016
5004
|
codes.map((code, i) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("li", { className: "flex min-h-7 items-center gap-1", children: [
|
|
5017
5005
|
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("code", { className: "min-w-0 flex-1 break-all font-mono text-sm text-foreground", children: code }),
|
|
5018
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_controls17.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
5006
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_controls17.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_icons9.CopyIcon, {}), "aria-label": `Copy code ${i + 1}`, onClick: () => void copyValue2(code, "Recovery code") }),
|
|
5019
5007
|
canEdit ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_controls17.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CheckGlyph, {}), disabled: busy, onClick: () => void markUsed(i), children: "Mark used" }) : null
|
|
5020
5008
|
] }, `${i}-${code}`)),
|
|
5021
5009
|
error ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("li", { role: "alert", className: "text-xs text-destructive", children: error }) : null
|
|
@@ -5024,33 +5012,17 @@ function RecoveryCodesRow({ item, field, port, onChanged }) {
|
|
|
5024
5012
|
);
|
|
5025
5013
|
}
|
|
5026
5014
|
|
|
5015
|
+
// src/ItemPane.tsx
|
|
5016
|
+
var import_icons11 = require("@ai-matrx/design-system/icons");
|
|
5017
|
+
var import_drafts = require("@ai-matrx/kit/drafts");
|
|
5018
|
+
|
|
5027
5019
|
// src/draft-keep.ts
|
|
5028
5020
|
var PREFIX = "matrx.vault.draft:";
|
|
5029
5021
|
function draftKey(itemId, definitionKey) {
|
|
5030
5022
|
return `${PREFIX}${itemId ?? `new:${definitionKey ?? "custom"}`}`;
|
|
5031
5023
|
}
|
|
5032
|
-
function
|
|
5033
|
-
|
|
5034
|
-
try {
|
|
5035
|
-
globalThis.sessionStorage?.setItem(key, JSON.stringify(kept));
|
|
5036
|
-
} catch {
|
|
5037
|
-
}
|
|
5038
|
-
}
|
|
5039
|
-
function readKeptDraft(key, basedOn) {
|
|
5040
|
-
try {
|
|
5041
|
-
const raw = globalThis.sessionStorage?.getItem(key);
|
|
5042
|
-
if (!raw) return null;
|
|
5043
|
-
const kept = JSON.parse(raw);
|
|
5044
|
-
return kept.basedOn === basedOn ? kept.draft : null;
|
|
5045
|
-
} catch {
|
|
5046
|
-
return null;
|
|
5047
|
-
}
|
|
5048
|
-
}
|
|
5049
|
-
function dropKeptDraft(key) {
|
|
5050
|
-
try {
|
|
5051
|
-
globalThis.sessionStorage?.removeItem(key);
|
|
5052
|
-
} catch {
|
|
5053
|
-
}
|
|
5024
|
+
function keptFieldsOf(d) {
|
|
5025
|
+
return { name: d.name, description: d.description, tags: d.tags, loginUrls: d.loginUrls, notes: d.notes, custom: d.custom };
|
|
5054
5026
|
}
|
|
5055
5027
|
|
|
5056
5028
|
// src/extension/page-logic.ts
|
|
@@ -5197,6 +5169,7 @@ var import_react26 = require("react");
|
|
|
5197
5169
|
var import_confirm_opener8 = require("@ai-matrx/kit/confirm-opener");
|
|
5198
5170
|
var import_controls20 = require("@ai-matrx/design-system/controls");
|
|
5199
5171
|
var import_design_system15 = require("@ai-matrx/design-system");
|
|
5172
|
+
var import_icons10 = require("@ai-matrx/design-system/icons");
|
|
5200
5173
|
|
|
5201
5174
|
// src/sharing/logic.ts
|
|
5202
5175
|
var LEVEL_OPTIONS = [
|
|
@@ -5228,7 +5201,7 @@ function copyRefusal(message2) {
|
|
|
5228
5201
|
return /duplicate/i.test(message2) ? "There is already a copy of this item there." : null;
|
|
5229
5202
|
}
|
|
5230
5203
|
var isPasskey = (item) => item.definitionKey === "native_passkey" || item.definitionKey === "passkey_private";
|
|
5231
|
-
function
|
|
5204
|
+
function itemMoveConsequence(item, to) {
|
|
5232
5205
|
if (item.authenticator) return "One-time password stays behind; set it up again";
|
|
5233
5206
|
return to ? "Its members get access; people you shared with lose it" : "Only you; organization members lose access";
|
|
5234
5207
|
}
|
|
@@ -5318,7 +5291,7 @@ function MovePanel({ item, port, organizations, onClose, onChanged }) {
|
|
|
5318
5291
|
const to = destinationOf(moveChoice.value);
|
|
5319
5292
|
const ok = await (0, import_confirm_opener7.confirm)({
|
|
5320
5293
|
title: `Move to ${moveChoice.label}?`,
|
|
5321
|
-
description: `"${item.name}" stays the same item, so everything using it keeps working. ${
|
|
5294
|
+
description: `"${item.name}" stays the same item, so everything using it keeps working. ${itemMoveConsequence(item, to)}.`,
|
|
5322
5295
|
confirmLabel: "Move"
|
|
5323
5296
|
});
|
|
5324
5297
|
if (!ok) return;
|
|
@@ -5354,17 +5327,17 @@ function MovePanel({ item, port, organizations, onClose, onChanged }) {
|
|
|
5354
5327
|
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(StatusLine, { error, notice }),
|
|
5355
5328
|
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_controls19.Button, { variant: "outline", className: "ml-auto", onClick: onClose, children: "Close" })
|
|
5356
5329
|
] }),
|
|
5357
|
-
children: nothing ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
5330
|
+
children: nothing ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(VaultSection, { children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Empty, { children: passkey ? "A passkey stays where it was created." : "Only the owner can move or give this item." }) }) : /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(VaultSection, { children: [
|
|
5358
5331
|
canMove && moves.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
5359
|
-
|
|
5332
|
+
VaultRow,
|
|
5360
5333
|
{
|
|
5361
5334
|
label: "Move to",
|
|
5362
|
-
hint: moveChoice ?
|
|
5335
|
+
hint: moveChoice ? itemMoveConsequence(item, destinationOf(moveChoice.value)) : void 0,
|
|
5363
5336
|
actions: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_controls19.Button, { variant: "outline", disabled: busy !== null || !moveChoice, onClick: () => void move(), children: "Move" }),
|
|
5364
5337
|
children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_controls19.Select, { className: "w-full", "aria-label": "Move to", value: moveTo || NONE, onValueChange: (v) => setMoveTo(v === NONE ? "" : v), options: [{ value: NONE, label: "Choose where" }, ...moves] })
|
|
5365
5338
|
}
|
|
5366
5339
|
) : null,
|
|
5367
|
-
canGive ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
5340
|
+
canGive ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(VaultRow, { label: "Give to", hint: "You lose all access; your shares end", actions: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_controls19.Button, { variant: "danger", disabled: busy !== null || !isEmail(email), onClick: () => void give(), children: "Give" }), children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
5368
5341
|
import_controls19.Field,
|
|
5369
5342
|
{
|
|
5370
5343
|
className: "w-full",
|
|
@@ -5378,7 +5351,7 @@ function MovePanel({ item, port, organizations, onClose, onChanged }) {
|
|
|
5378
5351
|
onChange: (e) => setEmail(e.target.value)
|
|
5379
5352
|
}
|
|
5380
5353
|
) }) : null,
|
|
5381
|
-
canCopy && copies.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
5354
|
+
canCopy && copies.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(VaultRow, { label: "Copy to", hint: "A separate item; edits no longer sync", actions: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_controls19.Button, { variant: "outline", disabled: busy !== null || !copyChoice, onClick: () => void copy(), children: "Copy" }), children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_controls19.Select, { className: "w-full", "aria-label": "Copy to", value: copyTo || NONE, onValueChange: (v) => setCopyTo(v === NONE ? "" : v), options: [{ value: NONE, label: "Choose where" }, ...copies] }) }) : null
|
|
5382
5355
|
] })
|
|
5383
5356
|
}
|
|
5384
5357
|
);
|
|
@@ -5460,7 +5433,7 @@ function SharePanel({ item, port, organizations, onClose, onChanged }) {
|
|
|
5460
5433
|
}
|
|
5461
5434
|
};
|
|
5462
5435
|
if (!item.capabilities.canManage) {
|
|
5463
|
-
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Panel, { title: "Share", size: "md", onClose, footer: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_controls20.Button, { variant: "primary", onClick: onClose, children: "Done" }), children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
5436
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Panel, { title: "Share", size: "md", onClose, footer: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_controls20.Button, { variant: "primary", onClick: onClose, children: "Done" }), children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(VaultSection, { children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Empty, { children: "Only the owner can change who has access." }) }) });
|
|
5464
5437
|
}
|
|
5465
5438
|
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
5466
5439
|
Panel,
|
|
@@ -5473,9 +5446,9 @@ function SharePanel({ item, port, organizations, onClose, onChanged }) {
|
|
|
5473
5446
|
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_controls20.Button, { variant: "primary", className: "ml-auto", onClick: onClose, children: "Done" })
|
|
5474
5447
|
] }),
|
|
5475
5448
|
children: [
|
|
5476
|
-
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
5449
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(VaultSection, { title: "Who has access", children: [
|
|
5477
5450
|
isOrg ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(AccessLine, { glyph: BuildingGlyph, who: `${orgName} admins`, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "px-2 text-sm text-muted-foreground", children: "Full access" }) }) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(AccessLine, { glyph: PersonGlyph, who: "You", meta: "Owner", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "px-2 text-sm text-muted-foreground", children: "Full access" }) }),
|
|
5478
|
-
isOrg ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(AccessLine, { glyph:
|
|
5451
|
+
isOrg ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(AccessLine, { glyph: import_icons10.UsersIcon, who: `${orgName} members`, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
5479
5452
|
import_controls20.Select,
|
|
5480
5453
|
{
|
|
5481
5454
|
variant: "inline",
|
|
@@ -5536,7 +5509,7 @@ function IntoOrganization({ item, port, organizations, grants, onShared }) {
|
|
|
5536
5509
|
const [level, setLevel] = (0, import_react26.useState)("use");
|
|
5537
5510
|
const chosen = open.find((o) => o.id === target);
|
|
5538
5511
|
if (item.owner.kind !== "me") return null;
|
|
5539
|
-
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
5512
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(VaultSection, { title: "Share into organization", children: open.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
|
|
5540
5513
|
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex min-h-11 items-center gap-2 px-3 sm:px-4", children: [
|
|
5541
5514
|
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(BuildingGlyph, { className: "size-4 shrink-0 text-muted-foreground" }),
|
|
5542
5515
|
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_controls20.Select, { className: "min-w-0 flex-1", "aria-label": "Organization", value: target || "__none__", onValueChange: (v) => setTarget(v === "__none__" ? "" : v), options: [{ value: "__none__", label: "Choose an organization" }, ...open.map((o) => ({ value: o.id, label: o.name }))] }),
|
|
@@ -5586,7 +5559,7 @@ function MemberAccess({ port, organizationId, organizationName }) {
|
|
|
5586
5559
|
const effective = await run(userId, () => port.sharing.setMemberAccess(organizationId, userId, access));
|
|
5587
5560
|
if (effective) setList((l) => l ? { ...l, members: l.members.map((m) => m.userId === userId ? { ...m, access, effective } : m) } : l);
|
|
5588
5561
|
};
|
|
5589
|
-
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
5562
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(VaultSection, { title: `${organizationName} vault access`, children: [
|
|
5590
5563
|
loadError ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Empty, { children: loadError }) : list === null ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_controls20.RegionSkeleton, { shape: "rows", count: 3, "aria-label": "Loading member access", className: "px-3 sm:px-4" }) : list.members.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Empty, { children: "No members yet." }) : list.members.map((m) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(AccessLine, { glyph: PersonGlyph, who: m.email || m.userId, meta: m.role, children: m.effective === "admin" ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "px-2 text-sm text-muted-foreground", children: MEMBER_ACCESS_LABEL.admin }) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
5591
5564
|
import_controls20.Select,
|
|
5592
5565
|
{
|
|
@@ -5621,7 +5594,7 @@ function SharingSummary({ item, port, className }) {
|
|
|
5621
5594
|
}
|
|
5622
5595
|
|
|
5623
5596
|
// src/ItemPane.tsx
|
|
5624
|
-
var
|
|
5597
|
+
var import_format8 = require("@ai-matrx/kit/format");
|
|
5625
5598
|
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
5626
5599
|
var USERNAME_KEYS = /^(username|user_name|email|login|username_or_email|account_email)$/;
|
|
5627
5600
|
function ItemPane(props) {
|
|
@@ -5662,7 +5635,7 @@ function ItemPane(props) {
|
|
|
5662
5635
|
if (was && was.id === id && was.mode === mode && editing) {
|
|
5663
5636
|
setDraft((d) => rebaseDraft(was.base, base, d));
|
|
5664
5637
|
} else {
|
|
5665
|
-
const kept = editing ? readKeptDraft(keepKey, item?.updatedAt ?? "new") : null;
|
|
5638
|
+
const kept = editing ? (0, import_drafts.readKeptDraft)(keepKey, { basedOn: item?.updatedAt ?? "new" })?.value ?? null : null;
|
|
5666
5639
|
setDraft(kept ? { ...base, ...kept } : base);
|
|
5667
5640
|
setTagsText((kept ?? base).tags.join(", "));
|
|
5668
5641
|
setError(null);
|
|
@@ -5677,8 +5650,8 @@ function ItemPane(props) {
|
|
|
5677
5650
|
(0, import_react27.useEffect)(() => onDirty(dirty), [dirty, onDirty]);
|
|
5678
5651
|
const keepKey = draftKey(item?.id ?? null, definition?.key ?? item?.definitionKey ?? null);
|
|
5679
5652
|
(0, import_react27.useEffect)(() => {
|
|
5680
|
-
if (editing && dirty) keepDraft(keepKey, item?.updatedAt ?? "new"
|
|
5681
|
-
else if (!editing) dropKeptDraft(keepKey);
|
|
5653
|
+
if (editing && dirty) (0, import_drafts.keepDraft)(keepKey, keptFieldsOf(draft), { basedOn: item?.updatedAt ?? "new" });
|
|
5654
|
+
else if (!editing) (0, import_drafts.dropKeptDraft)(keepKey);
|
|
5682
5655
|
}, [editing, dirty, draft, keepKey, item?.updatedAt]);
|
|
5683
5656
|
(0, import_react27.useEffect)(() => {
|
|
5684
5657
|
if (!editing || !item) return;
|
|
@@ -5715,7 +5688,7 @@ function ItemPane(props) {
|
|
|
5715
5688
|
if (item) {
|
|
5716
5689
|
const r = await port.save(item, definition, out);
|
|
5717
5690
|
const [next, n] = await withOtp(r.item, r.notice);
|
|
5718
|
-
dropKeptDraft(keepKey);
|
|
5691
|
+
(0, import_drafts.dropKeptDraft)(keepKey);
|
|
5719
5692
|
onSaved(next, false, n);
|
|
5720
5693
|
} else if (definition && owner === "person") {
|
|
5721
5694
|
const secretKey = declared.find((f) => f.storage === "encrypted" && f.kind === "secret")?.key ?? null;
|
|
@@ -5725,7 +5698,7 @@ function ItemPane(props) {
|
|
|
5725
5698
|
} else if (definition) {
|
|
5726
5699
|
const r = await port.create(definition, owner === "me" ? null : owner, out);
|
|
5727
5700
|
const [next, n] = await withOtp(r.item, r.notice);
|
|
5728
|
-
dropKeptDraft(keepKey);
|
|
5701
|
+
(0, import_drafts.dropKeptDraft)(keepKey);
|
|
5729
5702
|
onSaved(next, true, n);
|
|
5730
5703
|
}
|
|
5731
5704
|
} catch (e) {
|
|
@@ -5764,7 +5737,7 @@ function ItemPane(props) {
|
|
|
5764
5737
|
const viewCustom = (item?.custom ?? []).filter((c) => !declaredKeys.has(c.key) && c.key !== MFA_METHOD_KEY && !isAuthenticatorStorage(c.key));
|
|
5765
5738
|
const isLogin = (item?.definitionKey ?? definition?.key) === "website_login" || (item?.definitionKey ?? definition?.key) === "username_password";
|
|
5766
5739
|
const typeLabel = definition?.label ?? item?.definitionLabel ?? "";
|
|
5767
|
-
const shownOwner = mode === "new" ? owner === "me" ? { label: "Personal", glyph: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(PersonGlyph, {}) } : owner === "person" ? { label: "Someone else", glyph: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(SendGlyph, {}) } : { label: organizations.find((o) => o.id === owner)?.name ?? "Organization", glyph: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(BuildingGlyph, {}) } : item ? { label: item.owner.label, glyph: item.owner.kind === "me" ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(PersonGlyph, {}) : item.owner.kind === "organization" ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(BuildingGlyph, {}) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5740
|
+
const shownOwner = mode === "new" ? owner === "me" ? { label: "Personal", glyph: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(PersonGlyph, {}) } : owner === "person" ? { label: "Someone else", glyph: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(SendGlyph, {}) } : { label: organizations.find((o) => o.id === owner)?.name ?? "Organization", glyph: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(BuildingGlyph, {}) } : item ? { label: item.owner.label, glyph: item.owner.kind === "me" ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(PersonGlyph, {}) : item.owner.kind === "organization" ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(BuildingGlyph, {}) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_icons11.UsersIcon, {}) } : null;
|
|
5768
5741
|
const tagsVisible = showTags || draft.tags.length > 0 || tagsText !== "";
|
|
5769
5742
|
const descriptionVisible = showDescription || draft.description !== "";
|
|
5770
5743
|
const header = /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("header", { className: "flex min-h-14 items-center gap-2 border-b border-border px-3 py-2 sm:gap-3 sm:px-5", children: [
|
|
@@ -5821,7 +5794,7 @@ function ItemPane(props) {
|
|
|
5821
5794
|
"Send securely"
|
|
5822
5795
|
] }) : null,
|
|
5823
5796
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_design_system16.DropdownMenuItem, { onSelect: () => onPanel("history"), children: [
|
|
5824
|
-
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5797
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_icons11.HistoryIcon, { className: "size-4" }),
|
|
5825
5798
|
"Password history"
|
|
5826
5799
|
] }),
|
|
5827
5800
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_design_system16.DropdownMenuItem, { onSelect: () => onPanel("activity"), children: [
|
|
@@ -5829,7 +5802,7 @@ function ItemPane(props) {
|
|
|
5829
5802
|
"Activity"
|
|
5830
5803
|
] }),
|
|
5831
5804
|
canEdit ? /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_design_system16.DropdownMenuItem, { onSelect: () => onPanel("settings"), children: [
|
|
5832
|
-
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5805
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_icons11.SettingsIcon, { className: "size-4" }),
|
|
5833
5806
|
"Settings"
|
|
5834
5807
|
] }) : null,
|
|
5835
5808
|
canManage ? /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
|
|
@@ -5849,8 +5822,8 @@ function ItemPane(props) {
|
|
|
5849
5822
|
error ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { role: "alert", className: "border-b border-border bg-muted px-5 py-2 text-sm text-destructive", children: error }) : null,
|
|
5850
5823
|
notice && !editing ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { role: "status", className: "border-b border-border bg-muted px-5 py-2 text-sm text-warning", children: notice }) : null,
|
|
5851
5824
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "min-h-0 flex-1 overflow-y-auto", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "mx-auto flex w-full max-w-3xl flex-col gap-5 px-3 py-4 sm:px-6 sm:py-6", children: editing ? /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
|
|
5852
|
-
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
5853
|
-
mode === "new" ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5825
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(VaultSection, { children: [
|
|
5826
|
+
mode === "new" ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(VaultRow, { label: "Save to", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5854
5827
|
import_controls21.OptionCombobox,
|
|
5855
5828
|
{
|
|
5856
5829
|
value: owner,
|
|
@@ -5871,7 +5844,7 @@ function ItemPane(props) {
|
|
|
5871
5844
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(EditRow, { label: "Name", value: draft.name, onChange: (v) => patch({ name: v }), placeholder: "Name", autoFocus: mode === "new" }),
|
|
5872
5845
|
mode === "new" && owner === "person" ? /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
|
|
5873
5846
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(EditRow, { label: "Their email", value: recipient, placeholder: "name@company.com", inputMode: "email", onChange: setRecipient }),
|
|
5874
|
-
declared.some((f) => f.storage === "encrypted" && f.kind === "secret") ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5847
|
+
declared.some((f) => f.storage === "encrypted" && f.kind === "secret") ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(VaultRow, { label: "Password", hint: "You never see it", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_controls21.Switch, { checked: generatePrivately, onCheckedChange: setGeneratePrivately, "aria-label": "Generate the password privately" }) }) : null
|
|
5875
5848
|
] }) : null,
|
|
5876
5849
|
declared.map((f) => {
|
|
5877
5850
|
const existing = item?.fields.find((x) => x.key === f.key);
|
|
@@ -5891,7 +5864,7 @@ function ItemPane(props) {
|
|
|
5891
5864
|
actions: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
|
|
5892
5865
|
hidden && existing?.handling === "revealable" && item?.capabilities.canReveal ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_controls21.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(EyeGlyph, {}), "aria-label": `Show current ${f.label}`, onClick: () => void loadForEdit(f.key) }) : null,
|
|
5893
5866
|
secretKind ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(GenerateButton, { onUse: (v) => setValue(f.key, v) }) : null,
|
|
5894
|
-
existing ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_controls21.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5867
|
+
existing ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_controls21.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_icons11.SettingsIcon, {}), "aria-label": `${f.label} settings`, onClick: () => onPanel(`field:${existing.id}`) }) : null
|
|
5895
5868
|
] })
|
|
5896
5869
|
},
|
|
5897
5870
|
f.key
|
|
@@ -5909,7 +5882,7 @@ function ItemPane(props) {
|
|
|
5909
5882
|
removeLabel: `Delete ${f.label}`,
|
|
5910
5883
|
actions: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
|
|
5911
5884
|
f.handling === "revealable" && !(f.key in loaded) && item?.capabilities.canReveal ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_controls21.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(EyeGlyph, {}), "aria-label": `Show current ${f.label}`, onClick: () => void loadForEdit(f.key) }) : null,
|
|
5912
|
-
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_controls21.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5885
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_controls21.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_icons11.SettingsIcon, {}), "aria-label": `${f.label} settings`, onClick: () => onPanel(`field:${f.id}`) })
|
|
5913
5886
|
] })
|
|
5914
5887
|
},
|
|
5915
5888
|
f.id
|
|
@@ -5942,9 +5915,9 @@ function ItemPane(props) {
|
|
|
5942
5915
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(TotpEditRow, { value: draft.authenticator, onChange: (v) => patch({ authenticator: v }), hasExisting: Boolean(item?.authenticator), item, port, onEnrolled: onChanged }),
|
|
5943
5916
|
item && isLogin && !item.authenticator ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(TwoFactorMethodRow, { port, item, onChanged }) : null
|
|
5944
5917
|
] }),
|
|
5945
|
-
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5918
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(VaultSection, { children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(EditRow, { label: "Notes", value: draft.notes, multiline: true, placeholder: "Anything worth remembering", onChange: (v) => patch({ notes: v }) }) }),
|
|
5946
5919
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
5947
|
-
|
|
5920
|
+
VaultSection,
|
|
5948
5921
|
{
|
|
5949
5922
|
title: "More",
|
|
5950
5923
|
actions: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_design_system16.DropdownMenu, { children: [
|
|
@@ -5978,7 +5951,7 @@ function ItemPane(props) {
|
|
|
5978
5951
|
),
|
|
5979
5952
|
filesProps ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(FilesSection, { ...filesProps, editing: true }) : null
|
|
5980
5953
|
] }) : item ? /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
|
|
5981
|
-
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
5954
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(VaultSection, { children: [
|
|
5982
5955
|
declared.map((f) => {
|
|
5983
5956
|
if (f.storage === "metadata") {
|
|
5984
5957
|
const v = metaValue(f.key);
|
|
@@ -5993,18 +5966,18 @@ function ItemPane(props) {
|
|
|
5993
5966
|
item.authenticator ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(TotpRow, { port, item, onChanged }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(AddRow, { label: "One-time password", onAdd: canEdit ? () => onMode("edit") : null, children: "Set up" }),
|
|
5994
5967
|
!item.authenticator && item.custom.some((c) => c.key === MFA_METHOD_KEY && c.value) ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(TwoFactorMethodRow, { port, item, onChanged }) : null
|
|
5995
5968
|
] }),
|
|
5996
|
-
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5997
|
-
item.description || item.tags.length > 0 || viewCustom.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
5969
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(VaultSection, { children: item.notes ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(PlainRow, { label: "Notes", value: item.notes, multiline: true }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(AddRow, { label: "Notes", onAdd: canEdit ? () => onMode("edit") : null, children: "Add notes" }) }),
|
|
5970
|
+
item.description || item.tags.length > 0 || viewCustom.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(VaultSection, { title: "More", children: [
|
|
5998
5971
|
item.description ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(PlainRow, { label: "Description", value: item.description }) : null,
|
|
5999
|
-
item.tags.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5972
|
+
item.tags.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(VaultRow, { label: "Tags", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "flex flex-wrap gap-1", children: item.tags.map((t) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "rounded-md bg-muted px-1.5 py-0.5 text-xs", children: t }, t)) }) }) : null,
|
|
6000
5973
|
viewCustom.map((c) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(PlainRow, { label: c.label, value: c.value, openUrl: host.openUrl }, c.key))
|
|
6001
5974
|
] }) : null,
|
|
6002
5975
|
filesProps ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(FilesSection, { ...filesProps, editing: false }) : null,
|
|
6003
5976
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("p", { className: (0, import_design_system17.cn)("px-1 text-xs text-muted-foreground"), children: [
|
|
6004
5977
|
"Modified ",
|
|
6005
|
-
(0,
|
|
5978
|
+
(0, import_format8.formatAbsoluteDate)(item.updatedAt, DAY_FORMAT, ""),
|
|
6006
5979
|
" \xB7 Created ",
|
|
6007
|
-
(0,
|
|
5980
|
+
(0, import_format8.formatAbsoluteDate)(item.createdAt, DAY_FORMAT, "")
|
|
6008
5981
|
] })
|
|
6009
5982
|
] }) : null }) })
|
|
6010
5983
|
] }) });
|
|
@@ -6120,7 +6093,7 @@ function ListRow({ item, family, port, on, onSelect, withOwner }) {
|
|
|
6120
6093
|
// src/lists/TrashView.tsx
|
|
6121
6094
|
var import_react30 = require("react");
|
|
6122
6095
|
var import_controls24 = require("@ai-matrx/design-system/controls");
|
|
6123
|
-
var
|
|
6096
|
+
var import_format9 = require("@ai-matrx/kit/format");
|
|
6124
6097
|
|
|
6125
6098
|
// src/lists/logic.ts
|
|
6126
6099
|
var ENTITY_TYPE = "credential_item";
|
|
@@ -6244,13 +6217,13 @@ function RestorePanel({ lists, item, restore, onClose }) {
|
|
|
6244
6217
|
refused ? null : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_controls23.Button, { variant: "primary", icon: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(RestoreGlyph, {}), disabled: busy || loading || lists.preview !== void 0 && preview === null, onClick: () => void run(), children: busy ? "Restoring\u2026" : "Restore" })
|
|
6245
6218
|
] }),
|
|
6246
6219
|
children: [
|
|
6247
|
-
loading ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
6248
|
-
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
6249
|
-
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
6250
|
-
preview.passkeys === 1 ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
6251
|
-
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
6252
|
-
preview.priorWasDisabled ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
6253
|
-
] }) : preview ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
6220
|
+
loading ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(VaultSection, { children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Empty, { children: "Checking what comes back\u2026" }) }) : preview?.supported ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(VaultSection, { title: "Comes back", children: [
|
|
6221
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(VaultRow, { label: "Fields", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "text-foreground", children: count(preview.fields, "field") }) }),
|
|
6222
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(VaultRow, { label: "Files", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "text-foreground", children: count(preview.attachments, "file") }) }),
|
|
6223
|
+
preview.passkeys === 1 ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(VaultRow, { label: "Passkey", hint: "Not turned on; the site may not accept it", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "text-foreground", children: "1 passkey" }) }) : null,
|
|
6224
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(VaultRow, { label: "Stays off", hint: "Turn each back on yourself", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "text-muted-foreground", children: "Sharing, browser fill, codes, sandboxes, agents" }) }),
|
|
6225
|
+
preview.priorWasDisabled ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(VaultRow, { label: "Before", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "text-muted-foreground", children: "It was already off before it was deleted." }) }) : null
|
|
6226
|
+
] }) : preview ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(VaultSection, { children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Empty, { children: refusalText(preview.reason) }) }) : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(VaultSection, { children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Empty, { children: "It comes back turned off: sharing, browser fill, codes and sandbox use stay off." }) }),
|
|
6254
6227
|
error ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("p", { role: "alert", className: "px-1 text-sm text-destructive", children: error }) : null
|
|
6255
6228
|
]
|
|
6256
6229
|
}
|
|
@@ -6282,13 +6255,13 @@ function TrashView({ port, deleted, query, header, onChanged }) {
|
|
|
6282
6255
|
};
|
|
6283
6256
|
return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex min-h-0 flex-1 flex-col gap-3 overflow-y-auto p-3", children: [
|
|
6284
6257
|
header,
|
|
6285
|
-
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6258
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(VaultSection, { title: "Trash", children: shown.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Empty, { children: deleted.length === 0 ? "The trash is empty." : "Nothing matches." }) : shown.map((item) => (
|
|
6286
6259
|
// A list row, not a field row: the name gets the whole width (on a phone a label column
|
|
6287
6260
|
// left "Vau…" for every row), the deletion date sits under it.
|
|
6288
6261
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex min-h-12 items-center gap-3 px-3 py-1.5 sm:px-4", children: [
|
|
6289
6262
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("span", { className: "flex min-w-0 flex-1 flex-col leading-tight", children: [
|
|
6290
6263
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "truncate text-sm text-foreground", children: item.name }),
|
|
6291
|
-
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "truncate text-xs text-muted-foreground", children: [item.deletion?.deletedAt ? `Deleted ${(0,
|
|
6264
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "truncate text-xs text-muted-foreground", children: [item.deletion?.deletedAt ? `Deleted ${(0, import_format9.formatAbsoluteDate)(item.deletion.deletedAt, DAY_FORMAT, "")}` : null, item.owner.kind !== "me" ? item.owner.label : null].filter(Boolean).join(" \xB7 ") })
|
|
6292
6265
|
] }),
|
|
6293
6266
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_controls24.Button, { variant: "outline", icon: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(RestoreGlyph, {}), disabled: busyId !== null || !item.deletion, onClick: () => setRestoring(item), children: "Restore" })
|
|
6294
6267
|
] }, item.id)
|
|
@@ -6302,6 +6275,7 @@ function TrashView({ port, deleted, query, header, onChanged }) {
|
|
|
6302
6275
|
var import_react31 = require("react");
|
|
6303
6276
|
var import_design_system20 = require("@ai-matrx/design-system");
|
|
6304
6277
|
var import_controls25 = require("@ai-matrx/design-system/controls");
|
|
6278
|
+
var import_icons12 = require("@ai-matrx/design-system/icons");
|
|
6305
6279
|
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
6306
6280
|
function NewItemFlow({ definitions, url, onUrl, onChoose, onCancel }) {
|
|
6307
6281
|
const [search, setSearch] = (0, import_react31.useState)("");
|
|
@@ -6336,7 +6310,7 @@ function NewItemFlow({ definitions, url, onUrl, onChoose, onCancel }) {
|
|
|
6336
6310
|
"aria-label": "Website address",
|
|
6337
6311
|
inputMode: "url",
|
|
6338
6312
|
autoFocus: true,
|
|
6339
|
-
icon: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6313
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_icons12.GlobeIcon, {})
|
|
6340
6314
|
}
|
|
6341
6315
|
),
|
|
6342
6316
|
guess && login ? /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-col gap-2 rounded-xl border border-border bg-card p-3", children: [
|
|
@@ -6375,10 +6349,10 @@ var import_react32 = require("react");
|
|
|
6375
6349
|
var import_confirm_opener10 = require("@ai-matrx/kit/confirm-opener");
|
|
6376
6350
|
var import_design_system21 = require("@ai-matrx/design-system");
|
|
6377
6351
|
var import_controls26 = require("@ai-matrx/design-system/controls");
|
|
6378
|
-
var
|
|
6352
|
+
var import_format11 = require("@ai-matrx/kit/format");
|
|
6379
6353
|
|
|
6380
6354
|
// src/sharing/secure-link-logic.ts
|
|
6381
|
-
var
|
|
6355
|
+
var import_format10 = require("@ai-matrx/kit/format");
|
|
6382
6356
|
var SECURE_RESOURCE_TYPE = "credential_item";
|
|
6383
6357
|
var NOTE_MAX = 1e3;
|
|
6384
6358
|
var CHANNEL_WORD = { email: "email", sms: "text" };
|
|
@@ -6416,7 +6390,7 @@ function carriedWords(keys, fields) {
|
|
|
6416
6390
|
const known = new Map(fields.map((f) => [f.key, f.label]));
|
|
6417
6391
|
return keys.map((k) => known.get(k) ?? fieldNames([k])).join(", ");
|
|
6418
6392
|
}
|
|
6419
|
-
var lifetimeWords = (minutes) => (0,
|
|
6393
|
+
var lifetimeWords = (minutes) => (0, import_format10.formatDurationMinutes)(minutes, { style: "long" });
|
|
6420
6394
|
function remedyOf(e) {
|
|
6421
6395
|
const body = e?.serverDetail;
|
|
6422
6396
|
if (!body || typeof body !== "object") return null;
|
|
@@ -6586,9 +6560,9 @@ function SecureLinkPanel({ item, port, onClose }) {
|
|
|
6586
6560
|
] }),
|
|
6587
6561
|
children: [
|
|
6588
6562
|
remedy ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("p", { className: "px-1 text-xs text-muted-foreground", children: remedy }) : null,
|
|
6589
|
-
/* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
|
|
6590
|
-
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
6591
|
-
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
6563
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(VaultSection, { title: "Recipient", children: [
|
|
6564
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(VaultRow, { label: "Email", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_controls26.Field, { type: "email", autoComplete: "off", placeholder: "name@example.com", "aria-label": "Their email", value: email, onChange: (e) => setEmail(e.target.value), className: "w-full" }) }),
|
|
6565
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(VaultRow, { label: "Mobile", hint: "For the code", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
6592
6566
|
import_controls26.Field,
|
|
6593
6567
|
{
|
|
6594
6568
|
type: "tel",
|
|
@@ -6604,8 +6578,8 @@ function SecureLinkPanel({ item, port, onClose }) {
|
|
|
6604
6578
|
className: "w-full"
|
|
6605
6579
|
}
|
|
6606
6580
|
) }),
|
|
6607
|
-
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
6608
|
-
plan && !plan.same ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
6581
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(VaultRow, { label: "Name", hint: "Optional", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_controls26.Field, { autoComplete: "off", placeholder: "Their name", "aria-label": "Their name", value: name, onChange: (e) => setName(e.target.value), className: "w-full" }) }),
|
|
6582
|
+
plan && !plan.same ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(VaultRow, { label: "Link by", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
6609
6583
|
import_controls26.SegmentedControl,
|
|
6610
6584
|
{
|
|
6611
6585
|
"aria-label": "Send the link by",
|
|
@@ -6617,26 +6591,26 @@ function SecureLinkPanel({ item, port, onClose }) {
|
|
|
6617
6591
|
]
|
|
6618
6592
|
}
|
|
6619
6593
|
) }) : null,
|
|
6620
|
-
email.trim() ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
6594
|
+
email.trim() ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(VaultRow, { label: "Delivery", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: plan?.same ? "text-warning" : "text-foreground", children: planWords(plan) }) }) : null
|
|
6621
6595
|
] }),
|
|
6622
|
-
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
6596
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(VaultSection, { title: "Include", children: optionsError ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Empty, { children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "text-destructive", children: optionsError }) }) : !options ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_controls26.RegionSkeleton, { shape: "rows", count: 2, "aria-label": "Loading what can be sent", className: "px-3 sm:px-4" }) : options.fields.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Empty, { children: "Name and details only" }) : options.fields.map((f) => /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("label", { className: "flex min-h-11 items-center gap-3 px-3 py-1 sm:px-4", "data-clickable": f.available ? "" : void 0, children: [
|
|
6623
6597
|
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_design_system21.Checkbox, { checked: fields.includes(f.key), disabled: !f.available, onCheckedChange: (v) => toggle2(f.key, v === true), "aria-label": f.label }),
|
|
6624
6598
|
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "min-w-0 flex-1 truncate text-sm text-foreground", children: f.label }),
|
|
6625
6599
|
!f.available && f.reason ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "min-w-0 max-w-[55%] truncate text-xs text-muted-foreground", title: f.reason, children: f.reason }) : null
|
|
6626
6600
|
] }, f.key)) }),
|
|
6627
|
-
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
6628
|
-
options ? /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
|
|
6629
|
-
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
6630
|
-
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
6601
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(VaultSection, { title: "Message", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "px-3 py-1 sm:px-4", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_controls26.Textarea, { className: "w-full", rows: 2, maxLength: NOTE_MAX, placeholder: "Shown once, with it", "aria-label": "Message", value: note, onChange: (e) => setNote(e.target.value) }) }) }),
|
|
6602
|
+
options ? /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(VaultSection, { title: "Link", children: [
|
|
6603
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(VaultRow, { label: "Opens", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "text-foreground", children: "Once" }) }),
|
|
6604
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(VaultRow, { label: "Link expires", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("span", { className: "text-foreground", children: [
|
|
6631
6605
|
"After ",
|
|
6632
6606
|
lifetimeWords(options.linkMinutes)
|
|
6633
6607
|
] }) }),
|
|
6634
|
-
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
6608
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(VaultRow, { label: "Code expires", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("span", { className: "text-foreground", children: [
|
|
6635
6609
|
"After ",
|
|
6636
6610
|
lifetimeWords(options.codeMinutes)
|
|
6637
6611
|
] }) })
|
|
6638
6612
|
] }) : null,
|
|
6639
|
-
sharing.sentSecureLinks ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
6613
|
+
sharing.sentSecureLinks ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(VaultSection, { title: "Sent links", children: sentError ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Empty, { children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "text-destructive", children: sentError }) }) : !sent ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_controls26.RegionSkeleton, { shape: "rows", count: 2, "aria-label": "Loading sent links", className: "px-3 sm:px-4" }) : sent.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Empty, { children: "None yet" }) : sent.map((row) => /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(AccessLine, { glyph: row.status === "pending" ? ClockGlyph : row.fieldKeys.length ? LockGlyph : ShareGlyph, who: recipientOf(row), meta: sentMeta(row, options), children: [
|
|
6640
6614
|
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_controls26.Badge, { tone: STATUS_TONE[row.status] ?? "neutral", children: statusWord(row.status) }),
|
|
6641
6615
|
row.status === "pending" ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_controls26.Button, { variant: "quiet", disabled: busy !== null, onClick: () => void turnOff(row), children: "Turn off" }) : null
|
|
6642
6616
|
] }, row.id)) }) : null
|
|
@@ -6645,7 +6619,7 @@ function SecureLinkPanel({ item, port, onClose }) {
|
|
|
6645
6619
|
);
|
|
6646
6620
|
}
|
|
6647
6621
|
function sentMeta(row, options) {
|
|
6648
|
-
const when = row.status === "pending" ? `Until ${(0,
|
|
6622
|
+
const when = row.status === "pending" ? `Until ${(0, import_format11.formatAbsoluteDate)(row.expiresAt, void 0, "")}` : row.status === "viewed" && row.viewedAt ? (0, import_format11.formatAbsoluteDate)(row.viewedAt, void 0, "") : (0, import_format11.formatAbsoluteDate)(row.createdAt, DAY_FORMAT, "");
|
|
6649
6623
|
const carried = row.fieldKeys.length ? carriedWords(row.fieldKeys, options?.fields ?? []) : "";
|
|
6650
6624
|
return [when, carried].filter(Boolean).join(" \xB7 ");
|
|
6651
6625
|
}
|
|
@@ -6654,7 +6628,7 @@ function sentMeta(row, options) {
|
|
|
6654
6628
|
var import_react33 = require("react");
|
|
6655
6629
|
var import_confirm_opener11 = require("@ai-matrx/kit/confirm-opener");
|
|
6656
6630
|
var import_controls27 = require("@ai-matrx/design-system/controls");
|
|
6657
|
-
var
|
|
6631
|
+
var import_format12 = require("@ai-matrx/kit/format");
|
|
6658
6632
|
|
|
6659
6633
|
// src/devices/logic.ts
|
|
6660
6634
|
var PASSKEY_RP_ID = "aimatrx.com";
|
|
@@ -6778,19 +6752,19 @@ function DevicesPanel({ port, onClose }) {
|
|
|
6778
6752
|
};
|
|
6779
6753
|
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(Panel, { title: "Browsers that can fill", onClose, size: "md", children: [
|
|
6780
6754
|
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(ErrorLine2, { text: error }),
|
|
6781
|
-
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6755
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(VaultSection, { children: devices === null ? error ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Empty, { children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_controls27.Button, { variant: "outline", onClick: () => void load(), children: "Try again" }) }) : /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_controls27.RegionSkeleton, { shape: "rows", count: 2, "aria-label": "Loading your browsers", className: "px-3 sm:px-4" }) : devices.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Empty, { children: "No browser can fill yet. Turn it on in the extension." }) : devices.map((device) => {
|
|
6782
6756
|
const off = isRevoked(device);
|
|
6783
6757
|
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6784
|
-
|
|
6758
|
+
VaultRow,
|
|
6785
6759
|
{
|
|
6786
6760
|
label: off ? "Turned off" : "Can fill",
|
|
6787
|
-
hint: off ? (0,
|
|
6761
|
+
hint: off ? (0, import_format12.formatAbsoluteDate)(device.revokedAt, DAY_FORMAT, "") : void 0,
|
|
6788
6762
|
actions: off ? null : /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_controls27.Button, { variant: "outline", icon: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(PowerGlyph, {}), disabled: busyId !== null, onClick: () => void revoke(device), children: "Revoke" }),
|
|
6789
6763
|
children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("span", { className: "flex min-w-0 flex-col", children: [
|
|
6790
6764
|
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: off ? "truncate text-muted-foreground" : "truncate text-foreground", children: device.label }),
|
|
6791
6765
|
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("span", { className: "truncate text-xs text-muted-foreground", children: [
|
|
6792
|
-
device.lastUsedAt ? `Last used ${(0,
|
|
6793
|
-
device.addedAt ? ` \xB7 added ${(0,
|
|
6766
|
+
device.lastUsedAt ? `Last used ${(0, import_format12.formatAbsoluteDate)(device.lastUsedAt, void 0, "")}` : "Never used",
|
|
6767
|
+
device.addedAt ? ` \xB7 added ${(0, import_format12.formatAbsoluteDate)(device.addedAt, DAY_FORMAT, "")}` : ""
|
|
6794
6768
|
] })
|
|
6795
6769
|
] })
|
|
6796
6770
|
},
|
|
@@ -6869,29 +6843,29 @@ function ApprovePanel({ port, host, onClose, approvalKey, label, kind = "browser
|
|
|
6869
6843
|
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_controls27.Button, { variant: "quiet", disabled: busy !== null, onClick: refuse, children: key ? "Refuse" : "Close" }),
|
|
6870
6844
|
canApprove ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_controls27.Button, { variant: "primary", icon: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(FingerprintGlyph, {}), disabled: busy !== null, onClick: () => void approve(), children: busy === "approve" ? "Approving\u2026" : "Approve with passkey" }) : null
|
|
6871
6845
|
] });
|
|
6872
|
-
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Panel, { title, onClose: refuse, size: "sm", footer, children: !key ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6846
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Panel, { title, onClose: refuse, size: "sm", footer, children: !key ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(VaultSection, { children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(Empty, { children: [
|
|
6873
6847
|
"This link names no key. Start again from ",
|
|
6874
6848
|
where,
|
|
6875
6849
|
"."
|
|
6876
6850
|
] }) }) : /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment, { children: [
|
|
6877
|
-
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
6878
|
-
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6879
|
-
name ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6880
|
-
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6851
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(VaultSection, { title: "What is asking", children: [
|
|
6852
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(VaultRow, { label: "Asking", hint: "Approve only if you just asked", children: asker }),
|
|
6853
|
+
name ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(VaultRow, { label: "Name", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "block truncate", children: name }) }) : null,
|
|
6854
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(VaultRow, { label: "Code", hint: `Must match ${where}`, children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "font-mono tracking-wider text-foreground", children: shortFingerprint(key) }) })
|
|
6881
6855
|
] }),
|
|
6882
6856
|
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(ErrorLine2, { text: error }),
|
|
6883
|
-
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6857
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(VaultSection, { title: "Confirm it\u2019s you", children: approvedUntil ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(VaultRow, { label: "Approved", actions: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(CheckGlyph, { className: "size-4 text-primary" }), children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("span", { className: "text-foreground", children: [
|
|
6884
6858
|
"Return to ",
|
|
6885
6859
|
where,
|
|
6886
6860
|
" by ",
|
|
6887
|
-
(0,
|
|
6861
|
+
(0, import_format12.formatAbsoluteDate)(approvedUntil, void 0, ""),
|
|
6888
6862
|
"."
|
|
6889
6863
|
] }) }) : !passkeys ? /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(Empty, { children: [
|
|
6890
6864
|
"Approve with your password in ",
|
|
6891
6865
|
where,
|
|
6892
6866
|
"."
|
|
6893
6867
|
] }) : !here ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6894
|
-
|
|
6868
|
+
VaultRow,
|
|
6895
6869
|
{
|
|
6896
6870
|
label: "Passkey",
|
|
6897
6871
|
hint: `Passkeys work only on ${passkeys.rpId}`,
|
|
@@ -6899,14 +6873,14 @@ function ApprovePanel({ port, host, onClose, approvalKey, label, kind = "browser
|
|
|
6899
6873
|
children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "text-muted-foreground", children: "Not on this page" })
|
|
6900
6874
|
}
|
|
6901
6875
|
) : methods === null ? error ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Empty, { children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_controls27.Button, { variant: "outline", onClick: () => void load(), children: "Try again" }) }) : /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_controls27.RegionSkeleton, { shape: "rows", count: 1, "aria-label": "Checking your account", className: "px-3 sm:px-4" }) : !methods.passkey ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6902
|
-
|
|
6876
|
+
VaultRow,
|
|
6903
6877
|
{
|
|
6904
6878
|
label: "Passkey",
|
|
6905
6879
|
hint: methods.password ? `Or type your password in ${where}` : "Add one to approve",
|
|
6906
6880
|
actions: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_controls27.Button, { variant: "primary", icon: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(FingerprintGlyph, {}), disabled: busy !== null, onClick: () => void addPasskey(), children: busy === "add" ? "Adding\u2026" : "Add passkey" }),
|
|
6907
6881
|
children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "text-muted-foreground", children: methods.password ? "None yet" : "No password or passkey" })
|
|
6908
6882
|
}
|
|
6909
|
-
) : /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6883
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(VaultRow, { label: "Passkey", hint: "Your device asks for it next", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "text-foreground", children: "Ready" }) }) })
|
|
6910
6884
|
] }) });
|
|
6911
6885
|
}
|
|
6912
6886
|
|
|
@@ -7184,7 +7158,7 @@ var TONE = {
|
|
|
7184
7158
|
};
|
|
7185
7159
|
function NativeImportPanel({ bridge, readLimits, activeOrganizationId, organizations, onClose, onChanged }) {
|
|
7186
7160
|
if (!bridge) {
|
|
7187
|
-
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Panel, { title: "Import passkeys", size: "md", onClose, footer: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_controls28.Button, { variant: "primary", onClick: onClose, children: "Close" }), children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
7161
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Panel, { title: "Import passkeys", size: "md", onClose, footer: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_controls28.Button, { variant: "primary", onClick: onClose, children: "Close" }), children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(VaultSection, { children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Empty, { children: "Passkey import needs the desktop app." }) }) });
|
|
7188
7162
|
}
|
|
7189
7163
|
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Importer, { bridge, readLimits, activeOrganizationId, organizations, onClose, onChanged });
|
|
7190
7164
|
}
|
|
@@ -7231,25 +7205,25 @@ function Importer({ bridge, readLimits, activeOrganizationId, organizations, onC
|
|
|
7231
7205
|
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_controls28.Button, { variant: "primary", onClick: onClose, children: "Done" })
|
|
7232
7206
|
] }) : /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_controls28.Button, { variant: "quiet", onClick: onClose, children: "Close" });
|
|
7233
7207
|
return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(Panel, { title: "Import passkeys", size: "lg", onClose, footer, children: [
|
|
7234
|
-
screen.kind === "idle" ? /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
|
|
7235
|
-
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
7236
|
-
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
7237
|
-
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
7208
|
+
screen.kind === "idle" ? /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(VaultSection, { children: [
|
|
7209
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(VaultRow, { label: "Save to", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_controls28.Select, { value: organizationId, options, "aria-label": "Save to", disabled: busy, onValueChange: setOrganizationId }) }),
|
|
7210
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(VaultRow, { label: "File", hint: limits ? `Up to ${plural2(limits.maxItems, "passkey")}` : "A passkey exchange file", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_controls28.Button, { variant: "outline", icon: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ImportGlyph, { className: "size-4" }), disabled: busy || !organizationId || limitError !== null, onClick: () => void flow.begin(organizationId), children: busy ? "Opening\u2026" : "Choose file" }) }),
|
|
7211
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(VaultRow, { label: "Interrupted", hint: "Finish or clear an earlier import", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_controls28.Button, { variant: "quiet", disabled: busy, onClick: () => void flow.recover(), children: "Recover" }) })
|
|
7238
7212
|
] }) : null,
|
|
7239
|
-
preview ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
7213
|
+
preview ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(VaultSection, { title: `${ready} of ${preview.total} ready`, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
7240
7214
|
Windowed,
|
|
7241
7215
|
{
|
|
7242
7216
|
items: preview.slots,
|
|
7243
|
-
render: (slot) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
7217
|
+
render: (slot) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(VaultRow, { label: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_controls28.Badge, { tone: TONE[slot.disposition], children: dispositionLabel(slot.disposition) }), hint: void 0, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "block truncate text-foreground", title: slot.reason ?? void 0, children: slot.title ?? "Unnamed passkey" }) }, slot.slot_id)
|
|
7244
7218
|
}
|
|
7245
7219
|
) }) : null,
|
|
7246
|
-
status && !preview ? /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
|
|
7247
|
-
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
7248
|
-
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
7249
|
-
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
7250
|
-
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
7251
|
-
status.uncertain > 0 ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
7252
|
-
status.not_attempted > 0 ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
7220
|
+
status && !preview ? /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(VaultSection, { title: `${accounted(status)} of ${status.total} done`, children: [
|
|
7221
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(VaultRow, { label: "Imported", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "text-foreground", children: status.committed }) }),
|
|
7222
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(VaultRow, { label: "Already there", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "text-foreground", children: status.already_present }) }),
|
|
7223
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(VaultRow, { label: "Can't import", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "text-foreground", children: status.unsupported }) }),
|
|
7224
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(VaultRow, { label: "Failed", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: status.failed > 0 ? "text-destructive" : "text-foreground", children: status.failed }) }),
|
|
7225
|
+
status.uncertain > 0 ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(VaultRow, { label: "Needs recovery", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "text-foreground", children: status.uncertain }) }) : null,
|
|
7226
|
+
status.not_attempted > 0 ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(VaultRow, { label: "Not tried", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "text-foreground", children: status.not_attempted }) }) : null
|
|
7253
7227
|
] }) : null,
|
|
7254
7228
|
screen.message ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("p", { role: "status", className: "px-1 text-sm text-muted-foreground", children: screen.message }) : null,
|
|
7255
7229
|
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ErrorLine, { message: limitError })
|
|
@@ -7260,6 +7234,7 @@ function Importer({ bridge, readLimits, activeOrganizationId, organizations, onC
|
|
|
7260
7234
|
var import_react39 = require("react");
|
|
7261
7235
|
var import_design_system23 = require("@ai-matrx/design-system");
|
|
7262
7236
|
var import_controls32 = require("@ai-matrx/design-system/controls");
|
|
7237
|
+
var import_icons14 = require("@ai-matrx/design-system/icons");
|
|
7263
7238
|
|
|
7264
7239
|
// src/extension/CaptureCard.tsx
|
|
7265
7240
|
var import_react36 = require("react");
|
|
@@ -7402,6 +7377,7 @@ function FillSetupCard({ fillSetup }) {
|
|
|
7402
7377
|
var import_react38 = require("react");
|
|
7403
7378
|
var import_design_system22 = require("@ai-matrx/design-system");
|
|
7404
7379
|
var import_controls31 = require("@ai-matrx/design-system/controls");
|
|
7380
|
+
var import_icons13 = require("@ai-matrx/design-system/icons");
|
|
7405
7381
|
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
7406
7382
|
var HOLD_MS = 6e4;
|
|
7407
7383
|
function PageGenerator({ fields }) {
|
|
@@ -7455,11 +7431,11 @@ function PageGenerator({ fields }) {
|
|
|
7455
7431
|
const value = held.value;
|
|
7456
7432
|
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
|
|
7457
7433
|
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
7458
|
-
|
|
7434
|
+
VaultRow,
|
|
7459
7435
|
{
|
|
7460
7436
|
label: "New password",
|
|
7461
7437
|
actions: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
|
|
7462
|
-
value ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_controls31.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
7438
|
+
value ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_controls31.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_icons13.CopyIcon, {}), "aria-label": "Copy password", onClick: () => void copy(value, "Password") }) : null,
|
|
7463
7439
|
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_design_system22.Popover, { open, onOpenChange: setOpen, children: [
|
|
7464
7440
|
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_design_system22.PopoverTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_controls31.Button, { variant: "outline", icon: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(KeyGlyph, {}), disabled: busy, children: "Generate" }) }),
|
|
7465
7441
|
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_design_system22.PopoverContent, { sizing: "content", align: "end", children: open ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(PasswordGenerator, { limits, useLabel: "Fill page", onUse: (v) => void onUse(v) }) : null })
|
|
@@ -7468,7 +7444,7 @@ function PageGenerator({ fields }) {
|
|
|
7468
7444
|
children: said ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { role: "status", className: said.tone === "success" ? "line-clamp-2 text-xs text-foreground" : "line-clamp-2 text-xs text-muted-foreground", children: said.text }) : targets.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "text-xs text-muted-foreground", children: "Choose the boxes to fill." }) : /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "text-xs text-disabled-foreground", children: "Fills the page\u2019s new-password box" })
|
|
7469
7445
|
}
|
|
7470
7446
|
),
|
|
7471
|
-
value && targets.length > 0 ? targets.map((t) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
7447
|
+
value && targets.length > 0 ? targets.map((t) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(VaultRow, { label: t.topFrame ? "This page" : "In a frame", actions: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_controls31.Button, { variant: "primary", icon: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(CheckGlyph, {}), disabled: busy, onClick: () => void put(t.id, value), children: "Fill" }), children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "block truncate text-sm", children: targetLabel(t) }) }, t.id)) : null
|
|
7472
7448
|
] });
|
|
7473
7449
|
}
|
|
7474
7450
|
|
|
@@ -7530,7 +7506,7 @@ function PageView({ port, page, fill, capture, fillSetup, newPasswordFields, ite
|
|
|
7530
7506
|
return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "flex h-full min-h-0 flex-col overflow-y-auto bg-background text-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "flex flex-col gap-3 px-3 pb-4 pt-3", children: [
|
|
7531
7507
|
header,
|
|
7532
7508
|
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "flex min-h-7 items-center gap-2 px-1", children: [
|
|
7533
|
-
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_design_system23.SiteIcon, { site: page.url, fallback:
|
|
7509
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_design_system23.SiteIcon, { site: page.url, fallback: import_icons14.GlobeIcon, className: "size-4" }),
|
|
7534
7510
|
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "min-w-0 flex-1 truncate text-sm font-medium", title: page.url, children: site || "No page open" }),
|
|
7535
7511
|
page.refresh ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_controls32.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(RefreshGlyph, {}), "aria-label": "Check again", onClick: page.refresh }) : null,
|
|
7536
7512
|
onBrowse ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_controls32.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(ListGlyph, {}), onClick: onBrowse, children: "All items" }) : null
|
|
@@ -7538,7 +7514,7 @@ function PageView({ port, page, fill, capture, fillSetup, newPasswordFields, ite
|
|
|
7538
7514
|
fillSetup ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(FillSetupCard, { fillSetup }) : null,
|
|
7539
7515
|
capture ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(CaptureCard, { capture, onChanged }) : null,
|
|
7540
7516
|
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
7541
|
-
|
|
7517
|
+
VaultSection,
|
|
7542
7518
|
{
|
|
7543
7519
|
title: "This site",
|
|
7544
7520
|
actions: canSave ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_controls32.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(PlusGlyph, {}), onClick: () => onNewForPage(normalizeLoginUrl2(page.url) ?? page.url), children: "Save a login" }) : null,
|
|
@@ -7546,7 +7522,7 @@ function PageView({ port, page, fill, capture, fillSetup, newPasswordFields, ite
|
|
|
7546
7522
|
}
|
|
7547
7523
|
),
|
|
7548
7524
|
said ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(Outcome, { said, onDismiss: () => setSaid(null) }) : page.blocked && page.url && state.status === "ready" ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("p", { className: "px-1 text-xs text-muted-foreground", children: BLOCK_WORDS[page.blocked] }) : null,
|
|
7549
|
-
newPasswordFields && canSave ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
7525
|
+
newPasswordFields && canSave ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(VaultSection, { children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(PageGenerator, { fields: newPasswordFields }) }) : null
|
|
7550
7526
|
] }) });
|
|
7551
7527
|
}
|
|
7552
7528
|
function Outcome({ said, onDismiss }) {
|
|
@@ -7608,6 +7584,7 @@ function MatchRow({ itemId, item, tag, family, port, busy, running, onOpen, onFi
|
|
|
7608
7584
|
var import_react40 = require("react");
|
|
7609
7585
|
var import_design_system24 = require("@ai-matrx/design-system");
|
|
7610
7586
|
var import_controls33 = require("@ai-matrx/design-system/controls");
|
|
7587
|
+
var import_icons15 = require("@ai-matrx/design-system/icons");
|
|
7611
7588
|
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
7612
7589
|
function vaultChoices(items, organizations, current) {
|
|
7613
7590
|
const n = (f) => items.filter(f).length;
|
|
@@ -7623,7 +7600,7 @@ function vaultChoices(items, organizations, current) {
|
|
|
7623
7600
|
function VaultSelect({ value, choices, onChange }) {
|
|
7624
7601
|
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_controls33.Select, { value, onValueChange: onChange, "aria-label": "Vault", options: choices.map((c) => ({ value: c.value, label: c.label, meta: String(c.count) })) });
|
|
7625
7602
|
}
|
|
7626
|
-
var CATEGORY_GLYPHS = { logins:
|
|
7603
|
+
var CATEGORY_GLYPHS = { logins: import_icons15.GlobeIcon, passkeys: ShieldGlyph, api: KeyGlyph, oauth: PlugGlyph, infra: DatabaseGlyph, env: TerminalGlyph, files: FileGlyph, other: NoteGlyph };
|
|
7627
7604
|
var familyOf = (key, definitions) => definitions.find((d) => d.key === key)?.family ?? "generic";
|
|
7628
7605
|
function itemCategory(item, definitions) {
|
|
7629
7606
|
return categoryOf(item.definitionKey, familyOf(item.definitionKey, definitions));
|
|
@@ -7688,7 +7665,7 @@ function Group({ title, children }) {
|
|
|
7688
7665
|
children
|
|
7689
7666
|
] });
|
|
7690
7667
|
}
|
|
7691
|
-
function
|
|
7668
|
+
function VaultSidebar({ vault, choices, onVault, view, allCount, deletedCount, views, hasFavorites, hasRecents, onView, onPanel, nativeProvider, hasNativeImport = false, hasPage = false }) {
|
|
7692
7669
|
const [tagsOpen, setTagsOpen] = (0, import_react40.useState)(view.startsWith("tag:"));
|
|
7693
7670
|
return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("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: [
|
|
7694
7671
|
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "flex items-center gap-2 px-3 pb-2 pt-3", children: [
|
|
@@ -7697,7 +7674,7 @@ function Sidebar({ vault, choices, onVault, view, allCount, deletedCount, views,
|
|
|
7697
7674
|
] }),
|
|
7698
7675
|
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "flex min-h-0 flex-1 flex-col gap-5 overflow-y-auto px-2 pb-3 pt-1", children: [
|
|
7699
7676
|
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "flex flex-col gap-0.5", children: [
|
|
7700
|
-
hasPage ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Entry, { on: view === "page", glyph:
|
|
7677
|
+
hasPage ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Entry, { on: view === "page", glyph: import_icons15.GlobeIcon, label: "This page", onClick: () => onView("page") }) : null,
|
|
7701
7678
|
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Entry, { on: view === "all", glyph: GridGlyph, label: "All items", count: allCount, onClick: () => onView("all") }),
|
|
7702
7679
|
hasFavorites ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Entry, { on: view === "favorites", glyph: StarGlyph, label: "Favorites", count: views.favorites, onClick: () => onView("favorites") }) : null,
|
|
7703
7680
|
hasRecents ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Entry, { on: view === "recent", glyph: ClockGlyph, label: "Recently opened", count: views.recent, onClick: () => onView("recent") }) : null,
|
|
@@ -7737,7 +7714,7 @@ var NO_HOST = {};
|
|
|
7737
7714
|
var ITEM_PANELS = {
|
|
7738
7715
|
share: SharePanel,
|
|
7739
7716
|
move: MovePanel,
|
|
7740
|
-
history:
|
|
7717
|
+
history: ItemHistoryPanel,
|
|
7741
7718
|
activity: ActivityPanel,
|
|
7742
7719
|
settings: ItemSettingsPanel,
|
|
7743
7720
|
field: FieldSettingsPanel,
|
|
@@ -8128,7 +8105,7 @@ function Workspace({ port, host = NO_HOST, layout = "auto", location, onLocation
|
|
|
8128
8105
|
] }) : null,
|
|
8129
8106
|
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: `grid min-h-0 w-full flex-1 ${grid} overflow-hidden`, children: [
|
|
8130
8107
|
mode === "full" ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
8131
|
-
|
|
8108
|
+
VaultSidebar,
|
|
8132
8109
|
{
|
|
8133
8110
|
vault: loc.vault,
|
|
8134
8111
|
choices,
|