@elisra-devops/docgen-data-provider 1.43.0 → 1.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/helpers/helper.d.ts +3 -26
- package/bin/helpers/helper.js +39 -124
- package/bin/helpers/helper.js.map +1 -1
- package/package.json +1 -1
- package/src/helpers/helper.ts +62 -183
package/bin/helpers/helper.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Query, Workitem } from
|
|
1
|
+
import { Query, Workitem } from "../models/tfs-data";
|
|
2
2
|
export declare class suiteData {
|
|
3
3
|
name: string;
|
|
4
4
|
id: string;
|
|
@@ -29,32 +29,9 @@ export declare class Trace {
|
|
|
29
29
|
export declare class Helper {
|
|
30
30
|
static level: number;
|
|
31
31
|
static first: boolean;
|
|
32
|
-
static suitList: Array<suiteData>;
|
|
33
32
|
static buildSuiteslevel(dataSuites: any): any;
|
|
34
|
-
|
|
35
|
-
* Find suites recursively - O(n) complexity optimization with parent-child lookup map
|
|
36
|
-
* @param planId - The plan identifier
|
|
37
|
-
* @param url - Base URL
|
|
38
|
-
* @param project - Project name
|
|
39
|
-
* @param suits - Array of suite objects
|
|
40
|
-
* @param foundId - ID to search for
|
|
41
|
-
* @param recursive - Whether to search recursively
|
|
42
|
-
* @returns Array of suite data
|
|
43
|
-
*/
|
|
33
|
+
static suitList: Array<suiteData>;
|
|
44
34
|
static findSuitesRecursive(planId: string, url: string, project: string, suits: any, foundId: string, recursive: boolean): Array<suiteData>;
|
|
45
|
-
|
|
46
|
-
* Optimized recursive helper using lookup maps - O(d) where d is depth
|
|
47
|
-
*/
|
|
48
|
-
private static findSuitesRecursiveOptimized;
|
|
49
|
-
/**
|
|
50
|
-
* Optimized level builder without static state
|
|
51
|
-
* @param results - Query results containing work items
|
|
52
|
-
* @param foundId - ID to start building from
|
|
53
|
-
* @returns Array of work items with levels assigned
|
|
54
|
-
*/
|
|
35
|
+
static levelList: Array<Workitem>;
|
|
55
36
|
static LevelBuilder(results: Query, foundId: string): Array<Workitem>;
|
|
56
|
-
/**
|
|
57
|
-
* Internal recursive method for building levels
|
|
58
|
-
*/
|
|
59
|
-
private static buildLevelsRecursive;
|
|
60
37
|
}
|
package/bin/helpers/helper.js
CHANGED
|
@@ -24,145 +24,60 @@ class Trace {
|
|
|
24
24
|
exports.Trace = Trace;
|
|
25
25
|
class Helper {
|
|
26
26
|
static buildSuiteslevel(dataSuites) { }
|
|
27
|
-
/**
|
|
28
|
-
* Find suites recursively - O(n) complexity optimization with parent-child lookup map
|
|
29
|
-
* @param planId - The plan identifier
|
|
30
|
-
* @param url - Base URL
|
|
31
|
-
* @param project - Project name
|
|
32
|
-
* @param suits - Array of suite objects
|
|
33
|
-
* @param foundId - ID to search for
|
|
34
|
-
* @param recursive - Whether to search recursively
|
|
35
|
-
* @returns Array of suite data
|
|
36
|
-
*/
|
|
37
27
|
static findSuitesRecursive(planId, url, project, suits, foundId, recursive) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
28
|
+
for (let i = 0; i < suits.length; i++) {
|
|
29
|
+
if (suits[i].parentSuiteId != 0) {
|
|
30
|
+
if (suits[i].parentSuiteId == foundId) {
|
|
31
|
+
let suit = new suiteData(suits[i].title, suits[i].id, foundId, this.level++);
|
|
32
|
+
suit.url =
|
|
33
|
+
url +
|
|
34
|
+
project +
|
|
35
|
+
"/_testManagement?planId=" +
|
|
36
|
+
planId +
|
|
37
|
+
"&suiteId=" +
|
|
38
|
+
suits[i].id +
|
|
39
|
+
"&_a=tests";
|
|
40
|
+
this.suitList.push(suit);
|
|
41
|
+
if (recursive == false) {
|
|
42
|
+
return this.suitList;
|
|
43
|
+
}
|
|
44
|
+
this.findSuitesRecursive(planId, url, project, suits, suits[i].id, true);
|
|
45
|
+
this.level--;
|
|
46
|
+
}
|
|
56
47
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
const grandChildren = parentChildMap.get(singleChild.id.toString()) || [];
|
|
66
|
-
// Add each grandchild as a level 1 suite (promoted from level 2)
|
|
67
|
-
for (const grandChild of grandChildren) {
|
|
68
|
-
const suite = new suiteData(grandChild.title || '', grandChild.id, foundId, this.level++);
|
|
69
|
-
suite.url = `${url}${project}/_testManagement?planId=${planId}&suiteId=${grandChild.id}&_a=tests`;
|
|
70
|
-
this.suitList.push(suite);
|
|
71
|
-
if (!recursive) {
|
|
72
|
-
this.level--; // Restore level before returning
|
|
73
|
-
return this.suitList;
|
|
48
|
+
else {
|
|
49
|
+
if (suits[i].id == foundId && Helper.first) {
|
|
50
|
+
let suit = new suiteData(suits[i].title, suits[i].id, foundId, this.level);
|
|
51
|
+
suit.url = url + project + "/_workitems/edit/" + suits[i].id;
|
|
52
|
+
Helper.first = false;
|
|
53
|
+
if (recursive == false) {
|
|
54
|
+
return this.suitList;
|
|
55
|
+
}
|
|
74
56
|
}
|
|
75
|
-
// Now recursively process this grandchild's children
|
|
76
|
-
this.findSuitesRecursiveOptimized(planId, url, project, grandChild.id, recursive, parentChildMap, suiteById);
|
|
77
|
-
this.level--;
|
|
78
57
|
}
|
|
79
58
|
}
|
|
80
|
-
else {
|
|
81
|
-
// Normal processing - start recursion from the found ID
|
|
82
|
-
this.findSuitesRecursiveOptimized(planId, url, project, foundId, recursive, parentChildMap, suiteById);
|
|
83
|
-
}
|
|
84
59
|
return this.suitList;
|
|
85
60
|
}
|
|
86
|
-
/**
|
|
87
|
-
* Optimized recursive helper using lookup maps - O(d) where d is depth
|
|
88
|
-
*/
|
|
89
|
-
static findSuitesRecursiveOptimized(planId, url, project, foundId, recursive, parentChildMap, suiteById) {
|
|
90
|
-
const targetId = foundId.toString();
|
|
91
|
-
// Handle root suite (parentSuiteId === 0) - check if foundId is a root suite
|
|
92
|
-
const rootSuites = parentChildMap.get('0') || [];
|
|
93
|
-
const rootSuite = rootSuites.find((s) => s.id.toString() === targetId);
|
|
94
|
-
if (rootSuite && Helper.first) {
|
|
95
|
-
const suite = new suiteData(rootSuite.title || '', rootSuite.id, foundId, this.level);
|
|
96
|
-
suite.url = `${url}${project}/_workitems/edit/${rootSuite.id}`;
|
|
97
|
-
Helper.first = false;
|
|
98
|
-
if (!recursive) {
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
// Process child suites using the lookup map - O(children count)
|
|
103
|
-
const childSuites = parentChildMap.get(targetId) || [];
|
|
104
|
-
// Normal processing - add all children
|
|
105
|
-
for (const childSuite of childSuites) {
|
|
106
|
-
const suite = new suiteData(childSuite.title || '', childSuite.id, foundId, this.level++);
|
|
107
|
-
suite.url = `${url}${project}/_testManagement?planId=${planId}&suiteId=${childSuite.id}&_a=tests`;
|
|
108
|
-
this.suitList.push(suite);
|
|
109
|
-
if (!recursive) {
|
|
110
|
-
this.level--; // Restore level before returning
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
// Recursively process children
|
|
114
|
-
this.findSuitesRecursiveOptimized(planId, url, project, childSuite.id, true, parentChildMap, suiteById);
|
|
115
|
-
this.level--;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
/**
|
|
119
|
-
* Optimized level builder without static state
|
|
120
|
-
* @param results - Query results containing work items
|
|
121
|
-
* @param foundId - ID to start building from
|
|
122
|
-
* @returns Array of work items with levels assigned
|
|
123
|
-
*/
|
|
124
61
|
static LevelBuilder(results, foundId) {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
for (const workItem of results.workItems) {
|
|
131
|
-
workItemMap.set(((_a = workItem.fields[0]) === null || _a === void 0 ? void 0 : _a.value) || ((_b = workItem.id) === null || _b === void 0 ? void 0 : _b.toString()) || '', workItem);
|
|
132
|
-
}
|
|
133
|
-
this.buildLevelsRecursive(results, foundId, 0, levelList, processedIds, workItemMap);
|
|
134
|
-
return levelList;
|
|
135
|
-
}
|
|
136
|
-
/**
|
|
137
|
-
* Internal recursive method for building levels
|
|
138
|
-
*/
|
|
139
|
-
static buildLevelsRecursive(results, foundId, currentLevel, levelList, processedIds, workItemMap) {
|
|
140
|
-
var _a, _b, _c;
|
|
141
|
-
for (const workItem of results.workItems) {
|
|
142
|
-
const workItemId = ((_a = workItem.fields[0]) === null || _a === void 0 ? void 0 : _a.value) || ((_b = workItem.id) === null || _b === void 0 ? void 0 : _b.toString()) || '';
|
|
143
|
-
// Skip if already processed
|
|
144
|
-
if (processedIds.has(workItemId)) {
|
|
145
|
-
continue;
|
|
146
|
-
}
|
|
147
|
-
// Handle root items (Source === 0)
|
|
148
|
-
if (workItem.Source === 0) {
|
|
149
|
-
workItem.level = 0;
|
|
150
|
-
levelList.push(workItem);
|
|
151
|
-
processedIds.add(workItemId);
|
|
62
|
+
for (let i = 0; i < results.workItems.length; i++) {
|
|
63
|
+
if (results.workItems[i].Source == 0) {
|
|
64
|
+
results.workItems[i].level = 0;
|
|
65
|
+
if (!this.levelList.includes(results.workItems[i]))
|
|
66
|
+
this.levelList.push(results.workItems[i]);
|
|
152
67
|
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
// Recursively process children
|
|
159
|
-
this.buildLevelsRecursive(results, workItemId, currentLevel + 1, levelList, processedIds, workItemMap);
|
|
68
|
+
else if (results.workItems[i].Source.toString() == foundId) {
|
|
69
|
+
results.workItems[i].level = this.level++;
|
|
70
|
+
this.levelList.push(results.workItems[i]);
|
|
71
|
+
this.LevelBuilder(results, results.workItems[i].fields[0].value);
|
|
72
|
+
this.level--;
|
|
160
73
|
}
|
|
161
74
|
}
|
|
75
|
+
return this.levelList;
|
|
162
76
|
}
|
|
163
77
|
}
|
|
164
78
|
exports.Helper = Helper;
|
|
165
79
|
Helper.level = 1;
|
|
166
80
|
Helper.first = true;
|
|
167
81
|
Helper.suitList = new Array();
|
|
82
|
+
Helper.levelList = new Array();
|
|
168
83
|
//# sourceMappingURL=helper.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helper.js","sourceRoot":"","sources":["../../src/helpers/helper.ts"],"names":[],"mappings":";;;AAEA,MAAa,SAAS;IAMpB,YAAY,IAAY,EAAE,EAAU,EAAE,MAAc,EAAE,KAAa;QACjE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;CACF;AAZD,8BAYC;AACD,MAAa,SAAS;IAAtB;QAEE,SAAI,GAAkB,IAAI,KAAK,EAAU,CAAC;IAC5C,CAAC;CAAA;AAHD,8BAGC;AAED,MAAa,KAAK;CAOjB;AAPD,sBAOC;AACD,MAAa,KAAK;
|
|
1
|
+
{"version":3,"file":"helper.js","sourceRoot":"","sources":["../../src/helpers/helper.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/helpers/helper.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Query, Workitem } from
|
|
1
|
+
import { Query, Workitem } from "../models/tfs-data";
|
|
2
2
|
|
|
3
3
|
export class suiteData {
|
|
4
4
|
name: string;
|
|
@@ -32,25 +32,15 @@ export class Trace {
|
|
|
32
32
|
url: string;
|
|
33
33
|
customerId: string;
|
|
34
34
|
links: Array<Links>;
|
|
35
|
+
|
|
36
|
+
|
|
35
37
|
}
|
|
36
38
|
|
|
37
39
|
export class Helper {
|
|
38
40
|
static level: number = 1;
|
|
39
41
|
static first: boolean = true;
|
|
42
|
+
static buildSuiteslevel(dataSuites: any): any { }
|
|
40
43
|
public static suitList: Array<suiteData> = new Array<suiteData>();
|
|
41
|
-
|
|
42
|
-
static buildSuiteslevel(dataSuites: any): any {}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Find suites recursively - O(n) complexity optimization with parent-child lookup map
|
|
46
|
-
* @param planId - The plan identifier
|
|
47
|
-
* @param url - Base URL
|
|
48
|
-
* @param project - Project name
|
|
49
|
-
* @param suits - Array of suite objects
|
|
50
|
-
* @param foundId - ID to search for
|
|
51
|
-
* @param recursive - Whether to search recursively
|
|
52
|
-
* @returns Array of suite data
|
|
53
|
-
*/
|
|
54
44
|
public static findSuitesRecursive(
|
|
55
45
|
planId: string,
|
|
56
46
|
url: string,
|
|
@@ -59,182 +49,71 @@ export class Helper {
|
|
|
59
49
|
foundId: string,
|
|
60
50
|
recursive: boolean
|
|
61
51
|
): Array<suiteData> {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
52
|
+
for (let i = 0; i < suits.length; i++) {
|
|
53
|
+
if (suits[i].parentSuiteId != 0) {
|
|
54
|
+
if (suits[i].parentSuiteId == foundId) {
|
|
55
|
+
let suit: suiteData = new suiteData(
|
|
56
|
+
suits[i].title,
|
|
57
|
+
suits[i].id,
|
|
58
|
+
foundId,
|
|
59
|
+
this.level++
|
|
60
|
+
);
|
|
61
|
+
suit.url =
|
|
62
|
+
url +
|
|
63
|
+
project +
|
|
64
|
+
"/_testManagement?planId=" +
|
|
65
|
+
planId +
|
|
66
|
+
"&suiteId=" +
|
|
67
|
+
suits[i].id +
|
|
68
|
+
"&_a=tests";
|
|
69
|
+
this.suitList.push(suit);
|
|
70
|
+
if (recursive == false) {
|
|
71
|
+
return this.suitList;
|
|
72
|
+
}
|
|
73
|
+
this.findSuitesRecursive(
|
|
74
|
+
planId,
|
|
75
|
+
url,
|
|
76
|
+
project,
|
|
77
|
+
suits,
|
|
78
|
+
suits[i].id,
|
|
79
|
+
true
|
|
80
|
+
);
|
|
81
|
+
this.level--;
|
|
82
|
+
}
|
|
83
|
+
} else {
|
|
84
|
+
if (suits[i].id == foundId && Helper.first) {
|
|
85
|
+
let suit: suiteData = new suiteData(
|
|
86
|
+
suits[i].title,
|
|
87
|
+
suits[i].id,
|
|
88
|
+
foundId,
|
|
89
|
+
this.level
|
|
90
|
+
);
|
|
91
|
+
suit.url = url + project + "/_workitems/edit/" + suits[i].id;
|
|
92
|
+
Helper.first = false;
|
|
93
|
+
if (recursive == false) {
|
|
94
|
+
return this.suitList;
|
|
95
|
+
}
|
|
106
96
|
}
|
|
107
|
-
|
|
108
|
-
// Now recursively process this grandchild's children
|
|
109
|
-
this.findSuitesRecursiveOptimized(
|
|
110
|
-
planId,
|
|
111
|
-
url,
|
|
112
|
-
project,
|
|
113
|
-
grandChild.id,
|
|
114
|
-
recursive,
|
|
115
|
-
parentChildMap,
|
|
116
|
-
suiteById
|
|
117
|
-
);
|
|
118
|
-
this.level--;
|
|
119
97
|
}
|
|
120
|
-
} else {
|
|
121
|
-
// Normal processing - start recursion from the found ID
|
|
122
|
-
this.findSuitesRecursiveOptimized(planId, url, project, foundId, recursive, parentChildMap, suiteById);
|
|
123
98
|
}
|
|
124
|
-
|
|
125
99
|
return this.suitList;
|
|
126
100
|
}
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Optimized recursive helper using lookup maps - O(d) where d is depth
|
|
130
|
-
*/
|
|
131
|
-
private static findSuitesRecursiveOptimized(
|
|
132
|
-
planId: string,
|
|
133
|
-
url: string,
|
|
134
|
-
project: string,
|
|
135
|
-
foundId: string,
|
|
136
|
-
recursive: boolean,
|
|
137
|
-
parentChildMap: Map<string, any[]>,
|
|
138
|
-
suiteById: Map<string, any>
|
|
139
|
-
): void {
|
|
140
|
-
const targetId = foundId.toString();
|
|
141
|
-
|
|
142
|
-
// Handle root suite (parentSuiteId === 0) - check if foundId is a root suite
|
|
143
|
-
const rootSuites = parentChildMap.get('0') || [];
|
|
144
|
-
const rootSuite = rootSuites.find((s) => s.id.toString() === targetId);
|
|
145
|
-
|
|
146
|
-
if (rootSuite && Helper.first) {
|
|
147
|
-
const suite: suiteData = new suiteData(rootSuite.title || '', rootSuite.id, foundId, this.level);
|
|
148
|
-
suite.url = `${url}${project}/_workitems/edit/${rootSuite.id}`;
|
|
149
|
-
Helper.first = false;
|
|
150
|
-
|
|
151
|
-
if (!recursive) {
|
|
152
|
-
return;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// Process child suites using the lookup map - O(children count)
|
|
157
|
-
const childSuites = parentChildMap.get(targetId) || [];
|
|
158
|
-
|
|
159
|
-
// Normal processing - add all children
|
|
160
|
-
for (const childSuite of childSuites) {
|
|
161
|
-
const suite: suiteData = new suiteData(childSuite.title || '', childSuite.id, foundId, this.level++);
|
|
162
|
-
suite.url = `${url}${project}/_testManagement?planId=${planId}&suiteId=${childSuite.id}&_a=tests`;
|
|
163
|
-
this.suitList.push(suite);
|
|
164
|
-
|
|
165
|
-
if (!recursive) {
|
|
166
|
-
this.level--; // Restore level before returning
|
|
167
|
-
return;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
// Recursively process children
|
|
171
|
-
this.findSuitesRecursiveOptimized(planId, url, project, childSuite.id, true, parentChildMap, suiteById);
|
|
172
|
-
|
|
173
|
-
this.level--;
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Optimized level builder without static state
|
|
179
|
-
* @param results - Query results containing work items
|
|
180
|
-
* @param foundId - ID to start building from
|
|
181
|
-
* @returns Array of work items with levels assigned
|
|
182
|
-
*/
|
|
101
|
+
public static levelList: Array<Workitem> = new Array<Workitem>();
|
|
183
102
|
public static LevelBuilder(results: Query, foundId: string): Array<Workitem> {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* Internal recursive method for building levels
|
|
199
|
-
*/
|
|
200
|
-
private static buildLevelsRecursive(
|
|
201
|
-
results: Query,
|
|
202
|
-
foundId: string,
|
|
203
|
-
currentLevel: number,
|
|
204
|
-
levelList: Array<Workitem>,
|
|
205
|
-
processedIds: Set<string>,
|
|
206
|
-
workItemMap: Map<string, Workitem>
|
|
207
|
-
): void {
|
|
208
|
-
for (const workItem of results.workItems) {
|
|
209
|
-
const workItemId = workItem.fields[0]?.value || workItem.id?.toString() || '';
|
|
210
|
-
|
|
211
|
-
// Skip if already processed
|
|
212
|
-
if (processedIds.has(workItemId)) {
|
|
213
|
-
continue;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
// Handle root items (Source === 0)
|
|
217
|
-
if (workItem.Source === 0) {
|
|
218
|
-
workItem.level = 0;
|
|
219
|
-
levelList.push(workItem);
|
|
220
|
-
processedIds.add(workItemId);
|
|
221
|
-
}
|
|
222
|
-
// Handle items with matching source
|
|
223
|
-
else if (workItem.Source?.toString() === foundId) {
|
|
224
|
-
workItem.level = currentLevel;
|
|
225
|
-
levelList.push(workItem);
|
|
226
|
-
processedIds.add(workItemId);
|
|
227
|
-
|
|
228
|
-
// Recursively process children
|
|
229
|
-
this.buildLevelsRecursive(
|
|
230
|
-
results,
|
|
231
|
-
workItemId,
|
|
232
|
-
currentLevel + 1,
|
|
233
|
-
levelList,
|
|
234
|
-
processedIds,
|
|
235
|
-
workItemMap
|
|
236
|
-
);
|
|
103
|
+
for (let i = 0; i < results.workItems.length; i++) {
|
|
104
|
+
if (results.workItems[i].Source == 0) {
|
|
105
|
+
results.workItems[i].level = 0;
|
|
106
|
+
if (!this.levelList.includes(results.workItems[i]))
|
|
107
|
+
this.levelList.push(results.workItems[i]);
|
|
108
|
+
} else if (results.workItems[i].Source.toString() == foundId) {
|
|
109
|
+
results.workItems[i].level = this.level++;
|
|
110
|
+
this.levelList.push(results.workItems[i]);
|
|
111
|
+
|
|
112
|
+
this.LevelBuilder(results, results.workItems[i].fields[0].value);
|
|
113
|
+
this.level--;
|
|
237
114
|
}
|
|
238
115
|
}
|
|
116
|
+
|
|
117
|
+
return this.levelList;
|
|
239
118
|
}
|
|
240
119
|
}
|