1
0
mirror of https://github.com/ohwgiles/laminar.git synced 2025-06-13 12:54:29 +00:00

Finish semantic UI refresh

This commit is contained in:
Cameron Eagans 2020-03-03 16:09:08 -07:00
parent da44c86a63
commit 5bb5fbd0ca
2 changed files with 200 additions and 151 deletions

View File

@ -1,41 +1,41 @@
#app { #app {
height: 100%; height: 100%;
} }
#app aside { #app aside {
background-color: #eeeeee; background-color: #eeeeee;
height: 100%; height: 100%;
} }
@media only screen and (min-width: 768px) { @media only screen and (min-width: 768px) {
#app .main.grid { #app .main.grid {
height: 100%; height: 100%;
} }
#app .jobs.list { #app .jobs.list {
-webkit-box-shadow: 3px 0px 5px 0px rgba(50, 50, 50, 0.25); -webkit-box-shadow: 3px 0px 5px 0px rgba(50, 50, 50, 0.25);
-moz-box-shadow: 3px 0px 5px 0px rgba(50, 50, 50, 0.25); -moz-box-shadow: 3px 0px 5px 0px rgba(50, 50, 50, 0.25);
box-shadow: 3px 0px 5px 0px rgba(50, 50, 50, 0.25); box-shadow: 3px 0px 5px 0px rgba(50, 50, 50, 0.25);
} }
} }
#popup-connecting { #popup-connecting {
position: fixed; position: fixed;
bottom: 10px; bottom: 10px;
right: 10px; right: 10px;
padding: 20px; padding: 20px;
} }
canvas { canvas {
width: 100% !important; width: 100% !important;
max-width: 800px; max-width: 800px;
height: auto !important; height: auto !important;
} }
li.chart-overlay { li.chart-overlay {
position: absolute; position: absolute;
display: inline-block; display: inline-block;
background: white; background: white;
border: 1px solid lightgray; border: 1px solid lightgray;
padding: 3px; padding: 3px;
} }

View File

