[% WRAPPER layout.tt titleHTML=makeNameLinksForJobset(jobset) title=makeNameTextForJobset(jobset) %] [% PROCESS common.tt %] [% USE format %] [% BLOCK renderJobsetInput %] <tr class="input [% extraClass %]" [% IF id %]id="[% id %]"[% END %]> <td> <tt>[% HTML.escape(input.name) %]</tt> </td> <td> [% INCLUDE renderSelection curValue=input.type param="$baseName-type" options=inputTypes %] </td> <td class="inputalts" id="[% baseName %]"> [% FOREACH alt IN input.search_related('jobsetinputalts', {}, { order_by => 'altnr' }) %] <tt class="inputalt"> [% IF input.type == "string" %] "<span class="keep-whitespace">[% HTML.escape(alt.value) %]</span>" [% ELSE %] [% HTML.escape(alt.value) %] [% END %] </tt> [% END %] </td> </tr> [% END %] [% BLOCK renderJobsetInputs %] <h3>Inputs</h3> <table class="table table-striped table-condensed"> <thead> <tr><th>Input name</th><th>Type</th><th>Values</th></tr> </thead> <tbody class="inputs"> [% FOREACH input IN jobset.jobsetinputs %] [% INCLUDE renderJobsetInput input=input baseName="input-$input.name" %] [% END %] </tbody> </table> [% END %] <ul class="nav nav-tabs"> [% IF c.user_exists %] <li class="nav-item dropdown"> <a class="nav-link dropdown-toggle" data-toggle="dropdown" href="#">Actions</a> <div class="dropdown-menu"> [% UNLESS project.declfile %] [% INCLUDE menuItem title="Edit configuration" icon="icon-edit" uri=c.uri_for(c.controller('Jobset').action_for('edit'), c.req.captures) %] <!-- [% INCLUDE menuItem title="Delete this jobset" icon="icon-trash" uri="javascript:deleteJobset()" %] --> [% INCLUDE menuItem title="Clone this jobset" uri=c.uri_for(c.controller('Jobset').action_for('edit'), c.req.captures, { cloneJobset => 1 }) %] [% END %] [% INCLUDE menuItem title="Evaluate this jobset" uri="javascript:confirmEvaluateJobset()" %] </div> </li> [% END %] <li class="nav-item"><a class="nav-link active" href="#tabs-evaluations" data-toggle="tab">Evaluations</a></li> [% IF jobset.errormsg || jobset.fetcherrormsg %] <li class="nav-item"><a class="nav-link" href="#tabs-errors" data-toggle="tab"><span class="text-warning">Evaluation Errors</span></a></li> [% END %] <li class="nav-item"><a class="nav-link" href="#tabs-jobs" data-toggle="tab">Jobs</a></li> <li class="nav-item"><a class="nav-link" href="#tabs-configuration" data-toggle="tab">Configuration</a></li> <li class="nav-item"><a class="nav-link" href="#tabs-links" data-toggle="tab">Links</a></li> <li class="nav-item"><a class="nav-link" href="#tabs-channels" data-toggle="tab">Channels</a></li> </ul> <div id="generic-tabs" class="tab-content"> <div id="tabs-evaluations" class="tab-pane active"> <table class="info-table"> <tr> <th>Last checked:</th> <td> [% IF jobset.lastcheckedtime %] [% INCLUDE renderDateTime timestamp = jobset.lastcheckedtime %], [% IF jobset.errormsg || jobset.fetcherrormsg %]<em class="text-warning">with errors!</em>[% ELSE %]<em>no errors</em>[% END %] [% ELSE %] <em>never</em> [% END %] </td> </tr> <tr> <th>Last evaluation:</th> <td> [% IF latestEval %] [% INCLUDE renderDateTime timestamp = latestEval.timestamp %] (took [% relativeDuration (latestEval.checkouttime + latestEval.evaltime) %]) [% ELSE %] <em>never</em> [% END %] </td> </tr> [% IF jobset.starttime %] <tr> <th>Evaluation running since:</th> <td>[% INCLUDE renderRelativeDate timestamp = jobset.starttime %]</td> </tr> [% ELSIF jobset.triggertime %] <tr> <th>Evaluation pending since:</th> <td>[% INCLUDE renderRelativeDate timestamp = jobset.triggertime %]</td> </tr> [% END %] </table> <br/> [% IF evals.size() > 0 %] [% INCLUDE renderEvals linkToAll=c.uri_for(c.controller('Jobset').action_for('evals'), [project.name, jobset.name]) %] [% END %] </div> [% IF jobset.errormsg || jobset.fetcherrormsg %] <div id="tabs-errors" class="tab-pane"> <p>Errors occurred at [% INCLUDE renderDateTime timestamp=(jobset.errortime || jobset.lastcheckedtime) %].</p> <div class="card bg-light"><div class="card-body"><pre>[% HTML.escape(jobset.fetcherrormsg || jobset.errormsg) %]</pre></div></div> </div> [% END %] <div id="tabs-configuration" class="tab-pane"> <table class="info-table"> <tr> <th>State:</th> <td>[% IF jobset.enabled == 0; "Disabled"; ELSIF jobset.enabled == 1; "Enabled"; ELSIF jobset.enabled == 2; "One-shot"; ELSIF jobset.enabled == 3; "One-at-a-time"; END %]</td> </tr> <tr> <th>Description:</th> <td>[% HTML.escape(jobset.description) %]</td> </tr> [% IF jobset.type == 1 %] <tr> <th>Flake URI:</th> <td> <tt>[% HTML.escape(jobset.flake) %]</tt> </td> </tr> [% END %] [% IF jobset.type == 0 %] <tr> <th>Nix expression:</th> <td> <tt>[% HTML.escape(jobset.nixexprpath) %]</tt> in input <tt>[% HTML.escape(jobset.nixexprinput) %]</tt> </td> </tr> [% END %] <tr> <th>Check interval:</th> <td>[% jobset.checkinterval || "<em>disabled</em>" %]</td> </tr> <tr> <th>Scheduling shares:</th> <td>[% jobset.schedulingshares %] [% IF totalShares %] ([% f = format("%.2f"); f(jobset.schedulingshares / totalShares * 100) %]% out of [% totalShares %] shares)[% END %]</td> </tr> [% IF emailNotification %] <tr> <th>Enable email notification:</th> <td>[% jobset.enableemail ? "Yes" : "No" %]</td> </tr> <tr> <th>Email override:</th> <td>[% HTML.escape(jobset.emailoverride) %]</td> </tr> [% END %] <tr> <th>Number of evaluations to keep:</th> <td>[% jobset.keepnr %]</td> </tr> </table> [% IF jobset.type == 0 %] [% INCLUDE renderJobsetInputs %] [% END %] </div> [% INCLUDE makeLazyTab tabName="tabs-jobs" uri=c.uri_for('/jobset' project.name jobset.name "jobs-tab") %] <div id="tabs-links" class="tab-pane"> <ul> <li><a href="[% c.uri_for(c.controller('Jobset').action_for('latest_eval'), c.req.captures) %]">Latest finished evaluation</a></li> </ul> </div> [% INCLUDE makeLazyTab tabName="tabs-channels" uri=c.uri_for('/jobset' project.name jobset.name "channels-tab") %] </div> <script> function confirmEvaluateJobset() { bootbox.confirm( 'Are you sure you want to force evaluation of this jobset?', function(c) { if (!c) return; requestJSON({ url: "[% HTML.escape(c.uri_for('/api/push', { jobsets = project.name _ ':' _ jobset.name, force = "1" })) %]", success: function(data) { bootbox.alert("The jobset has been scheduled for evaluation."); } }); }); }; function deleteJobset() { bootbox.confirm( 'Are you sure you want to delete this jobset?', function(c) { if (!c) return; redirectJSON({ url: "[% c.uri_for(c.controller('Jobset').action_for('jobset'), c.req.captures) %]", type: 'DELETE' }); }); }; </script> [% END %]