fix(host): keep path entry available when the home listing fails
With no listed level (an unreadable or missing home directory), the path-edit zone previously disabled forever, stranding the operator on the alert with only Cancel; it now opens with an empty draft so an absolute path remains the way forward. Covered by a recovery test.
This commit is contained in:
@@ -282,9 +282,11 @@ export function DirectoryBrowser({ open, listDirectory, createDirectory, onOpen,
|
|||||||
type="button"
|
type="button"
|
||||||
className={css.crumbEditZone}
|
className={css.crumbEditZone}
|
||||||
aria-label={t('browser.editPath')}
|
aria-label={t('browser.editPath')}
|
||||||
disabled={parent === null || parentInert}
|
// Stays available with no listed level: when the home
|
||||||
/* v8 ignore next -- narrowing guard: the zone disables while the level is null. */
|
// listing itself fails, typing an absolute path is the one
|
||||||
onClick={() => { if (parent !== null) setPathDraft(selected?.path ?? parent.path) }}
|
// remaining way forward.
|
||||||
|
disabled={parentInert}
|
||||||
|
onClick={() => { setPathDraft(selected?.path ?? parent?.path ?? '') }}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -269,6 +269,21 @@ describe('DirectoryBrowser', () => {
|
|||||||
expect(screen.getByRole<HTMLButtonElement>('button', { name: 'browser.newFolder' }).disabled).toBe(false)
|
expect(screen.getByRole<HTMLButtonElement>('button', { name: 'browser.newFolder' }).disabled).toBe(false)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('keeps path entry available when the home listing fails', async () => {
|
||||||
|
const listDirectory = vi.fn(async (): Promise<DirectoryListing> => {
|
||||||
|
throw new DirectoryBrowseError({ code: 'directory-unreadable', message: 'home unreadable', details: { path: HOME } })
|
||||||
|
})
|
||||||
|
mount({ listDirectory })
|
||||||
|
await waitFor(() => { expect(screen.getByRole('alert').textContent).toBe('home unreadable') })
|
||||||
|
// With no listed level, typing an absolute path is the one way forward.
|
||||||
|
fireEvent.click(screen.getByRole('button', { name: 'browser.editPath' }))
|
||||||
|
const input = screen.getByLabelText('browser.editPath')
|
||||||
|
fireEvent.change(input, { target: { value: DOCS } })
|
||||||
|
listDirectory.mockImplementation(async (path?: string) => listingFor(path))
|
||||||
|
fireEvent.keyDown(input, { key: 'Enter' })
|
||||||
|
await waitFor(() => { expect(screen.getByText('harness')).toBeTruthy() })
|
||||||
|
})
|
||||||
|
|
||||||
it('ignores dismissal while adoption is busy', async () => {
|
it('ignores dismissal while adoption is busy', async () => {
|
||||||
const b = mount({ busy: true })
|
const b = mount({ busy: true })
|
||||||
await waitFor(() => { expect(screen.getByRole('dialog')).toBeTruthy() })
|
await waitFor(() => { expect(screen.getByRole('dialog')).toBeTruthy() })
|
||||||
|
|||||||
Reference in New Issue
Block a user