diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-10-21 07:08:36 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-10-21 07:08:36 +0000 |
commit | 48aff82709769b098321c738f3444b9bdaa694c6 (patch) | |
tree | e00c7c43e2d9b603a5a6af576b1685e400410dee /app/assets/javascripts/pipelines/components/dag | |
parent | 879f5329ee916a948223f8f43d77fba4da6cd028 (diff) | |
download | gitlab-ce-48aff82709769b098321c738f3444b9bdaa694c6.tar.gz |
Add latest changes from gitlab-org/gitlab@13-5-stable-eev13.5.0-rc42
Diffstat (limited to 'app/assets/javascripts/pipelines/components/dag')
4 files changed, 6 insertions, 171 deletions
diff --git a/app/assets/javascripts/pipelines/components/dag/constants.js b/app/assets/javascripts/pipelines/components/dag/constants.js index b6a98fdc488..cd89055737f 100644 --- a/app/assets/javascripts/pipelines/components/dag/constants.js +++ b/app/assets/javascripts/pipelines/components/dag/constants.js @@ -1,9 +1,3 @@ -/* Error constants */ -export const PARSE_FAILURE = 'parse_failure'; -export const LOAD_FAILURE = 'load_failure'; -export const UNSUPPORTED_DATA = 'unsupported_data'; -export const DEFAULT = 'default'; - /* Interaction handles */ export const IS_HIGHLIGHTED = 'dag-highlighted'; export const LINK_SELECTOR = 'dag-link'; diff --git a/app/assets/javascripts/pipelines/components/dag/dag.vue b/app/assets/javascripts/pipelines/components/dag/dag.vue index 8487da3d621..6267b63328c 100644 --- a/app/assets/javascripts/pipelines/components/dag/dag.vue +++ b/app/assets/javascripts/pipelines/components/dag/dag.vue @@ -6,16 +6,9 @@ import { fetchPolicies } from '~/lib/graphql'; import getDagVisData from '../../graphql/queries/get_dag_vis_data.query.graphql'; import DagGraph from './dag_graph.vue'; import DagAnnotations from './dag_annotations.vue'; -import { - DEFAULT, - PARSE_FAILURE, - LOAD_FAILURE, - UNSUPPORTED_DATA, - ADD_NOTE, - REMOVE_NOTE, - REPLACE_NOTES, -} from './constants'; -import { parseData } from './parsing_utils'; +import { ADD_NOTE, REMOVE_NOTE, REPLACE_NOTES } from './constants'; +import { parseData } from '../parsing_utils'; +import { DEFAULT, PARSE_FAILURE, LOAD_FAILURE, UNSUPPORTED_DATA } from '../../constants'; export default { // eslint-disable-next-line @gitlab/require-i18n-strings diff --git a/app/assets/javascripts/pipelines/components/dag/dag_graph.vue b/app/assets/javascripts/pipelines/components/dag/dag_graph.vue index d12baa9617e..42d1debcddf 100644 --- a/app/assets/javascripts/pipelines/components/dag/dag_graph.vue +++ b/app/assets/javascripts/pipelines/components/dag/dag_graph.vue @@ -1,14 +1,7 @@ <script> import * as d3 from 'd3'; import { uniqueId } from 'lodash'; -import { - LINK_SELECTOR, - NODE_SELECTOR, - PARSE_FAILURE, - ADD_NOTE, - REMOVE_NOTE, - REPLACE_NOTES, -} from './constants'; +import { LINK_SELECTOR, NODE_SELECTOR, ADD_NOTE, REMOVE_NOTE, REPLACE_NOTES } from './constants'; import { currentIsLive, getLiveLinksAsDict, @@ -17,8 +10,9 @@ import { toggleLinkHighlight, togglePathHighlights, } from './interactions'; -import { getMaxNodes, removeOrphanNodes } from './parsing_utils'; +import { getMaxNodes, removeOrphanNodes } from '../parsing_utils'; import { calculateClip, createLinkPath, createSankey, labelPosition } from './drawing_utils'; +import { PARSE_FAILURE } from '../../constants'; export default { viewOptions: { diff --git a/app/assets/javascripts/pipelines/components/dag/parsing_utils.js b/app/assets/javascripts/pipelines/components/dag/parsing_utils.js deleted file mode 100644 index 1ed415688f2..00000000000 --- a/app/assets/javascripts/pipelines/components/dag/parsing_utils.js +++ /dev/null @@ -1,146 +0,0 @@ -import { uniqWith, isEqual } from 'lodash'; - -/* - The following functions are the main engine in transforming the data as - received from the endpoint into the format the d3 graph expects. - - Input is of the form: - [nodes] - nodes: [{category, name, jobs, size}] - category is the stage name - name is a group name; in the case that the group has one job, it is - also the job name - size is the number of parallel jobs - jobs: [{ name, needs}] - job name is either the same as the group name or group x/y - needs: [job-names] - needs is an array of job-name strings - - Output is of the form: - { nodes: [node], links: [link] } - node: { name, category }, + unused info passed through - link: { source, target, value }, with source & target being node names - and value being a constant - - We create nodes in the GraphQL update function, and then here we create the node dictionary, - then create links, and then dedupe the links, so that in the case where - job 4 depends on job 1 and job 2, and job 2 depends on job 1, we show only a single link - from job 1 to job 2 then another from job 2 to job 4. - - CREATE LINKS - nodes.name -> target - nodes.name.needs.each -> source (source is the name of the group, not the parallel job) - 10 -> value (constant) - */ - -export const createNodeDict = nodes => { - return nodes.reduce((acc, node) => { - const newNode = { - ...node, - needs: node.jobs.map(job => job.needs || []).flat(), - }; - - if (node.size > 1) { - node.jobs.forEach(job => { - acc[job.name] = newNode; - }); - } - - acc[node.name] = newNode; - return acc; - }, {}); -}; - -export const makeLinksFromNodes = (nodes, nodeDict) => { - const constantLinkValue = 10; // all links are the same weight - return nodes - .map(group => { - return group.jobs.map(job => { - if (!job.needs) { - return []; - } - - return job.needs.map(needed => { - return { - source: nodeDict[needed]?.name, - target: group.name, - value: constantLinkValue, - }; - }); - }); - }) - .flat(2); -}; - -export const getAllAncestors = (nodes, nodeDict) => { - const needs = nodes - .map(node => { - return nodeDict[node].needs || ''; - }) - .flat() - .filter(Boolean); - - if (needs.length) { - return [...needs, ...getAllAncestors(needs, nodeDict)]; - } - - return []; -}; - -export const filterByAncestors = (links, nodeDict) => - links.filter(({ target, source }) => { - /* - - for every link, check out it's target - for every target, get the target node's needs - then drop the current link source from that list - - call a function to get all ancestors, recursively - is the current link's source in the list of all parents? - then we drop this link - - */ - const targetNode = target; - const targetNodeNeeds = nodeDict[targetNode].needs; - const targetNodeNeedsMinusSource = targetNodeNeeds.filter(need => need !== source); - - const allAncestors = getAllAncestors(targetNodeNeedsMinusSource, nodeDict); - return !allAncestors.includes(source); - }); - -export const parseData = nodes => { - const nodeDict = createNodeDict(nodes); - const allLinks = makeLinksFromNodes(nodes, nodeDict); - const filteredLinks = filterByAncestors(allLinks, nodeDict); - const links = uniqWith(filteredLinks, isEqual); - - return { nodes, links }; -}; - -/* - The number of nodes in the most populous generation drives the height of the graph. -*/ - -export const getMaxNodes = nodes => { - const counts = nodes.reduce((acc, { layer }) => { - if (!acc[layer]) { - acc[layer] = 0; - } - - acc[layer] += 1; - - return acc; - }, []); - - return Math.max(...counts); -}; - -/* - Because we cannot know if a node is part of a relationship until after we - generate the links with createSankey, this function is used after the first call - to find nodes that have no relations. -*/ - -export const removeOrphanNodes = sankeyfiedNodes => { - return sankeyfiedNodes.filter(node => node.sourceLinks.length || node.targetLinks.length); -}; |