@shipfox/client-runners 0.2.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/.storybook/main.ts +1 -0
- package/.storybook/preview.css +4 -0
- package/.storybook/preview.tsx +64 -0
- package/.turbo/turbo-build.log +2 -0
- package/.turbo/turbo-type$colon$emit.log +1 -0
- package/.turbo/turbo-type.log +1 -0
- package/CHANGELOG.md +112 -0
- package/LICENSE +21 -0
- package/dist/components/create-manual-registration-token-form.d.ts +10 -0
- package/dist/components/create-manual-registration-token-form.d.ts.map +1 -0
- package/dist/components/create-manual-registration-token-form.js +206 -0
- package/dist/components/create-manual-registration-token-form.js.map +1 -0
- package/dist/components/create-provisioner-token-form.d.ts +10 -0
- package/dist/components/create-provisioner-token-form.d.ts.map +1 -0
- package/dist/components/create-provisioner-token-form.js +206 -0
- package/dist/components/create-provisioner-token-form.js.map +1 -0
- package/dist/components/form-errors.d.ts +6 -0
- package/dist/components/form-errors.d.ts.map +1 -0
- package/dist/components/form-errors.js +9 -0
- package/dist/components/form-errors.js.map +1 -0
- package/dist/components/manual-registration-token-errors.d.ts +2 -0
- package/dist/components/manual-registration-token-errors.d.ts.map +1 -0
- package/dist/components/manual-registration-token-errors.js +14 -0
- package/dist/components/manual-registration-token-errors.js.map +1 -0
- package/dist/components/manual-registration-token-format.d.ts +5 -0
- package/dist/components/manual-registration-token-format.d.ts.map +1 -0
- package/dist/components/manual-registration-token-format.js +14 -0
- package/dist/components/manual-registration-token-format.js.map +1 -0
- package/dist/components/manual-registration-token-list.d.ts +8 -0
- package/dist/components/manual-registration-token-list.d.ts.map +1 -0
- package/dist/components/manual-registration-token-list.js +293 -0
- package/dist/components/manual-registration-token-list.js.map +1 -0
- package/dist/components/manual-registration-tokens-settings-section.d.ts +4 -0
- package/dist/components/manual-registration-tokens-settings-section.d.ts.map +1 -0
- package/dist/components/manual-registration-tokens-settings-section.js +109 -0
- package/dist/components/manual-registration-tokens-settings-section.js.map +1 -0
- package/dist/components/provisioner-token-errors.d.ts +2 -0
- package/dist/components/provisioner-token-errors.d.ts.map +1 -0
- package/dist/components/provisioner-token-errors.js +13 -0
- package/dist/components/provisioner-token-errors.js.map +1 -0
- package/dist/components/provisioner-token-form-errors.d.ts +6 -0
- package/dist/components/provisioner-token-form-errors.d.ts.map +1 -0
- package/dist/components/provisioner-token-form-errors.js +9 -0
- package/dist/components/provisioner-token-form-errors.js.map +1 -0
- package/dist/components/provisioner-token-format.d.ts +21 -0
- package/dist/components/provisioner-token-format.d.ts.map +1 -0
- package/dist/components/provisioner-token-format.js +36 -0
- package/dist/components/provisioner-token-format.js.map +1 -0
- package/dist/components/provisioner-token-list.d.ts +9 -0
- package/dist/components/provisioner-token-list.d.ts.map +1 -0
- package/dist/components/provisioner-token-list.js +344 -0
- package/dist/components/provisioner-token-list.js.map +1 -0
- package/dist/components/provisioner-tokens-settings-section.d.ts +4 -0
- package/dist/components/provisioner-tokens-settings-section.d.ts.map +1 -0
- package/dist/components/provisioner-tokens-settings-section.js +117 -0
- package/dist/components/provisioner-tokens-settings-section.js.map +1 -0
- package/dist/components/token-date.d.ts +6 -0
- package/dist/components/token-date.d.ts.map +1 -0
- package/dist/components/token-date.js +27 -0
- package/dist/components/token-date.js.map +1 -0
- package/dist/components/token-expiration-select.d.ts +11 -0
- package/dist/components/token-expiration-select.d.ts.map +1 -0
- package/dist/components/token-expiration-select.js +68 -0
- package/dist/components/token-expiration-select.js.map +1 -0
- package/dist/components/token-name.d.ts +4 -0
- package/dist/components/token-name.d.ts.map +1 -0
- package/dist/components/token-name.js +24 -0
- package/dist/components/token-name.js.map +1 -0
- package/dist/components/token-settings-sections.stories.d.ts +26 -0
- package/dist/components/token-settings-sections.stories.d.ts.map +1 -0
- package/dist/components/token-settings-sections.stories.js +370 -0
- package/dist/components/token-settings-sections.stories.js.map +1 -0
- package/dist/hooks/api/manual-registration-tokens.d.ts +83 -0
- package/dist/hooks/api/manual-registration-tokens.d.ts.map +1 -0
- package/dist/hooks/api/manual-registration-tokens.js +53 -0
- package/dist/hooks/api/manual-registration-tokens.js.map +1 -0
- package/dist/hooks/api/provisioner-tokens.d.ts +125 -0
- package/dist/hooks/api/provisioner-tokens.d.ts.map +1 -0
- package/dist/hooks/api/provisioner-tokens.js +81 -0
- package/dist/hooks/api/provisioner-tokens.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/tsconfig.test.tsbuildinfo +1 -0
- package/package.json +88 -0
- package/src/components/create-manual-registration-token-form.tsx +197 -0
- package/src/components/create-provisioner-token-form.tsx +193 -0
- package/src/components/form-errors.test.ts +24 -0
- package/src/components/form-errors.ts +9 -0
- package/src/components/manual-registration-token-errors.ts +13 -0
- package/src/components/manual-registration-token-format.test.ts +48 -0
- package/src/components/manual-registration-token-format.ts +18 -0
- package/src/components/manual-registration-token-list.tsx +246 -0
- package/src/components/manual-registration-tokens-settings-section.test.tsx +251 -0
- package/src/components/manual-registration-tokens-settings-section.tsx +110 -0
- package/src/components/provisioner-token-errors.ts +12 -0
- package/src/components/provisioner-token-form-errors.test.ts +35 -0
- package/src/components/provisioner-token-form-errors.ts +9 -0
- package/src/components/provisioner-token-format.test.ts +96 -0
- package/src/components/provisioner-token-format.ts +40 -0
- package/src/components/provisioner-token-list.tsx +280 -0
- package/src/components/provisioner-tokens-settings-section.test.tsx +362 -0
- package/src/components/provisioner-tokens-settings-section.tsx +114 -0
- package/src/components/token-date.tsx +27 -0
- package/src/components/token-expiration-select.tsx +64 -0
- package/src/components/token-name.tsx +19 -0
- package/src/components/token-settings-sections.stories.tsx +360 -0
- package/src/hooks/api/manual-registration-tokens.test.ts +87 -0
- package/src/hooks/api/manual-registration-tokens.ts +71 -0
- package/src/hooks/api/provisioner-tokens.test.ts +127 -0
- package/src/hooks/api/provisioner-tokens.ts +102 -0
- package/src/index.ts +4 -0
- package/test/setup.ts +3 -0
- package/tsconfig.build.json +9 -0
- package/tsconfig.build.tsbuildinfo +1 -0
- package/tsconfig.json +3 -0
- package/tsconfig.test.json +8 -0
- package/vercel.json +8 -0
- package/vitest.config.ts +74 -0
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { Button } from '@shipfox/react-ui/button';
|
|
3
|
+
import { Callout, CalloutContent, CalloutDescription, CalloutTitle } from '@shipfox/react-ui/callout';
|
|
4
|
+
import { FormField, FormFieldInput, fieldError } from '@shipfox/react-ui/form-field';
|
|
5
|
+
import { useCopyToClipboard } from '@shipfox/react-ui/hooks';
|
|
6
|
+
import { ModalBody, ModalFooter } from '@shipfox/react-ui/modal';
|
|
7
|
+
import { Code, Text } from '@shipfox/react-ui/typography';
|
|
8
|
+
import { useForm } from '@tanstack/react-form';
|
|
9
|
+
import { useQueryClient } from '@tanstack/react-query';
|
|
10
|
+
import { useState } from 'react';
|
|
11
|
+
import { provisionerTokenQueryKeys, useCreateProvisionerTokenMutation } from '#hooks/api/provisioner-tokens.js';
|
|
12
|
+
import { provisionerTokenCreateErrorToFormError } from './provisioner-token-form-errors.js';
|
|
13
|
+
import { ExpirationSelect, expirationHint } from './token-expiration-select.js';
|
|
14
|
+
export const CREATE_PROVISIONER_TOKEN_FORM_ID = 'create-provisioner-token-form';
|
|
15
|
+
export function CreateProvisionerTokenForm({ workspaceId, onCreated }) {
|
|
16
|
+
const queryClient = useQueryClient();
|
|
17
|
+
const createToken = useCreateProvisionerTokenMutation();
|
|
18
|
+
const [formError, setFormError] = useState();
|
|
19
|
+
const form = useForm({
|
|
20
|
+
defaultValues: {
|
|
21
|
+
name: '',
|
|
22
|
+
expiration: '86400'
|
|
23
|
+
},
|
|
24
|
+
onSubmit: async ({ value })=>{
|
|
25
|
+
setFormError(undefined);
|
|
26
|
+
const trimmedName = value.name.trim();
|
|
27
|
+
const body = {
|
|
28
|
+
...trimmedName ? {
|
|
29
|
+
name: trimmedName
|
|
30
|
+
} : {},
|
|
31
|
+
...value.expiration === 'never' ? {} : {
|
|
32
|
+
ttl_seconds: Number(value.expiration)
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
try {
|
|
36
|
+
const token = await createToken.mutateAsync({
|
|
37
|
+
workspaceId,
|
|
38
|
+
body
|
|
39
|
+
});
|
|
40
|
+
await queryClient.invalidateQueries({
|
|
41
|
+
queryKey: provisionerTokenQueryKeys.list(workspaceId)
|
|
42
|
+
});
|
|
43
|
+
onCreated(token);
|
|
44
|
+
} catch (error) {
|
|
45
|
+
const mapped = provisionerTokenCreateErrorToFormError(error);
|
|
46
|
+
setFormError(mapped.message);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
return /*#__PURE__*/ _jsxs(_Fragment, {
|
|
51
|
+
children: [
|
|
52
|
+
/*#__PURE__*/ _jsxs(ModalBody, {
|
|
53
|
+
className: "gap-16",
|
|
54
|
+
children: [
|
|
55
|
+
/*#__PURE__*/ _jsxs("form", {
|
|
56
|
+
id: CREATE_PROVISIONER_TOKEN_FORM_ID,
|
|
57
|
+
className: "flex w-full flex-col gap-8",
|
|
58
|
+
noValidate: true,
|
|
59
|
+
onSubmit: (event)=>{
|
|
60
|
+
event.preventDefault();
|
|
61
|
+
event.stopPropagation();
|
|
62
|
+
void form.handleSubmit();
|
|
63
|
+
},
|
|
64
|
+
children: [
|
|
65
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
66
|
+
className: "flex w-full items-end gap-16 max-[640px]:flex-col max-[640px]:items-stretch",
|
|
67
|
+
children: [
|
|
68
|
+
/*#__PURE__*/ _jsx(form.Field, {
|
|
69
|
+
name: "name",
|
|
70
|
+
validators: {
|
|
71
|
+
onBlur: ({ value })=>value.length <= 80 ? undefined : 'Token name must be 80 characters or fewer.'
|
|
72
|
+
},
|
|
73
|
+
children: (field)=>/*#__PURE__*/ _jsx(FormField, {
|
|
74
|
+
className: "flex-1",
|
|
75
|
+
label: "Token name",
|
|
76
|
+
id: "provisioner-token-name",
|
|
77
|
+
error: fieldError(field),
|
|
78
|
+
children: /*#__PURE__*/ _jsx(FormFieldInput, {
|
|
79
|
+
placeholder: "Docker provisioner",
|
|
80
|
+
maxLength: 80,
|
|
81
|
+
value: field.state.value,
|
|
82
|
+
onChange: (event)=>field.handleChange(event.target.value),
|
|
83
|
+
onBlur: field.handleBlur
|
|
84
|
+
})
|
|
85
|
+
})
|
|
86
|
+
}),
|
|
87
|
+
/*#__PURE__*/ _jsx(form.Field, {
|
|
88
|
+
name: "expiration",
|
|
89
|
+
children: (field)=>/*#__PURE__*/ _jsx(FormField, {
|
|
90
|
+
className: "flex-1",
|
|
91
|
+
label: "Expires",
|
|
92
|
+
id: "provisioner-token-expiration",
|
|
93
|
+
error: fieldError(field),
|
|
94
|
+
children: /*#__PURE__*/ _jsx(ExpirationSelect, {
|
|
95
|
+
value: field.state.value,
|
|
96
|
+
onValueChange: (next)=>field.handleChange(next)
|
|
97
|
+
})
|
|
98
|
+
})
|
|
99
|
+
})
|
|
100
|
+
]
|
|
101
|
+
}),
|
|
102
|
+
/*#__PURE__*/ _jsx(form.Subscribe, {
|
|
103
|
+
selector: (state)=>state.values.expiration,
|
|
104
|
+
children: (expiration)=>/*#__PURE__*/ _jsx(Text, {
|
|
105
|
+
size: "sm",
|
|
106
|
+
className: "text-foreground-neutral-muted",
|
|
107
|
+
children: expirationHint(expiration)
|
|
108
|
+
})
|
|
109
|
+
})
|
|
110
|
+
]
|
|
111
|
+
}),
|
|
112
|
+
formError ? /*#__PURE__*/ _jsx(Callout, {
|
|
113
|
+
role: "alert",
|
|
114
|
+
type: "error",
|
|
115
|
+
children: /*#__PURE__*/ _jsxs("div", {
|
|
116
|
+
className: "flex flex-col gap-8",
|
|
117
|
+
children: [
|
|
118
|
+
/*#__PURE__*/ _jsx(Text, {
|
|
119
|
+
size: "sm",
|
|
120
|
+
bold: true,
|
|
121
|
+
children: "Could not create token"
|
|
122
|
+
}),
|
|
123
|
+
/*#__PURE__*/ _jsx(Text, {
|
|
124
|
+
size: "sm",
|
|
125
|
+
children: formError
|
|
126
|
+
})
|
|
127
|
+
]
|
|
128
|
+
})
|
|
129
|
+
}) : null
|
|
130
|
+
]
|
|
131
|
+
}),
|
|
132
|
+
/*#__PURE__*/ _jsx(ModalFooter, {
|
|
133
|
+
children: /*#__PURE__*/ _jsx(Button, {
|
|
134
|
+
type: "submit",
|
|
135
|
+
form: CREATE_PROVISIONER_TOKEN_FORM_ID,
|
|
136
|
+
isLoading: createToken.isPending,
|
|
137
|
+
children: "Create token"
|
|
138
|
+
})
|
|
139
|
+
})
|
|
140
|
+
]
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
export function CreatedProvisionerTokenPanel({ token }) {
|
|
144
|
+
const [copyState, setCopyState] = useState('idle');
|
|
145
|
+
const { copy } = useCopyToClipboard({
|
|
146
|
+
text: token.raw_token,
|
|
147
|
+
onCopy: ()=>{
|
|
148
|
+
setCopyState('copied');
|
|
149
|
+
window.setTimeout(()=>setCopyState('idle'), 1500);
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
async function handleCopy() {
|
|
153
|
+
try {
|
|
154
|
+
await copy();
|
|
155
|
+
} catch {
|
|
156
|
+
setCopyState('failed');
|
|
157
|
+
window.setTimeout(()=>setCopyState('idle'), 2500);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return /*#__PURE__*/ _jsx(Callout, {
|
|
161
|
+
type: "success",
|
|
162
|
+
variant: "secondary",
|
|
163
|
+
icon: null,
|
|
164
|
+
children: /*#__PURE__*/ _jsxs(CalloutContent, {
|
|
165
|
+
className: "flex flex-col gap-12",
|
|
166
|
+
children: [
|
|
167
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
168
|
+
className: "flex flex-col gap-2",
|
|
169
|
+
children: [
|
|
170
|
+
/*#__PURE__*/ _jsx(CalloutTitle, {
|
|
171
|
+
className: "mb-0",
|
|
172
|
+
children: "Token created"
|
|
173
|
+
}),
|
|
174
|
+
/*#__PURE__*/ _jsx(CalloutDescription, {
|
|
175
|
+
children: "Copy this provisioner token now. It will not be shown again."
|
|
176
|
+
})
|
|
177
|
+
]
|
|
178
|
+
}),
|
|
179
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
180
|
+
className: "flex items-center gap-8 max-[640px]:flex-col max-[640px]:items-stretch",
|
|
181
|
+
children: [
|
|
182
|
+
/*#__PURE__*/ _jsx(Code, {
|
|
183
|
+
variant: "paragraph",
|
|
184
|
+
className: "min-w-0 flex-1 break-all",
|
|
185
|
+
children: token.raw_token
|
|
186
|
+
}),
|
|
187
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
188
|
+
size: "sm",
|
|
189
|
+
variant: "secondary",
|
|
190
|
+
iconLeft: "fileCopyLine",
|
|
191
|
+
onClick: ()=>void handleCopy(),
|
|
192
|
+
children: copyState === 'copied' ? 'Copied' : 'Copy'
|
|
193
|
+
})
|
|
194
|
+
]
|
|
195
|
+
}),
|
|
196
|
+
copyState === 'failed' ? /*#__PURE__*/ _jsx(Text, {
|
|
197
|
+
size: "sm",
|
|
198
|
+
className: "text-foreground-neutral-muted",
|
|
199
|
+
children: "Copy failed: select and copy manually."
|
|
200
|
+
}) : null
|
|
201
|
+
]
|
|
202
|
+
})
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
//# sourceMappingURL=create-provisioner-token-form.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/create-provisioner-token-form.tsx"],"sourcesContent":["import type {CreateProvisionerTokenResponseDto} from '@shipfox/api-runners-dto';\nimport {Button} from '@shipfox/react-ui/button';\nimport {Callout, CalloutContent, CalloutDescription, CalloutTitle} from '@shipfox/react-ui/callout';\nimport {FormField, FormFieldInput, fieldError} from '@shipfox/react-ui/form-field';\nimport {useCopyToClipboard} from '@shipfox/react-ui/hooks';\nimport {ModalBody, ModalFooter} from '@shipfox/react-ui/modal';\nimport {Code, Text} from '@shipfox/react-ui/typography';\nimport {useForm} from '@tanstack/react-form';\nimport {useQueryClient} from '@tanstack/react-query';\nimport {useState} from 'react';\nimport {\n provisionerTokenQueryKeys,\n useCreateProvisionerTokenMutation,\n} from '#hooks/api/provisioner-tokens.js';\nimport {provisionerTokenCreateErrorToFormError} from './provisioner-token-form-errors.js';\nimport {\n ExpirationSelect,\n expirationHint,\n type TokenExpirationOption,\n} from './token-expiration-select.js';\n\nexport const CREATE_PROVISIONER_TOKEN_FORM_ID = 'create-provisioner-token-form';\n\nexport function CreateProvisionerTokenForm({\n workspaceId,\n onCreated,\n}: {\n workspaceId: string;\n onCreated: (token: CreateProvisionerTokenResponseDto) => void;\n}) {\n const queryClient = useQueryClient();\n const createToken = useCreateProvisionerTokenMutation();\n const [formError, setFormError] = useState<string | undefined>();\n\n const form = useForm({\n defaultValues: {name: '', expiration: '86400' as TokenExpirationOption},\n onSubmit: async ({value}) => {\n setFormError(undefined);\n const trimmedName = value.name.trim();\n const body = {\n ...(trimmedName ? {name: trimmedName} : {}),\n ...(value.expiration === 'never' ? {} : {ttl_seconds: Number(value.expiration)}),\n };\n\n try {\n const token = await createToken.mutateAsync({workspaceId, body});\n await queryClient.invalidateQueries({\n queryKey: provisionerTokenQueryKeys.list(workspaceId),\n });\n onCreated(token);\n } catch (error) {\n const mapped = provisionerTokenCreateErrorToFormError(error);\n setFormError(mapped.message);\n }\n },\n });\n\n return (\n <>\n <ModalBody className=\"gap-16\">\n <form\n id={CREATE_PROVISIONER_TOKEN_FORM_ID}\n className=\"flex w-full flex-col gap-8\"\n noValidate\n onSubmit={(event) => {\n event.preventDefault();\n event.stopPropagation();\n void form.handleSubmit();\n }}\n >\n <div className=\"flex w-full items-end gap-16 max-[640px]:flex-col max-[640px]:items-stretch\">\n <form.Field\n name=\"name\"\n validators={{\n onBlur: ({value}) =>\n value.length <= 80 ? undefined : 'Token name must be 80 characters or fewer.',\n }}\n >\n {(field) => (\n <FormField\n className=\"flex-1\"\n label=\"Token name\"\n id=\"provisioner-token-name\"\n error={fieldError(field)}\n >\n <FormFieldInput\n placeholder=\"Docker provisioner\"\n maxLength={80}\n value={field.state.value}\n onChange={(event) => field.handleChange(event.target.value)}\n onBlur={field.handleBlur}\n />\n </FormField>\n )}\n </form.Field>\n <form.Field name=\"expiration\">\n {(field) => (\n <FormField\n className=\"flex-1\"\n label=\"Expires\"\n id=\"provisioner-token-expiration\"\n error={fieldError(field)}\n >\n <ExpirationSelect\n value={field.state.value}\n onValueChange={(next) => field.handleChange(next)}\n />\n </FormField>\n )}\n </form.Field>\n </div>\n <form.Subscribe selector={(state) => state.values.expiration}>\n {(expiration) => (\n <Text size=\"sm\" className=\"text-foreground-neutral-muted\">\n {expirationHint(expiration)}\n </Text>\n )}\n </form.Subscribe>\n </form>\n {formError ? (\n <Callout role=\"alert\" type=\"error\">\n <div className=\"flex flex-col gap-8\">\n <Text size=\"sm\" bold>\n Could not create token\n </Text>\n <Text size=\"sm\">{formError}</Text>\n </div>\n </Callout>\n ) : null}\n </ModalBody>\n <ModalFooter>\n <Button\n type=\"submit\"\n form={CREATE_PROVISIONER_TOKEN_FORM_ID}\n isLoading={createToken.isPending}\n >\n Create token\n </Button>\n </ModalFooter>\n </>\n );\n}\n\nexport function CreatedProvisionerTokenPanel({token}: {token: CreateProvisionerTokenResponseDto}) {\n const [copyState, setCopyState] = useState<'idle' | 'copied' | 'failed'>('idle');\n const {copy} = useCopyToClipboard({\n text: token.raw_token,\n onCopy: () => {\n setCopyState('copied');\n window.setTimeout(() => setCopyState('idle'), 1500);\n },\n });\n\n async function handleCopy() {\n try {\n await copy();\n } catch {\n setCopyState('failed');\n window.setTimeout(() => setCopyState('idle'), 2500);\n }\n }\n\n return (\n <Callout type=\"success\" variant=\"secondary\" icon={null}>\n <CalloutContent className=\"flex flex-col gap-12\">\n <div className=\"flex flex-col gap-2\">\n <CalloutTitle className=\"mb-0\">Token created</CalloutTitle>\n <CalloutDescription>\n Copy this provisioner token now. It will not be shown again.\n </CalloutDescription>\n </div>\n <div className=\"flex items-center gap-8 max-[640px]:flex-col max-[640px]:items-stretch\">\n <Code variant=\"paragraph\" className=\"min-w-0 flex-1 break-all\">\n {token.raw_token}\n </Code>\n <Button\n size=\"sm\"\n variant=\"secondary\"\n iconLeft=\"fileCopyLine\"\n onClick={() => void handleCopy()}\n >\n {copyState === 'copied' ? 'Copied' : 'Copy'}\n </Button>\n </div>\n {copyState === 'failed' ? (\n <Text size=\"sm\" className=\"text-foreground-neutral-muted\">\n Copy failed: select and copy manually.\n </Text>\n ) : null}\n </CalloutContent>\n </Callout>\n );\n}\n"],"names":["Button","Callout","CalloutContent","CalloutDescription","CalloutTitle","FormField","FormFieldInput","fieldError","useCopyToClipboard","ModalBody","ModalFooter","Code","Text","useForm","useQueryClient","useState","provisionerTokenQueryKeys","useCreateProvisionerTokenMutation","provisionerTokenCreateErrorToFormError","ExpirationSelect","expirationHint","CREATE_PROVISIONER_TOKEN_FORM_ID","CreateProvisionerTokenForm","workspaceId","onCreated","queryClient","createToken","formError","setFormError","form","defaultValues","name","expiration","onSubmit","value","undefined","trimmedName","trim","body","ttl_seconds","Number","token","mutateAsync","invalidateQueries","queryKey","list","error","mapped","message","className","id","noValidate","event","preventDefault","stopPropagation","handleSubmit","div","Field","validators","onBlur","length","field","label","placeholder","maxLength","state","onChange","handleChange","target","handleBlur","onValueChange","next","Subscribe","selector","values","size","role","type","bold","isLoading","isPending","CreatedProvisionerTokenPanel","copyState","setCopyState","copy","text","raw_token","onCopy","window","setTimeout","handleCopy","variant","icon","iconLeft","onClick"],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export type ManualRegistrationTokenCreateFormErrorMapping = {
|
|
2
|
+
kind: 'form';
|
|
3
|
+
message: string;
|
|
4
|
+
};
|
|
5
|
+
export declare function manualRegistrationTokenCreateErrorToFormError(error: unknown): ManualRegistrationTokenCreateFormErrorMapping;
|
|
6
|
+
//# sourceMappingURL=form-errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"form-errors.d.ts","sourceRoot":"","sources":["../../src/components/form-errors.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,6CAA6C,GAAG;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAC,CAAC;AAE5F,wBAAgB,6CAA6C,CAC3D,KAAK,EAAE,OAAO,GACb,6CAA6C,CAE/C"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { manualRegistrationTokenErrorMessage } from './manual-registration-token-errors.js';
|
|
2
|
+
export function manualRegistrationTokenCreateErrorToFormError(error) {
|
|
3
|
+
return {
|
|
4
|
+
kind: 'form',
|
|
5
|
+
message: manualRegistrationTokenErrorMessage(error)
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
//# sourceMappingURL=form-errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/form-errors.ts"],"sourcesContent":["import {manualRegistrationTokenErrorMessage} from './manual-registration-token-errors.js';\n\nexport type ManualRegistrationTokenCreateFormErrorMapping = {kind: 'form'; message: string};\n\nexport function manualRegistrationTokenCreateErrorToFormError(\n error: unknown,\n): ManualRegistrationTokenCreateFormErrorMapping {\n return {kind: 'form', message: manualRegistrationTokenErrorMessage(error)};\n}\n"],"names":["manualRegistrationTokenErrorMessage","manualRegistrationTokenCreateErrorToFormError","error","kind","message"],"mappings":"AAAA,SAAQA,mCAAmC,QAAO,wCAAwC;AAI1F,OAAO,SAASC,8CACdC,KAAc;IAEd,OAAO;QAACC,MAAM;QAAQC,SAASJ,oCAAoCE;IAAM;AAC3E"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manual-registration-token-errors.d.ts","sourceRoot":"","sources":["../../src/components/manual-registration-token-errors.ts"],"names":[],"mappings":"AAEA,wBAAgB,mCAAmC,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAU1E"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ApiError } from '@shipfox/client-api';
|
|
2
|
+
export function manualRegistrationTokenErrorMessage(error) {
|
|
3
|
+
if (error instanceof ApiError) {
|
|
4
|
+
// `network-error` carries the raw request URL in its message; never surface it.
|
|
5
|
+
if (error.code === 'network-error') {
|
|
6
|
+
return "We couldn't reach the server. Check your connection and try again.";
|
|
7
|
+
}
|
|
8
|
+
return error.message;
|
|
9
|
+
}
|
|
10
|
+
if (error instanceof Error) return error.message;
|
|
11
|
+
return 'Something went wrong. Try again.';
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
//# sourceMappingURL=manual-registration-token-errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/manual-registration-token-errors.ts"],"sourcesContent":["import {ApiError} from '@shipfox/client-api';\n\nexport function manualRegistrationTokenErrorMessage(error: unknown): string {\n if (error instanceof ApiError) {\n // `network-error` carries the raw request URL in its message; never surface it.\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 if (error instanceof Error) return error.message;\n return 'Something went wrong. Try again.';\n}\n"],"names":["ApiError","manualRegistrationTokenErrorMessage","error","code","message","Error"],"mappings":"AAAA,SAAQA,QAAQ,QAAO,sBAAsB;AAE7C,OAAO,SAASC,oCAAoCC,KAAc;IAChE,IAAIA,iBAAiBF,UAAU;QAC7B,gFAAgF;QAChF,IAAIE,MAAMC,IAAI,KAAK,iBAAiB;YAClC,OAAO;QACT;QACA,OAAOD,MAAME,OAAO;IACtB;IACA,IAAIF,iBAAiBG,OAAO,OAAOH,MAAME,OAAO;IAChD,OAAO;AACT"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ManualRegistrationTokenDto } from '@shipfox/api-runners-dto';
|
|
2
|
+
export declare function formatManualRegistrationTokenDate(value: string | null): string;
|
|
3
|
+
export declare function formatManualRegistrationTokenTimestamp(value: string | null): string | undefined;
|
|
4
|
+
export declare function manualRegistrationTokenDisplayName(token: Pick<ManualRegistrationTokenDto, 'name'>): string;
|
|
5
|
+
//# sourceMappingURL=manual-registration-token-format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manual-registration-token-format.d.ts","sourceRoot":"","sources":["../../src/components/manual-registration-token-format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,0BAA0B,EAAC,MAAM,0BAA0B,CAAC;AAGzE,wBAAgB,iCAAiC,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAG9E;AAED,wBAAgB,sCAAsC,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,CAG/F;AAED,wBAAgB,kCAAkC,CAChD,KAAK,EAAE,IAAI,CAAC,0BAA0B,EAAE,MAAM,CAAC,GAC9C,MAAM,CAER"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { formatDate, formatTimestamp } from '@shipfox/react-ui/utils';
|
|
2
|
+
export function formatManualRegistrationTokenDate(value) {
|
|
3
|
+
if (!value) return 'Never';
|
|
4
|
+
return formatDate(value);
|
|
5
|
+
}
|
|
6
|
+
export function formatManualRegistrationTokenTimestamp(value) {
|
|
7
|
+
if (!value) return undefined;
|
|
8
|
+
return formatTimestamp(value);
|
|
9
|
+
}
|
|
10
|
+
export function manualRegistrationTokenDisplayName(token) {
|
|
11
|
+
return token.name || 'Unnamed token';
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
//# sourceMappingURL=manual-registration-token-format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/manual-registration-token-format.ts"],"sourcesContent":["import type {ManualRegistrationTokenDto} from '@shipfox/api-runners-dto';\nimport {formatDate, formatTimestamp} from '@shipfox/react-ui/utils';\n\nexport function formatManualRegistrationTokenDate(value: string | null): string {\n if (!value) return 'Never';\n return formatDate(value);\n}\n\nexport function formatManualRegistrationTokenTimestamp(value: string | null): string | undefined {\n if (!value) return undefined;\n return formatTimestamp(value);\n}\n\nexport function manualRegistrationTokenDisplayName(\n token: Pick<ManualRegistrationTokenDto, 'name'>,\n): string {\n return token.name || 'Unnamed token';\n}\n"],"names":["formatDate","formatTimestamp","formatManualRegistrationTokenDate","value","formatManualRegistrationTokenTimestamp","undefined","manualRegistrationTokenDisplayName","token","name"],"mappings":"AACA,SAAQA,UAAU,EAAEC,eAAe,QAAO,0BAA0B;AAEpE,OAAO,SAASC,kCAAkCC,KAAoB;IACpE,IAAI,CAACA,OAAO,OAAO;IACnB,OAAOH,WAAWG;AACpB;AAEA,OAAO,SAASC,uCAAuCD,KAAoB;IACzE,IAAI,CAACA,OAAO,OAAOE;IACnB,OAAOJ,gBAAgBE;AACzB;AAEA,OAAO,SAASG,mCACdC,KAA+C;IAE/C,OAAOA,MAAMC,IAAI,IAAI;AACvB"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ManualRegistrationTokenDto } from '@shipfox/api-runners-dto';
|
|
2
|
+
export declare function ManualRegistrationTokenList({ workspaceId, tokens, }: {
|
|
3
|
+
workspaceId: string;
|
|
4
|
+
tokens: ManualRegistrationTokenDto[];
|
|
5
|
+
}): import("react").JSX.Element;
|
|
6
|
+
export declare function EmptyManualRegistrationTokens(): import("react").JSX.Element;
|
|
7
|
+
export declare function ManualRegistrationTokenTableSkeleton(): import("react").JSX.Element;
|
|
8
|
+
//# sourceMappingURL=manual-registration-token-list.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manual-registration-token-list.d.ts","sourceRoot":"","sources":["../../src/components/manual-registration-token-list.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,0BAA0B,EAAC,MAAM,0BAA0B,CAAC;AA2CzE,wBAAgB,2BAA2B,CAAC,EAC1C,WAAW,EACX,MAAM,GACP,EAAE;IACD,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,0BAA0B,EAAE,CAAC;CACtC,+BA4EA;AAkGD,wBAAgB,6BAA6B,gCAQ5C;AAED,wBAAgB,oCAAoC,gCAYnD"}
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { Button, IconButton } from '@shipfox/react-ui/button';
|
|
3
|
+
import { Callout } from '@shipfox/react-ui/callout';
|
|
4
|
+
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@shipfox/react-ui/dropdown-menu';
|
|
5
|
+
import { EmptyState } from '@shipfox/react-ui/empty-state';
|
|
6
|
+
import { Modal, ModalBody, ModalContent, ModalFooter, ModalHeader, ModalTitle } from '@shipfox/react-ui/modal';
|
|
7
|
+
import { Skeleton } from '@shipfox/react-ui/skeleton';
|
|
8
|
+
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@shipfox/react-ui/table';
|
|
9
|
+
import { Code, Text } from '@shipfox/react-ui/typography';
|
|
10
|
+
import { useQueryClient } from '@tanstack/react-query';
|
|
11
|
+
import { useState } from 'react';
|
|
12
|
+
import { manualRegistrationTokenQueryKeys, useRevokeManualRegistrationTokenMutation } from '#hooks/api/manual-registration-tokens.js';
|
|
13
|
+
import { manualRegistrationTokenErrorMessage } from './manual-registration-token-errors.js';
|
|
14
|
+
import { formatManualRegistrationTokenDate, formatManualRegistrationTokenTimestamp, manualRegistrationTokenDisplayName } from './manual-registration-token-format.js';
|
|
15
|
+
import { TokenDate } from './token-date.js';
|
|
16
|
+
import { TokenName } from './token-name.js';
|
|
17
|
+
export function ManualRegistrationTokenList({ workspaceId, tokens }) {
|
|
18
|
+
return /*#__PURE__*/ _jsxs(_Fragment, {
|
|
19
|
+
children: [
|
|
20
|
+
/*#__PURE__*/ _jsx("div", {
|
|
21
|
+
className: "max-[760px]:hidden",
|
|
22
|
+
children: /*#__PURE__*/ _jsxs(Table, {
|
|
23
|
+
className: "table-fixed",
|
|
24
|
+
children: [
|
|
25
|
+
/*#__PURE__*/ _jsx(TableHeader, {
|
|
26
|
+
children: /*#__PURE__*/ _jsxs(TableRow, {
|
|
27
|
+
children: [
|
|
28
|
+
/*#__PURE__*/ _jsx(TableHead, {
|
|
29
|
+
className: "w-[34%]",
|
|
30
|
+
children: "Name"
|
|
31
|
+
}),
|
|
32
|
+
/*#__PURE__*/ _jsx(TableHead, {
|
|
33
|
+
children: "Prefix"
|
|
34
|
+
}),
|
|
35
|
+
/*#__PURE__*/ _jsx(TableHead, {
|
|
36
|
+
className: "w-128",
|
|
37
|
+
children: "Expires"
|
|
38
|
+
}),
|
|
39
|
+
/*#__PURE__*/ _jsx(TableHead, {
|
|
40
|
+
className: "w-128",
|
|
41
|
+
children: "Created"
|
|
42
|
+
}),
|
|
43
|
+
/*#__PURE__*/ _jsx(TableHead, {
|
|
44
|
+
className: "w-80 text-right",
|
|
45
|
+
children: "Actions"
|
|
46
|
+
})
|
|
47
|
+
]
|
|
48
|
+
})
|
|
49
|
+
}),
|
|
50
|
+
/*#__PURE__*/ _jsx(TableBody, {
|
|
51
|
+
children: tokens.map((token)=>/*#__PURE__*/ _jsxs(TableRow, {
|
|
52
|
+
children: [
|
|
53
|
+
/*#__PURE__*/ _jsx(TableCell, {
|
|
54
|
+
children: /*#__PURE__*/ _jsx(TokenName, {
|
|
55
|
+
name: manualRegistrationTokenDisplayName(token)
|
|
56
|
+
})
|
|
57
|
+
}),
|
|
58
|
+
/*#__PURE__*/ _jsx(TableCell, {
|
|
59
|
+
children: /*#__PURE__*/ _jsx(Code, {
|
|
60
|
+
variant: "paragraph",
|
|
61
|
+
className: "block truncate",
|
|
62
|
+
children: token.prefix
|
|
63
|
+
})
|
|
64
|
+
}),
|
|
65
|
+
/*#__PURE__*/ _jsx(TableCell, {
|
|
66
|
+
children: /*#__PURE__*/ _jsx(ManualRegistrationTokenDate, {
|
|
67
|
+
value: token.expires_at
|
|
68
|
+
})
|
|
69
|
+
}),
|
|
70
|
+
/*#__PURE__*/ _jsx(TableCell, {
|
|
71
|
+
children: /*#__PURE__*/ _jsx(ManualRegistrationTokenDate, {
|
|
72
|
+
value: token.created_at
|
|
73
|
+
})
|
|
74
|
+
}),
|
|
75
|
+
/*#__PURE__*/ _jsx(TableCell, {
|
|
76
|
+
className: "text-right",
|
|
77
|
+
children: /*#__PURE__*/ _jsx(RevokeManualRegistrationTokenButton, {
|
|
78
|
+
workspaceId: workspaceId,
|
|
79
|
+
token: token
|
|
80
|
+
})
|
|
81
|
+
})
|
|
82
|
+
]
|
|
83
|
+
}, token.id))
|
|
84
|
+
})
|
|
85
|
+
]
|
|
86
|
+
})
|
|
87
|
+
}),
|
|
88
|
+
/*#__PURE__*/ _jsx("ul", {
|
|
89
|
+
className: "hidden flex-col gap-10 max-[760px]:flex",
|
|
90
|
+
"aria-label": "Manual registration tokens",
|
|
91
|
+
children: tokens.map((token)=>/*#__PURE__*/ _jsxs("li", {
|
|
92
|
+
className: "rounded-8 border border-border-neutral-base bg-background-neutral-base p-14",
|
|
93
|
+
children: [
|
|
94
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
95
|
+
className: "flex items-start justify-between gap-12",
|
|
96
|
+
children: [
|
|
97
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
98
|
+
className: "min-w-0 flex-1",
|
|
99
|
+
children: [
|
|
100
|
+
/*#__PURE__*/ _jsx(TokenName, {
|
|
101
|
+
name: manualRegistrationTokenDisplayName(token)
|
|
102
|
+
}),
|
|
103
|
+
/*#__PURE__*/ _jsx(Code, {
|
|
104
|
+
variant: "paragraph",
|
|
105
|
+
className: "block truncate text-foreground-neutral-muted",
|
|
106
|
+
children: token.prefix
|
|
107
|
+
})
|
|
108
|
+
]
|
|
109
|
+
}),
|
|
110
|
+
/*#__PURE__*/ _jsx(RevokeManualRegistrationTokenButton, {
|
|
111
|
+
workspaceId: workspaceId,
|
|
112
|
+
token: token
|
|
113
|
+
})
|
|
114
|
+
]
|
|
115
|
+
}),
|
|
116
|
+
/*#__PURE__*/ _jsxs("dl", {
|
|
117
|
+
className: "mt-12 grid grid-cols-2 gap-10 text-sm",
|
|
118
|
+
children: [
|
|
119
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
120
|
+
children: [
|
|
121
|
+
/*#__PURE__*/ _jsx("dt", {
|
|
122
|
+
className: "text-foreground-neutral-muted",
|
|
123
|
+
children: "Expires"
|
|
124
|
+
}),
|
|
125
|
+
/*#__PURE__*/ _jsx("dd", {
|
|
126
|
+
children: /*#__PURE__*/ _jsx(ManualRegistrationTokenDate, {
|
|
127
|
+
value: token.expires_at
|
|
128
|
+
})
|
|
129
|
+
})
|
|
130
|
+
]
|
|
131
|
+
}),
|
|
132
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
133
|
+
children: [
|
|
134
|
+
/*#__PURE__*/ _jsx("dt", {
|
|
135
|
+
className: "text-foreground-neutral-muted",
|
|
136
|
+
children: "Created"
|
|
137
|
+
}),
|
|
138
|
+
/*#__PURE__*/ _jsx("dd", {
|
|
139
|
+
children: /*#__PURE__*/ _jsx(ManualRegistrationTokenDate, {
|
|
140
|
+
value: token.created_at
|
|
141
|
+
})
|
|
142
|
+
})
|
|
143
|
+
]
|
|
144
|
+
})
|
|
145
|
+
]
|
|
146
|
+
})
|
|
147
|
+
]
|
|
148
|
+
}, token.id))
|
|
149
|
+
})
|
|
150
|
+
]
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
function ManualRegistrationTokenDate({ value }) {
|
|
154
|
+
return /*#__PURE__*/ _jsx(TokenDate, {
|
|
155
|
+
value: value,
|
|
156
|
+
date: formatManualRegistrationTokenDate(value),
|
|
157
|
+
timestamp: formatManualRegistrationTokenTimestamp(value)
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
function RevokeManualRegistrationTokenButton({ workspaceId, token }) {
|
|
161
|
+
const queryClient = useQueryClient();
|
|
162
|
+
const revokeToken = useRevokeManualRegistrationTokenMutation();
|
|
163
|
+
const [open, setOpen] = useState(false);
|
|
164
|
+
const tokenName = manualRegistrationTokenDisplayName(token);
|
|
165
|
+
async function handleRevoke() {
|
|
166
|
+
try {
|
|
167
|
+
await revokeToken.mutateAsync({
|
|
168
|
+
workspaceId,
|
|
169
|
+
tokenId: token.id
|
|
170
|
+
});
|
|
171
|
+
await queryClient.invalidateQueries({
|
|
172
|
+
queryKey: manualRegistrationTokenQueryKeys.list(workspaceId)
|
|
173
|
+
});
|
|
174
|
+
setOpen(false);
|
|
175
|
+
} catch {
|
|
176
|
+
// React Query stores the error for the inline modal alert.
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
function handleOpenChange(nextOpen) {
|
|
180
|
+
setOpen(nextOpen);
|
|
181
|
+
if (nextOpen) {
|
|
182
|
+
revokeToken.reset();
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
function openRevokeConfirmation() {
|
|
186
|
+
revokeToken.reset();
|
|
187
|
+
setOpen(true);
|
|
188
|
+
}
|
|
189
|
+
return /*#__PURE__*/ _jsxs(_Fragment, {
|
|
190
|
+
children: [
|
|
191
|
+
/*#__PURE__*/ _jsxs(DropdownMenu, {
|
|
192
|
+
children: [
|
|
193
|
+
/*#__PURE__*/ _jsx(DropdownMenuTrigger, {
|
|
194
|
+
asChild: true,
|
|
195
|
+
children: /*#__PURE__*/ _jsx(IconButton, {
|
|
196
|
+
type: "button",
|
|
197
|
+
size: "sm",
|
|
198
|
+
variant: "transparent",
|
|
199
|
+
icon: "more2Line",
|
|
200
|
+
"aria-label": `Open ${tokenName} registration token actions`
|
|
201
|
+
})
|
|
202
|
+
}),
|
|
203
|
+
/*#__PURE__*/ _jsx(DropdownMenuContent, {
|
|
204
|
+
align: "end",
|
|
205
|
+
size: "sm",
|
|
206
|
+
children: /*#__PURE__*/ _jsx(DropdownMenuItem, {
|
|
207
|
+
onSelect: openRevokeConfirmation,
|
|
208
|
+
children: "Revoke token"
|
|
209
|
+
})
|
|
210
|
+
})
|
|
211
|
+
]
|
|
212
|
+
}),
|
|
213
|
+
/*#__PURE__*/ _jsx(Modal, {
|
|
214
|
+
open: open,
|
|
215
|
+
onOpenChange: handleOpenChange,
|
|
216
|
+
children: /*#__PURE__*/ _jsxs(ModalContent, {
|
|
217
|
+
"aria-describedby": undefined,
|
|
218
|
+
className: "max-w-[420px]",
|
|
219
|
+
children: [
|
|
220
|
+
/*#__PURE__*/ _jsx(ModalTitle, {
|
|
221
|
+
className: "sr-only",
|
|
222
|
+
children: "Revoke token"
|
|
223
|
+
}),
|
|
224
|
+
/*#__PURE__*/ _jsx(ModalHeader, {
|
|
225
|
+
title: "Revoke token?"
|
|
226
|
+
}),
|
|
227
|
+
/*#__PURE__*/ _jsxs(ModalBody, {
|
|
228
|
+
className: "gap-16",
|
|
229
|
+
children: [
|
|
230
|
+
/*#__PURE__*/ _jsxs(Text, {
|
|
231
|
+
size: "sm",
|
|
232
|
+
className: "text-foreground-neutral-muted",
|
|
233
|
+
children: [
|
|
234
|
+
tokenName,
|
|
235
|
+
" will stop creating new runner sessions. Existing sessions and job leases expire on their own."
|
|
236
|
+
]
|
|
237
|
+
}),
|
|
238
|
+
revokeToken.isError ? /*#__PURE__*/ _jsx(Callout, {
|
|
239
|
+
role: "alert",
|
|
240
|
+
type: "error",
|
|
241
|
+
children: /*#__PURE__*/ _jsx(Text, {
|
|
242
|
+
size: "sm",
|
|
243
|
+
children: manualRegistrationTokenErrorMessage(revokeToken.error)
|
|
244
|
+
})
|
|
245
|
+
}) : null
|
|
246
|
+
]
|
|
247
|
+
}),
|
|
248
|
+
/*#__PURE__*/ _jsxs(ModalFooter, {
|
|
249
|
+
children: [
|
|
250
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
251
|
+
size: "sm",
|
|
252
|
+
variant: "secondary",
|
|
253
|
+
onClick: ()=>setOpen(false),
|
|
254
|
+
children: "Cancel"
|
|
255
|
+
}),
|
|
256
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
257
|
+
size: "sm",
|
|
258
|
+
variant: "danger",
|
|
259
|
+
isLoading: revokeToken.isPending,
|
|
260
|
+
onClick: handleRevoke,
|
|
261
|
+
children: "Revoke"
|
|
262
|
+
})
|
|
263
|
+
]
|
|
264
|
+
})
|
|
265
|
+
]
|
|
266
|
+
})
|
|
267
|
+
})
|
|
268
|
+
]
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
export function EmptyManualRegistrationTokens() {
|
|
272
|
+
return /*#__PURE__*/ _jsx(EmptyState, {
|
|
273
|
+
icon: "key2Line",
|
|
274
|
+
title: "No usable manual registration tokens",
|
|
275
|
+
description: "Create a token to connect a runner to this workspace."
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
export function ManualRegistrationTokenTableSkeleton() {
|
|
279
|
+
return /*#__PURE__*/ _jsx("div", {
|
|
280
|
+
role: "status",
|
|
281
|
+
"aria-label": "Loading manual registration tokens",
|
|
282
|
+
className: "flex flex-col gap-8",
|
|
283
|
+
children: [
|
|
284
|
+
0,
|
|
285
|
+
1,
|
|
286
|
+
2
|
|
287
|
+
].map((row)=>/*#__PURE__*/ _jsx(Skeleton, {
|
|
288
|
+
className: "h-44 w-full"
|
|
289
|
+
}, row))
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
//# sourceMappingURL=manual-registration-token-list.js.map
|