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:
Diffstat (limited to 'app/assets/javascripts/ci/pipeline_editor/components/graph/pipeline_graph.vue')
-rw-r--r--app/assets/javascripts/ci/pipeline_editor/components/graph/pipeline_graph.vue169
1 files changed, 169 insertions, 0 deletions
diff --git a/app/assets/javascripts/ci/pipeline_editor/components/graph/pipeline_graph.vue b/app/assets/javascripts/ci/pipeline_editor/components/graph/pipeline_graph.vue
new file mode 100644
index 00000000000..eb906cfc486
--- /dev/null
+++ b/app/assets/javascripts/ci/pipeline_editor/components/graph/pipeline_graph.vue
@@ -0,0 +1,169 @@
+<script>
+import { GlAlert } from '@gitlab/ui';
+import { __ } from '~/locale';
+import { DRAW_FAILURE, DEFAULT } from '~/ci/pipeline_details/constants';
+import LinksLayer from '~/ci/common/private/job_links_layer.vue';
+import JobPill from './job_pill.vue';
+import StageName from './stage_name.vue';
+
+export default {
+ components: {
+ GlAlert,
+ JobPill,
+ LinksLayer,
+ StageName,
+ },
+ CONTAINER_REF: 'PIPELINE_GRAPH_CONTAINER_REF',
+ BASE_CONTAINER_ID: 'pipeline-graph-container',
+ PIPELINE_ID: 0,
+ STROKE_WIDTH: 2,
+ errorTexts: {
+ [DRAW_FAILURE]: __('Could not draw the lines for job relationships'),
+ [DEFAULT]: __('An unknown error occurred.'),
+ },
+ // The combination of gl-w-full gl-min-w-full and gl-max-w-15 is necessary.
+ // The max width and the width make sure the ellipsis to work and the min width
+ // is for when there is less text than the stage column width (which the width 100% does not fix)
+ jobWrapperClasses:
+ 'gl-display-flex gl-flex-direction-column gl-align-items-stretch gl-w-full gl-px-8 gl-min-w-full gl-max-w-15',
+ props: {
+ pipelineData: {
+ required: true,
+ type: Object,
+ },
+ },
+ data() {
+ return {
+ failureType: null,
+ highlightedJob: null,
+ highlightedJobs: [],
+ measurements: {
+ height: 0,
+ width: 0,
+ },
+ };
+ },
+ computed: {
+ containerId() {
+ return `${this.$options.BASE_CONTAINER_ID}-${this.$options.PIPELINE_ID}`;
+ },
+ failure() {
+ switch (this.failureType) {
+ case DRAW_FAILURE:
+ return {
+ text: this.$options.errorTexts[DRAW_FAILURE],
+ variant: 'danger',
+ dismissible: true,
+ };
+ default:
+ return {
+ text: this.$options.errorTexts[DEFAULT],
+ variant: 'danger',
+ dismissible: true,
+ };
+ }
+ },
+ hasError() {
+ return this.failureType;
+ },
+ hasHighlightedJob() {
+ return Boolean(this.highlightedJob);
+ },
+ pipelineStages() {
+ return this.pipelineData?.stages || [];
+ },
+ },
+ watch: {
+ pipelineData: {
+ immediate: true,
+ handler() {
+ this.$nextTick(() => {
+ this.computeGraphDimensions();
+ });
+ },
+ },
+ },
+ methods: {
+ computeGraphDimensions() {
+ this.measurements = {
+ width: this.$refs[this.$options.CONTAINER_REF].scrollWidth,
+ height: this.$refs[this.$options.CONTAINER_REF].scrollHeight,
+ };
+ },
+ isFadedOut(jobName) {
+ return this.highlightedJobs.length > 1 && !this.isJobHighlighted(jobName);
+ },
+ isJobHighlighted(jobName) {
+ return this.highlightedJobs.includes(jobName);
+ },
+ onError(error) {
+ this.reportFailure(error.type);
+ },
+ removeHoveredJob() {
+ this.highlightedJob = null;
+ },
+ reportFailure(errorType) {
+ this.failureType = errorType;
+ },
+ resetFailure() {
+ this.failureType = null;
+ },
+ setHoveredJob(jobName) {
+ this.highlightedJob = jobName;
+ },
+ updateHighlightedJobs(jobs) {
+ this.highlightedJobs = jobs;
+ },
+ },
+};
+</script>
+<template>
+ <div>
+ <gl-alert
+ v-if="hasError"
+ :variant="failure.variant"
+ :dismissible="failure.dismissible"
+ @dismiss="resetFailure"
+ >
+ {{ failure.text }}
+ </gl-alert>
+ <div
+ :id="containerId"
+ :ref="$options.CONTAINER_REF"
+ class="gl-bg-gray-10 gl-overflow-auto"
+ data-testid="graph-container"
+ >
+ <links-layer
+ :pipeline-data="pipelineStages"
+ :pipeline-id="$options.PIPELINE_ID"
+ :container-id="containerId"
+ :container-measurements="measurements"
+ :highlighted-job="highlightedJob"
+ @highlightedJobsChange="updateHighlightedJobs"
+ @error="onError"
+ >
+ <div
+ v-for="(stage, index) in pipelineStages"
+ :key="`${stage.name}-${index}`"
+ class="gl-flex-direction-column"
+ >
+ <div class="gl-display-flex gl-align-items-center gl-w-full gl-px-9 gl-py-4 gl-mb-5">
+ <stage-name :stage-name="stage.name" />
+ </div>
+ <div :class="$options.jobWrapperClasses">
+ <job-pill
+ v-for="group in stage.groups"
+ :key="group.name"
+ :job-name="group.name"
+ :pipeline-id="$options.PIPELINE_ID"
+ :is-hovered="highlightedJob === group.name"
+ :is-faded-out="isFadedOut(group.name)"
+ @on-mouse-enter="setHoveredJob"
+ @on-mouse-leave="removeHoveredJob"
+ />
+ </div>
+ </div>
+ </links-layer>
+ </div>
+ </div>
+</template>