Merge pull request #677 from twhitehead/javascripts-update

Javascript libraries update
This commit is contained in:
Graham Christensen 2021-04-09 14:05:47 +00:00 committed by GitHub
commit 258b39f1e5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
36 changed files with 598 additions and 611 deletions

1
.gitignore vendored
View file

@ -40,3 +40,4 @@ config
stamp-h1 stamp-h1
src/hydra-evaluator/hydra-evaluator src/hydra-evaluator/hydra-evaluator
src/hydra-queue-runner/hydra-queue-runner src/hydra-queue-runner/hydra-queue-runner
src/root/static/fontawesome/

View file

@ -3,14 +3,16 @@ STATIC = \
$(wildcard static/images/*) \ $(wildcard static/images/*) \
$(wildcard static/css/*) \ $(wildcard static/css/*) \
static/js/bootbox.min.js \ static/js/bootbox.min.js \
static/js/popper.min.js \
static/js/common.js \ static/js/common.js \
static/js/jquery/jquery-1.12.3.min.js \ static/js/jquery/jquery-3.4.1.min.js \
static/js/jquery/jquery-ui-1.10.4.min.js static/js/jquery/jquery-ui-1.10.4.min.js
FLOT = flot-0.8.3.zip FLOT = flot-0.8.3.zip
BOOTSTRAP = bootstrap-2.3.1.zip BOOTSTRAP = bootstrap-4.3.1-dist.zip
FONTAWESOME = fontawesome-free-5.10.2-web.zip
ZIPS = $(FLOT) $(BOOTSTRAP) ZIPS = $(FLOT) $(BOOTSTRAP) $(FONTAWESOME)
EXTRA_DIST = $(TEMPLATES) $(STATIC) $(ZIPS) EXTRA_DIST = $(TEMPLATES) $(STATIC) $(ZIPS)
@ -20,10 +22,16 @@ nobase_hydra_DATA = $(EXTRA_DIST)
all: all:
mkdir -p $(srcdir)/static/js mkdir -p $(srcdir)/static/js
unzip -u -d $(srcdir)/static $(BOOTSTRAP) unzip -u -d $(srcdir)/static $(BOOTSTRAP)
mv $(srcdir)/static/$(basename $(BOOTSTRAP)) $(srcdir)/static/bootstrap
unzip -u -d $(srcdir)/static/js $(FLOT) unzip -u -d $(srcdir)/static/js $(FLOT)
unzip -u -d $(srcdir)/static $(FONTAWESOME)
mv $(srcdir)/static/$(basename $(FONTAWESOME)) $(srcdir)/static/fontawesome
install-data-local: $(ZIPS) install-data-local: $(ZIPS)
mkdir -p $(hydradir)/static/js mkdir -p $(hydradir)/static/js
cp -prvd $(srcdir)/static/js/* $(hydradir)/static/js cp -prvd $(srcdir)/static/js/* $(hydradir)/static/js
mkdir -p $(hydradir)/static/bootstrap mkdir -p $(hydradir)/static/bootstrap
cp -prvd $(srcdir)/static/bootstrap/* $(hydradir)/static/bootstrap cp -prvd $(srcdir)/static/bootstrap/* $(hydradir)/static/bootstrap
mkdir -p $(hydradir)/static/fontawesome/{css,webfonts}
cp -prvd $(srcdir)/static/fontawesome/css/* $(hydradir)/static/fontawesome/css
cp -prvd $(srcdir)/static/fontawesome/webfonts/* $(hydradir)/static/fontawesome/webfonts

View file

@ -31,27 +31,27 @@
[% ELSE %] [% ELSE %]
<div id="hydra-signin" class="modal hide fade" tabindex="-1" role="dialog" aria-hidden="true"> <div id="hydra-signin" class="modal hide fade" tabindex="-1" role="dialog" aria-hidden="true">
<form class="form-horizontal"> <div class="modal-dialog" role="document">
<div class="modal-content">
<form>
<div class="modal-body"> <div class="modal-body">
<div class="control-group"> <div class="form-group">
<label class="control-label">User name</label> <label for="username" class="col-form-label">User name</label>
<div class="controls"> <input type="text" class="form-control" name="username"/>
<input type="text" class="span3" name="username" value=""/>
</div>
</div>
<div class="control-group">
<label class="control-label">Password</label>
<div class="controls">
<input type="password" class="span3" name="password" value=""/>
</div> </div>
<div class="form-group">
<label for="password" class="col-form-label">Password</label>
<input type="password" class="form-control" name="password"/>
</div> </div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button id="do-signin" class="btn btn-primary">Sign in</button> <button id="do-signin" type="button" class="btn btn-primary">Sign in</button>
<button class="btn" data-dismiss="modal" aria-hidden="true">Cancel</button> <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
</div> </div>
</form> </form>
</div> </div>
</div>
</div>
<script> <script>

Binary file not shown.

Binary file not shown.

View file

@ -114,41 +114,38 @@ END;
[% END %] [% END %]
<ul class="nav nav-tabs"> <ul class="nav nav-tabs">
<li class="dropdown"> <li class="nav-item dropdown">
<a class="dropdown-toggle actions" data-toggle="dropdown" href="#"> <a class="nav-link dropdown-toggle" data-toggle="dropdown" href="#" role="button" area-haspopup="true" aria-expanded="false">Actions</a>
Actions <div class="dropdown-menu">
<b class="caret"></b>
</a>
<ul class="dropdown-menu">
[% IF eval.nixexprinput || eval.flake %] [% IF eval.nixexprinput || eval.flake %]
<li><a href="#reproduce" data-toggle="modal">Reproduce locally</a></li> <a class="dropdown-item" href="#reproduce" data-toggle="modal">Reproduce locally</a>
[% END %] [% END %]
[% IF c.user_exists %] [% IF c.user_exists %]
[% IF available %] [% IF available %]
[% IF build.keep %] [% IF build.keep %]
<li><a href="[% c.uri_for('/build' build.id 'keep' 0) %]">Unkeep</a></li> <a class="dropdown-item" href="[% c.uri_for('/build' build.id 'keep' 0) %]">Unkeep</a>
[% ELSE %] [% ELSE %]
<li><a href="[% c.uri_for('/build' build.id 'keep' 1) %]">Keep</a></li> <a class="dropdown-item" href="[% c.uri_for('/build' build.id 'keep' 1) %]">Keep</a>
[% END %] [% END %]
[% END %] [% END %]
[% IF build.finished %] [% IF build.finished %]
<li><a href="[% c.uri_for('/build' build.id 'restart') %]">Restart</a></li> <a class="dropdown-item" href="[% c.uri_for('/build' build.id 'restart') %]">Restart</a>
[% ELSE %] [% ELSE %]
<li><a href="[% c.uri_for('/build' build.id 'cancel') %]">Cancel</a></li> <a class="dropdown-item" href="[% c.uri_for('/build' build.id 'cancel') %]">Cancel</a>
<li><a href="[% c.uri_for('/build' build.id 'bump') %]">Bump up</a></li> <a class="dropdown-item" href="[% c.uri_for('/build' build.id 'bump') %]">Bump up</a>
[% END %] [% END %]
[% END %] [% END %]
</ul> </div>
</li> </li>
<li class="active"><a href="#tabs-summary" data-toggle="tab">Summary</a></li> <li class="nav-item"><a class="nav-link active" href="#tabs-summary" data-toggle="tab">Summary</a></li>
[% IF isAggregate %]<li><a href="#tabs-constituents" data-toggle="tab">Constituents</a></li>[% END %] [% IF isAggregate %]<li class="nav-item"><a class="nav-link" href="#tabs-constituents" data-toggle="tab">Constituents</a></li>[% END %]
<li><a href="#tabs-details" data-toggle="tab">Details</a></li> <li class="nav-item"><a class="nav-link" href="#tabs-details" data-toggle="tab">Details</a></li>
<li><a href="#tabs-buildinputs" data-toggle="tab">Inputs</a></li> <li class="nav-item"><a class="nav-link" href="#tabs-buildinputs" data-toggle="tab">Inputs</a></li>
[% IF steps.size() > 0 %]<li><a href="#tabs-buildsteps" data-toggle="tab">Build steps</a></li>[% END %] [% IF steps.size() > 0 %]<li class="nav-item"><a class="nav-link" href="#tabs-buildsteps" data-toggle="tab">Build steps</a></li>[% END %]
[% IF build.dependents %]<li><a href="#tabs-usedby" data-toggle="tab">Used by</a></li>[% END%] [% IF build.dependents %]<li class="nav-item"><a class="nav-link" href="#tabs-usedby" data-toggle="tab">Used by</a></li>[% END%]
[% IF drvAvailable %]<li><a href="#tabs-build-deps" data-toggle="tab">Build dependencies</a></li>[% END %] [% IF drvAvailable %]<li class="nav-item"><a class="nav-link" href="#tabs-build-deps" data-toggle="tab">Build dependencies</a></li>[% END %]
[% IF localStore && available %]<li><a href="#tabs-runtime-deps" data-toggle="tab">Runtime dependencies</a></li>[% END %] [% IF localStore && available %]<li class="nav-item"><a class="nav-link" href="#tabs-runtime-deps" data-toggle="tab">Runtime dependencies</a></li>[% END %]
</ul> </ul>
<div id="generic-tabs" class="tab-content"> <div id="generic-tabs" class="tab-content">
@ -239,9 +236,9 @@ END;
<th>Logfile:</th> <th>Logfile:</th>
<td> <td>
[% actualLog = cachedBuildStep ? c.uri_for('/build' cachedBuild.id 'nixlog' cachedBuildStep.stepnr) : c.uri_for('/build' build.id 'log') %] [% actualLog = cachedBuildStep ? c.uri_for('/build' cachedBuild.id 'nixlog' cachedBuildStep.stepnr) : c.uri_for('/build' build.id 'log') %]
<a class="btn btn-mini" href="[%actualLog%]">pretty</a> <a class="btn btn-secondary btn-sm" href="[%actualLog%]">pretty</a>
<a class="btn btn-mini" href="[%actualLog%]/raw">raw</a> <a class="btn btn-secondary btn-sm" href="[%actualLog%]/raw">raw</a>
<a class="btn btn-mini" href="[%actualLog%]/tail">tail</a> <a class="btn btn-secondary btn-sm" href="[%actualLog%]/tail">tail</a>
</td> </td>
</tr> </tr>
[% END %] [% END %]
@ -489,13 +486,14 @@ END;
</div> </div>
<div id="reproduce" class="modal hide fade" tabindex="-1" role="dialog" aria-hidden="true"> <div id="reproduce" class="modal hide fade" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
[% url = c.uri_for('/build' build.id 'reproduce') %] [% url = c.uri_for('/build' build.id 'reproduce') %]
<div class="modal-header"> <div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h3>Reproduce this build</h3> <h3>Reproduce this build</h3>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
</div> </div>
<div class="modal-body"> <div class="modal-body">
@ -506,9 +504,9 @@ END;
installed</a>, you can reproduce this build on your own machine by installed</a>, you can reproduce this build on your own machine by
running the following command:</p> running the following command:</p>
<pre> <div class="card bg-light"><div class="card-body p-2"><code>
<span class="shell-prompt"># </span>nix build [% HTML.escape(eval.flake) %]#hydraJobs.[% HTML.escape(job) %] <span class="shell-prompt"># </span>nix build [% HTML.escape(eval.flake) %]#hydraJobs.[% HTML.escape(job) %]
</pre> </code></div></div>
[% ELSE %] [% ELSE %]
@ -521,9 +519,9 @@ END;
<p>To download and execute the script from the command line, run the <p>To download and execute the script from the command line, run the
following command:</p> following command:</p>
<pre> <div class="card bg-light"><div class="card-body p-2"><code>
<span class="shell-prompt"># </span>curl <a [% HTML.attributes(href => url) %]>[% HTML.escape(url) %]</a> | bash <span class="shell-prompt"># </span>curl <a [% HTML.attributes(href => url) %]>[% HTML.escape(url) %]</a> | bash
</pre> </code></div></div>
[% END %] [% END %]
@ -532,6 +530,8 @@ END;
<div class="modal-footer"> <div class="modal-footer">
<a href="#" class="btn btn-primary" data-dismiss="modal">Close</a> <a href="#" class="btn btn-primary" data-dismiss="modal">Close</a>
</div> </div>
</div>
</div>
</div> </div>

View file

@ -6,21 +6,24 @@
href="http://nixos.org/">Nix package manager</a>. If you have Nix href="http://nixos.org/">Nix package manager</a>. If you have Nix
installed, you can subscribe to this channel by once executing</p> installed, you can subscribe to this channel by once executing</p>
<pre> <div class="card bg-light"><div class="card-body"><pre>
$ nix-channel --add [% curUri +%] <span class="shell-prompt">$ </span>nix-channel --add [% curUri +%]
$ nix-channel --update</pre> <span class="shell-prompt">$ </span>nix-channel --update
</pre></div></div>
<p>You can then query and install packages in the normal way, e.g.,</p> <p>You can then query and install packages in the normal way, e.g.,</p>
<pre> <div class="card bg-light"><div class="card-body"><pre>
$ nix-env -qa '*' <span class="shell-prompt">$ </span>nix-env -qa '*'
$ nix-env -i foo</pre> <span class="shell-prompt">$ </span>nix-env -i foo
</pre></pre></div>
<p>You can update to the latest versions of the packages in this channel by executing</p> <p>You can update to the latest versions of the packages in this channel by executing</p>
<pre> <div class="card bg-light"><div class="card-body"><pre>
$ nix-channel --update <span class="shell-prompt">$ </span>nix-channel --update
$ nix-env -u '*'</pre> <span class="shell-prompt">$ </span>nix-env -u '*'
</pre></div></div>
[% IF genericChannel %] [% IF genericChannel %]

View file

@ -127,7 +127,7 @@ BLOCK renderBuildListBody;
</td> </td>
[% END %] [% END %]
[% IF showSchedulingInfo %] [% IF showSchedulingInfo %]
<td>[% IF busy %]<span class="label label-success">Started</span>[% ELSE %]<span class="label">Queued</span>[% END %]</td> <td>[% IF busy %]<span class="badge badge-success">Started</span>[% ELSE %]<span class="badge badge-secondary">Queued</span>[% END %]</td>
[% END %] [% END %]
<td><a class="row-link" href="[% link %]">[% build.id %]</a></td> <td><a class="row-link" href="[% link %]">[% build.id %]</a></td>
[% IF !hideJobName %] [% IF !hideJobName %]
@ -182,7 +182,7 @@ BLOCK renderSelection;
[% END %] [% END %]
</div> </div>
[% ELSE %] [% ELSE %]
<select style='width: 15em;' [% HTML.attributes(id => param, name => param) %]> <select class="custom-select" [% HTML.attributes(id => param, name => param) %]>
[% FOREACH name IN options.keys.sort %] [% FOREACH name IN options.keys.sort %]
<option [% IF name == curValue; "selected='selected'"; END; " "; HTML.attributes(value => name) %]>[% options.$name %]</option> <option [% IF name == curValue; "selected='selected'"; END; " "; HTML.attributes(value => name) %]>[% options.$name %]</option>
[% END %] [% END %]
@ -405,11 +405,11 @@ BLOCK renderInputDiff; %]
BLOCK renderPager %] BLOCK renderPager %]
<ul class="pager"> <ul class="pagination">
<li [% IF page == 1 %]class="disabled"[% END %]><a href="[% "$baseUri?page=1" %]">« First</a></li> <li class="page-item[% IF page == 1 %] disabled[% END %]"><a class="page-link" href="[% "$baseUri?page=1" %]">&laquo; First</a></li>
<li [% IF page == 1 %]class="disabled"[% END %]><a href="[% "$baseUri?page="; (page - 1) %]"> Previous</a></li> <li class="page-item[% IF page == 1 %] disabled[% END %]"><a class="page-link" href="[% "$baseUri?page="; (page - 1) %]">&lsaquo; Previous</a></li>
<li [% IF page * resultsPerPage >= total %]class="disabled"[% END %]><a 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="; (page + 1) %]">Next &rsaquo;</a></li>
<li [% IF page * resultsPerPage >= total %]class="disabled"[% END %]><a href="[% "$baseUri?page="; (total - 1) div resultsPerPage + 1 %]">Last »</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 &raquo;</a></li>
</ul> </ul>
[% END; [% END;
@ -439,10 +439,7 @@ BLOCK renderEvals %]
[% END %] [% END %]
<th rowspan="2" style="width: 10em">Date</th> <th rowspan="2" style="width: 10em">Date</th>
<th rowspan="2">Input changes</th> <th rowspan="2">Input changes</th>
<th colspan="3">Jobs</th> <th colspan="4">Jobs</th>
<th rowspan="2">
<img src="[% c.uri_for("/static/images/delta.svg") %]" height="12" width="12" title="Delta" alt="Delta" class="build-status" />
</th>
</tr> </tr>
<tr> <tr>
<th style="width: 2em"> <th style="width: 2em">
@ -454,6 +451,9 @@ BLOCK renderEvals %]
<th style="width: 2em"> <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" /> <img src="[% c.uri_for("/static/images/emojione-question-2754.svg") %]" height="12" width="12" title="Queued" alt="Queued" class="build-status" />
</th> </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> </tr>
</thead> </thead>
<tbody> <tbody>
@ -477,33 +477,33 @@ BLOCK renderEvals %]
- -
[% END %] [% END %]
[% IF eval.evaluationerror.errormsg %] [% IF eval.evaluationerror.errormsg %]
<span class="label label-warning">Eval Errors</span> <span class="badge badge-warning">Eval Errors</span>
[% END %] [% END %]
</td> </td>
<td align='right' class="nowrap"> <td align='right' class="nowrap">
<span class="label label-success">[% e.nrSucceeded %]</span> <span class="badge badge-success">[% e.nrSucceeded %]</span>
</td> </td>
<td align="right" class="nowrap"> <td align="right" class="nowrap">
[% IF e.nrFailed > 0 %] [% IF e.nrFailed > 0 %]
<span class="label label-important">[% e.nrFailed %]</span> <span class="badge badge-danger">[% e.nrFailed %]</span>
[% END %] [% END %]
</td> </td>
<td align="right" class="nowrap"> <td align="right" class="nowrap">
[% IF e.nrScheduled > 0 %] [% IF e.nrScheduled > 0 %]
<span class="label">[% e.nrScheduled %]</span> <span class="badge badge-secondary">[% e.nrScheduled %]</span>
[% END %] [% END %]
</td> </td>
<td align='right' class="nowrap"> <td align='right' class="nowrap">
[% IF e.diff > 0 %] [% IF e.diff > 0 %]
<span class='label label-success'><strong>+[% e.diff %]</strong></span> <span class='badge badge-success'><strong>+[% e.diff %]</strong></span>
[% ELSIF e.diff < 0 && e.nrScheduled == 0 %] [% ELSIF e.diff < 0 && e.nrScheduled == 0 %]
<span class='label label-important'><strong>[% e.diff %]</strong></span> <span class='badge badge-danger'><strong>[% e.diff %]</strong></span>
[% END %] [% END %]
</td> </td>
</tr> </tr>
[% END; [% END;
IF linkToAll %] IF linkToAll %]
<tr><td class="centered" colspan="5"><a href="[% linkToAll %]"><em>More...</em></a></td></tr> <tr><td class="centered" colspan="7"><a href="[% linkToAll %]"><em>More...</em></a></td></tr>
[% END %] [% END %]
</tbody> </tbody>
</table> </table>
@ -517,7 +517,7 @@ BLOCK renderLogLinks %]
BLOCK makeLazyTab %] BLOCK makeLazyTab %]
<div id="[% tabName %]" class="tab-pane"> <div id="[% tabName %]" class="tab-pane">
<center><img src="[% c.uri_for("/static/images/ajax-loader.gif") %]" alt="Loading..." /></center> <center><span class="spinner-border spinner-border-sm"/></center>
</div> </div>
<script> <script>
$(function() { makeLazyTab("[% tabName %]", "[% uri %]"); }); $(function() { makeLazyTab("[% tabName %]", "[% uri %]"); });
@ -526,18 +526,28 @@ BLOCK makeLazyTab %]
BLOCK makePopover %] BLOCK makePopover %]
<div class="btn hydra-popover [% classes %]" data-toggle="popover" data-html="true" [% HTML.attributes('data-content' => content, 'data-placement' => placement || 'bottom') %]> <button type="button" class="btn hydra-popover [% classes %]" data-toggle="popover" data-html="true" [% HTML.attributes('data-content' => content, 'data-placement' => placement || 'bottom') %]>
[% title %] [% title %]
</div> </button>
[% END; [% END;
BLOCK menuItem %] BLOCK menuItem %]
<li class="[% IF "${root}${curUri}" == uri %]active[% END %]" [% IF confirmmsg %]onclick="javascript:return confirm('[% confirmmsg %]')"[% END %]> <a class="dropdown-item[% IF "${root}${curUri}" == uri %] active[% END %]"
<a [% HTML.attributes(href => uri) %] [%+ IF modal %]data-toggle="modal"[% 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 %] [% IF icon %]<i class="[% icon %] icon-black"></i> [%+ END %]
[% title %] [% title %]
</a> </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> </li>
[% END; [% END;
@ -588,35 +598,35 @@ BLOCK renderJobsetOverview %]
<td>[% HTML.escape(j.description) %]</td> <td>[% HTML.escape(j.description) %]</td>
<td>[% IF j.lastcheckedtime; <td>[% IF j.lastcheckedtime;
INCLUDE renderDateTime timestamp = j.lastcheckedtime; INCLUDE renderDateTime timestamp = j.lastcheckedtime;
IF j.errormsg || j.fetcherrormsg; %]&nbsp;<span class = 'label label-warning'>Error</span>[% END; IF j.errormsg || j.fetcherrormsg; %]&nbsp;<span class = 'badge badge-warning'>Error</span>[% END;
ELSE; "-"; ELSE; "-";
END %]</td> END %]</td>
[% IF j.get_column('nrtotal') > 0 %] [% IF j.get_column('nrtotal') > 0 %]
[% successrate = ( j.get_column('nrsucceeded') / j.get_column('nrtotal') )*100 %] [% successrate = ( j.get_column('nrsucceeded') / j.get_column('nrtotal') )*100 %]
[% IF j.get_column('nrscheduled') > 0 %] [% IF j.get_column('nrscheduled') > 0 %]
[% class = 'label' %] [% class = 'badge badge-secondary' %]
[% ELSIF successrate < 25 %] [% ELSIF successrate < 25 %]
[% class = 'label label-important' %] [% class = 'badge badge-danger' %]
[% ELSIF successrate < 75 %] [% ELSIF successrate < 75 %]
[% class = 'label label-warning' %] [% class = 'badge badge-warning' %]
[% ELSIF successrate <= 100 %] [% ELSIF successrate <= 100 %]
[% class = 'label label-success' %] [% class = 'badge badge-success' %]
[% END %] [% END %]
[% END %] [% END %]
<td><span class="[% class %]">[% successrate FILTER format('%d') %]%</span></td> <td><span class="[% class %]">[% successrate FILTER format('%d') %]%</span></td>
<td> <td>
[% IF j.get_column('nrsucceeded') > 0 %] [% IF j.get_column('nrsucceeded') > 0 %]
<span class="label label-success">[% j.get_column('nrsucceeded') %]</span> <span class="badge badge-success">[% j.get_column('nrsucceeded') %]</span>
[% END %] [% END %]
</td> </td>
<td> <td>
[% IF j.get_column('nrfailed') > 0 %] [% IF j.get_column('nrfailed') > 0 %]
<span class="label label-important">[% j.get_column('nrfailed') %]</span> <span class="badge badge-danger">[% j.get_column('nrfailed') %]</span>
[% END %] [% END %]
</td> </td>
<td> <td>
[% IF j.get_column('nrscheduled') > 0 %] [% IF j.get_column('nrscheduled') > 0 %]
<span class="label label">[% j.get_column('nrscheduled') %]</span> <span class="badge badge-secondary">[% j.get_column('nrscheduled') %]</span>
[% END %] [% END %]
</td> </td>
</tr> </tr>

View file

@ -2,9 +2,9 @@
[% PROCESS common.tt %] [% PROCESS common.tt %]
<ul class="nav nav-tabs"> <ul class="nav nav-tabs">
<li class="active"><a href="#tabs-starred-jobs" data-toggle="tab">Starred jobs</a></li> <li class="nav-item"><a class="nav-link active" href="#tabs-starred-jobs" data-toggle="tab">Starred jobs</a></li>
<li><a href="#tabs-my-jobs" data-toggle="tab">My jobs</a></li> <li class="nav-item"><a class="nav-link" href="#tabs-my-jobs" data-toggle="tab">My jobs</a></li>
<li><a href="#tabs-my-jobsets" data-toggle="tab">My jobsets</a></li> <li class="nav-item"><a class="nav-link" href="#tabs-my-jobsets" data-toggle="tab">My jobsets</a></li>
</ul> </ul>
<div id="generic-tabs" class="tab-content"> <div id="generic-tabs" class="tab-content">

View file

@ -9,7 +9,7 @@
[% BLOCK renderJobsetInput %] [% BLOCK renderJobsetInput %]
<tr class="input [% extraClass %]" [% IF id %]id="[% id %]"[% END %]> <tr class="input [% extraClass %]" [% IF id %]id="[% id %]"[% END %]>
<td> <td>
<button type="button" class="btn btn-warning" onclick='$(this).parents(".input").remove()'><i class="icon-trash icon-white"></i></button> <button type="button" class="btn btn-warning" onclick='$(this).parents(".input").remove()'><i class="fas fa-trash"></i></button>
</td> </td>
<td> <td>
<input type="text" id="[% baseName %]-name" name="[% baseName %]-name" [% HTML.attributes(value => input.name) %]/> <input type="text" id="[% baseName %]-name" name="[% baseName %]-name" [% HTML.attributes(value => input.name) %]/>
@ -51,130 +51,136 @@
[% INCLUDE renderJobsetInput input=input baseName="input-$input.name" %] [% INCLUDE renderJobsetInput input=input baseName="input-$input.name" %]
[% END %] [% END %]
<tr> <tr>
<td colspan="4" style="text-align: center;"><button type="button" class="add-input btn btn-success"><i class="icon-plus icon-white"></i> Add a new input</button></td> <td colspan="4" style="text-align: center;"><button type="button" class="add-input btn btn-success"><i class="fas fa-plus"></i> Add a new input</button></td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
[% END %] [% END %]
<form class="form-horizontal"> <form>
<fieldset> <div class="form-group row">
<label class="col-sm-3" for="editjobsetenabled">State</label>
<div class="control-group"> <div class="btn-group btn-group-toggle col-sm-9" data-toggle="buttons">
<label class="control-label">State</label> <label class="btn btn-secondary[% IF jobset.enabled == 1 %] active[% END %]">
<div class="controls"> <input type="radio" id="editjobsetenabled" name="enabled" value="1" [% IF jobset.enabled == 1 %]checked[% END %]>Enabled</button>
<div class="btn-group" data-toggle="buttons-radio"> </label>
<input type="hidden" name="enabled" value="[% jobset.enabled %]" /> <label class="btn btn-secondary[% IF jobset.enabled == 2 %] active[% END %]">
<button type="button" class="btn" value="1">Enabled</button> <input type="radio" name="enabled" value="2" [% IF jobset.enabled == 2 %]checked[% END %]>One-shot</button>
<button type="button" class="btn" value="2">One-shot</button> </label>
<button type="button" class="btn" value="3">One-at-a-time</button> <label class="btn btn-secondary[% IF jobset.enabled == 3 %] active[% END %]">
<button type="button" class="btn" value="0">Disabled</button> <input type="radio" name="enabled" value="3" [% IF jobset.enabled == 3 %]checked[% END %]>One-at-a-time</button>
</div> </label>
</div> <label class="btn btn-secondary[% IF jobset.enabled == 0 %] active[% END %]">
</div> <input type="radio" name="enabled" value="0" [% IF jobset.enabled == 0 %]checked[% END %]>Disabled</button>
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" name="visible" [% IF !jobset.hidden; 'checked="checked"'; END %]/>Visible
</label> </label>
</div> </div>
</div> </div>
<div class="control-group"> <div class="form-group row">
<label class="control-label">Identifier</label> <label class="col-form-label col-sm-3" for="editjobsetvisible">Visible</label>
<div class="controls"> <div class="col-sm-9">
<input type="text" class="span3" name="name" [% HTML.attributes(value => edit ? jobset.name : "") %]/> <input type="checkbox" id="editjobsetvisible" name="visible" [% IF !jobset.hidden; 'checked="checked"'; END %]/>
</div> </div>
</div> </div>
<div class="control-group"> <div class="form-group row">
<label class="control-label">Description</label> <label class="col-form-label col-sm-3" for="editjobsetname">Identifier</label>
<div class="controls"> <div class="col-sm-9">
<input type="text" class="span3" name="description" [% HTML.attributes(value => jobset.description) %]/> <input type="text" class="form-control" id="editjobsetname" name="name" [% HTML.attributes(value => edit ? jobset.name : "") %]/>
</div> </div>
</div> </div>
<div class="control-group"> <div class="form-group row">
<label class="control-label">Type</label> <label class="col-form-label col-sm-3" for="editjobsettype">Type</label>
<div class="controls"> <div class="btn-group btn-group-toggle col-sm-9" data-toggle="buttons">
<div class="btn-group" data-toggle="buttons-radio"> <label id="type-flake" class="btn btn-secondary[% IF jobset.type == 1 %] active[% END %]">
<input type="hidden" id="type" name="type" value="[% jobset.type %]" /> <input type="radio" id="editjobsettype" name="type" value="1" [% IF jobset.type == 1 %]checked[% END %]>Flake</button>
<button type="button" class="btn" value="1" id="type-flake">Flake</button> </label>
<button type="button" class="btn" value="0" id="type-legacy">Legacy</button> <label id="type-legacy" class="btn btn-secondary[% IF jobset.type == 0 %] active[% END %]">
<input type="radio" name="type" value="0" [% IF jobset.type == 0 %]checked[% END %]>Legacy</button>
</label>
</div>
</div>
<div class="form-group row">
<label class="col-form-label col-sm-3" for="editjobsetdescription">Description</label>
<div class="col-sm-9">
<input type="text" class="form-control" id="editjobsetdescription" name="description" [% HTML.attributes(value => jobset.description) %]/>
</div>
</div>
<div class="form-group row show-on-flake">
<label class="col-form-label col-sm-3" for="editjobsetflakeref">Flake URI</label>
<div class="col-sm-9">
<input type="text" class="form-control" id="editjobsetflakeref" name="flakeref" [% HTML.attributes(value => jobset.flake) %]/>
</div>
</div>
<div class="form-group row show-on-legacy">
<label class="col-form-label col-sm-3" for="editjobsetnixexpr">Nix expression</label>
<div class="col-sm-9">
<div class="input-group">
<input type="text" class="form-control" id="editjobsetnixexpr" name="nixexprpath" [% HTML.attributes(value => jobset.nixexprpath) %]/>
<div class="input-group-append input-group-prepend">
<span class="input-group-text">in</span>
</div>
<input type="text" class="form-control" name="nixexprinput" [% HTML.attributes(value => jobset.nixexprinput) %]/>
</div> </div>
</div> </div>
</div> </div>
<div class="control-group show-on-flake"> <div class="form-group row">
<label class="control-label">Flake URI</label> <label class="col-sm-3" for="editjobsetcheckinterval">
<div class="controls"> Check interval
<input type="text" class="span3" name="flakeref" [% HTML.attributes(value => jobset.flake) %]/> <small class="form-text text-muted">(0 to disable polling)</small>
</label>
<div class="col-sm-9">
<div class="input-group">
<input type="number" class="form-control" id="editjobsetcheckinterval" name="checkinterval" [% HTML.attributes(value => jobset.checkinterval) %]/>
<div class="input-group-append">
<span class="input-group-text">sec</span>
</div>
</div>
</div> </div>
</div> </div>
<div class="control-group show-on-legacy"> <div class="form-group row">
<label class="control-label">Nix expression</label> <label class="col-sm-3" for="editjobsetschedulingshares">
<div class="controls"> Scheduling shares
<input type="text" class="span3" name="nixexprpath" [% HTML.attributes(value => jobset.nixexprpath) %]/>
in
<input type="text" class="span3" name="nixexprinput" [% HTML.attributes(value => jobset.nixexprinput) %]/>
</div>
</div>
<div class="control-group">
<label class="control-label">Check interval</label>
<div class="controls">
<div class="input-append">
<input type="number" class="span3" name="checkinterval" [% HTML.attributes(value => jobset.checkinterval) %]/>
<span class="add-on">sec</span>
</div>
<span class="help-inline">(0 to disable polling)</span>
</div>
</div>
<div class="control-group">
<label class="control-label">Scheduling shares</label>
<div class="controls">
<div class="input-append">
<input type="number" class="span3" name="schedulingshares" [% HTML.attributes(value => jobset.schedulingshares) %]/>
</div>
[% IF totalShares %] [% IF totalShares %]
<span class="help-inline">([% f = format("%.2f"); f(jobset.schedulingshares / totalShares * 100) %]% out of [% totalShares %] shares)</span> <small class="form-text text-muted">([% f = format("%.2f"); f(jobset.schedulingshares / totalShares * 100) %]% out of [% totalShares %] shares)</small>
[% END %] [% END %]
</div>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" name="enableemail" [% IF jobset.enableemail; 'checked="checked"'; END %] [%IF !emailNotification%]disabled=1[%END%] />Email notification
</label> </label>
<div class="col-sm-9">
<input type="number" class="form-control" id="editjobschedulingshares" name="schedulingshares" [% HTML.attributes(value => jobset.schedulingshares) %]/>
</div> </div>
</div> </div>
<div class="control-group"> <div class="form-group row">
<label class="control-label">Email override</label> <label class="col-sm-3" for="editjobsetenableemail">Email notification</label>
<div class="controls"> <div class="col-sm-9">
<input type="text" class="span3" name="emailoverride" [% HTML.attributes(value => jobset.emailoverride) %] [%IF !emailNotification%]disabled=1[%END%] /> <input type="checkbox" id="editjobsetenableemail" name="enableemail" [% IF jobset.enableemail %]checked[% END %] [% IF !emailNotification %]disabled[% END %]/>
</div> </div>
</div> </div>
<div class="control-group"> <div class="form-group row">
<label class="control-label">Number of evaluations to keep</label> <label class="col-sm-3" for="editjobsetemailoverride">Email override</label>
<div class="controls"> <div class="col-sm-9">
<input type="number" class="span3" name="keepnr" [% HTML.attributes(value => jobset.keepnr) %]/> <input type="text" class="form-control" id="editjobsetemailoverride" name="emailoverride" [% HTML.attributes(value => jobset.emailoverride) %] [% IF !emailNotification %]disabled[% END %]/>
</div>
</div>
<div class="form-group row">
<label class="col-sm-3" for="editjobsetkeepnumber">Number of evaluations to keep</label>
<div class="col-sm-9">
<input type="number" class="form-control" id="editjobsetkeepnumber" name="keepnr" [% HTML.attributes(value => jobset.keepnr) %]/>
</div> </div>
</div> </div>
[% INCLUDE renderJobsetInputs %] [% INCLUDE renderJobsetInputs %]
<div class="form-actions"> <button id="submit-jobset" type="submit" class="btn btn-primary"><i class="fas fa-check"></i> [%IF !edit %]Create jobset[% ELSE %]Apply changes[% END %]</button>
<button id="submit-jobset" type="submit" class="btn btn-primary"><i class="icon-ok icon-white"></i> [%IF !edit %]Create jobset[% ELSE %]Apply changes[% END %]</button>
</div>
</fieldset>
<table style="display: none"> <table style="display: none">
[% INCLUDE renderJobsetInput input="" extraClass="template" id="input-template" baseName="input-template" %] [% INCLUDE renderJobsetInput input="" extraClass="template" id="input-template" baseName="input-template" %]
@ -187,7 +193,7 @@
var id = 0; var id = 0;
function update() { function update() {
if ($("#type").val() == 0) { if ($("input[type='radio'][name='type']:checked").val() == 0) {
$(".show-on-legacy").show(); $(".show-on-legacy").show();
$(".show-on-flake").hide(); $(".show-on-flake").hide();
} else { } else {
@ -196,8 +202,7 @@
} }
} }
$("#type-flake").click(function() { update(); }); $("input[type='radio'][name='type']").change(function() { update(); });
$("#type-legacy").click(function() { update(); });
update(); update();

View file

@ -1,85 +1,79 @@
[% WRAPPER layout.tt title=(create ? "New project" : "Editing project $project.name") %] [% WRAPPER layout.tt title=(create ? "New project" : "Editing project $project.name") %]
[% PROCESS common.tt %] [% PROCESS common.tt %]
<form class="form-horizontal"> <form>
<fieldset> <div class="form-group row">
<label class="col-sm-3" for="editprojectenabled">Enabled</label>
<div class="col-sm-9">
<input type="checkbox" id="editprojectenabled" name="enabled" [% IF create || project.enabled %] checked="checked" [% END %]/>
</div>
</div>
<div class="control-group"> <div class="form-group row">
<div class="controls"> <label class="col-sm-3" for="editprojectvisible">Visible in projects list</label>
<label class="checkbox"> <div class="col-sm-9">
<input type="checkbox" name="enabled" [% IF create || project.enabled; 'checked="checked"'; END %]/>Enabled <input type="checkbox" id="editprojectvisible" name="visible" [% IF !project.hidden %] checked="checked" [% END %]/>
</label> </div>
</div> </div>
<div class="controls">
<label class="checkbox"> <div class="form-group row">
<input type="checkbox" name="visible" [% IF !project.hidden; 'checked="checked"'; END %]/>Visible in the list of projects <label class="col-sm-3" for="editprojectidentifier">Identifier</label>
<div class="col-sm-9">
<input type="text" class="form-control" id="editprojectidentifier" name="name" [% HTML.attributes(value => project.name) %]/>
</div>
</div>
<div class="form-group row">
<label class="col-sm-3" for="editprojectdisplayname">Display name</label>
<div class="col-sm-9">
<input type="text" class="form-control" id="editprojectdisplayname" name="displayname" [% HTML.attributes(value => project.displayname) %]/>
</div>
</div>
<div class="form-group row">
<label class="col-sm-3" for="editprojectdescription">Description</label>
<div class="col-sm-9">
<input type="text" class="form-control" id="editprojectdescription" name="description" [% HTML.attributes(value => project.description) %]/>
</div>
</div>
<div class="form-group row">
<label class="col-sm-3" for="editprojecthomepage">Homepage</label>
<div class="col-sm-9">
<input type="text" class="form-control" id="editprojecthomepage" name="homepage" [% HTML.attributes(value => project.homepage) %]/>
</div>
</div>
<div class="form-group row">
<label class="col-sm-3" for="editprojectowner">Owner</label>
<div class="col-sm-9">
<input type="text" class="form-control" id="editprojectowner" name="owner" [% HTML.attributes(value => project.owner.username || c.user.username) %]/>
</div>
</div>
<div class="form-group row">
<label class="col-sm-3" for="editprojectdeclfile">
Declarative spec file
<small class="form-text text-muted">(Leave blank for non-declarative project configuration)</small>
</label> </label>
<div class="col-sm-9">
<input type="text" class="form-control" id="editprojectdeclfile" name="declfile" [% HTML.attributes(value => project.declfile) %]/>
</div> </div>
</div> </div>
<div class="control-group"> <div class="form-group row">
<label class="control-label">Identifier</label> <label class="col-sm-3" for="editprojectdeclvalue">Declarative input type</label>
<div class="controls"> <div class="col-sm-9">
<input type="text" class="span3" name="name" [% HTML.attributes(value => project.name) %]/>
</div>
</div>
<div class="control-group">
<label class="control-label">Display name</label>
<div class="controls">
<input type="text" class="span3" name="displayname" [% HTML.attributes(value => project.displayname) %]/>
</div>
</div>
<div class="control-group">
<label class="control-label">Description</label>
<div class="controls">
<input type="text" class="span3" name="description" [% HTML.attributes(value => project.description) %]/>
</div>
</div>
<div class="control-group">
<label class="control-label">Homepage</label>
<div class="controls">
<input type="text" class="span3" name="homepage" [% HTML.attributes(value => project.homepage) %]/>
</div>
</div>
<div class="control-group">
<label class="control-label">Owner</label>
<div class="controls">
<input type="text" class="span3" name="owner" [% HTML.attributes(value => project.owner.username || c.user.username) %]/>
</div>
</div>
<div class="control-group">
<label class="control-label">Declarative spec file</label>
<div class="controls">
<div class="input-append">
<input type="text" class="span3" name="declfile" [% HTML.attributes(value => project.declfile) %]/>
</div>
<span class="help-inline">(Leave blank for non-declarative project configuration)</span>
</div>
</div>
<div class="control-group">
<label class="control-label">Declarative input type</label>
<div class="controls">
[% INCLUDE renderSelection param="decltype" options=inputTypes edit=1 curValue=project.decltype %] [% INCLUDE renderSelection param="decltype" options=inputTypes edit=1 curValue=project.decltype %]
value <input type="text" class="form-control" id="editprojectdeclvalue" name="declvalue" [% HTML.attributes(value => project.declvalue) %]/>
<input style="width: 70%" type="text" [% HTML.attributes(value => project.declvalue, name => "declvalue") %]/>
</div> </div>
</div> </div>
<div class="form-actions">
<button id="submit-project" type="submit" class="btn btn-primary"> <button id="submit-project" type="submit" class="btn btn-primary">
<i class="icon-ok icon-white"></i> <i class="fas fa-check"></i>
[%IF create %]Create project[% ELSE %]Apply changes[% END %] [%IF create %]Create project[% ELSE %]Apply changes[% END %]
</button> </button>
</div>
</fieldset>
</form> </form>

Binary file not shown.

View file

@ -15,12 +15,12 @@ removed or had an evaluation error.</div>
[% END %] [% END %]
<ul class="nav nav-tabs"> <ul class="nav nav-tabs">
<li class="active"><a href="#tabs-status" data-toggle="tab">Status</a></li> <li class="nav-item"><a class="nav-link active" href="#tabs-status" data-toggle="tab">Status</a></li>
[% IF constituentJobs.size > 0 %] [% IF constituentJobs.size > 0 %]
<li><a href="#tabs-constituents" data-toggle="tab">Constituents</a></li> <li class="nav-item"><a class="nav-link" href="#tabs-constituents" data-toggle="tab">Constituents</a></li>
[% END %] [% END %]
<li><a href="#tabs-charts" data-toggle="tab">Charts</a></li> <li class="nav-item"><a class="nav-link" href="#tabs-charts" data-toggle="tab">Charts</a></li>
<li><a href="#tabs-links" data-toggle="tab">Links</a></li> <li class="nav-item"><a class="nav-link" href="#tabs-links" data-toggle="tab">Links</a></li>
</ul> </ul>
<div id="generic-tabs" class="tab-content"> <div id="generic-tabs" class="tab-content">

View file

@ -2,7 +2,7 @@
[% IF channels.size == 0 %] [% IF channels.size == 0 %]
<div class="alert">There are no channels available.</div> <div class="alert alert-warning">There are no channels available.</div>
[% ELSE %] [% ELSE %]

View file

@ -1,21 +1,21 @@
[% WRAPPER layout.tt title="Evaluation $eval.id of jobset $project.name:$jobset.name " %] [% WRAPPER layout.tt title="Evaluation $eval.id of jobset $project.name:$jobset.name " %]
[% PROCESS common.tt %] [% PROCESS common.tt %]
<div class="btn-group pull-right"> <div class="dropdown">
<a class="btn btn-primary dropdown-toggle" data-toggle="dropdown" href="#"><i class="icon-white icon-eye-open"></i> Compare to...</a> <button class="btn btn-primary dropdown-toggle float-right" data-toggle="dropdown"><i class="fas fa-eye"></i> Compare to...</button>
<ul class="dropdown-menu"> <div class="dropdown-menu dropdown-menu-right">
<li><a href="?">Preceding evaluation in this jobset</a></li> <a class="dropdown-item" href="?">Preceding evaluation in this jobset</a>
<li class="divider"></li> <div class="dropdown-divider"></div>
<li><a href="?compare=-[% 24 * 60 * 60 %]">This jobset <strong>one day</strong> earlier</a></li> <a class="dropdown-item" href="?compare=-[% 24 * 60 * 60 %]">This jobset <strong>one day</strong> earlier</a>
<li><a href="?compare=-[% 7 * 24 * 60 * 60 %]">This jobset <strong>one week</strong> earlier</a></li> <a class="dropdown-item" href="?compare=-[% 7 * 24 * 60 * 60 %]">This jobset <strong>one week</strong> earlier</a>
<li><a href="?compare=-[% 31 * 24 * 60 * 60 %]">This jobset <strong>one month</strong> earlier</a></li> <a class="dropdown-item" href="?compare=-[% 31 * 24 * 60 * 60 %]">This jobset <strong>one month</strong> earlier</a>
[% IF project.jobsets_rs.count > 1 %] [% IF project.jobsets_rs.count > 1 %]
<li class="divider"></li> <div class="dropdown-divider"></div>
[% FOREACH j IN project.jobsets.sort('name'); IF j.name != jobset.name %] [% FOREACH j IN project.jobsets.sort('name'); IF j.name != jobset.name %]
<li><a href="?compare=[% j.name %]">Jobset <tt>[% project.name %]:[% j.name %]</tt></a></li> <a class="dropdown-item" href="?compare=[% j.name %]">Jobset <tt>[% project.name %]:[% j.name %]</tt></a>
[% END; END %] [% END; END %]
[% END %] [% END %]
</ul> </div>
</div> </div>
<p>This evaluation was performed [% IF eval.flake %]from the flake <p>This evaluation was performed [% IF eval.flake %]from the flake
@ -29,70 +29,68 @@ project=otherEval.jobset.project.name jobset=otherEval.jobset.name %] evaluation
c.uri_for(c.controller('JobsetEval').action_for('view'), c.uri_for(c.controller('JobsetEval').action_for('view'),
[otherEval.id]) %]">[% otherEval.id %]</a>.</p> [otherEval.id]) %]">[% otherEval.id %]</a>.</p>
[% ELSE %] [% ELSE %]
<div class="alert">Couldn't find an evaluation to compare to.</div> <div class="alert alert-danger">Couldn't find an evaluation to compare to.</div>
[% END %] [% END %]
<form class="form-search"> <form>
<input name="filter" type="text" class="input-large search-query" placeholder="Search jobs by name..." [% HTML.attributes(value => filter) %]/> <div class="form-group">
<input name="filter" type="text" class="form-control" type="search" placeholder="Search jobs by name..." [% HTML.attributes(value => filter) %]/>
<input name="compare" type="hidden" [% HTML.attributes(value => otherEval.id) %]/> <input name="compare" type="hidden" [% HTML.attributes(value => otherEval.id) %]/>
<input name="full" type="hidden" [% HTML.attributes(value => full) %]/> <input name="full" type="hidden" [% HTML.attributes(value => full) %]/>
</div>
</form> </form>
<ul class="nav nav-tabs"> <ul class="nav nav-tabs">
[% IF c.user_exists %] [% IF c.user_exists %]
<li class="dropdown"> <li class="nav-item dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#"> <a class="nav-link dropdown-toggle" data-toggle="dropdown" href="#">Actions</a>
Actions <div class="dropdown-menu">
<b class="caret"></b> <a class="dropdown-item" href="[% c.uri_for(c.controller('JobsetEval').action_for('create_jobset'), [eval.id]) %]">Create a jobset from this evaluation</a>
</a>
<ul class="dropdown-menu">
<li><a href="[% c.uri_for(c.controller('JobsetEval').action_for('create_jobset'), [eval.id]) %]">Create a jobset from this evaluation</a></li>
[% IF unfinished.size > 0 %] [% IF unfinished.size > 0 %]
<li><a href="[% c.uri_for(c.controller('JobsetEval').action_for('cancel'), [eval.id]) %]">Cancel all scheduled builds</a></li> <a class="dropdown-item" href="[% c.uri_for(c.controller('JobsetEval').action_for('cancel'), [eval.id]) %]">Cancel all scheduled builds</a>
[% END %] [% END %]
[% IF aborted.size > 0 || stillFail.size > 0 || nowFail.size > 0 %] [% IF aborted.size > 0 || stillFail.size > 0 || nowFail.size > 0 %]
<li><a href="[% c.uri_for(c.controller('JobsetEval').action_for('restart_failed'), [eval.id]) %]">Restart all failed builds</a></li> <a class="dropdown-item" href="[% c.uri_for(c.controller('JobsetEval').action_for('restart_failed'), [eval.id]) %]">Restart all failed builds</a>
[% END %] [% END %]
[% IF aborted.size > 0 %] [% IF aborted.size > 0 %]
<li><a href="[% c.uri_for(c.controller('JobsetEval').action_for('restart_aborted'), [eval.id]) %]">Restart all aborted builds</a></li> <a class="dropdown-item" href="[% c.uri_for(c.controller('JobsetEval').action_for('restart_aborted'), [eval.id]) %]">Restart all aborted builds</a>
[% END %] [% END %]
[% IF unfinished.size > 0 %] [% IF unfinished.size > 0 %]
<li><a href="[% c.uri_for(c.controller('JobsetEval').action_for('bump'), [eval.id]) %]">Bump builds to front of queue</a></li> <a class="dropdown-item" href="[% c.uri_for(c.controller('JobsetEval').action_for('bump'), [eval.id]) %]">Bump builds to front of queue</a>
[% END %] [% END %]
</ul> </div>
</li> </li>
[% END %] [% END %]
[% IF aborted.size > 0 %] [% IF aborted.size > 0 %]
<li><a href="#tabs-aborted" data-toggle="tab"><span class="text-warning">Aborted jobs ([% aborted.size %])</span></a></li> <li class="nav-item"><a class="nav-link" href="#tabs-aborted" data-toggle="tab"><span class="text-warning">Aborted jobs ([% aborted.size %])</span></a></li>
[% END %] [% END %]
[% IF nowFail.size > 0 %] [% IF nowFail.size > 0 %]
<li><a href="#tabs-now-fail" data-toggle="tab"><span class="text-warning">Newly failing jobs ([% nowFail.size %])</span></a></li> <li class="nav-item"><a class="nav-link" href="#tabs-now-fail" data-toggle="tab"><span class="text-warning">Newly failing jobs ([% nowFail.size %])</span></a></li>
[% END %] [% END %]
[% IF nowSucceed.size > 0 %] [% IF nowSucceed.size > 0 %]
<li><a href="#tabs-now-succeed" data-toggle="tab"><span class="text-success">Newly succeeding jobs ([% nowSucceed.size %])</span></a></li> <li class="nav-item"><a class="nav-link" href="#tabs-now-succeed" data-toggle="tab"><span class="text-success">Newly succeeding jobs ([% nowSucceed.size %])</span></a></li>
[% END %] [% END %]
[% IF new.size > 0 %] [% IF new.size > 0 %]
<li><a href="#tabs-new" data-toggle="tab">New jobs ([% new.size %])</a></li> <li class="nav-item"><a class="nav-link" href="#tabs-new" data-toggle="tab">New jobs ([% new.size %])</a></li>
[% END %] [% END %]
[% IF removed.size > 0 %] [% IF removed.size > 0 %]
<li><a href="#tabs-removed" data-toggle="tab">Removed jobs ([% removed.size %])</a></li> <li class="nav-item"><a class="nav-link" href="#tabs-removed" data-toggle="tab">Removed jobs ([% removed.size %])</a></li>
[% END %] [% END %]
[% IF stillFail.size > 0 %] [% IF stillFail.size > 0 %]
<li><a href="#tabs-still-fail" data-toggle="tab">Still failing jobs ([% stillFail.size %])</a></li> <li class="nav-item"><a class="nav-link" href="#tabs-still-fail" data-toggle="tab">Still failing jobs ([% stillFail.size %])</a></li>
[% END %] [% END %]
[% IF stillSucceed.size > 0 %] [% IF stillSucceed.size > 0 %]
<li><a href="#tabs-still-succeed" data-toggle="tab">Still succeeding jobs ([% stillSucceed.size %])</a></li> <li class="nav-item"><a class="nav-link" href="#tabs-still-succeed" data-toggle="tab">Still succeeding jobs ([% stillSucceed.size %])</a></li>
[% END %] [% END %]
[% IF unfinished.size > 0 %] [% IF unfinished.size > 0 %]
<li><a href="#tabs-unfinished" data-toggle="tab">Queued jobs ([% unfinished.size %])</a></li> <li class="nav-item"><a class="nav-link" href="#tabs-unfinished" data-toggle="tab">Queued jobs ([% unfinished.size %])</a></li>
[% END %] [% END %]
<li><a href="#tabs-inputs" data-toggle="tab">Inputs</a></li> <li class="nav-item"><a class="nav-link" href="#tabs-inputs" data-toggle="tab">Inputs</a></li>
[% IF eval.evaluationerror.errormsg %] [% IF eval.evaluationerror.errormsg %]
<li><a href="#tabs-errors" data-toggle="tab"><span class="text-warning">Evaluation errors</span></a></li> <li class="nav-item"><a class="nav-link" href="#tabs-errors" data-toggle="tab"><span class="text-warning">Evaluation errors</span></a></li>
[% END %] [% END %]
</ul> </ul>
[% BLOCK renderSome %] [% BLOCK renderSome %]
@ -111,7 +109,7 @@ c.uri_for(c.controller('JobsetEval').action_for('view'),
[% IF eval.evaluationerror.errormsg %] [% IF eval.evaluationerror.errormsg %]
<div id="tabs-errors" class="tab-pane"> <div id="tabs-errors" class="tab-pane">
<p>Errors occurred at [% INCLUDE renderDateTime timestamp=(eval.evaluationerror.errortime || eval.timestamp) %].</p> <p>Errors occurred at [% INCLUDE renderDateTime timestamp=(eval.evaluationerror.errortime || eval.timestamp) %].</p>
<pre class="alert alert-error">[% HTML.escape(eval.evaluationerror.errormsg) %]</pre> <div class="card bg-light"><div class="card-body"><pre>[% HTML.escape(eval.evaluationerror.errormsg) %]</pre></div></div>
</div> </div>
[% END %] [% END %]
@ -175,7 +173,7 @@ c.uri_for(c.controller('JobsetEval').action_for('view'),
[% IF eval.evaluationerror.errormsg %] [% IF eval.evaluationerror.errormsg %]
<div id="tabs-errors" class="tab-pane"> <div id="tabs-errors" class="tab-pane">
<p>Errors occurred at [% INCLUDE renderDateTime timestamp=(eval.evaluationerror.errortime || eval.timestamp) %].</p> <p>Errors occurred at [% INCLUDE renderDateTime timestamp=(eval.evaluationerror.errortime || eval.timestamp) %].</p>
<pre class="alert alert-error">[% HTML.escape(eval.evaluationerror.errormsg) %]</pre> <div class="card bg-light"><div class="card-body"><pre>[% HTML.escape(eval.evaluationerror.errormsg) %]</pre></div></div>
</div> </div>
[% END %] [% END %]
</div> </div>

View file

@ -1,12 +1,15 @@
[% PROCESS common.tt; USE Math %] [% PROCESS common.tt; USE Math %]
<form class="form-search" id="filter-jobs"> <form id="filter-jobs">
<div class="input-append"> <div class="form-group input-group">
<input name="filter" type="text" class="input-large search-query" placeholder="Search jobs by name..." [% HTML.attributes(value => filter) %]/> <input name="filter" type="search" class="form-control" placeholder="Search jobs by name..." [% HTML.attributes(value => filter) %]/>
<button type="button" class="btn btn-info [% IF showInactive %]active[% END %]" id="active-toggle">Show inactive jobs</button> <div class="input-group-append">
<button type="button" class="btn btn-info [% IF showInactive %]active[% END %]" id="active-toggle">
<span class="spinner-border spinner-border-sm" id="filter-loading" style="display:none"/>
Show inactive jobs
</button>
</div>
</div> </div>
&nbsp;
<img src="[% c.uri_for("/static/images/ajax-loader.gif") %]" alt="Loading..." style="display: none;" id="filter-loading" />
</form> </form>
<script> <script>
@ -33,12 +36,12 @@
[% IF jobs.size == 0 %] [% IF jobs.size == 0 %]
<div class="alert">There are no matching jobs.</div> <div class="alert alert-warning">There are no matching jobs.</div>
[% ELSE %] [% ELSE %]
[% IF nrJobs > jobs.size %] [% IF nrJobs > jobs.size %]
<div class="alert">Showing the first [% jobs.size %] jobs. <a href="javascript:setFilter('filter=%')">Show all [% nrJobs %] jobs...</a></div> <div class="alert alert-info">Showing the first [% jobs.size %] jobs. <a href="javascript:setFilter('filter=%')">Show all [% nrJobs %] jobs...</a></div>
[% END %] [% END %]
[% evalIds = evals.keys.nsort.reverse %] [% evalIds = evals.keys.nsort.reverse %]

View file

@ -43,12 +43,9 @@
<ul class="nav nav-tabs"> <ul class="nav nav-tabs">
[% IF c.user_exists %] [% IF c.user_exists %]
<li class="dropdown"> <li class="nav-item dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#"> <a class="nav-link dropdown-toggle" data-toggle="dropdown" href="#">Actions</a>
Actions <div class="dropdown-menu">
<b class="caret"></b>
</a>
<ul class="dropdown-menu">
[% UNLESS project.declfile %] [% 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="Edit configuration" icon="icon-edit" uri=c.uri_for(c.controller('Jobset').action_for('edit'), c.req.captures) %]
<!-- <!--
@ -57,18 +54,18 @@
[% INCLUDE menuItem title="Clone this jobset" uri=c.uri_for(c.controller('Jobset').action_for('edit'), c.req.captures, { cloneJobset => 1 }) %] [% INCLUDE menuItem title="Clone this jobset" uri=c.uri_for(c.controller('Jobset').action_for('edit'), c.req.captures, { cloneJobset => 1 }) %]
[% END %] [% END %]
[% INCLUDE menuItem title="Evaluate this jobset" uri="javascript:confirmEvaluateJobset()" %] [% INCLUDE menuItem title="Evaluate this jobset" uri="javascript:confirmEvaluateJobset()" %]
</ul> </div>
</li> </li>
[% END %] [% END %]
<li class="active"><a href="#tabs-evaluations" data-toggle="tab">Evaluations</a></li> <li class="nav-item"><a class="nav-link active" href="#tabs-evaluations" data-toggle="tab">Evaluations</a></li>
[% IF jobset.errormsg || jobset.fetcherrormsg %] [% IF jobset.errormsg || jobset.fetcherrormsg %]
<li><a href="#tabs-errors" data-toggle="tab"><span class="text-warning">Evaluation errors</span></a></li> <li class="nav-item"><a class="nav-link" href="#tabs-errors" data-toggle="tab"><span class="text-warning">Evaluation errors</span></a></li>
[% END %] [% END %]
<li><a href="#tabs-jobs" data-toggle="tab">Jobs</a></li> <li class="nav-item"><a class="nav-link" href="#tabs-jobs" data-toggle="tab">Jobs</a></li>
<li><a href="#tabs-configuration" data-toggle="tab">Configuration</a></li> <li class="nav-item"><a class="nav-link" href="#tabs-configuration" data-toggle="tab">Configuration</a></li>
<li><a href="#tabs-links" data-toggle="tab">Links</a></li> <li class="nav-item"><a class="nav-link" href="#tabs-links" data-toggle="tab">Links</a></li>
<li><a href="#tabs-channels" data-toggle="tab">Channels</a></li> <li class="nav-item"><a class="nav-link" href="#tabs-channels" data-toggle="tab">Channels</a></li>
</ul> </ul>
<div id="generic-tabs" class="tab-content"> <div id="generic-tabs" class="tab-content">
@ -120,7 +117,7 @@
[% IF jobset.errormsg || jobset.fetcherrormsg %] [% IF jobset.errormsg || jobset.fetcherrormsg %]
<div id="tabs-errors" class="tab-pane"> <div id="tabs-errors" class="tab-pane">
<p>Errors occurred at [% INCLUDE renderDateTime timestamp=(jobset.errortime || jobset.lastcheckedtime) %].</p> <p>Errors occurred at [% INCLUDE renderDateTime timestamp=(jobset.errortime || jobset.lastcheckedtime) %].</p>
<pre class="alert alert-error">[% HTML.escape(jobset.fetcherrormsg || jobset.errormsg) %]</pre> <div class="card bg-light"><div class="card-body"><pre>[% HTML.escape(jobset.fetcherrormsg || jobset.errormsg) %]</pre></div></div>
</div> </div>
[% END %] [% END %]

View file

@ -11,20 +11,20 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=Edge" /> <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<script type="text/javascript" src="[% c.uri_for("/static/js/jquery/jquery-1.12.3.min.js") %]"></script> <script type="text/javascript" src="[% c.uri_for("/static/js/jquery/jquery-3.4.1.min.js") %]"></script>
<script type="text/javascript" src="[% c.uri_for("/static/js/jquery/jquery-ui-1.10.4.min.js") %]"></script> <script type="text/javascript" src="[% c.uri_for("/static/js/jquery/jquery-ui-1.10.4.min.js") %]"></script>
<script type="text/javascript" src="[% c.uri_for("/static/js/moment/moment-2.24.0.min.js") %]"></script> <script type="text/javascript" src="[% c.uri_for("/static/js/moment/moment-2.24.0.min.js") %]"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link href="[% c.uri_for("/static/fontawesome/css/all.css") %]" rel="stylesheet" />
<script type="text/javascript" src="[% c.uri_for("/static/js/popper.min.js") %]"></script>
<script type="text/javascript" src="[% c.uri_for("/static/bootstrap/js/bootstrap.min.js") %]"></script> <script type="text/javascript" src="[% c.uri_for("/static/bootstrap/js/bootstrap.min.js") %]"></script>
<link href="[% c.uri_for("/static/bootstrap/css/bootstrap.min.css") %]" rel="stylesheet" /> <link href="[% c.uri_for("/static/bootstrap/css/bootstrap.min.css") %]" rel="stylesheet" />
<!-- hydra.css must be included before bootstrap-responsive to <!-- hydra.css may need to be moved to before boostrap to make the @media rule work. -->
make the @media rule work. -->
<link rel="stylesheet" href="[% c.uri_for("/static/css/hydra.css") %]" type="text/css" /> <link rel="stylesheet" href="[% c.uri_for("/static/css/hydra.css") %]" type="text/css" />
<link rel="stylesheet" href="[% c.uri_for("/static/css/rotated-th.css") %]" type="text/css" /> <link rel="stylesheet" href="[% c.uri_for("/static/css/rotated-th.css") %]" type="text/css" />
<link href="[% c.uri_for("/static/bootstrap/css/bootstrap-responsive.min.css") %]" rel="stylesheet" />
<style> <style>
.popover { max-width: 40%; } .popover { max-width: 40%; }
@ -46,27 +46,23 @@
<body> <body>
<div class="navbar navbar-fixed-top"> <nav class="navbar navbar-expand-md navbar-light bg-light">
<div class="navbar-inner">
<div class="container"> <div class="container">
<button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse"> <a class="navbar-brand" href="[% c.uri_for(c.controller('Root').action_for('index')) %]">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="brand" href="[% c.uri_for(c.controller('Root').action_for('index')) %]">
[% IF logo == "" %] [% IF logo == "" %]
Hydra Hydra
[% ELSE %] [% ELSE %]
<img src="[% c.uri_for(logo) %]" alt="Hydra Logo" class="logo" /> <img src="[% c.uri_for(logo) %]" alt="Hydra Logo" class="logo" />
[% END %] [% END %]
</a> </a>
<div class="nav-collapse collapse"> <button type="button" class="navbar-toggler" data-toggle="collapse" data-target="#navbarSupportedContent">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
[% PROCESS topbar.tt %] [% PROCESS topbar.tt %]
</div> </div>
</div> </div>
</div> </nav>
</div>
<div class="container"> <div class="container">
<div class="skip-topbar"></div> <div class="skip-topbar"></div>

View file

@ -18,9 +18,9 @@
[% END %] [% END %]
</p> </p>
<pre class="log" id="contents"> <div class="card bg-light"><div class="card-body"><pre class="log" id="contents">
<em>Loading...</em> <em>Loading...</em>
</pre> </pre></div></div>
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function() { $(document).ready(function() {

View file

@ -14,29 +14,25 @@
<tr> <tr>
<td>[% INCLUDE renderDateTime timestamp=i.createtime %]</td> <td>[% INCLUDE renderDateTime timestamp=i.createtime %]</td>
<td>[% contents.replace('\n','<br />\n') %]</td> <td>[% contents.replace('\n','<br />\n') %]</td>
<td>[% INCLUDE maybeLink uri = c.uri_for(c.controller('Admin').action_for('news_delete') i.id) content = "Delete" confirmmsg = "Are you sure you want to delete this news item?" class = "btn btn-mini btn-danger" %]</td> <td>[% INCLUDE maybeLink uri = c.uri_for(c.controller('Admin').action_for('news_delete') i.id) content = "Delete" confirmmsg = "Are you sure you want to delete this news item?" class = "btn btn-sm btn-danger" %]</td>
</tr> </tr>
[% END %] [% END %]
</tbody> </tbody>
</table> </table>
[% END %] [% END %]
<form class="form-horizontal" action="[% c.uri_for('/admin/news/submit') %]" method="post"> <form action="[% c.uri_for('/admin/news/submit') %]" method="post">
<fieldset> <div class="page-header">Add news item</div>
<legend>Add news item</legend>
<div class="control-group"> <div class="form-group">
<label class="control-label">News text (HTML)</label> <label for="newscontents">News text (HTML)</label>
<div class="controls"> <textarea class="form-control" id="newscontents" name="contents"></textarea>
<textarea class="span9" name="contents"></textarea>
</div> </div>
</div>
</fieldset>
<div class="form-actions">
<button type="submit" class="btn btn-primary"> <button type="submit" class="btn btn-primary">
<i class="icon-ok icon-white"></i> <i class="fas fa-check"></i>
Post Post
</button> </button>
</div>
</form> </form>
[% END %] [% END %]

View file

@ -40,7 +40,7 @@
</script> </script>
<p>The following projects are hosted on this server: <p>The following projects are hosted on this server:
<label id="show-disabled" class="btn btn-small pull-right" data-toggle="button">Show disabled projects</label> <label id="show-disabled" class="btn btn-secondary btn-sm float-right" data-toggle="button">Show disabled projects</label>
</p> </p>
<table class="table table-condensed table-striped clickable-rows"> <table class="table table-condensed table-striped clickable-rows">

View file

@ -5,6 +5,6 @@
[% jobset = build.jobset %] [% jobset = build.jobset %]
[% job = build.job %] [% job = build.job %]
<pre>[% HTML.escape(contents) %]</pre> <div class="card bg-light"><div class="card-body"><pre>[% HTML.escape(contents) %]</pre></div></div>
[% END %] [% END %]

View file

@ -54,11 +54,11 @@
</a> </a>
</td> </td>
<td> <td>
[% WRAPPER makePopover title="Help" classes="btn-mini" %] [% WRAPPER makePopover title="Help" classes="btn-secondary btn-sm" %]
<p>If you have Nix installed on your machine, this failed build output and <p>If you have Nix installed on your machine, this failed build output and
all its dependencies can be unpacked into your local Nix store by doing:</p> all its dependencies can be unpacked into your local Nix store by doing:</p>
<pre><span class="shell-prompt">$ </span>curl [% uri %] | gunzip | nix-store --import</pre> <div class="card bg-light"><div class="card-body p-2"><code><span class="shell-prompt">$ </span>curl [% uri %] | gunzip | nix-store --import</code></div></div>
<p>The build output can then be found in the path <tt>[% product.path %]</tt>.</p> <p>The build output can then be found in the path <tt>[% product.path %]</tt>.</p>
[% END %] [% END %]
@ -77,14 +77,14 @@
<tt>[% HTML.escape(build.nixname) %]</tt> <tt>[% HTML.escape(build.nixname) %]</tt>
</td> </td>
<td> <td>
[% WRAPPER makePopover title="Help" classes="btn-mini" [% WRAPPER makePopover title="Help" classes="btn-secondary btn-sm"
%] <p>You can install this package using the Nix package %] <p>You can install this package using the Nix package
manager from the command-line:</p> manager from the command-line:</p>
<pre><span class="shell-prompt">$ </span>nix-env -i [%HTML.escape(product.path)%][% IF binaryCachePublicUri %] --option binary-caches [% HTML.escape(binaryCachePublicUri) %][% END %]</pre> <div class="card bg-light"><div class="card-body p-2"><code><span class="shell-prompt">$ </span>nix-env -i [%HTML.escape(product.path)%][% IF binaryCachePublicUri %] --option binary-caches [% HTML.escape(binaryCachePublicUri) %][% END %]</code></div></div>
[% END %] [% END %]
[% IF localStore %] [% IF localStore %]
<a class="btn btn-mini" href="[% contents %]">Contents</a> <a class="btn btn-secondary btn-sm" href="[% contents %]">Contents</a>
[% END %] [% END %]
</td> </td>
</tr> </tr>
@ -105,21 +105,21 @@
</a> </a>
</td> </td>
<td> <td>
[% WRAPPER makePopover title="Help" classes="btn-mini" %] [% WRAPPER makePopover title="Help" classes="btn-secondary btn-sm" %]
<p>If you have Nix installed on your machine, this build and <p>If you have Nix installed on your machine, this build and
all its dependencies can be unpacked into your local Nix all its dependencies can be unpacked into your local Nix
store by doing:</p> store by doing:</p>
<pre><span class="shell-prompt">$ </span>gunzip &lt; [% filename %] | nix-store --import</pre> <div class="card bg-light"><div class="card-body p-2"><code><span class="shell-prompt">$ </span>gunzip &lt; [% filename %] | nix-store --import</code></div></div>
<p>or to download and unpack in one command:</p> <p>or to download and unpack in one command:</p>
<pre><span class="shell-prompt">$ </span>curl [% uri %] | gunzip | nix-store --import</pre> <div class="card bg-light"><div class="card-body p-2"><code><span class="shell-prompt">$ </span>curl [% uri %] | gunzip | nix-store --import</code></div></div>
<p>The package can then be found in the path <tt>[% <p>The package can then be found in the path <tt>[%
product.path %]</tt>. Youll probably also want to do</p> product.path %]</tt>. Youll probably also want to do</p>
<pre><span class="shell-prompt">$ </span>nix-env -i [% product.path %]</pre> <div class="card bg-light"><div class="card-body p-2"><code><span class="shell-prompt">$ </span>nix-env -i [% product.path %]</code></div></div>
<p>to actually install the package in your Nix user environment.</p> <p>to actually install the package in your Nix user environment.</p>
@ -187,7 +187,7 @@
</a> </a>
</td> </td>
<td> <td>
[% WRAPPER makePopover title="Details" classes="btn-mini" %] [% WRAPPER makePopover title="Details" classes="btn-secondary btn-sm" %]
<table class="info-table"> <table class="info-table">
[% INCLUDE renderProductLinks %] [% INCLUDE renderProductLinks %]
<tr><th>File size:</th><td>[% product.filesize %] bytes ([% mibs(product.filesize / (1024 * 1024)) %] MiB)</td></tr> <tr><th>File size:</th><td>[% product.filesize %] bytes ([% mibs(product.filesize / (1024 * 1024)) %] MiB)</td></tr>
@ -196,7 +196,7 @@
</table> </table>
[% END %] [% END %]
[% IF localStore %] [% IF localStore %]
<a class="btn btn-mini" href="[% contents %]">Contents</a> <a class="btn btn-secondary btn-sm" href="[% contents %]">Contents</a>
[% END %] [% END %]
</td> </td>
</tr> </tr>
@ -254,7 +254,7 @@
</a> </a>
</td> </td>
<td> <td>
[% WRAPPER makePopover title="Details" classes="btn-mini" %] [% WRAPPER makePopover title="Details" classes="btn-secondary btn-sm" %]
<table class="info-table"> <table class="info-table">
[% INCLUDE renderProductLinks %] [% INCLUDE renderProductLinks %]
</table> </table>

View file

@ -3,23 +3,20 @@
<ul class="nav nav-tabs"> <ul class="nav nav-tabs">
[% IF c.user_exists %] [% IF c.user_exists %]
<li class="dropdown"> <li class="nav-item dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#"> <a class="nav-link dropdown-toggle" data-toggle="dropdown" href="#">Actions</a>
Actions <div class="dropdown-menu">
<b class="caret"></b>
</a>
<ul class="dropdown-menu">
[% INCLUDE menuItem title="Edit configuration" icon="icon-edit" uri=c.uri_for(c.controller('Project').action_for('edit'), c.req.captures) %] [% INCLUDE menuItem title="Edit configuration" icon="icon-edit" uri=c.uri_for(c.controller('Project').action_for('edit'), c.req.captures) %]
[% INCLUDE menuItem title="Delete this project" icon="icon-trash" uri="javascript:deleteProject()" %] [% INCLUDE menuItem title="Delete this project" icon="icon-trash" uri="javascript:deleteProject()" %]
[% UNLESS project.declfile %] [% UNLESS project.declfile %]
[% INCLUDE menuItem title="Create jobset" icon="icon-plus" uri=c.uri_for(c.controller('Project').action_for('create_jobset'), c.req.captures) %] [% INCLUDE menuItem title="Create jobset" icon="icon-plus" uri=c.uri_for(c.controller('Project').action_for('create_jobset'), c.req.captures) %]
[% END %] [% END %]
</ul> </div>
</li> </li>
[% END %] [% END %]
<li class="active"><a href="#tabs-project" data-toggle="tab">Jobsets</a></li> <li class="nav-item"><a class="nav-link active" href="#tabs-project" data-toggle="tab">Jobsets</a></li>
<li><a href="#tabs-configuration" data-toggle="tab">Configuration</a></li> <li class="nav-item"><a class="nav-link" href="#tabs-configuration" data-toggle="tab">Configuration</a></li>
</ul> </ul>
<div class="tab-content"> <div class="tab-content">
@ -50,12 +47,17 @@
<div id="tabs-project" class="tab-pane active"> <div id="tabs-project" class="tab-pane active">
[% IF project.jobsets %] [% IF project.jobsets %]
<p>This project has the following jobsets: <div class="row">
<label id="show-disabled" class="btn btn-small pull-right" data-toggle="button">Show disabled jobsets</label> <div class="col">
This project has the following jobsets:
</div>
<div class="col-auto">
<label id="show-disabled" class="btn btn-secondary" data-toggle="button">Show disabled jobsets</label>
[% IF isProjectOwner %] [% IF isProjectOwner %]
<label id="show-hidden" class="btn btn-small pull-right" data-toggle="button">Show hidden jobsets</label> <label id="show-hidden" class="btn btn-secondary" data-toggle="button">Show hidden jobsets</label>
[% END %] [% END %]
</p> </div>
</div>
[% INCLUDE renderJobsetOverview %] [% INCLUDE renderJobsetOverview %]
[% ELSE %] [% ELSE %]
<p>No jobsets have been defined yet.</p> <p>No jobsets have been defined yet.</p>

View file

@ -1,8 +1,6 @@
[% WRAPPER layout.tt title="Queue runner status" %] [% WRAPPER layout.tt title="Queue runner status" %]
[% PROCESS common.tt %] [% PROCESS common.tt %]
<pre> <div class="card bg-light"><div class="card-body"><pre>[% HTML.escape(status) %]</pre></div></div>
[% HTML.escape(status) %]
</pre>
[% END %] [% END %]

View file

@ -81,7 +81,7 @@
[% IF builds.size > 0 || buildsdrv.size > 0 ; matched = 1 ; END %] [% IF builds.size > 0 || buildsdrv.size > 0 ; matched = 1 ; END %]
[% IF !matched %] [% IF !matched %]
<div class="alert alert-warn">Sorry! Nothing matches your query.</div> <div class="alert alert-warning">Sorry! Nothing matches your query.</div>
[% END %] [% END %]
[% END %] [% END %]

View file

@ -33,12 +33,6 @@ span:target > span.dep-tree-line {
font-weight: bold; font-weight: bold;
} }
:target {
padding-top: 40px;
margin-top: -40px;
display: inline-block; /* required for webkit browsers */
}
span.disabled-project, span.disabled-jobset, span.disabled-job { span.disabled-project, span.disabled-jobset, span.disabled-job {
text-decoration: line-through; text-decoration: line-through;
} }
@ -52,11 +46,6 @@ table.info-table th {
padding-bottom: 0.2em; padding-bottom: 0.2em;
} }
/* Missing in bootstrap 2.0.2 */
.text-warning {
color: #c09853;
}
table.clickable-rows > tbody > tr { table.clickable-rows > tbody > tr {
cursor: pointer; cursor: pointer;
} }
@ -152,3 +141,7 @@ td.step-status span.warn {
cursor: help; cursor: help;
border-bottom: 1px dotted #999; border-bottom: 1px dotted #999;
} }
.tab-content > .tab-pane {
padding-top: 1.5rem;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

File diff suppressed because one or more lines are too long

View file

@ -46,29 +46,30 @@ $(document).ready(function() {
window.location = link.attr("href"); window.location = link.attr("href");
}); });
bootbox.animate(false); bootbox.setDefaults({ animate: false });
/* Enable popovers (and allow table and teletype elements in them). */
$.fn.popover.Constructor.Default.whiteList.table = [];
$.fn.popover.Constructor.Default.whiteList.thead = []
$.fn.popover.Constructor.Default.whiteList.tbody = [];
$.fn.popover.Constructor.Default.whiteList.tr = [];
$.fn.popover.Constructor.Default.whiteList.th = [];
$.fn.popover.Constructor.Default.whiteList.td = [];
$.fn.popover.Constructor.Default.whiteList.tt = [];
$(".hydra-popover").popover({}); $(".hydra-popover").popover({});
$(function() { /* Activates tab according to URL anchor. */
if (window.location.hash) { if (window.location.hash) {
$(".nav-tabs a[href='" + window.location.hash + "']").tab('show'); $('.nav-tabs > .nav-item:not(.dropdown) a[href="' + window.location.hash + '"]').tab('show');
} }
/* If no tab is active, show the first one. */ $('.nav-tabs').each(function() {
$(".nav-tabs").each(function() { if ($('.nav-item:not(.dropdown) a.active',this).length == 0)
if ($("li.active", this).length > 0) return; $('.nav-item:not(.dropdown) a',this).first().tab('show');
$("a", $(this).children("li:not(.dropdown)").first()).tab('show');
}); });
/* Ensure that pressing the back button on another page $('.nav-tabs > .nav-item:not(.dropdown) a[href^="#"]').on('click', function() {
navigates back to the previously selected tab on this history.replaceState(null, null, window.location.href.split("#")[0] + $(this).attr("href"));
page. */
$('.nav-tabs').bind('show', function(e) {
var pattern = /#.+/gi;
var id = e.target.toString().match(pattern)[0];
history.replaceState(null, "", id);
});
}); });
/* Automatically set Bootstrap radio buttons from hidden form controls. */ /* Automatically set Bootstrap radio buttons from hidden form controls. */
@ -131,7 +132,7 @@ $(document).ready(function() {
var tabsLoaded = {}; var tabsLoaded = {};
function makeLazyTab(tabName, uri) { function makeLazyTab(tabName, uri) {
$('.nav-tabs').bind('show', function(e) { $('.nav-tabs').bind('show.bs.tab', function(e) {
var pattern = /#.+/gi; var pattern = /#.+/gi;
var id = e.target.toString().match(pattern)[0]; var id = e.target.toString().match(pattern)[0];
if (id == '#' + tabName && !tabsLoaded[id]) { if (id == '#' + tabName && !tabsLoaded[id]) {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

4
src/root/static/js/popper.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View file

@ -1,18 +1,18 @@
[% BLOCK makeSubMenu %] [% BLOCK makeSubMenu %]
<li class="dropdown" [% IF id; HTML.attributes(id => id); END %] > <li class="nav-item dropdown" [% IF id; HTML.attributes(id => id); END %] >
<a class="dropdown-toggle" href="#" data-toggle="dropdown">[% title %]<b class="caret"></b></a> <a class="nav-link dropdown-toggle" href="#" data-toggle="dropdown">[% title %]<b class="caret"></b></a>
<ul class="dropdown-menu"> <div class="dropdown-menu[% IF align == 'right' %] dropdown-menu-right[% END %]">
[% content %] [% content %]
</ul> </div>
</li> </li>
[% END %] [% END %]
[% showPrivate = (isPrivateHydra && c.user_exists) || ! isPrivateHydra %] [% showPrivate = (isPrivateHydra && c.user_exists) || ! isPrivateHydra %]
[% IF showPrivate %] [% IF showPrivate %]
<ul class="nav pull-left"> <ul class="navbar-nav mr-auto">
[% IF c.user_exists %] [% IF c.user_exists %]
[% INCLUDE menuItem uri = c.uri_for(c.controller('User').action_for('dashboard'), [c.user.username]) title = "Dashboard" %] [% INCLUDE navItem uri = c.uri_for(c.controller('User').action_for('dashboard'), [c.user.username]) title = "Dashboard" %]
[% END %] [% END %]
[% WRAPPER makeSubMenu title="Status" %] [% WRAPPER makeSubMenu title="Status" %]
@ -38,8 +38,8 @@
[% IF project %] [% IF project %]
[% WRAPPER makeSubMenu title="Project" %] [% WRAPPER makeSubMenu title="Project" %]
<li class="nav-header">[% HTML.escape(project.name) %]</li> <h6 class="dropdown-header">[% HTML.escape(project.name) %]</h6>
<li class="divider"></li> <div class="dropdown-divider"></div>
[% INCLUDE menuItem uri = c.uri_for(c.controller('Project').action_for('project'), [project.name]) title = "Overview" %] [% INCLUDE menuItem uri = c.uri_for(c.controller('Project').action_for('project'), [project.name]) title = "Overview" %]
[% INCLUDE menuItem uri = c.uri_for(c.controller('Project').action_for('all'), [project.name]) title = "Latest builds" %] [% INCLUDE menuItem uri = c.uri_for(c.controller('Project').action_for('all'), [project.name]) title = "Latest builds" %]
[% INCLUDE menuItem uri = c.uri_for('/project' project.name 'channel' 'latest') title = "Channel" %] [% INCLUDE menuItem uri = c.uri_for('/project' project.name 'channel' 'latest') title = "Channel" %]
@ -48,8 +48,8 @@
[% IF jobset %] [% IF jobset %]
[% WRAPPER makeSubMenu title="Jobset" %] [% WRAPPER makeSubMenu title="Jobset" %]
<li class="nav-header">[% HTML.escape(jobset.name) %]</li> <h6 class="dropdown-header">[% HTML.escape(jobset.name) %]</h6>
<li class="divider"></li> <div class="dropdown-divider"></div>
[% INCLUDE menuItem [% INCLUDE menuItem
uri = c.uri_for(c.controller('Jobset').action_for('jobset'), [project.name, jobset.name]) uri = c.uri_for(c.controller('Jobset').action_for('jobset'), [project.name, jobset.name])
title = "Overview" %] title = "Overview" %]
@ -65,8 +65,8 @@
[% IF job %] [% IF job %]
[% WRAPPER makeSubMenu title="Job" %] [% WRAPPER makeSubMenu title="Job" %]
<li class="nav-header">[% HTML.escape(job) %]</li> <h6 class="dropdown-header">[% HTML.escape(job) %]</h6>
<li class="divider"></li> <div class="dropdown-divider"></div>
[% INCLUDE menuItem [% INCLUDE menuItem
uri = c.uri_for(c.controller('Job').action_for('overview'), [project.name, jobset.name, job]) uri = c.uri_for(c.controller('Job').action_for('overview'), [project.name, jobset.name, job])
title = "Overview" %] title = "Overview" %]
@ -82,7 +82,7 @@
[% WRAPPER makeSubMenu title="Admin" %] [% WRAPPER makeSubMenu title="Admin" %]
[% IF c.check_user_roles('admin') || c.check_user_roles('create-projects') %] [% IF c.check_user_roles('admin') || c.check_user_roles('create-projects') %]
[% INCLUDE menuItem uri = c.uri_for(c.controller('Project').action_for('create')) title = "Create project" %] [% INCLUDE menuItem uri = c.uri_for(c.controller('Project').action_for('create')) title = "Create project" %]
<li class="divider"></li> <div class="dropdown-divider"></div>
[% END %] [% END %]
[% IF c.check_user_roles('admin') %] [% IF c.check_user_roles('admin') %]
[% INCLUDE menuItem [% INCLUDE menuItem
@ -94,7 +94,7 @@
[% INCLUDE menuItem [% INCLUDE menuItem
uri = c.uri_for(c.controller('Admin').action_for('users')) uri = c.uri_for(c.controller('Admin').action_for('users'))
title = "Manage users" %] title = "Manage users" %]
<li class="divider"></li> <div class="dropdown-divider"></div>
[% INCLUDE menuItem [% INCLUDE menuItem
uri = c.uri_for(c.controller('Admin').action_for('clear_queue_non_current')) uri = c.uri_for(c.controller('Admin').action_for('clear_queue_non_current'))
title = "Cancel queued non-current builds" title = "Cancel queued non-current builds"
@ -117,32 +117,31 @@
</ul> </ul>
[% END %] [% END %]
<ul class="nav pull-right"> [% IF showPrivate %]
<form class="form-inline" action="[% c.uri_for('/search') %]">
[% IF showPrivate %] <input name="query" type="text" class="form-control" placeholder="Search" [% HTML.attributes(value => c.req.params.query) %]/>
<form class="navbar-search" action="[% c.uri_for('/search') %]">
<input name="query" type="text" class="search-query span2" placeholder="Search" [% HTML.attributes(value => c.req.params.query) %]/>
</form> </form>
[% END %] [% END %]
<ul class="navbar-nav">
[% IF c.user_exists %] [% IF c.user_exists %]
[% INCLUDE menuItem uri = c.uri_for(c.controller('User').action_for('edit'), [c.user.username]) title = "Preferences" %] [% INCLUDE navItem uri = c.uri_for(c.controller('User').action_for('edit'), [c.user.username]) title = "Preferences" %]
<li> <li class="nav-item">
<a href="#" onclick="signOut();">Sign out</a> <a class="nav-link" href="#" onclick="signOut();">Sign out</a>
</li> </li>
[% ELSE %] [% ELSE %]
[% WRAPPER makeSubMenu title="Sign in" id="sign-in-menu" %] [% WRAPPER makeSubMenu title="Sign in" id="sign-in-menu" align="right" %]
[% IF c.config.enable_google_login %] [% IF c.config.enable_google_login %]
<div style="display: none" class="g-signin2" data-onsuccess="onGoogleSignIn" data-theme="dark"></div></a> <div style="display: none" class="g-signin2" data-onsuccess="onGoogleSignIn" data-theme="dark"></div>
<li><a href="#" id="google-signin">Sign in with Google</a></li> <a class="dropdown-item" href="#" id="google-signin">Sign in with Google</a>
<li class="divider"></li> <div class="dropdown-divider"></div>
[% END %] [% END %]
[% IF c.config.github_client_id %] [% IF c.config.github_client_id %]
<li><a href="/github-redirect?after=[% c.req.path %]">Sign in with GitHub</a></li> <a class="dropdown-item" href="/github-redirect?after=[% c.req.path %]">Sign in with GitHub</a>
<li class="divider"></li> <div class="dropdown-divider"></div>
[% END %] [% END %]
<li> <a class="dropdown-item" href="#hydra-signin" data-toggle="modal">Sign in with a Hydra account</a>
<a href="#hydra-signin" data-toggle="modal">Sign in with a Hydra account</a>
</li>
[% END %] [% END %]
[% END %] [% END %]

View file

@ -14,70 +14,66 @@
>[% role %]</option> >[% role %]</option>
[% END %] [% END %]
<form class="form-horizontal"> <form>
<fieldset>
[% IF create %] [% IF create %]
<div class="control-group"> <div class="form-group row">
<label class="control-label">User name</label> <label class="col-sm-3" for="userusername">User name</label>
<div class="controls"> <div class="col-sm-9">
<input type="text" class="span3" name="username" [% HTML.attributes(value => username) %]/> <input type="text" class="form-control" id="userusername" name="username" [% HTML.attributes(value => username) %]/>
</div> </div>
</div> </div>
[% END %] [% END %]
<div class="control-group"> <div class="form-group row">
<label class="control-label">Full name</label> <label class="col-sm-3" for="userfullname">Full name</label>
<div class="controls"> <div class="col-sm-9">
<input type="text" class="span3" name="fullname" [% HTML.attributes(value => create ? '' : user.fullname) %]/> <input type="text" class="form-control" id="userfullname" name="fullname" [% HTML.attributes(value => create ? '' : user.fullname) %]/>
</div> </div>
</div> </div>
[% IF create || user.type == 'hydra' %] [% IF create || user.type == 'hydra' %]
<div class="control-group"> <div class="form-group row">
<label class="control-label">Password</label> <label class="col-sm-3" for="userpassword">Password</label>
<div class="controls"> <div class="col-sm-9">
<input type="password" class="span3" name="password" value=""/> <input type="password" class="form-control" id="userpassword" name="password" value=""/>
</div> </div>
</div> </div>
<div class="control-group"> <div class="form-group row">
<label class="control-label">Confirm password</label> <label class="col-sm-3" for="userpassword2">Confirm password</label>
<div class="controls"> <div class="col-sm-9">
<input type="password" class="span3" name="password2" value=""/> <input type="password" class="form-control" id="userpassword2" name="password2" value=""/>
</div> </div>
</div> </div>
[% END %] [% END %]
<div class="control-group"> <div class="form-group row">
<label class="control-label">Email</label> <label class="col-sm-3" for="useremailaddress">Email</label>
<div class="controls"> <div class="col-sm-9">
<input type="text" class="span3" name="emailaddress" [% IF !create && user.username.search('@') %]disabled="disabled"[% END %] [%+ HTML.attributes(value => user.emailaddress) %]/> <input type="text" class="form-control" id="useremailaddress" name="emailaddress" [% IF !create && user.username.search('@') %]disabled="disabled"[% END %] [%+ HTML.attributes(value => user.emailaddress) %]/>
</div> </div>
</div> </div>
<div class="control-group"> <div class="form-group row">
<div class="controls"> <label class="col-sm-3" for="useremailonerror">Receive evaluation error notifications</label>
<label class="checkbox"> <div class="col-sm-9">
<input type="checkbox" name="emailonerror" [% IF !create && user.emailonerror; 'checked="checked"'; END %]/>Receive evaluation error notifications <input type="checkbox" name="emailonerror" [% IF !create && user.emailonerror; 'checked="checked"'; END %]/>
</label>
</div> </div>
</div> </div>
<div class="control-group"> <div class="form-group row">
<div class="controls"> <label class="col-sm-3" for="userpublicdashboard">Public dashboard</label>
<label class="checkbox"> <div class="col-sm-9">
<input type="checkbox" name="publicdashboard" [% IF !create && user.publicdashboard; 'checked="checked"'; END %]/>Public dashboard <input type="checkbox" name="publicdashboard" [% IF !create && user.publicdashboard; 'checked="checked"'; END %]/>
</label>
</div> </div>
</div> </div>
[% IF !create || c.check_user_roles('admin') %] [% IF !create || c.check_user_roles('admin') %]
<div class="control-group"> <div class="form-group row">
<label class="control-label">Roles</label> <label class="col-sm-3">Roles</label>
<div class="controls"> <div class="col-sm-9">
<select multiple="multiple" name="roles" class="span3" [% IF !c.check_user_roles('admin') %]disabled="disabled"[% END %]> <select multiple="multiple" name="roles" class="form-control" [% IF !c.check_user_roles('admin') %]disabled="disabled"[% END %]>
[% INCLUDE roleoption role="admin" %] [% INCLUDE roleoption role="admin" %]
[% INCLUDE roleoption role="create-projects" %] [% INCLUDE roleoption role="create-projects" %]
[% INCLUDE roleoption role="restart-jobs" %] [% INCLUDE roleoption role="restart-jobs" %]
@ -89,40 +85,36 @@
[% END %] [% END %]
[% IF create && !c.check_user_roles('admin') %] [% IF create && !c.check_user_roles('admin') %]
<div class="control-group"> <div class="form-group row">
<div class="controls"> <label class="col-sm-3"></label>
<img src="[% c.uri_for('/captcha') %]" alt="CAPTCHA"/> <div class="col-sm-9">
<img src="[% c.uri_for('/captcha') %]" alt="CAPTCHA">
</div> </div>
</div> </div>
<div class="form-group row">
<div class="control-group"> <label class="col-sm-3" for="usercaptcha">Type the digits shown in the image above</label>
<label class="control-label">Type the digits shown in the image above</label> <div class="col-sm-9">
<div class="controls"> <input type="text" class="form-control" id="usercaptcha" name="captcha" value="">
<input type="text" class="span3" name="captcha" value=""/>
</div> </div>
</div> </div>
[% END %] [% END %]
<div class="form-actions">
<button id="submit-user" class="btn btn-primary"> <button id="submit-user" class="btn btn-primary">
<i class="icon-ok icon-white"></i> <i class="fas fa-check"></i>
[%IF create %]Create[% ELSE %]Apply changes[% END %] [%IF create %]Create[% ELSE %]Apply changes[% END %]
</button> </button>
[% IF !create && c.check_user_roles('admin') && user.type == 'hydra' %] [% IF !create && c.check_user_roles('admin') && user.type == 'hydra' %]
<button id="reset-password" class="btn btn-warning"> <button id="reset-password" class="btn btn-warning">
<i class="icon-trash icon-white"></i> <i class="fas fa-lock"></i>
Reset password Reset password
</button> </button>
[% END %] [% END %]
[% IF !create %] [% IF !create %]
<button id="delete-user" class="btn btn-danger"> <button id="delete-user" class="btn btn-danger">
<i class="icon-trash icon-white"></i> <i class="fas fa-trash"></i>
Delete this user Delete this user
</button> </button>
[% END %] [% END %]
</div>
</fieldset>
</form> </form>

View file

@ -24,8 +24,8 @@
</tbody> </tbody>
</table> </table>
<p><a class="btn" href="[% c.uri_for(c.controller('Root').action_for('register')) %]"> <a class="btn btn-primary" href="[% c.uri_for(c.controller('Root').action_for('register')) %]">
<i class="icon-plus"></i> Add a new user <i class="fas fa-plus"></i> Add a new user
</a></p> </a>
[% END %] [% END %]