@ -14,7 +14,6 @@
<script src="https://cdn.jsdelivr.net/npm/ansi_up@1.3.0/ansi_up.js" integrity="sha256-2UR0QYPMTIY0yP5S6ubBS7wFNKhn8uW7pV5E3LlvI6U=" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/ansi_up@1.3.0/ansi_up.js" integrity="sha256-2UR0QYPMTIY0yP5S6ubBS7wFNKhn8uW7pV5E3LlvI6U=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.3/dist/Chart.min.js" integrity="sha256-R4pqcOYV8lt7snxMQO/HSbVCFRPMdrhAFMH+vr9giYI=" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.3/dist/Chart.min.js" integrity="sha256-R4pqcOYV8lt7snxMQO/HSbVCFRPMdrhAFMH+vr9giYI=" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/semantic.min.css" integrity="sha256-UXesixbeLkB/UYxVTzuj/gg3+LMzgwAmg3zD+C4ZASQ=" crossorigin="anonymous"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/semantic.min.css" integrity="sha256-UXesixbeLkB/UYxVTzuj/gg3+LMzgwAmg3zD+C4ZASQ=" crossorigin="anonymous">
<link href="css/app.css" rel="stylesheet">
<link href="custom/style.css" rel="stylesheet"> <link href="custom/style.css" rel="stylesheet">
<script src="js/app.js" defer></script> <script src="js/app.js" defer></script>
</head> </head>
@ -23,7 +22,7 @@
<template id="home"> <template id="home">
<div class="ui stackable vertically padded grid"> <div class="ui stackable vertically padded grid">
<aside class="four wide column jobs list"> <aside class="four wide column jobs list">
<h3 class="ui header">Jobs</h3> <h2 class="ui header">Jobs</h2>
<div class="ui grey segment" v-for="job in jobsQueued"> <div class="ui grey segment" v-for="job in jobsQueued">
<p><router-link :to="'/jobs/'+job.name">{{job.name}}</router-link> queued</p> <p><router-link :to="'/jobs/'+job.name">{{job.name}}</router-link> queued</p>
</div> </div>
@ -139,143 +138,193 @@
</div> </div>
</template> </template>
<template id="jobs"><div> <template id="jobs">
<ol class="breadcrumb"><li><router-link to="/">Home</router-link></li><li class="active">Jobs</li></ol> <main class="ui stackable vertically padded fourteen wide column">
<div class="container-fluid"><div class="row"> <div class="ui basic segment masthead">
<div class="col-xs-12"> <h2 class="ui header">Jobs</h2>
<div class="pull-right"> </div>
<input class="form-control" id="jobFilter" v-model="search" placeholder="Filter..."> <div class="ui secondary pointing menu">
</div> <a v-show="ungrouped.length" :class="{'active':group==null}" v-on:click.prevent="group = null" class="item">Ungrouped jobs</a>
<ul class="nav nav-tabs"> <a v-for="g in Object.keys(groups)" :class="{'active':g==group}" href v-on:click.prevent="group = g" class="item">{{g}}</a>
<li v-show="ungrouped.length" :class="{'active':group==null}"><a href v-on:click.prevent="group = null">Ungrouped Jobs</a></li> <div class="right menu">
<li v-for="g in Object.keys(groups)" :class="{'active':g==group}"><a href v-on:click.prevent="group = g">{{g}}</a></li> <div class="item">
</ul> <div class="ui transparent icon input">
<table class="table table-striped" id="joblist"> <input id="jobFilter" v-model="search" type="text" placeholder="Filter...">
<tr v-for="job in filteredJobs()"> <i class="search link icon"></i>
<td><router-link :to="'/jobs/'+job.name">{{job.name}}</router-link></td> </div>
<td class="text-center"><span v-html="runIcon(job.result)"></span> <router-link :to="'/jobs/'+job.name+'/'+job.number">#{{job.number}}</router-link></td> </div>
<td class="text-center">{{formatDate(job.started)}}</td> </div>
<td class="text-center">{{formatDuration(job.started,job.completed)}}</td> </div>
</tr> <table class="ui striped table" id="joblist">
</table> <thead>
</div> <tr>
</div></div> <th class="four wide">Job</th>
</div></template> <th>Last run</th>
</tr>
<template id="job"><div> </thead>
<ol class="breadcrumb"><li><router-link to="/">Home</router-link></li><li><router-link to="/jobs">Jobs</router-link></li><li class="active">{{$route.params.name}}</li></ol></ol> <tbody>
<div class="container-fluid"> <tr v-for="job in filteredJobs()">
<div class="row"> <td><router-link :to="'/jobs/'+job.name">{{job.name}}</router-link></td>
<div class="col-sm-5 col-md-6 col-lg-7"> <td>
<h3>{{$route.params.name}}</h3> <router-link :to="'/jobs/'+job.name+'/'+job.number">#{{job.number}}</router-link>: <span v-html="job.result ? job.result : 'pending'"></span><br />
<div v-html="description"></div> Started at {{formatDate(job.started)}} and ran for {{formatDuration(job.started,job.completed)}}
<dl class="dl-horizontal"> </td>
<dt>Last Successful Run</dt> </tr>
<dd><router-link v-if="lastSuccess" :to="'/jobs/'+$route.params.name+'/'+lastSuccess.number">#{{lastSuccess.number}}</router-link> {{lastSuccess?' - at '+formatDate(lastSuccess.started):'never'}}</dd> </tbody>
<dt>Last Failed Run</dt> </table>
<dd><router-link v-if="lastFailed" :to="'/jobs/'+$route.params.name+'/'+lastFailed.number">#{{lastFailed.number}}</router-link> {{lastFailed?' - at '+formatDate(lastFailed.started):'never'}}</dd>
</dl>
</div>
<div class="col-sm-7 col-md-6 col-lg-5">
<div class="panel panel-default">
<div class="panel-heading">Build time</div>
<div class="panel-body">
<canvas id="chartBt"></canvas>
</div> </div>
</div> </template>
</div>
</div>
<div class="row"><div class="col-xs-12">
<table class="table table-striped">
<thead><tr>
<th><a class="sort" :class="(sort.field=='result'?sort.order:'')" v-on:click="do_sort('result')">&nbsp;</a></th>
<th>Run <a class="sort" :class="(sort.field=='number'?sort.order:'')" v-on:click="do_sort('number')">&nbsp;</a></th>
<th class="text-center">Started <a class="sort" :class="(sort.field=='started'?sort.order:'')" v-on:click="do_sort('started')">&nbsp;</a></th>
<th class="text-center">Duration <a class="sort" :class="(sort.field=='duration'?sort.order:'')" v-on:click="do_sort('duration')">&nbsp;</a></th>
<th class="text-center hidden-xs">Reason <a class="sort" :class="(sort.field=='reason'?sort.order:'')" v-on:click="do_sort('reason')">&nbsp;</a></th>
</tr></thead>
<tr v-show="nQueued">
<td colspan="5"><i>{{nQueued}} run(s) queued</i></td>
</tr>
<tr v-for="job in jobsRunning" track-by="$index">
<td style="width:1px"><span v-html="runIcon(job.result)"></span></td>
<td><router-link :to="'/jobs/'+$route.params.name+'/'+job.number">#{{job.number}}</router-link></td>
<td class="text-center">{{formatDate(job.started)}}</td>
<td class="text-center">{{formatDuration(job.started, job.completed)}}</td>
<td class="text-center hidden-xs">{{job.reason}}</td>
</tr>
<tr v-for="job in jobsRecent" track-by="$index">
<td style="width:1px"><span v-html="runIcon(job.result)"></span></td>
<td><router-link :to="'/jobs/'+$route.params.name+'/'+job.number">#{{job.number}}</router-link></td>
<td class="text-center">{{formatDate(job.started)}}</td>
<td class="text-center">{{formatDuration(job.started, job.completed)}}</td>
<td class="text-center hidden-xs">{{job.reason}}</td>
</tr>
</table>
<ul class="pagination pull-right">
<li><button class="btn btn-default" v-on:click="page_prev" :disabled="sort.page==0">&laquo;</button></li>
<li>Page {{sort.page+1}} of {{pages}}</li>
<li><button class="btn btn-default" v-on:click="page_next" :disabled="sort.page==pages-1">&raquo;</button></li>
</ul>
</div></div>
</div>
</div></template>
<template id="run"><div> <template id="job">
<ol class="breadcrumb"><li><router-link to="/">Home</router-link></li><li><router-link to="/jobs">Jobs</router-link></li><li><router-link :to="'/jobs/'+$route.params.name">{{$route.params.name}}</router-link></li><li class="active">#{{$route.params.number}}</li></ol></ol> <main class="ui stackable vertically padded fourteen wide column">
<div class="container-fluid"> <div class="ui basic segment">
<div class="row"> <h2 class="ui header">
<div class="col-sm-5 col-md-6 col-lg-7"> Job: {{$route.params.name}}
<h3 style="float:left"><span v-html="runIcon(job.result)"></span> {{$route.params.name}} #{{$route.params.number}}</h3> </h2>
<nav class="pull-left"> <router-link to="/jobs"><i class="angle left icon"></i>back to jobs list</router-link>
<ul class="pagination" style="margin:15px 20px"> </div>
<li v-show="$route.params.number > 1"><router-link :to="'/jobs/'+$route.params.name+'/'+($route.params.number-1)">&laquo;</router-link></li> <div class="ui stackable padded two column grid">
<li v-show="latestNum > $route.params.number"><router-link :to="'/jobs/'+$route.params.name+'/'+(parseInt($route.params.number)+1)">&raquo;</router-link></li> <div class="ui column seven wide">
</ul> <h3 class="ui header">Information</h3>
</nav> <div class="sub header" v-html="description"></div>
<div style="clear:both;"></div> <table class="ui table">
<dl class="dl-horizontal"> <tr>
<dt>Reason</dt><dd>{{job.reason}}</dd> <td>Last successful run</td>
<dt v-show="job.upstream.num > 0">Upstream</dt><dd v-show="job.upstream.num > 0"><router-link :to="'/jobs/'+job.upstream.name">{{job.upstream.name}}</router-link> <router-link :to="'/jobs/'+job.upstream.name+'/'+job.upstream.num">#{{job.upstream.num}}</router-link></li></dd> <td><router-link v-if="lastSuccess" :to="'/jobs/'+$route.params.name+'/'+lastSuccess.number">#{{lastSuccess.number}}</router-link> {{lastSuccess?' - at '+formatDate(lastSuccess.started):'never'}}</td>
<dt>Queued for</dt><dd>{{job.queued}}s</dd> </tr>
<dt>Started</dt><dd>{{formatDate(job.started)}}</dd> <tr>
<dt v-show="runComplete(job)">Completed</dt><dd v-show="job.completed">{{formatDate(job.completed)}}</dd> <td>Last failed run</td>
<dt>Duration</dt><dd>{{formatDuration(job.started, job.completed)}}</dd> <td><router-link v-if="lastFailed" :to="'/jobs/'+$route.params.name+'/'+lastFailed.number">#{{lastFailed.number}}</router-link> {{lastFailed?' - at '+formatDate(lastFailed.started):'never'}}</td>
</dl> </tr>
</div> </table>
<div class="col-sm-7 col-md-6 col-lg-5"> </div>
<div class="progress" v-show="job.result == 'running'"> <div class="ui column seven wide">
<div class="progress-bar progress-bar-striped" :class="'progress-bar-'+(job.overtime?'warning':'info')" :class="job.etc?'':'active'" :style="{width:!job.etc?100:job.progress + '%'}"></div> <h3 class="ui header">Build time</h3>
</div> <div><canvas id="chartBt"></canvas></div>
<div class="panel panel-default" v-show="job.artifacts.length"> </div>
<div class="panel-heading">Artifacts</div> </div>
<div class="panel-body"> <table class="ui striped table">
<ul class="list-unstyled" style="margin-bottom: 0"> <thead>
<li v-for="art in job.artifacts"><a :href="art.url" target="_self">{{art.filename}}</a> [{{ art.size | iecFileSize }}]</li> <tr>
</ul> <th class="three wide">Run</th>
</div> <th class="six wide">Duration</th>
</div> </tr>
</div> </thead>
</div> <tbody>
<div class="row"><div class="col-xs-12"> <tr v-show="nQueued">
<button type="button" class="btn btn-default btn-xs pull-right" :class="{'active':autoscroll}" v-on:click="autoscroll = !autoscroll" style="margin-top:10px">Autoscroll</button> <td colspan="5">{{nQueued}} more run(s) queued</td>
<h4>Console output</h4> </tr>
<pre v-html="log"></pre> <tr v-for="job in jobsRunning" track-by="$index">
</div></div> <td>
</div> <router-link :to="'/jobs/'+$route.params.name+'/'+job.number">#{{job.number}}</router-link><br>
</div></template> <span v-html="job.result ? job.result : 'pending'"></span>
</td>
<td>
<div class="ui active small blue progress">
<div class="bar" :class="job.etc?'':'active'" :style="'width:'+(!job.etc?'100':job.progress)+'%'"></div>
<div class="label">Running for {{formatDuration(job.started, job.completed)}}</div>
</div>
</td>
</tr>
<tr v-for="job in jobsRecent" track-by="$index">
<td>
<router-link :to="'/jobs/'+$route.params.name+'/'+job.number">#{{job.number}}</router-link><br>
<span v-html="job.result ? job.result : 'pending'"></span>
</td>
<td>
Started: {{formatDate(job.started)}}<br>
Ran for {{formatDuration(job.started,job.completed)}}
</td>
</tr>
</tbody>
</table>
<div class="ui pagination menu">
<a class="item" v-on:click="page_prev" :class="sort.page==0 ? 'disabled' : ''"><i class="left angle icon"></i>Previous</a>
<div class="item">
Page {{sort.page+1}} of {{pages}}
</div>
<a class="item" v-on:click="page_next" :class="sort.page==pages-1 ? 'disabled' : ''"><i class="right angle icon"></i>Next</a>
</div>
</main>
</template>
<template id="run">
<main class="ui stackable vertically padded fourteen wide column">
<div class="ui basic segment">
<h2 class="ui header">
Job run: {{$route.params.name}} #{{$route.params.number}}
</h2>
<router-link :to="'/jobs/' + $route.params.name"><i class="angle left icon"></i>back to {{$route.params.name}} job list</router-link>
</div>
<div class="ui stackable padded two column grid">
<div class="ui column four wide">
<h3 class="ui header">Information</h3>
<div class="ui pagination menu">
<router-link class="item" v-show="$route.params.number > 1" :to="'/jobs/'+$route.params.name+'/'+($route.params.number-1)"><i class="left angle icon"></i>Previous run</router-link>
<router-link class="item" v-show="latestNum > $route.params.number" :to="'/jobs/'+$route.params.name+'/'+(parseInt($route.params.number)+1)"><i class="right angle icon"></i>Next run</router-link>
</div>
<table class="ui table">
<tr v-show="job.reason">
<td>Reason</td>
<td>{{job.reason}}</td>
</tr>
<tr v-show="job.upstream.num > 0">
<td>Upstream</td>
<td><router-link :to="'/jobs/'+job.upstream.name">{{job.upstream.name}}</router-link> <router-link :to="'/jobs/'+job.upstream.name+'/'+job.upstream.num">#{{job.upstream.num}}</router-link></td>
</tr>
<tr>
<td>Queued for</td>
<td>{{job.queued}}s</td>
</tr>
<tr>
<td>Started</td>
<td>{{formatDate(job.started)}}</td>
</tr>
<tr v-show="runComplete(job)">
<td>Completed</td>
<td>{{formatDate(job.completed)}}</td>
</tr>
<tr v-show="runComplete(job)">
<td>Duration</td>
<td>{{formatDuration(job.started, job.completed)}}</td>
</tr>
<tr v-show="!runComplete(job) && job.result == 'running'">
<td>Progress</td>
<td>
<div class="ui active small blue progress">
<div class="bar" :class="job.etc?'':'active'" :style="'width:'+(!job.etc?'100':job.progress)+'%'"></div>
<div class="label">Running for {{formatDuration(job.started, job.completed)}}</div>
</div>
</td>
</tr>
</table>
<div v-show="job.artifacts.length">
<h3 class="ui header">Artifacts</h3>
<ul class="list-unstyled" style="margin-bottom: 0">
<li v-for="art in job.artifacts"><a :href="art.url" target="_self">{{art.filename}}</a> [{{ art.size | iecFileSize }}]</li>
</ul>
</div>
</div>
<div class="ui ten wide column">
<h3 class="ui header">Console output</h4>
<pre class="ui inverted segment" v-html="log"></pre>
</div>
</div>
</main>
</template>
<div id="app"> <div id="app">
<nav class="ui visible thin left sidebar inverted vertical labeled icon menu"> <nav class="ui visible thin left sidebar inverted vertical labeled icon menu">
<span class="item"><img class="icon" src="icon.png">{{title}}</span> <span class="item"><img class="icon" src="icon.png">{{title}}</span>
<router-link to="/" class="item"><i class="bar chart icon"></i>Status</router-link> <router-link to="/" class="item" exact-active-class="active"><i class="bar chart icon"></i>Status</router-link>
<router-link to="/jobs" class="item"><i class="tasks icon"></i>Jobs</router-link> <router-link to="/jobs" class="item" active-class="active"><i class="tasks icon"></i>Jobs</router-link>
<a v-on:click="toggleNotifications(!notify)" v-show="supportsNotifications" class="item" :title="(notify?'Disable':'Enable')+' notifications'"><i class="bell outline icon" :class="notify?'':'slash'"></i><span v-html="notify ? 'Disable' : 'Enable'"></span><br>notifications</a>
</nav> </nav>
<div class="ui main stackable padded grid pusher"> <div class="ui main stackable padded grid pusher">
<router-view></router-view> <router-view></router-view>
</div> </div>
<div v-show="!connected" id="popup-connecting" class="ui segment"><div class="ui basic loading segment"></div><p>Connecting</p></div> <div v-show="!connected" id="popup-connecting" class="ui segment"><div class="ui basic loading segment"></div><p>Connecting</p></div>
</div> </div>
<script src="http://localhost:35729/livereload.js?snipver=1"></script>
</body> </body>
</html> </html>