convert to coffeescript

This commit is contained in:
Sven Fuchs 2012-06-19 17:40:58 +02:00
parent f2c3ad4ff0
commit 0b8eb94dd5
18 changed files with 467 additions and 242 deletions

View File

@ -1,236 +0,0 @@
//= require_tree ./templates
//= require_self
App = Em.Application.create();
App.Store = DS.Store.extend({ revision: 4, adapter: DS.fixtureAdapter });
App.Repository = DS.Model.extend({
ownerName: DS.attr('string'),
name: DS.attr('string'),
builds: DS.hasMany('App.Build', { key: 'build_ids' }),
lastBuild: function() {
return this.getPath('builds.firstObject');
}.property()
});
App.Build = DS.Model.extend({
number: DS.attr('number'),
repository: DS.belongsTo('App.Repository')
});
App.Build.FIXTURES = [
{ id: 1, repositoryId: 1, repository_id: 1, number: 1 },
{ id: 2, repositoryId: 1, repository_id: 1, number: 2 },
{ id: 3, repositoryId: 2, repository_id: 2, number: 3 },
{ id: 4, repositoryId: 3, repository_id: 3, number: 4 }
];
App.Repository.FIXTURES = [
{ id: 1, owner_name: 'travis-ci', name: 'travis-core', build_ids: [1, 2] },
{ id: 2, owner_name: 'travis-ci', name: 'travis-assets', build_ids: [3] },
{ id: 3, owner_name: 'travis-ci', name: 'travis-hub', build_ids: [4] },
];
App.ApplicationController = Em.Controller.extend();
App.RepositoriesController = Em.ArrayController.extend();
App.RepositoryController = Em.Controller.extend();
App.TabsController = Em.Controller.extend();
App.CurrentController = Em.Controller.extend();
App.HistoryController = Em.ArrayController.extend();
App.BuildController = Em.Controller.extend();
App.LoadingController = Em.Controller.extend();
App.ApplicationView = Em.View.extend({ templateName: 'application' });
App.RepositoriesView = Em.View.extend({ templateName: 'repositories' });
App.RepositoryView = Em.View.extend({ templateName: 'repository' });
App.TabsView = Em.View.extend({ templateName: 'tabs' });
App.CurrentView = Em.View.extend({ templateName: 'current' });
App.HistoryView = Em.View.extend({ templateName: 'history' });
App.BuildView = Em.View.extend({ templateName: 'build' });
App.LoadingView = Em.View.extend({ templateName: 'loading' });
App.store = App.Store.create();
var onTrue = function(object, path, callback) {
if(object.getPath(path)) {
callback();
} else {
var observer = function() {
object.removeObserver(path, observer);
callback()
};
object.addObserver(path, observer);
}
};
var onLoaded = function(object, callback) {
if(object) {
var path = Ember.isArray(object) ? 'firstObject.isLoaded' : 'isLoaded';
// should observe RecordArray.isLoaded instead, but that doesn't seem to exist?
onTrue(object, path, function() {
callback(Ember.isArray(object) ? object.get('firstObject') : object);
});
} else {
callback(object);
}
}
App.Router = Em.Router.extend({
enableLogging: true,
location: 'hash',
root: Em.Route.extend({
viewRepository: Ember.Route.transitionTo('current'),
index: Em.Route.extend({
route: '/',
connectOutlets: function(router) {
router.connectLayout({}, function(repository) {
router.connectCurrent(repository.get('lastBuild'));
});
},
viewCurrent: Ember.Route.transitionTo('current'),
viewHistory: Ember.Route.transitionTo('history'),
viewBuild: Ember.Route.transitionTo('build'),
}),
current: Em.Route.extend({
route: '/:ownerName/:name',
serialize: function(router, repository) {
return router.serializeRepository(repository);
},
connectOutlets: function(router, repository) {
var params = router.serializeRepository(repository);
router.connectLayout(params, function(repository) {
router.connectCurrent(repository.get('lastBuild'));
});
}
}),
viewCurrent: Ember.Route.transitionTo('current'),
history: Em.Route.extend({
route: '/:ownerName/:name/builds',
serialize: function(router, repository) {
return router.serializeRepository(repository);
},
connectOutlets: function(router, repository) {
var params = router.serializeRepository(repository);
router.connectLayout(params, function(repository) {
var builds = repository.get('builds');
// why do i have to wait here. is repo.isLoaded true before the hasMany array is loaded?
onLoaded(builds, function() {
router.connectHistory(builds)
})
});
}
}),
viewHistory: Ember.Route.transitionTo('history'),
build: Em.Route.extend({
route: '/:ownerName/:name/builds/:id',
serialize: function(router, build) {
return router.serializeBuild(build);
},
connectOutlets: function(router, build) {
params = router.serializeBuild(build);
router.connectLayout(params, function(repository, build) {
router.connectBuild(build)
});
}
}),
viewBuild: Ember.Route.transitionTo('build')
}),
serializeRepository: function(repository) {
if(repository instanceof DS.Model) {
return repository.getProperties('ownerName', 'name');
} else {
return repository || {};
}
},
serializeBuild: function(build) {
if(build instanceof DS.Model) {
var repository = build.get('repository')
// var repository = App.Repository.find(build.get('repositoryId')); // wat.
var params = this.serializeRepository(repository);
return $.extend(params, { id: build.get('id') });
} else {
return build || {};
}
},
connectLayout: function(params, callback) {
var repositories = App.Repository.find();
this.connectLeft(repositories);
this.connectMain(repositories, params, callback);
this.connectRight();
},
connectLeft: function(repositories) {
this.get('applicationController').connectOutlet({ outletName: 'left', name: 'repositories', context: repositories })
},
connectRight: function() {
// this.get('applicationController').connectOutlet({ outletName: 'right', name: 'sidebar' })
},
connectLoading: function() {
this.get('applicationController').connectOutlet({ outletName: 'main', name: 'loading' });
},
connectMain: function(repositories, params, callback) {
this.connectLoading();
if(params.ownerName && params.name) {
// needs to implement findQuery
// var repositories = App.Repository.find(params);
repositories = App.Repository.find().filter(function(data) {
return data.get('owner_name') == params.owner_name && data.get('name') == params.name;
})
}
var build = params.id ? App.Build.find(params.id) : undefined;
onLoaded(repositories, function(repository) {
onLoaded(build, function(build) {
this.connectTabs(repository, build);
this.connectRepository(repository);
callback(repository, build);
}.bind(this));
}.bind(this));
},
connectRepository: function(repository) {
this.get('applicationController').connectOutlet({ outletName: 'main', name: 'repository', context: repository });
},
connectTabs: function(repository, build) {
this.setPath('tabsController.repository', repository);
this.setPath('tabsController.build', build);
this.get('repositoryController').connectOutlet({ outletName: 'tabs', name: 'tabs' });
},
connectCurrent: function(build) {
this.get('repositoryController').connectOutlet({ outletName: 'tab', name: 'current', context: build});
},
connectHistory: function(builds) {
this.get('repositoryController').connectOutlet({ outletName: 'tab', name: 'history', context: builds});
},
connectBuild: function(build) {
this.get('repositoryController').connectOutlet({ outletName: 'tab', name: 'build', context: build});
}
});
App.initialize();

