From 888c2719b8867723d6d483bbf3f51214c5f3079b Mon Sep 17 00:00:00 2001 From: Sven Fuchs Date: Sun, 1 Jul 2012 01:08:35 +0200 Subject: [PATCH] refactor layouts and add profile/service_hooks --- assets/javascripts/app/app.coffee | 11 +++++ assets/javascripts/app/controllers.coffee | 47 ++----------------- .../app/controllers/sponsors.coffee | 27 +++++++++++ .../app/controllers/workers.coffee | 10 ++++ assets/javascripts/app/layout.coffee | 4 +- assets/javascripts/app/layout/base.coffee | 19 +++++--- assets/javascripts/app/layout/default.coffee | 10 ++-- assets/javascripts/app/layout/profile.coffee | 13 ++++- assets/javascripts/app/layout/sidebar.coffee | 14 +++--- assets/javascripts/app/models.coffee | 2 + assets/javascripts/app/models/hook.coffee | 32 +++++++++++++ assets/javascripts/app/models/profile.coffee | 20 ++++++++ .../app/models/service_hook.coffee | 20 -------- assets/javascripts/app/router.coffee | 2 +- .../javascripts/app/store/rest_adapter.coffee | 1 - .../javascripts/app/templates/hooks/list.hbs | 18 +++++++ .../app/templates/layouts/default.hbs | 4 +- .../app/templates/profile/show.hbs | 46 ++++++++++++++++++ assets/javascripts/app/views.coffee | 7 ++- assets/javascripts/lib/ext/jquery.coffee | 19 ++++---- assets/javascripts/lib/mocks.coffee | 26 ++++++++++ public/javascripts/application.js | 2 +- 22 files changed, 255 insertions(+), 99 deletions(-) create mode 100644 assets/javascripts/app/controllers/sponsors.coffee create mode 100644 assets/javascripts/app/controllers/workers.coffee create mode 100644 assets/javascripts/app/models/hook.coffee create mode 100644 assets/javascripts/app/models/profile.coffee delete mode 100644 assets/javascripts/app/models/service_hook.coffee create mode 100644 assets/javascripts/app/templates/hooks/list.hbs create mode 100644 assets/javascripts/app/templates/profile/show.hbs diff --git a/assets/javascripts/app/app.coffee b/assets/javascripts/app/app.coffee index 35efc64d..9f43deac 100644 --- a/assets/javascripts/app/app.coffee +++ b/assets/javascripts/app/app.coffee @@ -22,18 +22,29 @@ require 'ext/jquery' { name: 'jvmotp', display: 'JVM and Erlang' }, ], + currentUserId: 1 + run: -> @app = Travis.App.create(this) @app.initialize() App: Em.Application.extend initialize: (router) -> + @connect() @store = Travis.Store.create() @store.loadMany(Travis.Sponsor, Travis.SPONSORS) @routes = Travis.Router.create(app: this) @_super(Em.Object.create()) @routes.start() + connect: -> + @controller = Em.Controller.create() + view = Em.View.create + template: Em.Handlebars.compile('{{outlet layout}}') + controller: @controller + view.appendTo(@get('rootElement') || 'body') + + require 'controllers' require 'helpers' require 'layout' diff --git a/assets/javascripts/app/controllers.coffee b/assets/javascripts/app/controllers.coffee index bda0810d..d13bcd97 100644 --- a/assets/javascripts/app/controllers.coffee +++ b/assets/javascripts/app/controllers.coffee @@ -2,54 +2,13 @@ require 'helpers' require 'travis/ticker' Travis.Controllers = Em.Namespace.create - AppController: Em.Controller.extend() - RepositoriesController: Em.ArrayController.extend() RepositoryController: Em.ObjectController.extend(Travis.Urls.Repository) - TabsController: Em.Controller.extend() BuildsController: Em.ArrayController.extend() BuildController: Em.ObjectController.extend(Travis.Urls.Commit) JobController: Em.ObjectController.extend(Travis.Urls.Commit) - - SidebarController: Em.Controller.extend() QueuesController: Em.ArrayController.extend() + HooksController: Em.ArrayController.extend() - SponsorsController: Em.ArrayController.extend - page: 0 - - arrangedContent: (-> - @get('shuffled').slice(@start(), @end()) - ).property('shuffled.length', 'page') - - shuffled: (-> - if content = @get('content') then $.shuffle(content) else [] - ).property('content.length') - - next: -> - @set('page', if @isLast() then 0 else @get('page') + 1) - - pages: (-> - length = @getPath('content.length') - if length then parseInt(length / @get('perPage') + 1) else 1 - ).property('length') - - isLast: -> - @get('page') == @get('pages') - 1 - - start: -> - @get('page') * @get('perPage') - - end: -> - @start() + @get('perPage') - - WorkersController: Em.ArrayController.extend - groups: (-> - groups = {} - for worker in @get('content').toArray() - host = worker.get('host') - groups[host] = Em.ArrayProxy.create(content: []) if !(host in groups) - groups[host].pushObject(worker) - $.values(groups) - ).property('content.length') - - +require 'controllers/sponsors' +require 'controllers/workers' diff --git a/assets/javascripts/app/controllers/sponsors.coffee b/assets/javascripts/app/controllers/sponsors.coffee new file mode 100644 index 00000000..72c7bd2d --- /dev/null +++ b/assets/javascripts/app/controllers/sponsors.coffee @@ -0,0 +1,27 @@ +Travis.Controllers.SponsorsController = Em.ArrayController.extend + page: 0 + + arrangedContent: (-> + @get('shuffled').slice(@start(), @end()) + ).property('shuffled.length', 'page') + + shuffled: (-> + if content = @get('content') then $.shuffle(content) else [] + ).property('content.length') + + next: -> + @set('page', if @isLast() then 0 else @get('page') + 1) + + pages: (-> + length = @getPath('content.length') + if length then parseInt(length / @get('perPage') + 1) else 1 + ).property('length') + + isLast: -> + @get('page') == @get('pages') - 1 + + start: -> + @get('page') * @get('perPage') + + end: -> + @start() + @get('perPage') diff --git a/assets/javascripts/app/controllers/workers.coffee b/assets/javascripts/app/controllers/workers.coffee new file mode 100644 index 00000000..5c6dc616 --- /dev/null +++ b/assets/javascripts/app/controllers/workers.coffee @@ -0,0 +1,10 @@ +Travis.Controllers.WorkersController = Em.ArrayController.extend + groups: (-> + groups = {} + for worker in @get('content').toArray() + host = worker.get('host') + groups[host] = Em.ArrayProxy.create(content: []) if !(host in groups) + groups[host].pushObject(worker) + $.values(groups) + ).property('content.length') + diff --git a/assets/javascripts/app/layout.coffee b/assets/javascripts/app/layout.coffee index 2ac09ba5..1cd84b5c 100644 --- a/assets/javascripts/app/layout.coffee +++ b/assets/javascripts/app/layout.coffee @@ -1,9 +1,9 @@ Travis.Layout = Em.Namespace.create() -Travis.Layout.instance = (name) -> +Travis.Layout.instance = (name, parent) -> if @layout && @layout.name == name @layout else - @layout = Travis.Layout[name].create(name: name) + @layout = Travis.Layout[name].create(parent: parent) require 'layout/default' require 'layout/sidebar' diff --git a/assets/javascripts/app/layout/base.coffee b/assets/javascripts/app/layout/base.coffee index 5ef92f92..b4470cb9 100644 --- a/assets/javascripts/app/layout/base.coffee +++ b/assets/javascripts/app/layout/base.coffee @@ -1,20 +1,27 @@ Travis.Layout.Base = Em.Object.extend init: -> - @setup(arguments) + @parent = @get('parent') + @setup(Array.prototype.slice.apply(arguments)) @connect() setup: (controllers) -> $.extend this, Travis.Controllers $.extend this, Travis.Views - for name in controllers + for name in controllers.concat(@get('name')) key = "#{$.camelize(name, false)}Controller" name = $.camelize(key) - this[key] = Travis.Controllers[name].create(namespace: this, controllers: this) + klass = Travis.Controllers[name] || Em.Controller + this[key] = klass.create(namespace: this, controllers: this) connect: -> - view = Em.View.create(templateName: "layouts/#{@get('name').toLowerCase()}") - view.set('controller', @appController) - view.appendTo(@get('rootElement') || 'body') + @parent.connectOutlet + outletName: 'layout' + controller: @controller() + viewClass: @viewClass() + controller: -> + this["#{$.camelize(@get('name'), false)}Controller"] + viewClass: -> + Travis.Views["#{$.camelize(@get('name'))}Layout"] diff --git a/assets/javascripts/app/layout/default.coffee b/assets/javascripts/app/layout/default.coffee index 07fdd8ae..3c6c0211 100644 --- a/assets/javascripts/app/layout/default.coffee +++ b/assets/javascripts/app/layout/default.coffee @@ -1,10 +1,12 @@ require 'layout/base' Travis.Layout.Default = Travis.Layout.Base.extend + name: 'default' + init: -> - @_super('app', 'repositories', 'repository', 'tabs', 'build', 'job') + @_super('repositories', 'repository', 'tabs', 'build', 'job') @connectLeft(Travis.Repository.find()) - Travis.Layout.Sidebar.create(appController: @get('appController')) + Travis.Layout.Sidebar.create(defaultController: @get('defaultController')) viewIndex: (params) -> onceLoaded @repositories, => @@ -59,11 +61,11 @@ Travis.Layout.Default = Travis.Layout.Base.extend connectLeft: (repositories) -> @repositories = repositories - @appController.connectOutlet(outletName: 'left', name: 'repositories', context: repositories) + @defaultController.connectOutlet(outletName: 'left', name: 'repositories', context: repositories) connectRepository: (repository) -> @repository = repository - @appController.connectOutlet(outletName: 'main', name: 'repository', context: repository) + @defaultController.connectOutlet(outletName: 'main', name: 'repository', context: repository) connectTabs: (build, job) -> @tabsController.set('repository', @repository) diff --git a/assets/javascripts/app/layout/profile.coffee b/assets/javascripts/app/layout/profile.coffee index 2861ce2e..d4f12dd0 100644 --- a/assets/javascripts/app/layout/profile.coffee +++ b/assets/javascripts/app/layout/profile.coffee @@ -1,7 +1,18 @@ require 'layout/base' Travis.Layout.Profile = Travis.Layout.Base.extend - name: 'default' + name: 'profile' init: -> + @_super('profile', 'hooks') + + viewShow: (params) -> + @connectProfile(Travis.Profile.find()) + @connectHooks(Travis.Hook.find()) + + connectProfile: (profile) -> + @profileController.connectOutlet(outletName: 'main', name: 'profile', context: profile) + + connectHooks: (hooks) -> + @profileController.connectOutlet(outletName: 'hooks', name: 'hooks', context: hooks) diff --git a/assets/javascripts/app/layout/sidebar.coffee b/assets/javascripts/app/layout/sidebar.coffee index 3e3efeab..32ac3fa6 100644 --- a/assets/javascripts/app/layout/sidebar.coffee +++ b/assets/javascripts/app/layout/sidebar.coffee @@ -1,9 +1,11 @@ require 'layout/base' Travis.Layout.Sidebar = Travis.Layout.Base.extend + name: 'sidebar' + init: -> - @_super('sidebar', 'sponsors', 'workers', 'queues') - @appController = @get('appController') + @_super('sponsors', 'workers', 'queues') + @defaultController = @get('defaultController') @connectSponsors(Travis.Sponsor.decks(), Travis.Sponsor.links()) @connectWorkers(Travis.Worker.find()) @@ -12,13 +14,13 @@ Travis.Layout.Sidebar = Travis.Layout.Base.extend Travis.Ticker.create(target: this, interval: Travis.INTERVALS.sponsors) connect: -> - @appController.connectOutlet(outletName: 'right', name: 'sidebar') + @defaultController.connectOutlet(outletName: 'right', name: 'sidebar') connectSponsors: (decks, links) -> @sponsorsController = Em.Controller.create decks: Travis.Controllers.SponsorsController.create(perPage: 1, content: decks) links: Travis.Controllers.SponsorsController.create(perPage: 6, content: links) - @appController.set 'sponsors', @sponsorsController + @defaultController.set 'sponsors', @sponsorsController tick: -> @sponsorsController.get('decks').next() @@ -26,7 +28,7 @@ Travis.Layout.Sidebar = Travis.Layout.Base.extend connectWorkers: (workers) -> @workersController.set('content', workers) - @appController.set('workers', @workersController) + @defaultController.set('workers', @workersController) connectQueues: (queues) -> queues = for queue in queues @@ -34,5 +36,5 @@ Travis.Layout.Sidebar = Travis.Layout.Base.extend content: Travis.Job.queued(queue.name) name: queue.display @queuesController.set('content', queues) - @appController.set('queues', @queuesController) + @defaultController.set('queues', @queuesController) diff --git a/assets/javascripts/app/models.coffee b/assets/javascripts/app/models.coffee index 890321fd..f5e77bad 100644 --- a/assets/javascripts/app/models.coffee +++ b/assets/javascripts/app/models.coffee @@ -1,7 +1,9 @@ require 'models/artifact' require 'models/build' require 'models/commit' +require 'models/hook' require 'models/job' +require 'models/profile' require 'models/repository' require 'models/sponsor' require 'models/worker' diff --git a/assets/javascripts/app/models/hook.coffee b/assets/javascripts/app/models/hook.coffee new file mode 100644 index 00000000..44f06323 --- /dev/null +++ b/assets/javascripts/app/models/hook.coffee @@ -0,0 +1,32 @@ +require 'travis/model' + +@Travis.Hook = Travis.Model.extend + primaryKey: 'slug' + slug: DS.attr('string') + description: DS.attr('string') + active: DS.attr('boolean') + + owner: (-> + @get('slug').split('/')[0] + ).property('slug') + + name: (-> + @get('slug').split('/')[1] + ).property('slug') + + urlGithub: (-> + "http://github.com/#{@get('slug')}" + ).property() + + urlGithubAdmin: (-> + "http://github.com/#{@get('slug')}/admin/hooks#travis_minibucket" + ).property() + + toggle: -> + @set 'active', !@get('active') + Travis.app.store.commit() + +@Travis.Hook.reopenClass + url: 'profile/hooks' + + diff --git a/assets/javascripts/app/models/profile.coffee b/assets/javascripts/app/models/profile.coffee new file mode 100644 index 00000000..dbe396b4 --- /dev/null +++ b/assets/javascripts/app/models/profile.coffee @@ -0,0 +1,20 @@ +require 'travis/model' + +@Travis.Profile = Travis.Model.extend + name: DS.attr('string') + email: DS.attr('string') + login: DS.attr('string') + token: DS.attr('string') + gravatarUrl: DS.attr('string') + + urlGithub: (-> + "http://github.com/#{@get('login')}" + ).property() + +@Travis.Profile.reopenClass + find: -> + @_super(Travis.currentUserId) if Travis.currentUserId + + buildURL: -> + 'profile' + diff --git a/assets/javascripts/app/models/service_hook.coffee b/assets/javascripts/app/models/service_hook.coffee deleted file mode 100644 index 70e0a227..00000000 --- a/assets/javascripts/app/models/service_hook.coffee +++ /dev/null @@ -1,20 +0,0 @@ -require 'travis/model' - -@Travis.ServiceHook = Travis.Model.extend - primaryKey: 'slug' - name: DS.attr('string') - owner_name: DS.attr('string') - active: DS.attr('boolean') - - slug: (-> - [@get('owner_name'), @get('name')].join('/') - ).property() - - toggle: -> - @set 'active', !@get('active') - Travis.app.store.commit() - -@Travis.ServiceHook.reopenClass - url: 'profile/service_hooks' - - diff --git a/assets/javascripts/app/router.coffee b/assets/javascripts/app/router.coffee index 0b7a1e95..ffad690a 100644 --- a/assets/javascripts/app/router.coffee +++ b/assets/javascripts/app/router.coffee @@ -21,5 +21,5 @@ Travis.Router = Em.Object.extend @action(layout, action, params) action: (layout, action, params) -> - layout = Travis.Layout.instance(layout) + layout = Travis.Layout.instance(layout, @app.controller) layout["view#{$.camelize(action)}"](params) diff --git a/assets/javascripts/app/store/rest_adapter.coffee b/assets/javascripts/app/store/rest_adapter.coffee index 9b008b23..fe3cc1c0 100644 --- a/assets/javascripts/app/store/rest_adapter.coffee +++ b/assets/javascripts/app/store/rest_adapter.coffee @@ -8,7 +8,6 @@ require 'models' builds: Travis.Build, commits: Travis.Commit, jobs: Travis.Job - service_hooks: Travis.ServiceHook plurals: repository: 'repositories', diff --git a/assets/javascripts/app/templates/hooks/list.hbs b/assets/javascripts/app/templates/hooks/list.hbs new file mode 100644 index 00000000..a8f8497c --- /dev/null +++ b/assets/javascripts/app/templates/hooks/list.hbs @@ -0,0 +1,18 @@ +{{#if content.length}} + +{{else}} +

Please wait while we sync with GitHub

+{{/if}} + diff --git a/assets/javascripts/app/templates/layouts/default.hbs b/assets/javascripts/app/templates/layouts/default.hbs index 4348b089..96f01119 100644 --- a/assets/javascripts/app/templates/layouts/default.hbs +++ b/assets/javascripts/app/templates/layouts/default.hbs @@ -1,6 +1,6 @@
diff --git a/assets/javascripts/app/templates/profile/show.hbs b/assets/javascripts/app/templates/profile/show.hbs new file mode 100644 index 00000000..58aea9f1 --- /dev/null +++ b/assets/javascripts/app/templates/profile/show.hbs @@ -0,0 +1,46 @@ +

{{name}}

+ + +
+
+ {{t profiles.show.github}}: +
+
+ {{login}} +
+
+ {{t profiles.show.email}}: +
+
+ {{email}} +
+
+ {{t profiles.show.token}}: +
+
+ {{token}} +
+
+ +

+ {{{t profiles.show.messages.notice}}} +

+ +

{{t profiles.show.your_locale}}

+
+ + +
+ +

{{t profiles.show.your_repos}}

+

+ {{{t profiles.show.message.your_repos}}} + + {{{t profiles.show.message.config}}} + +

+ +{{outlet hooks}} diff --git a/assets/javascripts/app/views.coffee b/assets/javascripts/app/views.coffee index 4ea675ed..6ee267a9 100644 --- a/assets/javascripts/app/views.coffee +++ b/assets/javascripts/app/views.coffee @@ -1,7 +1,12 @@ require 'ext/ember/namespace' @Travis.Views = Em.Namespace.create - SidebarView: Em.View.extend(templateName: 'layouts/sidebar') + DefaultLayout: Em.View.extend(templateName: 'layouts/default') + ProfileLayout: Em.View.extend(templateName: 'layouts/profile') + + SidebarView: Em.View.extend(templateName: 'layouts/sidebar') + ProfileView: Em.View.extend(templateName: 'profile/show') + HooksView: Em.View.extend(templateName: 'hooks/list') require 'views/build' require 'views/job' diff --git a/assets/javascripts/lib/ext/jquery.coffee b/assets/javascripts/lib/ext/jquery.coffee index e33e6758..4bef8fc8 100644 --- a/assets/javascripts/lib/ext/jquery.coffee +++ b/assets/javascripts/lib/ext/jquery.coffee @@ -40,29 +40,28 @@ $.fn.extend $.extend keys: (obj) -> keys = [] - $.each obj, (key) -> - keys.push key - + $.each obj, (key) -> keys.push key keys values: (obj) -> values = [] - $.each obj, (key, value) -> - values.push value - + $.each obj, (key, value) -> values.push value values + underscore: (string) -> + string[0].toLowerCase() + string.substring(1).replace /([A-Z])?/g, (match, chr) -> + if chr then "_#{chr.toUpperCase()}" else '' + camelize: (string, uppercase) -> - string = $.capitalize(string) if uppercase or typeof uppercase is 'undefined' + string = if uppercase == false then $.underscore(string) else $.capitalize(string) string.replace /_(.)?/g, (match, chr) -> - (if chr then chr.toUpperCase() else '') + if chr then chr.toUpperCase() else '' capitalize: (string) -> string[0].toUpperCase() + string.substring(1) compact: (array) -> - $.grep array, (value) -> - !!value + $.grep array, (value) -> !!value all: (array, callback) -> args = Array::slice.apply(arguments) diff --git a/assets/javascripts/lib/mocks.coffee b/assets/javascripts/lib/mocks.coffee index 68b12df1..76b78be9 100644 --- a/assets/javascripts/lib/mocks.coffee +++ b/assets/javascripts/lib/mocks.coffee @@ -45,6 +45,21 @@ workers = [ { id: 2, name: 'ruby-2', host: 'worker.travis-ci.org', state: 'ready' } ] +profile = + id: 1 + login: 'svenfuchs' + name: 'Sven Fuchs' + email: 'me@svenfuchs.com' + token: '1234567890' + gravatar_url: 'http://www.gravatar.com/avatar/402602a60e500e85f2f5dc1ff3648ecb?s=48&d=mm' + +hooks = [ + { slug: 'travis-ci/travis-core', description: 'description of travis-core', active: true, private: false } + { slug: 'travis-ci/travis-assets', description: 'description of travis-assets', active: false, private: false } + { slug: 'svenfuchs/minimal', description: 'description of minimal', active: true, private: false } +] + + $.mockjax url: '/repositories' responseTime: responseTime @@ -99,3 +114,14 @@ $.mockjax responseTime: responseTime responseText: jobs: $.select(jobs, (job) -> job.state == 'created') + +$.mockjax + url: '/profile' + responseTime: responseTime + responseText: { profile: profile } + +$.mockjax + url: '/profile/hooks' + responseTime: responseTime + responseText: { hooks: hooks } + diff --git a/public/javascripts/application.js b/public/javascripts/application.js index 40e9c84c..4e0d5e95 100644 --- a/public/javascripts/application.js +++ b/public/javascripts/application.js @@ -1 +1 @@ -minispade.register('templates', "(function() {Ember.TEMPLATES['builds/list']=Ember.Handlebars.compile(\"\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n\\n \\n {{#each build in content}}\\n {{#view Travis.Views.BuildsItemView contextBinding=\\\"build\\\"}}\\n \\n \\n \\n \\n \\n \\n \\n {{/view}}\\n {{/each}}\\n \\n
{{t builds.name}}{{t builds.commit}}{{t builds.message}}{{t builds.duration}}{{t builds.finished_at}}
#{{number}}{{formatCommit commit}}{{{formatMessage commit.message short=\\\"true\\\"}}}{{formatDuration duration}}{{formatTime finished_at}}
\\n\\n

\\n \\n

\\n\");Ember.TEMPLATES['builds/show']=Ember.Handlebars.compile(\"{{#unless isLoaded}}\\n Loading ...\\n{{else}}\\n
\\n
\\n
\\n
{{t builds.name}}
\\n
{{number}}
\\n
{{t builds.finished_at}}
\\n
{{formatTime finished_at}}
\\n
{{t builds.duration}}
\\n
{{formatDuration duration}}
\\n
\\n\\n
\\n
{{t builds.commit}}
\\n
{{formatCommit commit}}
\\n {{#if commit.compareUrl}}\\n
{{t builds.compare}}
\\n
{{pathFrom commit.compareUrl}}
\\n {{/if}}\\n {{#if commit.authorName}}\\n
{{t builds.author}}
\\n
{{commit.authorName}}
\\n {{/if}}\\n {{#if commit.committerName}}\\n
{{t builds.committer}}
\\n
{{commit.committerName}}
\\n {{/if}}\\n
\\n\\n
{{t builds.message}}
\\n
{{{formatMessage commit.message}}}
\\n\\n {{#unless isMatrix}}\\n
{{t builds.config}}
\\n
{{formatConfig config}}
\\n {{/unless}}\\n
\\n\\n {{#if isMatrix}}\\n {{view Travis.Views.JobsView jobsBinding=\\\"view.requiredJobs\\\" required=\\\"true\\\"}}\\n {{view Travis.Views.JobsView jobsBinding=\\\"view.allowedFailureJobs\\\"}}\\n {{else}}\\n {{view Travis.Views.LogView contextBinding=\\\"jobs.firstObject\\\"}}\\n {{/if}}\\n
\\n{{/unless}}\\n\");Ember.TEMPLATES['jobs/list']=Ember.Handlebars.compile(\"{{#if view.jobs.length}}\\n \\n \\n \\n \\n {{#each configKeys}}\\n \\n {{/each}}\\n \\n \\n \\n {{#each job in view.jobs}}\\n {{#view Travis.Views.JobsItemView contextBinding=\\\"job\\\"}}\\n \\n \\n \\n \\n {{#each configValues}}\\n \\n {{/each}}\\n \\n {{/view}}\\n {{/each}}\\n \\n
\\n {{#if view.required}}\\n {{t jobs.build_matrix}}\\n {{else}}\\n {{t jobs.allowed_failures}}{{whats_this allow_failure_help}}\\n {{/if}}\\n
{{this}}
#{{number}}{{formatDuration duration}}{{formatTime finished_at}}{{this}}
\\n\\n {{#unless view.required}}\\n
\\n
{{t \\\"jobs.allowed_failures\\\"}}
\\n
\\n

\\n Allowed Failures are items in your build matrix that are allowed to\\n fail without causing the entire build to be shown as failed. This lets you add\\n in experimental and preparatory builds to test against versions or\\n configurations that you are not ready to officially support.\\n

\\n

\\n You can define allowed failures in the build matrix as follows:\\n

\\n
\\n      matrix:\\n        allow_failures:\\n          - rvm: ruby-head\\n        
\\n
\\n
\\n {{/unless}}\\n{{/if}}\\n\");Ember.TEMPLATES['jobs/log']=Ember.Handlebars.compile(\"
{{{formatLog log.body}}}
\\n\\n{{#if sponsor.name}}\\n

\\n {{t builds.messages.sponsored_by}}\\n {{sponsor.name}}\\n

\\n{{/if}}\\n\");Ember.TEMPLATES['jobs/show']=Ember.Handlebars.compile(\"
\\n
\\n
\\n
Job
\\n
{{number}}
\\n
{{t jobs.finished_at}}
\\n
{{formatTime finished_at}}
\\n
{{t jobs.duration}}
\\n
{{formatDuration duration}}
\\n
\\n\\n
\\n
{{t jobs.commit}}
\\n
{{formatCommit commit}}
\\n {{#if commit.compareUrl}}\\n
{{t jobs.compare}}
\\n
{{pathFrom commit.compareUrl}}
\\n {{/if}}\\n {{#if commit.authorName}}\\n
{{t jobs.author}}
\\n
{{commit.authorName}}
\\n {{/if}}\\n {{#if commit.committerName}}\\n
{{t jobs.committer}}
\\n
{{commit.committerName}}
\\n {{/if}}\\n
\\n\\n
{{t jobs.message}}
\\n
{{formatMessage commit.message}}
\\n
{{t jobs.config}}
\\n
{{formatConfig config}}
\\n
\\n\\n {{view Travis.Views.LogView}}\\n
\\n\\n\");Ember.TEMPLATES['layouts/default']=Ember.Handlebars.compile(\"
\\n Travis CI\\n #\\n
\\n\\n
\\n {{outlet left}}\\n
\\n\\n
\\n {{outlet main}}\\n
\\n\\n
\\n {{outlet right}}\\n
\\n\");Ember.TEMPLATES['layouts/profile']=Ember.Handlebars.compile(\"
\\n Travis CI\\n Profile\\n
\\n\\n
\\n {{outlet main}}\\n
\\n\\n\");Ember.TEMPLATES['layouts/sidebar']=Ember.Handlebars.compile(\"
\\n
 
\\n
\\n\\n {{view templateName=\\\"sponsors/decks\\\"}}\\n {{view templateName=\\\"workers/list\\\" id=\\\"workers\\\"}}\\n {{view templateName=\\\"queues/list\\\" id=\\\"queues\\\"}}\\n {{view templateName=\\\"sponsors/links\\\"}}\\n\\n
\\n

{{t layouts.about.alpha}}

\\n

{{{t layouts.about.messages.alpha}}}

\\n
\\n
\\n

{{t layouts.about.join}}

\\n \\n
\\n
\\n
\\n\\n\\n\");Ember.TEMPLATES['queues/list']=Ember.Handlebars.compile(\"{{#each queue in queues}}\\n

{{t queue}}: {{queue.name}}

\\n \\n{{/each}}\\n\");Ember.TEMPLATES['repositories/list']=Ember.Handlebars.compile(\"{{#unless content.lastObject.isLoaded}}\\n Loading ...\\n{{else}}\\n