diff --git a/app/components/limit-concurrent-builds.coffee b/app/components/limit-concurrent-builds.coffee index e4eff2d8..11ef37b9 100644 --- a/app/components/limit-concurrent-builds.coffee +++ b/app/components/limit-concurrent-builds.coffee @@ -11,7 +11,16 @@ LimitConcurrentBuildsComponent = Ember.Component.extend description ).property('enabled') + limitChanged: -> + repo = @get('repo') + limit = parseInt(@get('value')) + if limit + @set('isSaving', true) + savingFinished = => + @set('isSaving', false) + repo.saveSettings(maximum_number_of_builds: limit). + then(savingFinished, savingFinished) actions: toggle: -> unless @get('enabled') @@ -26,15 +35,6 @@ LimitConcurrentBuildsComponent = Ember.Component.extend @set('value', 0) limitChanged: -> - repo = @get('repo') - limit = parseInt(@get('value')) - if limit - @set('isSaving', true) - savingFinished = => - @set('isSaving', false) - - repo.saveSettings(maximum_number_of_builds: limit). - then(savingFinished, savingFinished) - + Ember.run.debounce(this, 'limitChanged', 1000) `export default LimitConcurrentBuildsComponent` diff --git a/app/components/queued-jobs.coffee b/app/components/queued-jobs.coffee new file mode 100644 index 00000000..dfea033e --- /dev/null +++ b/app/components/queued-jobs.coffee @@ -0,0 +1,16 @@ +`import Ember from 'ember'` +`import config from 'travis/config/environment'` + +QueuedJobsComponent = Ember.Component.extend + store: Ember.inject.service() + + init: -> + @_super.apply this, arguments + if !Ember.testing + Visibility.every config.intervals.updateTimes, @updateTimes.bind(this) + + updateTimes: -> + if jobs = @get('jobs') + jobs.forEach (job) -> job.updateTimes() + +`export default QueuedJobsComponent` diff --git a/app/components/repo-show-tabs.coffee b/app/components/repo-show-tabs.coffee new file mode 100644 index 00000000..aa15b348 --- /dev/null +++ b/app/components/repo-show-tabs.coffee @@ -0,0 +1,54 @@ +`import Ember from 'ember'` + +RepoShowTabsComponent = Ember.Component.extend + # hrm. how to parametrize bind-attr? + classCurrent: (-> + 'active' if @get('tab') == 'current' + ).property('tab') + + classBuilds: (-> + 'active' if @get('tab') == 'builds' + ).property('tab') + + classPullRequests: (-> + 'active' if @get('tab') == 'pull_requests' + ).property('tab') + + classBranches: (-> + 'active' if @get('tab') == 'branches' + ).property('tab') + + classEvents: (-> + 'active' if @get('tab') == 'events' + ).property('tab') + + classBuild: (-> + tab = @get('tab') + classes = [] + classes.push('active') if tab == 'build' + classes.push('display-inline') if tab == 'build' || tab == 'job' + classes.join(' ') + ).property('tab') + + # TODO: refactor tabs, most of the things here are not really DRY + classJob: (-> + 'active' if @get('tab') == 'job' + ).property('tab') + + classRequests: (-> + 'active' if @get('tab') == 'requests' + ).property('tab') + + classCaches: (-> + 'active' if @get('tab') == 'caches' + ).property('tab') + + classSettings: (-> + 'active' if @get('tab') == 'settings' + ).property('tab') + + classRequest: (-> + 'active' if @get('tab') == 'request' + ).property('tab') + +`export default RepoShowTabsComponent` diff --git a/app/components/repo-show-tools.coffee b/app/components/repo-show-tools.coffee new file mode 100644 index 00000000..c5101af8 --- /dev/null +++ b/app/components/repo-show-tools.coffee @@ -0,0 +1,47 @@ +`import Ember from 'ember'` +`import config from 'travis/config/environment'` + +RepoShowToolsComponent = Ember.Component.extend + popup: Ember.inject.service() + + click: (event) -> + if $(event.target).is('a') && $(event.target).parents('.dropdown-menu').length + @closeMenu() + + closeMenu: -> + $('.menu').removeClass('display') + + actions: + menu: -> + @get('popup').close() + $('#tools .menu').toggleClass('display') + return false + + hasPermission: (-> + if permissions = @get('currentUser.permissions') + permissions.contains parseInt(@get('repo.id')) + ).property('currentUser.permissions.length', 'repo.id') + + hasPushPermission: (-> + if permissions = @get('currentUser.pushPermissions') + permissions.contains parseInt(@get('repo.id')) + ).property('currentUser.pushPermissions.length', 'repo.id') + + hasAdminPermission: (-> + if permissions = @get('currentUser.adminPermissions') + permissions.contains parseInt(@get('repo.id')) + ).property('currentUser.adminPermissions.length', 'repo.id') + + displaySettingsLink: (-> + @get('hasPushPermission') + ).property('hasPushPermission') + + displayCachesLink: (-> + @get('hasPushPermission') && config.endpoints.caches + ).property('hasPushPermission') + + displayStatusImages: (-> + @get('hasPermission') + ).property('hasPermission') + +`export default RepoShowToolsComponent` diff --git a/app/components/repos-list-item.coffee b/app/components/repos-list-item.coffee new file mode 100644 index 00000000..af4ee542 --- /dev/null +++ b/app/components/repos-list-item.coffee @@ -0,0 +1,31 @@ +`import Ember from 'ember'` +`import Polling from 'travis/mixins/polling'` +`import { colorForState } from 'travis/utils/helpers'` + +ReposListItemComponent = Ember.Component.extend Polling, + routing: Ember.inject.service('-routing') + + tagName: 'li' + + pollModels: 'repo' + + classNames: ['repo'] + classNameBindings: ['color', 'selected'] + selected: (-> + @get('repo') == @get('selectedRepo') + ).property('selectedRepo') + + color: (-> + colorForState(@get('repo.lastBuildState')) + ).property('repo.lastBuildState') + + scrollTop: (-> + if (window.scrollY > 0) + $('html, body').animate({scrollTop: 0}, 200) + ) + + click: -> + @scrollTop() + @get('routing').transitionTo('repo', @get('repo.slug').split('/')) + +`export default ReposListItemComponent` diff --git a/app/components/repos-list.coffee b/app/components/repos-list.coffee new file mode 100644 index 00000000..3dcf8f8c --- /dev/null +++ b/app/components/repos-list.coffee @@ -0,0 +1,6 @@ +`import Ember from 'ember'` + +ReposListComponent = Ember.Component.extend + tagName: 'ul' + +`export default ReposListComponent` diff --git a/app/components/running-jobs.coffee b/app/components/running-jobs.coffee new file mode 100644 index 00000000..3e97c933 --- /dev/null +++ b/app/components/running-jobs.coffee @@ -0,0 +1,20 @@ +`import Ember from 'ember'` +`import Polling from 'travis/mixins/polling'` +`import config from 'travis/config/environment'` + +RunningJobsComponent = Ember.Component.extend Polling, + store: Ember.inject.service() + + pollHook: (store) -> + @get('store').find('job', {}) + + init: -> + @_super.apply this, arguments + if !Ember.testing + Visibility.every config.intervals.updateTimes, @updateTimes.bind(this) + + updateTimes: -> + if jobs = @get('jobs') + jobs.forEach (job) -> job.updateTimes() + +`export default RunningJobsComponent` diff --git a/app/views/show-more-button.coffee b/app/components/show-more-button.coffee similarity index 65% rename from app/views/show-more-button.coffee rename to app/components/show-more-button.coffee index 6c11fe6f..392824fe 100644 --- a/app/views/show-more-button.coffee +++ b/app/components/show-more-button.coffee @@ -1,21 +1,19 @@ `import Ember from 'ember'` -View = Ember.View.extend +ShowMoreButtonComponent = Ember.Component.extend tagName: 'button' classNames: ['button button--grey button--showmore'] classNameBindings: ['isLoading', 'showMore'] showMore: true attributeBindings: ['disabled'] - isLoadingBinding: 'controller.isLoading' - templateName: 'show-more-button' disabledBinding: 'isLoading' - label: (-> + buttonLabel: (-> if @get('isLoading') then 'Loading' else 'Show more' ).property('isLoading') click: -> - @get('controller').showMore() + this.attrs.showMore() -`export default View` +`export default ShowMoreButtonComponent` diff --git a/app/controllers/builds.coffee b/app/controllers/builds.coffee index d0f28631..582307ad 100644 --- a/app/controllers/builds.coffee +++ b/app/controllers/builds.coffee @@ -45,5 +45,9 @@ Controller = Ember.ArrayController.extend @store.find('build', options) + actions: + showMoreBuilds: -> + @showMore() + `export default Controller` diff --git a/app/controllers/queue.coffee b/app/controllers/queue.coffee deleted file mode 100644 index a89d1b28..00000000 --- a/app/controllers/queue.coffee +++ /dev/null @@ -1,14 +0,0 @@ -`import Ember from 'ember'` - -Controller = Ember.ArrayController.extend - isLoaded: false - content: (-> - result = @store.filter('job', {}, (job) -> - ['created', 'queued'].indexOf(job.get('state')) != -1 - ) - result.then => - @set('isLoaded', true) - result - ).property() - -`export default Controller` diff --git a/app/controllers/repos.coffee b/app/controllers/repos.coffee index bce174fa..ccecfba8 100644 --- a/app/controllers/repos.coffee +++ b/app/controllers/repos.coffee @@ -2,7 +2,8 @@ `import limit from 'travis/utils/computed-limit'` `import Repo from 'travis/models/repo'` -Controller = Ember.ArrayController.extend +Controller = Ember.Controller.extend + contentBinding: 'repos' actions: activate: (name) -> @activate(name) @@ -29,8 +30,8 @@ Controller = Ember.ArrayController.extend if @get('tab') == 'owned' && @get('isLoaded') && @get('length') == 0 @container.lookup('router:main').send('redirectToGettingStarted') - isLoadedBinding: 'content.isLoaded' - needs: ['currentUser', 'repo', 'runningJobs', 'queue'] + isLoadedBinding: 'repos.isLoaded' + needs: ['currentUser', 'repo'] currentUserBinding: 'controllers.currentUser.model' selectedRepo: (-> # we need to observe also repo.content here, because we use @@ -39,16 +40,37 @@ Controller = Ember.ArrayController.extend @get('controllers.repo.repo.content') || @get('controllers.repo.repo') ).property('controllers.repo.repo', 'controllers.repo.repo.content') - startedJobsCount: Ember.computed.alias('controllers.runningJobs.length') + startedJobsCount: Ember.computed.alias('runningJobs.length') allJobsCount: (-> - @get('startedJobsCount') + @get('controllers.queue.length') - ).property('startedJobsCount', 'controllers.queue.length') + @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: (-> + # TODO: this should also query for received jobs + result = @store.filter('job', {}, (job) -> + ['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', 'queued'].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 @@ -57,8 +79,8 @@ Controller = Ember.ArrayController.extend ).property() updateTimes: -> - if content = @get('content') - content.forEach (r) -> r.updateTimes() + if repos = @get('repos') + repos.forEach (r) -> r.updateTimes() activate: (tab, params) -> @set('sortProperties', ['sortOrder']) @@ -66,7 +88,7 @@ Controller = Ember.ArrayController.extend this["view_#{tab}".camelize()](params) viewOwned: -> - @set('content', @get('userRepos')) + @set('repos', @get('userRepos')) viewRunning: -> @@ -79,7 +101,7 @@ Controller = Ember.ArrayController.extend viewSearch: (phrase) -> @set('search', phrase) - @set('content', Repo.search(@store, phrase)) + @set('repos', Repo.search(@store, phrase)) searchObserver: (-> search = @get('search') diff --git a/app/controllers/running-jobs.coffee b/app/controllers/running-jobs.coffee deleted file mode 100644 index 1058b304..00000000 --- a/app/controllers/running-jobs.coffee +++ /dev/null @@ -1,24 +0,0 @@ -`import Ember from 'ember'` - -Controller = Ember.ArrayController.extend - init: -> - @_super.apply this, arguments - if !Ember.testing - Visibility.every @config.intervals.updateTimes, @updateTimes.bind(this) - - updateTimes: -> - if content = @get('content') - content.forEach (job) -> job.updateTimes() - - isLoaded: false - content: (-> - # TODO: this should also query for received jobs - result = @store.filter('job', {}, (job) -> - ['started', 'received'].indexOf(job.get('state')) != -1 - ) - result.then => - @set('isLoaded', true) - result - ).property() - -`export default Controller` diff --git a/app/routes/main-tab.coffee b/app/routes/main-tab.coffee index bbc1d4da..6cf21fb6 100644 --- a/app/routes/main-tab.coffee +++ b/app/routes/main-tab.coffee @@ -12,15 +12,17 @@ Route = TravisRoute.extend @controllerFor('repos').activate(@get('reposTabName')) @currentRepoDidChange() - @controllerFor('repos').addObserver('firstObject', this, 'currentRepoDidChange') + if repos = @controllerFor('repos').get('repos') + repos.addObserver('firstObject', this, 'currentRepoDidChange') deactivate: -> - @controllerFor('repos').removeObserver('firstObject', this, 'currentRepoDidChange') + if repos = @controllerFor('repos').get('repos') + repos.removeObserver('firstObject', this, 'currentRepoDidChange') @_super.apply(this, arguments) currentRepoDidChange: -> - if repo = @controllerFor('repos').get('firstObject') + if repo = @controllerFor('repos').get('repos.firstObject') @controllerFor('repo').set('repo', repo) actions: diff --git a/app/routes/settings.coffee b/app/routes/settings.coffee index 76889e85..2c94c1da 100644 --- a/app/routes/settings.coffee +++ b/app/routes/settings.coffee @@ -44,21 +44,9 @@ Route = TravisRoute.extend hasPushAccess: -> repoId = parseInt @modelFor('repo').get('id') - pushAccess = true - Ajax.get '/users/permissions', (data) => - - admin = data.admin.filter (item) -> - return item == repoId - push = data.push.filter (item) -> - return item == repoId - pull = data.pull.filter (item) -> - return item == repoId - - if Ember.isEmpty admin && Ember.isEmpty push && !Ember.isEmpty pull - pushAccess = false - - pushAccess + @auth.get('currentUser').get('pushPermissions').filter (item) -> + item == repoId model: () -> return Ember.RSVP.hash({ diff --git a/app/services/popup.coffee b/app/services/popup.coffee new file mode 100644 index 00000000..83c8e37e --- /dev/null +++ b/app/services/popup.coffee @@ -0,0 +1,15 @@ +`import Ember from 'ember'` + +PopupService = Ember.Service.extend + open: (name) -> + @closeAll() + name = event?.target?.name || name + $("##{name}").toggleClass('display') + close: -> + if view = Ember.View.currentPopupView + view.destroy() + Ember.View.currentPopupView = null + + $('.popup').removeClass('display') + +`export default PopupService` diff --git a/app/templates/builds.hbs b/app/templates/builds.hbs index defdc32e..be1ab124 100644 --- a/app/templates/builds.hbs +++ b/app/templates/builds.hbs @@ -7,7 +7,7 @@ {{/each}} {{#if displayShowMoreButton}}

