@shipfox/client-runners 5.0.0 → 6.0.2
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 +49 -0
- package/dist/components/create-manual-registration-token-form.d.ts +3 -3
- package/dist/components/create-manual-registration-token-form.d.ts.map +1 -1
- package/dist/components/create-manual-registration-token-form.js +8 -23
- package/dist/components/create-manual-registration-token-form.js.map +1 -1
- package/dist/components/create-provisioner-token-form.d.ts +3 -3
- package/dist/components/create-provisioner-token-form.d.ts.map +1 -1
- package/dist/components/create-provisioner-token-form.js +8 -23
- package/dist/components/create-provisioner-token-form.js.map +1 -1
- package/dist/components/manual-registration-token-errors.d.ts.map +1 -1
- package/dist/components/manual-registration-token-errors.js +0 -1
- package/dist/components/manual-registration-token-errors.js.map +1 -1
- package/dist/components/manual-registration-token-format.d.ts +0 -2
- package/dist/components/manual-registration-token-format.d.ts.map +1 -1
- package/dist/components/manual-registration-token-format.js +0 -3
- package/dist/components/manual-registration-token-format.js.map +1 -1
- package/dist/components/manual-registration-token-list.d.ts +2 -2
- package/dist/components/manual-registration-token-list.d.ts.map +1 -1
- package/dist/components/manual-registration-token-list.js +12 -19
- 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 +1 -1
- package/dist/components/manual-registration-tokens-settings-section.js.map +1 -1
- package/dist/components/provisioner-token-errors.d.ts.map +1 -1
- package/dist/components/provisioner-token-errors.js +0 -1
- package/dist/components/provisioner-token-errors.js.map +1 -1
- package/dist/components/provisioner-token-format.d.ts +0 -18
- package/dist/components/provisioner-token-format.d.ts.map +1 -1
- package/dist/components/provisioner-token-format.js +0 -25
- package/dist/components/provisioner-token-format.js.map +1 -1
- package/dist/components/provisioner-token-list.d.ts +2 -2
- package/dist/components/provisioner-token-list.d.ts.map +1 -1
- package/dist/components/provisioner-token-list.js +9 -19
- package/dist/components/provisioner-token-list.js.map +1 -1
- package/dist/components/provisioner-tokens-settings-section.js +2 -2
- package/dist/components/provisioner-tokens-settings-section.js.map +1 -1
- package/dist/components/token-expiration-select.d.ts +7 -0
- package/dist/components/token-expiration-select.d.ts.map +1 -1
- package/dist/components/token-expiration-select.js +8 -0
- package/dist/components/token-expiration-select.js.map +1 -1
- package/dist/components/token-settings-sections.stories.d.ts.map +1 -1
- package/dist/components/token-settings-sections.stories.js +66 -23
- package/dist/components/token-settings-sections.stories.js.map +1 -1
- package/dist/core/token.d.ts +66 -0
- package/dist/core/token.d.ts.map +1 -0
- package/dist/core/token.js +37 -0
- package/dist/core/token.js.map +1 -0
- package/dist/feature.d.ts +13 -0
- package/dist/feature.d.ts.map +1 -1
- package/dist/feature.js +17 -16
- package/dist/feature.js.map +1 -1
- package/dist/hooks/api/manual-registration-tokens.d.ts +13 -71
- package/dist/hooks/api/manual-registration-tokens.d.ts.map +1 -1
- package/dist/hooks/api/manual-registration-tokens.js +40 -19
- package/dist/hooks/api/manual-registration-tokens.js.map +1 -1
- package/dist/hooks/api/provisioner-tokens.d.ts +17 -115
- package/dist/hooks/api/provisioner-tokens.d.ts.map +1 -1
- package/dist/hooks/api/provisioner-tokens.js +59 -32
- package/dist/hooks/api/provisioner-tokens.js.map +1 -1
- package/dist/hooks/api/token-mapper.d.ts +12 -0
- package/dist/hooks/api/token-mapper.d.ts.map +1 -0
- package/dist/hooks/api/token-mapper.js +61 -0
- package/dist/hooks/api/token-mapper.js.map +1 -0
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +9 -9
- package/src/components/create-manual-registration-token-form.tsx +11 -21
- package/src/components/create-provisioner-token-form.tsx +11 -21
- package/src/components/form-errors.test.ts +2 -2
- package/src/components/manual-registration-token-errors.ts +0 -1
- package/src/components/manual-registration-token-format.test.ts +4 -4
- package/src/components/manual-registration-token-format.ts +0 -7
- package/src/components/manual-registration-token-list.tsx +13 -22
- package/src/components/manual-registration-tokens-settings-section.tsx +3 -5
- package/src/components/provisioner-token-errors.ts +0 -1
- package/src/components/provisioner-token-form-errors.test.ts +2 -2
- package/src/components/provisioner-token-format.test.ts +15 -14
- package/src/components/provisioner-token-format.ts +0 -29
- package/src/components/provisioner-token-list.tsx +14 -23
- package/src/components/provisioner-tokens-settings-section.tsx +4 -4
- package/src/components/token-expiration-select.test.ts +15 -0
- package/src/components/token-expiration-select.tsx +6 -0
- package/src/components/token-settings-sections.stories.tsx +72 -23
- package/src/core/token.test.ts +30 -0
- package/src/core/token.ts +83 -0
- package/src/feature.ts +19 -17
- package/src/hooks/api/manual-registration-tokens.test.ts +8 -5
- package/src/hooks/api/manual-registration-tokens.ts +71 -24
- package/src/hooks/api/provisioner-tokens.test.ts +10 -7
- package/src/hooks/api/provisioner-tokens.ts +100 -36
- package/src/hooks/api/token-mapper.test.ts +161 -0
- package/src/hooks/api/token-mapper.ts +79 -0
- package/tsconfig.build.tsbuildinfo +1 -1
- package/vercel.json +5 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/manual-registration-tokens-settings-section.tsx"],"sourcesContent":["import
|
|
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-32\">\n <section className=\"flex flex-col gap-16\">\n <div className=\"flex items-center justify-between gap-16 max-[640px]:items-start\">\n <div className=\"flex flex-col gap-4\">\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-12\">\n {tokensQuery.isFetching && !tokensQuery.isPending ? (\n <Icon\n name=\"loader4Line\"\n className=\"mt-2 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-16\">\n <CreatedManualRegistrationTokenPanel token={createdToken} />\n </ModalBody>\n ) : (\n <CreateManualRegistrationTokenForm\n workspaceId={workspaceId}\n onCreated={setCreatedToken}\n />\n )}\n </ModalContent>\n </Modal>\n </div>\n </div>\n\n {tokensQuery.isPending ? <ManualRegistrationTokenTableSkeleton /> : null}\n\n {tokensQuery.isError && tokensQuery.data === undefined ? (\n <QueryLoadError query={tokensQuery} subject=\"manual registration tokens\" />\n ) : null}\n\n {tokensQuery.data !== undefined && tokens.length === 0 ? (\n <EmptyManualRegistrationTokens />\n ) : null}\n\n {tokens.length > 0 ? (\n <ManualRegistrationTokenList workspaceId={workspaceId} tokens={tokens} />\n ) : null}\n </section>\n </div>\n );\n}\n"],"names":["QueryLoadError","Button","Icon","Modal","ModalBody","ModalContent","ModalHeader","ModalTitle","ModalTrigger","Header","Text","useState","useManualRegistrationTokensQuery","CreatedManualRegistrationTokenPanel","CreateManualRegistrationTokenForm","EmptyManualRegistrationTokens","ManualRegistrationTokenList","ManualRegistrationTokenTableSkeleton","WorkspaceManualRegistrationTokensSettingsSection","workspaceId","tokensQuery","isModalOpen","setIsModalOpen","createdToken","setCreatedToken","tokens","data","handleOpenChange","nextOpen","div","className","section","variant","size","isFetching","isPending","name","aria-label","open","onOpenChange","asChild","aria-describedby","undefined","aria-hidden","token","onCreated","isError","query","subject","length"],"mappings":";AAAA,SAAQA,cAAc,QAAO,qBAAqB;AAClD,SAAQC,MAAM,QAAO,2BAA2B;AAChD,SAAQC,IAAI,QAAO,yBAAyB;AAC5C,SACEC,KAAK,EACLC,SAAS,EACTC,YAAY,EACZC,WAAW,EACXC,UAAU,EACVC,YAAY,QACP,0BAA0B;AACjC,SAAQC,MAAM,EAAEC,IAAI,QAAO,+BAA+B;AAC1D,SAAQC,QAAQ,QAAO,QAAQ;AAE/B,SAAQC,gCAAgC,QAAO,2CAA2C;AAC1F,SACEC,mCAAmC,EACnCC,iCAAiC,QAC5B,6CAA6C;AACpD,SACEC,6BAA6B,EAC7BC,2BAA2B,EAC3BC,oCAAoC,QAC/B,sCAAsC;AAE7C,OAAO,SAASC,iDAAiD,EAC/DC,WAAW,EAGZ;IACC,MAAMC,cAAcR,iCAAiCO;IACrD,MAAM,CAACE,aAAaC,eAAe,GAAGX,SAAS;IAC/C,MAAM,CAACY,cAAcC,gBAAgB,GAAGb,SAAgD;IACxF,MAAMc,SAASL,YAAYM,IAAI,IAAI,EAAE;IAErC,SAASC,iBAAiBC,QAAiB;QACzCN,eAAeM;QACf,IAAI,CAACA,UAAU;YACbJ,gBAAgB;QAClB;IACF;IAEA,qBACE,KAACK;QAAIC,WAAU;kBACb,cAAA,MAACC;YAAQD,WAAU;;8BACjB,MAACD;oBAAIC,WAAU;;sCACb,MAACD;4BAAIC,WAAU;;8CACb,KAACrB;oCAAOuB,SAAQ;8CAAK;;8CACrB,KAACtB;oCAAKuB,MAAK;oCAAKH,WAAU;8CAAgC;;;;sCAK5D,MAACD;4BAAIC,WAAU;;gCACZV,YAAYc,UAAU,IAAI,CAACd,YAAYe,SAAS,iBAC/C,KAACjC;oCACCkC,MAAK;oCACLN,WAAU;oCACVO,cAAW;qCAEX;8CACJ,MAAClC;oCAAMmC,MAAMjB;oCAAakB,cAAcZ;;sDACtC,KAACnB;4CAAagC,OAAO;sDACnB,cAAA,KAACvC;0DAAO;;;sDAEV,MAACI;4CAAaoC,oBAAkBC;;8DAC9B,KAACnC;oDAAWuB,WAAU;8DAAU;;8DAChC,KAACxB;8DACC,cAAA,KAACI;wDACCuB,MAAK;wDACLU,eAAY;wDACZb,WAAU;kEACX;;;gDAIFP,6BACC,KAACnB;oDAAU0B,WAAU;8DACnB,cAAA,KAACjB;wDAAoC+B,OAAOrB;;mEAG9C,KAACT;oDACCK,aAAaA;oDACb0B,WAAWrB;;;;;;;;;;gBAQtBJ,YAAYe,SAAS,iBAAG,KAAClB,4CAA0C;gBAEnEG,YAAY0B,OAAO,IAAI1B,YAAYM,IAAI,KAAKgB,0BAC3C,KAAC1C;oBAAe+C,OAAO3B;oBAAa4B,SAAQ;qBAC1C;gBAEH5B,YAAYM,IAAI,KAAKgB,aAAajB,OAAOwB,MAAM,KAAK,kBACnD,KAAClC,qCACC;gBAEHU,OAAOwB,MAAM,GAAG,kBACf,KAACjC;oBAA4BG,aAAaA;oBAAaM,QAAQA;qBAC7D;;;;AAIZ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provisioner-token-errors.d.ts","sourceRoot":"","sources":["../../src/components/provisioner-token-errors.ts"],"names":[],"mappings":"AAEA,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"provisioner-token-errors.d.ts","sourceRoot":"","sources":["../../src/components/provisioner-token-errors.ts"],"names":[],"mappings":"AAEA,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAQnE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/provisioner-token-errors.ts"],"sourcesContent":["import {ApiError} from '@shipfox/client-api';\n\nexport function provisionerTokenErrorMessage(error: unknown): string {\n if (error instanceof ApiError) {\n if (error.code === 'network-error') {\n return \"We couldn't reach the server. Check your connection and try again.\";\n }\n return error.message;\n }\n
|
|
1
|
+
{"version":3,"sources":["../../src/components/provisioner-token-errors.ts"],"sourcesContent":["import {ApiError} from '@shipfox/client-api';\n\nexport function provisionerTokenErrorMessage(error: unknown): string {\n if (error instanceof ApiError) {\n if (error.code === 'network-error') {\n return \"We couldn't reach the server. Check your connection and try again.\";\n }\n return error.message;\n }\n return 'Something went wrong. Try again.';\n}\n"],"names":["ApiError","provisionerTokenErrorMessage","error","code","message"],"mappings":"AAAA,SAAQA,QAAQ,QAAO,sBAAsB;AAE7C,OAAO,SAASC,6BAA6BC,KAAc;IACzD,IAAIA,iBAAiBF,UAAU;QAC7B,IAAIE,MAAMC,IAAI,KAAK,iBAAiB;YAClC,OAAO;QACT;QACA,OAAOD,MAAME,OAAO;IACtB;IACA,OAAO;AACT"}
|
|
@@ -1,21 +1,3 @@
|
|
|
1
|
-
import type { ProvisionerTokenDto } from '@shipfox/api-runners-dto';
|
|
2
|
-
import type { DotVariant } from '@shipfox/react-ui/dot';
|
|
3
|
-
export type ProvisionerConnectionStatus = {
|
|
4
|
-
kind: 'connected';
|
|
5
|
-
dotVariant: DotVariant;
|
|
6
|
-
label: 'Connected';
|
|
7
|
-
} | {
|
|
8
|
-
kind: 'last-seen';
|
|
9
|
-
dotVariant: DotVariant;
|
|
10
|
-
label: 'Last seen';
|
|
11
|
-
lastSeenAt: string;
|
|
12
|
-
} | {
|
|
13
|
-
kind: 'never-connected';
|
|
14
|
-
dotVariant: DotVariant;
|
|
15
|
-
label: 'Never connected';
|
|
16
|
-
};
|
|
17
1
|
export declare function formatProvisionerTokenDate(value: string | null): string;
|
|
18
2
|
export declare function formatProvisionerTokenTimestamp(value: string | null): string | undefined;
|
|
19
|
-
export declare function provisionerTokenDisplayName(token: Pick<ProvisionerTokenDto, 'name'>): string;
|
|
20
|
-
export declare function provisionerConnectionStatus(token: Pick<ProvisionerTokenDto, 'id' | 'last_seen_at'>, activeIds: ReadonlySet<string>): ProvisionerConnectionStatus;
|
|
21
3
|
//# sourceMappingURL=provisioner-token-format.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provisioner-token-format.d.ts","sourceRoot":"","sources":["../../src/components/provisioner-token-format.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"provisioner-token-format.d.ts","sourceRoot":"","sources":["../../src/components/provisioner-token-format.ts"],"names":[],"mappings":"AAEA,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAGvE;AAED,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,CAGxF"}
|
|
@@ -7,30 +7,5 @@ export function formatProvisionerTokenTimestamp(value) {
|
|
|
7
7
|
if (!value) return undefined;
|
|
8
8
|
return formatTimestamp(value);
|
|
9
9
|
}
|
|
10
|
-
export function provisionerTokenDisplayName(token) {
|
|
11
|
-
return token.name || 'Unnamed provisioner';
|
|
12
|
-
}
|
|
13
|
-
export function provisionerConnectionStatus(token, activeIds) {
|
|
14
|
-
if (activeIds.has(token.id)) {
|
|
15
|
-
return {
|
|
16
|
-
kind: 'connected',
|
|
17
|
-
dotVariant: 'success',
|
|
18
|
-
label: 'Connected'
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
if (token.last_seen_at) {
|
|
22
|
-
return {
|
|
23
|
-
kind: 'last-seen',
|
|
24
|
-
dotVariant: 'neutral',
|
|
25
|
-
label: 'Last seen',
|
|
26
|
-
lastSeenAt: token.last_seen_at
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
return {
|
|
30
|
-
kind: 'never-connected',
|
|
31
|
-
dotVariant: 'neutral',
|
|
32
|
-
label: 'Never connected'
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
10
|
|
|
36
11
|
//# sourceMappingURL=provisioner-token-format.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/provisioner-token-format.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"sources":["../../src/components/provisioner-token-format.ts"],"sourcesContent":["import {formatDate, formatTimestamp} from '@shipfox/react-ui/utils';\n\nexport function formatProvisionerTokenDate(value: string | null): string {\n if (!value) return 'Never';\n return formatDate(value);\n}\n\nexport function formatProvisionerTokenTimestamp(value: string | null): string | undefined {\n if (!value) return undefined;\n return formatTimestamp(value);\n}\n"],"names":["formatDate","formatTimestamp","formatProvisionerTokenDate","value","formatProvisionerTokenTimestamp","undefined"],"mappings":"AAAA,SAAQA,UAAU,EAAEC,eAAe,QAAO,0BAA0B;AAEpE,OAAO,SAASC,2BAA2BC,KAAoB;IAC7D,IAAI,CAACA,OAAO,OAAO;IACnB,OAAOH,WAAWG;AACpB;AAEA,OAAO,SAASC,gCAAgCD,KAAoB;IAClE,IAAI,CAACA,OAAO,OAAOE;IACnB,OAAOJ,gBAAgBE;AACzB"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ProvisionerToken } from '#core/token.js';
|
|
2
2
|
export declare function ProvisionerTokenList({ workspaceId, tokens, activeIds, }: {
|
|
3
3
|
workspaceId: string;
|
|
4
|
-
tokens:
|
|
4
|
+
tokens: ProvisionerToken[];
|
|
5
5
|
activeIds: ReadonlySet<string>;
|
|
6
6
|
}): import("react").JSX.Element;
|
|
7
7
|
export declare function EmptyProvisionerTokens(): import("react").JSX.Element;
|
|
@@ -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":"AA8BA,OAAO,EACL,KAAK,gBAAgB,EAGtB,MAAM,gBAAgB,CAAC;AAUxB,wBAAgB,oBAAoB,CAAC,EACnC,WAAW,EACX,MAAM,EACN,SAAS,GACV,EAAE;IACD,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAC3B,SAAS,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAChC,+BAmFA;AAqHD,wBAAgB,sBAAsB,gCAQrC;AAED,wBAAgB,6BAA6B,gCAQ5C"}
|
|
@@ -9,11 +9,11 @@ import { RelativeTime } from '@shipfox/react-ui/relative-time';
|
|
|
9
9
|
import { Skeleton } from '@shipfox/react-ui/skeleton';
|
|
10
10
|
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@shipfox/react-ui/table';
|
|
11
11
|
import { Code, Text } from '@shipfox/react-ui/typography';
|
|
12
|
-
import { useQueryClient } from '@tanstack/react-query';
|
|
13
12
|
import { useState } from 'react';
|
|
14
|
-
import {
|
|
13
|
+
import { provisionerConnectionStatus, provisionerTokenDisplayName } from '#core/token.js';
|
|
14
|
+
import { useRevokeProvisionerTokenMutation } from '#hooks/api/provisioner-tokens.js';
|
|
15
15
|
import { provisionerTokenErrorMessage } from './provisioner-token-errors.js';
|
|
16
|
-
import { formatProvisionerTokenDate, formatProvisionerTokenTimestamp
|
|
16
|
+
import { formatProvisionerTokenDate, formatProvisionerTokenTimestamp } from './provisioner-token-format.js';
|
|
17
17
|
import { TokenDate } from './token-date.js';
|
|
18
18
|
import { TokenName } from './token-name.js';
|
|
19
19
|
export function ProvisionerTokenList({ workspaceId, tokens, activeIds }) {
|
|
@@ -76,12 +76,12 @@ export function ProvisionerTokenList({ workspaceId, tokens, activeIds }) {
|
|
|
76
76
|
}),
|
|
77
77
|
/*#__PURE__*/ _jsx(TableCell, {
|
|
78
78
|
children: /*#__PURE__*/ _jsx(ProvisionerTokenDate, {
|
|
79
|
-
value: token.
|
|
79
|
+
value: token.expiresAt
|
|
80
80
|
})
|
|
81
81
|
}),
|
|
82
82
|
/*#__PURE__*/ _jsx(TableCell, {
|
|
83
83
|
children: /*#__PURE__*/ _jsx(ProvisionerTokenDate, {
|
|
84
|
-
value: token.
|
|
84
|
+
value: token.createdAt
|
|
85
85
|
})
|
|
86
86
|
}),
|
|
87
87
|
/*#__PURE__*/ _jsx(TableCell, {
|
|
@@ -150,7 +150,7 @@ export function ProvisionerTokenList({ workspaceId, tokens, activeIds }) {
|
|
|
150
150
|
}),
|
|
151
151
|
/*#__PURE__*/ _jsx("dd", {
|
|
152
152
|
children: /*#__PURE__*/ _jsx(ProvisionerTokenDate, {
|
|
153
|
-
value: token.
|
|
153
|
+
value: token.expiresAt
|
|
154
154
|
})
|
|
155
155
|
})
|
|
156
156
|
]
|
|
@@ -163,7 +163,7 @@ export function ProvisionerTokenList({ workspaceId, tokens, activeIds }) {
|
|
|
163
163
|
}),
|
|
164
164
|
/*#__PURE__*/ _jsx("dd", {
|
|
165
165
|
children: /*#__PURE__*/ _jsx(ProvisionerTokenDate, {
|
|
166
|
-
value: token.
|
|
166
|
+
value: token.createdAt
|
|
167
167
|
})
|
|
168
168
|
})
|
|
169
169
|
]
|
|
@@ -206,22 +206,12 @@ function ProvisionerStatusCell({ token, activeIds }) {
|
|
|
206
206
|
});
|
|
207
207
|
}
|
|
208
208
|
function RevokeProvisionerTokenButton({ workspaceId, token }) {
|
|
209
|
-
const
|
|
210
|
-
const revokeToken = useRevokeProvisionerTokenMutation();
|
|
209
|
+
const revokeToken = useRevokeProvisionerTokenMutation(workspaceId);
|
|
211
210
|
const [open, setOpen] = useState(false);
|
|
212
211
|
const tokenName = provisionerTokenDisplayName(token);
|
|
213
212
|
async function handleRevoke() {
|
|
214
213
|
try {
|
|
215
|
-
await revokeToken.mutateAsync(
|
|
216
|
-
workspaceId,
|
|
217
|
-
tokenId: token.id
|
|
218
|
-
});
|
|
219
|
-
await queryClient.invalidateQueries({
|
|
220
|
-
queryKey: provisionerTokenQueryKeys.list(workspaceId)
|
|
221
|
-
});
|
|
222
|
-
await queryClient.invalidateQueries({
|
|
223
|
-
queryKey: provisionerTokenQueryKeys.active(workspaceId)
|
|
224
|
-
});
|
|
214
|
+
await revokeToken.mutateAsync(token.id);
|
|
225
215
|
setOpen(false);
|
|
226
216
|
} catch {
|
|
227
217
|
// React Query stores the error for the inline modal alert.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/provisioner-token-list.tsx"],"sourcesContent":["import type {ProvisionerTokenDto} from '@shipfox/api-runners-dto';\nimport {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 {useQueryClient} from '@tanstack/react-query';\nimport {useState} from 'react';\nimport {\n provisionerTokenQueryKeys,\n useRevokeProvisionerTokenMutation,\n} from '#hooks/api/provisioner-tokens.js';\nimport {provisionerTokenErrorMessage} from './provisioner-token-errors.js';\nimport {\n formatProvisionerTokenDate,\n formatProvisionerTokenTimestamp,\n provisionerConnectionStatus,\n provisionerTokenDisplayName,\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: ProvisionerTokenDto[];\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.expires_at} />\n </TableCell>\n <TableCell>\n <ProvisionerTokenDate value={token.created_at} />\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-10 max-[760px]:flex\" aria-label=\"Provisioner tokens\">\n {tokens.map((token) => (\n <li\n key={token.id}\n className=\"rounded-8 border border-border-neutral-base bg-background-neutral-base p-14\"\n >\n <div className=\"flex items-start justify-between gap-12\">\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=\"mt-12 grid grid-cols-2 gap-10 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.expires_at} />\n </dd>\n </div>\n <div>\n <dt className=\"text-foreground-neutral-muted\">Created</dt>\n <dd>\n <ProvisionerTokenDate value={token.created_at} />\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: ProvisionerTokenDto;\n activeIds: ReadonlySet<string>;\n}) {\n const status = provisionerConnectionStatus(token, activeIds);\n\n return (\n <span className=\"inline-flex items-center gap-6\">\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: ProvisionerTokenDto;\n}) {\n const queryClient = useQueryClient();\n const revokeToken = useRevokeProvisionerTokenMutation();\n const [open, setOpen] = useState(false);\n const tokenName = provisionerTokenDisplayName(token);\n\n async function handleRevoke() {\n try {\n await revokeToken.mutateAsync({workspaceId, tokenId: token.id});\n await queryClient.invalidateQueries({\n queryKey: provisionerTokenQueryKeys.list(workspaceId),\n });\n await queryClient.invalidateQueries({\n queryKey: provisionerTokenQueryKeys.active(workspaceId),\n });\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-16\">\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-8\">\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","useQueryClient","useState","provisionerTokenQueryKeys","useRevokeProvisionerTokenMutation","provisionerTokenErrorMessage","formatProvisionerTokenDate","formatProvisionerTokenTimestamp","provisionerConnectionStatus","provisionerTokenDisplayName","TokenDate","TokenName","ProvisionerTokenList","workspaceId","tokens","activeIds","div","className","map","token","name","variant","prefix","ProvisionerStatusCell","ProvisionerTokenDate","value","expires_at","created_at","RevokeProvisionerTokenButton","id","ul","aria-label","li","dl","dt","dd","date","timestamp","status","span","dotVariant","kind","label","lastSeenAt","queryClient","revokeToken","open","setOpen","tokenName","handleRevoke","mutateAsync","tokenId","invalidateQueries","queryKey","list","active","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 {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-10 max-[760px]:flex\" aria-label=\"Provisioner tokens\">\n {tokens.map((token) => (\n <li\n key={token.id}\n className=\"rounded-8 border border-border-neutral-base bg-background-neutral-base p-14\"\n >\n <div className=\"flex items-start justify-between gap-12\">\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=\"mt-12 grid grid-cols-2 gap-10 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-6\">\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-16\">\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-8\">\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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"}
|
|
@@ -14,8 +14,8 @@ export function WorkspaceProvisionerTokensSettingsSection({ workspaceId }) {
|
|
|
14
14
|
const activeProvisionersQuery = useActiveProvisionersQuery(workspaceId);
|
|
15
15
|
const [isModalOpen, setIsModalOpen] = useState(false);
|
|
16
16
|
const [createdToken, setCreatedToken] = useState(null);
|
|
17
|
-
const tokens = tokensQuery.data
|
|
18
|
-
const activeIds = useMemo(()=>new Set(activeProvisionersQuery.data?.
|
|
17
|
+
const tokens = tokensQuery.data ?? [];
|
|
18
|
+
const activeIds = useMemo(()=>new Set(activeProvisionersQuery.data?.map((provisioner)=>provisioner.id)), [
|
|
19
19
|
activeProvisionersQuery.data
|
|
20
20
|
]);
|
|
21
21
|
function handleOpenChange(nextOpen) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/provisioner-tokens-settings-section.tsx"],"sourcesContent":["import
|
|
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-32\">\n <section className=\"flex flex-col gap-16\">\n <div className=\"flex items-center justify-between gap-16 max-[640px]:items-start\">\n <div className=\"flex flex-col gap-4\">\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-12\">\n {(tokensQuery.isFetching && !tokensQuery.isPending) ||\n (activeProvisionersQuery.isFetching && !activeProvisionersQuery.isPending) ? (\n <Icon\n name=\"loader4Line\"\n className=\"mt-2 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-16\">\n <CreatedProvisionerTokenPanel token={createdToken} />\n </ModalBody>\n ) : (\n <CreateProvisionerTokenForm\n workspaceId={workspaceId}\n onCreated={setCreatedToken}\n />\n )}\n </ModalContent>\n </Modal>\n </div>\n </div>\n\n {tokensQuery.isPending ? <ProvisionerTokenTableSkeleton /> : null}\n\n {tokensQuery.isError && tokensQuery.data === undefined ? (\n <QueryLoadError query={tokensQuery} subject=\"provisioner registration tokens\" />\n ) : null}\n\n {tokensQuery.data !== undefined && tokens.length === 0 ? <EmptyProvisionerTokens /> : null}\n\n {tokens.length > 0 ? (\n <RelativeTimeProvider>\n <ProvisionerTokenList workspaceId={workspaceId} tokens={tokens} activeIds={activeIds} />\n </RelativeTimeProvider>\n ) : null}\n </section>\n </div>\n );\n}\n"],"names":["QueryLoadError","Button","Icon","Modal","ModalBody","ModalContent","ModalHeader","ModalTitle","ModalTrigger","RelativeTimeProvider","Header","Text","useMemo","useState","useActiveProvisionersQuery","useProvisionerTokensQuery","CreatedProvisionerTokenPanel","CreateProvisionerTokenForm","EmptyProvisionerTokens","ProvisionerTokenList","ProvisionerTokenTableSkeleton","WorkspaceProvisionerTokensSettingsSection","workspaceId","tokensQuery","activeProvisionersQuery","isModalOpen","setIsModalOpen","createdToken","setCreatedToken","tokens","data","activeIds","Set","map","provisioner","id","handleOpenChange","nextOpen","div","className","section","variant","size","isFetching","isPending","name","aria-label","open","onOpenChange","asChild","aria-describedby","undefined","aria-hidden","token","onCreated","isError","query","subject","length"],"mappings":";AAAA,SAAQA,cAAc,QAAO,qBAAqB;AAClD,SAAQC,MAAM,QAAO,2BAA2B;AAChD,SAAQC,IAAI,QAAO,yBAAyB;AAC5C,SACEC,KAAK,EACLC,SAAS,EACTC,YAAY,EACZC,WAAW,EACXC,UAAU,EACVC,YAAY,QACP,0BAA0B;AACjC,SAAQC,oBAAoB,QAAO,kCAAkC;AACrE,SAAQC,MAAM,EAAEC,IAAI,QAAO,+BAA+B;AAC1D,SAAQC,OAAO,EAAEC,QAAQ,QAAO,QAAQ;AAExC,SACEC,0BAA0B,EAC1BC,yBAAyB,QACpB,mCAAmC;AAC1C,SACEC,4BAA4B,EAC5BC,0BAA0B,QACrB,qCAAqC;AAC5C,SACEC,sBAAsB,EACtBC,oBAAoB,EACpBC,6BAA6B,QACxB,8BAA8B;AAErC,OAAO,SAASC,0CAA0C,EAACC,WAAW,EAAwB;IAC5F,MAAMC,cAAcR,0BAA0BO;IAC9C,MAAME,0BAA0BV,2BAA2BQ;IAC3D,MAAM,CAACG,aAAaC,eAAe,GAAGb,SAAS;IAC/C,MAAM,CAACc,cAAcC,gBAAgB,GAAGf,SAAyC;IACjF,MAAMgB,SAASN,YAAYO,IAAI,IAAI,EAAE;IACrC,MAAMC,YAAYnB,QAChB,IAAM,IAAIoB,IAAIR,wBAAwBM,IAAI,EAAEG,IAAI,CAACC,cAAgBA,YAAYC,EAAE,IAC/E;QAACX,wBAAwBM,IAAI;KAAC;IAGhC,SAASM,iBAAiBC,QAAiB;QACzCX,eAAeW;QACf,IAAI,CAACA,UAAU;YACbT,gBAAgB;QAClB;IACF;IAEA,qBACE,KAACU;QAAIC,WAAU;kBACb,cAAA,MAACC;YAAQD,WAAU;;8BACjB,MAACD;oBAAIC,WAAU;;sCACb,MAACD;4BAAIC,WAAU;;8CACb,KAAC7B;oCAAO+B,SAAQ;8CAAK;;8CACrB,KAAC9B;oCAAK+B,MAAK;oCAAKH,WAAU;8CAAgC;;;;sCAK5D,MAACD;4BAAIC,WAAU;;gCACXhB,YAAYoB,UAAU,IAAI,CAACpB,YAAYqB,SAAS,IACjDpB,wBAAwBmB,UAAU,IAAI,CAACnB,wBAAwBoB,SAAS,iBACvE,KAAC1C;oCACC2C,MAAK;oCACLN,WAAU;oCACVO,cAAW;qCAEX;8CACJ,MAAC3C;oCAAM4C,MAAMtB;oCAAauB,cAAcZ;;sDACtC,KAAC5B;4CAAayC,OAAO;sDACnB,cAAA,KAAChD;0DAAO;;;sDAEV,MAACI;4CAAa6C,oBAAkBC;;8DAC9B,KAAC5C;oDAAWgC,WAAU;8DAAU;;8DAChC,KAACjC;8DACC,cAAA,KAACK;wDACC+B,MAAK;wDACLU,eAAY;wDACZb,WAAU;kEACX;;;gDAIFZ,6BACC,KAACvB;oDAAUmC,WAAU;8DACnB,cAAA,KAACvB;wDAA6BqC,OAAO1B;;mEAGvC,KAACV;oDACCK,aAAaA;oDACbgC,WAAW1B;;;;;;;;;;gBAQtBL,YAAYqB,SAAS,iBAAG,KAACxB,qCAAmC;gBAE5DG,YAAYgC,OAAO,IAAIhC,YAAYO,IAAI,KAAKqB,0BAC3C,KAACnD;oBAAewD,OAAOjC;oBAAakC,SAAQ;qBAC1C;gBAEHlC,YAAYO,IAAI,KAAKqB,aAAatB,OAAO6B,MAAM,KAAK,kBAAI,KAACxC,8BAA4B;gBAErFW,OAAO6B,MAAM,GAAG,kBACf,KAACjD;8BACC,cAAA,KAACU;wBAAqBG,aAAaA;wBAAaO,QAAQA;wBAAQE,WAAWA;;qBAE3E;;;;AAIZ"}
|
|
@@ -3,6 +3,13 @@ export declare const expirationOptions: Array<{
|
|
|
3
3
|
value: TokenExpirationOption;
|
|
4
4
|
label: string;
|
|
5
5
|
}>;
|
|
6
|
+
export declare function expirationCommand(expiration: TokenExpirationOption): {
|
|
7
|
+
readonly kind: "never";
|
|
8
|
+
readonly seconds?: never;
|
|
9
|
+
} | {
|
|
10
|
+
readonly kind: "expires-after";
|
|
11
|
+
readonly seconds: number;
|
|
12
|
+
};
|
|
6
13
|
export declare function expirationHint(expiration: TokenExpirationOption): string;
|
|
7
14
|
export declare function ExpirationSelect({ value, onValueChange, }: {
|
|
8
15
|
value: TokenExpirationOption;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token-expiration-select.d.ts","sourceRoot":"","sources":["../../src/components/token-expiration-select.tsx"],"names":[],"mappings":"AASA,MAAM,MAAM,qBAAqB,GAC7B,OAAO,GACP,QAAQ,GACR,SAAS,GACT,SAAS,GACT,UAAU,GACV,UAAU,GACV,OAAO,CAAC;AAEZ,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,qBAAqB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAC,CAQlF,CAAC;AAEF,wBAAgB,cAAc,CAAC,UAAU,EAAE,qBAAqB,GAAG,MAAM,CAKxE;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,KAAK,EACL,aAAa,GACd,EAAE;IACD,KAAK,EAAE,qBAAqB,CAAC;IAC7B,aAAa,EAAE,CAAC,IAAI,EAAE,qBAAqB,KAAK,IAAI,CAAC;CACtD,+BAsBA"}
|
|
1
|
+
{"version":3,"file":"token-expiration-select.d.ts","sourceRoot":"","sources":["../../src/components/token-expiration-select.tsx"],"names":[],"mappings":"AASA,MAAM,MAAM,qBAAqB,GAC7B,OAAO,GACP,QAAQ,GACR,SAAS,GACT,SAAS,GACT,UAAU,GACV,UAAU,GACV,OAAO,CAAC;AAEZ,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,qBAAqB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAC,CAQlF,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,qBAAqB;;;;;;EAIlE;AAED,wBAAgB,cAAc,CAAC,UAAU,EAAE,qBAAqB,GAAG,MAAM,CAKxE;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,KAAK,EACL,aAAa,GACd,EAAE;IACD,KAAK,EAAE,qBAAqB,CAAC;IAC7B,aAAa,EAAE,CAAC,IAAI,EAAE,qBAAqB,KAAK,IAAI,CAAC;CACtD,+BAsBA"}
|
|
@@ -31,6 +31,14 @@ export const expirationOptions = [
|
|
|
31
31
|
label: 'Never'
|
|
32
32
|
}
|
|
33
33
|
];
|
|
34
|
+
export function expirationCommand(expiration) {
|
|
35
|
+
return expiration === 'never' ? {
|
|
36
|
+
kind: 'never'
|
|
37
|
+
} : {
|
|
38
|
+
kind: 'expires-after',
|
|
39
|
+
seconds: Number(expiration)
|
|
40
|
+
};
|
|
41
|
+
}
|
|
34
42
|
export function expirationHint(expiration) {
|
|
35
43
|
if (expiration === 'never') return 'Token will not expire.';
|
|
36
44
|
const expiresAt = new Date(Date.now() + Number(expiration) * 1000);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/token-expiration-select.tsx"],"sourcesContent":["import {useFormField} from '@shipfox/react-ui/form-field';\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@shipfox/react-ui/select';\n\nexport type TokenExpirationOption =\n | '86400'\n | '604800'\n | '2592000'\n | '7776000'\n | '15552000'\n | '31536000'\n | 'never';\n\nexport const expirationOptions: Array<{value: TokenExpirationOption; label: string}> = [\n {value: '86400', label: '1 day'},\n {value: '604800', label: '7 days'},\n {value: '2592000', label: '30 days'},\n {value: '7776000', label: '90 days'},\n {value: '15552000', label: '180 days'},\n {value: '31536000', label: '1 year'},\n {value: 'never', label: 'Never'},\n];\n\nexport function expirationHint(expiration: TokenExpirationOption): string {\n if (expiration === 'never') return 'Token will not expire.';\n const expiresAt = new Date(Date.now() + Number(expiration) * 1000);\n const formatted = new Intl.DateTimeFormat(undefined, {dateStyle: 'medium'}).format(expiresAt);\n return `Expires on ${formatted}.`;\n}\n\nexport function ExpirationSelect({\n value,\n onValueChange,\n}: {\n value: TokenExpirationOption;\n onValueChange: (next: TokenExpirationOption) => void;\n}) {\n const wiring = useFormField();\n return (\n <Select value={value} onValueChange={(next) => onValueChange(next as TokenExpirationOption)}>\n <SelectTrigger\n id={wiring.id}\n aria-invalid={wiring['aria-invalid']}\n aria-describedby={wiring['aria-describedby']}\n aria-label=\"Token expiration\"\n className=\"w-full\"\n >\n <SelectValue placeholder=\"Select expiration\" />\n </SelectTrigger>\n <SelectContent>\n {expirationOptions.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n );\n}\n"],"names":["useFormField","Select","SelectContent","SelectItem","SelectTrigger","SelectValue","expirationOptions","value","label","
|
|
1
|
+
{"version":3,"sources":["../../src/components/token-expiration-select.tsx"],"sourcesContent":["import {useFormField} from '@shipfox/react-ui/form-field';\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@shipfox/react-ui/select';\n\nexport type TokenExpirationOption =\n | '86400'\n | '604800'\n | '2592000'\n | '7776000'\n | '15552000'\n | '31536000'\n | 'never';\n\nexport const expirationOptions: Array<{value: TokenExpirationOption; label: string}> = [\n {value: '86400', label: '1 day'},\n {value: '604800', label: '7 days'},\n {value: '2592000', label: '30 days'},\n {value: '7776000', label: '90 days'},\n {value: '15552000', label: '180 days'},\n {value: '31536000', label: '1 year'},\n {value: 'never', label: 'Never'},\n];\n\nexport function expirationCommand(expiration: TokenExpirationOption) {\n return expiration === 'never'\n ? ({kind: 'never'} as const)\n : ({kind: 'expires-after', seconds: Number(expiration)} as const);\n}\n\nexport function expirationHint(expiration: TokenExpirationOption): string {\n if (expiration === 'never') return 'Token will not expire.';\n const expiresAt = new Date(Date.now() + Number(expiration) * 1000);\n const formatted = new Intl.DateTimeFormat(undefined, {dateStyle: 'medium'}).format(expiresAt);\n return `Expires on ${formatted}.`;\n}\n\nexport function ExpirationSelect({\n value,\n onValueChange,\n}: {\n value: TokenExpirationOption;\n onValueChange: (next: TokenExpirationOption) => void;\n}) {\n const wiring = useFormField();\n return (\n <Select value={value} onValueChange={(next) => onValueChange(next as TokenExpirationOption)}>\n <SelectTrigger\n id={wiring.id}\n aria-invalid={wiring['aria-invalid']}\n aria-describedby={wiring['aria-describedby']}\n aria-label=\"Token expiration\"\n className=\"w-full\"\n >\n <SelectValue placeholder=\"Select expiration\" />\n </SelectTrigger>\n <SelectContent>\n {expirationOptions.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n );\n}\n"],"names":["useFormField","Select","SelectContent","SelectItem","SelectTrigger","SelectValue","expirationOptions","value","label","expirationCommand","expiration","kind","seconds","Number","expirationHint","expiresAt","Date","now","formatted","Intl","DateTimeFormat","undefined","dateStyle","format","ExpirationSelect","onValueChange","wiring","next","id","aria-invalid","aria-describedby","aria-label","className","placeholder","map","option"],"mappings":";AAAA,SAAQA,YAAY,QAAO,+BAA+B;AAC1D,SACEC,MAAM,EACNC,aAAa,EACbC,UAAU,EACVC,aAAa,EACbC,WAAW,QACN,2BAA2B;AAWlC,OAAO,MAAMC,oBAA0E;IACrF;QAACC,OAAO;QAASC,OAAO;IAAO;IAC/B;QAACD,OAAO;QAAUC,OAAO;IAAQ;IACjC;QAACD,OAAO;QAAWC,OAAO;IAAS;IACnC;QAACD,OAAO;QAAWC,OAAO;IAAS;IACnC;QAACD,OAAO;QAAYC,OAAO;IAAU;IACrC;QAACD,OAAO;QAAYC,OAAO;IAAQ;IACnC;QAACD,OAAO;QAASC,OAAO;IAAO;CAChC,CAAC;AAEF,OAAO,SAASC,kBAAkBC,UAAiC;IACjE,OAAOA,eAAe,UACjB;QAACC,MAAM;IAAO,IACd;QAACA,MAAM;QAAiBC,SAASC,OAAOH;IAAW;AAC1D;AAEA,OAAO,SAASI,eAAeJ,UAAiC;IAC9D,IAAIA,eAAe,SAAS,OAAO;IACnC,MAAMK,YAAY,IAAIC,KAAKA,KAAKC,GAAG,KAAKJ,OAAOH,cAAc;IAC7D,MAAMQ,YAAY,IAAIC,KAAKC,cAAc,CAACC,WAAW;QAACC,WAAW;IAAQ,GAAGC,MAAM,CAACR;IACnF,OAAO,CAAC,WAAW,EAAEG,UAAU,CAAC,CAAC;AACnC;AAEA,OAAO,SAASM,iBAAiB,EAC/BjB,KAAK,EACLkB,aAAa,EAId;IACC,MAAMC,SAAS1B;IACf,qBACE,MAACC;QAAOM,OAAOA;QAAOkB,eAAe,CAACE,OAASF,cAAcE;;0BAC3D,KAACvB;gBACCwB,IAAIF,OAAOE,EAAE;gBACbC,gBAAcH,MAAM,CAAC,eAAe;gBACpCI,oBAAkBJ,MAAM,CAAC,mBAAmB;gBAC5CK,cAAW;gBACXC,WAAU;0BAEV,cAAA,KAAC3B;oBAAY4B,aAAY;;;0BAE3B,KAAC/B;0BACEI,kBAAkB4B,GAAG,CAAC,CAACC,uBACtB,KAAChC;wBAA8BI,OAAO4B,OAAO5B,KAAK;kCAC/C4B,OAAO3B,KAAK;uBADE2B,OAAO5B,KAAK;;;;AAOvC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token-settings-sections.stories.d.ts","sourceRoot":"","sources":["../../src/components/token-settings-sections.stories.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAC,SAAS,EAAQ,QAAQ,EAAC,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"token-settings-sections.stories.d.ts","sourceRoot":"","sources":["../../src/components/token-settings-sections.stories.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAC,SAAS,EAAQ,QAAQ,EAAC,MAAM,kBAAkB,CAAC;AA8BhE,KAAK,QAAQ,GAAG,WAAW,GAAG,OAAO,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE7D,UAAU,+BAA+B;IACvC,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAcD,iBAAS,0BAA0B,CAAC,EAAC,QAAQ,EAAC,EAAE,+BAA+B,+BAY9E;AAED,QAAA,MAAM,IAAI;;;;;;;;;;CAMyC,CAAC;AAEpD,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,UAAU,EAAE,KAQxB,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,KAiBxB,CAAC;AAEF,eAAO,MAAM,MAAM,EAAE,KAOpB,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KAgCtB,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,KAkDrB,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,KAqBhC,CAAC"}
|
|
@@ -110,20 +110,20 @@ export const Statuses = {
|
|
|
110
110
|
children: /*#__PURE__*/ _jsx(ProvisionerTokenList, {
|
|
111
111
|
workspaceId: WORKSPACE_ID,
|
|
112
112
|
tokens: [
|
|
113
|
-
|
|
113
|
+
provisionerTokenModel({
|
|
114
114
|
id: '33333333-3333-4333-8333-333333333333',
|
|
115
115
|
name: 'Docker autoscaler',
|
|
116
|
-
|
|
116
|
+
lastSeenAt: NOW
|
|
117
117
|
}),
|
|
118
|
-
|
|
118
|
+
provisionerTokenModel({
|
|
119
119
|
id: '44444444-4444-4444-8444-444444444444',
|
|
120
120
|
name: 'Kubernetes spot pool',
|
|
121
|
-
|
|
121
|
+
lastSeenAt: EIGHT_MINUTES_AGO
|
|
122
122
|
}),
|
|
123
|
-
|
|
123
|
+
provisionerTokenModel({
|
|
124
124
|
id: '55555555-5555-4555-8555-555555555555',
|
|
125
125
|
name: 'Buildkite migration pool',
|
|
126
|
-
|
|
126
|
+
lastSeenAt: null
|
|
127
127
|
})
|
|
128
128
|
],
|
|
129
129
|
activeIds: new Set([
|
|
@@ -149,21 +149,21 @@ export const Content = {
|
|
|
149
149
|
/*#__PURE__*/ _jsx(ManualRegistrationTokenList, {
|
|
150
150
|
workspaceId: WORKSPACE_ID,
|
|
151
151
|
tokens: [
|
|
152
|
-
|
|
152
|
+
manualRegistrationToken({
|
|
153
153
|
name: 'Deploy runner',
|
|
154
154
|
prefix: 'sf_mrt_deploy'
|
|
155
155
|
}),
|
|
156
|
-
|
|
156
|
+
manualRegistrationToken({
|
|
157
157
|
id: '66666666-6666-4666-8666-666666666666',
|
|
158
158
|
name: 'macOS build host',
|
|
159
159
|
prefix: 'sf_mrt_macos',
|
|
160
|
-
|
|
160
|
+
expiresAt: null
|
|
161
161
|
})
|
|
162
162
|
]
|
|
163
163
|
}),
|
|
164
164
|
/*#__PURE__*/ _jsx(ProvisionerTokenList, {
|
|
165
165
|
workspaceId: WORKSPACE_ID,
|
|
166
|
-
tokens:
|
|
166
|
+
tokens: provisionerTokenModels(),
|
|
167
167
|
activeIds: new Set([
|
|
168
168
|
'33333333-3333-4333-8333-333333333333'
|
|
169
169
|
])
|
|
@@ -179,7 +179,7 @@ export const Content = {
|
|
|
179
179
|
/*#__PURE__*/ _jsx(ManualRegistrationTokenList, {
|
|
180
180
|
workspaceId: WORKSPACE_ID,
|
|
181
181
|
tokens: [
|
|
182
|
-
|
|
182
|
+
manualRegistrationToken({
|
|
183
183
|
name: 'self-hosted-runner-for-production-release-candidate-validation-on-metal',
|
|
184
184
|
prefix: 'sf_mrt_release_candidate_validation'
|
|
185
185
|
})
|
|
@@ -188,10 +188,10 @@ export const Content = {
|
|
|
188
188
|
/*#__PURE__*/ _jsx(ProvisionerTokenList, {
|
|
189
189
|
workspaceId: WORKSPACE_ID,
|
|
190
190
|
tokens: [
|
|
191
|
-
|
|
191
|
+
provisionerTokenModel({
|
|
192
192
|
name: 'docker-provisioner-for-west-coast-gpu-burst-capacity-and-fallback',
|
|
193
193
|
prefix: 'sf_pt_west_coast_gpu_burst',
|
|
194
|
-
|
|
194
|
+
lastSeenAt: EIGHT_MINUTES_AGO
|
|
195
195
|
})
|
|
196
196
|
],
|
|
197
197
|
activeIds: new Set()
|
|
@@ -210,24 +210,19 @@ export const CreatedTokenPanels = {
|
|
|
210
210
|
children: /*#__PURE__*/ _jsx(CreatedManualRegistrationTokenPanel, {
|
|
211
211
|
token: {
|
|
212
212
|
id: '77777777-7777-4777-8777-777777777777',
|
|
213
|
-
|
|
213
|
+
token: 'sf_mrt_4nJvNrs23ExampleManualTokenValue',
|
|
214
214
|
prefix: 'sf_mrt_4nJv',
|
|
215
215
|
name: 'Deploy runner',
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
216
|
+
workspaceId: WORKSPACE_ID,
|
|
217
|
+
expiresAt: EXPIRES_AT,
|
|
218
|
+
createdAt: CREATED_AT
|
|
219
219
|
}
|
|
220
220
|
})
|
|
221
221
|
}),
|
|
222
222
|
/*#__PURE__*/ _jsx(StateExample, {
|
|
223
223
|
label: "Provisioner token reveal",
|
|
224
224
|
children: /*#__PURE__*/ _jsx(CreatedProvisionerTokenPanel, {
|
|
225
|
-
token:
|
|
226
|
-
...provisionerToken({
|
|
227
|
-
name: 'Docker autoscaler'
|
|
228
|
-
}),
|
|
229
|
-
raw_token: 'sf_pt_Rv8YwrExampleProvisionerTokenValue'
|
|
230
|
-
}
|
|
225
|
+
token: createdProvisionerToken()
|
|
231
226
|
})
|
|
232
227
|
})
|
|
233
228
|
]
|
|
@@ -315,6 +310,54 @@ function provisionerTokens() {
|
|
|
315
310
|
})
|
|
316
311
|
];
|
|
317
312
|
}
|
|
313
|
+
function manualRegistrationToken(overrides = {}) {
|
|
314
|
+
return {
|
|
315
|
+
id: '22222222-2222-4222-8222-222222222222',
|
|
316
|
+
workspaceId: WORKSPACE_ID,
|
|
317
|
+
prefix: 'sf_mrt_deploy',
|
|
318
|
+
name: 'Deploy runner',
|
|
319
|
+
expiresAt: EXPIRES_AT,
|
|
320
|
+
revokedAt: null,
|
|
321
|
+
createdAt: CREATED_AT,
|
|
322
|
+
updatedAt: CREATED_AT,
|
|
323
|
+
...overrides
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
function provisionerTokenModel(overrides = {}) {
|
|
327
|
+
return {
|
|
328
|
+
...manualRegistrationToken(),
|
|
329
|
+
createdByUserId: '99999999-9999-4999-8999-999999999999',
|
|
330
|
+
revokedByUserId: null,
|
|
331
|
+
lastSeenAt: NOW,
|
|
332
|
+
...overrides
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
function provisionerTokenModels() {
|
|
336
|
+
return [
|
|
337
|
+
provisionerTokenModel({
|
|
338
|
+
id: '33333333-3333-4333-8333-333333333333',
|
|
339
|
+
name: 'Docker autoscaler'
|
|
340
|
+
}),
|
|
341
|
+
provisionerTokenModel({
|
|
342
|
+
id: '44444444-4444-4444-8444-444444444444',
|
|
343
|
+
name: 'Kubernetes spot pool',
|
|
344
|
+
lastSeenAt: EIGHT_MINUTES_AGO
|
|
345
|
+
}),
|
|
346
|
+
provisionerTokenModel({
|
|
347
|
+
id: '55555555-5555-4555-8555-555555555555',
|
|
348
|
+
name: 'Buildkite migration pool',
|
|
349
|
+
lastSeenAt: null
|
|
350
|
+
})
|
|
351
|
+
];
|
|
352
|
+
}
|
|
353
|
+
function createdProvisionerToken() {
|
|
354
|
+
return {
|
|
355
|
+
...provisionerTokenModel({
|
|
356
|
+
name: 'Docker autoscaler'
|
|
357
|
+
}),
|
|
358
|
+
token: 'sf_pt_Rv8YwrExampleProvisionerTokenValue'
|
|
359
|
+
};
|
|
360
|
+
}
|
|
318
361
|
function manualToken(overrides = {}) {
|
|
319
362
|
return {
|
|
320
363
|
id: '22222222-2222-4222-8222-222222222222',
|