Commit 8bf15ef4 authored by Phil Hughes's avatar Phil Hughes

Merge branch '45703-open-web-ide-file-tree' into 'master'

Show file in tree on WebIDE open

Closes #45703

See merge request gitlab-org/gitlab-ce!19887
parents 5f904e9c 1bfbee56
......@@ -95,24 +95,53 @@ export default {
return this.file.changed || this.file.tempFile || this.file.staged;
},
},
mounted() {
if (this.hasPathAtCurrentRoute()) {
this.scrollIntoView(true);
}
},
updated() {
if (this.file.type === 'blob' && this.file.active) {
this.$el.scrollIntoView({
behavior: 'smooth',
block: 'nearest',
});
this.scrollIntoView();
}
},
methods: {
...mapActions(['toggleTreeOpen']),
clickFile() {
// Manual Action if a tree is selected/opened
if (this.isTree && this.$router.currentRoute.path === `/project${this.file.url}`) {
if (this.isTree && this.hasUrlAtCurrentRoute()) {
this.toggleTreeOpen(this.file.path);
}
router.push(`/project${this.file.url}`);
},
scrollIntoView(isInit = false) {
const block = isInit && this.isTree ? 'center' : 'nearest';
this.$el.scrollIntoView({
behavior: 'smooth',
block,
});
},
hasPathAtCurrentRoute() {
if (!this.$router || !this.$router.currentRoute) {
return false;
}
// - strip route up to "/-/" and ending "/"
const routePath = this.$router.currentRoute.path
.replace(/^.*?[/]-[/]/g, '')
.replace(/[/]$/g, '');
// - strip ending "/"
const filePath = this.file.path
.replace(/[/]$/g, '');
return filePath === routePath;
},
hasUrlAtCurrentRoute() {
return this.$router.currentRoute.path === `/project${this.file.url}`;
},
},
};
</script>
......
......@@ -9,6 +9,17 @@ export const toggleTreeOpen = ({ commit }, path) => {
commit(types.TOGGLE_TREE_OPEN, path);
};
export const showTreeEntry = ({ commit, dispatch, state }, path) => {
const entry = state.entries[path];
const parentPath = entry ? entry.parentPath : '';
if (parentPath) {
commit(types.SET_TREE_OPEN, parentPath);
dispatch('showTreeEntry', parentPath);
}
};
export const handleTreeEntryAction = ({ commit, dispatch }, row) => {
if (row.type === 'tree') {
dispatch('toggleTreeOpen', row.path);
......@@ -21,6 +32,8 @@ export const handleTreeEntryAction = ({ commit, dispatch }, row) => {
} else {
dispatch('getFileData', { path: row.path });
}
dispatch('showTreeEntry', row.path);
};
export const getLastCommitData = ({ state, commit, dispatch }, tree = state) => {
......
......@@ -28,6 +28,7 @@ export const TOGGLE_BRANCH_OPEN = 'TOGGLE_BRANCH_OPEN';
// Tree mutation types
export const SET_DIRECTORY_DATA = 'SET_DIRECTORY_DATA';
export const TOGGLE_TREE_OPEN = 'TOGGLE_TREE_OPEN';
export const SET_TREE_OPEN = 'SET_TREE_OPEN';
export const SET_LAST_COMMIT_URL = 'SET_LAST_COMMIT_URL';
export const CREATE_TREE = 'CREATE_TREE';
export const REMOVE_ALL_CHANGES_FILES = 'REMOVE_ALL_CHANGES_FILES';
......
......@@ -6,6 +6,11 @@ export default {
opened: !state.entries[path].opened,
});
},
[types.SET_TREE_OPEN](state, path) {
Object.assign(state.entries[path], {
opened: true,
});
},
[types.CREATE_TREE](state, { treePath }) {
Object.assign(state, {
trees: Object.assign({}, state.trees, {
......
---
title: Update WebIDE to show file in tree on load
merge_request: 19887
author:
type: changed
import * as pathUtils from 'path';
import { decorateData } from '~/ide/stores/utils';
import state from '~/ide/stores/state';
import commitState from '~/ide/stores/modules/commit/state';
......@@ -14,13 +15,34 @@ export const resetStore = store => {
store.replaceState(newState);
};
export const file = (name = 'name', id = name, type = '') =>
export const file = (name = 'name', id = name, type = '', parent = null) =>
decorateData({
id,
type,
icon: 'icon',
url: 'url',
name,
path: name,
path: parent ? `${parent.path}/${name}` : name,
parentPath: parent ? parent.path : '',
lastCommit: {},
});
export const createEntriesFromPaths = (paths) =>
paths
.map(path => ({
name: pathUtils.basename(path),
dir: pathUtils.dirname(path),
ext: pathUtils.extname(path),
}))
.reduce((entries, path, idx) => {
const name = path.name;
const parent = path.dir ? entries[path.dir] : null;
const type = path.ext ? 'blob' : 'tree';
const entry = file(name, (idx + 1).toString(), type, parent);
return {
[entry.path]: entry,
...entries,
};
}, {});
import Vue from 'vue';
import testAction from 'spec/helpers/vuex_action_helper';
import { showTreeEntry } from '~/ide/stores/actions/tree';
import * as types from '~/ide/stores/mutation_types';
import store from '~/ide/stores';
import service from '~/ide/services';
import router from '~/ide/ide_router';
import { file, resetStore } from '../../helpers';
import { file, resetStore, createEntriesFromPaths } from '../../helpers';
describe('Multi-file store tree actions', () => {
let projectTree;
......@@ -96,6 +99,37 @@ describe('Multi-file store tree actions', () => {
});
});
describe('showTreeEntry', () => {
beforeEach(() => {
const paths = [
'grandparent',
'ancestor',
'grandparent/parent',
'grandparent/aunt',
'grandparent/parent/child.txt',
'grandparent/aunt/cousing.txt',
];
Object.assign(store.state.entries, createEntriesFromPaths(paths));
});
it('opens the parents', done => {
testAction(
showTreeEntry,
'grandparent/parent/child.txt',
store.state,
[
{ type: types.SET_TREE_OPEN, payload: 'grandparent/parent' },
{ type: types.SET_TREE_OPEN, payload: 'grandparent' },
],
[
{ type: 'showTreeEntry' },
],
done,
);
});
});
describe('getLastCommitData', () => {
beforeEach(() => {
spyOn(service, 'getTreeLastCommit').and.returnValue(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment