diff --git a/app/views/build.js b/app/components/build-wrapper.js similarity index 60% rename from app/views/build.js rename to app/components/build-wrapper.js index 0e981f04..9ea0f843 100644 --- a/app/views/build.js +++ b/app/components/build-wrapper.js @@ -1,11 +1,10 @@ +import Ember from 'ember'; import { colorForState } from 'travis/utils/helpers'; -import BasicView from 'travis/views/basic'; import Polling from 'travis/mixins/polling'; -export default BasicView.extend(Polling, { +export default Ember.Component.extend({ classNameBindings: ['color'], - buildBinding: 'controller.build', - pollModels: 'controller.build', + pollModels: 'build', color: function() { return colorForState(this.get('build.state')); diff --git a/app/views/builds.js b/app/components/builds-wrapper.js similarity index 70% rename from app/views/builds.js rename to app/components/builds-wrapper.js index eca5f332..b3a1ecb3 100644 --- a/app/views/builds.js +++ b/app/components/builds-wrapper.js @@ -1,12 +1,15 @@ -import BasicView from 'travis/views/basic'; +import Ember from 'ember'; import Polling from 'travis/mixins/polling'; -export default BasicView.extend(Polling, { +export default Ember.Component.extend({ + store: Ember.inject.service('store'), + pollHook: function(store) { var contentType, repositoryId; - contentType = this.get('controller.contentType'); - repositoryId = this.get('controller.repo.id'); - store = this.get('controller.store'); + contentType = this.get('contentType'); + repositoryId = this.get('repo.id'); + store = this.get('store'); + if (contentType === 'builds') { return store.query('build', { event_type: 'push', diff --git a/app/views/job.js b/app/components/job-wrapper.js similarity index 70% rename from app/views/job.js rename to app/components/job-wrapper.js index 032e5161..5b190528 100644 --- a/app/views/job.js +++ b/app/components/job-wrapper.js @@ -3,10 +3,8 @@ import { colorForState } from 'travis/utils/helpers'; import { githubCommit } from 'travis/utils/urls'; import Polling from 'travis/mixins/polling'; -export default Ember.View.extend(Polling, { - pollModels: 'controller.job.build', - repoBinding: 'controller.repo', - jobBinding: 'controller.job', +export default Ember.Component.extend({ + pollModels: 'job.build', commitBinding: 'job.commit', currentItemBinding: 'job', @@ -16,5 +14,5 @@ export default Ember.View.extend(Polling, { urlGithubCommit: function() { return githubCommit(this.get('repo.slug'), this.get('commit.sha')); - }.property('repo.slug', 'commit.sha'), + }.property('repo.slug', 'commit.sha') }); diff --git a/app/views/application.js b/app/components/popup-click-handler.js similarity index 61% rename from app/views/application.js rename to app/components/popup-click-handler.js index f706832f..c810b87b 100644 --- a/app/views/application.js +++ b/app/components/popup-click-handler.js @@ -1,18 +1,17 @@ -import BasicView from 'travis/views/basic'; import Ember from 'ember'; -export default BasicView.extend({ +export default Ember.Component.extend({ popup: Ember.inject.service(), classNames: ['application'], click(event) { - var targetAndParents; - targetAndParents = $(event.target).parents().andSelf(); + var targetAndParents = $(event.target).parents().andSelf(); + if (!(targetAndParents.hasClass('open-popup') || targetAndParents.hasClass('popup'))) { this.get('popup').close(); } if (!targetAndParents.hasClass('menu') && !targetAndParents.is('#tools > a')) { - return $('.menu').removeClass('display'); + $('.menu').removeClass('display'); } } }); diff --git a/app/components/profile-accounts-wrapper.js b/app/components/profile-accounts-wrapper.js new file mode 100644 index 00000000..83423d73 --- /dev/null +++ b/app/components/profile-accounts-wrapper.js @@ -0,0 +1,6 @@ +import Ember from 'ember'; + +export default Ember.Component.extend({ + classNames: ['profile-orglist', 'columns', 'medium-4'], + tagName: 'aside', +}); diff --git a/app/components/repo-wrapper.js b/app/components/repo-wrapper.js new file mode 100644 index 00000000..1ca2bd7f --- /dev/null +++ b/app/components/repo-wrapper.js @@ -0,0 +1,7 @@ +import Polling from 'travis/mixins/polling'; +import Ember from 'ember'; + +export default Ember.Component.extend(Polling, { + pollModels: 'repo', + classNameBindings: ['isLoading:loading'] +}); diff --git a/app/views/repos-list-tabs.js b/app/components/repos-list-tabs.js similarity index 78% rename from app/views/repos-list-tabs.js rename to app/components/repos-list-tabs.js index c24cc7f5..3524e1fc 100644 --- a/app/views/repos-list-tabs.js +++ b/app/components/repos-list-tabs.js @@ -1,13 +1,14 @@ import Ember from 'ember'; -export default Ember.View.extend({ - templateName: 'repos/list/tabs', - tabBinding: 'controller.tab', - currentUserBinding: 'controller.currentUser.model', +export default Ember.Component.extend({ + auth: Ember.inject.service(), + + currentUserBinding: 'auth.currentUser', + classRecent: function() { if (this.get('tab') === 'recent') { return 'active'; - } else if (this.get('tab') === 'search' && this.get('controller').auth.get('signedIn')) { + } else if (this.get('tab') === 'search' && this.get('auth.signedIn')) { return 'hidden'; } }.property('tab'), diff --git a/app/views/status-image-input.js b/app/components/status-image-input.js similarity index 100% rename from app/views/status-image-input.js rename to app/components/status-image-input.js diff --git a/app/components/status-images.js b/app/components/status-images.js new file mode 100644 index 00000000..7ced75f0 --- /dev/null +++ b/app/components/status-images.js @@ -0,0 +1,24 @@ +import Ember from 'ember'; +import { format as formatStatusImage } from 'travis/utils/status-image-formats'; + +export default Ember.Component.extend({ + popup: Ember.inject.service(), + + id: 'status-images', + attributeBindings: ['id'], + classNames: ['popup', 'status-images'], + formats: ['Image URL', 'Markdown', 'Textile', 'Rdoc', 'AsciiDoc', 'RST', 'Pod', 'CCTray'], + + actions: { + close() { + return this.get('popup').close(); + } + }, + + statusString: function() { + let format = this.get('format') || this.get('formats.firstObject'), + branch = this.get('branch') || 'master'; + + return formatStatusImage(format, this.get('repo.slug'), branch); + }.property('format', 'repo.slug', 'branch') +}); diff --git a/app/controllers/repo.js b/app/controllers/repo.js index bdda7a44..2e03d10c 100644 --- a/app/controllers/repo.js +++ b/app/controllers/repo.js @@ -1,11 +1,16 @@ import Ember from 'ember'; -import { githubRepo } from 'travis/utils/urls'; +import { githubRepo, statusImage } from 'travis/utils/urls'; +import config from 'travis/config/environment'; + export default Ember.Controller.extend({ + popup: Ember.inject.service(), + jobController: Ember.inject.controller('job'), buildController: Ember.inject.controller('build'), buildsController: Ember.inject.controller('builds'), reposController: Ember.inject.controller('repos'), + reposBinding: 'reposController.repos', currentUserBinding: 'auth.currentUser', classNames: ['repo'], @@ -14,6 +19,21 @@ export default Ember.Controller.extend({ builds: Ember.computed.alias('buildsController.content'), job: Ember.computed.alias('jobController.job'), + isEmpty: function() { + return this.get('repos.isLoaded') && this.get('repos.length') === 0; + }.property('repos.isLoaded', 'repos.length'), + + statusImageUrl: function() { + return statusImage(this.get('repo.slug')); + }.property('repo.slug'), + + actions: { + statusImages() { + this.get('popup').open('status-images'); + return false; + } + }, + slug: function() { return this.get('repo.slug'); }.property('repo.slug'), diff --git a/app/controllers/top.js b/app/controllers/top.js index 27cc673d..de6962d5 100644 --- a/app/controllers/top.js +++ b/app/controllers/top.js @@ -102,5 +102,17 @@ export default Ember.Controller.extend({ }, showCta: function() { return !this.get('auth.signedIn') && !this.get('config.pro') && !this.get('landingPage'); - }.property('auth.signedIn', 'landingPage') + }.property('auth.signedIn', 'landingPage'), + + classProfile: function() { + var classes = ['profile menu']; + + if (this.get('tab') === 'profile') { + classes.push('active'); + } + + classes.push(this.get('controller.auth.state') || 'signed-out'); + + return classes.join(' '); + }.property('tab', 'auth.state') }); diff --git a/app/routes/auth.js b/app/routes/auth.js index 42b86f76..f0707b5c 100644 --- a/app/routes/auth.js +++ b/app/routes/auth.js @@ -5,7 +5,7 @@ export default TravisRoute.extend({ renderTemplate() { $('body').attr('id', 'auth'); - return this.render('auth.signin'); + return this.render('signin'); }, deactivate() { diff --git a/app/services/popup.js b/app/services/popup.js index 89c51b97..2a866c97 100644 --- a/app/services/popup.js +++ b/app/services/popup.js @@ -9,11 +9,6 @@ export default Ember.Service.extend({ }, close() { - var view; - if (view = Ember.View.currentPopupView) { - view.destroy(); - Ember.View.currentPopupView = null; - } return $('.popup').removeClass('display'); } }); diff --git a/app/templates/application.hbs b/app/templates/application.hbs index c24cd689..47326c47 100644 --- a/app/templates/application.hbs +++ b/app/templates/application.hbs @@ -1 +1,3 @@ -{{outlet}} +{{#popup-click-handler}} + {{outlet}} +{{/popup-click-handler}} diff --git a/app/templates/build.hbs b/app/templates/build.hbs index 5ae9f8fb..02804d4e 100644 --- a/app/templates/build.hbs +++ b/app/templates/build.hbs @@ -1,3 +1,4 @@ +{{#build-wrapper build=build}} {{#if loading}} {{loading-indicator}} {{else}} @@ -16,3 +17,4 @@ {{/if}} {{/if}} +{{/build-wrapper}} diff --git a/app/templates/builds.hbs b/app/templates/builds.hbs index fe9fbfe1..87829b57 100644 --- a/app/templates/builds.hbs +++ b/app/templates/builds.hbs @@ -1,3 +1,4 @@ +{{#builds-wrapper contentType=contentType repo=repo}} {{#if model.isLoaded}}