@streamoid/settings 0.7.4 → 0.7.5

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/index.d.mts CHANGED
@@ -366,6 +366,14 @@ interface OrganizationWorkspaceItem {
366
366
  imageUrl?: string;
367
367
  orgVisibility: "private" | "shared";
368
368
  }
369
+ /** A shared workspace in the organization that the viewer isn't in yet. */
370
+ interface OrganizationJoinableWorkspace {
371
+ _id: string;
372
+ name: string;
373
+ imageUrl?: string;
374
+ /** Who created it, shown under the name. */
375
+ ownerName?: string;
376
+ }
369
377
  interface OrganizationJoinRequest {
370
378
  _id: string;
371
379
  workspace: {
@@ -455,6 +463,15 @@ interface SettingsOrganizationAdapter {
455
463
  canClaimEmailDomain?: boolean;
456
464
  }>;
457
465
  fetchWorkspaces: () => Promise<OrganizationWorkspaceItem[]>;
466
+ /**
467
+ * Optional: the organization's shared workspaces the viewer isn't in yet —
468
+ * the workspace picker's list. When given (with `joinWorkspaces`), org
469
+ * members see them under Organization › Workspaces and can join any of them
470
+ * as a member at any time, not only at first sign-in.
471
+ */
472
+ fetchJoinableWorkspaces?: () => Promise<OrganizationJoinableWorkspace[]>;
473
+ /** Optional: join those workspaces as a member. Resolves to the ids joined. */
474
+ joinWorkspaces?: (workspaceIds: string[]) => Promise<string[]>;
458
475
  fetchJoinRequests: () => Promise<OrganizationJoinRequest[]>;
459
476
  approveJoinRequest: (requestId: string) => Promise<void>;
460
477
  rejectJoinRequest: (requestId: string) => Promise<void>;
@@ -1468,4 +1485,4 @@ declare function SettingsAdaptersProvider({ adapters, children, }: {
1468
1485
  */
1469
1486
  declare function useSettingsAdapters(): SettingsAdapters;
1470
1487
 
1471
- export { APP_KEYS, type ApiToken, type AppKey, type AvailableCreditsResponse, BillingContent, type BillingEventPayload, type BillingProduct, type BillingSubscription, BuyCreditsModal, type BuyCreditsPayload, type BuyCreditsResponse, ConfirmDeleteModal, ConfirmLeaveModal, type CreatedToken, type CustomCreditInfo, type CustomCreditResponse, DEFAULT_PERMISSIONS, DEFAULT_USER_LANGUAGE, ExportDateModal, InviteUpdateModal, type InvoicePdfResponse, MemberListFrame, type MemberListFrameProps, type MemberListTab, MemberListToolbar, type MemberListToolbarProps, type MemberPermissionsPayload, OrganizationContent, type OrganizationData, type OrganizationInvite, type OrganizationJoinRequest, type OrganizationMember, OrganizationMemberModal, type OrganizationMemberModalProps, OrganizationModal, type OrganizationView, type OrganizationWorkspaceItem, type Price, type PriceMetadata, type ProductsResponse, ProfileAvatar, ProfileTab, ReferralTab, SCOPE_LABELS, ScopeHeader, type ScopeHeaderProps, type ServiceItem, type SettingsAdapters, SettingsAdaptersProvider, type SettingsApiAdapter, type SettingsAuthAdapter, type SettingsAuthUser, SettingsContent, type SettingsContentProps, type SettingsImageUploadAdapter, type SettingsNavigationAdapter, type SettingsOrganizationAdapter, type SettingsOrganizationCurrent, type SettingsOrganizationListItem, type SettingsScope, type SettingsTab, type SettingsToastAdapter, SettingsTooltip, type SettingsTooltipPlacement, type SettingsTooltipProps, type SettingsWorkspaceAdapter, type SettingsWorkspaceCurrent, type SettingsWorkspaceListItem, SiconKey, type StoreItem, type SubscriptionPlan, type SubscriptionResponse, TAB_DESCRIPTIONS, TAB_LABELS, TAB_SCOPE, TAB_TO_URL, type TeamMember, TeamsContent, type TokenExpiry, TokensContent, URL_TO_TAB, USER_LANGUAGES, type UpdateSubscriptionPayload, type UpdateSubscriptionResponse, type UsageHistoryItem, type UsageHistoryResponse, type UserLanguage, type UserPermissions, WORKSPACE_LIST_PAGE_SIZE, type WorkspaceData, WorkspaceGeneralTab, type WorkspaceGeneralTabProps, type WorkspaceInvite, type WorkspaceListOrganization, WorkspaceListTab, type WorkspaceMember, WorkspaceModal, type WorkspaceOrganization, type WorkspaceOrganizationRequest, WorkspacePicker, type WorkspacePickerItem, type WorkspacePickerProps, WorkspaceTab, type WorkspaceUsageResponse, countLabel, groupWorkspaceList, loadWorkspaceOrganization, resolveSettingsTabFromPath, useSettingsAdapters, useWorkspaceOrganization, userLanguageLabel };
1488
+ export { APP_KEYS, type ApiToken, type AppKey, type AvailableCreditsResponse, BillingContent, type BillingEventPayload, type BillingProduct, type BillingSubscription, BuyCreditsModal, type BuyCreditsPayload, type BuyCreditsResponse, ConfirmDeleteModal, ConfirmLeaveModal, type CreatedToken, type CustomCreditInfo, type CustomCreditResponse, DEFAULT_PERMISSIONS, DEFAULT_USER_LANGUAGE, ExportDateModal, InviteUpdateModal, type InvoicePdfResponse, MemberListFrame, type MemberListFrameProps, type MemberListTab, MemberListToolbar, type MemberListToolbarProps, type MemberPermissionsPayload, OrganizationContent, type OrganizationData, type OrganizationInvite, type OrganizationJoinRequest, type OrganizationJoinableWorkspace, type OrganizationMember, OrganizationMemberModal, type OrganizationMemberModalProps, OrganizationModal, type OrganizationView, type OrganizationWorkspaceItem, type Price, type PriceMetadata, type ProductsResponse, ProfileAvatar, ProfileTab, ReferralTab, SCOPE_LABELS, ScopeHeader, type ScopeHeaderProps, type ServiceItem, type SettingsAdapters, SettingsAdaptersProvider, type SettingsApiAdapter, type SettingsAuthAdapter, type SettingsAuthUser, SettingsContent, type SettingsContentProps, type SettingsImageUploadAdapter, type SettingsNavigationAdapter, type SettingsOrganizationAdapter, type SettingsOrganizationCurrent, type SettingsOrganizationListItem, type SettingsScope, type SettingsTab, type SettingsToastAdapter, SettingsTooltip, type SettingsTooltipPlacement, type SettingsTooltipProps, type SettingsWorkspaceAdapter, type SettingsWorkspaceCurrent, type SettingsWorkspaceListItem, SiconKey, type StoreItem, type SubscriptionPlan, type SubscriptionResponse, TAB_DESCRIPTIONS, TAB_LABELS, TAB_SCOPE, TAB_TO_URL, type TeamMember, TeamsContent, type TokenExpiry, TokensContent, URL_TO_TAB, USER_LANGUAGES, type UpdateSubscriptionPayload, type UpdateSubscriptionResponse, type UsageHistoryItem, type UsageHistoryResponse, type UserLanguage, type UserPermissions, WORKSPACE_LIST_PAGE_SIZE, type WorkspaceData, WorkspaceGeneralTab, type WorkspaceGeneralTabProps, type WorkspaceInvite, type WorkspaceListOrganization, WorkspaceListTab, type WorkspaceMember, WorkspaceModal, type WorkspaceOrganization, type WorkspaceOrganizationRequest, WorkspacePicker, type WorkspacePickerItem, type WorkspacePickerProps, WorkspaceTab, type WorkspaceUsageResponse, countLabel, groupWorkspaceList, loadWorkspaceOrganization, resolveSettingsTabFromPath, useSettingsAdapters, useWorkspaceOrganization, userLanguageLabel };
package/dist/index.d.ts CHANGED
@@ -366,6 +366,14 @@ interface OrganizationWorkspaceItem {
366
366
  imageUrl?: string;
367
367
  orgVisibility: "private" | "shared";
368
368
  }
369
+ /** A shared workspace in the organization that the viewer isn't in yet. */
370
+ interface OrganizationJoinableWorkspace {
371
+ _id: string;
372
+ name: string;
373
+ imageUrl?: string;
374
+ /** Who created it, shown under the name. */
375
+ ownerName?: string;
376
+ }
369
377
  interface OrganizationJoinRequest {
370
378
  _id: string;
371
379
  workspace: {
@@ -455,6 +463,15 @@ interface SettingsOrganizationAdapter {
455
463
  canClaimEmailDomain?: boolean;
456
464
  }>;
457
465
  fetchWorkspaces: () => Promise<OrganizationWorkspaceItem[]>;
466
+ /**
467
+ * Optional: the organization's shared workspaces the viewer isn't in yet —
468
+ * the workspace picker's list. When given (with `joinWorkspaces`), org
469
+ * members see them under Organization › Workspaces and can join any of them
470
+ * as a member at any time, not only at first sign-in.
471
+ */
472
+ fetchJoinableWorkspaces?: () => Promise<OrganizationJoinableWorkspace[]>;
473
+ /** Optional: join those workspaces as a member. Resolves to the ids joined. */
474
+ joinWorkspaces?: (workspaceIds: string[]) => Promise<string[]>;
458
475
  fetchJoinRequests: () => Promise<OrganizationJoinRequest[]>;
459
476
  approveJoinRequest: (requestId: string) => Promise<void>;
460
477
  rejectJoinRequest: (requestId: string) => Promise<void>;
@@ -1468,4 +1485,4 @@ declare function SettingsAdaptersProvider({ adapters, children, }: {
1468
1485
  */
1469
1486
  declare function useSettingsAdapters(): SettingsAdapters;
1470
1487
 
1471
- export { APP_KEYS, type ApiToken, type AppKey, type AvailableCreditsResponse, BillingContent, type BillingEventPayload, type BillingProduct, type BillingSubscription, BuyCreditsModal, type BuyCreditsPayload, type BuyCreditsResponse, ConfirmDeleteModal, ConfirmLeaveModal, type CreatedToken, type CustomCreditInfo, type CustomCreditResponse, DEFAULT_PERMISSIONS, DEFAULT_USER_LANGUAGE, ExportDateModal, InviteUpdateModal, type InvoicePdfResponse, MemberListFrame, type MemberListFrameProps, type MemberListTab, MemberListToolbar, type MemberListToolbarProps, type MemberPermissionsPayload, OrganizationContent, type OrganizationData, type OrganizationInvite, type OrganizationJoinRequest, type OrganizationMember, OrganizationMemberModal, type OrganizationMemberModalProps, OrganizationModal, type OrganizationView, type OrganizationWorkspaceItem, type Price, type PriceMetadata, type ProductsResponse, ProfileAvatar, ProfileTab, ReferralTab, SCOPE_LABELS, ScopeHeader, type ScopeHeaderProps, type ServiceItem, type SettingsAdapters, SettingsAdaptersProvider, type SettingsApiAdapter, type SettingsAuthAdapter, type SettingsAuthUser, SettingsContent, type SettingsContentProps, type SettingsImageUploadAdapter, type SettingsNavigationAdapter, type SettingsOrganizationAdapter, type SettingsOrganizationCurrent, type SettingsOrganizationListItem, type SettingsScope, type SettingsTab, type SettingsToastAdapter, SettingsTooltip, type SettingsTooltipPlacement, type SettingsTooltipProps, type SettingsWorkspaceAdapter, type SettingsWorkspaceCurrent, type SettingsWorkspaceListItem, SiconKey, type StoreItem, type SubscriptionPlan, type SubscriptionResponse, TAB_DESCRIPTIONS, TAB_LABELS, TAB_SCOPE, TAB_TO_URL, type TeamMember, TeamsContent, type TokenExpiry, TokensContent, URL_TO_TAB, USER_LANGUAGES, type UpdateSubscriptionPayload, type UpdateSubscriptionResponse, type UsageHistoryItem, type UsageHistoryResponse, type UserLanguage, type UserPermissions, WORKSPACE_LIST_PAGE_SIZE, type WorkspaceData, WorkspaceGeneralTab, type WorkspaceGeneralTabProps, type WorkspaceInvite, type WorkspaceListOrganization, WorkspaceListTab, type WorkspaceMember, WorkspaceModal, type WorkspaceOrganization, type WorkspaceOrganizationRequest, WorkspacePicker, type WorkspacePickerItem, type WorkspacePickerProps, WorkspaceTab, type WorkspaceUsageResponse, countLabel, groupWorkspaceList, loadWorkspaceOrganization, resolveSettingsTabFromPath, useSettingsAdapters, useWorkspaceOrganization, userLanguageLabel };
1488
+ export { APP_KEYS, type ApiToken, type AppKey, type AvailableCreditsResponse, BillingContent, type BillingEventPayload, type BillingProduct, type BillingSubscription, BuyCreditsModal, type BuyCreditsPayload, type BuyCreditsResponse, ConfirmDeleteModal, ConfirmLeaveModal, type CreatedToken, type CustomCreditInfo, type CustomCreditResponse, DEFAULT_PERMISSIONS, DEFAULT_USER_LANGUAGE, ExportDateModal, InviteUpdateModal, type InvoicePdfResponse, MemberListFrame, type MemberListFrameProps, type MemberListTab, MemberListToolbar, type MemberListToolbarProps, type MemberPermissionsPayload, OrganizationContent, type OrganizationData, type OrganizationInvite, type OrganizationJoinRequest, type OrganizationJoinableWorkspace, type OrganizationMember, OrganizationMemberModal, type OrganizationMemberModalProps, OrganizationModal, type OrganizationView, type OrganizationWorkspaceItem, type Price, type PriceMetadata, type ProductsResponse, ProfileAvatar, ProfileTab, ReferralTab, SCOPE_LABELS, ScopeHeader, type ScopeHeaderProps, type ServiceItem, type SettingsAdapters, SettingsAdaptersProvider, type SettingsApiAdapter, type SettingsAuthAdapter, type SettingsAuthUser, SettingsContent, type SettingsContentProps, type SettingsImageUploadAdapter, type SettingsNavigationAdapter, type SettingsOrganizationAdapter, type SettingsOrganizationCurrent, type SettingsOrganizationListItem, type SettingsScope, type SettingsTab, type SettingsToastAdapter, SettingsTooltip, type SettingsTooltipPlacement, type SettingsTooltipProps, type SettingsWorkspaceAdapter, type SettingsWorkspaceCurrent, type SettingsWorkspaceListItem, SiconKey, type StoreItem, type SubscriptionPlan, type SubscriptionResponse, TAB_DESCRIPTIONS, TAB_LABELS, TAB_SCOPE, TAB_TO_URL, type TeamMember, TeamsContent, type TokenExpiry, TokensContent, URL_TO_TAB, USER_LANGUAGES, type UpdateSubscriptionPayload, type UpdateSubscriptionResponse, type UsageHistoryItem, type UsageHistoryResponse, type UserLanguage, type UserPermissions, WORKSPACE_LIST_PAGE_SIZE, type WorkspaceData, WorkspaceGeneralTab, type WorkspaceGeneralTabProps, type WorkspaceInvite, type WorkspaceListOrganization, WorkspaceListTab, type WorkspaceMember, WorkspaceModal, type WorkspaceOrganization, type WorkspaceOrganizationRequest, WorkspacePicker, type WorkspacePickerItem, type WorkspacePickerProps, WorkspaceTab, type WorkspaceUsageResponse, countLabel, groupWorkspaceList, loadWorkspaceOrganization, resolveSettingsTabFromPath, useSettingsAdapters, useWorkspaceOrganization, userLanguageLabel };
package/dist/index.js CHANGED
@@ -6174,6 +6174,79 @@ function WorkspaceRow({ workspace }) {
6174
6174
  }
6175
6175
  );
6176
6176
  }
6177
+ function JoinableWorkspaceRow({
6178
+ workspace,
6179
+ joining,
6180
+ onJoin
6181
+ }) {
6182
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
6183
+ "div",
6184
+ {
6185
+ className: "flex items-center self-stretch shrink-0",
6186
+ style: {
6187
+ borderBottom: `1px solid ${T11.borderSubtle}`,
6188
+ padding: `${T11.spXl} ${T11.sp3xl}`,
6189
+ gap: T11.sp6xl
6190
+ },
6191
+ children: [
6192
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex items-center min-w-0", style: { flex: 1, gap: T11.spMd }, children: [
6193
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
6194
+ ProfileAvatar,
6195
+ {
6196
+ name: workspace.name,
6197
+ profileImage: workspace.imageUrl,
6198
+ size: 28,
6199
+ borderRadius: "var(--radius-lg)"
6200
+ }
6201
+ ),
6202
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex flex-col min-w-0", children: [
6203
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
6204
+ "span",
6205
+ {
6206
+ className: "truncate",
6207
+ style: {
6208
+ fontFamily: T11.font,
6209
+ fontSize: T11.fsSm,
6210
+ fontWeight: 500,
6211
+ lineHeight: T11.lhSm,
6212
+ color: T11.primary
6213
+ },
6214
+ children: workspace.name
6215
+ }
6216
+ ),
6217
+ workspace.ownerName && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
6218
+ "span",
6219
+ {
6220
+ className: "truncate",
6221
+ style: {
6222
+ fontFamily: T11.font,
6223
+ fontSize: T11.fsXs,
6224
+ fontWeight: 400,
6225
+ lineHeight: T11.lhXs,
6226
+ color: T11.muted
6227
+ },
6228
+ children: [
6229
+ "Created by ",
6230
+ workspace.ownerName
6231
+ ]
6232
+ }
6233
+ )
6234
+ ] })
6235
+ ] }),
6236
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
6237
+ import_ui8.ScButton,
6238
+ {
6239
+ text: joining ? "Joining\u2026" : "Join",
6240
+ variant: "secondary",
6241
+ size: "sm",
6242
+ state: joining ? "disabled" : "default",
6243
+ onClick: joining ? void 0 : onJoin
6244
+ }
6245
+ )
6246
+ ]
6247
+ }
6248
+ );
6249
+ }
6177
6250
  function JoinRequestRow({
6178
6251
  request,
6179
6252
  onApprove,
@@ -6293,10 +6366,13 @@ function OrganizationContent({
6293
6366
  embedded = false,
6294
6367
  view = "people"
6295
6368
  } = {}) {
6296
- const { organization, toast } = useSettingsAdapters();
6369
+ const { organization, workspace: workspaceAdapter, toast } = useSettingsAdapters();
6297
6370
  const current = organization.current;
6298
6371
  const [members, setMembers] = (0, import_react12.useState)([]);
6299
6372
  const [workspaces, setWorkspaces] = (0, import_react12.useState)([]);
6373
+ const canJoinShared = current?.role === "member" && !!organization.fetchJoinableWorkspaces && !!organization.joinWorkspaces;
6374
+ const [joinable, setJoinable] = (0, import_react12.useState)([]);
6375
+ const [joiningId, setJoiningId] = (0, import_react12.useState)(null);
6300
6376
  const [joinRequests, setJoinRequests] = (0, import_react12.useState)([]);
6301
6377
  const [highestRole, setHighestRole] = (0, import_react12.useState)("guest");
6302
6378
  const [searchQuery, setSearchQuery] = (0, import_react12.useState)("");
@@ -6306,12 +6382,20 @@ function OrganizationContent({
6306
6382
  if (!organization.current) return;
6307
6383
  setLoadingData(true);
6308
6384
  try {
6309
- const [membersRes, workspacesRes, joinRequestsRes, highestRoleRes] = await Promise.all([
6385
+ const [
6386
+ membersRes,
6387
+ workspacesRes,
6388
+ joinRequestsRes,
6389
+ highestRoleRes,
6390
+ joinableRes
6391
+ ] = await Promise.all([
6310
6392
  organization.fetchMembers().catch(() => null),
6311
6393
  organization.fetchWorkspaces().catch(() => null),
6312
6394
  organization.fetchJoinRequests().catch(() => null),
6313
- organization.getHighestRole?.().catch(() => null) ?? Promise.resolve(null)
6395
+ organization.getHighestRole?.().catch(() => null) ?? Promise.resolve(null),
6396
+ canJoinShared ? organization.fetchJoinableWorkspaces().catch(() => null) : Promise.resolve(null)
6314
6397
  ]);
6398
+ if (joinableRes) setJoinable(joinableRes);
6315
6399
  if (highestRoleRes?.role) setHighestRole(highestRoleRes.role);
6316
6400
  if (membersRes) setMembers(membersRes.filter((m) => m?.user));
6317
6401
  if (workspacesRes) setWorkspaces(workspacesRes);
@@ -6320,10 +6404,30 @@ function OrganizationContent({
6320
6404
  } finally {
6321
6405
  setLoadingData(false);
6322
6406
  }
6323
- }, [organization]);
6407
+ }, [organization, canJoinShared]);
6324
6408
  (0, import_react12.useEffect)(() => {
6325
6409
  fetchData();
6326
6410
  }, [fetchData]);
6411
+ const handleJoinWorkspace = async (target) => {
6412
+ if (!organization.joinWorkspaces) return;
6413
+ setJoiningId(target._id);
6414
+ try {
6415
+ const joined = await organization.joinWorkspaces([target._id]);
6416
+ if (!joined.includes(target._id)) {
6417
+ toast.error(`Couldn't join ${target.name}. Try again.`);
6418
+ return;
6419
+ }
6420
+ toast.success(`Joined ${target.name}`);
6421
+ await workspaceAdapter.refresh?.().catch(() => void 0);
6422
+ await fetchData();
6423
+ } catch (err) {
6424
+ toast.error(
6425
+ err instanceof Error ? err.message : `Couldn't join ${target.name}`
6426
+ );
6427
+ } finally {
6428
+ setJoiningId(null);
6429
+ }
6430
+ };
6327
6431
  const [manageModalOpen, setManageModalOpen] = (0, import_react12.useState)(false);
6328
6432
  const handleUpdateOrganization = async (name, imageFile) => {
6329
6433
  if (!current) return false;
@@ -6552,6 +6656,23 @@ function OrganizationContent({
6552
6656
  children: workspaces.map((ws) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(WorkspaceRow, { workspace: ws }, ws._id))
6553
6657
  }
6554
6658
  ),
6659
+ canJoinShared && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
6660
+ Section,
6661
+ {
6662
+ title: "Shared workspaces you can join",
6663
+ empty: joinable.length === 0,
6664
+ emptyText: "You're in every shared workspace in this organization",
6665
+ children: joinable.map((ws) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
6666
+ JoinableWorkspaceRow,
6667
+ {
6668
+ workspace: ws,
6669
+ joining: joiningId === ws._id,
6670
+ onJoin: () => void handleJoinWorkspace(ws)
6671
+ },
6672
+ ws._id
6673
+ ))
6674
+ }
6675
+ ),
6555
6676
  (isOrgAdmin || joinRequests.length > 0) && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
6556
6677
  Section,
6557
6678
  {
package/dist/index.mjs CHANGED
@@ -6151,6 +6151,79 @@ function WorkspaceRow({ workspace }) {
6151
6151
  }
6152
6152
  );
6153
6153
  }
6154
+ function JoinableWorkspaceRow({
6155
+ workspace,
6156
+ joining,
6157
+ onJoin
6158
+ }) {
6159
+ return /* @__PURE__ */ jsxs14(
6160
+ "div",
6161
+ {
6162
+ className: "flex items-center self-stretch shrink-0",
6163
+ style: {
6164
+ borderBottom: `1px solid ${T11.borderSubtle}`,
6165
+ padding: `${T11.spXl} ${T11.sp3xl}`,
6166
+ gap: T11.sp6xl
6167
+ },
6168
+ children: [
6169
+ /* @__PURE__ */ jsxs14("div", { className: "flex items-center min-w-0", style: { flex: 1, gap: T11.spMd }, children: [
6170
+ /* @__PURE__ */ jsx17(
6171
+ ProfileAvatar,
6172
+ {
6173
+ name: workspace.name,
6174
+ profileImage: workspace.imageUrl,
6175
+ size: 28,
6176
+ borderRadius: "var(--radius-lg)"
6177
+ }
6178
+ ),
6179
+ /* @__PURE__ */ jsxs14("div", { className: "flex flex-col min-w-0", children: [
6180
+ /* @__PURE__ */ jsx17(
6181
+ "span",
6182
+ {
6183
+ className: "truncate",
6184
+ style: {
6185
+ fontFamily: T11.font,
6186
+ fontSize: T11.fsSm,
6187
+ fontWeight: 500,
6188
+ lineHeight: T11.lhSm,
6189
+ color: T11.primary
6190
+ },
6191
+ children: workspace.name
6192
+ }
6193
+ ),
6194
+ workspace.ownerName && /* @__PURE__ */ jsxs14(
6195
+ "span",
6196
+ {
6197
+ className: "truncate",
6198
+ style: {
6199
+ fontFamily: T11.font,
6200
+ fontSize: T11.fsXs,
6201
+ fontWeight: 400,
6202
+ lineHeight: T11.lhXs,
6203
+ color: T11.muted
6204
+ },
6205
+ children: [
6206
+ "Created by ",
6207
+ workspace.ownerName
6208
+ ]
6209
+ }
6210
+ )
6211
+ ] })
6212
+ ] }),
6213
+ /* @__PURE__ */ jsx17(
6214
+ ScButton5,
6215
+ {
6216
+ text: joining ? "Joining\u2026" : "Join",
6217
+ variant: "secondary",
6218
+ size: "sm",
6219
+ state: joining ? "disabled" : "default",
6220
+ onClick: joining ? void 0 : onJoin
6221
+ }
6222
+ )
6223
+ ]
6224
+ }
6225
+ );
6226
+ }
6154
6227
  function JoinRequestRow({
6155
6228
  request,
6156
6229
  onApprove,
@@ -6270,10 +6343,13 @@ function OrganizationContent({
6270
6343
  embedded = false,
6271
6344
  view = "people"
6272
6345
  } = {}) {
6273
- const { organization, toast } = useSettingsAdapters();
6346
+ const { organization, workspace: workspaceAdapter, toast } = useSettingsAdapters();
6274
6347
  const current = organization.current;
6275
6348
  const [members, setMembers] = useState10([]);
6276
6349
  const [workspaces, setWorkspaces] = useState10([]);
6350
+ const canJoinShared = current?.role === "member" && !!organization.fetchJoinableWorkspaces && !!organization.joinWorkspaces;
6351
+ const [joinable, setJoinable] = useState10([]);
6352
+ const [joiningId, setJoiningId] = useState10(null);
6277
6353
  const [joinRequests, setJoinRequests] = useState10([]);
6278
6354
  const [highestRole, setHighestRole] = useState10("guest");
6279
6355
  const [searchQuery, setSearchQuery] = useState10("");
@@ -6283,12 +6359,20 @@ function OrganizationContent({
6283
6359
  if (!organization.current) return;
6284
6360
  setLoadingData(true);
6285
6361
  try {
6286
- const [membersRes, workspacesRes, joinRequestsRes, highestRoleRes] = await Promise.all([
6362
+ const [
6363
+ membersRes,
6364
+ workspacesRes,
6365
+ joinRequestsRes,
6366
+ highestRoleRes,
6367
+ joinableRes
6368
+ ] = await Promise.all([
6287
6369
  organization.fetchMembers().catch(() => null),
6288
6370
  organization.fetchWorkspaces().catch(() => null),
6289
6371
  organization.fetchJoinRequests().catch(() => null),
6290
- organization.getHighestRole?.().catch(() => null) ?? Promise.resolve(null)
6372
+ organization.getHighestRole?.().catch(() => null) ?? Promise.resolve(null),
6373
+ canJoinShared ? organization.fetchJoinableWorkspaces().catch(() => null) : Promise.resolve(null)
6291
6374
  ]);
6375
+ if (joinableRes) setJoinable(joinableRes);
6292
6376
  if (highestRoleRes?.role) setHighestRole(highestRoleRes.role);
6293
6377
  if (membersRes) setMembers(membersRes.filter((m) => m?.user));
6294
6378
  if (workspacesRes) setWorkspaces(workspacesRes);
@@ -6297,10 +6381,30 @@ function OrganizationContent({
6297
6381
  } finally {
6298
6382
  setLoadingData(false);
6299
6383
  }
6300
- }, [organization]);
6384
+ }, [organization, canJoinShared]);
6301
6385
  useEffect10(() => {
6302
6386
  fetchData();
6303
6387
  }, [fetchData]);
6388
+ const handleJoinWorkspace = async (target) => {
6389
+ if (!organization.joinWorkspaces) return;
6390
+ setJoiningId(target._id);
6391
+ try {
6392
+ const joined = await organization.joinWorkspaces([target._id]);
6393
+ if (!joined.includes(target._id)) {
6394
+ toast.error(`Couldn't join ${target.name}. Try again.`);
6395
+ return;
6396
+ }
6397
+ toast.success(`Joined ${target.name}`);
6398
+ await workspaceAdapter.refresh?.().catch(() => void 0);
6399
+ await fetchData();
6400
+ } catch (err) {
6401
+ toast.error(
6402
+ err instanceof Error ? err.message : `Couldn't join ${target.name}`
6403
+ );
6404
+ } finally {
6405
+ setJoiningId(null);
6406
+ }
6407
+ };
6304
6408
  const [manageModalOpen, setManageModalOpen] = useState10(false);
6305
6409
  const handleUpdateOrganization = async (name, imageFile) => {
6306
6410
  if (!current) return false;
@@ -6529,6 +6633,23 @@ function OrganizationContent({
6529
6633
  children: workspaces.map((ws) => /* @__PURE__ */ jsx17(WorkspaceRow, { workspace: ws }, ws._id))
6530
6634
  }
6531
6635
  ),
6636
+ canJoinShared && /* @__PURE__ */ jsx17(
6637
+ Section,
6638
+ {
6639
+ title: "Shared workspaces you can join",
6640
+ empty: joinable.length === 0,
6641
+ emptyText: "You're in every shared workspace in this organization",
6642
+ children: joinable.map((ws) => /* @__PURE__ */ jsx17(
6643
+ JoinableWorkspaceRow,
6644
+ {
6645
+ workspace: ws,
6646
+ joining: joiningId === ws._id,
6647
+ onJoin: () => void handleJoinWorkspace(ws)
6648
+ },
6649
+ ws._id
6650
+ ))
6651
+ }
6652
+ ),
6532
6653
  (isOrgAdmin || joinRequests.length > 0) && /* @__PURE__ */ jsx17(
6533
6654
  Section,
6534
6655
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@streamoid/settings",
3
- "version": "0.7.4",
3
+ "version": "0.7.5",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.mjs",
6
6
  "types": "./dist/index.d.ts",