@streamoid/settings 0.7.0 → 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/dist/index.d.mts CHANGED
@@ -227,6 +227,16 @@ interface SettingsWorkspaceAdapter {
227
227
  role?: string;
228
228
  } | null;
229
229
  }>;
230
+ /**
231
+ * Optional: plan labels ("Free", "Pro", …) for the given workspaces, keyed by
232
+ * id. My workspaces lists workspaces a page at a time and asks only for the
233
+ * page on screen, so `list()` doesn't have to look up every workspace's plan
234
+ * before anything renders. Leave a workspace out of the result when its
235
+ * lookup failed; it is shown without a plan.
236
+ *
237
+ * When omitted, the plan on each `list()` item is used as before.
238
+ */
239
+ fetchPlans?: (workspaceIds: string[]) => Promise<Record<string, string>>;
230
240
  /**
231
241
  * Optional: host-controlled refresh after the package mutates workspace
232
242
  * state. If provided, the package will call this instead of (or in addition
@@ -928,13 +938,18 @@ declare function ProfileTab(): react.JSX.Element;
928
938
  * workspace you are not currently inside — the current one has its own
929
939
  * General page.
930
940
  */
931
- declare function WorkspaceListTab({ workspaces, loading, onCreateClick: _onCreateClick, onEditClick, onSwitchClick, onLeaveClick, }: {
941
+ /** Workspaces shown per page in My workspaces. */
942
+ declare const WORKSPACE_LIST_PAGE_SIZE = 10;
943
+ declare function WorkspaceListTab({ workspaces, loading, onCreateClick: _onCreateClick, onEditClick, onSwitchClick, onLeaveClick, fetchPlans, pageSize, }: {
932
944
  workspaces: WorkspaceInfo[];
933
945
  loading: boolean;
934
946
  onCreateClick: () => void;
935
947
  onEditClick: (ws: WorkspaceInfo) => void;
936
948
  onSwitchClick: (ws: WorkspaceInfo) => void;
937
949
  onLeaveClick: (ws: WorkspaceInfo) => void;
950
+ /** See SettingsWorkspaceAdapter.fetchPlans. */
951
+ fetchPlans?: (workspaceIds: string[]) => Promise<Record<string, string>>;
952
+ pageSize?: number;
938
953
  }): react.JSX.Element;
939
954
  /**
940
955
  * @deprecated Renamed to `WorkspaceListTab` in 0.4.0 — the tab is a workspace
@@ -1399,4 +1414,4 @@ declare function SettingsAdaptersProvider({ adapters, children, }: {
1399
1414
  */
1400
1415
  declare function useSettingsAdapters(): SettingsAdapters;
1401
1416
 
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 };
1417
+ 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, WorkspaceListTab, type WorkspaceMember, WorkspaceModal, type WorkspaceOrganization, type WorkspaceOrganizationRequest, WorkspacePicker, type WorkspacePickerItem, type WorkspacePickerProps, WorkspaceTab, type WorkspaceUsageResponse, countLabel, loadWorkspaceOrganization, resolveSettingsTabFromPath, useSettingsAdapters, useWorkspaceOrganization, userLanguageLabel };
package/dist/index.d.ts CHANGED
@@ -227,6 +227,16 @@ interface SettingsWorkspaceAdapter {
227
227
  role?: string;
228
228
  } | null;
229
229
  }>;
230
+ /**
231
+ * Optional: plan labels ("Free", "Pro", …) for the given workspaces, keyed by
232
+ * id. My workspaces lists workspaces a page at a time and asks only for the
233
+ * page on screen, so `list()` doesn't have to look up every workspace's plan
234
+ * before anything renders. Leave a workspace out of the result when its
235
+ * lookup failed; it is shown without a plan.
236
+ *
237
+ * When omitted, the plan on each `list()` item is used as before.
238
+ */
239
+ fetchPlans?: (workspaceIds: string[]) => Promise<Record<string, string>>;
230
240
  /**
231
241
  * Optional: host-controlled refresh after the package mutates workspace
232
242
  * state. If provided, the package will call this instead of (or in addition
@@ -928,13 +938,18 @@ declare function ProfileTab(): react.JSX.Element;
928
938
  * workspace you are not currently inside — the current one has its own
929
939
  * General page.
930
940
  */
