Merge branch 'master' into mm-code-climate-window

Conflicts:
	assets/scripts/app/templates/repos/show/tools.hbs
	assets/scripts/app/views/repo/show.coffee
This commit is contained in:
Mathias Meyer 2013-09-10 14:32:20 +02:00
commit 8d3fa21665
52 changed files with 365 additions and 445 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 351 B

BIN
assets/images/icons/off.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
assets/images/icons/repeat.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 960 B

View File

@ -57,8 +57,6 @@ require 'controllers/job'
require 'controllers/profile'
require 'controllers/repos'
require 'controllers/repo'
#require 'controllers/running_jobs'
#require 'controllers/sidebar'
require 'controllers/stats'
require 'controllers/current_user'
require 'controllers/account_index'

View File

@ -3,6 +3,8 @@ Travis.BuildController = Ember.Controller.extend
repoBinding: 'controllers.repo.repo'
commitBinding: 'build.commit'
lineNumberBinding: 'controllers.repo.lineNumber'
currentUserBinding: 'controllers.repo.currentUser'
tabBinding: 'controllers.repo.tab'
currentItemBinding: 'build'

View File

@ -1,8 +1,17 @@
delegate = (name, options) ->
options ||= options
->
target = @get(options.to)
target[name].apply(target, arguments)
Travis.CurrentUserController = Em.ObjectController.extend
sync: ->
@get('content').sync()
syncingDidChange: (->
if (user = @get('content')) && user.get('isSyncing') && !user.get('syncedAt')
@container.lookup('router:main').send('renderFirstSync')
Ember.run.scheduleOnce 'routerTransitions', this, ->
@container.lookup('router:main').send('renderFirstSync')
).observes('isSyncing', 'content')
updateLocale: delegate('updateLocale', to: 'content')

View File

@ -5,6 +5,8 @@ Travis.JobController = Em.Controller.extend
repoBinding: 'controllers.repo.repo'
commitBinding: 'job.commit'
lineNumberBinding: 'controllers.repo.lineNumber'
currentUserBinding: 'controllers.repo.currentUser'
tabBinding: 'controllers.repo.tab'
currentItemBinding: 'job'

View File

