fix(file-viewer): COD-341 finalize deferred navigation

This commit is contained in:
Aamer Akhter
2026-08-23 22:42:10 -04:00
parent acd9ffedc8
commit c14171b534
2 changed files with 47 additions and 6 deletions
+11 -6
View File
@@ -3364,8 +3364,8 @@ Object.assign(CodemanApp.prototype, {
const nextNormalState = { sessionId, showHidden, treeEpoch, phase: 'ready', data };
state.normalState = nextNormalState;
this.fileBrowserData = data;
this._completeDeferredFileBrowserDirectory?.(nextNormalState);
this._renderFileBrowserNormalState(nextNormalState);
const deferredRendered = this._completeDeferredFileBrowserDirectory?.(nextNormalState) === true;
if (!deferredRendered) this._renderFileBrowserNormalState(nextNormalState);
} catch (error) {
if (!this._isFileBrowserTreeContextCurrent(record, true)) return;
const nextNormalState = {
@@ -3708,7 +3708,11 @@ Object.assign(CodemanApp.prototype, {
_completeDeferredFileBrowserDirectory(normalState) {
const state = this._ensureFileBrowserState();
const target = state.deferredDirectoryTarget;
if (!target || !this._isFileBrowserDirectoryContextCurrent(target)) return;
if (!target) return false;
if (!this._isFileBrowserDirectoryContextCurrent(target)) {
if (state.deferredDirectoryTarget === target) state.deferredDirectoryTarget = null;
return false;
}
if (
!this._isFileBrowserNormalCompatible(
normalState,
@@ -3718,21 +3722,22 @@ Object.assign(CodemanApp.prototype, {
) ||
(normalState.phase !== 'ready' && normalState.phase !== 'error')
) {
return;
return false;
}
state.deferredDirectoryTarget = null;
if (normalState.phase === 'error') {
this._promptFileBrowserDirectoryReload();
return;
return false;
}
const found = this._findFileBrowserDirectory(normalState.data?.tree, target.path);
if (!found) {
this._promptFileBrowserDirectoryReload();
return;
return false;
}
this._leaveFileBrowserSearchForDirectory([...found.ancestors, found.target.path], normalState);
return true;
},
_leaveFileBrowserSearchForDirectory(paths, normalState) {
+36
View File
@@ -1183,14 +1183,17 @@ describe('File Viewer server search', () => {
path: 'src/components/widgets',
view: 'search-results',
});
const renderNormalTree = vi.spyOn(app, 'renderFileBrowserTree');
pending[0].reply.resolve(
response(successfulTree('unused', { tree: unixTree, totalFiles: 1, totalDirectories: 3 }))
);
await treeLoad;
expect(renderNormalTree).toHaveBeenCalledTimes(1);
expect(app._fileBrowserState.view).toBe('normal');
expect(elements.fileBrowserTree.innerHTML).toContain('index.ts');
expect(elements.fileBrowserTree.querySelectorAll('.file-tree-item')).toHaveLength(4);
expect(app.fileBrowserExpandedDirs.has('src/components/widgets')).toBe(true);
});
@@ -1324,8 +1327,41 @@ describe('File Viewer server search', () => {
expect(elements.fileBrowserSearch.value).toBe('widget');
expect(elements.fileBrowserTree.innerHTML).toContain('widgets');
expect(app.fileBrowserExpandedDirs.size).toBe(0);
expect(app._fileBrowserState.deferredDirectoryTarget).toBeNull();
}
);
it('does not clear a newer deferred replacement while compare-and-clearing an obsolete binding', () => {
const { app } = loadPanel();
const state = app._ensureFileBrowserState();
const obsolete = {
ownerSessionId: 'session/A',
showHidden: false,
treeEpoch: 0,
searchEpoch: 0,
rawInput: 'old',
query: 'old',
path: 'old/path',
view: 'search-results',
};
const replacement = { ...obsolete, searchEpoch: 1, rawInput: 'new', query: 'new', path: 'new/path' };
state.deferredDirectoryTarget = obsolete;
vi.spyOn(app, '_isFileBrowserDirectoryContextCurrent').mockImplementationOnce((target) => {
expect(target).toBe(obsolete);
state.deferredDirectoryTarget = replacement;
return false;
});
app._completeDeferredFileBrowserDirectory({
sessionId: 'session/A',
showHidden: false,
treeEpoch: 0,
phase: 'ready',
data: successfulTree('ready.ts').data,
});
expect(state.deferredDirectoryTarget).toBe(replacement);
});
});
describe('normal tree loads', () => {