@ai-matrx/vault 0.1.21 → 0.1.23
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 +19 -2
- package/dist/index.cjs +207 -76
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +38 -2
- package/dist/index.d.ts +38 -2
- package/dist/index.js +207 -76
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,9 +1,26 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.23
|
|
4
|
+
|
|
5
|
+
- **The Vault and Show pickers read in full at every compact width (640-1119px).** They no longer share a row with the Authenticator and More buttons (which squeezed each to ~90px: "All ite…", long vault names cut): the pickers take the whole row (each at least 11rem; one above the other in the 19rem split column, side by side once there is room), and the Authenticator and More buttons moved onto the search row beside the + (`ItemList` `actions`; Trash, Authenticator and the extension's page view carry them on their own search row). Nothing removed, every button one press away as before. Guard: `src/parity-review-0-1-22.test.tsx` § 2. Consumer action: none.
|
|
6
|
+
|
|
7
|
+
## 0.1.22
|
|
8
|
+
|
|
9
|
+
- **A member's credential shared into an organization is the organization's, never "Personal".** An item in an organization's list is the viewer's own only when the viewer owns it (`platform.list_my_organizations` `user_id`, else the owner of the person's own list); a member's own credential shared into the organization is attributed to that organization (`VaultOwner.memberShared`), counted there, its badge says "A member's own credential, shared into <org>", and Share / Delete show disabled with the reason (`manageUnavailableReason`, `ownerDetail`); Copy stays offered to an editor. Consumer action: none.
|
|
10
|
+
- **The person's own items show first.** `VaultPort.load(onProgress?)` hands partial snapshots (`VaultSnapshot.pending`): the own list and the type catalog open the vault, each organization's list streams in as it answers; the list's count line says "loading <org>…" (no layout jump). A Refresh still applies only the finished read. Consumer action: none (a host with its own `VaultPort` may ignore `onProgress`).
|
|
11
|
+
- **The compact Vault and Show pickers keep a real width** (6rem minimum) at split widths (640–1119px): the Authenticator button beside them is icon-only (its name in the tooltip). Consumer action: none.
|
|
12
|
+
- **The star is on every list row** — the row's hover quick actions and its More / right-click menu (`ItemList` `favorites`, `onToggleFavorite`). Consumer action: none.
|
|
13
|
+
- **Every organization stays in the vault switcher**, empty ones too (count 0); an empty organization opens on "Nothing here yet" with New item saving there. Consumer action: none.
|
|
14
|
+
- **A host's own right-click menu reads the row's entries**: `rowMenuEntriesAt(target)` returns the clicked row's entries (`RowMenuEntry.kind` `copy` / `favorite` / `open` / `copy-name` / `host`) — the same list the row's own menu renders. **Consumer action:** web app (`rowContextMenu: "host"`): add the `copy` and `favorite` entries of `rowMenuEntriesAt(target)` to its v3 menu. Extension and desktop: none.
|
|
15
|
+
|
|
3
16
|
## 0.1.21
|
|
4
17
|
|
|
5
|
-
|
|
6
|
-
|
|
18
|
+
SOURCE CHANGED WITH NO RELEASE NOTE. This release shipped source changes that nobody described in an Unreleased entry,
|
|
19
|
+
so they may include breaking API changes. Consumer action is UNKNOWN: read the diff before upgrading.
|
|
20
|
+
Diff: `git diff 8efbb129f3 4abc64ee28 -- apps/shared/vault/src`
|
|
21
|
+
|
|
22
|
+
Changed shipped source files (1):
|
|
23
|
+
- `apps/shared/vault/src/FieldRows.tsx`
|
|
7
24
|
|
|
8
25
|
## 0.1.20
|
|
9
26
|
|
package/dist/index.cjs
CHANGED
|
@@ -160,6 +160,7 @@ __export(src_exports, {
|
|
|
160
160
|
needsRecentSignIn: () => needsRecentSignIn,
|
|
161
161
|
parseDefinitions: () => parseDefinitions,
|
|
162
162
|
providerOf: () => providerOf,
|
|
163
|
+
rowMenuEntriesAt: () => rowMenuEntriesAt,
|
|
163
164
|
siteDomainOf: () => siteDomainOf,
|
|
164
165
|
sortItems: () => sortItems,
|
|
165
166
|
useConfirmed: () => useConfirmed,
|
|
@@ -918,6 +919,19 @@ var import_format3 = require("@ai-matrx/kit/format");
|
|
|
918
919
|
var import_format = require("@ai-matrx/kit/format");
|
|
919
920
|
|
|
920
921
|
// src/model.ts
|
|
922
|
+
function manageUnavailableReason(item) {
|
|
923
|
+
if (item.capabilities.canManage) return null;
|
|
924
|
+
if (item.owner.memberShared) return "Only the member who owns it can share, move or delete it";
|
|
925
|
+
if (item.owner.kind === "shared") return "Only its owner can share, move or delete it";
|
|
926
|
+
if (item.owner.kind === "organization") return "Only this organization's vault admins can change that";
|
|
927
|
+
return "You can use this item but not share, move or delete it";
|
|
928
|
+
}
|
|
929
|
+
function ownerDetail(owner) {
|
|
930
|
+
if (owner.memberShared) return `A member's own credential, shared into ${owner.label}`;
|
|
931
|
+
if (owner.kind === "organization") return `Organization: ${owner.label}`;
|
|
932
|
+
if (owner.kind === "shared") return "Shared with you by its owner";
|
|
933
|
+
return "Your own vault";
|
|
934
|
+
}
|
|
921
935
|
var DEFAULT_LOCATION = { vault: "all", view: "all", q: "", sort: "name", itemId: null, mode: "view", kind: null, url: "", panel: null };
|
|
922
936
|
var SORTS = ["name", "name-desc", "website", "updated", "created", "viewed"];
|
|
923
937
|
function locationFromParams(params, itemId = params.get("item")) {
|
|
@@ -6057,6 +6071,7 @@ function ItemPane(props) {
|
|
|
6057
6071
|
const setValue = (key, v) => setDraft((d) => ({ ...d, values: { ...d.values, [key]: v } }));
|
|
6058
6072
|
const canEdit = item ? item.capabilities.canEdit || item.capabilities.canManage : true;
|
|
6059
6073
|
const canManage = item?.capabilities.canManage ?? false;
|
|
6074
|
+
const manageReason = item ? manageUnavailableReason(item) : null;
|
|
6060
6075
|
async function save() {
|
|
6061
6076
|
if (!definition && !item) return;
|
|
6062
6077
|
setBusy(true);
|
|
@@ -6203,7 +6218,8 @@ function ItemPane(props) {
|
|
|
6203
6218
|
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("h2", { className: "truncate text-base font-semibold leading-tight", children: editing ? draft.name || (mode === "new" ? `New ${typeLabel.toLowerCase()}` : item?.name) : item?.name }),
|
|
6204
6219
|
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("span", { className: "flex min-w-0 items-center gap-1 text-xs text-muted-foreground", children: [
|
|
6205
6220
|
typeLabel ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "truncate", children: typeLabel }) : null,
|
|
6206
|
-
shownOwner ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_controls22.Badge, { className: "shrink-0", icon: shownOwner.glyph, "aria-label": `Saved in ${shownOwner.label}`, children: shownOwner.label }) : null,
|
|
6221
|
+
shownOwner ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_controls22.Badge, { className: "shrink-0", icon: shownOwner.glyph, "aria-label": `Saved in ${shownOwner.label}`, title: item && mode !== "new" ? ownerDetail(item.owner) : void 0, children: shownOwner.label }) : null,
|
|
6222
|
+
item && mode !== "new" && item.owner.memberShared ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "shrink-0", "data-member-shared": "", children: "\xB7 A member\u2019s own" }) : null,
|
|
6207
6223
|
item && !editing ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(SharingSummary, { item, port, className: "hidden truncate before:mr-1 before:content-['\xB7'] sm:inline" }, `${item.updatedAt}-${refreshKey ?? ""}`) : null
|
|
6208
6224
|
] })
|
|
6209
6225
|
] }),
|
|
@@ -6241,9 +6257,9 @@ function ItemPane(props) {
|
|
|
6241
6257
|
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ShareGlyph, { className: "size-4" }),
|
|
6242
6258
|
"Share"
|
|
6243
6259
|
] }) : null,
|
|
6244
|
-
canManage ? /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_design_system17.DropdownMenuItem, { onSelect: () => onPanel("move"), children: [
|
|
6260
|
+
canManage || item.capabilities.canEdit ? /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_design_system17.DropdownMenuItem, { onSelect: () => onPanel("move"), children: [
|
|
6245
6261
|
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(MoveGlyph, { className: "size-4" }),
|
|
6246
|
-
"Move or copy"
|
|
6262
|
+
canManage ? "Move or copy" : "Copy to\u2026"
|
|
6247
6263
|
] }) : null,
|
|
6248
6264
|
item.capabilities.canReveal ? /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_design_system17.DropdownMenuItem, { onSelect: () => onPanel("send"), children: [
|
|
6249
6265
|
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(SendGlyph, { className: "size-4" }),
|
|
@@ -6267,6 +6283,17 @@ function ItemPane(props) {
|
|
|
6267
6283
|
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(TrashGlyph, { className: "size-4" }),
|
|
6268
6284
|
"Delete"
|
|
6269
6285
|
] })
|
|
6286
|
+
] }) : manageReason ? /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [
|
|
6287
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_design_system17.DropdownMenuSeparator, {}),
|
|
6288
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_design_system17.DropdownMenuItem, { disabled: true, children: [
|
|
6289
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ShareGlyph, { className: "size-4" }),
|
|
6290
|
+
"Share"
|
|
6291
|
+
] }),
|
|
6292
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_design_system17.DropdownMenuItem, { disabled: true, children: [
|
|
6293
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(TrashGlyph, { className: "size-4" }),
|
|
6294
|
+
"Delete"
|
|
6295
|
+
] }),
|
|
6296
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "max-w-64 px-2 py-1.5 text-xs text-muted-foreground", "data-manage-reason": "", children: manageReason })
|
|
6270
6297
|
] }) : null
|
|
6271
6298
|
] })
|
|
6272
6299
|
] })
|
|
@@ -6497,6 +6524,17 @@ function ItemPane(props) {
|
|
|
6497
6524
|
] }) });
|
|
6498
6525
|
}
|
|
6499
6526
|
|
|
6527
|
+
// src/row-menu.ts
|
|
6528
|
+
var readers = /* @__PURE__ */ new WeakMap();
|
|
6529
|
+
function registerRowMenu(el, read) {
|
|
6530
|
+
if (el) readers.set(el, read);
|
|
6531
|
+
}
|
|
6532
|
+
function rowMenuEntriesAt(target) {
|
|
6533
|
+
const row = target?.closest("[data-item]");
|
|
6534
|
+
const read = row ? readers.get(row) : void 0;
|
|
6535
|
+
return read ? read() : [];
|
|
6536
|
+
}
|
|
6537
|
+
|
|
6500
6538
|
// src/ItemList.tsx
|
|
6501
6539
|
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
6502
6540
|
var RECOVERY_KEYS = /^recovery_codes?$/;
|
|
@@ -6518,7 +6556,7 @@ function subtitleOf(item, withOwner) {
|
|
|
6518
6556
|
const what = loginSiteOf(item) || item.definitionLabel;
|
|
6519
6557
|
return withOwner ? `${what} \xB7 ${item.owner.label}` : what;
|
|
6520
6558
|
}
|
|
6521
|
-
function ItemList({ title, items, definitions, port, selectedId, onSelect, query, onQuery, sort, onSort, onNew, matchingIds, header, showOwner, canSortViewed = false, onRefresh, refreshing = false, rowContextMenu = "package", rowMenuItems }) {
|
|
6559
|
+
function ItemList({ title, items, definitions, port, selectedId, onSelect, query, onQuery, sort, onSort, onNew, matchingIds, header, actions, showOwner, canSortViewed = false, onRefresh, refreshing = false, rowContextMenu = "package", rowMenuItems, stillLoading, favorites, onToggleFavorite }) {
|
|
6522
6560
|
const sorts = SORTS2.filter((s) => canSortViewed || s.value !== "viewed");
|
|
6523
6561
|
const pinned = matchingIds ? items.filter((i) => matchingIds.has(i.id)) : [];
|
|
6524
6562
|
const rest = matchingIds ? items.filter((i) => !matchingIds.has(i.id)) : items;
|
|
@@ -6539,20 +6577,29 @@ function ItemList({ title, items, definitions, port, selectedId, onSelect, query
|
|
|
6539
6577
|
}
|
|
6540
6578
|
};
|
|
6541
6579
|
const mixedOwners = showOwner ?? new Set(items.map((i) => i.owner.organizationId ?? i.owner.kind)).size > 1;
|
|
6542
|
-
const row = (i) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ListRow, { item: i, family: familyOf2(i.definitionKey), port, on: i.id === selectedId, onSelect, withOwner: mixedOwners, ownContextMenu: rowContextMenu === "package", extra: rowMenuItems }, i.id);
|
|
6580
|
+
const row = (i) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ListRow, { item: i, family: familyOf2(i.definitionKey), port, on: i.id === selectedId, onSelect, withOwner: mixedOwners, ownContextMenu: rowContextMenu === "package", extra: rowMenuItems, favorite: onToggleFavorite ? { on: favorites?.has(i.id) ?? false, toggle: () => onToggleFavorite(i.id) } : void 0 }, i.id);
|
|
6543
6581
|
const sortLabel = sorts.find((s) => s.value === sort)?.label ?? "Name A\u2013Z";
|
|
6544
6582
|
return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("section", { "aria-label": title, className: "flex h-full min-h-0 flex-col border-r border-border bg-background", children: [
|
|
6545
6583
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex flex-col gap-2 px-3 pb-2 pt-3", children: [
|
|
6546
6584
|
header,
|
|
6547
6585
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
6548
6586
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_controls23.SearchField, { value: query, onChange: (e) => onQuery(e.target.value), onKeyDown, placeholder: `Search ${title}`, className: "min-w-0 flex-1", "aria-label": "Search the vault" }),
|
|
6587
|
+
actions,
|
|
6549
6588
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_controls23.Button, { variant: "primary", icon: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(PlusGlyph, {}), "aria-label": "New item", onClick: onNew })
|
|
6550
6589
|
] }),
|
|
6551
6590
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex items-center justify-between gap-2 px-1", children: [
|
|
6552
|
-
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { className: "truncate text-xs text-muted-foreground", children: [
|
|
6591
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { className: "flex min-w-0 items-center gap-1.5 truncate text-xs text-muted-foreground", role: "status", "aria-live": "polite", children: [
|
|
6553
6592
|
items.length,
|
|
6554
6593
|
" ",
|
|
6555
|
-
items.length === 1 ? "item" : "items"
|
|
6594
|
+
items.length === 1 ? "item" : "items",
|
|
6595
|
+
stillLoading && stillLoading.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { className: "flex min-w-0 items-center gap-1 truncate", title: `Still loading ${stillLoading.join(", ")}`, "data-still-loading": "", children: [
|
|
6596
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(RefreshGlyph, { className: "size-3 shrink-0 animate-spin" }),
|
|
6597
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { className: "truncate", children: [
|
|
6598
|
+
"loading ",
|
|
6599
|
+
stillLoading.length === 1 ? stillLoading[0] : `${stillLoading.length} more`,
|
|
6600
|
+
"\u2026"
|
|
6601
|
+
] })
|
|
6602
|
+
] }) : null
|
|
6556
6603
|
] }),
|
|
6557
6604
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { className: "flex shrink-0 items-center gap-0.5", children: [
|
|
6558
6605
|
onRefresh ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_controls23.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(RefreshGlyph, { className: refreshing ? "animate-spin" : "" }), "aria-label": "Refresh", title: "Refresh the list", disabled: refreshing, onClick: onRefresh }) : null,
|
|
@@ -6564,7 +6611,7 @@ function ItemList({ title, items, definitions, port, selectedId, onSelect, query
|
|
|
6564
6611
|
] })
|
|
6565
6612
|
] }),
|
|
6566
6613
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "min-h-0 flex-1 overflow-y-auto px-2 pb-3", onKeyDown, children: items.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex flex-col items-center gap-3 px-4 py-12 text-center", children: [
|
|
6567
|
-
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "text-sm text-muted-foreground", children: query ? `Nothing matches \u201C${query}\u201D.` : "Nothing here yet." }),
|
|
6614
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "text-sm text-muted-foreground", children: query ? `Nothing matches \u201C${query}\u201D.` : stillLoading && stillLoading.length > 0 ? "Still loading\u2026" : "Nothing here yet." }),
|
|
6568
6615
|
query ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_controls23.Button, { variant: "outline", onClick: () => onQuery(""), children: "Clear search" }) : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_controls23.Button, { variant: "outline", icon: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(PlusGlyph, {}), onClick: onNew, children: "New item" })
|
|
6569
6616
|
] }) : /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("ul", { ref: listRef, className: "flex flex-col gap-px", children: [
|
|
6570
6617
|
pinned.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("li", { className: "px-2 pb-1 pt-1 text-xs font-medium text-muted-foreground", children: "This page" }) : null,
|
|
@@ -6574,7 +6621,7 @@ function ItemList({ title, items, definitions, port, selectedId, onSelect, query
|
|
|
6574
6621
|
] }) })
|
|
6575
6622
|
] });
|
|
6576
6623
|
}
|
|
6577
|
-
function ListRow({ item, family, port, on, onSelect, withOwner, ownContextMenu, extra }) {
|
|
6624
|
+
function ListRow({ item, family, port, on, onSelect, withOwner, ownContextMenu, extra, favorite }) {
|
|
6578
6625
|
const confirmed = useConfirmed();
|
|
6579
6626
|
const copy = useCopy();
|
|
6580
6627
|
const notify = useNotify();
|
|
@@ -6602,9 +6649,32 @@ function ListRow({ item, family, port, on, onSelect, withOwner, ownContextMenu,
|
|
|
6602
6649
|
const others = otherCopyFields(item, user, secret);
|
|
6603
6650
|
const custom = canUse ? item.custom.filter((c) => c.value) : [];
|
|
6604
6651
|
const hostEntries = extra?.(item) ?? [];
|
|
6652
|
+
const copyEntries = [
|
|
6653
|
+
...user ? [{ id: "copy:username", kind: "copy", label: `Copy ${user.label.toLowerCase()}`, onSelect: copyUser }] : [],
|
|
6654
|
+
...secret ? [{ id: "copy:password", kind: "copy", label: "Copy password", onSelect: copyPassword }] : [],
|
|
6655
|
+
...code ? [{ id: "copy:code", kind: "copy", label: "Copy one-time code", onSelect: copyCode }] : [],
|
|
6656
|
+
...others.map((f) => ({ id: `copy:${f.key}`, kind: "copy", label: `Copy ${f.label.toLowerCase()}`, onSelect: () => void run(f.label, () => port.reveal(item, f.key), f.handling !== "visible") })),
|
|
6657
|
+
...custom.map((c) => ({ id: `copy:custom:${c.key}`, kind: "copy", label: `Copy ${c.label.toLowerCase()}`, onSelect: () => void copy(c.value, c.label, { secret: false }) }))
|
|
6658
|
+
];
|
|
6659
|
+
const favoriteEntry = favorite ? { id: "favorite", kind: "favorite", label: favorite.on ? "Remove from favorites" : "Add to favorites", onSelect: favorite.toggle } : null;
|
|
6660
|
+
const entries = [
|
|
6661
|
+
...copyEntries,
|
|
6662
|
+
...favoriteEntry ? [favoriteEntry] : [],
|
|
6663
|
+
{ id: "open", kind: "open", label: "Open", onSelect: () => onSelect(item.id) },
|
|
6664
|
+
{ id: "copy-name", kind: "copy-name", label: "Copy name", onSelect: copyName },
|
|
6665
|
+
...hostEntries.map((h) => ({ ...h, kind: h.kind ?? "host" }))
|
|
6666
|
+
];
|
|
6667
|
+
const entriesRef = (0, import_react29.useRef)(entries);
|
|
6668
|
+
entriesRef.current = entries;
|
|
6669
|
+
const glyphOf = (e) => e.id === "copy:username" ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(UserGlyph, { className: "size-4" }) : e.id === "copy:password" ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(KeyGlyph, { className: "size-4" }) : e.id === "copy:code" ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ClockGlyph, { className: "size-4" }) : e.kind === "favorite" ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(StarGlyph, { className: (0, import_design_system20.cn)("size-4", favorite?.on && "fill-current text-warning") }) : e.kind === "open" ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ChevronRightGlyph, { className: "size-4" }) : e.kind === "host" ? null : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_icons12.CopyIcon, { className: "size-4" });
|
|
6670
|
+
const menuItem = (e) => /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_design_system19.DropdownMenuItem, { disabled: e.disabled ?? false, onSelect: e.onSelect, children: [
|
|
6671
|
+
glyphOf(e),
|
|
6672
|
+
e.label
|
|
6673
|
+
] }, e.id ?? e.label);
|
|
6605
6674
|
return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
6606
6675
|
"li",
|
|
6607
6676
|
{
|
|
6677
|
+
ref: (el) => registerRowMenu(el, () => entriesRef.current),
|
|
6608
6678
|
className: "group relative",
|
|
6609
6679
|
"data-item": item.id,
|
|
6610
6680
|
onContextMenu: ownContextMenu ? (e) => {
|
|
@@ -6630,7 +6700,8 @@ function ListRow({ item, family, port, on, onSelect, withOwner, ownContextMenu,
|
|
|
6630
6700
|
}
|
|
6631
6701
|
),
|
|
6632
6702
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "absolute right-1.5 top-1/2 flex -translate-y-1/2 items-center gap-0.5", "data-surface": on ? "primary" : void 0, children: [
|
|
6633
|
-
user || secret ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: (0, import_design_system20.cn)("hidden items-center gap-0.5 rounded-md pl-2 [@media(hover:hover)]:group-hover:flex [@media(hover:hover)]:group-focus-within:flex", on ? "bg-primary" : "bg-accent"), "data-row-quick": "", children: [
|
|
6703
|
+
user || secret || favorite ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: (0, import_design_system20.cn)("hidden items-center gap-0.5 rounded-md pl-2 [@media(hover:hover)]:group-hover:flex [@media(hover:hover)]:group-focus-within:flex", on ? "bg-primary" : "bg-accent"), "data-row-quick": "", children: [
|
|
6704
|
+
favorite ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_controls23.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(StarGlyph, { className: favorite.on ? "fill-current text-warning" : "" }), "aria-label": favorite.on ? "Remove from favorites" : "Add to favorites", "aria-pressed": favorite.on, onClick: favorite.toggle }) : null,
|
|
6634
6705
|
user ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_controls23.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(UserGlyph, {}), "aria-label": `Copy ${user.label}`, disabled: busy, onClick: copyUser }) : null,
|
|
6635
6706
|
secret ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_controls23.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(KeyGlyph, {}), "aria-label": "Copy password", disabled: busy, onClick: copyPassword }) : null
|
|
6636
6707
|
] }) : null,
|
|
@@ -6646,40 +6717,11 @@ function ListRow({ item, family, port, on, onSelect, withOwner, ownContextMenu,
|
|
|
6646
6717
|
}
|
|
6647
6718
|
) }),
|
|
6648
6719
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_design_system19.DropdownMenuContent, { align: "end", children: [
|
|
6649
|
-
|
|
6650
|
-
|
|
6651
|
-
|
|
6652
|
-
user.label.toLowerCase()
|
|
6653
|
-
] }) : null,
|
|
6654
|
-
secret ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_design_system19.DropdownMenuItem, { onSelect: copyPassword, children: [
|
|
6655
|
-
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(KeyGlyph, { className: "size-4" }),
|
|
6656
|
-
"Copy password"
|
|
6657
|
-
] }) : null,
|
|
6658
|
-
code ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_design_system19.DropdownMenuItem, { onSelect: copyCode, children: [
|
|
6659
|
-
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ClockGlyph, { className: "size-4" }),
|
|
6660
|
-
"Copy one-time code"
|
|
6661
|
-
] }) : null,
|
|
6662
|
-
others.map((f) => /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_design_system19.DropdownMenuItem, { onSelect: () => void run(f.label, () => port.reveal(item, f.key), f.handling !== "visible"), children: [
|
|
6663
|
-
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_icons12.CopyIcon, { className: "size-4" }),
|
|
6664
|
-
"Copy ",
|
|
6665
|
-
f.label.toLowerCase()
|
|
6666
|
-
] }, f.key)),
|
|
6667
|
-
custom.map((c) => /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_design_system19.DropdownMenuItem, { onSelect: () => void copy(c.value, c.label, { secret: false }), children: [
|
|
6668
|
-
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_icons12.CopyIcon, { className: "size-4" }),
|
|
6669
|
-
"Copy ",
|
|
6670
|
-
c.label.toLowerCase()
|
|
6671
|
-
] }, `custom:${c.key}`)),
|
|
6672
|
-
user || secret || code || others.length > 0 || custom.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_design_system19.DropdownMenuSeparator, {}) : null,
|
|
6673
|
-
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_design_system19.DropdownMenuItem, { onSelect: () => onSelect(item.id), children: [
|
|
6674
|
-
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ChevronRightGlyph, { className: "size-4" }),
|
|
6675
|
-
"Open"
|
|
6676
|
-
] }),
|
|
6677
|
-
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_design_system19.DropdownMenuItem, { onSelect: copyName, children: [
|
|
6678
|
-
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_icons12.CopyIcon, { className: "size-4" }),
|
|
6679
|
-
"Copy name"
|
|
6680
|
-
] }),
|
|
6720
|
+
copyEntries.map(menuItem),
|
|
6721
|
+
copyEntries.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_design_system19.DropdownMenuSeparator, {}) : null,
|
|
6722
|
+
entries.filter((e) => e.kind === "favorite" || e.kind === "open" || e.kind === "copy-name").map(menuItem),
|
|
6681
6723
|
hostEntries.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_design_system19.DropdownMenuSeparator, {}) : null,
|
|
6682
|
-
|
|
6724
|
+
entries.filter((e) => e.kind === "host").map(menuItem)
|
|
6683
6725
|
] })
|
|
6684
6726
|
] })
|
|
6685
6727
|
] })
|
|
@@ -8187,15 +8229,17 @@ var import_controls34 = require("@ai-matrx/design-system/controls");
|
|
|
8187
8229
|
var import_icons16 = require("@ai-matrx/design-system/icons");
|
|
8188
8230
|
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
8189
8231
|
var AUTHENTICATOR_LABEL = "Authenticator";
|
|
8190
|
-
function vaultChoices(items, organizations,
|
|
8232
|
+
function vaultChoices(items, organizations, _current) {
|
|
8191
8233
|
const n = (f) => items.filter(f).length;
|
|
8192
8234
|
const shared = n((i) => i.owner.kind === "shared");
|
|
8193
8235
|
return [
|
|
8194
8236
|
{ value: "all", label: "All items", count: items.length },
|
|
8195
8237
|
{ value: "mine", label: "Personal", count: n((i) => i.owner.kind === "me") },
|
|
8196
8238
|
...shared > 0 ? [{ value: "shared", label: "Shared with me", count: shared }] : [],
|
|
8197
|
-
//
|
|
8198
|
-
|
|
8239
|
+
// Every organization the person belongs to, empty ones too: an empty vault opens on its own
|
|
8240
|
+
// "Nothing here yet" with New item, so the first credential can go there. (The organization
|
|
8241
|
+
// list carries no role, so who may add is the server's answer to the save, said in place.)
|
|
8242
|
+
...organizations.map((o) => ({ value: o.id, label: o.name, count: n((i) => i.owner.organizationId === o.id) }))
|
|
8199
8243
|
];
|
|
8200
8244
|
}
|
|
8201
8245
|
function VaultSelect({ value, choices, onChange }) {
|
|
@@ -8475,7 +8519,16 @@ function Workspace({ port, host = NO_HOST, layout = "auto", location, onLocation
|
|
|
8475
8519
|
const load = (0, import_react42.useCallback)(() => {
|
|
8476
8520
|
setError(null);
|
|
8477
8521
|
setRefreshError(null);
|
|
8478
|
-
|
|
8522
|
+
let finished = false;
|
|
8523
|
+
port.load((partial) => {
|
|
8524
|
+
if (finished) return;
|
|
8525
|
+
setSnap(partial);
|
|
8526
|
+
setItems(partial.items);
|
|
8527
|
+
setDeleted(partial.deleted);
|
|
8528
|
+
}).then((s) => {
|
|
8529
|
+
finished = true;
|
|
8530
|
+
apply(s);
|
|
8531
|
+
}).catch((e) => {
|
|
8479
8532
|
setSignedOut(e?.status === 401);
|
|
8480
8533
|
setError(e instanceof Error ? e.message : "The vault could not be loaded.");
|
|
8481
8534
|
});
|
|
@@ -8592,9 +8645,11 @@ function Workspace({ port, host = NO_HOST, layout = "auto", location, onLocation
|
|
|
8592
8645
|
}
|
|
8593
8646
|
const hasFavorites = port.lists.favorites !== void 0;
|
|
8594
8647
|
const title = loc.vault === "all" && loc.view === "all" ? "All items" : viewLabel(loc.view, views);
|
|
8595
|
-
const compactHeader = mode === "full" ? void 0 : /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "grid grid-cols-[
|
|
8648
|
+
const compactHeader = mode === "full" ? void 0 : /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "grid grid-cols-[repeat(auto-fit,minmax(11rem,1fr))] gap-2", "data-vault-compact-header": "", children: [
|
|
8596
8649
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(VaultSelect, { value: loc.vault, choices, onChange: (vault) => go({ vault, itemId: null, panel: null }) }),
|
|
8597
|
-
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_controls35.Select, { value: loc.view, onValueChange: (view) => go({ view, itemId: null, panel: null }), options: viewOptions(views, inThisVault.length, deleted.length, hasFavorites, port.lists.recents !== void 0, host.page !== void 0), "aria-label": "Show" })
|
|
8650
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_controls35.Select, { value: loc.view, onValueChange: (view) => go({ view, itemId: null, panel: null }), options: viewOptions(views, inThisVault.length, deleted.length, hasFavorites, port.lists.recents !== void 0, host.page !== void 0), "aria-label": "Show" })
|
|
8651
|
+
] });
|
|
8652
|
+
const compactActions = mode === "full" ? void 0 : /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "flex shrink-0 items-center gap-2", "data-vault-compact-actions": "", children: [
|
|
8598
8653
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
8599
8654
|
import_controls35.Button,
|
|
8600
8655
|
{
|
|
@@ -8603,8 +8658,7 @@ function Workspace({ port, host = NO_HOST, layout = "auto", location, onLocation
|
|
|
8603
8658
|
"aria-label": AUTHENTICATOR_LABEL,
|
|
8604
8659
|
"aria-pressed": loc.view === "authenticator",
|
|
8605
8660
|
title: AUTHENTICATOR_LABEL,
|
|
8606
|
-
onClick: () => go({ view: loc.view === "authenticator" ? "all" : "authenticator", itemId: null, mode: "view", panel: null })
|
|
8607
|
-
children: mode === "split" ? AUTHENTICATOR_LABEL : null
|
|
8661
|
+
onClick: () => go({ view: loc.view === "authenticator" ? "all" : "authenticator", itemId: null, mode: "view", panel: null })
|
|
8608
8662
|
}
|
|
8609
8663
|
),
|
|
8610
8664
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_design_system26.DropdownMenu, { children: [
|
|
@@ -8647,7 +8701,10 @@ function Workspace({ port, host = NO_HOST, layout = "auto", location, onLocation
|
|
|
8647
8701
|
] });
|
|
8648
8702
|
const viewHeader = /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "flex flex-col gap-2", children: [
|
|
8649
8703
|
compactHeader,
|
|
8650
|
-
/* @__PURE__ */ (0, import_jsx_runtime40.
|
|
8704
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
8705
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_controls35.SearchField, { value: loc.q, onChange: (e) => go({ q: e.target.value }, "replace"), placeholder: `Search ${viewLabel(loc.view, views)}`, "aria-label": `Search ${viewLabel(loc.view, views)}`, className: "min-w-0 flex-1" }),
|
|
8706
|
+
compactActions
|
|
8707
|
+
] })
|
|
8651
8708
|
] });
|
|
8652
8709
|
const viewProps = { port, host, items: inThisVault, deleted, definitions, query: loc.q, onOpen: (id) => go({ view: "all", itemId: id, mode: "view", panel: null }), onChanged: load, header: viewHeader };
|
|
8653
8710
|
const pageView = loc.view === "page" && host.page && !loc.q ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
@@ -8665,7 +8722,10 @@ function Workspace({ port, host = NO_HOST, layout = "auto", location, onLocation
|
|
|
8665
8722
|
onNewForPage: (url) => go({ mode: "new", kind: null, url, itemId: null, panel: null }),
|
|
8666
8723
|
onBrowse: () => go({ view: "all", itemId: null }),
|
|
8667
8724
|
onChanged: load,
|
|
8668
|
-
...compactHeader ? { header:
|
|
8725
|
+
...compactHeader ? { header: /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "flex flex-col gap-2", children: [
|
|
8726
|
+
compactHeader,
|
|
8727
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "flex justify-end", children: compactActions })
|
|
8728
|
+
] }) } : {}
|
|
8669
8729
|
}
|
|
8670
8730
|
) : null;
|
|
8671
8731
|
const specialView = pageView ?? (loc.view === "authenticator" ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(AuthenticatorView, { ...viewProps }) : loc.view === "trash" ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(TrashView, { ...viewProps }) : null);
|
|
@@ -8687,10 +8747,13 @@ function Workspace({ port, host = NO_HOST, layout = "auto", location, onLocation
|
|
|
8687
8747
|
onNew: () => go({ itemId: null, mode: "new", kind: null, panel: null }),
|
|
8688
8748
|
onRefresh: refresh,
|
|
8689
8749
|
refreshing,
|
|
8750
|
+
...snap.pending && snap.pending.length > 0 ? { stillLoading: snap.pending } : {},
|
|
8751
|
+
...hasFavorites ? { favorites: favorites ?? /* @__PURE__ */ new Set(), onToggleFavorite: toggleFavorite } : {},
|
|
8690
8752
|
rowContextMenu: host.rowContextMenu ?? "package",
|
|
8691
8753
|
...host.rowMenuItems ? { rowMenuItems: host.rowMenuItems } : {},
|
|
8692
8754
|
...matchingIds ? { matchingIds } : {},
|
|
8693
|
-
...compactHeader ? { header: compactHeader } : {}
|
|
8755
|
+
...compactHeader ? { header: compactHeader } : {},
|
|
8756
|
+
...compactActions ? { actions: compactActions } : {}
|
|
8694
8757
|
}
|
|
8695
8758
|
);
|
|
8696
8759
|
const showingDetail = loc.mode === "new" || loc.itemId !== null;
|
|
@@ -9576,6 +9639,12 @@ function createApiVaultPort(api, options = {}) {
|
|
|
9576
9639
|
if (id) return { kind: "organization", label: orgs.find((o) => o.id === id)?.name ?? "Organization", organizationId: id };
|
|
9577
9640
|
return mine || userId ? { kind: "me", label: "Personal", organizationId: null } : { kind: "shared", label: "Shared with me", organizationId: null };
|
|
9578
9641
|
};
|
|
9642
|
+
const ownerInOrgList = (w, via, meId) => {
|
|
9643
|
+
if (w.organization_id) return orgOf(w.organization_id, null, false);
|
|
9644
|
+
if (w.user_id && meId && w.user_id === meId) return { kind: "me", label: "Personal", organizationId: null };
|
|
9645
|
+
if (via) return { kind: "organization", label: via.name, organizationId: via.id, memberShared: { userId: w.user_id ?? null } };
|
|
9646
|
+
return { kind: "shared", label: "Shared with me", organizationId: null };
|
|
9647
|
+
};
|
|
9579
9648
|
async function refetch(id, owner) {
|
|
9580
9649
|
const w = await account9.getItem(api, { path: { item_id: id } });
|
|
9581
9650
|
return itemOf(w, owner, defs, auth);
|
|
@@ -9603,38 +9672,100 @@ function createApiVaultPort(api, options = {}) {
|
|
|
9603
9672
|
io: createIoPort(ctx),
|
|
9604
9673
|
fields: createFieldsPort(ctx),
|
|
9605
9674
|
lists: createListsPort(ctx, options.userState),
|
|
9606
|
-
async load() {
|
|
9675
|
+
async load(onProgress) {
|
|
9607
9676
|
const catalogP = retrying(() => apps2.getAppCatalogKind(api, { path: { app: "matrx", kind: "credential_definition" } }));
|
|
9608
9677
|
const authP = retrying(() => apps2.listAuthenticators(api));
|
|
9609
9678
|
const userP = retrying(() => account9.listItems(api, { query: { principal_type: "user" } }));
|
|
9610
9679
|
const sharedP = retrying(() => account9.sharedWithMe(api));
|
|
9611
9680
|
const quiet = (p) => void p.catch(() => void 0);
|
|
9612
9681
|
[catalogP, authP, userP, sharedP].forEach(quiet);
|
|
9613
|
-
const
|
|
9614
|
-
|
|
9615
|
-
|
|
9616
|
-
|
|
9617
|
-
|
|
9618
|
-
const [authSettled, sharedSettled, ...orgSettled] = await Promise.allSettled([authP, sharedP, ...orgListsP]);
|
|
9682
|
+
const raw = {
|
|
9683
|
+
orgLists: [],
|
|
9684
|
+
orgsKnown: options.organizations !== void 0,
|
|
9685
|
+
meId: null
|
|
9686
|
+
};
|
|
9619
9687
|
const unavailable = [];
|
|
9620
|
-
|
|
9621
|
-
const
|
|
9622
|
-
|
|
9623
|
-
|
|
9624
|
-
|
|
9625
|
-
|
|
9626
|
-
|
|
9627
|
-
|
|
9628
|
-
|
|
9629
|
-
|
|
9630
|
-
|
|
9631
|
-
if (seen.has(w.id) || deleted.has(w.id) || isHiddenItem(w)) continue;
|
|
9632
|
-
const owner = sharedList ? orgOf(w.organization_id, null, false) : orgOf(w.organization_id, w.user_id, i === 0);
|
|
9633
|
-
const item = itemOf(w, sharedList && !w.organization_id ? { kind: "shared", label: "Shared with me", organizationId: null } : owner, defs, auth);
|
|
9688
|
+
let done = false;
|
|
9689
|
+
const build = () => {
|
|
9690
|
+
const catalog2 = raw.catalog ?? [];
|
|
9691
|
+
defs = new Map(parseDefinitions(catalog2.filter((e) => e.is_active).map((e) => ({ key: e.key, payload: e.payload, sort_order: e.sort_order }))).map((d) => [d.key, d]));
|
|
9692
|
+
const mineItems = raw.mine?.items ?? [];
|
|
9693
|
+
const meId = raw.meId ?? mineItems.find((w) => w.user_id)?.user_id ?? null;
|
|
9694
|
+
const seen = /* @__PURE__ */ new Map();
|
|
9695
|
+
const deleted = /* @__PURE__ */ new Map();
|
|
9696
|
+
const take = (w, owner) => {
|
|
9697
|
+
if (seen.has(w.id) || deleted.has(w.id) || isHiddenItem(w)) return;
|
|
9698
|
+
const item = itemOf(w, owner, defs, auth);
|
|
9634
9699
|
(isDeleted(w) ? deleted : seen).set(w.id, item);
|
|
9700
|
+
};
|
|
9701
|
+
for (const w of mineItems) take(w, orgOf(w.organization_id, null, true));
|
|
9702
|
+
raw.orgLists.forEach((l, i) => {
|
|
9703
|
+
const via = orgs[i];
|
|
9704
|
+
for (const w of l?.items ?? []) take(w, ownerInOrgList(w, via, meId));
|
|
9705
|
+
});
|
|
9706
|
+
for (const w of raw.shared?.items ?? []) take(w, w.organization_id ? orgOf(w.organization_id, null, false) : { kind: "shared", label: "Shared with me", organizationId: null });
|
|
9707
|
+
const pending = done ? [] : [...raw.orgsKnown ? orgs.filter((_, i) => raw.orgLists[i] === void 0).map((o) => o.name) : ["your organizations"], ...raw.shared ? [] : ["Shared with me"]];
|
|
9708
|
+
return {
|
|
9709
|
+
unavailable: [...unavailable],
|
|
9710
|
+
...pending.length > 0 ? { pending } : {},
|
|
9711
|
+
items: [...seen.values()],
|
|
9712
|
+
deleted: [...deleted.values()],
|
|
9713
|
+
organizations: orgs,
|
|
9714
|
+
definitions: [...defs.values()].sort((a, b) => a.sortOrder - b.sortOrder || a.label.localeCompare(b.label))
|
|
9715
|
+
};
|
|
9716
|
+
};
|
|
9717
|
+
const progress = () => {
|
|
9718
|
+
if (!done && onProgress && raw.catalog && raw.mine) onProgress(build());
|
|
9719
|
+
};
|
|
9720
|
+
const orgReportP = options.organizations ? null : retrying(() => platform.listMyOrganizations(api));
|
|
9721
|
+
if (orgReportP) quiet(orgReportP);
|
|
9722
|
+
const orgListsReady = (async () => {
|
|
9723
|
+
const report = orgReportP ? await orgReportP : null;
|
|
9724
|
+
raw.meId = report?.user_id ?? null;
|
|
9725
|
+
orgs = [...new Map((options.organizations ?? (report?.organizations ?? []).filter((o) => !o.archived_at).map((o) => ({ id: o.id, name: o.name }))).map((o) => [o.id, o])).values()];
|
|
9726
|
+
raw.orgLists = orgs.map(() => void 0);
|
|
9727
|
+
raw.orgsKnown = true;
|
|
9728
|
+
progress();
|
|
9729
|
+
return orgs.map((o, i) => {
|
|
9730
|
+
const p = retrying(() => account9.listItems(api, { query: { principal_type: "organization", organization_id: o.id } }, { organizationId: o.id }));
|
|
9731
|
+
const arrived = p.then((l) => {
|
|
9732
|
+
raw.orgLists[i] = l;
|
|
9733
|
+
progress();
|
|
9734
|
+
return l;
|
|
9735
|
+
});
|
|
9736
|
+
quiet(arrived);
|
|
9737
|
+
return arrived;
|
|
9738
|
+
});
|
|
9739
|
+
})();
|
|
9740
|
+
quiet(orgListsReady);
|
|
9741
|
+
const authDone = authP.then((a) => {
|
|
9742
|
+
auth = new Map((a.entries ?? []).map((e) => [e.credential_item_id, e]));
|
|
9743
|
+
progress();
|
|
9744
|
+
}, () => {
|
|
9745
|
+
unavailable.push("One-time codes");
|
|
9746
|
+
});
|
|
9747
|
+
const sharedDone = sharedP.then((sh) => {
|
|
9748
|
+
raw.shared = sh;
|
|
9749
|
+
progress();
|
|
9750
|
+
}, () => {
|
|
9751
|
+
raw.shared = { items: [], count: 0 };
|
|
9752
|
+
unavailable.push("Shared with me");
|
|
9753
|
+
});
|
|
9754
|
+
const [catalog, mine] = await Promise.all([catalogP, userP]);
|
|
9755
|
+
raw.catalog = catalog;
|
|
9756
|
+
raw.mine = mine;
|
|
9757
|
+
progress();
|
|
9758
|
+
const orgPs = await orgListsReady;
|
|
9759
|
+
const orgSettled = await Promise.allSettled(orgPs);
|
|
9760
|
+
orgSettled.forEach((r, i) => {
|
|
9761
|
+
if (r.status === "rejected") {
|
|
9762
|
+
raw.orgLists[i] = { items: [], count: 0 };
|
|
9763
|
+
unavailable.push(orgs[i]?.name ?? "An organization");
|
|
9635
9764
|
}
|
|
9636
9765
|
});
|
|
9637
|
-
|
|
9766
|
+
await Promise.all([authDone, sharedDone]);
|
|
9767
|
+
done = true;
|
|
9768
|
+
return build();
|
|
9638
9769
|
},
|
|
9639
9770
|
async reveal(item, fieldKey2) {
|
|
9640
9771
|
const field = item.fields.find((f) => f.key === fieldKey2);
|