diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-04-20 23:50:22 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-04-20 23:50:22 +0000 |
commit | 9dc93a4519d9d5d7be48ff274127136236a3adb3 (patch) | |
tree | 70467ae3692a0e35e5ea56bcb803eb512a10bedb /app/assets/javascripts/pipelines/components/pipeline_graph/pipeline_graph.vue | |
parent | 4b0f34b6d759d6299322b3a54453e930c6121ff0 (diff) | |
download | gitlab-ce-9dc93a4519d9d5d7be48ff274127136236a3adb3.tar.gz |
Add latest changes from gitlab-org/gitlab@13-11-stable-eev13.11.0-rc43
Diffstat (limited to 'app/assets/javascripts/pipelines/components/pipeline_graph/pipeline_graph.vue')
-rw-r--r-- | app/assets/javascripts/pipelines/components/pipeline_graph/pipeline_graph.vue | 218 |
1 files changed, 70 insertions, 148 deletions
diff --git a/app/assets/javascripts/pipelines/components/pipeline_graph/pipeline_graph.vue b/app/assets/javascripts/pipelines/components/pipeline_graph/pipeline_graph.vue index 707d6966e77..3ba0d7d0120 100644 --- a/app/assets/javascripts/pipelines/components/pipeline_graph/pipeline_graph.vue +++ b/app/assets/javascripts/pipelines/components/pipeline_graph/pipeline_graph.vue @@ -1,11 +1,8 @@ <script> import { GlAlert } from '@gitlab/ui'; import { __ } from '~/locale'; -import { CI_CONFIG_STATUS_INVALID } from '~/pipeline_editor/constants'; -import { DRAW_FAILURE, DEFAULT, INVALID_CI_CONFIG, EMPTY_PIPELINE_DATA } from '../../constants'; -import { createJobsHash, generateJobNeedsDict } from '../../utils'; -import { generateLinksData } from '../graph_shared/drawing_utils'; -import { parseData } from '../parsing_utils'; +import { DRAW_FAILURE, DEFAULT } from '../../constants'; +import LinksLayer from '../graph_shared/links_layer.vue'; import JobPill from './job_pill.vue'; import StagePill from './stage_pill.vue'; @@ -13,18 +10,16 @@ export default { components: { GlAlert, JobPill, + LinksLayer, StagePill, }, CONTAINER_REF: 'PIPELINE_GRAPH_CONTAINER_REF', - CONTAINER_ID: 'pipeline-graph-container', + 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.'), - [EMPTY_PIPELINE_DATA]: __( - 'The visualization will appear in this tab when the CI/CD configuration file is populated with valid syntax.', - ), - [INVALID_CI_CONFIG]: __('Your CI configuration file is invalid.'), }, props: { pipelineData: { @@ -36,33 +31,16 @@ export default { return { failureType: null, highlightedJob: null, - links: [], - needsObject: null, - height: 0, - width: 0, + highlightedJobs: [], + measurements: { + height: 0, + width: 0, + }, }; }, computed: { - hideGraph() { - // We won't even try to render the graph with these condition - // because it would cause additional errors down the line for the user - // which is confusing. - return this.isPipelineDataEmpty || this.isInvalidCiConfig; - }, - pipelineStages() { - return this.pipelineData?.stages || []; - }, - isPipelineDataEmpty() { - return !this.isInvalidCiConfig && this.pipelineStages.length === 0; - }, - isInvalidCiConfig() { - return this.pipelineData?.status === CI_CONFIG_STATUS_INVALID; - }, - hasError() { - return this.failureType; - }, - hasHighlightedJob() { - return Boolean(this.highlightedJob); + containerId() { + return `${this.$options.BASE_CONTAINER_ID}-${this.$options.PIPELINE_ID}`; }, failure() { switch (this.failureType) { @@ -72,18 +50,6 @@ export default { variant: 'danger', dismissible: true, }; - case EMPTY_PIPELINE_DATA: - return { - text: this.$options.errorTexts[EMPTY_PIPELINE_DATA], - variant: 'tip', - dismissible: false, - }; - case INVALID_CI_CONFIG: - return { - text: this.$options.errorTexts[INVALID_CI_CONFIG], - variant: 'danger', - dismissible: false, - }; default: return { text: this.$options.errorTexts[DEFAULT], @@ -92,56 +58,32 @@ export default { }; } }, - viewBox() { - return [0, 0, this.width, this.height]; + hasError() { + return this.failureType; }, - highlightedJobs() { - // If you are hovering on a job, then the jobs we want to highlight are: - // The job you are currently hovering + all of its needs. - return [this.highlightedJob, ...this.needsObject[this.highlightedJob]]; + hasHighlightedJob() { + return Boolean(this.highlightedJob); }, - highlightedLinks() { - // If you are hovering on a job, then the links we want to highlight are: - // All the links whose `source` and `target` are highlighted jobs. - if (this.hasHighlightedJob) { - const filteredLinks = this.links.filter((link) => { - return ( - this.highlightedJobs.includes(link.source) && this.highlightedJobs.includes(link.target) - ); - }); - - return filteredLinks.map((link) => link.ref); - } - - return []; + pipelineStages() { + return this.pipelineData?.stages || []; }, }, watch: { pipelineData: { immediate: true, handler() { - if (this.isPipelineDataEmpty) { - this.reportFailure(EMPTY_PIPELINE_DATA); - } else if (this.isInvalidCiConfig) { - this.reportFailure(INVALID_CI_CONFIG); - } else { - this.$nextTick(() => { - this.computeGraphDimensions(); - this.prepareLinkData(); - }); - } + this.$nextTick(() => { + this.computeGraphDimensions(); + }); }, }, }, methods: { - prepareLinkData() { - try { - const arrayOfJobs = this.pipelineStages.flatMap(({ groups }) => groups); - const parsedData = parseData(arrayOfJobs); - this.links = generateLinksData(parsedData, this.$options.CONTAINER_ID); - } catch { - this.reportFailure(DRAW_FAILURE); - } + computeGraphDimensions() { + this.measurements = { + width: this.$refs[this.$options.CONTAINER_REF].scrollWidth, + height: this.$refs[this.$options.CONTAINER_REF].scrollHeight, + }; }, getStageBackgroundClasses(index) { const { length } = this.pipelineStages; @@ -161,22 +103,14 @@ export default { return ''; }, - highlightNeeds(uniqueJobId) { - // The first time we hover, we create the object where - // we store all the data to properly highlight the needs. - if (!this.needsObject) { - const jobs = createJobsHash(this.pipelineStages); - this.needsObject = generateJobNeedsDict(jobs) ?? {}; - } - - this.highlightedJob = uniqueJobId; + isJobHighlighted(jobName) { + return this.highlightedJobs.includes(jobName); }, - removeHighlightNeeds() { - this.highlightedJob = null; + onError(error) { + this.reportFailure(error.type); }, - computeGraphDimensions() { - this.width = `${this.$refs[this.$options.CONTAINER_REF].scrollWidth}`; - this.height = `${this.$refs[this.$options.CONTAINER_REF].scrollHeight}`; + removeHoveredJob() { + this.highlightedJob = null; }, reportFailure(errorType) { this.failureType = errorType; @@ -184,17 +118,11 @@ export default { resetFailure() { this.failureType = null; }, - isJobHighlighted(jobName) { - return this.highlightedJobs.includes(jobName); + setHoveredJob(jobName) { + this.highlightedJob = jobName; }, - isLinkHighlighted(linkRef) { - return this.highlightedLinks.includes(linkRef); - }, - getLinkClasses(link) { - return [ - this.isLinkHighlighted(link.ref) ? 'gl-stroke-blue-400' : 'gl-stroke-gray-200', - { 'gl-opacity-3': this.hasHighlightedJob && !this.isLinkHighlighted(link.ref) }, - ]; + updateHighlightedJobs(jobs) { + this.highlightedJobs = jobs; }, }, }; @@ -209,50 +137,44 @@ export default { > {{ failure.text }} </gl-alert> - <div - v-if="!hideGraph" - :id="$options.CONTAINER_ID" - :ref="$options.CONTAINER_REF" - class="gl-display-flex gl-bg-gray-50 gl-px-4 gl-overflow-auto gl-relative gl-py-7" - data-testid="graph-container" - > - <svg :viewBox="viewBox" :width="width" :height="height" class="gl-absolute"> - <path - v-for="link in links" - :key="link.path" - :ref="link.ref" - :d="link.path" - class="gl-fill-transparent gl-transition-duration-slow gl-transition-timing-function-ease" - :class="getLinkClasses(link)" - :stroke-width="$options.STROKE_WIDTH" - /> - </svg> - <div - v-for="(stage, index) in pipelineStages" - :key="`${stage.name}-${index}`" - class="gl-flex-direction-column" + <div :id="containerId" :ref="$options.CONTAINER_REF" 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 - class="gl-display-flex gl-align-items-center gl-bg-white gl-w-full gl-px-8 gl-py-4 gl-mb-5" - :class="getStageBackgroundClasses(index)" - data-testid="stage-background" - > - <stage-pill :stage-name="stage.name" :is-empty="stage.groups.length === 0" /> - </div> - <div - class="gl-display-flex gl-flex-direction-column gl-align-items-center gl-w-full gl-px-8" + v-for="(stage, index) in pipelineStages" + :key="`${stage.name}-${index}`" + class="gl-flex-direction-column" > - <job-pill - v-for="group in stage.groups" - :key="group.name" - :job-name="group.name" - :is-highlighted="hasHighlightedJob && isJobHighlighted(group.name)" - :is-faded-out="hasHighlightedJob && !isJobHighlighted(group.name)" - @on-mouse-enter="highlightNeeds" - @on-mouse-leave="removeHighlightNeeds" - /> + <div + class="gl-display-flex gl-align-items-center gl-bg-white gl-w-full gl-px-8 gl-py-4 gl-mb-5" + :class="getStageBackgroundClasses(index)" + data-testid="stage-background" + > + <stage-pill :stage-name="stage.name" :is-empty="stage.groups.length === 0" /> + </div> + <div + class="gl-display-flex gl-flex-direction-column gl-align-items-center gl-w-full gl-px-8" + > + <job-pill + v-for="group in stage.groups" + :key="group.name" + :job-name="group.name" + :pipeline-id="$options.PIPELINE_ID" + :is-highlighted="hasHighlightedJob && isJobHighlighted(group.name)" + :is-faded-out="hasHighlightedJob && !isJobHighlighted(group.name)" + @on-mouse-enter="setHoveredJob" + @on-mouse-leave="removeHoveredJob" + /> + </div> </div> - </div> + </links-layer> </div> </div> </template> |