mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
Revert "[Code] set loading false if do not need fetch tree (#36083)"
This reverts commit 5f388dc5b0
.
This commit is contained in:
parent
cb0335c095
commit
6a013cb82e
9 changed files with 129 additions and 111 deletions
|
@ -44,7 +44,6 @@ export interface RepoTreePayload {
|
|||
export const fetchRepoTree = createAction<FetchRepoTreePayload>('FETCH REPO TREE');
|
||||
export const fetchRepoTreeSuccess = createAction<RepoTreePayload>('FETCH REPO TREE SUCCESS');
|
||||
export const fetchRepoTreeFailed = createAction<Error>('FETCH REPO TREE FAILED');
|
||||
|
||||
export const resetRepoTree = createAction('CLEAR REPO TREE');
|
||||
export const closeTreePath = createAction<string>('CLOSE TREE PATH');
|
||||
export const openTreePath = createAction<string>('OPEN TREE PATH');
|
||||
|
|
|
@ -44,6 +44,7 @@ test('render correctly', () => {
|
|||
location={location}
|
||||
closeTreePath={mockFunction}
|
||||
openTreePath={mockFunction}
|
||||
fetchRepoTree={mockFunction}
|
||||
/>
|
||||
)
|
||||
.toJSON();
|
||||
|
|
|
@ -11,7 +11,7 @@ import classes from 'classnames';
|
|||
import { connect } from 'react-redux';
|
||||
import { RouteComponentProps, withRouter } from 'react-router-dom';
|
||||
import { FileTree as Tree, FileTreeItemType } from '../../../model';
|
||||
import { closeTreePath, openTreePath } from '../../actions';
|
||||
import { closeTreePath, fetchRepoTree, FetchRepoTreePayload, openTreePath } from '../../actions';
|
||||
import { EuiSideNavItem, MainRouteParams, PathTypes } from '../../common/types';
|
||||
import { RootState } from '../../reducers';
|
||||
import { encodeRevisionString } from '../../utils/url';
|
||||
|
@ -20,7 +20,9 @@ interface Props extends RouteComponentProps<MainRouteParams> {
|
|||
node?: Tree;
|
||||
closeTreePath: (paths: string) => void;
|
||||
openTreePath: (paths: string) => void;
|
||||
fetchRepoTree: (p: FetchRepoTreePayload) => void;
|
||||
openedPaths: string[];
|
||||
treeLoading?: boolean;
|
||||
}
|
||||
|
||||
export class CodeFileTree extends React.Component<Props> {
|
||||
|
@ -31,6 +33,16 @@ export class CodeFileTree extends React.Component<Props> {
|
|||
}
|
||||
}
|
||||
|
||||
public fetchTree(path = '', isDir: boolean) {
|
||||
const { resource, org, repo, revision } = this.props.match.params;
|
||||
this.props.fetchRepoTree({
|
||||
uri: `${resource}/${org}/${repo}`,
|
||||
revision,
|
||||
path: path || '',
|
||||
isDir,
|
||||
});
|
||||
}
|
||||
|
||||
public onClick = (node: Tree) => {
|
||||
const { resource, org, repo, revision, path } = this.props.match.params;
|
||||
if (!(path === node.path)) {
|
||||
|
@ -241,9 +253,11 @@ export class CodeFileTree extends React.Component<Props> {
|
|||
const mapStateToProps = (state: RootState) => ({
|
||||
node: state.file.tree,
|
||||
openedPaths: state.file.openedPaths,
|
||||
treeLoading: state.file.rootFileTreeLoading,
|
||||
});
|
||||
|
||||
const mapDispatchToProps = {
|
||||
fetchRepoTree,
|
||||
closeTreePath,
|
||||
openTreePath,
|
||||
};
|
||||
|
|
|
@ -52,9 +52,9 @@ interface Props extends RouteComponentProps<MainRouteParams> {
|
|||
loadingCommits: boolean;
|
||||
onSearchScopeChanged: (s: SearchScope) => void;
|
||||
repoScope: string[];
|
||||
fileTreeLoadingPaths: string[];
|
||||
searchOptions: SearchOptions;
|
||||
currentRepository?: Repository;
|
||||
fileTreeLoading: boolean;
|
||||
}
|
||||
const LANG_MD = 'markdown';
|
||||
|
||||
|
@ -272,7 +272,7 @@ class CodeContent extends React.PureComponent<Props> {
|
|||
return this.renderProgress();
|
||||
}
|
||||
|
||||
const { file, match, tree, fileTreeLoadingPaths } = this.props;
|
||||
const { file, match, tree, fileTreeLoading } = this.props;
|
||||
const { path, pathType, resource, org, repo, revision } = match.params;
|
||||
const repoUri = `${resource}/${org}/${repo}`;
|
||||
switch (pathType) {
|
||||
|
@ -280,7 +280,7 @@ class CodeContent extends React.PureComponent<Props> {
|
|||
const node = this.findNode(path ? path.split('/') : [], tree);
|
||||
return (
|
||||
<div className="codeContainer__directoryView">
|
||||
<Directory node={node} loading={fileTreeLoadingPaths.includes(path)} />
|
||||
<Directory node={node} loading={fileTreeLoading} />
|
||||
<CommitHistory
|
||||
repoUri={repoUri}
|
||||
header={
|
||||
|
@ -388,7 +388,7 @@ const mapStateToProps = (state: RootState) => ({
|
|||
isNotFound: state.file.isNotFound,
|
||||
file: state.file.file,
|
||||
tree: state.file.tree,
|
||||
fileTreeLoadingPaths: state.file.fileTreeLoadingPaths,
|
||||
fileTreeLoading: state.file.fileTreeLoading,
|
||||
currentTree: currentTreeSelector(state),
|
||||
branches: state.file.branches,
|
||||
hasMoreCommits: hasMoreCommitsSelector(state),
|
||||
|
|
|
@ -69,7 +69,7 @@ class CodeMain extends React.Component<Props> {
|
|||
}
|
||||
|
||||
const mapStateToProps = (state: RootState) => ({
|
||||
loadingFileTree: state.file.fileTreeLoadingPaths.includes(''),
|
||||
loadingFileTree: state.file.rootFileTreeLoading,
|
||||
loadingStructureTree: state.symbol.loading,
|
||||
hasStructure: structureSelector(state).length > 0 && !state.symbol.error,
|
||||
languageServerInitializing: state.symbol.languageServerInitializing,
|
||||
|
|
|
@ -33,6 +33,8 @@ import {
|
|||
|
||||
export interface FileState {
|
||||
tree: FileTree;
|
||||
fileTreeLoading: boolean;
|
||||
rootFileTreeLoading: boolean;
|
||||
openedPaths: string[];
|
||||
branches: ReferenceInfo[];
|
||||
tags: ReferenceInfo[];
|
||||
|
@ -44,7 +46,6 @@ export interface FileState {
|
|||
currentPath: string;
|
||||
loadingCommits: boolean;
|
||||
commitsFullyLoaded: { [path: string]: boolean };
|
||||
fileTreeLoadingPaths: string[];
|
||||
}
|
||||
|
||||
const initialState: FileState = {
|
||||
|
@ -55,7 +56,8 @@ const initialState: FileState = {
|
|||
type: FileTreeItemType.Directory,
|
||||
},
|
||||
openedPaths: [],
|
||||
fileTreeLoadingPaths: [''],
|
||||
rootFileTreeLoading: true,
|
||||
fileTreeLoading: false,
|
||||
branches: [],
|
||||
tags: [],
|
||||
commits: [],
|
||||
|
@ -107,13 +109,12 @@ export const file = handleActions(
|
|||
[String(fetchRepoTree)]: (state: FileState, action: any) =>
|
||||
produce(state, draft => {
|
||||
draft.currentPath = action.payload.path;
|
||||
draft.fileTreeLoadingPaths.push(action.payload!.path);
|
||||
draft.fileTreeLoading = true;
|
||||
}),
|
||||
[String(fetchRepoTreeSuccess)]: (state: FileState, action: Action<RepoTreePayload>) =>
|
||||
produce<FileState>(state, (draft: FileState) => {
|
||||
draft.fileTreeLoadingPaths = draft.fileTreeLoadingPaths.filter(
|
||||
p => p !== action.payload!.path && p !== ''
|
||||
);
|
||||
draft.fileTreeLoading = false;
|
||||
draft.rootFileTreeLoading = false;
|
||||
const { tree, path, withParents } = action.payload!;
|
||||
if (withParents || path === '/' || path === '') {
|
||||
draft.tree = mergeNode(draft.tree, tree);
|
||||
|
@ -137,11 +138,10 @@ export const file = handleActions(
|
|||
draft.tree = initialState.tree;
|
||||
draft.openedPaths = initialState.openedPaths;
|
||||
}),
|
||||
[String(fetchRepoTreeFailed)]: (state: FileState, action: Action<any>) =>
|
||||
[String(fetchRepoTreeFailed)]: (state: FileState) =>
|
||||
produce(state, draft => {
|
||||
draft.fileTreeLoadingPaths = draft.fileTreeLoadingPaths.filter(
|
||||
p => p !== action.payload!.path && p !== ''
|
||||
);
|
||||
draft.fileTreeLoading = false;
|
||||
draft.rootFileTreeLoading = false;
|
||||
}),
|
||||
[String(openTreePath)]: (state: FileState, action: Action<any>) =>
|
||||
produce<FileState>(state, (draft: FileState) => {
|
||||
|
|
|
@ -40,7 +40,6 @@ import {
|
|||
lastRequestPathSelector,
|
||||
refUrlSelector,
|
||||
repoScopeSelector,
|
||||
createTreeSelector,
|
||||
} from '../selectors';
|
||||
import { history } from '../utils/url';
|
||||
import { mainRoutePattern } from './patterns';
|
||||
|
@ -197,27 +196,15 @@ function* handleMainRouteChange(action: Action<Match>) {
|
|||
.slice(0, -1)
|
||||
.join('/');
|
||||
yield put(openTreePath(openPath));
|
||||
function isTreeLoaded(isDirectory: boolean, targetTree: FileTree | null) {
|
||||
if (!isDirectory) {
|
||||
return !!targetTree;
|
||||
} else if (!targetTree) {
|
||||
return false;
|
||||
} else {
|
||||
return targetTree.children && targetTree.children.length > 0;
|
||||
}
|
||||
}
|
||||
const targetTree: FileTree | null = yield select(createTreeSelector(file || ''));
|
||||
if (!isTreeLoaded(isDir, targetTree)) {
|
||||
yield put(
|
||||
fetchRepoTree({
|
||||
uri: repoUri,
|
||||
revision,
|
||||
path: file || '',
|
||||
parents: getPathOfTree(tree, (file || '').split('/')) === null,
|
||||
isDir,
|
||||
})
|
||||
);
|
||||
}
|
||||
yield put(
|
||||
fetchRepoTree({
|
||||
uri: repoUri,
|
||||
revision,
|
||||
path: file || '',
|
||||
parents: getPathOfTree(tree, (file || '').split('/')) === null,
|
||||
isDir,
|
||||
})
|
||||
);
|
||||
const uri = toCanonicalUrl({
|
||||
repoUri,
|
||||
file,
|
||||
|
|
|
@ -10,6 +10,7 @@ import { kfetch } from 'ui/kfetch';
|
|||
import Url from 'url';
|
||||
import { call, put, select, takeEvery, takeLatest } from 'redux-saga/effects';
|
||||
|
||||
import { FileTree } from '../../model';
|
||||
import {
|
||||
fetchDirectory,
|
||||
fetchDirectoryFailed,
|
||||
|
@ -40,34 +41,48 @@ import {
|
|||
setNotFound,
|
||||
} from '../actions';
|
||||
import { RootState } from '../reducers';
|
||||
import { treeCommitsSelector } from '../selectors';
|
||||
import { treeCommitsSelector, createTreeSelector } from '../selectors';
|
||||
import { repoRoutePattern } from './patterns';
|
||||
import { FileTree } from '../../model';
|
||||
|
||||
function* handleFetchRepoTree(action: Action<FetchRepoTreePayload>) {
|
||||
try {
|
||||
const tree = yield call(requestRepoTree, action.payload!);
|
||||
(tree.children || []).sort((a: FileTree, b: FileTree) => {
|
||||
const typeDiff = a.type - b.type;
|
||||
if (typeDiff === 0) {
|
||||
return a.name > b.name ? 1 : -1;
|
||||
const { uri, revision, path, parents, isDir } = action.payload!;
|
||||
if (path && isDir) {
|
||||
const tree = yield select(createTreeSelector(path));
|
||||
if (tree) {
|
||||
const { children } = tree;
|
||||
// do not request file tree if this tree exists and its children are not empty
|
||||
if (!children || children.length === 0) {
|
||||
yield call(fetchPath, { uri, revision, path, parents, isDir });
|
||||
}
|
||||
} else {
|
||||
return -typeDiff;
|
||||
yield call(fetchPath, { uri, revision, path, parents, isDir });
|
||||
}
|
||||
});
|
||||
tree.repoUri = action.payload!.uri;
|
||||
yield put(
|
||||
fetchRepoTreeSuccess({
|
||||
tree,
|
||||
path: action.payload!.path,
|
||||
withParents: action.payload!.parents,
|
||||
})
|
||||
);
|
||||
} else {
|
||||
yield call(fetchPath, action.payload!);
|
||||
}
|
||||
} catch (err) {
|
||||
yield put(fetchRepoTreeFailed({ ...err, path: action.payload!.path }));
|
||||
yield put(fetchRepoTreeFailed(err));
|
||||
}
|
||||
}
|
||||
|
||||
function* fetchPath(payload: FetchRepoTreePayload) {
|
||||
const update: FileTree = yield call(requestRepoTree, payload);
|
||||
(update.children || []).sort((a, b) => {
|
||||
const typeDiff = a.type - b.type;
|
||||
if (typeDiff === 0) {
|
||||
return a.name > b.name ? 1 : -1;
|
||||
} else {
|
||||
return -typeDiff;
|
||||
}
|
||||
});
|
||||
update.repoUri = payload.uri;
|
||||
yield put(
|
||||
fetchRepoTreeSuccess({ tree: update, path: payload.path, withParents: payload.parents })
|
||||
);
|
||||
return update;
|
||||
}
|
||||
|
||||
interface FileTreeQuery {
|
||||
parents?: boolean;
|
||||
limit: number;
|
||||
|
|
|
@ -194,70 +194,72 @@ export default function exploreRepositoryFunctonalTests({
|
|||
});
|
||||
});
|
||||
|
||||
it('Click file/directory on the right panel', async () => {
|
||||
log.debug('Click file/directory on the right panel');
|
||||
// TODO(qianliang): blocked by https://github.com/elastic/code/issues/1163
|
||||
// it('Click file/directory on the right panel', async () => {
|
||||
// log.debug('Click file/directory on the right panel');
|
||||
|
||||
// Wait the file tree to be rendered and click the 'src' folder on the file tree.
|
||||
await retry.try(async () => {
|
||||
expect(await testSubjects.exists('codeFileExplorerNode-src')).to.be(true);
|
||||
});
|
||||
// // Wait the file tree to be rendered and click the 'src' folder on the file tree.
|
||||
// await retry.try(async () => {
|
||||
// expect(await testSubjects.exists('codeFileExplorerNode-src')).to.be(true);
|
||||
// });
|
||||
|
||||
await testSubjects.click('codeFileExplorerNode-src');
|
||||
await retry.try(async () => {
|
||||
expect(await testSubjects.exists('codeFileExplorerNode-models')).to.be(true);
|
||||
});
|
||||
// await testSubjects.click('codeFileExplorerNode-src');
|
||||
// await retry.try(async () => {
|
||||
// expect(await testSubjects.exists('codeFileExplorerNode-models')).to.be(true);
|
||||
// });
|
||||
|
||||
await testSubjects.click('codeFileExplorerNode-models');
|
||||
// Then the 'models' folder on the file tree.
|
||||
await retry.try(async () => {
|
||||
expect(await testSubjects.exists('codeFileExplorerNode-User.ts')).to.be(true);
|
||||
});
|
||||
// await testSubjects.click('codeFileExplorerNode-models');
|
||||
// // Then the 'models' folder on the file tree.
|
||||
// await retry.try(async () => {
|
||||
// expect(await testSubjects.exists('codeFileExplorerNode-User.ts')).to.be(true);
|
||||
// });
|
||||
|
||||
await testSubjects.click('codeFileExplorerNode-User.ts');
|
||||
// Then the 'User.ts' file on the file tree.
|
||||
await retry.try(async () => {
|
||||
expect(await testSubjects.exists('codeSourceViewer')).to.be(true);
|
||||
});
|
||||
});
|
||||
// await testSubjects.click('codeFileExplorerNode-User.ts');
|
||||
// // Then the 'User.ts' file on the file tree.
|
||||
// await retry.try(async () => {
|
||||
// expect(await testSubjects.exists('codeSourceViewer')).to.be(true);
|
||||
// });
|
||||
// });
|
||||
|
||||
it('Navigate source file via structure tree', async () => {
|
||||
log.debug('Navigate source file via structure tree');
|
||||
// Wait the file tree to be rendered and click the 'src' folder on the file tree.
|
||||
await retry.try(async () => {
|
||||
expect(await testSubjects.exists('codeFileExplorerNode-src')).to.be(true);
|
||||
});
|
||||
// TODO(qianliang): blocked by https://github.com/elastic/code/issues/1163
|
||||
// it('Navigate source file via structure tree', async () => {
|
||||
// log.debug('Navigate source file via structure tree');
|
||||
// // Wait the file tree to be rendered and click the 'src' folder on the file tree.
|
||||
// await retry.try(async () => {
|
||||
// expect(await testSubjects.exists('codeFileExplorerNode-src')).to.be(true);
|
||||
// });
|
||||
|
||||
await testSubjects.click('codeFileExplorerNode-src');
|
||||
await retry.try(async () => {
|
||||
expect(await testSubjects.exists('codeFileExplorerNode-models')).to.be(true);
|
||||
});
|
||||
// await testSubjects.click('codeFileExplorerNode-src');
|
||||
// await retry.try(async () => {
|
||||
// expect(await testSubjects.exists('codeFileExplorerNode-models')).to.be(true);
|
||||
// });
|
||||
|
||||
await testSubjects.click('codeFileExplorerNode-models');
|
||||
// Then the 'models' folder on the file tree.
|
||||
await retry.try(async () => {
|
||||
expect(await testSubjects.exists('codeFileExplorerNode-User.ts')).to.be(true);
|
||||
});
|
||||
// await testSubjects.click('codeFileExplorerNode-models');
|
||||
// // Then the 'models' folder on the file tree.
|
||||
// await retry.try(async () => {
|
||||
// expect(await testSubjects.exists('codeFileExplorerNode-User.ts')).to.be(true);
|
||||
// });
|
||||
|
||||
await testSubjects.click('codeFileExplorerNode-User.ts');
|
||||
// Then the 'User.ts' file on the file tree.
|
||||
await retry.try(async () => {
|
||||
expect(await testSubjects.exists('codeSourceViewer')).to.be(true);
|
||||
expect(await testSubjects.exists('codeStructureTreeTab')).to.be(true);
|
||||
});
|
||||
// await testSubjects.click('codeFileExplorerNode-User.ts');
|
||||
// // Then the 'User.ts' file on the file tree.
|
||||
// await retry.try(async () => {
|
||||
// expect(await testSubjects.exists('codeSourceViewer')).to.be(true);
|
||||
// expect(await testSubjects.exists('codeStructureTreeTab')).to.be(true);
|
||||
// });
|
||||
|
||||
// Click the structure tree tab
|
||||
await testSubjects.click('codeStructureTreeTab');
|
||||
await retry.tryForTime(300000, async () => {
|
||||
expect(await testSubjects.exists('codeStructureTreeNode-User')).to.be(true);
|
||||
// // Click the structure tree tab
|
||||
// await testSubjects.click('codeStructureTreeTab');
|
||||
// await retry.tryForTime(300000, async () => {
|
||||
// expect(await testSubjects.exists('codeStructureTreeNode-User')).to.be(true);
|
||||
|
||||
await testSubjects.click('codeStructureTreeNode-User');
|
||||
await retry.tryForTime(120000, async () => {
|
||||
const currentUrl: string = await browser.getCurrentUrl();
|
||||
log.info(`Jump to url: ${currentUrl}`);
|
||||
expect(currentUrl.indexOf('src/models/User.ts!L92:6') > 0).to.be(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
// await testSubjects.click('codeStructureTreeNode-User');
|
||||
// await retry.tryForTime(120000, async () => {
|
||||
// const currentUrl: string = await browser.getCurrentUrl();
|
||||
// log.info(`Jump to url: ${currentUrl}`);
|
||||
// expect(currentUrl.indexOf('src/models/User.ts!L92:6') > 0).to.be(true);
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue