@orthacms/users-admin 0.4.2 → 0.5.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.
Files changed (115) hide show
  1. package/dist/lib/presentation/membersFilterFields/index.d.ts +3 -1
  2. package/dist/lib/presentation/membersFilterFields/index.d.ts.map +1 -1
  3. package/dist/lib/presentation/membersFilterFields/index.js +3 -1
  4. package/dist/lib/presentation/pages/MembersPage/index.d.ts.map +1 -1
  5. package/dist/lib/presentation/pages/MembersPage/index.js +21 -8
  6. package/dist/lib/presentation/usersPlugin/index.d.ts +14 -5
  7. package/dist/lib/presentation/usersPlugin/index.d.ts.map +1 -1
  8. package/dist/lib/presentation/usersPlugin/index.js +14 -5
  9. package/package.json +8 -8
  10. package/dist/lib/api/useAddWorkspaceMember/index.d.ts +0 -16
  11. package/dist/lib/api/useAddWorkspaceMember/index.d.ts.map +0 -1
  12. package/dist/lib/api/useInviteMember/index.d.ts +0 -17
  13. package/dist/lib/api/useInviteMember/index.d.ts.map +0 -1
  14. package/dist/lib/api/useMembers/index.d.ts +0 -15
  15. package/dist/lib/api/useMembers/index.d.ts.map +0 -1
  16. package/dist/lib/api/useMembersMutation/index.d.ts +0 -13
  17. package/dist/lib/api/useMembersMutation/index.d.ts.map +0 -1
  18. package/dist/lib/api/useRemoveWorkspaceMember/index.d.ts +0 -15
  19. package/dist/lib/api/useRemoveWorkspaceMember/index.d.ts.map +0 -1
  20. package/dist/lib/api/useResendInvite/index.d.ts +0 -8
  21. package/dist/lib/api/useResendInvite/index.d.ts.map +0 -1
  22. package/dist/lib/api/useRevokeInvite/index.d.ts +0 -7
  23. package/dist/lib/api/useRevokeInvite/index.d.ts.map +0 -1
  24. package/dist/lib/api/useRevokeSession/index.d.ts +0 -15
  25. package/dist/lib/api/useRevokeSession/index.d.ts.map +0 -1
  26. package/dist/lib/api/useSetMemberStatus/index.d.ts +0 -15
  27. package/dist/lib/api/useSetMemberStatus/index.d.ts.map +0 -1
  28. package/dist/lib/api/useUpdateMember/index.d.ts +0 -15
  29. package/dist/lib/api/useUpdateMember/index.d.ts.map +0 -1
  30. package/dist/lib/api/useUserDetail/index.d.ts +0 -9
  31. package/dist/lib/api/useUserDetail/index.d.ts.map +0 -1
  32. package/dist/lib/api/useUserSessions/index.d.ts +0 -25
  33. package/dist/lib/api/useUserSessions/index.d.ts.map +0 -1
  34. package/dist/lib/api/useWorkspaceOptions/index.d.ts +0 -18
  35. package/dist/lib/api/useWorkspaceOptions/index.d.ts.map +0 -1
  36. package/dist/lib/components/AccountMenu/index.d.ts +0 -9
  37. package/dist/lib/components/AccountMenu/index.d.ts.map +0 -1
  38. package/dist/lib/components/AddToWorkspacesDialog/index.d.ts +0 -19
  39. package/dist/lib/components/AddToWorkspacesDialog/index.d.ts.map +0 -1
  40. package/dist/lib/components/BackLink/index.d.ts +0 -14
  41. package/dist/lib/components/BackLink/index.d.ts.map +0 -1
  42. package/dist/lib/components/ConfirmDialog/index.d.ts +0 -30
  43. package/dist/lib/components/ConfirmDialog/index.d.ts.map +0 -1
  44. package/dist/lib/components/EditMemberDialog/index.d.ts +0 -21
  45. package/dist/lib/components/EditMemberDialog/index.d.ts.map +0 -1
  46. package/dist/lib/components/MemberAvatar/index.d.ts +0 -24
  47. package/dist/lib/components/MemberAvatar/index.d.ts.map +0 -1
  48. package/dist/lib/components/MembersEmpty/index.d.ts +0 -16
  49. package/dist/lib/components/MembersEmpty/index.d.ts.map +0 -1
  50. package/dist/lib/components/MembersNoAccess/index.d.ts +0 -7
  51. package/dist/lib/components/MembersNoAccess/index.d.ts.map +0 -1
  52. package/dist/lib/components/MembersPagination/index.d.ts +0 -17
  53. package/dist/lib/components/MembersPagination/index.d.ts.map +0 -1
  54. package/dist/lib/components/MembersSkeleton/index.d.ts +0 -32
  55. package/dist/lib/components/MembersSkeleton/index.d.ts.map +0 -1
  56. package/dist/lib/components/MembersTable/MemberRoleChip/index.d.ts +0 -10
  57. package/dist/lib/components/MembersTable/MemberRoleChip/index.d.ts.map +0 -1
  58. package/dist/lib/components/MembersTable/MemberRowActions/index.d.ts +0 -16
  59. package/dist/lib/components/MembersTable/MemberRowActions/index.d.ts.map +0 -1
  60. package/dist/lib/components/MembersTable/MemberStatusBadge/index.d.ts +0 -10
  61. package/dist/lib/components/MembersTable/MemberStatusBadge/index.d.ts.map +0 -1
  62. package/dist/lib/components/MembersTable/MemberWorkspaces/index.d.ts +0 -10
  63. package/dist/lib/components/MembersTable/MemberWorkspaces/index.d.ts.map +0 -1
  64. package/dist/lib/components/MembersTable/index.d.ts +0 -12
  65. package/dist/lib/components/MembersTable/index.d.ts.map +0 -1
  66. package/dist/lib/components/MembersToolbar/index.d.ts +0 -13
  67. package/dist/lib/components/MembersToolbar/index.d.ts.map +0 -1
  68. package/dist/lib/components/RolePicker/index.d.ts +0 -18
  69. package/dist/lib/components/RolePicker/index.d.ts.map +0 -1
  70. package/dist/lib/components/SessionCard/index.d.ts +0 -15
  71. package/dist/lib/components/SessionCard/index.d.ts.map +0 -1
  72. package/dist/lib/components/UserDetailLayout/UserDetailTabs/index.d.ts +0 -13
  73. package/dist/lib/components/UserDetailLayout/UserDetailTabs/index.d.ts.map +0 -1
  74. package/dist/lib/components/UserDetailLayout/UserHero/index.d.ts +0 -10
  75. package/dist/lib/components/UserDetailLayout/UserHero/index.d.ts.map +0 -1
  76. package/dist/lib/components/UserDetailLayout/UserSideRail/index.d.ts +0 -12
  77. package/dist/lib/components/UserDetailLayout/UserSideRail/index.d.ts.map +0 -1
  78. package/dist/lib/components/UserDetailLayout/UserStatsStrip/index.d.ts +0 -10
  79. package/dist/lib/components/UserDetailLayout/UserStatsStrip/index.d.ts.map +0 -1
  80. package/dist/lib/components/UserDetailLayout/index.d.ts +0 -13
  81. package/dist/lib/components/UserDetailLayout/index.d.ts.map +0 -1
  82. package/dist/lib/components/UserDetailRouter/index.d.ts +0 -13
  83. package/dist/lib/components/UserDetailRouter/index.d.ts.map +0 -1
  84. package/dist/lib/components/WorkspaceMembershipCard/index.d.ts +0 -15
  85. package/dist/lib/components/WorkspaceMembershipCard/index.d.ts.map +0 -1
  86. package/dist/lib/pages/InviteMemberPage/index.d.ts +0 -7
  87. package/dist/lib/pages/InviteMemberPage/index.d.ts.map +0 -1
  88. package/dist/lib/pages/MembersPage/index.d.ts +0 -13
  89. package/dist/lib/pages/MembersPage/index.d.ts.map +0 -1
  90. package/dist/lib/pages/UserAccessPage/index.d.ts +0 -9
  91. package/dist/lib/pages/UserAccessPage/index.d.ts.map +0 -1
  92. package/dist/lib/pages/UserActivityPage/index.d.ts +0 -8
  93. package/dist/lib/pages/UserActivityPage/index.d.ts.map +0 -1
  94. package/dist/lib/pages/UserGeneralPage/index.d.ts +0 -7
  95. package/dist/lib/pages/UserGeneralPage/index.d.ts.map +0 -1
  96. package/dist/lib/pages/UserRolesPage/index.d.ts +0 -8
  97. package/dist/lib/pages/UserRolesPage/index.d.ts.map +0 -1
  98. package/dist/lib/pages/UserSessionsPage/index.d.ts +0 -7
  99. package/dist/lib/pages/UserSessionsPage/index.d.ts.map +0 -1
  100. package/dist/lib/pages/UserWorkspacesPage/index.d.ts +0 -8
  101. package/dist/lib/pages/UserWorkspacesPage/index.d.ts.map +0 -1
  102. package/dist/lib/presentation/components/MembersTable/membersTableAnchor/index.d.ts +0 -14
  103. package/dist/lib/presentation/components/MembersTable/membersTableAnchor/index.d.ts.map +0 -1
  104. package/dist/lib/types/member/index.d.ts +0 -63
  105. package/dist/lib/types/member/index.d.ts.map +0 -1
  106. package/dist/lib/utils/membersFilterFields/index.d.ts +0 -10
  107. package/dist/lib/utils/membersFilterFields/index.d.ts.map +0 -1
  108. package/dist/lib/utils/membersKeys/index.d.ts +0 -27
  109. package/dist/lib/utils/membersKeys/index.d.ts.map +0 -1
  110. package/dist/lib/utils/toMember/index.d.ts +0 -33
  111. package/dist/lib/utils/toMember/index.d.ts.map +0 -1
  112. package/dist/lib/utils/userDetailContext/index.d.ts +0 -13
  113. package/dist/lib/utils/userDetailContext/index.d.ts.map +0 -1
  114. package/dist/lib/utils/usersPlugin/index.d.ts +0 -27
  115. package/dist/lib/utils/usersPlugin/index.d.ts.map +0 -1
