Advertisement
Guest User

Untitled

a guest
Sep 19th, 2017
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 29.02 KB | None | 0 0
  1. console.log('je tests 2');
  2.  
  3. function handlePipelineUpdate(self) {
  4. return function(divNames, errorDiv, view, fullscreen, page, component, showChanges, aggregatedChangesGroupingPattern, timeout, pipelineid, jsplumb) {
  5. Q.ajax({
  6. url: rootURL + '/' + view.viewUrl + 'api/json' + '?page=' + page + '&component=' + component + '&fullscreen=' + fullscreen,
  7. dataType: 'json',
  8. async: true,
  9. cache: false,
  10. timeout: 20000,
  11. success: function (data) {
  12. self.refreshPipelines(data, divNames, errorDiv, view, fullscreen, showChanges, aggregatedChangesGroupingPattern, pipelineid, jsplumb);
  13. setTimeout(function () {
  14. self.updatePipelines(divNames, errorDiv, view, fullscreen, page, component, showChanges, aggregatedChangesGroupingPattern, timeout, pipelineid, jsplumb);
  15. }, timeout);
  16. },
  17. error: function (xhr, status, error) {
  18. Q('#' + errorDiv).html('Error communicating to server! ' + htmlEncode(error)).show();
  19. jsplumb.repaintEverything();
  20. setTimeout(function () {
  21. self.updatePipelines(divNames, errorDiv, view, fullscreen, page, component, showChanges, aggregatedChangesGroupingPattern, timeout, pipelineid, jsplumb);
  22. }, timeout);
  23. }
  24. });
  25. };
  26. }
  27.  
  28. function handleRepeatingPipelineRefresh(data, lastUpdate) {
  29. var comp;
  30. var pipe;
  31. var head;
  32. var st;
  33. var ta;
  34. var time;
  35.  
  36. for (var p = 0; p < data.pipelines.length; p++) {
  37. comp = data.pipelines[p];
  38. for (var d = 0; d < comp.pipelines.length; d++) {
  39. pipe = comp.pipelines[d];
  40. head = document.getElementById(pipe.id);
  41. if (head) {
  42. head.innerHTML = formatDate(pipe.timestamp, lastUpdate)
  43. }
  44.  
  45. for (var l = 0; l < pipe.stages.length; l++) {
  46. st = pipe.stages[l];
  47. for (var m = 0; m < st.tasks.length; m++) {
  48. ta = st.tasks[m];
  49. time = document.getElementById(getTaskId(ta.id, d) + '.timestamp');
  50. if (time) {
  51. time.innerHTML = formatDate(ta.status.timestamp, lastUpdate);
  52. }
  53. }
  54. }
  55. }
  56. }
  57. }
  58.  
  59. function addPipelineHeader(html, component, data, c, resURL) {
  60. html.push('<h1>' + htmlEncode(component.name));
  61. if (data.allowPipelineStart) {
  62. if (component.workflowComponent) {
  63. html.push('&nbsp;<a id="startpipeline-' + c +'" class="task-icon-link" href="#" onclick="triggerBuild(\'' + component.workflowUrl + '\', \'' + data.name + '\')">');
  64. } else if (component.firstJobParameterized) {
  65. html.push('&nbsp;<a id="startpipeline-' + c +'" class="task-icon-link" href="#" onclick="triggerParameterizedBuild(\'' + component.firstJobUrl + '\', \'' + data.name + '\')">');
  66. } else {
  67. html.push('&nbsp;<a id="startpipeline-' + c +'" class="task-icon-link" href="#" onclick="triggerBuild(\'' + component.firstJobUrl + '\', \'' + data.name + '\')">');
  68. }
  69. html.push('<img class="icon-clock icon-md" title="Build now" src="' + resURL + '/images/24x24/clock.png">');
  70. html.push('</a>');
  71. }
  72. html.push('</h1>');
  73. }
  74.  
  75. function displayErrorIfAvailable(data, errrorDivId) {
  76. var cErrorDiv = Q('#' + errrorDivId);
  77. if (data.error) {
  78. cErrorDiv.html('Error: ' + data.error).show();
  79. } else {
  80. cErrorDiv.hide().html('');
  81. }
  82. }
  83.  
  84. function isTaskLinkedToConsoleLog(data, task) {
  85. return data.linkToConsoleLog
  86. && (task.status.success
  87. || task.status.failed
  88. || task.status.unstable
  89. || task.status.cancelled);
  90. }
  91.  
  92. function getPagination(showAvatars, component) {
  93. if (showAvatars || component.pagingData === '') {
  94. return '';
  95. }
  96.  
  97. var html = [];
  98. html.push('<div class="pagination">');
  99. html.push(component.pagingData);
  100. html.push('</div>');
  101. return html.join('');
  102. }
  103.  
  104. function getLink(data, link) {
  105. return data.linkRelative ? link : rootURL + '/' + link;
  106. }
  107.  
  108. function trimWarningsFromString(label) {
  109. var offset = label.indexOf('Warnings');
  110. return offset === -1 ? label : label.substring(0, offset).trim();
  111. }
  112.  
  113. function generatePromotionsInfo(data, task) {
  114. if (!data.showPromotions || !task.status.promoted || !task.status.promotions || task.status.promotions.length === 0) {
  115. return undefined;
  116. }
  117.  
  118. var html = ['<div class="infoPanelOuter">'];
  119. Q.each(task.status.promotions, function(i, promo) {
  120. html.push('<div class="infoPanel"><div class="infoPanelInner"><div class="promo-layer">');
  121. html.push('<img class="promo-icon" height="16" width="16" src="' + rootURL + promo.icon + '"/>');
  122. html.push('<span class="promo-name"><a href="' + getLink(data,task.link) + 'promotion">' + htmlEncode(promo.name) + '</a></span><br/>');
  123. if (promo.user !== 'anonymous') {
  124. html.push('<span class="promo-user">' + promo.user + '</span>');
  125. }
  126. html.push('<span class="promo-time">' + formatDuration(promo.time) + '</span><br/>');
  127. if (promo.params.length > 0) {
  128. html.push('<br/>');
  129. }
  130. Q.each(promo.params, function (j, param) {
  131. html.push(param.replace(/\r\n/g, '<br/>') + '<br />');
  132. });
  133. html.push('</div></div></div>');
  134. });
  135. html.push('</div>');
  136. return html.join('');
  137. }
  138.  
  139. function generateAggregatedChangelog(stageChanges, aggregatedChangesGroupingPattern) {
  140. var html = [];
  141. html.push('<div class="aggregatedChangesPanelOuter">');
  142. html.push('<div class="aggregatedChangesPanel">');
  143. html.push('<div class="aggregatedChangesPanelInner">');
  144. html.push('<b>Changes:</b>');
  145. html.push('<ul>');
  146.  
  147. var changes = {};
  148.  
  149. var unmatchedChangesKey = '';
  150.  
  151. if (aggregatedChangesGroupingPattern) {
  152. var re = new RegExp(aggregatedChangesGroupingPattern);
  153.  
  154. stageChanges.forEach(function(stageChange) {
  155. var matches = stageChange.message.match(re) || [unmatchedChangesKey];
  156.  
  157. Q.unique(matches).forEach(function (match) {
  158. changes[match] = changes[match] || [];
  159. changes[match].push(stageChange);
  160. });
  161. });
  162. } else {
  163. changes[unmatchedChangesKey] = stageChanges;
  164. }
  165.  
  166. var keys = Object.keys(changes).sort().filter(function(matchKey) {
  167. return matchKey !== unmatchedChangesKey;
  168. });
  169.  
  170. keys.push(unmatchedChangesKey);
  171.  
  172. keys.forEach(function(matchKey) {
  173. if (matchKey !== unmatchedChangesKey) {
  174. html.push('<li class="aggregatedKey"><b>' + matchKey + '</b><ul>');
  175. }
  176.  
  177. if (changes[matchKey]) {
  178. changes[matchKey].forEach(function (change) {
  179. html.push('<li>');
  180. html.push(change.message || '&nbsp;');
  181. html.push('</li>');
  182. });
  183. }
  184.  
  185. if (matchKey !== unmatchedChangesKey) {
  186. html.push('</ul></li>');
  187. }
  188. });
  189.  
  190. html.push('</ul>');
  191. html.push('</div>');
  192. html.push('</div>');
  193. html.push('</div>');
  194.  
  195. return html.join('')
  196. }
  197.  
  198. function getStageClassName(stagename) {
  199. return 'stage_' + replace(stagename, ' ', '_');
  200. }
  201.  
  202. function getTaskId(taskname, count) {
  203. return 'task-' + replace(replace(taskname, ' ', '_'), '/', '_') + count;
  204. }
  205.  
  206. function replace(string, replace, replaceWith) {
  207. var re = new RegExp(replace, 'g');
  208. return string.replace(re, replaceWith);
  209. }
  210.  
  211. function formatDate(date, currentTime) {
  212. return date !== null ? moment(date, 'YYYY-MM-DDTHH:mm:ss').from(moment(currentTime, 'YYYY-MM-DDTHH:mm:ss')) : '';
  213. }
  214.  
  215. function formatDuration(millis) {
  216. if (millis === 0) {
  217. return '0 sec';
  218. }
  219.  
  220. var seconds = Math.floor(millis / 1000);
  221. var minutes = Math.floor(seconds / 60);
  222. var minstr;
  223. var secstr;
  224.  
  225. seconds = seconds % 60;
  226. minstr = minutes === 0 ? '' : minutes + ' min ';
  227. secstr = '' + seconds + ' sec';
  228.  
  229. return minstr + secstr;
  230. }
  231.  
  232. function triggerManual(taskId, downstreamProject, upstreamProject, upstreamBuild, viewUrl) {
  233. Q('#manual-' + taskId).hide();
  234. var formData = {project: downstreamProject, upstream: upstreamProject, buildId: upstreamBuild};
  235. var before;
  236.  
  237. if (crumb.value !== null && crumb.value !== '') {
  238. console.info('Crumb found and will be added to request header');
  239. before = function(xhr){xhr.setRequestHeader(crumb.fieldName, crumb.value);}
  240. } else {
  241. console.info('Crumb not needed');
  242. before = function(xhr){}
  243. }
  244.  
  245. Q.ajax({
  246. url: rootURL + '/' + viewUrl + 'api/manualStep',
  247. type: 'POST',
  248. data: formData,
  249. beforeSend: before,
  250. timeout: 20000,
  251. async: true,
  252. success: function (data, textStatus, jqXHR) {
  253. console.info('Triggered build of ' + downstreamProject + ' successfully!');
  254. },
  255. error: function (jqXHR, textStatus, errorThrown) {
  256. window.alert('Could not trigger build! error: ' + errorThrown + ' status: ' + textStatus);
  257. }
  258. });
  259. }
  260.  
  261. function triggerRebuild(taskId, project, buildId, viewUrl) {
  262. Q('#rebuild-' + taskId).hide();
  263. var formData = {project: project, buildId: buildId};
  264.  
  265. var before;
  266. if (crumb.value !== null && crumb.value !== '') {
  267. console.info('Crumb found and will be added to request header');
  268. before = function(xhr){xhr.setRequestHeader(crumb.fieldName, crumb.value);}
  269. } else {
  270. console.info('Crumb not needed');
  271. before = function(xhr){}
  272. }
  273.  
  274. Q.ajax({
  275. url: rootURL + '/' + viewUrl + 'api/rebuildStep',
  276. type: 'POST',
  277. data: formData,
  278. beforeSend: before,
  279. timeout: 20000,
  280. success: function (data, textStatus, jqXHR) {
  281. console.info('Triggered rebuild of ' + project + ' successfully!')
  282. },
  283. error: function (jqXHR, textStatus, errorThrown) {
  284. window.alert('Could not trigger rebuild! error: ' + errorThrown + ' status: ' + textStatus)
  285. }
  286. });
  287. }
  288.  
  289. function specifyInput(taskId, project, buildId, viewUrl) {
  290. Q('#input-' + taskId).hide();
  291. var formData = {project: project, upstream: 'N/A', buildId: buildId};
  292. var before;
  293.  
  294. if (crumb.value !== null && crumb.value !== '') {
  295. console.info('Crumb found and will be added to request header');
  296. before = function(xhr){xhr.setRequestHeader(crumb.fieldName, crumb.value);}
  297. } else {
  298. console.info('Crumb not needed');
  299. before = function(xhr){}
  300. }
  301.  
  302. Q.ajax({
  303. url: rootURL + '/' + viewUrl + 'api/inputStep',
  304. type: 'POST',
  305. data: formData,
  306. beforeSend: before,
  307. timeout: 20000,
  308. success: function (data, textStatus, jqXHR) {
  309. console.info('Successfully triggered input step of ' + project + '!')
  310. },
  311. error: function (jqXHR, textStatus, errorThrown) {
  312. window.alert('Could not trigger input step! error: ' + errorThrown + ' status: ' + textStatus)
  313. }
  314. });
  315. }
  316.  
  317. function triggerParameterizedBuild(url, taskId) {
  318. console.info('Job is parameterized');
  319. window.location.href = rootURL + '/' + url + 'build?delay=0sec';
  320. }
  321.  
  322. function triggerBuild(url, taskId) {
  323. var before;
  324. if (crumb.value !== null && crumb.value !== '') {
  325. console.info('Crumb found and will be added to request header');
  326. before = function(xhr){xhr.setRequestHeader(crumb.fieldName, crumb.value);}
  327. } else {
  328. console.info('Crumb not needed');
  329. before = function(xhr){}
  330. }
  331.  
  332. Q.ajax({
  333. url: rootURL + '/' + url + 'build?delay=0sec',
  334. type: 'POST',
  335. beforeSend: before,
  336. timeout: 20000,
  337. success: function (data, textStatus, jqXHR) {
  338. console.info('Triggered build of ' + taskId + ' successfully!')
  339. },
  340. error: function (jqXHR, textStatus, errorThrown) {
  341. window.alert('Could not trigger build! error: ' + errorThrown + ' status: ' + textStatus)
  342. }
  343. });
  344. }
  345.  
  346. function htmlEncode(html) {
  347. return document.createElement('a')
  348. .appendChild(document.createTextNode(html))
  349. .parentNode.innerHTML
  350. .replace(/\n/g, '<br/>');
  351. }
  352.  
  353. function getStageId(name, count) {
  354. var re = / /g;
  355. return name.replace(re, '_') + '_' + count;
  356. }
  357.  
  358. function equalheight(container) {
  359. var currentTallest = 0;
  360. var currentRowStart = 0;
  361. var rowDivs = new Array();
  362. var $el;
  363. var topPosition = 0;
  364.  
  365. Q(container).each(function () {
  366. $el = Q(this);
  367. Q($el).height('auto');
  368. topPosition = $el.position().top;
  369.  
  370. if (currentRowStart !== topPosition) {
  371. rowDivs.length = 0; // empty the array
  372. currentRowStart = topPosition;
  373. currentTallest = $el.height() + 2;
  374. rowDivs.push($el);
  375. } else {
  376. rowDivs.push($el);
  377. currentTallest = (currentTallest < $el.height() + 2) ? ($el.height() + 2) : (currentTallest);
  378. }
  379. for (currentDiv = 0; currentDiv < rowDivs.length; currentDiv++) {
  380. rowDivs[currentDiv].height(currentTallest);
  381. }
  382. });
  383. }
  384.  
  385. function checkBuildAvailability(html, component) {
  386. if (component.pipelines.length === 0) {
  387. html.push('No builds done yet.');
  388. }
  389. }
  390.  
  391. function checkForAggregatedView(html, component) {
  392. if (component.pipelines.length > 1) {
  393. html.push('<h2>Aggregated view</h2>');
  394. }
  395. }
  396.  
  397. function addSpecificTaskDetails(task, data, html, id) {
  398. var progress = 100;
  399. var progressClass = 'task-progress-notrunning';
  400. var consoleLogLink = '';
  401.  
  402. if (task.status.percentage) {
  403. progress = task.status.percentage;
  404. progressClass = 'task-progress-running';
  405. } else if (isTaskLinkedToConsoleLog(data, task)) {
  406. consoleLogLink = 'console';
  407. }
  408.  
  409. html.push(
  410. '<div id="' + id + '" class="status stage-task ' + task.status.type + '">'
  411. + '<div class="task-progress ' + progressClass + '" style="width: ' + progress + '%">'
  412. + '<div class="task-content">'
  413. + '<div class="task-header">'
  414. + '<div class="taskname">'
  415. + '<a href="' + getLink(data, task.link) + consoleLogLink + '">' + htmlEncode(task.name) + '</a>'
  416. + '</div>'
  417. );
  418. }
  419.  
  420. function checkAvailableTasks(data, task, html, id, view, pipeline, component) {
  421. if (data.allowManualTriggers && task.manual && task.manualStep.enabled && task.manualStep.permission) {
  422. html.push('<div class="task-manual" id="manual-' + id + '" title="Trigger manual build" onclick="triggerManual(\'' + id + '\', \'' + task.id + '\', \'' + task.manualStep.upstreamProject + '\', \'' + task.manualStep.upstreamId + '\', \'' + view.viewUrl + '\')">');
  423. html.push('</div>');
  424. return;
  425. }
  426. if (pipeline.aggregated) {
  427. return;
  428. }
  429. if (data.allowRebuild && task.rebuildable) {
  430. html.push('<div class="task-rebuild" id="rebuild-' + id + '" title="Trigger rebuild" onclick="triggerRebuild(\'' + id + '\', \'' + task.id + '\', \'' + task.buildId + '\', \'' + view.viewUrl + '\')">');
  431. html.push('</div>');
  432. }
  433. if (task.requiringInput) {
  434. html.push('<div class="task-manual" id="input-' + id + '" title="Specify input" onclick="specifyInput(\'' + id + '\', \'' + component.name + '\', \'' + task.buildId + '\', \'' + view.viewUrl + '\')">');
  435. html.push('</div>');
  436. }
  437. }
  438.  
  439. function addTimeDetails(html, timestamp, id, task) {
  440. html.push('<div class="task-details">');
  441.  
  442. if (timestamp !== '') {
  443. html.push('<div id="' + id + '.timestamp" class="timestamp">' + timestamp + '</div>');
  444. }
  445.  
  446. if (task.status.duration >= 0) {
  447. html.push('<div class="duration">' + formatDuration(task.status.duration) + '</div>');
  448. }
  449.  
  450. html.push('</div>');
  451. }
  452.  
  453. function buildFullTaskLayout(task, data, html, id, view, pipeline, component, lastUpdate) {
  454. var timestamp = formatDate(task.status.timestamp, lastUpdate);
  455.  
  456. addSpecificTaskDetails(task, data, html, id);
  457. checkAvailableTasks(data, task, html, id, view, pipeline, component);
  458.  
  459. html.push('</div>');
  460.  
  461. addTimeDetails(html, timestamp, id, task);
  462.  
  463. html.push('</div></div></div>');
  464.  
  465. html.push(generateDescription(data, task));
  466. html.push(generateTestInfo(data, task));
  467. html.push(generateStaticAnalysisInfo(data, task));
  468. html.push(generatePromotionsInfo(data, task));
  469. }
  470.  
  471. function buildAllStageTasks(stage, i, tasks, data, html, view, pipeline, component, lastUpdate) {
  472. for (var k = 0; k < stage.tasks.length; k++) {
  473. var task = stage.tasks[k];
  474. var id = getTaskId(task.id, i);
  475. tasks.push({id: id, taskId: task.id, buildId: task.buildId});
  476. buildFullTaskLayout(task, data, html, id, view, pipeline, component, lastUpdate);
  477. }
  478. }
  479.  
  480. function buildStageHeader(html, stage, pipeline, clear) {
  481. html.push('<div class="stage-header"><div class="stage-name">' + htmlEncode(stage.name) + '</div>');
  482.  
  483. if (!pipeline.aggregated) {
  484. if (clear) {
  485. html.push('<div class="clear"></div>');
  486. }
  487. html.push('</div>');
  488. } else {
  489. var stageversion = stage.version || 'N/A';
  490. html.push(' <div class="stage-version">');
  491. html.push(htmlEncode(stageversion));
  492. html.push('</div>');
  493. if (clear) {
  494. html.push('<div class="clear"></div>');
  495. }
  496. html.push('</div>');
  497. }
  498. }
  499.  
  500. function generateDescription(data, task) {
  501. if (!data.showDescription || !task.description || task.description === '') {
  502. return undefined;
  503. }
  504.  
  505. var html = ['<div class="infoPanelOuter">'];
  506. html.push('<div class="infoPanel"><div class="infoPanelInner">' + task.description.replace(/\r\n/g, '<br/>') + '</div></div>');
  507. html.push('</div>');
  508. return html.join('');
  509. }
  510.  
  511. function generateTestInfo(data, task) {
  512. if (!data.showTestResults || !task.testResults || task.testResults.length === 0) {
  513. return undefined;
  514. }
  515.  
  516. var html = ['<div class="infoPanelOuter">'];
  517.  
  518. Q.each(task.testResults, function(i, analysis) {
  519. html.push('<div class="infoPanel"><div class="infoPanelInner">');
  520. html.push('<a href=' + getLink(data,analysis.url) + '>' + analysis.name + '</a>');
  521. html.push('<table id="priority.summary" class="pane">');
  522. html.push('<tbody>');
  523. html.push('<tr>');
  524. html.push('<td class="pane-header">Total</td>');
  525. html.push('<td class="pane-header">Failures</td>');
  526. html.push('<td class="pane-header">Skipped</td>');
  527. html.push('</tr>');
  528. html.push('</tbody>');
  529. html.push('<tbody>');
  530. html.push('<tr>');
  531. html.push('<td class="pane">' + analysis.total + '</td>');
  532. html.push('<td class="pane">' + analysis.failed + '</td>');
  533. html.push('<td class="pane">' + analysis.skipped + '</td>');
  534. html.push('</tr>');
  535. html.push('</tbody>');
  536. html.push('</table>');
  537. html.push('</div></div>');
  538. });
  539.  
  540. html.push('</div>');
  541. return html.join('');
  542. }
  543.  
  544. function generateStaticAnalysisInfo(data, task) {
  545. if (!data.showStaticAnalysisResults || !task.staticAnalysisResults || task.staticAnalysisResults.length === 0) {
  546. return undefined;
  547. }
  548.  
  549. var html = ['<div class="infoPanelOuter">'];
  550. html.push('<div class="infoPanel"><div class="infoPanelInner">');
  551. html.push('<table id="priority.summary" class="pane">');
  552. html.push('<thead>');
  553. html.push('<tr>');
  554. html.push('<td class="pane-header">Warnings</td>');
  555. html.push('<td class="pane-header" style="font-size: smaller; vertical-align: bottom">High</td>');
  556. html.push('<td class="pane-header" style="font-size: smaller; vertical-align: bottom">Normal</td>');
  557. html.push('<td class="pane-header" style="font-size: smaller; vertical-align: bottom">Low</td>');
  558. html.push('</tr>');
  559. html.push('</thead>');
  560. html.push('<tbody>');
  561.  
  562. Q.each(task.staticAnalysisResults, function(i, analysis) {
  563. html.push('<tr>');
  564. html.push('<td class="pane"><a href=' + getLink(data,analysis.url) + '>' + trimWarningsFromString(analysis.name) + '</a></td>');
  565. html.push('<td class="pane" style="text-align: center">' + analysis.high + '</td>');
  566. html.push('<td class="pane" style="text-align: center">' + analysis.normal + '</td>');
  567. html.push('<td class="pane" style="text-align: center">' + analysis.low + '</td>');
  568. html.push('</tr>');
  569. });
  570.  
  571. html.push('</tbody>');
  572. html.push('</table>');
  573. html.push('</div></div>');
  574. html.push('</div>');
  575. return html.join('');
  576. }
  577.  
  578.  
  579. function pipelineUtils() {
  580. var self = this;
  581. this.updatePipelines = handlePipelineUpdate(self);
  582.  
  583. var lastResponse = null;
  584.  
  585. this.refreshPipelines = function(data, divNames, errorDiv, view, showAvatars, showChanges, aggregatedChangesGroupingPattern, pipelineid, jsplumb) {
  586. var lastUpdate = data.lastUpdated;
  587. var pipeline;
  588. var component;
  589. var html;
  590. var trigger;
  591. var triggered;
  592. var contributors;
  593. var tasks = [];
  594.  
  595. displayErrorIfAvailable(data, errorDiv);
  596.  
  597. if (lastResponse === null || JSON.stringify(data.pipelines) !== JSON.stringify(lastResponse.pipelines)) {
  598. for (var divId = 0; divId < divNames.length; divId++) {
  599. Q('#' + divNames[divId]).html('');
  600. }
  601.  
  602. if (!data.pipelines || data.pipelines.length === 0) {
  603. Q('#pipeline-message-' + pipelineid).html('No pipelines configured or found. Please review the <a href="configure">configuration</a>')
  604. }
  605.  
  606. jsplumb.reset();
  607. for (var c = 0; c < data.pipelines.length; c++) {
  608. html = [];
  609. component = data.pipelines[c];
  610.  
  611. html.push('<section class="pipeline-component">');
  612. addPipelineHeader(html, component, data, c, resURL);
  613. html.push(getPagination(showAvatars, component));
  614.  
  615. checkBuildAvailability(html, component);
  616.  
  617. for (var i = 0; i < component.pipelines.length; i++) {
  618. pipeline = component.pipelines[i];
  619.  
  620. if (pipeline.triggeredBy && pipeline.triggeredBy.length > 0) {
  621. triggered = '';
  622. for (var y = 0; y < pipeline.triggeredBy.length; y++) {
  623. trigger = pipeline.triggeredBy[y];
  624. triggered = triggered + ' <span class="' + trigger.type + '">' + htmlEncode(trigger.description) + '</span>';
  625. if (y < pipeline.triggeredBy.length - 1) {
  626. triggered = triggered + ', ';
  627. }
  628. }
  629. }
  630.  
  631. contributors = [];
  632. if (pipeline.contributors) {
  633. Q.each(pipeline.contributors, function (index, contributor) {
  634. contributors.push(htmlEncode(contributor.name));
  635. });
  636. }
  637.  
  638. if (contributors.length > 0) {
  639. triggered = triggered + ' changes by ' + contributors.join(', ');
  640. }
  641.  
  642. if (!pipeline.aggregated) {
  643. html.push('<h2>' + htmlEncode(pipeline.version));
  644. if (triggered !== '') {
  645. html.push(' triggered by ' + triggered);
  646. }
  647.  
  648. html.push(' started <span id="' + pipeline.id + '\">' + formatDate(pipeline.timestamp, lastUpdate) + '</span></h2>');
  649.  
  650. if (data.showTotalBuildTime) {
  651. html.push('<h3>Total build time: ' + formatDuration(pipeline.totalBuildTime) + '</h3>');
  652. }
  653.  
  654. if (showChanges && pipeline.changes && pipeline.changes.length > 0) {
  655. html.push(generateChangeLog(pipeline.changes));
  656. }
  657. } else {
  658. checkForAggregatedView(html, component);
  659. }
  660.  
  661. html.push('<section class="pipeline">');
  662.  
  663. var row = 0;
  664. var column = 0;
  665. var stage;
  666.  
  667. html.push('<div class="pipeline-row">');
  668.  
  669. for (var j = 0; j < pipeline.stages.length; j++) {
  670. stage = pipeline.stages[j];
  671. if (stage.row > row) {
  672. html.push('</div><div class="pipeline-row">');
  673. column = 0;
  674. row++;
  675. }
  676.  
  677. if (stage.column > column) {
  678. for (var as = column; as < stage.column; as++) {
  679. html.push('<div class="pipeline-cell"><div class="stage hide"></div></div>');
  680. column++;
  681. }
  682. }
  683.  
  684. html.push('<div class="pipeline-cell">');
  685. html.push('<div id="' + getStageId(stage.id + '', i) + '" class="stage ' + getStageClassName(stage.name) + '">');
  686.  
  687. buildStageHeader(html, stage, pipeline, false);
  688. buildAllStageTasks(stage, i, tasks, data, html, view, pipeline, component, lastUpdate);
  689.  
  690. if (pipeline.aggregated && stage.changes && stage.changes.length > 0) {
  691. html.push(generateAggregatedChangelog(stage.changes, aggregatedChangesGroupingPattern));
  692. }
  693.  
  694. html.push('</div></div>');
  695. column++;
  696. }
  697.  
  698. html.push('</div>');
  699. html.push('</section>');
  700.  
  701. }
  702. html.push(getPagination(showAvatars, component));
  703. html.push('</section>');
  704. Q('#' + divNames[c % divNames.length]).append(html.join(''));
  705. Q('#pipeline-message-' + pipelineid).html('');
  706. }
  707.  
  708. var source;
  709. var target;
  710. lastResponse = data;
  711. equalheight('.pipeline-row .stage');
  712.  
  713. Q.each(data.pipelines, function (dataPipelineIndex, component) {
  714. Q.each(component.pipelines, function (componentPipelineIndex, pipeline) {
  715. Q.each(pipeline.stages, function (pipelineStagesIndex, stage) {
  716. if (stage.downstreamStages) {
  717. Q.each(stage.downstreamStageIds, function (l, value) {
  718. source = getStageId(stage.id + '', componentPipelineIndex);
  719. target = getStageId(value + '', componentPipelineIndex);
  720.  
  721. jsplumb.connect({
  722. source: source,
  723. target: target,
  724. anchors: [[1, 0, 1, 0, 0, 37], [0, 0, -1, 0, 0, 37]], // allow boxes to increase in height but keep anchor lines on the top
  725. overlays: [
  726. [ 'Arrow', { location: 1, foldback: 0.9, width: 12, length: 12}]
  727. ],
  728. cssClass: 'relation',
  729. connector: ['Flowchart', { stub: 25, gap: 2, midpoint: 1, alwaysRespectStubs: true } ],
  730. paintStyle: { lineWidth: 2, strokeStyle: 'rgba(118,118,118,1)' },
  731. endpoint: ['Blank']
  732. });
  733. });
  734. }
  735. });
  736. });
  737. });
  738. } else {
  739. handleRepeatingPipelineRefresh(data, lastUpdate);
  740. }
  741.  
  742. jsplumb.repaintEverything();
  743. }
  744. }
  745.  
  746. function generateChangeLog(changes) {
  747. var html = [
  748. '<div class="changes">',
  749. '<h1>Changes:</h1>'
  750. ];
  751.  
  752. for (var i = 0; i < changes.length; i++) {
  753. html.push('<div class="change">');
  754. var change = changes[i];
  755.  
  756. if (change.changeLink) {
  757. html.push('<a href="' + change.changeLink + '">');
  758. }
  759.  
  760. html.push('<div class="change-commit-id">' + htmlEncode(change.commitId) + '</div>');
  761.  
  762. if (change.changeLink) {
  763. html.push('</a>');
  764. }
  765.  
  766. html.push('<div class="change-author">' + htmlEncode(change.author.name) + '</div>');
  767. html.push('<div class="change-message">' + change.message + '</div>');
  768. html.push('</div>');
  769. }
  770. html.push('</div>');
  771. return html.join('');
  772. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement