@streamoid/settings 0.7.0 → 0.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -179,6 +179,9 @@ interface SettingsWorkspaceListItem {
179
179
  plan?: string;
180
180
  /** Optional owner email shown in the workspace list. */
181
181
  ownerEmail?: string;
182
+ /** The organization this workspace belongs to, if any. My workspaces groups
183
+ * the list under each organization (named from `organization.list()`). */
184
+ organizationId?: string;
182
185
  }
183
186
  interface SettingsWorkspaceAdapter {
184
187
  /** Same authenticated transport used by the sidebar owner lookup. */
@@ -227,6 +230,16 @@ interface SettingsWorkspaceAdapter {
227
230
  role?: string;
228
231
  } | null;
229
232
  }>;
233
+ /**
234
+ * Optional: plan labels ("Free", "Pro", …) for the given workspaces, keyed by
235
+ * id. My workspaces lists workspaces a page at a time and asks only for the
236
+ * page on screen, so `list()` doesn't have to look up every workspace's plan
237
+ * before anything renders. Leave a workspace out of the result when its
238
+ * lookup failed; it is shown without a plan.
239
+ *
240
+ * When omitted, the plan on each `list()` item is used as before.
241
+ */
242
+ fetchPlans?: (workspaceIds: string[]) => Promise<Record<string, string>>;
230
243
  /**
231
244
  * Optional: host-controlled refresh after the package mutates workspace
232
245
  * state. If provided, the package will call this instead of (or in addition
@@ -928,13 +941,38 @@ declare function ProfileTab(): react.JSX.Element;
928
941
  * workspace you are not currently inside — the current one has its own
929
942
  * General page.
930
943
  */
931
- declare function WorkspaceListTab({ workspaces, loading, onCreateClick: _onCreateClick, onEditClick, onSwitchClick, onLeaveClick, }: {
944
+ /** Workspaces shown per page in My workspaces. */
945
+ declare const WORKSPACE_LIST_PAGE_SIZE = 10;
946
+ /** An organization as My workspaces needs it to group the list. */
947
+ interface WorkspaceListOrganization {
948
+ _id: string;
949
+ name: string;
950
+ role?: string;
951
+ }
952
+ interface WorkspaceListGroup {
953
+ key: string;
954
+ label: string;
955
+ workspaces: WorkspaceInfo[];
956
+ }
957
+ /**
958
+ * The same grouping as CXO's workspace switcher: the viewer's own
959
+ * organizations first, then those they are only a guest of (labelled so), and
960
+ * workspaces in no organization — or in one the viewer isn't a member of —
961
+ * last. Groups keep the order the organizations came in.
962
+ */
963
+ declare function groupWorkspaceList(workspaces: WorkspaceInfo[], organizations?: WorkspaceListOrganization[]): WorkspaceListGroup[];
964
+ declare function WorkspaceListTab({ workspaces, loading, onCreateClick: _onCreateClick, onEditClick, onSwitchClick, onLeaveClick, fetchPlans, organizations, pageSize, }: {
932
965
  workspaces: WorkspaceInfo[];
933
966
  loading: boolean;
934
967
  onCreateClick: () => void;
935
968
  onEditClick: (ws: WorkspaceInfo) => void;
936
969
  onSwitchClick: (ws: WorkspaceInfo) => void;
937
970
  onLeaveClick: (ws: WorkspaceInfo) => void;
971
+ /** See SettingsWorkspaceAdapter.fetchPlans. */
972
+ fetchPlans?: (workspaceIds: string[]) => Promise<Record<string, string>>;
973
+ /** The viewer's organizations, to group the list under. */
974
+ organizations?: WorkspaceListOrganization[];
975
+ pageSize?: number;
938
976
  }): react.JSX.Element;
939
977
  /**
940
978
  * @deprecated Renamed to `WorkspaceListTab` in 0.4.0 — the tab is a workspace
@@ -1399,4 +1437,4 @@ declare function SettingsAdaptersProvider({ adapters, children, }: {
1399
1437
  */
1400
1438
  declare function useSettingsAdapters(): SettingsAdapters;
1401
1439
 
1402
- 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, type WorkspaceData, WorkspaceGeneralTab, type WorkspaceGeneralTabProps, type WorkspaceInvite, WorkspaceListTab, type WorkspaceMember, WorkspaceModal, type WorkspaceOrganization, type WorkspaceOrganizationRequest, WorkspacePicker, type WorkspacePickerItem, type WorkspacePickerProps, WorkspaceTab, type WorkspaceUsageResponse, countLabel, loadWorkspaceOrganization, resolveSettingsTabFromPath, useSettingsAdapters, useWorkspaceOrganization, userLanguageLabel };
1440
+ 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 };
package/dist/index.d.ts CHANGED
@@ -179,6 +179,9 @@ interface SettingsWorkspaceListItem {
179
179
  plan?: string;
180
180
  /** Optional owner email shown in the workspace list. */
181
181
  ownerEmail?: string;
182
+ /** The organization this workspace belongs to, if any. My workspaces groups
183
+ * the list under each organization (named from `organization.list()`). */
184
+ organizationId?: string;
182
185
  }
