ui: initial ember application

This commit is contained in:
Jack Pearkes 2014-04-23 14:01:42 -04:00
parent 83ebad5491
commit d669e78e3b
5 changed files with 247 additions and 11 deletions

View File

@ -7,22 +7,104 @@
<link rel="stylesheet" href="static/base.css"> <link rel="stylesheet" href="static/base.css">
</head> </head>
<body> <body>
<div class="container">
<div class="col-md-12">
<div id="app">
</div>
</div>
</div>
<script type="text/x-handlebars"> <script type="text/x-handlebars">
<h1>Base</h1>
{{outlet}} {{outlet}}
</script> </script>
<script type="text/x-handlebars" data-template-name="default_layout">
<div class="row">
<div class="col-md-12 col-sm-12 topbar">
<div class="col-md-1 col-sm-2">
<a href="#"><div class="top-brand"></div></a>
</div>
<div class="col-md-2 col-sm-3">
<a class="btn btn-primary" href="#">Services</a>
</div>
<div class="col-md-2 col-sm-3">
<a class="btn btn-default" href="#">Nodes</a>
</div>
<div class="col-md-2 col-sm-3">
<a class="btn btn-default" href="#">Key/Value</a>
</div>
<div class="col-md-2 col-md-offset-1 col-sm-3 col-sm-offset-0">
<a class="btn btn-warning" href="#">5 checks failing</a>
</div>
<div class="col-md-2 col-sm-3">
<a class="btn btn-dropdown btn-default" href="#">
us-east-1
<span class="caret"></span>
</a>
</div>
</div>
</div>
{{yield}}
</script>
<script type="text/x-handlebars" id="services">
<div class="col-md-6">
{{#each item in model}}
<div class="list-group-item">
<div {{bind-attr class="item.hasFailingChecks:bg-orange:bg-green :list-bar"}}></div>
<h4 class="list-group-item-heading">
<a href="#" class="subtle">{{item.Name}}</a>
<small>{{item.Name}}</small>
<div class="heading-helper">
<a class="subtle" href="#">{{item.checkMessage}}</a>
</div>
</h4>
<ul class="list-inline">
{{#each node in item.Nodes }}
<li>{{#link-to 'node' controllers.application.getDc node class='subtle'}}{{node}}{{/link-to}}</li>
{{/each}}
</ul>
</div>
{{/each}}
</div>
<div class="col-md-6">
</div>
</script>
<script type="text/x-handlebars" id="index"> <script type="text/x-handlebars" id="index">
<ul> <div class="col-md-8 col-md-offset-2 vertical-center">
{{#each item in model}} {{#each item in model}}
<li>{{item}}</li> <a {{action 'selectDc' item}}>
{{/each}} <div class="panel panel-success panel-link">
</ul> <div class="panel-bar"></div>
<div class="panel-heading">
<h3 class="panel-title">
{{item}}
<small>{{item}}</small>
<span class="panel-note">all checks passing</span>
</h3>
</div>
</div>
</a>
{{/each}}
</div>
</script> </script>
<script src="javascripts/libs/jquery-1.10.2.js"></script> <script src="javascripts/libs/jquery-1.10.2.js"></script>
<script src="javascripts/libs/handlebars-1.1.2.js"></script> <script src="javascripts/libs/handlebars-1.1.2.js"></script>
<script src="javascripts/libs/ember-1.5.0.js"></script> <script src="javascripts/libs/ember-1.5.0.js"></script>
<script src="javascripts/fixtures.js"></script>
<script src="javascripts/app.js"></script> <script src="javascripts/app.js"></script>
<!-- to activate the test runner, add the "?test" query string parameter --> <!-- to activate the test runner, add the "?test" query string parameter -->

View File

@ -1,11 +1,96 @@
App = Ember.Application.create(); window.App = Ember.Application.create({
rootElement: "#app",
LOG_TRANSITIONS: true,
currentPath: ''
});
App.Router.map(function() { App.Router.map(function() {
// put your routes here this.route("index", { path: "/" });
this.route("services", { path: "/:dc/services" });
this.route("nodes", { path: "/:dc/nodes" });
this.route("node", { path: "/:dc/nodes/:name" });
this.route("kv", { path: "/:dc/kv" });
}); });
App.IndexRoute = Ember.Route.extend({ App.ApplicationController = Ember.Controller.extend({
model: function() { setDc: function(dc) {
return ['red', 'yellow', 'blue']; localStorage.setItem("current_dc", dc);
},
getDc: function() {
return localStorage.getItem("current_dc");
}.property("getDc")
});
App.ServicesController = Ember.Controller.extend({
needs: ['application']
})
// Superclass to be used by all of the main routes below
App.BaseRoute = Ember.Route.extend({
activate: function() {
var controller = this.controllerFor('application');
if (controller.getDc === null) {
this.transitionTo('index');
};
} }
}); });
// Does not extend baseroute due to it not needing
// to check for an active DC
App.IndexRoute = Ember.Route.extend({
model: function() {
return window.fixtures.dcs;
},
afterModel: function(dcs, transition) {
if (dcs.get('length') === 1) {
this.get('controllers.application').setDc(dcs[0])
this.transitionTo('services', dcs[0]);
}
}
});
App.IndexController = Ember.Controller.extend({
needs: ['application'],
actions: {
selectDc: function(dc) {
this.get('controllers.application').setDc(dc)
this.transitionToRoute('services', dc)
}
}
});
App.Service = Ember.Object.extend({
failingChecks: function() {
return this.get('Checks').filterBy('Status', 'critical').get('length');
}.property('failingChecks'),
passingChecks: function() {
return this.get('Checks').filterBy('Status', 'passing').get('length');
}.property('passingChecks'),
checkMessage: function() {
if (this.get('hasFailingChecks') === false) {
return this.get('passingChecks') + ' passing';
} else {
return this.get('failingChecks') + ' failing';
}
}.property('checkMessage'),
hasFailingChecks: function() {
return (this.get('failingChecks') > 0);
}.property('hasFailingChecks')
});
App.ServicesRoute = App.BaseRoute.extend({
model: function() {
return [App.Service.create(window.fixtures.services[0]), App.Service.create(window.fixtures.services[1])];
}
});
App.ServicesView = Ember.View.extend({
layoutName: 'default_layout'
})

View File

@ -0,0 +1,60 @@
//
// I intentionally am not using ember-data and the fixture
// adapter. I'm not confident the Consul UI API will be compatible
// without a bunch of wrangling, and it's really not enough updating
// of the models to justify the use of such a big component. getJSON
// *should* be enough.
//
window.fixtures = {}
fixtures.services = [
{
"Name": "vagrant-cloud-http",
"Checks": [
{
"Name": "serfHealth",
"Status": "passing"
},
{
"Name": "fooHealth",
"Status": "critical"
},
{
"Name": "bazHealth",
"Status": "passing"
}
],
"Nodes": [
"node-10-0-1-109",
"node-10-0-1-102",
"node-10-0-1-103"
]
},
{
"Name": "vagrant-share-mux",
"Checks": [
{
"Name": "serfHealth",
"Status": "passing"
},
{
"Name": "fooHealth",
"Status": "passing"
},
{
"Name": "bazHealth",
"Status": "passing"
}
],
"Nodes": [
"node-10-0-1-109",
"node-10-0-1-102",
"node-10-0-1-103"
]
},
]
fixtures.dcs = ['nyc1', 'sf1', 'sg1']
localStorage.setItem("current_dc", fixtures.dcs[0]);

View File

@ -64,4 +64,8 @@
background-color: $orange-faded; background-color: $orange-faded;
} }
} }
&.panel-link:hover {
background-color: lighten($gray-background, 8%);
}
} }

View File

@ -6,6 +6,11 @@
@import "buttons"; @import "buttons";
@import "lists"; @import "lists";
.vertical-center {
margin-top: 200px;
}
.row { .row {
&.colored { &.colored {
background-color: $light-purple; background-color: $light-purple;