View File

@ -0,0 +1,13 @@
#= require_tree ./models
#= require_tree ./templates
#= require ./controllers.js
#= require ./views.js
#= require ./routes.js
#= require_self
Travis = window.Travis
Travis.store = DS.Store.extend(
revision: 4
adapter: Travis.FixtureAdapter.create()
).create()
Travis.initialize()

View File

@ -0,0 +1,8 @@
Travis.ApplicationController = Em.Controller.extend()
Travis.RepositoriesController = Em.ArrayController.extend()
Travis.RepositoryController = Em.Controller.extend()
Travis.TabsController = Em.Controller.extend()
Travis.CurrentController = Em.Controller.extend()
Travis.HistoryController = Em.ArrayController.extend()
Travis.BuildController = Em.Controller.extend()
Travis.LoadingController = Em.Controller.extend()

View File

@ -0,0 +1,63 @@
@Travis.Build = Travis.Model.extend # Travis.Helpers,
repository_id: DS.attr('number')
state: DS.attr('string')
number: DS.attr('number')
branch: DS.attr('string')
message: DS.attr('string')
result: DS.attr('number')
duration: DS.attr('number')
started_at: DS.attr('string')
finished_at: DS.attr('string')
committed_at: DS.attr('string')
committer_name: DS.attr('string')
committer_email: DS.attr('string')
author_name: DS.attr('string')
author_email: DS.attr('string')
compare_url: DS.attr('string')
repository: DS.belongsTo('Travis.Repository')
commit: DS.belongsTo('Travis.Commit')
# jobs: DS.hasMany('Travis.Job')
config: (->
@getPath 'data.config'
).property('data.config')
isMatrix: (->
@getPath('data.job_ids.length') > 1
).property('data.job_ids.length')
isFailureMatrix: (->
@get('allowedFailureJobs').length > 0
).property('allowedFailureJobs')
# TODO why does the hasMany association not work?
jobs: (->
Travis.Job.findMany(@getPath('data.job_ids'))
).property('data.job_ids.length')
requiredJobs: (->
@get('jobs').filter (item, index) -> item.get('allow_failure') isnt true
).property('jobs')
allowedFailureJobs: (->
@get('jobs').filter (item, index) -> item.get 'allow_failure'
).property('jobs')
tick: ->
@notifyPropertyChange 'duration'
@notifyPropertyChange 'finished_at'
@Travis.Build.reopenClass
byRepositoryId: (id, parameters) ->
@find($.extend(parameters || {}, repository_id: id, orderBy: 'number DESC'))
olderThanNumber: (id, build_number) ->
@find(url: '/repositories/' + id + '/builds.json?bare=true&after_number=' + build_number, repository_id: id, orderBy: 'number DESC')
@Travis.Build.FIXTURES = [
{ id: 1, repository_id: 1, number: 1, event_type: 'push' },
{ id: 2, repository_id: 1, number: 2, event_type: 'push' },
{ id: 3, repository_id: 2, number: 3, event_type: 'push' },
{ id: 4, repository_id: 3, number: 4, event_type: 'push' }
]