183
186
  interface SettingsWorkspaceAdapter {
184
187
  /** Same authenticated transport used by the sidebar owner lookup. */
@@ -227,6 +230,16 @@ interface SettingsWorkspaceAdapter {
227
230
  role?: string;
228
231
  } | null;
229
232
  }>;
233
+ /**
234
+ * Optional: plan labels ("Free", "Pro", …) for the given workspaces, keyed by
235
+ * id. My workspaces lists workspaces a page at a time and asks only for the
236
+ * page on screen, so `list()` doesn't have to look up every workspace's plan
237
+ * before anything renders. Leave a workspace out of the result when its
238
+ * lookup failed; it is shown without a plan.
239
+ *
240
+ * When omitted, the plan on each `list()` item is used as before.
241
+ */
242
+ fetchPlans?: (workspaceIds: string[]) => Promise<Record<string, string>>;
230
243
  /**
231
244
  * Optional: host-controlled refresh after the package mutates workspace
232
245
  * state. If provided, the package will call this instead of (or in addition
@@ -928,13 +941,38 @@ declare function ProfileTab(): react.JSX.Element;
928
941
  * workspace you are not currently inside — the current one has its own
929
942
  * General page.
930
943
  */
931
- declare function WorkspaceListTab({ workspaces, loading, onCreateClick: _onCreateClick, onEditClick, onSwitchClick, onLeaveClick, }: {
944
+ /** Workspaces shown per page in My workspaces. */
945
+ declare const WORKSPACE_LIST_PAGE_SIZE = 10;
946
+ /** An organization as My workspaces needs it to group the list. */
947
+ interface WorkspaceListOrganization {
948
+ _id: string;
949
+ name: string;
950
+ role?: string;
951
+ }
952
+ interface WorkspaceListGroup {
953
+ key: string;
954
+ label: string;
955
+ workspaces: WorkspaceInfo[];
956
+ }
957
+ /**
958
+ * The same grouping as CXO's workspace switcher: the viewer's own
959
+ * organizations first, then those they are only a guest of (labelled so), and
960
+ * workspaces in no organization — or in one the viewer isn't a member of —
961
+ * last. Groups keep the order the organizations came in.
962
+ */
963
+ declare function groupWorkspaceList(workspaces: WorkspaceInfo[], organizations?: WorkspaceListOrganization[]): WorkspaceListGroup[];
964
+ declare function WorkspaceListTab({ workspaces, loading, onCreateClick: _onCreateClick, onEditClick, onSwitchClick, onLeaveClick, fetchPlans, organizations, pageSize, }: {
932
965
  workspaces: WorkspaceInfo[];
933
966
  loading: boolean;
934
967
  onCreateClick: () => void;
935
968
  onEditClick: (ws: WorkspaceInfo) => void;
936
969
  onSwitchClick: (ws: WorkspaceInfo) => void;
937
970
  onLeaveClick: (ws: WorkspaceInfo) => void;
971
+ /** See SettingsWorkspaceAdapter.fetchPlans. */
972
+ fetchPlans?: (workspaceIds: string[]) => Promise<Record<string, string>>;
973
+ /** The viewer's organizations, to group the list under. */
974
+ organizations?: WorkspaceListOrganization[];
975
+ pageSize?: number;
938
976
  }): react.JSX.Element;
939
977
  /**
940
978
  * @deprecated Renamed to `WorkspaceListTab` in 0.4.0 — the tab is a workspace
@@ -1399,4 +1437,4 @@ declare function SettingsAdaptersProvider({ adapters, children, }: {
1399
1437
  */
1400
1438
  declare function useSettingsAdapters(): SettingsAdapters;
1401
1439
 
1402
- 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, type WorkspaceData, WorkspaceGeneralTab, type WorkspaceGeneralTabProps, type WorkspaceInvite, WorkspaceListTab, type WorkspaceMember, WorkspaceModal, type WorkspaceOrganization, type WorkspaceOrganizationRequest, WorkspacePicker, type WorkspacePickerItem, type WorkspacePickerProps, WorkspaceTab, type WorkspaceUsageResponse, countLabel, loadWorkspaceOrganization, resolveSettingsTabFromPath, useSettingsAdapters, useWorkspaceOrganization, userLanguageLabel };
1440
+ 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 };
package/dist/index.js CHANGED
@@ -51,12 +51,14 @@ __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,
57
58
  WorkspacePicker: () => WorkspacePicker,
58
59
  WorkspaceTab: () => WorkspaceTab,
59
60
  countLabel: () => countLabel,
61
+ groupWorkspaceList: () => groupWorkspaceList,
60
62
  loadWorkspaceOrganization: () => loadWorkspaceOrganization,
61
63
  resolveSettingsTabFromPath: () => resolveSettingsTabFromPath,
62
64
  useSettingsAdapters: () => useSettingsAdapters,
@@ -10896,16 +10898,91 @@ function ProfileTab() {
10896
10898
  }
10897
10899
  );
10898
10900
  }
