@streamoid/settings 0.7.3 → 0.7.4

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
@@ -182,6 +182,9 @@ interface SettingsWorkspaceListItem {
182
182
  /** The organization this workspace belongs to, if any. My workspaces groups
183
183
  * the list under each organization (named from `organization.list()`). */
184
184
  organizationId?: string;
185
+ /** The organization's name, when the host has it (used by `listPage()`
186
+ * rows whose organization isn't in `organization.list()`). */
187
+ organizationName?: string;
185
188
  }
186
189
  interface SettingsWorkspaceAdapter {
187
190
  /** Same authenticated transport used by the sidebar owner lookup. */
@@ -240,6 +243,20 @@ interface SettingsWorkspaceAdapter {
240
243
  * When omitted, the plan on each `list()` item is used as before.
241
244
  */
242
245
  fetchPlans?: (workspaceIds: string[]) => Promise<Record<string, string>>;
246
+ /**
247
+ * Optional: one page of the workspace list, from the API
248
+ * (`GET /workspace?limit=&offset=`). When given, My workspaces asks for each
249
+ * page as it is shown and renders exactly what comes back — `total` is every
250
+ * workspace the user can see. When omitted (or when a page request fails),
251
+ * My workspaces pages through `list()` in the browser as before.
252
+ */
253
+ listPage?: (params: {
254
+ limit: number;
255
+ offset: number;
256
+ }) => Promise<{
257
+ items: SettingsWorkspaceListItem[];
258
+ total: number;
259
+ }>;
243
260
  /**
244
261
  * Optional: host-controlled refresh after the package mutates workspace
245
262
  * state. If provided, the package will call this instead of (or in addition
@@ -961,7 +978,7 @@ interface WorkspaceListGroup {
961
978
  * last. Groups keep the order the organizations came in.
962
979
  */
963
980
  declare function groupWorkspaceList(workspaces: WorkspaceInfo[], organizations?: WorkspaceListOrganization[]): WorkspaceListGroup[];
964
- declare function WorkspaceListTab({ workspaces, loading, onCreateClick: _onCreateClick, onEditClick, onSwitchClick, onLeaveClick, fetchPlans, organizations, pageSize, }: {
981
+ declare function WorkspaceListTab({ workspaces, loading, onCreateClick: _onCreateClick, onEditClick, onSwitchClick, onLeaveClick, fetchPlans, organizations, pageSize, listPage, reloadKey, }: {
965
982
  workspaces: WorkspaceInfo[];
966
983
  loading: boolean;
967
984
  onCreateClick: () => void;
@@ -973,6 +990,18 @@ declare function WorkspaceListTab({ workspaces, loading, onCreateClick: _onCreat
973
990
  /** The viewer's organizations, to group the list under. */
974
991
  organizations?: WorkspaceListOrganization[];
975
992
  pageSize?: number;
993
+ /** One page from the API (see SettingsWorkspaceAdapter.listPage). When
994
+ * given, each page is fetched as it is shown and rendered as returned. */
995
+ listPage?: (params: {
996
+ limit: number;
997
+ offset: number;
998
+ }) => Promise<{
999
+ items: WorkspaceInfo[];
1000
+ total: number;
1001
+ }>;
1002
+ /** Changes whenever the host's list changes (a leave, a rename…), so the
1003
+ * page on screen is fetched again. */
1004
+ reloadKey?: string;
976
1005
  }): react.JSX.Element;
977
1006
  /**
978
1007
  * @deprecated Renamed to `WorkspaceListTab` in 0.4.0 — the tab is a workspace
package/dist/index.d.ts CHANGED
@@ -182,6 +182,9 @@ interface SettingsWorkspaceListItem {
182
182
  /** The organization this workspace belongs to, if any. My workspaces groups
183
183
  * the list under each organization (named from `organization.list()`). */
184
184
  organizationId?: string;
185
+ /** The organization's name, when the host has it (used by `listPage()`
186
+ * rows whose organization isn't in `organization.list()`). */
187
+ organizationName?: string;
185
188
  }
186
189
  interface SettingsWorkspaceAdapter {
187
190
  /** Same authenticated transport used by the sidebar owner lookup. */
@@ -240,6 +243,20 @@ interface SettingsWorkspaceAdapter {
240
243
  * When omitted, the plan on each `list()` item is used as before.
241
244
  */
242
245
  fetchPlans?: (workspaceIds: string[]) => Promise<Record<string, string>>;
246
+ /**
247
+ * Optional: one page of the workspace list, from the API
248
+ * (`GET /workspace?limit=&offset=`). When given, My workspaces asks for each
249
+ * page as it is shown and renders exactly what comes back — `total` is every
250
+ * workspace the user can see. When omitted (or when a page request fails),
251
+ * My workspaces pages through `list()` in the browser as before.
252
+ */
253
+ listPage?: (params: {
254
+ limit: number;
255
+ offset: number;
256
+ }) => Promise<{
257
+ items: SettingsWorkspaceListItem[];
258
+ total: number;
259
+ }>;
243
260
  /**
244
261
  * Optional: host-controlled refresh after the package mutates workspace
245
262
  * state. If provided, the package will call this instead of (or in addition
@@ -961,7 +978,7 @@ interface WorkspaceListGroup {
961
978
  * last. Groups keep the order the organizations came in.
962
979
  */
963
980
  declare function groupWorkspaceList(workspaces: WorkspaceInfo[], organizations?: WorkspaceListOrganization[]): WorkspaceListGroup[];
964
- declare function WorkspaceListTab({ workspaces, loading, onCreateClick: _onCreateClick, onEditClick, onSwitchClick, onLeaveClick, fetchPlans, organizations, pageSize, }: {
981
+ declare function WorkspaceListTab({ workspaces, loading, onCreateClick: _onCreateClick, onEditClick, onSwitchClick, onLeaveClick, fetchPlans, organizations, pageSize, listPage, reloadKey, }: {
965
982
  workspaces: WorkspaceInfo[];
966
983
  loading: boolean;
967
984
  onCreateClick: () => void;
@@ -973,6 +990,18 @@ declare function WorkspaceListTab({ workspaces, loading, onCreateClick: _onCreat
973
990
  /** The viewer's organizations, to group the list under. */
974
991
  organizations?: WorkspaceListOrganization[];
975
992
  pageSize?: number;
993
+ /** One page from the API (see SettingsWorkspaceAdapter.listPage). When
994
+ * given, each page is fetched as it is shown and rendered as returned. */
995
+ listPage?: (params: {
996
+ limit: number;
997
+ offset: number;
998
+ }) => Promise<{
999
+ items: WorkspaceInfo[];
1000
+ total: number;
1001
+ }>;
1002
+ /** Changes whenever the host's list changes (a leave, a rename…), so the
1003
+ * page on screen is fetched again. */
1004
+ reloadKey?: string;
976
1005
  }): react.JSX.Element;
977
1006
  /**
978
1007
  * @deprecated Renamed to `WorkspaceListTab` in 0.4.0 — the tab is a workspace
package/dist/index.js CHANGED
@@ -10938,26 +10938,59 @@ function WorkspaceListTab({
10938
10938
  onLeaveClick,
10939
10939
  fetchPlans,
10940
10940
  organizations = [],
10941
- pageSize = WORKSPACE_LIST_PAGE_SIZE
10941
+ pageSize = WORKSPACE_LIST_PAGE_SIZE,
10942
+ listPage,
10943
+ reloadKey
10942
10944
  }) {
10943
10945
  const currentWorkspace = workspaces.find((ws) => ws.isCurrent);
10944
- const groups = groupWorkspaceList(
10946
+ const currentOrganization = organizations.find(
10947
+ (org) => org._id && org._id === currentWorkspace?.organizationId
10948
+ );
10949
+ const [page, setPage] = (0, import_react17.useState)(0);
10950
+ const [serverPage, setServerPage] = (0, import_react17.useState)(null);
10951
+ const [serverFailed, setServerFailed] = (0, import_react17.useState)(false);
10952
+ const serverMode = !!listPage && !serverFailed;
10953
+ (0, import_react17.useEffect)(() => {
10954
+ if (!listPage || serverFailed) return;
10955
+ let cancelled = false;
10956
+ listPage({ limit: pageSize, offset: page * pageSize }).then((result) => {
10957
+ if (cancelled) return;
10958
+ const lastPage = Math.max(0, Math.ceil(result.total / pageSize) - 1);
10959
+ if (page > lastPage) {
10960
+ setPage(lastPage);
10961
+ return;
10962
+ }
10963
+ setServerPage({ page, items: result.items, total: result.total });
10964
+ }).catch(() => {
10965
+ if (!cancelled) setServerFailed(true);
10966
+ });
10967
+ return () => {
10968
+ cancelled = true;
10969
+ };
10970
+ }, [listPage, serverFailed, page, pageSize, reloadKey]);
10971
+ const organizationLabel = (org) => org.role === "guest" ? `${org.name} \xB7 Guest` : org.name;
10972
+ const serverGroupOf = (ws) => {
10973
+ const org = organizations.find((o) => o._id === ws.organizationId);
10974
+ if (org) return { key: org._id, label: organizationLabel(org), workspaces: [] };
10975
+ if (ws.organizationId && ws.organizationName) {
10976
+ return { key: ws.organizationId, label: ws.organizationName, workspaces: [] };
10977
+ }
10978
+ return { key: "__no_org__", label: "No organization", workspaces: [] };
10979
+ };
10980
+ const groups = serverMode ? [] : groupWorkspaceList(
10945
10981
  workspaces.filter((ws) => !ws.isCurrent),
10946
10982
  organizations
10947
10983
  );
10948
10984
  const rows = groups.flatMap(
10949
10985
  (group) => group.workspaces.map((ws) => ({ ws, group }))
10950
10986
  );
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);
10987
+ const listTotal = serverMode ? serverPage?.total ?? 0 : rows.length;
10988
+ const pageCount = Math.max(1, Math.ceil(listTotal / pageSize));
10989
+ const safePage = serverMode ? serverPage?.page ?? 0 : Math.min(page, pageCount - 1);
10958
10990
  const pageStart = safePage * pageSize;
10959
- const pageRows = rows.slice(pageStart, pageStart + pageSize);
10991
+ const pageRows = serverMode ? (serverPage?.items ?? []).map((ws) => ({ ws, group: serverGroupOf(ws) })) : rows.slice(pageStart, pageStart + pageSize);
10960
10992
  const pageWorkspaces = pageRows.map((row) => row.ws);
10993
+ const listLoading = loading || serverMode && !serverPage;
10961
10994
  const [plans, setPlans] = (0, import_react17.useState)({});
10962
10995
  const requestedPlans = (0, import_react17.useRef)(/* @__PURE__ */ new Set());
10963
10996
  const visibleIds = [
@@ -10973,7 +11006,7 @@ function WorkspaceListTab({
10973
11006
  };
10974
11007
  }, []);
10975
11008
  (0, import_react17.useEffect)(() => {
10976
- if (!fetchPlans || loading) return;
11009
+ if (!fetchPlans || listLoading) return;
10977
11010
  const missing = visibleKey.split(",").filter((id) => id && !requestedPlans.current.has(id));
10978
11011
  if (!missing.length) return;
10979
11012
  missing.forEach((id) => requestedPlans.current.add(id));
@@ -10981,7 +11014,7 @@ function WorkspaceListTab({
10981
11014
  if (mounted.current) setPlans((prev) => ({ ...prev, ...found }));
10982
11015
  }).catch(() => {
10983
11016
  });
10984
- }, [fetchPlans, loading, visibleKey]);
11017
+ }, [fetchPlans, listLoading, visibleKey]);
10985
11018
  const planOf = (ws) => fetchPlans ? plans[ws._id] ?? "" : ws.plan ?? "";
10986
11019
  return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
10987
11020
  "div",
@@ -11002,7 +11035,7 @@ function WorkspaceListTab({
11002
11035
  children: "Switching changes which workspace the rest of Settings acts on."
11003
11036
  }
11004
11037
  ),
11005
- loading && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
11038
+ listLoading && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
11006
11039
  "p",
11007
11040
  {
11008
11041
  style: {
@@ -11013,7 +11046,7 @@ function WorkspaceListTab({
11013
11046
  children: "Loading workspaces\u2026"
11014
11047
  }
11015
11048
  ),
11016
- !loading && currentWorkspace && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
11049
+ !listLoading && currentWorkspace && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
11017
11050
  "div",
11018
11051
  {
11019
11052
  className: "flex flex-col items-start shrink-0 w-full",
@@ -11053,7 +11086,7 @@ function WorkspaceListTab({
11053
11086
  ]
11054
11087
  }
11055
11088
  ),
11056
- !loading && currentWorkspace && otherWorkspaces.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
11089
+ !listLoading && currentWorkspace && listTotal > 0 && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
11057
11090
  "div",
11058
11091
  {
11059
11092
  className: "shrink-0 w-full",
@@ -11063,7 +11096,7 @@ function WorkspaceListTab({
11063
11096
  }
11064
11097
  }
11065
11098
  ),
11066
- !loading && otherWorkspaces.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
11099
+ !listLoading && listTotal > 0 && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
11067
11100
  "div",
11068
11101
  {
11069
11102
  className: "flex flex-col items-start flex-1 min-h-0 w-full",
@@ -11099,8 +11132,8 @@ function WorkspaceListTab({
11099
11132
  role: ws.role,
11100
11133
  plan: planOf(ws),
11101
11134
  ownerId: ws.ownerEmail,
11102
- type: "otherWS",
11103
- onSwitch: () => onSwitchClick(ws),
11135
+ type: ws.isCurrent ? "currentWS" : "otherWS",
11136
+ onSwitch: ws.isCurrent ? void 0 : () => onSwitchClick(ws),
11104
11137
  onSettings: () => onEditClick(ws),
11105
11138
  onLeave: () => onLeaveClick(ws)
11106
11139
  }
@@ -11129,7 +11162,7 @@ function WorkspaceListTab({
11129
11162
  pageStart + pageWorkspaces.length,
11130
11163
  " of",
11131
11164
  " ",
11132
- otherWorkspaces.length
11165
+ listTotal
11133
11166
  ]
11134
11167
  }
11135
11168
  ),
@@ -11303,6 +11336,24 @@ function SettingsContentInner({
11303
11336
  (0, import_react17.useEffect)(() => {
11304
11337
  void refreshWorkspaceList();
11305
11338
  }, [refreshWorkspaceList]);
11339
+ const hostListPage = workspace.listPage;
11340
+ const listWorkspacePage = (0, import_react17.useMemo)(
11341
+ () => hostListPage ? async (params) => {
11342
+ const result = await hostListPage(params);
11343
+ return {
11344
+ total: result.total,
11345
+ items: result.items.map(
11346
+ (it) => ({
11347
+ ...it,
11348
+ isCurrent: it.isCurrent ?? it._id === workspaceId,
11349
+ imageUrl: it.imageUrl ?? it.image,
11350
+ initials: deriveInitials(it.name)
11351
+ })
11352
+ )
11353
+ };
11354
+ } : void 0,
11355
+ [hostListPage, workspaceId]
11356
+ );
11306
11357
  const [listOrganizations, setListOrganizations] = (0, import_react17.useState)([]);
11307
11358
  (0, import_react17.useEffect)(() => {
11308
11359
  if (activeTab !== "workspaceList" || typeof organization?.list !== "function") {
@@ -11976,6 +12027,8 @@ function SettingsContentInner({
11976
12027
  loading: workspaceListLoading && workspaceList.length === 0,
11977
12028
  fetchPlans: workspace.fetchPlans,
11978
12029
  organizations: listOrganizations,
12030
+ listPage: listWorkspacePage,
12031
+ reloadKey: displayWorkspaces.map((ws) => `${ws._id}:${ws.name}:${ws.role}`).join(","),
11979
12032
  onCreateClick: handleCreateClick,
11980
12033
  onEditClick: handleEditClick,
11981
12034
  onSwitchClick: async (ws) => {
package/dist/index.mjs CHANGED
@@ -167,7 +167,8 @@ import {
167
167
  useState as useState15,
168
168
  useEffect as useEffect13,
169
169
  useRef as useRef7,
170
- useCallback as useCallback7
170
+ useCallback as useCallback7,
171
+ useMemo as useMemo3
171
172
  } from "react";
172
173
  import {
173
174
  ScSidebarMenu,
@@ -10941,26 +10942,59 @@ function WorkspaceListTab({
10941
10942
  onLeaveClick,
10942
10943
  fetchPlans,
10943
10944
  organizations = [],
10944
- pageSize = WORKSPACE_LIST_PAGE_SIZE
10945
+ pageSize = WORKSPACE_LIST_PAGE_SIZE,
10946
+ listPage,
10947
+ reloadKey
10945
10948
  }) {
10946
10949
  const currentWorkspace = workspaces.find((ws) => ws.isCurrent);
10947
- const groups = groupWorkspaceList(
10950
+ const currentOrganization = organizations.find(
10951
+ (org) => org._id && org._id === currentWorkspace?.organizationId
10952
+ );
10953
+ const [page, setPage] = useState15(0);
10954
+ const [serverPage, setServerPage] = useState15(null);
10955
+ const [serverFailed, setServerFailed] = useState15(false);
10956
+ const serverMode = !!listPage && !serverFailed;
10957
+ useEffect13(() => {
10958
+ if (!listPage || serverFailed) return;
10959
+ let cancelled = false;
10960
+ listPage({ limit: pageSize, offset: page * pageSize }).then((result) => {
10961
+ if (cancelled) return;
10962
+ const lastPage = Math.max(0, Math.ceil(result.total / pageSize) - 1);
10963
+ if (page > lastPage) {
10964
+ setPage(lastPage);
10965
+ return;
10966
+ }
10967
+ setServerPage({ page, items: result.items, total: result.total });
10968
+ }).catch(() => {
10969
+ if (!cancelled) setServerFailed(true);
10970
+ });
10971
+ return () => {
10972
+ cancelled = true;
10973
+ };
10974
+ }, [listPage, serverFailed, page, pageSize, reloadKey]);
10975
+ const organizationLabel = (org) => org.role === "guest" ? `${org.name} \xB7 Guest` : org.name;
10976
+ const serverGroupOf = (ws) => {
10977
+ const org = organizations.find((o) => o._id === ws.organizationId);
10978
+ if (org) return { key: org._id, label: organizationLabel(org), workspaces: [] };
10979
+ if (ws.organizationId && ws.organizationName) {
10980
+ return { key: ws.organizationId, label: ws.organizationName, workspaces: [] };
10981
+ }
10982
+ return { key: "__no_org__", label: "No organization", workspaces: [] };
10983
+ };
10984
+ const groups = serverMode ? [] : groupWorkspaceList(
10948
10985
  workspaces.filter((ws) => !ws.isCurrent),
10949
10986
  organizations
10950
10987
  );
10951
10988
  const rows = groups.flatMap(
10952
10989
  (group) => group.workspaces.map((ws) => ({ ws, group }))
10953
10990
  );
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);
10991
+ const listTotal = serverMode ? serverPage?.total ?? 0 : rows.length;
10992
+ const pageCount = Math.max(1, Math.ceil(listTotal / pageSize));
10993
+ const safePage = serverMode ? serverPage?.page ?? 0 : Math.min(page, pageCount - 1);
10961
10994
  const pageStart = safePage * pageSize;
10962
- const pageRows = rows.slice(pageStart, pageStart + pageSize);
10995
+ const pageRows = serverMode ? (serverPage?.items ?? []).map((ws) => ({ ws, group: serverGroupOf(ws) })) : rows.slice(pageStart, pageStart + pageSize);
10963
10996
  const pageWorkspaces = pageRows.map((row) => row.ws);
10997
+ const listLoading = loading || serverMode && !serverPage;
10964
10998
  const [plans, setPlans] = useState15({});
10965
10999
  const requestedPlans = useRef7(/* @__PURE__ */ new Set());
10966
11000
  const visibleIds = [
@@ -10976,7 +11010,7 @@ function WorkspaceListTab({
10976
11010
  };
10977
11011
  }, []);
10978
11012
  useEffect13(() => {
10979
- if (!fetchPlans || loading) return;
11013
+ if (!fetchPlans || listLoading) return;
10980
11014
  const missing = visibleKey.split(",").filter((id) => id && !requestedPlans.current.has(id));
10981
11015
  if (!missing.length) return;
10982
11016
  missing.forEach((id) => requestedPlans.current.add(id));
@@ -10984,7 +11018,7 @@ function WorkspaceListTab({
10984
11018
  if (mounted.current) setPlans((prev) => ({ ...prev, ...found }));
10985
11019
  }).catch(() => {
10986
11020
  });
10987
- }, [fetchPlans, loading, visibleKey]);
11021
+ }, [fetchPlans, listLoading, visibleKey]);
10988
11022
  const planOf = (ws) => fetchPlans ? plans[ws._id] ?? "" : ws.plan ?? "";
10989
11023
  return /* @__PURE__ */ jsxs19(
10990
11024
  "div",
@@ -11005,7 +11039,7 @@ function WorkspaceListTab({
11005
11039
  children: "Switching changes which workspace the rest of Settings acts on."
11006
11040
  }
11007
11041
  ),
11008
- loading && /* @__PURE__ */ jsx22(
11042
+ listLoading && /* @__PURE__ */ jsx22(
11009
11043
  "p",
11010
11044
  {
11011
11045
  style: {
@@ -11016,7 +11050,7 @@ function WorkspaceListTab({
11016
11050
  children: "Loading workspaces\u2026"
11017
11051
  }
11018
11052
  ),
11019
- !loading && currentWorkspace && /* @__PURE__ */ jsxs19(
11053
+ !listLoading && currentWorkspace && /* @__PURE__ */ jsxs19(
11020
11054
  "div",
11021
11055
  {
11022
11056
  className: "flex flex-col items-start shrink-0 w-full",
@@ -11056,7 +11090,7 @@ function WorkspaceListTab({
11056
11090
  ]
11057
11091
  }
11058
11092
  ),
11059
- !loading && currentWorkspace && otherWorkspaces.length > 0 && /* @__PURE__ */ jsx22(
11093
+ !listLoading && currentWorkspace && listTotal > 0 && /* @__PURE__ */ jsx22(
11060
11094
  "div",
11061
11095
  {
11062
11096
  className: "shrink-0 w-full",
@@ -11066,7 +11100,7 @@ function WorkspaceListTab({
11066
11100
  }
11067
11101
  }
11068
11102
  ),
11069
- !loading && otherWorkspaces.length > 0 && /* @__PURE__ */ jsxs19(
11103
+ !listLoading && listTotal > 0 && /* @__PURE__ */ jsxs19(
11070
11104
  "div",
11071
11105
  {
11072
11106
  className: "flex flex-col items-start flex-1 min-h-0 w-full",
@@ -11102,8 +11136,8 @@ function WorkspaceListTab({
11102
11136
  role: ws.role,
11103
11137
  plan: planOf(ws),
11104
11138
  ownerId: ws.ownerEmail,
11105
- type: "otherWS",
11106
- onSwitch: () => onSwitchClick(ws),
11139
+ type: ws.isCurrent ? "currentWS" : "otherWS",
11140
+ onSwitch: ws.isCurrent ? void 0 : () => onSwitchClick(ws),
11107
11141
  onSettings: () => onEditClick(ws),
11108
11142
  onLeave: () => onLeaveClick(ws)
11109
11143
  }
@@ -11132,7 +11166,7 @@ function WorkspaceListTab({
11132
11166
  pageStart + pageWorkspaces.length,
11133
11167
  " of",
11134
11168
  " ",
11135
- otherWorkspaces.length
11169
+ listTotal
11136
11170
  ]
11137
11171
  }
11138
11172
  ),
@@ -11306,6 +11340,24 @@ function SettingsContentInner({
11306
11340
  useEffect13(() => {
11307
11341
  void refreshWorkspaceList();
11308
11342
  }, [refreshWorkspaceList]);
11343
+ const hostListPage = workspace.listPage;
11344
+ const listWorkspacePage = useMemo3(
11345
+ () => hostListPage ? async (params) => {
11346
+ const result = await hostListPage(params);
11347
+ return {
11348
+ total: result.total,
11349
+ items: result.items.map(
11350
+ (it) => ({
11351
+ ...it,
11352
+ isCurrent: it.isCurrent ?? it._id === workspaceId,
11353
+ imageUrl: it.imageUrl ?? it.image,
11354
+ initials: deriveInitials(it.name)
11355
+ })
11356
+ )
11357
+ };
11358
+ } : void 0,
11359
+ [hostListPage, workspaceId]
11360
+ );
11309
11361
  const [listOrganizations, setListOrganizations] = useState15([]);
11310
11362
  useEffect13(() => {
11311
11363
  if (activeTab !== "workspaceList" || typeof organization?.list !== "function") {
@@ -11979,6 +12031,8 @@ function SettingsContentInner({
11979
12031
  loading: workspaceListLoading && workspaceList.length === 0,
11980
12032
  fetchPlans: workspace.fetchPlans,
11981
12033
  organizations: listOrganizations,
12034
+ listPage: listWorkspacePage,
12035
+ reloadKey: displayWorkspaces.map((ws) => `${ws._id}:${ws.name}:${ws.role}`).join(","),
11982
12036
  onCreateClick: handleCreateClick,
11983
12037
  onEditClick: handleEditClick,
11984
12038
  onSwitchClick: async (ws) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@streamoid/settings",
3
- "version": "0.7.3",
3
+ "version": "0.7.4",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.mjs",
6
6
  "types": "./dist/index.d.ts",