View File

@ -0,0 +1,67 @@
@Travis.Repository = Travis.Model.extend # Travis.Helpers,
slug: DS.attr('string')
name: DS.attr('string')
owner: DS.attr('string')
description: DS.attr('string')
last_build_id: DS.attr('number')
last_build_number: DS.attr('string')
last_build_result: DS.attr('number')
last_build_started_at: DS.attr('string')
last_build_finished_at: DS.attr('string')
builds: (->
Travis.Build.byRepositoryId @get('id'), event_type: 'push'
).property()
pullRequests: (->
Travis.Build.byRepositoryId @get('id'), event_type: 'pull_request'
).property()
lastBuild: (->
Travis.Build.find @get('last_build_id')
).property('last_build_id')
last_build_duration: (->
duration = @getPath('data.last_build_duration')
duration = @durationFrom(@get('last_build_started_at'), @get('last_build_finished_at')) unless duration
duration
).property('data.last_build_duration', 'last_build_started_at', 'last_build_finished_at')
stats: (->
return unless Travis.env is 'production'
url = 'https://api.github.com/json/repos/show/' + @get('slug')
@get('_stats') || $.get(url, (data) => @set('_stats', data)) && undefined
).property('_stats')
select: ->
Travis.Repository.select(self.get('id'))
tick: ->
@notifyPropertyChange 'last_build_duration'
@notifyPropertyChange 'last_build_finished_at'
@Travis.Repository.reopenClass
recent: ->
@find()
ownedBy: (owner) ->
@find(owner: owner, orderBy: 'name')
search: (query) ->
@find(search: query, orderBy: 'name')
bySlug: (slug) ->
repo = $.detect(@find().toArray(), (repo) -> repo.get('slug') == slug)
if repo then Ember.ArrayProxy.create(content: [repo]) else @find(slug: slug)
select: (id) ->
@find().forEach (repository) ->
repository.set 'selected', repository.get('id') is id
@Travis.Repository.FIXTURES = [
{ id: 1, owner: 'travis-ci', name: 'travis-core', build_ids: [1, 2] },
{ id: 2, owner: 'travis-ci', name: 'travis-assets', build_ids: [3] },
{ id: 3, owner: 'travis-ci', name: 'travis-hub', build_ids: [4] },
]

View File

