Commit bdc437fc authored by Phil Hughes's avatar Phil Hughes

Add left links sidebar to IDE

[ci skip]
parent d8dd75ca
<script>
import { mapActions, mapGetters, mapState } from 'vuex';
import Icon from '~/vue_shared/components/icon.vue';
import ExternalLinks from './ide_external_links.vue';
import { ActivityBarViews } from '../stores/state';
export default {
components: {
Icon,
ExternalLinks,
},
computed: {
...mapGetters(['currentProject']),
...mapState(['currentActivityView']),
},
methods: {
...mapActions(['updateActivityBarView']),
},
ActivityBarViews,
};
</script>
<template>
<nav class="ide-activity-bar">
<ul class="list-unstyled">
<li>
<external-links
class="ide-activity-bar-link"
:project-url="currentProject.web_url"
/>
</li>
<li>
<a
href="#"
class="ide-sidebar-link ide-activity-bar-link"
:class="{
active: currentActivityView === $options.ActivityBarViews.edit
}"
@click.prevent="updateActivityBarView($options.ActivityBarViews.edit)"
>
<icon
:size="16"
name="code"
/>
</a>
</li>
<li>
<a
href="#"
class="ide-sidebar-link ide-activity-bar-link"
:class="{
active: currentActivityView === $options.ActivityBarViews.commit
}"
@click.prevent="updateActivityBarView($options.ActivityBarViews.commit)"
>
<icon
:size="16"
name="commit"
/>
</a>
</li>
</ul>
</nav>
</template>
<style>
.ide-activity-bar {
position: relative;
flex: 0 0 60px;
z-index: 2;
}
.ide-activity-bar-link {
position: relative;
height: 55px;
margin: 2.5px 0;
color: #707070;
border-top: 1px solid transparent;
border-bottom: 1px solid transparent;
}
.ide-activity-bar-link svg {
margin: 0 auto;
fill: currentColor;
}
.ide-activity-bar-link.active {
color: #4b4ba3;
background-color: #fff;
border-top: 1px solid #eaeaea;
border-bottom: 1px solid #eaeaea;
box-shadow: inset 3px 0 #4b4ba3;
}
a.ide-sidebar-link.ide-activity-bar-link.active::after {
content: '';
position: absolute;
right: -1px;
top: 0;
bottom: 0;
width: 1px;
background: #fff;
}
.ide-activity-bar-link:hover {
color: #4b4ba3;
background-color: #fff;
}
</style>
...@@ -100,9 +100,9 @@ export default { ...@@ -100,9 +100,9 @@ export default {
</div> </div>
</template> </template>
</div> </div>
<ide-contextbar <!-- <ide-contextbar
:no-changes-state-svg-path="noChangesStateSvgPath" :no-changes-state-svg-path="noChangesStateSvgPath"
:committed-state-svg-path="committedStateSvgPath" :committed-state-svg-path="committedStateSvgPath"
/> /> -->
</div> </div>
</template> </template>
...@@ -20,24 +20,15 @@ export default { ...@@ -20,24 +20,15 @@ export default {
</script> </script>
<template> <template>
<nav <a
class="ide-external-links" :href="goBackUrl"
class="ide-sidebar-link"
:aria-label="s__('IDE|Go back')"
v-once v-once
> >
<p> <icon
<a :size="16"
:href="goBackUrl" name="go-back"
class="ide-sidebar-link" />
> </a>
<icon
:size="16"
class="append-right-8"
name="go-back"
/>
<span class="ide-external-links-text">
{{ s__('Go back') }}
</span>
</a>
</p>
</nav>
</template> </template>
<script> <script>
import ProjectAvatarImage from '~/vue_shared/components/project_avatar/image.vue';
import Identicon from '../../vue_shared/components/identicon.vue';
import BranchesTree from './ide_project_branches_tree.vue'; import BranchesTree from './ide_project_branches_tree.vue';
import ExternalLinks from './ide_external_links.vue';
export default { export default {
components: { components: {
BranchesTree, BranchesTree,
ExternalLinks,
ProjectAvatarImage,
Identicon,
}, },
props: { props: {
project: { project: {
...@@ -22,37 +16,6 @@ export default { ...@@ -22,37 +16,6 @@ export default {
<template> <template>
<div class="projects-sidebar"> <div class="projects-sidebar">
<div class="context-header">
<a
:title="project.name"
:href="project.web_url"
>
<div
v-if="project.avatar_url"
class="avatar-container s40 project-avatar"
>
<project-avatar-image
class="avatar-container project-avatar"
:link-href="project.path"
:img-src="project.avatar_url"
:img-alt="project.name"
:img-size="40"
/>
</div>
<identicon
v-else
size-class="s40"
:entity-id="project.id"
:entity-name="project.name"
/>
<div class="sidebar-context-title">
{{ project.name }}
</div>
</a>
</div>
<external-links
:project-url="project.web_url"
/>
<div class="multi-file-commit-panel-inner-scroll"> <div class="multi-file-commit-panel-inner-scroll">
<branches-tree <branches-tree
v-for="branch in project.branches" v-for="branch in project.branches"
......
<script> <script>
import { mapState, mapGetters } from 'vuex'; import { mapState, mapGetters } from 'vuex';
import icon from '~/vue_shared/components/icon.vue'; import ProjectAvatarImage from '~/vue_shared/components/project_avatar/image.vue';
import panelResizer from '~/vue_shared/components/panel_resizer.vue'; import icon from '~/vue_shared/components/icon.vue';
import skeletonLoadingContainer from '~/vue_shared/components/skeleton_loading_container.vue'; import panelResizer from '~/vue_shared/components/panel_resizer.vue';
import projectTree from './ide_project_tree.vue'; import skeletonLoadingContainer from '~/vue_shared/components/skeleton_loading_container.vue';
import ResizablePanel from './resizable_panel.vue'; import Identicon from '../../vue_shared/components/identicon.vue';
import projectTree from './ide_project_tree.vue';
import ResizablePanel from './resizable_panel.vue';
import ActivityBar from './activity_bar.vue';
export default { export default {
components: { components: {
projectTree, projectTree,
icon, icon,
panelResizer, panelResizer,
skeletonLoadingContainer, skeletonLoadingContainer,
ResizablePanel, ResizablePanel,
}, ActivityBar,
computed: { ProjectAvatarImage,
...mapState([ Identicon,
'loading', },
]), computed: {
...mapGetters([ ...mapState(['loading']),
'projectsWithTrees', ...mapGetters(['currentProjectWithTree', 'activityBarComponent']),
]), },
}, };
};
</script> </script>
<template> <template>
<resizable-panel <resizable-panel
:collapsible="false" :collapsible="false"
:initial-width="290" :initial-width="340"
side="left" side="left"
> >
<activity-bar
v-if="!loading"
/>
<div class="multi-file-commit-panel-inner"> <div class="multi-file-commit-panel-inner">
<template v-if="loading"> <template v-if="loading">
<div <div
...@@ -41,11 +46,40 @@ ...@@ -41,11 +46,40 @@
<skeleton-loading-container /> <skeleton-loading-container />
</div> </div>
</template> </template>
<project-tree <template v-else>
v-for="project in projectsWithTrees" <div class="context-header">
:key="project.id" <a
:project="project" :title="currentProjectWithTree.name"
/> :href="currentProjectWithTree.web_url"
>
<div
v-if="currentProjectWithTree.avatar_url"
class="avatar-container s40 project-avatar"
>
<project-avatar-image
class="avatar-container project-avatar"
:link-href="currentProjectWithTree.path"
:img-src="currentProjectWithTree.avatar_url"
:img-alt="currentProjectWithTree.name"
:img-size="40"
/>
</div>
<identicon
v-else
size-class="s40"
:entity-id="currentProjectWithTree.id"
:entity-name="currentProjectWithTree.name"
/>
<div class="sidebar-context-title">
{{ currentProjectWithTree.name }}
</div>
</a>
</div>
<component
:is="activityBarComponent"
:project="currentProjectWithTree"
/>
</template>
</div> </div>
</resizable-panel> </resizable-panel>
</template> </template>
...@@ -112,6 +112,10 @@ export const updateDelayViewerUpdated = ({ commit }, delay) => { ...@@ -112,6 +112,10 @@ export const updateDelayViewerUpdated = ({ commit }, delay) => {
commit(types.UPDATE_DELAY_VIEWER_CHANGE, delay); commit(types.UPDATE_DELAY_VIEWER_CHANGE, delay);
}; };
export const updateActivityBarView = ({ commit }, view) => {
commit(types.UPDATE_ACTIVITY_BAR_VIEW, view);
};
export * from './actions/tree'; export * from './actions/tree';
export * from './actions/file'; export * from './actions/file';
export * from './actions/project'; export * from './actions/project';
......
import { ActivityBarViews } from './state';
export const activeFile = state => state.openFiles.find(file => file.active) || null; export const activeFile = state => state.openFiles.find(file => file.active) || null;
export const addedFiles = state => state.changedFiles.filter(f => f.tempFile); export const addedFiles = state => state.changedFiles.filter(f => f.tempFile);
...@@ -21,6 +23,18 @@ export const projectsWithTrees = state => ...@@ -21,6 +23,18 @@ export const projectsWithTrees = state =>
}; };
}); });
export const currentProjectWithTree = state => ({
...state.projects[state.currentProjectId],
branches: Object.keys(state.projects[state.currentProjectId].branches).map(branchId => {
const branch = state.projects[state.currentProjectId].branches[branchId];
return {
...branch,
tree: state.trees[branch.treeId],
};
}),
});
export const currentMergeRequest = state => { export const currentMergeRequest = state => {
if (state.projects[state.currentProjectId]) { if (state.projects[state.currentProjectId]) {
return state.projects[state.currentProjectId].mergeRequests[state.currentMergeRequestId]; return state.projects[state.currentProjectId].mergeRequests[state.currentMergeRequestId];
...@@ -28,6 +42,8 @@ export const currentMergeRequest = state => { ...@@ -28,6 +42,8 @@ export const currentMergeRequest = state => {
return null; return null;
}; };
export const currentProject = state => state.projects[state.currentProjectId];
// eslint-disable-next-line no-confusing-arrow // eslint-disable-next-line no-confusing-arrow
export const currentIcon = state => export const currentIcon = state =>
state.rightPanelCollapsed ? 'angle-double-left' : 'angle-double-right'; state.rightPanelCollapsed ? 'angle-double-left' : 'angle-double-right';
...@@ -35,3 +51,12 @@ export const currentIcon = state => ...@@ -35,3 +51,12 @@ export const currentIcon = state =>
export const hasChanges = state => !!state.changedFiles.length; export const hasChanges = state => !!state.changedFiles.length;
export const hasMergeRequest = state => !!state.currentMergeRequestId; export const hasMergeRequest = state => !!state.currentMergeRequestId;
export const activityBarComponent = state => {
switch (state.currentActivityView) {
case ActivityBarViews.edit:
return 'project-tree';
default:
return null;
}
};
...@@ -53,3 +53,5 @@ export const UPDATE_DELAY_VIEWER_CHANGE = 'UPDATE_DELAY_VIEWER_CHANGE'; ...@@ -53,3 +53,5 @@ export const UPDATE_DELAY_VIEWER_CHANGE = 'UPDATE_DELAY_VIEWER_CHANGE';
export const ADD_PENDING_TAB = 'ADD_PENDING_TAB'; export const ADD_PENDING_TAB = 'ADD_PENDING_TAB';
export const REMOVE_PENDING_TAB = 'REMOVE_PENDING_TAB'; export const REMOVE_PENDING_TAB = 'REMOVE_PENDING_TAB';
export const UPDATE_ACTIVITY_BAR_VIEW = 'UPDATE_ACTIVITY_BAR_VIEW';
...@@ -95,6 +95,11 @@ export default { ...@@ -95,6 +95,11 @@ export default {
delayViewerUpdated, delayViewerUpdated,
}); });
}, },
[types.UPDATE_ACTIVITY_BAR_VIEW](state, currentActivityView) {
Object.assign(state, {
currentActivityView,
});
},
...projectMutations, ...projectMutations,
...mergeRequestMutation, ...mergeRequestMutation,
...fileMutations, ...fileMutations,
......
export const ActivityBarViews = {
edit: 0,
commit: 1,
};
export default () => ({ export default () => ({
currentProjectId: '', currentProjectId: '',
currentBranchId: '', currentBranchId: '',
...@@ -17,4 +22,5 @@ export default () => ({ ...@@ -17,4 +22,5 @@ export default () => ({
entries: {}, entries: {},
viewer: 'editor', viewer: 'editor',
delayViewerUpdated: false, delayViewerUpdated: false,
currentActivityView: ActivityBarViews.edit,
}); });
...@@ -177,25 +177,6 @@ ...@@ -177,25 +177,6 @@
} }
} }
// Web IDE
.ide-sidebar-link {
color: $color-200;
background-color: $color-700;
&:hover,
&:focus {
background-color: $color-500;
}
&:active {
background: $color-800;
}
}
.branch-container {
border-left-color: $color-700;
}
.branch-header-title { .branch-header-title {
color: $color-700; color: $color-700;
} }
...@@ -343,9 +324,5 @@ body { ...@@ -343,9 +324,5 @@ body {
.sidebar-top-level-items > li.active .badge { .sidebar-top-level-items > li.active .badge {
color: $theme-gray-900; color: $theme-gray-900;
} }
.ide-sidebar-link {
color: $white-light;
}
} }
} }
...@@ -420,27 +420,27 @@ ...@@ -420,27 +420,27 @@
.multi-file-commit-panel { .multi-file-commit-panel {
display: flex; display: flex;
position: relative; position: relative;
flex-direction: column;
width: 340px; width: 340px;
padding: 0; padding: 0;
background-color: $gray-light; background-color: $gray-light;
padding-right: 3px; padding-right: 3px;
.context-header {
width: auto;
margin-right: 0;
}
.projects-sidebar { .projects-sidebar {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: 100%; height: 100%;
.context-header {
width: auto;
margin-right: 0;
}
} }
.multi-file-commit-panel-inner { .multi-file-commit-panel-inner {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: 100%; height: 100%;
width: 100%;
} }
.multi-file-commit-panel-inner-scroll { .multi-file-commit-panel-inner-scroll {
...@@ -448,29 +448,8 @@ ...@@ -448,29 +448,8 @@
flex: 1; flex: 1;
flex-direction: column; flex-direction: column;
overflow: auto; overflow: auto;
} background-color: #fff;
border-left: 1px solid #eaeaea;
&.is-collapsed {
width: 60px;
.multi-file-commit-list {
padding-top: $gl-padding;
overflow: hidden;
}
.multi-file-context-bar-icon {
align-items: center;
svg {
float: none;
margin: 0;
}
}
}
.branch-container {
border-left: 4px solid;
margin-bottom: $gl-bar-padding;
} }
.branch-header { .branch-header {
...@@ -491,17 +470,6 @@ ...@@ -491,17 +470,6 @@
.branch-header-btns { .branch-header-btns {
padding: $gl-vert-padding $gl-padding; padding: $gl-vert-padding $gl-padding;
} }
.left-collapse-btn {
display: none;
background: $gray-light;
text-align: left;
border-top: 1px solid $white-dark;
svg {
vertical-align: middle;
}
}
} }
.multi-file-context-bar-icon { .multi-file-context-bar-icon {
...@@ -822,12 +790,6 @@ ...@@ -822,12 +790,6 @@
margin-left: 25px; margin-left: 25px;
} }
.ide-external-links {
p {
margin: 0;
}
}
.ide-sidebar-link { .ide-sidebar-link {
padding: $gl-padding-8 $gl-padding; padding: $gl-padding-8 $gl-padding;
display: flex; display: flex;
......
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