diff --git a/x-pack/plugins/code/public/actions/file.ts b/x-pack/plugins/code/public/actions/file.ts index 0473113cd73ad2..b91ead5889685e 100644 --- a/x-pack/plugins/code/public/actions/file.ts +++ b/x-pack/plugins/code/public/actions/file.ts @@ -38,6 +38,7 @@ export interface FetchFileResponse { export interface RepoTreePayload { tree: FileTree; path: string; + withParents: boolean | undefined; } export const fetchRepoTree = createAction('FETCH REPO TREE'); diff --git a/x-pack/plugins/code/public/reducers/file.ts b/x-pack/plugins/code/public/reducers/file.ts index f1f7f2d696cbb8..5868499954c18c 100644 --- a/x-pack/plugins/code/public/reducers/file.ts +++ b/x-pack/plugins/code/public/reducers/file.ts @@ -91,25 +91,16 @@ function mergeNode(a: FileTree, b: FileTree): FileTree { }; } -function mergeTree(draft: FileState, tree: FileTree, path: string) { - const pathSegments = path.split('/'); - let current = draft.tree; - const node = tree; - if (path && current.children != null) { - const pLastIndex = pathSegments.length - 1; - pathSegments.forEach((p, pidx) => { - const idx = current.children!.findIndex(child => child.name === p); - if (idx >= 0) { - if (pidx === pLastIndex) { - current.children![idx!] = mergeNode(current.children![idx!], node); - } - current = current.children![idx]; - } - }); - } else { - // it's root - draft.tree = tree; +export function getPathOfTree(tree: FileTree, paths: string[]) { + let child: FileTree | undefined = tree; + for (const p of paths) { + if (child && child.children) { + child = child.children.find(c => c.name === p); + } else { + return null; + } } + return child; } export const file = handleActions( @@ -117,13 +108,30 @@ export const file = handleActions( [String(fetchRepoTree)]: (state: FileState, action: any) => produce(state, draft => { draft.currentPath = action.payload.path; - draft.loading = true; + if (action.payload.parents) { + draft.loading = true; + } }), [String(fetchRepoTreeSuccess)]: (state: FileState, action: Action) => produce(state, (draft: FileState) => { draft.loading = false; - const { tree, path } = action.payload!; - mergeTree(draft, tree, path); + const { tree, path, withParents } = action.payload!; + if (withParents) { + draft.tree = mergeNode(draft.tree, tree); + } else { + const parentsPath = path.split('/'); + const lastPath = parentsPath.pop(); + const parent = getPathOfTree(draft.tree, parentsPath); + if (parent) { + parent.children = parent.children || []; + const idx = parent.children.findIndex(c => c.name === lastPath); + if (idx >= 0) { + parent.children[idx] = tree; + } else { + parent.children.push(tree); + } + } + } }), [String(resetRepoTree)]: (state: FileState) => produce(state, (draft: FileState) => { diff --git a/x-pack/plugins/code/public/sagas/editor.ts b/x-pack/plugins/code/public/sagas/editor.ts index 014ce6d4797fd6..a51de1b03f9ed4 100644 --- a/x-pack/plugins/code/public/sagas/editor.ts +++ b/x-pack/plugins/code/public/sagas/editor.ts @@ -29,6 +29,7 @@ import { import { loadRepo, loadRepoFailed, loadRepoSuccess } from '../actions/status'; import { PathTypes } from '../common/types'; import { RootState } from '../reducers'; +import { getPathOfTree } from '../reducers/file'; import { fileSelector, getTree, lastRequestPathSelector, refUrlSelector } from '../selectors'; import { history } from '../utils/url'; import { mainRoutePattern } from './patterns'; @@ -174,7 +175,7 @@ function* handleMainRouteChange(action: Action) { uri: repoUri, revision, path: file || '', - parents: tree.children == null, + parents: getPathOfTree(tree, (file || '').split('/')) === null, isDir: pathType === PathTypes.tree, }) ); diff --git a/x-pack/plugins/code/public/sagas/file.ts b/x-pack/plugins/code/public/sagas/file.ts index 1b9e7f86c67ae1..306eea687de34a 100644 --- a/x-pack/plugins/code/public/sagas/file.ts +++ b/x-pack/plugins/code/public/sagas/file.ts @@ -65,7 +65,9 @@ function* fetchPath(payload: FetchRepoTreePayload) { } }); update.repoUri = payload.uri; - yield put(fetchRepoTreeSuccess({ tree: update, path: payload.path })); + yield put( + fetchRepoTreeSuccess({ tree: update, path: payload.path, withParents: payload.parents }) + ); return update; }