10901
+ var WORKSPACE_LIST_PAGE_SIZE = 10;
10902
+ function groupWorkspaceList(workspaces, organizations = []) {
10903
+ const ordered = [
10904
+ ...organizations.filter((org) => org.role !== "guest"),
10905
+ ...organizations.filter((org) => org.role === "guest")
10906
+ ];
10907
+ const groups = [];
10908
+ for (const org of ordered) {
10909
+ const inOrg = workspaces.filter((ws) => ws.organizationId === org._id);
10910
+ if (inOrg.length) {
10911
+ groups.push({
10912
+ key: org._id,
10913
+ label: org.role === "guest" ? `${org.name} \xB7 Guest` : org.name,
10914
+ workspaces: inOrg
10915
+ });
10916
+ }
10917
+ }
10918
+ const known = new Set(organizations.map((org) => org._id));
10919
+ const ungrouped = workspaces.filter(
10920
+ (ws) => !ws.organizationId || !known.has(ws.organizationId)
10921
+ );
10922
+ if (ungrouped.length) {
10923
+ groups.push({
10924
+ key: "__no_org__",
10925
+ // "No organization" only means something next to named groups.
10926
+ label: groups.length ? "No organization" : "Other Workspaces",
10927
+ workspaces: ungrouped
10928
+ });
10929
+ }
10930
+ return groups;
10931
+ }
10899
10932
  function WorkspaceListTab({
10900
10933
  workspaces,
10901
10934
  loading,
10902
10935
  onCreateClick: _onCreateClick,
10903
10936
  onEditClick,
10904
10937
  onSwitchClick,
10905
- onLeaveClick
10938
+ onLeaveClick,
10939
+ fetchPlans,
10940
+ organizations = [],
10941
+ pageSize = WORKSPACE_LIST_PAGE_SIZE
10906
10942
  }) {
10907
10943
  const currentWorkspace = workspaces.find((ws) => ws.isCurrent);
10908
- const otherWorkspaces = workspaces.filter((ws) => !ws.isCurrent);
10944
+ const groups = groupWorkspaceList(
10945
+ workspaces.filter((ws) => !ws.isCurrent),
10946
+ organizations
10947
+ );
10948
+ const rows = groups.flatMap(
10949
+ (group) => group.workspaces.map((ws) => ({ ws, group }))
10950
+ );
10951
+ const otherWorkspaces = rows.map((row) => row.ws);
10952
+ const currentOrganization = organizations.find(
10953
+ (org) => org._id && org._id === currentWorkspace?.organizationId
10954
+ );
10955
+ const pageCount = Math.max(1, Math.ceil(otherWorkspaces.length / pageSize));
10956
+ const [page, setPage] = (0, import_react17.useState)(0);
10957
+ const safePage = Math.min(page, pageCount - 1);
10958
+ const pageStart = safePage * pageSize;
10959
+ const pageRows = rows.slice(pageStart, pageStart + pageSize);
10960
+ const pageWorkspaces = pageRows.map((row) => row.ws);
10961
+ const [plans, setPlans] = (0, import_react17.useState)({});
10962
+ const requestedPlans = (0, import_react17.useRef)(/* @__PURE__ */ new Set());
10963
+ const visibleIds = [
10964
+ ...currentWorkspace ? [currentWorkspace._id] : [],
10965
+ ...pageWorkspaces.map((ws) => ws._id)
10966
+ ];
10967
+ const visibleKey = visibleIds.join(",");
10968
+ const mounted = (0, import_react17.useRef)(true);
10969
+ (0, import_react17.useEffect)(() => {
10970
+ mounted.current = true;
10971
+ return () => {
10972
+ mounted.current = false;
10973
+ };
10974
+ }, []);
10975
+ (0, import_react17.useEffect)(() => {
10976
+ if (!fetchPlans || loading) return;
10977
+ const missing = visibleKey.split(",").filter((id) => id && !requestedPlans.current.has(id));
10978
+ if (!missing.length) return;
10979
+ missing.forEach((id) => requestedPlans.current.add(id));
10980
+ fetchPlans(missing).then((found) => {
10981
+ if (mounted.current) setPlans((prev) => ({ ...prev, ...found }));
10982
+ }).catch(() => {
10983
+ });
10984
+ }, [fetchPlans, loading, visibleKey]);
10985
+ const planOf = (ws) => fetchPlans ? plans[ws._id] ?? "" : ws.plan ?? "";
10909
10986
  return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
10910
10987
  "div",
10911
10988
  {
@@ -10942,7 +11019,7 @@ function WorkspaceListTab({
10942
11019
  className: "flex flex-col items-start shrink-0 w-full",
10943
11020
  style: { gap: 16, padding: "var(--spacing-md) 0" },
10944
11021
  children: [
10945
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
11022
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
10946
11023
  "p",
10947
11024
  {
10948
11025
  className: "w-full overflow-hidden text-ellipsis whitespace-nowrap",
@@ -10953,7 +11030,10 @@ function WorkspaceListTab({
10953
11030
  fontWeight: 400,
10954
11031
  lineHeight: "var(--line-height-line-height-md)"
10955
11032
  },
10956
- children: "Current Workspace"
11033
+ children: [
11034
+ "Current Workspace",
11035
+ currentOrganization ? ` \xB7 ${currentOrganization.name}${currentOrganization.role === "guest" ? " (guest)" : ""}` : ""
11036
+ ]
10957
11037
  }
10958
11038
  ),
10959
11039
  /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
@@ -10963,7 +11043,7 @@ function WorkspaceListTab({
10963
11043
  initials: currentWorkspace.initials,
10964
11044
  imageUrl: currentWorkspace.imageUrl,
10965
11045
  role: currentWorkspace.role,
10966
- plan: currentWorkspace.plan,
11046
+ plan: planOf(currentWorkspace),
10967
11047
  ownerId: currentWorkspace.ownerEmail,
10968
11048
  type: "currentWS",
10969
11049
  onSettings: () => onEditClick(currentWorkspace),
@@ -10990,40 +11070,92 @@ function WorkspaceListTab({
10990
11070
  style: { gap: 16, overflowY: "auto" },
10991
11071
  children: [
10992
11072
  /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
10993
- "p",
11073
+ "div",
10994
11074
  {
10995
- className: "w-full overflow-hidden text-ellipsis whitespace-nowrap shrink-0",
10996
- style: {
10997
- color: "var(--alias-text---icons-muted)",
10998
- fontFamily: "var(--font-family-font-family-body)",
10999
- fontSize: "var(--font-size-font-size-md)",
11000
- fontWeight: 400,
11001
- lineHeight: "var(--line-height-line-height-md)"
11002
- },
11003
- children: "Other Workspaces"
11075
+ className: "flex flex-col items-start w-full",
11076
+ style: { gap: 16 },
11077
+ children: pageRows.map(({ ws, group }, index) => /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_react17.Fragment, { children: [
11078
+ (index === 0 || pageRows[index - 1].group.key !== group.key) && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
11079
+ "p",
11080
+ {
11081
+ className: "w-full overflow-hidden text-ellipsis whitespace-nowrap shrink-0",
11082
+ style: {
11083
+ color: "var(--alias-text---icons-muted)",
11084
+ fontFamily: "var(--font-family-font-family-body)",
11085
+ fontSize: "var(--font-size-font-size-md)",
11086
+ fontWeight: 400,
11087
+ lineHeight: "var(--line-height-line-height-md)",
11088
+ marginTop: index === 0 ? 0 : 8
11089
+ },
11090
+ children: group.label
11091
+ }
11092
+ ),
11093
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
11094
+ import_ui14.ScWorkspaceSwitchCard,
11095
+ {
11096
+ wsName: ws.name,
11097
+ initials: ws.initials,
11098
+ imageUrl: ws.imageUrl,
11099
+ role: ws.role,
11100
+ plan: planOf(ws),
11101
+ ownerId: ws.ownerEmail,
11102
+ type: "otherWS",
11103
+ onSwitch: () => onSwitchClick(ws),
11104
+ onSettings: () => onEditClick(ws),
11105
+ onLeave: () => onLeaveClick(ws)
11106
+ }
11107
+ )
11108
+ ] }, ws._id))
11004
11109
  }
11005
11110
  ),
11006
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
11111
+ pageCount > 1 && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
11007
11112
  "div",
11008
11113
  {
11009
- className: "flex flex-col items-start w-full",
11010
- style: { gap: 16 },
11011
- children: otherWorkspaces.map((ws) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
11012
- import_ui14.ScWorkspaceSwitchCard,
11013
- {
11014
- wsName: ws.name,
11015
- initials: ws.initials,
11016
- imageUrl: ws.imageUrl,
11017
- role: ws.role,
11018
- plan: ws.plan,
11019
- ownerId: ws.ownerEmail,
11020
- type: "otherWS",
11021
- onSwitch: () => onSwitchClick(ws),
11022
- onSettings: () => onEditClick(ws),
11023
- onLeave: () => onLeaveClick(ws)
11024
- },
11025
- ws._id
11026
- ))
11114
+ className: "flex items-center justify-between shrink-0 w-full",
11115
+ style: { gap: "var(--spacing-md)" },
11116
+ children: [
11117
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
11118
+ "span",
11119
+ {
11120
+ style: {
11121
+ color: "var(--alias-text---icons-muted)",
11122
+ fontFamily: "var(--font-family-font-family-body)",
11123
+ fontSize: "var(--font-size-font-size-sm)",
11124
+ lineHeight: "var(--line-height-line-height-sm)"
11125
+ },
11126
+ children: [
11127
+ pageStart + 1,
11128
+ "\u2013",
11129
+ pageStart + pageWorkspaces.length,
11130
+ " of",
11131
+ " ",
11132
+ otherWorkspaces.length
11133
+ ]
11134
+ }
11135
+ ),
11136
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex items-center", style: { gap: "var(--spacing-md)" }, children: [
11137
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
11138
+ import_ui13.ScButton,
11139
+ {
11140
+ text: "Previous",
11141
+ variant: "tertiary",
11142
+ size: "sm",
11143
+ state: safePage === 0 ? "disabled" : "default",
11144
+ onClick: safePage === 0 ? void 0 : () => setPage(safePage - 1)
11145
+ }
11146
+ ),
11147
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
11148
+ import_ui13.ScButton,
11149
+ {
11150
+ text: "Next",
11151
+ variant: "tertiary",
11152
+ size: "sm",
11153
+ state: safePage >= pageCount - 1 ? "disabled" : "default",
11154
+ onClick: safePage >= pageCount - 1 ? void 0 : () => setPage(safePage + 1)
11155
+ }
11156
+ )
11157
+ ] })
11158
+ ]
11027
11159
  }
