diff options
author | Filipa Lacerda <filipa@gitlab.com> | 2018-04-17 13:04:53 +0100 |
---|---|---|
committer | Filipa Lacerda <filipa@gitlab.com> | 2018-04-17 13:04:53 +0100 |
commit | 6dd403d501b9f3faee8618130fd6b5107b6f9164 (patch) | |
tree | 64797d0c0dde0f50b93b50487d0dcc2f81820139 | |
parent | 5f85a64d89201e1d2a394d857c112f7f32255493 (diff) | |
download | gitlab-ce-33697-dropdown-json-endpoint-stages.tar.gz |
wip [ci skip]33697-dropdown-json-endpoint-stages
9 files changed, 99 insertions, 170 deletions
diff --git a/app/assets/javascripts/pipelines/components/graph/action_component.vue b/app/assets/javascripts/pipelines/components/graph/action_component.vue index e99d949801f..d81141941b4 100644 --- a/app/assets/javascripts/pipelines/components/graph/action_component.vue +++ b/app/assets/javascripts/pipelines/components/graph/action_component.vue @@ -32,26 +32,42 @@ export default { required: true, }, - buttonDisabled: { + requestDoneForLink: { type: String, required: false, default: null, }, }, + + data() { + return { + isDisabled: false, + linkRequested: '', + }; + }, + computed: { cssClass() { const actionIconDash = dasherize(this.actionIcon); return `${actionIconDash} js-icon-${actionIconDash}`; }, - isDisabled() { - return this.buttonDisabled === this.link; - }, + }, + + watch: { + requestDoneForLink(oldValue, newValue) { + debugger; + if (newValue === this.linkRequested) { + this.isDisabled = false; + } + } }, methods: { onClickAction() { $(this.$el).tooltip('hide'); eventHub.$emit('graphAction', this.link); + this.linkRequested = this.link; + this.isDisabled = true; }, }, }; @@ -62,7 +78,7 @@ export default { @click="onClickAction" v-tooltip :title="tooltipText" - class="btn btn-blank btn-transparent ci-action-icon-container ci-action-icon-wrapper" + class="btn btn-blank btn-transparent js-ci-action ci-action-icon-container ci-action-icon-wrapper" :class="cssClass" data-container="body" :disabled="isDisabled" diff --git a/app/assets/javascripts/pipelines/components/graph/dropdown_action_component.vue b/app/assets/javascripts/pipelines/components/graph/dropdown_action_component.vue deleted file mode 100644 index 7c4fd65e36f..00000000000 --- a/app/assets/javascripts/pipelines/components/graph/dropdown_action_component.vue +++ /dev/null @@ -1,53 +0,0 @@ -<script> - import icon from '../../../vue_shared/components/icon.vue'; - import tooltip from '../../../vue_shared/directives/tooltip'; - - /** - * Renders either a cancel, retry or play icon pointing to the given path. - * TODO: Remove UJS from here and use an async request instead. - */ - export default { - components: { - icon, - }, - - directives: { - tooltip, - }, - props: { - tooltipText: { - type: String, - required: true, - }, - - link: { - type: String, - required: true, - }, - - actionMethod: { - type: String, - required: true, - }, - - actionIcon: { - type: String, - required: true, - }, - }, - }; -</script> -<template> - <a - v-tooltip - :data-method="actionMethod" - :title="tooltipText" - :href="link" - rel="nofollow" - class="ci-action-icon-wrapper js-ci-status-icon" - data-container="body" - aria-label="Job's action" - > - <icon :name="actionIcon" /> - </a> -</template> diff --git a/app/assets/javascripts/pipelines/components/graph/dropdown_job_component.vue b/app/assets/javascripts/pipelines/components/graph/dropdown_job_component.vue index be213c2ee78..bb94726cc77 100644 --- a/app/assets/javascripts/pipelines/components/graph/dropdown_job_component.vue +++ b/app/assets/javascripts/pipelines/components/graph/dropdown_job_component.vue @@ -1,77 +1,78 @@ <script> - import $ from 'jquery'; - import jobNameComponent from './job_name_component.vue'; - import jobComponent from './job_component.vue'; - import tooltip from '../../../vue_shared/directives/tooltip'; +import $ from 'jquery'; +import JobNameComponent from './job_name_component.vue'; +import JobComponent from './job_component.vue'; +import tooltip from '../../../vue_shared/directives/tooltip'; - /** - * Renders the dropdown for the pipeline graph. - * - * The following object should be provided as `job`: - * - * { - * "id": 4256, - * "name": "test", - * "status": { - * "icon": "icon_status_success", - * "text": "passed", - * "label": "passed", - * "group": "success", - * "details_path": "/root/ci-mock/builds/4256", - * "action": { - * "icon": "retry", - * "title": "Retry", - * "path": "/root/ci-mock/builds/4256/retry", - * "method": "post" - * } - * } - * } - */ - export default { - directives: { - tooltip, - }, +/** + * Renders the dropdown for the pipeline graph. + * + * The following object should be provided as `job`: + * + * { + * "id": 4256, + * "name": "test", + * "status": { + * "icon": "icon_status_success", + * "text": "passed", + * "label": "passed", + * "group": "success", + * "details_path": "/root/ci-mock/builds/4256", + * "action": { + * "icon": "retry", + * "title": "Retry", + * "path": "/root/ci-mock/builds/4256/retry", + * "method": "post" + * } + * } + * } + */ +export default { + directives: { + tooltip, + }, - components: { - jobComponent, - jobNameComponent, - }, + components: { + JobComponent, + JobNameComponent, + }, - props: { - job: { - type: Object, - required: true, - }, + props: { + job: { + type: Object, + required: true, }, + }, - computed: { - tooltipText() { - return `${this.job.name} - ${this.job.status.label}`; - }, + computed: { + tooltipText() { + return `${this.job.name} - ${this.job.status.label}`; }, + }, - mounted() { - this.stopDropdownClickPropagation(); - }, + mounted() { + this.stopDropdownClickPropagation(); + }, - methods: { - /** - * When the user right clicks or cmd/ctrl + click in the job name + methods: { + /** + * When the user right clicks or cmd/ctrl + click in the job name or the action icon * the dropdown should not be closed and the link should open in another tab, * so we stop propagation of the click event inside the dropdown. * * Since this component is rendered multiple times per page we need to guarantee we only * target the click event of this component. */ - stopDropdownClickPropagation() { - $(this.$el - .querySelectorAll('.js-grouped-pipeline-dropdown a.mini-pipeline-graph-dropdown-item')) - .on('click', (e) => { - e.stopPropagation(); - }); - }, + stopDropdownClickPropagation() { + $( + '.js-grouped-pipeline-dropdown button, .js-grouped-pipeline-dropdown a.mini-pipeline-graph-dropdown-item', + this.$el, + ).on('click', e => { + e.stopPropagation(); + }); }, - }; + }, +}; </script> <template> <div class="ci-job-dropdown-container"> diff --git a/app/assets/javascripts/pipelines/components/graph/graph_component.vue b/app/assets/javascripts/pipelines/components/graph/graph_component.vue index ac9ce7e47d6..e6f38bae361 100644 --- a/app/assets/javascripts/pipelines/components/graph/graph_component.vue +++ b/app/assets/javascripts/pipelines/components/graph/graph_component.vue @@ -17,7 +17,7 @@ export default { type: Object, required: true, }, - actionDisabled: { + requestDoneForLink: { type: String, required: false, default: null, @@ -75,7 +75,7 @@ export default { :key="stage.name" :stage-connector-class="stageConnectorClass(index, stage)" :is-first-column="isFirstColumn(index)" - :action-disabled="actionDisabled" + :request-done-for-link="requestDoneForLink" /> </ul> </div> diff --git a/app/assets/javascripts/pipelines/components/graph/job_component.vue b/app/assets/javascripts/pipelines/components/graph/job_component.vue index c6e5ae6df41..7687cfd6148 100644 --- a/app/assets/javascripts/pipelines/components/graph/job_component.vue +++ b/app/assets/javascripts/pipelines/components/graph/job_component.vue @@ -1,6 +1,5 @@ <script> import ActionComponent from './action_component.vue'; -import DropdownActionComponent from './dropdown_action_component.vue'; import JobNameComponent from './job_name_component.vue'; import tooltip from '../../../vue_shared/directives/tooltip'; @@ -32,7 +31,6 @@ import tooltip from '../../../vue_shared/directives/tooltip'; export default { components: { ActionComponent, - DropdownActionComponent, JobNameComponent, }, @@ -57,7 +55,7 @@ export default { default: false, }, - actionDisabled: { + requestDoneForLink: { type: String, required: false, default: null, @@ -134,19 +132,12 @@ export default { </div> <action-component - v-if="hasAction && !isDropdown" + v-if="hasAction" :tooltip-text="status.action.title" :link="status.action.path" :action-icon="status.action.icon" - :button-disabled="actionDisabled" + :request-done-for-link="requestDoneForLink" /> - <dropdown-action-component - v-if="hasAction && isDropdown" - :tooltip-text="status.action.title" - :link="status.action.path" - :action-icon="status.action.icon" - :action-method="status.action.method" - /> </div> </template> diff --git a/app/assets/javascripts/pipelines/components/graph/stage_column_component.vue b/app/assets/javascripts/pipelines/components/graph/stage_column_component.vue index f6e6569e15b..0990ce70a84 100644 --- a/app/assets/javascripts/pipelines/components/graph/stage_column_component.vue +++ b/app/assets/javascripts/pipelines/components/graph/stage_column_component.vue @@ -29,7 +29,7 @@ export default { required: false, default: '', }, - actionDisabled: { + requestDoneForLink: { type: String, required: false, default: null, @@ -74,7 +74,7 @@ export default { v-if="job.size === 1" :job="job" css-class-job-name="build-content" - :action-disabled="actionDisabled" + :request-done-for-link="requestDoneForLink" /> <dropdown-job-component diff --git a/app/assets/javascripts/pipelines/pipeline_details_bundle.js b/app/assets/javascripts/pipelines/pipeline_details_bundle.js index 900eb7855f4..169e54721b6 100644 --- a/app/assets/javascripts/pipelines/pipeline_details_bundle.js +++ b/app/assets/javascripts/pipelines/pipeline_details_bundle.js @@ -25,7 +25,7 @@ export default () => { data() { return { mediator, - actionDisabled: null, + requestDoneForLink: '', }; }, created() { @@ -36,15 +36,13 @@ export default () => { }, methods: { postAction(action) { - this.actionDisabled = action; - this.mediator.service.postAction(action) .then(() => { this.mediator.refreshPipeline(); - this.actionDisabled = null; + this.requestDoneForLink = action; }) .catch(() => { - this.actionDisabled = null; + this.requestDoneForLink = action; Flash(__('An error occurred while making the request.')); }); }, @@ -54,7 +52,7 @@ export default () => { props: { isLoading: this.mediator.state.isLoading, pipeline: this.mediator.store.state.pipeline, - actionDisabled: this.actionDisabled, + requestDoneForLink: this.requestDoneForLink, }, }); }, diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss index 2c840cb407a..27b3b285649 100644 --- a/app/assets/stylesheets/pages/pipelines.scss +++ b/app/assets/stylesheets/pages/pipelines.scss @@ -463,6 +463,14 @@ margin-bottom: 10px; white-space: normal; + .ci-job-dropdown-container { + // override dropdown.scss + .dropdown-menu li button { + padding: 0; + text-align: center; + } + } + // ensure .build-content has hover style when action-icon is hovered .ci-job-dropdown-container:hover .build-content { @extend .build-content:hover; diff --git a/spec/javascripts/pipelines/graph/dropdown_action_component_spec.js b/spec/javascripts/pipelines/graph/dropdown_action_component_spec.js deleted file mode 100644 index ba721bc53c6..00000000000 --- a/spec/javascripts/pipelines/graph/dropdown_action_component_spec.js +++ /dev/null @@ -1,32 +0,0 @@ -import Vue from 'vue'; -import dropdownActionComponent from '~/pipelines/components/graph/dropdown_action_component.vue'; - -describe('action component', () => { - let component; - - beforeEach((done) => { - const DropdownActionComponent = Vue.extend(dropdownActionComponent); - component = new DropdownActionComponent({ - propsData: { - tooltipText: 'bar', - link: 'foo', - actionMethod: 'post', - actionIcon: 'cancel', - }, - }).$mount(); - - Vue.nextTick(done); - }); - - it('should render a link', () => { - expect(component.$el.getAttribute('href')).toEqual('foo'); - }); - - it('should render the provided title as a bootstrap tooltip', () => { - expect(component.$el.getAttribute('data-original-title')).toEqual('bar'); - }); - - it('should render an svg', () => { - expect(component.$el.querySelector('svg')).toBeDefined(); - }); -}); |