@burdenoff/fe-libs 2026.1030.1 → 2026.1030.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/dist/connections/ConnectionDetailsTab.d.ts +4 -1
- package/dist/connections/ConnectionDetailsTab.js +18 -15
- package/dist/connections/ConnectionDialog.d.ts +8 -2
- package/dist/connections/ConnectionDialog.js +18 -17
- package/dist/connections/ConnectionDialogPanel.d.ts +3 -1
- package/dist/connections/ConnectionDialogPanel.js +141 -135
- package/dist/connections/ShareConnectionDialog.d.ts +23 -0
- package/dist/connections/ShareConnectionDialog.js +146 -0
- package/dist/connections/SharePanels.d.ts +32 -0
- package/dist/connections/SharePanels.js +158 -0
- package/dist/connections/VisibilityChoice.d.ts +12 -0
- package/dist/connections/VisibilityChoice.js +60 -0
- package/dist/connections/api.d.ts +12 -1
- package/dist/connections/api.js +1 -1
- package/dist/connections/connectionFlow.d.ts +6 -1
- package/dist/connections/connectionFlow.js +1 -1
- package/dist/connections/index.d.ts +4 -1
- package/dist/connections/sharingApi.d.ts +28 -0
- package/dist/connections/sharingApi.js +215 -0
- package/dist/connections/types.d.ts +31 -0
- package/dist/connections/useConnectionSharingDraft.d.ts +40 -0
- package/dist/connections/useConnectionSharingDraft.js +93 -0
- package/dist/connections.js +12 -9
- package/dist/shared/assistant/ui/compact/AssistantDiscardDraftDialog.js +1 -0
- package/dist/shared/assistant/ui/compact/AssistantVoiceReady.js +34 -30
- package/dist/ui/modal-shell.d.ts +6 -1
- package/dist/ui/modal-shell.js +11 -11
- package/package.json +1 -1
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { cn as e } from "../lib/utils.js";
|
|
2
|
+
import { englishTranslator as t } from "../credentials/translate.js";
|
|
3
|
+
import { VisibilityChoice as n } from "./VisibilityChoice.js";
|
|
4
|
+
import { DIALOG_Z as r, OVERLAY_Z as i, SURFACE_CLASS as a } from "./frame.js";
|
|
5
|
+
import { createConnectionSharingApi as o } from "./sharingApi.js";
|
|
6
|
+
import { principalKey as s, useConnectionSharingDraft as c } from "./useConnectionSharingDraft.js";
|
|
7
|
+
import { GrantList as l, OwnerField as u, PrincipalSearch as d } from "./SharePanels.js";
|
|
8
|
+
import { useId as f, useMemo as p, useRef as m } from "react";
|
|
9
|
+
import { Loader2 as h, X as g } from "lucide-react";
|
|
10
|
+
import { Fragment as _, jsx as v, jsxs as y } from "react/jsx-runtime";
|
|
11
|
+
import * as b from "@radix-ui/react-dialog";
|
|
12
|
+
//#region src/connections/ShareConnectionDialog.tsx
|
|
13
|
+
var x = "share-connection-dialog-title", S = ({ draft: e, idPrefix: t, translate: r }) => {
|
|
14
|
+
let i = new Set([...e.grants.map((e) => s(e.principalType, e.principalId)), s("USER", e.ownerId)]);
|
|
15
|
+
return /* @__PURE__ */ y(_, { children: [
|
|
16
|
+
!e.editable && /* @__PURE__ */ v("p", {
|
|
17
|
+
className: "rounded-md border border-border-subtle bg-accent/30 p-3 text-xs text-text-secondary",
|
|
18
|
+
children: r("integrations.sharing.readOnly", "Only the owner, editors and workspace admins can change who can use this connection.")
|
|
19
|
+
}),
|
|
20
|
+
/* @__PURE__ */ v(u, {
|
|
21
|
+
id: `${t}-owner`,
|
|
22
|
+
ownerId: e.ownerId,
|
|
23
|
+
onChange: e.setOwnerId,
|
|
24
|
+
changeable: e.administrator,
|
|
25
|
+
members: e.principals.filter((e) => e.principalType === "USER"),
|
|
26
|
+
ownerLabel: e.labelOf("USER", e.ownerId),
|
|
27
|
+
translate: r
|
|
28
|
+
}),
|
|
29
|
+
/* @__PURE__ */ v(n, {
|
|
30
|
+
value: e.visibility,
|
|
31
|
+
onChange: e.setVisibility,
|
|
32
|
+
translate: r,
|
|
33
|
+
idPrefix: t,
|
|
34
|
+
disabled: !e.editable
|
|
35
|
+
}),
|
|
36
|
+
/* @__PURE__ */ v(d, {
|
|
37
|
+
id: `${t}-add`,
|
|
38
|
+
principals: e.principals,
|
|
39
|
+
excluded: i,
|
|
40
|
+
onAdd: e.addGrant,
|
|
41
|
+
disabled: !e.editable,
|
|
42
|
+
translate: r
|
|
43
|
+
}),
|
|
44
|
+
/* @__PURE__ */ v(l, {
|
|
45
|
+
idPrefix: t,
|
|
46
|
+
grants: e.grants,
|
|
47
|
+
visibility: e.visibility,
|
|
48
|
+
labelOf: e.labelOf,
|
|
49
|
+
onRole: e.setRole,
|
|
50
|
+
onRemove: e.removeGrant,
|
|
51
|
+
disabled: !e.editable,
|
|
52
|
+
translate: r
|
|
53
|
+
})
|
|
54
|
+
] });
|
|
55
|
+
};
|
|
56
|
+
function C(e, t, n) {
|
|
57
|
+
return e.loadError ? /* @__PURE__ */ v("p", {
|
|
58
|
+
role: "alert",
|
|
59
|
+
className: "text-sm text-status-error-text",
|
|
60
|
+
children: e.loadError
|
|
61
|
+
}) : e.sharing ? /* @__PURE__ */ v(S, {
|
|
62
|
+
draft: e,
|
|
63
|
+
idPrefix: t,
|
|
64
|
+
translate: n
|
|
65
|
+
}) : /* @__PURE__ */ y("div", {
|
|
66
|
+
className: "flex items-center gap-2 text-sm text-text-secondary",
|
|
67
|
+
children: [/* @__PURE__ */ v(h, {
|
|
68
|
+
size: 16,
|
|
69
|
+
className: "animate-spin",
|
|
70
|
+
"aria-hidden": !0
|
|
71
|
+
}), n("integrations.sharing.loading", "Loading sharing…")]
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
var w = ({ open: n, onClose: s, client: l, connectionId: u, workspaceId: d, translate: _ = t, onShared: S, api: w }) => {
|
|
75
|
+
let T = p(() => w ?? o(l), [w, l]), E = f(), D = c(T, n, u, d), O = m(null), k = m(null), A = async () => {
|
|
76
|
+
let e = await D.save();
|
|
77
|
+
e && (S?.(e), s());
|
|
78
|
+
};
|
|
79
|
+
return /* @__PURE__ */ v(b.Root, {
|
|
80
|
+
open: n,
|
|
81
|
+
onOpenChange: (e) => !e && s(),
|
|
82
|
+
children: /* @__PURE__ */ y(b.Portal, { children: [/* @__PURE__ */ v(b.Overlay, {
|
|
83
|
+
className: "fixed inset-0 bg-bg-overlay animate-in fade-in-0 duration-200",
|
|
84
|
+
style: { zIndex: i }
|
|
85
|
+
}), /* @__PURE__ */ y(b.Content, {
|
|
86
|
+
ref: O,
|
|
87
|
+
onOpenAutoFocus: (e) => {
|
|
88
|
+
k.current = document.activeElement instanceof HTMLElement ? document.activeElement : null, e.preventDefault(), O.current?.focus({ preventScroll: !0 });
|
|
89
|
+
},
|
|
90
|
+
onCloseAutoFocus: (e) => {
|
|
91
|
+
e.preventDefault();
|
|
92
|
+
let t = k.current;
|
|
93
|
+
t && t.isConnected && t !== document.body && t.focus({ preventScroll: !0 });
|
|
94
|
+
},
|
|
95
|
+
"aria-labelledby": x,
|
|
96
|
+
"aria-describedby": void 0,
|
|
97
|
+
style: { zIndex: r },
|
|
98
|
+
className: e(a, "fixed inset-x-4 top-4 bottom-4 mx-auto flex max-w-lg flex-col overflow-hidden rounded-xl sm:top-1/2 sm:bottom-auto sm:max-h-[min(90vh,48rem)] sm:-translate-y-1/2"),
|
|
99
|
+
"data-testid": "share-connection-dialog",
|
|
100
|
+
children: [
|
|
101
|
+
/* @__PURE__ */ y("div", {
|
|
102
|
+
className: "flex items-start justify-between gap-4 border-b border-border-subtle px-5 py-4",
|
|
103
|
+
children: [/* @__PURE__ */ v(b.Title, {
|
|
104
|
+
id: x,
|
|
105
|
+
className: "text-base font-semibold text-text-primary",
|
|
106
|
+
children: D.sharing ? _("integrations.sharing.title", "Share {{name}}", { name: D.sharing.name }) : _("integrations.sharing.titleLoading", "Share connection")
|
|
107
|
+
}), /* @__PURE__ */ v(b.Close, {
|
|
108
|
+
className: "rounded-md p-1 text-text-secondary hover:bg-accent",
|
|
109
|
+
"aria-label": _("integrations.common.close", "Close"),
|
|
110
|
+
children: /* @__PURE__ */ v(g, { size: 16 })
|
|
111
|
+
})]
|
|
112
|
+
}),
|
|
113
|
+
/* @__PURE__ */ y("div", {
|
|
114
|
+
className: "flex-1 space-y-5 overflow-y-auto px-5 py-4",
|
|
115
|
+
children: [C(D, E, _), D.saveError && /* @__PURE__ */ v("p", {
|
|
116
|
+
role: "alert",
|
|
117
|
+
className: "text-sm text-status-error-text",
|
|
118
|
+
children: D.saveError
|
|
119
|
+
})]
|
|
120
|
+
}),
|
|
121
|
+
/* @__PURE__ */ y("div", {
|
|
122
|
+
className: "flex justify-end gap-2 border-t border-border-subtle px-5 py-3",
|
|
123
|
+
children: [/* @__PURE__ */ v("button", {
|
|
124
|
+
type: "button",
|
|
125
|
+
onClick: s,
|
|
126
|
+
className: "rounded-md border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-accent",
|
|
127
|
+
children: _("integrations.common.cancel", "Cancel")
|
|
128
|
+
}), /* @__PURE__ */ y("button", {
|
|
129
|
+
type: "button",
|
|
130
|
+
onClick: () => void A(),
|
|
131
|
+
disabled: !D.editable || D.saving,
|
|
132
|
+
className: "inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text transition-colors hover:bg-action-primary-bg/90 disabled:opacity-50",
|
|
133
|
+
"data-testid": "share-connection-save",
|
|
134
|
+
children: [D.saving && /* @__PURE__ */ v(h, {
|
|
135
|
+
size: 14,
|
|
136
|
+
className: "animate-spin",
|
|
137
|
+
"aria-hidden": !0
|
|
138
|
+
}), _("integrations.sharing.save", "Save")]
|
|
139
|
+
})]
|
|
140
|
+
})
|
|
141
|
+
]
|
|
142
|
+
})] })
|
|
143
|
+
});
|
|
144
|
+
};
|
|
145
|
+
//#endregion
|
|
146
|
+
export { x as SHARE_TITLE_ID, w as ShareConnectionDialog };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
import { Translator } from '../credentials/translate';
|
|
3
|
+
import { ConnectionShareGrant, ConnectionShareRole, ConnectionSharePrincipalType, ConnectionVisibility, SharePrincipal } from './types';
|
|
4
|
+
export declare const OwnerField: FC<{
|
|
5
|
+
id: string;
|
|
6
|
+
ownerId: string;
|
|
7
|
+
onChange: (ownerId: string) => void;
|
|
8
|
+
/** Only a workspace admin can hand the connection to someone else. */
|
|
9
|
+
changeable: boolean;
|
|
10
|
+
members: SharePrincipal[];
|
|
11
|
+
ownerLabel: string;
|
|
12
|
+
translate: Translator;
|
|
13
|
+
}>;
|
|
14
|
+
export declare const PrincipalSearch: FC<{
|
|
15
|
+
id: string;
|
|
16
|
+
principals: SharePrincipal[];
|
|
17
|
+
/** Keys (`TYPE:id`) already granted, or the owner: never offered again. */
|
|
18
|
+
excluded: ReadonlySet<string>;
|
|
19
|
+
onAdd: (principal: SharePrincipal) => void;
|
|
20
|
+
disabled: boolean;
|
|
21
|
+
translate: Translator;
|
|
22
|
+
}>;
|
|
23
|
+
export declare const GrantList: FC<{
|
|
24
|
+
idPrefix: string;
|
|
25
|
+
grants: ConnectionShareGrant[];
|
|
26
|
+
visibility: ConnectionVisibility;
|
|
27
|
+
labelOf: (principalType: ConnectionSharePrincipalType, principalId: string) => string;
|
|
28
|
+
onRole: (index: number, role: ConnectionShareRole) => void;
|
|
29
|
+
onRemove: (index: number) => void;
|
|
30
|
+
disabled: boolean;
|
|
31
|
+
translate: Translator;
|
|
32
|
+
}>;
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { INPUT_CLASS as e } from "./frame.js";
|
|
2
|
+
import { principalKey as t } from "./useConnectionSharingDraft.js";
|
|
3
|
+
import { useState as n } from "react";
|
|
4
|
+
import { Folder as r, Trash2 as i, User as a, Users as o } from "lucide-react";
|
|
5
|
+
import { jsx as s, jsxs as c } from "react/jsx-runtime";
|
|
6
|
+
//#region src/connections/SharePanels.tsx
|
|
7
|
+
var l = 8, u = {
|
|
8
|
+
USER: a,
|
|
9
|
+
GROUP: o,
|
|
10
|
+
PROJECT: r
|
|
11
|
+
};
|
|
12
|
+
function d(e, t) {
|
|
13
|
+
switch (e) {
|
|
14
|
+
case "USER": return t("integrations.sharing.type.user", "Person");
|
|
15
|
+
case "GROUP": return t("integrations.sharing.type.group", "Group");
|
|
16
|
+
case "PROJECT": return t("integrations.sharing.type.project", "Project");
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
var f = ({ id: t, ownerId: n, onChange: r, changeable: i, members: a, ownerLabel: o, translate: l }) => /* @__PURE__ */ c("div", {
|
|
20
|
+
className: "space-y-1",
|
|
21
|
+
children: [/* @__PURE__ */ s("label", {
|
|
22
|
+
htmlFor: t,
|
|
23
|
+
className: "block text-sm font-medium text-text-primary",
|
|
24
|
+
children: l("integrations.sharing.owner", "Owner")
|
|
25
|
+
}), i ? /* @__PURE__ */ c("select", {
|
|
26
|
+
id: t,
|
|
27
|
+
value: n,
|
|
28
|
+
onChange: (e) => r(e.target.value),
|
|
29
|
+
className: e,
|
|
30
|
+
"data-testid": "share-connection-owner",
|
|
31
|
+
children: [!a.some((e) => e.principalId === n) && /* @__PURE__ */ s("option", {
|
|
32
|
+
value: n,
|
|
33
|
+
children: o
|
|
34
|
+
}), a.map((e) => /* @__PURE__ */ s("option", {
|
|
35
|
+
value: e.principalId,
|
|
36
|
+
children: e.label
|
|
37
|
+
}, e.principalId))]
|
|
38
|
+
}) : /* @__PURE__ */ s("p", {
|
|
39
|
+
id: t,
|
|
40
|
+
className: "text-sm text-text-secondary",
|
|
41
|
+
children: o
|
|
42
|
+
})]
|
|
43
|
+
}), p = ({ id: r, principals: i, excluded: a, onAdd: o, disabled: f, translate: p }) => {
|
|
44
|
+
let [m, h] = n(""), g = m.trim().toLowerCase(), _ = g ? i.filter((e) => !a.has(t(e.principalType, e.principalId)) && `${e.label} ${e.detail ?? ""}`.toLowerCase().includes(g)).slice(0, l) : [];
|
|
45
|
+
return /* @__PURE__ */ c("div", {
|
|
46
|
+
className: "space-y-2",
|
|
47
|
+
children: [
|
|
48
|
+
/* @__PURE__ */ s("label", {
|
|
49
|
+
htmlFor: r,
|
|
50
|
+
className: "block text-sm font-medium text-text-primary",
|
|
51
|
+
children: p("integrations.sharing.add", "Share with people, groups or projects")
|
|
52
|
+
}),
|
|
53
|
+
/* @__PURE__ */ s("input", {
|
|
54
|
+
id: r,
|
|
55
|
+
type: "search",
|
|
56
|
+
value: m,
|
|
57
|
+
onChange: (e) => h(e.target.value),
|
|
58
|
+
placeholder: p("integrations.sharing.addPlaceholder", "Search by name or email"),
|
|
59
|
+
className: e,
|
|
60
|
+
disabled: f,
|
|
61
|
+
"data-testid": "share-connection-search"
|
|
62
|
+
}),
|
|
63
|
+
_.length > 0 && /* @__PURE__ */ s("ul", {
|
|
64
|
+
className: "divide-y divide-border-subtle rounded-md border border-border-subtle",
|
|
65
|
+
children: _.map((e) => {
|
|
66
|
+
let n = u[e.principalType];
|
|
67
|
+
return /* @__PURE__ */ s("li", { children: /* @__PURE__ */ c("button", {
|
|
68
|
+
type: "button",
|
|
69
|
+
onClick: () => {
|
|
70
|
+
o(e), h("");
|
|
71
|
+
},
|
|
72
|
+
className: "flex w-full items-center gap-2 px-3 py-2 text-left text-sm hover:bg-accent",
|
|
73
|
+
"data-testid": "share-connection-match",
|
|
74
|
+
children: [
|
|
75
|
+
/* @__PURE__ */ s(n, {
|
|
76
|
+
size: 14,
|
|
77
|
+
className: "shrink-0 text-text-secondary",
|
|
78
|
+
"aria-hidden": !0
|
|
79
|
+
}),
|
|
80
|
+
/* @__PURE__ */ s("span", {
|
|
81
|
+
className: "flex-1 truncate text-text-primary",
|
|
82
|
+
children: e.label
|
|
83
|
+
}),
|
|
84
|
+
/* @__PURE__ */ s("span", {
|
|
85
|
+
className: "text-xs text-text-secondary",
|
|
86
|
+
children: e.detail ?? d(e.principalType, p)
|
|
87
|
+
})
|
|
88
|
+
]
|
|
89
|
+
}) }, t(e.principalType, e.principalId));
|
|
90
|
+
})
|
|
91
|
+
})
|
|
92
|
+
]
|
|
93
|
+
});
|
|
94
|
+
}, m = ({ idPrefix: e, grants: n, visibility: r, labelOf: a, onRole: o, onRemove: l, disabled: f, translate: p }) => /* @__PURE__ */ c("div", {
|
|
95
|
+
className: "space-y-2",
|
|
96
|
+
children: [/* @__PURE__ */ s("h3", {
|
|
97
|
+
className: "text-sm font-medium text-text-primary",
|
|
98
|
+
children: p("integrations.sharing.sharedWith", "Shared with")
|
|
99
|
+
}), n.length === 0 ? /* @__PURE__ */ s("p", {
|
|
100
|
+
className: "text-xs text-text-secondary",
|
|
101
|
+
children: r === "RESTRICTED" ? p("integrations.sharing.onlyOwner", "No one else yet. Only the owner can use it.") : p("integrations.sharing.none", "No one in particular.")
|
|
102
|
+
}) : /* @__PURE__ */ s("ul", {
|
|
103
|
+
className: "divide-y divide-border-subtle rounded-md border border-border-subtle",
|
|
104
|
+
children: n.map((n, r) => {
|
|
105
|
+
let m = u[n.principalType], h = `${e}-role-${r}`, g = a(n.principalType, n.principalId);
|
|
106
|
+
return /* @__PURE__ */ c("li", {
|
|
107
|
+
className: "flex items-center gap-2 px-3 py-2",
|
|
108
|
+
"data-testid": "share-connection-grant",
|
|
109
|
+
children: [
|
|
110
|
+
/* @__PURE__ */ s(m, {
|
|
111
|
+
size: 14,
|
|
112
|
+
className: "shrink-0 text-text-secondary",
|
|
113
|
+
"aria-hidden": !0
|
|
114
|
+
}),
|
|
115
|
+
/* @__PURE__ */ c("span", {
|
|
116
|
+
className: "min-w-0 flex-1",
|
|
117
|
+
children: [/* @__PURE__ */ s("span", {
|
|
118
|
+
className: "block truncate text-sm text-text-primary",
|
|
119
|
+
children: g
|
|
120
|
+
}), /* @__PURE__ */ s("span", {
|
|
121
|
+
className: "block text-xs text-text-secondary",
|
|
122
|
+
children: d(n.principalType, p)
|
|
123
|
+
})]
|
|
124
|
+
}),
|
|
125
|
+
/* @__PURE__ */ s("label", {
|
|
126
|
+
htmlFor: h,
|
|
127
|
+
className: "sr-only",
|
|
128
|
+
children: p("integrations.sharing.roleFor", "Access for {{name}}", { name: g })
|
|
129
|
+
}),
|
|
130
|
+
/* @__PURE__ */ c("select", {
|
|
131
|
+
id: h,
|
|
132
|
+
value: n.role,
|
|
133
|
+
onChange: (e) => o(r, e.target.value),
|
|
134
|
+
disabled: f,
|
|
135
|
+
className: "rounded-md border border-border-subtle bg-bg-surface px-2 py-1 text-xs",
|
|
136
|
+
children: [/* @__PURE__ */ s("option", {
|
|
137
|
+
value: "USE",
|
|
138
|
+
children: p("integrations.sharing.role.use", "Can use")
|
|
139
|
+
}), /* @__PURE__ */ s("option", {
|
|
140
|
+
value: "EDITOR",
|
|
141
|
+
children: p("integrations.sharing.role.editor", "Can edit")
|
|
142
|
+
})]
|
|
143
|
+
}),
|
|
144
|
+
/* @__PURE__ */ s("button", {
|
|
145
|
+
type: "button",
|
|
146
|
+
onClick: () => l(r),
|
|
147
|
+
disabled: f,
|
|
148
|
+
className: "rounded-md p-1 text-text-secondary hover:bg-accent disabled:opacity-50",
|
|
149
|
+
"aria-label": p("integrations.sharing.remove", "Stop sharing with {{name}}", { name: g }),
|
|
150
|
+
children: /* @__PURE__ */ s(i, { size: 14 })
|
|
151
|
+
})
|
|
152
|
+
]
|
|
153
|
+
}, t(n.principalType, n.principalId));
|
|
154
|
+
})
|
|
155
|
+
})]
|
|
156
|
+
});
|
|
157
|
+
//#endregion
|
|
158
|
+
export { m as GrantList, f as OwnerField, p as PrincipalSearch };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
import { Translator } from '../credentials/translate';
|
|
3
|
+
import { ConnectionVisibility } from './types';
|
|
4
|
+
export interface VisibilityChoiceProps {
|
|
5
|
+
value: ConnectionVisibility;
|
|
6
|
+
onChange: (value: ConnectionVisibility) => void;
|
|
7
|
+
translate: Translator;
|
|
8
|
+
/** Prefix for the inputs' ids, unique on the page. */
|
|
9
|
+
idPrefix: string;
|
|
10
|
+
disabled?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export declare const VisibilityChoice: FC<VisibilityChoiceProps>;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { cn as e } from "../lib/utils.js";
|
|
2
|
+
import { Lock as t, Users as n } from "lucide-react";
|
|
3
|
+
import { jsx as r, jsxs as i } from "react/jsx-runtime";
|
|
4
|
+
//#region src/connections/VisibilityChoice.tsx
|
|
5
|
+
var a = ({ value: a, onChange: o, translate: s, idPrefix: c, disabled: l = !1 }) => {
|
|
6
|
+
let u = [{
|
|
7
|
+
value: "RESTRICTED",
|
|
8
|
+
icon: t,
|
|
9
|
+
title: s("integrations.sharing.visibility.restricted", "Only people I choose"),
|
|
10
|
+
description: s("integrations.sharing.visibility.restrictedHint", "You, and the people, groups or projects you share it with. Workspace admins can manage it but not use it.")
|
|
11
|
+
}, {
|
|
12
|
+
value: "WORKSPACE",
|
|
13
|
+
icon: n,
|
|
14
|
+
title: s("integrations.sharing.visibility.workspace", "Everyone in this workspace"),
|
|
15
|
+
description: s("integrations.sharing.visibility.workspaceHint", "Anyone in the workspace whose role allows it can see it and use it in workflows.")
|
|
16
|
+
}];
|
|
17
|
+
return /* @__PURE__ */ i("fieldset", {
|
|
18
|
+
className: "space-y-2",
|
|
19
|
+
disabled: l,
|
|
20
|
+
children: [/* @__PURE__ */ r("legend", {
|
|
21
|
+
className: "mb-2 text-sm font-medium text-text-primary",
|
|
22
|
+
children: s("integrations.sharing.visibility.label", "Who can use this connection")
|
|
23
|
+
}), u.map((t) => {
|
|
24
|
+
let n = `${c}-visibility-${t.value.toLowerCase()}`, s = t.icon, u = a === t.value;
|
|
25
|
+
return /* @__PURE__ */ i("label", {
|
|
26
|
+
htmlFor: n,
|
|
27
|
+
className: e("flex cursor-pointer items-start gap-3 rounded-md border p-3 transition-colors", u ? "border-primary bg-primary/5" : "border-border-subtle hover:bg-accent/40", l && "cursor-not-allowed opacity-60"),
|
|
28
|
+
children: [
|
|
29
|
+
/* @__PURE__ */ r("input", {
|
|
30
|
+
id: n,
|
|
31
|
+
type: "radio",
|
|
32
|
+
name: `${c}-visibility`,
|
|
33
|
+
value: t.value,
|
|
34
|
+
checked: u,
|
|
35
|
+
onChange: () => o(t.value),
|
|
36
|
+
className: "mt-1",
|
|
37
|
+
"data-testid": `connection-visibility-${t.value.toLowerCase()}`
|
|
38
|
+
}),
|
|
39
|
+
/* @__PURE__ */ r(s, {
|
|
40
|
+
size: 16,
|
|
41
|
+
className: "mt-0.5 shrink-0 text-text-secondary",
|
|
42
|
+
"aria-hidden": !0
|
|
43
|
+
}),
|
|
44
|
+
/* @__PURE__ */ i("span", {
|
|
45
|
+
className: "space-y-0.5",
|
|
46
|
+
children: [/* @__PURE__ */ r("span", {
|
|
47
|
+
className: "block text-sm font-medium text-text-primary",
|
|
48
|
+
children: t.title
|
|
49
|
+
}), /* @__PURE__ */ r("span", {
|
|
50
|
+
className: "block text-xs text-text-secondary",
|
|
51
|
+
children: t.description
|
|
52
|
+
})]
|
|
53
|
+
})
|
|
54
|
+
]
|
|
55
|
+
}, t.value);
|
|
56
|
+
})]
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
//#endregion
|
|
60
|
+
export { a as VisibilityChoice };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ApolloClient } from '@apollo/client';
|
|
2
|
-
import { ConnectionAuthMethod, ConnectionProvider, ProviderAuthType, VaultSecretSummary, VaultSummary } from './types';
|
|
2
|
+
import { ConnectionAuthMethod, ConnectionProvider, ConnectionVisibility, ProviderAuthType, VaultSecretSummary, VaultSummary } from './types';
|
|
3
3
|
/** A connection as the dialog tracks it. */
|
|
4
4
|
export interface ConnectionRecord {
|
|
5
5
|
id: string;
|
|
@@ -16,6 +16,8 @@ export interface CreateConnectionInput {
|
|
|
16
16
|
vaultId?: string;
|
|
17
17
|
credentialSecretId?: string;
|
|
18
18
|
managedSecretName?: string;
|
|
19
|
+
/** Who can reach the connection; the service defaults to WORKSPACE. */
|
|
20
|
+
visibility?: ConnectionVisibility;
|
|
19
21
|
}
|
|
20
22
|
/** Everything the dialog asks of the service. Faked in tests. */
|
|
21
23
|
export interface ConnectionsApi {
|
|
@@ -56,4 +58,13 @@ export interface ConnectionsApiOptions {
|
|
|
56
58
|
export declare function normalizeAuthType(value: unknown): ProviderAuthType;
|
|
57
59
|
export declare function mapAuthMethod(raw: unknown): ConnectionAuthMethod;
|
|
58
60
|
export declare function mapProvider(raw: unknown): ConnectionProvider;
|
|
61
|
+
/**
|
|
62
|
+
* Throw an operation's error. Host clients are configured with
|
|
63
|
+
* `errorPolicy: 'all'`, so a failed call RESOLVES with the failure in
|
|
64
|
+
* `result.error`; reading only `data` would swallow the server's message.
|
|
65
|
+
*/
|
|
66
|
+
export declare function unwrap<T>(result: {
|
|
67
|
+
data?: T | null;
|
|
68
|
+
error?: unknown;
|
|
69
|
+
}): T | null;
|
|
59
70
|
export declare function createConnectionsApi(client: ApolloClient, options?: ConnectionsApiOptions): ConnectionsApi;
|
package/dist/connections/api.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Translator } from '../credentials/translate';
|
|
2
2
|
import { AuthMethodFlow, FormSchema } from '../credentials/types';
|
|
3
3
|
import { ConnectionRecord, ConnectionsApi, CreateConnectionInput } from './api';
|
|
4
|
-
import { ConnectionAuthMethod, ConnectionProvider, CredentialStorageMode, CredentialStorageState, ProviderAuthType } from './types';
|
|
4
|
+
import { ConnectionAuthMethod, ConnectionProvider, CredentialStorageMode, CredentialStorageState, ProviderAuthType, ConnectionVisibility } from './types';
|
|
5
5
|
/** Providers whose methods were never backfilled fall back to their type. */
|
|
6
6
|
export declare function flowForAuthType(authType: ProviderAuthType): AuthMethodFlow;
|
|
7
7
|
/** The methods a user may pick: enabled ones, in display order. */
|
|
@@ -43,6 +43,11 @@ export interface ConnectionDraft {
|
|
|
43
43
|
requireVault: boolean;
|
|
44
44
|
/** Host settings stored on the connection, e.g. a Botlit return path. */
|
|
45
45
|
extraConfig?: Record<string, unknown>;
|
|
46
|
+
/**
|
|
47
|
+
* Who can reach the new connection. Left out, the integrations service
|
|
48
|
+
* makes it visible to the whole workspace.
|
|
49
|
+
*/
|
|
50
|
+
visibility?: ConnectionVisibility;
|
|
46
51
|
}
|
|
47
52
|
/** The first thing stopping the draft from being submitted, or null. */
|
|
48
53
|
export declare function validateDraft(draft: ConnectionDraft, translate: Translator): string | null;
|
|
@@ -75,7 +75,7 @@ function _(e) {
|
|
|
75
75
|
name: e.name.trim(),
|
|
76
76
|
providerId: e.provider.id
|
|
77
77
|
}, c = e.description.trim();
|
|
78
|
-
if (c && (a.description = c), e.method && (a.authMethodKey = e.method.key), Object.keys(i).length > 0 && (a.config = i), m(t, e.provider)) {
|
|
78
|
+
if (c && (a.description = c), e.method && (a.authMethodKey = e.method.key), Object.keys(i).length > 0 && (a.config = i), e.visibility && (a.visibility = e.visibility), m(t, e.provider)) {
|
|
79
79
|
let { storage: t } = e;
|
|
80
80
|
if (!d(e.provider, e.method).includes(t.mode)) throw Error("This authentication method does not support the selected credential storage mode.");
|
|
81
81
|
if (t.mode === "existing") {
|
|
@@ -9,6 +9,9 @@
|
|
|
9
9
|
export { ConnectionDialog, type ConnectionDialogProps } from './ConnectionDialog';
|
|
10
10
|
export { CONNECTION_DIALOG_FRAME_CLASSES, type ConnectionDialogPresentation } from './frame';
|
|
11
11
|
export { ProviderIcon, type ProviderIconProps } from './ProviderIcon';
|
|
12
|
+
export { ShareConnectionDialog, SHARE_TITLE_ID, type ShareConnectionDialogProps, } from './ShareConnectionDialog';
|
|
13
|
+
export { VisibilityChoice, type VisibilityChoiceProps } from './VisibilityChoice';
|
|
14
|
+
export { canManageSharing, createConnectionSharingApi, mapConnectionSharing, SHARE_PICKER_LIMIT, type ConnectionSharingApi, type ShareConnectionInput, } from './sharingApi';
|
|
12
15
|
export { CredentialStorageSelector } from './CredentialStorageSelector';
|
|
13
16
|
export { compatibleSecrets, EMPTY_STORAGE } from './storage';
|
|
14
17
|
export { groupByCategory, pickableProviders } from './picker';
|
|
@@ -19,5 +22,5 @@ export { waitForOAuthCompletion, isOAuthCallbackMessage } from './oauthPopup';
|
|
|
19
22
|
export { getProviderAccent, getProviderIconName, getProviderImageSource, getProviderTextIcon, normalizeProviderCategory, type ProviderIdentity, } from './providerIdentity';
|
|
20
23
|
export { isScopeChecked, parseScopeOptions, requestedScopes, toggleScope, type ScopeOption, type ScopeSelection, } from './scopes';
|
|
21
24
|
export { authTypeLabel, categoryLabel } from './labels';
|
|
22
|
-
export type { ConnectionAuthMethod, ConnectionDialogEvent, ConnectionProvider, CreatedConnection, CredentialStorageState, ProviderAuthType, ProviderCategory, VaultSecretSummary, VaultSummary, } from './types';
|
|
25
|
+
export type { ConnectionAccess, ConnectionAuthMethod, ConnectionDialogEvent, ConnectionProvider, ConnectionShareGrant, ConnectionSharePrincipalType, ConnectionShareRole, ConnectionSharing, ConnectionVisibility, CreatedConnection, CredentialStorageState, ProviderAuthType, ProviderCategory, SharePrincipal, VaultSecretSummary, VaultSummary, } from './types';
|
|
23
26
|
export type { Translator } from '../credentials/translate';
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { ApolloClient } from '@apollo/client';
|
|
2
|
+
import { ConnectionAccess, ConnectionShareGrant, ConnectionSharing, ConnectionVisibility, SharePrincipal } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Most members, groups and projects the share picker loads of each kind. A
|
|
5
|
+
* workspace past it can still share with anyone through a group or project.
|
|
6
|
+
*/
|
|
7
|
+
export declare const SHARE_PICKER_LIMIT = 1000;
|
|
8
|
+
/** A connection's sharing from the service's answer; null when it is not one. */
|
|
9
|
+
export declare function mapConnectionSharing(raw: unknown): ConnectionSharing | null;
|
|
10
|
+
/** Whether someone reaching a connection this way may change its sharing. */
|
|
11
|
+
export declare function canManageSharing(access: ConnectionAccess | null): boolean;
|
|
12
|
+
export interface ShareConnectionInput {
|
|
13
|
+
connectionId: string;
|
|
14
|
+
visibility: ConnectionVisibility;
|
|
15
|
+
shares: ConnectionShareGrant[];
|
|
16
|
+
/**
|
|
17
|
+
* Hand the connection to this person in the same change, so the new owner
|
|
18
|
+
* and the new sharing apply together or not at all. Workspace admins only.
|
|
19
|
+
*/
|
|
20
|
+
ownerId?: string;
|
|
21
|
+
}
|
|
22
|
+
export interface ConnectionSharingApi {
|
|
23
|
+
getSharing(connectionId: string): Promise<ConnectionSharing>;
|
|
24
|
+
/** Members, groups and projects of the workspace. A kind the person may not list is left empty. */
|
|
25
|
+
listPrincipals(workspaceId: string): Promise<SharePrincipal[]>;
|
|
26
|
+
share(input: ShareConnectionInput): Promise<ConnectionSharing>;
|
|
27
|
+
}
|
|
28
|
+
export declare function createConnectionSharingApi(client: ApolloClient): ConnectionSharingApi;
|