mirror of
https://github.com/Kaelio/ktx.git
synced 2026-07-04 10:52:13 +02:00
feat(cli): skip-context-sources menu + clack-style tree picker UX (#213)
* feat(cli): add 'skip context sources' option to database setup menu After databases are configured, the post-setup menu now offers a 'Skip context sources' choice equivalent to passing --skip-sources, which plumbs through KtxSetupDatabasesResult.skipSources to bypass the context-source step in the same run. * feat(cli): standardize tree picker UX after clack autocomplete-multiselect Search is always on (no '/' to enter): typed printable chars feed the query, Tab toggles selection on the focused node without leaving the search bar, and Space toggles only after arrow-key navigation (isNavigating); otherwise it is appended to the query. Esc clears a non-empty query before quitting, Ctrl+A and Ctrl+N replace bare-letter bulk bindings, and the cursor refocuses on the first match when the query change would hide it.
This commit is contained in:
parent
96952fb43c
commit
cfd1749ab9
9 changed files with 292 additions and 83 deletions
|
|
@ -191,7 +191,7 @@ describe('search and cursor movement', () => {
|
|||
});
|
||||
const searching = {
|
||||
...state,
|
||||
search: { editing: false, query: 'architecture' },
|
||||
search: { query: 'architecture' },
|
||||
};
|
||||
|
||||
expect(filterTree(searching)).toEqual({
|
||||
|
|
@ -229,7 +229,7 @@ describe('bulk actions and reducer effects', () => {
|
|||
});
|
||||
const searching = {
|
||||
...state,
|
||||
search: { editing: false, query: 'architecture' },
|
||||
search: { query: 'architecture' },
|
||||
};
|
||||
|
||||
const selected = selectAllVisible(searching);
|
||||
|
|
@ -306,12 +306,11 @@ describe('bulk actions and reducer effects', () => {
|
|||
next: { ...state, pendingConfirm: null },
|
||||
effect: null,
|
||||
});
|
||||
expect(reducer(state, { type: 'search-input', value: 'a' }).next.search).toEqual({ query: 'a' });
|
||||
expect(reducer({ ...state, isNavigating: true }, { type: 'search-input', value: 'b' }).next.isNavigating).toBe(false);
|
||||
expect(
|
||||
reducer(
|
||||
reducer(reducer(state, 'search-start').next, { type: 'search-input', value: 'a' }).next,
|
||||
'search-submit',
|
||||
).next.search,
|
||||
).toEqual({ editing: false, query: 'a' });
|
||||
reducer({ ...state, search: { query: 'foo' }, isNavigating: true }, 'search-clear').next,
|
||||
).toEqual({ ...state, search: { query: '' }, isNavigating: false });
|
||||
expect(reducer(state, 'quit')).toEqual({
|
||||
next: state,
|
||||
effect: 'quit-without-save',
|
||||
|
|
@ -336,6 +335,34 @@ describe('bulk actions and reducer effects', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('navigates cursor commands set isNavigating, typed input clears it, and search refocuses cursor', () => {
|
||||
const state = buildInitialState({
|
||||
tree: buildPickerTree(pages()),
|
||||
existingSelectedIds: [],
|
||||
});
|
||||
|
||||
expect(state.isNavigating).toBe(false);
|
||||
const afterDown = reducer(state, 'cursor-down').next;
|
||||
expect(afterDown.isNavigating).toBe(true);
|
||||
|
||||
const afterType = reducer(afterDown, { type: 'search-input', value: 'a' }).next;
|
||||
expect(afterType.isNavigating).toBe(false);
|
||||
expect(afterType.search.query).toBe('a');
|
||||
|
||||
const afterBackspace = reducer({ ...afterDown, search: { query: 'foo' } }, 'search-backspace').next;
|
||||
expect(afterBackspace.search.query).toBe('fo');
|
||||
expect(afterBackspace.isNavigating).toBe(false);
|
||||
|
||||
const withCursorOnHidden = {
|
||||
...state,
|
||||
cursorId: IDS.journal,
|
||||
search: { query: 'arch' },
|
||||
};
|
||||
const refocused = reducer(withCursorOnHidden, { type: 'search-input', value: 'i' }).next;
|
||||
expect(refocused.search.query).toBe('archi');
|
||||
expect(visibleNodeIds(refocused)).toContain(refocused.cursorId);
|
||||
});
|
||||
|
||||
it('clears transient hints only when their expiry time has passed', () => {
|
||||
const state = buildInitialState({
|
||||
tree: buildPickerTree(pages()),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue