@workos-inc/widgets 1.1.5 → 1.2.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 (82) hide show
  1. package/dist/cjs/lib/organization-switcher.d.ts +10 -1
  2. package/dist/cjs/lib/organization-switcher.d.ts.map +1 -1
  3. package/dist/cjs/lib/organization-switcher.js +31 -3
  4. package/dist/cjs/lib/organization-switcher.js.map +1 -1
  5. package/dist/cjs/workos-widgets.client.d.ts +6 -0
  6. package/dist/cjs/workos-widgets.client.d.ts.map +1 -1
  7. package/dist/cjs/workos-widgets.client.js +23 -3
  8. package/dist/cjs/workos-widgets.client.js.map +1 -1
  9. package/dist/esm/lib/organization-switcher.d.ts +10 -1
  10. package/dist/esm/lib/organization-switcher.d.ts.map +1 -1
  11. package/dist/esm/lib/organization-switcher.js +31 -3
  12. package/dist/esm/lib/organization-switcher.js.map +1 -1
  13. package/dist/esm/workos-widgets.client.d.ts +6 -0
  14. package/dist/esm/workos-widgets.client.d.ts.map +1 -1
  15. package/dist/esm/workos-widgets.client.js +25 -5
  16. package/dist/esm/workos-widgets.client.js.map +1 -1
  17. package/package.json +8 -9
  18. package/src/api/api-provider.tsx +0 -158
  19. package/src/api/constants.ts +0 -1
  20. package/src/api/endpoint.ts +0 -3097
  21. package/src/api/errors.ts +0 -48
  22. package/src/api/index.ts +0 -2
  23. package/src/api/utils.ts +0 -42
  24. package/src/api/widgets-api-client.ts +0 -87
  25. package/src/card-list.tsx +0 -26
  26. package/src/index.ts +0 -9
  27. package/src/lib/add-mfa-dialog.tsx +0 -379
  28. package/src/lib/api/config.ts +0 -9
  29. package/src/lib/api/user.ts +0 -98
  30. package/src/lib/change-password-dialog.tsx +0 -290
  31. package/src/lib/constants.ts +0 -3
  32. package/src/lib/copy-button.tsx +0 -53
  33. package/src/lib/delete-user-dialog.tsx +0 -110
  34. package/src/lib/edit-user-profile-dialog.tsx +0 -181
  35. package/src/lib/edit-user-role-dialog.tsx +0 -178
  36. package/src/lib/elements.tsx +0 -428
  37. package/src/lib/elevated-access.tsx +0 -261
  38. package/src/lib/error-boundary.tsx +0 -166
  39. package/src/lib/errors.ts +0 -49
  40. package/src/lib/generic-error.tsx +0 -70
  41. package/src/lib/icon-panel.tsx +0 -26
  42. package/src/lib/icons.tsx +0 -21
  43. package/src/lib/invite-user-dialog.tsx +0 -327
  44. package/src/lib/logout-all-sessions-dialog.tsx +0 -82
  45. package/src/lib/logout-dialog.tsx +0 -85
  46. package/src/lib/marker.tsx +0 -39
  47. package/src/lib/oauth-icons.tsx +0 -138
  48. package/src/lib/organization-switcher.tsx +0 -156
  49. package/src/lib/otp-input.tsx +0 -276
  50. package/src/lib/resend-invite-dialog.tsx +0 -145
  51. package/src/lib/reset-mfa-dialog.tsx +0 -104
  52. package/src/lib/revoke-invite-dialog.tsx +0 -111
  53. package/src/lib/save-button.tsx +0 -113
  54. package/src/lib/search-provider.tsx +0 -51
  55. package/src/lib/set-password-dialog.tsx +0 -204
  56. package/src/lib/use-dialog-close.tsx +0 -19
  57. package/src/lib/use-is-hydrated.ts +0 -13
  58. package/src/lib/use-layout-effect.ts +0 -6
  59. package/src/lib/use-security-settings.tsx +0 -49
  60. package/src/lib/user-actions-dropdown.tsx +0 -157
  61. package/src/lib/user-profile.tsx +0 -227
  62. package/src/lib/user-security.tsx +0 -187
  63. package/src/lib/user-sessions.tsx +0 -204
  64. package/src/lib/users-filter.tsx +0 -62
  65. package/src/lib/users-management-context.tsx +0 -74
  66. package/src/lib/users-management-state.ts +0 -165
  67. package/src/lib/users-management.tsx +0 -594
  68. package/src/lib/users-search.tsx +0 -73
  69. package/src/lib/utils.ts +0 -131
  70. package/src/lib/widgets-context.ts +0 -29
  71. package/src/organization-switcher.client.tsx +0 -81
  72. package/src/user-profile.client.tsx +0 -55
  73. package/src/user-security.client.tsx +0 -55
  74. package/src/user-sessions.client.tsx +0 -100
  75. package/src/users-management.client.tsx +0 -73
  76. package/src/workos-widgets.client.tsx +0 -75
  77. /package/{src → dist/css}/base.css +0 -0
  78. /package/{src → dist/css}/lib/card-list.css +0 -0
  79. /package/{src → dist/css}/lib/marker.css +0 -0
  80. /package/{src → dist/css}/lib/save-button.css +0 -0
  81. /package/{src → dist/css}/styles.css +0 -0
  82. /package/{src → dist/css}/users-management.css +0 -0