@ -0,0 +1,132 @@
Travis.Router = Em.Router.extend
enableLogging: true
location: 'hash'
root: Em.Route.extend
viewRepository: Ember.Route.transitionTo('current')
index: Em.Route.extend
route: '/'
connectOutlets: (router) ->
router.connectLayout {}, (repository) ->
router.connectCurrent repository.get('lastBuild')
viewCurrent: Ember.Route.transitionTo('current')
viewHistory: Ember.Route.transitionTo('history')
viewBuild: Ember.Route.transitionTo('build')
current: Em.Route.extend
route: '/:owner/:name'
serialize: (router, repository) ->
router.serializeRepository repository
connectOutlets: (router, repository) ->
params = router.serializeRepository(repository)
router.connectLayout params, (repository) ->
builds = repository.get('builds')
onceLoaded builds, ->
router.connectCurrent builds.get('firstObject')
viewCurrent: Ember.Route.transitionTo('current')
history: Em.Route.extend
route: '/:owner/:name/builds'
serialize: (router, repository) ->
router.serializeRepository repository
connectOutlets: (router, repository) ->
params = router.serializeRepository(repository)
router.connectLayout params, (repository) ->
builds = repository.get('builds')
onceLoaded builds, ->
router.connectHistory builds
viewHistory: Ember.Route.transitionTo('history')
build: Em.Route.extend
route: '/:owner/:name/builds/:id'
serialize: (router, build) ->
router.serializeBuild build
connectOutlets: (router, build) ->
params = router.serializeBuild(build)
router.connectLayout params, (repository, build) ->
router.connectBuild build
viewBuild: Ember.Route.transitionTo('build')
serializeRepository: (repository) ->
if repository instanceof DS.Model
repository.getProperties 'owner', 'name'
else
repository or {}
serializeBuild: (build) ->
if build instanceof DS.Model
repository = build.get('repository')
params = @serializeRepository(repository)
$.extend params,
id: build.get('id')
else
build or {}
connectLayout: (params, callback) ->
repositories = Travis.Repository.find()
@connectLeft repositories
@connectMain repositories, params, callback
@connectRight()
connectLeft: (repositories) ->
@get('applicationController').connectOutlet
outletName: 'left'
name: 'repositories'
context: repositories
connectRight: ->
# ...
connectLoading: ->
@get('applicationController').connectOutlet
outletName: 'main'
name: 'loading'
connectMain: (repositories, params, callback) ->
@connectLoading()
if params.owner and params.name
repositories = Travis.Repository.find().filter (data) ->
data.get('owner_name') is params.owner_name and data.get('name') is params.name
build = (if params.id then Travis.Build.find(params.id) else `undefined`)
onceLoaded repositories, build, =>
repository = repositories.get('firstObject')
@connectRepository repository
@connectTabs repository, build
callback repository, build
connectRepository: (repository) ->
@get('applicationController').connectOutlet
outletName: 'main'
name: 'repository'
context: repository
connectTabs: (repository, build) ->
@setPath 'tabsController.repository', repository
@setPath 'tabsController.build', build
@get('repositoryController').connectOutlet
outletName: 'tabs'
name: 'tabs'
connectCurrent: (build) ->
@get('repositoryController').connectOutlet
outletName: 'tab'
name: 'current'
context: build
connectHistory: (builds) ->
@get('repositoryController').connectOutlet
outletName: 'tab'
name: 'history'
context: builds
connectBuild: (build) ->
@get('repositoryController').connectOutlet
outletName: 'tab'
name: 'build'
context: build

View File

@ -1 +0,0 @@

View File

@ -1,3 +0,0 @@
current build {{content.id}}

View File

