clearotron 0.3.1-beta.2 → 0.3.1-beta.3
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/bin/grant.mjs +21 -22
- package/build-info.json +2 -2
- package/driver/CHANGELOG.md +25 -0
- package/driver/package.json +1 -1
- package/driver/portal-config-view.mjs +26 -1
- package/driver/portal-report.mjs +16 -2
- package/driver/portal-service.mjs +286 -6
- package/driver/publish/render.mjs +0 -45
- package/driver/publish/templates/report.css +1 -30
- package/driver/skills/knockout-assess/SKILL.md +35 -6
- package/driver/skills/knockout-frame/SKILL.md +2 -1
- package/driver/skills/prelim-search/risk-framework-triage.md +3 -3
- package/driver/stages.mjs +2 -2
- package/driver/suite-census.json +75 -9
- package/driver/verify-knockout.mjs +58 -0
- package/mcp-server/CHANGELOG.md +7 -0
- package/mcp-server/lib/audit.mjs +96 -3
- package/mcp-server/lib/http-handler.mjs +76 -3
- package/mcp-server/lib/runs.mjs +42 -2
- package/mcp-server/package.json +1 -1
- package/mcp-server/packs/client/CONNECT.md +10 -6
- package/mcp-server/server.mjs +37 -3
- package/package.json +1 -1
- package/portal-ui/dist/assets/{index-D8ITW-aD.js → index-C-QysgZM.js} +1082 -630
- package/portal-ui/dist/assets/{index-D5WAoLZI.css → index-CaSZbEMb.css} +15 -0
- package/portal-ui/dist/index.html +2 -2
- package/portal-ui/package.json +1 -1
- package/providers/oauth-mcp-bridge/CHANGELOG.md +4 -0
- package/providers/oauth-mcp-bridge/package.json +1 -1
- package/scripts/ask-ai-render-check.mjs +359 -0
- package/shared/grants-edit.mjs +99 -2
|
@@ -11802,7 +11802,10 @@ function decodePerson(r) {
|
|
|
11802
11802
|
manage: asRecord(r["permissions"])["manage"] === true
|
|
11803
11803
|
},
|
|
11804
11804
|
access: decodeAccess(r),
|
|
11805
|
-
dangling: asArray(r["dangling"]).filter((s) => typeof s === "string")
|
|
11805
|
+
dangling: asArray(r["dangling"]).filter((s) => typeof s === "string"),
|
|
11806
|
+
listed: r["listed"] !== false,
|
|
11807
|
+
covered: r["covered"] === true,
|
|
11808
|
+
keys: typeof r["keys"] === "number" && r["keys"] > 0 ? r["keys"] : 0
|
|
11806
11809
|
};
|
|
11807
11810
|
}
|
|
11808
11811
|
var api = {
|
|
@@ -12051,6 +12054,7 @@ var api = {
|
|
|
12051
12054
|
keyUrl: asString(b["keyUrl"]),
|
|
12052
12055
|
email: asString(b["email"]),
|
|
12053
12056
|
enabled: b["enabled"] === true,
|
|
12057
|
+
aiConnected: typeof b["aiConnected"] === "boolean" ? b["aiConnected"] : null,
|
|
12054
12058
|
stdio: (() => {
|
|
12055
12059
|
const r = b["stdio"];
|
|
12056
12060
|
if (!r || typeof r !== "object") return null;
|
|
@@ -12218,7 +12222,8 @@ var api = {
|
|
|
12218
12222
|
} : null;
|
|
12219
12223
|
})(),
|
|
12220
12224
|
canAdd: b["canAdd"] === true,
|
|
12221
|
-
localSignIn: b["localSignIn"] === true
|
|
12225
|
+
localSignIn: b["localSignIn"] === true,
|
|
12226
|
+
keysRevocable: b["keysRevocable"] === true
|
|
12222
12227
|
})),
|
|
12223
12228
|
addPerson: (body) => call("/portal/admin/people", (b) => ({
|
|
12224
12229
|
person: decodePerson(asRecord(b["person"])),
|
|
@@ -12227,6 +12232,32 @@ var api = {
|
|
|
12227
12232
|
method: "POST",
|
|
12228
12233
|
body: JSON.stringify(body)
|
|
12229
12234
|
}),
|
|
12235
|
+
changePerson: (body) => call("/portal/admin/people/change", (b) => ({
|
|
12236
|
+
person: decodePerson(asRecord(b["person"])),
|
|
12237
|
+
switchesApplied: b["switchesApplied"] === true,
|
|
12238
|
+
added: typeof b["added"] === "number" ? b["added"] : 0,
|
|
12239
|
+
removed: typeof b["removed"] === "number" ? b["removed"] : 0
|
|
12240
|
+
}), {
|
|
12241
|
+
method: "POST",
|
|
12242
|
+
body: JSON.stringify(body)
|
|
12243
|
+
}),
|
|
12244
|
+
removePerson: (body) => call("/portal/admin/people/remove", (b) => {
|
|
12245
|
+
const k = asRecord(b["keys"]);
|
|
12246
|
+
return {
|
|
12247
|
+
removed: b["removed"] === "install" ? "install" : "organisations",
|
|
12248
|
+
organisations: asStrings(b["organisations"]),
|
|
12249
|
+
keys: {
|
|
12250
|
+
checked: k["checked"] === true,
|
|
12251
|
+
revoked: typeof k["revoked"] === "number" ? k["revoked"] : 0,
|
|
12252
|
+
lateArm: k["lateArm"] === true,
|
|
12253
|
+
failed: k["failed"] === true,
|
|
12254
|
+
note: asString(k["note"])
|
|
12255
|
+
}
|
|
12256
|
+
};
|
|
12257
|
+
}, {
|
|
12258
|
+
method: "POST",
|
|
12259
|
+
body: JSON.stringify(body)
|
|
12260
|
+
}),
|
|
12230
12261
|
adminObserved: () => call("/portal/admin/observed", (b) => ({
|
|
12231
12262
|
available: b["available"] === true,
|
|
12232
12263
|
truncated: b["truncated"] === true,
|
|
@@ -12302,6 +12333,15 @@ var NAV = [
|
|
|
12302
12333
|
hidden: true,
|
|
12303
12334
|
scope: "account"
|
|
12304
12335
|
},
|
|
12336
|
+
{
|
|
12337
|
+
id: "people.modify",
|
|
12338
|
+
label: "Modify access",
|
|
12339
|
+
path: "/portal/people/modify",
|
|
12340
|
+
icon: "users",
|
|
12341
|
+
needs: "manage",
|
|
12342
|
+
hidden: true,
|
|
12343
|
+
scope: "account"
|
|
12344
|
+
},
|
|
12305
12345
|
{
|
|
12306
12346
|
id: "new",
|
|
12307
12347
|
label: "New clearance",
|
|
@@ -12454,6 +12494,7 @@ function decode(segment) {
|
|
|
12454
12494
|
}
|
|
12455
12495
|
var PEOPLE = NAV.find((e) => e.id === "people");
|
|
12456
12496
|
var ADD_PERSON = NAV.find((e) => e.id === "people.add");
|
|
12497
|
+
var MODIFY_PERSON = NAV.find((e) => e.id === "people.modify");
|
|
12457
12498
|
//#endregion
|
|
12458
12499
|
//#region ../node_modules/react/cjs/react-jsx-runtime.production.js
|
|
12459
12500
|
var require_react_jsx_runtime_production = __commonJSMin(((exports) => {
|
|
@@ -12848,6 +12889,26 @@ function seesEverything(who) {
|
|
|
12848
12889
|
return who.allAccounts === true;
|
|
12849
12890
|
}
|
|
12850
12891
|
//#endregion
|
|
12892
|
+
//#region src/components/PageHeader.tsx
|
|
12893
|
+
function PageHeader({ title, lede, actions }) {
|
|
12894
|
+
return (0, import_jsx_runtime.jsxs)("header", {
|
|
12895
|
+
className: "page-header",
|
|
12896
|
+
children: [(0, import_jsx_runtime.jsxs)("div", {
|
|
12897
|
+
className: "page-header-text",
|
|
12898
|
+
children: [(0, import_jsx_runtime.jsx)("h1", {
|
|
12899
|
+
className: "page-title",
|
|
12900
|
+
children: title
|
|
12901
|
+
}), lede ? (0, import_jsx_runtime.jsx)("p", {
|
|
12902
|
+
className: "page-lede",
|
|
12903
|
+
children: lede
|
|
12904
|
+
}) : null]
|
|
12905
|
+
}), actions ? (0, import_jsx_runtime.jsx)("div", {
|
|
12906
|
+
className: "page-header-actions",
|
|
12907
|
+
children: actions
|
|
12908
|
+
}) : null]
|
|
12909
|
+
});
|
|
12910
|
+
}
|
|
12911
|
+
//#endregion
|
|
12851
12912
|
//#region src/shell/CompanyPicker.tsx
|
|
12852
12913
|
function CompanyCard({ row, onPick }) {
|
|
12853
12914
|
return (0, import_jsx_runtime.jsxs)("button", {
|
|
@@ -12907,51 +12968,26 @@ function CompanyCard({ row, onPick }) {
|
|
|
12907
12968
|
})]
|
|
12908
12969
|
});
|
|
12909
12970
|
}
|
|
12910
|
-
function CompanyPicker({
|
|
12971
|
+
function CompanyPicker({ heading, line, keys, orgOf, organisations, companyName, factsFor, onPick, onAdd }) {
|
|
12911
12972
|
const { headings, groups } = pickerGroups(keys, orgOf, organisations, companyName, factsFor);
|
|
12912
|
-
return (0, import_jsx_runtime.
|
|
12973
|
+
return (0, import_jsx_runtime.jsx)("div", {
|
|
12913
12974
|
className: "screen",
|
|
12914
|
-
children:
|
|
12915
|
-
className: "eyebrow",
|
|
12916
|
-
children: eyebrow
|
|
12917
|
-
}), (0, import_jsx_runtime.jsxs)("div", {
|
|
12975
|
+
children: (0, import_jsx_runtime.jsxs)("div", {
|
|
12918
12976
|
className: "measure",
|
|
12919
|
-
children: [(0, import_jsx_runtime.
|
|
12920
|
-
|
|
12921
|
-
|
|
12922
|
-
|
|
12923
|
-
gap: 20,
|
|
12924
|
-
margin: "4px 0 18px"
|
|
12925
|
-
},
|
|
12926
|
-
children: [(0, import_jsx_runtime.jsxs)("div", {
|
|
12927
|
-
style: { flex: 1 },
|
|
12928
|
-
children: [(0, import_jsx_runtime.jsx)("h1", {
|
|
12929
|
-
style: {
|
|
12930
|
-
fontSize: 27,
|
|
12931
|
-
margin: "0 0 4px",
|
|
12932
|
-
color: "var(--text-strong)"
|
|
12933
|
-
},
|
|
12934
|
-
children: heading
|
|
12935
|
-
}), (0, import_jsx_runtime.jsx)("p", {
|
|
12936
|
-
style: {
|
|
12937
|
-
margin: 0,
|
|
12938
|
-
color: "var(--text-muted)",
|
|
12939
|
-
fontSize: 14.5
|
|
12940
|
-
},
|
|
12941
|
-
children: line
|
|
12942
|
-
})]
|
|
12943
|
-
}), onAdd ? (0, import_jsx_runtime.jsx)("button", {
|
|
12977
|
+
children: [(0, import_jsx_runtime.jsx)(PageHeader, {
|
|
12978
|
+
title: heading,
|
|
12979
|
+
lede: line,
|
|
12980
|
+
actions: onAdd ? (0, import_jsx_runtime.jsx)("button", {
|
|
12944
12981
|
type: "button",
|
|
12945
12982
|
className: "start-pill",
|
|
12946
12983
|
onClick: onAdd,
|
|
12947
12984
|
style: {
|
|
12948
|
-
flex: "none",
|
|
12949
12985
|
borderColor: "var(--accent-ink)",
|
|
12950
12986
|
color: "var(--text-accent)",
|
|
12951
12987
|
fontWeight: 700
|
|
12952
12988
|
},
|
|
12953
12989
|
children: "+ New company"
|
|
12954
|
-
}) : null
|
|
12990
|
+
}) : null
|
|
12955
12991
|
}), groups.map((g, i) => (0, import_jsx_runtime.jsxs)("div", { children: [headings && g.org ? (0, import_jsx_runtime.jsx)("div", {
|
|
12956
12992
|
className: "eyebrow",
|
|
12957
12993
|
style: { margin: i === 0 ? "0 0 8px" : "16px 0 8px" },
|
|
@@ -12969,12 +13005,11 @@ function CompanyPicker({ eyebrow, heading, line, keys, orgOf, organisations, com
|
|
|
12969
13005
|
onPick: () => onPick(r.key)
|
|
12970
13006
|
}, r.key))
|
|
12971
13007
|
})] }, g.org?.key ?? ""))]
|
|
12972
|
-
})
|
|
13008
|
+
})
|
|
12973
13009
|
});
|
|
12974
13010
|
}
|
|
12975
|
-
function CompanyGate({ ctx,
|
|
13011
|
+
function CompanyGate({ ctx, heading, line }) {
|
|
12976
13012
|
return (0, import_jsx_runtime.jsx)(CompanyPicker, {
|
|
12977
|
-
eyebrow,
|
|
12978
13013
|
heading,
|
|
12979
13014
|
line,
|
|
12980
13015
|
keys: ctx.ownerKeys,
|
|
@@ -13859,23 +13894,18 @@ function Home({ ctx }) {
|
|
|
13859
13894
|
return (0, import_jsx_runtime.jsxs)("div", {
|
|
13860
13895
|
className: "screen home2",
|
|
13861
13896
|
children: [
|
|
13862
|
-
(0, import_jsx_runtime.jsx)(
|
|
13863
|
-
|
|
13864
|
-
children: "
|
|
13865
|
-
|
|
13866
|
-
|
|
13867
|
-
|
|
13868
|
-
|
|
13869
|
-
|
|
13870
|
-
color: "var(--text-strong)"
|
|
13871
|
-
},
|
|
13872
|
-
children: "Now"
|
|
13897
|
+
(0, import_jsx_runtime.jsx)(PageHeader, {
|
|
13898
|
+
title: "Home",
|
|
13899
|
+
actions: (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [(0, import_jsx_runtime.jsxs)("button", {
|
|
13900
|
+
type: "button",
|
|
13901
|
+
className: "btn-ghost home2-all",
|
|
13902
|
+
onClick: () => ctx.go("/portal/clearances"),
|
|
13903
|
+
children: [(0, import_jsx_runtime.jsx)(Icon, { name: "layers" }), (0, import_jsx_runtime.jsx)("span", { children: "All Clearances" })]
|
|
13904
|
+
}), canRun(ctx.me) ? (0, import_jsx_runtime.jsx)(NewClearanceButton, { onNew: () => ctx.go("/portal/new") }) : null] })
|
|
13873
13905
|
}),
|
|
13874
13906
|
(0, import_jsx_runtime.jsx)(InFlightBand, {
|
|
13875
13907
|
count: cards.length + queue.length,
|
|
13876
|
-
note: cards.length + queue.length === 0 ? `Nothing running right now.${canRun(ctx.me) ? " Start one with New clearance." : ""}` : slotNote(null, ctx.me.concurrentRuns)
|
|
13877
|
-
onNew: canRun(ctx.me) ? () => ctx.go("/portal/new") : null,
|
|
13878
|
-
onAll: () => ctx.go("/portal/clearances")
|
|
13908
|
+
note: cards.length + queue.length === 0 ? `Nothing running right now.${canRun(ctx.me) ? " Start one with New clearance." : ""}` : slotNote(null, ctx.me.concurrentRuns)
|
|
13879
13909
|
}),
|
|
13880
13910
|
(0, import_jsx_runtime.jsx)("div", {
|
|
13881
13911
|
style: { margin: "0 0 18px" },
|
|
@@ -13950,7 +13980,15 @@ function Home({ ctx }) {
|
|
|
13950
13980
|
]
|
|
13951
13981
|
});
|
|
13952
13982
|
}
|
|
13953
|
-
function
|
|
13983
|
+
function NewClearanceButton({ onNew }) {
|
|
13984
|
+
return (0, import_jsx_runtime.jsxs)("button", {
|
|
13985
|
+
type: "button",
|
|
13986
|
+
className: "home2-new",
|
|
13987
|
+
onClick: onNew,
|
|
13988
|
+
children: [(0, import_jsx_runtime.jsx)(Icon, { name: "plus-circle" }), "New clearance"]
|
|
13989
|
+
});
|
|
13990
|
+
}
|
|
13991
|
+
function InFlightBand({ count, note }) {
|
|
13954
13992
|
return (0, import_jsx_runtime.jsxs)("div", {
|
|
13955
13993
|
className: "home2-band",
|
|
13956
13994
|
children: [
|
|
@@ -13966,20 +14004,7 @@ function InFlightBand({ count, note, onNew, onAll }) {
|
|
|
13966
14004
|
(0, import_jsx_runtime.jsx)("span", {
|
|
13967
14005
|
className: "home2-band-note",
|
|
13968
14006
|
children: note
|
|
13969
|
-
})
|
|
13970
|
-
(0, import_jsx_runtime.jsxs)("button", {
|
|
13971
|
-
type: "button",
|
|
13972
|
-
className: "btn-ghost home2-all",
|
|
13973
|
-
onClick: onAll,
|
|
13974
|
-
style: { marginRight: 8 },
|
|
13975
|
-
children: [(0, import_jsx_runtime.jsx)(Icon, { name: "layers" }), (0, import_jsx_runtime.jsx)("span", { children: "All Clearances" })]
|
|
13976
|
-
}),
|
|
13977
|
-
onNew ? (0, import_jsx_runtime.jsxs)("button", {
|
|
13978
|
-
type: "button",
|
|
13979
|
-
className: "home2-new",
|
|
13980
|
-
onClick: onNew,
|
|
13981
|
-
children: [(0, import_jsx_runtime.jsx)(Icon, { name: "plus-circle" }), "New clearance"]
|
|
13982
|
-
}) : null
|
|
14007
|
+
})
|
|
13983
14008
|
]
|
|
13984
14009
|
});
|
|
13985
14010
|
}
|
|
@@ -14774,24 +14799,12 @@ function Clearances({ ctx }) {
|
|
|
14774
14799
|
return (0, import_jsx_runtime.jsxs)("div", {
|
|
14775
14800
|
className: "screen",
|
|
14776
14801
|
children: [
|
|
14777
|
-
(0, import_jsx_runtime.jsx)(
|
|
14778
|
-
|
|
14779
|
-
children: "
|
|
14780
|
-
|
|
14781
|
-
|
|
14782
|
-
|
|
14783
|
-
fontSize: 27,
|
|
14784
|
-
margin: "4px 0 6px",
|
|
14785
|
-
color: "var(--text-strong)"
|
|
14786
|
-
},
|
|
14787
|
-
children: ownerFilter ? ctx.ownerName(ownerFilter) : "All Clearances"
|
|
14788
|
-
}),
|
|
14789
|
-
(0, import_jsx_runtime.jsx)("p", {
|
|
14790
|
-
style: {
|
|
14791
|
-
margin: 0,
|
|
14792
|
-
color: "var(--text-muted)"
|
|
14793
|
-
},
|
|
14794
|
-
children: (0, import_jsx_runtime.jsx)(AllowanceLine, { account })
|
|
14802
|
+
(0, import_jsx_runtime.jsx)(PageHeader, {
|
|
14803
|
+
title: "All Clearances",
|
|
14804
|
+
lede: (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [ownerFilter ? (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [(0, import_jsx_runtime.jsx)("span", {
|
|
14805
|
+
"data-anon": "mark",
|
|
14806
|
+
children: ctx.ownerName(ownerFilter)
|
|
14807
|
+
}), " · "] }) : null, (0, import_jsx_runtime.jsx)(AllowanceLine, { account })] })
|
|
14795
14808
|
}),
|
|
14796
14809
|
(0, import_jsx_runtime.jsx)("div", {
|
|
14797
14810
|
className: "controls",
|
|
@@ -15784,16 +15797,48 @@ function frameCommand(command, value) {
|
|
|
15784
15797
|
}
|
|
15785
15798
|
//#endregion
|
|
15786
15799
|
//#region src/contract/askAi.ts
|
|
15787
|
-
|
|
15788
|
-
|
|
15789
|
-
|
|
15790
|
-
|
|
15791
|
-
|
|
15800
|
+
var MONTHS = [
|
|
15801
|
+
"",
|
|
15802
|
+
"January",
|
|
15803
|
+
"February",
|
|
15804
|
+
"March",
|
|
15805
|
+
"April",
|
|
15806
|
+
"May",
|
|
15807
|
+
"June",
|
|
15808
|
+
"July",
|
|
15809
|
+
"August",
|
|
15810
|
+
"September",
|
|
15811
|
+
"October",
|
|
15812
|
+
"November",
|
|
15813
|
+
"December"
|
|
15814
|
+
];
|
|
15815
|
+
function readableDate(iso) {
|
|
15816
|
+
const m = /^(\d{4})-(\d{2})-(\d{2})$/.exec(String(iso ?? "").trim());
|
|
15817
|
+
if (!m) return null;
|
|
15818
|
+
const month = MONTHS[Number(m[2])];
|
|
15819
|
+
const day = Number(m[3]);
|
|
15820
|
+
if (!month || !(day >= 1 && day <= 31)) return null;
|
|
15821
|
+
return `${day} ${month}`;
|
|
15822
|
+
}
|
|
15823
|
+
function askAiPrompt(mark, date, kind = "clearance") {
|
|
15824
|
+
const name = String(mark ?? "").trim() || "this mark";
|
|
15825
|
+
const noun = kind === "knockout-batch" ? "knockout search" : "clearance";
|
|
15826
|
+
const when = readableDate(date);
|
|
15827
|
+
return when ? `Brief me on the ${name} ${noun} from ${when}.` : `Brief me on the ${name} ${noun}.`;
|
|
15828
|
+
}
|
|
15829
|
+
var ASSISTANTS = [{
|
|
15830
|
+
label: "Ask Claude",
|
|
15831
|
+
href: (q) => `https://claude.ai/new?q=${encodeURIComponent(q)}`
|
|
15832
|
+
}, {
|
|
15833
|
+
label: "Ask ChatGPT",
|
|
15834
|
+
href: (q) => `https://chatgpt.com/?q=${encodeURIComponent(q)}`
|
|
15835
|
+
}];
|
|
15836
|
+
var AI_SETUP_PATH = "/portal/ai";
|
|
15837
|
+
function askAiOffer(run, access) {
|
|
15792
15838
|
return {
|
|
15793
|
-
|
|
15794
|
-
|
|
15795
|
-
|
|
15796
|
-
stdio: access?.stdio ?? null
|
|
15839
|
+
drawn: !!access && (!!(access.enabled && access.url) || !!access.stdio),
|
|
15840
|
+
question: askAiPrompt(run.markName, run.date, run.kind),
|
|
15841
|
+
connected: access?.aiConnected === true
|
|
15797
15842
|
};
|
|
15798
15843
|
}
|
|
15799
15844
|
//#endregion
|
|
@@ -15851,12 +15896,12 @@ function useReportFrame() {
|
|
|
15851
15896
|
clearFailed: () => setFailed(null)
|
|
15852
15897
|
};
|
|
15853
15898
|
}
|
|
15854
|
-
function AskAiMenu({
|
|
15899
|
+
function AskAiMenu({ run, ctx }) {
|
|
15855
15900
|
const [open, setOpen] = (0, import_react.useState)(false);
|
|
15856
|
-
const [
|
|
15901
|
+
const [askAnyway, setAskAnyway] = (0, import_react.useState)(false);
|
|
15857
15902
|
const box = (0, import_react.useRef)(null);
|
|
15858
15903
|
const { result } = useLoad(() => api.mcpAccess(), []);
|
|
15859
|
-
const offer = askAiOffer(
|
|
15904
|
+
const offer = askAiOffer(run, result?.kind === "ok" ? result.value : null);
|
|
15860
15905
|
(0, import_react.useEffect)(() => {
|
|
15861
15906
|
if (!open) return;
|
|
15862
15907
|
function onDown(e) {
|
|
@@ -15872,115 +15917,151 @@ function AskAiMenu({ runId, mark, ctx }) {
|
|
|
15872
15917
|
document.removeEventListener("keydown", onKey);
|
|
15873
15918
|
};
|
|
15874
15919
|
}, [open]);
|
|
15875
|
-
|
|
15876
|
-
|
|
15877
|
-
|
|
15878
|
-
|
|
15879
|
-
|
|
15880
|
-
} catch {
|
|
15881
|
-
setCopied(`${what}-failed`);
|
|
15882
|
-
}
|
|
15883
|
-
})();
|
|
15920
|
+
if (!offer.drawn) return null;
|
|
15921
|
+
const showMenu = offer.connected || askAnyway;
|
|
15922
|
+
const ask = (href) => {
|
|
15923
|
+
setOpen(false);
|
|
15924
|
+
window.open(href, "_blank", "noopener,noreferrer");
|
|
15884
15925
|
};
|
|
15885
|
-
|
|
15886
|
-
|
|
15887
|
-
|
|
15888
|
-
|
|
15889
|
-
|
|
15890
|
-
|
|
15891
|
-
|
|
15892
|
-
|
|
15893
|
-
|
|
15894
|
-
|
|
15895
|
-
style: {
|
|
15896
|
-
display: "flex",
|
|
15897
|
-
alignItems: "center",
|
|
15898
|
-
gap: 8
|
|
15899
|
-
},
|
|
15900
|
-
children: [(0, import_jsx_runtime.jsx)("span", {
|
|
15901
|
-
className: "mono",
|
|
15926
|
+
return (0, import_jsx_runtime.jsxs)("div", {
|
|
15927
|
+
ref: box,
|
|
15928
|
+
style: { position: "relative" },
|
|
15929
|
+
"data-ask-ai": showMenu ? "menu" : "connect",
|
|
15930
|
+
children: [
|
|
15931
|
+
(0, import_jsx_runtime.jsxs)("button", {
|
|
15932
|
+
type: "button",
|
|
15933
|
+
className: "nav-item",
|
|
15934
|
+
"aria-haspopup": showMenu ? "menu" : "dialog",
|
|
15935
|
+
"aria-expanded": open,
|
|
15902
15936
|
style: {
|
|
15903
|
-
|
|
15904
|
-
|
|
15905
|
-
|
|
15906
|
-
|
|
15937
|
+
width: "auto",
|
|
15938
|
+
margin: 0,
|
|
15939
|
+
padding: "6px 11px",
|
|
15940
|
+
border: "1px solid var(--border-hairline)"
|
|
15907
15941
|
},
|
|
15908
|
-
|
|
15909
|
-
|
|
15910
|
-
|
|
15911
|
-
|
|
15942
|
+
onClick: () => setOpen((v) => !v),
|
|
15943
|
+
children: [(0, import_jsx_runtime.jsx)(Icon, {
|
|
15944
|
+
name: "sparkles",
|
|
15945
|
+
size: 14
|
|
15946
|
+
}), (0, import_jsx_runtime.jsx)("span", { children: "Ask AI" })]
|
|
15947
|
+
}),
|
|
15948
|
+
open && showMenu ? (0, import_jsx_runtime.jsxs)("div", {
|
|
15949
|
+
className: "float",
|
|
15950
|
+
role: "menu",
|
|
15912
15951
|
style: {
|
|
15913
|
-
|
|
15914
|
-
|
|
15952
|
+
position: "absolute",
|
|
15953
|
+
right: 0,
|
|
15954
|
+
top: 38,
|
|
15955
|
+
width: 236,
|
|
15956
|
+
padding: 6,
|
|
15957
|
+
zIndex: 50
|
|
15915
15958
|
},
|
|
15916
|
-
|
|
15917
|
-
|
|
15918
|
-
|
|
15919
|
-
|
|
15920
|
-
|
|
15921
|
-
|
|
15922
|
-
|
|
15923
|
-
|
|
15924
|
-
|
|
15925
|
-
|
|
15926
|
-
|
|
15927
|
-
|
|
15928
|
-
|
|
15929
|
-
|
|
15930
|
-
|
|
15931
|
-
|
|
15932
|
-
|
|
15933
|
-
|
|
15934
|
-
|
|
15935
|
-
|
|
15936
|
-
|
|
15937
|
-
|
|
15938
|
-
|
|
15939
|
-
|
|
15940
|
-
|
|
15941
|
-
|
|
15942
|
-
|
|
15943
|
-
|
|
15944
|
-
|
|
15945
|
-
|
|
15946
|
-
|
|
15947
|
-
|
|
15948
|
-
|
|
15949
|
-
|
|
15950
|
-
|
|
15951
|
-
|
|
15952
|
-
|
|
15953
|
-
|
|
15954
|
-
|
|
15955
|
-
|
|
15956
|
-
|
|
15957
|
-
|
|
15958
|
-
|
|
15959
|
-
|
|
15960
|
-
|
|
15961
|
-
|
|
15962
|
-
|
|
15963
|
-
|
|
15964
|
-
|
|
15965
|
-
|
|
15966
|
-
|
|
15967
|
-
|
|
15968
|
-
|
|
15969
|
-
|
|
15970
|
-
|
|
15971
|
-
|
|
15972
|
-
|
|
15973
|
-
|
|
15974
|
-
|
|
15975
|
-
|
|
15976
|
-
|
|
15977
|
-
|
|
15978
|
-
|
|
15979
|
-
},
|
|
15980
|
-
|
|
15981
|
-
|
|
15982
|
-
|
|
15983
|
-
|
|
15959
|
+
children: [
|
|
15960
|
+
ASSISTANTS.map((a) => (0, import_jsx_runtime.jsxs)("button", {
|
|
15961
|
+
type: "button",
|
|
15962
|
+
role: "menuitem",
|
|
15963
|
+
className: "nav-item",
|
|
15964
|
+
style: {
|
|
15965
|
+
fontSize: 13,
|
|
15966
|
+
padding: "7px 10px",
|
|
15967
|
+
margin: 0,
|
|
15968
|
+
justifyContent: "space-between"
|
|
15969
|
+
},
|
|
15970
|
+
onClick: () => ask(a.href(offer.question)),
|
|
15971
|
+
children: [(0, import_jsx_runtime.jsx)("span", { children: a.label }), (0, import_jsx_runtime.jsx)(Icon, {
|
|
15972
|
+
name: "arrow-right",
|
|
15973
|
+
size: 14
|
|
15974
|
+
})]
|
|
15975
|
+
}, a.label)),
|
|
15976
|
+
(0, import_jsx_runtime.jsx)("div", { style: {
|
|
15977
|
+
height: 1,
|
|
15978
|
+
background: "var(--border-hairline)",
|
|
15979
|
+
margin: "5px 8px"
|
|
15980
|
+
} }),
|
|
15981
|
+
(0, import_jsx_runtime.jsx)("button", {
|
|
15982
|
+
type: "button",
|
|
15983
|
+
role: "menuitem",
|
|
15984
|
+
className: "nav-item",
|
|
15985
|
+
style: {
|
|
15986
|
+
fontSize: 13,
|
|
15987
|
+
padding: "7px 10px",
|
|
15988
|
+
margin: 0,
|
|
15989
|
+
justifyContent: "space-between",
|
|
15990
|
+
color: "var(--text-muted)"
|
|
15991
|
+
},
|
|
15992
|
+
onClick: () => {
|
|
15993
|
+
setOpen(false);
|
|
15994
|
+
ctx.go(AI_SETUP_PATH);
|
|
15995
|
+
},
|
|
15996
|
+
children: (0, import_jsx_runtime.jsx)("span", { children: "Connect another AI" })
|
|
15997
|
+
})
|
|
15998
|
+
]
|
|
15999
|
+
}) : null,
|
|
16000
|
+
open && !showMenu ? (0, import_jsx_runtime.jsxs)("div", {
|
|
16001
|
+
className: "float",
|
|
16002
|
+
role: "dialog",
|
|
16003
|
+
"aria-label": "Connect your AI first",
|
|
16004
|
+
style: {
|
|
16005
|
+
position: "absolute",
|
|
16006
|
+
right: 0,
|
|
16007
|
+
top: 38,
|
|
16008
|
+
width: 276,
|
|
16009
|
+
padding: 12,
|
|
16010
|
+
zIndex: 50,
|
|
16011
|
+
display: "grid",
|
|
16012
|
+
gap: 9
|
|
16013
|
+
},
|
|
16014
|
+
children: [
|
|
16015
|
+
(0, import_jsx_runtime.jsx)("div", {
|
|
16016
|
+
style: {
|
|
16017
|
+
fontSize: 13.5,
|
|
16018
|
+
fontWeight: 700,
|
|
16019
|
+
color: "var(--text-strong)"
|
|
16020
|
+
},
|
|
16021
|
+
children: "Connect your AI first"
|
|
16022
|
+
}),
|
|
16023
|
+
(0, import_jsx_runtime.jsx)("p", {
|
|
16024
|
+
style: {
|
|
16025
|
+
margin: 0,
|
|
16026
|
+
fontSize: 12.5,
|
|
16027
|
+
color: "var(--text-muted)",
|
|
16028
|
+
lineHeight: 1.5
|
|
16029
|
+
},
|
|
16030
|
+
children: "Connect Claude or ChatGPT once. After that, this button opens it with a question about this report typed in."
|
|
16031
|
+
}),
|
|
16032
|
+
(0, import_jsx_runtime.jsxs)("button", {
|
|
16033
|
+
type: "button",
|
|
16034
|
+
className: "btn-primary",
|
|
16035
|
+
style: {
|
|
16036
|
+
fontSize: 13,
|
|
16037
|
+
padding: "6px 11px",
|
|
16038
|
+
justifySelf: "start",
|
|
16039
|
+
display: "inline-flex",
|
|
16040
|
+
alignItems: "center",
|
|
16041
|
+
gap: 6
|
|
16042
|
+
},
|
|
16043
|
+
onClick: () => {
|
|
16044
|
+
setOpen(false);
|
|
16045
|
+
ctx.go(AI_SETUP_PATH);
|
|
16046
|
+
},
|
|
16047
|
+
children: ["Set it up ", (0, import_jsx_runtime.jsx)(Icon, {
|
|
16048
|
+
name: "arrow-right",
|
|
16049
|
+
size: 14
|
|
16050
|
+
})]
|
|
16051
|
+
}),
|
|
16052
|
+
(0, import_jsx_runtime.jsx)("button", {
|
|
16053
|
+
type: "button",
|
|
16054
|
+
className: "link-btn",
|
|
16055
|
+
style: {
|
|
16056
|
+
fontSize: 12.5,
|
|
16057
|
+
justifySelf: "start"
|
|
16058
|
+
},
|
|
16059
|
+
onClick: () => setAskAnyway(true),
|
|
16060
|
+
children: "Already connected? Ask anyway"
|
|
16061
|
+
})
|
|
16062
|
+
]
|
|
16063
|
+
}) : null
|
|
16064
|
+
]
|
|
15984
16065
|
});
|
|
15985
16066
|
}
|
|
15986
16067
|
function ExportMenu({ send, runId, offered }) {
|
|
@@ -16258,8 +16339,7 @@ function Result({ ctx, runId, markSlug }) {
|
|
|
16258
16339
|
}),
|
|
16259
16340
|
(0, import_jsx_runtime.jsx)("span", { style: { flex: 1 } }),
|
|
16260
16341
|
(0, import_jsx_runtime.jsx)(AskAiMenu, {
|
|
16261
|
-
|
|
16262
|
-
mark: run.markName,
|
|
16342
|
+
run,
|
|
16263
16343
|
ctx
|
|
16264
16344
|
}),
|
|
16265
16345
|
doc ? (0, import_jsx_runtime.jsx)(ExportMenu, {
|
|
@@ -17874,7 +17954,6 @@ function NewClearance({ ctx }) {
|
|
|
17874
17954
|
});
|
|
17875
17955
|
if (needsOwner || searches?.kind === "pickAccount") return (0, import_jsx_runtime.jsx)(CompanyGate, {
|
|
17876
17956
|
ctx,
|
|
17877
|
-
eyebrow: "New clearance",
|
|
17878
17957
|
heading: "New clearance",
|
|
17879
17958
|
line: "Pick a company to run this clearance on."
|
|
17880
17959
|
});
|
|
@@ -17902,19 +17981,8 @@ function NewClearance({ ctx }) {
|
|
|
17902
17981
|
return (0, import_jsx_runtime.jsxs)("div", {
|
|
17903
17982
|
className: "screen",
|
|
17904
17983
|
children: [
|
|
17905
|
-
(0, import_jsx_runtime.jsx)("div", {
|
|
17906
|
-
className: "eyebrow",
|
|
17907
|
-
children: editingSlug ? "Custom search" : "New clearance"
|
|
17908
|
-
}),
|
|
17909
17984
|
(0, import_jsx_runtime.jsx)(CreatedStrip, {}),
|
|
17910
|
-
(0, import_jsx_runtime.jsx)("
|
|
17911
|
-
style: {
|
|
17912
|
-
fontSize: 27,
|
|
17913
|
-
margin: "4px 0 14px",
|
|
17914
|
-
color: "var(--text-strong)"
|
|
17915
|
-
},
|
|
17916
|
-
children: editingSlug ? "Edit a custom search" : "New clearance"
|
|
17917
|
-
}),
|
|
17985
|
+
(0, import_jsx_runtime.jsx)(PageHeader, { title: editingSlug ? "Edit a custom search" : "New clearance" }),
|
|
17918
17986
|
editingSlug ? editingRes && editingRes.kind !== "ok" ? (0, import_jsx_runtime.jsxs)("div", {
|
|
17919
17987
|
className: "notice",
|
|
17920
17988
|
style: { borderColor: "var(--tone-high)" },
|
|
@@ -18565,7 +18633,7 @@ function NewClearance({ ctx }) {
|
|
|
18565
18633
|
nativeControl === "toggle" ? (0, import_jsx_runtime.jsx)("div", {
|
|
18566
18634
|
className: "sunken-block",
|
|
18567
18635
|
style: { marginTop: 12 },
|
|
18568
|
-
children: (0, import_jsx_runtime.jsx)(Lever$
|
|
18636
|
+
children: (0, import_jsx_runtime.jsx)(Lever$2, {
|
|
18569
18637
|
label: "Native-language investigation",
|
|
18570
18638
|
hint: "Native marketplaces and native registers in the language of the countries you named. A clearance already searches the mark transliterated into the scripts its territories register marks in — this is the deeper read.",
|
|
18571
18639
|
on: draft.pick.nativeLanguage,
|
|
@@ -19277,7 +19345,7 @@ function SetupCommand({ route }) {
|
|
|
19277
19345
|
"from a copy of the source."
|
|
19278
19346
|
] });
|
|
19279
19347
|
}
|
|
19280
|
-
function Lever$
|
|
19348
|
+
function Lever$2({ label, hint, on, onToggle, coming }) {
|
|
19281
19349
|
return (0, import_jsx_runtime.jsxs)("button", {
|
|
19282
19350
|
type: "button",
|
|
19283
19351
|
onClick: coming ? void 0 : onToggle,
|
|
@@ -19834,51 +19902,37 @@ function OptionsUnavailable({ kind, onRetry }) {
|
|
|
19834
19902
|
function Submitted({ go, onAnother }) {
|
|
19835
19903
|
return (0, import_jsx_runtime.jsxs)("div", {
|
|
19836
19904
|
className: "screen",
|
|
19837
|
-
children: [
|
|
19838
|
-
|
|
19839
|
-
|
|
19840
|
-
children: "
|
|
19841
|
-
|
|
19842
|
-
|
|
19843
|
-
|
|
19844
|
-
|
|
19845
|
-
|
|
19846
|
-
|
|
19847
|
-
},
|
|
19848
|
-
|
|
19849
|
-
|
|
19850
|
-
|
|
19851
|
-
|
|
19852
|
-
|
|
19853
|
-
|
|
19854
|
-
(0, import_jsx_runtime.jsx)("
|
|
19855
|
-
|
|
19856
|
-
|
|
19857
|
-
|
|
19858
|
-
|
|
19859
|
-
|
|
19860
|
-
|
|
19861
|
-
|
|
19862
|
-
|
|
19863
|
-
|
|
19864
|
-
|
|
19865
|
-
|
|
19866
|
-
|
|
19867
|
-
|
|
19868
|
-
type: "button",
|
|
19869
|
-
className: "btn-primary",
|
|
19870
|
-
onClick: () => go("/portal/clearances"),
|
|
19871
|
-
children: "View in Clearances"
|
|
19872
|
-
}), (0, import_jsx_runtime.jsx)("button", {
|
|
19873
|
-
type: "button",
|
|
19874
|
-
className: "btn-ghost",
|
|
19875
|
-
onClick: onAnother,
|
|
19876
|
-
children: "Start another"
|
|
19877
|
-
})]
|
|
19878
|
-
})
|
|
19879
|
-
]
|
|
19880
|
-
})
|
|
19881
|
-
]
|
|
19905
|
+
children: [(0, import_jsx_runtime.jsx)(PageHeader, { title: "Clearance started" }), (0, import_jsx_runtime.jsxs)("div", {
|
|
19906
|
+
className: "notice prose",
|
|
19907
|
+
children: [
|
|
19908
|
+
(0, import_jsx_runtime.jsx)("b", { children: "It is in the queue" }),
|
|
19909
|
+
(0, import_jsx_runtime.jsx)("p", {
|
|
19910
|
+
style: {
|
|
19911
|
+
margin: "6px 0 0",
|
|
19912
|
+
color: "var(--text-muted)"
|
|
19913
|
+
},
|
|
19914
|
+
children: "It will appear in Clearances, and the entry there tracks it the whole way — including if it stops early."
|
|
19915
|
+
}),
|
|
19916
|
+
(0, import_jsx_runtime.jsxs)("div", {
|
|
19917
|
+
style: {
|
|
19918
|
+
marginTop: 14,
|
|
19919
|
+
display: "flex",
|
|
19920
|
+
gap: 10
|
|
19921
|
+
},
|
|
19922
|
+
children: [(0, import_jsx_runtime.jsx)("button", {
|
|
19923
|
+
type: "button",
|
|
19924
|
+
className: "btn-primary",
|
|
19925
|
+
onClick: () => go("/portal/clearances"),
|
|
19926
|
+
children: "View in Clearances"
|
|
19927
|
+
}), (0, import_jsx_runtime.jsx)("button", {
|
|
19928
|
+
type: "button",
|
|
19929
|
+
className: "btn-ghost",
|
|
19930
|
+
onClick: onAnother,
|
|
19931
|
+
children: "Start another"
|
|
19932
|
+
})]
|
|
19933
|
+
})
|
|
19934
|
+
]
|
|
19935
|
+
})]
|
|
19882
19936
|
});
|
|
19883
19937
|
}
|
|
19884
19938
|
function CreatedStrip() {
|
|
@@ -20515,29 +20569,14 @@ function NewCompany({ ctx }) {
|
|
|
20515
20569
|
const rejected = result && !isOk(result) && result.kind === "reject" ? result.errors : null;
|
|
20516
20570
|
const takenBy = result && !isOk(result) && result.kind === "reject" && result.detail?.code === "key_exists" ? result.detail.key : null;
|
|
20517
20571
|
const otherFailure = result && !isOk(result) && result.kind !== "reject" ? result : null;
|
|
20518
|
-
return (0, import_jsx_runtime.
|
|
20572
|
+
return (0, import_jsx_runtime.jsx)("div", {
|
|
20519
20573
|
className: "screen",
|
|
20520
|
-
children:
|
|
20521
|
-
className: "eyebrow",
|
|
20522
|
-
children: "Company"
|
|
20523
|
-
}), (0, import_jsx_runtime.jsxs)("div", {
|
|
20574
|
+
children: (0, import_jsx_runtime.jsxs)("div", {
|
|
20524
20575
|
className: "measure",
|
|
20525
20576
|
children: [
|
|
20526
|
-
(0, import_jsx_runtime.jsx)(
|
|
20527
|
-
|
|
20528
|
-
|
|
20529
|
-
margin: "0 0 4px",
|
|
20530
|
-
color: "var(--text-strong)"
|
|
20531
|
-
},
|
|
20532
|
-
children: "New company"
|
|
20533
|
-
}),
|
|
20534
|
-
(0, import_jsx_runtime.jsx)("p", {
|
|
20535
|
-
style: {
|
|
20536
|
-
margin: "0 0 18px",
|
|
20537
|
-
color: "var(--text-muted)",
|
|
20538
|
-
fontSize: 14.5
|
|
20539
|
-
},
|
|
20540
|
-
children: "The business whose names you are checking. Only the name is needed; everything else has a default you can change later."
|
|
20577
|
+
(0, import_jsx_runtime.jsx)(PageHeader, {
|
|
20578
|
+
title: "New company",
|
|
20579
|
+
lede: "The business whose names you are checking. Only the name is needed; everything else has a default you can change later."
|
|
20541
20580
|
}),
|
|
20542
20581
|
orgsHeld.length > 1 ? (0, import_jsx_runtime.jsxs)("div", {
|
|
20543
20582
|
style: { marginBottom: 8 },
|
|
@@ -20684,7 +20723,7 @@ function NewCompany({ ctx }) {
|
|
|
20684
20723
|
}) : null]
|
|
20685
20724
|
})
|
|
20686
20725
|
]
|
|
20687
|
-
})
|
|
20726
|
+
})
|
|
20688
20727
|
});
|
|
20689
20728
|
}
|
|
20690
20729
|
function KeyLine({ value, onChange }) {
|
|
@@ -21140,23 +21179,12 @@ function Empty({ onNew }) {
|
|
|
21140
21179
|
function PickCompany({ ctx }) {
|
|
21141
21180
|
return (0, import_jsx_runtime.jsx)(CompanyGate, {
|
|
21142
21181
|
ctx,
|
|
21143
|
-
eyebrow: "Company",
|
|
21144
21182
|
heading: "Custom searches",
|
|
21145
21183
|
line: "Pick a company to see its custom searches."
|
|
21146
21184
|
});
|
|
21147
21185
|
}
|
|
21148
21186
|
function Heading() {
|
|
21149
|
-
return (0, import_jsx_runtime.
|
|
21150
|
-
className: "eyebrow",
|
|
21151
|
-
children: "Custom searches"
|
|
21152
|
-
}), (0, import_jsx_runtime.jsx)("h1", {
|
|
21153
|
-
style: {
|
|
21154
|
-
fontSize: 27,
|
|
21155
|
-
margin: "4px 0 6px",
|
|
21156
|
-
color: "var(--text-strong)"
|
|
21157
|
-
},
|
|
21158
|
-
children: "Custom searches"
|
|
21159
|
-
})] });
|
|
21187
|
+
return (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: (0, import_jsx_runtime.jsx)(PageHeader, { title: "Custom searches" }) });
|
|
21160
21188
|
}
|
|
21161
21189
|
//#endregion
|
|
21162
21190
|
//#region src/screens/Preferences.tsx
|
|
@@ -21172,222 +21200,203 @@ function Preferences({ ctx }) {
|
|
|
21172
21200
|
};
|
|
21173
21201
|
return (0, import_jsx_runtime.jsxs)("div", {
|
|
21174
21202
|
className: "screen",
|
|
21175
|
-
children: [
|
|
21176
|
-
|
|
21177
|
-
|
|
21178
|
-
|
|
21179
|
-
|
|
21180
|
-
|
|
21181
|
-
|
|
21182
|
-
|
|
21183
|
-
|
|
21184
|
-
|
|
21185
|
-
|
|
21186
|
-
|
|
21187
|
-
|
|
21188
|
-
|
|
21189
|
-
|
|
21190
|
-
|
|
21191
|
-
|
|
21192
|
-
|
|
21193
|
-
|
|
21194
|
-
|
|
21195
|
-
|
|
21196
|
-
|
|
21197
|
-
|
|
21198
|
-
|
|
21199
|
-
|
|
21200
|
-
|
|
21201
|
-
|
|
21202
|
-
|
|
21203
|
-
|
|
21204
|
-
|
|
21205
|
-
|
|
21206
|
-
|
|
21207
|
-
|
|
21208
|
-
|
|
21209
|
-
|
|
21210
|
-
|
|
21211
|
-
},
|
|
21212
|
-
|
|
21213
|
-
|
|
21214
|
-
|
|
21215
|
-
|
|
21216
|
-
}
|
|
21217
|
-
(
|
|
21218
|
-
|
|
21219
|
-
|
|
21220
|
-
|
|
21221
|
-
|
|
21222
|
-
|
|
21203
|
+
children: [(0, import_jsx_runtime.jsx)(PageHeader, {
|
|
21204
|
+
title: "Your preferences",
|
|
21205
|
+
lede: "Who you are signed in as, and how the portal looks on this computer."
|
|
21206
|
+
}), (0, import_jsx_runtime.jsxs)("div", {
|
|
21207
|
+
className: "measure",
|
|
21208
|
+
style: { "--screen-measure": "720px" },
|
|
21209
|
+
children: [
|
|
21210
|
+
(0, import_jsx_runtime.jsxs)(Section, {
|
|
21211
|
+
title: "Your sign-in",
|
|
21212
|
+
hint: `Held by ${operatorName(ctx.me.brand)}. Nothing here can be changed from this page.`,
|
|
21213
|
+
children: [
|
|
21214
|
+
(0, import_jsx_runtime.jsxs)("dl", {
|
|
21215
|
+
style: {
|
|
21216
|
+
margin: 0,
|
|
21217
|
+
display: "grid",
|
|
21218
|
+
gridTemplateColumns: "auto 1fr",
|
|
21219
|
+
gap: "8px 18px",
|
|
21220
|
+
fontSize: 14
|
|
21221
|
+
},
|
|
21222
|
+
children: [
|
|
21223
|
+
(0, import_jsx_runtime.jsx)("dt", {
|
|
21224
|
+
style: { color: "var(--text-muted)" },
|
|
21225
|
+
children: "Address"
|
|
21226
|
+
}),
|
|
21227
|
+
(0, import_jsx_runtime.jsx)("dd", {
|
|
21228
|
+
style: {
|
|
21229
|
+
margin: 0,
|
|
21230
|
+
color: "var(--text-strong)",
|
|
21231
|
+
wordBreak: "break-all"
|
|
21232
|
+
},
|
|
21233
|
+
"data-anon": "mark",
|
|
21234
|
+
children: ctx.me.email || "—"
|
|
21235
|
+
}),
|
|
21236
|
+
(0, import_jsx_runtime.jsx)("dt", {
|
|
21237
|
+
style: { color: "var(--text-muted)" },
|
|
21238
|
+
children: "Permissions"
|
|
21239
|
+
}),
|
|
21240
|
+
(0, import_jsx_runtime.jsx)("dd", {
|
|
21241
|
+
style: {
|
|
21242
|
+
margin: 0,
|
|
21243
|
+
color: "var(--text-strong)"
|
|
21244
|
+
},
|
|
21245
|
+
children: permissionsPhrase(ctx.me.permissions)
|
|
21246
|
+
}),
|
|
21247
|
+
(0, import_jsx_runtime.jsx)("dt", {
|
|
21248
|
+
style: { color: "var(--text-muted)" },
|
|
21249
|
+
children: "Access to"
|
|
21250
|
+
}),
|
|
21251
|
+
(0, import_jsx_runtime.jsx)("dd", {
|
|
21252
|
+
style: {
|
|
21253
|
+
margin: 0,
|
|
21254
|
+
color: "var(--text-strong)"
|
|
21255
|
+
},
|
|
21256
|
+
children: ctx.me.access.length ? (0, import_jsx_runtime.jsx)("span", {
|
|
21223
21257
|
"data-anon": "mark",
|
|
21224
|
-
children: ctx.me.
|
|
21225
|
-
}),
|
|
21226
|
-
(0, import_jsx_runtime.jsx)("dt", {
|
|
21227
|
-
style: { color: "var(--text-muted)" },
|
|
21228
|
-
children: "Permissions"
|
|
21229
|
-
}),
|
|
21230
|
-
(0, import_jsx_runtime.jsx)("dd", {
|
|
21231
|
-
style: {
|
|
21232
|
-
margin: 0,
|
|
21233
|
-
color: "var(--text-strong)"
|
|
21234
|
-
},
|
|
21235
|
-
children: permissionsPhrase(ctx.me.permissions)
|
|
21236
|
-
}),
|
|
21237
|
-
(0, import_jsx_runtime.jsx)("dt", {
|
|
21258
|
+
children: accessChips(ctx.me.access).map((c) => c.label).join(", ")
|
|
21259
|
+
}) : (0, import_jsx_runtime.jsx)("span", {
|
|
21238
21260
|
style: { color: "var(--text-muted)" },
|
|
21239
|
-
children: "
|
|
21240
|
-
}),
|
|
21241
|
-
(0, import_jsx_runtime.jsx)("dd", {
|
|
21242
|
-
style: {
|
|
21243
|
-
margin: 0,
|
|
21244
|
-
color: "var(--text-strong)"
|
|
21245
|
-
},
|
|
21246
|
-
children: ctx.me.access.length ? (0, import_jsx_runtime.jsx)("span", {
|
|
21247
|
-
"data-anon": "mark",
|
|
21248
|
-
children: accessChips(ctx.me.access).map((c) => c.label).join(", ")
|
|
21249
|
-
}) : (0, import_jsx_runtime.jsx)("span", {
|
|
21250
|
-
style: { color: "var(--text-muted)" },
|
|
21251
|
-
children: "None recorded against this address."
|
|
21252
|
-
})
|
|
21261
|
+
children: "None recorded against this address."
|
|
21253
21262
|
})
|
|
21254
|
-
|
|
21255
|
-
|
|
21256
|
-
|
|
21257
|
-
|
|
21258
|
-
margin: "14px 0 0",
|
|
21259
|
-
fontSize: 13,
|
|
21260
|
-
color: "var(--text-muted)"
|
|
21261
|
-
},
|
|
21262
|
-
children: [
|
|
21263
|
-
"To change the address, the role or the companies on it, ask ",
|
|
21264
|
-
operatorName(ctx.me.brand),
|
|
21265
|
-
" — enrolment is done for you, not from this page."
|
|
21266
|
-
]
|
|
21267
|
-
}),
|
|
21268
|
-
(0, import_jsx_runtime.jsx)("a", {
|
|
21269
|
-
className: "pill",
|
|
21270
|
-
href: "/portal/sign-out",
|
|
21271
|
-
style: {
|
|
21272
|
-
display: "inline-block",
|
|
21273
|
-
marginTop: 12,
|
|
21274
|
-
textDecoration: "none"
|
|
21275
|
-
},
|
|
21276
|
-
children: "Log out"
|
|
21277
|
-
})
|
|
21278
|
-
]
|
|
21279
|
-
}),
|
|
21280
|
-
(0, import_jsx_runtime.jsxs)(Section, {
|
|
21281
|
-
title: "Appearance",
|
|
21282
|
-
hint: "Applies straight away, and is remembered in this browser.",
|
|
21283
|
-
children: [(0, import_jsx_runtime.jsxs)("div", {
|
|
21284
|
-
style: {
|
|
21285
|
-
display: "flex",
|
|
21286
|
-
gap: 10,
|
|
21287
|
-
flexWrap: "wrap"
|
|
21288
|
-
},
|
|
21289
|
-
children: [(0, import_jsx_runtime.jsx)(ThemeOption, {
|
|
21290
|
-
label: "Light",
|
|
21291
|
-
value: "light",
|
|
21292
|
-
current: theme,
|
|
21293
|
-
onPick: applyTheme
|
|
21294
|
-
}), (0, import_jsx_runtime.jsx)(ThemeOption, {
|
|
21295
|
-
label: "Dark",
|
|
21296
|
-
value: "dark",
|
|
21297
|
-
current: theme,
|
|
21298
|
-
onPick: applyTheme
|
|
21299
|
-
})]
|
|
21300
|
-
}), (0, import_jsx_runtime.jsx)("p", {
|
|
21263
|
+
})
|
|
21264
|
+
]
|
|
21265
|
+
}),
|
|
21266
|
+
(0, import_jsx_runtime.jsxs)("p", {
|
|
21301
21267
|
style: {
|
|
21302
|
-
margin: "
|
|
21268
|
+
margin: "14px 0 0",
|
|
21303
21269
|
fontSize: 13,
|
|
21304
21270
|
color: "var(--text-muted)"
|
|
21305
21271
|
},
|
|
21306
|
-
children:
|
|
21272
|
+
children: [
|
|
21273
|
+
"To change the address, the role or the companies on it, ask ",
|
|
21274
|
+
operatorName(ctx.me.brand),
|
|
21275
|
+
" — enrolment is done for you, not from this page."
|
|
21276
|
+
]
|
|
21277
|
+
}),
|
|
21278
|
+
(0, import_jsx_runtime.jsx)("a", {
|
|
21279
|
+
className: "pill",
|
|
21280
|
+
href: "/portal/sign-out",
|
|
21281
|
+
style: {
|
|
21282
|
+
display: "inline-block",
|
|
21283
|
+
marginTop: 12,
|
|
21284
|
+
textDecoration: "none"
|
|
21285
|
+
},
|
|
21286
|
+
children: "Log out"
|
|
21287
|
+
})
|
|
21288
|
+
]
|
|
21289
|
+
}),
|
|
21290
|
+
(0, import_jsx_runtime.jsxs)(Section, {
|
|
21291
|
+
title: "Appearance",
|
|
21292
|
+
hint: "Applies straight away, and is remembered in this browser.",
|
|
21293
|
+
children: [(0, import_jsx_runtime.jsxs)("div", {
|
|
21294
|
+
style: {
|
|
21295
|
+
display: "flex",
|
|
21296
|
+
gap: 10,
|
|
21297
|
+
flexWrap: "wrap"
|
|
21298
|
+
},
|
|
21299
|
+
children: [(0, import_jsx_runtime.jsx)(ThemeOption, {
|
|
21300
|
+
label: "Light",
|
|
21301
|
+
value: "light",
|
|
21302
|
+
current: theme,
|
|
21303
|
+
onPick: applyTheme
|
|
21304
|
+
}), (0, import_jsx_runtime.jsx)(ThemeOption, {
|
|
21305
|
+
label: "Dark",
|
|
21306
|
+
value: "dark",
|
|
21307
|
+
current: theme,
|
|
21308
|
+
onPick: applyTheme
|
|
21307
21309
|
})]
|
|
21308
|
-
}),
|
|
21309
|
-
|
|
21310
|
-
|
|
21311
|
-
|
|
21312
|
-
|
|
21313
|
-
|
|
21310
|
+
}), (0, import_jsx_runtime.jsx)("p", {
|
|
21311
|
+
style: {
|
|
21312
|
+
margin: "12px 0 0",
|
|
21313
|
+
fontSize: 13,
|
|
21314
|
+
color: "var(--text-muted)"
|
|
21315
|
+
},
|
|
21316
|
+
children: "The same choice is on the top bar, under the circle icon — this page and that button set one and the same setting."
|
|
21317
|
+
})]
|
|
21318
|
+
}),
|
|
21319
|
+
(0, import_jsx_runtime.jsxs)(Section, {
|
|
21320
|
+
title: "Blurring names while you share a screen",
|
|
21321
|
+
hint: "There is one control for this, and it is on the top bar.",
|
|
21322
|
+
children: [
|
|
21323
|
+
(0, import_jsx_runtime.jsxs)("div", {
|
|
21324
|
+
style: {
|
|
21325
|
+
display: "flex",
|
|
21326
|
+
alignItems: "center",
|
|
21327
|
+
gap: 12
|
|
21328
|
+
},
|
|
21329
|
+
children: [(0, import_jsx_runtime.jsxs)("span", {
|
|
21330
|
+
className: "pill",
|
|
21314
21331
|
style: {
|
|
21315
|
-
display: "flex",
|
|
21332
|
+
display: "inline-flex",
|
|
21316
21333
|
alignItems: "center",
|
|
21317
|
-
gap:
|
|
21318
|
-
|
|
21319
|
-
children: [(0, import_jsx_runtime.jsxs)("span", {
|
|
21320
|
-
className: "pill",
|
|
21321
|
-
style: {
|
|
21322
|
-
display: "inline-flex",
|
|
21323
|
-
alignItems: "center",
|
|
21324
|
-
gap: 7,
|
|
21325
|
-
padding: "4px 11px"
|
|
21326
|
-
},
|
|
21327
|
-
children: [(0, import_jsx_runtime.jsx)(Icon, {
|
|
21328
|
-
name: "eye",
|
|
21329
|
-
size: 15
|
|
21330
|
-
}), "Top bar"]
|
|
21331
|
-
}), (0, import_jsx_runtime.jsx)("span", {
|
|
21332
|
-
style: {
|
|
21333
|
-
fontSize: 13.5,
|
|
21334
|
-
color: "var(--text-muted)"
|
|
21335
|
-
},
|
|
21336
|
-
children: "The eye button, to the left of your initials."
|
|
21337
|
-
})]
|
|
21338
|
-
}),
|
|
21339
|
-
(0, import_jsx_runtime.jsx)("p", {
|
|
21340
|
-
style: {
|
|
21341
|
-
margin: "12px 0 0",
|
|
21342
|
-
color: "var(--text-muted)",
|
|
21343
|
-
fontSize: 13.5
|
|
21334
|
+
gap: 7,
|
|
21335
|
+
padding: "4px 11px"
|
|
21344
21336
|
},
|
|
21345
|
-
children:
|
|
21346
|
-
|
|
21347
|
-
|
|
21348
|
-
|
|
21337
|
+
children: [(0, import_jsx_runtime.jsx)(Icon, {
|
|
21338
|
+
name: "eye",
|
|
21339
|
+
size: 15
|
|
21340
|
+
}), "Top bar"]
|
|
21341
|
+
}), (0, import_jsx_runtime.jsx)("span", {
|
|
21349
21342
|
style: {
|
|
21350
|
-
|
|
21351
|
-
|
|
21343
|
+
fontSize: 13.5,
|
|
21344
|
+
color: "var(--text-muted)"
|
|
21352
21345
|
},
|
|
21353
|
-
children:
|
|
21354
|
-
|
|
21355
|
-
|
|
21356
|
-
|
|
21357
|
-
|
|
21358
|
-
|
|
21359
|
-
|
|
21360
|
-
|
|
21361
|
-
|
|
21362
|
-
|
|
21363
|
-
|
|
21364
|
-
|
|
21346
|
+
children: "The eye button, to the left of your initials."
|
|
21347
|
+
})]
|
|
21348
|
+
}),
|
|
21349
|
+
(0, import_jsx_runtime.jsx)("p", {
|
|
21350
|
+
style: {
|
|
21351
|
+
margin: "12px 0 0",
|
|
21352
|
+
color: "var(--text-muted)",
|
|
21353
|
+
fontSize: 13.5
|
|
21354
|
+
},
|
|
21355
|
+
children: "Pressing it blurs every brand name, mark and company the portal puts on screen — in the lists, on this page, in the heading above a report, and the report itself — so you can put the portal on a call or a projector without showing whose names are in clearance. Nothing is hidden from you: the text is still there and still selectable by the page, it is only blurred on screen. Press the button again to bring the names back."
|
|
21356
|
+
}),
|
|
21357
|
+
(0, import_jsx_runtime.jsxs)("div", {
|
|
21358
|
+
className: "notice",
|
|
21359
|
+
style: {
|
|
21360
|
+
marginTop: 14,
|
|
21361
|
+
borderLeftColor: "var(--tone-medium)"
|
|
21362
|
+
},
|
|
21363
|
+
children: [(0, import_jsx_runtime.jsx)("b", {
|
|
21364
|
+
style: { color: "var(--text-strong)" },
|
|
21365
|
+
children: "An open report blurs completely"
|
|
21366
|
+
}), (0, import_jsx_runtime.jsx)("p", {
|
|
21365
21367
|
style: {
|
|
21366
|
-
margin: "
|
|
21367
|
-
color: "var(--text-muted)"
|
|
21368
|
-
fontSize: 13.5
|
|
21368
|
+
margin: "6px 0 0",
|
|
21369
|
+
color: "var(--text-muted)"
|
|
21369
21370
|
},
|
|
21370
|
-
children: "
|
|
21371
|
-
})
|
|
21372
|
-
|
|
21373
|
-
|
|
21374
|
-
(0, import_jsx_runtime.jsxs)("div", {
|
|
21375
|
-
className: "notice quiet",
|
|
21376
|
-
style: { marginTop: 26 },
|
|
21377
|
-
children: [(0, import_jsx_runtime.jsx)("b", {
|
|
21378
|
-
style: { color: "var(--text-strong)" },
|
|
21379
|
-
children: "These two settings stay on this computer"
|
|
21380
|
-
}), (0, import_jsx_runtime.jsxs)("p", {
|
|
21371
|
+
children: "A report is a separate document held inside the page, and it can only be covered whole. With a report open, the button blurs all of it rather than just the names in it. That is deliberate — it is the safer way round for a screen you are sharing."
|
|
21372
|
+
})]
|
|
21373
|
+
}),
|
|
21374
|
+
(0, import_jsx_runtime.jsx)("p", {
|
|
21381
21375
|
style: {
|
|
21382
|
-
margin: "
|
|
21383
|
-
color: "var(--text-muted)"
|
|
21376
|
+
margin: "10px 0 0",
|
|
21377
|
+
color: "var(--text-muted)",
|
|
21378
|
+
fontSize: 13.5
|
|
21384
21379
|
},
|
|
21385
|
-
children:
|
|
21386
|
-
})
|
|
21387
|
-
|
|
21388
|
-
|
|
21389
|
-
|
|
21390
|
-
|
|
21380
|
+
children: "It starts switched off every time you open the portal, so reloading the page brings the names back whether you meant it to or not. Turn it on again before you share."
|
|
21381
|
+
})
|
|
21382
|
+
]
|
|
21383
|
+
}),
|
|
21384
|
+
(0, import_jsx_runtime.jsxs)("div", {
|
|
21385
|
+
className: "notice quiet",
|
|
21386
|
+
style: { marginTop: 26 },
|
|
21387
|
+
children: [(0, import_jsx_runtime.jsx)("b", {
|
|
21388
|
+
style: { color: "var(--text-strong)" },
|
|
21389
|
+
children: "These two settings stay on this computer"
|
|
21390
|
+
}), (0, import_jsx_runtime.jsxs)("p", {
|
|
21391
|
+
style: {
|
|
21392
|
+
margin: "6px 0 0",
|
|
21393
|
+
color: "var(--text-muted)"
|
|
21394
|
+
},
|
|
21395
|
+
children: [operatorName(ctx.me.brand, { lead: true }), " does not store them against your account. The appearance choice is kept by this browser, so it holds for this computer and this browser only — sign in somewhere else, or use a different browser here, and you will get the light theme again until you set it. The screen-share blur is not kept at all: it lasts until you reload or close the page."]
|
|
21396
|
+
})]
|
|
21397
|
+
})
|
|
21398
|
+
]
|
|
21399
|
+
})]
|
|
21391
21400
|
});
|
|
21392
21401
|
}
|
|
21393
21402
|
function ThemeOption({ label, value, current, onPick }) {
|
|
@@ -21664,17 +21673,9 @@ function UseYourAI({ ctx }) {
|
|
|
21664
21673
|
return (0, import_jsx_runtime.jsxs)("div", {
|
|
21665
21674
|
className: "screen ai-screen",
|
|
21666
21675
|
children: [
|
|
21667
|
-
(0, import_jsx_runtime.jsx)(
|
|
21668
|
-
|
|
21669
|
-
|
|
21670
|
-
}),
|
|
21671
|
-
(0, import_jsx_runtime.jsx)("h1", {
|
|
21672
|
-
className: "ai-title",
|
|
21673
|
-
children: "Use your own AI"
|
|
21674
|
-
}),
|
|
21675
|
-
(0, import_jsx_runtime.jsx)("p", {
|
|
21676
|
-
className: "ai-lead",
|
|
21677
|
-
children: "Run and interrogate clearances from the assistant you already use — by voice, by email, or just by asking."
|
|
21676
|
+
(0, import_jsx_runtime.jsx)(PageHeader, {
|
|
21677
|
+
title: "Use your own AI",
|
|
21678
|
+
lede: "Run and interrogate clearances from the assistant you already use — by voice, by email, or just by asking."
|
|
21678
21679
|
}),
|
|
21679
21680
|
(0, import_jsx_runtime.jsxs)("section", {
|
|
21680
21681
|
className: "ctx-card ai-can",
|
|
@@ -21920,7 +21921,6 @@ function Profile({ ctx }) {
|
|
|
21920
21921
|
useUnsaved(dirty);
|
|
21921
21922
|
if (needsOwner || result?.kind === "pickAccount") return (0, import_jsx_runtime.jsx)(CompanyGate, {
|
|
21922
21923
|
ctx,
|
|
21923
|
-
eyebrow: "Company",
|
|
21924
21924
|
heading: "Profile",
|
|
21925
21925
|
line: "Pick a company to see its profile."
|
|
21926
21926
|
});
|
|
@@ -22472,7 +22472,6 @@ function Projects({ ctx }) {
|
|
|
22472
22472
|
const projects = result?.kind === "ok" ? result.value : [];
|
|
22473
22473
|
if (needsOwner || result?.kind === "pickAccount") return (0, import_jsx_runtime.jsx)(CompanyGate, {
|
|
22474
22474
|
ctx,
|
|
22475
|
-
eyebrow: "Company",
|
|
22476
22475
|
heading: "Projects",
|
|
22477
22476
|
line: "Pick a company to see its projects."
|
|
22478
22477
|
});
|
|
@@ -23685,54 +23684,29 @@ function PeopleAccess({ ctx }) {
|
|
|
23685
23684
|
const v = result.value;
|
|
23686
23685
|
const broken = v.people.filter((p) => p.dangling.length > 0);
|
|
23687
23686
|
const where = ctx.organisations.length === 1 ? `at ${ctx.organisations[0]?.name ?? ""}` : "here";
|
|
23688
|
-
return (0, import_jsx_runtime.
|
|
23687
|
+
return (0, import_jsx_runtime.jsx)("div", {
|
|
23689
23688
|
className: "screen",
|
|
23690
|
-
children:
|
|
23691
|
-
className: "eyebrow",
|
|
23692
|
-
children: "People"
|
|
23693
|
-
}), (0, import_jsx_runtime.jsxs)("div", {
|
|
23689
|
+
children: (0, import_jsx_runtime.jsxs)("div", {
|
|
23694
23690
|
className: "measure",
|
|
23695
23691
|
style: { "--screen-measure": "900px" },
|
|
23696
23692
|
children: [
|
|
23697
|
-
(0, import_jsx_runtime.
|
|
23698
|
-
|
|
23699
|
-
|
|
23700
|
-
|
|
23701
|
-
|
|
23702
|
-
|
|
23703
|
-
|
|
23704
|
-
|
|
23705
|
-
|
|
23706
|
-
|
|
23707
|
-
|
|
23708
|
-
fontSize: 27,
|
|
23709
|
-
margin: "0 0 4px",
|
|
23710
|
-
color: "var(--text-strong)"
|
|
23711
|
-
},
|
|
23712
|
-
children: "People"
|
|
23713
|
-
}), (0, import_jsx_runtime.jsxs)("p", {
|
|
23714
|
-
style: {
|
|
23715
|
-
margin: 0,
|
|
23716
|
-
color: "var(--text-muted)",
|
|
23717
|
-
fontSize: 14.5
|
|
23718
|
-
},
|
|
23719
|
-
children: [
|
|
23720
|
-
"Who can use Clearotron ",
|
|
23721
|
-
(0, import_jsx_runtime.jsx)("span", {
|
|
23722
|
-
"data-anon": "mark",
|
|
23723
|
-
children: where
|
|
23724
|
-
}),
|
|
23725
|
-
", what they can do, and which companies they can see."
|
|
23726
|
-
]
|
|
23727
|
-
})]
|
|
23728
|
-
}), (0, import_jsx_runtime.jsx)("button", {
|
|
23693
|
+
(0, import_jsx_runtime.jsx)(PageHeader, {
|
|
23694
|
+
title: "People",
|
|
23695
|
+
lede: (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
23696
|
+
"Who can use Clearotron ",
|
|
23697
|
+
(0, import_jsx_runtime.jsx)("span", {
|
|
23698
|
+
"data-anon": "mark",
|
|
23699
|
+
children: where
|
|
23700
|
+
}),
|
|
23701
|
+
", what they can do, and which companies they can see."
|
|
23702
|
+
] }),
|
|
23703
|
+
actions: (0, import_jsx_runtime.jsx)("button", {
|
|
23729
23704
|
type: "button",
|
|
23730
23705
|
className: "btn-primary",
|
|
23731
|
-
style: { flex: "none" },
|
|
23732
23706
|
disabled: !v.canAdd,
|
|
23733
23707
|
onClick: () => ctx.go(ADD_PERSON.path),
|
|
23734
23708
|
children: "+ Add a person"
|
|
23735
|
-
})
|
|
23709
|
+
})
|
|
23736
23710
|
}),
|
|
23737
23711
|
v.localSignIn ? (0, import_jsx_runtime.jsx)("div", {
|
|
23738
23712
|
className: "notice quiet",
|
|
@@ -23824,12 +23798,17 @@ function PeopleAccess({ ctx }) {
|
|
|
23824
23798
|
children: [(0, import_jsx_runtime.jsx)("thead", { children: (0, import_jsx_runtime.jsxs)("tr", { children: [
|
|
23825
23799
|
(0, import_jsx_runtime.jsx)("th", { children: "Person" }),
|
|
23826
23800
|
(0, import_jsx_runtime.jsx)("th", { children: "Permissions" }),
|
|
23827
|
-
(0, import_jsx_runtime.jsx)("th", { children: "Access to" })
|
|
23801
|
+
(0, import_jsx_runtime.jsx)("th", { children: "Access to" }),
|
|
23802
|
+
(0, import_jsx_runtime.jsx)("th", { "aria-label": "Change or remove" })
|
|
23828
23803
|
] }) }), (0, import_jsx_runtime.jsx)("tbody", { children: v.people.length === 0 ? (0, import_jsx_runtime.jsx)("tr", { children: (0, import_jsx_runtime.jsx)("td", {
|
|
23829
|
-
colSpan:
|
|
23804
|
+
colSpan: 4,
|
|
23830
23805
|
style: { color: "var(--text-muted)" },
|
|
23831
23806
|
children: "Nobody has been given access yet."
|
|
23832
|
-
}) }) : v.people.map((p) => (0, import_jsx_runtime.jsx)(Row, {
|
|
23807
|
+
}) }) : v.people.map((p) => (0, import_jsx_runtime.jsx)(Row, {
|
|
23808
|
+
person: p,
|
|
23809
|
+
you: p.email.toLowerCase() === ctx.me.email.toLowerCase(),
|
|
23810
|
+
onModify: () => ctx.go(`${MODIFY_PERSON.path}?email=${encodeURIComponent(p.email)}`)
|
|
23811
|
+
}, p.email)) })]
|
|
23833
23812
|
})
|
|
23834
23813
|
}),
|
|
23835
23814
|
v.grantsFile ? (0, import_jsx_runtime.jsxs)("p", {
|
|
@@ -23862,7 +23841,7 @@ function PeopleAccess({ ctx }) {
|
|
|
23862
23841
|
}) : null,
|
|
23863
23842
|
(0, import_jsx_runtime.jsx)(Observed, { result: observed })
|
|
23864
23843
|
]
|
|
23865
|
-
})
|
|
23844
|
+
})
|
|
23866
23845
|
});
|
|
23867
23846
|
}
|
|
23868
23847
|
function Observed({ result }) {
|
|
@@ -23958,11 +23937,11 @@ function Observed({ result }) {
|
|
|
23958
23937
|
]
|
|
23959
23938
|
});
|
|
23960
23939
|
}
|
|
23961
|
-
function Row({ person }) {
|
|
23940
|
+
function Row({ person, you, onModify }) {
|
|
23962
23941
|
const chips = accessChips(person.access);
|
|
23963
23942
|
const viewOnly = !person.permissions.run && !person.permissions.manage;
|
|
23964
23943
|
return (0, import_jsx_runtime.jsxs)("tr", { children: [
|
|
23965
|
-
(0, import_jsx_runtime.
|
|
23944
|
+
(0, import_jsx_runtime.jsxs)("td", { children: [(0, import_jsx_runtime.jsx)("span", {
|
|
23966
23945
|
style: {
|
|
23967
23946
|
fontWeight: 700,
|
|
23968
23947
|
color: "var(--text-strong)",
|
|
@@ -23970,7 +23949,15 @@ function Row({ person }) {
|
|
|
23970
23949
|
},
|
|
23971
23950
|
"data-anon": "mark",
|
|
23972
23951
|
children: person.email
|
|
23973
|
-
})
|
|
23952
|
+
}), you ? (0, import_jsx_runtime.jsx)("span", {
|
|
23953
|
+
className: "pill",
|
|
23954
|
+
style: {
|
|
23955
|
+
fontSize: 10.5,
|
|
23956
|
+
padding: "1px 7px",
|
|
23957
|
+
marginLeft: 7
|
|
23958
|
+
},
|
|
23959
|
+
children: "You"
|
|
23960
|
+
}) : null] }),
|
|
23974
23961
|
(0, import_jsx_runtime.jsx)("td", {
|
|
23975
23962
|
style: { color: viewOnly ? "var(--text-muted)" : "var(--text-strong)" },
|
|
23976
23963
|
children: person.listed === false ? (0, import_jsx_runtime.jsx)("span", {
|
|
@@ -23992,7 +23979,23 @@ function Row({ person }) {
|
|
|
23992
23979
|
}) : (0, import_jsx_runtime.jsx)("span", {
|
|
23993
23980
|
style: { color: "var(--text-muted)" },
|
|
23994
23981
|
children: "Nothing yet — signed in, and given no access."
|
|
23995
|
-
}) })
|
|
23982
|
+
}) }),
|
|
23983
|
+
(0, import_jsx_runtime.jsx)("td", {
|
|
23984
|
+
style: {
|
|
23985
|
+
textAlign: "right",
|
|
23986
|
+
whiteSpace: "nowrap"
|
|
23987
|
+
},
|
|
23988
|
+
children: you ? null : (0, import_jsx_runtime.jsx)("button", {
|
|
23989
|
+
type: "button",
|
|
23990
|
+
className: "pill",
|
|
23991
|
+
style: {
|
|
23992
|
+
cursor: "pointer",
|
|
23993
|
+
fontSize: 12
|
|
23994
|
+
},
|
|
23995
|
+
onClick: onModify,
|
|
23996
|
+
children: "Modify"
|
|
23997
|
+
})
|
|
23998
|
+
})
|
|
23996
23999
|
] });
|
|
23997
24000
|
}
|
|
23998
24001
|
//#endregion
|
|
@@ -24020,22 +24023,12 @@ function GiveAccess({ ctx }) {
|
|
|
24020
24023
|
(0, import_react.useEffect)(() => {
|
|
24021
24024
|
if (saved && !kept) ctx.go(PEOPLE.path);
|
|
24022
24025
|
}, [saved, kept]);
|
|
24023
|
-
if (view && isOk(view) && !view.value.canAdd) return (0, import_jsx_runtime.
|
|
24026
|
+
if (view && isOk(view) && !view.value.canAdd) return (0, import_jsx_runtime.jsx)("div", {
|
|
24024
24027
|
className: "screen",
|
|
24025
|
-
children:
|
|
24026
|
-
className: "eyebrow",
|
|
24027
|
-
children: "People"
|
|
24028
|
-
}), (0, import_jsx_runtime.jsxs)("div", {
|
|
24028
|
+
children: (0, import_jsx_runtime.jsxs)("div", {
|
|
24029
24029
|
className: "measure",
|
|
24030
24030
|
style: { "--screen-measure": "640px" },
|
|
24031
|
-
children: [(0, import_jsx_runtime.jsx)("
|
|
24032
|
-
style: {
|
|
24033
|
-
fontSize: 27,
|
|
24034
|
-
margin: "4px 0 12px",
|
|
24035
|
-
color: "var(--text-strong)"
|
|
24036
|
-
},
|
|
24037
|
-
children: "Give someone access to Clearotron"
|
|
24038
|
-
}), (0, import_jsx_runtime.jsx)("div", {
|
|
24031
|
+
children: [(0, import_jsx_runtime.jsx)(PageHeader, { title: "Give someone access to Clearotron" }), (0, import_jsx_runtime.jsx)("div", {
|
|
24039
24032
|
className: "notice quiet",
|
|
24040
24033
|
children: (0, import_jsx_runtime.jsxs)("p", {
|
|
24041
24034
|
style: {
|
|
@@ -24059,7 +24052,7 @@ function GiveAccess({ ctx }) {
|
|
|
24059
24052
|
]
|
|
24060
24053
|
})
|
|
24061
24054
|
})]
|
|
24062
|
-
})
|
|
24055
|
+
})
|
|
24063
24056
|
});
|
|
24064
24057
|
const holdsEverything = ctx.me.access.some((a) => a.kind === "everything");
|
|
24065
24058
|
const wholeOrgs = new Set(ctx.me.genericOrgs);
|
|
@@ -24111,30 +24104,15 @@ function GiveAccess({ ctx }) {
|
|
|
24111
24104
|
}
|
|
24112
24105
|
};
|
|
24113
24106
|
const failure = result && !isOk(result) ? result.kind === "conflict" ? "This Clearotron now signs in one person, so nobody can be added. Nothing was saved." : result.kind === "notFound" ? "You can only give access to what you have access to yourself. Nothing was saved." : result.kind === "reject" ? result.errors.join(" ") : saveFailureText(result, "That could not be saved. Nothing was changed.") : null;
|
|
24114
|
-
return (0, import_jsx_runtime.
|
|
24107
|
+
return (0, import_jsx_runtime.jsx)("div", {
|
|
24115
24108
|
className: "screen",
|
|
24116
|
-
children:
|
|
24117
|
-
className: "eyebrow",
|
|
24118
|
-
children: "People"
|
|
24119
|
-
}), (0, import_jsx_runtime.jsxs)("div", {
|
|
24109
|
+
children: (0, import_jsx_runtime.jsxs)("div", {
|
|
24120
24110
|
className: "measure",
|
|
24121
24111
|
style: { "--screen-measure": "640px" },
|
|
24122
24112
|
children: [
|
|
24123
|
-
(0, import_jsx_runtime.jsx)(
|
|
24124
|
-
|
|
24125
|
-
|
|
24126
|
-
margin: "4px 0 4px",
|
|
24127
|
-
color: "var(--text-strong)"
|
|
24128
|
-
},
|
|
24129
|
-
children: "Give someone access to Clearotron"
|
|
24130
|
-
}),
|
|
24131
|
-
(0, import_jsx_runtime.jsx)("p", {
|
|
24132
|
-
style: {
|
|
24133
|
-
margin: "0 0 22px",
|
|
24134
|
-
color: "var(--text-muted)",
|
|
24135
|
-
fontSize: 14.5
|
|
24136
|
-
},
|
|
24137
|
-
children: "Enter their email, choose what they can see and do, then save. They sign in the same way you do."
|
|
24113
|
+
(0, import_jsx_runtime.jsx)(PageHeader, {
|
|
24114
|
+
title: "Give someone access to Clearotron",
|
|
24115
|
+
lede: "Enter their email, choose what they can see and do, then save. They sign in the same way you do."
|
|
24138
24116
|
}),
|
|
24139
24117
|
(0, import_jsx_runtime.jsx)("label", {
|
|
24140
24118
|
className: "field-label",
|
|
@@ -24163,7 +24141,7 @@ function GiveAccess({ ctx }) {
|
|
|
24163
24141
|
gap: 8,
|
|
24164
24142
|
marginBottom: 6
|
|
24165
24143
|
},
|
|
24166
|
-
children: [(0, import_jsx_runtime.jsx)(Lever, {
|
|
24144
|
+
children: [(0, import_jsx_runtime.jsx)(Lever$1, {
|
|
24167
24145
|
on: permissions.run,
|
|
24168
24146
|
title: "Run clearances",
|
|
24169
24147
|
line: "Start and stop clearances on the companies they can see.",
|
|
@@ -24172,7 +24150,7 @@ function GiveAccess({ ctx }) {
|
|
|
24172
24150
|
...p,
|
|
24173
24151
|
run: !p.run
|
|
24174
24152
|
}))
|
|
24175
|
-
}), (0, import_jsx_runtime.jsx)(Lever, {
|
|
24153
|
+
}), (0, import_jsx_runtime.jsx)(Lever$1, {
|
|
24176
24154
|
on: permissions.manage,
|
|
24177
24155
|
title: "Manage",
|
|
24178
24156
|
line: "Add companies, add people and change settings for the companies they can see.",
|
|
@@ -24202,7 +24180,7 @@ function GiveAccess({ ctx }) {
|
|
|
24202
24180
|
gap: 6,
|
|
24203
24181
|
marginBottom: 8
|
|
24204
24182
|
},
|
|
24205
|
-
children: [holdsEverything ? (0, import_jsx_runtime.jsx)(AttachRow, {
|
|
24183
|
+
children: [holdsEverything ? (0, import_jsx_runtime.jsx)(AttachRow$1, {
|
|
24206
24184
|
on: chosen.everything,
|
|
24207
24185
|
name: "Everything on this Clearotron",
|
|
24208
24186
|
line: "all organisations and companies, including ones added later",
|
|
@@ -24213,7 +24191,7 @@ function GiveAccess({ ctx }) {
|
|
|
24213
24191
|
}))
|
|
24214
24192
|
}) : null, tree.map((t) => (0, import_jsx_runtime.jsxs)("div", {
|
|
24215
24193
|
style: { display: "contents" },
|
|
24216
|
-
children: [t.whole ? (0, import_jsx_runtime.jsx)(AttachRow, {
|
|
24194
|
+
children: [t.whole ? (0, import_jsx_runtime.jsx)(AttachRow$1, {
|
|
24217
24195
|
on: chosen.everything || chosen.orgs.has(t.org.key),
|
|
24218
24196
|
implied: chosen.everything,
|
|
24219
24197
|
name: t.org.name,
|
|
@@ -24223,7 +24201,7 @@ function GiveAccess({ ctx }) {
|
|
|
24223
24201
|
...c,
|
|
24224
24202
|
orgs: toggle(c.orgs, t.org.key)
|
|
24225
24203
|
}))
|
|
24226
|
-
}) : null, t.companies.map((k) => (0, import_jsx_runtime.jsx)(AttachRow, {
|
|
24204
|
+
}) : null, t.companies.map((k) => (0, import_jsx_runtime.jsx)(AttachRow$1, {
|
|
24227
24205
|
sub: t.whole,
|
|
24228
24206
|
on: covered(k),
|
|
24229
24207
|
implied: chosen.everything || chosen.orgs.has(t.org.key),
|
|
@@ -24319,9 +24297,496 @@ function GiveAccess({ ctx }) {
|
|
|
24319
24297
|
})] })
|
|
24320
24298
|
})
|
|
24321
24299
|
]
|
|
24300
|
+
})
|
|
24301
|
+
});
|
|
24302
|
+
}
|
|
24303
|
+
function Lever$1({ on, title, line, disabled, onToggle }) {
|
|
24304
|
+
return (0, import_jsx_runtime.jsxs)("button", {
|
|
24305
|
+
type: "button",
|
|
24306
|
+
className: on ? "lever lever-on" : "lever",
|
|
24307
|
+
"aria-pressed": on,
|
|
24308
|
+
disabled,
|
|
24309
|
+
onClick: onToggle,
|
|
24310
|
+
children: [(0, import_jsx_runtime.jsx)("span", { className: on ? "lever-box lever-box-on" : "lever-box" }), (0, import_jsx_runtime.jsxs)("span", {
|
|
24311
|
+
style: { textAlign: "left" },
|
|
24312
|
+
children: [(0, import_jsx_runtime.jsx)("span", {
|
|
24313
|
+
style: {
|
|
24314
|
+
display: "block",
|
|
24315
|
+
fontWeight: 600,
|
|
24316
|
+
color: "var(--text-strong)"
|
|
24317
|
+
},
|
|
24318
|
+
children: title
|
|
24319
|
+
}), (0, import_jsx_runtime.jsx)("span", {
|
|
24320
|
+
style: {
|
|
24321
|
+
display: "block",
|
|
24322
|
+
fontSize: 12.5,
|
|
24323
|
+
color: "var(--text-muted)"
|
|
24324
|
+
},
|
|
24325
|
+
children: line
|
|
24326
|
+
})]
|
|
24322
24327
|
})]
|
|
24323
24328
|
});
|
|
24324
24329
|
}
|
|
24330
|
+
function AttachRow$1({ on, implied = false, sub = false, name, line, disabled, onToggle }) {
|
|
24331
|
+
return (0, import_jsx_runtime.jsxs)("button", {
|
|
24332
|
+
type: "button",
|
|
24333
|
+
className: `attach-row${on ? " on" : ""}${sub ? " sub" : ""}`,
|
|
24334
|
+
"aria-pressed": on,
|
|
24335
|
+
disabled: disabled || implied,
|
|
24336
|
+
onClick: onToggle,
|
|
24337
|
+
children: [
|
|
24338
|
+
(0, import_jsx_runtime.jsx)("span", { className: on ? "lever-box lever-box-on" : "lever-box" }),
|
|
24339
|
+
(0, import_jsx_runtime.jsx)("span", {
|
|
24340
|
+
style: {
|
|
24341
|
+
color: "var(--text-strong)",
|
|
24342
|
+
fontWeight: sub ? 400 : 600
|
|
24343
|
+
},
|
|
24344
|
+
"data-anon": "mark",
|
|
24345
|
+
children: name
|
|
24346
|
+
}),
|
|
24347
|
+
(0, import_jsx_runtime.jsx)("span", {
|
|
24348
|
+
className: "sub-t",
|
|
24349
|
+
children: line
|
|
24350
|
+
})
|
|
24351
|
+
]
|
|
24352
|
+
});
|
|
24353
|
+
}
|
|
24354
|
+
//#endregion
|
|
24355
|
+
//#region src/screens/ModifyAccess.tsx
|
|
24356
|
+
var emailInQuery = () => (new URLSearchParams(window.location.search).get("email") ?? "").trim().toLowerCase();
|
|
24357
|
+
var heldBy = (person) => ({
|
|
24358
|
+
orgs: new Set(person.access.filter((a) => a.kind === "organisation").map((a) => a.key)),
|
|
24359
|
+
companies: new Set(person.access.filter((a) => a.kind === "company").map((a) => a.key))
|
|
24360
|
+
});
|
|
24361
|
+
var sameSet = (a, b) => a.size === b.size && [...a].every((k) => b.has(k));
|
|
24362
|
+
function ModifyAccess({ ctx }) {
|
|
24363
|
+
const email = emailInQuery();
|
|
24364
|
+
const { result: view } = useLoad(() => api.adminAccess(), []);
|
|
24365
|
+
if (!view) return (0, import_jsx_runtime.jsx)("div", { className: "screen" });
|
|
24366
|
+
if (!isOk(view)) return (0, import_jsx_runtime.jsx)("div", {
|
|
24367
|
+
className: "screen",
|
|
24368
|
+
children: (0, import_jsx_runtime.jsx)("div", {
|
|
24369
|
+
className: "empty",
|
|
24370
|
+
children: (0, import_jsx_runtime.jsx)("p", { children: "This page is not available." })
|
|
24371
|
+
})
|
|
24372
|
+
});
|
|
24373
|
+
const person = view.value.people.find((p) => p.email.toLowerCase() === email) ?? null;
|
|
24374
|
+
if (!person) return (0, import_jsx_runtime.jsx)("div", {
|
|
24375
|
+
className: "screen",
|
|
24376
|
+
children: (0, import_jsx_runtime.jsxs)("div", {
|
|
24377
|
+
className: "measure",
|
|
24378
|
+
style: { "--screen-measure": "640px" },
|
|
24379
|
+
children: [
|
|
24380
|
+
(0, import_jsx_runtime.jsx)(PageHeader, { title: "Modify access" }),
|
|
24381
|
+
(0, import_jsx_runtime.jsx)("div", {
|
|
24382
|
+
className: "notice quiet",
|
|
24383
|
+
children: (0, import_jsx_runtime.jsx)("p", {
|
|
24384
|
+
style: {
|
|
24385
|
+
margin: 0,
|
|
24386
|
+
fontSize: 13.5,
|
|
24387
|
+
color: "var(--text-muted)"
|
|
24388
|
+
},
|
|
24389
|
+
children: "Nobody with that address has access you can see. They may have been removed, or their access may be somewhere you cannot reach."
|
|
24390
|
+
})
|
|
24391
|
+
}),
|
|
24392
|
+
(0, import_jsx_runtime.jsx)("div", {
|
|
24393
|
+
style: { marginTop: 16 },
|
|
24394
|
+
children: (0, import_jsx_runtime.jsx)("button", {
|
|
24395
|
+
type: "button",
|
|
24396
|
+
className: "btn-ghost",
|
|
24397
|
+
onClick: () => ctx.go(PEOPLE.path),
|
|
24398
|
+
children: "Back to People"
|
|
24399
|
+
})
|
|
24400
|
+
})
|
|
24401
|
+
]
|
|
24402
|
+
})
|
|
24403
|
+
});
|
|
24404
|
+
return (0, import_jsx_runtime.jsx)(Form, {
|
|
24405
|
+
ctx,
|
|
24406
|
+
person,
|
|
24407
|
+
view: view.value
|
|
24408
|
+
}, person.email);
|
|
24409
|
+
}
|
|
24410
|
+
function Form({ ctx, person, view }) {
|
|
24411
|
+
const held = heldBy(person);
|
|
24412
|
+
const [permissions, setPermissions] = (0, import_react.useState)(person.permissions);
|
|
24413
|
+
const [chosen, setChosen] = (0, import_react.useState)(held);
|
|
24414
|
+
const [busy, setBusy] = (0, import_react.useState)(false);
|
|
24415
|
+
const [confirming, setConfirming] = (0, import_react.useState)(false);
|
|
24416
|
+
const [saved, setSaved] = (0, import_react.useState)(null);
|
|
24417
|
+
const [gone, setGone] = (0, import_react.useState)(null);
|
|
24418
|
+
const whole = person.covered === true;
|
|
24419
|
+
const holdsEverything = person.access.some((a) => a.kind === "everything");
|
|
24420
|
+
const orgName = (key) => ctx.organisations.find((o) => o.key === key)?.name ?? key;
|
|
24421
|
+
const wholeOrgs = new Set(ctx.me.genericOrgs);
|
|
24422
|
+
const companiesIn = (org) => ctx.ownerKeys.filter((k) => !isGenericKey(k) && ctx.orgOf(k) === org);
|
|
24423
|
+
const tree = ctx.organisations.map((o) => ({
|
|
24424
|
+
org: o,
|
|
24425
|
+
whole: wholeOrgs.has(o.key),
|
|
24426
|
+
companies: companiesIn(o.key)
|
|
24427
|
+
})).filter((t) => t.whole || t.companies.length > 0);
|
|
24428
|
+
const toggle = (set, key) => {
|
|
24429
|
+
const next = new Set(set);
|
|
24430
|
+
if (next.has(key)) next.delete(key);
|
|
24431
|
+
else next.add(key);
|
|
24432
|
+
return next;
|
|
24433
|
+
};
|
|
24434
|
+
const covered = (company) => chosen.companies.has(company) || chosen.orgs.has(ctx.orgOf(company) ?? "");
|
|
24435
|
+
const soloCompanies = [...chosen.companies].filter((k) => !chosen.orgs.has(ctx.orgOf(k) ?? ""));
|
|
24436
|
+
const dirty = !sameSet(chosen.orgs, held.orgs) || !sameSet(chosen.companies, held.companies) || permissions.run !== person.permissions.run || permissions.manage !== person.permissions.manage;
|
|
24437
|
+
useUnsaved(dirty && saved === null && gone === null);
|
|
24438
|
+
const access = [...[...chosen.orgs].map((key) => ({
|
|
24439
|
+
kind: "organisation",
|
|
24440
|
+
key
|
|
24441
|
+
})), ...soloCompanies.map((key) => ({
|
|
24442
|
+
kind: "company",
|
|
24443
|
+
key
|
|
24444
|
+
}))];
|
|
24445
|
+
const leftWithNothing = access.length === 0;
|
|
24446
|
+
const losing = [...[...held.orgs].filter((k) => !chosen.orgs.has(k)).map(orgName), ...[...held.companies].filter((k) => !covered(k)).map((k) => ctx.ownerName(k))];
|
|
24447
|
+
const sentence = accessSentence({
|
|
24448
|
+
who: person.email,
|
|
24449
|
+
permissions,
|
|
24450
|
+
everything: holdsEverything,
|
|
24451
|
+
organisations: [...chosen.orgs].map(orgName),
|
|
24452
|
+
companies: soloCompanies.map((k) => ({
|
|
24453
|
+
name: ctx.ownerName(k),
|
|
24454
|
+
organisation: orgName(ctx.orgOf(k) ?? "")
|
|
24455
|
+
}))
|
|
24456
|
+
});
|
|
24457
|
+
const save = async () => {
|
|
24458
|
+
setBusy(true);
|
|
24459
|
+
try {
|
|
24460
|
+
setSaved(await api.changePerson({
|
|
24461
|
+
email: person.email,
|
|
24462
|
+
permissions,
|
|
24463
|
+
access
|
|
24464
|
+
}));
|
|
24465
|
+
} finally {
|
|
24466
|
+
setBusy(false);
|
|
24467
|
+
}
|
|
24468
|
+
};
|
|
24469
|
+
const remove = async () => {
|
|
24470
|
+
setBusy(true);
|
|
24471
|
+
try {
|
|
24472
|
+
const r = await api.removePerson({ email: person.email });
|
|
24473
|
+
setGone(r);
|
|
24474
|
+
if (isOk(r)) ctx.go(PEOPLE.path);
|
|
24475
|
+
} finally {
|
|
24476
|
+
setBusy(false);
|
|
24477
|
+
}
|
|
24478
|
+
};
|
|
24479
|
+
const failure = (r) => r === null || isOk(r) ? null : r.kind === "conflict" ? "This Clearotron now signs in one person, so nobody else can be changed. Nothing was saved." : r.kind === "notFound" ? "That is not access you can change. Nothing was saved." : r.kind === "reject" ? r.errors.join(" ") : saveFailureText(r, "That could not be saved. Nothing was changed.");
|
|
24480
|
+
const problem = failure(saved) ?? failure(gone);
|
|
24481
|
+
const loses = person.access.length ? person.access.map((a) => a.kind === "everything" ? "everything on this Clearotron" : a.name ?? a.key) : [];
|
|
24482
|
+
const holdsKey = (person.keys ?? 0) > 0;
|
|
24483
|
+
const keyStaysLive = holdsKey && view.keysRevocable !== true;
|
|
24484
|
+
const domain = person.email.startsWith("*@") ? person.email.slice(2) : null;
|
|
24485
|
+
return (0, import_jsx_runtime.jsx)("div", {
|
|
24486
|
+
className: "screen",
|
|
24487
|
+
children: (0, import_jsx_runtime.jsxs)("div", {
|
|
24488
|
+
className: "measure",
|
|
24489
|
+
style: { "--screen-measure": "640px" },
|
|
24490
|
+
children: [
|
|
24491
|
+
(0, import_jsx_runtime.jsx)(PageHeader, {
|
|
24492
|
+
title: "Modify access",
|
|
24493
|
+
lede: (0, import_jsx_runtime.jsx)("b", {
|
|
24494
|
+
style: {
|
|
24495
|
+
color: "var(--text-strong)",
|
|
24496
|
+
wordBreak: "break-all"
|
|
24497
|
+
},
|
|
24498
|
+
"data-anon": "mark",
|
|
24499
|
+
children: person.email
|
|
24500
|
+
})
|
|
24501
|
+
}),
|
|
24502
|
+
(0, import_jsx_runtime.jsx)("div", {
|
|
24503
|
+
className: "field-label",
|
|
24504
|
+
children: "Permissions"
|
|
24505
|
+
}),
|
|
24506
|
+
(0, import_jsx_runtime.jsxs)("div", {
|
|
24507
|
+
style: {
|
|
24508
|
+
display: "flex",
|
|
24509
|
+
flexDirection: "column",
|
|
24510
|
+
gap: 8,
|
|
24511
|
+
marginBottom: 6
|
|
24512
|
+
},
|
|
24513
|
+
children: [(0, import_jsx_runtime.jsx)(Lever, {
|
|
24514
|
+
on: permissions.run,
|
|
24515
|
+
title: "Run clearances",
|
|
24516
|
+
line: "Start and stop clearances on the companies they can see.",
|
|
24517
|
+
disabled: !whole || busy,
|
|
24518
|
+
onToggle: () => setPermissions((p) => ({
|
|
24519
|
+
...p,
|
|
24520
|
+
run: !p.run
|
|
24521
|
+
}))
|
|
24522
|
+
}), (0, import_jsx_runtime.jsx)(Lever, {
|
|
24523
|
+
on: permissions.manage,
|
|
24524
|
+
title: "Manage",
|
|
24525
|
+
line: "Add companies, add people and change settings for the companies they can see.",
|
|
24526
|
+
disabled: !whole || busy,
|
|
24527
|
+
onToggle: () => setPermissions((p) => ({
|
|
24528
|
+
...p,
|
|
24529
|
+
manage: !p.manage
|
|
24530
|
+
}))
|
|
24531
|
+
})]
|
|
24532
|
+
}),
|
|
24533
|
+
(0, import_jsx_runtime.jsx)("p", {
|
|
24534
|
+
style: {
|
|
24535
|
+
margin: "0 0 22px",
|
|
24536
|
+
fontSize: 12.5,
|
|
24537
|
+
color: "var(--text-faint)"
|
|
24538
|
+
},
|
|
24539
|
+
children: whole ? "Everyone can view reports for the companies they can see. Leave both off for a view-only person." : "They have access you can't see, so only someone who can see all of it can change their permissions."
|
|
24540
|
+
}),
|
|
24541
|
+
(0, import_jsx_runtime.jsx)("div", {
|
|
24542
|
+
className: "field-label",
|
|
24543
|
+
children: "Access to"
|
|
24544
|
+
}),
|
|
24545
|
+
(0, import_jsx_runtime.jsxs)("div", {
|
|
24546
|
+
style: {
|
|
24547
|
+
display: "flex",
|
|
24548
|
+
flexDirection: "column",
|
|
24549
|
+
gap: 6,
|
|
24550
|
+
marginBottom: 8
|
|
24551
|
+
},
|
|
24552
|
+
children: [holdsEverything ? (0, import_jsx_runtime.jsx)(AttachRow, {
|
|
24553
|
+
on: true,
|
|
24554
|
+
name: "Everything on this Clearotron",
|
|
24555
|
+
line: "all organisations and companies, including ones added later",
|
|
24556
|
+
disabled: true,
|
|
24557
|
+
onToggle: () => {}
|
|
24558
|
+
}) : null, tree.map((t) => (0, import_jsx_runtime.jsxs)("div", {
|
|
24559
|
+
style: { display: "contents" },
|
|
24560
|
+
children: [t.whole ? (0, import_jsx_runtime.jsx)(AttachRow, {
|
|
24561
|
+
on: chosen.orgs.has(t.org.key),
|
|
24562
|
+
name: t.org.name,
|
|
24563
|
+
line: "every company in it, including ones added later",
|
|
24564
|
+
disabled: busy,
|
|
24565
|
+
onToggle: () => setChosen((c) => ({
|
|
24566
|
+
...c,
|
|
24567
|
+
orgs: toggle(c.orgs, t.org.key)
|
|
24568
|
+
}))
|
|
24569
|
+
}) : null, t.companies.map((k) => (0, import_jsx_runtime.jsx)(AttachRow, {
|
|
24570
|
+
sub: t.whole,
|
|
24571
|
+
on: covered(k),
|
|
24572
|
+
implied: chosen.orgs.has(t.org.key),
|
|
24573
|
+
name: ctx.ownerName(k),
|
|
24574
|
+
line: t.whole ? "company" : `company in ${t.org.name}`,
|
|
24575
|
+
disabled: busy,
|
|
24576
|
+
onToggle: () => setChosen((c) => ({
|
|
24577
|
+
...c,
|
|
24578
|
+
companies: toggle(c.companies, k)
|
|
24579
|
+
}))
|
|
24580
|
+
}, k))]
|
|
24581
|
+
}, t.org.key))]
|
|
24582
|
+
}),
|
|
24583
|
+
(0, import_jsx_runtime.jsxs)("p", {
|
|
24584
|
+
style: {
|
|
24585
|
+
margin: "0 0 22px",
|
|
24586
|
+
fontSize: 12.5,
|
|
24587
|
+
color: "var(--text-faint)"
|
|
24588
|
+
},
|
|
24589
|
+
children: ["Untick a row to take that access away.", whole ? "" : " You are seeing the part of their access you can reach; the rest is not shown and is not changed."]
|
|
24590
|
+
}),
|
|
24591
|
+
(0, import_jsx_runtime.jsx)("div", {
|
|
24592
|
+
className: "notice quiet",
|
|
24593
|
+
style: { marginBottom: 18 },
|
|
24594
|
+
children: (0, import_jsx_runtime.jsxs)("p", {
|
|
24595
|
+
style: {
|
|
24596
|
+
margin: 0,
|
|
24597
|
+
fontSize: 13.5,
|
|
24598
|
+
color: "var(--text-muted)"
|
|
24599
|
+
},
|
|
24600
|
+
"data-anon": "mark",
|
|
24601
|
+
children: [sentence, losing.length ? (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [" ", (0, import_jsx_runtime.jsxs)("b", {
|
|
24602
|
+
style: { color: "var(--text-strong)" },
|
|
24603
|
+
children: [
|
|
24604
|
+
"They lose ",
|
|
24605
|
+
losing.join(", "),
|
|
24606
|
+
"."
|
|
24607
|
+
]
|
|
24608
|
+
})] }) : null]
|
|
24609
|
+
})
|
|
24610
|
+
}),
|
|
24611
|
+
problem ? (0, import_jsx_runtime.jsx)("div", {
|
|
24612
|
+
className: "notice",
|
|
24613
|
+
style: {
|
|
24614
|
+
borderColor: "var(--tone-high)",
|
|
24615
|
+
marginBottom: 14
|
|
24616
|
+
},
|
|
24617
|
+
children: (0, import_jsx_runtime.jsx)("p", {
|
|
24618
|
+
style: {
|
|
24619
|
+
margin: 0,
|
|
24620
|
+
fontSize: 13.5
|
|
24621
|
+
},
|
|
24622
|
+
children: problem
|
|
24623
|
+
})
|
|
24624
|
+
}) : null,
|
|
24625
|
+
saved && isOk(saved) ? (0, import_jsx_runtime.jsx)("div", {
|
|
24626
|
+
className: "notice",
|
|
24627
|
+
style: {
|
|
24628
|
+
borderColor: "var(--tone-medium)",
|
|
24629
|
+
marginBottom: 14
|
|
24630
|
+
},
|
|
24631
|
+
children: (0, import_jsx_runtime.jsxs)("p", {
|
|
24632
|
+
style: {
|
|
24633
|
+
margin: 0,
|
|
24634
|
+
fontSize: 13.5
|
|
24635
|
+
},
|
|
24636
|
+
children: ["Saved. ", saved.value.switchesApplied ? permissionsPhrase(permissions) + "." : (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
24637
|
+
"Their permissions stay as they were: ",
|
|
24638
|
+
permissionsPhrase(person.permissions),
|
|
24639
|
+
". They have access you cannot see, and permissions apply everywhere a person has access."
|
|
24640
|
+
] })]
|
|
24641
|
+
})
|
|
24642
|
+
}) : null,
|
|
24643
|
+
(0, import_jsx_runtime.jsxs)("div", {
|
|
24644
|
+
style: {
|
|
24645
|
+
display: "flex",
|
|
24646
|
+
gap: 10,
|
|
24647
|
+
alignItems: "center"
|
|
24648
|
+
},
|
|
24649
|
+
children: [
|
|
24650
|
+
(0, import_jsx_runtime.jsx)("button", {
|
|
24651
|
+
type: "button",
|
|
24652
|
+
className: "btn-primary",
|
|
24653
|
+
disabled: !dirty || busy || leftWithNothing,
|
|
24654
|
+
onClick: () => void save(),
|
|
24655
|
+
children: busy && !confirming ? "Saving…" : "Save changes"
|
|
24656
|
+
}),
|
|
24657
|
+
(0, import_jsx_runtime.jsx)("button", {
|
|
24658
|
+
type: "button",
|
|
24659
|
+
className: "btn-ghost",
|
|
24660
|
+
onClick: () => ctx.go(PEOPLE.path),
|
|
24661
|
+
children: "Cancel"
|
|
24662
|
+
}),
|
|
24663
|
+
leftWithNothing ? (0, import_jsx_runtime.jsx)("span", {
|
|
24664
|
+
style: {
|
|
24665
|
+
fontSize: 12.5,
|
|
24666
|
+
color: "var(--text-faint)"
|
|
24667
|
+
},
|
|
24668
|
+
children: "Nothing is ticked. Leave them at least one, or remove them below."
|
|
24669
|
+
}) : null
|
|
24670
|
+
]
|
|
24671
|
+
}),
|
|
24672
|
+
(0, import_jsx_runtime.jsx)("div", {
|
|
24673
|
+
style: {
|
|
24674
|
+
marginTop: 34,
|
|
24675
|
+
paddingTop: 18,
|
|
24676
|
+
borderTop: "1px solid var(--border-hairline)",
|
|
24677
|
+
display: "flex",
|
|
24678
|
+
flexDirection: "column",
|
|
24679
|
+
gap: 10,
|
|
24680
|
+
alignItems: "flex-start"
|
|
24681
|
+
},
|
|
24682
|
+
children: confirming ? (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [(0, import_jsx_runtime.jsx)("div", {
|
|
24683
|
+
className: "notice",
|
|
24684
|
+
style: {
|
|
24685
|
+
borderColor: "var(--tone-high)",
|
|
24686
|
+
margin: 0,
|
|
24687
|
+
width: "100%"
|
|
24688
|
+
},
|
|
24689
|
+
children: (0, import_jsx_runtime.jsxs)("p", {
|
|
24690
|
+
style: {
|
|
24691
|
+
margin: 0,
|
|
24692
|
+
fontSize: 13.5
|
|
24693
|
+
},
|
|
24694
|
+
children: [
|
|
24695
|
+
(0, import_jsx_runtime.jsx)("b", {
|
|
24696
|
+
"data-anon": "mark",
|
|
24697
|
+
children: person.email
|
|
24698
|
+
}),
|
|
24699
|
+
" ",
|
|
24700
|
+
whole ? (0, import_jsx_runtime.jsxs)("b", { children: [
|
|
24701
|
+
"loses access to ",
|
|
24702
|
+
loses.length ? loses.join(" and ") : "this Clearotron",
|
|
24703
|
+
" straight away,"
|
|
24704
|
+
] }) : (0, import_jsx_runtime.jsxs)("b", { children: [
|
|
24705
|
+
"loses ",
|
|
24706
|
+
loses.join(" and "),
|
|
24707
|
+
" straight away,"
|
|
24708
|
+
] }),
|
|
24709
|
+
" ",
|
|
24710
|
+
keyStaysLive ? (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
24711
|
+
"here. Their AI was issued a key this Clearotron cannot withdraw — it was started without a revocation list — so that key keeps working until it expires.",
|
|
24712
|
+
" ",
|
|
24713
|
+
(0, import_jsx_runtime.jsx)("b", {
|
|
24714
|
+
className: "mono",
|
|
24715
|
+
children: "clearotron doctor"
|
|
24716
|
+
}),
|
|
24717
|
+
" reports it.",
|
|
24718
|
+
" "
|
|
24719
|
+
] }) : (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: ["here and through their AI.", " "] }),
|
|
24720
|
+
holdsKey && !keyStaysLive ? (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
24721
|
+
"Their AI’s key is withdrawn at the same time;",
|
|
24722
|
+
" ",
|
|
24723
|
+
(0, import_jsx_runtime.jsx)("b", {
|
|
24724
|
+
className: "mono",
|
|
24725
|
+
children: "clearotron doctor"
|
|
24726
|
+
}),
|
|
24727
|
+
" says whether the connector has picked it up.",
|
|
24728
|
+
" "
|
|
24729
|
+
] }) : null,
|
|
24730
|
+
whole ? "To stop them reaching your sign-in page, take them off your login system too." : "They keep the access you cannot see.",
|
|
24731
|
+
domain ? (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [" ", (0, import_jsx_runtime.jsxs)("b", { children: [
|
|
24732
|
+
"This takes access away from everyone with an address at ",
|
|
24733
|
+
(0, import_jsx_runtime.jsx)("span", {
|
|
24734
|
+
"data-anon": "mark",
|
|
24735
|
+
children: domain
|
|
24736
|
+
}),
|
|
24737
|
+
"."
|
|
24738
|
+
] })] }) : null
|
|
24739
|
+
]
|
|
24740
|
+
})
|
|
24741
|
+
}), (0, import_jsx_runtime.jsxs)("div", {
|
|
24742
|
+
style: {
|
|
24743
|
+
display: "flex",
|
|
24744
|
+
gap: 8
|
|
24745
|
+
},
|
|
24746
|
+
children: [(0, import_jsx_runtime.jsx)("button", {
|
|
24747
|
+
type: "button",
|
|
24748
|
+
className: "pill",
|
|
24749
|
+
style: {
|
|
24750
|
+
cursor: "pointer",
|
|
24751
|
+
fontSize: 12,
|
|
24752
|
+
borderColor: "var(--tone-high)"
|
|
24753
|
+
},
|
|
24754
|
+
disabled: busy,
|
|
24755
|
+
onClick: () => void remove(),
|
|
24756
|
+
children: busy ? "Working…" : "Confirm — remove"
|
|
24757
|
+
}), (0, import_jsx_runtime.jsx)("button", {
|
|
24758
|
+
type: "button",
|
|
24759
|
+
className: "pill",
|
|
24760
|
+
style: {
|
|
24761
|
+
cursor: "pointer",
|
|
24762
|
+
fontSize: 12
|
|
24763
|
+
},
|
|
24764
|
+
onClick: () => setConfirming(false),
|
|
24765
|
+
children: "Cancel"
|
|
24766
|
+
})]
|
|
24767
|
+
})] }) : (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [(0, import_jsx_runtime.jsx)("button", {
|
|
24768
|
+
type: "button",
|
|
24769
|
+
className: "pill",
|
|
24770
|
+
style: {
|
|
24771
|
+
cursor: "pointer",
|
|
24772
|
+
fontSize: 12
|
|
24773
|
+
},
|
|
24774
|
+
disabled: busy,
|
|
24775
|
+
onClick: () => setConfirming(true),
|
|
24776
|
+
children: whole ? domain ? `Remove everyone at ${domain}` : "Remove from Clearotron" : `Remove from ${[...held.orgs].map(orgName).join(", ") || "here"}`
|
|
24777
|
+
}), whole ? null : (0, import_jsx_runtime.jsx)("p", {
|
|
24778
|
+
style: {
|
|
24779
|
+
margin: 0,
|
|
24780
|
+
fontSize: 12.5,
|
|
24781
|
+
color: "var(--text-faint)"
|
|
24782
|
+
},
|
|
24783
|
+
children: "They keep the access you cannot see."
|
|
24784
|
+
})] })
|
|
24785
|
+
})
|
|
24786
|
+
]
|
|
24787
|
+
})
|
|
24788
|
+
});
|
|
24789
|
+
}
|
|
24325
24790
|
function Lever({ on, title, line, disabled, onToggle }) {
|
|
24326
24791
|
return (0, import_jsx_runtime.jsxs)("button", {
|
|
24327
24792
|
type: "button",
|
|
@@ -24393,7 +24858,7 @@ function About() {
|
|
|
24393
24858
|
if (failed) return (0, import_jsx_runtime.jsxs)("section", {
|
|
24394
24859
|
className: "screen",
|
|
24395
24860
|
children: [
|
|
24396
|
-
(0, import_jsx_runtime.jsx)(
|
|
24861
|
+
(0, import_jsx_runtime.jsx)(PageHeader, { title: "About" }),
|
|
24397
24862
|
(0, import_jsx_runtime.jsx)("p", { children: "This deployment could not report which build it is running. That is a fault, not a configuration choice — the source offer below is incomplete without it." }),
|
|
24398
24863
|
(0, import_jsx_runtime.jsxs)("p", { children: ["Source: ", (0, import_jsx_runtime.jsx)("a", {
|
|
24399
24864
|
href: "https://github.com/CordilleraSarl/Clearotron",
|
|
@@ -24403,13 +24868,13 @@ function About() {
|
|
|
24403
24868
|
});
|
|
24404
24869
|
if (!info) return (0, import_jsx_runtime.jsxs)("section", {
|
|
24405
24870
|
className: "screen",
|
|
24406
|
-
children: [(0, import_jsx_runtime.jsx)(
|
|
24871
|
+
children: [(0, import_jsx_runtime.jsx)(PageHeader, { title: "About" }), (0, import_jsx_runtime.jsx)("p", { children: "Loading…" })]
|
|
24407
24872
|
});
|
|
24408
24873
|
const shortSha = info.commit ? info.commit.slice(0, 12) : null;
|
|
24409
24874
|
return (0, import_jsx_runtime.jsxs)("section", {
|
|
24410
24875
|
className: "screen",
|
|
24411
24876
|
children: [
|
|
24412
|
-
(0, import_jsx_runtime.
|
|
24877
|
+
(0, import_jsx_runtime.jsx)(PageHeader, { title: `About ${info.name}` }),
|
|
24413
24878
|
(0, import_jsx_runtime.jsxs)("dl", { children: [
|
|
24414
24879
|
(0, import_jsx_runtime.jsx)("dt", { children: "Product" }),
|
|
24415
24880
|
(0, import_jsx_runtime.jsxs)("dd", { children: [info.name, info.version ? ` ${info.version}` : ""] }),
|
|
@@ -24506,41 +24971,27 @@ function About() {
|
|
|
24506
24971
|
function NotYet({ title, phase, what }) {
|
|
24507
24972
|
return (0, import_jsx_runtime.jsxs)("div", {
|
|
24508
24973
|
className: "screen",
|
|
24509
|
-
children: [
|
|
24510
|
-
|
|
24511
|
-
|
|
24512
|
-
children: title
|
|
24513
|
-
}),
|
|
24514
|
-
(0, import_jsx_runtime.jsx)("h1", {
|
|
24974
|
+
children: [(0, import_jsx_runtime.jsx)(PageHeader, { title }), (0, import_jsx_runtime.jsxs)("div", {
|
|
24975
|
+
className: "notice quiet",
|
|
24976
|
+
children: [(0, import_jsx_runtime.jsx)("p", {
|
|
24515
24977
|
style: {
|
|
24516
|
-
|
|
24517
|
-
|
|
24518
|
-
color: "var(--text-strong)"
|
|
24978
|
+
margin: 0,
|
|
24979
|
+
color: "var(--text-muted)"
|
|
24519
24980
|
},
|
|
24520
|
-
children:
|
|
24521
|
-
}),
|
|
24522
|
-
|
|
24523
|
-
|
|
24524
|
-
|
|
24525
|
-
|
|
24526
|
-
|
|
24527
|
-
|
|
24528
|
-
|
|
24529
|
-
|
|
24530
|
-
|
|
24531
|
-
|
|
24532
|
-
|
|
24533
|
-
|
|
24534
|
-
color: "var(--text-faint)"
|
|
24535
|
-
},
|
|
24536
|
-
children: [
|
|
24537
|
-
"Being built — ",
|
|
24538
|
-
phase,
|
|
24539
|
-
"."
|
|
24540
|
-
]
|
|
24541
|
-
})]
|
|
24542
|
-
})
|
|
24543
|
-
]
|
|
24981
|
+
children: what
|
|
24982
|
+
}), (0, import_jsx_runtime.jsxs)("p", {
|
|
24983
|
+
style: {
|
|
24984
|
+
margin: "8px 0 0",
|
|
24985
|
+
fontSize: 13,
|
|
24986
|
+
color: "var(--text-faint)"
|
|
24987
|
+
},
|
|
24988
|
+
children: [
|
|
24989
|
+
"Being built — ",
|
|
24990
|
+
phase,
|
|
24991
|
+
"."
|
|
24992
|
+
]
|
|
24993
|
+
})]
|
|
24994
|
+
})]
|
|
24544
24995
|
});
|
|
24545
24996
|
}
|
|
24546
24997
|
var ownerKey = (ctx) => `${ctx.owner ?? "*"}#${ctx.visit}`;
|
|
@@ -24570,6 +25021,7 @@ function screen(id, ctx) {
|
|
|
24570
25021
|
case "about": return (0, import_jsx_runtime.jsx)(About, {});
|
|
24571
25022
|
case "people": return (0, import_jsx_runtime.jsx)(PeopleAccess, { ctx });
|
|
24572
25023
|
case "people.add": return (0, import_jsx_runtime.jsx)(GiveAccess, { ctx });
|
|
25024
|
+
case "people.modify": return (0, import_jsx_runtime.jsx)(ModifyAccess, { ctx });
|
|
24573
25025
|
case "admin":
|
|
24574
25026
|
case "admin.config": return (0, import_jsx_runtime.jsx)(GlobalConfig, { ctx });
|
|
24575
25027
|
default: return (0, import_jsx_runtime.jsx)(NotYet, {
|