|
1 | 1 | <script> |
2 | 2 | import { onDestroy } from 'svelte'; |
3 | 3 | import { |
4 | | - IconCheck as Check, |
5 | | - IconCopy as Copy, |
6 | | - IconKey as Key, |
7 | 4 | IconRefresh as Refresh, |
8 | 5 | IconServer as Server, |
9 | 6 | IconX as X, |
10 | 7 | } from '@tabler/icons-svelte-runes'; |
11 | 8 | import { api } from '../../api.js'; |
12 | 9 | import AlertBox from '../../components/AlertBox.svelte'; |
| 10 | + import CopyButton from '../../components/CopyButton.svelte'; |
13 | 11 | import Badge from '../../components/Badge.svelte'; |
14 | 12 | import Button from '../../components/Button.svelte'; |
15 | 13 | import Card from '../../components/Card.svelte'; |
|
35 | 33 | let error = $state(''); |
36 | 34 | let installCommand = $state(''); |
37 | 35 | let plaintextToken = $state(''); |
38 | | - let copied = $state(''); |
39 | 36 | let setupStatus = $state('idle'); |
40 | 37 | let runnerName = $state(''); |
41 | 38 | let pollTimer = null; |
|
187 | 184 | if (!canMint) return; |
188 | 185 | minting = true; |
189 | 186 | error = ''; |
190 | | - copied = ''; |
191 | 187 | try { |
192 | 188 | if (pendingTokenId) await revokePending(); |
193 | 189 | const instances = await api.runnerPools.listWorkspaceInstances( |
|
226 | 222 | cancelling = false; |
227 | 223 | } |
228 | 224 | } |
229 | | -
|
230 | | - async function copy(value, kind) { |
231 | | - try { |
232 | | - await navigator.clipboard.writeText(value); |
233 | | - copied = kind; |
234 | | - window.setTimeout(() => { |
235 | | - if (copied === kind) copied = ''; |
236 | | - }, 2_000); |
237 | | - } catch { |
238 | | - error = 'Clipboard access is unavailable. Select and copy the value manually.'; |
239 | | - } |
240 | | - } |
241 | 225 | </script> |
242 | 226 |
|
243 | 227 | <Card variant="outlined" padding="default" dataTestid="agent-runner-setup"> |
|
306 | 290 | <span class="text-sm font-medium" style="color: var(--ds-text);"> |
307 | 291 | Run on the runner machine |
308 | 292 | </span> |
309 | | - <Button |
310 | | - variant="secondary" |
311 | | - size="small" |
312 | | - icon={copied === 'command' ? Check : Copy} |
| 293 | + <CopyButton |
| 294 | + getText={() => installCommand} |
| 295 | + label="Copy command" |
| 296 | + copiedLabel="Copied" |
313 | 297 | dataTestid="agent-runner-copy-command" |
314 | | - onclick={() => copy(installCommand, 'command')} |
315 | | - > |
316 | | - {copied === 'command' ? 'Copied' : 'Copy command'} |
317 | | - </Button> |
| 298 | + onError={() => (error = 'Clipboard access is unavailable. Select and copy the value manually.')} |
| 299 | + /> |
318 | 300 | </div> |
319 | 301 | <code |
320 | 302 | class="block max-h-40 overflow-auto whitespace-pre-wrap break-all rounded-md border p-3 text-xs" |
|
327 | 309 | <span class="text-sm font-medium" style="color: var(--ds-text);"> |
328 | 310 | One-time registration token |
329 | 311 | </span> |
330 | | - <Button |
331 | | - variant="secondary" |
332 | | - size="small" |
333 | | - icon={copied === 'token' ? Check : Key} |
| 312 | + <CopyButton |
| 313 | + getText={() => plaintextToken} |
| 314 | + label="Copy token" |
| 315 | + copiedLabel="Copied" |
334 | 316 | dataTestid="agent-runner-copy-token" |
335 | | - onclick={() => copy(plaintextToken, 'token')} |
336 | | - > |
337 | | - {copied === 'token' ? 'Copied' : 'Copy token'} |
338 | | - </Button> |
| 317 | + onError={() => (error = 'Clipboard access is unavailable. Select and copy the value manually.')} |
| 318 | + /> |
339 | 319 | </div> |
340 | 320 | <code |
341 | 321 | class="block overflow-auto break-all rounded-md border p-3 text-xs" |
|
0 commit comments