@shipfox/client-runners 17.0.1 → 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/.turbo/turbo-type.log +0 -1
- package/CHANGELOG.md +34 -0
- package/dist/components/manual-registration-token-list.d.ts.map +1 -1
- package/dist/components/manual-registration-token-list.js +9 -7
- 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 -7
- 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/components/token-settings-sections.stories.js +1 -1
- package/dist/components/token-settings-sections.stories.js.map +1 -1
- package/dist/routes/provisioners-settings.d.ts +3 -0
- package/dist/routes/provisioners-settings.js +3 -0
- package/dist/routes/provisioners-settings.js.map +1 -1
- package/dist/routes/runners-settings.d.ts +3 -0
- package/dist/routes/runners-settings.js +3 -0
- package/dist/routes/runners-settings.js.map +1 -1
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/src/components/manual-registration-token-list.tsx +9 -14
- package/src/components/manual-registration-tokens-settings-section.tsx +11 -2
- package/src/components/provisioner-token-list.tsx +12 -10
- package/src/components/provisioner-tokens-settings-section.tsx +13 -2
- package/src/components/token-settings-sections.stories.tsx +1 -1
- package/src/routes/provisioners-settings.tsx +1 -0
- package/src/routes/runners-settings.tsx +1 -0
- 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/.turbo/turbo-type.log
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,39 @@
|
|
|
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
|
+
|
|
19
|
+
## 21.0.0
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- Updated dependencies [0f4abe4]
|
|
24
|
+
- Updated dependencies [71d0c44]
|
|
25
|
+
- Updated dependencies [9c21429]
|
|
26
|
+
- Updated dependencies [30beb8f]
|
|
27
|
+
- Updated dependencies [16733a7]
|
|
28
|
+
- Updated dependencies [163c40a]
|
|
29
|
+
- Updated dependencies [c4376a1]
|
|
30
|
+
- Updated dependencies [6703982]
|
|
31
|
+
- Updated dependencies [f1d127e]
|
|
32
|
+
- Updated dependencies [0e860d7]
|
|
33
|
+
- @shipfox/react-ui@2.0.0
|
|
34
|
+
- @shipfox/client-shell@21.0.0
|
|
35
|
+
- @shipfox/client-ui@21.0.0
|
|
36
|
+
|
|
3
37
|
## 17.0.1
|
|
4
38
|
|
|
5
39
|
### 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":"
|
|
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"}
|
|
@@ -4,6 +4,7 @@ import { Callout } from '@shipfox/react-ui/callout';
|
|
|
4
4
|
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@shipfox/react-ui/dropdown-menu';
|
|
5
5
|
import { EmptyState } from '@shipfox/react-ui/empty-state';
|
|
6
6
|
import { Modal, ModalBody, ModalContent, ModalFooter, ModalHeader, ModalTitle } from '@shipfox/react-ui/modal';
|
|
7
|
+
import { Panel } from '@shipfox/react-ui/panel';
|
|
7
8
|
import { Skeleton } from '@shipfox/react-ui/skeleton';
|
|
8
9
|
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@shipfox/react-ui/table';
|
|
9
10
|
import { Code, Text } from '@shipfox/react-ui/typography';
|
|
@@ -15,7 +16,7 @@ import { formatManualRegistrationTokenDate, formatManualRegistrationTokenTimesta
|
|
|
15
16
|
import { TokenDate } from './token-date.js';
|
|
16
17
|
import { TokenName } from './token-name.js';
|
|
17
18
|
export function ManualRegistrationTokenList({ workspaceId, tokens }) {
|
|
18
|
-
return /*#__PURE__*/ _jsxs(
|
|
19
|
+
return /*#__PURE__*/ _jsxs(Panel, {
|
|
19
20
|
children: [
|
|
20
21
|
/*#__PURE__*/ _jsx("div", {
|
|
21
22
|
className: "max-[760px]:hidden",
|
|
@@ -86,10 +87,10 @@ export function ManualRegistrationTokenList({ workspaceId, tokens }) {
|
|
|
86
87
|
})
|
|
87
88
|
}),
|
|
88
89
|
/*#__PURE__*/ _jsx("ul", {
|
|
89
|
-
className: "hidden flex-col
|
|
90
|
+
className: "hidden flex-col divide-y divide-border-neutral-base max-[760px]:flex",
|
|
90
91
|
"aria-label": "Manual registration tokens",
|
|
91
92
|
children: tokens.map((token)=>/*#__PURE__*/ _jsxs("li", {
|
|
92
|
-
className: "flex flex-col gap-cluster
|
|
93
|
+
className: "flex flex-col gap-cluster p-panel-compact",
|
|
93
94
|
children: [
|
|
94
95
|
/*#__PURE__*/ _jsxs("div", {
|
|
95
96
|
className: "flex items-start justify-between gap-cluster",
|
|
@@ -265,20 +266,21 @@ export function EmptyManualRegistrationTokens() {
|
|
|
265
266
|
return /*#__PURE__*/ _jsx(EmptyState, {
|
|
266
267
|
icon: "key2Line",
|
|
267
268
|
title: "No usable manual registration tokens",
|
|
268
|
-
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"
|
|
269
271
|
});
|
|
270
272
|
}
|
|
271
273
|
export function ManualRegistrationTokenTableSkeleton() {
|
|
272
|
-
return /*#__PURE__*/ _jsx(
|
|
274
|
+
return /*#__PURE__*/ _jsx(Panel, {
|
|
273
275
|
role: "status",
|
|
274
276
|
"aria-label": "Loading manual registration tokens",
|
|
275
|
-
className: "
|
|
277
|
+
className: "divide-y",
|
|
276
278
|
children: [
|
|
277
279
|
0,
|
|
278
280
|
1,
|
|
279
281
|
2
|
|
280
282
|
].map((row)=>/*#__PURE__*/ _jsx(Skeleton, {
|
|
281
|
-
className: "h-44 w-full"
|
|
283
|
+
className: "h-44 w-full rounded-none"
|
|
282
284
|
}, row))
|
|
283
285
|
});
|
|
284
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 {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 <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 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","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,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;;0BACE,KAACC;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;wBAECd,WAAU;;0CAEV,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;;;;;;;;uBAtBpDP,MAAMS,EAAE;;;;AA+BzB;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,MAACtD;;kCACC,KAACG;wBAAoB2D,OAAO;kCAC1B,cAAA,KAAChE;4BACCiE,MAAK;4BACLC,MAAK;4BACL5B,SAAQ;4BACR6B,MAAK;4BACLpB,cAAY,CAAC,KAAK,EAAEU,UAAU,2BAA2B,CAAC;;;kCAG9D,KAACtD;wBAAoBiE,OAAM;wBAAMF,MAAK;kCACpC,cAAA,KAAC9D;4BAAiBiE,UAAUN;sCAAwB;;;;;0BAGxD,KAACxD;gBAAMgD,MAAMA;gBAAMe,cAAcV;0BAC/B,cAAA,MAACnD;oBAAa8D,oBAAkBC;oBAAWtC,WAAU;;sCACnD,KAACtB;4BAAWsB,WAAU;sCAAU;;sCAChC,KAACvB;4BAAY8D,OAAM;;sCACnB,MAACjE;4BAAU0B,WAAU;;8CACnB,MAACb;oCAAK6C,MAAK;oCAAKhC,WAAU;;wCACvBuB;wCAAU;;;gCAGZH,YAAYoB,OAAO,iBAClB,KAACzE;oCAAQ0E,MAAK;oCAAQV,MAAK;8CACzB,cAAA,KAAC5C;wCAAK6C,MAAK;kDAAMzC,oCAAoC6B,YAAYsB,KAAK;;qCAEtE;;;sCAEN,MAAClE;;8CACC,KAACX;oCAAOmE,MAAK;oCAAK5B,SAAQ;oCAAYuC,SAAS,IAAMrB,QAAQ;8CAAQ;;8CAGrE,KAACzD;oCACCmE,MAAK;oCACL5B,SAAQ;oCACRwC,WAAWxB,YAAYyB,SAAS;oCAChCF,SAASnB;8CACV;;;;;;;;;AAQb;AAEA,OAAO,SAASsB;IACd,qBACE,KAAC1E;QACC6D,MAAK;QACLM,OAAM;QACNQ,aAAY;;AAGlB;AAEA,OAAO,SAASC;IACd,qBACE,KAACjD;QACC0C,MAAK;QACL5B,cAAW;QACXb,WAAU;kBAET;YAAC;YAAG;YAAG;SAAE,CAACC,GAAG,CAAC,CAACgD,oBACd,KAACtE;gBAAmBqB,WAAU;eAAfiD;;AAIvB"}
|
|
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":"
|
|
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":"
|
|
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"}
|
|
@@ -5,6 +5,7 @@ import { Dot } from '@shipfox/react-ui/dot';
|
|
|
5
5
|
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@shipfox/react-ui/dropdown-menu';
|
|
6
6
|
import { EmptyState } from '@shipfox/react-ui/empty-state';
|
|
7
7
|
import { Modal, ModalBody, ModalContent, ModalFooter, ModalHeader, ModalTitle } from '@shipfox/react-ui/modal';
|
|
8
|
+
import { Panel } from '@shipfox/react-ui/panel';
|
|
8
9
|
import { RelativeTime } from '@shipfox/react-ui/relative-time';
|
|
9
10
|
import { Skeleton } from '@shipfox/react-ui/skeleton';
|
|
10
11
|
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@shipfox/react-ui/table';
|
|
@@ -17,7 +18,7 @@ import { formatProvisionerTokenDate, formatProvisionerTokenTimestamp } from './p
|
|
|
17
18
|
import { TokenDate } from './token-date.js';
|
|
18
19
|
import { TokenName } from './token-name.js';
|
|
19
20
|
export function ProvisionerTokenList({ workspaceId, tokens, activeIds }) {
|
|
20
|
-
return /*#__PURE__*/ _jsxs(
|
|
21
|
+
return /*#__PURE__*/ _jsxs(Panel, {
|
|
21
22
|
children: [
|
|
22
23
|
/*#__PURE__*/ _jsx("div", {
|
|
23
24
|
className: "max-[760px]:hidden",
|
|
@@ -98,10 +99,10 @@ export function ProvisionerTokenList({ workspaceId, tokens, activeIds }) {
|
|
|
98
99
|
})
|
|
99
100
|
}),
|
|
100
101
|
/*#__PURE__*/ _jsx("ul", {
|
|
101
|
-
className: "hidden flex-col
|
|
102
|
+
className: "hidden flex-col divide-y divide-border-neutral-base max-[760px]:flex",
|
|
102
103
|
"aria-label": "Provisioner tokens",
|
|
103
104
|
children: tokens.map((token)=>/*#__PURE__*/ _jsxs("li", {
|
|
104
|
-
className: "flex flex-col gap-cluster
|
|
105
|
+
className: "flex flex-col gap-cluster p-panel-compact",
|
|
105
106
|
children: [
|
|
106
107
|
/*#__PURE__*/ _jsxs("div", {
|
|
107
108
|
className: "flex items-start justify-between gap-cluster",
|
|
@@ -313,20 +314,21 @@ export function EmptyProvisionerTokens() {
|
|
|
313
314
|
return /*#__PURE__*/ _jsx(EmptyState, {
|
|
314
315
|
icon: "key2Line",
|
|
315
316
|
title: "No usable provisioner registration tokens",
|
|
316
|
-
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"
|
|
317
319
|
});
|
|
318
320
|
}
|
|
319
321
|
export function ProvisionerTokenTableSkeleton() {
|
|
320
|
-
return /*#__PURE__*/ _jsx(
|
|
322
|
+
return /*#__PURE__*/ _jsx(Panel, {
|
|
321
323
|
role: "status",
|
|
322
324
|
"aria-label": "Loading provisioner tokens",
|
|
323
|
-
className: "
|
|
325
|
+
className: "divide-y",
|
|
324
326
|
children: [
|
|
325
327
|
0,
|
|
326
328
|
1,
|
|
327
329
|
2
|
|
328
330
|
].map((row)=>/*#__PURE__*/ _jsx(Skeleton, {
|
|
329
|
-
className: "h-44 w-full"
|
|
331
|
+
className: "h-44 w-full rounded-none"
|
|
330
332
|
}, row))
|
|
331
333
|
});
|
|
332
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 {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 <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 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","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
|
+
{"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"}
|
|
@@ -230,7 +230,7 @@ export const CreatedTokenPanels = {
|
|
|
230
230
|
};
|
|
231
231
|
function StorySurface({ children }) {
|
|
232
232
|
return /*#__PURE__*/ _jsx("div", {
|
|
233
|
-
className: "min-h-screen bg-background-
|
|
233
|
+
className: "min-h-screen bg-background-subtle-base p-24",
|
|
234
234
|
children: /*#__PURE__*/ _jsx("div", {
|
|
235
235
|
className: "mx-auto flex w-full max-w-[920px] flex-col gap-32",
|
|
236
236
|
children: children
|