Merge pull request #414 from travis-ci/web-on-v3
Moving travis-web to V3 API
This commit is contained in:
commit
6ad07924d3
|
@ -3,7 +3,8 @@
|
|||
"document",
|
||||
"window",
|
||||
"-Promise",
|
||||
"jQuery"
|
||||
"jQuery",
|
||||
"Visibility"
|
||||
],
|
||||
"browser": true,
|
||||
"boss": true,
|
||||
|
|
|
@ -16,8 +16,8 @@ matrix:
|
|||
|
||||
fast_finish: true
|
||||
|
||||
#addons:
|
||||
# sauce_connect: true
|
||||
addons:
|
||||
sauce_connect: true
|
||||
|
||||
sudo: false
|
||||
|
||||
|
|
3
.watchmanconfig
Normal file
3
.watchmanconfig
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"ignore_dirs": ["tmp", "dist"]
|
||||
}
|
|
@ -2,6 +2,8 @@
|
|||
`import config from 'travis/config/environment'`
|
||||
|
||||
Adapter = DS.ActiveModelAdapter.extend
|
||||
auth: Ember.inject.service()
|
||||
|
||||
host: config.apiEndpoint
|
||||
coalesceFindRequests: true
|
||||
|
||||
|
@ -12,13 +14,13 @@ Adapter = DS.ActiveModelAdapter.extend
|
|||
|
||||
hash.headers['accept'] = 'application/json; version=2'
|
||||
|
||||
if token = Travis.sessionStorage.getItem('travis.token')
|
||||
if token = @get('auth').token()
|
||||
hash.headers['Authorization'] ||= "token #{token}"
|
||||
|
||||
hash
|
||||
|
||||
findMany: (store, type, ids) ->
|
||||
@ajax(@buildURL(type.typeKey), 'GET', data: { ids: ids })
|
||||
@ajax(@buildURL(type.modelName), 'GET', data: { ids: ids })
|
||||
|
||||
handleResponse: (status, headers, payload) ->
|
||||
if status > 299
|
||||
|
|
9
app/adapters/hook.js
Normal file
9
app/adapters/hook.js
Normal file
|
@ -0,0 +1,9 @@
|
|||
import ApplicationAdapter from 'travis/adapters/application';
|
||||
|
||||
export default ApplicationAdapter.extend({
|
||||
updateRecord(store, type, snapshot) {
|
||||
return this._super(...arguments).then( (data) => {
|
||||
return { hook: { id: snapshot.id } };
|
||||
});
|
||||
}
|
||||
});
|
26
app/adapters/repo.js
Normal file
26
app/adapters/repo.js
Normal file
|
@ -0,0 +1,26 @@
|
|||
import V3Adapter from 'travis/adapters/v3';
|
||||
|
||||
export default V3Adapter.extend({
|
||||
defaultSerializer: '-repo',
|
||||
|
||||
buildUrl(modelName, id, snapshot, requestType, query) {
|
||||
var url = this._super(...arguments);
|
||||
|
||||
return url;
|
||||
},
|
||||
|
||||
ajaxOptions(url, type, options) {
|
||||
var hash = options || {};
|
||||
if(!hash.data) {
|
||||
hash.data = {};
|
||||
}
|
||||
|
||||
if(hash.data.include) {
|
||||
hash.data.include += ',repository.default_branch,branch.last_build,build.commit';
|
||||
} else {
|
||||
hash.data.include = 'repository.default_branch,branch.last_build,build.commit';
|
||||
}
|
||||
|
||||
return this._super(url, type, hash);
|
||||
}
|
||||
});
|
|
@ -19,6 +19,7 @@ Adapter = ApplicationAdapter.extend
|
|||
|
||||
id = Ember.get(record, 'id')
|
||||
|
||||
this.ajax(this.urlPrefix() + '/ssh_key/' + id, "PATCH", { data: data })
|
||||
this.ajax(this.urlPrefix() + '/ssh_key/' + id, "PATCH", { data: data }).then (data) ->
|
||||
data.ssh_key
|
||||
|
||||
`export default Adapter`
|
||||
|
|
58
app/adapters/v3.js
Normal file
58
app/adapters/v3.js
Normal file
|
@ -0,0 +1,58 @@
|
|||
import Ember from 'ember';
|
||||
import DS from 'ember-data';
|
||||
import config from 'travis/config/environment';
|
||||
|
||||
export default DS.RESTAdapter.extend({
|
||||
auth: Ember.inject.service(),
|
||||
host: config.apiEndpoint,
|
||||
|
||||
sortQueryParams: false,
|
||||
coalesceFindRequests: false,
|
||||
headers: {
|
||||
'Travis-API-Version': '3',
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
|
||||
ajaxOptions: function(url, type, options) {
|
||||
var hash = this._super(...arguments);
|
||||
|
||||
hash.headers = hash.headers || {};
|
||||
|
||||
var token;
|
||||
if(token = this.get('auth').token()) {
|
||||
hash.headers['Authorization'] = "token " + token;
|
||||
}
|
||||
|
||||
return hash;
|
||||
},
|
||||
|
||||
// TODO: I shouldn't override this method as it's private, a better way would
|
||||
// be to create my own URL generator
|
||||
_buildURL: function(modelName, id) {
|
||||
var url = [];
|
||||
var host = Ember.get(this, 'host');
|
||||
var prefix = this.urlPrefix();
|
||||
var path;
|
||||
|
||||
if (modelName) {
|
||||
path = this.pathForType(modelName, id);
|
||||
if (path) { url.push(path); }
|
||||
}
|
||||
|
||||
if (id) { url.push(encodeURIComponent(id)); }
|
||||
if (prefix) { url.unshift(prefix); }
|
||||
|
||||
url = url.join('/');
|
||||
if (!host && url && url.charAt(0) !== '/') {
|
||||
url = '/' + url;
|
||||
}
|
||||
|
||||
return url;
|
||||
},
|
||||
|
||||
pathForType: function(modelName, id) {
|
||||
var underscored = Ember.String.underscore(modelName);
|
||||
return id ? underscored : Ember.String.pluralize(underscored);
|
||||
}
|
||||
});
|
|
@ -1,7 +1,7 @@
|
|||
`import Ember from 'ember'`
|
||||
`import Ajax from 'travis/utils/ajax'`
|
||||
|
||||
CachesItemComponent = Ember.Component.extend
|
||||
ajax: Ember.inject.service()
|
||||
|
||||
tagName: 'li'
|
||||
classNames: ['cache-item']
|
||||
|
@ -20,7 +20,7 @@ CachesItemComponent = Ember.Component.extend
|
|||
deletingDone = => @set('isDeleting', false)
|
||||
|
||||
repo = @get('repo')
|
||||
Ajax.ajax("/repos/#{repo.get('id')}/caches", "DELETE", data: data).then(deletingDone, deletingDone).then =>
|
||||
@get('ajax').ajax("/repos/#{repo.get('id')}/caches", "DELETE", data: data).then(deletingDone, deletingDone).then =>
|
||||
@get('caches').removeObject(@get('cache'))
|
||||
|
||||
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
`import Ember from 'ember'`
|
||||
`import Ajax from 'travis/utils/ajax'`
|
||||
`import config from 'travis/config/environment'`
|
||||
|
||||
NoBuildsComponent = Ember.Component.extend
|
||||
|
||||
actions:
|
||||
triggerBuild: () ->
|
||||
@set('isLoading', true)
|
||||
|
|
|
@ -15,6 +15,10 @@ ReposListItemComponent = Ember.Component.extend Polling,
|
|||
@get('repo') == @get('selectedRepo')
|
||||
).property('selectedRepo')
|
||||
|
||||
color: (->
|
||||
colorForState(@get('repo.defaultBranch.lastBuild.state'))
|
||||
).property('repo.defaultBranch.lastBuild.state')
|
||||
|
||||
scrollTop: (->
|
||||
if (window.scrollY > 0)
|
||||
$('html, body').animate({scrollTop: 0}, 200)
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
`import Ember from 'ember'`
|
||||
|
||||
ReposListComponent = Ember.Component.extend
|
||||
tagName: 'ul'
|
||||
|
||||
`export default ReposListComponent`
|
7
app/components/repos-list.js
Normal file
7
app/components/repos-list.js
Normal file
|
@ -0,0 +1,7 @@
|
|||
import Ember from 'ember';
|
||||
|
||||
var ReposListComponent = Ember.Component.extend({
|
||||
tagName: 'ul'
|
||||
});
|
||||
|
||||
export default ReposListComponent;
|
|
@ -1,5 +1,4 @@
|
|||
`import Ember from 'ember'`
|
||||
`import Ajax from 'travis/utils/ajax'`
|
||||
`import config from 'travis/config/environment'`
|
||||
|
||||
TravisStatusComponent = Ember.Component.extend
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
|
||||
Controller = Ember.Controller.extend
|
||||
allHooks: []
|
||||
needs: ['currentUser']
|
||||
userBinding: 'controllers.currentUser.model'
|
||||
userBinding: 'auth.currentUser'
|
||||
|
||||
init: ->
|
||||
@_super.apply this, arguments
|
||||
|
@ -22,7 +21,7 @@ Controller = Ember.Controller.extend
|
|||
|
||||
reloadHooks: ->
|
||||
if login = @get('model.login')
|
||||
hooks = @store.find('hook', all: true, owner_name: login)
|
||||
hooks = @store.query('hook', all: true, owner_name: login)
|
||||
|
||||
hooks.then () ->
|
||||
hooks.set('isLoaded', true)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
`import Ember from 'ember'`
|
||||
|
||||
Controller = Ember.Controller.extend
|
||||
needs: ['currentUser', 'repos']
|
||||
userBinding: 'controllers.currentUser'
|
||||
repos: Ember.inject.controller()
|
||||
userBinding: 'auth.currentUser'
|
||||
|
||||
`export default Controller`
|
||||
|
|
|
@ -3,11 +3,11 @@
|
|||
`import GithubUrlPropertievs from 'travis/mixins/github-url-properties'`
|
||||
|
||||
Controller = Ember.Controller.extend GithubUrlPropertievs,
|
||||
needs: ['repo', 'currentUser']
|
||||
repoBinding: 'controllers.repo.repo'
|
||||
repoController: Ember.inject.controller('repo')
|
||||
repoBinding: 'repoController.repo'
|
||||
commitBinding: 'build.commit'
|
||||
currentUserBinding: 'controllers.currentUser.model'
|
||||
tabBinding: 'controllers.repo.tab'
|
||||
currentUserBinding: 'auth.currentUser'
|
||||
tabBinding: 'repoController.tab'
|
||||
sendFaviconStateChanges: true
|
||||
|
||||
currentItemBinding: 'build'
|
||||
|
|
|
@ -4,10 +4,10 @@ Controller = Ember.ArrayController.extend
|
|||
sortAscending: false
|
||||
sortProperties: ['number']
|
||||
|
||||
needs: ['repo']
|
||||
repoController: Ember.inject.controller('repo')
|
||||
|
||||
repoBinding: 'controllers.repo.repo'
|
||||
tabBinding: 'controllers.repo.tab'
|
||||
repoBinding: 'repoController.repo'
|
||||
tabBinding: 'repoController.tab'
|
||||
isLoadedBinding: 'content.isLoaded'
|
||||
isLoadingBinding: 'content.isLoading'
|
||||
|
||||
|
@ -53,7 +53,7 @@ Controller = Ember.ArrayController.extend
|
|||
if type?
|
||||
options.event_type = type.replace(/s$/, '') # poor man's singularize
|
||||
|
||||
@store.find('build', options)
|
||||
@store.query('build', options)
|
||||
|
||||
actions:
|
||||
showMoreBuilds: ->
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
`import Ember from 'ember'`
|
||||
`import Ajax from 'travis/utils/ajax'`
|
||||
|
||||
Controller = Ember.Controller.extend
|
||||
needs: ['repo']
|
||||
repo: Ember.computed.alias('controllers.repo.repo')
|
||||
ajax: Ember.inject.service()
|
||||
|
||||
repoController: Ember.inject.controller('repo')
|
||||
repo: Ember.computed.alias('repoController.repo')
|
||||
|
||||
isDeleting: false
|
||||
|
||||
|
@ -21,7 +22,7 @@ Controller = Ember.Controller.extend
|
|||
deletingDone = => @set('isDeleting', false)
|
||||
|
||||
repo = @get('repo')
|
||||
Ajax.ajax("/repos/#{@get('repo.id')}/caches", "DELETE").then(deletingDone, deletingDone).then =>
|
||||
@get('ajax').ajax("/repos/#{@get('repo.id')}/caches", "DELETE").then(deletingDone, deletingDone).then =>
|
||||
@set('model', {})
|
||||
|
||||
`export default Controller`
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
`import Ember from 'ember'`
|
||||
`import Validations from 'travis/utils/validations'`
|
||||
|
||||
Controller = Ember.ObjectController.extend Validations,
|
||||
isEditing: false
|
||||
isDeleting: false
|
||||
|
||||
validates:
|
||||
name: ['presence']
|
||||
|
||||
actionType: 'Save'
|
||||
showValueField: Ember.computed.alias('public')
|
||||
|
||||
value: ( (key, value) ->
|
||||
if arguments.length == 2
|
||||
@get('model').set('value', value)
|
||||
value
|
||||
else if @get('public')
|
||||
@get('model.value')
|
||||
else
|
||||
'••••••••••••••••'
|
||||
).property('model.value', 'public')
|
||||
|
||||
actions:
|
||||
delete: ->
|
||||
return if @get('isDeleting')
|
||||
@set('isDeleting', true)
|
||||
|
||||
@get('model').destroyRecord()
|
||||
|
||||
edit: ->
|
||||
@set('isEditing', true)
|
||||
|
||||
cancel: ->
|
||||
@set('isEditing', false)
|
||||
@get('model').revert()
|
||||
|
||||
save: ->
|
||||
return if @get('isSaving')
|
||||
|
||||
if @isValid()
|
||||
env_var = @get('model')
|
||||
|
||||
# TODO: handle errors
|
||||
env_var.save().then =>
|
||||
@set('isEditing', false)
|
||||
|
||||
`export default Controller`
|
|
@ -1,6 +0,0 @@
|
|||
`import Ember from 'ember'`
|
||||
|
||||
Controller = Ember.ArrayController.extend
|
||||
vars: Ember.computed.alias('model')
|
||||
|
||||
`export default Controller`
|
|
@ -1,45 +0,0 @@
|
|||
`import Validations from 'travis/utils/validations'`
|
||||
|
||||
Controller = Ember.Controller.extend Validations,
|
||||
needs: ['repo']
|
||||
repo: Ember.computed.alias('controllers.repo.repo')
|
||||
|
||||
isSaving: false
|
||||
|
||||
validates:
|
||||
name: ['presence']
|
||||
|
||||
actionType: 'Add'
|
||||
showValueField: true
|
||||
|
||||
reset: ->
|
||||
@setProperties(name: null, value: null, public: null)
|
||||
|
||||
actions:
|
||||
cancel: ->
|
||||
@reset()
|
||||
@transitionToRoute('env_vars')
|
||||
|
||||
save: ->
|
||||
return if @get('isSaving')
|
||||
@set('isSaving', true)
|
||||
|
||||
if @isValid()
|
||||
env_var = @store.createRecord('env_var',
|
||||
name: @get('name')
|
||||
value: @get('value')
|
||||
public: @get('public')
|
||||
repo: @get('repo')
|
||||
)
|
||||
|
||||
self = this
|
||||
env_var.save().then =>
|
||||
@set('isSaving', false)
|
||||
@reset()
|
||||
self.transitionToRoute('env_vars')
|
||||
, =>
|
||||
@set('isSaving', false)
|
||||
else
|
||||
@set('isSaving', false)
|
||||
|
||||
`export default Controller`
|
|
@ -1,8 +1,7 @@
|
|||
`import Ember from 'ember'`
|
||||
|
||||
Controller = Ember.Controller.extend
|
||||
needs: ['currentUser']
|
||||
user: Ember.computed.alias('controllers.currentUser.model')
|
||||
user: Ember.computed.alias('auth.currentUser')
|
||||
|
||||
isSyncing: Ember.computed.alias('user.isSyncing')
|
||||
|
||||
|
|
|
@ -2,13 +2,13 @@
|
|||
`import { githubCommit } from 'travis/utils/urls'`
|
||||
|
||||
Controller = Ember.Controller.extend
|
||||
needs: ['repo', 'currentUser']
|
||||
repoController: Ember.inject.controller('repo')
|
||||
|
||||
repoBinding: 'controllers.repo.repo'
|
||||
repoBinding: 'repoController.repo'
|
||||
commitBinding: 'job.commit'
|
||||
annotationsBinding: 'job.annotations'
|
||||
currentUserBinding: 'controllers.currentUser.model'
|
||||
tabBinding: 'controllers.repo.tab'
|
||||
currentUserBinding: 'auth.currentUser'
|
||||
tabBinding: 'repoController.tab'
|
||||
|
||||
currentItemBinding: 'job'
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
`import Ember from 'ember'`
|
||||
`import Ajax from 'travis/utils/ajax'`
|
||||
|
||||
Controller = Ember.Controller.extend
|
||||
isLoading: false
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
`import Ember from 'ember'`
|
||||
`import Ajax from 'travis/utils/ajax'`
|
||||
|
||||
Controller = Ember.Controller.extend
|
||||
isLoading: false
|
||||
|
@ -13,7 +12,6 @@ Controller = Ember.Controller.extend
|
|||
item
|
||||
).sortBy('default_branch.last_build.finished_at').reverse()
|
||||
repos
|
||||
|
||||
).property('model')
|
||||
|
||||
# running: (->
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
`import Ember from 'ember'`
|
||||
`import Ajax from 'travis/utils/ajax'`
|
||||
|
||||
Controller = Ember.Controller.extend
|
||||
isLoading: false
|
||||
|
|
|
@ -3,16 +3,17 @@
|
|||
Controller = Ember.Controller.extend
|
||||
name: 'profile'
|
||||
|
||||
needs: ['currentUser', 'accounts', 'account']
|
||||
userBinding: 'controllers.currentUser.model'
|
||||
accountBinding: 'controllers.account.model'
|
||||
accountController: Ember.inject.controller('account')
|
||||
accountsController: Ember.inject.controller('accounts')
|
||||
userBinding: 'auth.currentUser'
|
||||
accountBinding: 'accountController.model'
|
||||
|
||||
activate: (action, params) ->
|
||||
this["view_#{action}".camelize()]()
|
||||
|
||||
viewHooks: ->
|
||||
@connectTab('hooks')
|
||||
@get('controllers.account').reloadHooks()
|
||||
@get('accountController').reloadHooks()
|
||||
|
||||
viewUser: ->
|
||||
@connectTab('user')
|
||||
|
|
|
@ -2,13 +2,15 @@
|
|||
`import { githubRepo } from 'travis/utils/urls'`
|
||||
|
||||
Controller = Ember.Controller.extend
|
||||
needs: ['repos', 'currentUser', 'build', 'job']
|
||||
currentUserBinding: 'controllers.currentUser.model'
|
||||
jobController: Ember.inject.controller('job')
|
||||
buildController: Ember.inject.controller('build')
|
||||
reposController: Ember.inject.controller('repos')
|
||||
currentUserBinding: 'auth.currentUser'
|
||||
|
||||
classNames: ['repo']
|
||||
|
||||
build: Ember.computed.alias('controllers.build.build')
|
||||
job: Ember.computed.alias('controllers.job.job')
|
||||
build: Ember.computed.alias('buildController.build')
|
||||
job: Ember.computed.alias('jobController.job')
|
||||
|
||||
slug: (-> @get('repo.slug') ).property('repo.slug')
|
||||
isLoading: (-> @get('repo.isLoading') ).property('repo.isLoading')
|
||||
|
@ -75,15 +77,15 @@ Controller = Ember.Controller.extend
|
|||
Ember.run.scheduleOnce('actions', this, @_lastBuildDidChange);
|
||||
|
||||
_lastBuildDidChange: ->
|
||||
build = @get('repo.lastBuild')
|
||||
build = @get('repo.defaultBranch.lastBuild')
|
||||
@set('build', build)
|
||||
|
||||
stopObservingLastBuild: ->
|
||||
@removeObserver('repo.lastBuild', this, 'lastBuildDidChange')
|
||||
@removeObserver('repo.defaultBranch.lastBuild', this, 'lastBuildDidChange')
|
||||
|
||||
observeLastBuild: ->
|
||||
@lastBuildDidChange()
|
||||
@addObserver('repo.lastBuild', this, 'lastBuildDidChange')
|
||||
@addObserver('repo.defaultBranch.lastBuild', this, 'lastBuildDidChange')
|
||||
|
||||
connectTab: (tab) ->
|
||||
# TODO: such implementation seems weird now, because we render
|
||||
|
|
|
@ -1,132 +0,0 @@
|
|||
`import Ember from 'ember'`
|
||||
`import limit from 'travis/utils/computed-limit'`
|
||||
`import Repo from 'travis/models/repo'`
|
||||
|
||||
Controller = Ember.Controller.extend
|
||||
contentBinding: 'repos'
|
||||
actions:
|
||||
activate: (name) ->
|
||||
@activate(name)
|
||||
|
||||
showRunningJobs: ->
|
||||
@activate('running')
|
||||
|
||||
showMyRepositories: ->
|
||||
# this is a bit of a hack. I don't want to switch URL for 'running'
|
||||
# so depending on current state I'm either just switching back or
|
||||
# redirecting
|
||||
if @get('tab') == 'running'
|
||||
@activate('owned')
|
||||
else
|
||||
@transitionToRoute('main.repositories')
|
||||
|
||||
|
||||
tabOrIsLoadedDidChange: (->
|
||||
@possiblyRedirectToGettingStartedPage()
|
||||
).observes('isLoaded', 'tab', 'repos.length')
|
||||
|
||||
possiblyRedirectToGettingStartedPage: ->
|
||||
Ember.run.scheduleOnce 'routerTransitions', this, ->
|
||||
if @get('tab') == 'owned' && @get('isLoaded') && @get('repos.length') == 0
|
||||
@container.lookup('router:main').send('redirectToGettingStarted')
|
||||
|
||||
isLoadedBinding: 'repos.isLoaded'
|
||||
needs: ['currentUser', 'repo']
|
||||
currentUserBinding: 'controllers.currentUser.model'
|
||||
selectedRepo: (->
|
||||
# we need to observe also repo.content here, because we use
|
||||
# ObjectProxy in repo controller
|
||||
# TODO: get rid of ObjectProxy there
|
||||
@get('controllers.repo.repo.content') || @get('controllers.repo.repo')
|
||||
).property('controllers.repo.repo', 'controllers.repo.repo.content')
|
||||
|
||||
startedJobsCount: Ember.computed.alias('runningJobs.length')
|
||||
allJobsCount: (->
|
||||
@get('startedJobsCount') + @get('queuedJobs.length')
|
||||
).property('startedJobsCount', 'queuedJobs.length')
|
||||
|
||||
init: ->
|
||||
@_super.apply this, arguments
|
||||
if !Ember.testing
|
||||
Visibility.every @config.intervals.updateTimes, @updateTimes.bind(this)
|
||||
|
||||
runningJobs: (->
|
||||
result = @store.filter('job', {}, (job) ->
|
||||
['queued', 'started', 'received'].indexOf(job.get('state')) != -1
|
||||
)
|
||||
result.set('isLoaded', false)
|
||||
result.then =>
|
||||
result.set('isLoaded', true)
|
||||
result
|
||||
).property()
|
||||
|
||||
queuedJobs: (->
|
||||
result = @get('store').filter('job', {}, (job) ->
|
||||
['created'].indexOf(job.get('state')) != -1
|
||||
)
|
||||
result.set('isLoaded', false)
|
||||
result.then =>
|
||||
result.set('isLoaded', true)
|
||||
result
|
||||
).property()
|
||||
|
||||
recentRepos: (->
|
||||
# I return an empty array here, because we're removing left sidebar, but
|
||||
# I don't want to refactor too much code (it will be all changed anyway
|
||||
# when we switch to new dashboard)
|
||||
[]
|
||||
).property()
|
||||
|
||||
updateTimes: ->
|
||||
if repos = @get('repos')
|
||||
repos.forEach (r) -> r.updateTimes()
|
||||
|
||||
activate: (tab, params) ->
|
||||
@set('sortProperties', ['sortOrder'])
|
||||
@set('tab', tab)
|
||||
this["view_#{tab}".camelize()](params)
|
||||
|
||||
viewOwned: ->
|
||||
@set('repos', @get('userRepos'))
|
||||
|
||||
viewRunning: ->
|
||||
|
||||
userRepos: (->
|
||||
if login = @get('currentUser.login')
|
||||
Repo.accessibleBy(@store, login)
|
||||
else
|
||||
[]
|
||||
).property('currentUser.login')
|
||||
|
||||
viewSearch: (phrase) ->
|
||||
@set('search', phrase)
|
||||
@set('repos', Repo.search(@store, phrase))
|
||||
|
||||
searchObserver: (->
|
||||
search = @get('search')
|
||||
if search
|
||||
@searchFor search
|
||||
).observes('search')
|
||||
|
||||
searchFor: (phrase) ->
|
||||
Ember.run.cancel(@searchLater) if @searchLater
|
||||
@searchLater = Ember.run.later(this, (->
|
||||
@transitionTo('main.search', phrase.replace(/\//g, '%2F'))
|
||||
), 500)
|
||||
|
||||
noReposMessage: (->
|
||||
tab = @get('tab')
|
||||
|
||||
if tab == 'owned'
|
||||
'You don\'t have any repos set up on Travis CI'
|
||||
else if tab == 'recent'
|
||||
'Repositories could not be loaded'
|
||||
else
|
||||
'Could not find any repos'
|
||||
).property('tab')
|
||||
|
||||
showRunningJobs: (->
|
||||
@get('tab') == 'running'
|
||||
).property('tab')
|
||||
|
||||
`export default Controller`
|
234
app/controllers/repos.js
Normal file
234
app/controllers/repos.js
Normal file
|
@ -0,0 +1,234 @@
|
|||
import Ember from 'ember';
|
||||
import limit from 'travis/utils/computed-limit';
|
||||
import Repo from 'travis/models/repo';
|
||||
|
||||
var sortCallback = function(repo1, repo2) {
|
||||
// this function could be made simpler, but I think it's clearer this way
|
||||
// what're we really trying to achieve
|
||||
|
||||
var lastBuild1 = repo1.get('defaultBranch.lastBuild');
|
||||
var lastBuild2 = repo2.get('defaultBranch.lastBuild');
|
||||
|
||||
if(!lastBuild1 && !lastBuild2) {
|
||||
// if both repos lack builds, put newer repo first
|
||||
return repo1.get('id') > repo2.get('id') ? -1 : 1;
|
||||
} else if(lastBuild1 && !lastBuild2) {
|
||||
// if only repo1 has a build, it goes first
|
||||
return -1;
|
||||
} else if(lastBuild2 && !lastBuild1) {
|
||||
// if only repo2 has a build, it goes first
|
||||
return 1;
|
||||
}
|
||||
|
||||
var finishedAt1 = lastBuild1.get('finishedAt');
|
||||
var finishedAt2 = lastBuild2.get('finishedAt');
|
||||
|
||||
if(finishedAt1) {
|
||||
finishedAt1 = new Date(finishedAt1);
|
||||
}
|
||||
if(finishedAt2) {
|
||||
finishedAt2 = new Date(finishedAt2);
|
||||
}
|
||||
|
||||
if(finishedAt1 && finishedAt2) {
|
||||
// if both builds finished, put newer first
|
||||
return finishedAt1.getTime() > finishedAt2.getTime() ? -1 : 1;
|
||||
} else if(finishedAt1 && !finishedAt2) {
|
||||
// if repo1 finished, but repo2 didn't, put repo2 first
|
||||
return 1;
|
||||
} else if(finishedAt2 && !finishedAt1) {
|
||||
// if repo2 finisher, but repo1 didn't, put repo1 first
|
||||
return -1;
|
||||
} else {
|
||||
// none of the builds finished, put newer build first
|
||||
return lastBuild1.get('id') > lastBuild2.get('id') ? -1 : 1;
|
||||
}
|
||||
|
||||
throw "should not happen";
|
||||
};
|
||||
|
||||
|
||||
|
||||
var Controller = Ember.Controller.extend({
|
||||
ajax: Ember.inject.service(),
|
||||
|
||||
actions: {
|
||||
activate: function(name) {
|
||||
return this.activate(name);
|
||||
},
|
||||
showRunningJobs: function() {
|
||||
return this.activate('running');
|
||||
},
|
||||
showMyRepositories: function() {
|
||||
if (this.get('tab') === 'running') {
|
||||
return this.activate('owned');
|
||||
} else {
|
||||
return this.transitionToRoute('main.repositories');
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
tabOrIsLoadedDidChange: function() {
|
||||
return this.possiblyRedirectToGettingStartedPage();
|
||||
}.observes('isLoaded', 'tab', 'repos.length'),
|
||||
|
||||
possiblyRedirectToGettingStartedPage() {
|
||||
return Ember.run.scheduleOnce('routerTransitions', this, function() {
|
||||
if (this.get('tab') === 'owned' && this.get('isLoaded') && this.get('repos.length') === 0) {
|
||||
return this.container.lookup('router:main').send('redirectToGettingStarted');
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
isLoaded: false,
|
||||
repoController: Ember.inject.controller('repo'),
|
||||
currentUserBinding: 'auth.currentUser',
|
||||
|
||||
selectedRepo: function() {
|
||||
return this.get('repoController.repo.content') || this.get('repoController.repo');
|
||||
}.property('repoController.repo', 'repoController.repo.content'),
|
||||
|
||||
startedJobsCount: Ember.computed.alias('runningJobs.length'),
|
||||
|
||||
allJobsCount: function() {
|
||||
return this.get('startedJobsCount') + this.get('queuedJobs.length');
|
||||
}.property('startedJobsCount', 'queuedJobs.length'),
|
||||
|
||||
init() {
|
||||
this._super.apply(this, arguments);
|
||||
if (!Ember.testing) {
|
||||
return Visibility.every(this.config.intervals.updateTimes, this.updateTimes.bind(this));
|
||||
}
|
||||
},
|
||||
|
||||
runningJobs: function() {
|
||||
var result;
|
||||
|
||||
result = this.store.filter('job', {}, function(job) {
|
||||
return ['queued', 'started', 'received'].indexOf(job.get('state')) !== -1;
|
||||
});
|
||||
result.set('isLoaded', false);
|
||||
result.then(function() {
|
||||
return result.set('isLoaded', true);
|
||||
});
|
||||
|
||||
return result;
|
||||
}.property(),
|
||||
|
||||
queuedJobs: function() {
|
||||
var result;
|
||||
result = this.get('store').filter('job', {}, function(job) {
|
||||
return ['created'].indexOf(job.get('state')) !== -1;
|
||||
});
|
||||
result.set('isLoaded', false);
|
||||
result.then(function() {
|
||||
result.set('isLoaded', true);
|
||||
});
|
||||
|
||||
return result;
|
||||
}.property(),
|
||||
|
||||
recentRepos: function() {
|
||||
return [];
|
||||
}.property(),
|
||||
|
||||
updateTimes() {
|
||||
var repos;
|
||||
if (repos = this.get('repos')) {
|
||||
return repos.forEach(function(r) {
|
||||
return r.updateTimes();
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
activate(tab, params) {
|
||||
this.set('sortProperties', ['sortOrder']);
|
||||
this.set('tab', tab);
|
||||
return this[("view_" + tab).camelize()](params);
|
||||
},
|
||||
|
||||
viewOwned() {
|
||||
var repos, user;
|
||||
|
||||
if (repos = this.get('ownedRepos')) {
|
||||
return this.set('_repos', repos);
|
||||
} else if (!this.get('fetchingOwnedRepos')) {
|
||||
this.set('fetchingOwnedRepos', true);
|
||||
this.set('isLoaded', false);
|
||||
|
||||
if (user = this.get('currentUser')) {
|
||||
user.get('_rawPermissions').then( (data) => {
|
||||
repos = Repo.accessibleBy(this.store, data.pull).then(
|
||||
(reposRecordArray) => {
|
||||
this.set('isLoaded', true);
|
||||
this.set('_repos', reposRecordArray);
|
||||
this.set('ownedRepos', reposRecordArray);
|
||||
this.set('fetchingOwnedRepos', false);
|
||||
return reposRecordArray;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
viewRunning() {},
|
||||
|
||||
viewSearch(phrase) {
|
||||
this.set('search', phrase);
|
||||
this.set('isLoaded', false);
|
||||
Repo.search(this.store, this.get('ajax'), phrase).then( (reposRecordArray) => {
|
||||
this.set('isLoaded', true);
|
||||
this.set('_repos', reposRecordArray);
|
||||
});
|
||||
},
|
||||
|
||||
searchObserver: function() {
|
||||
var search;
|
||||
search = this.get('search');
|
||||
if (search) {
|
||||
return this.searchFor(search);
|
||||
}
|
||||
}.observes('search'),
|
||||
|
||||
searchFor(phrase) {
|
||||
if (this.searchLater) {
|
||||
Ember.run.cancel(this.searchLater);
|
||||
}
|
||||
this.searchLater = Ember.run.later(this, (function() {
|
||||
this.transitionTo('main.search', phrase.replace(/\//g, '%2F'));
|
||||
}), 500);
|
||||
},
|
||||
|
||||
noReposMessage: function() {
|
||||
var tab;
|
||||
tab = this.get('tab');
|
||||
if (tab === 'owned') {
|
||||
return 'You don\'t have any repos set up on Travis CI';
|
||||
} else if (tab === 'recent') {
|
||||
return 'Repositories could not be loaded';
|
||||
} else {
|
||||
return 'Could not find any repos';
|
||||
}
|
||||
}.property('tab'),
|
||||
|
||||
showRunningJobs: function() {
|
||||
return this.get('tab') === 'running';
|
||||
}.property('tab'),
|
||||
|
||||
repos: function() {
|
||||
var repos = this.get('_repos');
|
||||
|
||||
if(repos && repos.toArray) {
|
||||
repos = repos.toArray();
|
||||
}
|
||||
|
||||
if(repos && repos.sort) {
|
||||
return repos.sort(sortCallback);
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}.property('_repos.[]', '_repos.@each.lastBuildFinishedAt',
|
||||
'_repos.@each.lastBuildId')
|
||||
});
|
||||
|
||||
export default Controller;
|
|
@ -1,12 +1,11 @@
|
|||
`import Ember from 'ember'`
|
||||
|
||||
Controller = Ember.ArrayController.extend
|
||||
needs: ['repo']
|
||||
repo: Ember.computed.alias('controllers.repo.repo')
|
||||
repoController: Ember.inject.controller('repo')
|
||||
|
||||
lintUrl: (->
|
||||
slug = @get('repo.slug')
|
||||
slug = @get('repoController.repo.slug')
|
||||
"https://lint.travis-ci.org/#{slug}"
|
||||
).property('repo.slug')
|
||||
).property('repoController.repo.slug')
|
||||
|
||||
`export default Controller`
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
`import Ember from 'ember'`
|
||||
|
||||
Controller = Ember.Controller.extend
|
||||
settings: Ember.computed.alias('model.settings')
|
||||
|
||||
settingsChanged: (->
|
||||
value = @get('settings.maximum_number_of_builds')
|
||||
console.log value
|
||||
if parseInt(value) > 0 || value == '0' || value == 0
|
||||
@set('settings.maximum_number_of_builds_valid', '')
|
||||
@get('model').saveSettings(@get('settings')).then null, ->
|
||||
Travis.flash(error: 'There was an error while saving settings. Please try again.')
|
||||
else
|
||||
@set('settings.maximum_number_of_builds_valid', 'invalid')
|
||||
).observes('settings.maximum_number_of_builds')
|
||||
|
||||
actions:
|
||||
save: ->
|
||||
@get('model').saveSettings(@get('settings')).then null, ->
|
||||
Travis.flash(error: 'There was an error while saving settings. Please try again.')
|
||||
|
||||
`export default Controller`
|
|
@ -1,12 +1,11 @@
|
|||
`import Ember from 'ember'`
|
||||
`import Ajax from 'travis/utils/ajax'`
|
||||
`import config from 'travis/config/environment'`
|
||||
|
||||
Controller = Ember.Controller.extend
|
||||
needs: ['currentUser']
|
||||
userBinding: 'controllers.currentUser.model'
|
||||
userBinding: 'auth.currentUser'
|
||||
|
||||
store: Ember.inject.service()
|
||||
storage: Ember.inject.service()
|
||||
currentUserBinding: 'auth.currentUser'
|
||||
|
||||
userName: (->
|
||||
|
@ -18,6 +17,8 @@ Controller = Ember.Controller.extend
|
|||
).property('user.gravatarId')
|
||||
|
||||
defineTowerColor: (broadcastArray) ->
|
||||
return '' unless broadcastArray
|
||||
|
||||
if broadcastArray.length
|
||||
if broadcastArray.findBy('category', 'warning')
|
||||
return 'warning'
|
||||
|
@ -39,7 +40,7 @@ Controller = Ember.Controller.extend
|
|||
options.type = 'GET'
|
||||
options.headers = { Authorization: "token #{@auth.token()}" }
|
||||
|
||||
seenBroadcasts = Travis.storage.getItem('travis.seen_broadcasts')
|
||||
seenBroadcasts = @get('storage').getItem('travis.seen_broadcasts')
|
||||
if seenBroadcasts
|
||||
seenBroadcasts = JSON.parse(seenBroadcasts)
|
||||
else
|
||||
|
@ -73,13 +74,13 @@ Controller = Ember.Controller.extend
|
|||
|
||||
markBroadcastAsSeen: (broadcast) ->
|
||||
id = broadcast.get('id').toString()
|
||||
seenBroadcasts = Travis.storage.getItem('travis.seen_broadcasts')
|
||||
seenBroadcasts = @get('storage').getItem('travis.seen_broadcasts')
|
||||
if seenBroadcasts
|
||||
seenBroadcasts = JSON.parse(seenBroadcasts)
|
||||
else
|
||||
seenBroadcasts = []
|
||||
seenBroadcasts.push(id)
|
||||
Travis.storage.setItem('travis.seen_broadcasts', JSON.stringify(seenBroadcasts))
|
||||
@get('storage').setItem('travis.seen_broadcasts', JSON.stringify(seenBroadcasts))
|
||||
@get('broadcasts.content').removeObject(broadcast)
|
||||
@set('broadcasts.lastBroadcastStatus', @defineTowerColor(@get('broadcasts.content')))
|
||||
return false
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
`import { safe, formatCommit as formatCommitHelper } from 'travis/utils/helpers'`
|
||||
|
||||
helper = Ember.HTMLBars.makeBoundHelper (params) ->
|
||||
helper = Ember.Helper.helper (params) ->
|
||||
commit = params[0]
|
||||
safe formatCommitHelper(commit.get('sha'), commit.get('branch')) if commit
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
`import { timeInWords, safe } from 'travis/utils/helpers'`
|
||||
`import Ember from "ember"`
|
||||
|
||||
helper = Ember.HTMLBars.makeBoundHelper (params) ->
|
||||
helper = Ember.Helper.helper (params) ->
|
||||
safe timeInWords(params[0])
|
||||
|
||||
`export default helper`
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
`import { formatMessage as _formatMessage, safe } from 'travis/utils/helpers'`
|
||||
`import Ember from "ember"`
|
||||
|
||||
helper = Ember.HTMLBars.makeBoundHelper (params, hash) ->
|
||||
helper = Ember.Helper.helper (params, hash) ->
|
||||
safe _formatMessage(params[0], hash)
|
||||
|
||||
`export default helper`
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
`import { formatSha as _formatSha, safe } from 'travis/utils/helpers'`
|
||||
`import Ember from "ember"`
|
||||
|
||||
helper = Ember.HTMLBars.makeBoundHelper (params) ->
|
||||
helper = Ember.Helper.helper (params) ->
|
||||
safe _formatSha(params[0])
|
||||
|
||||
`export default helper`
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
`import { timeAgoInWords, safe } from 'travis/utils/helpers'`
|
||||
`import Ember from "ember"`
|
||||
|
||||
helper = Ember.HTMLBars.makeBoundHelper (params) ->
|
||||
helper = Ember.Helper.helper (params) ->
|
||||
safe timeAgoInWords(params[0]) || '-'
|
||||
|
||||
`export default helper`
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
`import { formatCommit, safe } from 'travis/utils/helpers'`
|
||||
`import { githubCommit as githubCommitUrl } from 'travis/utils/urls'`
|
||||
|
||||
helper = Ember.HTMLBars.makeBoundHelper (params) ->
|
||||
helper = Ember.Helper.helper (params) ->
|
||||
slug = params[0]
|
||||
commitSha = params[1]
|
||||
return '' unless commitSha
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
`import { safe } from 'travis/utils/helpers'`
|
||||
`import Ember from "ember"`
|
||||
|
||||
helper = Ember.HTMLBars.makeBoundHelper (params) ->
|
||||
helper = Ember.Helper.helper (params) ->
|
||||
state = params[0]
|
||||
if state == 'received'
|
||||
'booting'
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
`import { timeAgoInWords, safe } from 'travis/utils/helpers'`
|
||||
`import Ember from "ember"`
|
||||
|
||||
helper = Ember.HTMLBars.makeBoundHelper (params) ->
|
||||
helper = Ember.Helper.helper (params) ->
|
||||
safe timeAgoInWords(params[0]) || 'currently running'
|
||||
|
||||
`export default helper`
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
`import { timeAgoInWords, safe } from 'travis/utils/helpers'`
|
||||
`import Ember from "ember"`
|
||||
|
||||
helper = Ember.HTMLBars.makeBoundHelper (params) ->
|
||||
helper = Ember.Helper.helper (params) ->
|
||||
safe moment(params[0]).format('MMMM D, YYYY H:mm:ss') || '-'
|
||||
|
||||
`export default helper`
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
`import { pathFrom } from 'travis/utils/helpers'`
|
||||
`import Ember from "ember"`
|
||||
|
||||
helper = Ember.HTMLBars.makeBoundHelper (params) ->
|
||||
helper = Ember.Helper.helper (params) ->
|
||||
url = params[0]
|
||||
path = pathFrom(url)
|
||||
if path.indexOf('...') >= 0
|
||||
|
|
|
@ -4,4 +4,4 @@ fn = (size) ->
|
|||
if size
|
||||
(size / 1024 / 1024).toFixed(2)
|
||||
|
||||
`export default Ember.HTMLBars.makeBoundHelper(fn)`
|
||||
`export default Ember.Helper.helper(fn)`
|
||||
|
|
|
@ -1,16 +1,11 @@
|
|||
`import Auth from 'travis/utils/auth'`
|
||||
`import TestAuth from 'travis/utils/test-auth'`
|
||||
|
||||
initialize = (container, app) ->
|
||||
app.register 'auth:main', if Ember.testing then TestAuth else Auth
|
||||
|
||||
app.inject('route', 'auth', 'auth:main')
|
||||
app.inject('controller', 'auth', 'auth:main')
|
||||
app.inject('application', 'auth', 'auth:main')
|
||||
app.inject('component', 'auth', 'auth:main')
|
||||
app.inject('service:flashes', 'auth', 'auth:main')
|
||||
|
||||
app.inject('auth', 'store', 'service:store')
|
||||
app.inject('route', 'auth', 'service:auth')
|
||||
app.inject('controller', 'auth', 'service:auth')
|
||||
app.inject('application', 'auth', 'service:auth')
|
||||
app.inject('component', 'auth', 'service:auth')
|
||||
app.inject('service:flashes', 'auth', 'service:auth')
|
||||
|
||||
AuthInitializer =
|
||||
name: 'auth'
|
||||
|
|
|
@ -2,12 +2,7 @@
|
|||
`import TravisPusher from 'travis/utils/pusher'`
|
||||
|
||||
initialize = (registry, application) ->
|
||||
if config.pusher.key
|
||||
application.pusher = new TravisPusher(config.pusher)
|
||||
|
||||
application.register 'pusher:main', application.pusher, { instantiate: false }
|
||||
|
||||
application.inject('route', 'pusher', 'pusher:main')
|
||||
null
|
||||
|
||||
PusherInitializer =
|
||||
name: 'pusher'
|
||||
|
|
|
@ -1,16 +1,11 @@
|
|||
`import Slider from 'travis/utils/slider'`
|
||||
`import Tailing from 'travis/utils/tailing'`
|
||||
`import ToTop from 'travis/utils/to-top'`
|
||||
`import config from 'travis/config/environment'`
|
||||
|
||||
initialize = (container, application) ->
|
||||
application.slider = new Slider(application.storage)
|
||||
application.tailing = new Tailing($(window), '#tail', '#log')
|
||||
application.toTop = new ToTop($(window), '.to-top', '#log-container')
|
||||
|
||||
application.register 'slider:main', application.slider, { instantiate: false }
|
||||
application.inject('controller', 'slider', 'slider:main')
|
||||
|
||||
Initializer =
|
||||
name: 'services'
|
||||
initialize: initialize
|
||||
|
|
|
@ -1,58 +0,0 @@
|
|||
`import Ember from 'ember'`
|
||||
|
||||
Storage = Em.Object.extend
|
||||
init: ->
|
||||
@set('storage', {})
|
||||
key: (key) ->
|
||||
"__#{key.replace('.', '__')}"
|
||||
getItem: (k) ->
|
||||
return @get("storage.#{@key(k)}")
|
||||
setItem: (k,v) ->
|
||||
@set("storage.#{@key(k)}", v)
|
||||
removeItem: (k) ->
|
||||
@setItem(k, null)
|
||||
clear: ->
|
||||
@set('storage', {})
|
||||
|
||||
sessionStorage = (->
|
||||
storage = null
|
||||
try
|
||||
# firefox will not throw error on access for sessionStorage var,
|
||||
# you need to actually get something from session
|
||||
window.sessionStorage.getItem('foo')
|
||||
storage = window.sessionStorage
|
||||
catch err
|
||||
storage = Storage.create()
|
||||
|
||||
storage
|
||||
)()
|
||||
|
||||
storage = (->
|
||||
storage = null
|
||||
try
|
||||
storage = window.localStorage || throw('no storage')
|
||||
catch err
|
||||
storage = Storage.create()
|
||||
|
||||
storage
|
||||
)()
|
||||
|
||||
initialize = (container, application) ->
|
||||
application.register 'storage:main', storage, { instantiate: false }
|
||||
application.register 'sessionStorage:main', sessionStorage, { instantiate: false }
|
||||
|
||||
application.inject('auth', 'storage', 'storage:main')
|
||||
application.inject('auth', 'sessionStorage', 'sessionStorage:main')
|
||||
|
||||
# I still use Travis.storage in some places which are not that easy to
|
||||
# refactor
|
||||
application.storage = storage
|
||||
application.sessionStorage = sessionStorage
|
||||
|
||||
StorageInitializer =
|
||||
name: 'storage'
|
||||
before: 'services'
|
||||
initialize: initialize
|
||||
|
||||
`export {initialize}`
|
||||
`export default StorageInitializer`
|
|
@ -1,5 +1,17 @@
|
|||
`import config from 'travis/config/environment'`
|
||||
`import TravisPusher from 'travis/utils/pusher'`
|
||||
|
||||
initialize = (data) ->
|
||||
data.application.pusher.store = data.container.lookup('service:store')
|
||||
application = data.application
|
||||
|
||||
if config.pusher.key
|
||||
application.pusher = new TravisPusher(config.pusher, data.container.lookup('service:ajax'))
|
||||
|
||||
application.register 'pusher:main', application.pusher, { instantiate: false }
|
||||
|
||||
application.inject('route', 'pusher', 'pusher:main')
|
||||
|
||||
application.pusher.store = data.container.lookup('service:store')
|
||||
|
||||
PusherInitializer =
|
||||
name: 'pusher'
|
||||
|
|
|
@ -2,25 +2,11 @@
|
|||
`import Model from 'travis/models/model'`
|
||||
|
||||
Branch = Model.extend
|
||||
repositoryId: DS.attr('number')
|
||||
commitId: DS.attr('number')
|
||||
state: DS.attr()
|
||||
number: DS.attr('number')
|
||||
branch: DS.attr()
|
||||
message: DS.attr()
|
||||
result: DS.attr('number')
|
||||
duration: DS.attr('number')
|
||||
startedAt: DS.attr()
|
||||
finishedAt: DS.attr()
|
||||
name: DS.attr('string')
|
||||
defaultBranch: DS.attr('boolean')
|
||||
|
||||
commit: DS.belongsTo('commit')
|
||||
|
||||
repo: (->
|
||||
@store.find('repo', @get('repositoryId')) if @get('repositoryId')
|
||||
).property('repositoryId')
|
||||
|
||||
updateTimes: ->
|
||||
@notifyPropertyChange 'started_at'
|
||||
@notifyPropertyChange 'finished_at'
|
||||
lastBuild: DS.belongsTo('build')
|
||||
builds: DS.hasMany('builds', inverse: 'branch')
|
||||
repo: DS.belongsTo('repo', inverse: 'defaultBranch')
|
||||
|
||||
`export default Branch`
|
||||
|
|
|
@ -18,7 +18,7 @@ Broadcast = Model.extend
|
|||
|
||||
Broadcast.reopenClass
|
||||
seen: (->
|
||||
seenBroadcasts = Travis.storage.getItem('travis.seen_broadcasts')
|
||||
seenBroadcasts = Travis.lookup('service:storage').getItem('travis.seen_broadcasts')
|
||||
seenBroadcasts = JSON.parse(seenBroadcasts) if seenBroadcasts?
|
||||
Ember.A(seenBroadcasts || [])
|
||||
).property()
|
||||
|
|
|
@ -1,26 +1,28 @@
|
|||
`import { durationFrom, configKeys, compact } from 'travis/utils/helpers'`
|
||||
`import Ajax from 'travis/utils/ajax'`
|
||||
`import configKeysMap from 'travis/utils/keys-map'`
|
||||
`import Ember from 'ember'`
|
||||
`import Model from 'travis/models/model'`
|
||||
`import DurationCalculations from 'travis/utils/duration-calculations'`
|
||||
|
||||
Build = Model.extend DurationCalculations,
|
||||
ajax: Ember.inject.service()
|
||||
|
||||
state: DS.attr()
|
||||
number: DS.attr('number')
|
||||
branch: DS.attr('string')
|
||||
message: DS.attr('string')
|
||||
_duration: DS.attr('number')
|
||||
_config: DS.attr('object')
|
||||
_startedAt: DS.attr()
|
||||
_finishedAt: DS.attr()
|
||||
_finishedAt: DS.attr('string')
|
||||
pullRequest: DS.attr('boolean')
|
||||
pullRequestTitle: DS.attr()
|
||||
pullRequestNumber: DS.attr('number')
|
||||
eventType: DS.attr('string')
|
||||
repositoryId: DS.attr('number')
|
||||
|
||||
branch: DS.belongsTo('branch', async: false, inverse: 'builds')
|
||||
repo: DS.belongsTo('repo', async: true)
|
||||
commit: DS.belongsTo('commit', async: true)
|
||||
commit: DS.belongsTo('commit', async: false)
|
||||
jobs: DS.hasMany('job', async: true)
|
||||
|
||||
config: (->
|
||||
|
@ -90,11 +92,11 @@ Build = Model.extend DurationCalculations,
|
|||
canRestart: Ember.computed.alias('isFinished')
|
||||
|
||||
cancel: (->
|
||||
Ajax.post "/builds/#{@get('id')}/cancel"
|
||||
@get('ajax').post "/builds/#{@get('id')}/cancel"
|
||||
)
|
||||
|
||||
restart: ->
|
||||
Ajax.post "/builds/#{@get('id')}/restart"
|
||||
@get('ajax').post "/builds/#{@get('id')}/restart"
|
||||
|
||||
formattedFinishedAt: (->
|
||||
if finishedAt = @get('finishedAt')
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
`import { durationFrom, configKeys, compact } from 'travis/utils/helpers'`
|
||||
`import Ajax from 'travis/utils/ajax'`
|
||||
`import configKeysMap from 'travis/utils/keys-map'`
|
||||
`import Ember from 'ember'`
|
||||
`import Model from 'travis/models/model'`
|
||||
|
@ -7,6 +6,7 @@
|
|||
`import DurationCalculations from 'travis/utils/duration-calculations'`
|
||||
|
||||
Job = Model.extend DurationCalculations,
|
||||
ajax: Ember.inject.service()
|
||||
logId: DS.attr()
|
||||
|
||||
queue: DS.attr()
|
||||
|
@ -24,13 +24,15 @@ Job = Model.extend DurationCalculations,
|
|||
build: DS.belongsTo('build', async: true)
|
||||
commit: DS.belongsTo('commit', async: true)
|
||||
|
||||
branch: Ember.computed.alias('build.branch')
|
||||
|
||||
annotations: DS.hasMany('annotation')
|
||||
|
||||
_config: DS.attr('object')
|
||||
|
||||
log: ( ->
|
||||
@set('isLogAccessed', true)
|
||||
Log.create(job: this)
|
||||
Log.create(job: this, ajax: @get('ajax'))
|
||||
).property()
|
||||
|
||||
startedAt: (->
|
||||
|
@ -94,11 +96,11 @@ Job = Model.extend DurationCalculations,
|
|||
canRestart: Ember.computed.alias('isFinished')
|
||||
|
||||
cancel: (->
|
||||
Ajax.post "/jobs/#{@get('id')}/cancel"
|
||||
@get('ajax').post "/jobs/#{@get('id')}/cancel"
|
||||
)
|
||||
|
||||
removeLog: ->
|
||||
Ajax.patch("/jobs/#{@get('id')}/log").then =>
|
||||
@get('ajax').patch("/jobs/#{@get('id')}/log").then =>
|
||||
@reloadLog()
|
||||
|
||||
reloadLog: ->
|
||||
|
@ -106,7 +108,7 @@ Job = Model.extend DurationCalculations,
|
|||
@get('log').fetch()
|
||||
|
||||
restart: ->
|
||||
Ajax.post "/jobs/#{@get('id')}/restart"
|
||||
@get('ajax').post "/jobs/#{@get('id')}/restart"
|
||||
|
||||
appendLog: (part) ->
|
||||
@get('log').append part
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
`import Model from 'travis/models/model'`
|
||||
`import Ajax from 'travis/utils/ajax'`
|
||||
`import Job from 'travis/models/job'`
|
||||
`import Ember from 'ember'`
|
||||
`import config from 'travis/config/environment'`
|
||||
|
@ -9,7 +8,7 @@ Request = Ember.Object.extend
|
|||
accept: 'application/json; chunked=true; version=2, text/plain; version=2'
|
||||
|
||||
run: ->
|
||||
Ajax.ajax "/jobs/#{@id}/log?cors_hax=true", 'GET',
|
||||
@get('ajax').ajax "/jobs/#{@id}/log?cors_hax=true", 'GET',
|
||||
dataType: 'text'
|
||||
headers: @HEADERS
|
||||
success: (body, status, xhr) => Ember.run(this, -> @handle(body, status, xhr))
|
||||
|
@ -50,7 +49,7 @@ Log = Ember.Object.extend
|
|||
data['part_numbers'] = partNumbers if partNumbers
|
||||
data['after'] = after if after
|
||||
|
||||
Ajax.ajax "/jobs/#{@get('job.id')}/log", 'GET',
|
||||
@get('ajax').ajax "/jobs/#{@get('job.id')}/log", 'GET',
|
||||
dataType: 'json'
|
||||
headers:
|
||||
accept: 'application/json; chunked=true; version=2'
|
||||
|
@ -81,7 +80,8 @@ Log = Ember.Object.extend
|
|||
@set('removed', true)
|
||||
@loadParts(json['log']['parts'])
|
||||
text: (text) => @loadText(text)
|
||||
Request.create(id: id, handlers: handlers, log: this).run() if id = @get('job.id')
|
||||
if id = @get('job.id')
|
||||
Request.create(id: id, handlers: handlers, log: this, ajax: @get('ajax')).run()
|
||||
|
||||
clear: ->
|
||||
@clearParts()
|
||||
|
|
|
@ -1,40 +1,28 @@
|
|||
`import ExpandableRecordArray from 'travis/utils/expandable-record-array'`
|
||||
`import Model from 'travis/models/model'`
|
||||
`import Ajax from 'travis/utils/ajax'`
|
||||
# TODO: Investigate for some weird reason if I use durationFrom here not durationFromHelper,
|
||||
# the function stops being visible inside computed properties.
|
||||
`import { durationFrom as durationFromHelper } from 'travis/utils/helpers'`
|
||||
`import Build from 'travis/models/build'`
|
||||
|
||||
Repo = Model.extend
|
||||
ajax: Ember.inject.service()
|
||||
|
||||
slug: DS.attr()
|
||||
description: DS.attr()
|
||||
private: DS.attr('boolean')
|
||||
lastBuildNumber: DS.attr('number')
|
||||
lastBuildState: DS.attr()
|
||||
lastBuildStartedAt: DS.attr()
|
||||
lastBuildFinishedAt: DS.attr()
|
||||
githubLanguage: DS.attr()
|
||||
_lastBuildDuration: DS.attr('number')
|
||||
lastBuildLanguage: DS.attr()
|
||||
active: DS.attr()
|
||||
lastBuildId: DS.attr('number')
|
||||
lastBuildHash: (->
|
||||
{
|
||||
id: @get('lastBuildId')
|
||||
number: @get('lastBuildNumber')
|
||||
repo: this
|
||||
}
|
||||
).property('lastBuildId', 'lastBuildNumber')
|
||||
|
||||
lastBuild: (->
|
||||
if id = @get('lastBuildId')
|
||||
@store.find('build', id)
|
||||
@store.recordForId('build', id)
|
||||
).property('lastBuildId')
|
||||
#lastBuild: DS.belongsTo('build')
|
||||
defaultBranch: DS.belongsTo('branch', async: false)
|
||||
|
||||
# just for sorting
|
||||
lastBuildFinishedAt: Ember.computed.oneWay('defaultBranch.lastBuild.finishedAt')
|
||||
lastBuildId: Ember.computed.oneWay('defaultBranch.lastBuild.id')
|
||||
|
||||
withLastBuild: ->
|
||||
@filter( (repo) -> repo.get('lastBuildId') )
|
||||
@filter( (repo) -> repo.get('defaultBranch.lastBuild') )
|
||||
|
||||
sshKey: (->
|
||||
@store.find('ssh_key', @get('id'))
|
||||
|
@ -51,7 +39,7 @@ Repo = Model.extend
|
|||
builds: (->
|
||||
id = @get('id')
|
||||
builds = @store.filter('build', event_type: ['push', 'api'], repository_id: id, (b) ->
|
||||
b.get('repo.id') == id && (b.get('eventType') == 'push' || b.get('eventType') == 'api')
|
||||
b.get('repositoryId')+'' == id+'' && (b.get('eventType') == 'push' || b.get('eventType') == 'api')
|
||||
)
|
||||
|
||||
# TODO: move to controller
|
||||
|
@ -68,7 +56,7 @@ Repo = Model.extend
|
|||
pullRequests: (->
|
||||
id = @get('id')
|
||||
builds = @store.filter('build', event_type: 'pull_request', repository_id: id, (b) ->
|
||||
b.get('repo.id') == id && b.get('eventType') == 'pull_request'
|
||||
b.get('repositoryId')+'' == id+'' && b.get('eventType') == 'pull_request'
|
||||
)
|
||||
|
||||
# TODO: move to controller
|
||||
|
@ -85,7 +73,7 @@ Repo = Model.extend
|
|||
).property()
|
||||
|
||||
branches: (->
|
||||
builds = @store.find 'build', repository_id: @get('id'), branches: true
|
||||
builds = @store.query 'build', repository_id: @get('id'), branches: true
|
||||
|
||||
builds.then ->
|
||||
builds.set 'isLoaded', true
|
||||
|
@ -101,27 +89,13 @@ Repo = Model.extend
|
|||
(@get('slug') || '').split('/')[1]
|
||||
).property('slug')
|
||||
|
||||
lastBuildDuration: (->
|
||||
duration = @get('_lastBuildDuration')
|
||||
duration = durationFromHelper(@get('lastBuildStartedAt'), @get('lastBuildFinishedAt')) unless duration
|
||||
duration
|
||||
).property('_lastBuildDuration', 'lastBuildStartedAt', 'lastBuildFinishedAt')
|
||||
|
||||
sortOrderForLandingPage: (->
|
||||
state = @get('lastBuildState')
|
||||
state = @get('defaultBranch.lastBuild.state')
|
||||
if state != 'passed' && state != 'failed'
|
||||
0
|
||||
else
|
||||
parseInt(@get('lastBuildId'))
|
||||
).property('lastBuildId', 'lastBuildState')
|
||||
|
||||
sortOrder: (->
|
||||
# cuz sortAscending seems buggy when set to false
|
||||
if lastBuildFinishedAt = @get('lastBuildFinishedAt')
|
||||
- new Date(lastBuildFinishedAt).getTime()
|
||||
else
|
||||
- new Date('9999').getTime() - parseInt(@get('lastBuildId'))
|
||||
).property('lastBuildFinishedAt', 'lastBuildId')
|
||||
parseInt(@get('defaultBranch.lastBuild.id'))
|
||||
).property('defaultBranch.lastBuild.id', 'defaultBranch.lastBuild.state')
|
||||
|
||||
stats: (->
|
||||
if @get('slug')
|
||||
|
@ -132,43 +106,58 @@ Repo = Model.extend
|
|||
).property('slug')
|
||||
|
||||
updateTimes: ->
|
||||
@notifyPropertyChange 'lastBuildDuration'
|
||||
if lastBuild = @get('defaultBranch.lastBuild')
|
||||
lastBuild.updateTimes()
|
||||
|
||||
regenerateKey: (options) ->
|
||||
Ajax.ajax '/repos/' + @get('id') + '/key', 'post', options
|
||||
@get('ajax').ajax '/repos/' + @get('id') + '/key', 'post', options
|
||||
|
||||
fetchSettings: ->
|
||||
Ajax.ajax('/repos/' + @get('id') + '/settings', 'get', forceAuth: true).then (data) ->
|
||||
@get('ajax').ajax('/repos/' + @get('id') + '/settings', 'get', forceAuth: true).then (data) ->
|
||||
data['settings']
|
||||
|
||||
saveSettings: (settings) ->
|
||||
Ajax.ajax('/repos/' + @get('id') + '/settings', 'patch', data: { settings: settings })
|
||||
@get('ajax').ajax('/repos/' + @get('id') + '/settings', 'patch', data: { settings: settings })
|
||||
|
||||
Repo.reopenClass
|
||||
recent: ->
|
||||
@find()
|
||||
|
||||
accessibleBy: (store, login) ->
|
||||
repos = store.find('repo', { member: login, orderBy: 'name' })
|
||||
accessibleBy: (store, reposIds) ->
|
||||
# this fires only for authenticated users and with API v3 that means getting
|
||||
# only repos of currently logged in owner, but in the future it would be
|
||||
# nice to not use that as it may change in the future
|
||||
repos = store.filter('repo', (repo) ->
|
||||
reposIds.indexOf(parseInt(repo.get('id'))) != -1
|
||||
)
|
||||
|
||||
repos.then () ->
|
||||
repos.set('isLoaded', true)
|
||||
promise = new Ember.RSVP.Promise (resolve, reject) ->
|
||||
store.query('repo', { 'repository.active': 'true' }).then( ->
|
||||
resolve(repos)
|
||||
, ->
|
||||
reject()
|
||||
)
|
||||
|
||||
repos
|
||||
promise
|
||||
|
||||
search: (store, query) ->
|
||||
promise = store.find('repo', search: query, orderBy: 'name')
|
||||
search: (store, ajax, query) ->
|
||||
queryString = $.param(search: query, orderBy: 'name', limit: 5)
|
||||
promise = ajax.ajax("/repos?#{queryString}", 'get')
|
||||
result = Ember.ArrayProxy.create(content: [])
|
||||
|
||||
promise.then ->
|
||||
result.pushObjects(promise.get('content').toArray())
|
||||
promise.then (data, status, xhr) ->
|
||||
promises = data.repos.map (repoData) ->
|
||||
store.findRecord('repo', repoData.id).then (record) ->
|
||||
result.pushObject(record)
|
||||
result.set('isLoaded', true)
|
||||
record
|
||||
|
||||
Ember.RSVP.allSettled(promises).then ->
|
||||
result
|
||||
|
||||
withLastBuild: (store) ->
|
||||
repos = store.filter('repo', {}, (build) ->
|
||||
build.get('lastBuildId')
|
||||
build.get('defaultBranch.lastBuild')
|
||||
)
|
||||
|
||||
repos.then () ->
|
||||
|
@ -176,20 +165,24 @@ Repo.reopenClass
|
|||
|
||||
repos
|
||||
|
||||
bySlug: (store, slug) ->
|
||||
# first check if there is a repo with a given slug already ordered
|
||||
repos = store.all('repo').filterBy('slug', slug)
|
||||
if repos.get('length') > 0
|
||||
repos
|
||||
else
|
||||
store.find('repo', { slug: slug })
|
||||
|
||||
fetchBySlug: (store, slug) ->
|
||||
repos = @bySlug(store, slug)
|
||||
repos = store.peekAll('repo').filterBy('slug', slug)
|
||||
if repos.get('length') > 0
|
||||
repos.get('firstObject')
|
||||
else
|
||||
repos.then (repos) ->
|
||||
adapter = store.adapterFor('repo')
|
||||
modelClass = store.modelFor('repo')
|
||||
adapter.findRecord(store, modelClass, slug).then (payload) ->
|
||||
serializer = store.serializerFor('repo')
|
||||
modelClass = store.modelFor('repo')
|
||||
result = serializer.normalizeResponse(store, modelClass, payload, null, 'findRecord')
|
||||
|
||||
repo = store.push(data: result.data)
|
||||
for record in result.included
|
||||
r = store.push(data: record)
|
||||
|
||||
repo
|
||||
, ->
|
||||
error = new Error('repo not found')
|
||||
error.slug = slug
|
||||
Ember.get(repos, 'firstObject') || throw(error)
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
`import Ember from 'ember'`
|
||||
`import Model from 'travis/models/model'`
|
||||
`import Ajax from 'travis/utils/ajax'`
|
||||
`import config from 'travis/config/environment'`
|
||||
|
||||
User = Model.extend
|
||||
ajax: Ember.inject.service()
|
||||
|
||||
# TODO: this totally not should be needed here
|
||||
sessionStorage: Ember.inject.service()
|
||||
|
||||
name: DS.attr()
|
||||
email: DS.attr()
|
||||
login: DS.attr()
|
||||
|
@ -27,7 +31,7 @@ User = Model.extend
|
|||
).property()
|
||||
|
||||
_rawPermissions: (->
|
||||
Ajax.get('/users/permissions')
|
||||
@get('ajax').get('/users/permissions')
|
||||
).property()
|
||||
|
||||
permissions: (->
|
||||
|
@ -72,12 +76,12 @@ User = Model.extend
|
|||
|
||||
sync: ->
|
||||
self = this
|
||||
Ajax.post('/users/sync', {}, ->
|
||||
@get('ajax').post('/users/sync', {}, ->
|
||||
self.setWithSession('isSyncing', true)
|
||||
)
|
||||
|
||||
poll: ->
|
||||
Ajax.get '/users', (data) =>
|
||||
@get('ajax').get '/users', (data) =>
|
||||
if data.user.is_syncing
|
||||
self = this
|
||||
setTimeout ->
|
||||
|
@ -88,12 +92,12 @@ User = Model.extend
|
|||
@setWithSession('syncedAt', data.user.synced_at)
|
||||
Travis.trigger('user:synced', data.user)
|
||||
|
||||
@store.findQuery('account', {})
|
||||
@store.query('account', {})
|
||||
|
||||
setWithSession: (name, value) ->
|
||||
@set(name, value)
|
||||
user = JSON.parse(Travis.sessionStorage.getItem('travis.user'))
|
||||
user = JSON.parse(@get('sessionStorage').getItem('travis.user'))
|
||||
user[name.underscore()] = @get(name)
|
||||
Travis.sessionStorage.setItem('travis.user', JSON.stringify(user))
|
||||
@get('sessionStorage').setItem('travis.user', JSON.stringify(user))
|
||||
|
||||
`export default User`
|
||||
|
|
|
@ -13,7 +13,7 @@ Router = Ember.Router.extend
|
|||
#
|
||||
# we should probably think about a more general way to
|
||||
# do this, location should not know about auth status
|
||||
Location.create(auth: @container.lookup('auth:main'))
|
||||
Location.create(auth: @container.lookup('service:auth'))
|
||||
).property()
|
||||
|
||||
# TODO: this is needed, because in the original version
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
Route = TravisRoute.extend
|
||||
model: ->
|
||||
@store.find('account', { all: true })
|
||||
@store.query('account', { all: true })
|
||||
|
||||
setupController: (controller, model) ->
|
||||
user = model.filterBy('type', 'user')[0]
|
||||
|
|
|
@ -21,7 +21,7 @@ Route = TravisRoute.extend BuildFaviconMixin,
|
|||
@get('stylesheetsManager').disable('dashboard')
|
||||
|
||||
if !config.pro
|
||||
repos = @get('store').all('repo')
|
||||
repos = @get('store').peekAll('repo')
|
||||
repos.forEach (repo) =>
|
||||
@subscribeToRepo(repo)
|
||||
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
`import Ember from 'ember'`
|
||||
`import TravisRoute from 'travis/routes/basic'`
|
||||
`import Ajax from 'travis/utils/ajax'`
|
||||
|
||||
Route = TravisRoute.extend
|
||||
ajax: Ember.inject.service()
|
||||
|
||||
needsAuth: true
|
||||
setupController: (controller) ->
|
||||
@_super.apply this, arguments
|
||||
|
@ -10,7 +11,7 @@ Route = TravisRoute.extend
|
|||
|
||||
model: ->
|
||||
repo = @modelFor('repo')
|
||||
Ajax.get("/repos/#{repo.get('id')}/caches").then( (data) ->
|
||||
@get('ajax').get("/repos/#{repo.get('id')}/caches").then( (data) ->
|
||||
caches = {}
|
||||
|
||||
data["caches"].forEach (cacheData) ->
|
||||
|
|
|
@ -15,7 +15,7 @@ Route = SimpleLayoutRoute.extend
|
|||
if !controller.get('isSyncing')
|
||||
self = this
|
||||
Ember.run.later this, ->
|
||||
@store.find('repo', member: @get('controller.user.login')).then( (repos) ->
|
||||
@store.query('repo', member: @get('controller.user.login')).then( (repos) ->
|
||||
if repos.get('length')
|
||||
self.transitionTo('main')
|
||||
else
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
`import TravisRoute from 'travis/routes/basic'`
|
||||
|
||||
Route = TravisRoute.extend()
|
||||
Route = TravisRoute.extend
|
||||
setupController: (controller)->
|
||||
@container.lookup('controller:repos').activate('owned')
|
||||
|
||||
`export default Route`
|
||||
|
|
|
@ -21,10 +21,10 @@ Route = BasicRoute.extend
|
|||
@_super.apply this, arguments
|
||||
|
||||
loadMoreRepos: ->
|
||||
@store.find('build').then (builds) =>
|
||||
@store.findAll('build').then (builds) =>
|
||||
repoIds = builds.mapBy('data.repo').uniq()
|
||||
repos = @get('repos.repos')
|
||||
@store.find('repo', ids: repoIds).then (reposFromRequest) =>
|
||||
@store.query('repo', ids: repoIds).then (reposFromRequest) =>
|
||||
reposFromRequest.toArray().forEach (repo) ->
|
||||
repos.pushObject(repo) unless repos.contains(repo)
|
||||
|
||||
|
|
|
@ -18,17 +18,19 @@ Route = TravisRoute.extend
|
|||
@controllerFor('job').set('job', model)
|
||||
repo.activate('job')
|
||||
|
||||
if build = model.get('build')
|
||||
build = @store.recordForId('build', build.get('id'))
|
||||
buildController = @controllerFor('build')
|
||||
|
||||
model.get('repo')
|
||||
if buildPromise = model.get('build')
|
||||
buildPromise.then (build) =>
|
||||
build = @store.recordForId('build', build.get('id'))
|
||||
buildController.set('build', build)
|
||||
|
||||
# this is a hack to not set favicon changes from build
|
||||
# controller while we're viewing job, this should go away
|
||||
# after refactoring of controllers
|
||||
buildController.set('sendFaviconStateChanges', false)
|
||||
|
||||
buildController.set('build', build)
|
||||
|
||||
model: (params) ->
|
||||
@store.find('job', params.job_id)
|
||||
|
||||
|
|
|
@ -11,13 +11,11 @@ Route = TravisRoute.extend
|
|||
@controllerFor('repo').activate('index')
|
||||
@controllerFor('repos').activate(@get('reposTabName'))
|
||||
|
||||
@currentRepoDidChange()
|
||||
if repos = @controllerFor('repos').get('repos')
|
||||
repos.addObserver('firstObject', this, 'currentRepoDidChange')
|
||||
@setCurrentRepoObservers()
|
||||
|
||||
deactivate: ->
|
||||
if repos = @controllerFor('repos').get('repos')
|
||||
repos.removeObserver('firstObject', this, 'currentRepoDidChange')
|
||||
if repos = @controllerFor('repos')
|
||||
repos.removeObserver('repos.firstObject', this, 'currentRepoDidChange')
|
||||
|
||||
@_super.apply(this, arguments)
|
||||
|
||||
|
@ -25,6 +23,11 @@ Route = TravisRoute.extend
|
|||
if repo = @controllerFor('repos').get('repos.firstObject')
|
||||
@controllerFor('repo').set('repo', repo)
|
||||
|
||||
setCurrentRepoObservers: ->
|
||||
@currentRepoDidChange()
|
||||
if repos = @controllerFor('repos')
|
||||
repos.addObserver('repos.firstObject', this, 'currentRepoDidChange')
|
||||
|
||||
actions:
|
||||
redirectToGettingStarted: ->
|
||||
@transitionTo('getting_started')
|
||||
|
|
|
@ -14,6 +14,6 @@ Route = TravisRoute.extend
|
|||
|
||||
setupController: (controller)->
|
||||
# TODO: this is redundant with repositories and recent routes
|
||||
@container.lookup('controller:repos').activate('owned')
|
||||
#@container.lookup('controller:repos').activate('owned')
|
||||
|
||||
`export default Route`
|
||||
|
|
|
@ -10,8 +10,7 @@ Route = MainTabRoute.extend
|
|||
@controllerFor('repo').activate('index')
|
||||
@controllerFor('repos').activate('search', searchPhrase)
|
||||
|
||||
@currentRepoDidChange()
|
||||
@controllerFor('repos').addObserver('firstObject', this, 'currentRepoDidChange')
|
||||
@setCurrentRepoObservers()
|
||||
|
||||
model: (params) ->
|
||||
params.phrase.replace(/%2F/g, '/')
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
`import Ember from 'ember'`
|
||||
`import TravisRoute from 'travis/routes/basic'`
|
||||
`import Ajax from 'travis/utils/ajax'`
|
||||
`import config from 'travis/config/environment'`
|
||||
|
||||
Route = TravisRoute.extend
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
`import Ember from 'ember'`
|
||||
`import TravisRoute from 'travis/routes/basic'`
|
||||
`import Ajax from 'travis/utils/ajax'`
|
||||
`import config from 'travis/config/environment'`
|
||||
|
||||
Route = TravisRoute.extend
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
`import Ember from 'ember'`
|
||||
`import TravisRoute from 'travis/routes/basic'`
|
||||
`import Ajax from 'travis/utils/ajax'`
|
||||
`import config from 'travis/config/environment'`
|
||||
|
||||
Route = TravisRoute.extend
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
`import TravisRoute from 'travis/routes/basic'`
|
||||
`import Repo from 'travis/models/repo'`
|
||||
`import Ember from 'ember'`
|
||||
|
||||
Route = TravisRoute.extend
|
||||
store: Ember.inject.service()
|
||||
titleToken: (model) ->
|
||||
model.get('slug')
|
||||
|
||||
|
@ -9,9 +11,10 @@ Route = TravisRoute.extend
|
|||
@render 'repo', into: 'main'
|
||||
|
||||
setupController: (controller, model) ->
|
||||
@container.lookup('controller:repos').activate('owned')
|
||||
# TODO: if repo is just a data hash with id and slug load it
|
||||
# as incomplete record
|
||||
model = @store.find('repo', model.id) if model && !model.get
|
||||
model = @get('store').find('repo', model.id) if model && !model.get
|
||||
controller.set('repo', model)
|
||||
|
||||
serialize: (repo) ->
|
||||
|
@ -21,7 +24,7 @@ Route = TravisRoute.extend
|
|||
|
||||
model: (params) ->
|
||||
slug = "#{params.owner}/#{params.name}"
|
||||
Repo.fetchBySlug(@store, slug)
|
||||
Repo.fetchBySlug(@get('store'), slug)
|
||||
|
||||
resetController: ->
|
||||
@controllerFor('repo').deactivate()
|
||||
|
|
|
@ -6,7 +6,7 @@ Route = TravisRoute.extend
|
|||
@controllerFor('repo').activate('current')
|
||||
|
||||
renderTemplate: ->
|
||||
if @modelFor('repo').get('lastBuildId')
|
||||
if @modelFor('repo').get('defaultBranch.lastBuild')
|
||||
@render 'build'
|
||||
else
|
||||
@render 'builds/not_found'
|
||||
|
|
|
@ -7,6 +7,6 @@ Route = TravisRoute.extend
|
|||
@controllerFor('repo').activate('requests')
|
||||
|
||||
model: ->
|
||||
@store.find 'request', repository_id: @modelFor('repo').get('id')
|
||||
@store.query 'request', repository_id: @modelFor('repo').get('id')
|
||||
|
||||
`export default Route`
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
`import TravisRoute from 'travis/routes/basic'`
|
||||
`import Ajax from 'travis/utils/ajax'`
|
||||
`import config from 'travis/config/environment'`
|
||||
|
||||
Route = TravisRoute.extend
|
||||
ajax: Ember.inject.service()
|
||||
|
||||
needsAuth: true
|
||||
setupController: (controller, model) ->
|
||||
@_super.apply(this, arguments)
|
||||
|
@ -27,7 +28,7 @@ Route = TravisRoute.extend
|
|||
|
||||
fetchSshKey: () ->
|
||||
repo = @modelFor('repo')
|
||||
Ajax.get "/repos/#{repo.get('id')}/key", (data) =>
|
||||
@get('ajax').get "/repos/#{repo.get('id')}/key", (data) =>
|
||||
Ember.Object.create(fingerprint: data.fingerprint)
|
||||
|
||||
fetchRepositoryActiveFlag: ->
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
`import Ember from 'ember'`
|
||||
`import Ajax from 'travis/utils/ajax'`
|
||||
`import TravisRoute from 'travis/routes/basic'`
|
||||
|
||||
Route = TravisRoute.extend
|
||||
ajax: Ember.inject.service()
|
||||
|
||||
titleToken: 'Ssh Keys'
|
||||
|
||||
model: (params) ->
|
||||
|
@ -17,7 +18,7 @@ Route = TravisRoute.extend
|
|||
|
||||
afterModel: (model, transition) ->
|
||||
repo = @modelFor('repo')
|
||||
Ajax.get "/repos/#{repo.get('id')}/key", (data) =>
|
||||
@get('ajax').get "/repos/#{repo.get('id')}/key", (data) =>
|
||||
@defaultKey = Ember.Object.create(fingerprint: data.fingerprint)
|
||||
|
||||
setupController: (controller, model) ->
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
`import DS from 'ember-data'`
|
||||
`import V2FallbackSerializer from 'travis/serializers/v2_fallback'`
|
||||
|
||||
Serializer = DS.ActiveModelSerializer.extend
|
||||
defaultSerializer: 'application'
|
||||
serializer: 'application'
|
||||
Serializer = V2FallbackSerializer.extend
|
||||
isNewSerializerAPI: true
|
||||
|
||||
`export default Serializer`
|
||||
|
|
12
app/serializers/branch.js
Normal file
12
app/serializers/branch.js
Normal file
|
@ -0,0 +1,12 @@
|
|||
import Ember from 'ember';
|
||||
import V2FallbackSerializer from 'travis/serializers/v2_fallback';
|
||||
|
||||
export default V2FallbackSerializer.extend({
|
||||
extractAttributes(klass, payload) {
|
||||
payload.id = payload['@href'];
|
||||
return this._super(...arguments);
|
||||
},
|
||||
extractId(modelClass, resourceHash) {
|
||||
return resourceHash.id || resourceHash['@href'];
|
||||
}
|
||||
});
|
|
@ -1,19 +0,0 @@
|
|||
`import Ember from 'ember'`
|
||||
`import ApplicationSerializer from 'travis/serializers/application'`
|
||||
|
||||
Serializer = ApplicationSerializer.extend
|
||||
attrs: {
|
||||
repo: { key: 'repository_id' }
|
||||
_config: { key: 'config' }
|
||||
_finishedAt: { key: 'finished_at' }
|
||||
_startedAt: { key: 'started_at' }
|
||||
_duration: { key: 'duration' }
|
||||
}
|
||||
|
||||
extractSingle: (store, primaryType, rawPayload, recordId) ->
|
||||
if commit = rawPayload.commit
|
||||
rawPayload.commits = [commit]
|
||||
|
||||
@_super(store, primaryType, rawPayload, recordId)
|
||||
|
||||
`export default Serializer`
|
109
app/serializers/build.js
Normal file
109
app/serializers/build.js
Normal file
|
@ -0,0 +1,109 @@
|
|||
import Ember from 'ember';
|
||||
import V2FallbackSerializer from 'travis/serializers/v2_fallback';
|
||||
|
||||
var Serializer = V2FallbackSerializer.extend({
|
||||
isNewSerializerAPI: true,
|
||||
attrs: {
|
||||
_config: {
|
||||
key: 'config'
|
||||
},
|
||||
_finished_at: {
|
||||
key: 'finished_at'
|
||||
},
|
||||
_started_at: {
|
||||
key: 'started_at'
|
||||
},
|
||||
_duration: {
|
||||
key: 'duration'
|
||||
}
|
||||
},
|
||||
|
||||
extractRelationships: function(modelClass, resourceHash) {
|
||||
var result;
|
||||
result = this._super(modelClass, resourceHash);
|
||||
return result;
|
||||
},
|
||||
|
||||
normalizeArrayResponse: function(store, primaryModelClass, payload, id, requestType) {
|
||||
var result;
|
||||
if (payload.commits) {
|
||||
payload.builds.forEach(function(build) {
|
||||
var commit, commit_id;
|
||||
commit_id = build.commit_id;
|
||||
if (commit = payload.commits.findBy('id', commit_id)) {
|
||||
build.commit = commit;
|
||||
return delete build.commit_id;
|
||||
}
|
||||
});
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
|
||||
keyForV2Relationship: function(key, typeClass, method) {
|
||||
if(key === 'jobs') {
|
||||
return 'job_ids';
|
||||
} else if (key === 'repo') {
|
||||
return 'repository_id';
|
||||
} else if (key === 'commit') {
|
||||
return key;
|
||||
} else {
|
||||
return this._super.apply(this, arguments);
|
||||
}
|
||||
},
|
||||
|
||||
keyForRelationship(key, typeClass, method) {
|
||||
if (key === 'repo') {
|
||||
return 'repository';
|
||||
} else {
|
||||
return this._super.apply(this, arguments);
|
||||
}
|
||||
},
|
||||
|
||||
normalize: function(modelClass, resourceHash) {
|
||||
var data, href, id, repoId, result;
|
||||
|
||||
// TODO: remove this after switching to V3 entirely
|
||||
if(!resourceHash['@type'] && resourceHash.commit && resourceHash.commit.branch_is_default) {
|
||||
let build = resourceHash.build,
|
||||
commit = resourceHash.commit;
|
||||
let branch = {
|
||||
name: commit.branch,
|
||||
default_branch: commit.branch_is_default,
|
||||
"@href": `/repo/${build.repository_id}/branch/${commit.branch}`
|
||||
};
|
||||
resourceHash.build.branch = branch;
|
||||
}
|
||||
|
||||
// fix pusher payload, it doesn't include a branch record:
|
||||
if(!resourceHash['@type'] && resourceHash.build &&
|
||||
resourceHash.repository && resourceHash.repository.default_branch) {
|
||||
let branchName = resourceHash.build.branch,
|
||||
repository = resourceHash.repository,
|
||||
defaultBranchName = repository.default_branch.name;
|
||||
|
||||
resourceHash.build.branch = {
|
||||
name: branchName,
|
||||
default_branch: branchName === defaultBranchName,
|
||||
'@href': `/repo/${repository.id}/branch/${branchName}`
|
||||
};
|
||||
|
||||
repository.default_branch['@href'] = `/repo/${repository.id}/branch/${defaultBranchName}`;
|
||||
}
|
||||
|
||||
result = this._super(modelClass, resourceHash);
|
||||
|
||||
data = result.data;
|
||||
|
||||
if (repoId = resourceHash.repository_id) {
|
||||
data.attributes.repositoryId = repoId;
|
||||
} else if (resourceHash.repository) {
|
||||
if (href = resourceHash.repository['@href']) {
|
||||
id = href.match(/\d+/)[0];
|
||||
data.attributes.repositoryId = id;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
});
|
||||
|
||||
export default Serializer;
|
|
@ -6,4 +6,7 @@ Serializer = ApplicationSerializer.extend
|
|||
repo: { key: 'repository_id' }
|
||||
}
|
||||
|
||||
serialize: (snapshot, options) ->
|
||||
return { env_var: this._super(snapshot, options) }
|
||||
|
||||
`export default Serializer`
|
||||
|
|
7
app/serializers/hook.js
Normal file
7
app/serializers/hook.js
Normal file
|
@ -0,0 +1,7 @@
|
|||
import ApplicationSerializer from 'travis/serializers/application';
|
||||
|
||||
export default ApplicationSerializer.extend({
|
||||
serialize(snapshot, options) {
|
||||
return { hook: this._super(...arguments) };
|
||||
}
|
||||
});
|
|
@ -1,18 +1,30 @@
|
|||
`import Ember from 'ember'`
|
||||
`import ApplicationSerializer from 'travis/serializers/application'`
|
||||
`import V2FallbackSerializer from 'travis/serializers/v2_fallback'`
|
||||
|
||||
Serializer = ApplicationSerializer.extend
|
||||
Serializer = V2FallbackSerializer.extend
|
||||
isNewSerializerAPI: true
|
||||
attrs: {
|
||||
repo: { key: 'repository_id' }
|
||||
_config: { key: 'config' }
|
||||
_finishedAt: { key: 'finished_at' }
|
||||
_startedAt: { key: 'started_at' }
|
||||
_finished_at: { key: 'finished_at' }
|
||||
_started_at: { key: 'started_at' }
|
||||
}
|
||||
|
||||
extractSingle: (store, primaryType, rawPayload, recordId) ->
|
||||
if commit = rawPayload.commit
|
||||
rawPayload.commits = [commit]
|
||||
keyForV2Relationship: (key, typeClass, method) ->
|
||||
if key == 'repo'
|
||||
'repository'
|
||||
else
|
||||
@_super.apply(this, arguments)
|
||||
|
||||
@_super(store, primaryType, rawPayload, recordId)
|
||||
keyForV2Relationship: (key, typeClass, method) ->
|
||||
if key == 'repo'
|
||||
'repository_id'
|
||||
else
|
||||
@_super.apply(this, arguments)
|
||||
|
||||
normalize: (modelClass, resourceHash) ->
|
||||
if resourceHash.commit
|
||||
resourceHash.commit['type'] = 'commit'
|
||||
|
||||
@_super(modelClass, resourceHash)
|
||||
|
||||
`export default Serializer`
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
`import Ember from 'ember'`
|
||||
`import ApplicationSerializer from 'travis/serializers/application'`
|
||||
|
||||
Serializer = ApplicationSerializer.extend
|
||||
attrs: {
|
||||
_lastBuildDuration: { key: 'last_build_duration' }
|
||||
}
|
||||
|
||||
`export default Serializer`
|
16
app/serializers/repo.js
Normal file
16
app/serializers/repo.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
import Ember from 'ember';
|
||||
import V2FallbackSerializer from 'travis/serializers/v2_fallback';
|
||||
|
||||
var Serializer = V2FallbackSerializer.extend({
|
||||
isNewSerializerAPI: true,
|
||||
|
||||
normalizeResponse(store, primaryModelClass, payload, id, requestType) {
|
||||
if(!id && requestType === 'findRecord') {
|
||||
id = payload.id;
|
||||
}
|
||||
|
||||
return this._super(store, primaryModelClass, payload, id, requestType);
|
||||
}
|
||||
});
|
||||
|
||||
export default Serializer;
|
|
@ -1,11 +0,0 @@
|
|||
`import Ember from 'ember'`
|
||||
`import ApplicationSerializer from 'travis/serializers/application'`
|
||||
|
||||
Serializer = ApplicationSerializer.extend
|
||||
attrs: {
|
||||
branchName: { key: 'branch' }
|
||||
tagName: { key: 'tag' }
|
||||
repo: { key: 'repository_id' }
|
||||
}
|
||||
|
||||
`export default Serializer`
|
35
app/serializers/request.js
Normal file
35
app/serializers/request.js
Normal file
|
@ -0,0 +1,35 @@
|
|||
import Ember from 'ember';
|
||||
import V2FallbackSerializer from 'travis/serializers/v2_fallback';
|
||||
|
||||
var Serializer = V2FallbackSerializer.extend({
|
||||
isNewSerializerAPI: true,
|
||||
attrs: {
|
||||
branch_name: { key: 'branch' },
|
||||
tag_name: { key: 'tag' }
|
||||
},
|
||||
|
||||
keyForV2Relationship: function(key, typeClass, method) {
|
||||
if (key === 'repo') {
|
||||
return 'repository_id';
|
||||
} else {
|
||||
return this._super.apply(this, arguments);
|
||||
}
|
||||
},
|
||||
|
||||
normalizeArrayResponse: function(store, primaryModelClass, payload, id, requestType) {
|
||||
var result;
|
||||
if (payload.commits) {
|
||||
payload.requests.forEach(function(request) {
|
||||
var commit, commit_id;
|
||||
commit_id = request.commit_id;
|
||||
if (commit = payload.commits.findBy('id', commit_id)) {
|
||||
request.commit = commit;
|
||||
return delete request.commit_id;
|
||||
}
|
||||
});
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
}
|
||||
});
|
||||
|
||||
export default Serializer;
|
7
app/serializers/ssh_key.js
Normal file
7
app/serializers/ssh_key.js
Normal file
|
@ -0,0 +1,7 @@
|
|||
import ApplicationSerializer from 'travis/serializers/application';
|
||||
|
||||
export default ApplicationSerializer.extend({
|
||||
serialize(snapshot, options) {
|
||||
return { ssh_key: this._super(...arguments) };
|
||||
}
|
||||
});
|
94
app/serializers/v2_fallback.js
Normal file
94
app/serializers/v2_fallback.js
Normal file
|
@ -0,0 +1,94 @@
|
|||
import Ember from 'ember';
|
||||
import V3Serializer from 'travis/serializers/v3';
|
||||
|
||||
export default V3Serializer.extend({
|
||||
isNewSerializerAPI: true,
|
||||
|
||||
extractRelationships(modelClass, resourceHash) {
|
||||
if(resourceHash['@type']) {
|
||||
return this._super(...arguments);
|
||||
} else {
|
||||
let relationships = {};
|
||||
|
||||
modelClass.eachRelationship((key, relationshipMeta) => {
|
||||
// V2 API payload
|
||||
let relationship = null;
|
||||
let relationshipKey = this.keyForV2Relationship(key, relationshipMeta.kind, 'deserialize');
|
||||
let alternativeRelationshipKey = key.underscore();
|
||||
|
||||
if (resourceHash.hasOwnProperty(alternativeRelationshipKey) || resourceHash.hasOwnProperty(relationshipKey)) {
|
||||
let data = null;
|
||||
let relationshipHash = resourceHash[alternativeRelationshipKey] || resourceHash[relationshipKey];
|
||||
if (relationshipMeta.kind === 'belongsTo') {
|
||||
data = this.extractRelationship(relationshipMeta.type, relationshipHash);
|
||||
} else if (relationshipMeta.kind === 'hasMany') {
|
||||
data = relationshipHash.map((item) => this.extractRelationship(relationshipMeta.type, item));
|
||||
}
|
||||
relationship = { data };
|
||||
}
|
||||
|
||||
if (relationship) {
|
||||
relationships[key] = relationship;
|
||||
}
|
||||
});
|
||||
|
||||
return relationships;
|
||||
}
|
||||
},
|
||||
|
||||
normalize(modelClass, resourceHash) {
|
||||
if(resourceHash['@type']) {
|
||||
return this._super(...arguments);
|
||||
} else {
|
||||
var modelKey = modelClass.modelName;
|
||||
var attributes = resourceHash[modelKey];
|
||||
if(attributes) {
|
||||
for(var key in attributes) {
|
||||
resourceHash[key] = attributes[key];
|
||||
}
|
||||
|
||||
resourceHash['type'] = modelKey;
|
||||
delete resourceHash[modelKey];
|
||||
}
|
||||
|
||||
let { data, included } = this._super(...arguments);
|
||||
if(!included) {
|
||||
included = [];
|
||||
}
|
||||
let store = this.store;
|
||||
|
||||
if(data.relationships) {
|
||||
Object.keys(data.relationships).forEach(function (key) {
|
||||
let relationship = data.relationships[key];
|
||||
let process = function(data) {
|
||||
if(Object.keys(data).sort()+'' !== 'id,type' || (data['@href'] && data.type === 'branch')) {
|
||||
// no need to add records if they have only id and type
|
||||
let type = key === 'defaultBranch' ? 'branch' : key.singularize();
|
||||
let serializer = store.serializerFor(type);
|
||||
let modelClass = store.modelFor(type);
|
||||
let normalized = serializer.normalize(modelClass, data);
|
||||
included.push(normalized.data);
|
||||
if(normalized.included) {
|
||||
normalized.included.forEach(function(item) {
|
||||
included.push(item);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if(Array.isArray(relationship.data)) {
|
||||
relationship.data.forEach(process);
|
||||
} else if(relationship && relationship.data) {
|
||||
process(relationship.data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return { data, included };
|
||||
}
|
||||
},
|
||||
|
||||
keyForV2Relationship(key, typeClass, method) {
|
||||
return key.underscore() + '_id';
|
||||
}
|
||||
});
|
186
app/serializers/v3.js
Normal file
186
app/serializers/v3.js
Normal file
|
@ -0,0 +1,186 @@
|
|||
import Ember from 'ember';
|
||||
import DS from 'ember-data';
|
||||
|
||||
var traverse = function(object, callback) {
|
||||
if(!object) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(typeof(object) === 'object' && !Ember.isArray(object)) {
|
||||
callback(object);
|
||||
}
|
||||
|
||||
if(Ember.isArray(object)) {
|
||||
for(let item of object) {
|
||||
traverse(item, callback);
|
||||
}
|
||||
} else if(typeof object === 'object') {
|
||||
for(let key in object) {
|
||||
if(object.hasOwnProperty(key)) {
|
||||
let item = object[key];
|
||||
traverse(item, callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default DS.JSONSerializer.extend({
|
||||
isNewSerializerAPI: true,
|
||||
|
||||
extractRelationship(type, hash) {
|
||||
if(hash && !hash.id && hash['@href']) {
|
||||
hash.id = hash['@href'];
|
||||
}
|
||||
|
||||
let relationshipHash = this._super(...arguments);
|
||||
if(relationshipHash && relationshipHash['@type']) {
|
||||
relationshipHash.type = relationshipHash['@type'];
|
||||
} else if(relationshipHash && !relationshipHash.type) {
|
||||
relationshipHash.type = type;
|
||||
}
|
||||
return relationshipHash;
|
||||
},
|
||||
|
||||
extractRelationships() {
|
||||
let relationships = this._super(...arguments);
|
||||
return relationships;
|
||||
},
|
||||
|
||||
keyForRelationship(key, typeClass, method) {
|
||||
if(key && key.underscore) {
|
||||
return key.underscore();
|
||||
} else {
|
||||
return key;
|
||||
}
|
||||
},
|
||||
|
||||
extractAttributes(modelClass, resourceHash) {
|
||||
let attributes = this._super(...arguments);
|
||||
for(let key in attributes) {
|
||||
if(key.startsWith('@')) {
|
||||
delete attributes.key;
|
||||
}
|
||||
}
|
||||
|
||||
return attributes;
|
||||
},
|
||||
|
||||
normalizeResponse(store, primaryModelClass, payload, id, requestType) {
|
||||
this._fixReferences(payload);
|
||||
return this._super(...arguments);
|
||||
},
|
||||
|
||||
normalizeArrayResponse(store, primaryModelClass, payload, id, requestType) {
|
||||
let documentHash = {
|
||||
data: null,
|
||||
included: []
|
||||
};
|
||||
|
||||
let meta = this.extractMeta(store, primaryModelClass, payload);
|
||||
if (meta) {
|
||||
Ember.assert('The `meta` returned from `extractMeta` has to be an object, not "' + Ember.typeOf(meta) + '".', Ember.typeOf(meta) === 'object');
|
||||
documentHash.meta = meta;
|
||||
}
|
||||
|
||||
let items, type;
|
||||
if(type = payload['@type']) {
|
||||
items = payload[type];
|
||||
} else {
|
||||
items = payload[primaryModelClass.modelName.underscore() + 's'];
|
||||
}
|
||||
|
||||
documentHash.data = items.map((item) => {
|
||||
let { data, included } = this.normalize(primaryModelClass, item);
|
||||
if (included) {
|
||||
documentHash.included.push(...included);
|
||||
}
|
||||
return data;
|
||||
});
|
||||
|
||||
return documentHash;
|
||||
},
|
||||
|
||||
normalize(modelClass, resourceHash) {
|
||||
let { data, included } = this._super(...arguments);
|
||||
if(!included) {
|
||||
included = [];
|
||||
}
|
||||
let store = this.store;
|
||||
|
||||
if(data.relationships) {
|
||||
Object.keys(data.relationships).forEach(function (key) {
|
||||
let relationship = data.relationships[key];
|
||||
let process = function(data) {
|
||||
if(data['@representation'] !== 'standard') {
|
||||
return;
|
||||
}
|
||||
let type = data['@type'];
|
||||
let serializer = store.serializerFor(type);
|
||||
let modelClass = store.modelFor(type);
|
||||
let normalized = serializer.normalize(modelClass, data);
|
||||
included.push(normalized.data);
|
||||
if(normalized.included) {
|
||||
normalized.included.forEach(function(item) {
|
||||
included.push(item);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
if(Array.isArray(relationship.data)) {
|
||||
relationship.data.forEach(process);
|
||||
} else if(relationship && relationship.data) {
|
||||
process(relationship.data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return { data, included };
|
||||
},
|
||||
|
||||
keyForAttribute(key, method) {
|
||||
if(method === 'deserialize') {
|
||||
return Ember.String.underscore(key);
|
||||
} else {
|
||||
return Ember.String.camelize(key);
|
||||
}
|
||||
},
|
||||
|
||||
_fixReferences(payload) {
|
||||
let byHref = {}, href, records;
|
||||
if(payload['@type']) {
|
||||
// API V3 doesn't return all of the objects in a full representation
|
||||
// If an object is present in one place in the response, all of the
|
||||
// other occurences will be just references of a kind - they will just
|
||||
// include @href property.
|
||||
//
|
||||
// I don't want to identify records by href in ember-data, so here I'll
|
||||
// set an id and a @type field on all of the references.
|
||||
//
|
||||
// First we need to group all of the items in the response by href:
|
||||
traverse(payload, (item) => {
|
||||
if(href = item['@href']) {
|
||||
if(records = byHref[href]) {
|
||||
records.push(item);
|
||||
} else {
|
||||
byHref[href] = [item];
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Then we can choose a record with an id for each href and put the id
|
||||
// in all of the other occurences.
|
||||
for(let href in byHref) {
|
||||
records = byHref[href];
|
||||
let recordWithAnId = records.find( (record) => record.id );
|
||||
if(recordWithAnId) {
|
||||
for(let record of records) {
|
||||
record.id = recordWithAnId.id;
|
||||
//record['@type'] = recordWithAnId['@type'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return payload;
|
||||
}
|
||||
});
|
|
@ -7,7 +7,9 @@ default_options =
|
|||
accepts:
|
||||
json: 'application/json; version=2'
|
||||
|
||||
ajax = Em.Object.create
|
||||
Ajax = Ember.Service.extend
|
||||
auth: Ember.inject.service()
|
||||
|
||||
publicEndpoints: [/\/repos\/?.*/, /\/builds\/?.*/, /\/jobs\/?.*/]
|
||||
privateEndpoints: [/\/repos\/\d+\/caches/]
|
||||
|
||||
|
@ -42,8 +44,8 @@ ajax = Em.Object.create
|
|||
endpoint = config.apiEndpoint || ''
|
||||
options = options || {}
|
||||
|
||||
token = Travis.sessionStorage.getItem('travis.token')
|
||||
if token && (ajax.needsAuth(method, url) || options.forceAuth)
|
||||
token = Ember.get(this, 'auth').token()
|
||||
if token && (@needsAuth(method, url) || options.forceAuth)
|
||||
options.headers ||= {}
|
||||
options.headers['Authorization'] ||= "token #{token}"
|
||||
|
||||
|
@ -66,9 +68,9 @@ ajax = Em.Object.create
|
|||
|
||||
error = options.error || (->)
|
||||
options.error = (data, status, xhr) =>
|
||||
console.log "[ERROR] API responded with an error (#{status}): #{JSON.stringify(data)}"
|
||||
Travis.lookup('controller:flash').pushObject(data.flash) if data?.flash
|
||||
delete data.flash if data?
|
||||
console.log "[ERROR] API responded with an error (#{status}): #{JSON.stringify(data)}"
|
||||
error.apply(this, arguments)
|
||||
|
||||
options = $.extend(options, default_options)
|
||||
|
@ -153,4 +155,4 @@ ajax = Em.Object.create
|
|||
|
||||
return promise
|
||||
|
||||
`export default ajax`
|
||||
`export default Ajax`
|
|
@ -1,7 +1,11 @@
|
|||
`import config from 'travis/config/environment'`
|
||||
`import Ajax from 'travis/utils/ajax'`
|
||||
|
||||
Auth = Ember.Object.extend
|
||||
Auth = Ember.Service.extend
|
||||
store: Ember.inject.service(),
|
||||
storage: Ember.inject.service(),
|
||||
sessionStorage: Ember.inject.service(),
|
||||
ajax: Ember.inject.service()
|
||||
|
||||
state: "signed-out"
|
||||
receivingEnd: "#{location.protocol}//#{location.host}"
|
||||
|
||||
|
@ -9,20 +13,20 @@ Auth = Ember.Object.extend
|
|||
window.addEventListener('message', (e) => @receiveMessage(e))
|
||||
|
||||
token: ->
|
||||
Travis.sessionStorage.getItem('travis.token')
|
||||
@get('sessionStorage').getItem('travis.token')
|
||||
|
||||
endpoint: (->
|
||||
config.apiEndpoint
|
||||
).property(),
|
||||
|
||||
signOut: ->
|
||||
@storage.removeItem('travis.user')
|
||||
@storage.removeItem('travis.token')
|
||||
@sessionStorage.clear()
|
||||
@get('storage').removeItem('travis.user')
|
||||
@get('storage').removeItem('travis.token')
|
||||
@get('sessionStorage').clear()
|
||||
@set('state', 'signed-out')
|
||||
@set('user', undefined)
|
||||
if user = @get('currentUser')
|
||||
@store.unloadAll('user')
|
||||
@get('store').unloadAll('user')
|
||||
@set('currentUser', null)
|
||||
@sendToApp('afterSignOut')
|
||||
Travis.trigger('user:signed_out')
|
||||
|
@ -36,7 +40,7 @@ Auth = Ember.Object.extend
|
|||
$('<iframe id="auth-frame" />').hide().appendTo('body').attr('src', url)
|
||||
|
||||
autoSignIn: (data) ->
|
||||
data ||= @userDataFrom(@sessionStorage) || @userDataFrom(@storage)
|
||||
data ||= @userDataFrom(@get('sessionStorage')) || @userDataFrom(@get('storage'))
|
||||
@setData(data) if data
|
||||
|
||||
userDataFrom: (storage) ->
|
||||
|
@ -54,7 +58,7 @@ Auth = Ember.Object.extend
|
|||
|
||||
validateUser: (user) ->
|
||||
fieldsToValidate = ['id', 'login', 'token']
|
||||
isTravisBecome = sessionStorage.getItem('travis.become')
|
||||
isTravisBecome = @get('sessionStorage').getItem('travis.become')
|
||||
|
||||
unless isTravisBecome
|
||||
fieldsToValidate.push 'correct_scopes'
|
||||
|
@ -72,8 +76,8 @@ Auth = Ember.Object.extend
|
|||
false
|
||||
|
||||
setData: (data) ->
|
||||
@storeData(data, @sessionStorage)
|
||||
@storeData(data, @storage) unless @userDataFrom(@storage)
|
||||
@storeData(data, @get('sessionStorage'))
|
||||
@storeData(data, @get('storage')) unless @userDataFrom(@get('storage'))
|
||||
user = @loadUser(data.user)
|
||||
@set('currentUser', user)
|
||||
|
||||
|
@ -83,19 +87,19 @@ Auth = Ember.Object.extend
|
|||
|
||||
refreshUserData: (user) ->
|
||||
unless user
|
||||
if data = @userDataFrom(@sessionStorage) || @userDataFrom(@storage)
|
||||
if data = @userDataFrom(@get('sessionStorage')) || @userDataFrom(@get('storage'))
|
||||
user = data.user
|
||||
|
||||
if user
|
||||
Ajax.get("/users/#{user.id}").then (data) =>
|
||||
@get('ajax').get("/users/#{user.id}").then (data) =>
|
||||
if data.user.correct_scopes
|
||||
userRecord = @loadUser(data.user)
|
||||
userRecord.get('permissions')
|
||||
# if user is still signed in, update saved data
|
||||
if @get('signedIn')
|
||||
data.user.token = user.token
|
||||
@storeData(data, @sessionStorage)
|
||||
@storeData(data, @storage)
|
||||
@storeData(data, @get('sessionStorage'))
|
||||
@storeData(data, @get('storage'))
|
||||
Travis.trigger('user:refreshed', data.user)
|
||||
else
|
||||
return Ember.RSVP.Promise.reject()
|
||||
|
@ -119,8 +123,13 @@ Auth = Ember.Object.extend
|
|||
storage.setItem('travis.user', JSON.stringify(data.user))
|
||||
|
||||
loadUser: (user) ->
|
||||
@store.pushPayload(users: [user])
|
||||
@store.recordForId('user', user.id)
|
||||
@get('store').push(
|
||||
data:
|
||||
type: 'user',
|
||||
id: user.id
|
||||
attributes: user
|
||||
)
|
||||
@get('store').recordForId('user', user.id)
|
||||
|
||||
receiveMessage: (event) ->
|
||||
if event.origin == @expectedOrigin()
|
18
app/services/session-storage.coffee
Normal file
18
app/services/session-storage.coffee
Normal file
|
@ -0,0 +1,18 @@
|
|||
`import Ember from 'ember'`
|
||||
`import StorageService from 'travis/services/storage'`
|
||||
`import Storage from 'travis/utils/hash-storage'`
|
||||
|
||||
SessionStorageService = StorageService.extend
|
||||
init: ->
|
||||
storage = null
|
||||
try
|
||||
# firefox will not throw error on access for sessionStorage var,
|
||||
# you need to actually get something from session
|
||||
window.sessionStorage.getItem('foo')
|
||||
storage = window.sessionStorage
|
||||
catch err
|
||||
storage = Storage.create()
|
||||
|
||||
@set('storage', storage)
|
||||
|
||||
`export default SessionStorageService`
|
22
app/services/storage.coffee
Normal file
22
app/services/storage.coffee
Normal file
|
@ -0,0 +1,22 @@
|
|||
`import Ember from 'ember'`
|
||||
`import Storage from 'travis/utils/hash-storage'`
|
||||
|
||||
StorageService = Ember.Service.extend
|
||||
init: ->
|
||||
storage = null
|
||||
try
|
||||
storage = window.localStorage || throw('no storage')
|
||||
catch err
|
||||
storage = Storage.create()
|
||||
|
||||
@set('storage', storage)
|
||||
getItem: (key) ->
|
||||
return @get("storage").getItem(key)
|
||||
setItem: (key, value) ->
|
||||
return @get("storage").setItem(key, value)
|
||||
removeItem: (key) ->
|
||||
return @get("storage").removeItem(key)
|
||||
clear: ->
|
||||
return @get("storage").clear()
|
||||
|
||||
`export default StorageService`
|
|
@ -2,6 +2,8 @@
|
|||
`import config from 'travis/config/environment'`
|
||||
|
||||
Store = DS.Store.extend
|
||||
auth: Ember.inject.service()
|
||||
|
||||
defaultAdapter: 'application'
|
||||
adapter: 'application'
|
||||
|
||||
|
@ -17,21 +19,6 @@ Store = DS.Store.extend
|
|||
|
||||
canHandleEvent: (event, data) ->
|
||||
[name, type] = event.split(':')
|
||||
auth = @container.lookup('auth:main')
|
||||
if event != 'job:log' && auth.get('signedIn') &&
|
||||
!config.pro && !config.enterprise
|
||||
# if recent repos hasn't been opened yet, we can safely
|
||||
# drop any events that doesn't belong to repos owned by
|
||||
# the logged in user and that aren't related to any
|
||||
# repositories that are already opened
|
||||
|
||||
permissions = auth.get('permissions')
|
||||
if name == 'job'
|
||||
id = data.job.repository_id
|
||||
else if name == 'build'
|
||||
id = data.repository.id
|
||||
|
||||
return @hasRecordForId('repo', id) || permissions.contains(id)
|
||||
|
||||
for name, callback of @get('pusherEventHandlerGuards')
|
||||
unless callback(event, data)
|
||||
|
@ -45,7 +32,7 @@ Store = DS.Store.extend
|
|||
return unless @canHandleEvent(event, data)
|
||||
|
||||
if name == 'job' && data.job?.commit
|
||||
@pushPayload(commits: [data.job.commit])
|
||||
@push(this.normalize('commit', data.job.commit))
|
||||
|
||||
if name == 'build' && data.build?.commit
|
||||
# TODO: commit should be a sideload record on build, not mixed with it
|
||||
|
@ -64,27 +51,41 @@ Store = DS.Store.extend
|
|||
}
|
||||
delete(data.build.commit)
|
||||
|
||||
@pushPayload(commits: [commit])
|
||||
@push(this.normalize('commit', commit))
|
||||
|
||||
if event == 'job:log'
|
||||
data = data.job
|
||||
job = @recordForId('job', data.id)
|
||||
job.appendLog(number: parseInt(data.number), content: data._log, final: data.final)
|
||||
else if data[name]
|
||||
@_loadOne(name, data)
|
||||
@loadOne(name, data)
|
||||
else
|
||||
throw "can't load data for #{name}" unless type
|
||||
|
||||
_loadOne: (type, json) ->
|
||||
payload = {}
|
||||
payload[type.pluralize()] = [json[type]]
|
||||
@pushPayload(payload)
|
||||
loadOne: (type, json) ->
|
||||
record = @push(this.normalize(type, json))
|
||||
|
||||
# we get other types of records only in a few situations and
|
||||
# it's not always needed to update data, so I'm specyfing which
|
||||
# things I want to update here:
|
||||
if type == 'build' && (json.repository || json.repo)
|
||||
data = json.repository || json.repo
|
||||
@pushPayload(repos: [data])
|
||||
|
||||
default_branch = data.default_branch
|
||||
if default_branch
|
||||
default_branch.default_branch = true
|
||||
|
||||
last_build_id = default_branch.last_build_id
|
||||
# a build is a synchronous relationship on a branch model, so we need to
|
||||
# have a build record present when we put default_branch from a repository
|
||||
# model into the store. We don't send last_build's payload in pusher, so
|
||||
# we need to get it here, if it's not already in the store. In the future
|
||||
# we may decide to make this relationship async, but I don't want to
|
||||
# change the code at the moment
|
||||
if build = @peekRecord('build', last_build_id)
|
||||
@push(this.normalize('repo', data))
|
||||
else
|
||||
@findRecord('build', last_build_id).then =>
|
||||
@push(this.normalize('repo', data))
|
||||
|
||||
`export default Store`
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<small class="commit-branch" title={{item.pullRequestTitle}}>Pull Request #{{item.pullRequestNumber}}</small>
|
||||
{{item.pullRequestTitle}}
|
||||
{{else}}
|
||||
<small class="commit-branch" title={{item.commit.branch}}>{{item.commit.branch}}</small>
|
||||
<small class="commit-branch" title={{item.branch.name}}>{{item.branch.name}}</small>
|
||||
{{format-message item.commit.subject repo=item.repo}}
|
||||
{{/if}}
|
||||
</h2>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<div id="code-climate" class="popup">
|
||||
<img src="/images/icons/code-climate-logo.svg" id="code-climate-logo"/>
|
||||
<img src="/images/ui/code-climate-logo.svg" id="code-climate-logo"/>
|
||||
<a href="#" class="close" {{action "close"}}></a>
|
||||
<p>
|
||||
<b>Want test coverage for your tests?</b>
|
||||
|
|
|
@ -1,38 +1,37 @@
|
|||
<div class="tile {{repo.lastBuildState}}">
|
||||
<h2 class="tile-title {{repo.lastBuildState}}">
|
||||
<div class="tile {{repo.defaultBranch.lastBuild.state}}">
|
||||
<h2 class="tile-title {{repo.defaultBranch.lastBuild.state}}">
|
||||
{{#if repo.slug}}
|
||||
{{#link-to "repo" repo}}
|
||||
{{status-icon status=repo.lastBuildState}}
|
||||
{{status-icon status=repo.defaultBranch.lastBuild.state}}
|
||||
<span class="label-align">{{repo.slug}}</span>
|
||||
{{/link-to}}
|
||||
{{/if}}
|
||||
</h2>
|
||||
{{#with repo.lastBuildHash as lastBuild}}
|
||||
|
||||
{{#if repo.slug}}
|
||||
{{#if lastBuild.id}}
|
||||
<p class="tile-title float-right {{repo.lastBuildState}}">
|
||||
{{#link-to "build" repo lastBuild.id}}
|
||||
{{#if repo.defaultBranch.lastBuild.id}}
|
||||
<p class="tile-title float-right {{repo.defaultBranch.lastBuild.state}}">
|
||||
{{#link-to "build" repo repo.defaultBranch.lastBuild.id}}
|
||||
<span class="icon-hash"></span>
|
||||
<span class="label-align">{{lastBuild.number}}</span>
|
||||
<span class="label-align">{{repo.defaultBranch.lastBuild.number}}</span>
|
||||
{{/link-to}}
|
||||
</p>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{/with}}
|
||||
|
||||
<p>
|
||||
<span class="icon-clock"></span>
|
||||
<span class="label-align">Duration:
|
||||
<abbr class="duration" title={{lastBuildStartedAt}}>
|
||||
{{format-duration repo.lastBuildDuration}}
|
||||
<abbr class="duration" title={{repo.defaultBranch.lastBuild.startedAt}}>
|
||||
{{format-duration repo.defaultBranch.lastBuild.duration}}
|
||||
</abbr></span>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<span class="icon-calendar"></span>
|
||||
<span class="label-align">Finished:
|
||||
<abbr class="finished_at timeago" title={{lastBuildFinishedAt}}>
|
||||
{{format-time repo.lastBuildFinishedAt}}
|
||||
<abbr class="finished_at timeago" title={{repo.defaultBranch.lastBuild.finishedAt}}>
|
||||
{{format-time repo.defaultBranch.lastBuild.finishedAt}}
|
||||
</abbr></span>
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
@ -3,5 +3,3 @@
|
|||
{{else}}
|
||||
<p class="empty">{{noReposMessage}}</p>
|
||||
{{/each}}
|
||||
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
{{#if repo.active}}
|
||||
{{outlet}}
|
||||
{{else}}
|
||||
{{#if repo.lastBuildId}}
|
||||
{{#if repo.defaultBranch.lastBuild.id}}
|
||||
{{outlet}}
|
||||
{{else}}
|
||||
{{not-active user=currentUser repo=repo}}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user