@orthacms/users-admin 0.0.0-reserve.0

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 (328) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +7 -0
  3. package/dist/index.d.ts +6 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +3 -0
  6. package/dist/lib/api/useAddWorkspaceMember/index.d.ts +16 -0
  7. package/dist/lib/api/useAddWorkspaceMember/index.d.ts.map +1 -0
  8. package/dist/lib/api/useInviteMember/index.d.ts +17 -0
  9. package/dist/lib/api/useInviteMember/index.d.ts.map +1 -0
  10. package/dist/lib/api/useMembers/index.d.ts +15 -0
  11. package/dist/lib/api/useMembers/index.d.ts.map +1 -0
  12. package/dist/lib/api/useMembersMutation/index.d.ts +13 -0
  13. package/dist/lib/api/useMembersMutation/index.d.ts.map +1 -0
  14. package/dist/lib/api/useRemoveWorkspaceMember/index.d.ts +15 -0
  15. package/dist/lib/api/useRemoveWorkspaceMember/index.d.ts.map +1 -0
  16. package/dist/lib/api/useResendInvite/index.d.ts +8 -0
  17. package/dist/lib/api/useResendInvite/index.d.ts.map +1 -0
  18. package/dist/lib/api/useRevokeInvite/index.d.ts +7 -0
  19. package/dist/lib/api/useRevokeInvite/index.d.ts.map +1 -0
  20. package/dist/lib/api/useRevokeSession/index.d.ts +15 -0
  21. package/dist/lib/api/useRevokeSession/index.d.ts.map +1 -0
  22. package/dist/lib/api/useSetMemberStatus/index.d.ts +15 -0
  23. package/dist/lib/api/useSetMemberStatus/index.d.ts.map +1 -0
  24. package/dist/lib/api/useUpdateMember/index.d.ts +15 -0
  25. package/dist/lib/api/useUpdateMember/index.d.ts.map +1 -0
  26. package/dist/lib/api/useUserDetail/index.d.ts +9 -0
  27. package/dist/lib/api/useUserDetail/index.d.ts.map +1 -0
  28. package/dist/lib/api/useUserSessions/index.d.ts +25 -0
  29. package/dist/lib/api/useUserSessions/index.d.ts.map +1 -0
  30. package/dist/lib/api/useWorkspaceOptions/index.d.ts +18 -0
  31. package/dist/lib/api/useWorkspaceOptions/index.d.ts.map +1 -0
  32. package/dist/lib/application/useAddWorkspaceMember/index.d.ts +11 -0
  33. package/dist/lib/application/useAddWorkspaceMember/index.d.ts.map +1 -0
  34. package/dist/lib/application/useAddWorkspaceMember/index.js +21 -0
  35. package/dist/lib/application/useInviteMember/index.d.ts +12 -0
  36. package/dist/lib/application/useInviteMember/index.d.ts.map +1 -0
  37. package/dist/lib/application/useInviteMember/index.js +12 -0
  38. package/dist/lib/application/useInviteMemberFlow/index.d.ts +59 -0
  39. package/dist/lib/application/useInviteMemberFlow/index.d.ts.map +1 -0
  40. package/dist/lib/application/useInviteMemberFlow/index.js +47 -0
  41. package/dist/lib/application/useIssuePasswordReset/index.d.ts +12 -0
  42. package/dist/lib/application/useIssuePasswordReset/index.d.ts.map +1 -0
  43. package/dist/lib/application/useIssuePasswordReset/index.js +14 -0
  44. package/dist/lib/application/useMembers/index.d.ts +15 -0
  45. package/dist/lib/application/useMembers/index.d.ts.map +1 -0
  46. package/dist/lib/application/useMembers/index.js +23 -0
  47. package/dist/lib/application/useMembersMutation/index.d.ts +14 -0
  48. package/dist/lib/application/useMembersMutation/index.d.ts.map +1 -0
  49. package/dist/lib/application/useMembersMutation/index.js +25 -0
  50. package/dist/lib/application/usePreferences/index.d.ts +15 -0
  51. package/dist/lib/application/usePreferences/index.d.ts.map +1 -0
  52. package/dist/lib/application/usePreferences/index.js +28 -0
  53. package/dist/lib/application/useRemoveWorkspaceMember/index.d.ts +10 -0
  54. package/dist/lib/application/useRemoveWorkspaceMember/index.d.ts.map +1 -0
  55. package/dist/lib/application/useRemoveWorkspaceMember/index.js +20 -0
  56. package/dist/lib/application/useResendInvite/index.d.ts +10 -0
  57. package/dist/lib/application/useResendInvite/index.d.ts.map +1 -0
  58. package/dist/lib/application/useResendInvite/index.js +12 -0
  59. package/dist/lib/application/useRevokeInvite/index.d.ts +7 -0
  60. package/dist/lib/application/useRevokeInvite/index.d.ts.map +1 -0
  61. package/dist/lib/application/useRevokeInvite/index.js +10 -0
  62. package/dist/lib/application/useRevokeSession/index.d.ts +10 -0
  63. package/dist/lib/application/useRevokeSession/index.d.ts.map +1 -0
  64. package/dist/lib/application/useRevokeSession/index.js +19 -0
  65. package/dist/lib/application/useSetMemberStatus/index.d.ts +11 -0
  66. package/dist/lib/application/useSetMemberStatus/index.d.ts.map +1 -0
  67. package/dist/lib/application/useSetMemberStatus/index.js +11 -0
  68. package/dist/lib/application/useUpdateMember/index.d.ts +11 -0
  69. package/dist/lib/application/useUpdateMember/index.d.ts.map +1 -0
  70. package/dist/lib/application/useUpdateMember/index.js +11 -0
  71. package/dist/lib/application/useUpdateTheme/index.d.ts +14 -0
  72. package/dist/lib/application/useUpdateTheme/index.d.ts.map +1 -0
  73. package/dist/lib/application/useUpdateTheme/index.js +25 -0
  74. package/dist/lib/application/useUserDetail/index.d.ts +9 -0
  75. package/dist/lib/application/useUserDetail/index.d.ts.map +1 -0
  76. package/dist/lib/application/useUserDetail/index.js +17 -0
  77. package/dist/lib/application/useUserSessions/index.d.ts +9 -0
  78. package/dist/lib/application/useUserSessions/index.d.ts.map +1 -0
  79. package/dist/lib/application/useUserSessions/index.js +17 -0
  80. package/dist/lib/application/useWorkspaceOptions/index.d.ts +10 -0
  81. package/dist/lib/application/useWorkspaceOptions/index.d.ts.map +1 -0
  82. package/dist/lib/application/useWorkspaceOptions/index.js +17 -0
  83. package/dist/lib/components/AccountMenu/index.d.ts +9 -0
  84. package/dist/lib/components/AccountMenu/index.d.ts.map +1 -0
  85. package/dist/lib/components/AddToWorkspacesDialog/index.d.ts +19 -0
  86. package/dist/lib/components/AddToWorkspacesDialog/index.d.ts.map +1 -0
  87. package/dist/lib/components/BackLink/index.d.ts +14 -0
  88. package/dist/lib/components/BackLink/index.d.ts.map +1 -0
  89. package/dist/lib/components/ConfirmDialog/index.d.ts +30 -0
  90. package/dist/lib/components/ConfirmDialog/index.d.ts.map +1 -0
  91. package/dist/lib/components/EditMemberDialog/index.d.ts +21 -0
  92. package/dist/lib/components/EditMemberDialog/index.d.ts.map +1 -0
  93. package/dist/lib/components/MemberAvatar/index.d.ts +24 -0
  94. package/dist/lib/components/MemberAvatar/index.d.ts.map +1 -0
  95. package/dist/lib/components/MembersEmpty/index.d.ts +16 -0
  96. package/dist/lib/components/MembersEmpty/index.d.ts.map +1 -0
  97. package/dist/lib/components/MembersNoAccess/index.d.ts +7 -0
  98. package/dist/lib/components/MembersNoAccess/index.d.ts.map +1 -0
  99. package/dist/lib/components/MembersPagination/index.d.ts +17 -0
  100. package/dist/lib/components/MembersPagination/index.d.ts.map +1 -0
  101. package/dist/lib/components/MembersSkeleton/index.d.ts +32 -0
  102. package/dist/lib/components/MembersSkeleton/index.d.ts.map +1 -0
  103. package/dist/lib/components/MembersTable/MemberRoleChip/index.d.ts +10 -0
  104. package/dist/lib/components/MembersTable/MemberRoleChip/index.d.ts.map +1 -0
  105. package/dist/lib/components/MembersTable/MemberRowActions/index.d.ts +16 -0
  106. package/dist/lib/components/MembersTable/MemberRowActions/index.d.ts.map +1 -0
  107. package/dist/lib/components/MembersTable/MemberStatusBadge/index.d.ts +10 -0
  108. package/dist/lib/components/MembersTable/MemberStatusBadge/index.d.ts.map +1 -0
  109. package/dist/lib/components/MembersTable/MemberWorkspaces/index.d.ts +10 -0
  110. package/dist/lib/components/MembersTable/MemberWorkspaces/index.d.ts.map +1 -0
  111. package/dist/lib/components/MembersTable/index.d.ts +12 -0
  112. package/dist/lib/components/MembersTable/index.d.ts.map +1 -0
  113. package/dist/lib/components/MembersToolbar/index.d.ts +13 -0
  114. package/dist/lib/components/MembersToolbar/index.d.ts.map +1 -0
  115. package/dist/lib/components/RolePicker/index.d.ts +18 -0
  116. package/dist/lib/components/RolePicker/index.d.ts.map +1 -0
  117. package/dist/lib/components/SessionCard/index.d.ts +15 -0
  118. package/dist/lib/components/SessionCard/index.d.ts.map +1 -0
  119. package/dist/lib/components/UserDetailLayout/UserDetailTabs/index.d.ts +13 -0
  120. package/dist/lib/components/UserDetailLayout/UserDetailTabs/index.d.ts.map +1 -0
  121. package/dist/lib/components/UserDetailLayout/UserHero/index.d.ts +10 -0
  122. package/dist/lib/components/UserDetailLayout/UserHero/index.d.ts.map +1 -0
  123. package/dist/lib/components/UserDetailLayout/UserSideRail/index.d.ts +12 -0
  124. package/dist/lib/components/UserDetailLayout/UserSideRail/index.d.ts.map +1 -0
  125. package/dist/lib/components/UserDetailLayout/UserStatsStrip/index.d.ts +10 -0
  126. package/dist/lib/components/UserDetailLayout/UserStatsStrip/index.d.ts.map +1 -0
  127. package/dist/lib/components/UserDetailLayout/index.d.ts +13 -0
  128. package/dist/lib/components/UserDetailLayout/index.d.ts.map +1 -0
  129. package/dist/lib/components/UserDetailRouter/index.d.ts +13 -0
  130. package/dist/lib/components/UserDetailRouter/index.d.ts.map +1 -0
  131. package/dist/lib/components/WorkspaceMembershipCard/index.d.ts +15 -0
  132. package/dist/lib/components/WorkspaceMembershipCard/index.d.ts.map +1 -0
  133. package/dist/lib/domain/member/index.d.ts +61 -0
  134. package/dist/lib/domain/member/index.d.ts.map +1 -0
  135. package/dist/lib/domain/member/index.js +61 -0
  136. package/dist/lib/domain/types/member/index.d.ts +90 -0
  137. package/dist/lib/domain/types/member/index.d.ts.map +1 -0
  138. package/dist/lib/domain/types/member/index.js +1 -0
  139. package/dist/lib/domain/types/session/index.d.ts +18 -0
  140. package/dist/lib/domain/types/session/index.d.ts.map +1 -0
  141. package/dist/lib/domain/types/session/index.js +1 -0
  142. package/dist/lib/domain/types/workspaceOption/index.d.ts +15 -0
  143. package/dist/lib/domain/types/workspaceOption/index.d.ts.map +1 -0
  144. package/dist/lib/domain/types/workspaceOption/index.js +1 -0
  145. package/dist/lib/domain/value-objects/email/index.d.ts +24 -0
  146. package/dist/lib/domain/value-objects/email/index.d.ts.map +1 -0
  147. package/dist/lib/domain/value-objects/email/index.js +45 -0
  148. package/dist/lib/infrastructure/httpMemberGateway/index.d.ts +12 -0
  149. package/dist/lib/infrastructure/httpMemberGateway/index.d.ts.map +1 -0
  150. package/dist/lib/infrastructure/httpMemberGateway/index.js +158 -0
  151. package/dist/lib/infrastructure/inviteLink/index.d.ts +13 -0
  152. package/dist/lib/infrastructure/inviteLink/index.d.ts.map +1 -0
  153. package/dist/lib/infrastructure/inviteLink/index.js +23 -0
  154. package/dist/lib/infrastructure/memberGateway/index.d.ts +103 -0
  155. package/dist/lib/infrastructure/memberGateway/index.d.ts.map +1 -0
  156. package/dist/lib/infrastructure/memberGateway/index.js +1 -0
  157. package/dist/lib/infrastructure/memberMapper/index.d.ts +59 -0
  158. package/dist/lib/infrastructure/memberMapper/index.d.ts.map +1 -0
  159. package/dist/lib/infrastructure/memberMapper/index.js +52 -0
  160. package/dist/lib/infrastructure/membersKeys/index.d.ts +37 -0
  161. package/dist/lib/infrastructure/membersKeys/index.d.ts.map +1 -0
  162. package/dist/lib/infrastructure/membersKeys/index.js +25 -0
  163. package/dist/lib/infrastructure/passwordResetLink/index.d.ts +13 -0
  164. package/dist/lib/infrastructure/passwordResetLink/index.d.ts.map +1 -0
  165. package/dist/lib/infrastructure/passwordResetLink/index.js +24 -0
  166. package/dist/lib/infrastructure/preferencesGateway/index.d.ts +37 -0
  167. package/dist/lib/infrastructure/preferencesGateway/index.d.ts.map +1 -0
  168. package/dist/lib/infrastructure/preferencesGateway/index.js +43 -0
  169. package/dist/lib/pages/InviteMemberPage/index.d.ts +7 -0
  170. package/dist/lib/pages/InviteMemberPage/index.d.ts.map +1 -0
  171. package/dist/lib/pages/MembersPage/index.d.ts +13 -0
  172. package/dist/lib/pages/MembersPage/index.d.ts.map +1 -0
  173. package/dist/lib/pages/UserAccessPage/index.d.ts +9 -0
  174. package/dist/lib/pages/UserAccessPage/index.d.ts.map +1 -0
  175. package/dist/lib/pages/UserActivityPage/index.d.ts +8 -0
  176. package/dist/lib/pages/UserActivityPage/index.d.ts.map +1 -0
  177. package/dist/lib/pages/UserGeneralPage/index.d.ts +7 -0
  178. package/dist/lib/pages/UserGeneralPage/index.d.ts.map +1 -0
  179. package/dist/lib/pages/UserRolesPage/index.d.ts +8 -0
  180. package/dist/lib/pages/UserRolesPage/index.d.ts.map +1 -0
  181. package/dist/lib/pages/UserSessionsPage/index.d.ts +7 -0
  182. package/dist/lib/pages/UserSessionsPage/index.d.ts.map +1 -0
  183. package/dist/lib/pages/UserWorkspacesPage/index.d.ts +8 -0
  184. package/dist/lib/pages/UserWorkspacesPage/index.d.ts.map +1 -0
  185. package/dist/lib/presentation/components/AccountMenu/index.d.ts +9 -0
  186. package/dist/lib/presentation/components/AccountMenu/index.d.ts.map +1 -0
  187. package/dist/lib/presentation/components/AccountMenu/index.js +42 -0
  188. package/dist/lib/presentation/components/AddToWorkspacesDialog/index.d.ts +19 -0
  189. package/dist/lib/presentation/components/AddToWorkspacesDialog/index.d.ts.map +1 -0
  190. package/dist/lib/presentation/components/AddToWorkspacesDialog/index.js +89 -0
  191. package/dist/lib/presentation/components/BackLink/index.d.ts +14 -0
  192. package/dist/lib/presentation/components/BackLink/index.d.ts.map +1 -0
  193. package/dist/lib/presentation/components/BackLink/index.js +12 -0
  194. package/dist/lib/presentation/components/InviteLinkDialog/index.d.ts +25 -0
  195. package/dist/lib/presentation/components/InviteLinkDialog/index.d.ts.map +1 -0
  196. package/dist/lib/presentation/components/InviteLinkDialog/index.js +77 -0
  197. package/dist/lib/presentation/components/InviteLinkPanel/index.d.ts +26 -0
  198. package/dist/lib/presentation/components/InviteLinkPanel/index.d.ts.map +1 -0
  199. package/dist/lib/presentation/components/InviteLinkPanel/index.js +59 -0
  200. package/dist/lib/presentation/components/InviteSent/index.d.ts +20 -0
  201. package/dist/lib/presentation/components/InviteSent/index.d.ts.map +1 -0
  202. package/dist/lib/presentation/components/InviteSent/index.js +60 -0
  203. package/dist/lib/presentation/components/MemberAvatar/index.d.ts +24 -0
  204. package/dist/lib/presentation/components/MemberAvatar/index.d.ts.map +1 -0
  205. package/dist/lib/presentation/components/MemberAvatar/index.js +14 -0
  206. package/dist/lib/presentation/components/MembersEmpty/index.d.ts +16 -0
  207. package/dist/lib/presentation/components/MembersEmpty/index.d.ts.map +1 -0
  208. package/dist/lib/presentation/components/MembersEmpty/index.js +42 -0
  209. package/dist/lib/presentation/components/MembersNoAccess/index.d.ts +7 -0
  210. package/dist/lib/presentation/components/MembersNoAccess/index.d.ts.map +1 -0
  211. package/dist/lib/presentation/components/MembersNoAccess/index.js +24 -0
  212. package/dist/lib/presentation/components/MembersPagination/index.d.ts +17 -0
  213. package/dist/lib/presentation/components/MembersPagination/index.d.ts.map +1 -0
  214. package/dist/lib/presentation/components/MembersPagination/index.js +45 -0
  215. package/dist/lib/presentation/components/MembersSkeleton/index.d.ts +32 -0
  216. package/dist/lib/presentation/components/MembersSkeleton/index.d.ts.map +1 -0
  217. package/dist/lib/presentation/components/MembersSkeleton/index.js +61 -0
  218. package/dist/lib/presentation/components/MembersTable/MemberRoleChip/index.d.ts +17 -0
  219. package/dist/lib/presentation/components/MembersTable/MemberRoleChip/index.d.ts.map +1 -0
  220. package/dist/lib/presentation/components/MembersTable/MemberRoleChip/index.js +36 -0
  221. package/dist/lib/presentation/components/MembersTable/MemberRowActions/index.d.ts +16 -0
  222. package/dist/lib/presentation/components/MembersTable/MemberRowActions/index.d.ts.map +1 -0
  223. package/dist/lib/presentation/components/MembersTable/MemberRowActions/index.js +284 -0
  224. package/dist/lib/presentation/components/MembersTable/MemberStatusBadge/index.d.ts +10 -0
  225. package/dist/lib/presentation/components/MembersTable/MemberStatusBadge/index.d.ts.map +1 -0
  226. package/dist/lib/presentation/components/MembersTable/MemberStatusBadge/index.js +49 -0
  227. package/dist/lib/presentation/components/MembersTable/MemberWorkspaces/index.d.ts +10 -0
  228. package/dist/lib/presentation/components/MembersTable/MemberWorkspaces/index.d.ts.map +1 -0
  229. package/dist/lib/presentation/components/MembersTable/MemberWorkspaces/index.js +37 -0
  230. package/dist/lib/presentation/components/MembersTable/index.d.ts +12 -0
  231. package/dist/lib/presentation/components/MembersTable/index.d.ts.map +1 -0
  232. package/dist/lib/presentation/components/MembersTable/index.js +54 -0
  233. package/dist/lib/presentation/components/MembersTable/membersTableAnchor/index.d.ts +14 -0
  234. package/dist/lib/presentation/components/MembersTable/membersTableAnchor/index.d.ts.map +1 -0
  235. package/dist/lib/presentation/components/MembersToolbar/index.d.ts +15 -0
  236. package/dist/lib/presentation/components/MembersToolbar/index.d.ts.map +1 -0
  237. package/dist/lib/presentation/components/MembersToolbar/index.js +23 -0
  238. package/dist/lib/presentation/components/PasswordResetCard/index.d.ts +19 -0
  239. package/dist/lib/presentation/components/PasswordResetCard/index.d.ts.map +1 -0
  240. package/dist/lib/presentation/components/PasswordResetCard/index.js +109 -0
  241. package/dist/lib/presentation/components/PasswordResetLinkDialog/index.d.ts +27 -0
  242. package/dist/lib/presentation/components/PasswordResetLinkDialog/index.d.ts.map +1 -0
  243. package/dist/lib/presentation/components/PasswordResetLinkDialog/index.js +79 -0
  244. package/dist/lib/presentation/components/PasswordResetLinkPanel/index.d.ts +31 -0
  245. package/dist/lib/presentation/components/PasswordResetLinkPanel/index.d.ts.map +1 -0
  246. package/dist/lib/presentation/components/PasswordResetLinkPanel/index.js +64 -0
  247. package/dist/lib/presentation/components/RolePicker/index.d.ts +21 -0
  248. package/dist/lib/presentation/components/RolePicker/index.d.ts.map +1 -0
  249. package/dist/lib/presentation/components/RolePicker/index.js +51 -0
  250. package/dist/lib/presentation/components/SessionCard/index.d.ts +15 -0
  251. package/dist/lib/presentation/components/SessionCard/index.d.ts.map +1 -0
  252. package/dist/lib/presentation/components/SessionCard/index.js +43 -0
  253. package/dist/lib/presentation/components/ThemeSync/index.d.ts +21 -0
  254. package/dist/lib/presentation/components/ThemeSync/index.d.ts.map +1 -0
  255. package/dist/lib/presentation/components/ThemeSync/index.js +32 -0
  256. package/dist/lib/presentation/components/UserDetailLayout/UserDetailTabs/index.d.ts +15 -0
  257. package/dist/lib/presentation/components/UserDetailLayout/UserDetailTabs/index.d.ts.map +1 -0
  258. package/dist/lib/presentation/components/UserDetailLayout/UserDetailTabs/index.js +52 -0
  259. package/dist/lib/presentation/components/UserDetailLayout/UserHero/index.d.ts +10 -0
  260. package/dist/lib/presentation/components/UserDetailLayout/UserHero/index.d.ts.map +1 -0
  261. package/dist/lib/presentation/components/UserDetailLayout/UserHero/index.js +26 -0
  262. package/dist/lib/presentation/components/UserDetailLayout/UserStatsStrip/index.d.ts +10 -0
  263. package/dist/lib/presentation/components/UserDetailLayout/UserStatsStrip/index.d.ts.map +1 -0
  264. package/dist/lib/presentation/components/UserDetailLayout/UserStatsStrip/index.js +39 -0
  265. package/dist/lib/presentation/components/UserDetailLayout/index.d.ts +13 -0
  266. package/dist/lib/presentation/components/UserDetailLayout/index.d.ts.map +1 -0
  267. package/dist/lib/presentation/components/UserDetailLayout/index.js +101 -0
  268. package/dist/lib/presentation/components/UserDetailRouter/index.d.ts +16 -0
  269. package/dist/lib/presentation/components/UserDetailRouter/index.d.ts.map +1 -0
  270. package/dist/lib/presentation/components/UserDetailRouter/index.js +33 -0
  271. package/dist/lib/presentation/components/WorkspaceMembershipCard/index.d.ts +15 -0
  272. package/dist/lib/presentation/components/WorkspaceMembershipCard/index.d.ts.map +1 -0
  273. package/dist/lib/presentation/components/WorkspaceMembershipCard/index.js +27 -0
  274. package/dist/lib/presentation/membersFilterFields/index.d.ts +10 -0
  275. package/dist/lib/presentation/membersFilterFields/index.d.ts.map +1 -0
  276. package/dist/lib/presentation/membersFilterFields/index.js +67 -0
  277. package/dist/lib/presentation/membersResultsAnchor/index.d.ts +17 -0
  278. package/dist/lib/presentation/membersResultsAnchor/index.d.ts.map +1 -0
  279. package/dist/lib/presentation/membersResultsAnchor/index.js +16 -0
  280. package/dist/lib/presentation/pages/InviteMemberPage/index.d.ts +7 -0
  281. package/dist/lib/presentation/pages/InviteMemberPage/index.d.ts.map +1 -0
  282. package/dist/lib/presentation/pages/InviteMemberPage/index.js +346 -0
  283. package/dist/lib/presentation/pages/MembersPage/index.d.ts +13 -0
  284. package/dist/lib/presentation/pages/MembersPage/index.d.ts.map +1 -0
  285. package/dist/lib/presentation/pages/MembersPage/index.js +140 -0
  286. package/dist/lib/presentation/pages/UserAccessPage/index.d.ts +18 -0
  287. package/dist/lib/presentation/pages/UserAccessPage/index.d.ts.map +1 -0
  288. package/dist/lib/presentation/pages/UserAccessPage/index.js +153 -0
  289. package/dist/lib/presentation/pages/UserActivityPage/index.d.ts +8 -0
  290. package/dist/lib/presentation/pages/UserActivityPage/index.d.ts.map +1 -0
  291. package/dist/lib/presentation/pages/UserActivityPage/index.js +228 -0
  292. package/dist/lib/presentation/pages/UserGeneralPage/index.d.ts +7 -0
  293. package/dist/lib/presentation/pages/UserGeneralPage/index.d.ts.map +1 -0
  294. package/dist/lib/presentation/pages/UserGeneralPage/index.js +72 -0
  295. package/dist/lib/presentation/pages/UserPreferencesPage/ThemePreview.d.ts +11 -0
  296. package/dist/lib/presentation/pages/UserPreferencesPage/ThemePreview.d.ts.map +1 -0
  297. package/dist/lib/presentation/pages/UserPreferencesPage/ThemePreview.js +24 -0
  298. package/dist/lib/presentation/pages/UserPreferencesPage/index.d.ts +10 -0
  299. package/dist/lib/presentation/pages/UserPreferencesPage/index.d.ts.map +1 -0
  300. package/dist/lib/presentation/pages/UserPreferencesPage/index.js +148 -0
  301. package/dist/lib/presentation/pages/UserRolesPage/index.d.ts +8 -0
  302. package/dist/lib/presentation/pages/UserRolesPage/index.d.ts.map +1 -0
  303. package/dist/lib/presentation/pages/UserRolesPage/index.js +110 -0
  304. package/dist/lib/presentation/pages/UserSessionsPage/index.d.ts +7 -0
  305. package/dist/lib/presentation/pages/UserSessionsPage/index.d.ts.map +1 -0
  306. package/dist/lib/presentation/pages/UserSessionsPage/index.js +121 -0
  307. package/dist/lib/presentation/pages/UserWorkspacesPage/index.d.ts +8 -0
  308. package/dist/lib/presentation/pages/UserWorkspacesPage/index.d.ts.map +1 -0
  309. package/dist/lib/presentation/pages/UserWorkspacesPage/index.js +111 -0
  310. package/dist/lib/presentation/userDetailContext/index.d.ts +13 -0
  311. package/dist/lib/presentation/userDetailContext/index.d.ts.map +1 -0
  312. package/dist/lib/presentation/userDetailContext/index.js +5 -0
  313. package/dist/lib/presentation/usersPlugin/index.d.ts +27 -0
  314. package/dist/lib/presentation/usersPlugin/index.d.ts.map +1 -0
  315. package/dist/lib/presentation/usersPlugin/index.js +109 -0
  316. package/dist/lib/types/member/index.d.ts +63 -0
  317. package/dist/lib/types/member/index.d.ts.map +1 -0
  318. package/dist/lib/utils/membersFilterFields/index.d.ts +10 -0
  319. package/dist/lib/utils/membersFilterFields/index.d.ts.map +1 -0
  320. package/dist/lib/utils/membersKeys/index.d.ts +27 -0
  321. package/dist/lib/utils/membersKeys/index.d.ts.map +1 -0
  322. package/dist/lib/utils/toMember/index.d.ts +33 -0
  323. package/dist/lib/utils/toMember/index.d.ts.map +1 -0
  324. package/dist/lib/utils/userDetailContext/index.d.ts +13 -0
  325. package/dist/lib/utils/userDetailContext/index.d.ts.map +1 -0
  326. package/dist/lib/utils/usersPlugin/index.d.ts +27 -0
  327. package/dist/lib/utils/usersPlugin/index.d.ts.map +1 -0
  328. package/package.json +50 -0