@@ -1,7 +1,9 @@
1
1
  import { type FilterField } from '@orthacms/query-builder-admin';
2
2
  /**
3
3
  * The members filter surface the query builder offers. A static mirror of the
4
- * server's `USERS_FILTER_SCHEMA` — each `id` matches a whitelisted field (the
4
+ * server's `MEMBER_FILTER_SCHEMA`
5
+ * (`users/server/…/member/application/member-filter.ts`) — each `id` matches a
6
+ * whitelisted field (the
5
7
  * `role.key` dotted path resolves to the BE's `role` relation), so a rule built
6
8
  * here always validates server-side. `status` / `role` render as dropdowns; the
7
9
  * BE still accepts any role key string, the UI just offers the system roles.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/presentation/membersFilterFields/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAc,KAAK,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAoC7E;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,EAAE,SAAS,WAAW,EAwBvD,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/presentation/membersFilterFields/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAc,KAAK,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAoC7E;;;;;;;;GAQG;AACH,eAAO,MAAM,qBAAqB,EAAE,SAAS,WAAW,EAwBvD,CAAC"}
@@ -35,7 +35,9 @@ const messages = defineMessages({
35
35
  });
36
36
  /**
37
37
  * The members filter surface the query builder offers. A static mirror of the
38
- * server's `USERS_FILTER_SCHEMA` — each `id` matches a whitelisted field (the
38
+ * server's `MEMBER_FILTER_SCHEMA`
39
+ * (`users/server/…/member/application/member-filter.ts`) — each `id` matches a
40
+ * whitelisted field (the
39
41
  * `role.key` dotted path resolves to the BE's `role` relation), so a rule built
40
42
  * here always validates server-side. `status` / `role` render as dropdowns; the
41
43
  * BE still accepts any role key string, the UI just offers the system roles.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/lib/presentation/pages/MembersPage/index.tsx"],"names":[],"mappings":"AAkEA;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,gCA2O1B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/lib/presentation/pages/MembersPage/index.tsx"],"names":[],"mappings":"AA2EA;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,gCAoR1B"}
@@ -1,13 +1,13 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { useCallback, useEffect, useMemo } from 'react';
2
+ import { useCallback, useEffect, useId, useMemo, useRef, useState } from 'react';
3
3
  import { useNavigate } from 'react-router-dom';
4
4
  import { defineMessages, useIntl } from 'react-intl';
5
- import { Filter, UserPlus, Users } from 'lucide-react';
5
+ import { ChevronDown, Filter, UserPlus, Users } from 'lucide-react';
6
6
  import { PageTopBar } from '@orthacms/shell-admin';
7
- import { QueryBuilderDrawer, countRules, jsonFilterToTree, treeToJsonFilter } from '@orthacms/query-builder-admin';
7
+ import { QueryBuilderPanel, QueryBuilderSummary, countRules, jsonFilterToTree, treeToJsonFilter } from '@orthacms/query-builder-admin';
8
8
  import { useHasPermission } from '@orthacms/identity-admin';
9
9
  import { useTableUrlState, useDocumentTitle } from '@orthacms/utils-admin';
10
- import { Alert, AlertDescription, Button, Container, ContainerHeader } from '@orthacms/design-system';
10
+ import { Alert, AlertDescription, Button, Container, ContainerHeader, cn } from '@orthacms/design-system';
11
11
  import { useMembers, DEFAULT_PAGE_SIZE } from '../../../application/useMembers';
12
12
  import { MembersTableSkeleton } from '../../components/MembersSkeleton';
13
13
  import { MembersEmpty } from '../../components/MembersEmpty';
@@ -72,7 +72,7 @@ export function MembersPage() {
72
72
  searchKey: 'search',
73
73
  defaultPageSize: DEFAULT_PAGE_SIZE
74
74
  });
75
- // Rehydrate the applied filter tree from the URL for the drawer. Keyed on
75
+ // Rehydrate the applied filter tree from the URL for the panel. Keyed on
76
76
  // the raw param so a deep-linked or hand-edited filter restores on load.
77
77
  const appliedFilter = useMemo(() => jsonFilterToTree(filterParam), [filterParam]);
78
78
  const ruleCount = countRules(appliedFilter);
@@ -98,6 +98,19 @@ export function MembersPage() {
98
98
  updateParams({ page: pageCount > 1 ? String(pageCount) : undefined }, false);
99
99
  }
100
100
  }, [data, page, pageCount, updateParams]);
101
+ // The inline filter panel: its own open state (the toolbar button toggles
102
+ // it), with the ids wiring the button's `aria-controls` to the region.
103
+ const [filtersOpen, setFiltersOpen] = useState(false);
104
+ const filtersPanelId = useId();
105
+ const filtersToggleId = useId();
106
+ const filtersToggleRef = useRef(null);
107
+ // Return focus to the toggle when the panel collapses (Esc, or a second
108
+ // press), so the now-`inert` panel doesn't strand focus on the body.
109
+ const setFiltersPanelOpen = useCallback((open) => {
110
+ setFiltersOpen(open);
111
+ if (!open)
112
+ filtersToggleRef.current?.focus();
113
+ }, []);
101
114
  /** Commit (or clear) the query-builder filter to the URL. */
