@shipfox/client-runners 21.0.0 → 22.0.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.
@@ -1,2 +1,2 @@
1
1
  $ shipfox-swc
2
- Successfully compiled: 24 files with swc (338.11ms)
2
+ Successfully compiled: 24 files with swc (357.78ms)
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @shipfox/client-runners
2
2
 
3
+ ## 22.0.0
4
+
5
+ ### Patch Changes
6
+
7
+ - 7693eb3: Render empty and load-error states inside bordered panel bodies and keep loading placeholders aligned with their data regions.
8
+ - Updated dependencies [50b3867]
9
+ - Updated dependencies [00c1cb8]
10
+ - Updated dependencies [7693eb3]
11
+ - Updated dependencies [00c1cb8]
12
+ - Updated dependencies [56f4526]
13
+ - Updated dependencies [af6b31e]
14
+ - @shipfox/client-shell@22.0.0
15
+ - @shipfox/react-ui@2.1.0
16
+ - @shipfox/client-ui@22.0.0
17
+ - @shipfox/api-runners-dto@13.0.0
18
+
3
19
  ## 21.0.0
4
20
 
5
21
  ### Patch Changes
@@ -1 +1 @@
1
- {"version":3,"file":"manual-registration-token-list.d.ts","sourceRoot":"","sources":["../../src/components/manual-registration-token-list.tsx"],"names":[],"mappings":"AA6BA,OAAO,EAAC,KAAK,uBAAuB,EAAmB,MAAM,gBAAgB,CAAC;AAU9E,wBAAgB,2BAA2B,CAAC,EAC1C,WAAW,EACX,MAAM,GACP,EAAE;IACD,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,uBAAuB,EAAE,CAAC;CACnC,+BA4EA;AA8FD,wBAAgB,6BAA6B,gCAQ5C;AAED,wBAAgB,oCAAoC,gCAYnD"}
1
+ {"version":3,"file":"manual-registration-token-list.d.ts","sourceRoot":"","sources":["../../src/components/manual-registration-token-list.tsx"],"names":[],"mappings":"AA6BA,OAAO,EAAC,KAAK,uBAAuB,EAAmB,MAAM,gBAAgB,CAAC;AAU9E,wBAAgB,2BAA2B,CAAC,EAC1C,WAAW,EACX,MAAM,GACP,EAAE;IACD,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,uBAAuB,EAAE,CAAC;CACnC,+BAyEA;AA8FD,wBAAgB,6BAA6B,gCAS5C;AAED,wBAAgB,oCAAoC,gCAQnD"}
@@ -16,9 +16,9 @@ import { formatManualRegistrationTokenDate, formatManualRegistrationTokenTimesta
16
16
  import { TokenDate } from './token-date.js';
17
17
  import { TokenName } from './token-name.js';
18
18
  export function ManualRegistrationTokenList({ workspaceId, tokens }) {
19
- return /*#__PURE__*/ _jsxs(_Fragment, {
19
+ return /*#__PURE__*/ _jsxs(Panel, {
20
20
  children: [
21
- /*#__PURE__*/ _jsx(Panel, {
21
+ /*#__PURE__*/ _jsx("div", {
22
22
  className: "max-[760px]:hidden",
23
23
  children: /*#__PURE__*/ _jsxs(Table, {
24
24
  className: "table-fixed",
@@ -87,10 +87,10 @@ export function ManualRegistrationTokenList({ workspaceId, tokens }) {
87
87
  })
88
88
  }),
89
89
  /*#__PURE__*/ _jsx("ul", {
90
- className: "hidden flex-col gap-inline max-[760px]:flex",
90
+ className: "hidden flex-col divide-y divide-border-neutral-base max-[760px]:flex",
91
91
  "aria-label": "Manual registration tokens",
92
92
  children: tokens.map((token)=>/*#__PURE__*/ _jsxs("li", {
93
- className: "flex flex-col gap-cluster rounded-8 border border-border-neutral-base bg-background-neutral-base p-panel-compact",
93
+ className: "flex flex-col gap-cluster p-panel-compact",
94
94
  children: [
95
95
  /*#__PURE__*/ _jsxs("div", {
96
96
  className: "flex items-start justify-between gap-cluster",
@@ -266,20 +266,21 @@ export function EmptyManualRegistrationTokens() {
266
266
  return /*#__PURE__*/ _jsx(EmptyState, {
267
267
  icon: "key2Line",
268
268
  title: "No usable manual registration tokens",
269
- description: "Create a token to connect a runner to this workspace."
269
+ description: "Create a token to connect a runner to this workspace.",
270
+ variant: "panel"
270
271
  });
271
272
  }
272
273
  export function ManualRegistrationTokenTableSkeleton() {
273
- return /*#__PURE__*/ _jsx("div", {
274
+ return /*#__PURE__*/ _jsx(Panel, {
274
275
  role: "status",
275
276
  "aria-label": "Loading manual registration tokens",
276
- className: "flex flex-col gap-inline",
277
+ className: "divide-y",
277
278
  children: [
278
279
  0,
279
280
  1,
280
281
  2
281
282
  ].map((row)=>/*#__PURE__*/ _jsx(Skeleton, {
282
- className: "h-44 w-full"
283
+ className: "h-44 w-full rounded-none"
283
284
  }, row))
284
285
  });
285
286
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/manual-registration-token-list.tsx"],"sourcesContent":["import {Button, IconButton} from '@shipfox/react-ui/button';\nimport {Callout} from '@shipfox/react-ui/callout';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@shipfox/react-ui/dropdown-menu';\nimport {EmptyState} from '@shipfox/react-ui/empty-state';\nimport {\n Modal,\n ModalBody,\n ModalContent,\n ModalFooter,\n ModalHeader,\n ModalTitle,\n} from '@shipfox/react-ui/modal';\nimport {Panel} from '@shipfox/react-ui/panel';\nimport {Skeleton} from '@shipfox/react-ui/skeleton';\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@shipfox/react-ui/table';\nimport {Code, Text} from '@shipfox/react-ui/typography';\nimport {useState} from 'react';\nimport {type ManualRegistrationToken, tokenDisplayName} from '#core/token.js';\nimport {useRevokeManualRegistrationTokenMutation} from '#hooks/api/manual-registration-tokens.js';\nimport {manualRegistrationTokenErrorMessage} from './manual-registration-token-errors.js';\nimport {\n formatManualRegistrationTokenDate,\n formatManualRegistrationTokenTimestamp,\n} from './manual-registration-token-format.js';\nimport {TokenDate} from './token-date.js';\nimport {TokenName} from './token-name.js';\n\nexport function ManualRegistrationTokenList({\n workspaceId,\n tokens,\n}: {\n workspaceId: string;\n tokens: ManualRegistrationToken[];\n}) {\n return (\n <>\n <Panel className=\"max-[760px]:hidden\">\n <Table className=\"table-fixed\">\n <TableHeader>\n <TableRow>\n <TableHead className=\"w-[34%]\">Name</TableHead>\n <TableHead>Prefix</TableHead>\n <TableHead className=\"w-128\">Expires</TableHead>\n <TableHead className=\"w-128\">Created</TableHead>\n <TableHead className=\"w-80 text-right\">Actions</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {tokens.map((token) => (\n <TableRow key={token.id}>\n <TableCell>\n <TokenName name={tokenDisplayName(token)} />\n </TableCell>\n <TableCell>\n <Code variant=\"paragraph\" className=\"block truncate\">\n {token.prefix}\n </Code>\n </TableCell>\n <TableCell>\n <ManualRegistrationTokenDate value={token.expiresAt} />\n </TableCell>\n <TableCell>\n <ManualRegistrationTokenDate value={token.createdAt} />\n </TableCell>\n <TableCell className=\"text-right\">\n <RevokeManualRegistrationTokenButton workspaceId={workspaceId} token={token} />\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </Panel>\n <ul\n className=\"hidden flex-col gap-inline max-[760px]:flex\"\n aria-label=\"Manual registration tokens\"\n >\n {tokens.map((token) => (\n <li\n key={token.id}\n className=\"flex flex-col gap-cluster rounded-8 border border-border-neutral-base bg-background-neutral-base p-panel-compact\"\n >\n <div className=\"flex items-start justify-between gap-cluster\">\n <div className=\"min-w-0 flex-1\">\n <TokenName name={tokenDisplayName(token)} />\n <Code variant=\"paragraph\" className=\"block truncate text-foreground-neutral-muted\">\n {token.prefix}\n </Code>\n </div>\n <RevokeManualRegistrationTokenButton workspaceId={workspaceId} token={token} />\n </div>\n <dl className=\"grid grid-cols-2 gap-inline text-sm\">\n <div>\n <dt className=\"text-foreground-neutral-muted\">Expires</dt>\n <dd>\n <ManualRegistrationTokenDate value={token.expiresAt} />\n </dd>\n </div>\n <div>\n <dt className=\"text-foreground-neutral-muted\">Created</dt>\n <dd>\n <ManualRegistrationTokenDate value={token.createdAt} />\n </dd>\n </div>\n </dl>\n </li>\n ))}\n </ul>\n </>\n );\n}\n\nfunction ManualRegistrationTokenDate({value}: {value: string | null}) {\n return (\n <TokenDate\n value={value}\n date={formatManualRegistrationTokenDate(value)}\n timestamp={formatManualRegistrationTokenTimestamp(value)}\n />\n );\n}\n\nfunction RevokeManualRegistrationTokenButton({\n workspaceId,\n token,\n}: {\n workspaceId: string;\n token: ManualRegistrationToken;\n}) {\n const revokeToken = useRevokeManualRegistrationTokenMutation(workspaceId);\n const [open, setOpen] = useState(false);\n const tokenName = tokenDisplayName(token);\n\n async function handleRevoke() {\n try {\n await revokeToken.mutateAsync(token.id);\n setOpen(false);\n } catch {\n // React Query stores the error for the inline modal alert.\n }\n }\n\n function handleOpenChange(nextOpen: boolean) {\n setOpen(nextOpen);\n if (nextOpen) {\n revokeToken.reset();\n }\n }\n\n function openRevokeConfirmation() {\n revokeToken.reset();\n setOpen(true);\n }\n\n return (\n <>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <IconButton\n type=\"button\"\n size=\"sm\"\n variant=\"transparent\"\n icon=\"more2Line\"\n aria-label={`Open ${tokenName} registration token actions`}\n />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" size=\"sm\">\n <DropdownMenuItem onSelect={openRevokeConfirmation}>Revoke token</DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n <Modal open={open} onOpenChange={handleOpenChange}>\n <ModalContent aria-describedby={undefined} className=\"max-w-[420px]\">\n <ModalTitle className=\"sr-only\">Revoke token</ModalTitle>\n <ModalHeader title=\"Revoke token?\" />\n <ModalBody className=\"gap-group\">\n <Text size=\"sm\" className=\"text-foreground-neutral-muted\">\n {tokenName} will stop creating new runner sessions. Existing sessions and job leases\n expire on their own.\n </Text>\n {revokeToken.isError ? (\n <Callout role=\"alert\" type=\"error\">\n <Text size=\"sm\">{manualRegistrationTokenErrorMessage(revokeToken.error)}</Text>\n </Callout>\n ) : null}\n </ModalBody>\n <ModalFooter>\n <Button size=\"sm\" variant=\"secondary\" onClick={() => setOpen(false)}>\n Cancel\n </Button>\n <Button\n size=\"sm\"\n variant=\"danger\"\n isLoading={revokeToken.isPending}\n onClick={handleRevoke}\n >\n Revoke\n </Button>\n </ModalFooter>\n </ModalContent>\n </Modal>\n </>\n );\n}\n\nexport function EmptyManualRegistrationTokens() {\n return (\n <EmptyState\n icon=\"key2Line\"\n title=\"No usable manual registration tokens\"\n description=\"Create a token to connect a runner to this workspace.\"\n />\n );\n}\n\nexport function ManualRegistrationTokenTableSkeleton() {\n return (\n <div\n role=\"status\"\n aria-label=\"Loading manual registration tokens\"\n className=\"flex flex-col gap-inline\"\n >\n {[0, 1, 2].map((row) => (\n <Skeleton key={row} className=\"h-44 w-full\" />\n ))}\n </div>\n );\n}\n"],"names":["Button","IconButton","Callout","DropdownMenu","DropdownMenuContent","DropdownMenuItem","DropdownMenuTrigger","EmptyState","Modal","ModalBody","ModalContent","ModalFooter","ModalHeader","ModalTitle","Panel","Skeleton","Table","TableBody","TableCell","TableHead","TableHeader","TableRow","Code","Text","useState","tokenDisplayName","useRevokeManualRegistrationTokenMutation","manualRegistrationTokenErrorMessage","formatManualRegistrationTokenDate","formatManualRegistrationTokenTimestamp","TokenDate","TokenName","ManualRegistrationTokenList","workspaceId","tokens","className","map","token","name","variant","prefix","ManualRegistrationTokenDate","value","expiresAt","createdAt","RevokeManualRegistrationTokenButton","id","ul","aria-label","li","div","dl","dt","dd","date","timestamp","revokeToken","open","setOpen","tokenName","handleRevoke","mutateAsync","handleOpenChange","nextOpen","reset","openRevokeConfirmation","asChild","type","size","icon","align","onSelect","onOpenChange","aria-describedby","undefined","title","isError","role","error","onClick","isLoading","isPending","EmptyManualRegistrationTokens","description","ManualRegistrationTokenTableSkeleton","row"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/components/manual-registration-token-list.tsx"],"sourcesContent":["import {Button, IconButton} from '@shipfox/react-ui/button';\nimport {Callout} from '@shipfox/react-ui/callout';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@shipfox/react-ui/dropdown-menu';\nimport {EmptyState} from '@shipfox/react-ui/empty-state';\nimport {\n Modal,\n ModalBody,\n ModalContent,\n ModalFooter,\n ModalHeader,\n ModalTitle,\n} from '@shipfox/react-ui/modal';\nimport {Panel} from '@shipfox/react-ui/panel';\nimport {Skeleton} from '@shipfox/react-ui/skeleton';\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@shipfox/react-ui/table';\nimport {Code, Text} from '@shipfox/react-ui/typography';\nimport {useState} from 'react';\nimport {type ManualRegistrationToken, tokenDisplayName} from '#core/token.js';\nimport {useRevokeManualRegistrationTokenMutation} from '#hooks/api/manual-registration-tokens.js';\nimport {manualRegistrationTokenErrorMessage} from './manual-registration-token-errors.js';\nimport {\n formatManualRegistrationTokenDate,\n formatManualRegistrationTokenTimestamp,\n} from './manual-registration-token-format.js';\nimport {TokenDate} from './token-date.js';\nimport {TokenName} from './token-name.js';\n\nexport function ManualRegistrationTokenList({\n workspaceId,\n tokens,\n}: {\n workspaceId: string;\n tokens: ManualRegistrationToken[];\n}) {\n return (\n <Panel>\n <div className=\"max-[760px]:hidden\">\n <Table className=\"table-fixed\">\n <TableHeader>\n <TableRow>\n <TableHead className=\"w-[34%]\">Name</TableHead>\n <TableHead>Prefix</TableHead>\n <TableHead className=\"w-128\">Expires</TableHead>\n <TableHead className=\"w-128\">Created</TableHead>\n <TableHead className=\"w-80 text-right\">Actions</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {tokens.map((token) => (\n <TableRow key={token.id}>\n <TableCell>\n <TokenName name={tokenDisplayName(token)} />\n </TableCell>\n <TableCell>\n <Code variant=\"paragraph\" className=\"block truncate\">\n {token.prefix}\n </Code>\n </TableCell>\n <TableCell>\n <ManualRegistrationTokenDate value={token.expiresAt} />\n </TableCell>\n <TableCell>\n <ManualRegistrationTokenDate value={token.createdAt} />\n </TableCell>\n <TableCell className=\"text-right\">\n <RevokeManualRegistrationTokenButton workspaceId={workspaceId} token={token} />\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n <ul\n className=\"hidden flex-col divide-y divide-border-neutral-base max-[760px]:flex\"\n aria-label=\"Manual registration tokens\"\n >\n {tokens.map((token) => (\n <li key={token.id} className=\"flex flex-col gap-cluster p-panel-compact\">\n <div className=\"flex items-start justify-between gap-cluster\">\n <div className=\"min-w-0 flex-1\">\n <TokenName name={tokenDisplayName(token)} />\n <Code variant=\"paragraph\" className=\"block truncate text-foreground-neutral-muted\">\n {token.prefix}\n </Code>\n </div>\n <RevokeManualRegistrationTokenButton workspaceId={workspaceId} token={token} />\n </div>\n <dl className=\"grid grid-cols-2 gap-inline text-sm\">\n <div>\n <dt className=\"text-foreground-neutral-muted\">Expires</dt>\n <dd>\n <ManualRegistrationTokenDate value={token.expiresAt} />\n </dd>\n </div>\n <div>\n <dt className=\"text-foreground-neutral-muted\">Created</dt>\n <dd>\n <ManualRegistrationTokenDate value={token.createdAt} />\n </dd>\n </div>\n </dl>\n </li>\n ))}\n </ul>\n </Panel>\n );\n}\n\nfunction ManualRegistrationTokenDate({value}: {value: string | null}) {\n return (\n <TokenDate\n value={value}\n date={formatManualRegistrationTokenDate(value)}\n timestamp={formatManualRegistrationTokenTimestamp(value)}\n />\n );\n}\n\nfunction RevokeManualRegistrationTokenButton({\n workspaceId,\n token,\n}: {\n workspaceId: string;\n token: ManualRegistrationToken;\n}) {\n const revokeToken = useRevokeManualRegistrationTokenMutation(workspaceId);\n const [open, setOpen] = useState(false);\n const tokenName = tokenDisplayName(token);\n\n async function handleRevoke() {\n try {\n await revokeToken.mutateAsync(token.id);\n setOpen(false);\n } catch {\n // React Query stores the error for the inline modal alert.\n }\n }\n\n function handleOpenChange(nextOpen: boolean) {\n setOpen(nextOpen);\n if (nextOpen) {\n revokeToken.reset();\n }\n }\n\n function openRevokeConfirmation() {\n revokeToken.reset();\n setOpen(true);\n }\n\n return (\n <>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <IconButton\n type=\"button\"\n size=\"sm\"\n variant=\"transparent\"\n icon=\"more2Line\"\n aria-label={`Open ${tokenName} registration token actions`}\n />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" size=\"sm\">\n <DropdownMenuItem onSelect={openRevokeConfirmation}>Revoke token</DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n <Modal open={open} onOpenChange={handleOpenChange}>\n <ModalContent aria-describedby={undefined} className=\"max-w-[420px]\">\n <ModalTitle className=\"sr-only\">Revoke token</ModalTitle>\n <ModalHeader title=\"Revoke token?\" />\n <ModalBody className=\"gap-group\">\n <Text size=\"sm\" className=\"text-foreground-neutral-muted\">\n {tokenName} will stop creating new runner sessions. Existing sessions and job leases\n expire on their own.\n </Text>\n {revokeToken.isError ? (\n <Callout role=\"alert\" type=\"error\">\n <Text size=\"sm\">{manualRegistrationTokenErrorMessage(revokeToken.error)}</Text>\n </Callout>\n ) : null}\n </ModalBody>\n <ModalFooter>\n <Button size=\"sm\" variant=\"secondary\" onClick={() => setOpen(false)}>\n Cancel\n </Button>\n <Button\n size=\"sm\"\n variant=\"danger\"\n isLoading={revokeToken.isPending}\n onClick={handleRevoke}\n >\n Revoke\n </Button>\n </ModalFooter>\n </ModalContent>\n </Modal>\n </>\n );\n}\n\nexport function EmptyManualRegistrationTokens() {\n return (\n <EmptyState\n icon=\"key2Line\"\n title=\"No usable manual registration tokens\"\n description=\"Create a token to connect a runner to this workspace.\"\n variant=\"panel\"\n />\n );\n}\n\nexport function ManualRegistrationTokenTableSkeleton() {\n return (\n <Panel role=\"status\" aria-label=\"Loading manual registration tokens\" className=\"divide-y\">\n {[0, 1, 2].map((row) => (\n <Skeleton key={row} className=\"h-44 w-full rounded-none\" />\n ))}\n </Panel>\n );\n}\n"],"names":["Button","IconButton","Callout","DropdownMenu","DropdownMenuContent","DropdownMenuItem","DropdownMenuTrigger","EmptyState","Modal","ModalBody","ModalContent","ModalFooter","ModalHeader","ModalTitle","Panel","Skeleton","Table","TableBody","TableCell","TableHead","TableHeader","TableRow","Code","Text","useState","tokenDisplayName","useRevokeManualRegistrationTokenMutation","manualRegistrationTokenErrorMessage","formatManualRegistrationTokenDate","formatManualRegistrationTokenTimestamp","TokenDate","TokenName","ManualRegistrationTokenList","workspaceId","tokens","div","className","map","token","name","variant","prefix","ManualRegistrationTokenDate","value","expiresAt","createdAt","RevokeManualRegistrationTokenButton","id","ul","aria-label","li","dl","dt","dd","date","timestamp","revokeToken","open","setOpen","tokenName","handleRevoke","mutateAsync","handleOpenChange","nextOpen","reset","openRevokeConfirmation","asChild","type","size","icon","align","onSelect","onOpenChange","aria-describedby","undefined","title","isError","role","error","onClick","isLoading","isPending","EmptyManualRegistrationTokens","description","ManualRegistrationTokenTableSkeleton","row"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"manual-registration-tokens-settings-section.d.ts","sourceRoot":"","sources":["../../src/components/manual-registration-tokens-settings-section.tsx"],"names":[],"mappings":"AAyBA,wBAAgB,gDAAgD,CAAC,EAC/D,WAAW,GACZ,EAAE;IACD,WAAW,EAAE,MAAM,CAAC;CACrB,+BA8EA"}
1
+ {"version":3,"file":"manual-registration-tokens-settings-section.d.ts","sourceRoot":"","sources":["../../src/components/manual-registration-tokens-settings-section.tsx"],"names":[],"mappings":"AA0BA,wBAAgB,gDAAgD,CAAC,EAC/D,WAAW,GACZ,EAAE;IACD,WAAW,EAAE,MAAM,CAAC;CACrB,+BAsFA"}
@@ -3,6 +3,7 @@ import { QueryLoadError } from '@shipfox/client-ui';
3
3
  import { Button } from '@shipfox/react-ui/button';
4
4
  import { Icon } from '@shipfox/react-ui/icon';
5
5
  import { Modal, ModalBody, ModalContent, ModalHeader, ModalTitle, ModalTrigger } from '@shipfox/react-ui/modal';
6
+ import { Panel } from '@shipfox/react-ui/panel';
6
7
  import { Header, Text } from '@shipfox/react-ui/typography';
7
8
  import { useState } from 'react';
8
9
  import { useManualRegistrationTokensQuery } from '#hooks/api/manual-registration-tokens.js';
@@ -92,11 +93,16 @@ export function WorkspaceManualRegistrationTokensSettingsSection({ workspaceId }
92
93
  ]
93
94
  }),
94
95
  tokensQuery.isPending ? /*#__PURE__*/ _jsx(ManualRegistrationTokenTableSkeleton, {}) : null,
95
- tokensQuery.isError && tokensQuery.data === undefined ? /*#__PURE__*/ _jsx(QueryLoadError, {
96
- query: tokensQuery,
97
- subject: "manual registration tokens"
96
+ tokensQuery.isError && tokensQuery.data === undefined ? /*#__PURE__*/ _jsx(Panel, {
97
+ children: /*#__PURE__*/ _jsx(QueryLoadError, {
98
+ query: tokensQuery,
99
+ subject: "manual registration tokens",
100
+ variant: "panel"
101
+ })
102
+ }) : null,
103
+ tokensQuery.data !== undefined && tokens.length === 0 ? /*#__PURE__*/ _jsx(Panel, {
104
+ children: /*#__PURE__*/ _jsx(EmptyManualRegistrationTokens, {})
98
105
  }) : null,
99
- tokensQuery.data !== undefined && tokens.length === 0 ? /*#__PURE__*/ _jsx(EmptyManualRegistrationTokens, {}) : null,
100
106
  tokens.length > 0 ? /*#__PURE__*/ _jsx(ManualRegistrationTokenList, {
101
107
  workspaceId: workspaceId,
102
108
  tokens: tokens
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/manual-registration-tokens-settings-section.tsx"],"sourcesContent":["import {QueryLoadError} from '@shipfox/client-ui';\nimport {Button} from '@shipfox/react-ui/button';\nimport {Icon} from '@shipfox/react-ui/icon';\nimport {\n Modal,\n ModalBody,\n ModalContent,\n ModalHeader,\n ModalTitle,\n ModalTrigger,\n} from '@shipfox/react-ui/modal';\nimport {Header, Text} from '@shipfox/react-ui/typography';\nimport {useState} from 'react';\nimport type {CreatedManualRegistrationToken} from '#core/token.js';\nimport {useManualRegistrationTokensQuery} from '#hooks/api/manual-registration-tokens.js';\nimport {\n CreatedManualRegistrationTokenPanel,\n CreateManualRegistrationTokenForm,\n} from './create-manual-registration-token-form.js';\nimport {\n EmptyManualRegistrationTokens,\n ManualRegistrationTokenList,\n ManualRegistrationTokenTableSkeleton,\n} from './manual-registration-token-list.js';\n\nexport function WorkspaceManualRegistrationTokensSettingsSection({\n workspaceId,\n}: {\n workspaceId: string;\n}) {\n const tokensQuery = useManualRegistrationTokensQuery(workspaceId);\n const [isModalOpen, setIsModalOpen] = useState(false);\n const [createdToken, setCreatedToken] = useState<CreatedManualRegistrationToken | null>(null);\n const tokens = tokensQuery.data ?? [];\n\n function handleOpenChange(nextOpen: boolean) {\n setIsModalOpen(nextOpen);\n if (!nextOpen) {\n setCreatedToken(null);\n }\n }\n\n return (\n <div className=\"flex min-w-0 flex-col gap-region\">\n <section className=\"flex flex-col gap-group\">\n <div className=\"flex items-center justify-between gap-group max-[640px]:items-start\">\n <div className=\"flex flex-col gap-tight\">\n <Header variant=\"h3\">Runner registration tokens</Header>\n <Text size=\"sm\" className=\"text-foreground-neutral-muted\">\n Register individual runner agents that run jobs directly in this workspace. Tokens are\n reusable until revoked.\n </Text>\n </div>\n <div className=\"flex items-center gap-cluster\">\n {tokensQuery.isFetching && !tokensQuery.isPending ? (\n <Icon\n name=\"loader4Line\"\n className=\"mt-[2px] size-18 text-foreground-neutral-muted\"\n aria-label=\"Refreshing tokens\"\n />\n ) : null}\n <Modal open={isModalOpen} onOpenChange={handleOpenChange}>\n <ModalTrigger asChild>\n <Button>Create token</Button>\n </ModalTrigger>\n <ModalContent aria-describedby={undefined}>\n <ModalTitle className=\"sr-only\">Create manual registration token</ModalTitle>\n <ModalHeader>\n <Text\n size=\"lg\"\n aria-hidden=\"true\"\n className=\"overflow-ellipsis overflow-hidden whitespace-nowrap\"\n >\n Create manual registration token\n </Text>\n </ModalHeader>\n {createdToken ? (\n <ModalBody className=\"gap-group\">\n <CreatedManualRegistrationTokenPanel token={createdToken} />\n </ModalBody>\n ) : (\n <CreateManualRegistrationTokenForm\n workspaceId={workspaceId}\n onCreated={setCreatedToken}\n />\n )}\n </ModalContent>\n </Modal>\n </div>\n </div>\n\n {tokensQuery.isPending ? <ManualRegistrationTokenTableSkeleton /> : null}\n\n {tokensQuery.isError && tokensQuery.data === undefined ? (\n <QueryLoadError query={tokensQuery} subject=\"manual registration tokens\" />\n ) : null}\n\n {tokensQuery.data !== undefined && tokens.length === 0 ? (\n <EmptyManualRegistrationTokens />\n ) : null}\n\n {tokens.length > 0 ? (\n <ManualRegistrationTokenList workspaceId={workspaceId} tokens={tokens} />\n ) : null}\n </section>\n </div>\n );\n}\n"],"names":["QueryLoadError","Button","Icon","Modal","ModalBody","ModalContent","ModalHeader","ModalTitle","ModalTrigger","Header","Text","useState","useManualRegistrationTokensQuery","CreatedManualRegistrationTokenPanel","CreateManualRegistrationTokenForm","EmptyManualRegistrationTokens","ManualRegistrationTokenList","ManualRegistrationTokenTableSkeleton","WorkspaceManualRegistrationTokensSettingsSection","workspaceId","tokensQuery","isModalOpen","setIsModalOpen","createdToken","setCreatedToken","tokens","data","handleOpenChange","nextOpen","div","className","section","variant","size","isFetching","isPending","name","aria-label","open","onOpenChange","asChild","aria-describedby","undefined","aria-hidden","token","onCreated","isError","query","subject","length"],"mappings":";AAAA,SAAQA,cAAc,QAAO,qBAAqB;AAClD,SAAQC,MAAM,QAAO,2BAA2B;AAChD,SAAQC,IAAI,QAAO,yBAAyB;AAC5C,SACEC,KAAK,EACLC,SAAS,EACTC,YAAY,EACZC,WAAW,EACXC,UAAU,EACVC,YAAY,QACP,0BAA0B;AACjC,SAAQC,MAAM,EAAEC,IAAI,QAAO,+BAA+B;AAC1D,SAAQC,QAAQ,QAAO,QAAQ;AAE/B,SAAQC,gCAAgC,QAAO,2CAA2C;AAC1F,SACEC,mCAAmC,EACnCC,iCAAiC,QAC5B,6CAA6C;AACpD,SACEC,6BAA6B,EAC7BC,2BAA2B,EAC3BC,oCAAoC,QAC/B,sCAAsC;AAE7C,OAAO,SAASC,iDAAiD,EAC/DC,WAAW,EAGZ;IACC,MAAMC,cAAcR,iCAAiCO;IACrD,MAAM,CAACE,aAAaC,eAAe,GAAGX,SAAS;IAC/C,MAAM,CAACY,cAAcC,gBAAgB,GAAGb,SAAgD;IACxF,MAAMc,SAASL,YAAYM,IAAI,IAAI,EAAE;IAErC,SAASC,iBAAiBC,QAAiB;QACzCN,eAAeM;QACf,IAAI,CAACA,UAAU;YACbJ,gBAAgB;QAClB;IACF;IAEA,qBACE,KAACK;QAAIC,WAAU;kBACb,cAAA,MAACC;YAAQD,WAAU;;8BACjB,MAACD;oBAAIC,WAAU;;sCACb,MAACD;4BAAIC,WAAU;;8CACb,KAACrB;oCAAOuB,SAAQ;8CAAK;;8CACrB,KAACtB;oCAAKuB,MAAK;oCAAKH,WAAU;8CAAgC;;;;sCAK5D,MAACD;4BAAIC,WAAU;;gCACZV,YAAYc,UAAU,IAAI,CAACd,YAAYe,SAAS,iBAC/C,KAACjC;oCACCkC,MAAK;oCACLN,WAAU;oCACVO,cAAW;qCAEX;8CACJ,MAAClC;oCAAMmC,MAAMjB;oCAAakB,cAAcZ;;sDACtC,KAACnB;4CAAagC,OAAO;sDACnB,cAAA,KAACvC;0DAAO;;;sDAEV,MAACI;4CAAaoC,oBAAkBC;;8DAC9B,KAACnC;oDAAWuB,WAAU;8DAAU;;8DAChC,KAACxB;8DACC,cAAA,KAACI;wDACCuB,MAAK;wDACLU,eAAY;wDACZb,WAAU;kEACX;;;gDAIFP,6BACC,KAACnB;oDAAU0B,WAAU;8DACnB,cAAA,KAACjB;wDAAoC+B,OAAOrB;;mEAG9C,KAACT;oDACCK,aAAaA;oDACb0B,WAAWrB;;;;;;;;;;gBAQtBJ,YAAYe,SAAS,iBAAG,KAAClB,4CAA0C;gBAEnEG,YAAY0B,OAAO,IAAI1B,YAAYM,IAAI,KAAKgB,0BAC3C,KAAC1C;oBAAe+C,OAAO3B;oBAAa4B,SAAQ;qBAC1C;gBAEH5B,YAAYM,IAAI,KAAKgB,aAAajB,OAAOwB,MAAM,KAAK,kBACnD,KAAClC,qCACC;gBAEHU,OAAOwB,MAAM,GAAG,kBACf,KAACjC;oBAA4BG,aAAaA;oBAAaM,QAAQA;qBAC7D;;;;AAIZ"}
1
+ {"version":3,"sources":["../../src/components/manual-registration-tokens-settings-section.tsx"],"sourcesContent":["import {QueryLoadError} from '@shipfox/client-ui';\nimport {Button} from '@shipfox/react-ui/button';\nimport {Icon} from '@shipfox/react-ui/icon';\nimport {\n Modal,\n ModalBody,\n ModalContent,\n ModalHeader,\n ModalTitle,\n ModalTrigger,\n} from '@shipfox/react-ui/modal';\nimport {Panel} from '@shipfox/react-ui/panel';\nimport {Header, Text} from '@shipfox/react-ui/typography';\nimport {useState} from 'react';\nimport type {CreatedManualRegistrationToken} from '#core/token.js';\nimport {useManualRegistrationTokensQuery} from '#hooks/api/manual-registration-tokens.js';\nimport {\n CreatedManualRegistrationTokenPanel,\n CreateManualRegistrationTokenForm,\n} from './create-manual-registration-token-form.js';\nimport {\n EmptyManualRegistrationTokens,\n ManualRegistrationTokenList,\n ManualRegistrationTokenTableSkeleton,\n} from './manual-registration-token-list.js';\n\nexport function WorkspaceManualRegistrationTokensSettingsSection({\n workspaceId,\n}: {\n workspaceId: string;\n}) {\n const tokensQuery = useManualRegistrationTokensQuery(workspaceId);\n const [isModalOpen, setIsModalOpen] = useState(false);\n const [createdToken, setCreatedToken] = useState<CreatedManualRegistrationToken | null>(null);\n const tokens = tokensQuery.data ?? [];\n\n function handleOpenChange(nextOpen: boolean) {\n setIsModalOpen(nextOpen);\n if (!nextOpen) {\n setCreatedToken(null);\n }\n }\n\n return (\n <div className=\"flex min-w-0 flex-col gap-region\">\n <section className=\"flex flex-col gap-group\">\n <div className=\"flex items-center justify-between gap-group max-[640px]:items-start\">\n <div className=\"flex flex-col gap-tight\">\n <Header variant=\"h3\">Runner registration tokens</Header>\n <Text size=\"sm\" className=\"text-foreground-neutral-muted\">\n Register individual runner agents that run jobs directly in this workspace. Tokens are\n reusable until revoked.\n </Text>\n </div>\n <div className=\"flex items-center gap-cluster\">\n {tokensQuery.isFetching && !tokensQuery.isPending ? (\n <Icon\n name=\"loader4Line\"\n className=\"mt-[2px] size-18 text-foreground-neutral-muted\"\n aria-label=\"Refreshing tokens\"\n />\n ) : null}\n <Modal open={isModalOpen} onOpenChange={handleOpenChange}>\n <ModalTrigger asChild>\n <Button>Create token</Button>\n </ModalTrigger>\n <ModalContent aria-describedby={undefined}>\n <ModalTitle className=\"sr-only\">Create manual registration token</ModalTitle>\n <ModalHeader>\n <Text\n size=\"lg\"\n aria-hidden=\"true\"\n className=\"overflow-ellipsis overflow-hidden whitespace-nowrap\"\n >\n Create manual registration token\n </Text>\n </ModalHeader>\n {createdToken ? (\n <ModalBody className=\"gap-group\">\n <CreatedManualRegistrationTokenPanel token={createdToken} />\n </ModalBody>\n ) : (\n <CreateManualRegistrationTokenForm\n workspaceId={workspaceId}\n onCreated={setCreatedToken}\n />\n )}\n </ModalContent>\n </Modal>\n </div>\n </div>\n\n {tokensQuery.isPending ? <ManualRegistrationTokenTableSkeleton /> : null}\n\n {tokensQuery.isError && tokensQuery.data === undefined ? (\n <Panel>\n <QueryLoadError\n query={tokensQuery}\n subject=\"manual registration tokens\"\n variant=\"panel\"\n />\n </Panel>\n ) : null}\n\n {tokensQuery.data !== undefined && tokens.length === 0 ? (\n <Panel>\n <EmptyManualRegistrationTokens />\n </Panel>\n ) : null}\n\n {tokens.length > 0 ? (\n <ManualRegistrationTokenList workspaceId={workspaceId} tokens={tokens} />\n ) : null}\n </section>\n </div>\n );\n}\n"],"names":["QueryLoadError","Button","Icon","Modal","ModalBody","ModalContent","ModalHeader","ModalTitle","ModalTrigger","Panel","Header","Text","useState","useManualRegistrationTokensQuery","CreatedManualRegistrationTokenPanel","CreateManualRegistrationTokenForm","EmptyManualRegistrationTokens","ManualRegistrationTokenList","ManualRegistrationTokenTableSkeleton","WorkspaceManualRegistrationTokensSettingsSection","workspaceId","tokensQuery","isModalOpen","setIsModalOpen","createdToken","setCreatedToken","tokens","data","handleOpenChange","nextOpen","div","className","section","variant","size","isFetching","isPending","name","aria-label","open","onOpenChange","asChild","aria-describedby","undefined","aria-hidden","token","onCreated","isError","query","subject","length"],"mappings":";AAAA,SAAQA,cAAc,QAAO,qBAAqB;AAClD,SAAQC,MAAM,QAAO,2BAA2B;AAChD,SAAQC,IAAI,QAAO,yBAAyB;AAC5C,SACEC,KAAK,EACLC,SAAS,EACTC,YAAY,EACZC,WAAW,EACXC,UAAU,EACVC,YAAY,QACP,0BAA0B;AACjC,SAAQC,KAAK,QAAO,0BAA0B;AAC9C,SAAQC,MAAM,EAAEC,IAAI,QAAO,+BAA+B;AAC1D,SAAQC,QAAQ,QAAO,QAAQ;AAE/B,SAAQC,gCAAgC,QAAO,2CAA2C;AAC1F,SACEC,mCAAmC,EACnCC,iCAAiC,QAC5B,6CAA6C;AACpD,SACEC,6BAA6B,EAC7BC,2BAA2B,EAC3BC,oCAAoC,QAC/B,sCAAsC;AAE7C,OAAO,SAASC,iDAAiD,EAC/DC,WAAW,EAGZ;IACC,MAAMC,cAAcR,iCAAiCO;IACrD,MAAM,CAACE,aAAaC,eAAe,GAAGX,SAAS;IAC/C,MAAM,CAACY,cAAcC,gBAAgB,GAAGb,SAAgD;IACxF,MAAMc,SAASL,YAAYM,IAAI,IAAI,EAAE;IAErC,SAASC,iBAAiBC,QAAiB;QACzCN,eAAeM;QACf,IAAI,CAACA,UAAU;YACbJ,gBAAgB;QAClB;IACF;IAEA,qBACE,KAACK;QAAIC,WAAU;kBACb,cAAA,MAACC;YAAQD,WAAU;;8BACjB,MAACD;oBAAIC,WAAU;;sCACb,MAACD;4BAAIC,WAAU;;8CACb,KAACrB;oCAAOuB,SAAQ;8CAAK;;8CACrB,KAACtB;oCAAKuB,MAAK;oCAAKH,WAAU;8CAAgC;;;;sCAK5D,MAACD;4BAAIC,WAAU;;gCACZV,YAAYc,UAAU,IAAI,CAACd,YAAYe,SAAS,iBAC/C,KAAClC;oCACCmC,MAAK;oCACLN,WAAU;oCACVO,cAAW;qCAEX;8CACJ,MAACnC;oCAAMoC,MAAMjB;oCAAakB,cAAcZ;;sDACtC,KAACpB;4CAAaiC,OAAO;sDACnB,cAAA,KAACxC;0DAAO;;;sDAEV,MAACI;4CAAaqC,oBAAkBC;;8DAC9B,KAACpC;oDAAWwB,WAAU;8DAAU;;8DAChC,KAACzB;8DACC,cAAA,KAACK;wDACCuB,MAAK;wDACLU,eAAY;wDACZb,WAAU;kEACX;;;gDAIFP,6BACC,KAACpB;oDAAU2B,WAAU;8DACnB,cAAA,KAACjB;wDAAoC+B,OAAOrB;;mEAG9C,KAACT;oDACCK,aAAaA;oDACb0B,WAAWrB;;;;;;;;;;gBAQtBJ,YAAYe,SAAS,iBAAG,KAAClB,4CAA0C;gBAEnEG,YAAY0B,OAAO,IAAI1B,YAAYM,IAAI,KAAKgB,0BAC3C,KAAClC;8BACC,cAAA,KAACT;wBACCgD,OAAO3B;wBACP4B,SAAQ;wBACRhB,SAAQ;;qBAGV;gBAEHZ,YAAYM,IAAI,KAAKgB,aAAajB,OAAOwB,MAAM,KAAK,kBACnD,KAACzC;8BACC,cAAA,KAACO;qBAED;gBAEHU,OAAOwB,MAAM,GAAG,kBACf,KAACjC;oBAA4BG,aAAaA;oBAAaM,QAAQA;qBAC7D;;;;AAIZ"}
@@ -1 +1 @@
1
- {"version":3,"file":"provisioner-token-list.d.ts","sourceRoot":"","sources":["../../src/components/provisioner-token-list.tsx"],"names":[],"mappings":"AA+BA,OAAO,EACL,KAAK,gBAAgB,EAGtB,MAAM,gBAAgB,CAAC;AAUxB,wBAAgB,oBAAoB,CAAC,EACnC,WAAW,EACX,MAAM,EACN,SAAS,GACV,EAAE;IACD,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAC3B,SAAS,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAChC,+BAmFA;AAqHD,wBAAgB,sBAAsB,gCAQrC;AAED,wBAAgB,6BAA6B,gCAQ5C"}
1
+ {"version":3,"file":"provisioner-token-list.d.ts","sourceRoot":"","sources":["../../src/components/provisioner-token-list.tsx"],"names":[],"mappings":"AA+BA,OAAO,EACL,KAAK,gBAAgB,EAGtB,MAAM,gBAAgB,CAAC;AAUxB,wBAAgB,oBAAoB,CAAC,EACnC,WAAW,EACX,MAAM,EACN,SAAS,GACV,EAAE;IACD,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAC3B,SAAS,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAChC,+BAmFA;AAqHD,wBAAgB,sBAAsB,gCASrC;AAED,wBAAgB,6BAA6B,gCAQ5C"}
@@ -18,9 +18,9 @@ import { formatProvisionerTokenDate, formatProvisionerTokenTimestamp } from './p
18
18
  import { TokenDate } from './token-date.js';
19
19
  import { TokenName } from './token-name.js';
20
20
  export function ProvisionerTokenList({ workspaceId, tokens, activeIds }) {
21
- return /*#__PURE__*/ _jsxs(_Fragment, {
21
+ return /*#__PURE__*/ _jsxs(Panel, {
22
22
  children: [
23
- /*#__PURE__*/ _jsx(Panel, {
23
+ /*#__PURE__*/ _jsx("div", {
24
24
  className: "max-[760px]:hidden",
25
25
  children: /*#__PURE__*/ _jsxs(Table, {
26
26
  className: "table-fixed",
@@ -99,10 +99,10 @@ export function ProvisionerTokenList({ workspaceId, tokens, activeIds }) {
99
99
  })
100
100
  }),
101
101
  /*#__PURE__*/ _jsx("ul", {
102
- className: "hidden flex-col gap-inline max-[760px]:flex",
102
+ className: "hidden flex-col divide-y divide-border-neutral-base max-[760px]:flex",
103
103
  "aria-label": "Provisioner tokens",
104
104
  children: tokens.map((token)=>/*#__PURE__*/ _jsxs("li", {
105
- className: "flex flex-col gap-cluster rounded-8 border border-border-neutral-base bg-background-neutral-base p-panel-compact",
105
+ className: "flex flex-col gap-cluster p-panel-compact",
106
106
  children: [
107
107
  /*#__PURE__*/ _jsxs("div", {
108
108
  className: "flex items-start justify-between gap-cluster",
@@ -314,20 +314,21 @@ export function EmptyProvisionerTokens() {
314
314
  return /*#__PURE__*/ _jsx(EmptyState, {
315
315
  icon: "key2Line",
316
316
  title: "No usable provisioner registration tokens",
317
- description: "Create a token to connect a provisioner that provisions runners on demand."
317
+ description: "Create a token to connect a provisioner that provisions runners on demand.",
318
+ variant: "panel"
318
319
  });
319
320
  }
320
321
  export function ProvisionerTokenTableSkeleton() {
321
- return /*#__PURE__*/ _jsx("div", {
322
+ return /*#__PURE__*/ _jsx(Panel, {
322
323
  role: "status",
323
324
  "aria-label": "Loading provisioner tokens",
324
- className: "flex flex-col gap-inline",
325
+ className: "divide-y",
325
326
  children: [
326
327
  0,
327
328
  1,
328
329
  2
329
330
  ].map((row)=>/*#__PURE__*/ _jsx(Skeleton, {
330
- className: "h-44 w-full"
331
+ className: "h-44 w-full rounded-none"
331
332
  }, row))
332
333
  });
333
334
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/provisioner-token-list.tsx"],"sourcesContent":["import {Button, IconButton} from '@shipfox/react-ui/button';\nimport {Callout} from '@shipfox/react-ui/callout';\nimport {Dot} from '@shipfox/react-ui/dot';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@shipfox/react-ui/dropdown-menu';\nimport {EmptyState} from '@shipfox/react-ui/empty-state';\nimport {\n Modal,\n ModalBody,\n ModalContent,\n ModalFooter,\n ModalHeader,\n ModalTitle,\n} from '@shipfox/react-ui/modal';\nimport {Panel} from '@shipfox/react-ui/panel';\nimport {RelativeTime} from '@shipfox/react-ui/relative-time';\nimport {Skeleton} from '@shipfox/react-ui/skeleton';\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@shipfox/react-ui/table';\nimport {Code, Text} from '@shipfox/react-ui/typography';\nimport {useState} from 'react';\nimport {\n type ProvisionerToken,\n provisionerConnectionStatus,\n provisionerTokenDisplayName,\n} from '#core/token.js';\nimport {useRevokeProvisionerTokenMutation} from '#hooks/api/provisioner-tokens.js';\nimport {provisionerTokenErrorMessage} from './provisioner-token-errors.js';\nimport {\n formatProvisionerTokenDate,\n formatProvisionerTokenTimestamp,\n} from './provisioner-token-format.js';\nimport {TokenDate} from './token-date.js';\nimport {TokenName} from './token-name.js';\n\nexport function ProvisionerTokenList({\n workspaceId,\n tokens,\n activeIds,\n}: {\n workspaceId: string;\n tokens: ProvisionerToken[];\n activeIds: ReadonlySet<string>;\n}) {\n return (\n <>\n <Panel className=\"max-[760px]:hidden\">\n <Table className=\"table-fixed\">\n <TableHeader>\n <TableRow>\n <TableHead className=\"w-[28%]\">Name</TableHead>\n <TableHead>Prefix</TableHead>\n <TableHead className=\"w-[18%]\">Status</TableHead>\n <TableHead className=\"w-112\">Expires</TableHead>\n <TableHead className=\"w-112\">Created</TableHead>\n <TableHead className=\"w-80 text-right\">Actions</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {tokens.map((token) => (\n <TableRow key={token.id}>\n <TableCell>\n <TokenName name={provisionerTokenDisplayName(token)} />\n </TableCell>\n <TableCell>\n <Code variant=\"paragraph\" className=\"block truncate\">\n {token.prefix}\n </Code>\n </TableCell>\n <TableCell>\n <ProvisionerStatusCell token={token} activeIds={activeIds} />\n </TableCell>\n <TableCell>\n <ProvisionerTokenDate value={token.expiresAt} />\n </TableCell>\n <TableCell>\n <ProvisionerTokenDate value={token.createdAt} />\n </TableCell>\n <TableCell className=\"text-right\">\n <RevokeProvisionerTokenButton workspaceId={workspaceId} token={token} />\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </Panel>\n <ul className=\"hidden flex-col gap-inline max-[760px]:flex\" aria-label=\"Provisioner tokens\">\n {tokens.map((token) => (\n <li\n key={token.id}\n className=\"flex flex-col gap-cluster rounded-8 border border-border-neutral-base bg-background-neutral-base p-panel-compact\"\n >\n <div className=\"flex items-start justify-between gap-cluster\">\n <div className=\"min-w-0 flex-1\">\n <TokenName name={provisionerTokenDisplayName(token)} />\n <Code variant=\"paragraph\" className=\"block truncate text-foreground-neutral-muted\">\n {token.prefix}\n </Code>\n </div>\n <RevokeProvisionerTokenButton workspaceId={workspaceId} token={token} />\n </div>\n <dl className=\"grid grid-cols-2 gap-inline text-sm\">\n <div>\n <dt className=\"text-foreground-neutral-muted\">Status</dt>\n <dd>\n <ProvisionerStatusCell token={token} activeIds={activeIds} />\n </dd>\n </div>\n <div>\n <dt className=\"text-foreground-neutral-muted\">Expires</dt>\n <dd>\n <ProvisionerTokenDate value={token.expiresAt} />\n </dd>\n </div>\n <div>\n <dt className=\"text-foreground-neutral-muted\">Created</dt>\n <dd>\n <ProvisionerTokenDate value={token.createdAt} />\n </dd>\n </div>\n </dl>\n </li>\n ))}\n </ul>\n </>\n );\n}\n\nfunction ProvisionerTokenDate({value}: {value: string | null}) {\n return (\n <TokenDate\n value={value}\n date={formatProvisionerTokenDate(value)}\n timestamp={formatProvisionerTokenTimestamp(value)}\n />\n );\n}\n\nfunction ProvisionerStatusCell({\n token,\n activeIds,\n}: {\n token: ProvisionerToken;\n activeIds: ReadonlySet<string>;\n}) {\n const status = provisionerConnectionStatus(token, activeIds);\n\n return (\n <span className=\"inline-flex items-center gap-inline\">\n <Dot variant={status.dotVariant} />\n {status.kind === 'last-seen' ? (\n <span>\n {status.label} <RelativeTime value={status.lastSeenAt} />\n </span>\n ) : (\n <span>{status.label}</span>\n )}\n </span>\n );\n}\n\nfunction RevokeProvisionerTokenButton({\n workspaceId,\n token,\n}: {\n workspaceId: string;\n token: ProvisionerToken;\n}) {\n const revokeToken = useRevokeProvisionerTokenMutation(workspaceId);\n const [open, setOpen] = useState(false);\n const tokenName = provisionerTokenDisplayName(token);\n\n async function handleRevoke() {\n try {\n await revokeToken.mutateAsync(token.id);\n setOpen(false);\n } catch {\n // React Query stores the error for the inline modal alert.\n }\n }\n\n function handleOpenChange(nextOpen: boolean) {\n setOpen(nextOpen);\n if (nextOpen) {\n revokeToken.reset();\n }\n }\n\n function openRevokeConfirmation() {\n revokeToken.reset();\n setOpen(true);\n }\n\n return (\n <>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <IconButton\n type=\"button\"\n size=\"sm\"\n variant=\"transparent\"\n icon=\"more2Line\"\n aria-label={`Open ${tokenName} token actions`}\n />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" size=\"sm\">\n <DropdownMenuItem onSelect={openRevokeConfirmation}>Revoke token</DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n <Modal open={open} onOpenChange={handleOpenChange}>\n <ModalContent aria-describedby={undefined} className=\"max-w-[420px]\">\n <ModalTitle className=\"sr-only\">Revoke token</ModalTitle>\n <ModalHeader title=\"Revoke token?\" />\n <ModalBody className=\"gap-group\">\n <Text size=\"sm\" className=\"text-foreground-neutral-muted\">\n {tokenName} will stop authenticating this provisioner. Runners it already provisioned\n keep running until their leases expire.\n </Text>\n {revokeToken.isError ? (\n <Callout role=\"alert\" type=\"error\">\n <Text size=\"sm\">{provisionerTokenErrorMessage(revokeToken.error)}</Text>\n </Callout>\n ) : null}\n </ModalBody>\n <ModalFooter>\n <Button size=\"sm\" variant=\"secondary\" onClick={() => setOpen(false)}>\n Cancel\n </Button>\n <Button\n size=\"sm\"\n variant=\"danger\"\n isLoading={revokeToken.isPending}\n onClick={handleRevoke}\n >\n Revoke\n </Button>\n </ModalFooter>\n </ModalContent>\n </Modal>\n </>\n );\n}\n\nexport function EmptyProvisionerTokens() {\n return (\n <EmptyState\n icon=\"key2Line\"\n title=\"No usable provisioner registration tokens\"\n description=\"Create a token to connect a provisioner that provisions runners on demand.\"\n />\n );\n}\n\nexport function ProvisionerTokenTableSkeleton() {\n return (\n <div role=\"status\" aria-label=\"Loading provisioner tokens\" className=\"flex flex-col gap-inline\">\n {[0, 1, 2].map((row) => (\n <Skeleton key={row} className=\"h-44 w-full\" />\n ))}\n </div>\n );\n}\n"],"names":["Button","IconButton","Callout","Dot","DropdownMenu","DropdownMenuContent","DropdownMenuItem","DropdownMenuTrigger","EmptyState","Modal","ModalBody","ModalContent","ModalFooter","ModalHeader","ModalTitle","Panel","RelativeTime","Skeleton","Table","TableBody","TableCell","TableHead","TableHeader","TableRow","Code","Text","useState","provisionerConnectionStatus","provisionerTokenDisplayName","useRevokeProvisionerTokenMutation","provisionerTokenErrorMessage","formatProvisionerTokenDate","formatProvisionerTokenTimestamp","TokenDate","TokenName","ProvisionerTokenList","workspaceId","tokens","activeIds","className","map","token","name","variant","prefix","ProvisionerStatusCell","ProvisionerTokenDate","value","expiresAt","createdAt","RevokeProvisionerTokenButton","id","ul","aria-label","li","div","dl","dt","dd","date","timestamp","status","span","dotVariant","kind","label","lastSeenAt","revokeToken","open","setOpen","tokenName","handleRevoke","mutateAsync","handleOpenChange","nextOpen","reset","openRevokeConfirmation","asChild","type","size","icon","align","onSelect","onOpenChange","aria-describedby","undefined","title","isError","role","error","onClick","isLoading","isPending","EmptyProvisionerTokens","description","ProvisionerTokenTableSkeleton","row"],"mappings":";AAAA,SAAQA,MAAM,EAAEC,UAAU,QAAO,2BAA2B;AAC5D,SAAQC,OAAO,QAAO,4BAA4B;AAClD,SAAQC,GAAG,QAAO,wBAAwB;AAC1C,SACEC,YAAY,EACZC,mBAAmB,EACnBC,gBAAgB,EAChBC,mBAAmB,QACd,kCAAkC;AACzC,SAAQC,UAAU,QAAO,gCAAgC;AACzD,SACEC,KAAK,EACLC,SAAS,EACTC,YAAY,EACZC,WAAW,EACXC,WAAW,EACXC,UAAU,QACL,0BAA0B;AACjC,SAAQC,KAAK,QAAO,0BAA0B;AAC9C,SAAQC,YAAY,QAAO,kCAAkC;AAC7D,SAAQC,QAAQ,QAAO,6BAA6B;AACpD,SACEC,KAAK,EACLC,SAAS,EACTC,SAAS,EACTC,SAAS,EACTC,WAAW,EACXC,QAAQ,QACH,0BAA0B;AACjC,SAAQC,IAAI,EAAEC,IAAI,QAAO,+BAA+B;AACxD,SAAQC,QAAQ,QAAO,QAAQ;AAC/B,SAEEC,2BAA2B,EAC3BC,2BAA2B,QACtB,iBAAiB;AACxB,SAAQC,iCAAiC,QAAO,mCAAmC;AACnF,SAAQC,4BAA4B,QAAO,gCAAgC;AAC3E,SACEC,0BAA0B,EAC1BC,+BAA+B,QAC1B,gCAAgC;AACvC,SAAQC,SAAS,QAAO,kBAAkB;AAC1C,SAAQC,SAAS,QAAO,kBAAkB;AAE1C,OAAO,SAASC,qBAAqB,EACnCC,WAAW,EACXC,MAAM,EACNC,SAAS,EAKV;IACC,qBACE;;0BACE,KAACvB;gBAAMwB,WAAU;0BACf,cAAA,MAACrB;oBAAMqB,WAAU;;sCACf,KAACjB;sCACC,cAAA,MAACC;;kDACC,KAACF;wCAAUkB,WAAU;kDAAU;;kDAC/B,KAAClB;kDAAU;;kDACX,KAACA;wCAAUkB,WAAU;kDAAU;;kDAC/B,KAAClB;wCAAUkB,WAAU;kDAAQ;;kDAC7B,KAAClB;wCAAUkB,WAAU;kDAAQ;;kDAC7B,KAAClB;wCAAUkB,WAAU;kDAAkB;;;;;sCAG3C,KAACpB;sCACEkB,OAAOG,GAAG,CAAC,CAACC,sBACX,MAAClB;;sDACC,KAACH;sDACC,cAAA,KAACc;gDAAUQ,MAAMd,4BAA4Ba;;;sDAE/C,KAACrB;sDACC,cAAA,KAACI;gDAAKmB,SAAQ;gDAAYJ,WAAU;0DACjCE,MAAMG,MAAM;;;sDAGjB,KAACxB;sDACC,cAAA,KAACyB;gDAAsBJ,OAAOA;gDAAOH,WAAWA;;;sDAElD,KAAClB;sDACC,cAAA,KAAC0B;gDAAqBC,OAAON,MAAMO,SAAS;;;sDAE9C,KAAC5B;sDACC,cAAA,KAAC0B;gDAAqBC,OAAON,MAAMQ,SAAS;;;sDAE9C,KAAC7B;4CAAUmB,WAAU;sDACnB,cAAA,KAACW;gDAA6Bd,aAAaA;gDAAaK,OAAOA;;;;mCAnBpDA,MAAMU,EAAE;;;;;0BA0B/B,KAACC;gBAAGb,WAAU;gBAA8Cc,cAAW;0BACpEhB,OAAOG,GAAG,CAAC,CAACC,sBACX,MAACa;wBAECf,WAAU;;0CAEV,MAACgB;gCAAIhB,WAAU;;kDACb,MAACgB;wCAAIhB,WAAU;;0DACb,KAACL;gDAAUQ,MAAMd,4BAA4Ba;;0DAC7C,KAACjB;gDAAKmB,SAAQ;gDAAYJ,WAAU;0DACjCE,MAAMG,MAAM;;;;kDAGjB,KAACM;wCAA6Bd,aAAaA;wCAAaK,OAAOA;;;;0CAEjE,MAACe;gCAAGjB,WAAU;;kDACZ,MAACgB;;0DACC,KAACE;gDAAGlB,WAAU;0DAAgC;;0DAC9C,KAACmB;0DACC,cAAA,KAACb;oDAAsBJ,OAAOA;oDAAOH,WAAWA;;;;;kDAGpD,MAACiB;;0DACC,KAACE;gDAAGlB,WAAU;0DAAgC;;0DAC9C,KAACmB;0DACC,cAAA,KAACZ;oDAAqBC,OAAON,MAAMO,SAAS;;;;;kDAGhD,MAACO;;0DACC,KAACE;gDAAGlB,WAAU;0DAAgC;;0DAC9C,KAACmB;0DACC,cAAA,KAACZ;oDAAqBC,OAAON,MAAMQ,SAAS;;;;;;;;uBA5B7CR,MAAMU,EAAE;;;;AAqCzB;AAEA,SAASL,qBAAqB,EAACC,KAAK,EAAyB;IAC3D,qBACE,KAACd;QACCc,OAAOA;QACPY,MAAM5B,2BAA2BgB;QACjCa,WAAW5B,gCAAgCe;;AAGjD;AAEA,SAASF,sBAAsB,EAC7BJ,KAAK,EACLH,SAAS,EAIV;IACC,MAAMuB,SAASlC,4BAA4Bc,OAAOH;IAElD,qBACE,MAACwB;QAAKvB,WAAU;;0BACd,KAACpC;gBAAIwC,SAASkB,OAAOE,UAAU;;YAC9BF,OAAOG,IAAI,KAAK,4BACf,MAACF;;oBACED,OAAOI,KAAK;oBAAC;kCAAC,KAACjD;wBAAa+B,OAAOc,OAAOK,UAAU;;;+BAGvD,KAACJ;0BAAMD,OAAOI,KAAK;;;;AAI3B;AAEA,SAASf,6BAA6B,EACpCd,WAAW,EACXK,KAAK,EAIN;IACC,MAAM0B,cAActC,kCAAkCO;IACtD,MAAM,CAACgC,MAAMC,QAAQ,GAAG3C,SAAS;IACjC,MAAM4C,YAAY1C,4BAA4Ba;IAE9C,eAAe8B;QACb,IAAI;YACF,MAAMJ,YAAYK,WAAW,CAAC/B,MAAMU,EAAE;YACtCkB,QAAQ;QACV,EAAE,OAAM;QACN,2DAA2D;QAC7D;IACF;IAEA,SAASI,iBAAiBC,QAAiB;QACzCL,QAAQK;QACR,IAAIA,UAAU;YACZP,YAAYQ,KAAK;QACnB;IACF;IAEA,SAASC;QACPT,YAAYQ,KAAK;QACjBN,QAAQ;IACV;IAEA,qBACE;;0BACE,MAACjE;;kCACC,KAACG;wBAAoBsE,OAAO;kCAC1B,cAAA,KAAC5E;4BACC6E,MAAK;4BACLC,MAAK;4BACLpC,SAAQ;4BACRqC,MAAK;4BACL3B,cAAY,CAAC,KAAK,EAAEiB,UAAU,cAAc,CAAC;;;kCAGjD,KAACjE;wBAAoB4E,OAAM;wBAAMF,MAAK;kCACpC,cAAA,KAACzE;4BAAiB4E,UAAUN;sCAAwB;;;;;0BAGxD,KAACnE;gBAAM2D,MAAMA;gBAAMe,cAAcV;0BAC/B,cAAA,MAAC9D;oBAAayE,oBAAkBC;oBAAW9C,WAAU;;sCACnD,KAACzB;4BAAWyB,WAAU;sCAAU;;sCAChC,KAAC1B;4BAAYyE,OAAM;;sCACnB,MAAC5E;4BAAU6B,WAAU;;8CACnB,MAACd;oCAAKsD,MAAK;oCAAKxC,WAAU;;wCACvB+B;wCAAU;;;gCAGZH,YAAYoB,OAAO,iBAClB,KAACrF;oCAAQsF,MAAK;oCAAQV,MAAK;8CACzB,cAAA,KAACrD;wCAAKsD,MAAK;kDAAMjD,6BAA6BqC,YAAYsB,KAAK;;qCAE/D;;;sCAEN,MAAC7E;;8CACC,KAACZ;oCAAO+E,MAAK;oCAAKpC,SAAQ;oCAAY+C,SAAS,IAAMrB,QAAQ;8CAAQ;;8CAGrE,KAACrE;oCACC+E,MAAK;oCACLpC,SAAQ;oCACRgD,WAAWxB,YAAYyB,SAAS;oCAChCF,SAASnB;8CACV;;;;;;;;;AAQb;AAEA,OAAO,SAASsB;IACd,qBACE,KAACrF;QACCwE,MAAK;QACLM,OAAM;QACNQ,aAAY;;AAGlB;AAEA,OAAO,SAASC;IACd,qBACE,KAACxC;QAAIiC,MAAK;QAASnC,cAAW;QAA6Bd,WAAU;kBAClE;YAAC;YAAG;YAAG;SAAE,CAACC,GAAG,CAAC,CAACwD,oBACd,KAAC/E;gBAAmBsB,WAAU;eAAfyD;;AAIvB"}
1
+ {"version":3,"sources":["../../src/components/provisioner-token-list.tsx"],"sourcesContent":["import {Button, IconButton} from '@shipfox/react-ui/button';\nimport {Callout} from '@shipfox/react-ui/callout';\nimport {Dot} from '@shipfox/react-ui/dot';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@shipfox/react-ui/dropdown-menu';\nimport {EmptyState} from '@shipfox/react-ui/empty-state';\nimport {\n Modal,\n ModalBody,\n ModalContent,\n ModalFooter,\n ModalHeader,\n ModalTitle,\n} from '@shipfox/react-ui/modal';\nimport {Panel} from '@shipfox/react-ui/panel';\nimport {RelativeTime} from '@shipfox/react-ui/relative-time';\nimport {Skeleton} from '@shipfox/react-ui/skeleton';\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@shipfox/react-ui/table';\nimport {Code, Text} from '@shipfox/react-ui/typography';\nimport {useState} from 'react';\nimport {\n type ProvisionerToken,\n provisionerConnectionStatus,\n provisionerTokenDisplayName,\n} from '#core/token.js';\nimport {useRevokeProvisionerTokenMutation} from '#hooks/api/provisioner-tokens.js';\nimport {provisionerTokenErrorMessage} from './provisioner-token-errors.js';\nimport {\n formatProvisionerTokenDate,\n formatProvisionerTokenTimestamp,\n} from './provisioner-token-format.js';\nimport {TokenDate} from './token-date.js';\nimport {TokenName} from './token-name.js';\n\nexport function ProvisionerTokenList({\n workspaceId,\n tokens,\n activeIds,\n}: {\n workspaceId: string;\n tokens: ProvisionerToken[];\n activeIds: ReadonlySet<string>;\n}) {\n return (\n <Panel>\n <div className=\"max-[760px]:hidden\">\n <Table className=\"table-fixed\">\n <TableHeader>\n <TableRow>\n <TableHead className=\"w-[28%]\">Name</TableHead>\n <TableHead>Prefix</TableHead>\n <TableHead className=\"w-[18%]\">Status</TableHead>\n <TableHead className=\"w-112\">Expires</TableHead>\n <TableHead className=\"w-112\">Created</TableHead>\n <TableHead className=\"w-80 text-right\">Actions</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {tokens.map((token) => (\n <TableRow key={token.id}>\n <TableCell>\n <TokenName name={provisionerTokenDisplayName(token)} />\n </TableCell>\n <TableCell>\n <Code variant=\"paragraph\" className=\"block truncate\">\n {token.prefix}\n </Code>\n </TableCell>\n <TableCell>\n <ProvisionerStatusCell token={token} activeIds={activeIds} />\n </TableCell>\n <TableCell>\n <ProvisionerTokenDate value={token.expiresAt} />\n </TableCell>\n <TableCell>\n <ProvisionerTokenDate value={token.createdAt} />\n </TableCell>\n <TableCell className=\"text-right\">\n <RevokeProvisionerTokenButton workspaceId={workspaceId} token={token} />\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n <ul\n className=\"hidden flex-col divide-y divide-border-neutral-base max-[760px]:flex\"\n aria-label=\"Provisioner tokens\"\n >\n {tokens.map((token) => (\n <li key={token.id} className=\"flex flex-col gap-cluster p-panel-compact\">\n <div className=\"flex items-start justify-between gap-cluster\">\n <div className=\"min-w-0 flex-1\">\n <TokenName name={provisionerTokenDisplayName(token)} />\n <Code variant=\"paragraph\" className=\"block truncate text-foreground-neutral-muted\">\n {token.prefix}\n </Code>\n </div>\n <RevokeProvisionerTokenButton workspaceId={workspaceId} token={token} />\n </div>\n <dl className=\"grid grid-cols-2 gap-inline text-sm\">\n <div>\n <dt className=\"text-foreground-neutral-muted\">Status</dt>\n <dd>\n <ProvisionerStatusCell token={token} activeIds={activeIds} />\n </dd>\n </div>\n <div>\n <dt className=\"text-foreground-neutral-muted\">Expires</dt>\n <dd>\n <ProvisionerTokenDate value={token.expiresAt} />\n </dd>\n </div>\n <div>\n <dt className=\"text-foreground-neutral-muted\">Created</dt>\n <dd>\n <ProvisionerTokenDate value={token.createdAt} />\n </dd>\n </div>\n </dl>\n </li>\n ))}\n </ul>\n </Panel>\n );\n}\n\nfunction ProvisionerTokenDate({value}: {value: string | null}) {\n return (\n <TokenDate\n value={value}\n date={formatProvisionerTokenDate(value)}\n timestamp={formatProvisionerTokenTimestamp(value)}\n />\n );\n}\n\nfunction ProvisionerStatusCell({\n token,\n activeIds,\n}: {\n token: ProvisionerToken;\n activeIds: ReadonlySet<string>;\n}) {\n const status = provisionerConnectionStatus(token, activeIds);\n\n return (\n <span className=\"inline-flex items-center gap-inline\">\n <Dot variant={status.dotVariant} />\n {status.kind === 'last-seen' ? (\n <span>\n {status.label} <RelativeTime value={status.lastSeenAt} />\n </span>\n ) : (\n <span>{status.label}</span>\n )}\n </span>\n );\n}\n\nfunction RevokeProvisionerTokenButton({\n workspaceId,\n token,\n}: {\n workspaceId: string;\n token: ProvisionerToken;\n}) {\n const revokeToken = useRevokeProvisionerTokenMutation(workspaceId);\n const [open, setOpen] = useState(false);\n const tokenName = provisionerTokenDisplayName(token);\n\n async function handleRevoke() {\n try {\n await revokeToken.mutateAsync(token.id);\n setOpen(false);\n } catch {\n // React Query stores the error for the inline modal alert.\n }\n }\n\n function handleOpenChange(nextOpen: boolean) {\n setOpen(nextOpen);\n if (nextOpen) {\n revokeToken.reset();\n }\n }\n\n function openRevokeConfirmation() {\n revokeToken.reset();\n setOpen(true);\n }\n\n return (\n <>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <IconButton\n type=\"button\"\n size=\"sm\"\n variant=\"transparent\"\n icon=\"more2Line\"\n aria-label={`Open ${tokenName} token actions`}\n />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" size=\"sm\">\n <DropdownMenuItem onSelect={openRevokeConfirmation}>Revoke token</DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n <Modal open={open} onOpenChange={handleOpenChange}>\n <ModalContent aria-describedby={undefined} className=\"max-w-[420px]\">\n <ModalTitle className=\"sr-only\">Revoke token</ModalTitle>\n <ModalHeader title=\"Revoke token?\" />\n <ModalBody className=\"gap-group\">\n <Text size=\"sm\" className=\"text-foreground-neutral-muted\">\n {tokenName} will stop authenticating this provisioner. Runners it already provisioned\n keep running until their leases expire.\n </Text>\n {revokeToken.isError ? (\n <Callout role=\"alert\" type=\"error\">\n <Text size=\"sm\">{provisionerTokenErrorMessage(revokeToken.error)}</Text>\n </Callout>\n ) : null}\n </ModalBody>\n <ModalFooter>\n <Button size=\"sm\" variant=\"secondary\" onClick={() => setOpen(false)}>\n Cancel\n </Button>\n <Button\n size=\"sm\"\n variant=\"danger\"\n isLoading={revokeToken.isPending}\n onClick={handleRevoke}\n >\n Revoke\n </Button>\n </ModalFooter>\n </ModalContent>\n </Modal>\n </>\n );\n}\n\nexport function EmptyProvisionerTokens() {\n return (\n <EmptyState\n icon=\"key2Line\"\n title=\"No usable provisioner registration tokens\"\n description=\"Create a token to connect a provisioner that provisions runners on demand.\"\n variant=\"panel\"\n />\n );\n}\n\nexport function ProvisionerTokenTableSkeleton() {\n return (\n <Panel role=\"status\" aria-label=\"Loading provisioner tokens\" className=\"divide-y\">\n {[0, 1, 2].map((row) => (\n <Skeleton key={row} className=\"h-44 w-full rounded-none\" />\n ))}\n </Panel>\n );\n}\n"],"names":["Button","IconButton","Callout","Dot","DropdownMenu","DropdownMenuContent","DropdownMenuItem","DropdownMenuTrigger","EmptyState","Modal","ModalBody","ModalContent","ModalFooter","ModalHeader","ModalTitle","Panel","RelativeTime","Skeleton","Table","TableBody","TableCell","TableHead","TableHeader","TableRow","Code","Text","useState","provisionerConnectionStatus","provisionerTokenDisplayName","useRevokeProvisionerTokenMutation","provisionerTokenErrorMessage","formatProvisionerTokenDate","formatProvisionerTokenTimestamp","TokenDate","TokenName","ProvisionerTokenList","workspaceId","tokens","activeIds","div","className","map","token","name","variant","prefix","ProvisionerStatusCell","ProvisionerTokenDate","value","expiresAt","createdAt","RevokeProvisionerTokenButton","id","ul","aria-label","li","dl","dt","dd","date","timestamp","status","span","dotVariant","kind","label","lastSeenAt","revokeToken","open","setOpen","tokenName","handleRevoke","mutateAsync","handleOpenChange","nextOpen","reset","openRevokeConfirmation","asChild","type","size","icon","align","onSelect","onOpenChange","aria-describedby","undefined","title","isError","role","error","onClick","isLoading","isPending","EmptyProvisionerTokens","description","ProvisionerTokenTableSkeleton","row"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"provisioner-tokens-settings-section.d.ts","sourceRoot":"","sources":["../../src/components/provisioner-tokens-settings-section.tsx"],"names":[],"mappings":"AA6BA,wBAAgB,yCAAyC,CAAC,EAAC,WAAW,EAAC,EAAE;IAAC,WAAW,EAAE,MAAM,CAAA;CAAC,+BAoF7F"}
1
+ {"version":3,"file":"provisioner-tokens-settings-section.d.ts","sourceRoot":"","sources":["../../src/components/provisioner-tokens-settings-section.tsx"],"names":[],"mappings":"AA8BA,wBAAgB,yCAAyC,CAAC,EAAC,WAAW,EAAC,EAAE;IAAC,WAAW,EAAE,MAAM,CAAA;CAAC,+BA8F7F"}
@@ -3,6 +3,7 @@ import { QueryLoadError } from '@shipfox/client-ui';
3
3
  import { Button } from '@shipfox/react-ui/button';
4
4
  import { Icon } from '@shipfox/react-ui/icon';
5
5
  import { Modal, ModalBody, ModalContent, ModalHeader, ModalTitle, ModalTrigger } from '@shipfox/react-ui/modal';
6
+ import { Panel } from '@shipfox/react-ui/panel';
6
7
  import { RelativeTimeProvider } from '@shipfox/react-ui/relative-time';
7
8
  import { Header, Text } from '@shipfox/react-ui/typography';
8
9
  import { useMemo, useState } from 'react';
@@ -97,11 +98,16 @@ export function WorkspaceProvisionerTokensSettingsSection({ workspaceId }) {
97
98
  ]
98
99
  }),
99
100
  tokensQuery.isPending ? /*#__PURE__*/ _jsx(ProvisionerTokenTableSkeleton, {}) : null,
100
- tokensQuery.isError && tokensQuery.data === undefined ? /*#__PURE__*/ _jsx(QueryLoadError, {
101
- query: tokensQuery,
102
- subject: "provisioner registration tokens"
101
+ tokensQuery.isError && tokensQuery.data === undefined ? /*#__PURE__*/ _jsx(Panel, {
102
+ children: /*#__PURE__*/ _jsx(QueryLoadError, {
103
+ query: tokensQuery,
104
+ subject: "provisioner registration tokens",
105
+ variant: "panel"
106
+ })
107
+ }) : null,
108
+ tokensQuery.data !== undefined && tokens.length === 0 ? /*#__PURE__*/ _jsx(Panel, {
109
+ children: /*#__PURE__*/ _jsx(EmptyProvisionerTokens, {})
103
110
  }) : null,
104
- tokensQuery.data !== undefined && tokens.length === 0 ? /*#__PURE__*/ _jsx(EmptyProvisionerTokens, {}) : null,
105
111
  tokens.length > 0 ? /*#__PURE__*/ _jsx(RelativeTimeProvider, {
106
112
  children: /*#__PURE__*/ _jsx(ProvisionerTokenList, {
107
113
  workspaceId: workspaceId,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/provisioner-tokens-settings-section.tsx"],"sourcesContent":["import {QueryLoadError} from '@shipfox/client-ui';\nimport {Button} from '@shipfox/react-ui/button';\nimport {Icon} from '@shipfox/react-ui/icon';\nimport {\n Modal,\n ModalBody,\n ModalContent,\n ModalHeader,\n ModalTitle,\n ModalTrigger,\n} from '@shipfox/react-ui/modal';\nimport {RelativeTimeProvider} from '@shipfox/react-ui/relative-time';\nimport {Header, Text} from '@shipfox/react-ui/typography';\nimport {useMemo, useState} from 'react';\nimport type {CreatedProvisionerToken} from '#core/token.js';\nimport {\n useActiveProvisionersQuery,\n useProvisionerTokensQuery,\n} from '#hooks/api/provisioner-tokens.js';\nimport {\n CreatedProvisionerTokenPanel,\n CreateProvisionerTokenForm,\n} from './create-provisioner-token-form.js';\nimport {\n EmptyProvisionerTokens,\n ProvisionerTokenList,\n ProvisionerTokenTableSkeleton,\n} from './provisioner-token-list.js';\n\nexport function WorkspaceProvisionerTokensSettingsSection({workspaceId}: {workspaceId: string}) {\n const tokensQuery = useProvisionerTokensQuery(workspaceId);\n const activeProvisionersQuery = useActiveProvisionersQuery(workspaceId);\n const [isModalOpen, setIsModalOpen] = useState(false);\n const [createdToken, setCreatedToken] = useState<CreatedProvisionerToken | null>(null);\n const tokens = tokensQuery.data ?? [];\n const activeIds = useMemo(\n () => new Set(activeProvisionersQuery.data?.map((provisioner) => provisioner.id)),\n [activeProvisionersQuery.data],\n );\n\n function handleOpenChange(nextOpen: boolean) {\n setIsModalOpen(nextOpen);\n if (!nextOpen) {\n setCreatedToken(null);\n }\n }\n\n return (\n <div className=\"flex min-w-0 flex-col gap-region\">\n <section className=\"flex flex-col gap-group\">\n <div className=\"flex items-center justify-between gap-group max-[640px]:items-start\">\n <div className=\"flex flex-col gap-tight\">\n <Header variant=\"h3\">Runner provisioner registration tokens</Header>\n <Text size=\"sm\" className=\"text-foreground-neutral-muted\">\n Register runner provisioners that connect to this workspace and create runners\n dynamically based on demand.\n </Text>\n </div>\n <div className=\"flex items-center gap-cluster\">\n {(tokensQuery.isFetching && !tokensQuery.isPending) ||\n (activeProvisionersQuery.isFetching && !activeProvisionersQuery.isPending) ? (\n <Icon\n name=\"loader4Line\"\n className=\"mt-[2px] size-18 text-foreground-neutral-muted\"\n aria-label=\"Refreshing provisioner tokens\"\n />\n ) : null}\n <Modal open={isModalOpen} onOpenChange={handleOpenChange}>\n <ModalTrigger asChild>\n <Button>Create token</Button>\n </ModalTrigger>\n <ModalContent aria-describedby={undefined}>\n <ModalTitle className=\"sr-only\">Create provisioner registration token</ModalTitle>\n <ModalHeader>\n <Text\n size=\"lg\"\n aria-hidden=\"true\"\n className=\"overflow-ellipsis overflow-hidden whitespace-nowrap\"\n >\n Create provisioner registration token\n </Text>\n </ModalHeader>\n {createdToken ? (\n <ModalBody className=\"gap-group\">\n <CreatedProvisionerTokenPanel token={createdToken} />\n </ModalBody>\n ) : (\n <CreateProvisionerTokenForm\n workspaceId={workspaceId}\n onCreated={setCreatedToken}\n />\n )}\n </ModalContent>\n </Modal>\n </div>\n </div>\n\n {tokensQuery.isPending ? <ProvisionerTokenTableSkeleton /> : null}\n\n {tokensQuery.isError && tokensQuery.data === undefined ? (\n <QueryLoadError query={tokensQuery} subject=\"provisioner registration tokens\" />\n ) : null}\n\n {tokensQuery.data !== undefined && tokens.length === 0 ? <EmptyProvisionerTokens /> : null}\n\n {tokens.length > 0 ? (\n <RelativeTimeProvider>\n <ProvisionerTokenList workspaceId={workspaceId} tokens={tokens} activeIds={activeIds} />\n </RelativeTimeProvider>\n ) : null}\n </section>\n </div>\n );\n}\n"],"names":["QueryLoadError","Button","Icon","Modal","ModalBody","ModalContent","ModalHeader","ModalTitle","ModalTrigger","RelativeTimeProvider","Header","Text","useMemo","useState","useActiveProvisionersQuery","useProvisionerTokensQuery","CreatedProvisionerTokenPanel","CreateProvisionerTokenForm","EmptyProvisionerTokens","ProvisionerTokenList","ProvisionerTokenTableSkeleton","WorkspaceProvisionerTokensSettingsSection","workspaceId","tokensQuery","activeProvisionersQuery","isModalOpen","setIsModalOpen","createdToken","setCreatedToken","tokens","data","activeIds","Set","map","provisioner","id","handleOpenChange","nextOpen","div","className","section","variant","size","isFetching","isPending","name","aria-label","open","onOpenChange","asChild","aria-describedby","undefined","aria-hidden","token","onCreated","isError","query","subject","length"],"mappings":";AAAA,SAAQA,cAAc,QAAO,qBAAqB;AAClD,SAAQC,MAAM,QAAO,2BAA2B;AAChD,SAAQC,IAAI,QAAO,yBAAyB;AAC5C,SACEC,KAAK,EACLC,SAAS,EACTC,YAAY,EACZC,WAAW,EACXC,UAAU,EACVC,YAAY,QACP,0BAA0B;AACjC,SAAQC,oBAAoB,QAAO,kCAAkC;AACrE,SAAQC,MAAM,EAAEC,IAAI,QAAO,+BAA+B;AAC1D,SAAQC,OAAO,EAAEC,QAAQ,QAAO,QAAQ;AAExC,SACEC,0BAA0B,EAC1BC,yBAAyB,QACpB,mCAAmC;AAC1C,SACEC,4BAA4B,EAC5BC,0BAA0B,QACrB,qCAAqC;AAC5C,SACEC,sBAAsB,EACtBC,oBAAoB,EACpBC,6BAA6B,QACxB,8BAA8B;AAErC,OAAO,SAASC,0CAA0C,EAACC,WAAW,EAAwB;IAC5F,MAAMC,cAAcR,0BAA0BO;IAC9C,MAAME,0BAA0BV,2BAA2BQ;IAC3D,MAAM,CAACG,aAAaC,eAAe,GAAGb,SAAS;IAC/C,MAAM,CAACc,cAAcC,gBAAgB,GAAGf,SAAyC;IACjF,MAAMgB,SAASN,YAAYO,IAAI,IAAI,EAAE;IACrC,MAAMC,YAAYnB,QAChB,IAAM,IAAIoB,IAAIR,wBAAwBM,IAAI,EAAEG,IAAI,CAACC,cAAgBA,YAAYC,EAAE,IAC/E;QAACX,wBAAwBM,IAAI;KAAC;IAGhC,SAASM,iBAAiBC,QAAiB;QACzCX,eAAeW;QACf,IAAI,CAACA,UAAU;YACbT,gBAAgB;QAClB;IACF;IAEA,qBACE,KAACU;QAAIC,WAAU;kBACb,cAAA,MAACC;YAAQD,WAAU;;8BACjB,MAACD;oBAAIC,WAAU;;sCACb,MAACD;4BAAIC,WAAU;;8CACb,KAAC7B;oCAAO+B,SAAQ;8CAAK;;8CACrB,KAAC9B;oCAAK+B,MAAK;oCAAKH,WAAU;8CAAgC;;;;sCAK5D,MAACD;4BAAIC,WAAU;;gCACXhB,YAAYoB,UAAU,IAAI,CAACpB,YAAYqB,SAAS,IACjDpB,wBAAwBmB,UAAU,IAAI,CAACnB,wBAAwBoB,SAAS,iBACvE,KAAC1C;oCACC2C,MAAK;oCACLN,WAAU;oCACVO,cAAW;qCAEX;8CACJ,MAAC3C;oCAAM4C,MAAMtB;oCAAauB,cAAcZ;;sDACtC,KAAC5B;4CAAayC,OAAO;sDACnB,cAAA,KAAChD;0DAAO;;;sDAEV,MAACI;4CAAa6C,oBAAkBC;;8DAC9B,KAAC5C;oDAAWgC,WAAU;8DAAU;;8DAChC,KAACjC;8DACC,cAAA,KAACK;wDACC+B,MAAK;wDACLU,eAAY;wDACZb,WAAU;kEACX;;;gDAIFZ,6BACC,KAACvB;oDAAUmC,WAAU;8DACnB,cAAA,KAACvB;wDAA6BqC,OAAO1B;;mEAGvC,KAACV;oDACCK,aAAaA;oDACbgC,WAAW1B;;;;;;;;;;gBAQtBL,YAAYqB,SAAS,iBAAG,KAACxB,qCAAmC;gBAE5DG,YAAYgC,OAAO,IAAIhC,YAAYO,IAAI,KAAKqB,0BAC3C,KAACnD;oBAAewD,OAAOjC;oBAAakC,SAAQ;qBAC1C;gBAEHlC,YAAYO,IAAI,KAAKqB,aAAatB,OAAO6B,MAAM,KAAK,kBAAI,KAACxC,8BAA4B;gBAErFW,OAAO6B,MAAM,GAAG,kBACf,KAACjD;8BACC,cAAA,KAACU;wBAAqBG,aAAaA;wBAAaO,QAAQA;wBAAQE,WAAWA;;qBAE3E;;;;AAIZ"}
1
+ {"version":3,"sources":["../../src/components/provisioner-tokens-settings-section.tsx"],"sourcesContent":["import {QueryLoadError} from '@shipfox/client-ui';\nimport {Button} from '@shipfox/react-ui/button';\nimport {Icon} from '@shipfox/react-ui/icon';\nimport {\n Modal,\n ModalBody,\n ModalContent,\n ModalHeader,\n ModalTitle,\n ModalTrigger,\n} from '@shipfox/react-ui/modal';\nimport {Panel} from '@shipfox/react-ui/panel';\nimport {RelativeTimeProvider} from '@shipfox/react-ui/relative-time';\nimport {Header, Text} from '@shipfox/react-ui/typography';\nimport {useMemo, useState} from 'react';\nimport type {CreatedProvisionerToken} from '#core/token.js';\nimport {\n useActiveProvisionersQuery,\n useProvisionerTokensQuery,\n} from '#hooks/api/provisioner-tokens.js';\nimport {\n CreatedProvisionerTokenPanel,\n CreateProvisionerTokenForm,\n} from './create-provisioner-token-form.js';\nimport {\n EmptyProvisionerTokens,\n ProvisionerTokenList,\n ProvisionerTokenTableSkeleton,\n} from './provisioner-token-list.js';\n\nexport function WorkspaceProvisionerTokensSettingsSection({workspaceId}: {workspaceId: string}) {\n const tokensQuery = useProvisionerTokensQuery(workspaceId);\n const activeProvisionersQuery = useActiveProvisionersQuery(workspaceId);\n const [isModalOpen, setIsModalOpen] = useState(false);\n const [createdToken, setCreatedToken] = useState<CreatedProvisionerToken | null>(null);\n const tokens = tokensQuery.data ?? [];\n const activeIds = useMemo(\n () => new Set(activeProvisionersQuery.data?.map((provisioner) => provisioner.id)),\n [activeProvisionersQuery.data],\n );\n\n function handleOpenChange(nextOpen: boolean) {\n setIsModalOpen(nextOpen);\n if (!nextOpen) {\n setCreatedToken(null);\n }\n }\n\n return (\n <div className=\"flex min-w-0 flex-col gap-region\">\n <section className=\"flex flex-col gap-group\">\n <div className=\"flex items-center justify-between gap-group max-[640px]:items-start\">\n <div className=\"flex flex-col gap-tight\">\n <Header variant=\"h3\">Runner provisioner registration tokens</Header>\n <Text size=\"sm\" className=\"text-foreground-neutral-muted\">\n Register runner provisioners that connect to this workspace and create runners\n dynamically based on demand.\n </Text>\n </div>\n <div className=\"flex items-center gap-cluster\">\n {(tokensQuery.isFetching && !tokensQuery.isPending) ||\n (activeProvisionersQuery.isFetching && !activeProvisionersQuery.isPending) ? (\n <Icon\n name=\"loader4Line\"\n className=\"mt-[2px] size-18 text-foreground-neutral-muted\"\n aria-label=\"Refreshing provisioner tokens\"\n />\n ) : null}\n <Modal open={isModalOpen} onOpenChange={handleOpenChange}>\n <ModalTrigger asChild>\n <Button>Create token</Button>\n </ModalTrigger>\n <ModalContent aria-describedby={undefined}>\n <ModalTitle className=\"sr-only\">Create provisioner registration token</ModalTitle>\n <ModalHeader>\n <Text\n size=\"lg\"\n aria-hidden=\"true\"\n className=\"overflow-ellipsis overflow-hidden whitespace-nowrap\"\n >\n Create provisioner registration token\n </Text>\n </ModalHeader>\n {createdToken ? (\n <ModalBody className=\"gap-group\">\n <CreatedProvisionerTokenPanel token={createdToken} />\n </ModalBody>\n ) : (\n <CreateProvisionerTokenForm\n workspaceId={workspaceId}\n onCreated={setCreatedToken}\n />\n )}\n </ModalContent>\n </Modal>\n </div>\n </div>\n\n {tokensQuery.isPending ? <ProvisionerTokenTableSkeleton /> : null}\n\n {tokensQuery.isError && tokensQuery.data === undefined ? (\n <Panel>\n <QueryLoadError\n query={tokensQuery}\n subject=\"provisioner registration tokens\"\n variant=\"panel\"\n />\n </Panel>\n ) : null}\n\n {tokensQuery.data !== undefined && tokens.length === 0 ? (\n <Panel>\n <EmptyProvisionerTokens />\n </Panel>\n ) : null}\n\n {tokens.length > 0 ? (\n <RelativeTimeProvider>\n <ProvisionerTokenList workspaceId={workspaceId} tokens={tokens} activeIds={activeIds} />\n </RelativeTimeProvider>\n ) : null}\n </section>\n </div>\n );\n}\n"],"names":["QueryLoadError","Button","Icon","Modal","ModalBody","ModalContent","ModalHeader","ModalTitle","ModalTrigger","Panel","RelativeTimeProvider","Header","Text","useMemo","useState","useActiveProvisionersQuery","useProvisionerTokensQuery","CreatedProvisionerTokenPanel","CreateProvisionerTokenForm","EmptyProvisionerTokens","ProvisionerTokenList","ProvisionerTokenTableSkeleton","WorkspaceProvisionerTokensSettingsSection","workspaceId","tokensQuery","activeProvisionersQuery","isModalOpen","setIsModalOpen","createdToken","setCreatedToken","tokens","data","activeIds","Set","map","provisioner","id","handleOpenChange","nextOpen","div","className","section","variant","size","isFetching","isPending","name","aria-label","open","onOpenChange","asChild","aria-describedby","undefined","aria-hidden","token","onCreated","isError","query","subject","length"],"mappings":";AAAA,SAAQA,cAAc,QAAO,qBAAqB;AAClD,SAAQC,MAAM,QAAO,2BAA2B;AAChD,SAAQC,IAAI,QAAO,yBAAyB;AAC5C,SACEC,KAAK,EACLC,SAAS,EACTC,YAAY,EACZC,WAAW,EACXC,UAAU,EACVC,YAAY,QACP,0BAA0B;AACjC,SAAQC,KAAK,QAAO,0BAA0B;AAC9C,SAAQC,oBAAoB,QAAO,kCAAkC;AACrE,SAAQC,MAAM,EAAEC,IAAI,QAAO,+BAA+B;AAC1D,SAAQC,OAAO,EAAEC,QAAQ,QAAO,QAAQ;AAExC,SACEC,0BAA0B,EAC1BC,yBAAyB,QACpB,mCAAmC;AAC1C,SACEC,4BAA4B,EAC5BC,0BAA0B,QACrB,qCAAqC;AAC5C,SACEC,sBAAsB,EACtBC,oBAAoB,EACpBC,6BAA6B,QACxB,8BAA8B;AAErC,OAAO,SAASC,0CAA0C,EAACC,WAAW,EAAwB;IAC5F,MAAMC,cAAcR,0BAA0BO;IAC9C,MAAME,0BAA0BV,2BAA2BQ;IAC3D,MAAM,CAACG,aAAaC,eAAe,GAAGb,SAAS;IAC/C,MAAM,CAACc,cAAcC,gBAAgB,GAAGf,SAAyC;IACjF,MAAMgB,SAASN,YAAYO,IAAI,IAAI,EAAE;IACrC,MAAMC,YAAYnB,QAChB,IAAM,IAAIoB,IAAIR,wBAAwBM,IAAI,EAAEG,IAAI,CAACC,cAAgBA,YAAYC,EAAE,IAC/E;QAACX,wBAAwBM,IAAI;KAAC;IAGhC,SAASM,iBAAiBC,QAAiB;QACzCX,eAAeW;QACf,IAAI,CAACA,UAAU;YACbT,gBAAgB;QAClB;IACF;IAEA,qBACE,KAACU;QAAIC,WAAU;kBACb,cAAA,MAACC;YAAQD,WAAU;;8BACjB,MAACD;oBAAIC,WAAU;;sCACb,MAACD;4BAAIC,WAAU;;8CACb,KAAC7B;oCAAO+B,SAAQ;8CAAK;;8CACrB,KAAC9B;oCAAK+B,MAAK;oCAAKH,WAAU;8CAAgC;;;;sCAK5D,MAACD;4BAAIC,WAAU;;gCACXhB,YAAYoB,UAAU,IAAI,CAACpB,YAAYqB,SAAS,IACjDpB,wBAAwBmB,UAAU,IAAI,CAACnB,wBAAwBoB,SAAS,iBACvE,KAAC3C;oCACC4C,MAAK;oCACLN,WAAU;oCACVO,cAAW;qCAEX;8CACJ,MAAC5C;oCAAM6C,MAAMtB;oCAAauB,cAAcZ;;sDACtC,KAAC7B;4CAAa0C,OAAO;sDACnB,cAAA,KAACjD;0DAAO;;;sDAEV,MAACI;4CAAa8C,oBAAkBC;;8DAC9B,KAAC7C;oDAAWiC,WAAU;8DAAU;;8DAChC,KAAClC;8DACC,cAAA,KAACM;wDACC+B,MAAK;wDACLU,eAAY;wDACZb,WAAU;kEACX;;;gDAIFZ,6BACC,KAACxB;oDAAUoC,WAAU;8DACnB,cAAA,KAACvB;wDAA6BqC,OAAO1B;;mEAGvC,KAACV;oDACCK,aAAaA;oDACbgC,WAAW1B;;;;;;;;;;gBAQtBL,YAAYqB,SAAS,iBAAG,KAACxB,qCAAmC;gBAE5DG,YAAYgC,OAAO,IAAIhC,YAAYO,IAAI,KAAKqB,0BAC3C,KAAC3C;8BACC,cAAA,KAACT;wBACCyD,OAAOjC;wBACPkC,SAAQ;wBACRhB,SAAQ;;qBAGV;gBAEHlB,YAAYO,IAAI,KAAKqB,aAAatB,OAAO6B,MAAM,KAAK,kBACnD,KAAClD;8BACC,cAAA,KAACU;qBAED;gBAEHW,OAAO6B,MAAM,GAAG,kBACf,KAACjD;8BACC,cAAA,KAACU;wBAAqBG,aAAaA;wBAAaO,QAAQA;wBAAQE,WAAWA;;qBAE3E;;;;AAIZ"}