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"
|
||||
className={css.crumbEditZone}
|
||||
aria-label={t('browser.editPath')}
|
||||
disabled={parent === null || parentInert}
|
||||
/* v8 ignore next -- narrowing guard: the zone disables while the level is null. */
|
||||
onClick={() => { if (parent !== null) setPathDraft(selected?.path ?? parent.path) }}
|
||||
// Stays available with no listed level: when the home
|
||||
// listing itself fails, typing an absolute path is the one
|
||||
// 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)
|
||||
})
|
||||
|
||||
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 () => {
|
||||
const b = mount({ busy: true })
|
||||
await waitFor(() => { expect(screen.getByRole('dialog')).toBeTruthy() })
|
||||
|
||||
Reference in New Issue
Block a user