102
115
  const applyFilter = useCallback((next) => {
103
116
  updateParams({ filter: treeToJsonFilter(next) ?? undefined });
@@ -134,7 +147,7 @@ export function MembersPage() {
134
147
  ? undefined
135
148
  : intl.formatMessage(messages.subtitle, {
136
149
  count: total
137
- }), actions: canInvite ? (_jsxs(Button, { onClick: openInvite, children: [_jsx(UserPlus, {}), intl.formatMessage(messages.invite)] })) : undefined }), _jsx(MembersToolbar, { search: searchInput, onSearchChange: setSearchInput, busy: searchPending || isFetching, filterControl: _jsx(QueryBuilderDrawer, { fields: MEMBERS_FILTER_FIELDS, value: appliedFilter, onApply: applyFilter, trigger: _jsxs(Button, { variant: "outline", className: "shadow-none", children: [_jsx(Filter, { "aria-hidden": true, className: "size-4" }), intl.formatMessage(messages.filters, {
138
- count: ruleCount
139
- })] }) }) }), !isPending && !isError && (_jsx("p", { role: "status", "aria-live": "polite", className: "sr-only", children: intl.formatMessage(messages.results, { count: total }) })), _jsx("div", { id: MEMBERS_RESULTS_ANCHOR_ID, tabIndex: -1, className: "outline-none", children: isPending ? (_jsx(MembersTableSkeleton, {})) : isError ? (_jsx(Alert, { variant: "destructive", role: "alert", className: "mt-4", children: _jsxs(AlertDescription, { className: "flex flex-wrap items-center justify-between gap-3", children: [_jsx("span", { children: intl.formatMessage(messages.error) }), _jsx(Button, { variant: "outline", size: "sm", className: "shadow-none", onClick: () => refetch(), children: intl.formatMessage(messages.retry) })] }) })) : members.length === 0 ? (_jsx(MembersEmpty, { filtered: hasFilters, onClear: clearFilters, onInvite: canInvite ? openInvite : undefined })) : (_jsxs(_Fragment, { children: [_jsx(MembersTable, { members: members }), _jsx(MembersPagination, { page: page, pageCount: pageCount, pageSize: effectivePageSize, total: total, onPageChange: (next) => updateParams({ page: String(next) }, false), onPageSizeChange: (next) => updateParams({ pageSize: String(next) }) })] })) })] })] }));
150
+ }), actions: canInvite ? (_jsxs(Button, { onClick: openInvite, children: [_jsx(UserPlus, {}), intl.formatMessage(messages.invite)] })) : undefined }), _jsx(MembersToolbar, { search: searchInput, onSearchChange: setSearchInput, busy: searchPending || isFetching, filterControl: _jsxs(Button, { ref: filtersToggleRef, id: filtersToggleId, variant: "outline", className: "shadow-none", "aria-expanded": filtersOpen, "aria-controls": filtersPanelId, onClick: () => setFiltersPanelOpen(!filtersOpen), children: [_jsx(Filter, { "aria-hidden": true, className: "size-4" }), intl.formatMessage(messages.filters, {
151
+ count: ruleCount
152
+ }), _jsx(ChevronDown, { "aria-hidden": true, className: cn('size-4 transition-transform duration-150 motion-reduce:transition-none', filtersOpen && 'rotate-180') })] }) }), _jsx(QueryBuilderPanel, { id: filtersPanelId, labelledBy: filtersToggleId, open: filtersOpen, onOpenChange: setFiltersPanelOpen, fields: MEMBERS_FILTER_FIELDS, value: appliedFilter, onApply: applyFilter }), !filtersOpen && appliedFilter && ruleCount > 0 ? (_jsx(QueryBuilderSummary, { className: "mb-4", tree: appliedFilter, fields: MEMBERS_FILTER_FIELDS, onChange: applyFilter })) : null, !isPending && !isError && (_jsx("p", { role: "status", "aria-live": "polite", className: "sr-only", children: intl.formatMessage(messages.results, { count: total }) })), _jsx("div", { id: MEMBERS_RESULTS_ANCHOR_ID, tabIndex: -1, className: "outline-none", children: isPending ? (_jsx(MembersTableSkeleton, {})) : isError ? (_jsx(Alert, { variant: "destructive", role: "alert", className: "mt-4", children: _jsxs(AlertDescription, { className: "flex flex-wrap items-center justify-between gap-3", children: [_jsx("span", { children: intl.formatMessage(messages.error) }), _jsx(Button, { variant: "outline", size: "sm", className: "shadow-none", onClick: () => refetch(), children: intl.formatMessage(messages.retry) })] }) })) : members.length === 0 ? (_jsx(MembersEmpty, { filtered: hasFilters, onClear: clearFilters, onInvite: canInvite ? openInvite : undefined })) : (_jsxs(_Fragment, { children: [_jsx(MembersTable, { members: members }), _jsx(MembersPagination, { page: page, pageCount: pageCount, pageSize: effectivePageSize, total: total, onPageChange: (next) => updateParams({ page: String(next) }, false), onPageSizeChange: (next) => updateParams({ pageSize: String(next) }) })] })) })] })] }));
140
153
  }
