summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/pipelines/components/parsing_utils.js
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/pipelines/components/parsing_utils.js')
-rw-r--r--app/assets/javascripts/pipelines/components/parsing_utils.js78
1 files changed, 14 insertions, 64 deletions
diff --git a/app/assets/javascripts/pipelines/components/parsing_utils.js b/app/assets/javascripts/pipelines/components/parsing_utils.js
index 7e7f0572faf..fa7330ce890 100644
--- a/app/assets/javascripts/pipelines/components/parsing_utils.js
+++ b/app/assets/javascripts/pipelines/components/parsing_utils.js
@@ -1,55 +1,18 @@
import { memoize } from 'lodash';
+import { createNodeDict } from '../utils';
import { createSankey } from './dag/drawing_utils';
/*
- 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;
- });
- }
+ A peformant alternative to lodash's isEqual. Because findIndex always finds
+ the first instance of a match, if the found index is not the first, we know
+ it is in fact a duplicate.
+*/
+const deduplicate = (item, itemIndex, arr) => {
+ const foundIdx = arr.findIndex((test) => {
+ return test.source === item.source && test.target === item.target;
+ });
- acc[node.name] = newNode;
- return acc;
- }, {});
+ return foundIdx === itemIndex;
};
export const makeLinksFromNodes = (nodes, nodeDict) => {
@@ -83,7 +46,8 @@ export const getAllAncestors = (nodes, nodeDict) => {
return nodeDict[node]?.needs || '';
})
.flat()
- .filter(Boolean);
+ .filter(Boolean)
+ .filter(deduplicate);
if (needs.length) {
return [...needs, ...getAllAncestors(needs, nodeDict)];
@@ -108,29 +72,15 @@ export const filterByAncestors = (links, nodeDict) =>
const targetNode = target;
const targetNodeNeeds = nodeDict[targetNode].needs;
const targetNodeNeedsMinusSource = targetNodeNeeds.filter((need) => need !== source);
-
const allAncestors = getAllAncestors(targetNodeNeedsMinusSource, nodeDict);
return !allAncestors.includes(source);
});
-/*
- A peformant alternative to lodash's isEqual. Because findIndex always finds
- the first instance of a match, if the found index is not the first, we know
- it is in fact a duplicate.
-*/
-const deduplicate = (item, itemIndex, arr) => {
- const foundIdx = arr.findIndex((test) => {
- return test.source === item.source && test.target === item.target;
- });
-
- return foundIdx === itemIndex;
-};
-
export const parseData = (nodes) => {
const nodeDict = createNodeDict(nodes);
const allLinks = makeLinksFromNodes(nodes, nodeDict);
- const filteredLinks = filterByAncestors(allLinks, nodeDict);
- const links = filteredLinks.filter(deduplicate);
+ const filteredLinks = allLinks.filter(deduplicate);
+ const links = filterByAncestors(filteredLinks, nodeDict);
return { nodes, links };
};