Commit 002cc923 authored by Phil Hughes's avatar Phil Hughes

Added pending tabs to IDE

Pending tabs are normal tabs that are opened from the right sidebar.
They are opened in diff mode and when changed to edit mode they get
closed
& the actual file gets opened.
parent b3fb82a9
<script>
import { mapActions } from 'vuex';
import icon from '~/vue_shared/components/icon.vue';
import router from '../../ide_router';
import { mapActions } from 'vuex';
import icon from '~/vue_shared/components/icon.vue';
import router from '../../ide_router';
export default {
export default {
components: {
icon,
},
......@@ -22,17 +22,15 @@
},
},
methods: {
...mapActions([
'discardFileChanges',
'updateViewer',
]),
...mapActions(['discardFileChanges', 'updateViewer', 'openPendingTab']),
openFileInEditor(file) {
this.updateViewer('diff');
router.push(`/project${file.url}`);
return this.updateViewer('diff').then(() => {
this.openPendingTab(file);
router.push(`/project/${file.projectId}/tree/master/`);
});
},
},
};
};
</script>
<template>
......
<script>
import { mapState, mapGetters } from 'vuex';
import ideSidebar from './ide_side_bar.vue';
import ideContextbar from './ide_context_bar.vue';
import repoTabs from './repo_tabs.vue';
import repoFileButtons from './repo_file_buttons.vue';
import ideStatusBar from './ide_status_bar.vue';
import repoEditor from './repo_editor.vue';
import { mapState, mapGetters } from 'vuex';
import ideSidebar from './ide_side_bar.vue';
import ideContextbar from './ide_context_bar.vue';
import repoTabs from './repo_tabs.vue';
import repoFileButtons from './repo_file_buttons.vue';
import ideStatusBar from './ide_status_bar.vue';
import repoEditor from './repo_editor.vue';
export default {
export default {
components: {
ideSidebar,
ideContextbar,
......@@ -32,7 +32,7 @@
},
computed: {
...mapState(['changedFiles', 'openFiles', 'viewer']),
...mapGetters(['activeFile', 'hasChanges']),
...mapGetters(['activeFile', 'hasChanges', 'tabs']),
},
mounted() {
const returnValue = 'Are you sure you want to lose unsaved changes?';
......@@ -45,7 +45,7 @@
return returnValue;
};
},
};
};
</script>
<template>
......@@ -60,7 +60,7 @@
v-if="activeFile"
>
<repo-tabs
:files="openFiles"
:files="tabs"
:viewer="viewer"
:has-changes="hasChanges"
/>
......
<script>
import { mapActions } from 'vuex';
import { mapActions } from 'vuex';
import fileIcon from '~/vue_shared/components/file_icon.vue';
import icon from '~/vue_shared/components/icon.vue';
import fileStatusIcon from './repo_file_status_icon.vue';
import changedFileIcon from './changed_file_icon.vue';
import fileIcon from '~/vue_shared/components/file_icon.vue';
import icon from '~/vue_shared/components/icon.vue';
import fileStatusIcon from './repo_file_status_icon.vue';
import changedFileIcon from './changed_file_icon.vue';
export default {
export default {
components: {
fileStatusIcon,
fileIcon,
......@@ -37,9 +37,7 @@
},
methods: {
...mapActions([
'closeFile',
]),
...mapActions(['closeFile']),
clickFile(tab) {
this.$router.push(`/project${tab.url}`);
},
......@@ -54,7 +52,7 @@
}
},
},
};
};
</script>
<template>
......@@ -66,7 +64,7 @@
<button
type="button"
class="multi-file-tab-close"
@click.stop.prevent="closeFile(tab.path)"
@click.stop.prevent="closeFile(tab)"
:aria-label="closeLabel"
>
<icon
......@@ -82,7 +80,10 @@
<div
class="multi-file-tab"
:class="{active : tab.active }"
:class="{
active: tab.active,
pending: tab.pending
}"
:title="tab.url"
>
<file-icon
......
<script>
import { mapActions } from 'vuex';
import RepoTab from './repo_tab.vue';
import EditorMode from './editor_mode_dropdown.vue';
import { mapActions } from 'vuex';
import RepoTab from './repo_tab.vue';
import EditorMode from './editor_mode_dropdown.vue';
export default {
export default {
components: {
RepoTab,
EditorMode,
......@@ -30,13 +30,12 @@
updated() {
if (!this.$refs.tabsScroller) return;
this.showShadow =
this.$refs.tabsScroller.scrollWidth > this.$refs.tabsScroller.offsetWidth;
this.showShadow = this.$refs.tabsScroller.scrollWidth > this.$refs.tabsScroller.offsetWidth;
},
methods: {
...mapActions(['updateViewer']),
},
};
};
</script>
<template>
......@@ -47,7 +46,7 @@
>
<repo-tab
v-for="tab in files"
:key="tab.key"
:key="`${tab.key}${tab.pending ? '-pending' : ''}`"
:tab="tab"
/>
</ul>
......
......@@ -6,8 +6,7 @@ import FilesDecoratorWorker from './workers/files_decorator_worker';
export const redirectToUrl = (_, url) => visitUrl(url);
export const setInitialData = ({ commit }, data) =>
commit(types.SET_INITIAL_DATA, data);
export const setInitialData = ({ commit }, data) => commit(types.SET_INITIAL_DATA, data);
export const discardAllChanges = ({ state, commit, dispatch }) => {
state.changedFiles.forEach(file => {
......@@ -43,14 +42,11 @@ export const createTempEntry = (
) =>
new Promise(resolve => {
const worker = new FilesDecoratorWorker();
const fullName =
name.slice(-1) !== '/' && type === 'tree' ? `${name}/` : name;
const fullName = name.slice(-1) !== '/' && type === 'tree' ? `${name}/` : name;
if (state.entries[name]) {
flash(
`The name "${name
.split('/')
.pop()}" is already taken in this directory.`,
`The name "${name.split('/').pop()}" is already taken in this directory.`,
'alert',
document,
null,
......
......@@ -6,9 +6,13 @@ import * as types from '../mutation_types';
import router from '../../ide_router';
import { setPageTitle } from '../utils';
export const closeFile = ({ commit, state, getters, dispatch }, path) => {
export const closeFile = ({ commit, state, getters, dispatch }, file) => {
const path = file.path;
if (file.pending) {
commit(types.REMOVE_PENDING_TAB, file);
} else {
const indexOfClosedFile = state.openFiles.findIndex(f => f.path === path);
const file = state.entries[path];
const fileWasActive = file.active;
commit(types.TOGGLE_FILE_OPEN, path);
......@@ -22,6 +26,7 @@ export const closeFile = ({ commit, state, getters, dispatch }, path) => {
} else if (!state.openFiles.length) {
router.push(`/project/${file.projectId}/tree/${file.branchId}/`);
}
}
eventHub.$emit(`editor.update.model.dispose.${file.path}`);
};
......@@ -66,14 +71,7 @@ export const getFileData = ({ state, commit, dispatch }, file) => {
})
.catch(() => {
commit(types.TOGGLE_LOADING, { entry: file });
flash(
'Error loading file data. Please try again.',
'alert',
document,
null,
false,
true,
);
flash('Error loading file data. Please try again.', 'alert', document, null, false, true);
});
};
......@@ -84,14 +82,7 @@ export const getRawFileData = ({ commit, dispatch }, file) =>
commit(types.SET_FILE_RAW_DATA, { file, raw });
})
.catch(() =>
flash(
'Error loading file content. Please try again.',
'alert',
document,
null,
false,
true,
),
flash('Error loading file content. Please try again.', 'alert', document, null, false, true),
);
export const changeFileContent = ({ state, commit }, { path, content }) => {
......@@ -119,10 +110,7 @@ export const setFileEOL = ({ getters, commit }, { eol }) => {
}
};
export const setEditorPosition = (
{ getters, commit },
{ editorRow, editorColumn },
) => {
export const setEditorPosition = ({ getters, commit }, { editorRow, editorColumn }) => {
if (getters.activeFile) {
commit(types.SET_FILE_POSITION, {
file: getters.activeFile,
......@@ -144,3 +132,7 @@ export const discardFileChanges = ({ state, commit }, path) => {
eventHub.$emit(`editor.update.model.content.${file.path}`, file.raw);
};
export const openPendingTab = ({ commit }, file) => {
commit(types.ADD_PENDING_TAB, file);
};
export const activeFile = state =>
state.openFiles.find(file => file.active) || null;
export const tabs = state => state.openFiles.concat(state.pendingTabs);
export const activeFile = state => tabs(state).find(file => file.active) || null;
export const addedFiles = state => state.changedFiles.filter(f => f.tempFile);
export const modifiedFiles = state =>
state.changedFiles.filter(f => !f.tempFile);
export const modifiedFiles = state => state.changedFiles.filter(f => !f.tempFile);
export const projectsWithTrees = state =>
Object.keys(state.projects).map(projectId => {
......
......@@ -41,3 +41,6 @@ export const SET_ENTRIES = 'SET_ENTRIES';
export const CREATE_TMP_ENTRY = 'CREATE_TMP_ENTRY';
export const UPDATE_VIEWER = 'UPDATE_VIEWER';
export const UPDATE_DELAY_VIEWER_CHANGE = 'UPDATE_DELAY_VIEWER_CHANGE';
export const ADD_PENDING_TAB = 'ADD_PENDING_TAB';
export const REMOVE_PENDING_TAB = 'REMOVE_PENDING_TAB';
......@@ -80,4 +80,18 @@ export default {
changed,
});
},
[types.ADD_PENDING_TAB](state, file) {
Object.assign(state, {
pendingTabs: state.pendingTabs.concat({
...file,
active: true,
pending: true,
}),
});
},
[types.REMOVE_PENDING_TAB](state, file) {
Object.assign(state, {
pendingTabs: state.pendingTabs.filter(f => f.path !== file.path),
});
},
};
......@@ -16,4 +16,5 @@ export default () => ({
entries: {},
viewer: 'editor',
delayViewerUpdated: false,
pendingTabs: [],
});
......@@ -177,6 +177,10 @@
background-color: $white-light;
border-bottom-color: $white-light;
}
&.pending {
font-style: italic;
}
}
.multi-file-tab-close {
......@@ -720,9 +724,7 @@
}
.ide-view {
height: calc(
100vh - #{$header-height + $performance-bar-height + $flash-height}
);
height: calc(100vh - #{$header-height + $performance-bar-height + $flash-height});
}
}
}
......
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