- {{view 'show-more-button'}} + {{show-more-button isLoading=isLoading showMore=(action 'showMoreBuilds')}} {{#if isLoading}} {{loading-indicator}} {{/if}} diff --git a/app/templates/queue.hbs b/app/templates/components/queued-jobs.hbs similarity index 90% rename from app/templates/queue.hbs rename to app/templates/components/queued-jobs.hbs index a2d70ec2..27b545e3 100644 --- a/app/templates/queue.hbs +++ b/app/templates/components/queued-jobs.hbs @@ -1,6 +1,6 @@ -{{#if isLoaded}} - {{#if length}} - {{#each job in controller}} +{{#if jobs.isLoaded}} + {{#if jobs.length}} + {{#each jobs as |job|}}

{{#if job.repo.slug}} diff --git a/app/templates/components/repo-show-tabs.hbs b/app/templates/components/repo-show-tabs.hbs new file mode 100644 index 00000000..670869db --- /dev/null +++ b/app/templates/components/repo-show-tabs.hbs @@ -0,0 +1,83 @@ +
+ +
diff --git a/app/templates/components/repo-show-tools.hbs b/app/templates/components/repo-show-tools.hbs new file mode 100644 index 00000000..5300edd9 --- /dev/null +++ b/app/templates/components/repo-show-tools.hbs @@ -0,0 +1,18 @@ + diff --git a/app/templates/components/repos-list-item.hbs b/app/templates/components/repos-list-item.hbs new file mode 100644 index 00000000..8b7f4b97 --- /dev/null +++ b/app/templates/components/repos-list-item.hbs @@ -0,0 +1,35 @@ +
+

+ {{#if repo.slug}} + + {{#link-to "repo" repo class="slug"}}{{repo.slug}}{{/link-to}} + {{/if}} +

+ {{#with repo.lastBuildHash as lastBuild}} + {{#if repo.slug}} + {{#if lastBuild.id}} +

+ + {{#link-to "build" repo lastBuild.id + class="last_build"}}{{lastBuild.number}}{{/link-to}} +

+ {{/if}} + {{/if}} + {{/with}} + +

+ + Duration: + + {{format-duration repo.lastBuildDuration}} + +

+ +

+ + Finished: + + {{format-time repo.lastBuildFinishedAt}} + +

+
diff --git a/app/templates/components/repos-list.hbs b/app/templates/components/repos-list.hbs new file mode 100644 index 00000000..faf4b471 --- /dev/null +++ b/app/templates/components/repos-list.hbs @@ -0,0 +1,7 @@ +{{#each repos as |repo|}} + {{repos-list-item repo=repo selectedRepo=selectedRepo}} +{{else}} +

{{noReposMessage}}

+{{/each}} + + diff --git a/app/templates/running-jobs.hbs b/app/templates/components/running-jobs.hbs similarity index 91% rename from app/templates/running-jobs.hbs rename to app/templates/components/running-jobs.hbs index a04e187b..a1a45fc2 100644 --- a/app/templates/running-jobs.hbs +++ b/app/templates/components/running-jobs.hbs @@ -1,6 +1,6 @@ -{{#if isLoaded}} - {{#if controller.length}} - {{#each job in controller}} +{{#if jobs.isLoaded}} + {{#if jobs.length}} + {{#each jobs as |job| }}
{{#if job.repo.slug}} diff --git a/app/templates/components/show-more-button.hbs b/app/templates/components/show-more-button.hbs new file mode 100644 index 00000000..0bb41de2 --- /dev/null +++ b/app/templates/components/show-more-button.hbs @@ -0,0 +1 @@ +{{buttonLabel}} diff --git a/app/templates/repo.hbs b/app/templates/repo.hbs index f81053d6..8d824359 100644 --- a/app/templates/repo.hbs +++ b/app/templates/repo.hbs @@ -18,9 +18,9 @@
- {{view 'repo-show-tools'}} + {{repo-show-tools repo=repo build=build job=job tab=tab currentUser=auth.currentUser}} - {{view 'repo-show-tabs'}} + {{repo-show-tabs repo=repo tab=tab}}
{{#if repo.active}} diff --git a/app/templates/repos.hbs b/app/templates/repos.hbs index 7bf3f1d4..0451b2af 100644 --- a/app/templates/repos.hbs +++ b/app/templates/repos.hbs @@ -9,60 +9,17 @@ {{#if showRunningJobs}} {{else}}