@burdenoff/microfe-workspaces 2026.624.1 → 2026.624.2
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.
|
@@ -11,18 +11,67 @@ import { useWorkspaceRoles as oe } from "../hooks/useWorkspaceRoles.js";
|
|
|
11
11
|
import { useProjects as se } from "../hooks/useProjects.js";
|
|
12
12
|
import { downloadWorkspaceBulkInviteTemplate as ce, parseWorkspaceBulkInviteCsv as le } from "../utils/workspaceBulkInviteCsv.js";
|
|
13
13
|
import { useMemo as s, useRef as ue, useState as c } from "react";
|
|
14
|
-
import { AlertCircle as
|
|
15
|
-
import { PermissionProvider as
|
|
16
|
-
import { Fragment as
|
|
17
|
-
import { AlertDialog as
|
|
14
|
+
import { AlertCircle as l, ArrowLeft as de, CheckCircle2 as u, Download as fe, Loader2 as d, Mail as pe, RefreshCw as me, Send as he, Upload as ge, UserPlus as _e, XCircle as f } from "lucide-react";
|
|
15
|
+
import { PermissionProvider as ve } from "@burdenoff/fe-libs/shared/providers/shell";
|
|
16
|
+
import { Fragment as ye, jsx as p, jsxs as m } from "react/jsx-runtime";
|
|
17
|
+
import { AlertDialog as be, AlertDialogAction as xe, AlertDialogCancel as Se, AlertDialogContent as Ce, AlertDialogDescription as we, AlertDialogFooter as Te, AlertDialogHeader as Ee, AlertDialogTitle as De, Badge as h, Button as g, Card as _, CardContent as v, CardHeader as y, CardTitle as b, Checkbox as x, Input as Oe, ResponsiveTable as ke, Skeleton as S, Tabs as Ae, TabsContent as je, TabsList as Me, TabsTrigger as Ne, Tooltip as C, TooltipContent as w, TooltipProvider as Pe, TooltipTrigger as T } from "@burdenoff/fe-libs/ui";
|
|
18
18
|
import { useNavigate as Fe, useParams as Ie } from "react-router-dom";
|
|
19
19
|
import { useI18n as Le } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
20
20
|
//#region src/pages/WorkspaceInvitePage.tsx
|
|
21
|
-
var Re = 1024 * 1024,
|
|
22
|
-
|
|
21
|
+
var Re = 1024 * 1024, E = 500, ze = [
|
|
22
|
+
{
|
|
23
|
+
key: "rowNumber",
|
|
24
|
+
header: "#",
|
|
25
|
+
priority: "secondary",
|
|
26
|
+
headerClassName: "text-xs font-semibold uppercase tracking-wide text-text-secondary",
|
|
27
|
+
cellClassName: "text-xs text-text-secondary tabular-nums",
|
|
28
|
+
cell: (e) => e.rowNumber
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
key: "email",
|
|
32
|
+
header: "Email",
|
|
33
|
+
priority: "primary",
|
|
34
|
+
headerClassName: "text-xs font-semibold uppercase tracking-wide text-text-secondary",
|
|
35
|
+
cellClassName: "text-sm",
|
|
36
|
+
cell: (e) => e.email || /* @__PURE__ */ p("span", {
|
|
37
|
+
className: "italic text-text-secondary",
|
|
38
|
+
children: "(empty)"
|
|
39
|
+
})
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
key: "status",
|
|
43
|
+
header: "Status",
|
|
44
|
+
priority: "secondary",
|
|
45
|
+
headerClassName: "text-xs font-semibold uppercase tracking-wide text-text-secondary",
|
|
46
|
+
cellClassName: "text-xs",
|
|
47
|
+
cell: (e) => e.errors.length > 0 ? /* @__PURE__ */ p("div", {
|
|
48
|
+
className: "space-y-1 text-status-error-text",
|
|
49
|
+
children: e.errors.map((t) => /* @__PURE__ */ m("span", {
|
|
50
|
+
className: "inline-flex items-center gap-1 pr-3",
|
|
51
|
+
children: [/* @__PURE__ */ p(f, { size: 14 }), t]
|
|
52
|
+
}, `${e.rowNumber}-${t}`))
|
|
53
|
+
}) : e.status.kind === "sending" ? /* @__PURE__ */ m("span", {
|
|
54
|
+
className: "inline-flex items-center gap-1 text-text-secondary",
|
|
55
|
+
children: [/* @__PURE__ */ p(d, {
|
|
56
|
+
size: 14,
|
|
57
|
+
className: "animate-spin"
|
|
58
|
+
}), "Sending..."]
|
|
59
|
+
}) : e.status.kind === "invited" ? /* @__PURE__ */ m("span", {
|
|
60
|
+
className: "inline-flex items-center gap-1 text-green-700 dark:text-green-400",
|
|
61
|
+
children: [/* @__PURE__ */ p(u, { size: 14 }), "Invited"]
|
|
62
|
+
}) : e.status.kind === "failed" ? /* @__PURE__ */ m("span", {
|
|
63
|
+
className: "inline-flex items-center gap-1 text-status-error-text",
|
|
64
|
+
children: [/* @__PURE__ */ p(f, { size: 14 }), e.status.message]
|
|
65
|
+
}) : /* @__PURE__ */ p("span", {
|
|
66
|
+
className: "text-text-secondary",
|
|
67
|
+
children: "Ready"
|
|
68
|
+
})
|
|
69
|
+
}
|
|
70
|
+
];
|
|
71
|
+
function Be(e) {
|
|
23
72
|
return e.type === "text/csv" || e.name.toLowerCase().endsWith(".csv");
|
|
24
73
|
}
|
|
25
|
-
function
|
|
74
|
+
function Ve(e) {
|
|
26
75
|
if (!e) return null;
|
|
27
76
|
let t = new Date(e);
|
|
28
77
|
return Number.isNaN(t.getTime()) ? null : t.toLocaleDateString(void 0, {
|
|
@@ -33,14 +82,14 @@ function Be(e) {
|
|
|
33
82
|
minute: "2-digit"
|
|
34
83
|
});
|
|
35
84
|
}
|
|
36
|
-
function
|
|
85
|
+
function D(e) {
|
|
37
86
|
let t = e instanceof Error ? e.message : String(e);
|
|
38
87
|
return t.includes("CONFLICT") ? "An invite already exists for this email address." : t.includes("already a member") ? "This user is already a member of the workspace." : "Something went wrong. Please try again or contact support.";
|
|
39
88
|
}
|
|
40
|
-
function
|
|
89
|
+
function He(e, t, n) {
|
|
41
90
|
return e.length === 0 ? t : e.map((e) => n ? n(e) : e).join(", ");
|
|
42
91
|
}
|
|
43
|
-
function
|
|
92
|
+
function Ue(e, t, n, r) {
|
|
44
93
|
return {
|
|
45
94
|
email: t,
|
|
46
95
|
workspaceId: e,
|
|
@@ -51,62 +100,62 @@ function He(e, t, n, r) {
|
|
|
51
100
|
} } : {}
|
|
52
101
|
};
|
|
53
102
|
}
|
|
54
|
-
function
|
|
55
|
-
return /* @__PURE__ */
|
|
103
|
+
function We({ selectedRoleIds: e, onRoleToggle: t, selectedProjectIds: n, onProjectToggle: r, availableRoles: i, availableProjects: a, isLoadingRoles: ee, isLoadingProjects: te, disabled: o }) {
|
|
104
|
+
return /* @__PURE__ */ m("div", {
|
|
56
105
|
className: "space-y-6",
|
|
57
|
-
children: [/* @__PURE__ */
|
|
106
|
+
children: [/* @__PURE__ */ m("div", {
|
|
58
107
|
className: "space-y-3",
|
|
59
|
-
children: [/* @__PURE__ */
|
|
108
|
+
children: [/* @__PURE__ */ m("div", {
|
|
60
109
|
className: "flex flex-wrap items-center justify-between gap-2",
|
|
61
|
-
children: [/* @__PURE__ */
|
|
110
|
+
children: [/* @__PURE__ */ m("div", {
|
|
62
111
|
className: "space-y-1",
|
|
63
|
-
children: [/* @__PURE__ */
|
|
112
|
+
children: [/* @__PURE__ */ p("h3", {
|
|
64
113
|
className: "text-base font-semibold",
|
|
65
114
|
children: "Roles (Optional)"
|
|
66
|
-
}), /* @__PURE__ */
|
|
115
|
+
}), /* @__PURE__ */ p("p", {
|
|
67
116
|
className: "text-sm text-text-secondary",
|
|
68
117
|
children: "Choose roles. Hover any role to preview its full description."
|
|
69
118
|
})]
|
|
70
|
-
}), e.length > 0 ? /* @__PURE__ */
|
|
119
|
+
}), e.length > 0 ? /* @__PURE__ */ m(h, {
|
|
71
120
|
variant: "secondary",
|
|
72
121
|
children: [e.length, " selected"]
|
|
73
122
|
}) : null]
|
|
74
|
-
}), /* @__PURE__ */
|
|
123
|
+
}), /* @__PURE__ */ p(Pe, { children: /* @__PURE__ */ p("div", {
|
|
75
124
|
className: "grid grid-cols-1 gap-2 md:grid-cols-2 xl:grid-cols-3",
|
|
76
|
-
children: ee ? /* @__PURE__ */
|
|
125
|
+
children: ee ? /* @__PURE__ */ p("p", {
|
|
77
126
|
className: "text-sm text-text-secondary",
|
|
78
127
|
children: "Loading roles…"
|
|
79
|
-
}) : i.length === 0 ? /* @__PURE__ */
|
|
128
|
+
}) : i.length === 0 ? /* @__PURE__ */ p("p", {
|
|
80
129
|
className: "text-sm text-text-secondary",
|
|
81
130
|
children: "No assignable roles were returned for this workspace."
|
|
82
131
|
}) : i.map((n) => {
|
|
83
132
|
let r = e.includes(n.id);
|
|
84
|
-
return /* @__PURE__ */
|
|
133
|
+
return /* @__PURE__ */ m(C, { children: [/* @__PURE__ */ p(T, {
|
|
85
134
|
asChild: !0,
|
|
86
|
-
children: /* @__PURE__ */
|
|
135
|
+
children: /* @__PURE__ */ m("label", {
|
|
87
136
|
className: `flex cursor-pointer items-center justify-between gap-3 rounded-lg border px-3 py-3 text-left text-sm font-medium transition-colors focus-within:ring-2 focus-within:ring-[var(--color-focus-ring)] focus-within:ring-offset-2 ${r ? "border-primary bg-action-primary-bg/10 text-text-primary shadow-sm" : "border-border-subtle bg-bg-surface text-text-primary hover:bg-accent"} ${o ? "opacity-70" : ""}`,
|
|
88
|
-
children: [/* @__PURE__ */
|
|
137
|
+
children: [/* @__PURE__ */ p("span", {
|
|
89
138
|
className: "min-w-0 flex-1 truncate",
|
|
90
139
|
children: n.name
|
|
91
|
-
}), /* @__PURE__ */
|
|
140
|
+
}), /* @__PURE__ */ p(x, {
|
|
92
141
|
checked: r,
|
|
93
142
|
disabled: o,
|
|
94
143
|
onCheckedChange: (e) => t(n.id, !!e),
|
|
95
144
|
"aria-label": `Select ${n.name}`
|
|
96
145
|
})]
|
|
97
146
|
})
|
|
98
|
-
}), /* @__PURE__ */
|
|
147
|
+
}), /* @__PURE__ */ m(w, {
|
|
99
148
|
className: "max-w-xs text-sm leading-6",
|
|
100
149
|
children: [
|
|
101
|
-
/* @__PURE__ */
|
|
150
|
+
/* @__PURE__ */ p("p", {
|
|
102
151
|
className: "font-medium",
|
|
103
152
|
children: n.name
|
|
104
153
|
}),
|
|
105
|
-
/* @__PURE__ */
|
|
154
|
+
/* @__PURE__ */ p("p", {
|
|
106
155
|
className: "mt-1 text-text-secondary",
|
|
107
156
|
children: n.description || "No description available for this role."
|
|
108
157
|
}),
|
|
109
|
-
n.isSystem ? /* @__PURE__ */
|
|
158
|
+
n.isSystem ? /* @__PURE__ */ p("p", {
|
|
110
159
|
className: "mt-2 text-xs",
|
|
111
160
|
children: "System role"
|
|
112
161
|
}) : null
|
|
@@ -114,51 +163,51 @@ function Ue({ selectedRoleIds: e, onRoleToggle: t, selectedProjectIds: n, onProj
|
|
|
114
163
|
})] }, n.id);
|
|
115
164
|
})
|
|
116
165
|
}) })]
|
|
117
|
-
}), /* @__PURE__ */
|
|
166
|
+
}), /* @__PURE__ */ m("div", {
|
|
118
167
|
className: "space-y-3",
|
|
119
|
-
children: [/* @__PURE__ */
|
|
168
|
+
children: [/* @__PURE__ */ m("div", {
|
|
120
169
|
className: "flex flex-wrap items-center justify-between gap-2",
|
|
121
|
-
children: [/* @__PURE__ */
|
|
170
|
+
children: [/* @__PURE__ */ m("div", {
|
|
122
171
|
className: "space-y-1",
|
|
123
|
-
children: [/* @__PURE__ */
|
|
172
|
+
children: [/* @__PURE__ */ p("h3", {
|
|
124
173
|
className: "text-base font-semibold",
|
|
125
174
|
children: "Projects to add on acceptance (Optional)"
|
|
126
|
-
}), /* @__PURE__ */
|
|
175
|
+
}), /* @__PURE__ */ p("p", {
|
|
127
176
|
className: "text-sm text-text-secondary",
|
|
128
177
|
children: "The invited user will be added to these projects automatically after they accept."
|
|
129
178
|
})]
|
|
130
|
-
}), n.length > 0 ? /* @__PURE__ */
|
|
179
|
+
}), n.length > 0 ? /* @__PURE__ */ m(h, {
|
|
131
180
|
variant: "secondary",
|
|
132
181
|
children: [n.length, " selected"]
|
|
133
182
|
}) : null]
|
|
134
|
-
}), /* @__PURE__ */
|
|
183
|
+
}), /* @__PURE__ */ p("div", {
|
|
135
184
|
className: "grid grid-cols-1 gap-2 md:grid-cols-2 xl:grid-cols-3",
|
|
136
|
-
children: te ? /* @__PURE__ */
|
|
185
|
+
children: te ? /* @__PURE__ */ p("p", {
|
|
137
186
|
className: "text-sm text-text-secondary",
|
|
138
187
|
children: "Loading projects…"
|
|
139
|
-
}) : a.length === 0 ? /* @__PURE__ */
|
|
188
|
+
}) : a.length === 0 ? /* @__PURE__ */ p("p", {
|
|
140
189
|
className: "text-sm text-text-secondary",
|
|
141
190
|
children: "No active projects are available in this workspace yet."
|
|
142
191
|
}) : a.map((e) => {
|
|
143
192
|
let t = n.includes(e.id);
|
|
144
|
-
return /* @__PURE__ */
|
|
193
|
+
return /* @__PURE__ */ m("label", {
|
|
145
194
|
className: `flex cursor-pointer items-start justify-between gap-3 rounded-lg border px-3 py-3 transition-colors focus-within:ring-2 focus-within:ring-[var(--color-focus-ring)] focus-within:ring-offset-2 ${t ? "border-primary bg-action-primary-bg/10 text-text-primary shadow-sm" : "border-border-subtle bg-bg-surface text-text-primary hover:bg-accent"} ${o ? "opacity-70" : ""}`,
|
|
146
|
-
children: [/* @__PURE__ */
|
|
195
|
+
children: [/* @__PURE__ */ m("div", {
|
|
147
196
|
className: "min-w-0 flex-1 space-y-1",
|
|
148
|
-
children: [/* @__PURE__ */
|
|
197
|
+
children: [/* @__PURE__ */ p("p", {
|
|
149
198
|
className: "truncate text-sm font-semibold leading-tight",
|
|
150
199
|
children: e.name
|
|
151
|
-
}), /* @__PURE__ */
|
|
200
|
+
}), /* @__PURE__ */ m("div", {
|
|
152
201
|
className: "flex items-center gap-2 text-xs text-text-secondary",
|
|
153
|
-
children: [/* @__PURE__ */
|
|
202
|
+
children: [/* @__PURE__ */ p("span", {
|
|
154
203
|
className: "truncate font-mono",
|
|
155
204
|
children: e.key
|
|
156
|
-
}), /* @__PURE__ */
|
|
205
|
+
}), /* @__PURE__ */ p(h, {
|
|
157
206
|
variant: "outline",
|
|
158
207
|
children: e.status
|
|
159
208
|
})]
|
|
160
209
|
})]
|
|
161
|
-
}), /* @__PURE__ */
|
|
210
|
+
}), /* @__PURE__ */ p(x, {
|
|
162
211
|
checked: t,
|
|
163
212
|
disabled: o,
|
|
164
213
|
onCheckedChange: (t) => r(e.id, !!t),
|
|
@@ -170,326 +219,326 @@ function Ue({ selectedRoleIds: e, onRoleToggle: t, selectedProjectIds: n, onProj
|
|
|
170
219
|
})]
|
|
171
220
|
});
|
|
172
221
|
}
|
|
173
|
-
function
|
|
174
|
-
let { workspaceId:
|
|
175
|
-
i("workspaces.invite", { workspaceId:
|
|
176
|
-
let { canInviteMember:
|
|
177
|
-
if (!
|
|
222
|
+
function O() {
|
|
223
|
+
let { workspaceId: ve } = Ie(), { t: x } = Le(), C = Fe(), { basePath: w = "/workspaces", workspaceId: Pe } = e(), { withCurrentSearch: T } = n(), O = ve || Pe || "";
|
|
224
|
+
i("workspaces.invite", { workspaceId: O || void 0 });
|
|
225
|
+
let { canInviteMember: Ge, isLoading: Ke } = ae(), { data: qe, isLoading: Je, error: Ye } = t(O), { data: k = [], isLoading: Xe } = oe(O), { data: A, isLoading: Ze } = se({ archived: !1 }, { limit: 100 }, O), { data: Qe, isLoading: $e, isFetching: j, error: et, refetch: tt } = a(O, "PENDING", { limit: 50 }, { retry: !1 }), M = s(() => (A?.items ?? []).filter((e) => !e.archived), [A?.items]), [nt, rt] = c("single"), [N, it] = c(""), [P, at] = c([]), [F, ot] = c([]), [st, I] = c(null), [ct, lt] = c(null), [ut, L] = c(null), [dt, R] = c(null), [z, B] = c(null), [V, H] = c([]), [ft, pt] = c(null), [mt, U] = c(!1), [W, ht] = c(!1), gt = ue(null), [G, K] = c(null), { mutateAsync: _t, isPending: q } = o(O), { mutateAsync: vt, isPending: yt } = ee(), { mutate: bt, isPending: J } = ne(O), { mutate: xt, isPending: Y } = te(O), [St, X] = c(null), Z = Qe?.items ?? [], Ct = q || yt || W, wt = s(() => k.filter((e) => P.includes(e.id)).map((e) => e.name), [k, P]), Tt = s(() => M.filter((e) => F.includes(e.id)).map((e) => e.name), [M, F]), Q = s(() => V.filter((e) => e.errors.length === 0 && e.status.kind !== "invited"), [V]), $ = s(() => V.filter((e) => e.errors.length > 0), [V]);
|
|
226
|
+
if (!O) return /* @__PURE__ */ p("div", {
|
|
178
227
|
className: "space-y-4 p-6",
|
|
179
|
-
children: /* @__PURE__ */
|
|
228
|
+
children: /* @__PURE__ */ m("div", {
|
|
180
229
|
className: "rounded-xl border bg-bg-surface p-8 text-center",
|
|
181
230
|
children: [
|
|
182
|
-
/* @__PURE__ */
|
|
231
|
+
/* @__PURE__ */ p("h1", {
|
|
183
232
|
className: "text-2xl font-bold",
|
|
184
|
-
children: r(
|
|
233
|
+
children: r(x, "workspaceInvite.noWorkspaceTitle", "Select a workspace first")
|
|
185
234
|
}),
|
|
186
|
-
/* @__PURE__ */
|
|
235
|
+
/* @__PURE__ */ p("p", {
|
|
187
236
|
className: "mt-2 text-text-secondary",
|
|
188
|
-
children: r(
|
|
237
|
+
children: r(x, "workspaceInvite.noWorkspaceDescription", "Choose a current workspace from the header or open a workspace detail page before inviting members.")
|
|
189
238
|
}),
|
|
190
|
-
/* @__PURE__ */
|
|
239
|
+
/* @__PURE__ */ p("div", {
|
|
191
240
|
className: "mt-4",
|
|
192
|
-
children: /* @__PURE__ */
|
|
193
|
-
onClick: () =>
|
|
241
|
+
children: /* @__PURE__ */ p(g, {
|
|
242
|
+
onClick: () => C(T(`${w}/list`)),
|
|
194
243
|
variant: "outline",
|
|
195
|
-
children: r(
|
|
244
|
+
children: r(x, "workspaceInvite.backToWorkspaces", "Back to Workspaces")
|
|
196
245
|
})
|
|
197
246
|
})
|
|
198
247
|
]
|
|
199
248
|
})
|
|
200
249
|
});
|
|
201
|
-
if (
|
|
250
|
+
if (Ke || Je) return /* @__PURE__ */ m("div", {
|
|
202
251
|
className: "space-y-6 p-6",
|
|
203
252
|
children: [
|
|
204
|
-
/* @__PURE__ */
|
|
205
|
-
/* @__PURE__ */
|
|
206
|
-
/* @__PURE__ */
|
|
253
|
+
/* @__PURE__ */ p(S, { className: "h-10 w-48" }),
|
|
254
|
+
/* @__PURE__ */ p(S, { className: "h-40 w-full" }),
|
|
255
|
+
/* @__PURE__ */ p(S, { className: "h-80 w-full" })
|
|
207
256
|
]
|
|
208
257
|
});
|
|
209
|
-
if (!
|
|
258
|
+
if (!Ge) return /* @__PURE__ */ p("div", {
|
|
210
259
|
className: "flex min-h-[400px] items-center justify-center",
|
|
211
|
-
children: /* @__PURE__ */
|
|
260
|
+
children: /* @__PURE__ */ m("div", {
|
|
212
261
|
className: "space-y-2 text-center",
|
|
213
|
-
children: [/* @__PURE__ */
|
|
262
|
+
children: [/* @__PURE__ */ p("h2", {
|
|
214
263
|
className: "text-lg font-semibold",
|
|
215
|
-
children: r(
|
|
216
|
-
}), /* @__PURE__ */
|
|
264
|
+
children: r(x, "workspaceInvite.accessDenied", "Access Denied")
|
|
265
|
+
}), /* @__PURE__ */ p("p", {
|
|
217
266
|
className: "text-sm text-text-secondary",
|
|
218
|
-
children: r(
|
|
267
|
+
children: r(x, "workspaceInvite.accessDeniedDescription", "You don't have permission to invite members into this workspace.")
|
|
219
268
|
})]
|
|
220
269
|
})
|
|
221
270
|
});
|
|
222
|
-
if (
|
|
271
|
+
if (Ye || !qe) return /* @__PURE__ */ m("div", {
|
|
223
272
|
className: "space-y-4 p-6",
|
|
224
|
-
children: [/* @__PURE__ */
|
|
273
|
+
children: [/* @__PURE__ */ m(g, {
|
|
225
274
|
variant: "ghost",
|
|
226
|
-
onClick: () =>
|
|
275
|
+
onClick: () => C(T(`${w}/list`)),
|
|
227
276
|
className: "gap-2",
|
|
228
|
-
children: [/* @__PURE__ */
|
|
229
|
-
}), /* @__PURE__ */
|
|
277
|
+
children: [/* @__PURE__ */ p(de, { size: 18 }), r(x, "workspaceInvite.backToWorkspaces", "Back to Workspaces")]
|
|
278
|
+
}), /* @__PURE__ */ p("div", {
|
|
230
279
|
className: "rounded-xl border bg-bg-surface p-8 text-center text-status-error-text",
|
|
231
|
-
children: r(
|
|
280
|
+
children: r(x, "workspaceInvite.workspaceLoadError", "Unable to load workspace invite details.")
|
|
232
281
|
})]
|
|
233
282
|
});
|
|
234
|
-
let
|
|
235
|
-
it((n) => t ? [...n, e].filter((e, t, n) => n.indexOf(e) === t) : n.filter((t) => t !== e));
|
|
236
|
-
}, Tt = (e, t) => {
|
|
283
|
+
let Et = (e, t) => {
|
|
237
284
|
at((n) => t ? [...n, e].filter((e, t, n) => n.indexOf(e) === t) : n.filter((t) => t !== e));
|
|
238
|
-
},
|
|
239
|
-
|
|
240
|
-
|
|
285
|
+
}, Dt = (e, t) => {
|
|
286
|
+
ot((n) => t ? [...n, e].filter((e, t, n) => n.indexOf(e) === t) : n.filter((t) => t !== e));
|
|
287
|
+
}, Ot = async (e) => {
|
|
288
|
+
if (e.preventDefault(), I(null), lt(null), B(null), !N.trim()) {
|
|
289
|
+
I("Email is required.");
|
|
241
290
|
return;
|
|
242
291
|
}
|
|
243
292
|
try {
|
|
244
|
-
await
|
|
293
|
+
await _t(Ue(O, N.trim().toLowerCase(), P, F)), it(""), lt(`Invitation sent to ${N.trim().toLowerCase()}.`);
|
|
245
294
|
} catch (e) {
|
|
246
|
-
|
|
295
|
+
I(D(e));
|
|
247
296
|
}
|
|
248
|
-
},
|
|
249
|
-
if (!
|
|
250
|
-
|
|
297
|
+
}, kt = (e) => {
|
|
298
|
+
if (!Be(e)) {
|
|
299
|
+
L("Please upload a .csv file.");
|
|
251
300
|
return;
|
|
252
301
|
}
|
|
253
302
|
if (e.size > Re) {
|
|
254
|
-
|
|
303
|
+
L("CSV file is too large (max 1 MB).");
|
|
255
304
|
return;
|
|
256
305
|
}
|
|
257
306
|
let t = new FileReader();
|
|
258
307
|
t.onload = () => {
|
|
259
308
|
let n = le(typeof t.result == "string" ? t.result : "");
|
|
260
|
-
|
|
309
|
+
H(n.slice(0, E).map((e) => ({
|
|
261
310
|
...e,
|
|
262
311
|
status: { kind: "idle" }
|
|
263
|
-
}))),
|
|
312
|
+
}))), pt(e.name), L(n.length > E ? `Only the first ${E} rows were loaded. Split larger CSV files into smaller batches.` : null), R(null), B(null);
|
|
264
313
|
}, t.onerror = () => {
|
|
265
|
-
|
|
314
|
+
L("Failed to read CSV file.");
|
|
266
315
|
}, t.readAsText(e);
|
|
267
|
-
},
|
|
268
|
-
if (!(Q.length === 0 ||
|
|
269
|
-
|
|
316
|
+
}, At = async () => {
|
|
317
|
+
if (!(Q.length === 0 || W)) {
|
|
318
|
+
L(null), R(null), B(null), ht(!0), H((e) => e.map((e) => e.errors.length === 0 && e.status.kind !== "invited" ? {
|
|
270
319
|
...e,
|
|
271
320
|
status: { kind: "sending" }
|
|
272
321
|
} : e));
|
|
273
322
|
try {
|
|
274
|
-
await
|
|
323
|
+
await vt(Q.map((e) => Ue(O, e.email, P, F))), H((e) => e.map((e) => e.status.kind === "sending" ? {
|
|
275
324
|
...e,
|
|
276
325
|
status: { kind: "invited" }
|
|
277
|
-
} : e)),
|
|
326
|
+
} : e)), R(`Sent ${Q.length} workspace invitation${Q.length === 1 ? "" : "s"}.`);
|
|
278
327
|
} catch (e) {
|
|
279
|
-
let t =
|
|
280
|
-
|
|
328
|
+
let t = D(e);
|
|
329
|
+
H((e) => e.map((e) => e.status.kind === "sending" ? {
|
|
281
330
|
...e,
|
|
282
331
|
status: {
|
|
283
332
|
kind: "failed",
|
|
284
333
|
message: t
|
|
285
334
|
}
|
|
286
|
-
} : e)),
|
|
335
|
+
} : e)), L(t);
|
|
287
336
|
} finally {
|
|
288
|
-
|
|
337
|
+
ht(!1);
|
|
289
338
|
}
|
|
290
339
|
}
|
|
291
|
-
},
|
|
292
|
-
|
|
340
|
+
}, jt = (e) => {
|
|
341
|
+
B(null), X(e.id), bt(e.id, {
|
|
293
342
|
onSuccess: () => {
|
|
294
|
-
|
|
343
|
+
B({
|
|
295
344
|
tone: "success",
|
|
296
345
|
message: `Invitation resent to ${e.email}.`
|
|
297
346
|
});
|
|
298
347
|
},
|
|
299
348
|
onError: (e) => {
|
|
300
|
-
|
|
349
|
+
B({
|
|
301
350
|
tone: "error",
|
|
302
|
-
message:
|
|
351
|
+
message: D(e)
|
|
303
352
|
});
|
|
304
353
|
},
|
|
305
354
|
onSettled: () => X(null)
|
|
306
355
|
});
|
|
307
356
|
};
|
|
308
|
-
return /* @__PURE__ */
|
|
309
|
-
open: !!
|
|
310
|
-
onOpenChange: (e) => !e &&
|
|
311
|
-
children: /* @__PURE__ */
|
|
357
|
+
return /* @__PURE__ */ m(ye, { children: [/* @__PURE__ */ p(be, {
|
|
358
|
+
open: !!G,
|
|
359
|
+
onOpenChange: (e) => !e && K(null),
|
|
360
|
+
children: /* @__PURE__ */ m(Ce, { children: [/* @__PURE__ */ m(Ee, { children: [/* @__PURE__ */ p(De, { children: "Cancel pending invitation?" }), /* @__PURE__ */ p(we, { children: G ? `This will revoke the pending invite for ${G.email}. They will need a new invitation to join later.` : "This will revoke the pending invitation." })] }), /* @__PURE__ */ m(Te, { children: [/* @__PURE__ */ p(Se, {
|
|
312
361
|
disabled: Y,
|
|
313
362
|
children: "Keep invitation"
|
|
314
|
-
}), /* @__PURE__ */
|
|
363
|
+
}), /* @__PURE__ */ m(xe, {
|
|
315
364
|
onClick: () => {
|
|
316
|
-
|
|
365
|
+
G && (B(null), X(G.id), xt(G.id, {
|
|
317
366
|
onSuccess: () => {
|
|
318
|
-
|
|
367
|
+
B({
|
|
319
368
|
tone: "success",
|
|
320
|
-
message: `Invitation cancelled for ${
|
|
321
|
-
}),
|
|
369
|
+
message: `Invitation cancelled for ${G.email}.`
|
|
370
|
+
}), K(null);
|
|
322
371
|
},
|
|
323
372
|
onError: (e) => {
|
|
324
|
-
|
|
373
|
+
B({
|
|
325
374
|
tone: "error",
|
|
326
|
-
message:
|
|
375
|
+
message: D(e)
|
|
327
376
|
});
|
|
328
377
|
},
|
|
329
378
|
onSettled: () => X(null)
|
|
330
379
|
}));
|
|
331
380
|
},
|
|
332
381
|
disabled: Y,
|
|
333
|
-
children: [Y ? /* @__PURE__ */
|
|
382
|
+
children: [Y ? /* @__PURE__ */ p(d, { className: "size-4 animate-spin" }) : null, "Cancel invitation"]
|
|
334
383
|
})] })] })
|
|
335
|
-
}), /* @__PURE__ */
|
|
384
|
+
}), /* @__PURE__ */ m("div", {
|
|
336
385
|
className: "space-y-6 p-3 sm:p-6",
|
|
337
386
|
children: [
|
|
338
|
-
/* @__PURE__ */
|
|
387
|
+
/* @__PURE__ */ p("div", {
|
|
339
388
|
className: "flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between",
|
|
340
|
-
children: /* @__PURE__ */
|
|
341
|
-
/* @__PURE__ */
|
|
389
|
+
children: /* @__PURE__ */ m("div", { children: [
|
|
390
|
+
/* @__PURE__ */ m(g, {
|
|
342
391
|
variant: "ghost",
|
|
343
|
-
onClick: () =>
|
|
392
|
+
onClick: () => C(T(`${w}/${O}`)),
|
|
344
393
|
className: "-ml-2 mb-2 gap-2",
|
|
345
|
-
children: [/* @__PURE__ */
|
|
394
|
+
children: [/* @__PURE__ */ p(de, { size: 18 }), r(x, "workspaceInvite.backToWorkspace", "Back to Workspace")]
|
|
346
395
|
}),
|
|
347
|
-
/* @__PURE__ */
|
|
396
|
+
/* @__PURE__ */ m("div", {
|
|
348
397
|
className: "flex items-center gap-2",
|
|
349
|
-
children: [/* @__PURE__ */
|
|
398
|
+
children: [/* @__PURE__ */ p(_e, {
|
|
350
399
|
className: "text-primary",
|
|
351
400
|
size: 24
|
|
352
|
-
}), /* @__PURE__ */
|
|
401
|
+
}), /* @__PURE__ */ p("h1", {
|
|
353
402
|
className: "text-2xl font-bold sm:text-3xl",
|
|
354
|
-
children: r(
|
|
403
|
+
children: r(x, "workspaceInvite.title", "Invite Members")
|
|
355
404
|
})]
|
|
356
405
|
}),
|
|
357
|
-
/* @__PURE__ */
|
|
406
|
+
/* @__PURE__ */ m("p", {
|
|
358
407
|
className: "mt-2 text-sm text-text-secondary sm:text-base",
|
|
359
408
|
children: [
|
|
360
|
-
|
|
409
|
+
qe.name,
|
|
361
410
|
" —",
|
|
362
411
|
" ",
|
|
363
|
-
r(
|
|
412
|
+
r(x, "workspaceInvite.subtitle", "Invite people into this workspace and optionally grant project access.")
|
|
364
413
|
]
|
|
365
414
|
})
|
|
366
415
|
] })
|
|
367
416
|
}),
|
|
368
|
-
/* @__PURE__ */
|
|
369
|
-
selectedRoleIds:
|
|
370
|
-
onRoleToggle:
|
|
371
|
-
selectedProjectIds:
|
|
372
|
-
onProjectToggle:
|
|
373
|
-
availableRoles:
|
|
374
|
-
availableProjects:
|
|
375
|
-
isLoadingRoles:
|
|
376
|
-
isLoadingProjects:
|
|
377
|
-
disabled:
|
|
417
|
+
/* @__PURE__ */ m(_, { children: [/* @__PURE__ */ p(y, { children: /* @__PURE__ */ p(b, { children: r(x, "workspaceInvite.setupTitle", "Access to grant on acceptance") }) }), /* @__PURE__ */ p(v, { children: /* @__PURE__ */ p(We, {
|
|
418
|
+
selectedRoleIds: P,
|
|
419
|
+
onRoleToggle: Et,
|
|
420
|
+
selectedProjectIds: F,
|
|
421
|
+
onProjectToggle: Dt,
|
|
422
|
+
availableRoles: k,
|
|
423
|
+
availableProjects: M,
|
|
424
|
+
isLoadingRoles: Xe,
|
|
425
|
+
isLoadingProjects: Ze,
|
|
426
|
+
disabled: Ct
|
|
378
427
|
}) })] }),
|
|
379
|
-
/* @__PURE__ */
|
|
428
|
+
/* @__PURE__ */ m(_, { children: [/* @__PURE__ */ p(y, { children: /* @__PURE__ */ p(b, { children: "Selection summary" }) }), /* @__PURE__ */ m(v, {
|
|
380
429
|
className: "grid gap-4 md:grid-cols-2",
|
|
381
|
-
children: [/* @__PURE__ */
|
|
430
|
+
children: [/* @__PURE__ */ m("div", {
|
|
382
431
|
className: "space-y-2 rounded-lg border p-4",
|
|
383
|
-
children: [/* @__PURE__ */
|
|
432
|
+
children: [/* @__PURE__ */ m("div", {
|
|
384
433
|
className: "flex items-center justify-between gap-2",
|
|
385
|
-
children: [/* @__PURE__ */
|
|
434
|
+
children: [/* @__PURE__ */ p("p", {
|
|
386
435
|
className: "text-sm font-medium",
|
|
387
436
|
children: "Roles"
|
|
388
|
-
}), /* @__PURE__ */
|
|
437
|
+
}), /* @__PURE__ */ p(h, {
|
|
389
438
|
variant: "secondary",
|
|
390
|
-
children:
|
|
439
|
+
children: wt.length
|
|
391
440
|
})]
|
|
392
|
-
}), /* @__PURE__ */
|
|
441
|
+
}), /* @__PURE__ */ p("p", {
|
|
393
442
|
className: "text-sm text-text-secondary",
|
|
394
|
-
children:
|
|
443
|
+
children: He(wt, "No roles selected")
|
|
395
444
|
})]
|
|
396
|
-
}), /* @__PURE__ */
|
|
445
|
+
}), /* @__PURE__ */ m("div", {
|
|
397
446
|
className: "space-y-2 rounded-lg border p-4",
|
|
398
|
-
children: [/* @__PURE__ */
|
|
447
|
+
children: [/* @__PURE__ */ m("div", {
|
|
399
448
|
className: "flex items-center justify-between gap-2",
|
|
400
|
-
children: [/* @__PURE__ */
|
|
449
|
+
children: [/* @__PURE__ */ p("p", {
|
|
401
450
|
className: "text-sm font-medium",
|
|
402
451
|
children: "Projects"
|
|
403
|
-
}), /* @__PURE__ */
|
|
452
|
+
}), /* @__PURE__ */ p(h, {
|
|
404
453
|
variant: "secondary",
|
|
405
|
-
children:
|
|
454
|
+
children: Tt.length
|
|
406
455
|
})]
|
|
407
|
-
}), /* @__PURE__ */
|
|
456
|
+
}), /* @__PURE__ */ p("p", {
|
|
408
457
|
className: "text-sm text-text-secondary",
|
|
409
|
-
children:
|
|
458
|
+
children: He(Tt, "No project access will be granted automatically")
|
|
410
459
|
})]
|
|
411
460
|
})]
|
|
412
461
|
})] }),
|
|
413
|
-
/* @__PURE__ */
|
|
414
|
-
value:
|
|
415
|
-
onValueChange: (e) =>
|
|
462
|
+
/* @__PURE__ */ m(_, { children: [/* @__PURE__ */ p(y, { children: /* @__PURE__ */ p(b, { children: r(x, "workspaceInvite.sendTitle", "Send invitations") }) }), /* @__PURE__ */ p(v, { children: /* @__PURE__ */ m(Ae, {
|
|
463
|
+
value: nt,
|
|
464
|
+
onValueChange: (e) => rt(e),
|
|
416
465
|
className: "space-y-5",
|
|
417
466
|
children: [
|
|
418
|
-
/* @__PURE__ */
|
|
467
|
+
/* @__PURE__ */ m(Me, { children: [/* @__PURE__ */ p(Ne, {
|
|
419
468
|
value: "single",
|
|
420
|
-
children: r(
|
|
421
|
-
}), /* @__PURE__ */
|
|
469
|
+
children: r(x, "workspaceInvite.modeSingle", "Single")
|
|
470
|
+
}), /* @__PURE__ */ p(Ne, {
|
|
422
471
|
value: "bulk",
|
|
423
|
-
children: r(
|
|
472
|
+
children: r(x, "workspaceInvite.modeBulk", "Bulk CSV")
|
|
424
473
|
})] }),
|
|
425
|
-
/* @__PURE__ */
|
|
474
|
+
/* @__PURE__ */ m(je, {
|
|
426
475
|
value: "single",
|
|
427
476
|
className: "space-y-4",
|
|
428
477
|
children: [
|
|
429
|
-
|
|
478
|
+
st ? /* @__PURE__ */ m("div", {
|
|
430
479
|
className: "flex items-center gap-2 rounded-md border border-status-error-border/20 bg-status-error-bg/10 p-3 text-sm text-status-error-text",
|
|
431
|
-
children: [/* @__PURE__ */
|
|
480
|
+
children: [/* @__PURE__ */ p(l, { className: "size-4 shrink-0" }), /* @__PURE__ */ p("span", { children: st })]
|
|
432
481
|
}) : null,
|
|
433
|
-
|
|
482
|
+
ct ? /* @__PURE__ */ m("div", {
|
|
434
483
|
className: "flex items-center gap-2 rounded-md border border-green-500/20 bg-green-500/10 p-3 text-sm text-green-700 dark:text-green-400",
|
|
435
|
-
children: [/* @__PURE__ */
|
|
484
|
+
children: [/* @__PURE__ */ p(u, { className: "size-4 shrink-0" }), /* @__PURE__ */ p("span", { children: ct })]
|
|
436
485
|
}) : null,
|
|
437
|
-
/* @__PURE__ */
|
|
438
|
-
onSubmit:
|
|
486
|
+
/* @__PURE__ */ m("form", {
|
|
487
|
+
onSubmit: Ot,
|
|
439
488
|
className: "space-y-4",
|
|
440
|
-
children: [/* @__PURE__ */
|
|
489
|
+
children: [/* @__PURE__ */ m("div", {
|
|
441
490
|
className: "space-y-2",
|
|
442
|
-
children: [/* @__PURE__ */
|
|
491
|
+
children: [/* @__PURE__ */ p("label", {
|
|
443
492
|
htmlFor: "workspace-invite-email",
|
|
444
493
|
className: "text-sm font-medium",
|
|
445
|
-
children: r(
|
|
446
|
-
}), /* @__PURE__ */
|
|
494
|
+
children: r(x, "workspaceInvite.emailLabel", "Email Address")
|
|
495
|
+
}), /* @__PURE__ */ p(Oe, {
|
|
447
496
|
id: "workspace-invite-email",
|
|
448
497
|
type: "email",
|
|
449
498
|
placeholder: "member@example.com",
|
|
450
|
-
value:
|
|
451
|
-
onChange: (e) =>
|
|
452
|
-
disabled:
|
|
499
|
+
value: N,
|
|
500
|
+
onChange: (e) => it(e.target.value),
|
|
501
|
+
disabled: q
|
|
453
502
|
})]
|
|
454
|
-
}), /* @__PURE__ */
|
|
503
|
+
}), /* @__PURE__ */ p("div", {
|
|
455
504
|
className: "flex justify-end",
|
|
456
|
-
children: /* @__PURE__ */
|
|
505
|
+
children: /* @__PURE__ */ m(g, {
|
|
457
506
|
type: "submit",
|
|
458
|
-
disabled:
|
|
507
|
+
disabled: q,
|
|
459
508
|
className: "gap-2",
|
|
460
|
-
children: [
|
|
509
|
+
children: [q ? /* @__PURE__ */ p(d, { className: "size-4 animate-spin" }) : /* @__PURE__ */ p(he, { className: "size-4" }), r(x, "workspaceInvite.sendSingleButton", "Send Invitation")]
|
|
461
510
|
})
|
|
462
511
|
})]
|
|
463
512
|
})
|
|
464
513
|
]
|
|
465
514
|
}),
|
|
466
|
-
/* @__PURE__ */
|
|
515
|
+
/* @__PURE__ */ m(je, {
|
|
467
516
|
value: "bulk",
|
|
468
517
|
className: "space-y-5",
|
|
469
518
|
children: [
|
|
470
|
-
|
|
519
|
+
ut ? /* @__PURE__ */ m("div", {
|
|
471
520
|
className: "flex items-center gap-2 rounded-md border border-status-error-border/20 bg-status-error-bg/10 p-3 text-sm text-status-error-text",
|
|
472
|
-
children: [/* @__PURE__ */
|
|
521
|
+
children: [/* @__PURE__ */ p(l, { className: "size-4 shrink-0" }), /* @__PURE__ */ p("span", { children: ut })]
|
|
473
522
|
}) : null,
|
|
474
|
-
|
|
523
|
+
dt ? /* @__PURE__ */ m("div", {
|
|
475
524
|
className: "flex items-center gap-2 rounded-md border border-green-500/20 bg-green-500/10 p-3 text-sm text-green-700 dark:text-green-400",
|
|
476
|
-
children: [/* @__PURE__ */
|
|
525
|
+
children: [/* @__PURE__ */ p(u, { className: "size-4 shrink-0" }), /* @__PURE__ */ p("span", { children: dt })]
|
|
477
526
|
}) : null,
|
|
478
|
-
/* @__PURE__ */
|
|
527
|
+
/* @__PURE__ */ m("div", {
|
|
479
528
|
className: "flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",
|
|
480
|
-
children: [/* @__PURE__ */
|
|
529
|
+
children: [/* @__PURE__ */ m("div", {
|
|
481
530
|
className: "space-y-1",
|
|
482
531
|
children: [
|
|
483
|
-
/* @__PURE__ */
|
|
532
|
+
/* @__PURE__ */ p("p", {
|
|
484
533
|
className: "text-sm text-text-secondary",
|
|
485
|
-
children: r(
|
|
534
|
+
children: r(x, "workspaceInvite.bulkDescription", "Upload a CSV with one email column. All valid rows will receive the currently selected roles and projects.")
|
|
486
535
|
}),
|
|
487
|
-
/* @__PURE__ */
|
|
536
|
+
/* @__PURE__ */ m("div", {
|
|
488
537
|
className: "rounded-md border bg-bg-sunken/30 px-3 py-2 text-xs text-text-secondary",
|
|
489
|
-
children: [/* @__PURE__ */
|
|
538
|
+
children: [/* @__PURE__ */ p("p", {
|
|
490
539
|
className: "font-medium text-text-primary",
|
|
491
540
|
children: "Sample format"
|
|
492
|
-
}), /* @__PURE__ */
|
|
541
|
+
}), /* @__PURE__ */ m("pre", {
|
|
493
542
|
className: "mt-1 whitespace-pre-wrap",
|
|
494
543
|
children: [
|
|
495
544
|
"email",
|
|
@@ -500,81 +549,81 @@ function D() {
|
|
|
500
549
|
]
|
|
501
550
|
})]
|
|
502
551
|
}),
|
|
503
|
-
(
|
|
552
|
+
(A?.total ?? 0) > M.length ? /* @__PURE__ */ m("p", {
|
|
504
553
|
className: "text-xs text-text-secondary",
|
|
505
554
|
children: [
|
|
506
555
|
"Showing the first ",
|
|
507
|
-
|
|
556
|
+
M.length,
|
|
508
557
|
" active projects. Narrow the workspace project list if you need to invite into more."
|
|
509
558
|
]
|
|
510
559
|
}) : null
|
|
511
560
|
]
|
|
512
|
-
}), /* @__PURE__ */
|
|
561
|
+
}), /* @__PURE__ */ m(g, {
|
|
513
562
|
type: "button",
|
|
514
563
|
variant: "outline",
|
|
515
564
|
onClick: ce,
|
|
516
565
|
className: "gap-2",
|
|
517
|
-
children: [/* @__PURE__ */
|
|
566
|
+
children: [/* @__PURE__ */ p(fe, { size: 16 }), r(x, "workspaceInvite.downloadTemplate", "Download template")]
|
|
518
567
|
})]
|
|
519
568
|
}),
|
|
520
|
-
/* @__PURE__ */
|
|
569
|
+
/* @__PURE__ */ m("div", {
|
|
521
570
|
onDragOver: (e) => {
|
|
522
|
-
e.preventDefault(),
|
|
571
|
+
e.preventDefault(), U(!0);
|
|
523
572
|
},
|
|
524
|
-
onDragLeave: () =>
|
|
573
|
+
onDragLeave: () => U(!1),
|
|
525
574
|
onDrop: (e) => {
|
|
526
|
-
e.preventDefault(),
|
|
575
|
+
e.preventDefault(), U(!1);
|
|
527
576
|
let t = e.dataTransfer.files?.[0];
|
|
528
|
-
t ?
|
|
577
|
+
t ? kt(t) : L("Please upload a .csv file.");
|
|
529
578
|
},
|
|
530
|
-
className: `flex flex-col items-center justify-center gap-3 rounded-xl border-2 border-dashed p-8 transition-colors ${
|
|
579
|
+
className: `flex flex-col items-center justify-center gap-3 rounded-xl border-2 border-dashed p-8 transition-colors ${mt ? "border-primary bg-action-primary-bg/5" : "border-border-subtle bg-bg-surface"}`,
|
|
531
580
|
children: [
|
|
532
|
-
/* @__PURE__ */
|
|
581
|
+
/* @__PURE__ */ p(ge, {
|
|
533
582
|
size: 28,
|
|
534
583
|
className: "text-text-secondary"
|
|
535
584
|
}),
|
|
536
|
-
/* @__PURE__ */
|
|
585
|
+
/* @__PURE__ */ m("div", {
|
|
537
586
|
className: "text-center",
|
|
538
|
-
children: [/* @__PURE__ */
|
|
587
|
+
children: [/* @__PURE__ */ p("p", {
|
|
539
588
|
className: "text-sm font-medium",
|
|
540
|
-
children:
|
|
541
|
-
}), /* @__PURE__ */
|
|
589
|
+
children: ft || "Drop a CSV file here or click to browse"
|
|
590
|
+
}), /* @__PURE__ */ p("p", {
|
|
542
591
|
className: "mt-1 text-xs text-text-secondary",
|
|
543
592
|
children: "CSV files only. Required column: email."
|
|
544
593
|
})]
|
|
545
594
|
}),
|
|
546
|
-
/* @__PURE__ */
|
|
547
|
-
ref:
|
|
595
|
+
/* @__PURE__ */ p("input", {
|
|
596
|
+
ref: gt,
|
|
548
597
|
type: "file",
|
|
549
598
|
accept: ".csv,text/csv",
|
|
550
599
|
onChange: (e) => {
|
|
551
600
|
let t = e.target.files?.[0];
|
|
552
|
-
t &&
|
|
601
|
+
t && kt(t), e.target.value = "";
|
|
553
602
|
},
|
|
554
603
|
className: "hidden",
|
|
555
604
|
"aria-label": "Choose CSV file"
|
|
556
605
|
}),
|
|
557
|
-
/* @__PURE__ */
|
|
606
|
+
/* @__PURE__ */ p(g, {
|
|
558
607
|
type: "button",
|
|
559
|
-
onClick: () =>
|
|
560
|
-
children: r(
|
|
608
|
+
onClick: () => gt.current?.click(),
|
|
609
|
+
children: r(x, "workspaceInvite.chooseFile", "Choose file")
|
|
561
610
|
})
|
|
562
611
|
]
|
|
563
612
|
}),
|
|
564
|
-
|
|
565
|
-
/* @__PURE__ */
|
|
613
|
+
V.length > 0 ? /* @__PURE__ */ m(ye, { children: [
|
|
614
|
+
/* @__PURE__ */ m("div", {
|
|
566
615
|
className: "flex flex-wrap gap-4 text-xs text-text-secondary",
|
|
567
616
|
children: [
|
|
568
|
-
/* @__PURE__ */
|
|
569
|
-
/* @__PURE__ */
|
|
570
|
-
/* @__PURE__ */
|
|
571
|
-
$.length > 0 ? /* @__PURE__ */
|
|
617
|
+
/* @__PURE__ */ m("span", { children: ["Total rows: ", V.length] }),
|
|
618
|
+
/* @__PURE__ */ m("span", { children: ["Ready: ", Q.length] }),
|
|
619
|
+
/* @__PURE__ */ m("span", { children: ["With errors: ", $.length] }),
|
|
620
|
+
$.length > 0 ? /* @__PURE__ */ p(h, {
|
|
572
621
|
variant: "destructive",
|
|
573
622
|
children: "Invalid rows will be skipped"
|
|
574
623
|
}) : null
|
|
575
624
|
]
|
|
576
625
|
}),
|
|
577
|
-
$.length > 0 ? /* @__PURE__ */
|
|
626
|
+
$.length > 0 ? /* @__PURE__ */ m("div", {
|
|
578
627
|
className: "rounded-md border border-status-error-border/20 bg-status-error-bg/10 px-3 py-2 text-sm text-status-error-text",
|
|
579
628
|
children: [
|
|
580
629
|
$.length,
|
|
@@ -583,217 +632,153 @@ function D() {
|
|
|
583
632
|
" need attention. Only valid rows can be invited."
|
|
584
633
|
]
|
|
585
634
|
}) : null,
|
|
586
|
-
/* @__PURE__ */
|
|
635
|
+
/* @__PURE__ */ p("div", {
|
|
587
636
|
className: "overflow-hidden rounded-xl border",
|
|
588
|
-
children: /* @__PURE__ */
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
children: [/* @__PURE__ */ f("thead", {
|
|
593
|
-
className: "bg-bg-sunken/40",
|
|
594
|
-
children: /* @__PURE__ */ p("tr", { children: [
|
|
595
|
-
/* @__PURE__ */ f("th", {
|
|
596
|
-
className: "px-3 py-2 text-left text-xs font-semibold uppercase tracking-wide text-text-secondary",
|
|
597
|
-
children: "#"
|
|
598
|
-
}),
|
|
599
|
-
/* @__PURE__ */ f("th", {
|
|
600
|
-
className: "px-3 py-2 text-left text-xs font-semibold uppercase tracking-wide text-text-secondary",
|
|
601
|
-
children: "Email"
|
|
602
|
-
}),
|
|
603
|
-
/* @__PURE__ */ f("th", {
|
|
604
|
-
className: "px-3 py-2 text-left text-xs font-semibold uppercase tracking-wide text-text-secondary",
|
|
605
|
-
children: "Status"
|
|
606
|
-
})
|
|
607
|
-
] })
|
|
608
|
-
}), /* @__PURE__ */ f("tbody", {
|
|
609
|
-
className: "divide-y",
|
|
610
|
-
children: B.map((e) => {
|
|
611
|
-
let t = e.errors.length > 0;
|
|
612
|
-
return /* @__PURE__ */ p("tr", {
|
|
613
|
-
className: t ? "bg-status-error-bg/5" : void 0,
|
|
614
|
-
children: [
|
|
615
|
-
/* @__PURE__ */ f("td", {
|
|
616
|
-
className: "px-3 py-2 text-xs text-text-secondary",
|
|
617
|
-
children: e.rowNumber
|
|
618
|
-
}),
|
|
619
|
-
/* @__PURE__ */ f("td", {
|
|
620
|
-
className: "px-3 py-2 text-sm",
|
|
621
|
-
children: e.email || /* @__PURE__ */ f("span", {
|
|
622
|
-
className: "italic text-text-secondary",
|
|
623
|
-
children: "(empty)"
|
|
624
|
-
})
|
|
625
|
-
}),
|
|
626
|
-
/* @__PURE__ */ f("td", {
|
|
627
|
-
className: "px-3 py-2 text-xs",
|
|
628
|
-
children: t ? /* @__PURE__ */ f("div", {
|
|
629
|
-
className: "space-y-1 text-status-error-text",
|
|
630
|
-
children: e.errors.map((t) => /* @__PURE__ */ p("span", {
|
|
631
|
-
className: "inline-flex items-center gap-1 pr-3",
|
|
632
|
-
children: [/* @__PURE__ */ f(d, { size: 14 }), t]
|
|
633
|
-
}, `${e.rowNumber}-${t}`))
|
|
634
|
-
}) : e.status.kind === "sending" ? /* @__PURE__ */ p("span", {
|
|
635
|
-
className: "inline-flex items-center gap-1 text-text-secondary",
|
|
636
|
-
children: [/* @__PURE__ */ f(u, {
|
|
637
|
-
size: 14,
|
|
638
|
-
className: "animate-spin"
|
|
639
|
-
}), "Sending..."]
|
|
640
|
-
}) : e.status.kind === "invited" ? /* @__PURE__ */ p("span", {
|
|
641
|
-
className: "inline-flex items-center gap-1 text-green-700 dark:text-green-400",
|
|
642
|
-
children: [/* @__PURE__ */ f(l, { size: 14 }), "Invited"]
|
|
643
|
-
}) : e.status.kind === "failed" ? /* @__PURE__ */ p("span", {
|
|
644
|
-
className: "inline-flex items-center gap-1 text-status-error-text",
|
|
645
|
-
children: [/* @__PURE__ */ f(d, { size: 14 }), e.status.message]
|
|
646
|
-
}) : /* @__PURE__ */ f("span", {
|
|
647
|
-
className: "text-text-secondary",
|
|
648
|
-
children: "Ready"
|
|
649
|
-
})
|
|
650
|
-
})
|
|
651
|
-
]
|
|
652
|
-
}, `${e.rowNumber}-${e.email}`);
|
|
653
|
-
})
|
|
654
|
-
})]
|
|
655
|
-
})
|
|
637
|
+
children: /* @__PURE__ */ p(ke, {
|
|
638
|
+
columns: ze,
|
|
639
|
+
data: V,
|
|
640
|
+
rowKey: (e) => `${e.rowNumber}-${e.email}`
|
|
656
641
|
})
|
|
657
642
|
})
|
|
658
|
-
] }) : /* @__PURE__ */
|
|
643
|
+
] }) : /* @__PURE__ */ p("div", {
|
|
659
644
|
className: "rounded-xl border border-dashed p-6 text-center text-sm text-text-secondary",
|
|
660
645
|
children: "Upload a CSV to preview invite rows here before sending."
|
|
661
646
|
}),
|
|
662
|
-
/* @__PURE__ */
|
|
647
|
+
/* @__PURE__ */ p("div", {
|
|
663
648
|
className: "flex justify-end",
|
|
664
|
-
children: /* @__PURE__ */
|
|
649
|
+
children: /* @__PURE__ */ m(g, {
|
|
665
650
|
type: "button",
|
|
666
|
-
onClick:
|
|
667
|
-
disabled: Q.length === 0 ||
|
|
651
|
+
onClick: At,
|
|
652
|
+
disabled: Q.length === 0 || yt || W,
|
|
668
653
|
className: "gap-2",
|
|
669
|
-
children: [
|
|
654
|
+
children: [yt || W ? /* @__PURE__ */ p(d, { className: "size-4 animate-spin" }) : /* @__PURE__ */ p(he, { className: "size-4" }), r(x, "workspaceInvite.sendBulkButton", "Send Bulk Invites")]
|
|
670
655
|
})
|
|
671
656
|
})
|
|
672
657
|
]
|
|
673
658
|
})
|
|
674
659
|
]
|
|
675
660
|
}) })] }),
|
|
676
|
-
/* @__PURE__ */
|
|
661
|
+
/* @__PURE__ */ m(_, { children: [/* @__PURE__ */ p(y, { children: /* @__PURE__ */ m(b, {
|
|
677
662
|
className: "flex items-center gap-2",
|
|
678
663
|
children: [
|
|
679
|
-
/* @__PURE__ */
|
|
680
|
-
r(
|
|
681
|
-
/* @__PURE__ */
|
|
664
|
+
/* @__PURE__ */ p(pe, { className: "size-5 text-primary" }),
|
|
665
|
+
r(x, "workspaceInvite.pendingTitle", "Pending Invitations"),
|
|
666
|
+
/* @__PURE__ */ p(h, {
|
|
682
667
|
variant: "secondary",
|
|
683
668
|
children: Z.length
|
|
684
669
|
})
|
|
685
670
|
]
|
|
686
|
-
}) }), /* @__PURE__ */
|
|
687
|
-
className: `mb-4 flex items-center gap-2 rounded-md border p-3 text-sm ${
|
|
688
|
-
children: [
|
|
689
|
-
}) : null,
|
|
671
|
+
}) }), /* @__PURE__ */ m(v, { children: [z ? /* @__PURE__ */ m("div", {
|
|
672
|
+
className: `mb-4 flex items-center gap-2 rounded-md border p-3 text-sm ${z.tone === "success" ? "border-green-500/20 bg-green-500/10 text-green-700 dark:text-green-400" : "border-status-error-border/20 bg-status-error-bg/10 text-status-error-text"}`,
|
|
673
|
+
children: [z.tone === "success" ? /* @__PURE__ */ p(u, { className: "size-4 shrink-0" }) : /* @__PURE__ */ p(l, { className: "size-4 shrink-0" }), /* @__PURE__ */ p("span", { children: z.message })]
|
|
674
|
+
}) : null, $e ? /* @__PURE__ */ m("div", {
|
|
690
675
|
className: "space-y-3",
|
|
691
|
-
children: [/* @__PURE__ */
|
|
692
|
-
}) :
|
|
676
|
+
children: [/* @__PURE__ */ p(S, { className: "h-20 w-full" }), /* @__PURE__ */ p(S, { className: "h-20 w-full" })]
|
|
677
|
+
}) : et && Z.length === 0 ? /* @__PURE__ */ m("div", {
|
|
693
678
|
role: "alert",
|
|
694
679
|
className: "space-y-3 rounded-md border border-status-error-border/20 bg-status-error-bg/10 p-3 text-sm text-status-error-text",
|
|
695
|
-
children: [/* @__PURE__ */
|
|
680
|
+
children: [/* @__PURE__ */ p("p", { children: r(x, "workspaceInvite.pendingLoadFailed", "Failed to load pending invitations for this workspace.") }), /* @__PURE__ */ p(g, {
|
|
696
681
|
type: "button",
|
|
697
682
|
variant: "outline",
|
|
698
683
|
size: "sm",
|
|
699
684
|
className: "w-fit",
|
|
700
|
-
disabled:
|
|
685
|
+
disabled: j,
|
|
701
686
|
onClick: () => {
|
|
702
|
-
|
|
687
|
+
tt();
|
|
703
688
|
},
|
|
704
|
-
children:
|
|
689
|
+
children: j ? r(x, "workspaceInvite.retrying", "Retrying…") : r(x, "workspaceInvite.tryAgain", "Try again")
|
|
705
690
|
})]
|
|
706
|
-
}) : Z.length === 0 ? /* @__PURE__ */
|
|
691
|
+
}) : Z.length === 0 ? /* @__PURE__ */ p("p", {
|
|
707
692
|
className: "text-sm text-text-secondary",
|
|
708
|
-
children: r(
|
|
709
|
-
}) : /* @__PURE__ */
|
|
693
|
+
children: r(x, "workspaceInvite.pendingEmpty", "No pending invitations for this workspace.")
|
|
694
|
+
}) : /* @__PURE__ */ m("div", {
|
|
710
695
|
className: "space-y-3",
|
|
711
|
-
children: [
|
|
696
|
+
children: [et ? /* @__PURE__ */ m("div", {
|
|
712
697
|
role: "alert",
|
|
713
698
|
className: "flex flex-wrap items-center justify-between gap-3 rounded-md border border-status-error-border/20 bg-status-error-bg/10 p-3 text-sm text-status-error-text",
|
|
714
|
-
children: [/* @__PURE__ */
|
|
699
|
+
children: [/* @__PURE__ */ p("span", { children: r(x, "workspaceInvite.pendingStaleWarning", "Pending invitations may be outdated. Try again to refresh this list.") }), /* @__PURE__ */ p(g, {
|
|
715
700
|
type: "button",
|
|
716
701
|
variant: "outline",
|
|
717
702
|
size: "sm",
|
|
718
703
|
className: "w-fit",
|
|
719
|
-
disabled:
|
|
704
|
+
disabled: j,
|
|
720
705
|
onClick: () => {
|
|
721
|
-
|
|
706
|
+
tt();
|
|
722
707
|
},
|
|
723
|
-
children:
|
|
708
|
+
children: j ? r(x, "workspaceInvite.retrying", "Retrying…") : r(x, "workspaceInvite.tryAgain", "Try again")
|
|
724
709
|
})]
|
|
725
710
|
}) : null, Z.map((e) => {
|
|
726
|
-
let t = ie(e), n = re(e), r =
|
|
727
|
-
return /* @__PURE__ */
|
|
711
|
+
let t = ie(e), n = re(e), r = St === e.id && (J || Y);
|
|
712
|
+
return /* @__PURE__ */ p("div", {
|
|
728
713
|
className: "rounded-lg border p-4",
|
|
729
|
-
children: /* @__PURE__ */
|
|
714
|
+
children: /* @__PURE__ */ m("div", {
|
|
730
715
|
className: "flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between",
|
|
731
|
-
children: [/* @__PURE__ */
|
|
716
|
+
children: [/* @__PURE__ */ m("div", {
|
|
732
717
|
className: "space-y-3",
|
|
733
718
|
children: [
|
|
734
|
-
/* @__PURE__ */
|
|
719
|
+
/* @__PURE__ */ m("div", {
|
|
735
720
|
className: "flex flex-wrap items-center gap-2",
|
|
736
|
-
children: [/* @__PURE__ */
|
|
721
|
+
children: [/* @__PURE__ */ p("p", {
|
|
737
722
|
className: "font-semibold",
|
|
738
723
|
children: e.email
|
|
739
|
-
}), /* @__PURE__ */
|
|
724
|
+
}), /* @__PURE__ */ p(h, {
|
|
740
725
|
variant: "outline",
|
|
741
726
|
children: e.status
|
|
742
727
|
})]
|
|
743
728
|
}),
|
|
744
|
-
/* @__PURE__ */
|
|
729
|
+
/* @__PURE__ */ m("div", {
|
|
745
730
|
className: "grid gap-3 text-sm text-text-secondary sm:grid-cols-2",
|
|
746
|
-
children: [/* @__PURE__ */
|
|
731
|
+
children: [/* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("p", {
|
|
747
732
|
className: "font-medium text-text-primary",
|
|
748
733
|
children: "Received"
|
|
749
|
-
}), /* @__PURE__ */
|
|
734
|
+
}), /* @__PURE__ */ p("p", { children: Ve(e.createdAt) ?? "—" })] }), /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("p", {
|
|
750
735
|
className: "font-medium text-text-primary",
|
|
751
736
|
children: "Expires"
|
|
752
|
-
}), /* @__PURE__ */
|
|
737
|
+
}), /* @__PURE__ */ p("p", { children: Ve(e.expiresAt) ?? "—" })] })]
|
|
753
738
|
}),
|
|
754
|
-
/* @__PURE__ */
|
|
739
|
+
/* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("p", {
|
|
755
740
|
className: "mb-2 text-sm font-medium text-text-primary",
|
|
756
741
|
children: "Roles"
|
|
757
|
-
}), /* @__PURE__ */
|
|
742
|
+
}), /* @__PURE__ */ p("div", {
|
|
758
743
|
className: "flex flex-wrap gap-2",
|
|
759
|
-
children: t.length > 0 ? t.map((t, n) => /* @__PURE__ */
|
|
744
|
+
children: t.length > 0 ? t.map((t, n) => /* @__PURE__ */ p(h, {
|
|
760
745
|
variant: "outline",
|
|
761
746
|
children: t
|
|
762
|
-
}, `${e.id}-${e.roleIds[n] ?? t}`)) : /* @__PURE__ */
|
|
747
|
+
}, `${e.id}-${e.roleIds[n] ?? t}`)) : /* @__PURE__ */ p("span", {
|
|
763
748
|
className: "text-sm text-text-secondary",
|
|
764
749
|
children: "No roles selected"
|
|
765
750
|
})
|
|
766
751
|
})] }),
|
|
767
|
-
/* @__PURE__ */
|
|
752
|
+
/* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("p", {
|
|
768
753
|
className: "mb-2 text-sm font-medium text-text-primary",
|
|
769
754
|
children: "Projects"
|
|
770
|
-
}), /* @__PURE__ */
|
|
755
|
+
}), /* @__PURE__ */ p("div", {
|
|
771
756
|
className: "flex flex-wrap gap-2",
|
|
772
|
-
children: n.length > 0 ? n.map((t, n) => /* @__PURE__ */
|
|
757
|
+
children: n.length > 0 ? n.map((t, n) => /* @__PURE__ */ p(h, {
|
|
773
758
|
variant: "secondary",
|
|
774
759
|
children: t
|
|
775
|
-
}, `${e.id}-project-${t}-${n}`)) : /* @__PURE__ */
|
|
760
|
+
}, `${e.id}-project-${t}-${n}`)) : /* @__PURE__ */ p("span", {
|
|
776
761
|
className: "text-sm text-text-secondary",
|
|
777
762
|
children: "No project access will be granted automatically"
|
|
778
763
|
})
|
|
779
764
|
})] })
|
|
780
765
|
]
|
|
781
|
-
}), /* @__PURE__ */
|
|
766
|
+
}), /* @__PURE__ */ m("div", {
|
|
782
767
|
className: "flex gap-2",
|
|
783
|
-
children: [/* @__PURE__ */
|
|
768
|
+
children: [/* @__PURE__ */ m(g, {
|
|
784
769
|
type: "button",
|
|
785
770
|
variant: "outline",
|
|
786
771
|
disabled: J || Y,
|
|
787
|
-
onClick: () =>
|
|
772
|
+
onClick: () => jt(e),
|
|
788
773
|
className: "gap-2",
|
|
789
|
-
children: [r && J ? /* @__PURE__ */
|
|
790
|
-
}), /* @__PURE__ */
|
|
774
|
+
children: [r && J ? /* @__PURE__ */ p(me, { className: "size-4 animate-spin" }) : /* @__PURE__ */ p(me, { className: "size-4" }), "Resend"]
|
|
775
|
+
}), /* @__PURE__ */ m(g, {
|
|
791
776
|
type: "button",
|
|
792
777
|
variant: "outline",
|
|
793
778
|
disabled: J || Y,
|
|
794
|
-
onClick: () =>
|
|
779
|
+
onClick: () => K(e),
|
|
795
780
|
className: "gap-2",
|
|
796
|
-
children: [r && Y ? /* @__PURE__ */
|
|
781
|
+
children: [r && Y ? /* @__PURE__ */ p(d, { className: "size-4 animate-spin" }) : /* @__PURE__ */ p(f, { className: "size-4" }), "Cancel"]
|
|
797
782
|
})]
|
|
798
783
|
})]
|
|
799
784
|
})
|
|
@@ -803,16 +788,16 @@ function D() {
|
|
|
803
788
|
]
|
|
804
789
|
})] });
|
|
805
790
|
}
|
|
806
|
-
function
|
|
791
|
+
function Ge() {
|
|
807
792
|
let { workspaceId: t } = Ie(), { workspaceId: n } = e();
|
|
808
|
-
return /* @__PURE__ */
|
|
793
|
+
return /* @__PURE__ */ p(ve, {
|
|
809
794
|
scopeId: t || n || null,
|
|
810
795
|
gateway: "workspace",
|
|
811
796
|
debug: !1,
|
|
812
|
-
children: /* @__PURE__ */
|
|
797
|
+
children: /* @__PURE__ */ p(O, {})
|
|
813
798
|
});
|
|
814
799
|
}
|
|
815
800
|
//#endregion
|
|
816
|
-
export {
|
|
801
|
+
export { Ge as WorkspaceInvitePage };
|
|
817
802
|
|
|
818
803
|
//# sourceMappingURL=WorkspaceInvitePage.js.map
|