diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-09-20 02:18:09 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-09-20 02:18:09 +0300 |
commit | 6ed4ec3e0b1340f96b7c043ef51d1b33bbe85fde (patch) | |
tree | dc4d20fe6064752c0bd323187252c77e0a89144b /app/assets/javascripts/pipelines/components/pipeline_mini_graph/pipeline_stage.vue | |
parent | 9868dae7fc0655bd7ce4a6887d4e6d487690eeed (diff) |
Add latest changes from gitlab-org/gitlab@15-4-stable-eev15.4.0-rc42
Diffstat (limited to 'app/assets/javascripts/pipelines/components/pipeline_mini_graph/pipeline_stage.vue')
-rw-r--r-- | app/assets/javascripts/pipelines/components/pipeline_mini_graph/pipeline_stage.vue | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/app/assets/javascripts/pipelines/components/pipeline_mini_graph/pipeline_stage.vue b/app/assets/javascripts/pipelines/components/pipeline_mini_graph/pipeline_stage.vue new file mode 100644 index 00000000000..a68797a7235 --- /dev/null +++ b/app/assets/javascripts/pipelines/components/pipeline_mini_graph/pipeline_stage.vue @@ -0,0 +1,186 @@ +<script> +/** + * Renders each stage of the pipeline mini graph. + * + * Given the provided endpoint will make a request to + * fetch the dropdown data when the stage is clicked. + * + * Request is made inside this component to make it reusable between: + * 1. Pipelines main table + * 2. Pipelines table in commit and Merge request views + * 3. Merge request widget + * 4. Commit widget + */ + +import { GlDropdown, GlLoadingIcon, GlTooltipDirective } from '@gitlab/ui'; +import CiIcon from '~/vue_shared/components/ci_icon.vue'; +import createFlash from '~/flash'; +import axios from '~/lib/utils/axios_utils'; +import { __, sprintf } from '~/locale'; +import eventHub from '../../event_hub'; +import JobItem from './job_item.vue'; + +export default { + i18n: { + stage: __('Stage:'), + loadingText: __('Loading, please wait.'), + }, + dropdownPopperOpts: { + placement: 'bottom', + }, + components: { + CiIcon, + GlLoadingIcon, + GlDropdown, + JobItem, + }, + directives: { + GlTooltip: GlTooltipDirective, + }, + props: { + stage: { + type: Object, + required: true, + }, + updateDropdown: { + type: Boolean, + required: false, + default: false, + }, + isMergeTrain: { + type: Boolean, + required: false, + default: false, + }, + }, + data() { + return { + isDropdownOpen: false, + isLoading: false, + dropdownContent: [], + stageName: '', + }; + }, + watch: { + updateDropdown() { + if (this.updateDropdown && this.isDropdownOpen && !this.isLoading) { + this.fetchJobs(); + } + }, + }, + methods: { + onHideDropdown() { + this.isDropdownOpen = false; + }, + onShowDropdown() { + eventHub.$emit('clickedDropdown'); + this.isDropdownOpen = true; + this.isLoading = true; + this.fetchJobs(); + + // used for tracking and is separate from event hub + // to avoid complexity with mixin + this.$emit('miniGraphStageClick'); + }, + fetchJobs() { + axios + .get(this.stage.dropdown_path) + .then(({ data }) => { + this.dropdownContent = data.latest_statuses; + this.stageName = data.name; + this.isLoading = false; + }) + .catch(() => { + this.$refs.dropdown.hide(); + this.isLoading = false; + + createFlash({ + message: __('Something went wrong on our end.'), + }); + }); + }, + pipelineActionRequestComplete() { + // close the dropdown in MR widget + this.$refs.dropdown.hide(); + + // warn the pipelines table to update + this.$emit('pipelineActionRequestComplete'); + }, + stageAriaLabel(title) { + return sprintf(__('View Stage: %{title}'), { title }); + }, + }, +}; +</script> + +<template> + <gl-dropdown + ref="dropdown" + v-gl-tooltip.hover.ds0 + v-gl-tooltip="stage.title" + data-testid="mini-pipeline-graph-dropdown" + variant="link" + :aria-label="stageAriaLabel(stage.title)" + :lazy="true" + :popper-opts="$options.dropdownPopperOpts" + :toggle-class="['gl-rounded-full!']" + menu-class="mini-pipeline-graph-dropdown-menu" + @hide="onHideDropdown" + @show="onShowDropdown" + > + <template #button-content> + <ci-icon + is-borderless + is-interactive + css-classes="gl-rounded-full" + :is-active="isDropdownOpen" + :size="24" + :status="stage.status" + class="gl-align-items-center gl-border gl-display-inline-flex gl-z-index-1" + /> + </template> + <div + v-if="isLoading" + class="gl-display-flex gl-justify-content-center gl-p-2" + data-testid="pipeline-stage-loading-state" + > + <gl-loading-icon size="sm" class="gl-mr-3" /> + <p class="gl-mb-0">{{ $options.i18n.loadingText }}</p> + </div> + <ul + v-else + class="js-builds-dropdown-list scrollable-menu" + data-testid="mini-pipeline-graph-dropdown-menu-list" + > + <div + class="gl-align-items-center gl-border-b gl-display-flex gl-font-weight-bold gl-justify-content-center gl-pb-3" + > + <span class="gl-mr-1">{{ $options.i18n.stage }}</span> + <span data-testid="pipeline-stage-dropdown-menu-title">{{ stageName }}</span> + </div> + <li v-for="job in dropdownContent" :key="job.id"> + <job-item + :dropdown-length="dropdownContent.length" + :job="job" + css-class-job-name="mini-pipeline-graph-dropdown-item" + @pipelineActionRequestComplete="pipelineActionRequestComplete" + /> + </li> + <template v-if="isMergeTrain"> + <li class="gl-new-dropdown-divider" role="presentation"> + <hr role="separator" aria-orientation="horizontal" class="dropdown-divider" /> + </li> + <li> + <div + class="gl-display-flex gl-align-items-center" + data-testid="warning-message-merge-trains" + > + <div class="menu-item gl-font-sm gl-text-gray-300!"> + {{ s__('Pipeline|Merge train pipeline jobs can not be retried') }} + </div> + </div> + </li> + </template> + </ul> + </gl-dropdown> +</template> |