Commit 01a2d0f2 authored by Paul Slaughter's avatar Paul Slaughter

Refactor IDE to allow RightPane extension

**Why?**
- This is needed by the Web Terminal EE feature.
  https://gitlab.com/gitlab-org/gitlab-ee/issues/5426

**Notes:**
- RightPane component tabs is now data driven.
parent 912d068d
<script> <script>
import Vue from 'vue';
import Mousetrap from 'mousetrap'; import Mousetrap from 'mousetrap';
import { mapActions, mapState, mapGetters } from 'vuex'; import { mapActions, mapState, mapGetters } from 'vuex';
import { __ } from '~/locale'; import { __ } from '~/locale';
...@@ -22,10 +23,16 @@ export default { ...@@ -22,10 +23,16 @@ export default {
IdeStatusBar, IdeStatusBar,
RepoEditor, RepoEditor,
FindFile, FindFile,
RightPane,
ErrorMessage, ErrorMessage,
CommitEditorHeader, CommitEditorHeader,
}, },
props: {
rightPaneComponent: {
type: Vue.Component,
required: false,
default: () => RightPane,
},
},
computed: { computed: {
...mapState([ ...mapState([
'openFiles', 'openFiles',
...@@ -143,7 +150,8 @@ export default { ...@@ -143,7 +150,8 @@ export default {
</div> </div>
</template> </template>
</div> </div>
<right-pane <component
:is="rightPaneComponent"
v-if="currentProjectId" v-if="currentProjectId"
/> />
</div> </div>
......
<script> <script>
import { mapActions, mapState, mapGetters } from 'vuex'; import { mapActions, mapState, mapGetters } from 'vuex';
import { __ } from '~/locale';
import tooltip from '../../../vue_shared/directives/tooltip'; import tooltip from '../../../vue_shared/directives/tooltip';
import Icon from '../../../vue_shared/components/icon.vue'; import Icon from '../../../vue_shared/components/icon.vue';
import { rightSidebarViews } from '../../constants'; import { rightSidebarViews } from '../../constants';
...@@ -21,6 +22,13 @@ export default { ...@@ -21,6 +22,13 @@ export default {
MergeRequestInfo, MergeRequestInfo,
Clientside, Clientside,
}, },
props: {
extensionTabs: {
type: Array,
required: false,
default: () => [],
},
},
computed: { computed: {
...mapState(['rightPane', 'currentMergeRequestId', 'clientsidePreviewEnabled']), ...mapState(['rightPane', 'currentMergeRequestId', 'clientsidePreviewEnabled']),
...mapGetters(['packageJson']), ...mapGetters(['packageJson']),
...@@ -33,6 +41,36 @@ export default { ...@@ -33,6 +41,36 @@ export default {
showLivePreview() { showLivePreview() {
return this.packageJson && this.clientsidePreviewEnabled; return this.packageJson && this.clientsidePreviewEnabled;
}, },
defaultTabs() {
return [
{
show: this.currentMergeRequestId,
title: __('Merge Request'),
isActive: this.rightPane === rightSidebarViews.mergeRequestInfo,
view: rightSidebarViews.mergeRequestInfo,
icon: 'text-description',
},
{
show: true,
title: __('Pipelines'),
isActive: this.pipelinesActive,
view: rightSidebarViews.pipelines,
icon: 'rocket',
},
{
show: this.showLivePreview,
title: __('Live preview'),
isActive: this.rightPane === rightSidebarViews.clientSidePreview,
view: rightSidebarViews.clientSidePreview,
icon: 'live-preview',
},
];
},
tabs() {
return this.defaultTabs
.concat(this.extensionTabs)
.filter(tab => tab.show);
},
}, },
methods: { methods: {
...mapActions(['setRightPane']), ...mapActions(['setRightPane']),
...@@ -42,7 +80,6 @@ export default { ...@@ -42,7 +80,6 @@ export default {
this.setRightPane(view); this.setRightPane(view);
}, },
}, },
rightSidebarViews,
}; };
</script> </script>
...@@ -64,64 +101,25 @@ export default { ...@@ -64,64 +101,25 @@ export default {
<nav class="ide-activity-bar"> <nav class="ide-activity-bar">
<ul class="list-unstyled"> <ul class="list-unstyled">
<li <li
v-if="currentMergeRequestId" v-for="tab of tabs"
> :key="tab.title"
<button
v-tooltip
:title="__('Merge Request')"
:aria-label="__('Merge Request')"
:class="{
active: rightPane === $options.rightSidebarViews.mergeRequestInfo
}"
data-container="body"
data-placement="left"
class="ide-sidebar-link is-right"
type="button"
@click="clickTab($event, $options.rightSidebarViews.mergeRequestInfo)"
> >
<icon
:size="16"
name="text-description"
/>
</button>
</li>
<li>
<button
v-tooltip
:title="__('Pipelines')"
:aria-label="__('Pipelines')"
:class="{
active: pipelinesActive
}"
data-container="body"
data-placement="left"
class="ide-sidebar-link is-right"
type="button"
@click="clickTab($event, $options.rightSidebarViews.pipelines)"
>
<icon
:size="16"
name="rocket"
/>
</button>
</li>
<li v-if="showLivePreview">
<button <button
v-tooltip v-tooltip
:title="__('Live preview')" :title="tab.title"
:aria-label="__('Live preview')" :aria-label="tab.title"
:class="{ :class="{
active: rightPane === $options.rightSidebarViews.clientSidePreview active: tab.isActive
}" }"
data-container="body" data-container="body"
data-placement="left" data-placement="left"
class="ide-sidebar-link is-right" class="ide-sidebar-link is-right"
type="button" type="button"
@click="clickTab($event, $options.rightSidebarViews.clientSidePreview)" @click="clickTab($event, tab.view)"
> >
<icon <icon
:size="16" :size="16"
name="live-preview" :name="tab.icon"
/> />
</button> </button>
</li> </li>
......
...@@ -15,21 +15,21 @@ Vue.use(Translate); ...@@ -15,21 +15,21 @@ Vue.use(Translate);
* @param {Object} options - Extra options for the IDE (Used by EE). * @param {Object} options - Extra options for the IDE (Used by EE).
* @param {(e:Element) => Object} options.extraInitialData - * @param {(e:Element) => Object} options.extraInitialData -
* Function that returns extra properties to seed initial data. * Function that returns extra properties to seed initial data.
* @param {Component} options.rootComponent -
* Component that overrides the root component.
*/ */
export function initIde(el, options = {}) { export function initIde(el, options = {}) {
if (!el) return null; if (!el) return null;
const { const {
extraInitialData = () => ({}), extraInitialData = () => ({}),
rootComponent = ide,
} = options; } = options;
return new Vue({ return new Vue({
el, el,
store, store,
router, router,
components: {
ide,
},
created() { created() {
this.setEmptyStateSvgs({ this.setEmptyStateSvgs({
emptyStateSvgPath: el.dataset.emptyStateSvgPath, emptyStateSvgPath: el.dataset.emptyStateSvgPath,
...@@ -51,7 +51,7 @@ export function initIde(el, options = {}) { ...@@ -51,7 +51,7 @@ export function initIde(el, options = {}) {
...mapActions(['setEmptyStateSvgs', 'setLinks', 'setInitialData']), ...mapActions(['setEmptyStateSvgs', 'setLinks', 'setInitialData']),
}, },
render(createElement) { render(createElement) {
return createElement('ide'); return createElement(rootComponent);
}, },
}); });
} }
......
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