[% USE date; USE String; USE HTML; USE Math; USE mibs=format("%.2f"); # Formatted date time, in hydra-local timezone. # Use only where an HTML element cannot be used. BLOCK dateTimeText; date.format(timestamp, '%Y-%m-%d %H:%M:%S'); END; # HTML-rendered date. Formatted in hydra-local timezone. # It is enhanced with JavaScript to show user-local and UTC time zones. BLOCK renderDateTime %] <time [% HTML.attributes( "data-timestamp" => timestamp, title => date.format(timestamp, '%Y-%m-%d %H:%M:%S (%Z)'), datetime => date.format(timestamp, "%Y-%m-%dT%H:%M:%SZ", gmt => 1), ) %] class="date is-absolute"> [% INCLUDE dateTimeText %] </time> [% END; # Relative date, as text. # Use only where an HTML element cannot be used. BLOCK relativeDateText; ago = date.now - timestamp; IF ago >= 0 && ago < 60; THEN; ago _ 's ago'; ELSIF ago >= 0 && ago < 60 * 60; THEN; Math.int(ago / 60) _ 'm ago'; ELSIF ago >= 0 && ago < 24 * 60 * 60; THEN; Math.int(ago / (60 * 60)) _ 'h ago'; ELSIF ago >= 0 && ago < 7 * 24 * 60 * 60; THEN; Math.int(ago / (24 * 60 * 60)) _ 'd ago'; ELSE; date.format(timestamp, '%Y-%m-%d'); END; END; # HTML-rendered relative date. # It is enhanced with JavaScript to show user-local and UTC time zones. BLOCK renderRelativeDate %] <time [% HTML.attributes( "data-timestamp" => timestamp, title => date.format(timestamp, '%Y-%m-%d %H:%M:%S (%Z)'), datetime => date.format(timestamp, "%Y-%m-%dT%H:%M:%SZ", gmt => 1), ) %] class="date is-relative"> [% INCLUDE relativeDateText %] </time> [% END; BLOCK renderProjectName %] <a [% IF inRow %]class="row-link"[% END %] href="[% c.uri_for('/project' project) %]"><tt>[% project %]</tt></a> [% END; BLOCK renderJobsetName %] <a [% IF inRow %]class="row-link"[% END %] href="[% c.uri_for('/jobset' project jobset) %]"><tt>[% jobset %]</tt></a> [% END; BLOCK renderJobName %] <a [% IF inRow %]class="row-link"[% END %] href="[% c.uri_for('/job' project jobset job) %]">[% job %]</a> [% END; BLOCK renderFullJobsetName %] <tt>[% INCLUDE renderProjectName inRow=0 %]:[% INCLUDE renderJobsetName %]</tt> [% END; BLOCK renderFullJobName %] <tt>[% IF !hideProjectName; INCLUDE renderProjectName inRow=0 %]:[% END; IF !hideJobsetName; INCLUDE renderJobsetName inRow=0 %]:[% END; INCLUDE renderJobName %]</tt> [% END; BLOCK renderFullJobNameOfBuild; INCLUDE renderFullJobName project=build.get_column("project") jobset = build.get_column("jobset") job = build.get_column("job"); END; BLOCK renderDuration; IF duration >= 24 * 60 * 60; duration div (24 * 60 * 60) %]d [% END; IF duration >= 60 * 60; duration div (60 * 60) % 24 %]h [% END; IF duration >= 60; duration div 60 % 60 %]m [% END; duration % 60 %]s[% END; BLOCK renderBuildListHeader %] <table class="table table-striped table-condensed clickable-rows"> <thead> <tr> [% IF !hideResultInfo %] <th></th> [% END %] [% IF showSchedulingInfo %] <th></th> [% END %] <th>#</th> [% IF !hideJobName %] <th>Job</th> [% END %] <th>[% IF showSchedulingInfo %]Queued at[% ELSE %]Finished at[% END %]</th> <th>Package/release name</th> <th>System</th> [% IF showDescription %] <th>Description</th> [% END %] </tr> </thead> <tbody> [% END; BLOCK renderBuildListBody; FOREACH build IN builds; link = c.uri_for('/build' build.id) %] <tr> [% IF !hideResultInfo %] <td> [% INCLUDE renderBuildStatusIcon size=16 buildstatus=build.buildstatus %] </td> [% END %] [% IF showSchedulingInfo %] <td>[% IF busy %]<span class="badge badge-success">Started</span>[% ELSE %]<span class="badge badge-secondary">Queued</span>[% END %]</td> [% END %] <td><a class="row-link" href="[% link %]">[% build.id %]</a></td> [% IF !hideJobName %] <td><a href="[%link%]">[% IF !hideJobsetName %][%build.get_column("project")%]:[%build.get_column("jobset")%]:[% END %][%build.get_column("job")%]</td> [% END %] <td class="nowrap">[% t = showSchedulingInfo ? build.timestamp : build.stoptime; IF t; INCLUDE renderRelativeDate timestamp=(showSchedulingInfo ? build.timestamp : build.stoptime); ELSE; "-"; END %]</td> <td>[% !showSchedulingInfo and build.get_column('releasename') ? build.get_column('releasename') : build.nixname %]</td> <td class="nowrap"><tt>[% build.system %]</tt></td> [% IF showDescription %] <td>[% build.description %]</td> [% END %] </tr> [% END; IF linkToAll %] <tr><td class="centered" colspan="5"><a href="[% linkToAll %]"><em>More...</em></a></td></tr> [% END; END; BLOCK renderBuildListFooter %] </tbody> </table> [% END; BLOCK renderBuildList; INCLUDE renderBuildListHeader; INCLUDE renderBuildListBody; INCLUDE renderBuildListFooter; END; BLOCK renderLink %]<a href="[% uri %]">[% title %]</a>[% END; BLOCK maybeLink; IF uri %]<a [% HTML.attributes(href => uri, class => class); IF confirmmsg +%] onclick="javascript:return confirm('[% confirmmsg %]')"[% END %]>[% content %]</a>[% ELSE; content; END; END; BLOCK renderSelection; IF edit; IF radiobuttons; %] <div class="controls"> [% FOREACH name IN options.keys.sort %] <label class="radio inline"> <input type="radio" [% HTML.attributes(id => param, name => param, value => name) %] [% IF name == curValue; "checked='1'"; END %]> [% options.$name %] </input> </label> [% END %] </div> [% ELSE %] <select class="custom-select" [% HTML.attributes(id => param, name => param) %]> [% FOREACH name IN options.keys.sort %] <option [% IF name == curValue; "selected='selected'"; END; " "; HTML.attributes(value => name) %]>[% options.$name %]</option> [% END %] </select> [% END; ELSE; options.$curValue; END; END; BLOCK editString; %] <input type="text" class="string" [% HTML.attributes(id => param, name => param, value => value) %] /> [% END; BLOCK renderFullBuildLink; INCLUDE renderFullJobNameOfBuild build=build %] <a href="[% c.uri_for('/build' build.id) %]">build [% build.id %]</a>[% END; BLOCK renderBuildIdLink; %] <a href="[% c.uri_for('/build' id) %]">build [% id %]</a> [% END; BLOCK renderBuildLink; INCLUDE renderBuildIdLink id=build.id; END; BLOCK renderBuildStatusIcon; finished = build != undef ? build.finished : 1; buildstatus = buildstatus != undef ? buildstatus : build.buildstatus; IF finished; IF buildstatus == 0 %] <img src="[% c.uri_for("/static/images/emojione-check-2714.svg") %]" height="[% size %]" width="[% size %]" title="Succeeded" alt="Succeeded" class="build-status" /> [% ELSIF buildstatus == 1 %] <img src="[% c.uri_for("/static/images/emojione-red-x-274c.svg") %]" height="[% size %]" width="[% size %]" title="Failed" alt="Failed" class="build-status" /> [% ELSIF buildstatus == 2 %] <img src="[% c.uri_for("/static/images/emojione-gray-x-2716.svg") %]" height="[% size %]" width="[% size %]" title="Dependency failed" alt="Dependency failed" class="build-status" /> [% ELSIF buildstatus == 3 || buildstatus == 9 %] <img src="[% c.uri_for("/static/images/emojione-stopsign-1f6d1.svg") %]" height="[% size %]" width="[% size %]" title="Aborted" alt="Aborted" class="build-status" /> [% ELSIF buildstatus == 4 %] <img src="[% c.uri_for("/static/images/emojione-stopsign-1f6d1.svg") %]" height="[% size %]" width="[% size %]" title="Cancelled" alt="Cancelled" class="build-status" /> [% ELSIF buildstatus == 6 %] <img src="[% c.uri_for("/static/images/emojione-red-x-274c.svg") %]" height="[% size %]" width="[% size %]" title="Failed with output" alt="Failed with output" class="build-status" /> [% ELSIF buildstatus == 7 %] <img src="[% c.uri_for("/static/images/emojione-stopsign-1f6d1.svg") %]" height="[% size %]" width="[% size %]" title="Timed out" alt="Timed out" class="build-status" /> [% ELSIF buildstatus == 10 %] <img src="[% c.uri_for("/static/images/emojione-stopsign-1f6d1.svg") %]" height="[% size %]" width="[% size %]" title="Log limit exceeded" alt="Log limit exceeded" class="build-status" /> [% ELSIF buildstatus == 11 %] <img src="[% c.uri_for("/static/images/emojione-red-x-274c.svg") %]" height="[% size %]" width="[% size %]" title="Output size limit exceeded" alt="Output size limit exceeded" class="build-status" /> [% ELSIF buildstatus == 12 %] <img src="[% c.uri_for("/static/images/emojione-red-x-274c.svg") %]" height="[% size %]" width="[% size %]" title="Non-deterministic build" alt="Non-deterministic build" class="build-status" /> [% ELSE %] <img src="[% c.uri_for("/static/images/emojione-red-x-274c.svg") %]" height="[% size %]" width="[% size %]" title="Failed" alt="Failed" class="build-status" /> [% END; ELSE %] <img src="[% c.uri_for("/static/images/emojione-question-2754.svg") %]" height="[% size %]" width="[% size %]" title="Queued" alt="Queued" class="build-status" /> [% END; END; BLOCK renderStatus; IF build.finished; buildstatus = build.buildstatus; IF icon; INCLUDE renderBuildStatusIcon size=16; END; IF buildstatus == 0 %] <strong>Success</strong> [% ELSIF buildstatus == 1 %] <span class="error">Build returned a non-zero exit code</span> [% ELSIF buildstatus == 2 %] <span class="error">A dependency of the build failed</span> [% ELSIF buildstatus == 4 %] <span class="error">Cancelled by user</span> [% ELSIF buildstatus == 6 %] <span class="error">Build failed with output</span> [% ELSIF buildstatus == 7 %] <span class="error">Timed out</span> [% ELSIF buildstatus == 9 %] <span class="error">Unsupported system type</span> [% ELSIF buildstatus == 10 %] <span class="error">Log limit exceeded</span> [% ELSIF buildstatus == 11 %] <span class="error">Output limit exceeded</span> [% ELSIF buildstatus == 12 %] <span class="error">Non-deterministic build</span> [% ELSE %] <span class="error">Aborted</span> (Hydra failure; see <a href="#nix-error">below</a>) [% END; ELSIF busy %] <strong>Build in progress</strong>[%- ELSE %] <strong>Scheduled to be built</strong> [% END; END; BLOCK renderShortInputValue; IF input.type == "build" || input.type == "sysbuild" %] <a href="[% c.uri_for('/build' input.dependency.id) %]">[% input.dependency.id %]</a> [% ELSIF input.type == "string" %] <tt>"[% HTML.escape(input.value) %]"</tt> [% ELSIF input.type == "nix" || input.type == "boolean" %] <tt>[% HTML.escape(input.value) %]</tt> [% ELSE %] <tt>[% HTML.escape(input.uri) %][% IF input.revision %] (r[% HTML.escape(input.revision) %])[% END %]</tt> [% END %] [% END; BLOCK renderDiffUri; nouri = 1; FOREACH m IN mappers; base = m.baseuri; url = bi1.uri; path = url.replace(base, ''); IF url.match(base) %] <a target="_blank" href="[% m.uri.replace('_path_', path).replace('_1_', bi1.revision).replace('_2_', bi2.revision) %]">[% contents %]</a> [% nouri = 0; END; END; IF nouri; res = bi1.uri.split(' '); url = res.0; branch = res.1; IF bi1.type == "hg" || bi1.type == "git" %] <a target="_blank" href="[% HTML.escape(c.uri_for('/api/scmdiff', { uri = url, rev1 = bi1.revision, rev2 = bi2.revision, type = bi1.type, branch = branch })) %]">[% contents %]</a> [% ELSE; contents; END; END; END; BLOCK renderInputs; %] <table class="table table-striped table-condensed"> <thead> <tr><th>Name</th><th>Type</th><th>Value</th><th>Revision</th><th>Store path</th></tr> </thead> <tbody> [% FOREACH input IN inputs %] <tr> <td><tt>[% input.name %]</tt></td> <td>[% type = input.type; inputTypes.$type %]</td> <td> [% IF input.type == "build" || input.type == "sysbuild" %] [% INCLUDE renderFullBuildLink build=input.dependency %] [% ELSIF input.type == "string" %] <tt>"[% HTML.escape(input.value) %]"</tt> [% ELSIF input.type == "nix" || input.type == "boolean" %] <tt>[% HTML.escape(input.value) %]</tt> [% ELSE %] <tt>[% HTML.escape(input.uri) %]</tt> [% END %] </td> <td>[% IF input.revision %][% HTML.escape(input.revision) %][% END %]</td> <td><tt>[% input.path %]</tt></td> </tr> [% END %] </tbody> </table> [% END; BLOCK renderInputDiff; %] <table class="table table-striped table-condensed"> [% IF !nestedDiff %] <tr><th>Input</th><th>Changes</th></tr> [% END; IF !nestLevel; nestLevel = 0; END; IF nestLevel <= 3; FOREACH bi1 IN inputs1; deletedInput = 1; FOREACH bi2 IN inputs2; IF bi1.name == bi2.name; IF bi1.type == bi2.type; IF bi1.value != bi2.value || bi1.uri != bi2.uri %] <tr><td><b>[% bi1.name %]</b></td><td><tt>[% INCLUDE renderShortInputValue input=bi1 %]</tt> to <tt>[% INCLUDE renderShortInputValue input=bi2 %]</tt></td></tr> [% ELSIF bi1.uri == bi2.uri && bi1.revision != bi2.revision %] [% IF bi1.type == "git" %] <tr><td> <b>[% bi1.name %]</b></td><td><tt>[% INCLUDE renderDiffUri contents=(bi1.revision.substr(0, 6) _ ' to ' _ bi2.revision.substr(0, 6)) %]</tt> </td></tr> [% ELSE %] <tr><td> <b>[% bi1.name %]</b></td><td><tt>[% INCLUDE renderDiffUri contents=(bi1.revision _ ' to ' _ bi2.revision) %]</tt> </td></tr> [% END %] [% ELSIF bi1.dependency.id != bi2.dependency.id || bi1.path != bi2.path %] <tr><td> <b>[% bi1.name %]</b></td><td><tt>[% INCLUDE renderShortInputValue input=bi1 %]</tt> to <tt>[% INCLUDE renderShortInputValue input=bi2 %]</tt> <br/> <br/> [% INCLUDE renderInputDiff inputs1=bi1.dependency.inputs inputs2=bi2.dependency.inputs nestedDiff=1 nestLevel=nestLevel+1 %] </td></tr> [% END %] [% ELSE %] <tr><td><b>[% bi1.name %]</b></td><td>Changed input type from '[% type = bi1.type; inputTypes.$type %]' to '[% type = bi2.type; inputTypes.$type %]'</td></tr> [% END; deletedInput = 0; END; END; IF deletedInput == 1 %] <tr><td><b>[% bi1.name %]</b></td><td>Input not present in this build.</td></tr> [% END; END; END %] </table> [% END; BLOCK renderPager %] <ul class="pagination"> <li class="page-item[% IF page == 1 %] disabled[% END %]"><a class="page-link" href="[% "$baseUri?page=1" %]">« First</a></li> <li class="page-item[% IF page == 1 %] disabled[% END %]"><a class="page-link" href="[% "$baseUri?page="; (page - 1) %]">‹ Previous</a></li> <li class="page-item[% IF page * resultsPerPage >= total %] disabled[% END %]"><a class="page-link" href="[% "$baseUri?page="; (page + 1) %]">Next ›</a></li> <li class="page-item[% IF page * resultsPerPage >= total %] disabled[% END %]"><a class="page-link" href="[% "$baseUri?page="; (total - 1) div resultsPerPage + 1 %]">Last »</a></li> </ul> [% END; BLOCK renderShortEvalInput; IF input.type == "svn" || input.type == "svn-checkout" || input.type == "bzr" || input.type == "bzr-checkout" %] r[% input.revision %] [% ELSIF input.type == "git" %] <tt>[% input.revision.substr(0, 7) %]</tt> [% ELSIF input.type == "hg" %] <tt>[% input.revision.substr(0, 12) %]</tt> [% ELSIF input.type == "build" || input.type == "sysbuild" %] <a href="[% c.uri_for('/build' input.get_column('dependency')) %]">[% input.get_column('dependency') %]</a> [% ELSE %] <tt>[% input.revision %]</tt> [% END; END; BLOCK renderEvals %] <table class="table table-condensed table-striped clickable-rows"> <thead> <tr> <th rowspan="2">#</th> [% IF !jobset && !build %] <th rowspan="2">Jobset</th> [% END %] <th rowspan="2" style="width: 10em">Date</th> <th rowspan="2">Input changes</th> <th colspan="4">Jobs</th> </tr> <tr> <th style="width: 2em"> <img src="[% c.uri_for("/static/images/emojione-check-2714.svg") %]" height="12" width="12" title="Succeeded" alt="Succeeded" class="build-status" /> </th> <th style="width: 2em"> <img src="[% c.uri_for("/static/images/emojione-red-x-274c.svg") %]" height="12" width="12" title="Failed" alt="Failed" class="build-status" /> </th> <th style="width: 2em"> <img src="[% c.uri_for("/static/images/emojione-question-2754.svg") %]" height="12" width="12" title="Queued" alt="Queued" class="build-status" /> </th> <th style="width: 2em"> <img src="[% c.uri_for("/static/images/delta.svg") %]" height="12" width="12" title="Delta" alt="Delta" class="build-status" /> </th> </tr> </thead> <tbody> [% FOREACH e IN evals; eval = e.eval; link = c.uri_for(c.controller('JobsetEval').action_for('view'), [eval.id]) %] <tr> <td><a class="row-link" href="[% link %]">[% eval.id %]</a></td> [% IF !jobset && !build %] <td>[% INCLUDE renderFullJobsetName project=eval.jobset.project.name jobset=eval.jobset.name %]</td> [% END %] <td class="nowrap">[% INCLUDE renderRelativeDate timestamp = eval.timestamp %]</td> <td> [% IF e.changedInputs.size > 0; sep=''; FOREACH input IN e.changedInputs; sep; %] [% input.name %] → [% INCLUDE renderShortEvalInput input=input; sep=', '; END; ELSE %] - [% END %] [% IF eval.evaluationerror.errormsg %] <span class="badge badge-warning">Eval Errors</span> [% END %] </td> <td align='right' class="nowrap"> <span class="badge badge-success">[% e.nrSucceeded %]</span> </td> <td align="right" class="nowrap"> [% IF e.nrFailed > 0 %] <span class="badge badge-danger">[% e.nrFailed %]</span> [% END %] </td> <td align="right" class="nowrap"> [% IF e.nrScheduled > 0 %] <span class="badge badge-secondary">[% e.nrScheduled %]</span> [% END %] </td> <td align='right' class="nowrap"> [% IF e.diff > 0 %] <span class='badge badge-success'><strong>+[% e.diff %]</strong></span> [% ELSIF e.diff < 0 && e.nrScheduled == 0 %] <span class='badge badge-danger'><strong>[% e.diff %]</strong></span> [% END %] </td> </tr> [% END; IF linkToAll %] <tr><td class="centered" colspan="7"><a href="[% linkToAll %]"><em>More...</em></a></td></tr> [% END %] </tbody> </table> [% END; BLOCK renderLogLinks %] (<a [% IF inRow %]class="row-link"[% END %] href="[% url %]">log</a>, <a href="[% "$url/raw" %]">raw</a>, <a href="[% "$url/tail" %]">tail</a>) [% END; BLOCK makeLazyTab %] <div id="[% tabName %]" class="tab-pane"> <center><span class="spinner-border spinner-border-sm"/></center> </div> <script> $(function() { makeLazyTab("[% tabName %]", "[% uri %]"); }); </script> [% END; BLOCK makePopover %] <button type="button" class="btn hydra-popover [% classes %]" data-toggle="popover" data-html="true" [% HTML.attributes('data-content' => content, 'data-placement' => placement || 'bottom') %]> [% title %] </button> [% END; BLOCK menuItem %] <a class="dropdown-item[% IF "${root}${curUri}" == uri %] active[% END %]" [% HTML.attributes(href => uri) %] [%+ IF modal %]data-toggle="modal"[% END %] [% IF confirmmsg %]onclick="javascript:return confirm('[% confirmmsg %]')"[% END %]> [% IF icon %]<i class="[% icon %] icon-black"></i> [%+ END %] [% title %] </a> [% END; BLOCK navItem %] <li class="nav-item"> <a class="nav-link[% IF "${root}${curUri}" == uri %] active[% END %]" [% HTML.attributes(href => uri) %]> [% title %] </a> </li> [% END; BLOCK makeStar %] <span class="star" data-post="[% starUri %]">[% IF starred; "★"; ELSE; "☆"; END %]</span> [% END; BLOCK renderJobsetOverview %] <table class="table table-striped table-condensed clickable-rows"> <thead> <tr> <th></th> <th>Name</th> <th>Description</th> <th>Last evaluated</th> <th style="width: 2em"> Jobs </th> <th style="width: 2em"> <img src="[% c.uri_for("/static/images/emojione-check-2714.svg") %]" height="12" width="12" title="Succeeded" alt="Succeeded" class="build-status" /> </th> <th style="width: 2em"> <img src="[% c.uri_for("/static/images/emojione-red-x-274c.svg") %]" height="12" width="12" title="Failed" alt="Failed" class="build-status" /> </th> <th style="width: 2em"> <img src="[% c.uri_for("/static/images/emojione-question-2754.svg") %]" height="12" width="12" title="Queued" alt="Queued" class="build-status" /> </th> </tr> </thead> <tbody> [% FOREACH j IN jobsets %] [% successrate = 0 %] <tr class="jobset [% IF j.hidden && !showHidden %] hidden-jobset [% END %] [% IF !j.enabled %] disabled-jobset [% END %]" > <td> [% IF j.get_column('nrscheduled') > 0 %] <img src="[% c.uri_for("/static/images/emojione-question-2754.svg") %]" height="16" width="16" title="Scheduled" alt="Scheduled" /> [% ELSIF j.get_column('nrfailed') == 0 %] <img src="[% c.uri_for("/static/images/emojione-check-2714.svg") %]" height="16" width="16" title="Succeeded" alt="Succeeded" /> [% ELSIF j.get_column('nrfailed') > 0 && j.get_column('nrsucceeded') > 0 %] <img src="[% c.uri_for("/static/images/emojione-red-x-274c.svg") %]" height="16" width="16" title="Some Failed" alt="Some Failed" /> [% ELSE %] <img src="[% c.uri_for("/static/images/emojione-red-x-274c.svg") %]" height="16" width="16" title="All Failed" alt="All Failed" /> [% END %] </td> <td><span class="[% IF !j.enabled %]disabled-jobset[% END %] [%+ IF j.hidden %]hidden-jobset[% END %]">[% IF showProject; INCLUDE renderFullJobsetName project=j.get_column('project') jobset=j.name inRow=1; ELSE; INCLUDE renderJobsetName project=j.get_column('project') jobset=j.name inRow=1; END %]</span></td> <td>[% HTML.escape(j.description) %]</td> <td>[% IF j.lastcheckedtime; INCLUDE renderDateTime timestamp = j.lastcheckedtime; IF j.errormsg || j.fetcherrormsg; %] <span class = 'badge badge-warning'>Error</span>[% END; ELSE; "-"; END %]</td> [% IF j.get_column('nrtotal') > 0 %] [% successrate = ( j.get_column('nrsucceeded') / j.get_column('nrtotal') )*100 %] [% IF j.get_column('nrscheduled') > 0 %] [% class = 'badge badge-secondary' %] [% ELSIF successrate < 25 %] [% class = 'badge badge-danger' %] [% ELSIF successrate < 75 %] [% class = 'badge badge-warning' %] [% ELSIF successrate <= 100 %] [% class = 'badge badge-success' %] [% END %] [% END %] <td><span class="[% class %]">[% successrate FILTER format('%d') %]%</span></td> <td> [% IF j.get_column('nrsucceeded') > 0 %] <span class="badge badge-success">[% j.get_column('nrsucceeded') %]</span> [% END %] </td> <td> [% IF j.get_column('nrfailed') > 0 %] <span class="badge badge-danger">[% j.get_column('nrfailed') %]</span> [% END %] </td> <td> [% IF j.get_column('nrscheduled') > 0 %] <span class="badge badge-secondary">[% j.get_column('nrscheduled') %]</span> [% END %] </td> </tr> [% END %] </tbody> </table> [% END; BLOCK includeFlot %] <script src="[% c.uri_for("/static/js/flot/jquery.flot.min.js") %]" type="text/javascript"></script> <script src="[% c.uri_for("/static/js/flot/jquery.flot.time.min.js") %]" type="text/javascript"></script> <script src="[% c.uri_for("/static/js/flot/jquery.flot.selection.min.js") %]" type="text/javascript"></script> <div id="flot-tooltip" class="flot-tooltip"></div> [% END; BLOCK createChart %] <div id="[%id%]-chart" style="width: 1000px; height: 400px;"></div> <div id="[%id%]-overview" style="margin-top: 20px; margin-left: 50px; margin-right: 50px; width: 900px; height: 100px"></div> <script type="text/javascript"> $(function() { showChart("[%id%]", "[%dataUrl%]", "[%yaxis%]"); }); </script> [% END; BLOCK renderMachineName; machine ? stripSSHUser(machine).match('^(([^\.]|\.[0-9])*)').0 : "localhost"; END; %]