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