@ -35,7 +35,8 @@ Travis.ProfileController = Travis.Controller.extend
@reloadHooks()
reloadHooks: ->
@set('allHooks', Travis.Hook.find(all: true, owner_name: @get('params.login') || @get('user.login')))
# TODO: figure out why user is not available sometimes
@set('allHooks', Travis.Hook.find(all: true, owner_name: @get('params.login') || @get('user.login') || Travis.lookup('controller:currentUser').get('login')))
hooks: (->
@get('allHooks').filter (hook) -> hook.get('admin')

View File

@ -1,103 +0,0 @@
Travis.RunningJobsController = Em.ArrayProxy.extend
Group: Em.Object.extend
slug: (-> @get('jobs.firstObject.repoSlug') ).property('jobs.firstObject.repoSlug')
init: ->
@_super.apply this, arguments
@set 'jobs', []
@set 'sortedJobs', Em.ArrayProxy.extend(Em.SortableMixin,
sortProperties: ['number']
).create(content: @get('jobs'))
willDestroy: ->
@get('sortedJobs').destroy()
add: (job) ->
@get('jobs').pushObject(job) unless @get('jobs').contains job
@attach()
remove: (job) ->
@get('jobs').removeObject(job)
@clean()
attach: ->
@get('parent').addGroup(this)
clean: ->
@get('parent').removeGroup(this) if @get('isEmpty')
isEmpty: (->
@get('jobs.length') == 0
).property('jobs.length')
groups: []
sortedGroups: (->
Em.ArrayProxy.extend(Em.SortableMixin,
sortProperties: ['slug']
).create(content: @get('groups'))
).property()
groupsBySlug: {}
init: ->
@_super.apply this, arguments
jobs = Travis.Job.running()
@set 'content', jobs
@addedJobs jobs
contentArrayWillChange: (array, index, removedCount, addedCount) ->
@_super.apply this, arguments
if removedCount
@removedJobs array.slice(index, index + removedCount)
contentArrayDidChange: (array, index, removedCount, addedCount) ->
@_super.apply this, arguments
if addedCount
@addedJobs array.slice(index, index + addedCount)
addedJobs: (jobs) ->
self = this
jobs.forEach (job) ->
self.waitForSlug(job, 'addJob')
removedJobs: (jobs) ->
self = this
jobs.forEach (job) ->
self.waitForSlug(job, 'removeJob')
addJob: (job) ->
slug = job.get('repoSlug')
group = @groupForSlug(slug)
group.add(job)
removeJob: (job) ->
slug = job.get('repoSlug')
group = @groupForSlug(slug)
group.remove(job)
waitForSlug: (job, callbackName) ->
callback = @[callbackName]
self = this
if job.get('repoSlug')?
callback.call self, job
else
observer = ->
if job.get('repoSlug')?
callback.call self, job
job.removeObserver 'repoSlug', observer
job.addObserver 'repoSlug', observer
groupForSlug: (slug) ->
@groupsBySlug[slug] ||= @Group.create(slug: slug, parent: this)
addGroup: (group) ->
@get('groups').pushObject group unless @get('groups').contains group
removeGroup: (group) ->
@get('groups').removeObject group
delete @groupsBySlug[group.get('slug')]
group.destroy()

View File

@ -1,41 +0,0 @@
Travis.reopen
SidebarController: Em.ArrayController.extend
needs: ['runningJobs']
jobsBinding: 'controllers.runningJobs'
init: ->
@_super.apply this, arguments
QueuesController: Em.ArrayController.extend
init: ->
@_super.apply this, arguments
queues = for queue in Travis.QUEUES
Travis.LimitedArray.create
content: Travis.Job.queued(queue.name), limit: 20
id: "queue_#{queue.name}"
name: queue.display
@set 'content', queues
showAll: (queue) ->
queue.showAll()
WorkersController: Em.ArrayController.extend
init: ->
@_super.apply this, arguments
@set 'content', Travis.Worker.find()
groups: (->
if content = @get 'arrangedContent'
groups = {}
for worker in content.toArray()
host = worker.get('host')
unless groups[host]
groups[host] = Em.ArrayProxy.extend(Em.SortableMixin,
content: [],
sortProperties: ['nameForSort']
).create()
groups[host].pushObject(worker)
$.values(groups)
).property('length')

View File

@ -28,8 +28,8 @@ Ember.registerBoundHelper 'formatSha', (sha, options) ->
Ember.registerBoundHelper 'pathFrom', (url, options) ->
safe Travis.Helpers.pathFrom(url)
Ember.registerBoundHelper 'formatMessage', (message, options) ->
safe Travis.Helpers.formatMessage(message, options)
Ember.Handlebars.helper 'formatMessage', (message, options) ->
safe Travis.Helpers.formatMessage(message, options.hash)
Ember.registerBoundHelper 'formatConfig', (config, options) ->
safe Travis.Helpers.formatConfig(config)

View File

@ -37,7 +37,10 @@ require 'config/emoij'
formatMessage: (message, options) ->
message = message || ''
message = message.split(/\n/)[0] if options.short
@_emojize(@_escape(message)).replace /\n/g, '<br/>'
message = @_emojize(@_escape(message))
if !!options.repo
message = @githubify(message, options.repo.get('owner'), options.repo.get('name'))
message.replace /\n/g, '<br/>'
pathFrom: (url) ->
(url || '').split('/').pop()
@ -66,6 +69,26 @@ require 'config/emoij'
result.push seconds + ' sec' if seconds > 0
if result.length > 0 then result.join(' ') else '-'
githubify: (text, owner, repo) ->
self = this
text = text.replace @_githubReferenceRegexp, (reference, matchedOwner, matchedRepo, matchedNumber) ->
self._githubReferenceLink(reference, { owner: owner, repo: repo }, { owner: matchedOwner, repo: matchedRepo, number: matchedNumber } )
text = text.replace @_githubUserRegexp, (reference, username) ->
self._githubUserLink(reference, username)
text
_githubReferenceLink: (reference, current, matched) ->
owner = matched.owner || current.owner
repo = matched.repo || current.repo
"<a href=\"http://github.com/#{owner}/#{repo}/issues/#{matched.number}\">#{reference}</a>"
_githubReferenceRegexp: new RegExp("([\\w-]+)?\\/?([\\w-]+)?(?:#|gh-)(\\d+)", 'g')
_githubUserRegexp: new RegExp("@([\\w-]+)", 'g')
_githubUserLink: (reference, username) ->
"<a href=\"http://github.com/#{username}\">#{reference}</a>"
_normalizeDateString: (string) ->
if window.JHW
string = string.replace('T', ' ').replace(/-/g, '/')

View File

@ -25,7 +25,7 @@ require 'travis/model'
).property('_config')
isPullRequest: (->
@get('eventType') == 'pull_request'
@get('eventType') == 'pull_request' || @get('pullRequest')
).property('eventType')
isMatrix: (->

View File

@ -10,6 +10,5 @@ require 'travis/model'
authorEmail: Ember.attr('string')
committerName: Ember.attr('string')
committerEmail: Ember.attr('string')
pullRequestNumber: Ember.attr('number')
build: Ember.belongsTo('Travis.Build')

View File

@ -103,25 +103,32 @@ require 'travis/model'
).property('state')
@Travis.Job.reopenClass
queued: (queue) ->
@find()
Ember.FilteredRecordArray.create(
queued: ->
filtered = Ember.FilteredRecordArray.create(
modelClass: Travis.Job
filterFunction: (job) ->
queued = ['created', 'queued'].indexOf(job.get('state')) != -1
# TODO: why queue is sometimes just common instead of build.common?
queued && (!queue || job.get('queue') == "builds.#{queue}" || job.get('queue') == queue)
['created', 'queued'].indexOf(job.get('state')) != -1
filterProperties: ['state', 'queue']
)
@fetch().then (array) ->
filtered.updateFilter()
filtered.set('isLoaded', true)
filtered
running: ->
@find(state: 'started')
Ember.FilteredRecordArray.create(
filtered = Ember.FilteredRecordArray.create(
modelClass: Travis.Job
filterFunction: (job) ->
job.get('state') == 'started'
filterProperties: ['state']
)
@fetch(state: 'started').then (array) ->
filtered.updateFilter()
filtered.set('isLoaded', true)
filtered

View File

@ -46,7 +46,7 @@ Ember.Route.reopen
Travis.auth.set('afterSignInTransition', null)
transition.retry()
else
@transitionTo('index.current') if @constructor == Travis.AuthRoute
@transitionTo('index.current') if @constructor == Travis.AuthRoute || @constructor.superclass == Travis.AuthRoute
afterSignOut: ->
@transitionTo('index.current')
@ -248,6 +248,7 @@ Travis.JobRoute = Ember.Route.extend
model.removeObserver('build', buildObserver)
model.addObserver('build', this, buildObserver)
buildObserver.apply(this)
model: (params) ->
Travis.Job.find(params.job_id)
@ -306,7 +307,6 @@ Travis.IndexRoute = Ember.Route.extend
$('body').attr('id', 'home')
@render 'repos', outlet: 'left'
@render 'sidebar', outlet: 'right'
@render 'top', outlet: 'top'
@render 'flash', outlet: 'flash'

View File

@ -32,7 +32,7 @@
{{/if}}
</td>
<td class="message">
{{{formatMessage commit.message short="true"}}}
{{{formatMessage commit.message short="true" repoBinding=build.repo}}}
</td>
<td class="commit">
<a {{bindAttr href="view.urlGithubCommit"}}>

View File

@ -44,8 +44,9 @@
</div>
{{/with}}
<dt>{{t builds.message}}</dt>
<dd class="message">{{formatMessage build.commit.message}}</dd>
<dd class="message">{{formatMessage build.commit.message repoBinding=build.repo}}</dd>
{{#unless isMatrix}}
<dt>{{t builds.config}}</dt>

View File

@ -1,7 +0,0 @@
<ul class="groups">
{{#each group in view.groups}}
{{view view.GroupView groupBinding="group"}}
{{else}}
{{t no_job}}
{{/each}}
</ul>

View File

@ -1,15 +0,0 @@
<a {{action "toggle" target="view"}}>
<span class="slug">{{slug}}</span> ({{jobs.length}})
</a>
<ul class="jobs">
{{#each job in sortedJobs}}
<li class="job">
{{#if job.repo.slug}}
{{#linkTo "job" job.repo job}}
#{{job.number}}
{{/linkTo}}
{{/if}}
</li>
{{/each}}
</ul>

View File

@ -43,7 +43,7 @@
</div>
{{/with}}
<dt>{{t jobs.message}}</dt>
<dd class="message">{{formatMessage job.commit.message}}</dd>
<dd class="message">{{formatMessage job.commit.message repoBinding=job.repo}}</dd>
<dt>{{t jobs.config}}</dt>
<dd class="config">{{formatConfig job.config}}</dd>
</dl>

View File

@ -7,12 +7,13 @@
<div id="repo-header">
<h3>{{#linkTo "repo" this}}{{slug}}{{/linkTo}}</h3>
<div class="github-icon"><a {{bindAttr href="controller.urlGithub"}}><img src="/images/icons/github.png" width="21" height="21"/></a></div>
{{view Travis.RepoShowToolsView}}
</div>
<p class="description">{{description}}</p>
{{view Travis.RepoShowTabsView}}
{{view Travis.RepoShowToolsView}}
{{view Travis.RepoActionsView}}
{{/with}}
<div class="tab">

View File

@ -0,0 +1,52 @@
<div id="actions">
<ul>
{{#if view.displayCodeClimate}}
<li>
<a href="#" name="code-climate"
{{action "codeClimatePopup" target="view"}}
{{bindAttr class=":open-popup"}}>
Test Coverage
</a>
</li>
{{/if}}
{{#if view.displayStatusImages}}
<li id="status-image-popup">
<a href="#" name="status-images" class="open-popup" {{action "statusImages" target="view"}} style="margin-top: 0px;">
<img {{bindAttr src="view.statusImageUrl"}} title="Build Status Images"/>
</a>
</li>
{{/if}}
{{#if view.displayCancelBuild}}
<li class="icon">
<a href="#" {{action "cancelBuild" target="view"}}
{{bindAttr class="view.canCancelBuild::disabled"}}><img class="icon" src="/images/icons/off.png" width="20" title="Cancel Build"></a>
</li>
{{/if}}
{{#if view.displayCancelJob}}
<li class="icon">
<a href="#" {{action "cancelJob" target="view"}}
{{bindAttr class="view.canCancelJob::disabled"}}><img class="icon" width="20" src="/images/icons/off.png" title="Cancel Job"/></a>
</li>
{{/if}}
{{#if view.displayRequeueBuild}}
<li class="icon">
<a href="#" {{action "requeueBuild" target="view"}}
{{bindAttr class="view.canRequeueBuild::disabled"}}><img class="icon" src="/images/icons/repeat.png" width="20"
title="Restart Build"></a>
</li>
{{/if}}
{{#if view.displayRequeueJob}}
<li class="icon">
<a href="#" {{action "requeueJob" target="view"}}
{{bindAttr class="view.canRequeueJob::disabled"}}><img src="/images/icons/repeat.png" width="20" title="Restart Job"></a>
</li>
{{/if}}
{{!TODO: for some reason showDownloadLog, which just delegates to jobIdForLog
does not refresh 'if' properly, need further investigation}}
{{#if view.jobIdForLog}}
<li class="icon">
<a class="download-log" {{bindAttr href="view.plainTextLogUrl"}}><img class="icon" src="/images/icons/align-justify.png" width="20" title="Download Log"/></a>
</li>
{{/if}}
</ul>
</div>

View File

@ -1,34 +1,8 @@
<div id="tools">
<a href="#" {{action "menu" target="view"}}></a>
<a href="#" {{action "menu" target="view"}} class="menu-popup-button"></a>
<ul class="menu">
<li>
<a href="#" name="status-images" class="open-popup" {{action "statusImages" target="view"}}>Status Images</a>
</li>
{{#if view.displayCancelBuild}}
<li>
<a href="#" {{action "cancelBuild" target="view"}}
{{bindAttr class="view.canCancelBuild::disabled"}}>Cancel Build</a>
</li>
{{/if}}
{{#if view.displayCancelJob}}
<li>
<a href="#" {{action "cancelJob" target="view"}}
{{bindAttr class="view.canCancelJob::disabled"}}>Cancel Job</a>
</li>
{{/if}}
{{#if view.displayRequeueBuild}}
<li>
<a href="#" {{action "requeueBuild" target="view"}}
{{bindAttr class="view.canRequeueBuild::disabled"}}>Restart Build</a>
</li>
{{/if}}
{{#if view.displayRequeueJob}}
<li>
<a href="#" {{action "requeueJob" target="view"}}
{{bindAttr class="view.canRequeueJob::disabled"}}> Restart Job </a>
</li>
{{/if}}
{{#if view.displayRegenerateKey}}
{{#if view.displayRegenerateKey}}
<li>
<a href="#" name="regenerate-key"
{{action "regenerateKeyPopup" target="view"}}
@ -37,23 +11,6 @@
</a>
</li>
{{/if}}
{{!TODO: for some reason showDownloadLog, which just delegates to jobIdForLog
does not refresh 'if' properly, need further investigation}}
{{#if view.jobIdForLog}}
<li>
<a class="download-log" {{bindAttr href="view.plainTextLogUrl"}}>Download log</a>
</li>
{{/if}}
{{#if view.displayCodeClimate}}
<li>
<a href="#" name="code-climate"
{{action "codeClimatePopup" target="view"}}
{{bindAttr class=":open-popup"}}>
Code Climate
</a>
</li>
{{/if}}
</ul>
</div>
@ -67,7 +24,7 @@
</p>
<p>
<a class="sync_now button" {{action "regenerateKey" target="view"}}>Yes! Do it!</a>
<a class="sync_now button" {{action "regenerateKey" target="view"}}>Yes, do it!</a>
<span class="or">or</span>
<a href="#" class="cancel" {{action "popupClose" target="view"}}>Cancel</a>
</p>

View File

@ -54,7 +54,6 @@ require 'views/job'
require 'views/log'
require 'views/repo'
require 'views/profile'
require 'views/sidebar'
require 'views/stats'
require 'views/signin'
require 'views/top'

View File

@ -41,8 +41,8 @@ Travis.reopen
).property('repo.slug', 'commit.sha')
urlGithubPullRequest: (->
Travis.Urls.githubPullRequest(@get('repo.slug'), @get('commit.pullRequestNumber'))
).property('repo.slug', 'commit.pullRequestNumber')
Travis.Urls.githubPullRequest(@get('repo.slug'), @get('build.pullRequestNumber'))
).property('repo.slug', 'build.pullRequestNumber')
BuildView: Travis.View.extend
templateName: 'builds/show'

View File

@ -15,15 +15,18 @@ Travis.reopen
# in repos/show.hbs is empty when view is rerendered without routing
# taking place. Try to render the default outlet in such case
# TODO: look into fixing it in more general way
pane = Ember.get('_outlets.pane')
if @get('controller.repo.isLoaded') && @state == 'inDOM' &&
@get('controller.repo.lastBuild') &&
@get('controller.tab') == 'current' && (!pane || pane.state == 'destroyed')
view = @get('controller.container').lookup('view:build')
view.set('controller', @get('controller.container').lookup('controller:build'))
Ember.run.next =>
@set('_outlets', {}) if !@get('_outlets') && !@isDestroyed
@connectOutlet('pane', view) unless @isDestroyed
Ember.run.schedule('afterRender', this, ->
pane = Ember.get('_outlets.pane')
console.log('tab', @get('controller.tab'))
if @get('controller.repo.isLoaded') && @state == 'inDOM' &&
@get('controller.repo.lastBuild') &&
@get('controller.tab') == 'current' && (!pane || pane.state == 'destroyed')
view = @get('controller.container').lookup('view:build')
view.set('controller', @get('controller.container').lookup('controller:build'))
Ember.run.next =>
@set('_outlets', {}) if !@get('_outlets') && !@isDestroyed
@connectOutlet('pane', view) unless @isDestroyed
)
).observes('controller.repo.isLoaded')
ReposEmptyView: Travis.View.extend
@ -85,13 +88,56 @@ Travis.reopen
$('#tools .menu').toggleClass('display')
event.stopPropagation()
regenerateKeyPopup: ->
if @get('canRegenerateKey')
@set('active', true)
@closeMenu()
@popup(event)
event.stopPropagation()
regenerateKey: ->
@popupCloseAll()
(@get('repo.content') || @get('repo')).regenerateKey
success: =>
@popup('regeneration-success')
error: ->
Travis.lookup('controller:flash').loadFlashes([{ error: 'Travis encountered an error while trying to regenerate the key, please try again.'}])
displayRegenerateKey: true
canRegenerateKey: (->
@get('displayRegenerateKey') && @get('hasPermission')
).property('hasPermission')
hasPermission: (->
if permissions = @get('currentUser.permissions')
permissions.contains parseInt(@get('repo.id'))
).property('currentUser.permissions.length', 'repo.id')
RepoActionsView: Travis.View.extend
templateName: 'repos/show/actions'
repoBinding: 'controller.repo'
buildBinding: 'controller.build'
jobBinding: 'controller.job'
tabBinding: 'controller.tab'
slugBinding: 'controller.repo.slug'
currentUserBinding: 'controller.currentUser'
statusImageUrl: (->
Travis.Urls.statusImage(@get('slug'))
).property('slug')
displayStatusImages: (->
@get('hasPermission')
).property('hasPermission')
requeue: ->
@closeMenu()
@get('build').requeue()
cancelBuild: ->
if @get('canCancelBuild')
@closeMenu()
Travis.flash(notice: 'Build cancelation has been scheduled.')
@get('build').cancel().then ->
Travis.flash(success: 'Build has been successfuly canceled.')
@ -105,7 +151,6 @@ Travis.reopen
cancelJob: ->
if @get('canCancelJob')
@closeMenu()
Travis.flash(notice: 'Job cancelation has been scheduled.')
@get('job').cancel().then ->
Travis.flash(success: 'Job has been successfuly canceled.')
@ -117,48 +162,10 @@ Travis.reopen
else
Travis.flash(error: 'An error occured when canceling the job')
statusImages: ->
@set('active', true)
@closeMenu()
@popupCloseAll()
view = Travis.StatusImagesView.create(toolsView: this)
# TODO: create a general mechanism for managing current popup
# and move all popups to use it
Travis.View.currentPopupView = view
view.appendTo($('body'))
event.stopPropagation()
regenerateKeyPopup: ->
if @get('canRegenerateKey')
@set('active', true)
@closeMenu()
@popup(event)
event.stopPropagation()
codeClimatePopup: ->
@set('active', true)
@closeMenu()
@popup(event)
event.stopPropagation()
requeueBuild: ->
if @get('canRequeueBuild')
@closeMenu()
@get('build').requeue()
requeueJob: ->
if @get('canRequeueJob')
@closeMenu()
@get('job').requeue()
regenerateKey: ->
@popupCloseAll()
(@get('repo.content') || @get('repo')).regenerateKey
success: =>
@popup('regeneration-success')
error: ->
Travis.lookup('controller:flash').loadFlashes([{ error: 'Travis encountered an error while trying to regenerate the key, please try again.'}])
hasPermission: (->
if permissions = @get('currentUser.permissions')
permissions.contains parseInt(@get('repo.id'))
).property('currentUser.permissions.length', 'repo.id')
displayRequeueBuild: (->
@get('isBuildTab') && @get('build.isFinished')
@ -206,26 +213,30 @@ Travis.reopen
@get('isJobTab') && @get('job.canCancel')
).property('isJobTab', 'job.canCancel')
displayRegenerateKey: true
canRegenerateKey: (->
@get('displayRegenerateKey') && @get('hasPermission')
).property('hasPermission')
isJobTab: (->
@get('tab') == 'job'
).property('tab')
).property('tab', 'repo.id')
isBuildTab: (->
['current', 'build'].indexOf(@get('tab')) > -1
).property('tab')
hasPermission: (->
if permissions = @get('currentUser.permissions')
permissions.contains parseInt(@get('repo.id'))
).property('currentUser.permissions.length', 'repo.id')
displayCodeClimate: (->
Travis.config.code_climate == "true" and @get('repo.githubLanguage') == 'Ruby'
).property('repo.githubLanguage')
requeueBuild: ->
if @get('canRequeueBuild')
@get('build').requeue()
requeueJob: ->
if @get('canRequeueJob')
@get('job').requeue()
statusImages: ->
@popupCloseAll()
view = Travis.StatusImagesView.create(toolsView: this)
Travis.View.currentPopupView = view
view.appendTo($('body'))
event.stopPropagation()

View File

@ -1,87 +0,0 @@
@Travis.reopen
SidebarView: Travis.View.extend
templateName: 'layouts/sidebar'
didInsertElement: ->
@_super.apply this, arguments
#@activate('jobs')
activate: (name) ->
console.log
return if @get('activeTab') == name
@set('activeTab', name)
@connectOutlet 'pane', Travis.SidebarView["#{name.capitalize()}View"].create(controller: @get('controller'))
classQueues: (->
'active' if @get('activeTab') == 'queues'
).property('activeTab')
classWorkers: (->
'active' if @get('activeTab') == 'workers'
).property('activeTab')
classJobs: (->
'active' if @get('activeTab') == 'jobs'
).property('activeTab')
QueuesView: Em.View.extend
templateName: 'queues/list'
init: ->
@_super.apply this, arguments
@set 'controller', @get('controller').container.lookup('controller:queues')
WorkersView: Travis.View.extend
toggleWorkers: ->
handle = $(event.target).toggleClass('open')
if handle.hasClass('open')
$('#workers li').addClass('open')
else
$('#workers li').removeClass('open')
WorkersListView: Travis.View.extend
toggle: ->
this.$().find('> li').toggleClass('open')
WorkersItemView: Travis.View.extend
classNameBindings: ['worker.state']
display: (->
name = (@get('worker.name') || '').replace('travis-', '')
state = @get('worker.state')
if state == 'working'
"<span class='name'>#{name}: #{@get('worker.repoSlug')}</span> ##{@get('worker.jobNumber')}".htmlSafe()
else
"#{name}: #{state}"
).property('worker.state')
QueueItemView: Travis.View.extend
tagName: 'li'
Travis.SidebarView.reopenClass
WorkersView: Em.View.extend
templateName: 'workers/list'
init: ->
@_super.apply this, arguments
@set 'controller', @get('controller').container.lookup('controller:workers')
JobsView: Em.View.extend
templateName: 'jobs/running'
elementId: 'running-jobs'
init: ->
@_super.apply this, arguments
@set 'controller', @get('controller').container.lookup('controller:runningJobs')
groupsBinding: 'controller.sortedGroups'
jobsBinding: 'controller'
GroupView: Em.View.extend
templateName: 'jobs/running/group'
tagName: 'li'
contextBinding: 'group'
expanded: false
classNameBindings: ['expanded']
classNames: ['group']
toggle: ->
@toggleProperty('expanded')

View File

@ -12,7 +12,7 @@ Travis.ExpandableRecordArray = Ember.RecordArray.extend
array.removeObserver 'isLoaded', observer
array.forEach (record) ->
self.pushObject record
self.pushObject(record) unless self.contains(record)
self.set 'isLoading', false
self.set 'isLoaded', true
@ -30,7 +30,8 @@ Travis.ExpandableRecordArray = Ember.RecordArray.extend
addedObjects = array.slice index, index + addedCount
for object in addedObjects
if @get('filterWith').call this, object
@pushObject object
@pushObject(object) unless @contains(object)
pushObject: (record) ->
@get('content').pushObject(record)
if content = @get('content')
content.pushObject(record) unless content.contains(record)

View File

@ -172,12 +172,23 @@ Array.prototype.diff = (a) ->
delete this.recordCache[key]
loadRecordForReference: (reference) ->
record = this.create({ _reference: reference })
this.recordCache = {} unless this.recordCache
this.sideloadedData = {} unless this.sideloadedData
this.recordCache[reference.id] = record
record = @create({ _reference: reference })
@recordCache = {} unless @recordCache
@sideloadedData = {} unless @sideloadedData
@recordCache[reference.id] = record
reference.record = record
record.load(reference.id, this.sideloadedData[reference.id])
record.load(reference.id, @sideloadedData[reference.id])
# TODO: find a nicer way to not add record to record arrays twice
if !this._findAllRecordArray || !this._findAllRecordArray.contains(record)
this.addToRecordArrays(record)
if @currentRecordsToAdd
@currentRecordsToAdd.pushObject(record) unless @currentRecordsToAdd.contains(record)
else
@currentRecordsToAdd = [record]
Ember.run.scheduleOnce('data', this, @_batchAddToRecordArrays);
_batchAddToRecordArrays: ->
for record in @currentRecordsToAdd
if !@_findAllRecordArray || !@_findAllRecordArray.contains(record)
@addToRecordArrays(record)
@currentRecordsToAdd = null

View File

@ -50,6 +50,9 @@ test "an event with a build adds a build to a builds list", ->
message: 'commit message 3'
commit: '1234567'
state: 'failed'
pull_request: false
pull_request_number: null
pull_request_title: null
Em.run ->
Travis.receive 'build:started', payload

View File

@ -0,0 +1,54 @@
module "Travis.Helpers.githubify"
test 'replaces #Num with github issues link', ->
message = 'Solved #11hey'
result = Travis.Helpers.githubify(message, 'travis-ci', 'travis-web')
expected = 'Solved <a href="http://github.com/travis-ci/travis-web/issues/11">#11</a>hey'
equal(result, expected, "#num should be converted to a link")
test 'replaces User#Num with github issues link to forked repo', ->
message = 'Solved test#11hey'
result = Travis.Helpers.githubify(message, 'travis-ci', 'travis-web')
expected = 'Solved <a href="http://github.com/test/travis-web/issues/11">test#11</a>hey'
equal(result, expected, "user#num should be converted to a link")
test 'replaces User/Project#Num with github issues link to another repo', ->
message = 'Solved test_1-a2/test-a_11#11hey'
result = Travis.Helpers.githubify(message, 'travis-ci', 'travis-web')
expected = 'Solved <a href="http://github.com/test_1-a2/test-a_11/issues/11">test_1-a2/test-a_11#11</a>hey'
equal(result, expected, "owner/repo#num should be converted to a link")
test 'replaces gh-Num with github issues link', ->
message = 'Solved gh-22hey'
result = Travis.Helpers.githubify(message, 'travis-ci', 'travis-web')
expected = 'Solved <a href="http://github.com/travis-ci/travis-web/issues/22">gh-22</a>hey'
equal(result, expected, "gh-Num should be converted to a link")
test 'replaces multiple references with github issues links', ->
message = 'Try #1 and test#2 and test/testing#3'
result = Travis.Helpers.githubify(message, 'travis-ci', 'travis-web')
expected = 'Try <a href="http://github.com/travis-ci/travis-web/issues/1">#1</a> and '
expected += '<a href="http://github.com/test/travis-web/issues/2">test#2</a> and '
expected += '<a href="http://github.com/test/testing/issues/3">test/testing#3</a>'
equal(result, expected, "references should be converted to links")
test 'replaces multiple references with github issues links', ->
message = 'Try #1 and test#2 and test/testing#3'
result = Travis.Helpers.githubify(message, 'travis-ci', 'travis-web')
expected = 'Try <a href="http://github.com/travis-ci/travis-web/issues/1">#1</a> and '
expected += '<a href="http://github.com/test/travis-web/issues/2">test#2</a> and '
expected += '<a href="http://github.com/test/testing/issues/3">test/testing#3</a>'
equal(result, expected, "references should be converted to links")
test 'replaces @user with github user link', ->
message = 'It is for you @tender_love1'
result = Travis.Helpers.githubify(message, 'travis-ci', 'travis-web')
expected = 'It is for you <a href="http://github.com/tender_love1">@tender_love1</a>'
equal(result, expected, "@user should be converted to a link")

View File

@ -64,6 +64,8 @@ window.Travis = TravisApplication.create(
LOG_TRANSITIONS: true
)
Travis.deferReadiness()
$.extend Travis,
run: ->
Travis.advanceReadiness() # bc, remove once merged to master

View File

@ -186,6 +186,8 @@ Ember.FilteredRecordArray = Ember.RecordArray.extend({
get(this, 'modelClass').forEachCachedRecord(function(record) {
if (self.filterFunction(record)) {
results.push(record);
} else {
results.removeObject(record);
}
});
this.set('content', Ember.A(results));
@ -193,8 +195,12 @@ Ember.FilteredRecordArray = Ember.RecordArray.extend({
updateFilterForRecord: function(record) {
var results = get(this, 'content');
if (this.filterFunction(record) && !results.contains(record)) {
results.pushObject(record);
if (this.filterFunction(record)) {
if(!results.contains(record)) {
results.pushObject(record);
}
} else {
results.removeObject(record);
}
},
@ -432,6 +438,10 @@ Ember.Model = Ember.Object.extend(Ember.Evented, {
init: function() {
this._createReference();
this._super();
this.one('didLoad', function() {
this.constructor.addToRecordArrays(this);
});
},
_createReference: function() {

File diff suppressed because one or more lines are too long

View File

@ -55,7 +55,7 @@ html, body
-moz-box-flex: 4
-webkit-box-flex: 4
position: relative
min-width: 630px
min-width: 760px
padding: 20px 40px 80px 30px
#right

View File

@ -4,13 +4,16 @@
position: relative
float: right
top: 2px
& > a
width: 200px
& > a.menu-popup-button
display: block
width: 39px
height: 21px
margin-top: -27px
background: inline-image('ui/tools-button.png') no-repeat
cursor: pointer
float: right
.menu
display: none
@ -32,3 +35,55 @@
&.disabled
cursor: default
color: $color-link-disabled
#actions
float: right
text-align: right
li#status-image-popup
opacity: 0.5
&:hover
opacity: 1.0
li.icon
a
-webkit-border-radius: .5em
-moz-border-radius: .5em
border-radius: .5em
-webkit-box-shadow: 0 1px 2px rgba(0,0,0,0.2)
-moz-box-shadow: 0 1px 2px rgba(0,0,0,0.2)
box-shadow: 0 1px 2px rgba(0,0,0,0.2)
display: inline-block
width: 22px
height: 20px
position: relative
top: -2px
cursor: pointer
color: #fef4e9
border: solid 1px #afafaf
background: #eee
background: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#eee))
background: -moz-linear-gradient(top, #fff, #eee)
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#faa51a', endColorstr='#f47a20')
text-align: center
margin-left: 5px
img
width: 15px
height: 15px
margin-top: 3px
margin-left: 0px
&:hover
opacity: 1.0
&.disabled
opacity: 0.6
display: none
visibility: hidden
ul
margin-top: -27px
li
display: inline

View File

@ -4,6 +4,7 @@
#right
width: 0
padding: 0
flex: 0
*:not(#slider):not(.icon):not(.ember-view)
display: none

View File

@ -41,22 +41,3 @@
#right .show-more-jobs
text-decoration: underline
cursor: pointer
#running-jobs
.jobs
display: none
margin: 5px 0 5px
.job
list-style-type: disc
list-style-position: inside
.expanded .jobs
display: block
.slug
max-width: 150px
overflow: hidden
white-space: nowrap
text-overflow: ellipsis
display: inline-block
display: -moz-inline-stack
.group a
cursor: pointer

View File

@ -118,7 +118,7 @@ de:
locale: Sprache
message:
config: Wie du eigene Build-Optionen konfigurieren kannst
your_repos: Lege die Schalter unten um, um den Travis Dienst-Hook für deine Projekte zu aktivieren, dann pushe zu GitHub.<br />\n Um gegen mehrere Rubine zu testen, sehe
your_repos: Lege die Schalter unten um, um den Travis Dienst-Hook für deine Projekte zu aktivieren, dann pushe zu GitHub.
messages:
notice: Bitte lese dir unser <a href=\\"http://about.travis-ci.org/docs/user/getting-started/\\">Getting Started-Handbuch</a> durch, um loszulegen.\\n <small>Es dauert nur ein paar Minuten.</small>
token:

View File

@ -118,7 +118,7 @@ en:
locale: locale
message:
config: how to configure custom build options
your_repos: ! " Flick the switches below to turn on the Travis service hook for your projects, then push to GitHub.<br />"
your_repos: ! " Flick the switches below to turn on the Travis service hook for your projects, then push to GitHub."
messages:
notice: ! "To get started, please read our <a href=\"http://about.travis-ci.org/docs/user/getting-started/\">Getting Started guide</a>.\n <small>It will only take a couple of minutes.</small>"
token: Token

View File

@ -118,7 +118,7 @@ es:
locale:
message:
config: como configurar tus propias opciones para el Build
your_repos: ! " Activa los interruptores para inicial el Travis service hook para tus proyectos, y haz un Push en GitHub.<br />\n Para probar varias versiones de ruby, mira"
your_repos: ! " Activa los interruptores para inicial el Travis service hook para tus proyectos, y haz un Push en GitHub."
messages:
notice: ! "Para comenzar, por favor lee nuestra <a href=\"http://about.travis-ci.org/docs/user/getting-started/\">Guía de Inicio </a>.\n <small>Solo tomará unos pocos minutos.</small>"
token: Token

View File

@ -118,9 +118,7 @@ fr:
locale:
message:
config: comment configurer des options de version personnalisées
your_repos: ! 'Utilisez les boutons ci-dessous pour activer Travis sur vos projets puis déployez sur GitHub.<br />
Pour tester sur plus de versions de ruby, voir'
your_repos: ! 'Utilisez les boutons ci-dessous pour activer Travis sur vos projets puis déployez sur GitHub.'
messages:
notice: ! "Pour commencer, veuillez lire notre <a href=\"http://about.travis-ci.org/docs/user/getting-started/\">guide de démarrage</a>.\n <small>Cela ne vous prendra que quelques minutes.</small>"
token: Jeton

View File

@ -118,7 +118,7 @@ nb:
locale:
message:
config: hvordan sette opp egne jobbinnstillinger
your_repos: ! "Slå\x10 på Travis for prosjektene dine ved å dra i bryterne under, og send koden til Github.<br />\nFor å teste mot flere versjoner av ruby, se "
your_repos: ! "Slå\x10 på Travis for prosjektene dine ved å dra i bryterne under, og send koden til Github."
messages:
notice: For å komme i gang, vennligst les <a href="http://about.travis-ci.org/docs/user/getting-started/">kom-i-gang-veivisereren</a> vår. <small>Det tar bare et par minutter.</small>
token: Kode

View File

@ -118,9 +118,7 @@ nl:
locale: Taal
message:
config: hoe eigen bouw-opties in te stellen
your_repos: ! 'Zet de schakelaars hieronder aan om de Travis hook voor uw projecten te activeren en push daarna naar Github<br />
Om te testen tegen meerdere rubies, zie'
your_repos: ! 'Zet de schakelaars hieronder aan om de Travis hook voor uw projecten te activeren en push daarna naar Github.'
messages:
notice: Om te beginnen kunt u onze <a href=\"http://about.travis-ci.org/docs/user/getting-started/\">startersgids</a> lezen.\n <small>Het zal maar enkele minuten van uw tijd vergen.</small>
token: Token

View File

@ -121,9 +121,7 @@ pl:
locale: język
message:
config: jak skonfigurować niestandardowe opcje builda
your_repos: ! 'Przesuń suwak poniżej, aby włączyć Travisa dla twoich projektów, a następnie umieść swój kod na GitHubie.<br />
Aby testować swój kod przy użyciu wielu wersji Rubiego, zobacz'
your_repos: ! 'Przesuń suwak poniżej, aby włączyć Travisa dla twoich projektów, a następnie umieść swój kod na GitHubie.'
messages:
notice: ! "Aby zacząć, przeczytaj nasz <a href=\"http://about.travis-ci.org/docs/user/getting-started/\">Przewodnik</a>.\n <small>Zajmie ci to tylko kilka minut.</small>"
token: Token

View File

@ -118,7 +118,7 @@ pt-BR:
locale:
message:
config: como configurar opções de build
your_repos: Use os botões abaixo para ligar ou desligar o hook de serviço do Travis para seus projetos, e então, faça um push para o Github.<br />Para testar com múltiplas versões do Ruby, leia
your_repos: Use os botões abaixo para ligar ou desligar o hook de serviço do Travis para seus projetos, e então, faça um push para o Github.
messages:
notice: Para começar, leia nosso <a href="http://about.travis-ci.org/docs/user/getting-started/">Guia de início</a>. <small>Só leva alguns minutinhos.</small>
token: Token

View File

@ -124,9 +124,7 @@ ru:
locale: Язык
message:
config: как настроить специальные опции билда
your_repos: ! 'Используйте переключатели, чтобы включить Travis service hook для вашего проекта, а потом отправьте код на GitHub.<br />
Для тестирования на нескольких версиях Ruby смотрите'
your_repos: ! 'Используйте переключатели, чтобы включить Travis service hook для вашего проекта, а потом отправьте код на GitHub.'
messages:
notice: Перед началом, пожалуйста, прочтите <a href="http://about.travis-ci.org/docs/user/getting-started/">Руководство для быстрого старта</a>. <small>Это займет всего несколько минут.</small>
token: Токен

Binary file not shown.

After

Width:  |  Height:  |  Size: 351 B

BIN
public/images/icons/off.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 960 B

View File

@ -53,6 +53,7 @@
<script src="/scripts/app.js"></script>
<script>
minispade.require('travis');
Travis.run()
</script>
<script src="/scripts/specs.js"></script>
</body>