@workos-inc/widgets 1.20.0 → 1.20.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -174,8 +174,8 @@ function ApiKeysTable({ apiKeys }) {
174
174
  const { dispatch } = useApiKeysContext();
175
175
  const pagination = getListMetadata(apiKeys);
176
176
  const hasPagination = !!(pagination.before || pagination.after);
177
- const hasPreviousPage = !!pagination.after;
178
- const hasNextPage = !!pagination.before;
177
+ const hasPreviousPage = !!pagination.before;
178
+ const hasNextPage = !!pagination.after;
179
179
  return /* @__PURE__ */ jsxs(Flex, {
180
180
  direction: "column",
181
181
  align: "stretch",
@@ -228,8 +228,8 @@ function ApiKeysTable({ apiKeys }) {
228
228
  onClick: () => dispatch({
229
229
  type: "SET_PAGINATION",
230
230
  pagination: {
231
- before: null,
232
- after: pagination.after
231
+ before: pagination.before,
232
+ after: null
233
233
  }
234
234
  }),
235
235
  children: /* @__PURE__ */ jsx(Translation, {
@@ -244,8 +244,8 @@ function ApiKeysTable({ apiKeys }) {
244
244
  onClick: () => dispatch({
245
245
  type: "SET_PAGINATION",
246
246
  pagination: {
247
- before: pagination.before,
248
- after: null
247
+ before: null,
248
+ after: pagination.after
249
249
  }
250
250
  }),
251
251
  children: /* @__PURE__ */ jsx(Translation, {
@@ -1 +1 @@
1
- {"version":3,"file":"api-keys-table.js","names":["Button","DropdownMenu.Root","DropdownMenu.Trigger","IconButton","DropdownMenu.Content","DropdownMenu.Item","DropdownMenu.Separator"],"sources":["../../../../src/lib/api-keys/api-keys-table.tsx"],"sourcesContent":["import { Flex, Text, Table, Code, Heading } from \"@radix-ui/themes\";\nimport { Button, DropdownMenu, IconButton } from \"../elements.js\";\nimport { DotsHorizontalIcon, MagnifyingGlassIcon } from \"@radix-ui/react-icons\";\nimport { useState } from \"react\";\nimport { RevokeApiKeyDialog } from \"./revoke-api-key-dialog.js\";\nimport { CreateApiKeyButton } from \"./create-api-key.js\";\nimport { ApiKeyDetailsDialog } from \"./api-key-details-dialog.js\";\nimport { RelativeTime } from \"./relative-time.js\";\nimport {\n ListOrganizationApiKeysResponse,\n ListOrganizationApiKeysResponseData,\n} from \"../api/types.js\";\nimport { useApiKeysContext } from \"./api-keys-context.js\";\nimport { useApiKeysSearchContext } from \"./api-keys-search-provider.js\";\nimport { ApiKeysSearch } from \"./api-keys-search.js\";\nimport { Translation } from \"../i18n/translation.js\";\nimport { useTranslation } from \"../i18n/use-translation.js\";\nimport { getListMetadata } from \"../utils/get-list-metadata.js\";\nimport {\n ApiKeyExpiresOn,\n EditApiKeyExpirationDialog,\n} from \"./api-key-expiration.js\";\nimport { useExpireApiKey } from \"../api/api-key.js\";\n\nfunction NoApiKeys() {\n const { clearSearch } = useApiKeysSearchContext();\n return (\n <Flex p=\"6\" gap=\"4\" justify=\"center\" align=\"center\" direction=\"column\">\n <Flex direction=\"column\" gap=\"1\" maxWidth=\"420px\" align=\"center\">\n <MagnifyingGlassIcon\n style={{ color: \"var(--gray-9)\" }}\n width=\"32px\"\n height=\"32px\"\n />\n <Heading size=\"5\" mb=\"1\" wrap=\"balance\" as=\"h3\">\n <Translation\n defaultMessage=\"No API keys match your search\"\n id=\"cKitHb\"\n description=\"Empty state message when no API keys match search\"\n />\n </Heading>\n </Flex>\n\n <Button variant=\"secondary\" onClick={clearSearch}>\n <Translation\n defaultMessage=\"Clear search\"\n id=\"jTupOW\"\n description=\"Button to clear API key search filters\"\n />\n </Button>\n </Flex>\n );\n}\n\nfunction ApiKeysTableHeader() {\n return (\n <Flex justify=\"between\" align=\"center\">\n <ApiKeysSearch name=\"api-keys-widget-search\" style={{ width: \"390px\" }} />\n <CreateApiKeyButton />\n </Flex>\n );\n}\n\ninterface ApiKeyRowProps {\n apiKey: ListOrganizationApiKeysResponseData;\n}\n\nfunction ApiKeyRow({ apiKey }: ApiKeyRowProps) {\n const [revokeDialogOpen, setRevokeDialogOpen] = useState(false);\n const [detailsOpen, setDetailsOpen] = useState(false);\n const [editExpirationOpen, setEditExpirationOpen] = useState(false);\n const {\n mutate: expireApiKey,\n error: expireError,\n isPending: expirePending,\n isSuccess: expireSuccess,\n reset: resetExpireApiKey,\n } = useExpireApiKey();\n const translate = useTranslation();\n const openEditExpirationDialog = () => {\n resetExpireApiKey();\n setEditExpirationOpen(true);\n };\n return (\n <>\n <RevokeApiKeyDialog\n // always remount the form when the dialog is opened to reset the validation errors\n key={`${revokeDialogOpen}`}\n open={revokeDialogOpen}\n onOpenChange={setRevokeDialogOpen}\n apiKey={apiKey}\n />\n <ApiKeyDetailsDialog\n open={detailsOpen}\n onOpenChange={setDetailsOpen}\n apiKey={apiKey}\n permissions={apiKey.permissions}\n />\n <EditApiKeyExpirationDialog\n open={editExpirationOpen}\n onOpenChange={(open) => {\n if (open) {\n resetExpireApiKey();\n }\n setEditExpirationOpen(open);\n }}\n apiKeyName={apiKey.name}\n expiresAt={apiKey.expiresAt}\n error={expireError}\n isPending={expirePending}\n isSuccess={expireSuccess}\n onReset={resetExpireApiKey}\n onSave={(expiresAt) =>\n expireApiKey(\n { apiKeyId: apiKey.id, expiresAt },\n { onSuccess: () => setEditExpirationOpen(false) },\n )\n }\n />\n <Table.Row align=\"center\">\n <Table.Cell>\n <Text>{apiKey.name}</Text>\n </Table.Cell>\n <Table.Cell>\n <Code color=\"gray\">{apiKey.obfuscatedValue}</Code>\n </Table.Cell>\n <Table.Cell>\n <Text\n style={apiKey.lastUsedAt ? undefined : { color: \"var(--gray-10)\" }}\n >\n <RelativeTime\n date={apiKey.lastUsedAt ? new Date(apiKey.lastUsedAt) : undefined}\n />\n </Text>\n </Table.Cell>\n <Table.Cell>\n <Text>\n <ApiKeyExpiresOn expiresAt={apiKey.expiresAt} includeTime />\n </Text>\n </Table.Cell>\n <Table.Cell justify=\"end\">\n <DropdownMenu.Root>\n <DropdownMenu.Trigger>\n {(() => {\n const title = translate({\n defaultMessage: \"API key actions\",\n id: \"RIBfYe\",\n description: \"Tooltip for API key actions menu button\",\n });\n return (\n <IconButton title={title}>\n <DotsHorizontalIcon />\n </IconButton>\n );\n })()}\n </DropdownMenu.Trigger>\n <DropdownMenu.Content size=\"2\" align=\"end\">\n <DropdownMenu.Item onSelect={() => setDetailsOpen(true)}>\n <Translation\n defaultMessage=\"View details\"\n id=\"VGKbbj\"\n description=\"Menu item to view API key details\"\n />\n </DropdownMenu.Item>\n <DropdownMenu.Item onSelect={openEditExpirationDialog}>\n <Translation\n defaultMessage=\"Edit expiration\"\n id=\"fONrTk\"\n description=\"Menu item to edit an API key expiration\"\n />\n </DropdownMenu.Item>\n <DropdownMenu.Separator />\n <DropdownMenu.Item\n variant=\"destructive\"\n onSelect={() => setRevokeDialogOpen(true)}\n >\n <Translation\n defaultMessage=\"Revoke key\"\n id=\"KZIJPP\"\n description=\"Menu item to revoke an API key\"\n />\n </DropdownMenu.Item>\n </DropdownMenu.Content>\n </DropdownMenu.Root>\n </Table.Cell>\n </Table.Row>\n </>\n );\n}\n\nexport function ApiKeysTable({\n apiKeys,\n}: {\n apiKeys: ListOrganizationApiKeysResponse;\n}) {\n const { dispatch } = useApiKeysContext();\n\n // The API response previously returned an object with the `listMetadata`\n // property. We might not need this, but it's a defensive check until we\n // verify the API response changes are correct.\n const pagination = getListMetadata(apiKeys);\n\n const hasPagination = !!(pagination.before || pagination.after);\n const hasPreviousPage = !!pagination.after;\n const hasNextPage = !!pagination.before;\n\n return (\n <Flex direction=\"column\" align=\"stretch\" gap=\"3\">\n <ApiKeysTableHeader />\n {apiKeys.data.length === 0 ? (\n <NoApiKeys />\n ) : (\n <>\n <Table.Root variant=\"ghost\" size=\"2\">\n <Table.Header>\n <Table.Row>\n <Table.ColumnHeaderCell width=\"25%\">\n <Translation\n defaultMessage=\"Name\"\n id=\"VYbVXN\"\n description=\"Table column header for API key name\"\n />\n </Table.ColumnHeaderCell>\n <Table.ColumnHeaderCell width=\"25%\">\n <Translation\n defaultMessage=\"Secret key\"\n id=\"H5k7GB\"\n description=\"Table column header for API key secret value\"\n />\n </Table.ColumnHeaderCell>\n <Table.ColumnHeaderCell width=\"25%\">\n <Translation\n defaultMessage=\"Last used\"\n id=\"E46t3O\"\n description=\"Table column header for API key last used timestamp\"\n />\n </Table.ColumnHeaderCell>\n <Table.ColumnHeaderCell width=\"25%\">\n <Translation\n defaultMessage=\"Expires\"\n id=\"3q8EjA\"\n description=\"Table column header for API key expiration date\"\n />\n </Table.ColumnHeaderCell>\n <Table.ColumnHeaderCell width=\"28px\" />\n </Table.Row>\n </Table.Header>\n <Table.Body>\n {apiKeys.data.map((apiKey) => (\n <ApiKeyRow key={apiKey.id} apiKey={apiKey} />\n ))}\n </Table.Body>\n </Table.Root>\n {hasPagination && (\n <Flex gap=\"2\" justify=\"end\">\n <Button\n variant=\"secondary\"\n disabled={!hasPreviousPage}\n size=\"1\"\n onClick={() =>\n dispatch({\n type: \"SET_PAGINATION\",\n pagination: { before: null, after: pagination.after },\n })\n }\n >\n <Translation\n defaultMessage=\"Previous\"\n id=\"f7TUj0\"\n description=\"Button to navigate to previous page of API keys\"\n />\n </Button>\n <Button\n variant=\"secondary\"\n disabled={!hasNextPage}\n size=\"1\"\n onClick={() =>\n dispatch({\n type: \"SET_PAGINATION\",\n pagination: { before: pagination.before, after: null },\n })\n }\n >\n <Translation\n defaultMessage=\"Next\"\n id=\"L2EBxV\"\n description=\"Button to navigate to next page of API keys\"\n />\n </Button>\n </Flex>\n )}\n </>\n )}\n </Flex>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"api-keys-table.js","names":["Button","DropdownMenu.Root","DropdownMenu.Trigger","IconButton","DropdownMenu.Content","DropdownMenu.Item","DropdownMenu.Separator"],"sources":["../../../../src/lib/api-keys/api-keys-table.tsx"],"sourcesContent":["import { Flex, Text, Table, Code, Heading } from \"@radix-ui/themes\";\nimport { Button, DropdownMenu, IconButton } from \"../elements.js\";\nimport { DotsHorizontalIcon, MagnifyingGlassIcon } from \"@radix-ui/react-icons\";\nimport { useState } from \"react\";\nimport { RevokeApiKeyDialog } from \"./revoke-api-key-dialog.js\";\nimport { CreateApiKeyButton } from \"./create-api-key.js\";\nimport { ApiKeyDetailsDialog } from \"./api-key-details-dialog.js\";\nimport { RelativeTime } from \"./relative-time.js\";\nimport {\n ListOrganizationApiKeysResponse,\n ListOrganizationApiKeysResponseData,\n} from \"../api/types.js\";\nimport { useApiKeysContext } from \"./api-keys-context.js\";\nimport { useApiKeysSearchContext } from \"./api-keys-search-provider.js\";\nimport { ApiKeysSearch } from \"./api-keys-search.js\";\nimport { Translation } from \"../i18n/translation.js\";\nimport { useTranslation } from \"../i18n/use-translation.js\";\nimport { getListMetadata } from \"../utils/get-list-metadata.js\";\nimport {\n ApiKeyExpiresOn,\n EditApiKeyExpirationDialog,\n} from \"./api-key-expiration.js\";\nimport { useExpireApiKey } from \"../api/api-key.js\";\n\nfunction NoApiKeys() {\n const { clearSearch } = useApiKeysSearchContext();\n return (\n <Flex p=\"6\" gap=\"4\" justify=\"center\" align=\"center\" direction=\"column\">\n <Flex direction=\"column\" gap=\"1\" maxWidth=\"420px\" align=\"center\">\n <MagnifyingGlassIcon\n style={{ color: \"var(--gray-9)\" }}\n width=\"32px\"\n height=\"32px\"\n />\n <Heading size=\"5\" mb=\"1\" wrap=\"balance\" as=\"h3\">\n <Translation\n defaultMessage=\"No API keys match your search\"\n id=\"cKitHb\"\n description=\"Empty state message when no API keys match search\"\n />\n </Heading>\n </Flex>\n\n <Button variant=\"secondary\" onClick={clearSearch}>\n <Translation\n defaultMessage=\"Clear search\"\n id=\"jTupOW\"\n description=\"Button to clear API key search filters\"\n />\n </Button>\n </Flex>\n );\n}\n\nfunction ApiKeysTableHeader() {\n return (\n <Flex justify=\"between\" align=\"center\">\n <ApiKeysSearch name=\"api-keys-widget-search\" style={{ width: \"390px\" }} />\n <CreateApiKeyButton />\n </Flex>\n );\n}\n\ninterface ApiKeyRowProps {\n apiKey: ListOrganizationApiKeysResponseData;\n}\n\nfunction ApiKeyRow({ apiKey }: ApiKeyRowProps) {\n const [revokeDialogOpen, setRevokeDialogOpen] = useState(false);\n const [detailsOpen, setDetailsOpen] = useState(false);\n const [editExpirationOpen, setEditExpirationOpen] = useState(false);\n const {\n mutate: expireApiKey,\n error: expireError,\n isPending: expirePending,\n isSuccess: expireSuccess,\n reset: resetExpireApiKey,\n } = useExpireApiKey();\n const translate = useTranslation();\n const openEditExpirationDialog = () => {\n resetExpireApiKey();\n setEditExpirationOpen(true);\n };\n return (\n <>\n <RevokeApiKeyDialog\n // always remount the form when the dialog is opened to reset the validation errors\n key={`${revokeDialogOpen}`}\n open={revokeDialogOpen}\n onOpenChange={setRevokeDialogOpen}\n apiKey={apiKey}\n />\n <ApiKeyDetailsDialog\n open={detailsOpen}\n onOpenChange={setDetailsOpen}\n apiKey={apiKey}\n permissions={apiKey.permissions}\n />\n <EditApiKeyExpirationDialog\n open={editExpirationOpen}\n onOpenChange={(open) => {\n if (open) {\n resetExpireApiKey();\n }\n setEditExpirationOpen(open);\n }}\n apiKeyName={apiKey.name}\n expiresAt={apiKey.expiresAt}\n error={expireError}\n isPending={expirePending}\n isSuccess={expireSuccess}\n onReset={resetExpireApiKey}\n onSave={(expiresAt) =>\n expireApiKey(\n { apiKeyId: apiKey.id, expiresAt },\n { onSuccess: () => setEditExpirationOpen(false) },\n )\n }\n />\n <Table.Row align=\"center\">\n <Table.Cell>\n <Text>{apiKey.name}</Text>\n </Table.Cell>\n <Table.Cell>\n <Code color=\"gray\">{apiKey.obfuscatedValue}</Code>\n </Table.Cell>\n <Table.Cell>\n <Text\n style={apiKey.lastUsedAt ? undefined : { color: \"var(--gray-10)\" }}\n >\n <RelativeTime\n date={apiKey.lastUsedAt ? new Date(apiKey.lastUsedAt) : undefined}\n />\n </Text>\n </Table.Cell>\n <Table.Cell>\n <Text>\n <ApiKeyExpiresOn expiresAt={apiKey.expiresAt} includeTime />\n </Text>\n </Table.Cell>\n <Table.Cell justify=\"end\">\n <DropdownMenu.Root>\n <DropdownMenu.Trigger>\n {(() => {\n const title = translate({\n defaultMessage: \"API key actions\",\n id: \"RIBfYe\",\n description: \"Tooltip for API key actions menu button\",\n });\n return (\n <IconButton title={title}>\n <DotsHorizontalIcon />\n </IconButton>\n );\n })()}\n </DropdownMenu.Trigger>\n <DropdownMenu.Content size=\"2\" align=\"end\">\n <DropdownMenu.Item onSelect={() => setDetailsOpen(true)}>\n <Translation\n defaultMessage=\"View details\"\n id=\"VGKbbj\"\n description=\"Menu item to view API key details\"\n />\n </DropdownMenu.Item>\n <DropdownMenu.Item onSelect={openEditExpirationDialog}>\n <Translation\n defaultMessage=\"Edit expiration\"\n id=\"fONrTk\"\n description=\"Menu item to edit an API key expiration\"\n />\n </DropdownMenu.Item>\n <DropdownMenu.Separator />\n <DropdownMenu.Item\n variant=\"destructive\"\n onSelect={() => setRevokeDialogOpen(true)}\n >\n <Translation\n defaultMessage=\"Revoke key\"\n id=\"KZIJPP\"\n description=\"Menu item to revoke an API key\"\n />\n </DropdownMenu.Item>\n </DropdownMenu.Content>\n </DropdownMenu.Root>\n </Table.Cell>\n </Table.Row>\n </>\n );\n}\n\nexport function ApiKeysTable({\n apiKeys,\n}: {\n apiKeys: ListOrganizationApiKeysResponse;\n}) {\n const { dispatch } = useApiKeysContext();\n\n // The API response previously returned an object with the `listMetadata`\n // property. We might not need this, but it's a defensive check until we\n // verify the API response changes are correct.\n const pagination = getListMetadata(apiKeys);\n\n const hasPagination = !!(pagination.before || pagination.after);\n const hasPreviousPage = !!pagination.before;\n const hasNextPage = !!pagination.after;\n\n return (\n <Flex direction=\"column\" align=\"stretch\" gap=\"3\">\n <ApiKeysTableHeader />\n {apiKeys.data.length === 0 ? (\n <NoApiKeys />\n ) : (\n <>\n <Table.Root variant=\"ghost\" size=\"2\">\n <Table.Header>\n <Table.Row>\n <Table.ColumnHeaderCell width=\"25%\">\n <Translation\n defaultMessage=\"Name\"\n id=\"VYbVXN\"\n description=\"Table column header for API key name\"\n />\n </Table.ColumnHeaderCell>\n <Table.ColumnHeaderCell width=\"25%\">\n <Translation\n defaultMessage=\"Secret key\"\n id=\"H5k7GB\"\n description=\"Table column header for API key secret value\"\n />\n </Table.ColumnHeaderCell>\n <Table.ColumnHeaderCell width=\"25%\">\n <Translation\n defaultMessage=\"Last used\"\n id=\"E46t3O\"\n description=\"Table column header for API key last used timestamp\"\n />\n </Table.ColumnHeaderCell>\n <Table.ColumnHeaderCell width=\"25%\">\n <Translation\n defaultMessage=\"Expires\"\n id=\"3q8EjA\"\n description=\"Table column header for API key expiration date\"\n />\n </Table.ColumnHeaderCell>\n <Table.ColumnHeaderCell width=\"28px\" />\n </Table.Row>\n </Table.Header>\n <Table.Body>\n {apiKeys.data.map((apiKey) => (\n <ApiKeyRow key={apiKey.id} apiKey={apiKey} />\n ))}\n </Table.Body>\n </Table.Root>\n {hasPagination && (\n <Flex gap=\"2\" justify=\"end\">\n <Button\n variant=\"secondary\"\n disabled={!hasPreviousPage}\n size=\"1\"\n onClick={() =>\n dispatch({\n type: \"SET_PAGINATION\",\n pagination: { before: pagination.before, after: null },\n })\n }\n >\n <Translation\n defaultMessage=\"Previous\"\n id=\"f7TUj0\"\n description=\"Button to navigate to previous page of API keys\"\n />\n </Button>\n <Button\n variant=\"secondary\"\n disabled={!hasNextPage}\n size=\"1\"\n onClick={() =>\n dispatch({\n type: \"SET_PAGINATION\",\n pagination: { before: null, after: pagination.after },\n })\n }\n >\n <Translation\n defaultMessage=\"Next\"\n id=\"L2EBxV\"\n description=\"Button to navigate to next page of API keys\"\n />\n </Button>\n </Flex>\n )}\n </>\n )}\n </Flex>\n );\n}\n"],"mappings":"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"}
@@ -176,8 +176,8 @@ function UserApiKeysTable({ apiKeys, canCreate, canManageAll }) {
176
176
  const { dispatch } = useUserApiKeysContext();
177
177
  const pagination = getListMetadata(apiKeys);
178
178
  const hasPagination = !!(pagination.before || pagination.after);
179
- const hasPreviousPage = !!pagination.after;
180
- const hasNextPage = !!pagination.before;
179
+ const hasPreviousPage = !!pagination.before;
180
+ const hasNextPage = !!pagination.after;
181
181
  return /* @__PURE__ */ jsxs(Flex, {
182
182
  direction: "column",
183
183
  align: "stretch",
@@ -241,8 +241,8 @@ function UserApiKeysTable({ apiKeys, canCreate, canManageAll }) {
241
241
  onClick: () => dispatch({
242
242
  type: "SET_PAGINATION",
243
243
  pagination: {
244
- before: null,
245
- after: pagination.after
244
+ before: pagination.before,
245
+ after: null
246
246
  }
247
247
  }),
248
248
  children: /* @__PURE__ */ jsx(Translation, {
@@ -257,8 +257,8 @@ function UserApiKeysTable({ apiKeys, canCreate, canManageAll }) {
257
257
  onClick: () => dispatch({
258
258
  type: "SET_PAGINATION",
259
259
  pagination: {
260
- before: pagination.before,
261
- after: null
260
+ before: null,
261
+ after: pagination.after
262
262
  }
263
263
  }),
264
264
  children: /* @__PURE__ */ jsx(Translation, {
@@ -1 +1 @@
1
- {"version":3,"file":"user-api-keys-table.js","names":["Button","DropdownMenu.Root","DropdownMenu.Trigger","IconButton","DropdownMenu.Content","DropdownMenu.Item","DropdownMenu.Separator"],"sources":["../../../../src/lib/user-api-keys/user-api-keys-table.tsx"],"sourcesContent":["import { Flex, Text, Table, Code, Heading } from \"@radix-ui/themes\";\nimport { Button, DropdownMenu, IconButton } from \"../elements.js\";\nimport { DotsHorizontalIcon, MagnifyingGlassIcon } from \"@radix-ui/react-icons\";\nimport { useState } from \"react\";\nimport { RevokeUserApiKeyDialog } from \"./revoke-user-api-key-dialog.js\";\nimport { CreateUserApiKeyButton } from \"./create-user-api-key.js\";\nimport { UserApiKeyDetailsDialog } from \"./user-api-key-details-dialog.js\";\nimport { RelativeTime } from \"../api-keys/relative-time.js\";\nimport type {\n ListUserApiKeysResponse,\n ListUserApiKeysResponseData,\n} from \"../api/user-api-key.js\";\nimport { useUserApiKeysContext } from \"./user-api-keys-context.js\";\nimport { useUserApiKeysSearchContext } from \"./user-api-keys-search-provider.js\";\nimport { UserApiKeysSearch } from \"./user-api-keys-search.js\";\nimport { Translation } from \"../i18n/translation.js\";\nimport { useTranslation } from \"../i18n/use-translation.js\";\nimport { getListMetadata } from \"../utils/get-list-metadata.js\";\nimport {\n ApiKeyExpiresOn,\n EditApiKeyExpirationDialog,\n} from \"../api-keys/api-key-expiration.js\";\nimport { useExpireUserApiKey } from \"../api/user-api-key.js\";\nimport { getUserApiKeyCreatedByLabel } from \"./user-api-key-owner.js\";\n\nfunction NoUserApiKeys() {\n const { clearSearch } = useUserApiKeysSearchContext();\n return (\n <Flex p=\"6\" gap=\"4\" justify=\"center\" align=\"center\" direction=\"column\">\n <Flex direction=\"column\" gap=\"1\" maxWidth=\"420px\" align=\"center\">\n <MagnifyingGlassIcon\n style={{ color: \"var(--gray-9)\" }}\n width=\"32px\"\n height=\"32px\"\n />\n <Heading size=\"5\" mb=\"1\" wrap=\"balance\" as=\"h3\">\n <Translation\n defaultMessage=\"No API keys match your search\"\n id=\"cKitHb\"\n description=\"Empty state message when no API keys match search\"\n />\n </Heading>\n </Flex>\n\n <Button variant=\"secondary\" onClick={clearSearch}>\n <Translation\n defaultMessage=\"Clear search\"\n id=\"jTupOW\"\n description=\"Button to clear API key search filters\"\n />\n </Button>\n </Flex>\n );\n}\n\nfunction UserApiKeysTableHeader({ canCreate }: { canCreate: boolean }) {\n return (\n <Flex justify=\"between\" align=\"center\">\n <UserApiKeysSearch\n name=\"user-api-keys-widget-search\"\n style={{ width: \"390px\" }}\n />\n <CreateUserApiKeyButton canCreate={canCreate} />\n </Flex>\n );\n}\n\ninterface UserApiKeyRowProps {\n apiKey: ListUserApiKeysResponseData;\n canManageAll: boolean;\n}\n\nfunction UserApiKeyRow({ apiKey, canManageAll }: UserApiKeyRowProps) {\n const [revokeDialogOpen, setRevokeDialogOpen] = useState(false);\n const [detailsOpen, setDetailsOpen] = useState(false);\n const [editExpirationOpen, setEditExpirationOpen] = useState(false);\n const {\n mutate: expireUserApiKey,\n error: expireError,\n isPending: expirePending,\n isSuccess: expireSuccess,\n reset: resetExpireUserApiKey,\n } = useExpireUserApiKey();\n const translate = useTranslation();\n const openEditExpirationDialog = () => {\n resetExpireUserApiKey();\n setEditExpirationOpen(true);\n };\n return (\n <>\n <RevokeUserApiKeyDialog\n key={`${revokeDialogOpen}`}\n open={revokeDialogOpen}\n onOpenChange={setRevokeDialogOpen}\n apiKey={apiKey}\n />\n <UserApiKeyDetailsDialog\n open={detailsOpen}\n onOpenChange={setDetailsOpen}\n apiKey={apiKey}\n permissions={apiKey.permissions}\n />\n <EditApiKeyExpirationDialog\n open={editExpirationOpen}\n onOpenChange={(open) => {\n if (open) {\n resetExpireUserApiKey();\n }\n setEditExpirationOpen(open);\n }}\n apiKeyName={apiKey.name}\n expiresAt={apiKey.expiresAt}\n error={expireError}\n isPending={expirePending}\n isSuccess={expireSuccess}\n onReset={resetExpireUserApiKey}\n onSave={(expiresAt) =>\n expireUserApiKey(\n { apiKeyId: apiKey.id, expiresAt },\n { onSuccess: () => setEditExpirationOpen(false) },\n )\n }\n />\n <Table.Row align=\"center\">\n <Table.Cell>\n <Text>{apiKey.name}</Text>\n </Table.Cell>\n <Table.Cell>\n <Code color=\"gray\">{apiKey.obfuscatedValue}</Code>\n </Table.Cell>\n {canManageAll ? (\n <Table.Cell>\n <Text>{getUserApiKeyCreatedByLabel(apiKey)}</Text>\n </Table.Cell>\n ) : null}\n <Table.Cell>\n <Text\n style={apiKey.lastUsedAt ? undefined : { color: \"var(--gray-10)\" }}\n >\n <RelativeTime\n date={apiKey.lastUsedAt ? new Date(apiKey.lastUsedAt) : undefined}\n />\n </Text>\n </Table.Cell>\n <Table.Cell>\n <Text>\n <ApiKeyExpiresOn expiresAt={apiKey.expiresAt} includeTime />\n </Text>\n </Table.Cell>\n <Table.Cell justify=\"end\">\n <DropdownMenu.Root>\n <DropdownMenu.Trigger>\n {(() => {\n const title = translate({\n defaultMessage: \"API key actions\",\n id: \"RIBfYe\",\n description: \"Tooltip for API key actions menu button\",\n });\n return (\n <IconButton title={title}>\n <DotsHorizontalIcon />\n </IconButton>\n );\n })()}\n </DropdownMenu.Trigger>\n <DropdownMenu.Content size=\"2\" align=\"end\">\n <DropdownMenu.Item onSelect={() => setDetailsOpen(true)}>\n <Translation\n defaultMessage=\"View details\"\n id=\"VGKbbj\"\n description=\"Menu item to view API key details\"\n />\n </DropdownMenu.Item>\n <DropdownMenu.Item onSelect={openEditExpirationDialog}>\n <Translation\n defaultMessage=\"Edit expiration\"\n id=\"fONrTk\"\n description=\"Menu item to edit an API key expiration\"\n />\n </DropdownMenu.Item>\n <DropdownMenu.Separator />\n <DropdownMenu.Item\n variant=\"destructive\"\n onSelect={() => setRevokeDialogOpen(true)}\n >\n <Translation\n defaultMessage=\"Revoke key\"\n id=\"KZIJPP\"\n description=\"Menu item to revoke an API key\"\n />\n </DropdownMenu.Item>\n </DropdownMenu.Content>\n </DropdownMenu.Root>\n </Table.Cell>\n </Table.Row>\n </>\n );\n}\n\nexport function UserApiKeysTable({\n apiKeys,\n canCreate,\n canManageAll,\n}: {\n apiKeys: ListUserApiKeysResponse;\n canCreate: boolean;\n canManageAll: boolean;\n}) {\n const { dispatch } = useUserApiKeysContext();\n const pagination = getListMetadata(apiKeys);\n\n const hasPagination = !!(pagination.before || pagination.after);\n const hasPreviousPage = !!pagination.after;\n const hasNextPage = !!pagination.before;\n\n return (\n <Flex direction=\"column\" align=\"stretch\" gap=\"3\">\n <UserApiKeysTableHeader canCreate={canCreate} />\n {apiKeys.data.length === 0 ? (\n <NoUserApiKeys />\n ) : (\n <>\n <Table.Root variant=\"ghost\" size=\"2\">\n <Table.Header>\n <Table.Row>\n <Table.ColumnHeaderCell width={canManageAll ? \"20%\" : \"25%\"}>\n <Translation\n defaultMessage=\"Name\"\n id=\"VYbVXN\"\n description=\"Table column header for API key name\"\n />\n </Table.ColumnHeaderCell>\n <Table.ColumnHeaderCell width={canManageAll ? \"20%\" : \"25%\"}>\n <Translation\n defaultMessage=\"Secret key\"\n id=\"H5k7GB\"\n description=\"Table column header for API key secret value\"\n />\n </Table.ColumnHeaderCell>\n {canManageAll ? (\n <Table.ColumnHeaderCell width=\"20%\">\n <Translation\n defaultMessage=\"Created by\"\n id=\"en10bZ\"\n description=\"Table column header for API key creator\"\n />\n </Table.ColumnHeaderCell>\n ) : null}\n <Table.ColumnHeaderCell width={canManageAll ? \"20%\" : \"25%\"}>\n <Translation\n defaultMessage=\"Last used\"\n id=\"E46t3O\"\n description=\"Table column header for API key last used timestamp\"\n />\n </Table.ColumnHeaderCell>\n <Table.ColumnHeaderCell width={canManageAll ? \"20%\" : \"25%\"}>\n <Translation\n defaultMessage=\"Expires\"\n id=\"3q8EjA\"\n description=\"Table column header for API key expiration date\"\n />\n </Table.ColumnHeaderCell>\n <Table.ColumnHeaderCell width=\"28px\" />\n </Table.Row>\n </Table.Header>\n <Table.Body>\n {apiKeys.data.map((apiKey) => (\n <UserApiKeyRow\n key={apiKey.id}\n apiKey={apiKey}\n canManageAll={canManageAll}\n />\n ))}\n </Table.Body>\n </Table.Root>\n {hasPagination && (\n <Flex gap=\"2\" justify=\"end\">\n <Button\n variant=\"secondary\"\n disabled={!hasPreviousPage}\n size=\"1\"\n onClick={() =>\n dispatch({\n type: \"SET_PAGINATION\",\n pagination: { before: null, after: pagination.after },\n })\n }\n >\n <Translation\n defaultMessage=\"Previous\"\n id=\"f7TUj0\"\n description=\"Button to navigate to previous page of API keys\"\n />\n </Button>\n <Button\n variant=\"secondary\"\n disabled={!hasNextPage}\n size=\"1\"\n onClick={() =>\n dispatch({\n type: \"SET_PAGINATION\",\n pagination: { before: pagination.before, after: null },\n })\n }\n >\n <Translation\n defaultMessage=\"Next\"\n id=\"L2EBxV\"\n description=\"Button to navigate to next page of API keys\"\n />\n </Button>\n </Flex>\n )}\n </>\n )}\n </Flex>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"user-api-keys-table.js","names":["Button","DropdownMenu.Root","DropdownMenu.Trigger","IconButton","DropdownMenu.Content","DropdownMenu.Item","DropdownMenu.Separator"],"sources":["../../../../src/lib/user-api-keys/user-api-keys-table.tsx"],"sourcesContent":["import { Flex, Text, Table, Code, Heading } from \"@radix-ui/themes\";\nimport { Button, DropdownMenu, IconButton } from \"../elements.js\";\nimport { DotsHorizontalIcon, MagnifyingGlassIcon } from \"@radix-ui/react-icons\";\nimport { useState } from \"react\";\nimport { RevokeUserApiKeyDialog } from \"./revoke-user-api-key-dialog.js\";\nimport { CreateUserApiKeyButton } from \"./create-user-api-key.js\";\nimport { UserApiKeyDetailsDialog } from \"./user-api-key-details-dialog.js\";\nimport { RelativeTime } from \"../api-keys/relative-time.js\";\nimport type {\n ListUserApiKeysResponse,\n ListUserApiKeysResponseData,\n} from \"../api/user-api-key.js\";\nimport { useUserApiKeysContext } from \"./user-api-keys-context.js\";\nimport { useUserApiKeysSearchContext } from \"./user-api-keys-search-provider.js\";\nimport { UserApiKeysSearch } from \"./user-api-keys-search.js\";\nimport { Translation } from \"../i18n/translation.js\";\nimport { useTranslation } from \"../i18n/use-translation.js\";\nimport { getListMetadata } from \"../utils/get-list-metadata.js\";\nimport {\n ApiKeyExpiresOn,\n EditApiKeyExpirationDialog,\n} from \"../api-keys/api-key-expiration.js\";\nimport { useExpireUserApiKey } from \"../api/user-api-key.js\";\nimport { getUserApiKeyCreatedByLabel } from \"./user-api-key-owner.js\";\n\nfunction NoUserApiKeys() {\n const { clearSearch } = useUserApiKeysSearchContext();\n return (\n <Flex p=\"6\" gap=\"4\" justify=\"center\" align=\"center\" direction=\"column\">\n <Flex direction=\"column\" gap=\"1\" maxWidth=\"420px\" align=\"center\">\n <MagnifyingGlassIcon\n style={{ color: \"var(--gray-9)\" }}\n width=\"32px\"\n height=\"32px\"\n />\n <Heading size=\"5\" mb=\"1\" wrap=\"balance\" as=\"h3\">\n <Translation\n defaultMessage=\"No API keys match your search\"\n id=\"cKitHb\"\n description=\"Empty state message when no API keys match search\"\n />\n </Heading>\n </Flex>\n\n <Button variant=\"secondary\" onClick={clearSearch}>\n <Translation\n defaultMessage=\"Clear search\"\n id=\"jTupOW\"\n description=\"Button to clear API key search filters\"\n />\n </Button>\n </Flex>\n );\n}\n\nfunction UserApiKeysTableHeader({ canCreate }: { canCreate: boolean }) {\n return (\n <Flex justify=\"between\" align=\"center\">\n <UserApiKeysSearch\n name=\"user-api-keys-widget-search\"\n style={{ width: \"390px\" }}\n />\n <CreateUserApiKeyButton canCreate={canCreate} />\n </Flex>\n );\n}\n\ninterface UserApiKeyRowProps {\n apiKey: ListUserApiKeysResponseData;\n canManageAll: boolean;\n}\n\nfunction UserApiKeyRow({ apiKey, canManageAll }: UserApiKeyRowProps) {\n const [revokeDialogOpen, setRevokeDialogOpen] = useState(false);\n const [detailsOpen, setDetailsOpen] = useState(false);\n const [editExpirationOpen, setEditExpirationOpen] = useState(false);\n const {\n mutate: expireUserApiKey,\n error: expireError,\n isPending: expirePending,\n isSuccess: expireSuccess,\n reset: resetExpireUserApiKey,\n } = useExpireUserApiKey();\n const translate = useTranslation();\n const openEditExpirationDialog = () => {\n resetExpireUserApiKey();\n setEditExpirationOpen(true);\n };\n return (\n <>\n <RevokeUserApiKeyDialog\n key={`${revokeDialogOpen}`}\n open={revokeDialogOpen}\n onOpenChange={setRevokeDialogOpen}\n apiKey={apiKey}\n />\n <UserApiKeyDetailsDialog\n open={detailsOpen}\n onOpenChange={setDetailsOpen}\n apiKey={apiKey}\n permissions={apiKey.permissions}\n />\n <EditApiKeyExpirationDialog\n open={editExpirationOpen}\n onOpenChange={(open) => {\n if (open) {\n resetExpireUserApiKey();\n }\n setEditExpirationOpen(open);\n }}\n apiKeyName={apiKey.name}\n expiresAt={apiKey.expiresAt}\n error={expireError}\n isPending={expirePending}\n isSuccess={expireSuccess}\n onReset={resetExpireUserApiKey}\n onSave={(expiresAt) =>\n expireUserApiKey(\n { apiKeyId: apiKey.id, expiresAt },\n { onSuccess: () => setEditExpirationOpen(false) },\n )\n }\n />\n <Table.Row align=\"center\">\n <Table.Cell>\n <Text>{apiKey.name}</Text>\n </Table.Cell>\n <Table.Cell>\n <Code color=\"gray\">{apiKey.obfuscatedValue}</Code>\n </Table.Cell>\n {canManageAll ? (\n <Table.Cell>\n <Text>{getUserApiKeyCreatedByLabel(apiKey)}</Text>\n </Table.Cell>\n ) : null}\n <Table.Cell>\n <Text\n style={apiKey.lastUsedAt ? undefined : { color: \"var(--gray-10)\" }}\n >\n <RelativeTime\n date={apiKey.lastUsedAt ? new Date(apiKey.lastUsedAt) : undefined}\n />\n </Text>\n </Table.Cell>\n <Table.Cell>\n <Text>\n <ApiKeyExpiresOn expiresAt={apiKey.expiresAt} includeTime />\n </Text>\n </Table.Cell>\n <Table.Cell justify=\"end\">\n <DropdownMenu.Root>\n <DropdownMenu.Trigger>\n {(() => {\n const title = translate({\n defaultMessage: \"API key actions\",\n id: \"RIBfYe\",\n description: \"Tooltip for API key actions menu button\",\n });\n return (\n <IconButton title={title}>\n <DotsHorizontalIcon />\n </IconButton>\n );\n })()}\n </DropdownMenu.Trigger>\n <DropdownMenu.Content size=\"2\" align=\"end\">\n <DropdownMenu.Item onSelect={() => setDetailsOpen(true)}>\n <Translation\n defaultMessage=\"View details\"\n id=\"VGKbbj\"\n description=\"Menu item to view API key details\"\n />\n </DropdownMenu.Item>\n <DropdownMenu.Item onSelect={openEditExpirationDialog}>\n <Translation\n defaultMessage=\"Edit expiration\"\n id=\"fONrTk\"\n description=\"Menu item to edit an API key expiration\"\n />\n </DropdownMenu.Item>\n <DropdownMenu.Separator />\n <DropdownMenu.Item\n variant=\"destructive\"\n onSelect={() => setRevokeDialogOpen(true)}\n >\n <Translation\n defaultMessage=\"Revoke key\"\n id=\"KZIJPP\"\n description=\"Menu item to revoke an API key\"\n />\n </DropdownMenu.Item>\n </DropdownMenu.Content>\n </DropdownMenu.Root>\n </Table.Cell>\n </Table.Row>\n </>\n );\n}\n\nexport function UserApiKeysTable({\n apiKeys,\n canCreate,\n canManageAll,\n}: {\n apiKeys: ListUserApiKeysResponse;\n canCreate: boolean;\n canManageAll: boolean;\n}) {\n const { dispatch } = useUserApiKeysContext();\n const pagination = getListMetadata(apiKeys);\n\n const hasPagination = !!(pagination.before || pagination.after);\n const hasPreviousPage = !!pagination.before;\n const hasNextPage = !!pagination.after;\n\n return (\n <Flex direction=\"column\" align=\"stretch\" gap=\"3\">\n <UserApiKeysTableHeader canCreate={canCreate} />\n {apiKeys.data.length === 0 ? (\n <NoUserApiKeys />\n ) : (\n <>\n <Table.Root variant=\"ghost\" size=\"2\">\n <Table.Header>\n <Table.Row>\n <Table.ColumnHeaderCell width={canManageAll ? \"20%\" : \"25%\"}>\n <Translation\n defaultMessage=\"Name\"\n id=\"VYbVXN\"\n description=\"Table column header for API key name\"\n />\n </Table.ColumnHeaderCell>\n <Table.ColumnHeaderCell width={canManageAll ? \"20%\" : \"25%\"}>\n <Translation\n defaultMessage=\"Secret key\"\n id=\"H5k7GB\"\n description=\"Table column header for API key secret value\"\n />\n </Table.ColumnHeaderCell>\n {canManageAll ? (\n <Table.ColumnHeaderCell width=\"20%\">\n <Translation\n defaultMessage=\"Created by\"\n id=\"en10bZ\"\n description=\"Table column header for API key creator\"\n />\n </Table.ColumnHeaderCell>\n ) : null}\n <Table.ColumnHeaderCell width={canManageAll ? \"20%\" : \"25%\"}>\n <Translation\n defaultMessage=\"Last used\"\n id=\"E46t3O\"\n description=\"Table column header for API key last used timestamp\"\n />\n </Table.ColumnHeaderCell>\n <Table.ColumnHeaderCell width={canManageAll ? \"20%\" : \"25%\"}>\n <Translation\n defaultMessage=\"Expires\"\n id=\"3q8EjA\"\n description=\"Table column header for API key expiration date\"\n />\n </Table.ColumnHeaderCell>\n <Table.ColumnHeaderCell width=\"28px\" />\n </Table.Row>\n </Table.Header>\n <Table.Body>\n {apiKeys.data.map((apiKey) => (\n <UserApiKeyRow\n key={apiKey.id}\n apiKey={apiKey}\n canManageAll={canManageAll}\n />\n ))}\n </Table.Body>\n </Table.Root>\n {hasPagination && (\n <Flex gap=\"2\" justify=\"end\">\n <Button\n variant=\"secondary\"\n disabled={!hasPreviousPage}\n size=\"1\"\n onClick={() =>\n dispatch({\n type: \"SET_PAGINATION\",\n pagination: { before: pagination.before, after: null },\n })\n }\n >\n <Translation\n defaultMessage=\"Previous\"\n id=\"f7TUj0\"\n description=\"Button to navigate to previous page of API keys\"\n />\n </Button>\n <Button\n variant=\"secondary\"\n disabled={!hasNextPage}\n size=\"1\"\n onClick={() =>\n dispatch({\n type: \"SET_PAGINATION\",\n pagination: { before: null, after: pagination.after },\n })\n }\n >\n <Translation\n defaultMessage=\"Next\"\n id=\"L2EBxV\"\n description=\"Button to navigate to next page of API keys\"\n />\n </Button>\n </Flex>\n )}\n </>\n )}\n </Flex>\n );\n}\n"],"mappings":"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"}
@@ -202,14 +202,14 @@ const UsersManagement = ({ userData, rolesData, isPending, disableRolesFilter, .
202
202
  children: [/* @__PURE__ */ jsx(Button$1, {
203
203
  variant: "secondary",
204
204
  size: "1",
205
- disabled: !pagination.after || isPending || void 0,
205
+ disabled: !pagination.before || isPending || void 0,
206
206
  loading: deferredLoading,
207
207
  onClick: () => {
208
- if (pagination.after) dispatch({
208
+ if (pagination.before) dispatch({
209
209
  type: "SET_PAGINATION",
210
210
  pagination: {
211
- after: pagination.after,
212
- before: null
211
+ before: pagination.before,
212
+ after: null
213
213
  }
214
214
  });
215
215
  },
@@ -221,14 +221,14 @@ const UsersManagement = ({ userData, rolesData, isPending, disableRolesFilter, .
221
221
  }), /* @__PURE__ */ jsx(Button$1, {
222
222
  variant: "secondary",
223
223
  size: "1",
224
- disabled: !pagination.before || isPending || void 0,
224
+ disabled: !pagination.after || isPending || void 0,
225
225
  loading: deferredLoading,
226
226
  onClick: () => {
227
- if (pagination.before) dispatch({
227
+ if (pagination.after) dispatch({
228
228
  type: "SET_PAGINATION",
229
229
  pagination: {
230
- before: pagination.before,
231
- after: null
230
+ after: pagination.after,
231
+ before: null
232
232
  }
233
233
  });
234
234
  },
@@ -1 +1 @@
1
- {"version":3,"file":"users-management.js","names":["Button","Avatar","IconButton","Skeleton","TextField","Select.Root","Select.Trigger","Select.Content","Select.Item","Badge"],"sources":["../../../src/lib/users-management.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport {\n Box,\n Flex,\n Grid,\n Separator,\n Table,\n Tooltip,\n Text,\n type TextProps,\n VisuallyHidden,\n} from \"@radix-ui/themes\";\nimport {\n Avatar,\n Badge,\n IconButton,\n Button,\n Select,\n Skeleton,\n TextField,\n} from \"./elements.js\";\nimport { InviteUserDialog } from \"./invite-user-dialog.js\";\nimport { SearchProvider, useSearchContext } from \"./search-provider.js\";\nimport { useIsHydrated } from \"./use-is-hydrated.js\";\nimport { UserActionsDropdown } from \"./user-actions-dropdown.js\";\nimport { UsersFilter } from \"./users-filter.js\";\nimport { UsersSearch } from \"./users-search.js\";\nimport { getBestName } from \"./utils/get-best-name.js\";\nimport { getWidgetDomProps } from \"./utils/widget-dom-props.js\";\nimport { getListMetadata } from \"./utils/get-list-metadata.js\";\nimport { WidgetRootState, type WidgetRootDomProps } from \"./widget-types.js\";\nimport { USER_ROW_LIMIT } from \"./constants.js\";\nimport { useUsersManagementContext } from \"./users-management-context.js\";\nimport type { Member, MembersQueryResult, RolesAndConfig } from \"./api/user.js\";\nimport { GenericError } from \"./generic-error.js\";\nimport { DotsHorizontalIcon } from \"@radix-ui/react-icons\";\nimport { Translation } from \"./i18n/translation.js\";\nimport { useTranslation } from \"./i18n/use-translation.js\";\nimport { useLocale } from \"./i18n/use-locale.js\";\nimport { useComparativeReadableDate } from \"../use-comparative-readable-date.js\";\n\ninterface UsersManagementProps extends WidgetRootDomProps {\n rolesData: RolesAndConfig;\n userData: MembersQueryResult;\n disableRolesFilter?: boolean;\n // When the users list is loading new users\n isPending: boolean;\n}\n\nconst UsersManagement: React.FC<UsersManagementProps> = ({\n userData,\n rolesData,\n isPending,\n disableRolesFilter,\n ...domProps\n}) => {\n const users = userData?.data ?? [];\n const usersCount = users?.length ?? 0;\n const isHydrated = useIsHydrated();\n const pagination = getListMetadata(userData);\n\n const { dispatch } = useUsersManagementContext();\n const isMultipleRolesEnabled = rolesData.multipleRolesEnabled;\n const translate = useTranslation();\n\n // we only want to show the loading indicator for some buttons if the request\n // is still pending after 500ms. If the request is fast enough the indicator\n // is a bit jarring.\n const [deferredLoading, setDeferredLoading] = React.useState(false);\n React.useEffect(() => {\n if (isPending) {\n const timeoutId = window.setTimeout(() => {\n setDeferredLoading(true);\n }, 500);\n return () => {\n window.clearTimeout(timeoutId);\n };\n } else {\n // TODO: Fix this\n // oxlint-disable-next-line react/set-state-in-effect\n setDeferredLoading(false);\n }\n }, [isPending]);\n\n const showPagination = !!(pagination.before || pagination.after);\n\n return (\n <SearchProvider>\n <Flex\n direction=\"column\"\n gap=\"3\"\n {...getWidgetRootDomProps(\"resolved\", domProps)}\n >\n <Grid columns=\"1fr auto\" gap=\"2\">\n <Flex gap=\"2\" align=\"center\">\n <Box flexBasis=\"380px\" flexGrow=\"0\" flexShrink=\"1\">\n <UsersSearch />\n </Box>\n <Box flexGrow=\"0\" flexShrink=\"0\">\n <UsersFilter\n roles={rolesData.roles}\n disabled={disableRolesFilter}\n />\n </Box>\n </Flex>\n <Box flexGrow=\"0\" flexShrink=\"0\" style={{ placeSelf: \"flex-end\" }}>\n <InviteUserDialog>\n <Button>\n <Translation\n defaultMessage=\"Invite user\"\n id=\"NBXpRj\"\n description=\"Button text to invite a new user to the organization\"\n />\n </Button>\n </InviteUserDialog>\n </Box>\n </Grid>\n <Table.Root variant=\"ghost\" size=\"1\">\n <Table.Header>\n <Table.Row>\n <Table.ColumnHeaderCell width=\"260px\">\n <Translation\n defaultMessage=\"User\"\n id=\"BBh86k\"\n description=\"Column header for user information in the users table\"\n />\n </Table.ColumnHeaderCell>\n <Table.ColumnHeaderCell width=\"100px\">\n {isMultipleRolesEnabled ? (\n <Translation\n defaultMessage=\"Roles\"\n id=\"A1DuWM\"\n description=\"Column header for user roles when multiple roles are enabled\"\n />\n ) : (\n <Translation\n defaultMessage=\"Role\"\n id=\"nQbe+Y\"\n description=\"Column header for user role when only single role is allowed\"\n />\n )}\n </Table.ColumnHeaderCell>\n <Table.ColumnHeaderCell width=\"140px\">\n <Translation\n defaultMessage=\"Last active\"\n id=\"oOwLGt\"\n description=\"Column header showing when users were last active\"\n />\n </Table.ColumnHeaderCell>\n <Table.ColumnHeaderCell width=\"28px\" />\n </Table.Row>\n </Table.Header>\n\n <Table.Body\n style={{\n transition: `opacity 0.2s ease-out ${isPending ? \"0.2s\" : \"0s\"}`,\n opacity: isPending && usersCount > 0 ? 0.5 : 1,\n }}\n >\n {users.length > 0 ? (\n users.map((user) => {\n const userDisplayName = getBestName(user);\n const dimText =\n user.status === \"InviteRevoked\" ||\n user.status === \"InviteExpired\";\n return (\n <Table.Row key={user.id} align=\"center\">\n <Table.RowHeaderCell>\n <Flex\n align=\"center\"\n gap=\"3\"\n overflow=\"hidden\"\n height=\"var(--space-7)\"\n >\n <Avatar\n size=\"2\"\n fallback={<FallbackUserIcon />}\n src={user.profilePictureUrl ?? undefined}\n dim={dimText}\n />\n\n {userDisplayName ? (\n <Flex\n direction=\"column\"\n align=\"start\"\n height=\"var(--space-7)\"\n justify=\"center\"\n overflow=\"hidden\"\n >\n <Flex gap=\"2\" align=\"center\" minWidth=\"0\">\n <TableCellText dim={dimText}>\n {userDisplayName}\n </TableCellText>\n <UserBadge user={user} />\n </Flex>\n <TableCellText\n level=\"secondary\"\n title={user.email}\n dim={dimText}\n >\n {user.email}\n </TableCellText>\n </Flex>\n ) : (\n <Flex gap=\"2\" align=\"center\" minWidth=\"0\">\n <TableCellText dim={dimText} title={user.email}>\n {user.email}\n </TableCellText>\n <UserBadge user={user} />\n </Flex>\n )}\n </Flex>\n </Table.RowHeaderCell>\n <Table.Cell>\n <UserRolesCellContent\n user={user}\n isMultipleRolesEnabled={isMultipleRolesEnabled}\n dimText={dimText}\n />\n </Table.Cell>\n <Table.Cell>\n <LastActive user={user} isHydrated={isHydrated} />\n </Table.Cell>\n <Table.Cell justify=\"end\">\n <UserActionsDropdown user={user}>\n <IconButton\n title={translate({\n defaultMessage: \"User actions\",\n id: \"1nsmNS\",\n description:\n \"Button tooltip for opening user actions menu\",\n })}\n >\n <DotsHorizontalIcon />\n </IconButton>\n </UserActionsDropdown>\n </Table.Cell>\n </Table.Row>\n );\n })\n ) : (\n <Table.Row align=\"center\">\n <Table.Cell colSpan={4}>\n <UsersManagementEmptyState isPending={isPending} />\n </Table.Cell>\n </Table.Row>\n )}\n </Table.Body>\n </Table.Root>\n\n {showPagination ? (\n <Flex gap=\"2\" justify=\"end\">\n <Button\n variant=\"secondary\"\n size=\"1\"\n disabled={!pagination.after || isPending || undefined}\n loading={deferredLoading}\n onClick={() => {\n if (pagination.after) {\n dispatch({\n type: \"SET_PAGINATION\",\n pagination: { after: pagination.after, before: null },\n });\n }\n }}\n >\n <Translation\n defaultMessage=\"Previous\"\n id=\"910Q6b\"\n description=\"Button text to navigate to the previous page of users\"\n />\n </Button>\n <Button\n variant=\"secondary\"\n size=\"1\"\n disabled={!pagination.before || isPending || undefined}\n loading={deferredLoading}\n onClick={() => {\n if (pagination.before) {\n dispatch({\n type: \"SET_PAGINATION\",\n pagination: { before: pagination.before, after: null },\n });\n }\n }}\n >\n <Translation\n defaultMessage=\"Next\"\n id=\"UlAY08\"\n description=\"Button text to navigate to the next page of users\"\n />\n </Button>\n </Flex>\n ) : null}\n </Flex>\n </SearchProvider>\n );\n};\n\ninterface UsersManagementLoadingProps extends WidgetRootDomProps {}\n\nconst UsersManagementLoading: React.FC<UsersManagementLoadingProps> = (\n props,\n) => {\n const translate = useTranslation();\n const placeholderText = (\n <Translation\n defaultMessage=\"All\"\n id=\"l/Do9/\"\n description=\"Filter option to show all users\"\n />\n );\n return (\n <Flex\n direction=\"column\"\n gap=\"3\"\n {...getWidgetRootDomProps(\"loading\", props)}\n >\n <Grid columns=\"1fr auto\" gap=\"2\">\n <Flex gap=\"2\" align=\"center\">\n <Skeleton loading>\n <Box flexBasis=\"380px\" flexGrow=\"0\" flexShrink=\"1\">\n <TextField\n disabled\n aria-label={translate({\n defaultMessage: \"User search\",\n id: \"lzPOKv\",\n description: \"Label for the user search input field\",\n })}\n />\n </Box>\n </Skeleton>\n <Skeleton loading>\n <Box flexGrow=\"0\" flexShrink=\"0\">\n <Select.Root disabled value=\"all\" onValueChange={() => void 0}>\n <Select.Trigger>{placeholderText}</Select.Trigger>\n <Select.Content>\n <Select.Item value=\"all\">{placeholderText}</Select.Item>\n </Select.Content>\n </Select.Root>\n </Box>\n </Skeleton>\n </Flex>\n <Skeleton loading>\n <Box flexGrow=\"0\" flexShrink=\"0\" style={{ placeSelf: \"flex-end\" }}>\n <Button disabled>\n <Translation\n defaultMessage=\"Invite user\"\n id=\"NBXpRj\"\n description=\"Button text to invite a new user to the organization\"\n />\n </Button>\n </Box>\n </Skeleton>\n </Grid>\n <Table.Root variant=\"ghost\" size=\"1\">\n <Table.Header>\n <Table.Row>\n <Table.ColumnHeaderCell width=\"260px\">\n <Skeleton loading>\n <Translation\n defaultMessage=\"User\"\n id=\"BBh86k\"\n description=\"Column header for user information in the users table\"\n />\n </Skeleton>\n </Table.ColumnHeaderCell>\n <Table.ColumnHeaderCell width=\"100px\">\n <Skeleton>\n <Translation\n defaultMessage=\"Role\"\n id=\"FK7mP4\"\n description=\"Column header for user role\"\n />\n </Skeleton>\n </Table.ColumnHeaderCell>\n <Table.ColumnHeaderCell width=\"140px\">\n <Skeleton>\n <Translation\n defaultMessage=\"Last active\"\n id=\"oOwLGt\"\n description=\"Column header showing when users were last active\"\n />\n </Skeleton>\n </Table.ColumnHeaderCell>\n <Table.ColumnHeaderCell width=\"28px\" />\n </Table.Row>\n </Table.Header>\n\n <Table.Body>\n {Array.from({ length: USER_ROW_LIMIT }, (_, index) => (\n <Table.Row key={index} align=\"center\">\n <Table.RowHeaderCell>\n <Flex align=\"center\" gap=\"3\">\n <Skeleton>\n <Avatar size=\"2\" fallback=\"F\" />\n </Skeleton>\n\n <Flex\n direction=\"column\"\n height=\"var(--space-7)\"\n justify=\"center\"\n >\n <Skeleton width=\"180px\" height=\"var(--space-4)\" />\n <Skeleton width=\"90px\" height=\"var(--space-3)\" mt=\"1\" />\n </Flex>\n </Flex>\n </Table.RowHeaderCell>\n <Table.Cell>\n <Flex wrap=\"wrap\" gap=\"1\">\n <Skeleton width=\"75px\" height=\"var(--space-4)\" />\n </Flex>\n </Table.Cell>\n <Table.Cell>\n <Skeleton width=\"120px\" height=\"var(--space-4)\" />\n </Table.Cell>\n <Table.Cell justify=\"end\" />\n </Table.Row>\n ))}\n </Table.Body>\n </Table.Root>\n\n <Flex gap=\"2\" justify=\"end\">\n <Skeleton loading>\n <Button disabled variant=\"secondary\" size=\"1\">\n <Translation\n defaultMessage=\"Previous\"\n id=\"910Q6b\"\n description=\"Button text to navigate to the previous page of users\"\n />\n </Button>\n </Skeleton>\n <Skeleton loading>\n <Button disabled variant=\"secondary\" size=\"1\">\n <Translation\n defaultMessage=\"Next\"\n id=\"UlAY08\"\n description=\"Button text to navigate to the next page of users\"\n />\n </Button>\n </Skeleton>\n </Flex>\n </Flex>\n );\n};\n\ninterface UsersManagementErrorProps extends WidgetRootDomProps {\n error: unknown;\n}\n\nconst UsersManagementError: React.FC<UsersManagementErrorProps> = ({\n error,\n ...domProps\n}) => {\n return (\n <GenericError\n error={error}\n minHeight=\"676px\"\n {...getWidgetRootDomProps(\"error\", domProps)}\n />\n );\n};\n\nfunction UserBadge({ user }: { user: Member }) {\n if (user.isLoggedInUser) {\n return (\n <Badge color=\"gray\" style={{ userSelect: \"none\" }}>\n <Translation\n defaultMessage=\"You\"\n id=\"ER1Vmv\"\n description=\"Badge indicating the current logged-in user\"\n />\n </Badge>\n );\n }\n if (user.status === \"Invited\") {\n return (\n <Badge color=\"amber\" style={{ userSelect: \"none\" }}>\n <VisuallyHidden>\n <Translation\n defaultMessage=\"Status: \"\n id=\"E2o/+H\"\n description=\"Prefix for status indicator in screen reader\"\n />\n </VisuallyHidden>\n <Translation\n defaultMessage=\"Invited\"\n id=\"byIkUu\"\n description=\"Badge status indicating user has been invited but not yet accepted\"\n />\n </Badge>\n );\n }\n if (user.status === \"InviteExpired\") {\n return (\n <Badge color=\"red\" style={{ userSelect: \"none\" }}>\n <VisuallyHidden>\n <Translation\n defaultMessage=\"Status: Invite \"\n id=\"BWvbwY\"\n description=\"Prefix for invite status indicator in screen reader\"\n />\n </VisuallyHidden>\n <Translation\n defaultMessage=\"Expired\"\n id=\"+0sQaN\"\n description=\"Badge status indicating user invitation has expired\"\n />\n </Badge>\n );\n }\n if (user.status === \"InviteRevoked\") {\n return (\n <Badge color=\"red\" style={{ userSelect: \"none\" }}>\n <VisuallyHidden>\n <Translation\n defaultMessage=\"Status: Invite \"\n id=\"BWvbwY\"\n description=\"Prefix for invite status indicator in screen reader\"\n />\n </VisuallyHidden>\n <Translation\n defaultMessage=\"Revoked\"\n id=\"NNBv+r\"\n description=\"Badge status indicating user invitation has been revoked\"\n />\n </Badge>\n );\n }\n return null;\n}\n\ninterface LastActiveProps {\n user: Member;\n isHydrated: boolean;\n dim?: boolean;\n}\n\nfunction LastActive(props: LastActiveProps) {\n if (!props.user.lastActivityAt) {\n return (\n <>\n <VisuallyHidden>\n {props.user.status === \"Active\" ? (\n <Translation\n defaultMessage=\"Never\"\n id=\"0duvF4\"\n description=\"Screen reader text indicating user has never been active\"\n />\n ) : (\n <Translation\n defaultMessage=\"Not active\"\n id=\"hd2+kk\"\n description=\"Screen reader text indicating user is not active\"\n />\n )}\n </VisuallyHidden>\n <Separator />\n </>\n );\n }\n return <LastActiveImpl {...props} date={props.user.lastActivityAt} />;\n}\n\nfunction LastActiveImpl({\n date,\n isHydrated,\n dim,\n}: LastActiveProps & { date: string }) {\n const locale = useLocale();\n\n const lastActiveDate = new Date(date);\n const lastActiveDateTime = lastActiveDate.toLocaleTimeString(locale, {\n // hard-coded timezone before hydration to prevent server/client mismatch\n timeZone: isHydrated ? undefined : \"America/Los_Angeles\",\n month: \"long\",\n day: \"numeric\",\n year: \"numeric\",\n hour: \"numeric\",\n minute: \"numeric\",\n });\n\n const lastActiveDisplay = useComparativeReadableDate({\n date: lastActiveDate,\n });\n\n // handle cases where the DB might return an invalid date string\n if (lastActiveDisplay === \"Invalid Date\") {\n return (\n <>\n <VisuallyHidden>\n <Translation\n defaultMessage=\"Unknown\"\n id=\"UUigrK\"\n description=\"Screen reader text indicating last active date is unknown\"\n />\n </VisuallyHidden>\n <Separator />\n </>\n );\n }\n\n return (\n <TableCellText asChild dim={dim}>\n <time dateTime={date} title={lastActiveDateTime}>\n {lastActiveDisplay}\n </time>\n </TableCellText>\n );\n}\n\nconst TableCellText = React.forwardRef<HTMLSpanElement, TableCellTextProps>(\n function TableCellText(\n { children, dim, level = \"primary\", ...props },\n forwardedRef,\n ) {\n return (\n <Text\n ref={forwardedRef}\n color={level === \"secondary\" ? \"gray\" : undefined}\n weight={level === \"secondary\" ? \"regular\" : \"medium\"}\n size={level === \"secondary\" ? \"1\" : \"2\"}\n truncate\n {...props}\n style={\n dim\n ? {\n // TODO: use CSS var instead of hard-coded value for opacity\n opacity: 0.6,\n ...props.style,\n }\n : props.style\n }\n >\n {children}\n </Text>\n );\n },\n);\n\ntype TableCellTextProps = TextProps & {\n level?: \"primary\" | \"secondary\";\n dim?: boolean;\n};\n\nconst FallbackUserIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"20\"\n height=\"20\"\n fill=\"currentColor\"\n viewBox=\"0 0 256 256\"\n >\n {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}\n <title>User icon</title>\n <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\" />\n </svg>\n);\n\nconst UsersManagementEmptyState = ({ isPending }: { isPending: boolean }) => {\n const { clearSearch } = useSearchContext();\n const {\n state: { searchQuery },\n } = useUsersManagementContext();\n\n // When the search query is cleared, the users query is re-fetched which sends\n // us into a pending state. When this happens we want to keep a snapshot of\n // the previous search query while the query is revalidated. We can use this\n // to keep the 'No users found for query' UI in place until re-fetching is\n // complete, otherwise the view flips to 'No users found' very quickly before\n // the full table is shown again.\n const [{ isClearing, lastSearchQuery }, setClearing] = React.useState({\n isClearing: false,\n lastSearchQuery: null as null | string,\n });\n const [wasPending, setWasPending] = React.useState(isPending);\n if (wasPending !== isPending) {\n setWasPending(isPending);\n if (!isPending) {\n setClearing((prev) =>\n prev.isClearing ? { isClearing: false, lastSearchQuery: null } : prev,\n );\n }\n }\n\n if (searchQuery || isClearing) {\n return (\n <Flex align=\"center\" justify=\"center\" py=\"8\" direction=\"column\" gap=\"2\">\n <Text size=\"2\">\n <Translation\n defaultMessage=\"No users found for query '{query}'\"\n id=\"wrEZ8+\"\n description=\"Message shown when no users match the search query\"\n values={{\n query: isClearing ? lastSearchQuery : searchQuery,\n }}\n />\n </Text>\n\n <Button\n variant=\"secondary\"\n size=\"1\"\n onClick={() => {\n setClearing({ isClearing: true, lastSearchQuery: searchQuery });\n clearSearch();\n }}\n loading={isPending}\n >\n <Translation\n defaultMessage=\"Clear search\"\n id=\"Xv3fVI\"\n description=\"Button text to clear the current search query\"\n />\n </Button>\n </Flex>\n );\n }\n\n return (\n <Flex align=\"center\" justify=\"center\" py=\"8\" gap=\"2\">\n <Text size=\"2\">\n <Translation\n defaultMessage=\"No users found\"\n id=\"MQ+LoA\"\n description=\"Message shown when there are no users in the system\"\n />\n </Text>\n </Flex>\n );\n};\n\ninterface UserRolesCellContentProps {\n user: Member;\n isMultipleRolesEnabled: boolean;\n dimText: boolean;\n}\n\nfunction UserRolesCellContent({\n user,\n isMultipleRolesEnabled,\n dimText,\n}: UserRolesCellContentProps) {\n if (!user.roles || user.roles.length === 0) {\n return (\n <>\n <VisuallyHidden>\n <Translation\n defaultMessage=\"No roles assigned\"\n id=\"CVOVB0\"\n description=\"Screen reader text indicating user has no roles assigned\"\n />\n </VisuallyHidden>\n {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}\n <span aria-hidden style={{ userSelect: \"none\" }}>\n –\n </span>\n </>\n );\n }\n\n if (isMultipleRolesEnabled && user.roles.length > 1) {\n const roleNames = user.roles?.map((role) => role.name).join(\", \");\n return (\n <Tooltip content={roleNames} maxWidth=\"250px\">\n <TableCellText dim={dimText}>\n <Translation\n defaultMessage=\"{count} roles\"\n id=\"lWAmRC\"\n description=\"Shows the number of roles assigned to a user (plural)\"\n values={{ count: user.roles.length }}\n />\n </TableCellText>\n </Tooltip>\n );\n }\n\n return <TableCellText dim={dimText}>{user.roles?.[0]?.name}</TableCellText>;\n}\n\nfunction getWidgetRootDomProps(\n state: WidgetRootState,\n domProps: WidgetRootDomProps,\n) {\n return getWidgetDomProps({\n ...domProps,\n isWidgetRoot: true,\n widgetId: \"users-management\",\n widgetState: state,\n });\n}\n\nexport type { UsersManagementLoadingProps, UsersManagementErrorProps };\nexport { UsersManagement, UsersManagementLoading, UsersManagementError };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAmDA,MAAM,mBAAmD,EACvD,UACA,WACA,WACA,oBACA,GAAG,eACC;CACJ,MAAM,QAAQ,UAAU,QAAQ,CAAC;CACjC,MAAM,aAAa,OAAO,UAAU;CACpC,MAAM,aAAa,cAAc;CACjC,MAAM,aAAa,gBAAgB,QAAQ;CAE3C,MAAM,EAAE,aAAa,0BAA0B;CAC/C,MAAM,yBAAyB,UAAU;CACzC,MAAM,YAAY,eAAe;CAKjC,MAAM,CAAC,iBAAiB,sBAAsB,MAAM,SAAS,KAAK;CAClE,MAAM,gBAAgB;EACpB,IAAI,WAAW;GACb,MAAM,YAAY,OAAO,iBAAiB;IACxC,mBAAmB,IAAI;GACzB,GAAG,GAAG;GACN,aAAa;IACX,OAAO,aAAa,SAAS;GAC/B;EACF,OAGE,mBAAmB,KAAK;CAE5B,GAAG,CAAC,SAAS,CAAC;CAEd,MAAM,iBAAiB,CAAC,EAAE,WAAW,UAAU,WAAW;CAE1D,OACE,oBAAC,gBAAD,EAAA,UACE,qBAAC,MAAD;EACE,WAAU;EACV,KAAI;EACJ,GAAI,sBAAsB,YAAY,QAAQ;EAHhD,UAAA;GAKE,qBAAC,MAAD;IAAM,SAAQ;IAAW,KAAI;IAA7B,UAAA,CACE,qBAAC,MAAD;KAAM,KAAI;KAAI,OAAM;KAApB,UAAA,CACE,oBAAC,KAAD;MAAK,WAAU;MAAQ,UAAS;MAAI,YAAW;MAC7C,UAAA,oBAAC,aAAD,CAAc,CAAA;KACX,CAAA,GACL,oBAAC,KAAD;MAAK,UAAS;MAAI,YAAW;MAC3B,UAAA,oBAAC,aAAD;OACE,OAAO,UAAU;OACjB,UAAU;MACX,CAAA;KACE,CAAA,CACD;IACN,CAAA,GAAA,oBAAC,KAAD;KAAK,UAAS;KAAI,YAAW;KAAI,OAAO,EAAE,WAAW,WAAW;KAC9D,UAAA,oBAAC,kBAAD,EAAA,UACE,oBAACA,UAAD,EAAA,UACE,oBAAC,aAAD;MACE,gBAAe;MACf,IAAG;MACH,aAAY;KACb,CAAA,EACK,CAAA,EACQ,CAAA;IACf,CAAA,CACD;;GACN,qBAAC,MAAM,MAAP;IAAY,SAAQ;IAAQ,MAAK;IAAjC,UAAA,CACE,oBAAC,MAAM,QAAP,EAAA,UACE,qBAAC,MAAM,KAAP,EAAA,UAAA;KACE,oBAAC,MAAM,kBAAP;MAAwB,OAAM;MAC5B,UAAA,oBAAC,aAAD;OACE,gBAAe;OACf,IAAG;OACH,aAAY;MACb,CAAA;KACqB,CAAA;KACxB,oBAAC,MAAM,kBAAP;MAAwB,OAAM;MAC3B,UAAA,yBACC,oBAAC,aAAD;OACE,gBAAe;OACf,IAAG;OACH,aAAY;MACb,CAAA,IAED,oBAAC,aAAD;OACE,gBAAe;OACf,IAAG;OACH,aAAY;MACb,CAAA;KAEmB,CAAA;KACxB,oBAAC,MAAM,kBAAP;MAAwB,OAAM;MAC5B,UAAA,oBAAC,aAAD;OACE,gBAAe;OACf,IAAG;OACH,aAAY;MACb,CAAA;KACqB,CAAA;KACxB,oBAAC,MAAM,kBAAP,EAAwB,OAAM,OAAQ,CAAA;IAC7B,EAAA,CAAA,EACC,CAAA,GAEd,oBAAC,MAAM,MAAP;KACE,OAAO;MACL,YAAY,yBAAyB,YAAY,SAAS;MAC1D,SAAS,aAAa,aAAa,IAAI,KAAM;KAC/C;KAEC,UAAA,MAAM,SAAS,IACd,MAAM,KAAK,SAAS;MAClB,MAAM,kBAAkB,YAAY,IAAI;MACxC,MAAM,UACJ,KAAK,WAAW,mBAChB,KAAK,WAAW;MAClB,OACE,qBAAC,MAAM,KAAP;OAAyB,OAAM;OAA/B,UAAA;QACE,oBAAC,MAAM,eAAP,EAAA,UACE,qBAAC,MAAD;SACE,OAAM;SACN,KAAI;SACJ,UAAS;SACT,QAAO;SAJT,UAAA,CAME,oBAACC,UAAD;UACE,MAAK;UACL,UAAU,oBAAC,kBAAD,CAAmB,CAAA;UAC7B,KAAK,KAAK,qBAAqB;UAC/B,KAAK;SACN,CAAA,GAEA,kBACC,qBAAC,MAAD;UACE,WAAU;UACV,OAAM;UACN,QAAO;UACP,SAAQ;UACR,UAAS;UALX,UAAA,CAOE,qBAAC,MAAD;WAAM,KAAI;WAAI,OAAM;WAAS,UAAS;WAAtC,UAAA,CACE,oBAAC,eAAD;YAAe,KAAK;YACjB,UAAA;WACY,CAAA,GACf,oBAAC,WAAD,EAAiB,KAAO,CAAA,CACpB;UACN,CAAA,GAAA,oBAAC,eAAD;WACE,OAAM;WACN,OAAO,KAAK;WACZ,KAAK;WAEJ,UAAA,KAAK;UACO,CAAA,CACX;SAEN,CAAA,IAAA,qBAAC,MAAD;UAAM,KAAI;UAAI,OAAM;UAAS,UAAS;UAAtC,UAAA,CACE,oBAAC,eAAD;WAAe,KAAK;WAAS,OAAO,KAAK;WACtC,UAAA,KAAK;UACO,CAAA,GACf,oBAAC,WAAD,EAAiB,KAAO,CAAA,CACpB;SAEJ,CAAA,CAAA;QACa,CAAA,EAAA,CAAA;QACrB,oBAAC,MAAM,MAAP,EAAA,UACE,oBAAC,sBAAD;SACQ;SACkB;SACf;QACV,CAAA,EACS,CAAA;QACZ,oBAAC,MAAM,MAAP,EAAA,UACE,oBAAC,YAAD;SAAkB;SAAkB;QAAa,CAAA,EACvC,CAAA;QACZ,oBAAC,MAAM,MAAP;SAAY,SAAQ;SAClB,UAAA,oBAAC,qBAAD;UAA2B;UACzB,UAAA,oBAACC,cAAD;WACE,OAAO,UAAU;YACf,gBAAgB;YAChB,IAAI;YACJ,aACE;WACJ,CAAC;WAED,UAAA,oBAAC,oBAAD,CAAqB,CAAA;UACX,CAAA;SACO,CAAA;QACX,CAAA;OACH;MAvEK,GAAA,KAAK,EAuEV;KAEf,CAAC,IAED,oBAAC,MAAM,KAAP;MAAW,OAAM;MACf,UAAA,oBAAC,MAAM,MAAP;OAAY,SAAS;OACnB,UAAA,oBAAC,2BAAD,EAAsC,UAAY,CAAA;MACxC,CAAA;KACH,CAAA;IAEH,CAAA,CACF;;GAEX,iBACC,qBAAC,MAAD;IAAM,KAAI;IAAI,SAAQ;IAAtB,UAAA,CACE,oBAACF,UAAD;KACE,SAAQ;KACR,MAAK;KACL,UAAU,CAAC,WAAW,SAAS,aAAa;KAC5C,SAAS;KACT,eAAe;MACb,IAAI,WAAW,OACb,SAAS;OACP,MAAM;OACN,YAAY;QAAE,OAAO,WAAW;QAAO,QAAQ;OAAK;MACtD,CAAC;KAEL;KAEA,UAAA,oBAAC,aAAD;MACE,gBAAe;MACf,IAAG;MACH,aAAY;KACb,CAAA;IACK,CAAA,GACR,oBAACA,UAAD;KACE,SAAQ;KACR,MAAK;KACL,UAAU,CAAC,WAAW,UAAU,aAAa;KAC7C,SAAS;KACT,eAAe;MACb,IAAI,WAAW,QACb,SAAS;OACP,MAAM;OACN,YAAY;QAAE,QAAQ,WAAW;QAAQ,OAAO;OAAK;MACvD,CAAC;KAEL;KAEA,UAAA,oBAAC,aAAD;MACE,gBAAe;MACf,IAAG;MACH,aAAY;KACb,CAAA;IACK,CAAA,CACJ;GACJ,CAAA,IAAA;EACA;CACQ,CAAA,EAAA,CAAA;AAEpB;AAIA,MAAM,0BACJ,UACG;CACH,MAAM,YAAY,eAAe;CACjC,MAAM,kBACJ,oBAAC,aAAD;EACE,gBAAe;EACf,IAAG;EACH,aAAY;CACb,CAAA;CAEH,OACE,qBAAC,MAAD;EACE,WAAU;EACV,KAAI;EACJ,GAAI,sBAAsB,WAAW,KAAK;EAH5C,UAAA;GAKE,qBAAC,MAAD;IAAM,SAAQ;IAAW,KAAI;IAA7B,UAAA,CACE,qBAAC,MAAD;KAAM,KAAI;KAAI,OAAM;KAApB,UAAA,CACE,oBAACG,YAAD;MAAU,SAAA;MACR,UAAA,oBAAC,KAAD;OAAK,WAAU;OAAQ,UAAS;OAAI,YAAW;OAC7C,UAAA,oBAACC,aAAD;QACE,UAAA;QACA,cAAY,UAAU;SACpB,gBAAgB;SAChB,IAAI;SACJ,aAAa;QACf,CAAC;OACF,CAAA;MACE,CAAA;KACG,CAAA,GACV,oBAACD,YAAD;MAAU,SAAA;MACR,UAAA,oBAAC,KAAD;OAAK,UAAS;OAAI,YAAW;OAC3B,UAAA,qBAACE,MAAD;QAAa,UAAA;QAAS,OAAM;QAAM,qBAAqB,KAAK;QAA5D,UAAA,CACE,oBAACC,eAAD,EAAA,UAAiB,gBAAgC,CAAA,GACjD,oBAACC,eAAD,EAAA,UACE,oBAACC,YAAD;SAAa,OAAM;SAAO,UAAA;QAA6B,CAAA,EACzC,CAAA,CACL;;MACV,CAAA;KACG,CAAA,CACN;IACN,CAAA,GAAA,oBAACL,YAAD;KAAU,SAAA;KACR,UAAA,oBAAC,KAAD;MAAK,UAAS;MAAI,YAAW;MAAI,OAAO,EAAE,WAAW,WAAW;MAC9D,UAAA,oBAACH,UAAD;OAAQ,UAAA;OACN,UAAA,oBAAC,aAAD;QACE,gBAAe;QACf,IAAG;QACH,aAAY;OACb,CAAA;MACK,CAAA;KACL,CAAA;IACG,CAAA,CACN;;GACN,qBAAC,MAAM,MAAP;IAAY,SAAQ;IAAQ,MAAK;IAAjC,UAAA,CACE,oBAAC,MAAM,QAAP,EAAA,UACE,qBAAC,MAAM,KAAP,EAAA,UAAA;KACE,oBAAC,MAAM,kBAAP;MAAwB,OAAM;MAC5B,UAAA,oBAACG,YAAD;OAAU,SAAA;OACR,UAAA,oBAAC,aAAD;QACE,gBAAe;QACf,IAAG;QACH,aAAY;OACb,CAAA;MACO,CAAA;KACY,CAAA;KACxB,oBAAC,MAAM,kBAAP;MAAwB,OAAM;MAC5B,UAAA,oBAACA,YAAD,EAAA,UACE,oBAAC,aAAD;OACE,gBAAe;OACf,IAAG;OACH,aAAY;MACb,CAAA,EACO,CAAA;KACY,CAAA;KACxB,oBAAC,MAAM,kBAAP;MAAwB,OAAM;MAC5B,UAAA,oBAACA,YAAD,EAAA,UACE,oBAAC,aAAD;OACE,gBAAe;OACf,IAAG;OACH,aAAY;MACb,CAAA,EACO,CAAA;KACY,CAAA;KACxB,oBAAC,MAAM,kBAAP,EAAwB,OAAM,OAAQ,CAAA;IAC7B,EAAA,CAAA,EACC,CAAA,GAEd,oBAAC,MAAM,MAAP,EAAA,UACG,MAAM,KAAK,EAAE,QAAA,GAAuB,IAAI,GAAG,UAC1C,qBAAC,MAAM,KAAP;KAAuB,OAAM;KAA7B,UAAA;MACE,oBAAC,MAAM,eAAP,EAAA,UACE,qBAAC,MAAD;OAAM,OAAM;OAAS,KAAI;OAAzB,UAAA,CACE,oBAACA,YAAD,EAAA,UACE,oBAACF,UAAD;QAAQ,MAAK;QAAI,UAAS;OAAK,CAAA,EACvB,CAAA,GAEV,qBAAC,MAAD;QACE,WAAU;QACV,QAAO;QACP,SAAQ;QAHV,UAAA,CAKE,oBAACE,YAAD;SAAU,OAAM;SAAQ,QAAO;QAAkB,CAAA,GACjD,oBAACA,YAAD;SAAU,OAAM;SAAO,QAAO;SAAiB,IAAG;QAAK,CAAA,CACnD;OACF,CAAA,CAAA;MACa,CAAA,EAAA,CAAA;MACrB,oBAAC,MAAM,MAAP,EAAA,UACE,oBAAC,MAAD;OAAM,MAAK;OAAO,KAAI;OACpB,UAAA,oBAACA,YAAD;QAAU,OAAM;QAAO,QAAO;OAAkB,CAAA;MAC5C,CAAA,EACI,CAAA;MACZ,oBAAC,MAAM,MAAP,EAAA,UACE,oBAACA,YAAD;OAAU,OAAM;OAAQ,QAAO;MAAkB,CAAA,EACvC,CAAA;MACZ,oBAAC,MAAM,MAAP,EAAY,SAAQ,MAAO,CAAA;KAClB;IA1BK,GAAA,KA0BL,CACZ,EACS,CAAA,CACF;;GAEZ,qBAAC,MAAD;IAAM,KAAI;IAAI,SAAQ;IAAtB,UAAA,CACE,oBAACA,YAAD;KAAU,SAAA;KACR,UAAA,oBAACH,UAAD;MAAQ,UAAA;MAAS,SAAQ;MAAY,MAAK;MACxC,UAAA,oBAAC,aAAD;OACE,gBAAe;OACf,IAAG;OACH,aAAY;MACb,CAAA;KACK,CAAA;IACA,CAAA,GACV,oBAACG,YAAD;KAAU,SAAA;KACR,UAAA,oBAACH,UAAD;MAAQ,UAAA;MAAS,SAAQ;MAAY,MAAK;MACxC,UAAA,oBAAC,aAAD;OACE,gBAAe;OACf,IAAG;OACH,aAAY;MACb,CAAA;KACK,CAAA;IACA,CAAA,CACN;;EACF;;AAEV;AAMA,MAAM,wBAA6D,EACjE,OACA,GAAG,eACC;CACJ,OACE,oBAAC,cAAD;EACS;EACP,WAAU;EACV,GAAI,sBAAsB,SAAS,QAAQ;CAC5C,CAAA;AAEL;AAEA,SAAS,UAAU,EAAE,QAA0B;CAC7C,IAAI,KAAK,gBACP,OACE,oBAACS,SAAD;EAAO,OAAM;EAAO,OAAO,EAAE,YAAY,OAAO;EAC9C,UAAA,oBAAC,aAAD;GACE,gBAAe;GACf,IAAG;GACH,aAAY;EACb,CAAA;CACI,CAAA;CAGX,IAAI,KAAK,WAAW,WAClB,OACE,qBAACA,SAAD;EAAO,OAAM;EAAQ,OAAO,EAAE,YAAY,OAAO;EAAjD,UAAA,CACE,oBAAC,gBAAD,EAAA,UACE,oBAAC,aAAD;GACE,gBAAe;GACf,IAAG;GACH,aAAY;EACb,CAAA,EACa,CAAA,GAChB,oBAAC,aAAD;GACE,gBAAe;GACf,IAAG;GACH,aAAY;EACb,CAAA,CACI;;CAGX,IAAI,KAAK,WAAW,iBAClB,OACE,qBAACA,SAAD;EAAO,OAAM;EAAM,OAAO,EAAE,YAAY,OAAO;EAA/C,UAAA,CACE,oBAAC,gBAAD,EAAA,UACE,oBAAC,aAAD;GACE,gBAAe;GACf,IAAG;GACH,aAAY;EACb,CAAA,EACa,CAAA,GAChB,oBAAC,aAAD;GACE,gBAAe;GACf,IAAG;GACH,aAAY;EACb,CAAA,CACI;;CAGX,IAAI,KAAK,WAAW,iBAClB,OACE,qBAACA,SAAD;EAAO,OAAM;EAAM,OAAO,EAAE,YAAY,OAAO;EAA/C,UAAA,CACE,oBAAC,gBAAD,EAAA,UACE,oBAAC,aAAD;GACE,gBAAe;GACf,IAAG;GACH,aAAY;EACb,CAAA,EACa,CAAA,GAChB,oBAAC,aAAD;GACE,gBAAe;GACf,IAAG;GACH,aAAY;EACb,CAAA,CACI;;CAGX,OAAO;AACT;AAQA,SAAS,WAAW,OAAwB;CAC1C,IAAI,CAAC,MAAM,KAAK,gBACd,OACE,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,gBAAD,EAAA,UACG,MAAM,KAAK,WAAW,WACrB,oBAAC,aAAD;EACE,gBAAe;EACf,IAAG;EACH,aAAY;CACb,CAAA,IAED,oBAAC,aAAD;EACE,gBAAe;EACf,IAAG;EACH,aAAY;CACb,CAAA,EAEW,CAAA,GAChB,oBAAC,WAAD,CAAY,CAAA,CACZ,EAAA,CAAA;CAGN,OAAO,oBAAC,gBAAD;EAAgB,GAAI;EAAO,MAAM,MAAM,KAAK;CAAiB,CAAA;AACtE;AAEA,SAAS,eAAe,EACtB,MACA,YACA,OACqC;CACrC,MAAM,SAAS,UAAU;CAEzB,MAAM,iBAAiB,IAAI,KAAK,IAAI;CACpC,MAAM,qBAAqB,eAAe,mBAAmB,QAAQ;EAEnE,UAAU,aAAa,SAAY;EACnC,OAAO;EACP,KAAK;EACL,MAAM;EACN,MAAM;EACN,QAAQ;CACV,CAAC;CAED,MAAM,oBAAoB,2BAA2B,EACnD,MAAM,eACR,CAAC;CAGD,IAAI,sBAAsB,gBACxB,OACE,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,gBAAD,EAAA,UACE,oBAAC,aAAD;EACE,gBAAe;EACf,IAAG;EACH,aAAY;CACb,CAAA,EACa,CAAA,GAChB,oBAAC,WAAD,CAAY,CAAA,CACZ,EAAA,CAAA;CAIN,OACE,oBAAC,eAAD;EAAe,SAAA;EAAa;EAC1B,UAAA,oBAAC,QAAD;GAAM,UAAU;GAAM,OAAO;GAC1B,UAAA;EACG,CAAA;CACO,CAAA;AAEnB;AAEA,MAAM,gBAAgB,MAAM,WAC1B,SAAS,cACP,EAAE,UAAU,KAAK,QAAQ,WAAW,GAAG,SACvC,cACA;CACA,OACE,oBAAC,MAAD;EACE,KAAK;EACL,OAAO,UAAU,cAAc,SAAS;EACxC,QAAQ,UAAU,cAAc,YAAY;EAC5C,MAAM,UAAU,cAAc,MAAM;EACpC,UAAA;EACA,GAAI;EACJ,OACE,MACI;GAEE,SAAS;GACT,GAAG,MAAM;EACX,IACA,MAAM;EAGX;CACG,CAAA;AAEV,CACF;AAOA,MAAM,yBACJ,qBAAC,OAAD;CACE,OAAM;CACN,OAAM;CACN,QAAO;CACP,MAAK;CACL,SAAQ;CALV,UAAA,CAQE,oBAAC,SAAD,EAAA,UAAO,YAAgB,CAAA,GACvB,oBAAC,QAAD,EAAM,GAAE,kPAAmP,CAAA,CACxP;;AAGP,MAAM,6BAA6B,EAAE,gBAAwC;CAC3E,MAAM,EAAE,gBAAgB,iBAAiB;CACzC,MAAM,EACJ,OAAO,EAAE,kBACP,0BAA0B;CAQ9B,MAAM,CAAC,EAAE,YAAY,mBAAmB,eAAe,MAAM,SAAS;EACpE,YAAY;EACZ,iBAAiB;CACnB,CAAC;CACD,MAAM,CAAC,YAAY,iBAAiB,MAAM,SAAS,SAAS;CAC5D,IAAI,eAAe,WAAW;EAC5B,cAAc,SAAS;EACvB,IAAI,CAAC,WACH,aAAa,SACX,KAAK,aAAa;GAAE,YAAY;GAAO,iBAAiB;EAAK,IAAI,IACnE;CAEJ;CAEA,IAAI,eAAe,YACjB,OACE,qBAAC,MAAD;EAAM,OAAM;EAAS,SAAQ;EAAS,IAAG;EAAI,WAAU;EAAS,KAAI;EAApE,UAAA,CACE,oBAAC,MAAD;GAAM,MAAK;GACT,UAAA,oBAAC,aAAD;IACE,gBAAe;IACf,IAAG;IACH,aAAY;IACZ,QAAQ,EACN,OAAO,aAAa,kBAAkB,YACxC;GACD,CAAA;EACG,CAAA,GAEN,oBAACT,UAAD;GACE,SAAQ;GACR,MAAK;GACL,eAAe;IACb,YAAY;KAAE,YAAY;KAAM,iBAAiB;IAAY,CAAC;IAC9D,YAAY;GACd;GACA,SAAS;GAET,UAAA,oBAAC,aAAD;IACE,gBAAe;IACf,IAAG;IACH,aAAY;GACb,CAAA;EACK,CAAA,CACJ;;CAIV,OACE,oBAAC,MAAD;EAAM,OAAM;EAAS,SAAQ;EAAS,IAAG;EAAI,KAAI;EAC/C,UAAA,oBAAC,MAAD;GAAM,MAAK;GACT,UAAA,oBAAC,aAAD;IACE,gBAAe;IACf,IAAG;IACH,aAAY;GACb,CAAA;EACG,CAAA;CACF,CAAA;AAEV;AAQA,SAAS,qBAAqB,EAC5B,MACA,wBACA,WAC4B;CAC5B,IAAI,CAAC,KAAK,SAAS,KAAK,MAAM,WAAW,GACvC,OACE,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,gBAAD,EAAA,UACE,oBAAC,aAAD;EACE,gBAAe;EACf,IAAG;EACH,aAAY;CACb,CAAA,EACa,CAAA,GAEhB,oBAAC,QAAD;EAAM,eAAA;EAAY,OAAO,EAAE,YAAY,OAAO;EAAG,UAAA;CAE3C,CAAA,CACN,EAAA,CAAA;CAIN,IAAI,0BAA0B,KAAK,MAAM,SAAS,GAAG;EACnD,MAAM,YAAY,KAAK,OAAO,KAAK,SAAS,KAAK,IAAI,CAAC,CAAC,KAAK,IAAI;EAChE,OACE,oBAAC,SAAD;GAAS,SAAS;GAAW,UAAS;GACpC,UAAA,oBAAC,eAAD;IAAe,KAAK;IAClB,UAAA,oBAAC,aAAD;KACE,gBAAe;KACf,IAAG;KACH,aAAY;KACZ,QAAQ,EAAE,OAAO,KAAK,MAAM,OAAO;IACpC,CAAA;GACY,CAAA;EACR,CAAA;CAEb;CAEA,OAAO,oBAAC,eAAD;EAAe,KAAK;EAAU,UAAA,KAAK,QAAQ,EAAE,EAAE;CAAoB,CAAA;AAC5E;AAEA,SAAS,sBACP,OACA,UACA;CACA,OAAO,kBAAkB;EACvB,GAAG;EACH,cAAc;EACd,UAAU;EACV,aAAa;CACf,CAAC;AACH"}
1
+ {"version":3,"file":"users-management.js","names":["Button","Avatar","IconButton","Skeleton","TextField","Select.Root","Select.Trigger","Select.Content","Select.Item","Badge"],"sources":["../../../src/lib/users-management.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport {\n Box,\n Flex,\n Grid,\n Separator,\n Table,\n Tooltip,\n Text,\n type TextProps,\n VisuallyHidden,\n} from \"@radix-ui/themes\";\nimport {\n Avatar,\n Badge,\n IconButton,\n Button,\n Select,\n Skeleton,\n TextField,\n} from \"./elements.js\";\nimport { InviteUserDialog } from \"./invite-user-dialog.js\";\nimport { SearchProvider, useSearchContext } from \"./search-provider.js\";\nimport { useIsHydrated } from \"./use-is-hydrated.js\";\nimport { UserActionsDropdown } from \"./user-actions-dropdown.js\";\nimport { UsersFilter } from \"./users-filter.js\";\nimport { UsersSearch } from \"./users-search.js\";\nimport { getBestName } from \"./utils/get-best-name.js\";\nimport { getWidgetDomProps } from \"./utils/widget-dom-props.js\";\nimport { getListMetadata } from \"./utils/get-list-metadata.js\";\nimport { WidgetRootState, type WidgetRootDomProps } from \"./widget-types.js\";\nimport { USER_ROW_LIMIT } from \"./constants.js\";\nimport { useUsersManagementContext } from \"./users-management-context.js\";\nimport type { Member, MembersQueryResult, RolesAndConfig } from \"./api/user.js\";\nimport { GenericError } from \"./generic-error.js\";\nimport { DotsHorizontalIcon } from \"@radix-ui/react-icons\";\nimport { Translation } from \"./i18n/translation.js\";\nimport { useTranslation } from \"./i18n/use-translation.js\";\nimport { useLocale } from \"./i18n/use-locale.js\";\nimport { useComparativeReadableDate } from \"../use-comparative-readable-date.js\";\n\ninterface UsersManagementProps extends WidgetRootDomProps {\n rolesData: RolesAndConfig;\n userData: MembersQueryResult;\n disableRolesFilter?: boolean;\n // When the users list is loading new users\n isPending: boolean;\n}\n\nconst UsersManagement: React.FC<UsersManagementProps> = ({\n userData,\n rolesData,\n isPending,\n disableRolesFilter,\n ...domProps\n}) => {\n const users = userData?.data ?? [];\n const usersCount = users?.length ?? 0;\n const isHydrated = useIsHydrated();\n const pagination = getListMetadata(userData);\n\n const { dispatch } = useUsersManagementContext();\n const isMultipleRolesEnabled = rolesData.multipleRolesEnabled;\n const translate = useTranslation();\n\n // we only want to show the loading indicator for some buttons if the request\n // is still pending after 500ms. If the request is fast enough the indicator\n // is a bit jarring.\n const [deferredLoading, setDeferredLoading] = React.useState(false);\n React.useEffect(() => {\n if (isPending) {\n const timeoutId = window.setTimeout(() => {\n setDeferredLoading(true);\n }, 500);\n return () => {\n window.clearTimeout(timeoutId);\n };\n } else {\n // TODO: Fix this\n // oxlint-disable-next-line react/set-state-in-effect\n setDeferredLoading(false);\n }\n }, [isPending]);\n\n const showPagination = !!(pagination.before || pagination.after);\n\n return (\n <SearchProvider>\n <Flex\n direction=\"column\"\n gap=\"3\"\n {...getWidgetRootDomProps(\"resolved\", domProps)}\n >\n <Grid columns=\"1fr auto\" gap=\"2\">\n <Flex gap=\"2\" align=\"center\">\n <Box flexBasis=\"380px\" flexGrow=\"0\" flexShrink=\"1\">\n <UsersSearch />\n </Box>\n <Box flexGrow=\"0\" flexShrink=\"0\">\n <UsersFilter\n roles={rolesData.roles}\n disabled={disableRolesFilter}\n />\n </Box>\n </Flex>\n <Box flexGrow=\"0\" flexShrink=\"0\" style={{ placeSelf: \"flex-end\" }}>\n <InviteUserDialog>\n <Button>\n <Translation\n defaultMessage=\"Invite user\"\n id=\"NBXpRj\"\n description=\"Button text to invite a new user to the organization\"\n />\n </Button>\n </InviteUserDialog>\n </Box>\n </Grid>\n <Table.Root variant=\"ghost\" size=\"1\">\n <Table.Header>\n <Table.Row>\n <Table.ColumnHeaderCell width=\"260px\">\n <Translation\n defaultMessage=\"User\"\n id=\"BBh86k\"\n description=\"Column header for user information in the users table\"\n />\n </Table.ColumnHeaderCell>\n <Table.ColumnHeaderCell width=\"100px\">\n {isMultipleRolesEnabled ? (\n <Translation\n defaultMessage=\"Roles\"\n id=\"A1DuWM\"\n description=\"Column header for user roles when multiple roles are enabled\"\n />\n ) : (\n <Translation\n defaultMessage=\"Role\"\n id=\"nQbe+Y\"\n description=\"Column header for user role when only single role is allowed\"\n />\n )}\n </Table.ColumnHeaderCell>\n <Table.ColumnHeaderCell width=\"140px\">\n <Translation\n defaultMessage=\"Last active\"\n id=\"oOwLGt\"\n description=\"Column header showing when users were last active\"\n />\n </Table.ColumnHeaderCell>\n <Table.ColumnHeaderCell width=\"28px\" />\n </Table.Row>\n </Table.Header>\n\n <Table.Body\n style={{\n transition: `opacity 0.2s ease-out ${isPending ? \"0.2s\" : \"0s\"}`,\n opacity: isPending && usersCount > 0 ? 0.5 : 1,\n }}\n >\n {users.length > 0 ? (\n users.map((user) => {\n const userDisplayName = getBestName(user);\n const dimText =\n user.status === \"InviteRevoked\" ||\n user.status === \"InviteExpired\";\n return (\n <Table.Row key={user.id} align=\"center\">\n <Table.RowHeaderCell>\n <Flex\n align=\"center\"\n gap=\"3\"\n overflow=\"hidden\"\n height=\"var(--space-7)\"\n >\n <Avatar\n size=\"2\"\n fallback={<FallbackUserIcon />}\n src={user.profilePictureUrl ?? undefined}\n dim={dimText}\n />\n\n {userDisplayName ? (\n <Flex\n direction=\"column\"\n align=\"start\"\n height=\"var(--space-7)\"\n justify=\"center\"\n overflow=\"hidden\"\n >\n <Flex gap=\"2\" align=\"center\" minWidth=\"0\">\n <TableCellText dim={dimText}>\n {userDisplayName}\n </TableCellText>\n <UserBadge user={user} />\n </Flex>\n <TableCellText\n level=\"secondary\"\n title={user.email}\n dim={dimText}\n >\n {user.email}\n </TableCellText>\n </Flex>\n ) : (\n <Flex gap=\"2\" align=\"center\" minWidth=\"0\">\n <TableCellText dim={dimText} title={user.email}>\n {user.email}\n </TableCellText>\n <UserBadge user={user} />\n </Flex>\n )}\n </Flex>\n </Table.RowHeaderCell>\n <Table.Cell>\n <UserRolesCellContent\n user={user}\n isMultipleRolesEnabled={isMultipleRolesEnabled}\n dimText={dimText}\n />\n </Table.Cell>\n <Table.Cell>\n <LastActive user={user} isHydrated={isHydrated} />\n </Table.Cell>\n <Table.Cell justify=\"end\">\n <UserActionsDropdown user={user}>\n <IconButton\n title={translate({\n defaultMessage: \"User actions\",\n id: \"1nsmNS\",\n description:\n \"Button tooltip for opening user actions menu\",\n })}\n >\n <DotsHorizontalIcon />\n </IconButton>\n </UserActionsDropdown>\n </Table.Cell>\n </Table.Row>\n );\n })\n ) : (\n <Table.Row align=\"center\">\n <Table.Cell colSpan={4}>\n <UsersManagementEmptyState isPending={isPending} />\n </Table.Cell>\n </Table.Row>\n )}\n </Table.Body>\n </Table.Root>\n\n {showPagination ? (\n <Flex gap=\"2\" justify=\"end\">\n <Button\n variant=\"secondary\"\n size=\"1\"\n disabled={!pagination.before || isPending || undefined}\n loading={deferredLoading}\n onClick={() => {\n if (pagination.before) {\n dispatch({\n type: \"SET_PAGINATION\",\n pagination: { before: pagination.before, after: null },\n });\n }\n }}\n >\n <Translation\n defaultMessage=\"Previous\"\n id=\"910Q6b\"\n description=\"Button text to navigate to the previous page of users\"\n />\n </Button>\n <Button\n variant=\"secondary\"\n size=\"1\"\n disabled={!pagination.after || isPending || undefined}\n loading={deferredLoading}\n onClick={() => {\n if (pagination.after) {\n dispatch({\n type: \"SET_PAGINATION\",\n pagination: { after: pagination.after, before: null },\n });\n }\n }}\n >\n <Translation\n defaultMessage=\"Next\"\n id=\"UlAY08\"\n description=\"Button text to navigate to the next page of users\"\n />\n </Button>\n </Flex>\n ) : null}\n </Flex>\n </SearchProvider>\n );\n};\n\ninterface UsersManagementLoadingProps extends WidgetRootDomProps {}\n\nconst UsersManagementLoading: React.FC<UsersManagementLoadingProps> = (\n props,\n) => {\n const translate = useTranslation();\n const placeholderText = (\n <Translation\n defaultMessage=\"All\"\n id=\"l/Do9/\"\n description=\"Filter option to show all users\"\n />\n );\n return (\n <Flex\n direction=\"column\"\n gap=\"3\"\n {...getWidgetRootDomProps(\"loading\", props)}\n >\n <Grid columns=\"1fr auto\" gap=\"2\">\n <Flex gap=\"2\" align=\"center\">\n <Skeleton loading>\n <Box flexBasis=\"380px\" flexGrow=\"0\" flexShrink=\"1\">\n <TextField\n disabled\n aria-label={translate({\n defaultMessage: \"User search\",\n id: \"lzPOKv\",\n description: \"Label for the user search input field\",\n })}\n />\n </Box>\n </Skeleton>\n <Skeleton loading>\n <Box flexGrow=\"0\" flexShrink=\"0\">\n <Select.Root disabled value=\"all\" onValueChange={() => void 0}>\n <Select.Trigger>{placeholderText}</Select.Trigger>\n <Select.Content>\n <Select.Item value=\"all\">{placeholderText}</Select.Item>\n </Select.Content>\n </Select.Root>\n </Box>\n </Skeleton>\n </Flex>\n <Skeleton loading>\n <Box flexGrow=\"0\" flexShrink=\"0\" style={{ placeSelf: \"flex-end\" }}>\n <Button disabled>\n <Translation\n defaultMessage=\"Invite user\"\n id=\"NBXpRj\"\n description=\"Button text to invite a new user to the organization\"\n />\n </Button>\n </Box>\n </Skeleton>\n </Grid>\n <Table.Root variant=\"ghost\" size=\"1\">\n <Table.Header>\n <Table.Row>\n <Table.ColumnHeaderCell width=\"260px\">\n <Skeleton loading>\n <Translation\n defaultMessage=\"User\"\n id=\"BBh86k\"\n description=\"Column header for user information in the users table\"\n />\n </Skeleton>\n </Table.ColumnHeaderCell>\n <Table.ColumnHeaderCell width=\"100px\">\n <Skeleton>\n <Translation\n defaultMessage=\"Role\"\n id=\"FK7mP4\"\n description=\"Column header for user role\"\n />\n </Skeleton>\n </Table.ColumnHeaderCell>\n <Table.ColumnHeaderCell width=\"140px\">\n <Skeleton>\n <Translation\n defaultMessage=\"Last active\"\n id=\"oOwLGt\"\n description=\"Column header showing when users were last active\"\n />\n </Skeleton>\n </Table.ColumnHeaderCell>\n <Table.ColumnHeaderCell width=\"28px\" />\n </Table.Row>\n </Table.Header>\n\n <Table.Body>\n {Array.from({ length: USER_ROW_LIMIT }, (_, index) => (\n <Table.Row key={index} align=\"center\">\n <Table.RowHeaderCell>\n <Flex align=\"center\" gap=\"3\">\n <Skeleton>\n <Avatar size=\"2\" fallback=\"F\" />\n </Skeleton>\n\n <Flex\n direction=\"column\"\n height=\"var(--space-7)\"\n justify=\"center\"\n >\n <Skeleton width=\"180px\" height=\"var(--space-4)\" />\n <Skeleton width=\"90px\" height=\"var(--space-3)\" mt=\"1\" />\n </Flex>\n </Flex>\n </Table.RowHeaderCell>\n <Table.Cell>\n <Flex wrap=\"wrap\" gap=\"1\">\n <Skeleton width=\"75px\" height=\"var(--space-4)\" />\n </Flex>\n </Table.Cell>\n <Table.Cell>\n <Skeleton width=\"120px\" height=\"var(--space-4)\" />\n </Table.Cell>\n <Table.Cell justify=\"end\" />\n </Table.Row>\n ))}\n </Table.Body>\n </Table.Root>\n\n <Flex gap=\"2\" justify=\"end\">\n <Skeleton loading>\n <Button disabled variant=\"secondary\" size=\"1\">\n <Translation\n defaultMessage=\"Previous\"\n id=\"910Q6b\"\n description=\"Button text to navigate to the previous page of users\"\n />\n </Button>\n </Skeleton>\n <Skeleton loading>\n <Button disabled variant=\"secondary\" size=\"1\">\n <Translation\n defaultMessage=\"Next\"\n id=\"UlAY08\"\n description=\"Button text to navigate to the next page of users\"\n />\n </Button>\n </Skeleton>\n </Flex>\n </Flex>\n );\n};\n\ninterface UsersManagementErrorProps extends WidgetRootDomProps {\n error: unknown;\n}\n\nconst UsersManagementError: React.FC<UsersManagementErrorProps> = ({\n error,\n ...domProps\n}) => {\n return (\n <GenericError\n error={error}\n minHeight=\"676px\"\n {...getWidgetRootDomProps(\"error\", domProps)}\n />\n );\n};\n\nfunction UserBadge({ user }: { user: Member }) {\n if (user.isLoggedInUser) {\n return (\n <Badge color=\"gray\" style={{ userSelect: \"none\" }}>\n <Translation\n defaultMessage=\"You\"\n id=\"ER1Vmv\"\n description=\"Badge indicating the current logged-in user\"\n />\n </Badge>\n );\n }\n if (user.status === \"Invited\") {\n return (\n <Badge color=\"amber\" style={{ userSelect: \"none\" }}>\n <VisuallyHidden>\n <Translation\n defaultMessage=\"Status: \"\n id=\"E2o/+H\"\n description=\"Prefix for status indicator in screen reader\"\n />\n </VisuallyHidden>\n <Translation\n defaultMessage=\"Invited\"\n id=\"byIkUu\"\n description=\"Badge status indicating user has been invited but not yet accepted\"\n />\n </Badge>\n );\n }\n if (user.status === \"InviteExpired\") {\n return (\n <Badge color=\"red\" style={{ userSelect: \"none\" }}>\n <VisuallyHidden>\n <Translation\n defaultMessage=\"Status: Invite \"\n id=\"BWvbwY\"\n description=\"Prefix for invite status indicator in screen reader\"\n />\n </VisuallyHidden>\n <Translation\n defaultMessage=\"Expired\"\n id=\"+0sQaN\"\n description=\"Badge status indicating user invitation has expired\"\n />\n </Badge>\n );\n }\n if (user.status === \"InviteRevoked\") {\n return (\n <Badge color=\"red\" style={{ userSelect: \"none\" }}>\n <VisuallyHidden>\n <Translation\n defaultMessage=\"Status: Invite \"\n id=\"BWvbwY\"\n description=\"Prefix for invite status indicator in screen reader\"\n />\n </VisuallyHidden>\n <Translation\n defaultMessage=\"Revoked\"\n id=\"NNBv+r\"\n description=\"Badge status indicating user invitation has been revoked\"\n />\n </Badge>\n );\n }\n return null;\n}\n\ninterface LastActiveProps {\n user: Member;\n isHydrated: boolean;\n dim?: boolean;\n}\n\nfunction LastActive(props: LastActiveProps) {\n if (!props.user.lastActivityAt) {\n return (\n <>\n <VisuallyHidden>\n {props.user.status === \"Active\" ? (\n <Translation\n defaultMessage=\"Never\"\n id=\"0duvF4\"\n description=\"Screen reader text indicating user has never been active\"\n />\n ) : (\n <Translation\n defaultMessage=\"Not active\"\n id=\"hd2+kk\"\n description=\"Screen reader text indicating user is not active\"\n />\n )}\n </VisuallyHidden>\n <Separator />\n </>\n );\n }\n return <LastActiveImpl {...props} date={props.user.lastActivityAt} />;\n}\n\nfunction LastActiveImpl({\n date,\n isHydrated,\n dim,\n}: LastActiveProps & { date: string }) {\n const locale = useLocale();\n\n const lastActiveDate = new Date(date);\n const lastActiveDateTime = lastActiveDate.toLocaleTimeString(locale, {\n // hard-coded timezone before hydration to prevent server/client mismatch\n timeZone: isHydrated ? undefined : \"America/Los_Angeles\",\n month: \"long\",\n day: \"numeric\",\n year: \"numeric\",\n hour: \"numeric\",\n minute: \"numeric\",\n });\n\n const lastActiveDisplay = useComparativeReadableDate({\n date: lastActiveDate,\n });\n\n // handle cases where the DB might return an invalid date string\n if (lastActiveDisplay === \"Invalid Date\") {\n return (\n <>\n <VisuallyHidden>\n <Translation\n defaultMessage=\"Unknown\"\n id=\"UUigrK\"\n description=\"Screen reader text indicating last active date is unknown\"\n />\n </VisuallyHidden>\n <Separator />\n </>\n );\n }\n\n return (\n <TableCellText asChild dim={dim}>\n <time dateTime={date} title={lastActiveDateTime}>\n {lastActiveDisplay}\n </time>\n </TableCellText>\n );\n}\n\nconst TableCellText = React.forwardRef<HTMLSpanElement, TableCellTextProps>(\n function TableCellText(\n { children, dim, level = \"primary\", ...props },\n forwardedRef,\n ) {\n return (\n <Text\n ref={forwardedRef}\n color={level === \"secondary\" ? \"gray\" : undefined}\n weight={level === \"secondary\" ? \"regular\" : \"medium\"}\n size={level === \"secondary\" ? \"1\" : \"2\"}\n truncate\n {...props}\n style={\n dim\n ? {\n // TODO: use CSS var instead of hard-coded value for opacity\n opacity: 0.6,\n ...props.style,\n }\n : props.style\n }\n >\n {children}\n </Text>\n );\n },\n);\n\ntype TableCellTextProps = TextProps & {\n level?: \"primary\" | \"secondary\";\n dim?: boolean;\n};\n\nconst FallbackUserIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"20\"\n height=\"20\"\n fill=\"currentColor\"\n viewBox=\"0 0 256 256\"\n >\n {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}\n <title>User icon</title>\n <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\" />\n </svg>\n);\n\nconst UsersManagementEmptyState = ({ isPending }: { isPending: boolean }) => {\n const { clearSearch } = useSearchContext();\n const {\n state: { searchQuery },\n } = useUsersManagementContext();\n\n // When the search query is cleared, the users query is re-fetched which sends\n // us into a pending state. When this happens we want to keep a snapshot of\n // the previous search query while the query is revalidated. We can use this\n // to keep the 'No users found for query' UI in place until re-fetching is\n // complete, otherwise the view flips to 'No users found' very quickly before\n // the full table is shown again.\n const [{ isClearing, lastSearchQuery }, setClearing] = React.useState({\n isClearing: false,\n lastSearchQuery: null as null | string,\n });\n const [wasPending, setWasPending] = React.useState(isPending);\n if (wasPending !== isPending) {\n setWasPending(isPending);\n if (!isPending) {\n setClearing((prev) =>\n prev.isClearing ? { isClearing: false, lastSearchQuery: null } : prev,\n );\n }\n }\n\n if (searchQuery || isClearing) {\n return (\n <Flex align=\"center\" justify=\"center\" py=\"8\" direction=\"column\" gap=\"2\">\n <Text size=\"2\">\n <Translation\n defaultMessage=\"No users found for query '{query}'\"\n id=\"wrEZ8+\"\n description=\"Message shown when no users match the search query\"\n values={{\n query: isClearing ? lastSearchQuery : searchQuery,\n }}\n />\n </Text>\n\n <Button\n variant=\"secondary\"\n size=\"1\"\n onClick={() => {\n setClearing({ isClearing: true, lastSearchQuery: searchQuery });\n clearSearch();\n }}\n loading={isPending}\n >\n <Translation\n defaultMessage=\"Clear search\"\n id=\"Xv3fVI\"\n description=\"Button text to clear the current search query\"\n />\n </Button>\n </Flex>\n );\n }\n\n return (\n <Flex align=\"center\" justify=\"center\" py=\"8\" gap=\"2\">\n <Text size=\"2\">\n <Translation\n defaultMessage=\"No users found\"\n id=\"MQ+LoA\"\n description=\"Message shown when there are no users in the system\"\n />\n </Text>\n </Flex>\n );\n};\n\ninterface UserRolesCellContentProps {\n user: Member;\n isMultipleRolesEnabled: boolean;\n dimText: boolean;\n}\n\nfunction UserRolesCellContent({\n user,\n isMultipleRolesEnabled,\n dimText,\n}: UserRolesCellContentProps) {\n if (!user.roles || user.roles.length === 0) {\n return (\n <>\n <VisuallyHidden>\n <Translation\n defaultMessage=\"No roles assigned\"\n id=\"CVOVB0\"\n description=\"Screen reader text indicating user has no roles assigned\"\n />\n </VisuallyHidden>\n {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}\n <span aria-hidden style={{ userSelect: \"none\" }}>\n –\n </span>\n </>\n );\n }\n\n if (isMultipleRolesEnabled && user.roles.length > 1) {\n const roleNames = user.roles?.map((role) => role.name).join(\", \");\n return (\n <Tooltip content={roleNames} maxWidth=\"250px\">\n <TableCellText dim={dimText}>\n <Translation\n defaultMessage=\"{count} roles\"\n id=\"lWAmRC\"\n description=\"Shows the number of roles assigned to a user (plural)\"\n values={{ count: user.roles.length }}\n />\n </TableCellText>\n </Tooltip>\n );\n }\n\n return <TableCellText dim={dimText}>{user.roles?.[0]?.name}</TableCellText>;\n}\n\nfunction getWidgetRootDomProps(\n state: WidgetRootState,\n domProps: WidgetRootDomProps,\n) {\n return getWidgetDomProps({\n ...domProps,\n isWidgetRoot: true,\n widgetId: \"users-management\",\n widgetState: state,\n });\n}\n\nexport type { UsersManagementLoadingProps, UsersManagementErrorProps };\nexport { UsersManagement, UsersManagementLoading, UsersManagementError };\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@workos-inc/widgets",
3
- "version": "1.20.0",
3
+ "version": "1.20.1",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",