@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.
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +16 -0
- package/dist/components/manual-registration-token-list.d.ts.map +1 -1
- package/dist/components/manual-registration-token-list.js +9 -8
- package/dist/components/manual-registration-token-list.js.map +1 -1
- package/dist/components/manual-registration-tokens-settings-section.d.ts.map +1 -1
- package/dist/components/manual-registration-tokens-settings-section.js +10 -4
- package/dist/components/manual-registration-tokens-settings-section.js.map +1 -1
- package/dist/components/provisioner-token-list.d.ts.map +1 -1
- package/dist/components/provisioner-token-list.js +9 -8
- package/dist/components/provisioner-token-list.js.map +1 -1
- package/dist/components/provisioner-tokens-settings-section.d.ts.map +1 -1
- package/dist/components/provisioner-tokens-settings-section.js +10 -4
- package/dist/components/provisioner-tokens-settings-section.js.map +1 -1
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/src/components/manual-registration-token-list.tsx +10 -16
- package/src/components/manual-registration-tokens-settings-section.tsx +11 -2
- package/src/components/provisioner-token-list.tsx +13 -12
- package/src/components/provisioner-tokens-settings-section.tsx +13 -2
- package/tsconfig.build.tsbuildinfo +1 -1
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
$ shipfox-swc
|
|
2
|
-
Successfully compiled: 24 files with swc (
|
|
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,+
|
|
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(
|
|
19
|
+
return /*#__PURE__*/ _jsxs(Panel, {
|
|
20
20
|
children: [
|
|
21
|
-
/*#__PURE__*/ _jsx(
|
|
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
|
|
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
|
|
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(
|
|
274
|
+
return /*#__PURE__*/ _jsx(Panel, {
|
|
274
275
|
role: "status",
|
|
275
276
|
"aria-label": "Loading manual registration tokens",
|
|
276
|
-
className: "
|
|
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":";AAAA,SAAQA,MAAM,EAAEC,UAAU,QAAO,2BAA2B;AAC5D,SAAQC,OAAO,QAAO,4BAA4B;AAClD,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,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,SAAsCC,gBAAgB,QAAO,iBAAiB;AAC9E,SAAQC,wCAAwC,QAAO,2CAA2C;AAClG,SAAQC,mCAAmC,QAAO,wCAAwC;AAC1F,SACEC,iCAAiC,EACjCC,sCAAsC,QACjC,wCAAwC;AAC/C,SAAQC,SAAS,QAAO,kBAAkB;AAC1C,SAAQC,SAAS,QAAO,kBAAkB;AAE1C,OAAO,SAASC,4BAA4B,EAC1CC,WAAW,EACXC,MAAM,EAIP;IACC,qBACE,MAACpB;;0BACC,KAACqB;gBAAIC,WAAU;0BACb,cAAA,MAACpB;oBAAMoB,WAAU;;sCACf,KAAChB;sCACC,cAAA,MAACC;;kDACC,KAACF;wCAAUiB,WAAU;kDAAU;;kDAC/B,KAACjB;kDAAU;;kDACX,KAACA;wCAAUiB,WAAU;kDAAQ;;kDAC7B,KAACjB;wCAAUiB,WAAU;kDAAQ;;kDAC7B,KAACjB;wCAAUiB,WAAU;kDAAkB;;;;;sCAG3C,KAACnB;sCACEiB,OAAOG,GAAG,CAAC,CAACC,sBACX,MAACjB;;sDACC,KAACH;sDACC,cAAA,KAACa;gDAAUQ,MAAMd,iBAAiBa;;;sDAEpC,KAACpB;sDACC,cAAA,KAACI;gDAAKkB,SAAQ;gDAAYJ,WAAU;0DACjCE,MAAMG,MAAM;;;sDAGjB,KAACvB;sDACC,cAAA,KAACwB;gDAA4BC,OAAOL,MAAMM,SAAS;;;sDAErD,KAAC1B;sDACC,cAAA,KAACwB;gDAA4BC,OAAOL,MAAMO,SAAS;;;sDAErD,KAAC3B;4CAAUkB,WAAU;sDACnB,cAAA,KAACU;gDAAoCb,aAAaA;gDAAaK,OAAOA;;;;mCAhB3DA,MAAMS,EAAE;;;;;0BAuB/B,KAACC;gBACCZ,WAAU;gBACVa,cAAW;0BAEVf,OAAOG,GAAG,CAAC,CAACC,sBACX,MAACY;wBAAkBd,WAAU;;0CAC3B,MAACD;gCAAIC,WAAU;;kDACb,MAACD;wCAAIC,WAAU;;0DACb,KAACL;gDAAUQ,MAAMd,iBAAiBa;;0DAClC,KAAChB;gDAAKkB,SAAQ;gDAAYJ,WAAU;0DACjCE,MAAMG,MAAM;;;;kDAGjB,KAACK;wCAAoCb,aAAaA;wCAAaK,OAAOA;;;;0CAExE,MAACa;gCAAGf,WAAU;;kDACZ,MAACD;;0DACC,KAACiB;gDAAGhB,WAAU;0DAAgC;;0DAC9C,KAACiB;0DACC,cAAA,KAACX;oDAA4BC,OAAOL,MAAMM,SAAS;;;;;kDAGvD,MAACT;;0DACC,KAACiB;gDAAGhB,WAAU;0DAAgC;;0DAC9C,KAACiB;0DACC,cAAA,KAACX;oDAA4BC,OAAOL,MAAMO,SAAS;;;;;;;;uBApBlDP,MAAMS,EAAE;;;;AA6B3B;AAEA,SAASL,4BAA4B,EAACC,KAAK,EAAyB;IAClE,qBACE,KAACb;QACCa,OAAOA;QACPW,MAAM1B,kCAAkCe;QACxCY,WAAW1B,uCAAuCc;;AAGxD;AAEA,SAASG,oCAAoC,EAC3Cb,WAAW,EACXK,KAAK,EAIN;IACC,MAAMkB,cAAc9B,yCAAyCO;IAC7D,MAAM,CAACwB,MAAMC,QAAQ,GAAGlC,SAAS;IACjC,MAAMmC,YAAYlC,iBAAiBa;IAEnC,eAAesB;QACb,IAAI;YACF,MAAMJ,YAAYK,WAAW,CAACvB,MAAMS,EAAE;YACtCW,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,MAACvD;;kCACC,KAACG;wBAAoB4D,OAAO;kCAC1B,cAAA,KAACjE;4BACCkE,MAAK;4BACLC,MAAK;4BACL5B,SAAQ;4BACR6B,MAAK;4BACLpB,cAAY,CAAC,KAAK,EAAEU,UAAU,2BAA2B,CAAC;;;kCAG9D,KAACvD;wBAAoBkE,OAAM;wBAAMF,MAAK;kCACpC,cAAA,KAAC/D;4BAAiBkE,UAAUN;sCAAwB;;;;;0BAGxD,KAACzD;gBAAMiD,MAAMA;gBAAMe,cAAcV;0BAC/B,cAAA,MAACpD;oBAAa+D,oBAAkBC;oBAAWtC,WAAU;;sCACnD,KAACvB;4BAAWuB,WAAU;sCAAU;;sCAChC,KAACxB;4BAAY+D,OAAM;;sCACnB,MAAClE;4BAAU2B,WAAU;;8CACnB,MAACb;oCAAK6C,MAAK;oCAAKhC,WAAU;;wCACvBuB;wCAAU;;;gCAGZH,YAAYoB,OAAO,iBAClB,KAAC1E;oCAAQ2E,MAAK;oCAAQV,MAAK;8CACzB,cAAA,KAAC5C;wCAAK6C,MAAK;kDAAMzC,oCAAoC6B,YAAYsB,KAAK;;qCAEtE;;;sCAEN,MAACnE;;8CACC,KAACX;oCAAOoE,MAAK;oCAAK5B,SAAQ;oCAAYuC,SAAS,IAAMrB,QAAQ;8CAAQ;;8CAGrE,KAAC1D;oCACCoE,MAAK;oCACL5B,SAAQ;oCACRwC,WAAWxB,YAAYyB,SAAS;oCAChCF,SAASnB;8CACV;;;;;;;;;AAQb;AAEA,OAAO,SAASsB;IACd,qBACE,KAAC3E;QACC8D,MAAK;QACLM,OAAM;QACNQ,aAAY;QACZ3C,SAAQ;;AAGd;AAEA,OAAO,SAAS4C;IACd,qBACE,KAACtE;QAAM+D,MAAK;QAAS5B,cAAW;QAAqCb,WAAU;kBAC5E;YAAC;YAAG;YAAG;SAAE,CAACC,GAAG,CAAC,CAACgD,oBACd,KAACtE;gBAAmBqB,WAAU;eAAfiD;;AAIvB"}
|
|
@@ -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":"
|
|
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(
|
|
96
|
-
|
|
97
|
-
|
|
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
|
|
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,
|
|
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(
|
|
21
|
+
return /*#__PURE__*/ _jsxs(Panel, {
|
|
22
22
|
children: [
|
|
23
|
-
/*#__PURE__*/ _jsx(
|
|
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
|
|
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
|
|
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(
|
|
322
|
+
return /*#__PURE__*/ _jsx(Panel, {
|
|
322
323
|
role: "status",
|
|
323
324
|
"aria-label": "Loading provisioner tokens",
|
|
324
|
-
className: "
|
|
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":"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"}
|
|
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":"
|
|
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(
|
|
101
|
-
|
|
102
|
-
|
|
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
|
|
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"}
|