From a1348a5d2932784b29b0b9fb18e519f18c085e62 Mon Sep 17 00:00:00 2001 From: Filipa Lacerda Date: Fri, 12 May 2017 11:28:26 +0000 Subject: [PATCH] Uniform CI status components in vue --- .../javascripts/pipelines/components/stage.js | 104 ------------------ .../pipelines/components/status.js | 60 ---------- .../components/mr_widget_deployment.js | 4 +- .../components/mr_widget_pipeline.js | 21 +++- .../javascripts/vue_shared/ci_status_icons.js | 12 -- .../vue_shared/components/ci_badge_link.vue | 52 +++++++++ .../vue_shared/components/ci_icon.vue | 25 ++++- .../components/pipeline_status_icon.js | 23 ---- .../components/pipelines_table_row.js | 15 ++- .../vue_shared/pipeline_svg_icons.js | 43 -------- .../stylesheets/pages/merge_requests.scss | 8 +- .../unreleased/30286-ci-badge-component.yml | 4 + .../components/mr_widget_deployment_spec.js | 4 +- .../components/mr_widget_pipeline_spec.js | 6 +- .../components/ci_badge_link_spec.js | 89 +++++++++++++++ .../vue_shared/components/ci_icon_spec.js | 9 ++ 16 files changed, 213 insertions(+), 266 deletions(-) delete mode 100644 app/assets/javascripts/pipelines/components/stage.js delete mode 100644 app/assets/javascripts/pipelines/components/status.js create mode 100644 app/assets/javascripts/vue_shared/components/ci_badge_link.vue delete mode 100644 app/assets/javascripts/vue_shared/components/pipeline_status_icon.js delete mode 100644 app/assets/javascripts/vue_shared/pipeline_svg_icons.js create mode 100644 changelogs/unreleased/30286-ci-badge-component.yml create mode 100644 spec/javascripts/vue_shared/components/ci_badge_link_spec.js diff --git a/app/assets/javascripts/pipelines/components/stage.js b/app/assets/javascripts/pipelines/components/stage.js deleted file mode 100644 index 034e8d3280e..00000000000 --- a/app/assets/javascripts/pipelines/components/stage.js +++ /dev/null @@ -1,104 +0,0 @@ -/* global Flash */ -import { borderlessStatusIconEntityMap } from '../../vue_shared/ci_status_icons'; - -export default { - data() { - return { - builds: '', - spinner: '', - }; - }, - - props: { - stage: { - type: Object, - required: true, - }, - }, - - updated() { - if (this.builds) { - this.stopDropdownClickPropagation(); - } - }, - - methods: { - fetchBuilds(e) { - const ariaExpanded = e.currentTarget.attributes['aria-expanded']; - - if (ariaExpanded && (ariaExpanded.textContent === 'true')) return null; - - return this.$http.get(this.stage.dropdown_path) - .then((response) => { - this.builds = JSON.parse(response.body).html; - }, () => { - const flash = new Flash('Something went wrong on our end.'); - return flash; - }); - }, - - /** - * When the user right clicks or cmd/ctrl + click in the job name - * 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-builds-dropdown-list a.mini-pipeline-graph-dropdown-item')).on('click', (e) => { - e.stopPropagation(); - }); - }, - }, - computed: { - buildsOrSpinner() { - return this.builds ? this.builds : this.spinner; - }, - dropdownClass() { - if (this.builds) return 'js-builds-dropdown-container'; - return 'js-builds-dropdown-loading builds-dropdown-loading'; - }, - buildStatus() { - return `Build: ${this.stage.status.label}`; - }, - tooltip() { - return `has-tooltip ci-status-icon ci-status-icon-${this.stage.status.group}`; - }, - triggerButtonClass() { - return `mini-pipeline-graph-dropdown-toggle has-tooltip js-builds-dropdown-button ci-status-icon-${this.stage.status.group}`; - }, - svgHTML() { - return borderlessStatusIconEntityMap[this.stage.status.icon]; - }, - }, - watch: { - 'stage.title': function stageTitle() { - $(this.$refs.button).tooltip('destroy').tooltip(); - }, - }, - template: ` -
- - -
- `, -}; diff --git a/app/assets/javascripts/pipelines/components/status.js b/app/assets/javascripts/pipelines/components/status.js deleted file mode 100644 index 21a281af438..00000000000 --- a/app/assets/javascripts/pipelines/components/status.js +++ /dev/null @@ -1,60 +0,0 @@ -import canceledSvg from 'icons/_icon_status_canceled.svg'; -import createdSvg from 'icons/_icon_status_created.svg'; -import failedSvg from 'icons/_icon_status_failed.svg'; -import manualSvg from 'icons/_icon_status_manual.svg'; -import pendingSvg from 'icons/_icon_status_pending.svg'; -import runningSvg from 'icons/_icon_status_running.svg'; -import skippedSvg from 'icons/_icon_status_skipped.svg'; -import successSvg from 'icons/_icon_status_success.svg'; -import warningSvg from 'icons/_icon_status_warning.svg'; - -export default { - props: { - pipeline: { - type: Object, - required: true, - }, - }, - - data() { - const svgsDictionary = { - icon_status_canceled: canceledSvg, - icon_status_created: createdSvg, - icon_status_failed: failedSvg, - icon_status_manual: manualSvg, - icon_status_pending: pendingSvg, - icon_status_running: runningSvg, - icon_status_skipped: skippedSvg, - icon_status_success: successSvg, - icon_status_warning: warningSvg, - }; - - return { - svg: svgsDictionary[this.pipeline.details.status.icon], - }; - }, - - computed: { - cssClasses() { - return `ci-status ci-${this.pipeline.details.status.group}`; - }, - - detailsPath() { - const { status } = this.pipeline.details; - return status.has_details ? status.details_path : false; - }, - - content() { - return `${this.svg} ${this.pipeline.details.status.text}`; - }, - }, - template: ` - - - - - `, -}; diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_deployment.js b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_deployment.js index 3c23b8e472b..8b59e018836 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_deployment.js +++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_deployment.js @@ -1,7 +1,7 @@ /* global Flash */ import '~/lib/utils/datetime_utility'; -import { statusClassToSvgMap } from '../../vue_shared/pipeline_svg_icons'; +import { statusIconEntityMap } from '../../vue_shared/ci_status_icons'; import MemoryUsage from './mr_widget_memory_usage'; import MRWidgetService from '../services/mr_widget_service'; @@ -16,7 +16,7 @@ export default { }, computed: { svg() { - return statusClassToSvgMap.icon_status_success; + return statusIconEntityMap.icon_status_success; }, }, methods: { diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.js b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.js index 801b9fb1ba1..d8c27013cd3 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.js +++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.js @@ -1,6 +1,6 @@ -import PipelineStage from '../../pipelines/components/stage'; -import pipelineStatusIcon from '../../vue_shared/components/pipeline_status_icon'; -import { statusClassToSvgMap } from '../../vue_shared/pipeline_svg_icons'; +import PipelineStage from '../../pipelines/components/stage.vue'; +import ciIcon from '../../vue_shared/components/ci_icon.vue'; +import { statusIconEntityMap } from '../../vue_shared/ci_status_icons'; export default { name: 'MRWidgetPipeline', @@ -9,7 +9,7 @@ export default { }, components: { 'pipeline-stage': PipelineStage, - 'pipeline-status-icon': pipelineStatusIcon, + ciIcon, }, computed: { hasCIError() { @@ -18,11 +18,14 @@ export default { return hasCI && !ciStatus; }, svg() { - return statusClassToSvgMap.icon_status_failed; + return statusIconEntityMap.icon_status_failed; }, stageText() { return this.mr.pipeline.details.stages.length > 1 ? 'stages' : 'stage'; }, + status() { + return this.mr.pipeline.details.status || {}; + }, }, template: `
@@ -38,7 +41,13 @@ export default { Could not connect to the CI server. Please check your settings and try again.