@@ -0,0 +1,346 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ import { defineMessages, useIntl } from 'react-intl';
4
+ import { Link, Navigate } from 'react-router-dom';
5
+ import { ArrowLeft, ArrowRight, Info, Search, Users } from 'lucide-react';
6
+ import { PageTopBar } from '@orthacms/shell-admin';
7
+ import { useHasPermission } from '@orthacms/identity-admin';
8
+ import { Alert, AlertDescription, Button, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, Container, ContainerHeader, FieldGroup, InputField, InputGroup, InputGroupAddon, InputGroupInput, Label, RadioGroup, RadioGroupItem, Spinner, Stepper, WizardFooter, WizardStepCard, cn } from '@orthacms/design-system';
9
+ import { useInviteMemberFlow } from '../../../application/useInviteMemberFlow';
10
+ import { useWorkspaceOptions } from '../../../application/useWorkspaceOptions';
11
+ import { Email } from '../../../domain/value-objects/email';
12
+ import { MemberAvatar } from '../../components/MemberAvatar';
13
+ import { InviteSent } from '../../components/InviteSent';
14
+ import { WorkspaceOptionsSkeleton } from '../../components/MembersSkeleton';
15
+ import { useDocumentTitle } from '@orthacms/utils-admin';
16
+ const messages = defineMessages({
17
+ title: { id: 'users.invitePage.title', defaultMessage: 'Invite a member' },
18
+ sentTitle: {
19
+ id: 'users.invitePage.sentTitle',
20
+ defaultMessage: 'Invite created'
21
+ },
22
+ sentSubtitle: {
23
+ id: 'users.invitePage.sentSubtitle',
24
+ defaultMessage: 'One step left, and it’s yours: get the link below to them. Nobody can join without it.'
25
+ },
26
+ subtitle: {
27
+ id: 'users.invitePage.subtitle',
28
+ defaultMessage: 'Add someone to Ortha in three short steps: who they are, what they can do, and which workspaces they can reach.'
29
+ },
30
+ back: { id: 'users.invitePage.back', defaultMessage: 'Back to members' },
31
+ crumbMembers: {
32
+ id: 'users.invitePage.crumbMembers',
33
+ defaultMessage: 'Members'
34
+ },
35
+ // Rail
36
+ stepDetails: {
37
+ id: 'users.invitePage.stepDetails',
38
+ defaultMessage: 'Details'
39
+ },
40
+ stepDetailsHint: {
41
+ id: 'users.invitePage.stepDetailsHint',
42
+ defaultMessage: 'Who you’re inviting'
43
+ },
44
+ stepRole: { id: 'users.invitePage.stepRole', defaultMessage: 'Role' },
45
+ stepRoleHint: {
46
+ id: 'users.invitePage.stepRoleHint',
47
+ defaultMessage: 'What they can do'
48
+ },
49
+ stepWorkspaces: {
50
+ id: 'users.invitePage.stepWorkspaces',
51
+ defaultMessage: 'Workspaces'
52
+ },
53
+ stepWorkspacesHint: {
54
+ id: 'users.invitePage.stepWorkspacesHint',
55
+ defaultMessage: 'What they can reach'
56
+ },
57
+ stepAria: {
58
+ id: 'users.invitePage.stepAria',
59
+ defaultMessage: 'Step {number}: {label}'
60
+ },
61
+ summaryAccess: {
62
+ id: 'users.invitePage.summaryAccess',
63
+ defaultMessage: '{count, plural, =0 {No workspaces} one {# workspace} other {# workspaces}}'
64
+ },
65
+ summaryAllWorkspaces: {
66
+ id: 'users.invitePage.summaryAllWorkspaces',
67
+ defaultMessage: 'All workspaces'
68
+ },
69
+ // Step 1 — Details
70
+ detailsTitle: {
71
+ id: 'users.invitePage.detailsTitle',
72
+ defaultMessage: 'Who are you inviting?'
73
+ },
74
+ detailsDescription: {
75
+ id: 'users.invitePage.detailsDescription',
76
+ defaultMessage: 'We’ll send a join link to this address. A name is optional — they can set their own when they accept.'
77
+ },
78
+ emailLabel: { id: 'users.invitePage.emailLabel', defaultMessage: 'Email' },
79
+ emailInvalid: {
80
+ id: 'users.invitePage.emailInvalid',
81
+ defaultMessage: 'Enter a valid email address'
82
+ },
83
+ nameLabel: {
84
+ id: 'users.invitePage.nameLabel',
85
+ defaultMessage: 'Name (optional)'
86
+ },
87
+ detailsInfo: {
88
+ id: 'users.invitePage.detailsInfo',
89
+ defaultMessage: 'Until they accept the invite, they appear in the members list as “Invited” and can’t sign in. You can resend or revoke the invite anytime.'
90
+ },
91
+ continueToRole: {
92
+ id: 'users.invitePage.continueToRole',
93
+ defaultMessage: 'Continue to role'
94
+ },
95
+ // Step 2 — Role
96
+ roleTitle: {
97
+ id: 'users.invitePage.roleTitle',
98
+ defaultMessage: 'What can they do?'
99
+ },
100
+ roleDescription: {
101
+ id: 'users.invitePage.roleDescription',
102
+ defaultMessage: 'Pick the access level for this member.'
103
+ },
104
+ roleAdmin: { id: 'users.role.admin', defaultMessage: 'Admin' },
105
+ roleAdminHint: {
106
+ id: 'users.invitePage.roleAdminHint',
107
+ defaultMessage: 'Full control of Ortha. Manages members, roles, and settings, and can reach every workspace and all of its content.'
108
+ },
109
+ roleContributor: {
110
+ id: 'users.role.contributor',
111
+ defaultMessage: 'Contributor'
112
+ },
113
+ roleContributorHint: {
114
+ id: 'users.invitePage.roleContributorHint',
115
+ defaultMessage: 'Works on content — creates, edits, and publishes in the workspaces they’re assigned to. Can’t manage members or settings.'
116
+ },
117
+ roleViewer: { id: 'users.role.viewer', defaultMessage: 'Viewer' },
118
+ roleViewerHint: {
119
+ id: 'users.invitePage.roleViewerHint',
120
+ defaultMessage: 'Read-only. Browses content in assigned workspaces but can’t make changes.'
121
+ },
122
+ roleInfo: {
123
+ id: 'users.invitePage.roleInfo',
124
+ defaultMessage: 'A member has one global role that applies across Ortha — it isn’t set per workspace. You can change it later from the members list.'
125
+ },
126
+ continueToWorkspaces: {
127
+ id: 'users.invitePage.continueToWorkspaces',
128
+ defaultMessage: 'Continue to workspaces'
129
+ },
130
+ // Step 3 — Workspaces
131
+ workspacesTitle: {
132
+ id: 'users.invitePage.workspacesTitle',
133
+ defaultMessage: 'Which workspaces can they reach?'
134
+ },
135
+ workspacesDescription: {
136
+ id: 'users.invitePage.workspacesDescription',
137
+ defaultMessage: 'Give this member access to all workspaces, or pick specific ones. You can change access later.'
138
+ },
139
+ modeAllTitle: {
140
+ id: 'users.invitePage.modeAllTitle',
141
+ defaultMessage: 'All workspaces'
142
+ },
143
+ modeAllDescription: {
144
+ id: 'users.invitePage.modeAllDescription',
145
+ defaultMessage: 'Add them to every workspace ({count}). Newly created workspaces aren’t included automatically.'
146
+ },
147
+ modeSpecificTitle: {
148
+ id: 'users.invitePage.modeSpecificTitle',
149
+ defaultMessage: 'Specific workspaces'
150
+ },
151
+ modeSpecificDescription: {
152
+ id: 'users.invitePage.modeSpecificDescription',
153
+ defaultMessage: 'Choose exactly which workspaces they can reach.'
154
+ },
155
+ workspacesInfo: {
156
+ id: 'users.invitePage.workspacesInfo',
157
+ defaultMessage: 'Membership only controls which workspaces a person can reach — what they can do inside one comes from their role above. You can change access anytime from a workspace.'
158
+ },
159
+ workspacesSearch: {
160
+ id: 'users.invitePage.workspacesSearch',
161
+ defaultMessage: 'Search workspaces'
162
+ },
163
+ workspacesNoMatch: {
164
+ id: 'users.invitePage.workspacesNoMatch',
165
+ defaultMessage: 'No workspaces match your search.'
166
+ },
167
+ workspacesEmpty: {
168
+ id: 'users.invitePage.workspacesEmpty',
169
+ defaultMessage: 'There are no workspaces yet. You can invite this member now and assign access once a workspace exists.'
170
+ },
171
+ workspacesError: {
172
+ id: 'users.invitePage.workspacesError',
173
+ defaultMessage: 'Couldn’t load workspaces. Try again in a moment.'
174
+ },
175
+ selectedCount: {
176
+ id: 'users.invitePage.selectedCount',
177
+ defaultMessage: '{count, plural, =0 {None selected} one {# selected} other {# selected}}'
178
+ },
179
+ back2: { id: 'users.invitePage.backLabel', defaultMessage: 'Back' },
180
+ submit: { id: 'users.invitePage.submit', defaultMessage: 'Send invite' },
181
+ submitting: {
182
+ id: 'users.invitePage.submitting',
183
+ defaultMessage: 'Sending invite…'
184
+ },
185
+ emailTaken: {
186
+ id: 'users.invitePage.emailTaken',
187
+ defaultMessage: 'A member with this email already exists.'
188
+ },
189
+ failed: {
190
+ id: 'users.invitePage.failed',
191
+ defaultMessage: 'Couldn’t send the invite. Please try again.'
192
+ }
193
+ });
194
+ /** The two workspace-access modes, mirroring the workspace create wizard. */
195
+ const WORKSPACE_MODE_TILES = [
196
+ {
197
+ value: 'all',
198
+ title: messages.modeAllTitle,
199
+ description: messages.modeAllDescription
200
+ },
201
+ {
202
+ value: 'specific',
203
+ title: messages.modeSpecificTitle,
204
+ description: messages.modeSpecificDescription
205
+ }
206
+ ];
207
+ /** A muted, icon-led note for the extra context shown on each step. */
208
+ function InfoNote({ children }) {
209
+ return (_jsxs("div", { className: "mt-4 flex gap-2.5 rounded-xl border bg-muted/40 p-3 text-xs text-muted-foreground", children: [_jsx(Info, { "aria-hidden": true, className: "mt-0.5 size-4 shrink-0" }), _jsx("p", { children: children })] }));
210
+ }
211
+ /**
212
+ * Full-page, three-step invite wizard (Details → Role → Workspaces) at
213
+ * `/users/invite`, on the design-system wizard chrome. Gated on `users:create`
214
+ * — the server enforces the same — so a user without it is redirected.
215
+ */
216
+ export function InviteMemberPage() {
217
+ const intl = useIntl();
218
+ // Names this route in the tab strip, the window list, the history
219
+ // and a screen reader's window announcement. Every private route but
220
+ // Workspaces was still titled a bare "Admin" (WCAG 2.4.2, `ORT-140`).
221
+ useDocumentTitle(intl.formatMessage(messages.title));
222
+ const canInvite = useHasPermission('users:create');
223
+ const flow = useInviteMemberFlow();
224
+ const [step, setStep] = useState(1);
225
+ const [maxReached, setMaxReached] = useState(1);
226
+ const [email, setEmail] = useState('');
227
+ const [emailTouched, setEmailTouched] = useState(false);
228
+ const [name, setName] = useState('');
229
+ const [role, setRole] = useState('viewer');
230
+ const [selected, setSelected] = useState(new Set());
231
+ const [wsMode, setWsMode] = useState('specific');
232
+ const [wsSearch, setWsSearch] = useState('');
233
+ // Prefetch the workspace list once the user has moved past the first step.
234
+ const workspaces = useWorkspaceOptions(canInvite && maxReached >= 2);
235
+ if (!canInvite) {
236
+ return _jsx(Navigate, { to: "/users", replace: true });
237
+ }
238
+ const emailValid = Email.isValid(email.trim());
239
+ const emailError = emailTouched && !emailValid
240
+ ? intl.formatMessage(messages.emailInvalid)
241
+ : undefined;
242
+ const roles = [
243
+ {
244
+ value: 'admin',
245
+ label: intl.formatMessage(messages.roleAdmin),
246
+ hint: intl.formatMessage(messages.roleAdminHint)
247
+ },
248
+ {
249
+ value: 'contributor',
250
+ label: intl.formatMessage(messages.roleContributor),
251
+ hint: intl.formatMessage(messages.roleContributorHint)
252
+ },
253
+ {
254
+ value: 'viewer',
255
+ label: intl.formatMessage(messages.roleViewer),
256
+ hint: intl.formatMessage(messages.roleViewerHint)
257
+ }
258
+ ];
259
+ const roleLabel = roles.find((r) => r.value === role)?.label;
260
+ const options = workspaces.data ?? [];
261
+ const query = wsSearch.trim().toLowerCase();
262
+ const filteredOptions = query
263
+ ? options.filter((workspace) => workspace.name.toLowerCase().includes(query))
264
+ : options;
265
+ const goStep = (next) => {
266
+ setStep(next);
267
+ setMaxReached((m) => Math.max(m, next));
268
+ };
269
+ const toggleWorkspace = (id, checked) => {
270
+ setSelected((prev) => {
271
+ const next = new Set(prev);
272
+ if (checked) {
273
+ next.add(id);
274
+ }
275
+ else {
276
+ next.delete(id);
277
+ }
278
+ return next;
279
+ });
280
+ };
281
+ // "All" sends every workspace's id (a snapshot — memberships are explicit
282
+ // rows); "specific" sends the checked ones.
283
+ const workspaceIds = wsMode === 'all' ? options.map((w) => w.id) : [...selected];
284
+ // The use-case hook owns the orchestration (validate → invite → toast →
285
+ // navigate); this page just hands it the collected fields.
286
+ const submit = () => flow.submit({ email, role, name, workspaceIds });
287
+ const errorMessage = flow.errorReason === 'taken'
288
+ ? intl.formatMessage(messages.emailTaken)
289
+ : flow.errorReason === 'failed'
290
+ ? intl.formatMessage(messages.failed)
291
+ : null;
292
+ const railSteps = [
293
+ {
294
+ label: intl.formatMessage(messages.stepDetails),
295
+ hint: intl.formatMessage(messages.stepDetailsHint),
296
+ summary: email.trim() || undefined
297
+ },
298
+ {
299
+ label: intl.formatMessage(messages.stepRole),
300
+ hint: intl.formatMessage(messages.stepRoleHint),
301
+ summary: roleLabel
302
+ },
303
+ {
304
+ label: intl.formatMessage(messages.stepWorkspaces),
305
+ hint: intl.formatMessage(messages.stepWorkspacesHint),
306
+ optional: true,
307
+ summary: wsMode === 'all'
308
+ ? intl.formatMessage(messages.summaryAllWorkspaces)
309
+ : intl.formatMessage(messages.summaryAccess, {
310
+ count: selected.size
311
+ })
312
+ }
313
+ ];
314
+ /** The page chrome both the wizard and the sent-invite view sit inside. */
315
+ const chrome = (crumb, heading, subheading, body) => (_jsxs(_Fragment, { children: [_jsx(PageTopBar, { icon: Users, iconClassName: "bg-success-soft text-success-soft-foreground", crumbs: [
316
+ {
317
+ key: 'members',
318
+ label: intl.formatMessage(messages.crumbMembers),
319
+ to: '/users'
320
+ },
321
+ { key: 'invite', label: crumb }
322
+ ] }), _jsxs(Container, { className: "max-w-[920px]", children: [_jsxs(Link, { to: "/users", className: "mb-4 inline-flex items-center gap-1.5 text-sm text-muted-foreground transition-colors hover:text-foreground", children: [_jsx(ArrowLeft, { className: "size-4" }), intl.formatMessage(messages.back)] }), _jsx(ContainerHeader, { title: heading, subtitle: subheading }), body] })] }));
323
+ // The invite landed. Swap the wizard for the link hand-off rather than
324
+ // redirecting: the raw token is returned once, so navigating away without
325
+ // copying it means starting over with a resend.
326
+ if (flow.sent) {
327
+ return chrome(intl.formatMessage(messages.sentTitle), intl.formatMessage(messages.sentTitle), intl.formatMessage(messages.sentSubtitle), _jsx(InviteSent, { email: flow.sent.email, link: flow.sent.link, roleLabel: roleLabel ?? role }));
328
+ }
329
+ return chrome(intl.formatMessage(messages.title), intl.formatMessage(messages.title), intl.formatMessage(messages.subtitle), _jsx(_Fragment, { children: _jsxs("div", { className: "grid gap-8 lg:grid-cols-[244px_1fr]", children: [_jsx("div", { className: "lg:sticky lg:top-6 lg:self-start", children: _jsx(Stepper, { current: step, maxReached: maxReached, steps: railSteps, onStepClick: goStep, stepAriaLabel: (s, number) => intl.formatMessage(messages.stepAria, {
330
+ number,
331
+ label: s.label
332
+ }) }) }), _jsxs(WizardStepCard, { children: [step === 1 ? (_jsxs(_Fragment, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { children: intl.formatMessage(messages.detailsTitle) }), _jsx(CardDescription, { children: intl.formatMessage(messages.detailsDescription) })] }), _jsxs(CardContent, { children: [_jsxs(FieldGroup, { children: [_jsx(InputField, { id: "invite-email", type: "email", label: intl.formatMessage(messages.emailLabel), value: email, autoComplete: "off", onBlur: () => setEmailTouched(true), onChange: (event) => setEmail(event.target.value), errors: emailError
333
+ ? [{ message: emailError }]
334
+ : undefined }), _jsx(InputField, { id: "invite-name", label: intl.formatMessage(messages.nameLabel), value: name, autoComplete: "off", onChange: (event) => setName(event.target.value) })] }), _jsx(InfoNote, { children: intl.formatMessage(messages.detailsInfo) })] }), _jsx(CardFooter, { children: _jsx(WizardFooter, { primary: _jsxs(Button, { type: "button", onClick: () => goStep(2), disabled: !emailValid, children: [intl.formatMessage(messages.continueToRole), _jsx(ArrowRight, {})] }) }) })] })) : null, step === 2 ? (_jsxs(_Fragment, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { children: intl.formatMessage(messages.roleTitle) }), _jsx(CardDescription, { children: intl.formatMessage(messages.roleDescription) })] }), _jsxs(CardContent, { children: [_jsx(RadioGroup, { value: role, onValueChange: (value) => setRole(value), className: "gap-3", children: roles.map((option) => (_jsxs(Label, { htmlFor: `invite-role-${option.value}`, className: cn('flex cursor-pointer items-start gap-3 rounded-xl border p-3 transition-colors hover:bg-accent', role === option.value &&
335
+ 'border-primary'), children: [_jsx(RadioGroupItem, { id: `invite-role-${option.value}`, value: option.value, "aria-label": option.label, className: "mt-0.5" }), _jsxs("span", { className: "flex flex-col gap-0.5", children: [_jsx("span", { className: "text-sm font-medium", children: option.label }), _jsx("span", { className: "text-xs text-muted-foreground", children: option.hint })] })] }, option.value))) }), _jsx(InfoNote, { children: intl.formatMessage(messages.roleInfo) })] }), _jsx(CardFooter, { children: _jsx(WizardFooter, { onBack: () => goStep(1), backLabel: intl.formatMessage(messages.back2), primary: _jsxs(Button, { type: "button", onClick: () => goStep(3), children: [intl.formatMessage(messages.continueToWorkspaces), _jsx(ArrowRight, {})] }) }) })] })) : null, step === 3 ? (_jsxs(_Fragment, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { children: intl.formatMessage(messages.workspacesTitle) }), _jsx(CardDescription, { children: intl.formatMessage(messages.workspacesDescription) })] }), _jsxs(CardContent, { children: [workspaces.isPending ? (_jsx(WorkspaceOptionsSkeleton, {})) : workspaces.isError ? (_jsx(Alert, { variant: "destructive", children: _jsx(AlertDescription, { children: intl.formatMessage(messages.workspacesError) }) })) : options.length === 0 ? (_jsx("p", { className: "rounded-xl border border-dashed p-4 text-sm text-muted-foreground", children: intl.formatMessage(messages.workspacesEmpty) })) : (_jsxs(_Fragment, { children: [_jsx(RadioGroup, { value: wsMode, onValueChange: (value) => setWsMode(value), className: "grid gap-3 sm:grid-cols-2", children: WORKSPACE_MODE_TILES.map((tile) => (_jsxs(Label, { htmlFor: `invite-ws-mode-${tile.value}`, className: cn('flex cursor-pointer items-start gap-3 rounded-xl border p-4 transition-colors', wsMode ===
336
+ tile.value
337
+ ? 'border-primary bg-primary/5'
338
+ : 'hover:bg-accent'), children: [_jsx(RadioGroupItem, { id: `invite-ws-mode-${tile.value}`, value: tile.value, "aria-label": intl.formatMessage(tile.title), className: "mt-0.5" }), _jsxs("span", { className: "flex flex-col gap-1", children: [_jsx("span", { className: "text-sm font-medium", children: intl.formatMessage(tile.title) }), _jsx("span", { className: "text-sm text-muted-foreground", children: intl.formatMessage(tile.description, {
339
+ count: options.length
340
+ }) })] })] }, tile.value))) }), wsMode === 'specific' ? (_jsxs("div", { className: "mt-4 flex flex-col", children: [_jsxs(InputGroup, { className: "mb-3 shadow-none", children: [_jsx(InputGroupAddon, { children: _jsx(Search, {}) }), _jsx(InputGroupInput, { value: wsSearch, onChange: (event) => setWsSearch(event.target
341
+ .value), placeholder: intl.formatMessage(messages.workspacesSearch), "aria-label": intl.formatMessage(messages.workspacesSearch), autoComplete: "off" })] }), _jsx("div", { role: "group", className: "flex max-h-[320px] flex-col gap-2 overflow-y-auto", children: filteredOptions.length ===
342
+ 0 ? (_jsx("p", { className: "px-1 py-3 text-sm text-muted-foreground", children: intl.formatMessage(messages.workspacesNoMatch) })) : (filteredOptions.map((workspace) => (_jsxs(Label, { htmlFor: `invite-ws-${workspace.id}`, className: "flex cursor-pointer items-center gap-3 rounded-xl border p-3 transition-colors hover:bg-accent", children: [_jsx(Checkbox, { id: `invite-ws-${workspace.id}`, "aria-label": workspace.name, checked: selected.has(workspace.id), onCheckedChange: (checked) => toggleWorkspace(workspace.id, checked ===
343
+ true) }), _jsx(MemberAvatar, { initials: workspace.initials, color: workspace.color, className: "size-7 text-[10px]" }), _jsx("span", { className: "truncate text-sm font-medium", children: workspace.name })] }, workspace.id)))) }), _jsx("p", { className: "mt-2 text-xs text-muted-foreground", children: intl.formatMessage(messages.selectedCount, {
344
+ count: selected.size
345
+ }) })] })) : null] })), _jsx(InfoNote, { children: intl.formatMessage(messages.workspacesInfo) }), errorMessage ? (_jsx(Alert, { variant: "destructive", className: "mt-4", children: _jsx(AlertDescription, { children: errorMessage }) })) : null] }), _jsx(CardFooter, { children: _jsx(WizardFooter, { onBack: () => goStep(2), backLabel: intl.formatMessage(messages.back2), primary: _jsxs(Button, { type: "button", onClick: submit, disabled: flow.submitting, children: [flow.submitting ? (_jsxs(_Fragment, { children: [_jsx(Spinner, { "aria-hidden": true }), _jsx("span", { className: "sr-only", children: intl.formatMessage(messages.submitting) })] })) : null, intl.formatMessage(messages.submit)] }) }) })] })) : null] }, step)] }) }));
346
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * The Members management page: a searchable, filterable, paginated, and
3
+ * deep-linkable table of everyone who can sign in, with invite / edit / role /
4
+ * status controls gated on the signed-in user's `users:*` permissions. The URL
5
+ * query string is the single source of truth for search, the query-builder
6
+ * filter, and the page (via `useTableUrlState`), so a filtered view can be
7
+ * shared or bookmarked. Rendered at `/users` inside the authenticated shell.
8
+ *
9
+ * Gated on `users:read`: without it the page shows a no-access state and
10
+ * fetches nothing (the server would refuse the request anyway).
11
+ */
12
+ export declare function MembersPage(): import("react").JSX.Element;
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,140 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useCallback, useEffect, useMemo } from 'react';
3
+ import { useNavigate } from 'react-router-dom';
4
+ import { defineMessages, useIntl } from 'react-intl';
5
+ import { Filter, UserPlus, Users } from 'lucide-react';
6
+ import { PageTopBar } from '@orthacms/shell-admin';
7
+ import { QueryBuilderDrawer, countRules, jsonFilterToTree, treeToJsonFilter } from '@orthacms/query-builder-admin';
8
+ import { useHasPermission } from '@orthacms/identity-admin';
9
+ import { useTableUrlState, useDocumentTitle } from '@orthacms/utils-admin';
10
+ import { Alert, AlertDescription, Button, Container, ContainerHeader } from '@orthacms/design-system';
11
+ import { useMembers, DEFAULT_PAGE_SIZE } from '../../../application/useMembers';
12
+ import { MembersTableSkeleton } from '../../components/MembersSkeleton';
13
+ import { MembersEmpty } from '../../components/MembersEmpty';
14
+ import { MembersNoAccess } from '../../components/MembersNoAccess';
15
+ import { MembersPagination } from '../../components/MembersPagination';
16
+ import { MEMBERS_RESULTS_ANCHOR_ID } from '../../membersResultsAnchor';
17
+ import { MembersTable } from '../../components/MembersTable';
18
+ import { MembersToolbar } from '../../components/MembersToolbar';
19
+ import { MEMBERS_FILTER_FIELDS } from '../../membersFilterFields';
20
+ /** Intl descriptors for {@link MembersPage}, co-located with the component. */
21
+ const messages = defineMessages({
22
+ title: {
23
+ id: 'users.page.title',
24
+ defaultMessage: 'Members'
25
+ },
26
+ subtitle: {
27
+ id: 'users.page.subtitle',
28
+ defaultMessage: '{count, plural, one {# person} other {# people}} who can sign in to this workspace.'
29
+ },
30
+ invite: {
31
+ id: 'users.page.invite',
32
+ defaultMessage: 'Invite member'
33
+ },
34
+ error: {
35
+ id: 'users.page.error',
36
+ defaultMessage: 'Couldn’t load members. Please try again.'
37
+ },
38
+ retry: {
39
+ id: 'users.page.retry',
40
+ defaultMessage: 'Retry'
41
+ },
42
+ filters: {
43
+ id: 'users.page.filters',
44
+ defaultMessage: 'Filters{count, plural, =0 {} other { (#)}}'
45
+ },
46
+ results: {
47
+ id: 'users.page.results',
48
+ defaultMessage: '{count, plural, one {# member} other {# members}} found.'
49
+ }
50
+ });
51
+ /**
52
+ * The Members management page: a searchable, filterable, paginated, and
53
+ * deep-linkable table of everyone who can sign in, with invite / edit / role /
54
+ * status controls gated on the signed-in user's `users:*` permissions. The URL
55
+ * query string is the single source of truth for search, the query-builder
56
+ * filter, and the page (via `useTableUrlState`), so a filtered view can be
57
+ * shared or bookmarked. Rendered at `/users` inside the authenticated shell.
58
+ *
59
+ * Gated on `users:read`: without it the page shows a no-access state and
60
+ * fetches nothing (the server would refuse the request anyway).
61
+ */
62
+ export function MembersPage() {
63
+ const intl = useIntl();
64
+ // Names this route in the tab strip, the window list, the history
65
+ // and a screen reader's window announcement. Every private route but
66
+ // Workspaces was still titled a bare "Admin" (WCAG 2.4.2, `ORT-140`).
67
+ useDocumentTitle(intl.formatMessage(messages.title));
68
+ const navigate = useNavigate();
69
+ const canRead = useHasPermission('users:read');
70
+ const canInvite = useHasPermission('users:create');
71
+ const { searchParam, filterParam, page, pageSize, searchInput, searchPending, setSearchInput, updateParams } = useTableUrlState({
72
+ searchKey: 'search',
73
+ defaultPageSize: DEFAULT_PAGE_SIZE
74
+ });
75
+ // Rehydrate the applied filter tree from the URL for the drawer. Keyed on
76
+ // the raw param so a deep-linked or hand-edited filter restores on load.
77
+ const appliedFilter = useMemo(() => jsonFilterToTree(filterParam), [filterParam]);
78
+ const ruleCount = countRules(appliedFilter);
79
+ const params = {
80
+ search: searchParam || undefined,
81
+ filter: filterParam || undefined,
82
+ page,
83
+ pageSize
84
+ };
85
+ const { data, isPending, isFetching, isError, refetch } = useMembers(params, canRead);
86
+ const total = data?.total ?? 0;
87
+ // The server echoes the effective page size; fall back to the requested one
88
+ // until the first response lands.
89
+ const effectivePageSize = data?.pageSize ?? pageSize;
90
+ const pageCount = Math.max(1, Math.ceil(total / effectivePageSize));
91
+ // A mutation (revoke/disable) or a narrowing search/filter can leave fewer
92
+ // pages than the current one; pull `page` back so we never strand the user
93
+ // on an empty page past the end. Guarded on `data` so it runs only after a
94
+ // real response — otherwise a deep-linked `?page=N>1` resets to 1 before the
95
+ // first fetch lands (when `total` is 0 and `pageCount` is 1).
96
+ useEffect(() => {
97
+ if (data && page > pageCount) {
98
+ updateParams({ page: pageCount > 1 ? String(pageCount) : undefined }, false);
99
+ }
100
+ }, [data, page, pageCount, updateParams]);
101
+ /** Commit (or clear) the query-builder filter to the URL. */
102
+ const applyFilter = useCallback((next) => {
103
+ updateParams({ filter: treeToJsonFilter(next) ?? undefined });
104
+ }, [updateParams]);
105
+ if (!canRead) {
106
+ return (_jsxs(_Fragment, { children: [_jsx(PageTopBar, { icon: Users, iconClassName: "bg-success-soft text-success-soft-foreground", crumbs: [
107
+ {
108
+ key: 'members',
109
+ label: intl.formatMessage(messages.title)
110
+ }
111
+ ] }), _jsxs(Container, { children: [_jsx(ContainerHeader, { title: intl.formatMessage(messages.title) }), _jsx(MembersNoAccess, {})] })] }));
112
+ }
113
+ const members = data?.items ?? [];
114
+ const hasFilters = searchInput.trim().length > 0 || ruleCount > 0;
115
+ /**
116
+ * Clear the filters (search + query builder) and reset to the first page,
117
+ * while preserving the user's page-size choice.
118
+ */
119
+ const clearFilters = () => {
120
+ setSearchInput('');
121
+ updateParams({ search: undefined, filter: undefined });
122
+ };
123
+ const openInvite = () => navigate('/users/invite');
124
+ return (_jsxs(_Fragment, { children: [_jsx(PageTopBar, { icon: Users, iconClassName: "bg-success-soft text-success-soft-foreground", crumbs: [
125
+ {
126
+ key: 'members',
127
+ label: intl.formatMessage(messages.title)
128
+ }
129
+ ] }), _jsxs(Container, { children: [_jsx(ContainerHeader, { title: intl.formatMessage(messages.title),
130
+ // No count until one is known: the read failed or hasn't
131
+ // landed, and "0 people" is a claim about the directory
132
+ // rather than a description of what happened.
133
+ subtitle: isPending || isError
134
+ ? undefined
135
+ : intl.formatMessage(messages.subtitle, {
136
+ 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) }) })] })) })] })] }));
140
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * The Access tab: everything that governs whether — and how — this member gets
3
+ * into the product. Two cards:
4
+ *
5
+ * - **sign-in access** — suspend or reactivate. Mirrors the server's lifecycle:
6
+ * only `active` can be suspended, only `disabled` reactivated, and `pending`
7
+ * (un-accepted invite) is read-only. The last active admin and your own
8
+ * account can't be suspended; the button explains why instead of failing on
9
+ * submit.
10
+ * - **password** — generate a single-use reset link for the member
11
+ * ({@link PasswordResetCard}).
12
+ *
13
+ * The two belong on one tab because they answer the same question from either
14
+ * side: this is where an admin goes when someone can't get in, whether the
15
+ * reason is that they were locked out or that they forgot their password.
16
+ */
17
+ export declare function UserAccessPage(): import("react").JSX.Element;
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/lib/presentation/pages/UserAccessPage/index.tsx"],"names":[],"mappings":"AAgGA;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,cAAc,gCAiI7B"}