Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/components/form/fields/DisksTableField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ export function DisksTableField({
onChange([...items, { type: 'attach', ...values }])
setShowDiskAttach(false)
}}
diskNamesToExclude={items.filter((i) => i.type === 'attach').map((i) => i.name)}
/>
)}
</>
Expand Down
4 changes: 3 additions & 1 deletion app/forms/disk-attach.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ type AttachDiskProps = {
/** If defined, this overrides the usual mutation */
onSubmit: (diskAttach: { name: string }) => void
onDismiss: () => void
diskNamesToExclude?: string[]
loading?: boolean
submitError?: ApiError | null
}
Expand All @@ -28,6 +29,7 @@ type AttachDiskProps = {
export function AttachDiskSideModalForm({
onSubmit,
onDismiss,
diskNamesToExclude = [],
loading,
submitError = null,
}: AttachDiskProps) {
Expand All @@ -39,7 +41,7 @@ export function AttachDiskSideModalForm({
// TODO: error handling
const detachedDisks =
useApiQuery('diskList', { query: projectSelector }).data?.items.filter(
(d) => d.state.state === 'detached'
(d) => d.state.state === 'detached' && !diskNamesToExclude.includes(d.name)
) || []

const form = useForm({ defaultValues })
Expand Down
32 changes: 32 additions & 0 deletions test/e2e/instance-create.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,38 @@ test('start with an existing disk, but then switch to a silo image', async ({ pa
await expectNotVisible(page, ['text=disk-7'])
})

test('additional disks do not list committed disks as available', async ({ page }) => {
await page.goto('/projects/mock-project/instances-new')

const attachExistingDiskButton = page.getByRole('button', {
name: 'Attach existing disk',
})
const selectAnOption = page.getByRole('button', { name: 'Select an option' })
const disk2 = page.getByRole('option', { name: 'disk-2' })
const disk3 = page.getByRole('option', { name: 'disk-3' })
const disk4 = page.getByRole('option', { name: 'disk-4' })

await attachExistingDiskButton.click()
await selectAnOption.click()
// disk-2 is already attached, so should not be visible in the list
await expect(disk2).toBeHidden()
// disk-3, though, should be present
await expect(disk3).toBeVisible()
await expect(disk4).toBeVisible()

// select disk-3 and "attach" it to the instance that will be created
await disk3.click()
await page.getByRole('button', { name: 'Attach disk' }).click()

await attachExistingDiskButton.click()
await selectAnOption.click()
// disk-2 should still be hidden
await expect(disk2).toBeHidden()
// now disk-3 should be hidden as well
await expect(disk3).toBeHidden()
await expect(disk4).toBeVisible()
})

test('maintains selected values even when changing tabs', async ({ page }) => {
const instanceName = 'arch-based-instance'
await page.goto('/projects/mock-project/instances-new')
Expand Down
2 changes: 2 additions & 0 deletions test/e2e/instance-disks.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ test('Attach disk', async ({ page }) => {
await expectVisible(page, ['role=dialog >> text="Disk name is required"'])

await page.click('role=button[name*="Disk name"]')
// disk-1 is already attached, so should not be visible in the list
await expectNotVisible(page, ['role=option[name="disk-1"]'])
await expectVisible(page, ['role=option[name="disk-3"]', 'role=option[name="disk-4"]'])
await page.click('role=option[name="disk-3"]')

Expand Down