Skip to content

Commit

Permalink
Remove unnecessary code due to new upstream API
Browse files Browse the repository at this point in the history
  • Loading branch information
fschopp committed Aug 5, 2019
1 parent c7455ec commit a205163
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 92 deletions.
16 changes: 8 additions & 8 deletions package.json
Expand Up @@ -44,27 +44,27 @@
"node": ">=10.0.0"
},
"dependencies": {
"@fschopp/project-planning-for-you-track": "fschopp/project-planning-for-you-track#6dec2d7612431016baea70e6ffb1f67079f8c082",
"@fschopp/project-planning-ui-for-you-track": "fschopp/project-planning-ui-for-you-track#5cca070ea7ee228ac115ae6f1a8d5cca83c4e2fa",
"@fschopp/project-planning-for-you-track": "fschopp/project-planning-for-you-track#7203d312a07c6dc9bd6559579cbd6e1b3dcf61a5",
"@fschopp/project-planning-ui-for-you-track": "fschopp/project-planning-ui-for-you-track#7373b881d30bf3deae7f047eec291d5f4db042d3",
"s-js": "^0.4.9",
"surplus": "^0.5.3",
"surplus-mixin-data": "^0.5.0",
"viz.js": "^2.1.2"
},
"devDependencies": {
"@babel/core": "^7.5.4",
"@babel/preset-env": "^7.5.4",
"@types/jest": "^24.0.15",
"@types/node": "^12.6.4",
"@babel/core": "^7.5.5",
"@babel/preset-env": "^7.5.5",
"@types/jest": "^24.0.17",
"@types/node": "^12.6.9",
"babel-plugin-unassert": "^3.0.1",
"babel-polyfill": "^6.26.0",
"jest": "^24.8.0",
"parcel-bundler": "^1.12.3",
"regenerator-runtime": "^0.13.2",
"regenerator-runtime": "^0.13.3",
"source-map": "^0.7.3",
"ts-jest": "^24.0.2",
"tslint": "^5.18.0",
"typedoc": "TypeStrong/typedoc#e9b28ee2c336617687a968820515b6a37d44515f",
"typedoc": "^0.15.0",
"typescript": "^3.5.3"
},
"jest": {
Expand Down
128 changes: 46 additions & 82 deletions src/main/graphviz-app-ctrl.ts
Expand Up @@ -2,9 +2,12 @@
/// <reference path="module.d.ts"/>

import {
IssueNode,
makeForest,
ProjectPlan,
retrieveProjectPlan,
RetrieveProjectPlanOptions,
traverseIssueForest,
YouTrackConfig,
YouTrackIssue,
} from '@fschopp/project-planning-for-you-track';
Expand Down Expand Up @@ -247,66 +250,21 @@ interface GraphvizIssue {
isResolved: boolean;
assignee?: User;
type?: EnumBundleElement;
parent?: GraphvizIssue;
dependencies: GraphvizIssue[];
children: GraphvizIssue[];
}

/**
* Creates a new tree of {@link GraphvizIssue} nodes, and returns an `Iterable` over all roots.
*/
function rootIssues(issues: YouTrackIssue[], userMap: Map<string, User>, typeFieldId: string,
typeMap: Map<string, EnumBundleElement>): Iterable<GraphvizIssue> {
const idToYouTrackIssueMap: Map<string, YouTrackIssue> =
issues.reduce((map, issue) => map.set(issue.id, issue), new Map<string, YouTrackIssue>());
const idToGraphvizMap: Map<string, GraphvizIssue> =
issues.reduce((map, issue) => {
const typeId: string | undefined = issue.customFields[typeFieldId];
return map.set(issue.id, {
id: issue.id,
label: labelFromId(issue.id),
summary: issue.summary,
escapedSummary: replaceWithHtmlEntities(issue.summary),
isResolved: issue.resolved < Number.MAX_SAFE_INTEGER,
assignee: userMap.get(issue.assignee),
type: typeId === undefined
? undefined
: typeMap.get(typeId),
dependencies: [],
children: [],
});
}, new Map<string, GraphvizIssue>());
for (const graphvizIssue of idToGraphvizMap.values()) {
const youTrackIssue: YouTrackIssue = idToYouTrackIssueMap.get(graphvizIssue.id)!;

const parentKey: string = youTrackIssue.parent;
if (parentKey.length > 0) {
graphvizIssue.parent = idToGraphvizMap.get(parentKey)!;
graphvizIssue.parent.children.push(graphvizIssue);
}

for (const dependency of youTrackIssue.dependencies) {
graphvizIssue.dependencies.push(idToGraphvizMap.get(dependency)!);
}
}
return {
* [Symbol.iterator]() {
for (const graphvizIssue of idToGraphvizMap.values()[Symbol.iterator]()) {
if (graphvizIssue.parent === undefined) {
yield graphvizIssue;
}
}
},
};
interface ExtendedIssue extends YouTrackIssue {
graphvizIssue: GraphvizIssue;
}

interface DotBuilder {
dot: string;
dependenciesDot: string;
}

function enterNode(dotBuilder: DotBuilder, currentIndent: string, graphvizIssue: GraphvizIssue, baseUrl: string): void {
const isSubgraph: boolean = graphvizIssue.children.length > 0;
function enterNode(dotBuilder: DotBuilder, currentIndent: string, node: IssueNode<ExtendedIssue>, baseUrl: string):
void {
const graphvizIssue: GraphvizIssue = node.issue.graphvizIssue;
const isSubgraph: boolean = node.children.length > 0;
dotBuilder.dot += currentIndent;
if (isSubgraph) {
dotBuilder.dot += `subgraph cluster_${graphvizIssue.label} {\n`;
Expand All @@ -333,9 +291,10 @@ function enterNode(dotBuilder: DotBuilder, currentIndent: string, graphvizIssue:
currentIndent + ` fillcolor = "${bgColor}";\n` +
currentIndent + ` fontcolor = "${fgColor}";\n` +
currentIndent + ` color = "${fgColor}";\n`;
const label: string = linkNodeForIssue(graphvizIssue);
for (const dependency of graphvizIssue.dependencies) {
const dependencyLabel: string = linkNodeForIssue(dependency);
const label: string = linkLabelForIssueNode(node);
for (const dependencyNode of node.dependencies) {
const dependency: GraphvizIssue = dependencyNode.issue.graphvizIssue;
const dependencyLabel: string = linkLabelForIssueNode(dependencyNode);
const isDependencySubgraph: boolean = dependencyLabel !== dependency.label;
dotBuilder.dependenciesDot += ` ${dependencyLabel} -> ${label}`;
if (isSubgraph || isDependencySubgraph) {
Expand All @@ -350,7 +309,7 @@ function enterNode(dotBuilder: DotBuilder, currentIndent: string, graphvizIssue:
}
dotBuilder.dependenciesDot += '\n';
}
if (graphvizIssue.children.length > 0) {
if (node.children.length > 0) {
dotBuilder.dot += '\n';
}
}
Expand Down Expand Up @@ -390,29 +349,34 @@ function computeDotFromIssues(issues: YouTrackIssue[], baseUrl: string, userMap:
'\n',
dependenciesDot: '',
};
let currentIterator: Iterator<GraphvizIssue> = rootIssues(issues, userMap, typeFieldId, typeMap)[Symbol.iterator]();
const stack: Iterator<GraphvizIssue>[] = [];
const indent: () => string = () => ' '.repeat(stack.length + 1);
while (true) {
const iteratorResult = currentIterator.next();
if (iteratorResult.done) {
if (stack.length === 0) {
break;
}
currentIterator = stack.pop()!;
leaveNode(dotBuilder, indent(), true);
} else {
const graphvizIssue: GraphvizIssue = iteratorResult.value;
const currentIndent: string = indent();
enterNode(dotBuilder, currentIndent, graphvizIssue, baseUrl);
if (graphvizIssue.children.length > 0) {
stack.push(currentIterator);
currentIterator = graphvizIssue.children[Symbol.iterator]();
} else {
leaveNode(dotBuilder, currentIndent, false);
const extendedIssues: ExtendedIssue[] = issues.map((issue) => {
const typeId: string | undefined = issue.customFields[typeFieldId];
const graphvizIssue: GraphvizIssue = {
id: issue.id,
label: labelFromId(issue.id),
summary: issue.summary,
escapedSummary: replaceWithHtmlEntities(issue.summary),
isResolved: issue.resolved < Number.MAX_SAFE_INTEGER,
assignee: userMap.get(issue.assignee),
type: typeId === undefined
? undefined
: typeMap.get(typeId),
};
return {...issue, graphvizIssue};
});
let indentLevel = 0;
const indent: () => string = () => ' '.repeat(indentLevel);
traverseIssueForest(
makeForest(extendedIssues),
(node) => {
++indentLevel;
enterNode(dotBuilder, indent(), node, baseUrl);
},
(node) => {
leaveNode(dotBuilder, indent(), node.children.length > 0);
--indentLevel;
}
}
}
);
if (dotBuilder.dependenciesDot.length > 0) {
dotBuilder.dot += '\n' + dotBuilder.dependenciesDot;
}
Expand Down Expand Up @@ -468,12 +432,12 @@ function sixDigitColor(color: string) {
: color);
}

function linkNodeForIssue(issue: GraphvizIssue): string {
let currentIssue: GraphvizIssue = issue;
while (currentIssue.children.length > 0) {
currentIssue = currentIssue.children[0];
function linkLabelForIssueNode(node: IssueNode<ExtendedIssue>): string {
let currentNode: IssueNode<ExtendedIssue> = node;
while (currentNode.children.length > 0) {
currentNode = currentNode.children[0];
}
return currentIssue.label;
return currentNode.issue.graphvizIssue.label;
}

/**
Expand Down
4 changes: 2 additions & 2 deletions src/spec/visual-plan-ctrl.spec.ts
Expand Up @@ -30,10 +30,10 @@ afterEach(() => {

test('generates visualization if GraphvizAppComputation.projectPlan signal changes', async () => {
const app: GraphvizApp = createGraphvizApp();
const appComputation: GraphvizAppComputation = createGraphvizAppComputation();

app.settings.youTrackBaseUrl('http://fake-youtrack/');
app.settings.hubUrl('http://fake-hub/');
const appComputation: GraphvizAppComputation = createGraphvizAppComputation();

let appCtrl: GraphvizAppCtrl | undefined;
S.root(() => {
appCtrl = GraphvizAppCtrl.createDefaultGraphvizCtrl(app, appComputation, '/mock/path/to/worker.js');
Expand Down

0 comments on commit a205163

Please sign in to comment.