@ -1,6 +1,6 @@
<ul>
{{#each repository in content}}
<li><a {{action viewRepository href=true context="repository"}}>{{repository.ownerName}}/{{repository.name}}</a></li>
<li><a {{action viewRepository href=true context="repository"}}>{{repository.owner}}/{{repository.name}}</a></li>
{{/each}}
</ul>

View File

@ -1,4 +1,4 @@
<h2>{{content.ownerName}}/{{content.name}}</h2>
<h2>{{content.owner}}/{{content.name}}</h2>
{{outlet tabs}}

View File

@ -0,0 +1,9 @@
Travis.ApplicationView = Em.View.extend templateName: 'application'
Travis.RepositoriesView = Em.View.extend templateName: 'repositories/list'
Travis.RepositoryView = Em.View.extend templateName: 'repositories/show'
Travis.TabsView = Em.View.extend templateName: 'repositories/tabs'
Travis.CurrentView = Em.View.extend templateName: 'builds/show'
Travis.HistoryView = Em.View.extend templateName: 'builds/list'
Travis.BuildView = Em.View.extend templateName: 'builds/show'
Travis.LoadingView = Em.View.extend templateName: 'loading'

View File

@ -0,0 +1,127 @@
@Travis.FixtureAdapter = DS.Adapter.extend
find: (store, type, id) ->
fixtures = type.FIXTURES
Ember.assert "Unable to find fixtures for model type " + type.toString(), !!fixtures
return if fixtures.hasLoaded
setTimeout (->
store.loadMany type, fixtures
fixtures.hasLoaded = true
), 300
findMany: ->
@find.apply this, arguments
findAll: (store, type) ->
fixtures = type.FIXTURES
Ember.assert "Unable to find fixtures for model type " + type.toString(), !!fixtures
ids = fixtures.map (item, index, self) ->
item.id
store.loadMany type, ids, fixtures
findQuery: (store, type, params, array) ->
fixtures = type.FIXTURES
Ember.assert "Unable to find fixtures for model type " + type.toString(), !!fixtures
hashes = for fixture in fixtures
matches = for key, value of params
key == 'orderBy' || fixture[key] == value
if matches.reduce((a, b) -> a && b) then fixture else null
array.load(hashes.compact())
@Travis.DataStoreAdapter = DS.RESTAdapter.extend
init: ->
@_super()
# TODO should be able to specify these as strings
@set 'mappings',
builds: Travis.Build,
commits: Travis.Commit,
jobs: Travis.Job
service_hooks: Travis.ServiceHook
plurals:
repository: 'repositories',
branch: 'branches'
updateRecord: (store, type, record) ->
id = get(record, record.get('primaryKey') || 'id')
root = @rootForType(type)
plural = @pluralize(root)
url = @buildURL(type.url || plural, id)
data = root: record.toJSON()
@ajax url, 'PUT',
data: data
success: (json) ->
@sideload(store, type, json, root)
store.didUpdateRecord(record, json && json[root])
find: (store, type, id) ->
root = @rootForType(type)
plural = @pluralize(root)
url = @buildURL(type.url || plural, id)
@ajax url, 'GET',
success: (json) ->
@sideload(store, type, json, root)
store.load(type, json[root])
accepts:
json: 'application/vnd.travis-ci.2+json'
findMany: (store, type, ids) ->
root = @rootForType(type)
plural = @pluralize(root)
url = @buildURL(type.url || plural)
@ajax url, 'GET',
data:
ids: ids
success: (json) ->
@sideload(store, type, json, plural)
store.loadMany(type, json[plural])
accepts:
json: 'application/vnd.travis-ci.2+json'
findAll: (store, type) ->
root = @rootForType(type)
plural = @pluralize(root)
url = @buildURL(type.url || plural)
@ajax url, 'GET',
success: (json) ->
@sideload(store, type, json, plural)
store.loadMany(type, json[plural])
accepts:
json: 'application/vnd.travis-ci.2+json'
findQuery: (store, type, query, recordArray) ->
root = @rootForType(type)
plural = @pluralize(root)
url = @buildURL(type.url || plural)
@ajax url, 'GET',
data: query,
success: (json) ->
@sideload(store, type, json, plural)
recordArray.load(json[plural])
accepts:
json: 'application/vnd.travis-ci.2+json'
rootForType: (type) ->
# sorry, but this seems very weird, really
# return type.url if (type.url)
parts = type.toString().split('.')
name = parts[parts.length - 1]
name.replace(/([A-Z])/g, '_$1').toLowerCase().slice(1)
buildURL: (record, suffix) ->
Ember.assert('Namespace URL (' + @namespace + ') must not start with slash', !@namespace || @namespace.toString().charAt(0) != '/')
Ember.assert('Record URL (' + record + ') must not start with slash', !record || record.toString().charAt(0) != '/')
Ember.assert('URL suffix (' + suffix + ') must not start with slash', !suffix || suffix.toString().charAt(0) != '/')
url = ['']
url.push(@namespace) if (@namespace != undefined)
url.push(record)
url.push(suffix) if (suffix != undefined)
url.join('/')

View File

@ -0,0 +1,26 @@
window.onTrue = (object, path, callback) ->
if object.getPath(path)
callback()
else
observer = ->
object.removeObserver path, observer
callback()
object.addObserver path, observer
window.onceLoaded = ->
objects = Array.prototype.slice.apply(arguments)
callback = objects.pop()
# sadly Ember.Enumerable.compact does not remove undefined values
objects = (if object then object else null for object in objects).compact()
object = objects.shift()
if object
path = if Ember.isArray(object) then 'firstObject.isLoaded' else 'isLoaded'
onTrue object, path, ->
if objects.length == 0
callback(object)
else
onceLoaded.apply(objects + [callback])
else
callback object

View File

@ -0,0 +1,17 @@
@Travis.Model = DS.Model.extend
primaryKey: 'id'
id: DS.attr('number')
refresh: ->
id = @get('id')
Travis.app.store.adapter.find(Travis.app.store, @constructor, id) if id
update: (attrs) ->
$.each attrs, (key, value) =>
@set(key, value) unless key is 'id'
this
@Travis.Model.reopenClass
load: (attrs) ->
Travis.app.store.load(this, attrs)

View File

@ -1,2 +1,5 @@
//= require_self
//= require_tree ./lib
//= require app/app.js
Travis = Em.Application.create();