11028
11160
  )
11029
11161
  ]
@@ -11171,6 +11303,28 @@ function SettingsContentInner({
11171
11303
  (0, import_react17.useEffect)(() => {
11172
11304
  void refreshWorkspaceList();
11173
11305
  }, [refreshWorkspaceList]);
11306
+ const [listOrganizations, setListOrganizations] = (0, import_react17.useState)([]);
11307
+ (0, import_react17.useEffect)(() => {
11308
+ if (activeTab !== "workspaceList" || typeof organization?.list !== "function") {
11309
+ return;
11310
+ }
11311
+ let cancelled = false;
11312
+ organization.list().then((orgs) => {
11313
+ if (!cancelled) {
11314
+ setListOrganizations(
11315
+ (orgs ?? []).map((org) => ({
11316
+ _id: org._id,
11317
+ name: org.name,
11318
+ role: org.role
11319
+ }))
11320
+ );
11321
+ }
11322
+ }).catch(() => {
11323
+ });
11324
+ return () => {
11325
+ cancelled = true;
11326
+ };
11327
+ }, [activeTab, organization]);
11174
11328
  const switchWorkspace = (0, import_react17.useCallback)(
11175
11329
  async (id) => {
11176
11330
  await workspace.switch(id);
@@ -11818,6 +11972,8 @@ function SettingsContentInner({
11818
11972
  {
11819
11973
  workspaces: displayWorkspaces,
11820
11974
  loading: workspaceListLoading && workspaceList.length === 0,
11975
+ fetchPlans: workspace.fetchPlans,
11976
+ organizations: listOrganizations,
11821
11977
  onCreateClick: handleCreateClick,
11822
11978
  onEditClick: handleEditClick,
11823
11979
  onSwitchClick: async (ws) => {
package/dist/index.mjs CHANGED
@@ -163,6 +163,7 @@ function useWorkspaceOrganization({
163
163
 
164
164
  // src/settings-content.tsx
165
165
  import {
166
+ Fragment as Fragment11,
166
167
  useState as useState15,
167
168
  useEffect as useEffect13,
168
169
  useRef as useRef7,
@@ -10097,7 +10098,7 @@ function TokenTable({ tokens, deletingId, onRevoke, onDelete }) {
10097
10098
  }
10098
10099
 
10099
10100
  // src/settings-content.tsx
10100
- import { Fragment as Fragment11, jsx as jsx22, jsxs as jsxs19 } from "react/jsx-runtime";
10101
+ import { Fragment as Fragment12, jsx as jsx22, jsxs as jsxs19 } from "react/jsx-runtime";
10101
10102
  function deriveInitials(name) {
10102
10103
  return name.split(/\s+/).slice(0, 2).map((part) => part[0]?.toUpperCase() ?? "").join("") || "WS";
10103
10104
  }
@@ -10205,14 +10206,14 @@ function SettingsNav({
10205
10206
  /* @__PURE__ */ jsx22("div", { title: workspaceName ?? void 0, style: { padding: "4px 12px", fontSize: 11, fontWeight: 500, color: MUTED_COLOR2, textTransform: "uppercase", letterSpacing: "0.08em" }, children: "Workspace" }),
10206
10207
  item("workspace", (color) => /* @__PURE__ */ jsx22(SiconSettings2, { className: "w-5 h-5", color })),
10207
10208
  item("workspaceMembers", (color) => /* @__PURE__ */ jsx22(SiconTeam, { className: "w-5 h-5", color })),
10208
- isWorkspaceAdmin && /* @__PURE__ */ jsxs19(Fragment11, { children: [
10209
+ isWorkspaceAdmin && /* @__PURE__ */ jsxs19(Fragment12, { children: [
10209
10210
  item("billing", (color) => /* @__PURE__ */ jsx22(SiconBilling, { className: "w-5 h-5", color })),
10210
10211
  item("apikey", (color) => /* @__PURE__ */ jsx22(SiconKey_default, { className: "w-5 h-5", color }))
10211
10212
  ] }),
10212
10213
  !isWorkspaceAdmin && /* @__PURE__ */ jsx22("p", { style: { margin: "4px 12px", fontSize: 12, lineHeight: "18px", color: MUTED_COLOR2 }, children: "Contact your workspace admin for credit top-ups and billing history." })
10213
10214
  ] }),
10214
10215
  /* @__PURE__ */ jsx22(ScHDivider, {}),
10215
- /* @__PURE__ */ jsx22("div", { className: "flex flex-col w-full", style: { gap: "var(--spacing-md)" }, children: hasOrganization ? /* @__PURE__ */ jsxs19(Fragment11, { children: [
10216
+ /* @__PURE__ */ jsx22("div", { className: "flex flex-col w-full", style: { gap: "var(--spacing-md)" }, children: hasOrganization ? /* @__PURE__ */ jsxs19(Fragment12, { children: [
10216
10217
  /* @__PURE__ */ jsx22("div", { style: { padding: "4px 12px", fontSize: 11, fontWeight: 500, color: MUTED_COLOR2, textTransform: "uppercase", letterSpacing: "0.08em" }, children: "Organization" }),
10217
10218
  item("organization", (color) => /* @__PURE__ */ jsx22(SiconTeam, { className: "w-5 h-5", color })),
10218
10219
  item("organizationWorkspaces", (color) => /* @__PURE__ */ jsx22(SiconWorkspace2, { className: "w-5 h-5", color }))
@@ -10510,7 +10511,7 @@ function LanguageDropdown({
10510
10511
  ScMenuOptions,
10511
10512
  {
10512
10513
  text: lang.label,
10513
- icon: /* @__PURE__ */ jsx22(Fragment11, {}),
10514
+ icon: /* @__PURE__ */ jsx22(Fragment12, {}),
10514
10515
  hover: isActive ? "true" : "false",
10515
10516
  variant: "default",
10516
10517
  role: "option",
@@ -10900,16 +10901,91 @@ function ProfileTab() {
10900
10901
  }
10901
10902
  );
10902
10903
  }
10904
+ var WORKSPACE_LIST_PAGE_SIZE = 10;
10905
+ function groupWorkspaceList(workspaces, organizations = []) {
10906
+ const ordered = [
10907
+ ...organizations.filter((org) => org.role !== "guest"),
10908
+ ...organizations.filter((org) => org.role === "guest")
10909
+ ];
10910
+ const groups = [];
10911
+ for (const org of ordered) {
10912
+ const inOrg = workspaces.filter((ws) => ws.organizationId === org._id);
10913
+ if (inOrg.length) {
10914
+ groups.push({
10915
+ key: org._id,
10916
+ label: org.role === "guest" ? `${org.name} \xB7 Guest` : org.name,
10917
+ workspaces: inOrg
10918
+ });
10919
+ }
10920
+ }
10921
+ const known = new Set(organizations.map((org) => org._id));
10922
+ const ungrouped = workspaces.filter(
10923
+ (ws) => !ws.organizationId || !known.has(ws.organizationId)
10924
+ );
10925
+ if (ungrouped.length) {
10926
+ groups.push({
10927
+ key: "__no_org__",
10928
+ // "No organization" only means something next to named groups.
10929
+ label: groups.length ? "No organization" : "Other Workspaces",
10930
+ workspaces: ungrouped
10931
+ });
10932
+ }
10933
+ return groups;
10934
+ }
10903
10935
  function WorkspaceListTab({
10904
10936
  workspaces,
10905
10937
  loading,
10906
10938
  onCreateClick: _onCreateClick,
10907
10939
  onEditClick,
10908
10940
  onSwitchClick,
10909
- onLeaveClick
10941
+ onLeaveClick,
10942
+ fetchPlans,
10943
+ organizations = [],
10944
+ pageSize = WORKSPACE_LIST_PAGE_SIZE
10910
10945
  }) {
10911
10946
  const currentWorkspace = workspaces.find((ws) => ws.isCurrent);
10912
- const otherWorkspaces = workspaces.filter((ws) => !ws.isCurrent);
10947
+ const groups = groupWorkspaceList(
10948
+ workspaces.filter((ws) => !ws.isCurrent),
10949
+ organizations
10950
+ );
10951
+ const rows = groups.flatMap(
10952
+ (group) => group.workspaces.map((ws) => ({ ws, group }))
10953
+ );
10954
+ const otherWorkspaces = rows.map((row) => row.ws);
10955
+ const currentOrganization = organizations.find(
10956
+ (org) => org._id && org._id === currentWorkspace?.organizationId
10957
+ );
10958
+ const pageCount = Math.max(1, Math.ceil(otherWorkspaces.length / pageSize));
10959
+ const [page, setPage] = useState15(0);
10960
+ const safePage = Math.min(page, pageCount - 1);
10961
+ const pageStart = safePage * pageSize;
10962
+ const pageRows = rows.slice(pageStart, pageStart + pageSize);
10963
+ const pageWorkspaces = pageRows.map((row) => row.ws);
10964
+ const [plans, setPlans] = useState15({});
10965
+ const requestedPlans = useRef7(/* @__PURE__ */ new Set());
10966
+ const visibleIds = [
10967
+ ...currentWorkspace ? [currentWorkspace._id] : [],
10968
+ ...pageWorkspaces.map((ws) => ws._id)
10969
+ ];
10970
+ const visibleKey = visibleIds.join(",");
10971
+ const mounted = useRef7(true);
10972
+ useEffect13(() => {
10973
+ mounted.current = true;
10974
+ return () => {
10975
+ mounted.current = false;
10976
+ };
10977
+ }, []);
10978
+ useEffect13(() => {
10979
+ if (!fetchPlans || loading) return;
10980
+ const missing = visibleKey.split(",").filter((id) => id && !requestedPlans.current.has(id));
10981
+ if (!missing.length) return;
10982
+ missing.forEach((id) => requestedPlans.current.add(id));
10983
+ fetchPlans(missing).then((found) => {
10984
+ if (mounted.current) setPlans((prev) => ({ ...prev, ...found }));
10985
+ }).catch(() => {
10986
+ });
10987
+ }, [fetchPlans, loading, visibleKey]);
10988
+ const planOf = (ws) => fetchPlans ? plans[ws._id] ?? "" : ws.plan ?? "";
10913
10989
  return /* @__PURE__ */ jsxs19(
10914
10990
  "div",
10915
10991
  {
@@ -10946,7 +11022,7 @@ function WorkspaceListTab({
10946
11022
  className: "flex flex-col items-start shrink-0 w-full",
10947
11023
  style: { gap: 16, padding: "var(--spacing-md) 0" },
10948
11024
  children: [
10949
- /* @__PURE__ */ jsx22(
11025
+ /* @__PURE__ */ jsxs19(
10950
11026
  "p",
10951
11027
  {
10952
11028
  className: "w-full overflow-hidden text-ellipsis whitespace-nowrap",
@@ -10957,7 +11033,10 @@ function WorkspaceListTab({
10957
11033
  fontWeight: 400,
10958
11034
  lineHeight: "var(--line-height-line-height-md)"
10959
11035
  },
10960
- children: "Current Workspace"
11036
+ children: [
11037
+ "Current Workspace",
11038
+ currentOrganization ? ` \xB7 ${currentOrganization.name}${currentOrganization.role === "guest" ? " (guest)" : ""}` : ""
11039
+ ]
10961
11040
  }
10962
11041
  ),
10963
11042
  /* @__PURE__ */ jsx22(
@@ -10967,7 +11046,7 @@ function WorkspaceListTab({
10967
11046
  initials: currentWorkspace.initials,
10968
11047
  imageUrl: currentWorkspace.imageUrl,
10969
11048
  role: currentWorkspace.role,
10970
- plan: currentWorkspace.plan,
11049
+ plan: planOf(currentWorkspace),
10971
11050
  ownerId: currentWorkspace.ownerEmail,
10972
11051
  type: "currentWS",
10973
11052
  onSettings: () => onEditClick(currentWorkspace),
@@ -10994,40 +11073,92 @@ function WorkspaceListTab({
10994
11073
  style: { gap: 16, overflowY: "auto" },
10995
11074
  children: [
10996
11075
  /* @__PURE__ */ jsx22(
10997
- "p",
11076
+ "div",
10998
11077
  {
10999
- className: "w-full overflow-hidden text-ellipsis whitespace-nowrap shrink-0",
11000
- style: {
11001
- color: "var(--alias-text---icons-muted)",
11002
- fontFamily: "var(--font-family-font-family-body)",
11003
- fontSize: "var(--font-size-font-size-md)",
11004
- fontWeight: 400,
11005
- lineHeight: "var(--line-height-line-height-md)"
11006
- },
11007
- children: "Other Workspaces"
11078
+ className: "flex flex-col items-start w-full",
11079
+ style: { gap: 16 },
11080
+ children: pageRows.map(({ ws, group }, index) => /* @__PURE__ */ jsxs19(Fragment11, { children: [
11081
+ (index === 0 || pageRows[index - 1].group.key !== group.key) && /* @__PURE__ */ jsx22(
11082
+ "p",
11083
+ {
11084
+ className: "w-full overflow-hidden text-ellipsis whitespace-nowrap shrink-0",
11085
+ style: {
11086
+ color: "var(--alias-text---icons-muted)",
11087
+ fontFamily: "var(--font-family-font-family-body)",
11088
+ fontSize: "var(--font-size-font-size-md)",
11089
+ fontWeight: 400,
11090
+ lineHeight: "var(--line-height-line-height-md)",
11091
+ marginTop: index === 0 ? 0 : 8
11092
+ },
11093
+ children: group.label
11094
+ }
11095
+ ),
11096
+ /* @__PURE__ */ jsx22(
11097
+ ScWorkspaceSwitchCard,
11098
+ {
11099
+ wsName: ws.name,
11100
+ initials: ws.initials,
11101
+ imageUrl: ws.imageUrl,
11102
+ role: ws.role,
11103
+ plan: planOf(ws),
11104
+ ownerId: ws.ownerEmail,
11105
+ type: "otherWS",
11106
+ onSwitch: () => onSwitchClick(ws),
11107
+ onSettings: () => onEditClick(ws),
11108
+ onLeave: () => onLeaveClick(ws)
11109
+ }
11110
+ )
11111
+ ] }, ws._id))
11008
11112
  }
11009
11113
  ),
11010
- /* @__PURE__ */ jsx22(
11114
+ pageCount > 1 && /* @__PURE__ */ jsxs19(
11011
11115
  "div",
11012
11116
  {
11013
- className: "flex flex-col items-start w-full",
11014
- style: { gap: 16 },
11015
- children: otherWorkspaces.map((ws) => /* @__PURE__ */ jsx22(
11016
- ScWorkspaceSwitchCard,
11017
- {
11018
- wsName: ws.name,
11019
- initials: ws.initials,
11020
- imageUrl: ws.imageUrl,
11021
- role: ws.role,
11022
- plan: ws.plan,
11023
- ownerId: ws.ownerEmail,
11024
- type: "otherWS",
11025
- onSwitch: () => onSwitchClick(ws),
11026
- onSettings: () => onEditClick(ws),
11027
- onLeave: () => onLeaveClick(ws)
11028
- },
11029
- ws._id
11030
- ))
11117
+ className: "flex items-center justify-between shrink-0 w-full",
11118
+ style: { gap: "var(--spacing-md)" },
11119
+ children: [
11120
+ /* @__PURE__ */ jsxs19(
11121
+ "span",
11122
+ {
11123
+ style: {
11124
+ color: "var(--alias-text---icons-muted)",
11125
+ fontFamily: "var(--font-family-font-family-body)",
11126
+ fontSize: "var(--font-size-font-size-sm)",
11127
+ lineHeight: "var(--line-height-line-height-sm)"
11128
+ },
11129
+ children: [
11130
+ pageStart + 1,
11131
+ "\u2013",
11132
+ pageStart + pageWorkspaces.length,
11133
+ " of",
11134
+ " ",
11135
+ otherWorkspaces.length
11136
+ ]
11137
+ }
11138
+ ),
11139
+ /* @__PURE__ */ jsxs19("div", { className: "flex items-center", style: { gap: "var(--spacing-md)" }, children: [
11140
+ /* @__PURE__ */ jsx22(
11141
+ ScButton7,
11142
+ {
11143
+ text: "Previous",
11144
+ variant: "tertiary",
11145
+ size: "sm",
11146
+ state: safePage === 0 ? "disabled" : "default",
11147
+ onClick: safePage === 0 ? void 0 : () => setPage(safePage - 1)
11148
+ }
11149
+ ),
11150
+ /* @__PURE__ */ jsx22(
11151
+ ScButton7,
11152
+ {
11153
+ text: "Next",
11154
+ variant: "tertiary",
11155
+ size: "sm",
11156
+ state: safePage >= pageCount - 1 ? "disabled" : "default",
11157
+ onClick: safePage >= pageCount - 1 ? void 0 : () => setPage(safePage + 1)
11158
+ }
11159
+ )
11160
+ ] })
11161
+ ]
11031
11162
  }
11032
11163
  )
11033
11164
  ]
@@ -11175,6 +11306,28 @@ function SettingsContentInner({
11175
11306
  useEffect13(() => {
11176
11307
  void refreshWorkspaceList();
11177
11308
  }, [refreshWorkspaceList]);
11309
+ const [listOrganizations, setListOrganizations] = useState15([]);
11310
+ useEffect13(() => {
11311
+ if (activeTab !== "workspaceList" || typeof organization?.list !== "function") {
11312
+ return;
11313
+ }
11314
+ let cancelled = false;
11315
+ organization.list().then((orgs) => {
11316
+ if (!cancelled) {
11317
+ setListOrganizations(
11318
+ (orgs ?? []).map((org) => ({
11319
+ _id: org._id,
11320
+ name: org.name,
11321
+ role: org.role
11322
+ }))
11323
+ );
11324
+ }
11325
+ }).catch(() => {
11326
+ });
11327
+ return () => {
11328
+ cancelled = true;
11329
+ };
11330
+ }, [activeTab, organization]);
11178
11331
  const switchWorkspace = useCallback7(
11179
11332
  async (id) => {
11180
11333
  await workspace.switch(id);
@@ -11562,7 +11715,7 @@ function SettingsContentInner({
11562
11715
  children: "Settings"
11563
11716
  }
11564
11717
  ),
11565
- scopeCrumb && /* @__PURE__ */ jsxs19(Fragment11, { children: [
11718
+ scopeCrumb && /* @__PURE__ */ jsxs19(Fragment12, { children: [
11566
11719
  /* @__PURE__ */ jsx22(SiconRight2, { className: "w-6 h-6 shrink-0", color: "var(--alias-text---icons-primary)" }),
11567
11720
  /* @__PURE__ */ jsx22(
11568
11721
  "span",
@@ -11595,7 +11748,7 @@ function SettingsContentInner({
11595
11748
  children: leafLabel
11596
11749
  }
11597
11750
  ),
11598
- isBillingPlans && /* @__PURE__ */ jsxs19(Fragment11, { children: [
11751
+ isBillingPlans && /* @__PURE__ */ jsxs19(Fragment12, { children: [
11599
11752
  /* @__PURE__ */ jsx22(SiconRight2, { className: "w-6 h-6 shrink-0", color: "var(--alias-text---icons-primary)" }),
11600
11753
  /* @__PURE__ */ jsx22(
11601
11754
  "span",
@@ -11822,6 +11975,8 @@ function SettingsContentInner({
11822
11975
  {
11823
11976
  workspaces: displayWorkspaces,
11824
11977
  loading: workspaceListLoading && workspaceList.length === 0,
11978
+ fetchPlans: workspace.fetchPlans,
11979
+ organizations: listOrganizations,
11825
11980
  onCreateClick: handleCreateClick,
11826
11981
  onEditClick: handleEditClick,
11827
11982
  onSwitchClick: async (ws) => {
@@ -12264,12 +12419,14 @@ export {
12264
12419
  TokensContent,
12265
12420
  URL_TO_TAB,
12266
12421
  USER_LANGUAGES,
12422
+ WORKSPACE_LIST_PAGE_SIZE,
12267
12423
  WorkspaceGeneralTab,
12268
12424
  WorkspaceListTab,
12269
12425
  WorkspaceModal,
12270
12426
  WorkspacePicker,
12271
12427
  WorkspaceTab,
12272
12428
  countLabel,
12429
+ groupWorkspaceList,
12273
12430
  loadWorkspaceOrganization,
12274
12431
  resolveSettingsTabFromPath,
12275
12432
  useSettingsAdapters,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@streamoid/settings",
3
- "version": "0.7.0",
3
+ "version": "0.7.2",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.mjs",
6
6
  "types": "./dist/index.d.ts",