diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-01-17 03:09:00 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-01-17 03:09:00 +0300 |
commit | efb0c7f501e4a8883796b5acfdc584e2720febba (patch) | |
tree | a5870a33d1154a555a46b293aac42dbb4197b31d /app/assets/javascripts/ide/components | |
parent | 727b1a890c8e44440414c59611e9ead34d6edc93 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/ide/components')
3 files changed, 167 insertions, 89 deletions
diff --git a/app/assets/javascripts/ide/components/ide.vue b/app/assets/javascripts/ide/components/ide.vue index 363a8f43033..6ed863c9c2e 100644 --- a/app/assets/javascripts/ide/components/ide.vue +++ b/app/assets/javascripts/ide/components/ide.vue @@ -1,6 +1,6 @@ <script> import Vue from 'vue'; -import { mapActions, mapState, mapGetters } from 'vuex'; +import { mapActions, mapGetters, mapState } from 'vuex'; import { GlButton, GlLoadingIcon } from '@gitlab/ui'; import { __ } from '~/locale'; import FindFile from '~/vue_shared/components/file_finder/index.vue'; diff --git a/app/assets/javascripts/ide/components/panes/collapsible_sidebar.vue b/app/assets/javascripts/ide/components/panes/collapsible_sidebar.vue new file mode 100644 index 00000000000..d5a123edb80 --- /dev/null +++ b/app/assets/javascripts/ide/components/panes/collapsible_sidebar.vue @@ -0,0 +1,151 @@ +<script> +import { mapActions, mapState } from 'vuex'; +import _ from 'underscore'; +import tooltip from '~/vue_shared/directives/tooltip'; +import Icon from '~/vue_shared/components/icon.vue'; +import ResizablePanel from '../resizable_panel.vue'; +import { GlSkeletonLoading } from '@gitlab/ui'; + +export default { + name: 'CollapsibleSidebar', + directives: { + tooltip, + }, + components: { + Icon, + ResizablePanel, + GlSkeletonLoading, + }, + props: { + extensionTabs: { + type: Array, + required: false, + default: () => [], + }, + side: { + type: String, + required: true, + }, + width: { + type: Number, + required: true, + }, + }, + computed: { + ...mapState(['loading']), + ...mapState({ + isOpen(state) { + return state[this.namespace].isOpen; + }, + currentView(state) { + return state[this.namespace].currentView; + }, + isActiveView(state, getters) { + return getters[`${this.namespace}/isActiveView`]; + }, + isAliveView(_state, getters) { + return getters[`${this.namespace}/isAliveView`]; + }, + }), + namespace() { + // eslint-disable-next-line @gitlab/i18n/no-non-i18n-strings + return `${this.side}Pane`; + }, + tabs() { + return this.extensionTabs.filter(tab => tab.show); + }, + tabViews() { + return _.flatten(this.tabs.map(tab => tab.views)); + }, + aliveTabViews() { + return this.tabViews.filter(view => this.isAliveView(view.name)); + }, + otherSide() { + return this.side === 'right' ? 'left' : 'right'; + }, + }, + methods: { + ...mapActions({ + toggleOpen(dispatch) { + return dispatch(`${this.namespace}/toggleOpen`); + }, + open(dispatch, view) { + return dispatch(`${this.namespace}/open`, view); + }, + }), + clickTab(e, tab) { + e.target.blur(); + + if (this.isActiveTab(tab)) { + this.toggleOpen(); + } else { + this.open(tab.views[0]); + } + }, + isActiveTab(tab) { + return tab.views.some(view => this.isActiveView(view.name)); + }, + buttonClasses(tab) { + return [ + this.side === 'right' ? 'is-right' : '', + this.isActiveTab(tab) && this.isOpen ? 'active' : '', + ...(tab.buttonClasses || []), + ]; + }, + }, +}; +</script> + +<template> + <div + :class="`ide-${side}-sidebar`" + :data-qa-selector="`ide_${side}_sidebar`" + class="multi-file-commit-panel ide-sidebar" + > + <resizable-panel + v-show="isOpen" + :collapsible="false" + :initial-width="width" + :min-size="width" + :class="`ide-${side}-sidebar-${currentView}`" + :side="side" + class="multi-file-commit-panel-inner" + > + <div class="h-100 d-flex flex-column align-items-stretch"> + <slot v-if="isOpen" name="header"></slot> + <div + v-for="tabView in aliveTabViews" + v-show="isActiveView(tabView.name)" + :key="tabView.name" + class="flex-fill js-tab-view" + > + <component :is="tabView.component" /> + </div> + <slot name="footer"></slot> + </div> + </resizable-panel> + <nav class="ide-activity-bar"> + <ul class="list-unstyled"> + <li> + <slot name="header-icon"></slot> + </li> + <li v-for="tab of tabs" :key="tab.title"> + <button + v-tooltip + :title="tab.title" + :aria-label="tab.title" + :class="buttonClasses(tab)" + data-container="body" + :data-placement="otherSide" + :data-qa-selector="`${tab.title.toLowerCase()}_tab_button`" + class="ide-sidebar-link" + type="button" + @click="clickTab($event, tab)" + > + <icon :size="16" :name="tab.icon" /> + </button> + </li> + </ul> + </nav> + </div> +</template> diff --git a/app/assets/javascripts/ide/components/panes/right.vue b/app/assets/javascripts/ide/components/panes/right.vue index 200391282e7..40ed7d9c422 100644 --- a/app/assets/javascripts/ide/components/panes/right.vue +++ b/app/assets/javascripts/ide/components/panes/right.vue @@ -1,27 +1,17 @@ <script> -import { mapActions, mapState, mapGetters } from 'vuex'; -import _ from 'underscore'; +import { mapGetters, mapState } from 'vuex'; import { __ } from '~/locale'; -import tooltip from '../../../vue_shared/directives/tooltip'; -import Icon from '../../../vue_shared/components/icon.vue'; +import CollapsibleSidebar from './collapsible_sidebar.vue'; import { rightSidebarViews } from '../../constants'; +import MergeRequestInfo from '../merge_requests/info.vue'; import PipelinesList from '../pipelines/list.vue'; import JobsDetail from '../jobs/detail.vue'; -import MergeRequestInfo from '../merge_requests/info.vue'; -import ResizablePanel from '../resizable_panel.vue'; import Clientside from '../preview/clientside.vue'; export default { - directives: { - tooltip, - }, + name: 'RightPane', components: { - Icon, - PipelinesList, - JobsDetail, - ResizablePanel, - MergeRequestInfo, - Clientside, + CollapsibleSidebar, }, props: { extensionTabs: { @@ -32,103 +22,40 @@ export default { }, computed: { ...mapState(['currentMergeRequestId', 'clientsidePreviewEnabled']), - ...mapState('rightPane', ['isOpen', 'currentView']), ...mapGetters(['packageJson']), - ...mapGetters('rightPane', ['isActiveView', 'isAliveView']), showLivePreview() { return this.packageJson && this.clientsidePreviewEnabled; }, - defaultTabs() { + rightExtensionTabs() { return [ { - show: this.currentMergeRequestId, + show: Boolean(this.currentMergeRequestId), title: __('Merge Request'), - views: [rightSidebarViews.mergeRequestInfo], + views: [{ component: MergeRequestInfo, ...rightSidebarViews.mergeRequestInfo }], icon: 'text-description', }, { show: true, title: __('Pipelines'), - views: [rightSidebarViews.pipelines, rightSidebarViews.jobsDetail], + views: [ + { component: PipelinesList, ...rightSidebarViews.pipelines }, + { component: JobsDetail, ...rightSidebarViews.jobsDetail }, + ], icon: 'rocket', }, { show: this.showLivePreview, title: __('Live preview'), - views: [rightSidebarViews.clientSidePreview], + views: [{ component: Clientside, ...rightSidebarViews.clientSidePreview }], icon: 'live-preview', }, + ...this.extensionTabs, ]; }, - tabs() { - return this.defaultTabs.concat(this.extensionTabs).filter(tab => tab.show); - }, - tabViews() { - return _.flatten(this.tabs.map(tab => tab.views)); - }, - aliveTabViews() { - return this.tabViews.filter(view => this.isAliveView(view.name)); - }, - }, - methods: { - ...mapActions('rightPane', ['toggleOpen', 'open']), - clickTab(e, tab) { - e.target.blur(); - - if (this.isActiveTab(tab)) { - this.toggleOpen(); - } else { - this.open(tab.views[0]); - } - }, - isActiveTab(tab) { - return tab.views.some(view => this.isActiveView(view.name)); - }, }, }; </script> <template> - <div class="multi-file-commit-panel ide-right-sidebar" data-qa-selector="ide_right_sidebar"> - <resizable-panel - v-show="isOpen" - :collapsible="false" - :initial-width="350" - :min-size="350" - :class="`ide-right-sidebar-${currentView}`" - side="right" - class="multi-file-commit-panel-inner" - > - <div - v-for="tabView in aliveTabViews" - v-show="isActiveView(tabView.name)" - :key="tabView.name" - class="h-100" - > - <component :is="tabView.component || tabView.name" /> - </div> - </resizable-panel> - <nav class="ide-activity-bar"> - <ul class="list-unstyled"> - <li v-for="tab of tabs" :key="tab.title"> - <button - v-tooltip - :title="tab.title" - :aria-label="tab.title" - :class="{ - active: isActiveTab(tab) && isOpen, - }" - data-container="body" - data-placement="left" - :data-qa-selector="`${tab.title.toLowerCase()}_tab_button`" - class="ide-sidebar-link is-right" - type="button" - @click="clickTab($event, tab)" - > - <icon :size="16" :name="tab.icon" /> - </button> - </li> - </ul> - </nav> - </div> + <collapsible-sidebar :extension-tabs="rightExtensionTabs" side="right" :width="350" /> </template> |