931
- declare function WorkspaceListTab({ workspaces, loading, onCreateClick: _onCreateClick, onEditClick, onSwitchClick, onLeaveClick, }: {
941
+ /** Workspaces shown per page in My workspaces. */
942
+ declare const WORKSPACE_LIST_PAGE_SIZE = 10;
943
+ declare function WorkspaceListTab({ workspaces, loading, onCreateClick: _onCreateClick, onEditClick, onSwitchClick, onLeaveClick, fetchPlans, pageSize, }: {
932
944
  workspaces: WorkspaceInfo[];
933
945
  loading: boolean;
934
946
  onCreateClick: () => void;
935
947
  onEditClick: (ws: WorkspaceInfo) => void;
936
948
  onSwitchClick: (ws: WorkspaceInfo) => void;
937
949
  onLeaveClick: (ws: WorkspaceInfo) => void;
950
+ /** See SettingsWorkspaceAdapter.fetchPlans. */
951
+ fetchPlans?: (workspaceIds: string[]) => Promise<Record<string, string>>;
952
+ pageSize?: number;
938
953
  }): react.JSX.Element;
939
954
  /**
940
955
  * @deprecated Renamed to `WorkspaceListTab` in 0.4.0 — the tab is a workspace
@@ -1399,4 +1414,4 @@ declare function SettingsAdaptersProvider({ adapters, children, }: {
1399
1414
  */
1400
1415
  declare function useSettingsAdapters(): SettingsAdapters;
1401
1416
 
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 };
1417
+ 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, WorkspaceListTab, type WorkspaceMember, WorkspaceModal, type WorkspaceOrganization, type WorkspaceOrganizationRequest, WorkspacePicker, type WorkspacePickerItem, type WorkspacePickerProps, WorkspaceTab, type WorkspaceUsageResponse, countLabel, loadWorkspaceOrganization, resolveSettingsTabFromPath, useSettingsAdapters, useWorkspaceOrganization, userLanguageLabel };
package/dist/index.js CHANGED
@@ -51,6 +51,7 @@ __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,
@@ -10896,16 +10897,49 @@ function ProfileTab() {
10896
10897
  }
10897
10898
  );
10898
10899
  }
