@streamoid/settings 0.6.6 → 0.7.1
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/README.md +11 -3
- package/dist/index.d.mts +117 -98
- package/dist/index.d.ts +117 -98
- package/dist/index.js +585 -690
- package/dist/index.mjs +608 -713
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -32,7 +32,7 @@ __export(index_exports, {
|
|
|
32
32
|
MemberListFrame: () => MemberListFrame,
|
|
33
33
|
MemberListToolbar: () => MemberListToolbar,
|
|
34
34
|
OrganizationContent: () => OrganizationContent,
|
|
35
|
-
|
|
35
|
+
OrganizationMemberModal: () => OrganizationMemberModal,
|
|
36
36
|
OrganizationModal: () => OrganizationModal,
|
|
37
37
|
ProfileAvatar: () => ProfileAvatar,
|
|
38
38
|
ProfileTab: () => ProfileTab,
|
|
@@ -51,9 +51,11 @@ __export(index_exports, {
|
|
|
51
51
|
TokensContent: () => TokensContent,
|
|
52
52
|
URL_TO_TAB: () => URL_TO_TAB,
|
|
53
53
|
USER_LANGUAGES: () => USER_LANGUAGES,
|
|
54
|
+
WORKSPACE_LIST_PAGE_SIZE: () => WORKSPACE_LIST_PAGE_SIZE,
|
|
54
55
|
WorkspaceGeneralTab: () => WorkspaceGeneralTab,
|
|
55
56
|
WorkspaceListTab: () => WorkspaceListTab,
|
|
56
57
|
WorkspaceModal: () => WorkspaceModal,
|
|
58
|
+
WorkspacePicker: () => WorkspacePicker,
|
|
57
59
|
WorkspaceTab: () => WorkspaceTab,
|
|
58
60
|
countLabel: () => countLabel,
|
|
59
61
|
loadWorkspaceOrganization: () => loadWorkspaceOrganization,
|
|
@@ -431,8 +433,9 @@ function WorkspaceModal({
|
|
|
431
433
|
let cancelled = false;
|
|
432
434
|
organizationAdapter.list().then((orgs) => {
|
|
433
435
|
if (cancelled) return;
|
|
434
|
-
|
|
435
|
-
|
|
436
|
+
const joinable = orgs.filter((org) => org.role !== "guest");
|
|
437
|
+
setAvailableOrgs(joinable);
|
|
438
|
+
setSelectedOrgId((prev) => prev || joinable[0]?._id || "");
|
|
436
439
|
}).catch(() => {
|
|
437
440
|
if (!cancelled) setAvailableOrgs([]);
|
|
438
441
|
});
|
|
@@ -547,7 +550,7 @@ function WorkspaceModal({
|
|
|
547
550
|
async function handleLeaveOrganization() {
|
|
548
551
|
if (orgActionSubmitting || !workspaceAdapter.leaveOrganization) return;
|
|
549
552
|
const confirmed = window.confirm(
|
|
550
|
-
"
|
|
553
|
+
"Take this workspace out of the organization? It will no longer be listed in the workspace picker, and org admins will lose access unless they are members."
|
|
551
554
|
);
|
|
552
555
|
if (!confirmed) return;
|
|
553
556
|
setOrgActionSubmitting(true);
|
|
@@ -892,7 +895,7 @@ function WorkspaceModal({
|
|
|
892
895
|
color: active ? "#ffffff" : T.muted,
|
|
893
896
|
textAlign: "center"
|
|
894
897
|
},
|
|
895
|
-
children: opt === "private" ? "Private" : "
|
|
898
|
+
children: opt === "private" ? "Private" : "Listed in picker"
|
|
896
899
|
}
|
|
897
900
|
) })
|
|
898
901
|
},
|
|
@@ -1643,7 +1646,7 @@ var TAB_TO_URL = {
|
|
|
1643
1646
|
workspaceList: "workspace/all",
|
|
1644
1647
|
organization: "organization/people",
|
|
1645
1648
|
organizationWorkspaces: "organization/workspaces",
|
|
1646
|
-
organizationDomains: "organization/
|
|
1649
|
+
organizationDomains: "organization/workspaces",
|
|
1647
1650
|
referral: "referral",
|
|
1648
1651
|
billing: "billing",
|
|
1649
1652
|
apikey: "api-keys"
|
|
@@ -1655,7 +1658,8 @@ var URL_TO_TAB = {
|
|
|
1655
1658
|
"workspace/all": "workspaceList",
|
|
1656
1659
|
"organization/people": "organization",
|
|
1657
1660
|
"organization/workspaces": "organizationWorkspaces",
|
|
1658
|
-
|
|
1661
|
+
/* The Domains tab is gone; its join requests live under Workspaces. */
|
|
1662
|
+
"organization/domains": "organizationWorkspaces",
|
|
1659
1663
|
/* Unscoped destinations. */
|
|
1660
1664
|
account: "profile",
|
|
1661
1665
|
referral: "referral",
|
|
@@ -1674,7 +1678,7 @@ var TAB_LABELS = {
|
|
|
1674
1678
|
workspaceList: "My workspaces",
|
|
1675
1679
|
organization: "People",
|
|
1676
1680
|
organizationWorkspaces: "Workspaces",
|
|
1677
|
-
organizationDomains: "
|
|
1681
|
+
organizationDomains: "Workspaces",
|
|
1678
1682
|
referral: "Referral",
|
|
1679
1683
|
/* "Billing & usage", not "Billing". The tab has held usage history as well
|
|
1680
1684
|
as the plan and invoices since the credits work, and hosts had started
|
|
@@ -1688,9 +1692,9 @@ var TAB_DESCRIPTIONS = {
|
|
|
1688
1692
|
workspace: "Rename or re-brand this workspace, or leave and delete it",
|
|
1689
1693
|
workspaceMembers: "Invite people to this workspace and control which apps they can use",
|
|
1690
1694
|
workspaceList: "Switch between your workspaces, or start a new one",
|
|
1691
|
-
organization: "Everyone in the organization
|
|
1692
|
-
organizationWorkspaces: "Every workspace
|
|
1693
|
-
organizationDomains: "
|
|
1695
|
+
organization: "Everyone in the organization and their role",
|
|
1696
|
+
organizationWorkspaces: "Every workspace in this organization, and workspaces asking to join it",
|
|
1697
|
+
organizationDomains: "Every workspace in this organization, and workspaces asking to join it",
|
|
1694
1698
|
referral: "Invite friends to Streamoid and track the rewards you have earned",
|
|
1695
1699
|
billing: "Workspace plan, credits, invoices and usage history",
|
|
1696
1700
|
apikey: "Create and revoke keys for calling the Streamoid APIs"
|
|
@@ -2309,7 +2313,7 @@ function OrganizationAffiliationCard({
|
|
|
2309
2313
|
style: { gap: T5.spMd, opacity: submitting ? 0.6 : 1 },
|
|
2310
2314
|
children: [
|
|
2311
2315
|
workspaceAdapter.setOrgVisibility && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex flex-col items-start w-full", style: { gap: T5.spXs }, children: [
|
|
2312
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(FieldLabel, { children: "
|
|
2316
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(FieldLabel, { children: "List this workspace in the organization's workspace picker" }),
|
|
2313
2317
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2314
2318
|
"div",
|
|
2315
2319
|
{
|
|
@@ -2340,11 +2344,11 @@ function OrganizationAffiliationCard({
|
|
|
2340
2344
|
if (active || !workspaceAdapter.setOrgVisibility) return;
|
|
2341
2345
|
void run(
|
|
2342
2346
|
() => workspaceAdapter.setOrgVisibility(opt),
|
|
2343
|
-
opt === "private" ? "Workspace is now private" : "Workspace is now
|
|
2347
|
+
opt === "private" ? "Workspace is now private" : "Workspace is now listed in the workspace picker",
|
|
2344
2348
|
"Failed to change visibility"
|
|
2345
2349
|
);
|
|
2346
2350
|
},
|
|
2347
|
-
children: opt === "private" ? "
|
|
2351
|
+
children: opt === "private" ? "Private (invite only)" : "Listed in the workspace picker"
|
|
2348
2352
|
},
|
|
2349
2353
|
opt
|
|
2350
2354
|
);
|
|
@@ -2370,7 +2374,7 @@ function OrganizationAffiliationCard({
|
|
|
2370
2374
|
},
|
|
2371
2375
|
onClick: () => {
|
|
2372
2376
|
const confirmed = window.confirm(
|
|
2373
|
-
"
|
|
2377
|
+
"Take this workspace out of the organization? It will no longer be listed in the workspace picker, and org admins will lose access unless they are members."
|
|
2374
2378
|
);
|
|
2375
2379
|
if (!confirmed || !workspaceAdapter.leaveOrganization) return;
|
|
2376
2380
|
void run(
|
|
@@ -2763,12 +2767,13 @@ function InviteUpdateModal({
|
|
|
2763
2767
|
organizationName,
|
|
2764
2768
|
allowGuestStanding = true,
|
|
2765
2769
|
initialOrganizationStanding = "guest",
|
|
2770
|
+
organizationDomain,
|
|
2766
2771
|
onInvite
|
|
2767
2772
|
}) {
|
|
2768
2773
|
useOverlayOpen(open, onClose);
|
|
2769
2774
|
const [emailValue, setEmailValue] = (0, import_react8.useState)("");
|
|
2770
2775
|
const [hasChanges, setHasChanges] = (0, import_react8.useState)(false);
|
|
2771
|
-
const [role, setRole] = (0, import_react8.useState)("
|
|
2776
|
+
const [role, setRole] = (0, import_react8.useState)("member");
|
|
2772
2777
|
const [orgStanding, setOrgStanding] = (0, import_react8.useState)(
|
|
2773
2778
|
initialOrganizationStanding
|
|
2774
2779
|
);
|
|
@@ -2807,7 +2812,7 @@ function InviteUpdateModal({
|
|
|
2807
2812
|
if (!open) {
|
|
2808
2813
|
setEmailValue("");
|
|
2809
2814
|
setHasChanges(false);
|
|
2810
|
-
setRole("
|
|
2815
|
+
setRole("member");
|
|
2811
2816
|
setOrgStanding(initialOrganizationStanding);
|
|
2812
2817
|
setCanUseCredits(true);
|
|
2813
2818
|
setCanInviteUser(true);
|
|
@@ -2819,6 +2824,14 @@ function InviteUpdateModal({
|
|
|
2819
2824
|
setSelectedStores(/* @__PURE__ */ new Set());
|
|
2820
2825
|
}
|
|
2821
2826
|
}, [open, initialPermissions, hiddenKey, initialOrganizationStanding]);
|
|
2827
|
+
const orgDomain = (organizationDomain || "").trim().toLowerCase();
|
|
2828
|
+
const inviteeDomains = emailValue.split(/[\s,;]+/).map((email) => email.trim().toLowerCase().split("@")[1] || "").filter(Boolean);
|
|
2829
|
+
const inviteeIsGuest = mode === "invite" && inviteeDomains.some(
|
|
2830
|
+
(domain) => !(orgDomain && domain === orgDomain) && (showOrganizationStanding ? orgStanding === "guest" : !!orgDomain)
|
|
2831
|
+
);
|
|
2832
|
+
(0, import_react8.useEffect)(() => {
|
|
2833
|
+
if (inviteeIsGuest && role === "admin") setRole("member");
|
|
2834
|
+
}, [inviteeIsGuest, role]);
|
|
2822
2835
|
if (!open) return null;
|
|
2823
2836
|
const isInvite = mode === "invite";
|
|
2824
2837
|
const hasEmail = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(emailValue.trim());
|
|
@@ -3009,12 +3022,15 @@ function InviteUpdateModal({
|
|
|
3009
3022
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
3010
3023
|
"div",
|
|
3011
3024
|
{
|
|
3012
|
-
className:
|
|
3025
|
+
className: `flex-1 min-w-0 ${inviteeIsGuest ? "cursor-not-allowed" : "cursor-pointer"}`,
|
|
3026
|
+
"aria-disabled": inviteeIsGuest,
|
|
3013
3027
|
style: {
|
|
3014
3028
|
background: role === "admin" ? T6.neutral300 : "transparent",
|
|
3015
|
-
borderRadius: T6.rMd
|
|
3029
|
+
borderRadius: T6.rMd,
|
|
3030
|
+
opacity: inviteeIsGuest ? 0.4 : 1
|
|
3016
3031
|
},
|
|
3017
3032
|
onClick: () => {
|
|
3033
|
+
if (inviteeIsGuest) return;
|
|
3018
3034
|
setRole("admin");
|
|
3019
3035
|
setCanUseCredits(true);
|
|
3020
3036
|
setCanInviteUser(true);
|
|
@@ -3088,6 +3104,19 @@ function InviteUpdateModal({
|
|
|
3088
3104
|
) })
|
|
3089
3105
|
]
|
|
3090
3106
|
}
|
|
3107
|
+
),
|
|
3108
|
+
inviteeIsGuest && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
3109
|
+
"span",
|
|
3110
|
+
{
|
|
3111
|
+
style: {
|
|
3112
|
+
fontFamily: T6.font,
|
|
3113
|
+
fontSize: T6.fsXs,
|
|
3114
|
+
fontWeight: 400,
|
|
3115
|
+
lineHeight: T6.lhXs,
|
|
3116
|
+
color: T6.tertiary
|
|
3117
|
+
},
|
|
3118
|
+
children: "Guests can only be Members."
|
|
3119
|
+
}
|
|
3091
3120
|
)
|
|
3092
3121
|
]
|
|
3093
3122
|
}
|
|
@@ -3277,7 +3306,7 @@ function InviteUpdateModal({
|
|
|
3277
3306
|
lineHeight: T6.lhXs,
|
|
3278
3307
|
color: T6.tertiary
|
|
3279
3308
|
},
|
|
3280
|
-
children: orgStanding === "colleague" ? `Joins ${organizationName || "the organization"} as a member \u2014 they
|
|
3309
|
+
children: orgStanding === "colleague" ? `Joins ${organizationName || "the organization"} as a member \u2014 they can also join its shared workspaces.` : `This workspace only, as a member. They see nothing else in ${organizationName || "the organization"}.`
|
|
3281
3310
|
}
|
|
3282
3311
|
)
|
|
3283
3312
|
]
|
|
@@ -3972,7 +4001,19 @@ function MemberListToolbar({
|
|
|
3972
4001
|
className: "flex flex-wrap items-center justify-between shrink-0 w-full",
|
|
3973
4002
|
style: { gap: "var(--spacing-md)" },
|
|
3974
4003
|
children: [
|
|
3975
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
4004
|
+
pendingCount === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
4005
|
+
"span",
|
|
4006
|
+
{
|
|
4007
|
+
style: {
|
|
4008
|
+
fontFamily: T7.font,
|
|
4009
|
+
fontSize: T7.fsSm,
|
|
4010
|
+
fontWeight: 500,
|
|
4011
|
+
lineHeight: T7.lhSm,
|
|
4012
|
+
color: T7.primary
|
|
4013
|
+
},
|
|
4014
|
+
children: withCount(activeLabel, activeCount)
|
|
4015
|
+
}
|
|
4016
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3976
4017
|
import_ui4.ScTabSwitcher,
|
|
3977
4018
|
{
|
|
3978
4019
|
tabCount: "2",
|
|
@@ -4938,9 +4979,9 @@ function TeamsContent({
|
|
|
4938
4979
|
lineHeight: "var(--line-height-line-height-xs)"
|
|
4939
4980
|
},
|
|
4940
4981
|
children: [
|
|
4941
|
-
"
|
|
4982
|
+
"Anyone in ",
|
|
4942
4983
|
organizationName,
|
|
4943
|
-
", and its admins keep access whether or not they are listed here. Change that under Workspace \u203A General."
|
|
4984
|
+
" can join this workspace as a member from the workspace picker, and its org admins keep access whether or not they are listed here. Change that under Workspace \u203A General."
|
|
4944
4985
|
]
|
|
4945
4986
|
}
|
|
4946
4987
|
),
|
|
@@ -5022,6 +5063,7 @@ function TeamsContent({
|
|
|
5022
5063
|
),
|
|
5023
5064
|
showOrganizationStanding: mayGrantOrgMembership,
|
|
5024
5065
|
organizationName: organizationName ?? orgCurrent?.name,
|
|
5066
|
+
organizationDomain: workspaceOrgId && orgCurrent?.id === workspaceOrgId ? orgCurrent?.domain : void 0,
|
|
5025
5067
|
onInvite: handleInvite
|
|
5026
5068
|
}
|
|
5027
5069
|
)
|
|
@@ -5092,7 +5134,7 @@ var import_react12 = require("react");
|
|
|
5092
5134
|
var import_ui8 = require("@streamoid/ui");
|
|
5093
5135
|
var import_icons8 = require("@streamoid/icons");
|
|
5094
5136
|
|
|
5095
|
-
// src/organization-
|
|
5137
|
+
// src/organization-member-modal.tsx
|
|
5096
5138
|
var import_react10 = require("react");
|
|
5097
5139
|
var import_ui7 = require("@streamoid/ui");
|
|
5098
5140
|
var import_icons7 = require("@streamoid/icons");
|
|
@@ -5123,33 +5165,6 @@ var T9 = {
|
|
|
5123
5165
|
r4xl: "var(--radius-4xl)",
|
|
5124
5166
|
neutral300: "var(--primitives-neutral-300)"
|
|
5125
5167
|
};
|
|
5126
|
-
function CheckboxSvg2({ checked }) {
|
|
5127
|
-
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "relative shrink-0", style: { width: 24, height: 24 }, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", children: checked ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
|
|
5128
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
5129
|
-
"rect",
|
|
5130
|
-
{
|
|
5131
|
-
x: "0.75",
|
|
5132
|
-
y: "0.75",
|
|
5133
|
-
width: "22.5",
|
|
5134
|
-
height: "22.5",
|
|
5135
|
-
rx: "5.65",
|
|
5136
|
-
fill: T9.primary,
|
|
5137
|
-
stroke: T9.primary,
|
|
5138
|
-
strokeWidth: "1.5"
|
|
5139
|
-
}
|
|
5140
|
-
),
|
|
5141
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
5142
|
-
"path",
|
|
5143
|
-
{
|
|
5144
|
-
d: "M7 12.5L10.5 16L17 8",
|
|
5145
|
-
stroke: T9.inverse,
|
|
5146
|
-
strokeWidth: "1.5",
|
|
5147
|
-
strokeLinecap: "round",
|
|
5148
|
-
strokeLinejoin: "round"
|
|
5149
|
-
}
|
|
5150
|
-
)
|
|
5151
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("path", { d: svg_rodctpja6f_default.p4792500, fill: T9.muted }) }) });
|
|
5152
|
-
}
|
|
5153
5168
|
function FieldLabel3({ text }) {
|
|
5154
5169
|
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "flex items-center shrink-0 w-full", style: { height: 24 }, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
5155
5170
|
"div",
|
|
@@ -5225,69 +5240,29 @@ function SegmentedToggle({
|
|
|
5225
5240
|
}
|
|
5226
5241
|
);
|
|
5227
5242
|
}
|
|
5228
|
-
function
|
|
5243
|
+
function OrganizationMemberModal({
|
|
5229
5244
|
open,
|
|
5230
|
-
mode,
|
|
5231
5245
|
userEmail = "email@domain.in",
|
|
5232
5246
|
initialRole,
|
|
5233
5247
|
lockRole,
|
|
5234
|
-
canClaimDomain = true,
|
|
5235
|
-
claimableDomain,
|
|
5236
5248
|
lockedRoleLabel,
|
|
5237
|
-
initialInviteAccess,
|
|
5238
|
-
allowSubmitWithoutChanges = false,
|
|
5239
5249
|
canRemove = true,
|
|
5240
5250
|
onClose,
|
|
5241
|
-
onInviteEmail,
|
|
5242
|
-
onInviteDomain,
|
|
5243
5251
|
onUpdate,
|
|
5244
5252
|
onRemove
|
|
5245
5253
|
}) {
|
|
5246
5254
|
useOverlayOpen(open, onClose);
|
|
5247
|
-
const [inviteMode, setInviteMode] = (0, import_react10.useState)("email");
|
|
5248
|
-
const [emailValue, setEmailValue] = (0, import_react10.useState)("");
|
|
5249
|
-
const [domainValue, setDomainValue] = (0, import_react10.useState)(claimableDomain ?? "");
|
|
5250
5255
|
const [hasChanges, setHasChanges] = (0, import_react10.useState)(false);
|
|
5251
|
-
const [role, setRole] = (0, import_react10.useState)("
|
|
5252
|
-
const [inviteAccess, setInviteAccess] = (0, import_react10.useState)(false);
|
|
5256
|
+
const [role, setRole] = (0, import_react10.useState)("member");
|
|
5253
5257
|
(0, import_react10.useEffect)(() => {
|
|
5254
|
-
if (open
|
|
5258
|
+
if (open) {
|
|
5255
5259
|
setRole(initialRole ?? "member");
|
|
5256
|
-
|
|
5257
|
-
}
|
|
5258
|
-
if (!open) {
|
|
5259
|
-
setInviteMode("email");
|
|
5260
|
-
setEmailValue("");
|
|
5261
|
-
setDomainValue(claimableDomain ?? "");
|
|
5260
|
+
} else {
|
|
5262
5261
|
setHasChanges(false);
|
|
5263
|
-
setRole("admin");
|
|
5264
|
-
setInviteAccess(true);
|
|
5265
5262
|
}
|
|
5266
|
-
}, [open,
|
|
5263
|
+
}, [open, initialRole]);
|
|
5267
5264
|
if (!open) return null;
|
|
5268
|
-
const
|
|
5269
|
-
const isEmailInvite = isInvite && inviteMode === "email";
|
|
5270
|
-
const isDomainInvite = isInvite && inviteMode === "domain";
|
|
5271
|
-
const hasEmail = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(emailValue.trim());
|
|
5272
|
-
const hasDomain = /^[^\s@]+\.[^\s@]+$/.test(domainValue.trim());
|
|
5273
|
-
const isSubmitDisabled = isEmailInvite ? !hasEmail : isDomainInvite ? !hasDomain : (
|
|
5274
|
-
// A locked role has nothing this modal can legitimately submit.
|
|
5275
|
-
lockRole || !(allowSubmitWithoutChanges || hasChanges)
|
|
5276
|
-
);
|
|
5277
|
-
function markChanged() {
|
|
5278
|
-
setHasChanges(true);
|
|
5279
|
-
}
|
|
5280
|
-
function handleSubmit() {
|
|
5281
|
-
if (isEmailInvite) {
|
|
5282
|
-
onInviteEmail?.({ email: emailValue.trim(), role, inviteAccess });
|
|
5283
|
-
return;
|
|
5284
|
-
}
|
|
5285
|
-
if (isDomainInvite) {
|
|
5286
|
-
onInviteDomain?.({ domain: domainValue.trim(), autoJoinRole: role });
|
|
5287
|
-
return;
|
|
5288
|
-
}
|
|
5289
|
-
onUpdate?.({ role, inviteAccess });
|
|
5290
|
-
}
|
|
5265
|
+
const isSubmitDisabled = lockRole || !hasChanges;
|
|
5291
5266
|
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
5292
5267
|
"div",
|
|
5293
5268
|
{
|
|
@@ -5305,6 +5280,7 @@ function OrganizationInviteModal({
|
|
|
5305
5280
|
borderRadius: T9.r4xl,
|
|
5306
5281
|
border: `1px solid ${T9.borderSubtle}`,
|
|
5307
5282
|
width: 480,
|
|
5283
|
+
maxWidth: "calc(100vw - 32px)",
|
|
5308
5284
|
maxHeight: "85vh"
|
|
5309
5285
|
},
|
|
5310
5286
|
children: [
|
|
@@ -5334,7 +5310,7 @@ function OrganizationInviteModal({
|
|
|
5334
5310
|
fontWeight: 600,
|
|
5335
5311
|
lineHeight: T9.lhLg
|
|
5336
5312
|
},
|
|
5337
|
-
children:
|
|
5313
|
+
children: "Update member"
|
|
5338
5314
|
}
|
|
5339
5315
|
),
|
|
5340
5316
|
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "shrink-0 cursor-pointer", onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_icons7.SiconClose, { className: "w-6 h-6", color: T9.primary }) })
|
|
@@ -5348,116 +5324,41 @@ function OrganizationInviteModal({
|
|
|
5348
5324
|
className: "flex flex-col items-start w-full",
|
|
5349
5325
|
style: { padding: `${T9.sp3xl} ${T9.sp6xl}`, gap: T9.sp3xl },
|
|
5350
5326
|
children: [
|
|
5351
|
-
isInvite && canClaimDomain && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
5352
|
-
"div",
|
|
5353
|
-
{
|
|
5354
|
-
className: "flex flex-col items-start justify-center shrink-0 w-full",
|
|
5355
|
-
style: { gap: T9.spXs },
|
|
5356
|
-
children: [
|
|
5357
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(FieldLabel3, { text: "Invite by" }),
|
|
5358
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
5359
|
-
SegmentedToggle,
|
|
5360
|
-
{
|
|
5361
|
-
options: [
|
|
5362
|
-
{ value: "email", label: "Email" },
|
|
5363
|
-
{ value: "domain", label: "Domain" }
|
|
5364
|
-
],
|
|
5365
|
-
value: inviteMode,
|
|
5366
|
-
onChange: setInviteMode
|
|
5367
|
-
}
|
|
5368
|
-
)
|
|
5369
|
-
]
|
|
5370
|
-
}
|
|
5371
|
-
),
|
|
5372
5327
|
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
5373
5328
|
"div",
|
|
5374
5329
|
{
|
|
5375
5330
|
className: "flex flex-col items-start justify-center shrink-0 w-full",
|
|
5376
5331
|
style: { gap: T9.spXs },
|
|
5377
5332
|
children: [
|
|
5378
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
5379
|
-
FieldLabel3,
|
|
5380
|
-
{
|
|
5381
|
-
text: isDomainInvite ? "Domain" : isEmailInvite ? "Email ID" : "Email ID"
|
|
5382
|
-
}
|
|
5383
|
-
),
|
|
5333
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(FieldLabel3, { text: "Email ID" }),
|
|
5384
5334
|
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
5385
5335
|
"div",
|
|
5386
5336
|
{
|
|
5387
5337
|
className: "shrink-0 w-full",
|
|
5388
5338
|
style: { background: T9.fillPlus, height: 48, borderRadius: T9.r3xl },
|
|
5389
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "flex flex-row items-center size-full", children: /* @__PURE__ */ (0, import_jsx_runtime15.
|
|
5339
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "flex flex-row items-center size-full", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
5390
5340
|
"div",
|
|
5391
5341
|
{
|
|
5392
5342
|
className: "flex items-center relative size-full",
|
|
5393
5343
|
style: { padding: `${T9.spXl} ${T9.sp3xl}` },
|
|
5394
|
-
children:
|
|
5395
|
-
|
|
5396
|
-
|
|
5397
|
-
|
|
5398
|
-
|
|
5399
|
-
|
|
5400
|
-
|
|
5401
|
-
|
|
5402
|
-
|
|
5403
|
-
|
|
5404
|
-
|
|
5405
|
-
|
|
5406
|
-
|
|
5407
|
-
|
|
5408
|
-
|
|
5409
|
-
}
|
|
5410
|
-
),
|
|
5411
|
-
isDomainInvite && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
5412
|
-
"span",
|
|
5413
|
-
{
|
|
5414
|
-
className: "flex-1 min-w-0 truncate",
|
|
5415
|
-
style: {
|
|
5416
|
-
fontFamily: T9.font,
|
|
5417
|
-
fontSize: T9.fsSm,
|
|
5418
|
-
fontWeight: 400,
|
|
5419
|
-
lineHeight: T9.lhSm,
|
|
5420
|
-
color: T9.primary
|
|
5421
|
-
},
|
|
5422
|
-
children: domainValue
|
|
5423
|
-
}
|
|
5424
|
-
),
|
|
5425
|
-
!isInvite && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
5426
|
-
"div",
|
|
5427
|
-
{
|
|
5428
|
-
className: "flex-1 flex flex-col justify-center",
|
|
5429
|
-
style: {
|
|
5430
|
-
fontFamily: T9.font,
|
|
5431
|
-
fontSize: T9.fsSm,
|
|
5432
|
-
fontWeight: 400,
|
|
5433
|
-
lineHeight: T9.lhSm,
|
|
5434
|
-
color: T9.muted,
|
|
5435
|
-
opacity: 0.6
|
|
5436
|
-
},
|
|
5437
|
-
children: userEmail
|
|
5438
|
-
}
|
|
5439
|
-
)
|
|
5440
|
-
]
|
|
5344
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
5345
|
+
"div",
|
|
5346
|
+
{
|
|
5347
|
+
className: "flex-1 flex flex-col justify-center truncate",
|
|
5348
|
+
style: {
|
|
5349
|
+
fontFamily: T9.font,
|
|
5350
|
+
fontSize: T9.fsSm,
|
|
5351
|
+
fontWeight: 400,
|
|
5352
|
+
lineHeight: T9.lhSm,
|
|
5353
|
+
color: T9.muted,
|
|
5354
|
+
opacity: 0.6
|
|
5355
|
+
},
|
|
5356
|
+
children: userEmail
|
|
5357
|
+
}
|
|
5358
|
+
)
|
|
5441
5359
|
}
|
|
5442
5360
|
) })
|
|
5443
5361
|
}
|
|
5444
|
-
),
|
|
5445
|
-
isDomainInvite && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
5446
|
-
"span",
|
|
5447
|
-
{
|
|
5448
|
-
style: {
|
|
5449
|
-
fontFamily: T9.font,
|
|
5450
|
-
fontSize: T9.fsSm,
|
|
5451
|
-
fontWeight: 400,
|
|
5452
|
-
color: T9.muted
|
|
5453
|
-
},
|
|
5454
|
-
children: [
|
|
5455
|
-
"Anyone who signs up or logs in with an @",
|
|
5456
|
-
domainValue.trim(),
|
|
5457
|
-
" ",
|
|
5458
|
-
"address will automatically join this organization from now on."
|
|
5459
|
-
]
|
|
5460
|
-
}
|
|
5461
5362
|
)
|
|
5462
5363
|
]
|
|
5463
5364
|
}
|
|
@@ -5468,7 +5369,7 @@ function OrganizationInviteModal({
|
|
|
5468
5369
|
className: "flex flex-col items-start justify-center shrink-0 w-full",
|
|
5469
5370
|
style: { gap: T9.spXs },
|
|
5470
5371
|
children: [
|
|
5471
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(FieldLabel3, { text:
|
|
5372
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(FieldLabel3, { text: "Role" }),
|
|
5472
5373
|
lockRole ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
5473
5374
|
"span",
|
|
5474
5375
|
{
|
|
@@ -5480,49 +5381,33 @@ function OrganizationInviteModal({
|
|
|
5480
5381
|
},
|
|
5481
5382
|
children: [
|
|
5482
5383
|
lockedRoleLabel || "Guest",
|
|
5483
|
-
" \u2014 invited to specific workspaces only, with no access to the rest of the organization. Remove them to end that access."
|
|
5384
|
+
" \u2014 invited to specific workspaces only, with no access to the rest of the organization. Guests can't be made members or admins. Remove them to end that access."
|
|
5484
5385
|
]
|
|
5485
5386
|
}
|
|
5486
5387
|
) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
5487
5388
|
SegmentedToggle,
|
|
5488
5389
|
{
|
|
5489
5390
|
options: [
|
|
5490
|
-
{ value: "admin", label: "
|
|
5391
|
+
{ value: "admin", label: "Org admin" },
|
|
5491
5392
|
{ value: "member", label: "Member" }
|
|
5492
5393
|
],
|
|
5493
5394
|
value: role,
|
|
5494
5395
|
onChange: (v) => {
|
|
5495
5396
|
setRole(v);
|
|
5496
|
-
|
|
5497
|
-
markChanged();
|
|
5397
|
+
setHasChanges(v !== (initialRole ?? "member"));
|
|
5498
5398
|
}
|
|
5499
5399
|
}
|
|
5500
|
-
)
|
|
5501
|
-
|
|
5502
|
-
}
|
|
5503
|
-
),
|
|
5504
|
-
!isDomainInvite && !lockRole && role === "member" && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
5505
|
-
"div",
|
|
5506
|
-
{
|
|
5507
|
-
className: "flex items-center shrink-0 w-full cursor-pointer",
|
|
5508
|
-
style: { gap: T9.spMd },
|
|
5509
|
-
onClick: () => {
|
|
5510
|
-
setInviteAccess(!inviteAccess);
|
|
5511
|
-
markChanged();
|
|
5512
|
-
},
|
|
5513
|
-
children: [
|
|
5514
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(CheckboxSvg2, { checked: inviteAccess }),
|
|
5515
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
5400
|
+
),
|
|
5401
|
+
!lockRole && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
5516
5402
|
"span",
|
|
5517
5403
|
{
|
|
5518
5404
|
style: {
|
|
5519
5405
|
fontFamily: T9.font,
|
|
5520
5406
|
fontSize: T9.fsSm,
|
|
5521
|
-
fontWeight: 400,
|
|
5522
5407
|
lineHeight: T9.lhSm,
|
|
5523
|
-
color: T9.
|
|
5408
|
+
color: T9.muted
|
|
5524
5409
|
},
|
|
5525
|
-
children: "
|
|
5410
|
+
children: "Org admins can see and manage every workspace in the organization."
|
|
5526
5411
|
}
|
|
5527
5412
|
)
|
|
5528
5413
|
]
|
|
@@ -5543,10 +5428,10 @@ function OrganizationInviteModal({
|
|
|
5543
5428
|
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "flex flex-row items-center size-full", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
5544
5429
|
"div",
|
|
5545
5430
|
{
|
|
5546
|
-
className:
|
|
5431
|
+
className: "flex items-center w-full justify-between",
|
|
5547
5432
|
style: { padding: `${T9.sp3xl} ${T9.sp6xl}` },
|
|
5548
5433
|
children: [
|
|
5549
|
-
|
|
5434
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
5550
5435
|
import_ui7.ScButton,
|
|
5551
5436
|
{
|
|
5552
5437
|
text: "Remove member",
|
|
@@ -5559,11 +5444,11 @@ function OrganizationInviteModal({
|
|
|
5559
5444
|
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
5560
5445
|
import_ui7.ScButton,
|
|
5561
5446
|
{
|
|
5562
|
-
text:
|
|
5447
|
+
text: "Save changes",
|
|
5563
5448
|
variant: "primary",
|
|
5564
5449
|
size: "md",
|
|
5565
5450
|
state: isSubmitDisabled ? "disabled" : "default",
|
|
5566
|
-
onClick: !isSubmitDisabled ?
|
|
5451
|
+
onClick: !isSubmitDisabled ? () => onUpdate?.({ role }) : void 0
|
|
5567
5452
|
}
|
|
5568
5453
|
)
|
|
5569
5454
|
]
|
|
@@ -6057,20 +5942,6 @@ function formatDate(iso) {
|
|
|
6057
5942
|
return iso;
|
|
6058
5943
|
}
|
|
6059
5944
|
}
|
|
6060
|
-
function toDisplayText2(value, fallback = "\u2013") {
|
|
6061
|
-
if (typeof value === "string") {
|
|
6062
|
-
const trimmed = value.trim();
|
|
6063
|
-
return trimmed.length > 0 ? trimmed : fallback;
|
|
6064
|
-
}
|
|
6065
|
-
if (value && typeof value === "object") {
|
|
6066
|
-
const record = value;
|
|
6067
|
-
const name = typeof record.name === "string" ? record.name.trim() : "";
|
|
6068
|
-
if (name) return name;
|
|
6069
|
-
const email = typeof record.email === "string" ? record.email.trim() : "";
|
|
6070
|
-
if (email) return email;
|
|
6071
|
-
}
|
|
6072
|
-
return fallback;
|
|
6073
|
-
}
|
|
6074
5945
|
function VisibilityBadge({ visibility }) {
|
|
6075
5946
|
const isShared = visibility === "shared";
|
|
6076
5947
|
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
@@ -6091,10 +5962,46 @@ function VisibilityBadge({ visibility }) {
|
|
|
6091
5962
|
}
|
|
6092
5963
|
);
|
|
6093
5964
|
}
|
|
5965
|
+
function RowIconButton({
|
|
5966
|
+
label,
|
|
5967
|
+
onClick,
|
|
5968
|
+
children,
|
|
5969
|
+
visible = true
|
|
5970
|
+
}) {
|
|
5971
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5972
|
+
"button",
|
|
5973
|
+
{
|
|
5974
|
+
type: "button",
|
|
5975
|
+
"aria-label": label,
|
|
5976
|
+
title: label,
|
|
5977
|
+
className: "flex items-center justify-center shrink-0 cursor-pointer border-none",
|
|
5978
|
+
style: {
|
|
5979
|
+
width: 32,
|
|
5980
|
+
height: 32,
|
|
5981
|
+
borderRadius: T11.rLg,
|
|
5982
|
+
background: "transparent",
|
|
5983
|
+
opacity: visible ? 1 : 0,
|
|
5984
|
+
transition: "opacity 120ms ease"
|
|
5985
|
+
},
|
|
5986
|
+
onMouseEnter: (e) => {
|
|
5987
|
+
e.currentTarget.style.background = T11.fillPlus;
|
|
5988
|
+
},
|
|
5989
|
+
onMouseLeave: (e) => {
|
|
5990
|
+
e.currentTarget.style.background = "transparent";
|
|
5991
|
+
},
|
|
5992
|
+
onClick,
|
|
5993
|
+
children
|
|
5994
|
+
}
|
|
5995
|
+
);
|
|
5996
|
+
}
|
|
6094
5997
|
function MemberRow({
|
|
6095
5998
|
member,
|
|
6096
|
-
|
|
5999
|
+
onEdit,
|
|
6000
|
+
onCopyEmail
|
|
6097
6001
|
}) {
|
|
6002
|
+
const [copied, setCopied] = (0, import_react12.useState)(false);
|
|
6003
|
+
const [active, setActive] = (0, import_react12.useState)(false);
|
|
6004
|
+
const noHover = typeof window !== "undefined" && window.matchMedia?.("(hover: none)").matches === true;
|
|
6098
6005
|
const name = member.user.name?.trim();
|
|
6099
6006
|
const email = member.user.email || "";
|
|
6100
6007
|
const displayIdent = name || email.split("@")[0] || "user";
|
|
@@ -6106,18 +6013,20 @@ function MemberRow({
|
|
|
6106
6013
|
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
6107
6014
|
"div",
|
|
6108
6015
|
{
|
|
6109
|
-
className:
|
|
6016
|
+
className: "flex items-center self-stretch shrink-0 cursor-default",
|
|
6110
6017
|
style: {
|
|
6111
6018
|
borderBottom: `1px solid ${T11.borderSubtle}`,
|
|
6112
6019
|
padding: `${T11.sp5xl} ${T11.sp3xl}`,
|
|
6113
|
-
gap: T11.sp6xl
|
|
6114
|
-
|
|
6115
|
-
onClick,
|
|
6116
|
-
onMouseEnter: (e) => {
|
|
6117
|
-
if (onClick) e.currentTarget.style.background = T11.fillPlus;
|
|
6020
|
+
gap: T11.sp6xl,
|
|
6021
|
+
background: active && onEdit ? T11.fillPlus : "transparent"
|
|
6118
6022
|
},
|
|
6119
|
-
|
|
6120
|
-
|
|
6023
|
+
onMouseEnter: () => setActive(true),
|
|
6024
|
+
onMouseLeave: () => setActive(false),
|
|
6025
|
+
onFocus: () => setActive(true),
|
|
6026
|
+
onBlur: (e) => {
|
|
6027
|
+
if (!e.currentTarget.contains(e.relatedTarget)) {
|
|
6028
|
+
setActive(false);
|
|
6029
|
+
}
|
|
6121
6030
|
},
|
|
6122
6031
|
children: [
|
|
6123
6032
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
@@ -6196,112 +6105,29 @@ function MemberRow({
|
|
|
6196
6105
|
},
|
|
6197
6106
|
children: formatDate(member.createdAt || member.user.createdAt)
|
|
6198
6107
|
}
|
|
6199
|
-
)
|
|
6200
|
-
|
|
6201
|
-
|
|
6202
|
-
);
|
|
6203
|
-
}
|
|
6204
|
-
function InviteRow({
|
|
6205
|
-
invite,
|
|
6206
|
-
onCancel,
|
|
6207
|
-
onResend
|
|
6208
|
-
}) {
|
|
6209
|
-
const isDomain = invite.kind === "domain";
|
|
6210
|
-
const invitedByText = (() => {
|
|
6211
|
-
if (!invite.invitedBy) return "\u2013";
|
|
6212
|
-
if (typeof invite.invitedBy === "string") return invite.invitedBy;
|
|
6213
|
-
return invite.invitedBy.name || invite.invitedBy.email || "\u2013";
|
|
6214
|
-
})();
|
|
6215
|
-
const role = isDomain ? invite.autoJoinRole : invite.role;
|
|
6216
|
-
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
6217
|
-
"div",
|
|
6218
|
-
{
|
|
6219
|
-
className: "flex items-center self-stretch shrink-0",
|
|
6220
|
-
style: {
|
|
6221
|
-
borderBottom: `1px solid ${T11.borderSubtle}`,
|
|
6222
|
-
padding: `${T11.sp5xl} ${T11.sp3xl}`,
|
|
6223
|
-
gap: T11.sp6xl
|
|
6224
|
-
},
|
|
6225
|
-
children: [
|
|
6226
|
-
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex items-center min-w-0", style: { flex: 1, gap: T11.spMd }, children: [
|
|
6227
|
-
isDomain ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
6228
|
-
"div",
|
|
6229
|
-
{
|
|
6230
|
-
className: "shrink-0 flex items-center justify-center",
|
|
6231
|
-
style: {
|
|
6232
|
-
width: 32,
|
|
6233
|
-
height: 32,
|
|
6234
|
-
borderRadius: T11.rXl,
|
|
6235
|
-
background: T11.fillNeutral
|
|
6236
|
-
},
|
|
6237
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_icons8.SiconGlobe, { className: "w-4 h-4", color: T11.primary })
|
|
6238
|
-
}
|
|
6239
|
-
) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ProfileAvatar, { name: invite.email || "invite", size: 32 }),
|
|
6240
|
-
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex flex-col min-w-0", children: [
|
|
6241
|
-
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
6242
|
-
"span",
|
|
6243
|
-
{
|
|
6244
|
-
className: "truncate",
|
|
6245
|
-
style: {
|
|
6246
|
-
fontFamily: T11.font,
|
|
6247
|
-
fontSize: T11.fsSm,
|
|
6248
|
-
fontWeight: 500,
|
|
6249
|
-
lineHeight: T11.lhSm,
|
|
6250
|
-
color: T11.primary
|
|
6251
|
-
},
|
|
6252
|
-
children: isDomain ? `Domain: ${invite.domain}` : toDisplayText2(invite.email, "")
|
|
6253
|
-
}
|
|
6254
|
-
),
|
|
6255
|
-
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
6256
|
-
"span",
|
|
6257
|
-
{
|
|
6258
|
-
className: "truncate",
|
|
6259
|
-
style: {
|
|
6260
|
-
fontFamily: T11.font,
|
|
6261
|
-
fontSize: T11.fsXs,
|
|
6262
|
-
fontWeight: 400,
|
|
6263
|
-
lineHeight: T11.lhXs,
|
|
6264
|
-
color: T11.muted
|
|
6265
|
-
},
|
|
6266
|
-
children: isDomain ? "Auto-join by verified domain" : "Email invite"
|
|
6267
|
-
}
|
|
6268
|
-
)
|
|
6269
|
-
] })
|
|
6270
|
-
] }),
|
|
6271
|
-
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
6272
|
-
RoleLabel,
|
|
6108
|
+
),
|
|
6109
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "flex items-center justify-end shrink-0", style: { width: 32 }, children: onEdit ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
6110
|
+
RowIconButton,
|
|
6273
6111
|
{
|
|
6274
|
-
|
|
6275
|
-
|
|
6112
|
+
label: `Manage ${email || "member"}`,
|
|
6113
|
+
onClick: onEdit,
|
|
6114
|
+
visible: active || noHover,
|
|
6115
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_icons8.SiconSettings, { className: "w-4 h-4", color: T11.primary })
|
|
6276
6116
|
}
|
|
6277
|
-
),
|
|
6278
|
-
|
|
6279
|
-
"div",
|
|
6117
|
+
) : email && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
6118
|
+
RowIconButton,
|
|
6280
6119
|
{
|
|
6281
|
-
|
|
6282
|
-
|
|
6283
|
-
|
|
6284
|
-
|
|
6285
|
-
|
|
6286
|
-
|
|
6287
|
-
|
|
6288
|
-
color: T11.primary
|
|
6120
|
+
label: copied ? "Copied" : `Copy ${email}`,
|
|
6121
|
+
onClick: () => {
|
|
6122
|
+
void onCopyEmail().then((ok) => {
|
|
6123
|
+
if (!ok) return;
|
|
6124
|
+
setCopied(true);
|
|
6125
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
6126
|
+
});
|
|
6289
6127
|
},
|
|
6290
|
-
children:
|
|
6128
|
+
children: copied ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_icons8.SiconCheck, { className: "w-4 h-4", color: T11.primary }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_icons8.SiconCopy, { className: "w-4 h-4", color: T11.primary })
|
|
6291
6129
|
}
|
|
6292
|
-
)
|
|
6293
|
-
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex items-center shrink-0", style: { gap: T11.spMd }, children: [
|
|
6294
|
-
!isDomain && onResend && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_ui8.ScButton, { text: "Resend", variant: "tertiary", size: "sm", onClick: onResend }),
|
|
6295
|
-
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
6296
|
-
import_ui8.ScButton,
|
|
6297
|
-
{
|
|
6298
|
-
text: isDomain ? "Revoke" : "Cancel",
|
|
6299
|
-
variant: "error",
|
|
6300
|
-
size: "sm",
|
|
6301
|
-
onClick: onCancel
|
|
6302
|
-
}
|
|
6303
|
-
)
|
|
6304
|
-
] })
|
|
6130
|
+
) })
|
|
6305
6131
|
]
|
|
6306
6132
|
}
|
|
6307
6133
|
);
|
|
@@ -6408,7 +6234,7 @@ function JoinRequestRow({
|
|
|
6408
6234
|
)
|
|
6409
6235
|
] })
|
|
6410
6236
|
] }),
|
|
6411
|
-
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex items-center shrink-0", style: { gap: T11.spMd }, children: [
|
|
6237
|
+
onApprove && onReject && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex items-center shrink-0", style: { gap: T11.spMd }, children: [
|
|
6412
6238
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_ui8.ScButton, { text: "Reject", variant: "error", size: "sm", onClick: onReject }),
|
|
6413
6239
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_ui8.ScButton, { text: "Approve", variant: "primary", size: "sm", onClick: onApprove })
|
|
6414
6240
|
] })
|
|
@@ -6464,42 +6290,29 @@ function Section({
|
|
|
6464
6290
|
}
|
|
6465
6291
|
function OrganizationContent({
|
|
6466
6292
|
embedded = false,
|
|
6467
|
-
view = "people"
|
|
6468
|
-
onInviteOpen,
|
|
6469
|
-
onInviteOpenChange
|
|
6293
|
+
view = "people"
|
|
6470
6294
|
} = {}) {
|
|
6471
6295
|
const { organization, toast } = useSettingsAdapters();
|
|
6472
6296
|
const current = organization.current;
|
|
6473
|
-
const [activeTab, setActiveTab] = (0, import_react12.useState)("active");
|
|
6474
6297
|
const [members, setMembers] = (0, import_react12.useState)([]);
|
|
6475
|
-
const [invites, setInvites] = (0, import_react12.useState)([]);
|
|
6476
6298
|
const [workspaces, setWorkspaces] = (0, import_react12.useState)([]);
|
|
6477
6299
|
const [joinRequests, setJoinRequests] = (0, import_react12.useState)([]);
|
|
6478
6300
|
const [highestRole, setHighestRole] = (0, import_react12.useState)("guest");
|
|
6479
|
-
const [emailDomain, setEmailDomain] = (0, import_react12.useState)(null);
|
|
6480
|
-
const [canClaimEmailDomain, setCanClaimEmailDomain] = (0, import_react12.useState)(true);
|
|
6481
6301
|
const [searchQuery, setSearchQuery] = (0, import_react12.useState)("");
|
|
6482
6302
|
const [loadingData, setLoadingData] = (0, import_react12.useState)(false);
|
|
6483
|
-
const [modal, setModal] = (0, import_react12.useState)({ open: false
|
|
6303
|
+
const [modal, setModal] = (0, import_react12.useState)({ open: false });
|
|
6484
6304
|
const fetchData = (0, import_react12.useCallback)(async () => {
|
|
6305
|
+
if (!organization.current) return;
|
|
6485
6306
|
setLoadingData(true);
|
|
6486
6307
|
try {
|
|
6487
|
-
const [membersRes,
|
|
6308
|
+
const [membersRes, workspacesRes, joinRequestsRes, highestRoleRes] = await Promise.all([
|
|
6488
6309
|
organization.fetchMembers().catch(() => null),
|
|
6489
|
-
organization.fetchInvites().catch(() => null),
|
|
6490
6310
|
organization.fetchWorkspaces().catch(() => null),
|
|
6491
6311
|
organization.fetchJoinRequests().catch(() => null),
|
|
6492
6312
|
organization.getHighestRole?.().catch(() => null) ?? Promise.resolve(null)
|
|
6493
6313
|
]);
|
|
6494
6314
|
if (highestRoleRes?.role) setHighestRole(highestRoleRes.role);
|
|
6495
|
-
if (highestRoleRes?.emailDomain !== void 0) {
|
|
6496
|
-
setEmailDomain(highestRoleRes.emailDomain ?? null);
|
|
6497
|
-
}
|
|
6498
|
-
if (highestRoleRes?.canClaimEmailDomain !== void 0) {
|
|
6499
|
-
setCanClaimEmailDomain(highestRoleRes.canClaimEmailDomain);
|
|
6500
|
-
}
|
|
6501
6315
|
if (membersRes) setMembers(membersRes.filter((m) => m?.user));
|
|
6502
|
-
if (invitesRes) setInvites(invitesRes);
|
|
6503
6316
|
if (workspacesRes) setWorkspaces(workspacesRes);
|
|
6504
6317
|
if (joinRequestsRes) setJoinRequests(joinRequestsRes);
|
|
6505
6318
|
} catch {
|
|
@@ -6510,51 +6323,6 @@ function OrganizationContent({
|
|
|
6510
6323
|
(0, import_react12.useEffect)(() => {
|
|
6511
6324
|
fetchData();
|
|
6512
6325
|
}, [fetchData]);
|
|
6513
|
-
const [domainMatch, setDomainMatch] = (0, import_react12.useState)(null);
|
|
6514
|
-
const [checkingDomainMatch, setCheckingDomainMatch] = (0, import_react12.useState)(false);
|
|
6515
|
-
const [joiningByDomain, setJoiningByDomain] = (0, import_react12.useState)(false);
|
|
6516
|
-
const [createModalOpen, setCreateModalOpen] = (0, import_react12.useState)(false);
|
|
6517
|
-
(0, import_react12.useEffect)(() => {
|
|
6518
|
-
if (current) return;
|
|
6519
|
-
let cancelled = false;
|
|
6520
|
-
setCheckingDomainMatch(true);
|
|
6521
|
-
organization.checkDomainMatch().then((match) => {
|
|
6522
|
-
if (!cancelled) setDomainMatch(match);
|
|
6523
|
-
}).catch(() => {
|
|
6524
|
-
if (!cancelled) setDomainMatch(null);
|
|
6525
|
-
}).finally(() => {
|
|
6526
|
-
if (!cancelled) setCheckingDomainMatch(false);
|
|
6527
|
-
});
|
|
6528
|
-
return () => {
|
|
6529
|
-
cancelled = true;
|
|
6530
|
-
};
|
|
6531
|
-
}, [current, organization]);
|
|
6532
|
-
const handleJoinByDomain = async () => {
|
|
6533
|
-
if (!domainMatch) return;
|
|
6534
|
-
setJoiningByDomain(true);
|
|
6535
|
-
try {
|
|
6536
|
-
await organization.joinByDomain();
|
|
6537
|
-
await organization.switch(domainMatch.organizationId);
|
|
6538
|
-
toast.success(`Joined ${domainMatch.organizationName}`);
|
|
6539
|
-
} catch (err) {
|
|
6540
|
-
toast.error(err instanceof Error ? err.message : "Failed to join organization");
|
|
6541
|
-
} finally {
|
|
6542
|
-
setJoiningByDomain(false);
|
|
6543
|
-
}
|
|
6544
|
-
};
|
|
6545
|
-
const handleCreateOrganization = async (name, imageFile) => {
|
|
6546
|
-
try {
|
|
6547
|
-
const result = await organization.create({ name, imageFile });
|
|
6548
|
-
if (result && "id" in result && result.id) {
|
|
6549
|
-
await organization.switch(result.id);
|
|
6550
|
-
}
|
|
6551
|
-
toast.success("Organization created");
|
|
6552
|
-
return true;
|
|
6553
|
-
} catch (err) {
|
|
6554
|
-
toast.error(err instanceof Error ? err.message : "Failed to create organization");
|
|
6555
|
-
return false;
|
|
6556
|
-
}
|
|
6557
|
-
};
|
|
6558
6326
|
const [manageModalOpen, setManageModalOpen] = (0, import_react12.useState)(false);
|
|
6559
6327
|
const handleUpdateOrganization = async (name, imageFile) => {
|
|
6560
6328
|
if (!current) return false;
|
|
@@ -6578,45 +6346,9 @@ function OrganizationContent({
|
|
|
6578
6346
|
return false;
|
|
6579
6347
|
}
|
|
6580
6348
|
};
|
|
6581
|
-
const
|
|
6582
|
-
|
|
6583
|
-
|
|
6584
|
-
openInviteModal();
|
|
6585
|
-
onInviteOpenChange?.(false);
|
|
6586
|
-
}
|
|
6587
|
-
}, [onInviteOpen]);
|
|
6588
|
-
const openUpdateModal = (member) => setModal({ open: true, mode: "update", target: member });
|
|
6589
|
-
const closeModal = () => setModal({ open: false, mode: "invite" });
|
|
6590
|
-
const handleInviteEmail = async (input) => {
|
|
6591
|
-
if (highestRole !== "admin") {
|
|
6592
|
-
toast.error("You do not have permission to invite members");
|
|
6593
|
-
closeModal();
|
|
6594
|
-
return;
|
|
6595
|
-
}
|
|
6596
|
-
try {
|
|
6597
|
-
await organization.inviteMemberByEmail(input);
|
|
6598
|
-
toast.success(`Invitation sent to ${input.email}`);
|
|
6599
|
-
await fetchData();
|
|
6600
|
-
closeModal();
|
|
6601
|
-
} catch (err) {
|
|
6602
|
-
toast.error(err instanceof Error ? err.message : "Failed to send invite");
|
|
6603
|
-
}
|
|
6604
|
-
};
|
|
6605
|
-
const handleInviteDomain = async (input) => {
|
|
6606
|
-
if (highestRole !== "admin") {
|
|
6607
|
-
toast.error("You do not have permission to invite members");
|
|
6608
|
-
closeModal();
|
|
6609
|
-
return;
|
|
6610
|
-
}
|
|
6611
|
-
try {
|
|
6612
|
-
await organization.inviteDomain(input);
|
|
6613
|
-
toast.success(`Domain ${input.domain} added`);
|
|
6614
|
-
await fetchData();
|
|
6615
|
-
closeModal();
|
|
6616
|
-
} catch (err) {
|
|
6617
|
-
toast.error(err instanceof Error ? err.message : "Failed to add domain");
|
|
6618
|
-
}
|
|
6619
|
-
};
|
|
6349
|
+
const openUpdateModal = (member) => setModal({ open: true, target: member });
|
|
6350
|
+
const closeModal = () => setModal({ open: false });
|
|
6351
|
+
const adminCount = members.filter((m) => m.role === "admin").length;
|
|
6620
6352
|
const handleUpdateMember = async (input) => {
|
|
6621
6353
|
const target = modal.target;
|
|
6622
6354
|
if (!target) {
|
|
@@ -6628,20 +6360,16 @@ function OrganizationContent({
|
|
|
6628
6360
|
closeModal();
|
|
6629
6361
|
return;
|
|
6630
6362
|
}
|
|
6631
|
-
if (target.role === "admin" && input.role === "member") {
|
|
6632
|
-
|
|
6633
|
-
|
|
6634
|
-
|
|
6635
|
-
|
|
6636
|
-
);
|
|
6637
|
-
return;
|
|
6638
|
-
}
|
|
6363
|
+
if (target.role === "admin" && input.role === "member" && adminCount <= 1) {
|
|
6364
|
+
toast.error(
|
|
6365
|
+
"This is the only org admin. Make someone else an org admin first."
|
|
6366
|
+
);
|
|
6367
|
+
return;
|
|
6639
6368
|
}
|
|
6640
6369
|
try {
|
|
6641
6370
|
await organization.updateMemberRole({
|
|
6642
6371
|
userId: target.user._id,
|
|
6643
|
-
role: input.role
|
|
6644
|
-
inviteAccess: input.inviteAccess
|
|
6372
|
+
role: input.role
|
|
6645
6373
|
});
|
|
6646
6374
|
toast.success("Member updated");
|
|
6647
6375
|
await fetchData();
|
|
@@ -6661,8 +6389,14 @@ function OrganizationContent({
|
|
|
6661
6389
|
closeModal();
|
|
6662
6390
|
return;
|
|
6663
6391
|
}
|
|
6392
|
+
if (target.role === "admin" && adminCount <= 1) {
|
|
6393
|
+
toast.error(
|
|
6394
|
+
"This is the only org admin. Make someone else an org admin first."
|
|
6395
|
+
);
|
|
6396
|
+
return;
|
|
6397
|
+
}
|
|
6664
6398
|
const confirmed = window.confirm(
|
|
6665
|
-
`Remove ${target.user.email} from this organization
|
|
6399
|
+
`Remove ${target.user.email} from this organization? They'll also be removed from every workspace in it.`
|
|
6666
6400
|
);
|
|
6667
6401
|
if (!confirmed) return;
|
|
6668
6402
|
try {
|
|
@@ -6674,44 +6408,6 @@ function OrganizationContent({
|
|
|
6674
6408
|
}
|
|
6675
6409
|
closeModal();
|
|
6676
6410
|
};
|
|
6677
|
-
const handleCancelInvite = async (invite) => {
|
|
6678
|
-
if (highestRole !== "admin") {
|
|
6679
|
-
toast.error("You do not have permission to manage invites");
|
|
6680
|
-
return;
|
|
6681
|
-
}
|
|
6682
|
-
const label = invite.kind === "domain" ? invite.domain : invite.email;
|
|
6683
|
-
const confirmed = window.confirm(
|
|
6684
|
-
invite.kind === "domain" ? `Revoke domain invite for ${label}? Members who already joined will keep their access.` : `Cancel invitation for ${label}?`
|
|
6685
|
-
);
|
|
6686
|
-
if (!confirmed) return;
|
|
6687
|
-
try {
|
|
6688
|
-
if (invite.kind === "domain") {
|
|
6689
|
-
await organization.revokeDomainInvite(invite._id);
|
|
6690
|
-
} else if (invite.token) {
|
|
6691
|
-
await organization.cancelInvite(invite.token);
|
|
6692
|
-
} else {
|
|
6693
|
-
await organization.removeMember({ invitationIds: [invite._id] });
|
|
6694
|
-
}
|
|
6695
|
-
toast.success(invite.kind === "domain" ? "Domain invite revoked" : "Invitation removed");
|
|
6696
|
-
await fetchData();
|
|
6697
|
-
} catch (err) {
|
|
6698
|
-
toast.error(err instanceof Error ? err.message : "Failed to update invite");
|
|
6699
|
-
}
|
|
6700
|
-
};
|
|
6701
|
-
const handleResendInvite = async (invite) => {
|
|
6702
|
-
if (invite.kind !== "email") return;
|
|
6703
|
-
if (highestRole !== "admin") {
|
|
6704
|
-
toast.error("You do not have permission to invite members");
|
|
6705
|
-
return;
|
|
6706
|
-
}
|
|
6707
|
-
try {
|
|
6708
|
-
await organization.resendInvite(invite._id);
|
|
6709
|
-
toast.success("Invitation resent");
|
|
6710
|
-
await fetchData();
|
|
6711
|
-
} catch (err) {
|
|
6712
|
-
toast.error(err instanceof Error ? err.message : "Failed to resend invitation");
|
|
6713
|
-
}
|
|
6714
|
-
};
|
|
6715
6411
|
const handleApproveJoinRequest = async (request) => {
|
|
6716
6412
|
try {
|
|
6717
6413
|
await organization.approveJoinRequest(request._id);
|
|
@@ -6733,101 +6429,29 @@ function OrganizationContent({
|
|
|
6733
6429
|
}
|
|
6734
6430
|
};
|
|
6735
6431
|
if (!current) {
|
|
6736
|
-
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
6737
|
-
|
|
6738
|
-
|
|
6739
|
-
|
|
6740
|
-
|
|
6741
|
-
|
|
6742
|
-
|
|
6743
|
-
|
|
6744
|
-
|
|
6745
|
-
|
|
6746
|
-
|
|
6747
|
-
|
|
6748
|
-
|
|
6749
|
-
|
|
6750
|
-
|
|
6751
|
-
|
|
6752
|
-
|
|
6753
|
-
|
|
6754
|
-
}
|
|
6755
|
-
),
|
|
6756
|
-
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
6757
|
-
"p",
|
|
6758
|
-
{
|
|
6759
|
-
className: "text-center",
|
|
6760
|
-
style: { color: T11.muted, fontFamily: T11.font, fontSize: T11.fsSm },
|
|
6761
|
-
children: [
|
|
6762
|
-
domainMatch.organizationName,
|
|
6763
|
-
" \u2014 join it instead of creating a new one and fragmenting your company across multiple orgs."
|
|
6764
|
-
]
|
|
6765
|
-
}
|
|
6766
|
-
),
|
|
6767
|
-
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
6768
|
-
import_ui8.ScButton,
|
|
6769
|
-
{
|
|
6770
|
-
text: joiningByDomain ? "Joining\u2026" : `Join ${domainMatch.organizationName}`,
|
|
6771
|
-
variant: "primary",
|
|
6772
|
-
size: "md",
|
|
6773
|
-
state: joiningByDomain ? "disabled" : "default",
|
|
6774
|
-
onClick: handleJoinByDomain
|
|
6775
|
-
}
|
|
6776
|
-
)
|
|
6777
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
|
|
6778
|
-
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
6779
|
-
"p",
|
|
6780
|
-
{
|
|
6781
|
-
className: "text-center",
|
|
6782
|
-
style: { color: T11.primary, fontFamily: T11.font, fontSize: T11.fsMd, fontWeight: 600 },
|
|
6783
|
-
children: "You're not part of an organization yet"
|
|
6784
|
-
}
|
|
6785
|
-
),
|
|
6786
|
-
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
6787
|
-
"p",
|
|
6788
|
-
{
|
|
6789
|
-
className: "text-center",
|
|
6790
|
-
style: { color: T11.muted, fontFamily: T11.font, fontSize: T11.fsSm },
|
|
6791
|
-
children: "Create one to invite your team and manage workspaces together."
|
|
6792
|
-
}
|
|
6793
|
-
),
|
|
6794
|
-
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
6795
|
-
import_ui8.ScButton,
|
|
6796
|
-
{
|
|
6797
|
-
text: "Create organization",
|
|
6798
|
-
variant: "primary",
|
|
6799
|
-
size: "md",
|
|
6800
|
-
styleVariant: "icon-left",
|
|
6801
|
-
icon: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_icons8.SiconUserAdd, { className: "w-5 h-5", color: T11.inverse }),
|
|
6802
|
-
state: checkingDomainMatch ? "disabled" : "default",
|
|
6803
|
-
onClick: () => setCreateModalOpen(true)
|
|
6804
|
-
}
|
|
6805
|
-
)
|
|
6806
|
-
] })
|
|
6807
|
-
]
|
|
6808
|
-
}
|
|
6809
|
-
),
|
|
6810
|
-
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
6811
|
-
OrganizationModal,
|
|
6812
|
-
{
|
|
6813
|
-
open: createModalOpen,
|
|
6814
|
-
mode: "create",
|
|
6815
|
-
onClose: () => setCreateModalOpen(false),
|
|
6816
|
-
onCreate: handleCreateOrganization
|
|
6817
|
-
}
|
|
6818
|
-
)
|
|
6819
|
-
] });
|
|
6432
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
6433
|
+
"div",
|
|
6434
|
+
{
|
|
6435
|
+
className: "flex flex-col flex-1 min-w-0 min-h-0 w-full items-center justify-center",
|
|
6436
|
+
style: { gap: T11.spXl, padding: T11.sp6xl },
|
|
6437
|
+
children: [
|
|
6438
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_icons8.SiconGlobe, { className: "w-10 h-10", color: T11.muted }),
|
|
6439
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
6440
|
+
"p",
|
|
6441
|
+
{
|
|
6442
|
+
className: "text-center",
|
|
6443
|
+
style: { color: T11.primary, fontFamily: T11.font, fontSize: T11.fsMd, fontWeight: 600 },
|
|
6444
|
+
children: "Your workspace isn't part of an organization"
|
|
6445
|
+
}
|
|
6446
|
+
)
|
|
6447
|
+
]
|
|
6448
|
+
}
|
|
6449
|
+
);
|
|
6820
6450
|
}
|
|
6821
6451
|
const q = searchQuery.toLowerCase();
|
|
6822
6452
|
const filteredMembers = members.filter(
|
|
6823
6453
|
(m) => (m.user.email || "").toLowerCase().includes(q) || (m.user.name || "").toLowerCase().includes(q) || m.role.toLowerCase().includes(q)
|
|
6824
6454
|
);
|
|
6825
|
-
const filteredInvites = invites.filter((inv) => {
|
|
6826
|
-
const label = inv.kind === "domain" ? inv.domain ?? "" : inv.email ?? "";
|
|
6827
|
-
return label.toLowerCase().includes(q);
|
|
6828
|
-
});
|
|
6829
|
-
const emailInvites = filteredInvites.filter((inv) => inv.kind !== "domain");
|
|
6830
|
-
const domainInvites = invites.filter((inv) => inv.kind === "domain");
|
|
6831
6455
|
const scopeHeader = /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
6832
6456
|
ScopeHeader,
|
|
6833
6457
|
{
|
|
@@ -6876,15 +6500,26 @@ function OrganizationContent({
|
|
|
6876
6500
|
)
|
|
6877
6501
|
}
|
|
6878
6502
|
);
|
|
6503
|
+
const isOrgAdmin = highestRole === "admin";
|
|
6504
|
+
const copyEmail = async (email) => {
|
|
6505
|
+
try {
|
|
6506
|
+
await navigator.clipboard.writeText(email);
|
|
6507
|
+
toast.success("Email copied");
|
|
6508
|
+
return true;
|
|
6509
|
+
} catch {
|
|
6510
|
+
toast.error("Couldn't copy the email");
|
|
6511
|
+
return false;
|
|
6512
|
+
}
|
|
6513
|
+
};
|
|
6879
6514
|
const peopleView = /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
|
|
6880
6515
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
6881
6516
|
MemberListToolbar,
|
|
6882
6517
|
{
|
|
6883
|
-
activeTab,
|
|
6884
|
-
onTabChange:
|
|
6518
|
+
activeTab: "active",
|
|
6519
|
+
onTabChange: () => {
|
|
6520
|
+
},
|
|
6885
6521
|
activeLabel: "Members",
|
|
6886
6522
|
activeCount: filteredMembers.length,
|
|
6887
|
-
pendingCount: emailInvites.length,
|
|
6888
6523
|
searchQuery,
|
|
6889
6524
|
onSearchChange: setSearchQuery
|
|
6890
6525
|
}
|
|
@@ -6892,47 +6527,31 @@ function OrganizationContent({
|
|
|
6892
6527
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
6893
6528
|
MemberListFrame,
|
|
6894
6529
|
{
|
|
6895
|
-
isEmpty:
|
|
6896
|
-
emptyText:
|
|
6530
|
+
isEmpty: filteredMembers.length === 0,
|
|
6531
|
+
emptyText: "No members yet",
|
|
6897
6532
|
grow: "fill",
|
|
6898
|
-
children:
|
|
6899
|
-
|
|
6533
|
+
children: filteredMembers.map((m) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
6534
|
+
MemberRow,
|
|
6900
6535
|
{
|
|
6901
|
-
|
|
6902
|
-
|
|
6903
|
-
|
|
6536
|
+
member: m,
|
|
6537
|
+
onEdit: isOrgAdmin ? () => openUpdateModal(m) : void 0,
|
|
6538
|
+
onCopyEmail: () => copyEmail(m.user.email)
|
|
6904
6539
|
},
|
|
6905
|
-
|
|
6540
|
+
m._id
|
|
6906
6541
|
))
|
|
6907
6542
|
}
|
|
6908
6543
|
)
|
|
6909
6544
|
] });
|
|
6910
|
-
const workspacesView = /* @__PURE__ */ (0, import_jsx_runtime17.
|
|
6911
|
-
Section,
|
|
6912
|
-
{
|
|
6913
|
-
title: "Workspaces in this organization",
|
|
6914
|
-
empty: workspaces.length === 0,
|
|
6915
|
-
children: workspaces.map((ws) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(WorkspaceRow, { workspace: ws }, ws._id))
|
|
6916
|
-
}
|
|
6917
|
-
);
|
|
6918
|
-
const domainsView = /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
|
|
6545
|
+
const workspacesView = /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
|
|
6919
6546
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
6920
6547
|
Section,
|
|
6921
6548
|
{
|
|
6922
|
-
title: "
|
|
6923
|
-
empty:
|
|
6924
|
-
|
|
6925
|
-
children: domainInvites.map((inv) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
6926
|
-
InviteRow,
|
|
6927
|
-
{
|
|
6928
|
-
invite: inv,
|
|
6929
|
-
onCancel: () => void handleCancelInvite(inv)
|
|
6930
|
-
},
|
|
6931
|
-
inv._id
|
|
6932
|
-
))
|
|
6549
|
+
title: "Workspaces in this organization",
|
|
6550
|
+
empty: workspaces.length === 0,
|
|
6551
|
+
children: workspaces.map((ws) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(WorkspaceRow, { workspace: ws }, ws._id))
|
|
6933
6552
|
}
|
|
6934
6553
|
),
|
|
6935
|
-
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
6554
|
+
(isOrgAdmin || joinRequests.length > 0) && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
6936
6555
|
Section,
|
|
6937
6556
|
{
|
|
6938
6557
|
title: "Workspaces asking to join",
|
|
@@ -6941,8 +6560,8 @@ function OrganizationContent({
|
|
|
6941
6560
|
JoinRequestRow,
|
|
6942
6561
|
{
|
|
6943
6562
|
request: req,
|
|
6944
|
-
onApprove: () => void handleApproveJoinRequest(req),
|
|
6945
|
-
onReject: () => void handleRejectJoinRequest(req)
|
|
6563
|
+
onApprove: isOrgAdmin ? () => void handleApproveJoinRequest(req) : void 0,
|
|
6564
|
+
onReject: isOrgAdmin ? () => void handleRejectJoinRequest(req) : void 0
|
|
6946
6565
|
},
|
|
6947
6566
|
req._id
|
|
6948
6567
|
))
|
|
@@ -6953,25 +6572,17 @@ function OrganizationContent({
|
|
|
6953
6572
|
scopeHeader,
|
|
6954
6573
|
loadingData && loadingBlock,
|
|
6955
6574
|
!loadingData && view === "people" && peopleView,
|
|
6956
|
-
!loadingData && view
|
|
6957
|
-
!loadingData && view === "domains" && domainsView,
|
|
6575
|
+
!loadingData && view !== "people" && workspacesView,
|
|
6958
6576
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
6959
|
-
|
|
6577
|
+
OrganizationMemberModal,
|
|
6960
6578
|
{
|
|
6961
6579
|
open: modal.open,
|
|
6962
|
-
mode: modal.mode,
|
|
6963
6580
|
userEmail: modal.target?.user.email,
|
|
6964
6581
|
initialRole: modal.target?.role === "admin" || modal.target?.role === "member" ? modal.target.role : void 0,
|
|
6965
|
-
initialInviteAccess: modal.target?.inviteAccess,
|
|
6966
|
-
allowSubmitWithoutChanges: false,
|
|
6967
6582
|
lockRole: modal.target?.role === "guest",
|
|
6968
6583
|
lockedRoleLabel: orgRoleLabel(modal.target?.role),
|
|
6969
6584
|
canRemove: highestRole === "admin",
|
|
6970
|
-
canClaimDomain: canClaimEmailDomain,
|
|
6971
|
-
claimableDomain: emailDomain,
|
|
6972
6585
|
onClose: closeModal,
|
|
6973
|
-
onInviteEmail: handleInviteEmail,
|
|
6974
|
-
onInviteDomain: handleInviteDomain,
|
|
6975
6586
|
onUpdate: handleUpdateMember,
|
|
6976
6587
|
onRemove: handleRemoveMember
|
|
6977
6588
|
}
|
|
@@ -7016,34 +6627,20 @@ function OrganizationContent({
|
|
|
7016
6627
|
backgroundSize: "24px 24px"
|
|
7017
6628
|
},
|
|
7018
6629
|
children: [
|
|
7019
|
-
/* @__PURE__ */ (0, import_jsx_runtime17.
|
|
7020
|
-
|
|
7021
|
-
|
|
7022
|
-
|
|
7023
|
-
|
|
7024
|
-
|
|
7025
|
-
|
|
7026
|
-
|
|
7027
|
-
|
|
7028
|
-
|
|
7029
|
-
|
|
7030
|
-
|
|
7031
|
-
|
|
7032
|
-
|
|
7033
|
-
),
|
|
7034
|
-
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
7035
|
-
import_ui8.ScButton,
|
|
7036
|
-
{
|
|
7037
|
-
text: "Invite",
|
|
7038
|
-
variant: "primary",
|
|
7039
|
-
size: "md",
|
|
7040
|
-
styleVariant: "icon-left",
|
|
7041
|
-
state: highestRole !== "admin" ? "disabled" : "default",
|
|
7042
|
-
icon: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_icons8.SiconUserAdd, { className: "w-5 h-5", color: "var(--alias-text---icons-inverse)" }),
|
|
7043
|
-
onClick: openInviteModal
|
|
7044
|
-
}
|
|
7045
|
-
)
|
|
7046
|
-
] }),
|
|
6630
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "flex items-center justify-between shrink-0 w-full", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
6631
|
+
"p",
|
|
6632
|
+
{
|
|
6633
|
+
className: "flex-1 min-w-0 truncate",
|
|
6634
|
+
style: {
|
|
6635
|
+
color: T11.primary,
|
|
6636
|
+
fontFamily: T11.font,
|
|
6637
|
+
fontSize: "var(--font-size-font-size-xxl)",
|
|
6638
|
+
fontWeight: 600,
|
|
6639
|
+
lineHeight: "var(--line-height-line-height-xxl)"
|
|
6640
|
+
},
|
|
6641
|
+
children: current?.name ? `${current.name} \u2014 Organization` : "Organization"
|
|
6642
|
+
}
|
|
6643
|
+
) }),
|
|
7047
6644
|
innerContent
|
|
7048
6645
|
]
|
|
7049
6646
|
}
|
|
@@ -10615,8 +10212,7 @@ function SettingsNav({
|
|
|
10615
10212
|
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "flex flex-col w-full", style: { gap: "var(--spacing-md)" }, children: hasOrganization ? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
|
|
10616
10213
|
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { padding: "4px 12px", fontSize: 11, fontWeight: 500, color: MUTED_COLOR2, textTransform: "uppercase", letterSpacing: "0.08em" }, children: "Organization" }),
|
|
10617
10214
|
item("organization", (color) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons13.SiconTeam, { className: "w-5 h-5", color })),
|
|
10618
|
-
item("organizationWorkspaces", (color) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons13.SiconWorkspace, { className: "w-5 h-5", color }))
|
|
10619
|
-
item("organizationDomains", (color) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons13.SiconLock, { className: "w-5 h-5", color }))
|
|
10215
|
+
item("organizationWorkspaces", (color) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons13.SiconWorkspace, { className: "w-5 h-5", color }))
|
|
10620
10216
|
] }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
10621
10217
|
SettingsNavItem,
|
|
10622
10218
|
{
|
|
@@ -11301,16 +10897,49 @@ function ProfileTab() {
|
|
|
11301
10897
|
}
|
|
11302
10898
|
);
|
|
11303
10899
|
}
|
|
10900
|
+
var WORKSPACE_LIST_PAGE_SIZE = 10;
|
|
11304
10901
|
function WorkspaceListTab({
|
|
11305
10902
|
workspaces,
|
|
11306
10903
|
loading,
|
|
11307
10904
|
onCreateClick: _onCreateClick,
|
|
11308
10905
|
onEditClick,
|
|
11309
10906
|
onSwitchClick,
|
|
11310
|
-
onLeaveClick
|
|
10907
|
+
onLeaveClick,
|
|
10908
|
+
fetchPlans,
|
|
10909
|
+
pageSize = WORKSPACE_LIST_PAGE_SIZE
|
|
11311
10910
|
}) {
|
|
11312
10911
|
const currentWorkspace = workspaces.find((ws) => ws.isCurrent);
|
|
11313
10912
|
const otherWorkspaces = workspaces.filter((ws) => !ws.isCurrent);
|
|
10913
|
+
const pageCount = Math.max(1, Math.ceil(otherWorkspaces.length / pageSize));
|
|
10914
|
+
const [page, setPage] = (0, import_react17.useState)(0);
|
|
10915
|
+
const safePage = Math.min(page, pageCount - 1);
|
|
10916
|
+
const pageStart = safePage * pageSize;
|
|
10917
|
+
const pageWorkspaces = otherWorkspaces.slice(pageStart, pageStart + pageSize);
|
|
10918
|
+
const [plans, setPlans] = (0, import_react17.useState)({});
|
|
10919
|
+
const requestedPlans = (0, import_react17.useRef)(/* @__PURE__ */ new Set());
|
|
10920
|
+
const visibleIds = [
|
|
10921
|
+
...currentWorkspace ? [currentWorkspace._id] : [],
|
|
10922
|
+
...pageWorkspaces.map((ws) => ws._id)
|
|
10923
|
+
];
|
|
10924
|
+
const visibleKey = visibleIds.join(",");
|
|
10925
|
+
const mounted = (0, import_react17.useRef)(true);
|
|
10926
|
+
(0, import_react17.useEffect)(() => {
|
|
10927
|
+
mounted.current = true;
|
|
10928
|
+
return () => {
|
|
10929
|
+
mounted.current = false;
|
|
10930
|
+
};
|
|
10931
|
+
}, []);
|
|
10932
|
+
(0, import_react17.useEffect)(() => {
|
|
10933
|
+
if (!fetchPlans || loading) return;
|
|
10934
|
+
const missing = visibleKey.split(",").filter((id) => id && !requestedPlans.current.has(id));
|
|
10935
|
+
if (!missing.length) return;
|
|
10936
|
+
missing.forEach((id) => requestedPlans.current.add(id));
|
|
10937
|
+
fetchPlans(missing).then((found) => {
|
|
10938
|
+
if (mounted.current) setPlans((prev) => ({ ...prev, ...found }));
|
|
10939
|
+
}).catch(() => {
|
|
10940
|
+
});
|
|
10941
|
+
}, [fetchPlans, loading, visibleKey]);
|
|
10942
|
+
const planOf = (ws) => fetchPlans ? plans[ws._id] ?? "" : ws.plan ?? "";
|
|
11314
10943
|
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
11315
10944
|
"div",
|
|
11316
10945
|
{
|
|
@@ -11368,7 +10997,7 @@ function WorkspaceListTab({
|
|
|
11368
10997
|
initials: currentWorkspace.initials,
|
|
11369
10998
|
imageUrl: currentWorkspace.imageUrl,
|
|
11370
10999
|
role: currentWorkspace.role,
|
|
11371
|
-
plan: currentWorkspace
|
|
11000
|
+
plan: planOf(currentWorkspace),
|
|
11372
11001
|
ownerId: currentWorkspace.ownerEmail,
|
|
11373
11002
|
type: "currentWS",
|
|
11374
11003
|
onSettings: () => onEditClick(currentWorkspace),
|
|
@@ -11413,14 +11042,14 @@ function WorkspaceListTab({
|
|
|
11413
11042
|
{
|
|
11414
11043
|
className: "flex flex-col items-start w-full",
|
|
11415
11044
|
style: { gap: 16 },
|
|
11416
|
-
children:
|
|
11045
|
+
children: pageWorkspaces.map((ws) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
11417
11046
|
import_ui14.ScWorkspaceSwitchCard,
|
|
11418
11047
|
{
|
|
11419
11048
|
wsName: ws.name,
|
|
11420
11049
|
initials: ws.initials,
|
|
11421
11050
|
imageUrl: ws.imageUrl,
|
|
11422
11051
|
role: ws.role,
|
|
11423
|
-
plan: ws
|
|
11052
|
+
plan: planOf(ws),
|
|
11424
11053
|
ownerId: ws.ownerEmail,
|
|
11425
11054
|
type: "otherWS",
|
|
11426
11055
|
onSwitch: () => onSwitchClick(ws),
|
|
@@ -11430,6 +11059,56 @@ function WorkspaceListTab({
|
|
|
11430
11059
|
ws._id
|
|
11431
11060
|
))
|
|
11432
11061
|
}
|
|
11062
|
+
),
|
|
11063
|
+
pageCount > 1 && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
11064
|
+
"div",
|
|
11065
|
+
{
|
|
11066
|
+
className: "flex items-center justify-between shrink-0 w-full",
|
|
11067
|
+
style: { gap: "var(--spacing-md)" },
|
|
11068
|
+
children: [
|
|
11069
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
11070
|
+
"span",
|
|
11071
|
+
{
|
|
11072
|
+
style: {
|
|
11073
|
+
color: "var(--alias-text---icons-muted)",
|
|
11074
|
+
fontFamily: "var(--font-family-font-family-body)",
|
|
11075
|
+
fontSize: "var(--font-size-font-size-sm)",
|
|
11076
|
+
lineHeight: "var(--line-height-line-height-sm)"
|
|
11077
|
+
},
|
|
11078
|
+
children: [
|
|
11079
|
+
pageStart + 1,
|
|
11080
|
+
"\u2013",
|
|
11081
|
+
pageStart + pageWorkspaces.length,
|
|
11082
|
+
" of",
|
|
11083
|
+
" ",
|
|
11084
|
+
otherWorkspaces.length
|
|
11085
|
+
]
|
|
11086
|
+
}
|
|
11087
|
+
),
|
|
11088
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex items-center", style: { gap: "var(--spacing-md)" }, children: [
|
|
11089
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
11090
|
+
import_ui13.ScButton,
|
|
11091
|
+
{
|
|
11092
|
+
text: "Previous",
|
|
11093
|
+
variant: "tertiary",
|
|
11094
|
+
size: "sm",
|
|
11095
|
+
state: safePage === 0 ? "disabled" : "default",
|
|
11096
|
+
onClick: safePage === 0 ? void 0 : () => setPage(safePage - 1)
|
|
11097
|
+
}
|
|
11098
|
+
),
|
|
11099
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
11100
|
+
import_ui13.ScButton,
|
|
11101
|
+
{
|
|
11102
|
+
text: "Next",
|
|
11103
|
+
variant: "tertiary",
|
|
11104
|
+
size: "sm",
|
|
11105
|
+
state: safePage >= pageCount - 1 ? "disabled" : "default",
|
|
11106
|
+
onClick: safePage >= pageCount - 1 ? void 0 : () => setPage(safePage + 1)
|
|
11107
|
+
}
|
|
11108
|
+
)
|
|
11109
|
+
] })
|
|
11110
|
+
]
|
|
11111
|
+
}
|
|
11433
11112
|
)
|
|
11434
11113
|
]
|
|
11435
11114
|
}
|
|
@@ -11588,7 +11267,6 @@ function SettingsContentInner({
|
|
|
11588
11267
|
const [creatingWorkspace, setCreatingWorkspace] = (0, import_react17.useState)(false);
|
|
11589
11268
|
const [updatingWorkspace, setUpdatingWorkspace] = (0, import_react17.useState)(false);
|
|
11590
11269
|
const [teamInviteOpen, setTeamInviteOpen] = (0, import_react17.useState)(false);
|
|
11591
|
-
const [organizationInviteOpen, setOrganizationInviteOpen] = (0, import_react17.useState)(false);
|
|
11592
11270
|
const [tokenShowRevoked, setTokenShowRevoked] = (0, import_react17.useState)(false);
|
|
11593
11271
|
const [tokenCreateOpen, setTokenCreateOpen] = (0, import_react17.useState)(false);
|
|
11594
11272
|
const [billingShowPlans, setBillingShowPlans] = (0, import_react17.useState)(false);
|
|
@@ -12095,31 +11773,6 @@ function SettingsContentInner({
|
|
|
12095
11773
|
)
|
|
12096
11774
|
}
|
|
12097
11775
|
),
|
|
12098
|
-
activeTab === "organization" && hasOrganization && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
12099
|
-
SettingsTooltip,
|
|
12100
|
-
{
|
|
12101
|
-
content: "Invite someone into your organization",
|
|
12102
|
-
placement: "bottom",
|
|
12103
|
-
inline: true,
|
|
12104
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
12105
|
-
import_ui13.ScButton,
|
|
12106
|
-
{
|
|
12107
|
-
text: "Invite",
|
|
12108
|
-
variant: "secondary",
|
|
12109
|
-
size: "md",
|
|
12110
|
-
styleVariant: "icon-left",
|
|
12111
|
-
icon: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
12112
|
-
import_icons13.SiconUserAdd,
|
|
12113
|
-
{
|
|
12114
|
-
className: "w-5 h-5",
|
|
12115
|
-
color: "var(--alias-text---icons-inverse)"
|
|
12116
|
-
}
|
|
12117
|
-
),
|
|
12118
|
-
onClick: () => setOrganizationInviteOpen(true)
|
|
12119
|
-
}
|
|
12120
|
-
)
|
|
12121
|
-
}
|
|
12122
|
-
),
|
|
12123
11776
|
activeTab === "apikey" && isWorkspaceAdmin && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex items-center shrink-0", style: { gap: "var(--spacing-md)" }, children: [
|
|
12124
11777
|
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
12125
11778
|
SettingsTooltip,
|
|
@@ -12249,6 +11902,7 @@ function SettingsContentInner({
|
|
|
12249
11902
|
{
|
|
12250
11903
|
workspaces: displayWorkspaces,
|
|
12251
11904
|
loading: workspaceListLoading && workspaceList.length === 0,
|
|
11905
|
+
fetchPlans: workspace.fetchPlans,
|
|
12252
11906
|
onCreateClick: handleCreateClick,
|
|
12253
11907
|
onEditClick: handleEditClick,
|
|
12254
11908
|
onSwitchClick: async (ws) => {
|
|
@@ -12278,9 +11932,7 @@ function SettingsContentInner({
|
|
|
12278
11932
|
OrganizationContent,
|
|
12279
11933
|
{
|
|
12280
11934
|
embedded: true,
|
|
12281
|
-
view: activeTab === "organizationWorkspaces"
|
|
12282
|
-
onInviteOpen: organizationInviteOpen,
|
|
12283
|
-
onInviteOpenChange: setOrganizationInviteOpen
|
|
11935
|
+
view: activeTab === "organizationWorkspaces" || activeTab === "organizationDomains" ? "workspaces" : "people"
|
|
12284
11936
|
}
|
|
12285
11937
|
) }),
|
|
12286
11938
|
activeTab === "billing" && isWorkspaceAdmin && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "flex flex-col flex-1 min-w-0 min-h-0 h-full", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
@@ -12418,3 +12070,246 @@ function SettingsContentInner({
|
|
|
12418
12070
|
}
|
|
12419
12071
|
);
|
|
12420
12072
|
}
|
|
12073
|
+
|
|
12074
|
+
// src/workspace-picker.tsx
|
|
12075
|
+
var import_react18 = require("react");
|
|
12076
|
+
var import_ui15 = require("@streamoid/ui");
|
|
12077
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
12078
|
+
var T13 = {
|
|
12079
|
+
primary: "var(--alias-text---icons-primary)",
|
|
12080
|
+
muted: "var(--alias-text---icons-muted)",
|
|
12081
|
+
tertiary: "var(--alias-text---icons-tertiary)",
|
|
12082
|
+
surface: "var(--alias-surface-base)",
|
|
12083
|
+
fillPlus: "var(--alias-fill-neutral-neutralplus)",
|
|
12084
|
+
borderSubtle: "var(--alias-border-subtle)",
|
|
12085
|
+
font: "var(--font-family-font-family-body)",
|
|
12086
|
+
fsXs: "var(--font-size-font-size-xs)",
|
|
12087
|
+
fsSm: "var(--font-size-font-size-sm)",
|
|
12088
|
+
fsXl: "var(--font-size-font-size-xl)",
|
|
12089
|
+
lhXs: "var(--line-height-line-height-xs)",
|
|
12090
|
+
lhSm: "var(--line-height-line-height-sm)",
|
|
12091
|
+
lhXl: "var(--line-height-line-height-xl)",
|
|
12092
|
+
spXs: "var(--spacing-xs)",
|
|
12093
|
+
spMd: "var(--spacing-md)",
|
|
12094
|
+
spXl: "var(--spacing-xl)",
|
|
12095
|
+
sp3xl: "var(--spacing-3xl)",
|
|
12096
|
+
sp5xl: "var(--spacing-5xl)",
|
|
12097
|
+
sp6xl: "var(--spacing-6xl)",
|
|
12098
|
+
rLg: "var(--radius-lg)",
|
|
12099
|
+
r3xl: "var(--radius-3xl)"
|
|
12100
|
+
};
|
|
12101
|
+
function WorkspacePicker({
|
|
12102
|
+
organizationName,
|
|
12103
|
+
workspaces,
|
|
12104
|
+
loading = false,
|
|
12105
|
+
onJoin,
|
|
12106
|
+
onCreate
|
|
12107
|
+
}) {
|
|
12108
|
+
const [selected, setSelected] = (0, import_react18.useState)(/* @__PURE__ */ new Set());
|
|
12109
|
+
const [creating, setCreating] = (0, import_react18.useState)(false);
|
|
12110
|
+
const [name, setName] = (0, import_react18.useState)("");
|
|
12111
|
+
const [busy, setBusy] = (0, import_react18.useState)(false);
|
|
12112
|
+
const hasWorkspaces = workspaces.length > 0;
|
|
12113
|
+
const showCreate = creating || !loading && !hasWorkspaces;
|
|
12114
|
+
const orgLabel = organizationName || "your organization";
|
|
12115
|
+
const toggle = (id) => setSelected((prev) => {
|
|
12116
|
+
const next = new Set(prev);
|
|
12117
|
+
if (next.has(id)) next.delete(id);
|
|
12118
|
+
else next.add(id);
|
|
12119
|
+
return next;
|
|
12120
|
+
});
|
|
12121
|
+
const run = async (action) => {
|
|
12122
|
+
setBusy(true);
|
|
12123
|
+
try {
|
|
12124
|
+
await action();
|
|
12125
|
+
} catch {
|
|
12126
|
+
} finally {
|
|
12127
|
+
setBusy(false);
|
|
12128
|
+
}
|
|
12129
|
+
};
|
|
12130
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
12131
|
+
"div",
|
|
12132
|
+
{
|
|
12133
|
+
className: "flex flex-col w-full",
|
|
12134
|
+
style: { maxWidth: 520, gap: T13.sp5xl, fontFamily: T13.font },
|
|
12135
|
+
children: [
|
|
12136
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col", style: { gap: T13.spMd }, children: [
|
|
12137
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
12138
|
+
"p",
|
|
12139
|
+
{
|
|
12140
|
+
style: {
|
|
12141
|
+
color: T13.primary,
|
|
12142
|
+
fontSize: T13.fsXl,
|
|
12143
|
+
fontWeight: 600,
|
|
12144
|
+
lineHeight: T13.lhXl,
|
|
12145
|
+
margin: 0
|
|
12146
|
+
},
|
|
12147
|
+
children: "Choose your workspaces"
|
|
12148
|
+
}
|
|
12149
|
+
),
|
|
12150
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { style: { color: T13.muted, fontSize: T13.fsSm, lineHeight: T13.lhSm, margin: 0 }, children: hasWorkspaces || loading ? `Join one or more workspaces in ${orgLabel} as a member, or create your own.` : `There are no workspaces to join in ${orgLabel} yet. Create one to get started.` })
|
|
12151
|
+
] }),
|
|
12152
|
+
(loading || hasWorkspaces) && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
12153
|
+
"div",
|
|
12154
|
+
{
|
|
12155
|
+
className: "flex flex-col w-full overflow-y-auto",
|
|
12156
|
+
style: {
|
|
12157
|
+
maxHeight: 360,
|
|
12158
|
+
background: T13.surface,
|
|
12159
|
+
border: `1px solid ${T13.borderSubtle}`,
|
|
12160
|
+
borderRadius: T13.r3xl
|
|
12161
|
+
},
|
|
12162
|
+
children: loading ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
12163
|
+
"div",
|
|
12164
|
+
{
|
|
12165
|
+
className: "flex items-center justify-center",
|
|
12166
|
+
style: { padding: T13.sp6xl, color: T13.muted, fontSize: T13.fsSm },
|
|
12167
|
+
children: "Loading workspaces\u2026"
|
|
12168
|
+
}
|
|
12169
|
+
) : workspaces.map((workspace, index) => {
|
|
12170
|
+
const checked = selected.has(workspace._id);
|
|
12171
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
12172
|
+
"div",
|
|
12173
|
+
{
|
|
12174
|
+
role: "checkbox",
|
|
12175
|
+
"aria-checked": checked,
|
|
12176
|
+
tabIndex: 0,
|
|
12177
|
+
className: "flex items-center cursor-pointer",
|
|
12178
|
+
style: {
|
|
12179
|
+
gap: T13.spXl,
|
|
12180
|
+
padding: `${T13.spXl} ${T13.sp3xl}`,
|
|
12181
|
+
borderTop: index ? `1px solid ${T13.borderSubtle}` : "none"
|
|
12182
|
+
},
|
|
12183
|
+
onClick: () => toggle(workspace._id),
|
|
12184
|
+
onKeyDown: (e) => {
|
|
12185
|
+
if (e.key === " " || e.key === "Enter") {
|
|
12186
|
+
e.preventDefault();
|
|
12187
|
+
toggle(workspace._id);
|
|
12188
|
+
}
|
|
12189
|
+
},
|
|
12190
|
+
children: [
|
|
12191
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_ui15.ScCheckbox, { checked }),
|
|
12192
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
12193
|
+
ProfileAvatar,
|
|
12194
|
+
{
|
|
12195
|
+
name: workspace.name,
|
|
12196
|
+
profileImage: workspace.imageUrl,
|
|
12197
|
+
size: 32,
|
|
12198
|
+
borderRadius: T13.rLg
|
|
12199
|
+
}
|
|
12200
|
+
),
|
|
12201
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col min-w-0", children: [
|
|
12202
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
12203
|
+
"span",
|
|
12204
|
+
{
|
|
12205
|
+
className: "truncate",
|
|
12206
|
+
style: {
|
|
12207
|
+
color: T13.primary,
|
|
12208
|
+
fontSize: T13.fsSm,
|
|
12209
|
+
fontWeight: 500,
|
|
12210
|
+
lineHeight: T13.lhSm
|
|
12211
|
+
},
|
|
12212
|
+
children: workspace.name
|
|
12213
|
+
}
|
|
12214
|
+
),
|
|
12215
|
+
workspace.ownerName && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
12216
|
+
"span",
|
|
12217
|
+
{
|
|
12218
|
+
className: "truncate",
|
|
12219
|
+
style: { color: T13.muted, fontSize: T13.fsXs, lineHeight: T13.lhXs },
|
|
12220
|
+
children: [
|
|
12221
|
+
"Created by ",
|
|
12222
|
+
workspace.ownerName
|
|
12223
|
+
]
|
|
12224
|
+
}
|
|
12225
|
+
)
|
|
12226
|
+
] })
|
|
12227
|
+
]
|
|
12228
|
+
},
|
|
12229
|
+
workspace._id
|
|
12230
|
+
);
|
|
12231
|
+
})
|
|
12232
|
+
}
|
|
12233
|
+
),
|
|
12234
|
+
showCreate ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col w-full", style: { gap: T13.spMd }, children: [
|
|
12235
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
12236
|
+
"label",
|
|
12237
|
+
{
|
|
12238
|
+
htmlFor: "workspace-picker-name",
|
|
12239
|
+
style: { color: T13.tertiary, fontSize: T13.fsSm, lineHeight: T13.lhSm },
|
|
12240
|
+
children: "New workspace name"
|
|
12241
|
+
}
|
|
12242
|
+
),
|
|
12243
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
12244
|
+
"input",
|
|
12245
|
+
{
|
|
12246
|
+
id: "workspace-picker-name",
|
|
12247
|
+
autoFocus: true,
|
|
12248
|
+
value: name,
|
|
12249
|
+
onChange: (e) => setName(e.target.value),
|
|
12250
|
+
onKeyDown: (e) => {
|
|
12251
|
+
if (e.key === "Enter" && name.trim() && !busy) {
|
|
12252
|
+
void run(() => onCreate(name.trim()));
|
|
12253
|
+
}
|
|
12254
|
+
},
|
|
12255
|
+
placeholder: "e.g. Marketing",
|
|
12256
|
+
style: {
|
|
12257
|
+
height: 48,
|
|
12258
|
+
padding: `0 ${T13.sp3xl}`,
|
|
12259
|
+
background: T13.fillPlus,
|
|
12260
|
+
border: "none",
|
|
12261
|
+
outline: "none",
|
|
12262
|
+
borderRadius: T13.r3xl,
|
|
12263
|
+
color: T13.primary,
|
|
12264
|
+
fontFamily: T13.font,
|
|
12265
|
+
fontSize: T13.fsSm
|
|
12266
|
+
}
|
|
12267
|
+
}
|
|
12268
|
+
),
|
|
12269
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center justify-end w-full", style: { gap: T13.spMd }, children: [
|
|
12270
|
+
hasWorkspaces && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
12271
|
+
import_ui15.ScButton,
|
|
12272
|
+
{
|
|
12273
|
+
text: "Back",
|
|
12274
|
+
variant: "tertiary",
|
|
12275
|
+
size: "md",
|
|
12276
|
+
onClick: () => setCreating(false)
|
|
12277
|
+
}
|
|
12278
|
+
),
|
|
12279
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
12280
|
+
import_ui15.ScButton,
|
|
12281
|
+
{
|
|
12282
|
+
text: busy ? "Creating\u2026" : "Create workspace",
|
|
12283
|
+
variant: "primary",
|
|
12284
|
+
size: "md",
|
|
12285
|
+
state: !name.trim() || busy ? "disabled" : "default",
|
|
12286
|
+
onClick: name.trim() && !busy ? () => void run(() => onCreate(name.trim())) : void 0
|
|
12287
|
+
}
|
|
12288
|
+
)
|
|
12289
|
+
] })
|
|
12290
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-wrap items-center justify-between w-full", style: { gap: T13.spMd }, children: [
|
|
12291
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
12292
|
+
import_ui15.ScButton,
|
|
12293
|
+
{
|
|
12294
|
+
text: "Create a workspace",
|
|
12295
|
+
variant: "tertiary",
|
|
12296
|
+
size: "md",
|
|
12297
|
+
state: loading || busy ? "disabled" : "default",
|
|
12298
|
+
onClick: loading || busy ? void 0 : () => setCreating(true)
|
|
12299
|
+
}
|
|
12300
|
+
),
|
|
12301
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
12302
|
+
import_ui15.ScButton,
|
|
12303
|
+
{
|
|
12304
|
+
text: busy ? "Joining\u2026" : selected.size > 1 ? `Join ${selected.size} workspaces` : "Join workspace",
|
|
12305
|
+
variant: "primary",
|
|
12306
|
+
size: "md",
|
|
12307
|
+
state: !selected.size || busy ? "disabled" : "default",
|
|
12308
|
+
onClick: selected.size && !busy ? () => void run(() => onJoin([...selected])) : void 0
|
|
12309
|
+
}
|
|
12310
|
+
)
|
|
12311
|
+
] })
|
|
12312
|
+
]
|
|
12313
|
+
}
|
|
12314
|
+
);
|
|
12315
|
+
}
|