Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-09-20 02:18:09 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-09-20 02:18:09 +0300
commit6ed4ec3e0b1340f96b7c043ef51d1b33bbe85fde (patch)
treedc4d20fe6064752c0bd323187252c77e0a89144b /app/assets/javascripts/pipelines/components/pipeline_mini_graph/pipeline_stage.vue
parent9868dae7fc0655bd7ce4a6887d4e6d487690eeed (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.vue186
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>