10900
+ var WORKSPACE_LIST_PAGE_SIZE = 10;
10899
10901
  function WorkspaceListTab({
10900
10902
  workspaces,
10901
10903
  loading,
10902
10904
  onCreateClick: _onCreateClick,
10903
10905
  onEditClick,
10904
10906
  onSwitchClick,
10905
- onLeaveClick
10907
+ onLeaveClick,
10908
+ fetchPlans,
10909
+ pageSize = WORKSPACE_LIST_PAGE_SIZE
10906
10910
  }) {
10907
10911
  const currentWorkspace = workspaces.find((ws) => ws.isCurrent);
10908
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 ?? "";
10909
10943
  return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
10910
10944
  "div",
10911
10945
  {
@@ -10963,7 +10997,7 @@ function WorkspaceListTab({
10963
10997
  initials: currentWorkspace.initials,
10964
10998
  imageUrl: currentWorkspace.imageUrl,
10965
10999
  role: currentWorkspace.role,
10966
- plan: currentWorkspace.plan,
11000
+ plan: planOf(currentWorkspace),
10967
11001
  ownerId: currentWorkspace.ownerEmail,
10968
11002
  type: "currentWS",
10969
11003
  onSettings: () => onEditClick(currentWorkspace),
@@ -11008,14 +11042,14 @@ function WorkspaceListTab({
11008
11042
  {
11009
11043
  className: "flex flex-col items-start w-full",
11010
11044
  style: { gap: 16 },
11011
- children: otherWorkspaces.map((ws) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
11045
+ children: pageWorkspaces.map((ws) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
11012
11046
  import_ui14.ScWorkspaceSwitchCard,
11013
11047
  {
11014
11048
  wsName: ws.name,
11015
11049
  initials: ws.initials,
11016
11050
  imageUrl: ws.imageUrl,
11017
11051
  role: ws.role,
11018
- plan: ws.plan,
11052
+ plan: planOf(ws),
11019
11053
  ownerId: ws.ownerEmail,
11020
11054
  type: "otherWS",
11021
11055
  onSwitch: () => onSwitchClick(ws),
@@ -11025,6 +11059,56 @@ function WorkspaceListTab({
11025
11059
  ws._id
11026
11060
  ))
11027
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
+ }
11028
11112
  )
11029
11113
  ]
11030
11114
  }
@@ -11818,6 +11902,7 @@ function SettingsContentInner({
11818
11902
  {
11819
11903
  workspaces: displayWorkspaces,
11820
11904
  loading: workspaceListLoading && workspaceList.length === 0,
11905
+ fetchPlans: workspace.fetchPlans,
11821
11906
  onCreateClick: handleCreateClick,
11822
11907
  onEditClick: handleEditClick,
11823
11908
  onSwitchClick: async (ws) => {
package/dist/index.mjs CHANGED
@@ -10900,16 +10900,49 @@ function ProfileTab() {
10900
10900
  }
10901
10901
  );
10902
10902
  }
10903
+ var WORKSPACE_LIST_PAGE_SIZE = 10;
10903
10904
  function WorkspaceListTab({
10904
10905
  workspaces,
10905
10906
  loading,
10906
10907
  onCreateClick: _onCreateClick,
10907
10908
  onEditClick,
10908
10909
  onSwitchClick,
10909
- onLeaveClick
10910
+ onLeaveClick,
10911
+ fetchPlans,
10912
+ pageSize = WORKSPACE_LIST_PAGE_SIZE
10910
10913
  }) {
10911
10914
  const currentWorkspace = workspaces.find((ws) => ws.isCurrent);
10912
10915
  const otherWorkspaces = workspaces.filter((ws) => !ws.isCurrent);
10916
+ const pageCount = Math.max(1, Math.ceil(otherWorkspaces.length / pageSize));
10917
+ const [page, setPage] = useState15(0);
10918
+ const safePage = Math.min(page, pageCount - 1);
10919
+ const pageStart = safePage * pageSize;
10920
+ const pageWorkspaces = otherWorkspaces.slice(pageStart, pageStart + pageSize);
10921
+ const [plans, setPlans] = useState15({});
10922
+ const requestedPlans = useRef7(/* @__PURE__ */ new Set());
10923
+ const visibleIds = [
10924
+ ...currentWorkspace ? [currentWorkspace._id] : [],
10925
+ ...pageWorkspaces.map((ws) => ws._id)
10926
+ ];
10927
+ const visibleKey = visibleIds.join(",");
10928
+ const mounted = useRef7(true);
10929
+ useEffect13(() => {
10930
+ mounted.current = true;
10931
+ return () => {
10932
+ mounted.current = false;
10933
+ };
10934
+ }, []);
10935
+ useEffect13(() => {
10936
+ if (!fetchPlans || loading) return;
10937
+ const missing = visibleKey.split(",").filter((id) => id && !requestedPlans.current.has(id));
10938
+ if (!missing.length) return;
10939
+ missing.forEach((id) => requestedPlans.current.add(id));
10940
+ fetchPlans(missing).then((found) => {
10941
+ if (mounted.current) setPlans((prev) => ({ ...prev, ...found }));
10942
+ }).catch(() => {
10943
+ });
10944
+ }, [fetchPlans, loading, visibleKey]);
10945
+ const planOf = (ws) => fetchPlans ? plans[ws._id] ?? "" : ws.plan ?? "";
10913
10946
  return /* @__PURE__ */ jsxs19(
10914
10947
  "div",
10915
10948
  {
@@ -10967,7 +11000,7 @@ function WorkspaceListTab({
10967
11000
  initials: currentWorkspace.initials,
10968
11001
  imageUrl: currentWorkspace.imageUrl,
10969
11002
  role: currentWorkspace.role,
10970
- plan: currentWorkspace.plan,
11003
+ plan: planOf(currentWorkspace),
10971
11004
  ownerId: currentWorkspace.ownerEmail,
10972
11005
  type: "currentWS",
10973
11006
  onSettings: () => onEditClick(currentWorkspace),
@@ -11012,14 +11045,14 @@ function WorkspaceListTab({
11012
11045
  {
11013
11046
  className: "flex flex-col items-start w-full",
11014
11047
  style: { gap: 16 },
11015
- children: otherWorkspaces.map((ws) => /* @__PURE__ */ jsx22(
11048
+ children: pageWorkspaces.map((ws) => /* @__PURE__ */ jsx22(
11016
11049
  ScWorkspaceSwitchCard,
11017
11050
  {
11018
11051
  wsName: ws.name,
11019
11052
  initials: ws.initials,
11020
11053
  imageUrl: ws.imageUrl,
11021
11054
  role: ws.role,
11022
- plan: ws.plan,
11055
+ plan: planOf(ws),
11023
11056
  ownerId: ws.ownerEmail,
11024
11057
  type: "otherWS",
11025
11058
  onSwitch: () => onSwitchClick(ws),
@@ -11029,6 +11062,56 @@ function WorkspaceListTab({
11029
11062
  ws._id
11030
11063
  ))
11031
11064
  }
11065
+ ),
11066
+ pageCount > 1 && /* @__PURE__ */ jsxs19(
11067
+ "div",
11068
+ {
11069
+ className: "flex items-center justify-between shrink-0 w-full",
11070
+ style: { gap: "var(--spacing-md)" },
11071
+ children: [
11072
+ /* @__PURE__ */ jsxs19(
11073
+ "span",
11074
+ {
11075
+ style: {
11076
+ color: "var(--alias-text---icons-muted)",
11077
+ fontFamily: "var(--font-family-font-family-body)",
11078
+ fontSize: "var(--font-size-font-size-sm)",
11079
+ lineHeight: "var(--line-height-line-height-sm)"
11080
+ },
11081
+ children: [
11082
+ pageStart + 1,
11083
+ "\u2013",
11084
+ pageStart + pageWorkspaces.length,
11085
+ " of",
11086
+ " ",
11087
+ otherWorkspaces.length
11088
+ ]
11089
+ }
11090
+ ),
11091
+ /* @__PURE__ */ jsxs19("div", { className: "flex items-center", style: { gap: "var(--spacing-md)" }, children: [
11092
+ /* @__PURE__ */ jsx22(
11093
+ ScButton7,
11094
+ {
11095
+ text: "Previous",
11096
+ variant: "tertiary",
11097
+ size: "sm",
11098
+ state: safePage === 0 ? "disabled" : "default",
11099
+ onClick: safePage === 0 ? void 0 : () => setPage(safePage - 1)
11100
+ }
11101
+ ),
11102
+ /* @__PURE__ */ jsx22(
11103
+ ScButton7,
11104
+ {
11105
+ text: "Next",
11106
+ variant: "tertiary",
11107
+ size: "sm",
11108
+ state: safePage >= pageCount - 1 ? "disabled" : "default",
11109
+ onClick: safePage >= pageCount - 1 ? void 0 : () => setPage(safePage + 1)
11110
+ }
11111
+ )
11112
+ ] })
11113
+ ]
11114
+ }
11032
11115
  )
11033
11116
  ]
11034
11117
  }
@@ -11822,6 +11905,7 @@ function SettingsContentInner({
11822
11905
  {
11823
11906
  workspaces: displayWorkspaces,
11824
11907
  loading: workspaceListLoading && workspaceList.length === 0,
11908
+ fetchPlans: workspace.fetchPlans,
11825
11909
  onCreateClick: handleCreateClick,
11826
11910
  onEditClick: handleEditClick,
11827
11911
  onSwitchClick: async (ws) => {
@@ -12264,6 +12348,7 @@ export {
12264
12348
  TokensContent,
12265
12349
  URL_TO_TAB,
12266
12350
  USER_LANGUAGES,
12351
+ WORKSPACE_LIST_PAGE_SIZE,
12267
12352
  WorkspaceGeneralTab,
12268
12353
  WorkspaceListTab,
12269
12354
  WorkspaceModal,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@streamoid/settings",
3
- "version": "0.7.0",
3
+ "version": "0.7.1",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.mjs",
6
6
  "types": "./dist/index.d.ts",