diff --git a/app/components/form/fields/SshKeysField.tsx b/app/components/form/fields/SshKeysField.tsx index 45603548a..e03d4d2c7 100644 --- a/app/components/form/fields/SshKeysField.tsx +++ b/app/components/form/fields/SshKeysField.tsx @@ -55,11 +55,11 @@ export function SshKeysField({ control: Control isSubmitting: boolean }) { - const keys = usePrefetchedQuery(q(api.currentUserSshKeyList, {})).data?.items || [] + const allKeys = usePrefetchedQuery(q(api.currentUserSshKeyList, {})).data.items const [showAddSshKey, setShowAddSshKey] = useState(false) const { - field: { value, onChange }, + field: { value: selectedKeys, onChange }, fieldState: { error }, } = useController({ control, @@ -73,6 +73,8 @@ export function SshKeysField({ }, }) + const allAreSelected = allKeys.length === selectedKeys.length + return (
@@ -81,11 +83,11 @@ export function SshKeysField({ SSH keys can be added and removed in your user settings
- {keys.length > 0 ? ( + {allKeys.length > 0 ? ( <>
- {keys.map((key) => ( + {allKeys.map((key) => ( 0 && value.length < keys.length} + checked={allAreSelected} + indeterminate={selectedKeys.length > 0 && !allAreSelected} // if fewer than all are checked, check all. if all are checked, check none - onChange={() => - onChange(value.length < keys.length ? keys.map((key) => key.id) : []) - } + onChange={() => onChange(allAreSelected ? [] : allKeys.map((key) => key.id))} disabled={isSubmitting} > Select all @@ -140,6 +140,7 @@ export function SshKeysField({ {showAddSshKey && ( setShowAddSshKey(false)} + onSuccess={(sshKey) => onChange([...selectedKeys, sshKey.id])} message={ void + onSuccess?: (sshKey: SshKey) => void message?: React.ReactNode } -export function SSHKeyCreate({ onDismiss, message }: Props) { +export function SSHKeyCreate({ onDismiss, onSuccess, message }: Props) { const navigate = useNavigate() const handleDismiss = onDismiss ? onDismiss : () => navigate(pb.sshKeys()) @@ -39,6 +46,7 @@ export function SSHKeyCreate({ onDismiss, message }: Props) { const createSshKey = useApiMutation(api.currentUserSshKeyCreate, { onSuccess(sshKey) { queryClient.invalidateEndpoint('currentUserSshKeyList') + onSuccess?.(sshKey) handleDismiss() // prettier-ignore addToast(<>SSH key {sshKey.name} created) diff --git a/test/e2e/instance-create.e2e.ts b/test/e2e/instance-create.e2e.ts index 8cfa7a9db..e7ed4d785 100644 --- a/test/e2e/instance-create.e2e.ts +++ b/test/e2e/instance-create.e2e.ts @@ -338,11 +338,15 @@ test('add ssh key from instance create form', async ({ page }) => { await dialog.getByRole('button', { name: 'Add SSH Key' }).click() await expect(newCheckbox).toBeVisible() - await expect(newCheckbox).not.toBeChecked() + await expect(newCheckbox).toBeChecked() + + await closeToast(page) // pop over to the real SSH keys page and see it there, why not await page.getByLabel('User menu').click() await page.getByRole('menuitem', { name: 'Settings' }).click() + // the new key being auto-checked makes the form dirty, which triggers confirm leave + await page.getByRole('button', { name: 'Leave this page' }).click() await page.getByRole('link', { name: 'SSH Keys' }).click() await expectRowVisible(page.getByRole('table'), { name: newKey, description: 'hi' }) })