@@ -1,157 +0,0 @@
1
- "use client";
2
-
3
- import { DropdownMenu } from "@radix-ui/themes";
4
- import * as React from "react";
5
- import { Member } from "../api";
6
- import { DeleteUserDialog } from "./delete-user-dialog";
7
- import { EditUserRoleDialog } from "./edit-user-role-dialog";
8
- import {
9
- DestructiveMenuItem,
10
- DropdownMenuContent,
11
- PrimaryMenuItem,
12
- } from "./elements";
13
- import { ResendInviteDialog } from "./resend-invite-dialog";
14
- import { RevokeInviteDialog } from "./revoke-invite-dialog";
15
- import { useRoles } from "../api";
16
-
17
- interface UserActionsDropdownProps {
18
- user: Member;
19
- children: React.ReactNode;
20
- }
21
-
22
- type UserActionDialog =
23
- | "revoke-membership"
24
- | "revoke-invite"
25
- | "resend-invite"
26
- | "edit-role";
27
-
28
- export const UserActionsDropdown = ({
29
- user,
30
- children,
31
- }: UserActionsDropdownProps) => {
32
- const rolesQuery = useRoles({
33
- query: {
34
- initialData: [],
35
- },
36
- });
37
- const [openDialog, setOpenDialog] = React.useState<UserActionDialog | null>(
38
- null,
39
- );
40
-
41
- /**
42
- * Assigns a key for each dialog based on its open state to ensure its
43
- * internal state is cleared when it is closed.
44
- */
45
- function getDialogKey(dialog: UserActionDialog) {
46
- return `${dialog}-${openDialog === dialog}-${user.id}`;
47
- }
48
-
49
- const { actions, items } = React.useMemo(() => {
50
- const actions = new Set(user.actions);
51
- const items: React.ReactElement[] = [];
52
- if (actions.has("edit-role")) {
53
- items.push(
54
- <PrimaryMenuItem
55
- key="edit-role"
56
- onSelect={() => setOpenDialog("edit-role")}
57
- disabled={
58
- rolesQuery.isLoading ||
59
- (rolesQuery.isSuccess && rolesQuery.data.length <= 1)
60
- }
61
- title={
62
- rolesQuery.isSuccess && rolesQuery.data.length <= 1
63
- ? "You cannot update the role for this user as there is only one role available."
64
- : undefined
65
- }
66
- >
67
- Edit role
68
- </PrimaryMenuItem>,
69
- );
70
- }
71
- if (actions.has("resend-invite")) {
72
- items.push(
73
- <PrimaryMenuItem
74
- key="resend-invite"
75
- onSelect={() => setOpenDialog("resend-invite")}
76
- >
77
- Resend invitation
78
- </PrimaryMenuItem>,
79
- );
80
- }
81
- if (actions.has("revoke-invite")) {
82
- items.push(
83
- <DestructiveMenuItem
84
- key="revoke-invite"
85
- onSelect={() => setOpenDialog("revoke-invite")}
86
- >
87
- Revoke invitation
88
- </DestructiveMenuItem>,
89
- );
90
- }
91
- if (actions.has("revoke-membership")) {
92
- items.push(
93
- <DestructiveMenuItem
94
- key="revoke-membership"
95
- onSelect={() => setOpenDialog("revoke-membership")}
96
- >
97
- Remove user
98
- </DestructiveMenuItem>,
99
- );
100
- }
101
- return {
102
- actions,
103
- items,
104
- };
105
- }, [rolesQuery, user.actions]);
106
-
107
- if (user.isLoggedInUser || items.length === 0) {
108
- return null;
109
- }
110
-
111
- return (
112
- <>
113
- <DropdownMenu.Root>
114
- <DropdownMenu.Trigger>{children}</DropdownMenu.Trigger>
115
- <DropdownMenuContent size="2" align="end">
116
- {items}
117
- </DropdownMenuContent>
118
- </DropdownMenu.Root>
119
-
120
- {actions.has("edit-role") && (
121
- <EditUserRoleDialog
122
- key={getDialogKey("edit-role")}
123
- user={user}
124
- open={openDialog === "edit-role"}
125
- onOpenChange={(open) => !open && setOpenDialog(null)}
126
- />
127
- )}
128
-
129
- {actions.has("revoke-membership") && (
130
- <DeleteUserDialog
131
- key={getDialogKey("revoke-membership")}
132
- user={user}
133
- open={openDialog === "revoke-membership"}
134
- onOpenChange={(open) => !open && setOpenDialog(null)}
135
- />
136
- )}
137
-
138
- {actions.has("revoke-invite") && (
139
- <RevokeInviteDialog
140
- key={getDialogKey("revoke-invite")}
141
- user={user}
142
- open={openDialog === "revoke-invite"}
143
- onOpenChange={(open) => !open && setOpenDialog(null)}
144
- />
145
- )}
146
-
147
- {actions.has("resend-invite") && (
148
- <ResendInviteDialog
149
- key={getDialogKey("resend-invite")}
150
- user={user}
151
- open={openDialog === "resend-invite"}
152
- onOpenChange={(open) => !open && setOpenDialog(null)}
153
- />
154
- )}
155
- </>
156
- );
157
- };
@@ -1,227 +0,0 @@
1
- "use client";
2
-
3
- import {
4
- Box,
5
- Card,
6
- DataList,
7
- Flex,
8
- Inset,
9
- Separator,
10
- Strong,
11
- Text,
12
- } from "@radix-ui/themes";
13
- import clsx from "clsx";
14
- import { Avatar, SecondaryButton, Skeleton } from "./elements";
15
- import { Me } from "../api";
16
- import { EditUserProfileDialog } from "./edit-user-profile-dialog";
17
- import { getBestName } from "./utils";
18
- import { getOAuthIcon, getOAuthName } from "./oauth-icons";
19
- import { GenericError } from "./generic-error";
20
-
21
- interface UserProfileProps {
22
- userData: Me;
23
- }
24
-
25
- export const UserProfile = ({ userData: user }: UserProfileProps) => {
26
- const oauthAccounts = Object.entries(user.oauthProfiles || {});
27
-
28
- return (
29
- <Card
30
- className={clsx("woswidgets-widget")}
31
- data-woswidgets-widget-id="user-profile"
32
- size="2"
33
- >
34
- <DataList.Root>
35
- {user.profilePictureUrl && (
36
- <>
37
- <DataList.Item align="center">
38
- <DataList.Label minWidth="220px" highContrast>
39
- <Strong>Profile picture</Strong>
40
- </DataList.Label>
41
- <DataList.Value>
42
- <Avatar
43
- size="2"
44
- fallback={<FallbackUserIcon />}
45
- src={user.profilePictureUrl}
46
- />
47
- </DataList.Value>
48
- </DataList.Item>
49
-
50
- <ListSeparator />
51
- </>
52
- )}
53
-
54
- <DataList.Item align="center">
55
- <DataList.Label highContrast>
56
- <Strong>Full name</Strong>
57
- </DataList.Label>
58
- <DataList.Value>
59
- <Flex
60
- align="center"
61
- justify="between"
62
- width="100%"
63
- minHeight="var(--space-6)"
64
- >
65
- <Text size="2">
66
- {getBestName(user) || (
67
- <Text
68
- color="gray"
69
- style={{ color: "var(--gray-10)", cursor: "default" }}
70
- >
71
- Not set
72
- </Text>
73
- )}
74
- </Text>
75
-
76
- <EditUserProfileDialog user={user}>
77
- <SecondaryButton>Edit</SecondaryButton>
78
- </EditUserProfileDialog>
79
- </Flex>
80
- </DataList.Value>
81
- </DataList.Item>
82
-
83
- <ListSeparator />
84
-
85
- <DataList.Item align="center">
86
- <DataList.Label highContrast>
87
- <Strong>Email address</Strong>
88
- </DataList.Label>
89
- <DataList.Value>
90
- <Flex align="center" minHeight="var(--space-6)">
91
- <Text size="2">{user.email}</Text>
92
- </Flex>
93
- </DataList.Value>
94
- </DataList.Item>
95
-
96
- {oauthAccounts.length > 0 && (
97
- <>
98
- <ListSeparator />
99
-
100
- <DataList.Item>
101
- <DataList.Label highContrast>
102
- <Strong>Connected accounts</Strong>
103
- </DataList.Label>
104
- <DataList.Value>
105
- <Flex direction="column" gap="2">
106
- {oauthAccounts.map(([account, data]) => (
107
- <OAuthAccount
108
- key={account}
109
- account={account}
110
- email={data?.email}
111
- />
112
- ))}
113
- </Flex>
114
- </DataList.Value>
115
- </DataList.Item>
116
- </>
117
- )}
118
- </DataList.Root>
119
- </Card>
120
- );
121
- };
122
-
123
- export function UserProfileLoading() {
124
- return (
125
- <Card size="2">
126
- <DataList.Root>
127
- <DataList.Item align="center">
128
- <DataList.Label minWidth="220px" highContrast>
129
- <Strong>
130
- <Skeleton>Full name</Skeleton>
131
- </Strong>
132
- </DataList.Label>
133
- <DataList.Value>
134
- <Flex
135
- align="center"
136
- justify="between"
137
- width="100%"
138
- minHeight="var(--space-6)"
139
- >
140
- <Text size="2">
141
- <Skeleton>Full name</Skeleton>
142
- </Text>
143
- </Flex>
144
- </DataList.Value>
145
- </DataList.Item>
146
-
147
- <ListSeparator />
148
-
149
- <DataList.Item align="center">
150
- <DataList.Label highContrast>
151
- <Strong>
152
- <Skeleton>Email address</Skeleton>
153
- </Strong>
154
- </DataList.Label>
155
- <DataList.Value>
156
- <Flex align="center" minHeight="var(--space-6)">
157
- <Text size="2">
158
- <Skeleton>Email address</Skeleton>
159
- </Text>
160
- </Flex>
161
- </DataList.Value>
162
- </DataList.Item>
163
- </DataList.Root>
164
- </Card>
165
- );
166
- }
167
-
168
- export function UserProfileError({ error }: { error: unknown }) {
169
- return (
170
- <Card size="2">
171
- <GenericError error={error} />
172
- </Card>
173
- );
174
- }
175
-
176
- const ListSeparator = () => (
177
- <Box asChild gridColumn="span 2">
178
- <Inset side="x">
179
- <Separator size="4" />
180
- </Inset>
181
- </Box>
182
- );
183
-
184
- const OAuthAccount = ({
185
- account,
186
- email,
187
- }: {
188
- account: string;
189
- email?: string | null;
190
- }) => {
191
- const Icon = getOAuthIcon(account);
192
- const name = getOAuthName(account);
193
-
194
- return (
195
- <Flex align="center" gap="1">
196
- <Icon />
197
-
198
- <Text size="2" ml="1">
199
- {name}
200
- </Text>
201
-
202
- {email && (
203
- <Box display={{ initial: "none", sm: "contents" }}>
204
- <Text size="2" color="gray">
205
-
206
- </Text>
207
- <Text size="2" color="gray">
208
- {email}
209
- </Text>
210
- </Box>
211
- )}
212
- </Flex>
213
- );
214
- };
215
-
216
- const FallbackUserIcon = () => (
217
- <svg
218
- xmlns="http://www.w3.org/2000/svg"
219
- width="20"
220
- height="20"
221
- fill="currentColor"
222
- viewBox="0 0 256 256"
223
- >
224
- <title>User icon</title>
225
- <path d="M229.19,213c-15.81-27.32-40.63-46.49-69.47-54.62a70,70,0,1,0-63.44,0C67.44,166.5,42.62,185.67,26.81,213a6,6,0,1,0,10.38,6C56.4,185.81,90.34,166,128,166s71.6,19.81,90.81,53a6,6,0,1,0,10.38-6ZM70,96a58,58,0,1,1,58,58A58.07,58.07,0,0,1,70,96Z" />
226
- </svg>
227
- );
@@ -1,187 +0,0 @@
1
- "use client";
2
-
3
- import { Card, Flex, Grid, Text } from "@radix-ui/themes";
4
- import clsx from "clsx";
5
- import { SecondaryButton, Skeleton } from "./elements";
6
- import { IconPanel } from "./icon-panel";
7
- import { ButtonIcon, LockClosedIcon } from "@radix-ui/react-icons";
8
- import { SetPasswordDialog } from "./set-password-dialog";
9
- import { ChangePasswordDialog } from "./change-password-dialog";
10
- import { AddMfaDialog } from "./add-mfa-dialog";
11
- import type {
12
- AuthenticationInformationResponseData as AuthenticationSettings,
13
- AuthenticationInformationResponseDataVerificationMethodsPassword as PasswordVerificationMethod,
14
- AuthenticationInformationResponseDataVerificationMethodsMfa as MfaVerificationMethod,
15
- } from "../api";
16
- import { ResetMfaDialog } from "./reset-mfa-dialog";
17
- import * as CardList from "../card-list";
18
- import { GenericError } from "./generic-error";
19
- import { getComparativeReadableDate } from "./utils";
20
-
21
- interface UserSecurityProps {
22
- settings: AuthenticationSettings;
23
- }
24
-
25
- export const UserSecurity = ({ settings }: UserSecurityProps) => {
26
- const passwordSettings = settings.verificationMethods.Password;
27
- const mfaSettings = settings.verificationMethods.Mfa;
28
-
29
- return (
30
- <CardList.Root
31
- className={clsx("woswidgets-widget")}
32
- data-woswidgets-widget-id="user-security"
33
- >
34
- {passwordSettings && (
35
- <CardList.Item>
36
- <PasswordSettings settings={passwordSettings} />
37
- </CardList.Item>
38
- )}
39
-
40
- {mfaSettings && (
41
- <CardList.Item>
42
- <MfaSettings
43
- settings={mfaSettings}
44
- isPasswordSet={!!passwordSettings?.isSetUp}
45
- />
46
- </CardList.Item>
47
- )}
48
- </CardList.Root>
49
- );
50
- };
51
-
52
- export function UserSecurityError({ error }: { error: unknown }) {
53
- return (
54
- <Card size="2">
55
- <GenericError error={error} />
56
- </Card>
57
- );
58
- }
59
-
60
- export function UserSecurityLoading() {
61
- return (
62
- <Card size="2">
63
- <Grid columns="auto 1fr auto" align="center" gap="4">
64
- <Skeleton>
65
- <IconPanel />
66
- </Skeleton>
67
-
68
- <Flex direction="column">
69
- <Text size="2" highContrast weight="bold" as="p" mb="-2px">
70
- <Skeleton>Password</Skeleton>
71
- </Text>
72
- <Text as="p" size="2" color="gray">
73
- <Skeleton>Set a password to access your account</Skeleton>
74
- </Text>
75
- </Flex>
76
-
77
- <ChangePasswordDialog>
78
- <Skeleton>
79
- <SecondaryButton>Change</SecondaryButton>
80
- </Skeleton>
81
- </ChangePasswordDialog>
82
- </Grid>
83
- </Card>
84
- );
85
- }
86
-
87
- function PasswordSettings({
88
- settings,
89
- }: {
90
- settings: NonNullable<PasswordVerificationMethod>;
91
- }) {
92
- return (
93
- <Grid columns="auto 1fr auto" align="center" gap="4">
94
- <IconPanel>
95
- <LockClosedIcon />
96
- </IconPanel>
97
-
98
- <Flex direction="column">
99
- <Text size="2" highContrast weight="bold" as="p" mb="-2px">
100
- Password
101
- </Text>
102
-
103
- {settings.isSetUp ? (
104
- settings.lastUsed && (
105
- <Text size="2" color="gray">
106
- Last used{" "}
107
- {getComparativeReadableDate(
108
- new Date(),
109
- new Date(settings.lastUsed),
110
- )}
111
- </Text>
112
- )
113
- ) : (
114
- <Text as="p" size="2" color="gray">
115
- Set a password to access your account
116
- </Text>
117
- )}
118
- </Flex>
119
-
120
- {settings.isSetUp ? (
121
- <ChangePasswordDialog>
122
- <SecondaryButton>Change</SecondaryButton>
123
- </ChangePasswordDialog>
124
- ) : (
125
- <SetPasswordDialog>
126
- <SecondaryButton>Set a password</SecondaryButton>
127
- </SetPasswordDialog>
128
- )}
129
- </Grid>
130
- );
131
- }
132
-
133
- function MfaSettings({
134
- settings,
135
- isPasswordSet,
136
- }: {
137
- settings: NonNullable<MfaVerificationMethod>;
138
- isPasswordSet: boolean;
139
- }) {
140
- return (
141
- <Grid columns="auto 1fr auto" align="center" gap="4">
142
- <IconPanel>
143
- <ButtonIcon />
144
- </IconPanel>
145
-
146
- <Flex direction="column">
147
- <Text size="2" highContrast weight="bold" as="p" mb="-2px">
148
- Multi-factor authentication
149
- </Text>
150
-
151
- {settings.isSetUp ? (
152
- <Text size="2">
153
- Authenticator app
154
- {settings.lastUsed && (
155
- <>
156
- <Text size="2" color="gray" mx="1">
157
-
158
- </Text>
159
- <Text size="2" color="gray">
160
- Last used{" "}
161
- {getComparativeReadableDate(
162
- new Date(),
163
- new Date(settings.lastUsed),
164
- )}
165
- </Text>
166
- </>
167
- )}
168
- </Text>
169
- ) : (
170
- <Text as="p" size="2" color="gray">
171
- Secure your account with an extra verification step
172
- </Text>
173
- )}
174
- </Flex>
175
-
176
- {settings.isSetUp ? (
177
- <ResetMfaDialog isPasswordSet={isPasswordSet}>
178
- <SecondaryButton>Disable</SecondaryButton>
179
- </ResetMfaDialog>
180
- ) : (
181
- <AddMfaDialog>
182
- <SecondaryButton>Set up authenticator app</SecondaryButton>
183
- </AddMfaDialog>
184
- )}
185
- </Grid>
186
- );
187
- }