diff options
Diffstat (limited to 'app/assets/javascripts/pipelines/components/pipelines_list')
12 files changed, 83 insertions, 466 deletions
diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/job_item.vue b/app/assets/javascripts/pipelines/components/pipelines_list/job_item.vue deleted file mode 100644 index 670fa398536..00000000000 --- a/app/assets/javascripts/pipelines/components/pipelines_list/job_item.vue +++ /dev/null @@ -1,190 +0,0 @@ -<script> -import { GlTooltipDirective, GlLink } from '@gitlab/ui'; -import delayedJobMixin from '~/jobs/mixins/delayed_job_mixin'; -import { BV_HIDE_TOOLTIP } from '~/lib/utils/constants'; -import { sprintf } from '~/locale'; -import { reportToSentry } from '../../utils'; -import ActionComponent from '../jobs_shared/action_component.vue'; -import JobNameComponent from '../jobs_shared/job_name_component.vue'; - -/** - * Renders the badge for the pipeline graph and the job's dropdown. - * - * The following object should be provided as `job`: - * - * { - * "id": 4256, - * "name": "test", - * "status": { - * "icon": "status_success", - * "text": "passed", - * "label": "passed", - * "group": "success", - * "tooltip": "passed", - * "details_path": "/root/ci-mock/builds/4256", - * "action": { - * "icon": "retry", - * "title": "Retry", - * "path": "/root/ci-mock/builds/4256/retry", - * "method": "post" - * } - * } - * } - */ - -export default { - hoverClass: 'gl-shadow-x0-y0-b3-s1-blue-500', - components: { - ActionComponent, - JobNameComponent, - GlLink, - }, - directives: { - GlTooltip: GlTooltipDirective, - }, - mixins: [delayedJobMixin], - props: { - job: { - type: Object, - required: true, - }, - cssClassJobName: { - type: String, - required: false, - default: '', - }, - dropdownLength: { - type: Number, - required: false, - default: Infinity, - }, - jobHovered: { - type: String, - required: false, - default: '', - }, - pipelineExpanded: { - type: Object, - required: false, - default: () => ({}), - }, - pipelineId: { - type: Number, - required: false, - default: -1, - }, - }, - computed: { - boundary() { - return this.dropdownLength === 1 ? 'viewport' : 'scrollParent'; - }, - detailsPath() { - return this.status.details_path; - }, - hasDetails() { - return this.status.has_details; - }, - status() { - return this.job && this.job.status ? this.job.status : {}; - }, - tooltipText() { - const textBuilder = []; - const { name: jobName } = this.job; - - if (jobName) { - textBuilder.push(jobName); - } - - const { tooltip: statusTooltip } = this.status; - if (jobName && statusTooltip) { - textBuilder.push('-'); - } - - if (statusTooltip) { - if (this.isDelayedJob) { - textBuilder.push(sprintf(statusTooltip, { remainingTime: this.remainingTime })); - } else { - textBuilder.push(statusTooltip); - } - } - - return textBuilder.join(' '); - }, - /** - * Verifies if the provided job has an action path - * - * @return {Boolean} - */ - hasAction() { - return this.job.status && this.job.status.action && this.job.status.action.path; - }, - relatedDownstreamHovered() { - return this.job.name === this.jobHovered; - }, - relatedDownstreamExpanded() { - return this.job.name === this.pipelineExpanded.jobName && this.pipelineExpanded.expanded; - }, - jobClasses() { - return this.relatedDownstreamHovered || this.relatedDownstreamExpanded - ? `${this.$options.hoverClass} ${this.cssClassJobName}` - : this.cssClassJobName; - }, - }, - errorCaptured(err, _vm, info) { - reportToSentry('pipelines_job_item', `pipelines_job_item error: ${err}, info: ${info}`); - }, - methods: { - hideTooltips() { - this.$root.$emit(BV_HIDE_TOOLTIP); - }, - pipelineActionRequestComplete() { - this.$emit('pipelineActionRequestComplete'); - }, - }, -}; -</script> -<template> - <div - class="ci-job-component gl-display-flex gl-align-items-center gl-justify-content-space-between" - data-qa-selector="job_item_container" - > - <gl-link - v-if="hasDetails" - v-gl-tooltip="{ - boundary: 'viewport', - placement: 'bottom', - customClass: 'gl-pointer-events-none', - }" - :href="detailsPath" - :title="tooltipText" - :class="jobClasses" - class="js-pipeline-graph-job-link qa-job-link menu-item gl-text-gray-900 gl-active-text-decoration-none gl-focus-text-decoration-none gl-hover-text-decoration-none" - data-testid="job-with-link" - @click.stop="hideTooltips" - @mouseout="hideTooltips" - > - <job-name-component :name="job.name" :status="job.status" :icon-size="24" /> - </gl-link> - - <div - v-else - v-gl-tooltip="{ boundary, placement: 'bottom', customClass: 'gl-pointer-events-none' }" - :title="tooltipText" - :class="jobClasses" - class="js-job-component-tooltip non-details-job-component menu-item" - data-testid="job-without-link" - @mouseout="hideTooltips" - > - <job-name-component :name="job.name" :status="job.status" :icon-size="24" /> - </div> - - <action-component - v-if="hasAction" - :tooltip-text="status.action.title" - :link="status.action.path" - :action-icon="status.action.icon" - data-qa-selector="action_button" - @pipelineActionRequestComplete="pipelineActionRequestComplete" - /> - </div> -</template> diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_mini_graph.vue b/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_mini_graph.vue deleted file mode 100644 index 05cb2ebb769..00000000000 --- a/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_mini_graph.vue +++ /dev/null @@ -1,54 +0,0 @@ -<script> -import PipelineStage from '~/pipelines/components/pipelines_list/pipeline_stage.vue'; -/** - * Renders the pipeline mini graph. - */ -export default { - components: { - PipelineStage, - }, - props: { - stages: { - type: Array, - required: true, - }, - updateDropdown: { - type: Boolean, - required: false, - default: false, - }, - stagesClass: { - type: [Array, Object, String], - required: false, - default: '', - }, - isMergeTrain: { - type: Boolean, - required: false, - default: false, - }, - }, - methods: { - onPipelineActionRequestComplete() { - this.$emit('pipelineActionRequestComplete'); - }, - }, -}; -</script> -<template> - <div data-testid="pipeline-mini-graph" class="gl-display-inline gl-vertical-align-middle"> - <div - v-for="stage in stages" - :key="stage.name" - :class="stagesClass" - class="dropdown gl-display-inline-block gl-mr-2 gl-my-2 gl-vertical-align-middle stage-container" - > - <pipeline-stage - :stage="stage" - :update-dropdown="updateDropdown" - :is-merge-train="isMergeTrain" - @pipelineActionRequestComplete="onPipelineActionRequestComplete" - /> - </div> - </div> -</template> diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_multi_actions.vue b/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_multi_actions.vue index 05a1ceface3..2d2f649f651 100644 --- a/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_multi_actions.vue +++ b/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_multi_actions.vue @@ -10,6 +10,8 @@ import { import fuzzaldrinPlus from 'fuzzaldrin-plus'; import axios from '~/lib/utils/axios_utils'; import { __, s__ } from '~/locale'; +import Tracking from '~/tracking'; +import { TRACKING_CATEGORIES } from '../../constants'; export const i18n = { downloadArtifacts: __('Download artifacts'), @@ -29,6 +31,7 @@ export default { GlSearchBoxByType, GlLoadingIcon, }, + mixins: [Tracking.mixin()], inject: { artifactsEndpoint: { default: '', @@ -60,6 +63,10 @@ export default { }, methods: { fetchArtifacts() { + // refactor tracking based on action once this dropdown supports + // actions other than artifacts + this.track('click_artifacts_dropdown', { label: TRACKING_CATEGORIES.table }); + this.isLoading = true; // Replace the placeholder with the ID of the pipeline we are viewing const endpoint = this.artifactsEndpoint.replace( diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_operations.vue b/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_operations.vue index 7a08dacb824..dd62ffb27f7 100644 --- a/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_operations.vue +++ b/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_operations.vue @@ -1,7 +1,8 @@ <script> import { GlButton, GlTooltipDirective, GlModalDirective } from '@gitlab/ui'; +import Tracking from '~/tracking'; import eventHub from '../../event_hub'; -import { BUTTON_TOOLTIP_RETRY, BUTTON_TOOLTIP_CANCEL } from '../../constants'; +import { BUTTON_TOOLTIP_RETRY, BUTTON_TOOLTIP_CANCEL, TRACKING_CATEGORIES } from '../../constants'; import PipelineMultiActions from './pipeline_multi_actions.vue'; import PipelinesManualActions from './pipelines_manual_actions.vue'; @@ -17,6 +18,7 @@ export default { PipelineMultiActions, PipelinesManualActions, }, + mixins: [Tracking.mixin()], props: { pipeline: { type: Object, @@ -52,6 +54,7 @@ export default { }, methods: { handleCancelClick() { + this.trackClick('click_cancel_button'); eventHub.$emit('openConfirmationModal', { pipeline: this.pipeline, endpoint: this.pipeline.cancel_path, @@ -59,8 +62,12 @@ export default { }, handleRetryClick() { this.isRetrying = true; + this.trackClick('click_retry_button'); eventHub.$emit('retryPipeline', this.pipeline.retry_path); }, + trackClick(action) { + this.track(action, { label: TRACKING_CATEGORIES.table }); + }, }, }; </script> diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_stage.vue b/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_stage.vue deleted file mode 100644 index d7e55d36ff6..00000000000 --- a/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_stage.vue +++ /dev/null @@ -1,182 +0,0 @@ -<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(); - }, - 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> diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_stop_modal.vue b/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_stop_modal.vue index ef21673115e..eb70b5fbb7a 100644 --- a/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_stop_modal.vue +++ b/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_stop_modal.vue @@ -83,9 +83,7 @@ export default { <span class="font-weight-bold">{{ __('Pipeline') }}</span> - <a :href="pipeline.path" class="js-pipeline-path link-commit qa-pipeline-path" - >#{{ pipeline.id }}</a - > + <a :href="pipeline.path" class="js-pipeline-path link-commit">#{{ pipeline.id }}</a> <template v-if="hasRef"> {{ __('from') }} <a :href="pipeline.ref.path" class="link-commit ref-name">{{ pipeline.ref.name }}</a> diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_url.vue b/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_url.vue index 09d588aaafd..39d41415456 100644 --- a/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_url.vue +++ b/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_url.vue @@ -1,9 +1,10 @@ <script> import { GlIcon, GlLink, GlTooltipDirective } from '@gitlab/ui'; import { __ } from '~/locale'; +import Tracking from '~/tracking'; import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate/tooltip_on_truncate.vue'; import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue'; -import { ICONS } from '../../constants'; +import { ICONS, TRACKING_CATEGORIES } from '../../constants'; import PipelineLabels from './pipeline_labels.vue'; export default { @@ -17,6 +18,7 @@ export default { directives: { GlTooltip: GlTooltipDirective, }, + mixins: [Tracking.mixin()], props: { pipeline: { type: Object, @@ -114,6 +116,11 @@ export default { return this.pipeline?.commit?.title; }, }, + methods: { + trackClick(action) { + this.track(action, { label: TRACKING_CATEGORIES.table }); + }, + }, }; </script> <template> @@ -125,6 +132,7 @@ export default { :href="commitUrl" class="commit-row-message gl-text-gray-900" data-testid="commit-title" + @click="trackClick('click_commit_title')" >{{ commitTitle }}</gl-link > </tooltip-on-truncate> @@ -137,6 +145,7 @@ export default { class="gl-text-decoration-underline gl-text-blue-600! gl-mr-3" data-testid="pipeline-url-link" data-qa-selector="pipeline_url_link" + @click="trackClick('click_pipeline_id')" >#{{ pipeline[pipelineKey] }}</gl-link > <!--Commit row--> @@ -154,11 +163,17 @@ export default { :href="mergeRequestRef.path" class="ref-name gl-mr-3" data-testid="merge-request-ref" + @click="trackClick('click_mr_ref')" >{{ mergeRequestRef.iid }}</gl-link > - <gl-link v-else :href="refUrl" class="ref-name gl-mr-3" data-testid="commit-ref-name">{{ - commitRef.name - }}</gl-link> + <gl-link + v-else + :href="refUrl" + class="ref-name gl-mr-3" + data-testid="commit-ref-name" + @click="trackClick('click_commit_name')" + >{{ commitRef.name }}</gl-link + > </tooltip-on-truncate> <gl-icon v-gl-tooltip @@ -167,9 +182,13 @@ export default { :title="__('Commit')" data-testid="commit-icon" /> - <gl-link :href="commitUrl" class="commit-sha mr-0" data-testid="commit-short-sha">{{ - commitShortSha - }}</gl-link> + <gl-link + :href="commitUrl" + class="commit-sha mr-0" + data-testid="commit-short-sha" + @click="trackClick('click_commit_sha')" + >{{ commitShortSha }}</gl-link + > <user-avatar-link v-if="commitAuthor" :link-href="commitAuthor.path" diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines.vue b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines.vue index 485e338f639..f9022be888a 100644 --- a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines.vue +++ b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines.vue @@ -4,6 +4,7 @@ import { isEqual } from 'lodash'; import createFlash from '~/flash'; import { getParameterByName } from '~/lib/utils/url_utility'; import { __, s__ } from '~/locale'; +import Tracking from '~/tracking'; import NavigationTabs from '~/vue_shared/components/navigation_tabs.vue'; import TablePagination from '~/vue_shared/components/pagination/table_pagination.vue'; import { @@ -11,6 +12,7 @@ import { RAW_TEXT_WARNING, FILTER_TAG_IDENTIFIER, PipelineKeyOptions, + TRACKING_CATEGORIES, } from '../../constants'; import PipelinesMixin from '../../mixins/pipelines_mixin'; import PipelinesService from '../../services/pipelines_service'; @@ -35,7 +37,7 @@ export default { PipelinesTableComponent, TablePagination, }, - mixins: [PipelinesMixin], + mixins: [PipelinesMixin, Tracking.mixin()], props: { store: { type: Object, @@ -246,6 +248,8 @@ export default { params = this.onChangeWithFilter(params); this.updateContent(params); + + this.track('click_filter_tabs', { label: TRACKING_CATEGORIES.tabs }); }, successCallback(resp) { // Because we are polling & the user is interacting verify if the response received diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_filtered_search.vue b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_filtered_search.vue index 4d28545a035..af089aebbbe 100644 --- a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_filtered_search.vue +++ b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_filtered_search.vue @@ -2,7 +2,9 @@ import { GlFilteredSearch } from '@gitlab/ui'; import { map } from 'lodash'; import { s__ } from '~/locale'; +import Tracking from '~/tracking'; import { OPERATOR_IS_ONLY } from '~/vue_shared/components/filtered_search_bar/constants'; +import { TRACKING_CATEGORIES } from '../../constants'; import PipelineBranchNameToken from './tokens/pipeline_branch_name_token.vue'; import PipelineSourceToken from './tokens/pipeline_source_token.vue'; import PipelineStatusToken from './tokens/pipeline_status_token.vue'; @@ -19,6 +21,7 @@ export default { components: { GlFilteredSearch, }, + mixins: [Tracking.mixin()], props: { projectId: { type: String, @@ -110,6 +113,7 @@ export default { }, methods: { onSubmit(filters) { + this.track('click_filtered_search', { label: TRACKING_CATEGORIES.search }); this.$emit('filterPipelines', filters); }, }, diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_manual_actions.vue b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_manual_actions.vue index 47fffa8a6b2..16a747f6165 100644 --- a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_manual_actions.vue +++ b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_manual_actions.vue @@ -4,8 +4,10 @@ import createFlash from '~/flash'; import axios from '~/lib/utils/axios_utils'; import { confirmAction } from '~/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal'; import { s__, __, sprintf } from '~/locale'; +import Tracking from '~/tracking'; import GlCountdown from '~/vue_shared/components/gl_countdown.vue'; import eventHub from '../../event_hub'; +import { TRACKING_CATEGORIES } from '../../constants'; export default { directives: { @@ -17,6 +19,7 @@ export default { GlDropdownItem, GlIcon, }, + mixins: [Tracking.mixin()], props: { actions: { type: Array, @@ -66,7 +69,6 @@ export default { createFlash({ message: __('An error occurred while making the request.') }); }); }, - isActionDisabled(action) { if (action.playable === undefined) { return false; @@ -74,6 +76,9 @@ export default { return !action.playable; }, + trackClick() { + this.track('click_manual_actions', { label: TRACKING_CATEGORIES.table }); + }, }, }; </script> @@ -86,6 +91,7 @@ export default { right lazy icon="play" + @shown="trackClick" > <gl-dropdown-item v-for="action in actions" diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_status_badge.vue b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_status_badge.vue index e765a8cd86c..936ae4da1ec 100644 --- a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_status_badge.vue +++ b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_status_badge.vue @@ -1,6 +1,7 @@ <script> -import { CHILD_VIEW } from '~/pipelines/constants'; +import { CHILD_VIEW, TRACKING_CATEGORIES } from '~/pipelines/constants'; import CiBadge from '~/vue_shared/components/ci_badge_link.vue'; +import Tracking from '~/tracking'; import PipelinesTimeago from './time_ago.vue'; export default { @@ -8,6 +9,7 @@ export default { CiBadge, PipelinesTimeago, }, + mixins: [Tracking.mixin()], props: { pipeline: { type: Object, @@ -26,6 +28,11 @@ export default { return this.viewType === CHILD_VIEW; }, }, + methods: { + trackClick() { + this.track('click_ci_status_badge', { label: TRACKING_CATEGORIES.table }); + }, + }, }; </script> @@ -37,6 +44,7 @@ export default { :show-text="!isChildView" :icon-classes="'gl-vertical-align-middle!'" data-qa-selector="pipeline_commit_status" + @ciStatusBadgeClick="trackClick" /> <pipelines-timeago class="gl-mt-3" :pipeline="pipeline" /> </div> diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_table.vue b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_table.vue index 53da98434b0..f6e46c090d3 100644 --- a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_table.vue +++ b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_table.vue @@ -1,8 +1,10 @@ <script> import { GlTableLite, GlTooltipDirective } from '@gitlab/ui'; import { s__, __ } from '~/locale'; +import Tracking from '~/tracking'; +import PipelineMiniGraph from '~/pipelines/components/pipeline_mini_graph/pipeline_mini_graph.vue'; import eventHub from '../../event_hub'; -import PipelineMiniGraph from './pipeline_mini_graph.vue'; +import { TRACKING_CATEGORIES } from '../../constants'; import PipelineOperations from './pipeline_operations.vue'; import PipelineStopModal from './pipeline_stop_modal.vue'; import PipelineTriggerer from './pipeline_triggerer.vue'; @@ -17,8 +19,6 @@ const DEFAULT_TH_CLASSES = export default { components: { GlTableLite, - LinkedPipelinesMiniList: () => - import('ee_component/vue_shared/components/linked_pipelines_mini_list.vue'), PipelineMiniGraph, PipelineOperations, PipelinesStatusBadge, @@ -70,6 +70,7 @@ export default { directives: { GlTooltip: GlTooltipDirective, }, + mixins: [Tracking.mixin()], props: { pipelines: { type: Array, @@ -126,6 +127,9 @@ export default { onPipelineActionRequestComplete() { eventHub.$emit('refreshPipelinesTable'); }, + trackPipelineMiniGraph() { + this.track('click_minigraph', { label: TRACKING_CATEGORIES.table }); + }, }, TBODY_TR_ATTR: { 'data-testid': 'pipeline-table-row', @@ -169,29 +173,15 @@ export default { </template> <template #cell(stages)="{ item }"> - <div class="stage-cell"> - <!-- This empty div should be removed, see https://gitlab.com/gitlab-org/gitlab/-/issues/323488 --> - <div></div> - <linked-pipelines-mini-list - v-if="item.triggered_by" - :triggered-by="/* eslint-disable @gitlab/vue-no-new-non-primitive-in-template */ [ - item.triggered_by, - ] /* eslint-enable @gitlab/vue-no-new-non-primitive-in-template */" - data-testid="mini-graph-upstream" - /> - <pipeline-mini-graph - v-if="item.details && item.details.stages && item.details.stages.length > 0" - :stages="item.details.stages" - :update-dropdown="updateGraphDropdown" - @pipelineActionRequestComplete="onPipelineActionRequestComplete" - /> - <linked-pipelines-mini-list - v-if="item.triggered.length" - :triggered="item.triggered" - :pipeline-path="item.path" - data-testid="mini-graph-downstream" - /> - </div> + <pipeline-mini-graph + :downstream-pipelines="item.triggered" + :pipeline-path="item.path" + :stages="item.details.stages" + :update-dropdown="updateGraphDropdown" + :upstream-pipeline="item.triggered_by" + @pipelineActionRequestComplete="onPipelineActionRequestComplete" + @miniGraphStageClick="trackPipelineMiniGraph" + /> </template> <template #cell(actions)="{ item }"> |