@@ -5,11 +5,20 @@ import type { AdminPlugin } from '@orthacms/bootstrap-admin';
5
5
  */
6
6
  export type UsersAdminPlugin = AdminPlugin;
7
7
  /**
8
- * Creates the admin-side users plugin. It owns the members feature: the
9
- * private `/users` route (the Members page, rendered inside the shell's
10
- * authenticated layout) and its toolbar nav entry, contributed to the shell's
11
- * {@link NAVBAR_START_SLOT} at `order: 30` (after Workspaces). The page itself
12
- * gates on the `users:read` permission.
8
+ * Creates the admin-side users plugin. It owns the members feature: three
9
+ * private routes — `/users` (the Members page), `/users/invite` (the invite
10
+ * wizard) and `/users/:id/*` (the member card's own nested router) — rendered
11
+ * inside the shell's authenticated layout.
12
+ *
13
+ * It contributes to two slots. The nav entry goes to {@link SIDEBAR_NAV_SLOT}
14
+ * with `group: 'directory'`, `order: 20` and `permission: 'users:read'` —
15
+ * declared so the entry disappears for someone the page would refuse, rather
16
+ * than promising a screen that answers "no access". {@link ThemeSync} and
17
+ * {@link AccountMenu} go to {@link SIDEBAR_FOOTER_SLOT}, the one region the
18
+ * shell keeps mounted in both the global and the workspace sidebar.
19
+ *
20
+ * The static `/users/invite` route is declared **before** the `/users/:id/*`
21
+ * splat, so "invite" is never parsed as a member id.
13
22
  *
14
23
  * @example
15
24
  * ```typescript
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/presentation/usersPlugin/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAgC7D;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,WAAW,CAAC;AAE3C;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,WAAW,IAAI,gBAAgB,CAiF9C"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/presentation/usersPlugin/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAgC7D;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,WAAW,CAAC;AAE3C;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,WAAW,IAAI,gBAAgB,CAiF9C"}
@@ -19,11 +19,20 @@ const UserDetailRouter = lazy(() => import('../components/UserDetailRouter').the
19
19
  default: module.UserDetailRouter
20
20
  })));
21
21
  /**
22
- * Creates the admin-side users plugin. It owns the members feature: the
23
- * private `/users` route (the Members page, rendered inside the shell's
24
- * authenticated layout) and its toolbar nav entry, contributed to the shell's
25
- * {@link NAVBAR_START_SLOT} at `order: 30` (after Workspaces). The page itself
26
- * gates on the `users:read` permission.
22
+ * Creates the admin-side users plugin. It owns the members feature: three
23
+ * private routes — `/users` (the Members page), `/users/invite` (the invite
24
+ * wizard) and `/users/:id/*` (the member card's own nested router) — rendered
25
+ * inside the shell's authenticated layout.
26
+ *
27
+ * It contributes to two slots. The nav entry goes to {@link SIDEBAR_NAV_SLOT}
28
+ * with `group: 'directory'`, `order: 20` and `permission: 'users:read'` —
29
+ * declared so the entry disappears for someone the page would refuse, rather
30
+ * than promising a screen that answers "no access". {@link ThemeSync} and
31
+ * {@link AccountMenu} go to {@link SIDEBAR_FOOTER_SLOT}, the one region the
32
+ * shell keeps mounted in both the global and the workspace sidebar.
33
+ *
34
+ * The static `/users/invite` route is declared **before** the `/users/:id/*`
35
+ * splat, so "invite" is never parsed as a member id.
27
36
  *
28
37
  * @example
29
38
  * ```typescript
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orthacms/users-admin",
3
- "version": "0.4.2",
3
+ "version": "0.5.1",
4
4
  "description": "@orthacms/users-admin — part of Ortha CMS.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://github.com/ortha-source/ortha-cms/tree/main/packages/users/admin",
@@ -25,13 +25,13 @@
25
25
  "dist"
26
26
  ],
27
27
  "dependencies": {
28
- "@orthacms/activity-admin": "^0.4.2",
29
- "@orthacms/bootstrap-admin": "^0.4.2",
30
- "@orthacms/design-system": "^0.4.2",
31
- "@orthacms/identity-admin": "^0.4.2",
32
- "@orthacms/query-builder-admin": "^0.4.2",
33
- "@orthacms/shell-admin": "^0.4.2",
34
- "@orthacms/utils-admin": "^0.4.2",
28
+ "@orthacms/activity-admin": "^0.5.1",
29
+ "@orthacms/bootstrap-admin": "^0.5.1",
30
+ "@orthacms/design-system": "^0.5.1",
31
+ "@orthacms/identity-admin": "^0.5.1",
32
+ "@orthacms/query-builder-admin": "^0.5.1",
33
+ "@orthacms/shell-admin": "^0.5.1",
34
+ "@orthacms/utils-admin": "^0.5.1",
35
35
  "@tanstack/react-form": "^1.0.0",
36
36
  "@tanstack/react-query": "^5.0.0",
37
37
  "lucide-react": "^1.17.0",
@@ -1,16 +0,0 @@
1
- import { type ApiError } from '@ortha-cms/utils-admin';
2
- /** Identifies the membership to create: which member, which workspace. */
3
- export type AddWorkspaceMemberInput = {
4
- /** The member being added. */
5
- userId: string;
6
- /** The workspace to add them to. */
7
- workspaceId: string;
8
- };
9
- /**
10
- * Adds a member to a workspace from the Workspaces tab. The endpoint is
11
- * idempotent (re-adding is a no-op). Invalidates the member's detail (its
12
- * `workspaces` list) and the members list (its Workspaces column) on success.
13
- * Errors normalize to {@link ApiError}.
14
- */
15
- export declare function useAddWorkspaceMember(): import("@tanstack/react-query").UseMutationResult<void, ApiError, AddWorkspaceMemberInput, unknown>;
16
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/api/useAddWorkspaceMember/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAyB,KAAK,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAG9E,0EAA0E;AAC1E,MAAM,MAAM,uBAAuB,GAAG;IAClC,8BAA8B;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,oCAAoC;IACpC,WAAW,EAAE,MAAM,CAAC;CACvB,CAAC;AAUF;;;;;GAKG;AACH,wBAAgB,qBAAqB,wGAcpC"}
@@ -1,17 +0,0 @@
1
- import type { Member, MemberRole } from '../../types/member';
2
- /** The shape the invite form submits. */
3
- export type InviteMemberInput = {
4
- email: string;
5
- role: MemberRole;
6
- name?: string;
7
- /** Workspaces to grant the new member access to (optional). */
8
- workspaceIds?: string[];
9
- };
10
- /**
11
- * Invites a person by email. Errors are normalized to `ApiError` so the dialog
12
- * can branch on `HTTP_STATUS.CONFLICT` (email already taken); every page of the
13
- * members cache is refreshed on success — the new "Invited" row may land on any
14
- * page.
15
- */
16
- export declare function useInviteMember(): import("@tanstack/react-query").UseMutationResult<Member, import("@ortha-cms/utils-admin").ApiError, InviteMemberInput, unknown>;
17
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/api/useInviteMember/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAI7D,yCAAyC;AACzC,MAAM,MAAM,iBAAiB,GAAG;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+DAA+D;IAC/D,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B,CAAC;AAWF;;;;;GAKG;AACH,wBAAgB,eAAe,qIAE9B"}
@@ -1,15 +0,0 @@
1
- import type { MemberList } from '../../types/member';
2
- import { type MembersListParams } from '../../utils/membersKeys';
3
- /**
4
- * Page size the server applies when none is requested. Mirrors the server's
5
- * `DEFAULT_PAGE_SIZE`; used only as a fallback for the page-count math before
6
- * the first response lands.
7
- */
8
- export declare const DEFAULT_PAGE_SIZE = 10;
9
- /**
10
- * Fetches one page of members. `keepPreviousData` holds the current rows on
11
- * screen while a new page or search resolves, so the table doesn't flash
12
- * empty between pages. Disabled until the caller confirms `users:read`.
13
- */
14
- export declare function useMembers(params: MembersListParams, enabled?: boolean): import("@tanstack/react-query").UseQueryResult<NoInfer<MemberList>, Error>;
15
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/api/useMembers/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAe,KAAK,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAG9E;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,KAAK,CAAC;AAuBpC;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,iBAAiB,EAAE,OAAO,UAAO,8EAOnE"}
@@ -1,13 +0,0 @@
1
- import { type ApiError } from '@ortha-cms/utils-admin';
2
- /**
3
- * Shared shell for the member mutations. Every member mutation normalizes its
4
- * transport error to {@link ApiError} (so dialogs can branch on
5
- * `HTTP_STATUS.CONFLICT`) and, by default, invalidates the whole members cache
6
- * on success (an added/changed/removed row may land on any page). The one
7
- * exception is "resend invite", which changes no list-visible field — it opts
8
- * out with `invalidate: false`. Each hook is then just its request function.
9
- */
10
- export declare function useMembersMutation<TInput, TResult>(mutationFn: (input: TInput) => Promise<TResult>, { invalidate }?: {
11
- invalidate?: boolean;
12
- }): import("@tanstack/react-query").UseMutationResult<TResult, ApiError, TInput, unknown>;
13
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/api/useMembersMutation/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAc,KAAK,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAGnE;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,OAAO,EAC9C,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,EAC/C,EAAE,UAAiB,EAAE,GAAE;IAAE,UAAU,CAAC,EAAE,OAAO,CAAA;CAAO,yFAevD"}
@@ -1,15 +0,0 @@
1
- import { type ApiError } from '@ortha-cms/utils-admin';
2
- /** Identifies the membership to remove: which member, which workspace. */
3
- export type RemoveWorkspaceMemberInput = {
4
- /** The member being removed. */
5
- userId: string;
6
- /** The workspace to remove them from. */
7
- workspaceId: string;
8
- };
9
- /**
10
- * Removes a member from a workspace from the Workspaces tab. Invalidates the
11
- * member's detail (its `workspaces` list) and the members list (its Workspaces
12
- * column) on success. Errors normalize to {@link ApiError}.
13
- */
14
- export declare function useRemoveWorkspaceMember(): import("@tanstack/react-query").UseMutationResult<void, ApiError, RemoveWorkspaceMemberInput, unknown>;
15
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/api/useRemoveWorkspaceMember/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAyB,KAAK,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAG9E,0EAA0E;AAC1E,MAAM,MAAM,0BAA0B,GAAG;IACrC,gCAAgC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,yCAAyC;IACzC,WAAW,EAAE,MAAM,CAAC;CACvB,CAAC;AAUF;;;;GAIG;AACH,wBAAgB,wBAAwB,2GAcvC"}
@@ -1,8 +0,0 @@
1
- import type { Member } from '../../types/member';
2
- /**
3
- * Re-sends a pending member's invite (the server rotates the token,
4
- * invalidating the previous link). No cache invalidation — the row itself is
5
- * unchanged. Errors normalize to `ApiError`.
6
- */
7
- export declare function useResendInvite(): import("@tanstack/react-query").UseMutationResult<Member, import("@ortha-cms/utils-admin").ApiError, string, unknown>;
8
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/api/useResendInvite/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAYjD;;;;GAIG;AACH,wBAAgB,eAAe,0HAI9B"}
@@ -1,7 +0,0 @@
1
- /**
2
- * Revokes a pending invite — the row disappears from the list (the server
3
- * deletes the placeholder account). Invalidates the members cache on
4
- * success. Errors normalize to `ApiError`.
5
- */
6
- export declare function useRevokeInvite(): import("@tanstack/react-query").UseMutationResult<void, import("@ortha-cms/utils-admin").ApiError, string, unknown>;
7
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/api/useRevokeInvite/index.ts"],"names":[],"mappings":"AAQA;;;;GAIG;AACH,wBAAgB,eAAe,wHAE9B"}
@@ -1,15 +0,0 @@
1
- import { type ApiError } from '@ortha-cms/utils-admin';
2
- /** Identifies the session to revoke: whose, and which. */
3
- export type RevokeSessionInput = {
4
- /** The member who owns the session. */
5
- userId: string;
6
- /** The session row id to revoke. */
7
- sessionId: string;
8
- };
9
- /**
10
- * Revokes a member's session from the Sessions tab. Invalidates that member's
11
- * sessions query on success so the revoked row drops off. Errors normalize to
12
- * {@link ApiError}.
13
- */
14
- export declare function useRevokeSession(): import("@tanstack/react-query").UseMutationResult<void, ApiError, RevokeSessionInput, unknown>;
15
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/api/useRevokeSession/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAyB,KAAK,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAG9E,0DAA0D;AAC1D,MAAM,MAAM,kBAAkB,GAAG;IAC7B,uCAAuC;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,oCAAoC;IACpC,SAAS,EAAE,MAAM,CAAC;CACrB,CAAC;AAUF;;;;GAIG;AACH,wBAAgB,gBAAgB,mGAa/B"}
@@ -1,15 +0,0 @@
1
- import type { Member } from '../../types/member';
2
- /** Input for {@link useSetMemberStatus}: who, and which way to flip. */
3
- export type SetMemberStatusInput = {
4
- /** The member to update. */
5
- id: string;
6
- /** `true` disables the account, `false` re-enables it. */
7
- disabled: boolean;
8
- };
9
- /**
10
- * Disables or re-enables a member's account from the row menu. One hook for
11
- * the pair — the menu renders exactly one of the two actions per row, and
12
- * both invalidate the same cache. Errors normalize to `ApiError`.
13
- */
14
- export declare function useSetMemberStatus(): import("@tanstack/react-query").UseMutationResult<Member, import("@ortha-cms/utils-admin").ApiError, SetMemberStatusInput, unknown>;
15
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/api/useSetMemberStatus/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAIjD,wEAAwE;AACxE,MAAM,MAAM,oBAAoB,GAAG;IAC/B,4BAA4B;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,0DAA0D;IAC1D,QAAQ,EAAE,OAAO,CAAC;CACrB,CAAC;AAkBF;;;;GAIG;AACH,wBAAgB,kBAAkB,wIAIjC"}
@@ -1,15 +0,0 @@
1
- import type { Member, MemberRole } from '../../types/member';
2
- /** A partial member edit; omitted fields are left unchanged. */
3
- export type UpdateMemberInput = {
4
- id: string;
5
- name?: string;
6
- role?: MemberRole;
7
- };
8
- /**
9
- * Edits a member's name and/or role (the inline role select and the Edit
10
- * dialog both submit through here). Errors normalize to `ApiError` —
11
- * `HTTP_STATUS.CONFLICT` means the last-admin guardrail (or the self-role
12
- * guard) rejected the change. Invalidates the members cache on success.
13
- */
14
- export declare function useUpdateMember(): import("@tanstack/react-query").UseMutationResult<Member, import("@ortha-cms/utils-admin").ApiError, UpdateMemberInput, unknown>;
15
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/api/useUpdateMember/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAI7D,gEAAgE;AAChE,MAAM,MAAM,iBAAiB,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,UAAU,CAAC;CACrB,CAAC;AAYF;;;;;GAKG;AACH,wBAAgB,eAAe,qIAE9B"}
@@ -1,9 +0,0 @@
1
- import type { Member } from '../../types/member';
2
- /**
3
- * Fetches a single member for the user detail page. The result is shared with
4
- * every tab via the route's Outlet context, so the tabs never re-fetch. A 404
5
- * (unknown/deleted member) surfaces as the query's error so the layout can show
6
- * a not-found state. Disabled until the caller confirms `users:read`.
7
- */
8
- export declare function useUserDetail(id: string, enabled?: boolean): import("@tanstack/react-query").UseQueryResult<NoInfer<Member>, Error>;
9
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/api/useUserDetail/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAkBjD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,UAAO,0EAMvD"}
@@ -1,25 +0,0 @@
1
- /** A live session as the detail page's Sessions tab renders it. */
2
- export type UserSession = {
3
- /** Revocation handle (the session row id). */
4
- id: string;
5
- /** Originating `User-Agent`, or `null` if it was never captured. */
6
- userAgent: string | null;
7
- /** Originating IP, or `null` if it was never captured. */
8
- ipAddress: string | null;
9
- /** When the session was opened. */
10
- createdAt: Date;
11
- /** Last authenticated request seen on this session. */
12
- lastSeenAt: Date;
13
- /** Absolute expiry. */
14
- expiresAt: Date;
15
- /** Whether this is the viewer's own session (never revocable from here). */
16
- current: boolean;
17
- };
18
- /**
19
- * Fetches the live sessions for a member (the Sessions tab). `staleTime: 0` so
20
- * a session that has since expired or been revoked elsewhere drops off on the
21
- * next mount/refocus rather than lingering. Gated on `users:update` (the tab
22
- * is only shown to admins who can act on what they see).
23
- */
24
- export declare function useUserSessions(id: string, enabled?: boolean): import("@tanstack/react-query").UseQueryResult<NoInfer<UserSession[]>, Error>;
25
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/api/useUserSessions/index.ts"],"names":[],"mappings":"AAIA,mEAAmE;AACnE,MAAM,MAAM,WAAW,GAAG;IACtB,8CAA8C;IAC9C,EAAE,EAAE,MAAM,CAAC;IACX,oEAAoE;IACpE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,0DAA0D;IAC1D,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,mCAAmC;IACnC,SAAS,EAAE,IAAI,CAAC;IAChB,uDAAuD;IACvD,UAAU,EAAE,IAAI,CAAC;IACjB,uBAAuB;IACvB,SAAS,EAAE,IAAI,CAAC;IAChB,4EAA4E;IAC5E,OAAO,EAAE,OAAO,CAAC;CACpB,CAAC;AAkCF;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,UAAO,iFAOzD"}
@@ -1,18 +0,0 @@
1
- import type { AvatarColor } from '@ortha-cms/design-system';
2
- /** A workspace as the invite wizard's assignment step renders it. */
3
- export type WorkspaceOption = {
4
- id: string;
5
- name: string;
6
- description: string | null;
7
- initials: string;
8
- color: AvatarColor;
9
- };
10
- /** Query key for the workspace options list. */
11
- export declare const workspaceOptionsKey: readonly ["workspaces", "options"];
12
- /**
13
- * Lists every workspace (via the shared `GET /api/workspaces`) for the invite
14
- * wizard's "assign workspaces" step. `enabled` defers the fetch until the step
15
- * is reached.
16
- */
17
- export declare function useWorkspaceOptions(enabled?: boolean): import("@tanstack/react-query").UseQueryResult<NoInfer<WorkspaceOption[]>, Error>;
18
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/api/useWorkspaceOptions/index.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAE5D,qEAAqE;AACrE,MAAM,MAAM,eAAe,GAAG;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,WAAW,CAAC;CACtB,CAAC;AAUF,gDAAgD;AAChD,eAAO,MAAM,mBAAmB,oCAAqC,CAAC;AAkBtE;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,UAAO,qFAOjD"}
@@ -1,9 +0,0 @@
1
- /**
2
- * The account widget pinned to the sidebar footer: a full-width row showing the
3
- * signed-in user's avatar, name, and email that opens a menu with a link to
4
- * their own profile (the user detail page) and a Logout action. Contributed to
5
- * the shell's `SIDEBAR_FOOTER_SLOT`. Renders nothing until a user is resolved,
6
- * so it never flashes an empty row during the auth probe.
7
- */
8
- export declare function AccountMenu(): import("react").JSX.Element | null;
9
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/AccountMenu/index.tsx"],"names":[],"mappings":"AAgCA;;;;;;GAMG;AACH,wBAAgB,WAAW,uCA6D1B"}
@@ -1,19 +0,0 @@
1
- /**
2
- * A modal to add the member to one or more workspaces. Lists every workspace
3
- * they're not already in (via the shared `GET /api/workspaces`), with a search
4
- * filter and multi-select. The parent runs the actual additions and owns
5
- * `busy`; the dialog stays open and non-dismissable until they settle.
6
- */
7
- export declare function AddToWorkspacesDialog({ open, onOpenChange, existingIds, busy, onAdd }: {
8
- /** Whether the dialog is shown. */
9
- open: boolean;
10
- /** Open/close handler; ignored while busy. */
11
- onOpenChange: (open: boolean) => void;
12
- /** Workspace ids the member already belongs to (excluded from the list). */
13
- existingIds: ReadonlyArray<string>;
14
- /** Whether additions are in flight. */
15
- busy?: boolean;
16
- /** Called with the chosen workspace ids. */
17
- onAdd: (workspaceIds: string[]) => void;
18
- }): import("react").JSX.Element;
19
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/AddToWorkspacesDialog/index.tsx"],"names":[],"mappings":"AAkDA;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,EAClC,IAAI,EACJ,YAAY,EACZ,WAAW,EACX,IAAY,EACZ,KAAK,EACR,EAAE;IACC,mCAAmC;IACnC,IAAI,EAAE,OAAO,CAAC;IACd,8CAA8C;IAC9C,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,4EAA4E;IAC5E,WAAW,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACnC,uCAAuC;IACvC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,4CAA4C;IAC5C,KAAK,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;CAC3C,+BAuJA"}
@@ -1,14 +0,0 @@
1
- /**
2
- * A muted "back" link with a leading arrow — the detail page's return path to
3
- * the members roster. The arrow is decorative; the text label carries the
4
- * destination for assistive tech.
5
- */
6
- export declare function BackLink({ to, label, className }: {
7
- /** Destination path. */
8
- to: string;
9
- /** Visible, accessible label (e.g. "Back to members"). */
10
- label: string;
11
- /** Extra classes. */
12
- className?: string;
13
- }): import("react").JSX.Element;
14
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/BackLink/index.tsx"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,EACrB,EAAE,EACF,KAAK,EACL,SAAS,EACZ,EAAE;IACC,wBAAwB;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAC;IACd,qBAAqB;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB,+BAaA"}
@@ -1,30 +0,0 @@
1
- import type { ReactNode } from 'react';
2
- import { type ButtonProps } from '@ortha-cms/design-system';
3
- /**
4
- * A small confirm/cancel modal for the detail page's reversible actions (revoke
5
- * a session, remove a workspace, change a role, suspend an account). The parent
6
- * owns `open` and runs the action on `onConfirm`; while `busy`, the dialog can't
7
- * be dismissed and the confirm button shows a spinner, so a double-submit can't
8
- * fire a second request.
9
- */
10
- export declare function ConfirmDialog({ open, onOpenChange, title, description, confirmLabel, cancelLabel, confirmVariant, busy, onConfirm }: {
11
- /** Whether the dialog is shown. */
12
- open: boolean;
13
- /** Called to open/close; ignored while busy. */
14
- onOpenChange: (open: boolean) => void;
15
- /** Heading. */
16
- title: ReactNode;
17
- /** Supporting copy. */
18
- description: ReactNode;
19
- /** Confirm button label. */
20
- confirmLabel: ReactNode;
21
- /** Cancel button label; defaults to a translated "Cancel". */
22
- cancelLabel?: ReactNode;
23
- /** Confirm button variant (e.g. `destructive` for irreversible-feeling acts). */
24
- confirmVariant?: ButtonProps['variant'];
25
- /** Disables dismissal and shows a spinner on confirm while the act is in flight. */
26
- busy?: boolean;
27
- /** Runs the confirmed action. */
28
- onConfirm: () => void;
29
- }): import("react").JSX.Element;
30
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/ConfirmDialog/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,EASH,KAAK,WAAW,EACnB,MAAM,0BAA0B,CAAC;AAUlC;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,EAC1B,IAAI,EACJ,YAAY,EACZ,KAAK,EACL,WAAW,EACX,YAAY,EACZ,WAAW,EACX,cAA0B,EAC1B,IAAY,EACZ,SAAS,EACZ,EAAE;IACC,mCAAmC;IACnC,IAAI,EAAE,OAAO,CAAC;IACd,gDAAgD;IAChD,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,eAAe;IACf,KAAK,EAAE,SAAS,CAAC;IACjB,uBAAuB;IACvB,WAAW,EAAE,SAAS,CAAC;IACvB,4BAA4B;IAC5B,YAAY,EAAE,SAAS,CAAC;IACxB,8DAA8D;IAC9D,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,iFAAiF;IACjF,cAAc,CAAC,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;IACxC,oFAAoF;IACpF,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,iCAAiC;IACjC,SAAS,EAAE,MAAM,IAAI,CAAC;CACzB,+BAqCA"}
@@ -1,21 +0,0 @@
1
- import { type RefObject } from 'react';
2
- import type { Member } from '../../types/member';
3
- type EditMemberDialogProps = {
4
- /** The member being edited; `null` keeps the dialog closed. */
5
- member: Member | null;
6
- onOpenChange: (open: boolean) => void;
7
- /**
8
- * Element to return focus to when the dialog closes. The row menu that
9
- * opened it has already closed, so the page supplies a stable target.
10
- */
11
- restoreFocusRef?: RefObject<HTMLElement | null>;
12
- };
13
- /**
14
- * The edit-member modal: display name and role. The role select locks for the
15
- * sole active admin (with the rationale shown inline); a 409 — a demotion
16
- * that raced past the guard — surfaces as an alert. Closes with a toast on
17
- * success.
18
- */
19
- export declare function EditMemberDialog({ member, onOpenChange, restoreFocusRef }: EditMemberDialogProps): import("react").JSX.Element;
20
- export {};
21
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/EditMemberDialog/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AA8BhD,OAAO,KAAK,EAAE,MAAM,EAAc,MAAM,oBAAoB,CAAC;AAsE7D,KAAK,qBAAqB,GAAG;IACzB,+DAA+D;IAC/D,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC;;;OAGG;IACH,eAAe,CAAC,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;CACnD,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,EAC7B,MAAM,EACN,YAAY,EACZ,eAAe,EAClB,EAAE,qBAAqB,+BAoCvB"}
@@ -1,24 +0,0 @@
1
- import type { CSSProperties } from 'react';
2
- import { type AvatarColor } from '@ortha-cms/design-system';
3
- type MemberAvatarProps = {
4
- /** Initials rendered as the avatar content. */
5
- initials: string;
6
- /** Accent color tinting the avatar background. */
7
- color: AvatarColor;
8
- /** Extra classes (size, border). */
9
- className?: string;
10
- /** Extra inline styles (e.g. overlap margin in a stack). */
11
- style?: CSSProperties;
12
- };
13
- /**
14
- * An initials avatar tinted with one of the shared accent colors — members in
15
- * the table, and the smaller workspace chips in the Workspaces column, both
16
- * sized via `className`. Shape comes from the design-system `Avatar` default
17
- * (rounded square). Purely decorative: the member/workspace
18
- * name is always rendered as adjacent text (or an `aria-label` on the
19
- * enclosing control), so the initials are hidden from assistive tech to avoid
20
- * a meaningless "J D A B" reading.
21
- */
22
- export declare function MemberAvatar({ initials, color, className, style }: MemberAvatarProps): import("react").JSX.Element;
23
- export {};
24
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/MemberAvatar/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAC3C,OAAO,EAKH,KAAK,WAAW,EACnB,MAAM,0BAA0B,CAAC;AAElC,KAAK,iBAAiB,GAAG;IACrB,+CAA+C;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB,kDAAkD;IAClD,KAAK,EAAE,WAAW,CAAC;IACnB,oCAAoC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4DAA4D;IAC5D,KAAK,CAAC,EAAE,aAAa,CAAC;CACzB,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,EACzB,QAAQ,EACR,KAAK,EACL,SAAS,EACT,KAAK,EACR,EAAE,iBAAiB,+BAYnB"}