[ARVADOS] created: 6f3346e85dacf1041de13f8961063b9f470c7255
git at public.curoverse.com
git at public.curoverse.com
Sat Nov 29 21:23:50 EST 2014
at 6f3346e85dacf1041de13f8961063b9f470c7255 (commit)
commit 6f3346e85dacf1041de13f8961063b9f470c7255
Author: Tom Clegg <tom at curoverse.com>
Date: Sat Nov 29 21:23:44 2014 -0500
4446: Ember first draft.
diff --git a/apps/workbench/Gemfile b/apps/workbench/Gemfile
index 5ab6eac..e2297e4 100644
--- a/apps/workbench/Gemfile
+++ b/apps/workbench/Gemfile
@@ -1,4 +1,5 @@
source 'https://rubygems.org'
+source 'https://rails-assets.org'
gem 'rails', '~> 4.1.0'
gem 'minitest', '>= 5.0.0'
@@ -56,6 +57,8 @@ gem 'bootstrap-sass', '~> 3.1.0'
gem 'bootstrap-x-editable-rails'
gem 'bootstrap-tab-history-rails'
+gem 'ember-rails'
+
gem 'less'
gem 'less-rails'
gem 'wiselinks'
diff --git a/apps/workbench/Gemfile.lock b/apps/workbench/Gemfile.lock
index 8b9ea94..ed351e3 100644
--- a/apps/workbench/Gemfile.lock
+++ b/apps/workbench/Gemfile.lock
@@ -8,6 +8,7 @@ GIT
GEM
remote: https://rubygems.org/
+ remote: https://rails-assets.org/
specs:
RedCloth (4.2.9)
actionmailer (4.1.1)
@@ -23,6 +24,8 @@ GEM
activesupport (= 4.1.1)
builder (~> 3.1)
erubis (~> 2.7.0)
+ active_model_serializers (0.9.0)
+ activemodel (>= 3.2)
activemodel (4.1.1)
activesupport (= 4.1.1)
builder (~> 3.1)
@@ -49,6 +52,10 @@ GEM
addressable (>= 2.3.1)
extlib (>= 0.9.15)
multi_json (>= 1.0.0)
+ barber (0.5.0)
+ ember-source
+ execjs
+ handlebars-source (>= 1.0.0.rc.4)
bootstrap-sass (3.1.0.1)
sass (~> 3.2)
bootstrap-tab-history-rails (0.1.0)
@@ -87,6 +94,19 @@ GEM
daemon_controller (1.1.7)
debugger-linecache (1.2.0)
deep_merge (1.0.1)
+ ember-data-source (1.0.0.beta.12)
+ ember-source
+ ember-rails (0.15.0)
+ active_model_serializers
+ barber (>= 0.4.1)
+ ember-data-source (>= 1.0.0.beta.5)
+ ember-source (>= 1.1.0)
+ execjs (>= 1.2)
+ handlebars-source (> 1.0.0)
+ jquery-rails (>= 1.0.17)
+ railties (>= 3.1)
+ ember-source (1.8.1)
+ handlebars-source (~> 1.0)
erubis (2.7.0)
execjs (2.0.2)
extlib (0.9.16)
@@ -103,6 +123,7 @@ GEM
multi_json (>= 1.0.0)
signet (~> 0.4.5)
uuidtools (>= 2.1.0)
+ handlebars-source (1.3.0)
headless (1.0.1)
highline (1.6.20)
hike (1.2.3)
@@ -250,6 +271,7 @@ DEPENDENCIES
capybara
coffee-rails
deep_merge
+ ember-rails
headless
httpclient (~> 2.5.0)
jquery-rails
diff --git a/apps/workbench/app/assets/javascripts/application.js b/apps/workbench/app/assets/javascripts/application.js
index 1990b8b..c6d0182 100644
--- a/apps/workbench/app/assets/javascripts/application.js
+++ b/apps/workbench/app/assets/javascripts/application.js
@@ -23,15 +23,17 @@
//= require bootstrap3-editable/bootstrap-editable
//= require bootstrap-tab-history
//= require wiselinks
-//= require_tree .
+//= require handlebars
+//= require ember
+//= require ember-data
+//= require_self
+//= require workbench-ember
+//= require_directory .
-jQuery(function($){
- $.ajaxSetup({
- headers: {
- 'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
- }
- });
+// for more details see: http://emberjs.com/guides/application/
+window.App = Ember.Application.create()
+jQuery(function($){
$(document).ajaxStart(function(){
$('.modal-with-loading-spinner .spinner').show();
}).ajaxStop(function(){
diff --git a/apps/workbench/app/assets/javascripts/ember/arvados.controller.js b/apps/workbench/app/assets/javascripts/ember/arvados.controller.js
new file mode 100644
index 0000000..2b2e35d
--- /dev/null
+++ b/apps/workbench/app/assets/javascripts/ember/arvados.controller.js
@@ -0,0 +1,4 @@
+App.ArvadosObjectController = Ember.Controller.extend({
+});
+App.ArvadosArrayController = Ember.ArrayController.extend({
+});
diff --git a/apps/workbench/app/assets/javascripts/ember/arvados_route.js b/apps/workbench/app/assets/javascripts/ember/arvados_route.js
new file mode 100644
index 0000000..937caed
--- /dev/null
+++ b/apps/workbench/app/assets/javascripts/ember/arvados_route.js
@@ -0,0 +1,48 @@
+App.ApplicationRoute = Ember.Route.extend({
+ model: function() {
+ var that = this;
+ $('body').
+ addClass('arv-log-event-listener').
+ attr('data-object-uuid', 'all').
+ on('arv-log-event', function(event, data) {
+ return that.updateStoreWithLogEvent(that.store, event, data);
+ });
+ },
+ updateStoreWithLogEvent: function(store, event, data) {
+ var payload = {};
+ var attrs;
+ var kind;
+ var model;
+ if (!(data &&
+ data.object_kind &&
+ data.event_type === 'update' &&
+ data.properties &&
+ data.properties.new_attributes)) {
+ return;
+ }
+ kind = data.object_kind.replace('arvados#','');
+ attrs = data.properties.new_attributes;
+ model = store.getById(kind, attrs.uuid);
+ if (!model) {
+ // If the updated object isn't in our store, we don't care
+ // about the update.
+ return;
+ }
+ if (false) {
+ // Unfortunately, attrs is just a hash of database values,
+ // not the usual API response for this object type. If we
+ // received the usual API response via websockets, we
+ // would just do this:
+ attrs.id = attrs.uuid;
+ delete attrs.updated_at;
+ payload[kind] = attrs;
+ store.pushPayload(kind, payload);
+ } else {
+ // Until then, the safest approach is to ignore the detail
+ // we get from data.properties.new_attributes and instead
+ // use ember-data's ActiveRecordAdapter to reload the
+ // model in a separate AJAX call.
+ model.reload();
+ }
+ }
+});
diff --git a/apps/workbench/app/assets/javascripts/ember/arvados_store.js b/apps/workbench/app/assets/javascripts/ember/arvados_store.js
new file mode 100644
index 0000000..28022fa
--- /dev/null
+++ b/apps/workbench/app/assets/javascripts/ember/arvados_store.js
@@ -0,0 +1,42 @@
+App.ArvadosModel = DS.Model.extend({
+ uuid: DS.attr('string'),
+ createdAt: DS.attr('date'),
+ etag: DS.attr('string'),
+ href: DS.attr('string'),
+ kind: DS.attr('string'),
+ modifiedAt: DS.attr('date'),
+ modifiedByClient_Uuid: DS.attr('string'),
+ modifiedByUserUuid: DS.attr('string'),
+ ownerUuid: DS.attr('string')
+});
+
+App.ApplicationAdapter = DS.ActiveModelAdapter.extend({
+ host: $('meta[name=arvados-discovery-uri]').attr('content').
+ replace(/\/discovery.*/, ''),
+ namespace: 'arvados/v1',
+ headers: {
+ Authorization: 'OAuth2 '+$('meta[name=arvados-api-token]').attr('content')
+ },
+ defaultSerializer: 'arvados'
+});
+
+App.ArvadosSerializer = DS.ActiveModelSerializer.extend({
+ extractArray: function(store, type, arvResp) {
+ payload = {}
+ if (arvResp.items)
+ payload[Ember.Inflector.inflector.pluralize(type.typeKey)] = arvResp.items;
+ else
+ payload[type.typeKey] = arvResp;
+ return this._super(store, type, payload);
+ },
+ extractSingle: function(store, primaryType, payload, recordId) {
+ var rootedPayload = {}
+ payload.id = payload.uuid;
+ rootedPayload[payload.kind.replace('arvados#','')] = payload;
+ return this._super(store, primaryType, rootedPayload, recordId);
+ },
+ normalize: function(type, hash, prop) {
+ hash.id = hash.uuid;
+ return this._super(type, hash, prop);
+ }
+});
diff --git a/apps/workbench/app/assets/javascripts/ember/node.controller.js b/apps/workbench/app/assets/javascripts/ember/node.controller.js
new file mode 100644
index 0000000..837fdf0
--- /dev/null
+++ b/apps/workbench/app/assets/javascripts/ember/node.controller.js
@@ -0,0 +1,20 @@
+App.NodesController = App.ArvadosArrayController.extend({
+ itemController: 'node'
+});
+
+App.NodeController = App.ArvadosObjectController.extend({
+ stateClassMap: {
+ idle: 'label-success',
+ alloc: 'label-primary',
+ down: 'label-default'
+ },
+ stateClass: function() {
+ var cws = this.get('model.crunchWorkerState');
+ return this.stateClassMap[cws];
+ }.property('model.crunchWorkerState'),
+
+ dotDomain: function() {
+ var domain = this.get('model.domain');
+ return domain ? '.'+domain : '';
+ }.property('model.domain')
+});
diff --git a/apps/workbench/app/assets/javascripts/ember/node.js.coffee b/apps/workbench/app/assets/javascripts/ember/node.js.coffee
new file mode 100644
index 0000000..b2fb3e6
--- /dev/null
+++ b/apps/workbench/app/assets/javascripts/ember/node.js.coffee
@@ -0,0 +1,14 @@
+App.Node = App.ArvadosModel.extend {
+ hostname: DS.attr 'string'
+ domain: DS.attr 'string'
+ crunchWorkerState: DS.attr 'string'
+ ipAddress: DS.attr 'string'
+ firstPingAt: DS.attr 'date'
+ lastPingAt: DS.attr 'date'
+ slot_number: DS.attr 'number'
+ job_uuid: DS.attr 'string'
+ status: DS.attr 'string'
+ properties: DS.attr 'string'
+ info: DS.attr 'string'
+ nameservers: DS.attr 'string'
+}
diff --git a/apps/workbench/app/assets/javascripts/ember/node.routes.js b/apps/workbench/app/assets/javascripts/ember/node.routes.js
new file mode 100644
index 0000000..156b0af
--- /dev/null
+++ b/apps/workbench/app/assets/javascripts/ember/node.routes.js
@@ -0,0 +1,5 @@
+App.NodesRoute = Ember.Route.extend({
+ model: function() {
+ return this.store.find('node');
+ }
+});
diff --git a/apps/workbench/app/assets/javascripts/ember/router.js b/apps/workbench/app/assets/javascripts/ember/router.js
new file mode 100644
index 0000000..72f40c8
--- /dev/null
+++ b/apps/workbench/app/assets/javascripts/ember/router.js
@@ -0,0 +1,5 @@
+App.Router.map(function() {
+ this.resource('nodes', {path: '/'}, function() {
+ this.resource('node', {path: ':id'});
+ });
+});
diff --git a/apps/workbench/app/assets/javascripts/nodes.js b/apps/workbench/app/assets/javascripts/nodes.js
new file mode 100644
index 0000000..e69de29
diff --git a/apps/workbench/app/assets/javascripts/templates/all.js b/apps/workbench/app/assets/javascripts/templates/all.js
new file mode 100644
index 0000000..2c03f2d
--- /dev/null
+++ b/apps/workbench/app/assets/javascripts/templates/all.js
@@ -0,0 +1 @@
+//= require_tree .
diff --git a/apps/workbench/app/assets/javascripts/templates/nodes/index.hbs b/apps/workbench/app/assets/javascripts/templates/nodes/index.hbs
new file mode 100644
index 0000000..85f4098
--- /dev/null
+++ b/apps/workbench/app/assets/javascripts/templates/nodes/index.hbs
@@ -0,0 +1,45 @@
+<div class="container">
+ <table class="table table-condensed">
+ <colgroup>
+ <col width="10%" />
+ <col width="20%" />
+ <col width="20%" />
+ <col width="20%" />
+ <col width="30%" />
+ </colgroup>
+ <thead>
+ <tr>
+ <th>alloc</th>
+ <th>uuid</th>
+ <th>job</th>
+ <th>hostname</th>
+ <th>lastPingAt</th>
+ </tr>
+ </thead>
+ <tbody>
+ {{#each node in model itemController="node"}}
+ <tr>
+ <td>
+ <span {{bind-attr class=":label :label-default node.stateClass"}}>
+ {{node.model.crunchWorkerState}}
+ </span>
+ </td>
+ <td>
+ <a class="arvados-uuid" {{bind-attr href=node.model.href}}>{{node.model.id}}</a>
+ </td>
+ <td>
+ <span class="arvados-uuid">{{node.job_uuid}}</span>
+ </td>
+ <td>
+ {{node.model.hostname}}{{node.dotDomain}}
+ </td>
+ <td>{{node.model.lastPingAt}}</td>
+ </tr>
+ {{else}}
+ <tr>
+ <td colspan="*">No nodes.</td>
+ </tr>
+ {{/each}}
+ </tbody>
+ </table>
+</div>
diff --git a/apps/workbench/app/assets/javascripts/workbench-ember.js.coffee b/apps/workbench/app/assets/javascripts/workbench-ember.js.coffee
new file mode 100644
index 0000000..fe91904
--- /dev/null
+++ b/apps/workbench/app/assets/javascripts/workbench-ember.js.coffee
@@ -0,0 +1,12 @@
+#= require_tree ./ember
+
+# - require ./store
+# - require_tree ./models
+# - require_tree ./controllers
+# - require_tree ./views
+# - require_tree ./helpers
+# - require_tree ./components
+# - require_tree ./templates
+# - require_tree ./routes
+# - require ./router
+# - require_self
diff --git a/apps/workbench/app/views/layouts/application.html.erb b/apps/workbench/app/views/layouts/application.html.erb
index 324714e..5e63d7e 100644
--- a/apps/workbench/app/views/layouts/application.html.erb
+++ b/apps/workbench/app/views/layouts/application.html.erb
@@ -14,12 +14,15 @@
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
<meta name="description" content="">
<meta name="author" content="">
+ <meta name="arvados-api-token" content="<%=Thread.current[:arvados_api_token]%>">
+ <meta name="arvados-discovery-uri" content="<%= Rails.configuration.arvados_v1_base.sub '/arvados/v1', '/discovery/v1/apis/arvados/v1/rest' %>">
<% if current_user and $arvados_api_client.discovery[:websocketUrl] %>
<meta name="arv-websocket-url" content="<%=$arvados_api_client.discovery[:websocketUrl]%>?api_token=<%=Thread.current[:arvados_api_token]%>">
<% end %>
<meta name="robots" content="NOINDEX, NOFOLLOW">
<%= stylesheet_link_tag "application", :media => "all" %>
<%= javascript_include_tag "application" %>
+ <%= javascript_include_tag "templates/all" %>
<%= csrf_meta_tags %>
<%= yield :head %>
<%= javascript_tag do %>
diff --git a/apps/workbench/app/views/nodes/index.html.erb b/apps/workbench/app/views/nodes/index.html.erb
new file mode 100644
index 0000000..79c82c9
--- /dev/null
+++ b/apps/workbench/app/views/nodes/index.html.erb
@@ -0,0 +1,3 @@
+<script type="text/x-handlebars">
+ {{outlet}}
+</script>
diff --git a/apps/workbench/config/initializers/active_model_serializers.rb b/apps/workbench/config/initializers/active_model_serializers.rb
new file mode 100644
index 0000000..9068d4a
--- /dev/null
+++ b/apps/workbench/config/initializers/active_model_serializers.rb
@@ -0,0 +1,3 @@
+# Stop active_model_serializers from adding root elements to JSON responses.
+ActiveModel::Serializer.root = false
+ActiveModel::ArraySerializer.root = false
-----------------------------------------------------------------------
hooks/post-receive
--
More information about the arvados-commits
mailing list