@workos-inc/widgets 1.0.0 → 1.1.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.
- package/README.md +68 -1
- package/dist/cjs/card-list.d.ts +6 -0
- package/dist/cjs/card-list.d.ts.map +1 -0
- package/dist/cjs/card-list.js +13 -0
- package/dist/cjs/card-list.js.map +1 -0
- package/dist/cjs/index.d.ts +3 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +7 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/lib/add-mfa-dialog.d.ts +9 -0
- package/dist/cjs/lib/add-mfa-dialog.d.ts.map +1 -0
- package/dist/cjs/lib/add-mfa-dialog.js +135 -0
- package/dist/cjs/lib/add-mfa-dialog.js.map +1 -0
- package/dist/cjs/lib/api/user.d.ts +13 -57
- package/dist/cjs/lib/api/user.d.ts.map +1 -1
- package/dist/cjs/lib/api/user.js +44 -314
- package/dist/cjs/lib/api/user.js.map +1 -1
- package/dist/cjs/lib/change-password-dialog.d.ts +8 -0
- package/dist/cjs/lib/change-password-dialog.d.ts.map +1 -0
- package/dist/cjs/lib/change-password-dialog.js +97 -0
- package/dist/cjs/lib/change-password-dialog.js.map +1 -0
- package/dist/cjs/lib/copy-button.d.ts +8 -0
- package/dist/cjs/lib/copy-button.d.ts.map +1 -0
- package/dist/cjs/lib/copy-button.js +63 -0
- package/dist/cjs/lib/copy-button.js.map +1 -0
- package/dist/cjs/lib/delete-user-dialog.d.ts +2 -2
- package/dist/cjs/lib/delete-user-dialog.d.ts.map +1 -1
- package/dist/cjs/lib/delete-user-dialog.js +1 -1
- package/dist/cjs/lib/delete-user-dialog.js.map +1 -1
- package/dist/cjs/lib/edit-user-profile-dialog.d.ts +10 -0
- package/dist/cjs/lib/edit-user-profile-dialog.d.ts.map +1 -0
- package/dist/cjs/lib/edit-user-profile-dialog.js +85 -0
- package/dist/cjs/lib/edit-user-profile-dialog.js.map +1 -0
- package/dist/cjs/lib/edit-user-role-dialog.d.ts +12 -0
- package/dist/cjs/lib/edit-user-role-dialog.d.ts.map +1 -0
- package/dist/cjs/lib/{edit-user-details-dialog.js → edit-user-role-dialog.js} +11 -7
- package/dist/cjs/lib/edit-user-role-dialog.js.map +1 -0
- package/dist/cjs/lib/elements.d.ts +1 -0
- package/dist/cjs/lib/elements.d.ts.map +1 -1
- package/dist/cjs/lib/elements.js +10 -4
- package/dist/cjs/lib/elements.js.map +1 -1
- package/dist/cjs/lib/elevated-access.d.ts +8 -0
- package/dist/cjs/lib/elevated-access.d.ts.map +1 -0
- package/dist/cjs/lib/elevated-access.js +130 -0
- package/dist/cjs/lib/elevated-access.js.map +1 -0
- package/dist/cjs/lib/generic-error.d.ts +4 -0
- package/dist/cjs/lib/generic-error.d.ts.map +1 -0
- package/dist/cjs/lib/generic-error.js +57 -0
- package/dist/cjs/lib/generic-error.js.map +1 -0
- package/dist/cjs/lib/icon-panel.d.ts +3 -0
- package/dist/cjs/lib/icon-panel.d.ts.map +1 -0
- package/dist/cjs/lib/icon-panel.js +16 -0
- package/dist/cjs/lib/icon-panel.js.map +1 -0
- package/dist/cjs/lib/icons.d.ts +3 -0
- package/dist/cjs/lib/icons.d.ts.map +1 -0
- package/dist/cjs/lib/icons.js +8 -0
- package/dist/cjs/lib/icons.js.map +1 -0
- package/dist/cjs/lib/invite-user-dialog.d.ts.map +1 -1
- package/dist/cjs/lib/invite-user-dialog.js +7 -5
- package/dist/cjs/lib/invite-user-dialog.js.map +1 -1
- package/dist/cjs/lib/logout-all-sessions-dialog.d.ts +9 -0
- package/dist/cjs/lib/logout-all-sessions-dialog.d.ts.map +1 -0
- package/dist/cjs/lib/logout-all-sessions-dialog.js +52 -0
- package/dist/cjs/lib/logout-all-sessions-dialog.js.map +1 -0
- package/dist/cjs/lib/logout-dialog.d.ts +10 -0
- package/dist/cjs/lib/logout-dialog.d.ts.map +1 -0
- package/dist/cjs/lib/logout-dialog.js +58 -0
- package/dist/cjs/lib/logout-dialog.js.map +1 -0
- package/dist/cjs/lib/marker.d.ts +14 -0
- package/dist/cjs/lib/marker.d.ts.map +1 -0
- package/dist/cjs/lib/marker.js +38 -0
- package/dist/cjs/lib/marker.js.map +1 -0
- package/dist/cjs/lib/oauth-icons.d.ts +4 -0
- package/dist/cjs/lib/oauth-icons.d.ts.map +1 -0
- package/dist/cjs/lib/oauth-icons.js +67 -0
- package/dist/cjs/lib/oauth-icons.js.map +1 -0
- package/dist/cjs/lib/organization-switcher.d.ts +24 -0
- package/dist/cjs/lib/organization-switcher.d.ts.map +1 -0
- package/dist/cjs/lib/organization-switcher.js +35 -0
- package/dist/cjs/lib/organization-switcher.js.map +1 -0
- package/dist/cjs/lib/otp-input.d.ts +20 -0
- package/dist/cjs/lib/otp-input.d.ts.map +1 -0
- package/dist/cjs/lib/otp-input.js +174 -0
- package/dist/cjs/lib/otp-input.js.map +1 -0
- package/dist/cjs/lib/resend-invite-dialog.d.ts +2 -2
- package/dist/cjs/lib/resend-invite-dialog.d.ts.map +1 -1
- package/dist/cjs/lib/resend-invite-dialog.js +1 -1
- package/dist/cjs/lib/resend-invite-dialog.js.map +1 -1
- package/dist/cjs/lib/reset-mfa-dialog.d.ts +9 -0
- package/dist/cjs/lib/reset-mfa-dialog.d.ts.map +1 -0
- package/dist/cjs/lib/reset-mfa-dialog.js +60 -0
- package/dist/cjs/lib/reset-mfa-dialog.js.map +1 -0
- package/dist/cjs/lib/revoke-invite-dialog.d.ts +2 -2
- package/dist/cjs/lib/revoke-invite-dialog.d.ts.map +1 -1
- package/dist/cjs/lib/revoke-invite-dialog.js +1 -1
- package/dist/cjs/lib/revoke-invite-dialog.js.map +1 -1
- package/dist/cjs/lib/save-button.d.ts +11 -0
- package/dist/cjs/lib/save-button.d.ts.map +1 -0
- package/dist/cjs/lib/save-button.js +47 -0
- package/dist/cjs/lib/save-button.js.map +1 -0
- package/dist/cjs/lib/set-password-dialog.d.ts +8 -0
- package/dist/cjs/lib/set-password-dialog.d.ts.map +1 -0
- package/dist/cjs/lib/set-password-dialog.js +80 -0
- package/dist/cjs/lib/set-password-dialog.js.map +1 -0
- package/dist/cjs/lib/use-dialog-close.d.ts +2 -0
- package/dist/cjs/lib/use-dialog-close.d.ts.map +1 -0
- package/dist/cjs/lib/use-dialog-close.js +43 -0
- package/dist/cjs/lib/use-dialog-close.js.map +1 -0
- package/dist/cjs/lib/use-security-settings.d.ts +11 -0
- package/dist/cjs/lib/use-security-settings.d.ts.map +1 -0
- package/dist/cjs/lib/use-security-settings.js +39 -0
- package/dist/cjs/lib/use-security-settings.js.map +1 -0
- package/dist/cjs/lib/user-actions-dropdown.d.ts +2 -2
- package/dist/cjs/lib/user-actions-dropdown.d.ts.map +1 -1
- package/dist/cjs/lib/user-actions-dropdown.js +8 -4
- package/dist/cjs/lib/user-actions-dropdown.js.map +1 -1
- package/dist/cjs/lib/user-profile.d.ts +11 -0
- package/dist/cjs/lib/user-profile.d.ts.map +1 -0
- package/dist/cjs/lib/user-profile.js +36 -0
- package/dist/cjs/lib/user-profile.js.map +1 -0
- package/dist/cjs/lib/user-security.d.ts +11 -0
- package/dist/cjs/lib/user-security.d.ts.map +1 -0
- package/dist/cjs/lib/user-security.js +64 -0
- package/dist/cjs/lib/user-security.js.map +1 -0
- package/dist/cjs/lib/user-sessions.d.ts +12 -0
- package/dist/cjs/lib/user-sessions.d.ts.map +1 -0
- package/dist/cjs/lib/user-sessions.js +72 -0
- package/dist/cjs/lib/user-sessions.js.map +1 -0
- package/dist/cjs/lib/users-filter.d.ts +2 -2
- package/dist/cjs/lib/users-filter.d.ts.map +1 -1
- package/dist/cjs/lib/users-filter.js.map +1 -1
- package/dist/cjs/lib/users-management-context.d.ts +0 -9
- package/dist/cjs/lib/users-management-context.d.ts.map +1 -1
- package/dist/cjs/lib/users-management-context.js +13 -26
- package/dist/cjs/lib/users-management-context.js.map +1 -1
- package/dist/cjs/lib/users-management-state.d.ts +3 -3
- package/dist/cjs/lib/users-management-state.d.ts.map +1 -1
- package/dist/cjs/lib/users-management-state.js.map +1 -1
- package/dist/cjs/lib/users-management.d.ts +3 -4
- package/dist/cjs/lib/users-management.d.ts.map +1 -1
- package/dist/cjs/lib/users-management.js +8 -26
- package/dist/cjs/lib/users-management.js.map +1 -1
- package/dist/cjs/lib/utils.d.ts +10 -2
- package/dist/cjs/lib/utils.d.ts.map +1 -1
- package/dist/cjs/lib/utils.js +18 -0
- package/dist/cjs/lib/utils.js.map +1 -1
- package/dist/cjs/organization-switcher.client.d.ts +8 -0
- package/dist/cjs/organization-switcher.client.d.ts.map +1 -0
- package/dist/cjs/organization-switcher.client.js +37 -0
- package/dist/cjs/organization-switcher.client.js.map +1 -0
- package/dist/cjs/user-profile.client.d.ts +7 -0
- package/dist/cjs/user-profile.client.d.ts.map +1 -0
- package/dist/cjs/user-profile.client.js +31 -0
- package/dist/cjs/user-profile.client.js.map +1 -0
- package/dist/cjs/user-security.client.d.ts +7 -0
- package/dist/cjs/user-security.client.d.ts.map +1 -0
- package/dist/cjs/user-security.client.js +27 -0
- package/dist/cjs/user-security.client.js.map +1 -0
- package/dist/cjs/user-sessions.client.d.ts +12 -0
- package/dist/cjs/user-sessions.client.d.ts.map +1 -0
- package/dist/cjs/user-sessions.client.js +48 -0
- package/dist/cjs/user-sessions.client.js.map +1 -0
- package/dist/cjs/users-management.client.d.ts +2 -1
- package/dist/cjs/users-management.client.d.ts.map +1 -1
- package/dist/cjs/users-management.client.js +12 -43
- package/dist/cjs/users-management.client.js.map +1 -1
- package/dist/esm/card-list.d.ts +6 -0
- package/dist/esm/card-list.d.ts.map +1 -0
- package/dist/esm/card-list.js +9 -0
- package/dist/esm/card-list.js.map +1 -0
- package/dist/esm/index.d.ts +3 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +3 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/lib/add-mfa-dialog.d.ts +9 -0
- package/dist/esm/lib/add-mfa-dialog.d.ts.map +1 -0
- package/dist/esm/lib/add-mfa-dialog.js +109 -0
- package/dist/esm/lib/add-mfa-dialog.js.map +1 -0
- package/dist/esm/lib/api/user.d.ts +13 -57
- package/dist/esm/lib/api/user.d.ts.map +1 -1
- package/dist/esm/lib/api/user.js +44 -313
- package/dist/esm/lib/api/user.js.map +1 -1
- package/dist/esm/lib/change-password-dialog.d.ts +8 -0
- package/dist/esm/lib/change-password-dialog.d.ts.map +1 -0
- package/dist/esm/lib/change-password-dialog.js +71 -0
- package/dist/esm/lib/change-password-dialog.js.map +1 -0
- package/dist/esm/lib/copy-button.d.ts +8 -0
- package/dist/esm/lib/copy-button.d.ts.map +1 -0
- package/dist/esm/lib/copy-button.js +37 -0
- package/dist/esm/lib/copy-button.js.map +1 -0
- package/dist/esm/lib/delete-user-dialog.d.ts +2 -2
- package/dist/esm/lib/delete-user-dialog.d.ts.map +1 -1
- package/dist/esm/lib/delete-user-dialog.js +1 -1
- package/dist/esm/lib/delete-user-dialog.js.map +1 -1
- package/dist/esm/lib/edit-user-profile-dialog.d.ts +10 -0
- package/dist/esm/lib/edit-user-profile-dialog.d.ts.map +1 -0
- package/dist/esm/lib/edit-user-profile-dialog.js +59 -0
- package/dist/esm/lib/edit-user-profile-dialog.js.map +1 -0
- package/dist/esm/lib/edit-user-role-dialog.d.ts +12 -0
- package/dist/esm/lib/edit-user-role-dialog.d.ts.map +1 -0
- package/dist/esm/lib/{edit-user-details-dialog.js → edit-user-role-dialog.js} +10 -6
- package/dist/esm/lib/edit-user-role-dialog.js.map +1 -0
- package/dist/esm/lib/elements.d.ts +1 -0
- package/dist/esm/lib/elements.d.ts.map +1 -1
- package/dist/esm/lib/elements.js +9 -3
- package/dist/esm/lib/elements.js.map +1 -1
- package/dist/esm/lib/elevated-access.d.ts +8 -0
- package/dist/esm/lib/elevated-access.d.ts.map +1 -0
- package/dist/esm/lib/elevated-access.js +104 -0
- package/dist/esm/lib/elevated-access.js.map +1 -0
- package/dist/esm/lib/generic-error.d.ts +4 -0
- package/dist/esm/lib/generic-error.d.ts.map +1 -0
- package/dist/esm/lib/generic-error.js +31 -0
- package/dist/esm/lib/generic-error.js.map +1 -0
- package/dist/esm/lib/icon-panel.d.ts +3 -0
- package/dist/esm/lib/icon-panel.d.ts.map +1 -0
- package/dist/esm/lib/icon-panel.js +13 -0
- package/dist/esm/lib/icon-panel.js.map +1 -0
- package/dist/esm/lib/icons.d.ts +3 -0
- package/dist/esm/lib/icons.d.ts.map +1 -0
- package/dist/esm/lib/icons.js +5 -0
- package/dist/esm/lib/icons.js.map +1 -0
- package/dist/esm/lib/invite-user-dialog.d.ts.map +1 -1
- package/dist/esm/lib/invite-user-dialog.js +7 -5
- package/dist/esm/lib/invite-user-dialog.js.map +1 -1
- package/dist/esm/lib/logout-all-sessions-dialog.d.ts +9 -0
- package/dist/esm/lib/logout-all-sessions-dialog.d.ts.map +1 -0
- package/dist/esm/lib/logout-all-sessions-dialog.js +26 -0
- package/dist/esm/lib/logout-all-sessions-dialog.js.map +1 -0
- package/dist/esm/lib/logout-dialog.d.ts +10 -0
- package/dist/esm/lib/logout-dialog.d.ts.map +1 -0
- package/dist/esm/lib/logout-dialog.js +32 -0
- package/dist/esm/lib/logout-dialog.js.map +1 -0
- package/dist/esm/lib/marker.d.ts +14 -0
- package/dist/esm/lib/marker.d.ts.map +1 -0
- package/dist/esm/lib/marker.js +9 -0
- package/dist/esm/lib/marker.js.map +1 -0
- package/dist/esm/lib/oauth-icons.d.ts +4 -0
- package/dist/esm/lib/oauth-icons.d.ts.map +1 -0
- package/dist/esm/lib/oauth-icons.js +39 -0
- package/dist/esm/lib/oauth-icons.js.map +1 -0
- package/dist/esm/lib/organization-switcher.d.ts +24 -0
- package/dist/esm/lib/organization-switcher.d.ts.map +1 -0
- package/dist/esm/lib/organization-switcher.js +29 -0
- package/dist/esm/lib/organization-switcher.js.map +1 -0
- package/dist/esm/lib/otp-input.d.ts +20 -0
- package/dist/esm/lib/otp-input.d.ts.map +1 -0
- package/dist/esm/lib/otp-input.js +148 -0
- package/dist/esm/lib/otp-input.js.map +1 -0
- package/dist/esm/lib/resend-invite-dialog.d.ts +2 -2
- package/dist/esm/lib/resend-invite-dialog.d.ts.map +1 -1
- package/dist/esm/lib/resend-invite-dialog.js +1 -1
- package/dist/esm/lib/resend-invite-dialog.js.map +1 -1
- package/dist/esm/lib/reset-mfa-dialog.d.ts +9 -0
- package/dist/esm/lib/reset-mfa-dialog.d.ts.map +1 -0
- package/dist/esm/lib/reset-mfa-dialog.js +34 -0
- package/dist/esm/lib/reset-mfa-dialog.js.map +1 -0
- package/dist/esm/lib/revoke-invite-dialog.d.ts +2 -2
- package/dist/esm/lib/revoke-invite-dialog.d.ts.map +1 -1
- package/dist/esm/lib/revoke-invite-dialog.js +1 -1
- package/dist/esm/lib/revoke-invite-dialog.js.map +1 -1
- package/dist/esm/lib/save-button.d.ts +11 -0
- package/dist/esm/lib/save-button.d.ts.map +1 -0
- package/dist/esm/lib/save-button.js +44 -0
- package/dist/esm/lib/save-button.js.map +1 -0
- package/dist/esm/lib/set-password-dialog.d.ts +8 -0
- package/dist/esm/lib/set-password-dialog.d.ts.map +1 -0
- package/dist/esm/lib/set-password-dialog.js +54 -0
- package/dist/esm/lib/set-password-dialog.js.map +1 -0
- package/dist/esm/lib/use-dialog-close.d.ts +2 -0
- package/dist/esm/lib/use-dialog-close.d.ts.map +1 -0
- package/dist/esm/lib/use-dialog-close.js +17 -0
- package/dist/esm/lib/use-dialog-close.js.map +1 -0
- package/dist/esm/lib/use-security-settings.d.ts +11 -0
- package/dist/esm/lib/use-security-settings.d.ts.map +1 -0
- package/dist/esm/lib/use-security-settings.js +36 -0
- package/dist/esm/lib/use-security-settings.js.map +1 -0
- package/dist/esm/lib/user-actions-dropdown.d.ts +2 -2
- package/dist/esm/lib/user-actions-dropdown.d.ts.map +1 -1
- package/dist/esm/lib/user-actions-dropdown.js +8 -4
- package/dist/esm/lib/user-actions-dropdown.js.map +1 -1
- package/dist/esm/lib/user-profile.d.ts +11 -0
- package/dist/esm/lib/user-profile.d.ts.map +1 -0
- package/dist/esm/lib/user-profile.js +27 -0
- package/dist/esm/lib/user-profile.js.map +1 -0
- package/dist/esm/lib/user-security.d.ts +11 -0
- package/dist/esm/lib/user-security.d.ts.map +1 -0
- package/dist/esm/lib/user-security.js +32 -0
- package/dist/esm/lib/user-security.js.map +1 -0
- package/dist/esm/lib/user-sessions.d.ts +12 -0
- package/dist/esm/lib/user-sessions.d.ts.map +1 -0
- package/dist/esm/lib/user-sessions.js +40 -0
- package/dist/esm/lib/user-sessions.js.map +1 -0
- package/dist/esm/lib/users-filter.d.ts +2 -2
- package/dist/esm/lib/users-filter.d.ts.map +1 -1
- package/dist/esm/lib/users-filter.js.map +1 -1
- package/dist/esm/lib/users-management-context.d.ts +0 -9
- package/dist/esm/lib/users-management-context.d.ts.map +1 -1
- package/dist/esm/lib/users-management-context.js +13 -25
- package/dist/esm/lib/users-management-context.js.map +1 -1
- package/dist/esm/lib/users-management-state.d.ts +3 -3
- package/dist/esm/lib/users-management-state.d.ts.map +1 -1
- package/dist/esm/lib/users-management-state.js.map +1 -1
- package/dist/esm/lib/users-management.d.ts +3 -4
- package/dist/esm/lib/users-management.d.ts.map +1 -1
- package/dist/esm/lib/users-management.js +9 -27
- package/dist/esm/lib/users-management.js.map +1 -1
- package/dist/esm/lib/users-search.d.ts +1 -1
- package/dist/esm/lib/users-search.d.ts.map +1 -1
- package/dist/esm/lib/utils.d.ts +10 -2
- package/dist/esm/lib/utils.d.ts.map +1 -1
- package/dist/esm/lib/utils.js +16 -0
- package/dist/esm/lib/utils.js.map +1 -1
- package/dist/esm/organization-switcher.client.d.ts +8 -0
- package/dist/esm/organization-switcher.client.d.ts.map +1 -0
- package/dist/esm/organization-switcher.client.js +33 -0
- package/dist/esm/organization-switcher.client.js.map +1 -0
- package/dist/esm/user-profile.client.d.ts +7 -0
- package/dist/esm/user-profile.client.d.ts.map +1 -0
- package/dist/esm/user-profile.client.js +27 -0
- package/dist/esm/user-profile.client.js.map +1 -0
- package/dist/esm/user-security.client.d.ts +7 -0
- package/dist/esm/user-security.client.d.ts.map +1 -0
- package/dist/esm/user-security.client.js +23 -0
- package/dist/esm/user-security.client.js.map +1 -0
- package/dist/esm/user-sessions.client.d.ts +12 -0
- package/dist/esm/user-sessions.client.d.ts.map +1 -0
- package/dist/esm/user-sessions.client.js +44 -0
- package/dist/esm/user-sessions.client.js.map +1 -0
- package/dist/esm/users-management.client.d.ts +2 -1
- package/dist/esm/users-management.client.d.ts.map +1 -1
- package/dist/esm/users-management.client.js +12 -20
- package/dist/esm/users-management.client.js.map +1 -1
- package/dist/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/tsconfig.esm.tsbuildinfo +1 -1
- package/package.json +10 -4
- package/src/card-list.tsx +26 -0
- package/src/index.ts +3 -0
- package/src/lib/add-mfa-dialog.tsx +379 -0
- package/src/lib/api/user.ts +54 -458
- package/src/lib/card-list.css +3 -0
- package/src/lib/change-password-dialog.tsx +290 -0
- package/src/lib/copy-button.tsx +53 -0
- package/src/lib/delete-user-dialog.tsx +9 -6
- package/src/lib/edit-user-profile-dialog.tsx +181 -0
- package/src/lib/{edit-user-details-dialog.tsx → edit-user-role-dialog.tsx} +12 -9
- package/src/lib/elements.tsx +34 -1
- package/src/lib/elevated-access.tsx +261 -0
- package/src/lib/generic-error.tsx +70 -0
- package/src/lib/icon-panel.tsx +26 -0
- package/src/lib/icons.tsx +21 -0
- package/src/lib/invite-user-dialog.tsx +15 -10
- package/src/lib/logout-all-sessions-dialog.tsx +82 -0
- package/src/lib/logout-dialog.tsx +89 -0
- package/src/lib/marker.css +81 -0
- package/src/lib/marker.tsx +39 -0
- package/src/lib/oauth-icons.tsx +138 -0
- package/src/lib/organization-switcher.tsx +160 -0
- package/src/lib/otp-input.tsx +276 -0
- package/src/lib/resend-invite-dialog.tsx +9 -6
- package/src/lib/reset-mfa-dialog.tsx +104 -0
- package/src/lib/revoke-invite-dialog.tsx +9 -6
- package/src/lib/save-button.css +60 -0
- package/src/lib/save-button.tsx +113 -0
- package/src/lib/set-password-dialog.tsx +204 -0
- package/src/lib/use-dialog-close.tsx +19 -0
- package/src/lib/use-security-settings.tsx +49 -0
- package/src/lib/user-actions-dropdown.tsx +10 -6
- package/src/lib/user-profile.tsx +247 -0
- package/src/lib/user-security.tsx +187 -0
- package/src/lib/user-sessions.tsx +204 -0
- package/src/lib/users-filter.tsx +2 -2
- package/src/lib/users-management-context.tsx +21 -36
- package/src/lib/users-management-state.ts +3 -3
- package/src/lib/users-management.tsx +21 -77
- package/src/lib/utils.ts +30 -2
- package/src/organization-switcher.client.tsx +77 -0
- package/src/styles.css +44 -0
- package/src/user-profile.client.tsx +51 -0
- package/src/user-security.client.tsx +55 -0
- package/src/user-sessions.client.tsx +96 -0
- package/src/users-management.client.tsx +28 -39
- package/dist/cjs/lib/api/role.d.ts +0 -9
- package/dist/cjs/lib/api/role.d.ts.map +0 -1
- package/dist/cjs/lib/api/role.js +0 -115
- package/dist/cjs/lib/api/role.js.map +0 -1
- package/dist/cjs/lib/edit-user-details-dialog.d.ts +0 -12
- package/dist/cjs/lib/edit-user-details-dialog.d.ts.map +0 -1
- package/dist/cjs/lib/edit-user-details-dialog.js.map +0 -1
- package/dist/esm/lib/api/role.d.ts +0 -9
- package/dist/esm/lib/api/role.d.ts.map +0 -1
- package/dist/esm/lib/api/role.js +0 -110
- package/dist/esm/lib/api/role.js.map +0 -1
- package/dist/esm/lib/edit-user-details-dialog.d.ts +0 -12
- package/dist/esm/lib/edit-user-details-dialog.d.ts.map +0 -1
- package/dist/esm/lib/edit-user-details-dialog.js.map +0 -1
- package/src/lib/api/role.ts +0 -147
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import * as React from "react";
|
|
4
|
-
import type { PaginationData } from "./api/user";
|
|
5
4
|
import {
|
|
6
5
|
UsersManagementAction,
|
|
7
6
|
UsersManagementState,
|
|
7
|
+
useUsersManagementState,
|
|
8
8
|
} from "./users-management-state";
|
|
9
|
+
import { ListMetadata } from "@repo/api";
|
|
9
10
|
|
|
10
11
|
export interface UsersManagementContextType {
|
|
11
|
-
authToken: (() => Promise<string>) | null;
|
|
12
12
|
state: UsersManagementState;
|
|
13
13
|
dispatch: React.Dispatch<UsersManagementAction>;
|
|
14
14
|
}
|
|
@@ -18,19 +18,34 @@ const UsersManagementContext = React.createContext<
|
|
|
18
18
|
>(undefined);
|
|
19
19
|
UsersManagementContext.displayName = "UsersManagementContext";
|
|
20
20
|
|
|
21
|
+
const initialState: UsersManagementState = {
|
|
22
|
+
pagination: null,
|
|
23
|
+
role: null,
|
|
24
|
+
searchQuery: null,
|
|
25
|
+
};
|
|
26
|
+
|
|
21
27
|
export const UsersManagementContextProvider: React.FC<{
|
|
22
28
|
children?: React.ReactNode;
|
|
23
|
-
|
|
24
|
-
|
|
29
|
+
}> = ({ children }) => {
|
|
30
|
+
const [state, dispatch] = useUsersManagementState(initialState);
|
|
31
|
+
|
|
32
|
+
const context = React.useMemo<UsersManagementContextType>(
|
|
33
|
+
() => ({
|
|
34
|
+
state,
|
|
35
|
+
dispatch,
|
|
36
|
+
}),
|
|
37
|
+
[state, dispatch],
|
|
38
|
+
);
|
|
39
|
+
|
|
25
40
|
return (
|
|
26
|
-
<UsersManagementContext.Provider value={
|
|
41
|
+
<UsersManagementContext.Provider value={context}>
|
|
27
42
|
{children}
|
|
28
43
|
</UsersManagementContext.Provider>
|
|
29
44
|
);
|
|
30
45
|
};
|
|
31
46
|
|
|
32
47
|
const NOOP = () => void 0;
|
|
33
|
-
const EMPTY_PAGINATION:
|
|
48
|
+
const EMPTY_PAGINATION: ListMetadata = {};
|
|
34
49
|
|
|
35
50
|
/**
|
|
36
51
|
* The context may be provided if it is instantiated in the tree above the user.
|
|
@@ -39,15 +54,6 @@ export function useUsersManagementContext(
|
|
|
39
54
|
initialContext?: UsersManagementContextType | null,
|
|
40
55
|
): UsersManagementContextType {
|
|
41
56
|
const context = React.useContext(UsersManagementContext);
|
|
42
|
-
const providedToken = initialContext?.authToken ?? null;
|
|
43
|
-
const hasContext = !!context;
|
|
44
|
-
React.useEffect(() => {
|
|
45
|
-
if (!providedToken && !hasContext) {
|
|
46
|
-
console.error(
|
|
47
|
-
"useUsersManagementContext was called from a component outside of the UsersManagementContext provider without providing an authToken directly. Resulting queries may not run as expected.",
|
|
48
|
-
);
|
|
49
|
-
}
|
|
50
|
-
}, [providedToken, hasContext]);
|
|
51
57
|
|
|
52
58
|
if (context) {
|
|
53
59
|
return context;
|
|
@@ -58,7 +64,6 @@ export function useUsersManagementContext(
|
|
|
58
64
|
}
|
|
59
65
|
|
|
60
66
|
return {
|
|
61
|
-
authToken: null,
|
|
62
67
|
dispatch: NOOP,
|
|
63
68
|
state: {
|
|
64
69
|
pagination: EMPTY_PAGINATION,
|
|
@@ -67,23 +72,3 @@ export function useUsersManagementContext(
|
|
|
67
72
|
},
|
|
68
73
|
};
|
|
69
74
|
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* The auth token may be provided if it is instantiated in the tree above the
|
|
73
|
-
* user management context. Otherwise we'll use the context value if it exists.
|
|
74
|
-
*/
|
|
75
|
-
export function useUsersManagementPagniatoin(
|
|
76
|
-
args: { authToken?: string | null } | undefined | null,
|
|
77
|
-
) {
|
|
78
|
-
const context = React.useContext(UsersManagementContext);
|
|
79
|
-
const providedToken = args?.authToken;
|
|
80
|
-
const hasContext = !!context;
|
|
81
|
-
React.useEffect(() => {
|
|
82
|
-
if (!providedToken && !hasContext) {
|
|
83
|
-
console.error(
|
|
84
|
-
"useUsersManagementAuthToken was called from a component outside of the UsersManagementContext provider without providing an authToken directly. Resulting queries may not run as expected.",
|
|
85
|
-
);
|
|
86
|
-
}
|
|
87
|
-
}, [providedToken, hasContext]);
|
|
88
|
-
return providedToken || context?.authToken || null;
|
|
89
|
-
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import type { PaginationData } from "./api/user";
|
|
3
2
|
import { canUseDOM } from "./utils";
|
|
3
|
+
import { ListMetadata } from "@repo/api";
|
|
4
4
|
|
|
5
5
|
export function useUsersManagementState(initialState: UsersManagementState) {
|
|
6
6
|
const [[state, effects], dispatch] = React.useReducer(reducer, [
|
|
@@ -110,14 +110,14 @@ function reducer(
|
|
|
110
110
|
export interface UsersManagementState {
|
|
111
111
|
searchQuery: string | null;
|
|
112
112
|
role: string | null;
|
|
113
|
-
pagination:
|
|
113
|
+
pagination: ListMetadata | null;
|
|
114
114
|
}
|
|
115
115
|
|
|
116
116
|
export type UsersManagementAction =
|
|
117
117
|
| { type: "INIT"; params: URLSearchParams }
|
|
118
118
|
| { type: "FILTER_BY_SEARCH"; searchQuery: string | null }
|
|
119
119
|
| { type: "FILTER_BY_ROLE"; role: string | null }
|
|
120
|
-
| { type: "SET_PAGINATION"; pagination:
|
|
120
|
+
| { type: "SET_PAGINATION"; pagination: ListMetadata };
|
|
121
121
|
|
|
122
122
|
type EffectFn = {
|
|
123
123
|
(): void;
|
|
@@ -5,15 +5,13 @@ import {
|
|
|
5
5
|
Box,
|
|
6
6
|
Flex,
|
|
7
7
|
Grid,
|
|
8
|
-
Heading,
|
|
9
8
|
Select,
|
|
9
|
+
Separator,
|
|
10
10
|
Table,
|
|
11
11
|
Text,
|
|
12
12
|
type TextProps,
|
|
13
13
|
VisuallyHidden,
|
|
14
14
|
} from "@radix-ui/themes";
|
|
15
|
-
import type { Role } from "./api/role";
|
|
16
|
-
import type { Paginated, User } from "./api/user";
|
|
17
15
|
import {
|
|
18
16
|
Avatar,
|
|
19
17
|
Badge,
|
|
@@ -36,11 +34,12 @@ import { getBestName, getComparativeReadableDate } from "./utils";
|
|
|
36
34
|
import { USER_ROW_LIMIT } from "./constants";
|
|
37
35
|
import { useUsersManagementContext } from "./users-management-context";
|
|
38
36
|
import clsx from "clsx";
|
|
39
|
-
import {
|
|
37
|
+
import { Member, MemberRole, MembersQueryResult } from "@repo/api";
|
|
38
|
+
import { GenericError } from "./generic-error";
|
|
40
39
|
|
|
41
40
|
interface UsersManagementProps {
|
|
42
|
-
rolesData:
|
|
43
|
-
userData:
|
|
41
|
+
rolesData: MemberRole[];
|
|
42
|
+
userData: MembersQueryResult;
|
|
44
43
|
disableRolesFilter?: boolean;
|
|
45
44
|
// When the users list is loading new users
|
|
46
45
|
isPending: boolean;
|
|
@@ -52,10 +51,10 @@ export const UsersManagement = ({
|
|
|
52
51
|
isPending,
|
|
53
52
|
disableRolesFilter,
|
|
54
53
|
}: UsersManagementProps) => {
|
|
55
|
-
const users = userData?.data;
|
|
54
|
+
const users = userData?.data ?? [];
|
|
56
55
|
const usersCount = users?.length ?? 0;
|
|
57
56
|
const isHydrated = useIsHydrated();
|
|
58
|
-
const { pagination } = userData;
|
|
57
|
+
const { listMetadata: pagination = {} } = userData;
|
|
59
58
|
const { dispatch } = useUsersManagementContext();
|
|
60
59
|
|
|
61
60
|
// we only want to show the loading indicator for some buttons if the request
|
|
@@ -120,7 +119,7 @@ export const UsersManagement = ({
|
|
|
120
119
|
{users.length > 0 ? (
|
|
121
120
|
users.map((user) => {
|
|
122
121
|
// TODO only support one role for now
|
|
123
|
-
const userRole = user
|
|
122
|
+
const userRole = user?.roles?.at(0)?.name;
|
|
124
123
|
const userDisplayName = getBestName(user);
|
|
125
124
|
const dimText =
|
|
126
125
|
user.status === "InviteRevoked" ||
|
|
@@ -186,11 +185,7 @@ export const UsersManagement = ({
|
|
|
186
185
|
</TableCellText>
|
|
187
186
|
</Table.Cell>
|
|
188
187
|
<Table.Cell>
|
|
189
|
-
<LastActive
|
|
190
|
-
user={user}
|
|
191
|
-
isHydrated={isHydrated}
|
|
192
|
-
dim={dimText}
|
|
193
|
-
/>
|
|
188
|
+
<LastActive user={user} isHydrated={isHydrated} />
|
|
194
189
|
</Table.Cell>
|
|
195
190
|
<Table.Cell justify="end">
|
|
196
191
|
<UserActionsDropdown user={user}>
|
|
@@ -356,59 +351,16 @@ export function UsersManagementLoading() {
|
|
|
356
351
|
}
|
|
357
352
|
|
|
358
353
|
export function UsersManagementError({ error }: { error: unknown }) {
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
justify="center"
|
|
368
|
-
align="center"
|
|
369
|
-
direction="column"
|
|
370
|
-
maxWidth="520px"
|
|
371
|
-
>
|
|
372
|
-
<Heading size="5" align="center" mb="1" wrap="balance" asChild>
|
|
373
|
-
<h3>{heading}</h3>
|
|
374
|
-
</Heading>
|
|
375
|
-
<Text align="center" wrap="balance">
|
|
376
|
-
{message}
|
|
377
|
-
</Text>
|
|
378
|
-
</Flex>
|
|
354
|
+
return (
|
|
355
|
+
<UsersManagementRoot
|
|
356
|
+
direction="row"
|
|
357
|
+
justify="center"
|
|
358
|
+
align="center"
|
|
359
|
+
minHeight="676px"
|
|
360
|
+
>
|
|
361
|
+
<GenericError error={error} />
|
|
379
362
|
</UsersManagementRoot>
|
|
380
363
|
);
|
|
381
|
-
|
|
382
|
-
if (error instanceof FetchError) {
|
|
383
|
-
return render(
|
|
384
|
-
"Error fetching data",
|
|
385
|
-
"An error occurred. You may need to configure CORS in the WorkOS Dashboard. " +
|
|
386
|
-
"Contact your organization admin for support.",
|
|
387
|
-
);
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
if (error instanceof NoAuthTokenError) {
|
|
391
|
-
return render(
|
|
392
|
-
"Error fetching data",
|
|
393
|
-
"Authorization error. You likely forgot to provide an authorization " +
|
|
394
|
-
"token to the Users Management Widget.",
|
|
395
|
-
);
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
if (error instanceof ApiError && error.status === 404) {
|
|
399
|
-
// The widgets API treats all authorization errors as 404s. If there is a
|
|
400
|
-
// legitimate 404, it's a bug on our end but there's currently no way to
|
|
401
|
-
// distinguish between the two.
|
|
402
|
-
return render(
|
|
403
|
-
"Error fetching data",
|
|
404
|
-
"Authorization error. Contact your organization admin for support.",
|
|
405
|
-
);
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
return render(
|
|
409
|
-
"Error fetching data",
|
|
410
|
-
"Unknown error. Contact your organization admin for support.",
|
|
411
|
-
);
|
|
412
364
|
}
|
|
413
365
|
|
|
414
366
|
function UsersManagementRoot({
|
|
@@ -429,7 +381,7 @@ function UsersManagementRoot({
|
|
|
429
381
|
);
|
|
430
382
|
}
|
|
431
383
|
|
|
432
|
-
function UserBadge({ user }: { user:
|
|
384
|
+
function UserBadge({ user }: { user: Member }) {
|
|
433
385
|
// TODO: This is not yet available in the data. Update here after API is updated.
|
|
434
386
|
if (user.isLoggedInUser) {
|
|
435
387
|
return (
|
|
@@ -465,7 +417,7 @@ function UserBadge({ user }: { user: User }) {
|
|
|
465
417
|
}
|
|
466
418
|
|
|
467
419
|
interface LastActiveProps {
|
|
468
|
-
user:
|
|
420
|
+
user: Member;
|
|
469
421
|
isHydrated: boolean;
|
|
470
422
|
dim?: boolean;
|
|
471
423
|
}
|
|
@@ -477,13 +429,7 @@ function LastActive(props: LastActiveProps) {
|
|
|
477
429
|
<VisuallyHidden>
|
|
478
430
|
{props.user.status === "Active" ? "Never" : "Not active"}
|
|
479
431
|
</VisuallyHidden>
|
|
480
|
-
<
|
|
481
|
-
dim={props.dim}
|
|
482
|
-
aria-hidden
|
|
483
|
-
style={{ userSelect: "none" }}
|
|
484
|
-
>
|
|
485
|
-
–
|
|
486
|
-
</TableCellText>
|
|
432
|
+
<Separator />
|
|
487
433
|
</>
|
|
488
434
|
);
|
|
489
435
|
}
|
|
@@ -529,9 +475,7 @@ function LastActiveImpl({
|
|
|
529
475
|
return (
|
|
530
476
|
<>
|
|
531
477
|
<VisuallyHidden>Unknown</VisuallyHidden>
|
|
532
|
-
<
|
|
533
|
-
–
|
|
534
|
-
</TableCellText>
|
|
478
|
+
<Separator />
|
|
535
479
|
</>
|
|
536
480
|
);
|
|
537
481
|
}
|
package/src/lib/utils.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Member } from "@repo/api";
|
|
2
|
+
import { UAParser } from "ua-parser-js";
|
|
2
3
|
import { WIDGETS_CLASS_NAMESPACE } from "./constants";
|
|
3
4
|
|
|
4
5
|
export const canUseDOM = !!(
|
|
@@ -10,7 +11,7 @@ export const canUseDOM = !!(
|
|
|
10
11
|
export function getBestName({
|
|
11
12
|
firstName,
|
|
12
13
|
lastName,
|
|
13
|
-
}: Pick<
|
|
14
|
+
}: Pick<Member, "firstName" | "lastName">) {
|
|
14
15
|
return [firstName, lastName].filter(Boolean).join(" ") || null;
|
|
15
16
|
}
|
|
16
17
|
|
|
@@ -101,3 +102,30 @@ export function namespaceClassNames(...classNames: string[]): string {
|
|
|
101
102
|
.map((className) => `${WIDGETS_CLASS_NAMESPACE}-${className}`)
|
|
102
103
|
.join(" ");
|
|
103
104
|
}
|
|
105
|
+
|
|
106
|
+
export function parseUserAgent(userAgent?: string | null) {
|
|
107
|
+
const { browser, device, os } = UAParser(userAgent ?? "");
|
|
108
|
+
|
|
109
|
+
const browserName = browser.name?.replace(/^Mobile\s*/i, "");
|
|
110
|
+
const pretty = [browserName, os.name].filter(Boolean).join(" on ");
|
|
111
|
+
|
|
112
|
+
return { pretty, isMobile: device.type === "mobile" };
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export function getUserLocation(
|
|
116
|
+
location?: {
|
|
117
|
+
cityName: string;
|
|
118
|
+
countryISOCode: string;
|
|
119
|
+
} | null,
|
|
120
|
+
ipAddress?: string | null,
|
|
121
|
+
) {
|
|
122
|
+
if (location) {
|
|
123
|
+
return `${location.cityName}, ${location.countryISOCode}`;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (ipAddress) {
|
|
127
|
+
return ipAddress;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return "Unknown location";
|
|
131
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
ApiProvider,
|
|
5
|
+
AuthToken,
|
|
6
|
+
OrganizationInfo,
|
|
7
|
+
useOrganizations,
|
|
8
|
+
} from "@repo/api";
|
|
9
|
+
import * as React from "react";
|
|
10
|
+
import { ErrorBoundary } from "./lib/error-boundary";
|
|
11
|
+
import { useIsHydrated } from "./lib/use-is-hydrated";
|
|
12
|
+
import {
|
|
13
|
+
OrganizationSwitcherError,
|
|
14
|
+
OrganizationSwitcherLoading,
|
|
15
|
+
OrganizationSwitcherPassthroughProps,
|
|
16
|
+
OrganizationSwitcher as OrganizationSwitcherPresentational,
|
|
17
|
+
} from "./lib/organization-switcher";
|
|
18
|
+
import { useWorkOsApiUrl } from "./lib/widgets-context";
|
|
19
|
+
import { keepPreviousData } from "@tanstack/react-query";
|
|
20
|
+
|
|
21
|
+
export interface OrganizationSwitcherProps
|
|
22
|
+
extends OrganizationSwitcherPassthroughProps {
|
|
23
|
+
authToken: AuthToken;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const OrganizationSwitcher: React.FC<OrganizationSwitcherProps> = ({
|
|
27
|
+
authToken,
|
|
28
|
+
...passthroughProps
|
|
29
|
+
}) => {
|
|
30
|
+
const baseUrl = useWorkOsApiUrl();
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<ErrorBoundary FallbackComponent={OrganizationSwitcherError}>
|
|
34
|
+
<ApiProvider authToken={authToken} baseUrl={baseUrl}>
|
|
35
|
+
<OrganizationSwitcherContent {...passthroughProps} />
|
|
36
|
+
</ApiProvider>
|
|
37
|
+
</ErrorBoundary>
|
|
38
|
+
);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
// Constant reference to avoid unnecessary prop changes
|
|
42
|
+
const emptyOrganizations: OrganizationInfo[] = [];
|
|
43
|
+
|
|
44
|
+
const OrganizationSwitcherContent = ({
|
|
45
|
+
variant,
|
|
46
|
+
...rest
|
|
47
|
+
}: OrganizationSwitcherPassthroughProps) => {
|
|
48
|
+
const isHydrated = useIsHydrated();
|
|
49
|
+
const organizationsQuery = useOrganizations({
|
|
50
|
+
query: {
|
|
51
|
+
placeholderData: keepPreviousData,
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
const organizations = organizationsQuery.data?.data ?? emptyOrganizations;
|
|
56
|
+
|
|
57
|
+
if (
|
|
58
|
+
organizationsQuery.isLoading ||
|
|
59
|
+
// render loading state on the server to prevent FOUC or hydration mismatch
|
|
60
|
+
!isHydrated
|
|
61
|
+
) {
|
|
62
|
+
return <OrganizationSwitcherLoading organizations={organizations} />;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (organizationsQuery.isError) {
|
|
66
|
+
return <OrganizationSwitcherError error={organizationsQuery.error} />;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return (
|
|
70
|
+
<ErrorBoundary FallbackComponent={OrganizationSwitcherError}>
|
|
71
|
+
<OrganizationSwitcherPresentational
|
|
72
|
+
organizations={organizations}
|
|
73
|
+
{...rest}
|
|
74
|
+
/>
|
|
75
|
+
</ErrorBoundary>
|
|
76
|
+
);
|
|
77
|
+
};
|
package/src/styles.css
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
@import "./lib/card-list.css";
|
|
2
|
+
@import "./lib/marker.css";
|
|
3
|
+
@import "./lib/save-button.css";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Dialog exit animation
|
|
7
|
+
*/
|
|
8
|
+
@keyframes woswidgets-dialog-out {
|
|
9
|
+
from {
|
|
10
|
+
opacity: 1;
|
|
11
|
+
transform: translateY(0px);
|
|
12
|
+
}
|
|
13
|
+
to {
|
|
14
|
+
opacity: 0;
|
|
15
|
+
transform: translateY(10px) scale(0.97);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
@keyframes woswidgets-dialog-overlay-out {
|
|
20
|
+
from {
|
|
21
|
+
opacity: 1;
|
|
22
|
+
}
|
|
23
|
+
to {
|
|
24
|
+
opacity: 0;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
29
|
+
.rt-BaseDialogContent[data-state="closed"] {
|
|
30
|
+
transition: none;
|
|
31
|
+
animation: woswidgets-dialog-out 150ms ease-out;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.rt-BaseDialogOverlay[data-state="closed"] {
|
|
35
|
+
transition: none;
|
|
36
|
+
animation: woswidgets-dialog-overlay-out 300ms ease-out;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.rt-BaseDialogOverlay:where([data-state="closed"])::before {
|
|
40
|
+
transition: none;
|
|
41
|
+
animation: none;
|
|
42
|
+
opacity: 1;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import {
|
|
5
|
+
UserProfileError,
|
|
6
|
+
UserProfileLoading,
|
|
7
|
+
UserProfile as UserProfilePresentational,
|
|
8
|
+
} from "./lib/user-profile";
|
|
9
|
+
import { useIsHydrated } from "./lib/use-is-hydrated";
|
|
10
|
+
import { ApiProvider, AuthToken, useMe } from "@repo/api";
|
|
11
|
+
import { useWorkOsApiUrl } from "./lib/widgets-context";
|
|
12
|
+
import { ErrorBoundary } from "./lib/error-boundary";
|
|
13
|
+
|
|
14
|
+
export interface UserProfileProps {
|
|
15
|
+
authToken: AuthToken;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const UserProfile: React.FC<UserProfileProps> = ({ authToken }) => {
|
|
19
|
+
const baseUrl = useWorkOsApiUrl();
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<ApiProvider authToken={authToken} baseUrl={baseUrl}>
|
|
23
|
+
<UserProfileContent />
|
|
24
|
+
</ApiProvider>
|
|
25
|
+
);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const UserProfileContent = () => {
|
|
29
|
+
const isHydrated = useIsHydrated();
|
|
30
|
+
const meQuery = useMe();
|
|
31
|
+
|
|
32
|
+
if (
|
|
33
|
+
// render loading state on the server to prevent FOUC or hydration mismatch
|
|
34
|
+
!isHydrated ||
|
|
35
|
+
meQuery.isLoading
|
|
36
|
+
) {
|
|
37
|
+
return <UserProfileLoading />;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (meQuery.isError) {
|
|
41
|
+
return <UserProfileError error={meQuery.error} />;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const user = meQuery.data!;
|
|
45
|
+
|
|
46
|
+
return (
|
|
47
|
+
<ErrorBoundary FallbackComponent={UserProfileError}>
|
|
48
|
+
<UserProfilePresentational userData={user} />
|
|
49
|
+
</ErrorBoundary>
|
|
50
|
+
);
|
|
51
|
+
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import {
|
|
5
|
+
ApiProvider,
|
|
6
|
+
AuthToken,
|
|
7
|
+
useAuthenticationInformation,
|
|
8
|
+
} from "@repo/api";
|
|
9
|
+
import {
|
|
10
|
+
UserSecurityError,
|
|
11
|
+
UserSecurityLoading,
|
|
12
|
+
UserSecurity as UserSecurityPresentational,
|
|
13
|
+
} from "./lib/user-security";
|
|
14
|
+
import { useIsHydrated } from "./lib/use-is-hydrated";
|
|
15
|
+
import { useWorkOsApiUrl } from "./lib/widgets-context";
|
|
16
|
+
import { ErrorBoundary } from "./lib/error-boundary";
|
|
17
|
+
|
|
18
|
+
export interface UserSecurityProps {
|
|
19
|
+
authToken: AuthToken;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const UserSecurity: React.FC<UserSecurityProps> = ({ authToken }) => {
|
|
23
|
+
const baseUrl = useWorkOsApiUrl();
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<ApiProvider authToken={authToken} baseUrl={baseUrl}>
|
|
27
|
+
<UserSecurityContent />
|
|
28
|
+
</ApiProvider>
|
|
29
|
+
);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const UserSecurityContent = () => {
|
|
33
|
+
const isHydrated = useIsHydrated();
|
|
34
|
+
const {
|
|
35
|
+
data: settings,
|
|
36
|
+
isLoading,
|
|
37
|
+
isError,
|
|
38
|
+
isSuccess,
|
|
39
|
+
error,
|
|
40
|
+
} = useAuthenticationInformation();
|
|
41
|
+
|
|
42
|
+
if (!isHydrated || isLoading) {
|
|
43
|
+
return <UserSecurityLoading />;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (isError || !isSuccess) {
|
|
47
|
+
return <UserSecurityError error={error} />;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<ErrorBoundary FallbackComponent={UserSecurityError}>
|
|
52
|
+
<UserSecurityPresentational settings={settings.data} />
|
|
53
|
+
</ErrorBoundary>
|
|
54
|
+
);
|
|
55
|
+
};
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import {
|
|
5
|
+
UserSessionsError,
|
|
6
|
+
UserSessionsLoading,
|
|
7
|
+
UserSessions as UserSessionsPresentational,
|
|
8
|
+
} from "./lib/user-sessions";
|
|
9
|
+
import { useIsHydrated } from "./lib/use-is-hydrated";
|
|
10
|
+
import { ApiProvider, useApi, useSessions } from "@repo/api";
|
|
11
|
+
import { useWorkOsApiUrl } from "./lib/widgets-context";
|
|
12
|
+
import { ErrorBoundary } from "./lib/error-boundary";
|
|
13
|
+
import { useQuery } from "@tanstack/react-query";
|
|
14
|
+
|
|
15
|
+
type UserSessionsWithoutCurrentSessionIdProps = {
|
|
16
|
+
authToken: () => Promise<string>;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
type UserSessionsWithCurrentSessionIdProps = {
|
|
20
|
+
authToken: string;
|
|
21
|
+
currentSessionId: string;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
type UserSessionsProps =
|
|
25
|
+
| UserSessionsWithoutCurrentSessionIdProps
|
|
26
|
+
| UserSessionsWithCurrentSessionIdProps;
|
|
27
|
+
|
|
28
|
+
export const UserSessions: React.FC<UserSessionsProps> = (props) => {
|
|
29
|
+
const baseUrl = useWorkOsApiUrl();
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<ApiProvider authToken={props.authToken} baseUrl={baseUrl}>
|
|
33
|
+
<UserSessionsContent
|
|
34
|
+
currentSessionId={
|
|
35
|
+
"currentSessionId" in props ? props.currentSessionId : undefined
|
|
36
|
+
}
|
|
37
|
+
/>
|
|
38
|
+
</ApiProvider>
|
|
39
|
+
);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const UserSessionsContent = ({
|
|
43
|
+
currentSessionId,
|
|
44
|
+
}: {
|
|
45
|
+
currentSessionId?: string;
|
|
46
|
+
}) => {
|
|
47
|
+
const isHydrated = useIsHydrated();
|
|
48
|
+
const sessionsQuery = useSessions();
|
|
49
|
+
const currentSessionIdQuery = useCurrentSessionIdQuery(currentSessionId);
|
|
50
|
+
|
|
51
|
+
if (
|
|
52
|
+
!isHydrated ||
|
|
53
|
+
sessionsQuery.isLoading ||
|
|
54
|
+
currentSessionIdQuery.isLoading
|
|
55
|
+
) {
|
|
56
|
+
return <UserSessionsLoading />;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (sessionsQuery.isError || currentSessionIdQuery.isError) {
|
|
60
|
+
return (
|
|
61
|
+
<UserSessionsError
|
|
62
|
+
error={sessionsQuery.error || currentSessionIdQuery.error}
|
|
63
|
+
/>
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return (
|
|
68
|
+
<ErrorBoundary FallbackComponent={UserSessionsError}>
|
|
69
|
+
<UserSessionsPresentational
|
|
70
|
+
sessionsData={sessionsQuery.data?.data || []}
|
|
71
|
+
currentSessionId={currentSessionIdQuery.data ?? ""}
|
|
72
|
+
/>
|
|
73
|
+
</ErrorBoundary>
|
|
74
|
+
);
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
function useCurrentSessionIdQuery(currentSessionId?: string) {
|
|
78
|
+
const { authToken } = useApi();
|
|
79
|
+
|
|
80
|
+
return useQuery({
|
|
81
|
+
queryKey: ["authToken"],
|
|
82
|
+
queryFn: async () => {
|
|
83
|
+
if (currentSessionId) {
|
|
84
|
+
return currentSessionId;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const res = await Promise.resolve(authToken);
|
|
88
|
+
const claims = getClaims(res);
|
|
89
|
+
return claims.sid;
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function getClaims(accessToken: string) {
|
|
95
|
+
return JSON.parse(atob(accessToken.split(".")[1])) as { sid: string };
|
|
96
|
+
}
|