diff --git a/.jshintrc b/.jshintrc index 98bf8385..f7c2060c 100644 --- a/.jshintrc +++ b/.jshintrc @@ -4,7 +4,8 @@ "window", "-Promise", "jQuery", - "Visibility" + "Visibility", + "$" ], "browser": true, "boss": true, diff --git a/app/adapters/application.coffee b/app/adapters/application.coffee deleted file mode 100644 index d36bca6d..00000000 --- a/app/adapters/application.coffee +++ /dev/null @@ -1,30 +0,0 @@ -`import DS from 'ember-data'` -`import config from 'travis/config/environment'` - -Adapter = DS.ActiveModelAdapter.extend - auth: Ember.inject.service() - - host: config.apiEndpoint - coalesceFindRequests: true - - ajaxOptions: (url, type, options) -> - hash = @_super(url, type, options) - - hash.headers ||= {} - - hash.headers['accept'] = 'application/json; version=2' - - if token = @get('auth').token() - hash.headers['Authorization'] ||= "token #{token}" - - hash - - findMany: (store, type, ids) -> - @ajax(@buildURL(type.modelName), 'GET', data: { ids: ids }) - - handleResponse: (status, headers, payload) -> - if status > 299 - console.log "[ERROR] API responded with an error (#{status}): #{JSON.stringify(payload)}" - return @_super.apply(this, arguments) - -`export default Adapter` diff --git a/app/adapters/application.js b/app/adapters/application.js new file mode 100644 index 00000000..aa721541 --- /dev/null +++ b/app/adapters/application.js @@ -0,0 +1,41 @@ +import DS from 'ember-data'; +import config from 'travis/config/environment'; +var Adapter; + +Adapter = DS.ActiveModelAdapter.extend({ + auth: Ember.inject.service(), + host: config.apiEndpoint, + coalesceFindRequests: true, + + ajaxOptions(url, type, options) { + var base, hash, token; + + hash = this._super(...arguments); + hash.headers || (hash.headers = {}); + hash.headers['accept'] = 'application/json; version=2'; + + if (token = this.get('auth').token()) { + (base = hash.headers)['Authorization'] || (base['Authorization'] = "token " + token); + } + + return hash; + }, + + findMany(store, type, ids) { + return this.ajax(this.buildURL(type.modelName), 'GET', { + data: { + ids: ids + } + }); + }, + + handleResponse(status, headers, payload) { + if (status > 299) { + console.log("[ERROR] API responded with an error (" + status + "): " + (JSON.stringify(payload))); + } + + return this._super(...arguments); + } +}); + +export default Adapter; diff --git a/app/adapters/env-var.coffee b/app/adapters/env-var.coffee deleted file mode 100644 index 751e4488..00000000 --- a/app/adapters/env-var.coffee +++ /dev/null @@ -1,26 +0,0 @@ -`import Ember from 'ember'` -`import ApplicationAdapter from 'travis/adapters/application'` - -Adapter = ApplicationAdapter.extend - namespace: 'settings' - - buildURL: (type, id, record) -> - url = @_super.apply this, arguments - - if record && (repoId = Ember.get(record, 'repo.id')) - delimiter = if url.indexOf('?') != -1 then '&' else '?' - url = "#{url}#{delimiter}repository_id=#{repoId}" - - url - - updateRecord: (store, type, record) -> - data = {}; - serializer = store.serializerFor(type.typeKey); - - serializer.serializeIntoHash(data, type, record); - - id = Ember.get(record, 'id'); - - this.ajax(this.buildURL(type.typeKey, id, record), "PATCH", { data: data }) - -`export default Adapter` diff --git a/app/adapters/env-var.js b/app/adapters/env-var.js new file mode 100644 index 00000000..4aaca486 --- /dev/null +++ b/app/adapters/env-var.js @@ -0,0 +1,27 @@ +import Ember from 'ember'; +import ApplicationAdapter from 'travis/adapters/application'; + +export default ApplicationAdapter.extend({ + namespace: 'settings', + + buildURL(type, id, record) { + var delimiter, repoId, url; + url = this._super.apply(this, arguments); + if (record && (repoId = Ember.get(record, 'repo.id'))) { + delimiter = url.indexOf('?') !== -1 ? '&' : '?'; + url = "" + url + delimiter + "repository_id=" + repoId; + } + return url; + }, + + updateRecord(store, type, record) { + var data, id, serializer; + data = {}; + serializer = store.serializerFor(type.typeKey); + serializer.serializeIntoHash(data, type, record); + id = Ember.get(record, 'id'); + return this.ajax(this.buildURL(type.typeKey, id, record), "PATCH", { + data: data + }); + } +}); diff --git a/app/adapters/ssh-key.coffee b/app/adapters/ssh-key.coffee deleted file mode 100644 index f4bad312..00000000 --- a/app/adapters/ssh-key.coffee +++ /dev/null @@ -1,24 +0,0 @@ -`import Ember from 'ember'` -`import ApplicationAdapter from 'travis/adapters/application'` - -Adapter = ApplicationAdapter.extend - namespace: 'settings' - - find: (store, type, id, record) -> - @ajax(this.urlPrefix() + '/ssh_key/' + id, 'GET') - - deleteRecord: (store, type, record) -> - id = Ember.get(record, 'id') - - @ajax(this.urlPrefix() + '/ssh_key/' + id, "DELETE"); - - createRecord: (store, type, record) -> - data = {}; - serializer = store.serializerFor(type.typeKey); - serializer.serializeIntoHash(data, type, record, { includeId: true }); - - id = Ember.get(record, 'id') - - this.ajax(this.urlPrefix() + '/ssh_key/' + id, "PATCH", { data: data }) - -`export default Adapter` diff --git a/app/adapters/ssh-key.js b/app/adapters/ssh-key.js new file mode 100644 index 00000000..25e9113a --- /dev/null +++ b/app/adapters/ssh-key.js @@ -0,0 +1,29 @@ +import Ember from 'ember'; +import ApplicationAdapter from 'travis/adapters/application'; + +export default ApplicationAdapter.extend({ + namespace: 'settings', + + find(store, type, id, record) { + return this.ajax(this.urlPrefix() + '/ssh_key/' + id, 'GET'); + }, + + deleteRecord(store, type, record) { + var id; + id = Ember.get(record, 'id'); + return this.ajax(this.urlPrefix() + '/ssh_key/' + id, "DELETE"); + }, + + createRecord(store, type, record) { + var data, id, serializer; + data = {}; + serializer = store.serializerFor(type.typeKey); + serializer.serializeIntoHash(data, type, record, { + includeId: true + }); + id = Ember.get(record, 'id'); + return this.ajax(this.urlPrefix() + '/ssh_key/' + id, "PATCH", { + data: data + }); + } +}); diff --git a/app/app.coffee b/app/app.coffee deleted file mode 100644 index 7ca627e3..00000000 --- a/app/app.coffee +++ /dev/null @@ -1,111 +0,0 @@ -`import Ember from 'ember'` -`import Resolver from 'ember/resolver'` -`import loadInitializers from 'ember/load-initializers'` -`import config from './config/environment'` - -Ember.MODEL_FACTORY_INJECTIONS = true - -Ember.LinkView.reopen( - attributeBindings: ['alt'] -); - -App = Ember.Application.extend(Ember.Evented, - LOG_TRANSITIONS: true - LOG_TRANSITIONS_INTERNAL: true - LOG_ACTIVE_GENERATION: true - LOG_MODULE_RESOLVER: true - LOG_VIEW_LOOKUPS: true - #LOG_RESOLVER: true - - modulePrefix: config.modulePrefix - podModulePrefix: config.podModulePrefix - Resolver: Resolver - - lookup: -> - @__container__.lookup.apply @__container__, arguments - - flash: (options) -> - Travis.lookup('controller:flash').loadFlashes([options]) - - toggleSidebar: -> - $('body').toggleClass('maximized') - # TODO gotta force redraws here :/ - element = $('') - $('#top .profile').append(element) - Em.run.later (-> element.remove()), 10 - element = $('') - $('#repo').append(element) - Em.run.later (-> element.remove()), 10 - - ready: -> - location.href = location.href.replace('#!/', '') if location.hash.slice(0, 2) == '#!' - - @on 'user:signed_in', (user) -> - Travis.onUserUpdate(user) - - @on 'user:refreshed', (user) -> - Travis.onUserUpdate(user) - - @on 'user:synced', (user) -> - Travis.onUserUpdate(user) - - @on 'user:signed_out', () -> - if config.userlike - Travis.removeUserlike() - - currentDate: -> - new Date() - - onUserUpdate: (user) -> - if config.pro - @identifyCustomer(user) - if config.userlike - @setupUserlike(user) - - @subscribePusher(user) - - subscribePusher: (user) -> - return unless user.channels - channels = user.channels - if config.pro - channels = channels.map (channel) -> - if channel.match /^private-/ - channel - else - "private-#{channel}" - - Travis.pusher.subscribeAll(channels) - - setupUserlike: (user) -> - - btn = document.getElementById('userlikeCustomTab') - btn.classList.add("logged-in") - - userlikeData = window.userlikeData = {} - userlikeData.user = {} - - userlikeData.user.name= user.login; - userlikeData.user.email = user.email; - - unless document.getElementById('userlike-script') - s = document.createElement('script') - s.id = 'userlike-script' - s.src = '//userlike-cdn-widgets.s3-eu-west-1.amazonaws.com/0327dbb23382ccbbb91b445b76e8a91d4b37d90ef9f2faf84e11177847ff7bb9.js' - document.body.appendChild(s) - - removeUserlike: () -> - btn = document.getElementById('userlikeCustomTab') - btn.classList.remove("logged-in") - - identifyCustomer: (user) -> - if _cio && _cio.identify - _cio.identify - id: user.id - email: user.email - name: user.name - created_at: (Date.parse(user.created_at) / 1000) || null - login: user.login -) -loadInitializers(App, config.modulePrefix) - -`export default App` diff --git a/app/app.js b/app/app.js new file mode 100644 index 00000000..3380119c --- /dev/null +++ b/app/app.js @@ -0,0 +1,134 @@ +import Ember from 'ember'; +import Resolver from 'ember/resolver'; +import loadInitializers from 'ember/load-initializers'; +import config from './config/environment'; + +Ember.MODEL_FACTORY_INJECTIONS = true; + +Ember.LinkView.reopen({ + attributeBindings: ['alt'] +}); + +var App = Ember.Application.extend(Ember.Evented, { + LOG_TRANSITIONS: true, + LOG_TRANSITIONS_INTERNAL: true, + LOG_ACTIVE_GENERATION: true, + LOG_MODULE_RESOLVER: true, + LOG_VIEW_LOOKUPS: true, + modulePrefix: config.modulePrefix, + podModulePrefix: config.podModulePrefix, + Resolver: Resolver, + + lookup() { + return this.__container__.lookup.apply(this.__container__, arguments); + }, + + flash(options) { + return Travis.lookup('controller:flash').loadFlashes([options]); + }, + + toggleSidebar() { + var element; + $('body').toggleClass('maximized'); + element = $(''); + $('#top .profile').append(element); + Em.run.later((function() { + return element.remove(); + }), 10); + element = $(''); + $('#repo').append(element); + return Em.run.later((function() { + return element.remove(); + }), 10); + }, + + ready() { + if (location.hash.slice(0, 2) === '#!') { + location.href = location.href.replace('#!/', ''); + } + this.on('user:signed_in', function(user) { + return Travis.onUserUpdate(user); + }); + this.on('user:refreshed', function(user) { + return Travis.onUserUpdate(user); + }); + this.on('user:synced', function(user) { + return Travis.onUserUpdate(user); + }); + return this.on('user:signed_out', function() { + if (config.userlike) { + return Travis.removeUserlike(); + } + }); + }, + + currentDate() { + return new Date(); + }, + + onUserUpdate(user) { + if (config.pro) { + this.identifyCustomer(user); + } + if (config.userlike) { + this.setupUserlike(user); + } + return this.subscribePusher(user); + }, + + subscribePusher(user) { + var channels; + if (!user.channels) { + return; + } + channels = user.channels; + if (config.pro) { + channels = channels.map(function(channel) { + if (channel.match(/^private-/)) { + return channel; + } else { + return "private-" + channel; + } + }); + } + return Travis.pusher.subscribeAll(channels); + }, + + setupUserlike(user) { + var btn, s, userlikeData; + btn = document.getElementById('userlikeCustomTab'); + btn.classList.add("logged-in"); + userlikeData = window.userlikeData = {}; + userlikeData.user = {}; + userlikeData.user.name = user.login; + userlikeData.user.email = user.email; + if (!document.getElementById('userlike-script')) { + s = document.createElement('script'); + s.id = 'userlike-script'; + s.src = '//userlike-cdn-widgets.s3-eu-west-1.amazonaws.com/0327dbb23382ccbbb91b445b76e8a91d4b37d90ef9f2faf84e11177847ff7bb9.js'; + return document.body.appendChild(s); + } + }, + + removeUserlike() { + var btn; + btn = document.getElementById('userlikeCustomTab'); + return btn.classList.remove("logged-in"); + }, + + identifyCustomer(user) { + if (_cio && _cio.identify) { + return _cio.identify({ + id: user.id, + email: user.email, + name: user.name, + created_at: (Date.parse(user.created_at) / 1000) || null, + login: user.login + }); + } + } +}); + +loadInitializers(App, config.modulePrefix); + +export default App; diff --git a/app/components/add-env-var.coffee b/app/components/add-env-var.coffee deleted file mode 100644 index df96537e..00000000 --- a/app/components/add-env-var.coffee +++ /dev/null @@ -1,46 +0,0 @@ -`import Ember from 'ember'` - -AddEnvVarComponent = Ember.Component.extend - - classNames: ['form--envvar'] - classNameBindings: ['nameIsBlank:form-error'] - - store: Ember.inject.service() - - isValid: () -> - if Ember.isBlank(@get('name')) - this.set('nameIsBlank', true) - false - else - true - - reset: -> - @setProperties(name: null, value: null, public: null) - - actions: - save: -> - return if @get('isSaving') - @set('isSaving', true) - - if @isValid() - env_var = @get('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() - , => - @set('isSaving', false) - else - @set('isSaving', false) - - nameChanged: -> - this.set('nameIsBlank', false) - - -`export default AddEnvVarComponent` diff --git a/app/components/add-env-var.js b/app/components/add-env-var.js new file mode 100644 index 00000000..82393ec4 --- /dev/null +++ b/app/components/add-env-var.js @@ -0,0 +1,55 @@ +import Ember from 'ember'; + +export default Ember.Component.extend({ + classNames: ['form--envvar'], + classNameBindings: ['nameIsBlank:form-error'], + store: Ember.inject.service(), + + isValid() { + if (Ember.isBlank(this.get('name'))) { + this.set('nameIsBlank', true); + return false; + } else { + return true; + } + }, + + reset() { + return this.setProperties({ + name: null, + value: null, + "public": null + }); + }, + + actions: { + save() { + var env_var, self; + if (this.get('isSaving')) { + return; + } + this.set('isSaving', true); + if (this.isValid()) { + env_var = this.get('store').createRecord('env_var', { + name: this.get('name'), + value: this.get('value'), + "public": this.get('public'), + repo: this.get('repo') + }); + self = this; + return env_var.save().then(() => { + this.set('isSaving', false); + return this.reset(); + }, () => { + return this.set('isSaving', false); + }); + } else { + return this.set('isSaving', false); + } + }, + + nameChanged() { + return this.set('nameIsBlank', false); + } + } +}); diff --git a/app/components/add-ssh-key.coffee b/app/components/add-ssh-key.coffee deleted file mode 100644 index 1f414097..00000000 --- a/app/components/add-ssh-key.coffee +++ /dev/null @@ -1,73 +0,0 @@ -# `import Ember from 'ember'` - -AddSshKeyComponent = Ember.Component.extend - - classNames: ['form--sshkey'] - classNameBindings: ['valueError:form-error'] - - store: Ember.inject.service() - isSaving: false - - didInsertElement: () -> - id = @get('repo.id') - model = @get('store').recordForId('ssh_key', id) - # TODO: this can be removed in favor of simply unloading record - # once https://github.com/emberjs/data/pull/2867 - # and https://github.com/emberjs/data/pull/2870 are merged - if model - @get('store').dematerializeRecord(model._internalModel) - typeMap = @get('store').typeMapFor(model.constructor) - idToRecord = typeMap.idToRecord - delete idToRecord[id] - - model = @get('store').createRecord('ssh_key', id: id) - @set('model', model) - - isValid: () -> - if Ember.isBlank(@get('value')) - this.set('valueError', 'Value can\'t be blank.') - false - else - true - - reset: -> - @setProperties(description: null, value: null) - - valueChanged: (-> - this.set('valueError', false) - ).observes('value') - - addErrorsFromResponse: (errArr) -> - error = errArr[0].detail - if error.code == 'not_a_private_key' - this.set('valueError', 'This key is not a private key.') - else if error.code == 'key_with_a_passphrase' - this.set('valueError', 'The key can\'t have a passphrase.') - - actions: - - save: -> - this.set('valueError', false) - return if @get('isSaving') - @set('isSaving', true) - if @isValid() - - ssh_key = @get('model').setProperties( - description: @get('description') - value: @get('value') - ) - - ssh_key.save().then => - @set('isSaving', false) - @reset() - - @sendAction('sshKeyAdded', ssh_key) - , (error) => - @set('isSaving', false) - if error.errors - @addErrorsFromResponse(error.errors) - - else - @set('isSaving', false) - -`export default AddSshKeyComponent` diff --git a/app/components/add-ssh-key.js b/app/components/add-ssh-key.js new file mode 100644 index 00000000..5740f966 --- /dev/null +++ b/app/components/add-ssh-key.js @@ -0,0 +1,82 @@ +var AddSshKeyComponent; + +export default Ember.Component.extend({ + classNames: ['form--sshkey'], + classNameBindings: ['valueError:form-error'], + store: Ember.inject.service(), + isSaving: false, + + didInsertElement() { + id = this.get('repo.id'); + model = this.get('store').recordForId('ssh_key', id); + if (model) { + this.get('store').dematerializeRecord(model._internalModel); + typeMap = this.get('store').typeMapFor(model.constructor); + idToRecord = typeMap.idToRecord; + delete idToRecord[id]; + } + model = this.get('store').createRecord('ssh_key', { + id: id + }); + return this.set('model', model); + }, + + isValid() { + if (Ember.isBlank(this.get('value'))) { + this.set('valueError', 'Value can\'t be blank.'); + return false; + } else { + return true; + } + }, + + reset() { + return this.setProperties({ + description: null, + value: null + }); + }, + + valueChanged: function() { + return this.set('valueError', false); + }.observes('value'), + + addErrorsFromResponse(errArr) { + var error; + error = errArr[0].detail; + if (error.code === 'not_a_private_key') { + return this.set('valueError', 'This key is not a private key.'); + } else if (error.code === 'key_with_a_passphrase') { + return this.set('valueError', 'The key can\'t have a passphrase.'); + } + }, + + actions: { + save() { + var ssh_key; + this.set('valueError', false); + if (this.get('isSaving')) { + return; + } + this.set('isSaving', true); + if (this.isValid()) { + ssh_key = this.get('model').setProperties({ + description: this.get('description'), + value: this.get('value') + }); + return ssh_key.save().then(() => { + this.set('isSaving', false); + this.reset(); + return this.sendAction('sshKeyAdded', ssh_key); + }, () => { + this.set('isSaving', false); + if (error.errors) { + return this.addErrorsFromResponse(error.errors); + } + }); + } else { + return this.set('isSaving', false); + } + } + } +}); diff --git a/app/components/branch-row.coffee b/app/components/branch-row.coffee deleted file mode 100644 index bb40ad55..00000000 --- a/app/components/branch-row.coffee +++ /dev/null @@ -1,90 +0,0 @@ -`import Ember from 'ember'` -`import { githubCommit as githubCommitUrl } from 'travis/utils/urls'` -`import TravisRoute from 'travis/routes/basic'` -`import config from 'travis/config/environment'` - -BranchRowComponent = Ember.Component.extend - routing: Ember.inject.service('-routing') - tagName: 'li' - classNameBindings: ['build.last_build.state'] - classNames: ['branch-row', 'row-li'] - isLoading: false - isTriggering: false - hasTriggered: false - - urlGithubCommit: (-> - githubCommitUrl(@get('build.repository.slug'), @get('build.last_build.commit.sha')) - ).property('build.last_build') - - getLast5Builds: (-> - - lastBuilds = Ember.ArrayProxy.create( - content: [{}, {}, {}, {}, {}] - isLoading: true, - count: 0 - ) - - if !@get('build.last_build') - lastBuilds.set('isLoading', false) - else - apiEndpoint = config.apiEndpoint - repoId = @get('build.repository.id') - branchName = @get('build.name') - - options = {} - if @get('auth.signedIn') - options.headers = { Authorization: "token #{@auth.token()}" } - - $.ajax("#{apiEndpoint}/v3/repo/#{repoId}/builds?branch.name=#{branchName}&limit=5&build.event_type=push,api", options).then (response) -> - array = response.builds.map( (build) -> - Ember.Object.create(build) - ) - if array.length < 5 - for i in [1..5 - array.length] by 1 - array.push({}) - - lastBuilds.set('count', response['@pagination'].count) - lastBuilds.set('content', array) - lastBuilds.set('isLoading', false) - - lastBuilds - ).property() - - canTrigger: (-> - if !@get('auth.signedIn') - false - else - permissions = @get('auth.currentUser.permissions') - if permissions.contains parseInt(@get('build.repository.id')) - true - else - false - ).property() - - triggerBuild: (-> - apiEndpoint = config.apiEndpoint - repoId = @get('build.repository.id') - options = { - type: 'POST', - body: { - request: { - branch: @get('build.name') - } - } - } - if @get('auth.signedIn') - options.headers = { Authorization: "token #{@auth.token()}" } - $.ajax("#{apiEndpoint}/v3/repo/#{repoId}/requests", options).then (response) => - @set('isTriggering', false) - @set('hasTriggered', true) - ) - - actions: - tiggerBuild: (branch) -> - @set('isTriggering', true) - @triggerBuild() - - viewAllBuilds: (branch) -> - @get('routing').transitionTo('builds') - -`export default BranchRowComponent` diff --git a/app/components/branch-row.js b/app/components/branch-row.js new file mode 100644 index 00000000..d4ae6c98 --- /dev/null +++ b/app/components/branch-row.js @@ -0,0 +1,103 @@ +import Ember from 'ember'; +import { githubCommit as githubCommitUrl } from 'travis/utils/urls'; +import TravisRoute from 'travis/routes/basic'; +import config from 'travis/config/environment'; + +export default Ember.Component.extend({ + routing: Ember.inject.service('-routing'), + tagName: 'li', + classNameBindings: ['build.last_build.state'], + classNames: ['branch-row', 'row-li'], + isLoading: false, + isTriggering: false, + hasTriggered: false, + + urlGithubCommit: function() { + return githubCommitUrl(this.get('build.repository.slug'), this.get('build.last_build.commit.sha')); + }.property('build.last_build'), + + getLast5Builds: function() { + var apiEndpoint, branchName, lastBuilds, options, repoId; + lastBuilds = Ember.ArrayProxy.create({ + content: [{}, {}, {}, {}, {}], + isLoading: true, + count: 0 + }); + if (!this.get('build.last_build')) { + lastBuilds.set('isLoading', false); + } else { + apiEndpoint = config.apiEndpoint; + repoId = this.get('build.repository.id'); + branchName = this.get('build.name'); + options = {}; + if (this.get('auth.signedIn')) { + options.headers = { + Authorization: "token " + (this.auth.token()) + }; + } + $.ajax(apiEndpoint + "/v3/repo/" + repoId + "/builds?branch.name=" + branchName + "&limit=5&build.event_type=push,api", options).then(function(response) { + var array, i, j, ref; + array = response.builds.map(function(build) { + return Ember.Object.create(build); + }); + if (array.length < 5) { + for (i = j = 1, ref = 5 - array.length; j <= ref; i = j += 1) { + array.push({}); + } + } + lastBuilds.set('count', response['@pagination'].count); + lastBuilds.set('content', array); + return lastBuilds.set('isLoading', false); + }); + } + return lastBuilds; + }.property(), + + canTrigger: function() { + var permissions; + if (!this.get('auth.signedIn')) { + return false; + } else { + permissions = this.get('auth.currentUser.permissions'); + if (permissions.contains(parseInt(this.get('build.repository.id')))) { + return true; + } else { + return false; + } + } + }.property(), + + triggerBuild: function() { + var apiEndpoint, options, repoId; + apiEndpoint = config.apiEndpoint; + repoId = this.get('build.repository.id'); + options = { + type: 'POST', + body: { + request: { + branch: this.get('build.name') + } + } + }; + if (this.get('auth.signedIn')) { + options.headers = { + Authorization: "token " + (this.auth.token()) + }; + } + return $.ajax(apiEndpoint + "/v3/repo/" + repoId + "/requests", options).then(() => { + this.set('isTriggering', false); + return this.set('hasTriggered', true); + }); + }, + + actions: { + tiggerBuild(branch) { + this.set('isTriggering', true); + return this.triggerBuild(); + }, + + viewAllBuilds(branch) { + return this.get('routing').transitionTo('builds'); + } + } +}); diff --git a/app/components/broadcast-tower.coffee b/app/components/broadcast-tower.coffee deleted file mode 100644 index bc977531..00000000 --- a/app/components/broadcast-tower.coffee +++ /dev/null @@ -1,24 +0,0 @@ -`import Ember from 'ember'` - -BroadcastTowerComponent = Ember.Component.extend - - classNames: ['broadcast'] - - isOpen: false - timeoutId: '' - - actions: - toggleBroadcasts:() -> - @toggleProperty('isOpen') - @sendAction('toggleBroadcasts') - - if @get('isOpen') == true - @set('timeoutId', setTimeout => - @toggleProperty('isOpen') - @sendAction('toggleBroadcasts') - , 10000 - ) - else - clearTimeout(@get('timeoutId')) - -`export default BroadcastTowerComponent` diff --git a/app/components/broadcast-tower.js b/app/components/broadcast-tower.js new file mode 100644 index 00000000..cb42efef --- /dev/null +++ b/app/components/broadcast-tower.js @@ -0,0 +1,21 @@ +import Ember from 'ember'; + +export default Ember.Component.extend({ + classNames: ['broadcast'], + isOpen: false, + timeoutId: '', + actions: { + toggleBroadcasts() { + this.toggleProperty('isOpen'); + this.sendAction('toggleBroadcasts'); + if (this.get('isOpen') === true) { + return this.set('timeoutId', setTimeout(() => { + this.toggleProperty('isOpen'); + return this.sendAction('toggleBroadcasts'); + }, 10000)); + } else { + return clearTimeout(this.get('timeoutId')); + } + } + } +}); diff --git a/app/components/build-header.coffee b/app/components/build-header.coffee deleted file mode 100644 index 92eda750..00000000 --- a/app/components/build-header.coffee +++ /dev/null @@ -1,24 +0,0 @@ -`import Ember from 'ember'` -`import GithubUrlPropertievs from 'travis/mixins/github-url-properties'` -`import { durationFrom, safe } from 'travis/utils/helpers'` -`import { githubCommit } from 'travis/utils/urls'` - -BuildHeaderComponent = Ember.Component.extend - - tagName: 'section' - classNames: ['build-header'] - classNameBindings: ['item.state'] - - isJob: (-> - if @get('item.build') then true else false - ).property('item') - - urlGithubCommit: (-> - githubCommit(@get('repo.slug'), @get('commit.sha')) - ).property('item') - - elapsedTime: (-> - durationFrom(@get('item.startedAt'), @get('item.finishedAt')) - ).property('item.startedAt', 'item.finishedAt', 'item.duration') - -`export default BuildHeaderComponent` diff --git a/app/components/build-header.js b/app/components/build-header.js new file mode 100644 index 00000000..6699aa2a --- /dev/null +++ b/app/components/build-header.js @@ -0,0 +1,27 @@ +import Ember from 'ember'; +import { gravatarImage } from 'travis/utils/urls'; +import GithubUrlPropertievs from 'travis/mixins/github-url-properties'; +import { durationFrom, safe } from 'travis/utils/helpers'; +import { githubCommit } from 'travis/utils/urls'; + +export default Ember.Component.extend({ + tagName: 'section', + classNames: ['build-header'], + classNameBindings: ['item.state'], + + isJob: function() { + if (this.get('item.build')) { + return true; + } else { + return false; + } + }.property('item'), + + urlGithubCommit: function() { + return githubCommit(this.get('repo.slug'), this.get('commit.sha')); + }.property('item'), + + elapsedTime: function() { + return durationFrom(this.get('item.startedAt'), this.get('item.finishedAt')); + }.property('item.startedAt', 'item.finishedAt', 'item.duration') +}); diff --git a/app/components/build-repo-actions.coffee b/app/components/build-repo-actions.coffee deleted file mode 100644 index 5c2c2278..00000000 --- a/app/components/build-repo-actions.coffee +++ /dev/null @@ -1,9 +0,0 @@ -`import Ember from 'ember'` -`import RepoActionsItemComponentMixin from 'travis/utils/repo-actions-item-component-mixin'` - -BuildRepoActionsComponent = Ember.Component.extend(RepoActionsItemComponentMixin, - item: Ember.computed.alias('build') - type: 'build' -) - -`export default BuildRepoActionsComponent` diff --git a/app/components/build-repo-actions.js b/app/components/build-repo-actions.js new file mode 100644 index 00000000..ffa7ab62 --- /dev/null +++ b/app/components/build-repo-actions.js @@ -0,0 +1,7 @@ +import Ember from 'ember'; +import RepoActionsItemComponentMixin from 'travis/utils/repo-actions-item-component-mixin'; + +export default Ember.Component.extend(RepoActionsItemComponentMixin, { + item: Ember.computed.alias('build'), + type: 'build' +}); diff --git a/app/components/build-tile.coffee b/app/components/build-tile.coffee deleted file mode 100644 index f0ee48ab..00000000 --- a/app/components/build-tile.coffee +++ /dev/null @@ -1,14 +0,0 @@ -`import Ember from 'ember'` - -BuildTileComponent = Ember.Component.extend - - tagName: 'li' - classNameBindings: ['build.state'] - attributeBindings: ['title'], - - title: (-> - num = @get('build.number') - "##{num}" - ).property('build') - -`export default BuildTileComponent` diff --git a/app/components/build-tile.js b/app/components/build-tile.js new file mode 100644 index 00000000..dba111af --- /dev/null +++ b/app/components/build-tile.js @@ -0,0 +1,13 @@ +import Ember from 'ember'; + +export default Ember.Component.extend({ + tagName: 'li', + classNameBindings: ['build.state'], + attributeBindings: ['title'], + + title: function() { + var num; + num = this.get('build.number'); + return "#" + num; + }.property('build') +}); diff --git a/app/components/builds-item.coffee b/app/components/builds-item.coffee deleted file mode 100644 index c2cf4740..00000000 --- a/app/components/builds-item.coffee +++ /dev/null @@ -1,13 +0,0 @@ -`import Ember from 'ember'` -`import { githubCommit as githubCommitUrl } from 'travis/utils/urls'` - -BuildsItemComponent = Ember.Component.extend - tagName: 'li' - classNameBindings: ['build.state'] - classNames: ['row-li', 'pr-row'] - - urlGithubCommit: (-> - githubCommitUrl(@get('build.repo.slug'), @get('build.commit.sha')) - ).property('build.commit.sha') - -`export default BuildsItemComponent` diff --git a/app/components/builds-item.js b/app/components/builds-item.js new file mode 100644 index 00000000..a55ccacc --- /dev/null +++ b/app/components/builds-item.js @@ -0,0 +1,12 @@ +import Ember from 'ember'; +import { githubCommit as githubCommitUrl } from 'travis/utils/urls'; + +export default Ember.Component.extend({ + tagName: 'li', + classNameBindings: ['build.state'], + classNames: ['row-li', 'pr-row'], + + urlGithubCommit: function() { + return githubCommitUrl(this.get('build.repo.slug'), this.get('build.commit.sha')); + }.property('build.commit.sha') +}); diff --git a/app/components/caches-item.coffee b/app/components/caches-item.coffee deleted file mode 100644 index 00c96a9a..00000000 --- a/app/components/caches-item.coffee +++ /dev/null @@ -1,27 +0,0 @@ -`import Ember from 'ember'` - -CachesItemComponent = Ember.Component.extend - ajax: Ember.inject.service() - - tagName: 'li' - classNames: ['cache-item'] - classNameBindings: ['cache.type'] - isDeleting: false - - actions: - delete: -> - return if @get('isDeleting') - - if confirm('Are you sure?') - @set('isDeleting', true) - - data = { branch: @get('cache.branch') } - - deletingDone = => @set('isDeleting', false) - - repo = @get('repo') - @get('ajax').ajax("/repos/#{repo.get('id')}/caches", "DELETE", data: data).then(deletingDone, deletingDone).then => - @get('caches').removeObject(@get('cache')) - - -`export default CachesItemComponent` diff --git a/app/components/caches-item.js b/app/components/caches-item.js new file mode 100644 index 00000000..41b33513 --- /dev/null +++ b/app/components/caches-item.js @@ -0,0 +1,33 @@ +import Ember from 'ember'; + +export default Ember.Component.extend({ + ajax: Ember.inject.service(), + tagName: 'li', + classNames: ['cache-item'], + classNameBindings: ['cache.type'], + isDeleting: false, + + actions: { + "delete": function() { + var data, deletingDone, repo; + if (this.get('isDeleting')) { + return; + } + if (confirm('Are you sure?')) { + this.set('isDeleting', true); + data = { + branch: this.get('cache.branch') + }; + deletingDone = () => { + return this.set('isDeleting', false); + }; + repo = this.get('repo'); + return this.get('ajax').ajax("/repos/" + (repo.get('id')) + "/caches", "DELETE", { + data: data + }).then(deletingDone, deletingDone).then(() => { + return this.get('caches').removeObject(this.get('cache')); + }); + } + } + } +}); diff --git a/app/components/code-climate-popup.coffee b/app/components/code-climate-popup.coffee deleted file mode 100644 index 206106e5..00000000 --- a/app/components/code-climate-popup.coffee +++ /dev/null @@ -1,10 +0,0 @@ -`import Ember from 'ember'` - -Component = Ember.Component.extend( - actions: - close: -> - $('.popup').removeClass('display') - return false -) - -`export default Component` diff --git a/app/components/code-climate-popup.js b/app/components/code-climate-popup.js new file mode 100644 index 00000000..c7d31f4c --- /dev/null +++ b/app/components/code-climate-popup.js @@ -0,0 +1,10 @@ +import Ember from 'ember'; + +export default Ember.Component.extend({ + actions: { + close() { + $('.popup').removeClass('display'); + return false; + } + } +}); diff --git a/app/components/dashboard-row.coffee b/app/components/dashboard-row.coffee deleted file mode 100644 index 62379a05..00000000 --- a/app/components/dashboard-row.coffee +++ /dev/null @@ -1,55 +0,0 @@ -`import Ember from 'ember'` -`import { githubCommit as githubCommitUrl } from 'travis/utils/urls'` -`import config from 'travis/config/environment'` - -DashboardRowComponent = Ember.Component.extend - - tagName: 'li' - classNameBindings: ['repo.default_branch.last_build.state'] - classNames: ['dashboard-row', 'row-li'] - isLoading: false - isTriggering: false - hasTriggered: false - - urlGithubCommit: (-> - githubCommitUrl(@get('repo.slug'), @get('repo.default_branch.last_build.commit.sha')) - ).property('repo') - - # canTrigger: (-> - # if !@get('auth.signedIn') - # false - # else - # permissions = @get('auth.currentUser.permissions') - # if permissions.contains parseInt(@get('build.repository.id')) - # true - # else - # false - # ).property() - - # triggerBuild: (-> - # apiEndpoint = config.apiEndpoint - # repoId = @get('build.repository.id') - # options = { - # type: 'POST', - # body: { - # request: { - # branch: @get('build.name') - # } - # } - # } - # if @get('auth.signedIn') - # options.headers = { Authorization: "token #{@auth.token()}" } - # $.ajax("#{apiEndpoint}/v3/repo/#{repoId}/requests", options).then (response) => - # @set('isTriggering', false) - # @set('hasTriggered', true) - # ) - - actions: - tiggerBuild: (branch) -> - @set('isTriggering', true) - @triggerBuild() - - # viewAllBuilds: (branch) -> - # @get('routing').transitionTo('builds') - -`export default DashboardRowComponent` diff --git a/app/components/dashboard-row.js b/app/components/dashboard-row.js new file mode 100644 index 00000000..49a010fa --- /dev/null +++ b/app/components/dashboard-row.js @@ -0,0 +1,23 @@ +import Ember from 'ember'; +import { githubCommit as githubCommitUrl } from 'travis/utils/urls'; +import config from 'travis/config/environment'; + +export default Ember.Component.extend({ + tagName: 'li', + classNameBindings: ['repo.default_branch.last_build.state'], + classNames: ['dashboard-row', 'row-li'], + isLoading: false, + isTriggering: false, + hasTriggered: false, + + urlGithubCommit: function() { + return githubCommitUrl(this.get('repo.slug'), this.get('repo.default_branch.last_build.commit.sha')); + }.property('repo'), + + actions: { + tiggerBuild(branch) { + this.set('isTriggering', true); + return this.triggerBuild(); + } + } +}); diff --git a/app/components/env-var.coffee b/app/components/env-var.coffee deleted file mode 100644 index 61acca7e..00000000 --- a/app/components/env-var.coffee +++ /dev/null @@ -1,29 +0,0 @@ -`import Ember from 'ember'` - -EnvVarComponent = Ember.Component.extend - - classNames: ['settings-envvar'] - classNameBindings: ['envVar.public:is-public'] - - isDeleting: false - - validates: - name: ['presence'] - - actionType: 'Save' - showValueField: Ember.computed.alias('public') - - value: ( (key, value) -> - if @get('envVar.public') - @get('envVar.value') - else - '••••••••••••••••' - ).property('envVar.value', 'envVar.public') - - actions: - delete: -> - return if @get('isDeleting') - @set('isDeleting', true) - @get('envVar').destroyRecord() - -`export default EnvVarComponent` diff --git a/app/components/env-var.js b/app/components/env-var.js new file mode 100644 index 00000000..92f935a6 --- /dev/null +++ b/app/components/env-var.js @@ -0,0 +1,28 @@ +import Ember from 'ember'; + +export default Ember.Component.extend({ + classNames: ['settings-envvar'], + classNameBindings: ['envVar.public:is-public'], + isDeleting: false, + validates: { name: ['presence'] }, + actionType: 'Save', + showValueField: Ember.computed.alias('public'), + + value: function(key, value) { + if (this.get('envVar.public')) { + return this.get('envVar.value'); + } else { + return '••••••••••••••••'; + } + }.property('envVar.value', 'envVar.public'), + + actions: { + "delete": function() { + if (this.get('isDeleting')) { + return; + } + this.set('isDeleting', true); + return this.get('envVar').destroyRecord(); + } + } +}); diff --git a/app/components/eye-icon.coffee b/app/components/eye-icon.coffee deleted file mode 100644 index 91740fd1..00000000 --- a/app/components/eye-icon.coffee +++ /dev/null @@ -1,8 +0,0 @@ -`import Ember from 'ember'` - -EyeIconComponent = Ember.Component.extend - - tagName: 'span' - classNames: ['icon-eye'] - -`export default EyeIconComponent` diff --git a/app/components/eye-icon.js b/app/components/eye-icon.js new file mode 100644 index 00000000..70be5027 --- /dev/null +++ b/app/components/eye-icon.js @@ -0,0 +1,6 @@ +import Ember from 'ember'; + +export default Ember.Component.extend({ + tagName: 'span', + classNames: ['icon-eye'] +}); diff --git a/app/components/flash-display.coffee b/app/components/flash-display.coffee deleted file mode 100644 index bb21f6a0..00000000 --- a/app/components/flash-display.coffee +++ /dev/null @@ -1,15 +0,0 @@ -`import Ember from 'ember'` - -FlashDisplayComponent = Ember.Component.extend - flashes: Ember.inject.service() - - classNames: ['flash'] - tagName: 'ul' - - messagesBinding: 'flashes.messages' - - actions: - closeMessage: (msg) -> - @get('flashes').close(msg) - -`export default FlashDisplayComponent` diff --git a/app/components/flash-display.js b/app/components/flash-display.js new file mode 100644 index 00000000..f7e6ba8c --- /dev/null +++ b/app/components/flash-display.js @@ -0,0 +1,14 @@ +import Ember from 'ember'; + +export default Ember.Component.extend({ + flashes: Ember.inject.service(), + classNames: ['flash'], + tagName: 'ul', + messagesBinding: 'flashes.messages', + + actions: { + closeMessage(msg) { + return this.get('flashes').close(msg); + } + } +}); diff --git a/app/components/flash-item.coffee b/app/components/flash-item.coffee deleted file mode 100644 index 5f6df701..00000000 --- a/app/components/flash-item.coffee +++ /dev/null @@ -1,15 +0,0 @@ -`import Ember from 'ember'` - -FlashItemComponent = Ember.Component.extend - tagName: 'li' - classNameBindings: ['type'] - - type: (-> - @get('flash.type') || 'broadcast' - ).property('flash.type') - - actions: - close: -> - this.attrs.close(@get('flash')) - -`export default FlashItemComponent` diff --git a/app/components/flash-item.js b/app/components/flash-item.js new file mode 100644 index 00000000..36dd9213 --- /dev/null +++ b/app/components/flash-item.js @@ -0,0 +1,16 @@ +import Ember from 'ember'; + +export default Ember.Component.extend({ + tagName: 'li', + classNameBindings: ['type'], + + type: function() { + return this.get('flash.type') || 'broadcast'; + }.property('flash.type'), + + actions: { + close() { + return this.attrs.close(this.get('flash')); + } + } +}); diff --git a/app/components/hook-switch.coffee b/app/components/hook-switch.coffee deleted file mode 100644 index 7f76944f..00000000 --- a/app/components/hook-switch.coffee +++ /dev/null @@ -1,18 +0,0 @@ -`import Ember from 'ember'` - -HookSwitchComponent = Ember.Component.extend - tagName: 'a' - classNames: ['switch--icon'] - classNameBindings: ['active'] - activeBinding: "hook.active" - - click: -> - @sendAction('onToggle') - hook = @get('hook') - hook.toggle().then( (->), => - @toggleProperty('hook.active') - @sendAction('onToggleError', hook) - ) - - -`export default HookSwitchComponent` diff --git a/app/components/hook-switch.js b/app/components/hook-switch.js new file mode 100644 index 00000000..dfcf61a8 --- /dev/null +++ b/app/components/hook-switch.js @@ -0,0 +1,17 @@ +import Ember from 'ember'; + +export default Ember.Component.extend({ + tagName: 'a', + classNames: ['switch--icon'], + classNameBindings: ['active'], + activeBinding: "hook.active", + click() { + var hook; + this.sendAction('onToggle'); + hook = this.get('hook'); + return hook.toggle().then((function() {}), () => { + this.toggleProperty('hook.active'); + return this.sendAction('onToggleError', hook); + }); + } +}); diff --git a/app/components/hooks-list-item.coffee b/app/components/hooks-list-item.coffee deleted file mode 100644 index f0f69e3e..00000000 --- a/app/components/hooks-list-item.coffee +++ /dev/null @@ -1,21 +0,0 @@ -`import Ember from 'ember'` -`import config from 'travis/config/environment'` - -HooksListItemComponent = Ember.Component.extend - tagName: 'li' - classNames: ['row'] - classNameBindings: ['hook.active:active'] - - githubOrgsOauthAccessSettingsUrl: config.githubOrgsOauthAccessSettingsUrl - - actions: - handleToggleError: -> - @set("showError", true) - - close: -> - @send('resetErrors') - - resetErrors: -> - @set("showError", false) - -`export default HooksListItemComponent` diff --git a/app/components/hooks-list-item.js b/app/components/hooks-list-item.js new file mode 100644 index 00000000..ecee5072 --- /dev/null +++ b/app/components/hooks-list-item.js @@ -0,0 +1,23 @@ +import Ember from 'ember'; +import config from 'travis/config/environment'; + +export default Ember.Component.extend({ + tagName: 'li', + classNames: ['row'], + classNameBindings: ['hook.active:active'], + githubOrgsOauthAccessSettingsUrl: config.githubOrgsOauthAccessSettingsUrl, + + actions: { + handleToggleError() { + return this.set("showError", true); + }, + + close() { + return this.send('resetErrors'); + }, + + resetErrors() { + return this.set("showError", false); + } + } +}); diff --git a/app/components/job-log.coffee b/app/components/job-log.coffee deleted file mode 100644 index 5adb3f97..00000000 --- a/app/components/job-log.coffee +++ /dev/null @@ -1,30 +0,0 @@ -`import Ember from 'ember'` - -JobLogComponent = Ember.Component.extend - logBinding: 'job.log' - - didInsertElement: -> - @setupLog() - - logDidChange: (-> - @setupLog() - ).observes('log') - - logWillChange: (-> - @teardownLog() - ).observesBefore('log') - - willDestroyElement: -> - @teardownLog() - - teardownLog: -> - job = @get('job') - job.unsubscribe() if job - - setupLog: -> - job = @get('job') - if job - job.get('log').fetch() - job.subscribe() - -`export default JobLogComponent` diff --git a/app/components/job-log.js b/app/components/job-log.js new file mode 100644 index 00000000..37f31999 --- /dev/null +++ b/app/components/job-log.js @@ -0,0 +1,38 @@ +import Ember from 'ember'; + +export default Ember.Component.extend({ + logBinding: 'job.log', + + didInsertElement() { + return this.setupLog(); + }, + + logDidChange: function() { + return this.setupLog(); + }.observes('log'), + + logWillChange: function() { + return this.teardownLog(); + }.observesBefore('log'), + + willDestroyElement() { + return this.teardownLog(); + }, + + teardownLog() { + var job; + job = this.get('job'); + if (job) { + return job.unsubscribe(); + } + }, + + setupLog() { + var job; + job = this.get('job'); + if (job) { + job.get('log').fetch(); + return job.subscribe(); + } + } +}); diff --git a/app/components/job-repo-actions.coffee b/app/components/job-repo-actions.coffee deleted file mode 100644 index 4b6deb59..00000000 --- a/app/components/job-repo-actions.coffee +++ /dev/null @@ -1,9 +0,0 @@ -`import Ember from 'ember'` -`import RepoActionsItemComponentMixin from 'travis/utils/repo-actions-item-component-mixin'` - -JobRepoActionsComponent = Ember.Component.extend(RepoActionsItemComponentMixin, - item: Ember.computed.alias('job') - type: 'job' -) - -`export default JobRepoActionsComponent` diff --git a/app/components/job-repo-actions.js b/app/components/job-repo-actions.js new file mode 100644 index 00000000..ae19bce0 --- /dev/null +++ b/app/components/job-repo-actions.js @@ -0,0 +1,7 @@ +import Ember from 'ember'; +import RepoActionsItemComponentMixin from 'travis/utils/repo-actions-item-component-mixin'; + +export default Ember.Component.extend(RepoActionsItemComponentMixin, { + item: Ember.computed.alias('job'), + type: 'job' +}); diff --git a/app/components/jobs-item.coffee b/app/components/jobs-item.coffee deleted file mode 100644 index 77bc96e2..00000000 --- a/app/components/jobs-item.coffee +++ /dev/null @@ -1,32 +0,0 @@ -`import Ember from 'ember'` -`import { colorForState } from 'travis/utils/helpers'` -`import { languageConfigKeys } from 'travis/utils/keys-map';` - -JobsItemComponent = Ember.Component.extend - tagName: 'li' - classNameBindings: ['job.state'] - classNames: ['jobs-item'] - - languages: (-> - output = [] - - if config = @get('job.config') - for key, languageName of languageConfigKeys - if version = config[key] - output.push(languageName + ': ' + version) - - gemfile = @get('job.config.gemfile') - if gemfile && @get('job.config.env') - output.push "Gemfile: #{gemfile}" - - output.join(' ') - ).property('job.config') - - environment: (-> - if env = @get('job.config.env') - env - else if gemfile = @get('job.config.gemfile') - "Gemfile: #{gemfile}" - ).property('job.config.env', 'job.config.gemfile') - -`export default JobsItemComponent` diff --git a/app/components/jobs-item.js b/app/components/jobs-item.js new file mode 100644 index 00000000..e2046e99 --- /dev/null +++ b/app/components/jobs-item.js @@ -0,0 +1,36 @@ +import Ember from 'ember'; +import { colorForState } from 'travis/utils/helpers'; +import { languageConfigKeys } from 'travis/utils/keys-map';; + +export default Ember.Component.extend({ + tagName: 'li', + classNameBindings: ['job.state'], + classNames: ['jobs-item'], + + languages: function() { + var config, gemfile, key, languageName, output, version; + output = []; + if (config = this.get('job.config')) { + for (key in languageConfigKeys) { + languageName = languageConfigKeys[key]; + if (version = config[key]) { + output.push(languageName + ': ' + version); + } + } + gemfile = this.get('job.config.gemfile'); + if (gemfile && this.get('job.config.env')) { + output.push("Gemfile: " + gemfile); + } + } + return output.join(' '); + }.property('job.config'), + + environment: function() { + var env, gemfile; + if (env = this.get('job.config.env')) { + return env; + } else if (gemfile = this.get('job.config.gemfile')) { + return "Gemfile: " + gemfile; + } + }.property('job.config.env', 'job.config.gemfile') +}); diff --git a/app/components/jobs-list.coffee b/app/components/jobs-list.coffee deleted file mode 100644 index 9ecf3b2b..00000000 --- a/app/components/jobs-list.coffee +++ /dev/null @@ -1,15 +0,0 @@ -`import Ember from 'ember'` - -JobsListComponent = Ember.Component.extend - - tagName: 'section' - classNames: ['jobs'] - - jobTableId: Ember.computed(-> - if @get('required') - 'jobs' - else - 'allowed_failure_jobs' - ) - -`export default JobsListComponent` diff --git a/app/components/jobs-list.js b/app/components/jobs-list.js new file mode 100644 index 00000000..4dbccd54 --- /dev/null +++ b/app/components/jobs-list.js @@ -0,0 +1,13 @@ +import Ember from 'ember'; + +export default Ember.Component.extend({ + tagName: 'section', + classNames: ['jobs'], + jobTableId: Ember.computed(function() { + if (this.get('required')) { + return 'jobs'; + } else { + return 'allowed_failure_jobs'; + } + }) +}); diff --git a/app/components/landing-row.coffee b/app/components/landing-row.coffee deleted file mode 100644 index cdc405a8..00000000 --- a/app/components/landing-row.coffee +++ /dev/null @@ -1,12 +0,0 @@ -`import Ember from 'ember'` -`import { githubCommit as githubCommitUrl } from 'travis/utils/urls'` -`import TravisRoute from 'travis/routes/basic'` -`import config from 'travis/config/environment'` - -LandingRowComponent = Ember.Component.extend - - tagName: 'li' - classNameBindings: ['repo.lastBuildState'] - classNames: ['landing-row', 'row-li'] - -`export default LandingRowComponent` diff --git a/app/components/landing-row.js b/app/components/landing-row.js new file mode 100644 index 00000000..87e7711b --- /dev/null +++ b/app/components/landing-row.js @@ -0,0 +1,10 @@ +import Ember from 'ember'; +import { githubCommit as githubCommitUrl } from 'travis/utils/urls'; +import TravisRoute from 'travis/routes/basic'; +import config from 'travis/config/environment'; + +export default Ember.Component.extend({ + tagName: 'li', + classNameBindings: ['repo.lastBuildState'], + classNames: ['landing-row', 'row-li'] +}); diff --git a/app/components/limit-concurrent-builds.coffee b/app/components/limit-concurrent-builds.coffee deleted file mode 100644 index 11ef37b9..00000000 --- a/app/components/limit-concurrent-builds.coffee +++ /dev/null @@ -1,40 +0,0 @@ -`import Ember from 'ember'` - -LimitConcurrentBuildsComponent = Ember.Component.extend - - classNames: ['limit-concurrent-builds'] - - description: (-> - description = "Limit concurrent jobs" - if @get('enabled') - description += " " - 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') - return if @get('value') == 0 - return if @get('isSaving') - @set('isSaving', true) - - savingFinished = => - @set('isSaving', false) - - @get('repo').saveSettings(maximum_number_of_builds: 0).then(savingFinished, savingFinished) - @set('value', 0) - - limitChanged: -> - Ember.run.debounce(this, 'limitChanged', 1000) - -`export default LimitConcurrentBuildsComponent` diff --git a/app/components/limit-concurrent-builds.js b/app/components/limit-concurrent-builds.js new file mode 100644 index 00000000..144e279e --- /dev/null +++ b/app/components/limit-concurrent-builds.js @@ -0,0 +1,55 @@ +import Ember from 'ember'; + +export default Ember.Component.extend({ + classNames: ['limit-concurrent-builds'], + + description: function() { + var description; + description = "Limit concurrent jobs"; + if (this.get('enabled')) { + description += " "; + } + return description; + }.property('enabled'), + + limitChanged() { + var limit, repo, savingFinished; + repo = this.get('repo'); + limit = parseInt(this.get('value')); + if (limit) { + this.set('isSaving', true); + savingFinished = () => { + return this.set('isSaving', false); + }; + return repo.saveSettings({ + maximum_number_of_builds: limit + }).then(savingFinished, savingFinished); + } + }, + + actions: { + toggle() { + var savingFinished; + if (!this.get('enabled')) { + if (this.get('value') === 0) { + return; + } + if (this.get('isSaving')) { + return; + } + this.set('isSaving', true); + savingFinished = () => { + return this.set('isSaving', false); + }; + this.get('repo').saveSettings({ + maximum_number_of_builds: 0 + }).then(savingFinished, savingFinished); + return this.set('value', 0); + } + }, + + limitChanged() { + return Ember.run.debounce(this, 'limitChanged', 1000); + } + } +}); diff --git a/app/components/loading-indicator.coffee b/app/components/loading-indicator.coffee deleted file mode 100644 index d4af3f17..00000000 --- a/app/components/loading-indicator.coffee +++ /dev/null @@ -1,8 +0,0 @@ -`import Ember from 'ember'` - -LoadingIndicatorComponent = Ember.Component.extend - tagName: 'div' - classNameBindings: ['center:loading-container', 'inline:inline-block', 'height:icon-height'] - center: false - -`export default LoadingIndicatorComponent` diff --git a/app/components/loading-indicator.js b/app/components/loading-indicator.js new file mode 100644 index 00000000..5c7950e3 --- /dev/null +++ b/app/components/loading-indicator.js @@ -0,0 +1,7 @@ +import Ember from 'ember'; + +export default Ember.Component.extend({ + tagName: 'div', + classNameBindings: ['center:loading-container', 'inline:inline-block', 'height:icon-height'], + center: false +}); diff --git a/app/components/log-content.js b/app/components/log-content.js index 367a7e1c..97cb14a1 100644 --- a/app/components/log-content.js +++ b/app/components/log-content.js @@ -9,12 +9,12 @@ Log.DEBUG = false; Log.LIMIT = 10000; Log.Scroll = function(options) { - options = options || {}; + options || (options = {}); this.beforeScroll = options.beforeScroll; return this; }; -Log.Scroll.prototype = $.extend(new Log.Listener(), { +Log.Scroll.prototype = $.extend(new Log.Listener, { insert: function(log, data, pos) { if (this.numbers) { this.tryScroll(); @@ -39,7 +39,7 @@ Log.Limit = function(max_lines, limitedLogCallback) { return this; }; -Log.Limit.prototype = Log.extend(new Log.Listener(), { +Log.Limit.prototype = Log.extend(new Log.Listener, { count: 0, insert: function(log, node, pos) { if (node.type === 'paragraph' && !node.hidden) { @@ -90,8 +90,8 @@ export default Ember.Component.extend({ if ((ref = this.lineSelector) != null) { ref.willDestroy(); } - if (logElement = this.$('#log')[0]) { - logElement.innerHTML = ''; + if (logElement = this.$('#log')) { + return logElement.empty(); } } }, @@ -99,8 +99,8 @@ export default Ember.Component.extend({ createEngine(log) { var logElement; if (log || (log = this.get('log'))) { - if (logElement = this.$('#log')[0]) { - logElement.innerHTML = ''; + if (logElement = this.$('#log')) { + logElement.empty(); } log.onClear(() => { this.teardownLog(); @@ -212,7 +212,7 @@ export default Ember.Component.extend({ toggleTailing() { Travis.tailing.toggle(); this.engine.autoCloseFold = !Travis.tailing.isActive(); - return false; + return event.preventDefault(); }, removeLogPopup() { diff --git a/app/components/no-builds.coffee b/app/components/no-builds.coffee deleted file mode 100644 index 66e72d8a..00000000 --- a/app/components/no-builds.coffee +++ /dev/null @@ -1,19 +0,0 @@ -`import Ember from 'ember'` -`import config from 'travis/config/environment'` - -NoBuildsComponent = Ember.Component.extend - actions: - triggerBuild: () -> - @set('isLoading', true) - apiEndpoint = config.apiEndpoint - $.ajax(apiEndpoint + "/v3/repo/#{@get('repo.repo.id')}/requests", { - headers: { - Authorization: 'token ' + @get('repo.auth') - }, - type: "POST" - }).then( => - @set('isLoading', false) - # @transitionToRoute('repo') - ); - -`export default NoBuildsComponent` diff --git a/app/components/no-builds.js b/app/components/no-builds.js new file mode 100644 index 00000000..e35bedbb --- /dev/null +++ b/app/components/no-builds.js @@ -0,0 +1,20 @@ +import Ember from 'ember'; +import config from 'travis/config/environment'; + +export default Ember.Component.extend({ + actions: { + triggerBuild() { + var apiEndpoint; + this.set('isLoading', true); + apiEndpoint = config.apiEndpoint; + return $.ajax(apiEndpoint + ("/v3/repo/" + (this.get('repo.repo.id')) + "/requests"), { + headers: { + Authorization: 'token ' + this.get('repo.auth') + }, + type: "POST" + }).then(() => { + return this.set('isLoading', false); + }); + } + } +}); diff --git a/app/components/no-repos.coffee b/app/components/no-repos.coffee deleted file mode 100644 index 92130ae7..00000000 --- a/app/components/no-repos.coffee +++ /dev/null @@ -1,5 +0,0 @@ -`import Ember from 'ember'` - -NoReposComponent = Ember.Component.extend() - -`export default NoReposComponent` diff --git a/app/components/no-repos.js b/app/components/no-repos.js new file mode 100644 index 00000000..a3e1d832 --- /dev/null +++ b/app/components/no-repos.js @@ -0,0 +1,3 @@ +import Ember from 'ember'; + +export default Ember.Component.extend(); diff --git a/app/components/not-active.coffee b/app/components/not-active.coffee deleted file mode 100644 index f535d7f6..00000000 --- a/app/components/not-active.coffee +++ /dev/null @@ -1,5 +0,0 @@ -`import Ember from 'ember'` - -NotActiveComponent = Ember.Component.extend() - -`export default NotActiveComponent` diff --git a/app/components/not-active.js b/app/components/not-active.js new file mode 100644 index 00000000..a3e1d832 --- /dev/null +++ b/app/components/not-active.js @@ -0,0 +1,3 @@ +import Ember from 'ember'; + +export default Ember.Component.extend(); diff --git a/app/components/org-item.coffee b/app/components/org-item.coffee deleted file mode 100644 index 64233d3e..00000000 --- a/app/components/org-item.coffee +++ /dev/null @@ -1,28 +0,0 @@ -`import Ember from 'ember'` - -OrgItemComponent = Ember.Component.extend - - classNames: ['media', 'account'] - tagName: 'li' - classNameBindings: ['type', 'selected'] - typeBinding: 'account.type' - selectedBinding: 'account.selected' - tokenIsVisible: false - - name: (-> - @get('account.name') || @get('account.login') - ).property('account') - - avatarUrl: (-> - @get('account.avatarUrl') || false - ).property('account') - - isUser: (-> - @get('account.type') == 'user' - ).property('account') - - actions: - tokenVisibility: () -> - @toggleProperty('tokenIsVisible') - -`export default OrgItemComponent` diff --git a/app/components/org-item.js b/app/components/org-item.js new file mode 100644 index 00000000..d782e04b --- /dev/null +++ b/app/components/org-item.js @@ -0,0 +1,28 @@ +import Ember from 'ember'; + +export default Ember.Component.extend({ + classNames: ['media', 'account'], + tagName: 'li', + classNameBindings: ['type', 'selected'], + typeBinding: 'account.type', + selectedBinding: 'account.selected', + tokenIsVisible: false, + + name: function() { + return this.get('account.name') || this.get('account.login'); + }.property('account'), + + avatarUrl: function() { + return this.get('account.avatarUrl') || false; + }.property('account'), + + isUser: function() { + return this.get('account.type') === 'user'; + }.property('account'), + + actions: { + tokenVisibility() { + return this.toggleProperty('tokenIsVisible'); + } + } +}); diff --git a/app/components/orgs-filter.coffee b/app/components/orgs-filter.coffee deleted file mode 100644 index 037e4c64..00000000 --- a/app/components/orgs-filter.coffee +++ /dev/null @@ -1,13 +0,0 @@ -`import Ember from 'ember'` - -Component = Ember.Component.extend - - actions: - toggleOrgFilter: () -> - @toggleProperty('showFilter') - false - select: (org) -> - @toggleProperty('showFilter') - @sendAction('action', org) - -`export default Component` diff --git a/app/components/orgs-filter.js b/app/components/orgs-filter.js new file mode 100644 index 00000000..7434cefe --- /dev/null +++ b/app/components/orgs-filter.js @@ -0,0 +1,15 @@ +import Ember from 'ember'; + +export default Ember.Component.extend({ + actions: { + toggleOrgFilter() { + this.toggleProperty('showFilter'); + return false; + }, + + select(org) { + this.toggleProperty('showFilter'); + return this.sendAction('action', org); + } + } +}); diff --git a/app/components/owner-repo-tile.coffee b/app/components/owner-repo-tile.coffee deleted file mode 100644 index d98020a1..00000000 --- a/app/components/owner-repo-tile.coffee +++ /dev/null @@ -1,29 +0,0 @@ -`import Ember from 'ember'` - -OwnerRepoTileComponent = Ember.Component.extend - - tagName: 'li' - classNames: ['owner-tile', 'row-li'] - classNameBindings: ['repo.default_branch.last_build.state'] - - ownerName: (-> - @get('repo.slug').split(/\//)[0] - ).property('repo.slug') - - repoName: (-> - @get('repo.slug').split(/\//)[1] - ).property('repo.slug') - - isAnimating: (-> - state = @get('repo.default_branch.last_build.state') - animationStates = ['received', 'queued', 'started', 'booting'] - - unless animationStates.indexOf(state) == -1 - true - - ).property('repo.default_branch.last_build.state') - - - - -`export default OwnerRepoTileComponent` diff --git a/app/components/owner-repo-tile.js b/app/components/owner-repo-tile.js new file mode 100644 index 00000000..63cab400 --- /dev/null +++ b/app/components/owner-repo-tile.js @@ -0,0 +1,24 @@ +import Ember from 'ember'; + +export default Ember.Component.extend({ + tagName: 'li', + classNames: ['owner-tile', 'row-li'], + classNameBindings: ['repo.default_branch.last_build.state'], + + ownerName: function() { + return this.get('repo.slug').split(/\//)[0]; + }.property('repo.slug'), + + repoName: function() { + return this.get('repo.slug').split(/\//)[1]; + }.property('repo.slug'), + + isAnimating: function() { + var animationStates, state; + state = this.get('repo.default_branch.last_build.state'); + animationStates = ['received', 'queued', 'started', 'booting']; + if (animationStates.indexOf(state) !== -1) { + return true; + } + }.property('repo.default_branch.last_build.state') +}); diff --git a/app/components/owner-sync-button.coffee b/app/components/owner-sync-button.coffee deleted file mode 100644 index bfe0bd2d..00000000 --- a/app/components/owner-sync-button.coffee +++ /dev/null @@ -1,6 +0,0 @@ -`import Ember from 'ember'` -`import SyncButton from 'travis/components/sync-button'` - -Component = SyncButton.extend() - -`export default Component` diff --git a/app/components/owner-sync-button.js b/app/components/owner-sync-button.js new file mode 100644 index 00000000..842e2c69 --- /dev/null +++ b/app/components/owner-sync-button.js @@ -0,0 +1,4 @@ +import Ember from 'ember'; +import SyncButton from 'travis/components/sync-button'; + +export default SyncButton.extend(); diff --git a/app/components/queued-jobs.coffee b/app/components/queued-jobs.coffee deleted file mode 100644 index dfea033e..00000000 --- a/app/components/queued-jobs.coffee +++ /dev/null @@ -1,16 +0,0 @@ -`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/queued-jobs.js b/app/components/queued-jobs.js new file mode 100644 index 00000000..633900f5 --- /dev/null +++ b/app/components/queued-jobs.js @@ -0,0 +1,21 @@ +import Ember from 'ember'; +import config from 'travis/config/environment'; + +export default Ember.Component.extend({ + store: Ember.inject.service(), + init() { + this._super.apply(this, arguments); + if (!Ember.testing) { + return Visibility.every(config.intervals.updateTimes, this.updateTimes.bind(this)); + } + }, + + updateTimes() { + var jobs; + if (jobs = this.get('jobs')) { + return jobs.forEach(function(job) { + return job.updateTimes(); + }); + } + } +}); diff --git a/app/components/remove-log-popup.coffee b/app/components/remove-log-popup.coffee deleted file mode 100644 index 4ec49473..00000000 --- a/app/components/remove-log-popup.coffee +++ /dev/null @@ -1,23 +0,0 @@ -`import Ember from 'ember'` - -Component = Ember.Component.extend( - actions: - close: -> - $('.popup').removeClass('display') - return false - - removeLog: -> - $('.popup').removeClass('display') - job = @get('job') - job.removeLog().then -> - Travis.flash(success: 'Log has been successfully removed.') - , (xhr) -> - if xhr.status == 409 - Travis.flash(error: 'Log can\'t be removed') - else if xhr.status == 401 - Travis.flash(error: 'You don\'t have sufficient access to remove the log') - else - Travis.flash(error: 'An error occured when removing the log') -) - -`export default Component` diff --git a/app/components/remove-log-popup.js b/app/components/remove-log-popup.js new file mode 100644 index 00000000..f997fb6f --- /dev/null +++ b/app/components/remove-log-popup.js @@ -0,0 +1,27 @@ +import Ember from 'ember'; + +export default Ember.Component.extend({ + actions: { + close() { + $('.popup').removeClass('display'); + return false; + }, + + removeLog() { + var job = this.get('job'); + $('.popup').removeClass('display'); + + return job.removeLog().then(function() { + return Travis.flash({ success: 'Log has been successfully removed.' }); + }, function(xhr) { + if (xhr.status === 409) { + return Travis.flash({ error: 'Log can\'t be removed' }); + } else if (xhr.status === 401) { + return Travis.flash({ error: 'You don\'t have sufficient access to remove the log' }); + } else { + return Travis.flash({ error: 'An error occured when removing the log' }); + } + }); + } + } +}); diff --git a/app/components/repo-actions.coffee b/app/components/repo-actions.coffee deleted file mode 100644 index 43d38649..00000000 --- a/app/components/repo-actions.coffee +++ /dev/null @@ -1,15 +0,0 @@ -`import Ember from 'ember'` - -RepoActionsComponent = Ember.Component.extend( - displayCodeClimate: (-> - @get('repo.githubLanguage') == 'Ruby' - ).property('repo.githubLanguage') - - actions: - codeClimatePopup: -> - $('.popup').removeClass('display') - $('#code-climate').addClass('display') - return false -) - -`export default RepoActionsComponent` diff --git a/app/components/repo-actions.js b/app/components/repo-actions.js new file mode 100644 index 00000000..58400fac --- /dev/null +++ b/app/components/repo-actions.js @@ -0,0 +1,15 @@ +import Ember from 'ember'; + +export default Ember.Component.extend({ + displayCodeClimate: function() { + return this.get('repo.githubLanguage') === 'Ruby'; + }.property('repo.githubLanguage'), + + actions: { + codeClimatePopup() { + $('.popup').removeClass('display'); + $('#code-climate').addClass('display'); + return false; + } + } +}); diff --git a/app/components/repo-show-tabs.coffee b/app/components/repo-show-tabs.coffee deleted file mode 100644 index f6a9a446..00000000 --- a/app/components/repo-show-tabs.coffee +++ /dev/null @@ -1,55 +0,0 @@ -`import Ember from 'ember'` - -RepoShowTabsComponent = Ember.Component.extend - - tagName: 'nav' - classNames: ['tabnav'] - ariaRole: 'tablist' - - # 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') - - 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-tabs.js b/app/components/repo-show-tabs.js new file mode 100644 index 00000000..72225f74 --- /dev/null +++ b/app/components/repo-show-tabs.js @@ -0,0 +1,74 @@ +import Ember from 'ember'; + +export default Ember.Component.extend({ + tagName: 'nav', + classNames: ['tabnav'], + ariaRole: 'tablist', + + classCurrent: function() { + if (this.get('tab') === 'current') { + return 'active'; + } + }.property('tab'), + + classBuilds: function() { + if (this.get('tab') === 'builds') { + return 'active'; + } + }.property('tab'), + + classPullRequests: function() { + if (this.get('tab') === 'pull_requests') { + return 'active'; + } + }.property('tab'), + + classBranches: function() { + if (this.get('tab') === 'branches') { + return 'active'; + } + }.property('tab'), + + classBuild: function() { + var classes, tab; + tab = this.get('tab'); + classes = []; + if (tab === 'build') { + classes.push('active'); + } + if (tab === 'build' || tab === 'job') { + classes.push('display-inline'); + } + return classes.join(' '); + }.property('tab'), + + classJob: function() { + if (this.get('tab') === 'job') { + return 'active'; + } + }.property('tab'), + + classRequests: function() { + if (this.get('tab') === 'requests') { + return 'active'; + } + }.property('tab'), + + classCaches: function() { + if (this.get('tab') === 'caches') { + return 'active'; + } + }.property('tab'), + + classSettings: function() { + if (this.get('tab') === 'settings') { + return 'active'; + } + }.property('tab'), + + classRequest: function() { + if (this.get('tab') === 'request') { + return 'active'; + } + }.property('tab') +}); diff --git a/app/components/repo-show-tools.coffee b/app/components/repo-show-tools.coffee deleted file mode 100644 index dd056154..00000000 --- a/app/components/repo-show-tools.coffee +++ /dev/null @@ -1,49 +0,0 @@ -`import Ember from 'ember'` -`import config from 'travis/config/environment'` - -RepoShowToolsComponent = Ember.Component.extend - popup: Ember.inject.service() - - classNames: ['settings-menu'] - classNameBindings: ['isOpen:display'] - isOpen: false - - click: (event) -> - if $(event.target).is('a') && $(event.target).parents('.settings-dropdown').length - @closeMenu() - - closeMenu: -> - @toggleProperty('isOpen') - - actions: - menu: -> - @toggleProperty('isOpen') - - 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/repo-show-tools.js b/app/components/repo-show-tools.js new file mode 100644 index 00000000..bc7e0fef --- /dev/null +++ b/app/components/repo-show-tools.js @@ -0,0 +1,58 @@ +import Ember from 'ember'; +import config from 'travis/config/environment'; + +export default Ember.Component.extend({ + popup: Ember.inject.service(), + classNames: ['settings-menu'], + classNameBindings: ['isOpen:display'], + isOpen: false, + + click(event) { + if ($(event.target).is('a') && $(event.target).parents('.settings-dropdown').length) { + return this.closeMenu(); + } + }, + + closeMenu() { + return this.toggleProperty('isOpen'); + }, + + actions: { + menu() { + return this.toggleProperty('isOpen'); + } + }, + + hasPermission: function() { + var permissions; + if (permissions = this.get('currentUser.permissions')) { + return permissions.contains(parseInt(this.get('repo.id'))); + } + }.property('currentUser.permissions.length', 'repo.id'), + + hasPushPermission: function() { + var permissions; + if (permissions = this.get('currentUser.pushPermissions')) { + return permissions.contains(parseInt(this.get('repo.id'))); + } + }.property('currentUser.pushPermissions.length', 'repo.id'), + + hasAdminPermission: function() { + var permissions; + if (permissions = this.get('currentUser.adminPermissions')) { + return permissions.contains(parseInt(this.get('repo.id'))); + } + }.property('currentUser.adminPermissions.length', 'repo.id'), + + displaySettingsLink: function() { + return this.get('hasPushPermission'); + }.property('hasPushPermission'), + + displayCachesLink: function() { + return this.get('hasPushPermission') && config.endpoints.caches; + }.property('hasPushPermission'), + + displayStatusImages: function() { + return this.get('hasPermission'); + }.property('hasPermission') +}); diff --git a/app/components/repos-empty.coffee b/app/components/repos-empty.coffee deleted file mode 100644 index 345de82e..00000000 --- a/app/components/repos-empty.coffee +++ /dev/null @@ -1,5 +0,0 @@ -`import Ember from 'ember'` - -ReposEmptyComponent = Ember.Component.extend() - -`export default ReposEmptyComponent` diff --git a/app/components/repos-empty.js b/app/components/repos-empty.js new file mode 100644 index 00000000..a3e1d832 --- /dev/null +++ b/app/components/repos-empty.js @@ -0,0 +1,3 @@ +import Ember from 'ember'; + +export default Ember.Component.extend(); diff --git a/app/components/repos-list-item.coffee b/app/components/repos-list-item.coffee deleted file mode 100644 index ef664690..00000000 --- a/app/components/repos-list-item.coffee +++ /dev/null @@ -1,31 +0,0 @@ -`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: ['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-item.js b/app/components/repos-list-item.js new file mode 100644 index 00000000..89b777d2 --- /dev/null +++ b/app/components/repos-list-item.js @@ -0,0 +1,32 @@ +import Ember from 'ember'; +import Polling from 'travis/mixins/polling'; +import { colorForState } from 'travis/utils/helpers'; + +export default Ember.Component.extend(Polling, { + routing: Ember.inject.service('-routing'), + tagName: 'li', + pollModels: 'repo', + classNames: ['repo'], + classNameBindings: ['selected'], + + selected: function() { + return this.get('repo') === this.get('selectedRepo'); + }.property('selectedRepo'), + + color: function() { + return colorForState(this.get('repo.lastBuildState')); + }.property('repo.lastBuildState'), + + scrollTop: function() { + if (window.scrollY > 0) { + return $('html, body').animate({ + scrollTop: 0 + }, 200); + } + }, + + click() { + this.scrollTop(); + return this.get('routing').transitionTo('repo', this.get('repo.slug').split('/')); + } +}); diff --git a/app/components/request-icon.coffee b/app/components/request-icon.coffee deleted file mode 100644 index 1ac50c88..00000000 --- a/app/components/request-icon.coffee +++ /dev/null @@ -1,25 +0,0 @@ -`import Ember from 'ember'` - -RequestIconComponent = Ember.Component.extend - - tagName: 'span' - classNames: ['status-icon', 'icon'] - classNameBindings: ['event', 'state'] - - isPush: (-> - @get('event') == 'push' - ).property('event') - - isPR: (-> - @get('event') == 'pull_request' - ).property('event') - - isAPI: (-> - @get('event') == 'api' - ).property('event') - - isEmpty: (-> - true if @get('event') == null || @get('event') == null - ).property('event') - -`export default RequestIconComponent` diff --git a/app/components/request-icon.js b/app/components/request-icon.js new file mode 100644 index 00000000..ac668b0d --- /dev/null +++ b/app/components/request-icon.js @@ -0,0 +1,25 @@ +import Ember from 'ember'; + +export default Ember.Component.extend({ + tagName: 'span', + classNames: ['status-icon', 'icon'], + classNameBindings: ['event', 'state'], + + isPush: function() { + return this.get('event') === 'push'; + }.property('event'), + + isPR: function() { + return this.get('event') === 'pull_request'; + }.property('event'), + + isAPI: function() { + return this.get('event') === 'api'; + }.property('event'), + + isEmpty: function() { + if (this.get('event') === null || this.get('event') === null) { + return true; + } + }.property('event') +}); diff --git a/app/components/requests-item.coffee b/app/components/requests-item.coffee deleted file mode 100644 index c0a4382f..00000000 --- a/app/components/requests-item.coffee +++ /dev/null @@ -1,45 +0,0 @@ -`import Ember from 'ember'` -`import config from 'travis/config/environment'` - -RequestsItemComponent = Ember.Component.extend - classNames: ['request-item'] - classNameBindings: ['requestClass'] - tagName: 'li' - - requestClass: (-> - if @get('request.isAccepted') - 'accepted' - else - 'rejected' - ).property('content.isAccepted') - - type: (-> - if @get('request.isPullRequest') - 'pull_request' - else - 'push' - ).property('request.isPullRequest') - - status: (-> - if @get('request.isAccepted') - 'Accepted' - else - 'Rejected' - ).property('request.isAccepted') - - hasBranchName: (-> - @get('request.branchName') - ).property('request') - - message: (-> - message = @get('request.message') - if config.pro && message == "private repository" - '' - else if !message - 'Build created successfully ' - else - message - ).property('request.message') - - -`export default RequestsItemComponent` diff --git a/app/components/requests-item.js b/app/components/requests-item.js new file mode 100644 index 00000000..ef7a61ca --- /dev/null +++ b/app/components/requests-item.js @@ -0,0 +1,48 @@ +import Ember from 'ember'; +import config from 'travis/config/environment'; + +export default Ember.Component.extend({ + classNames: ['request-item'], + classNameBindings: ['requestClass'], + tagName: 'li', + + requestClass: function() { + if (this.get('request.isAccepted')) { + return 'accepted'; + } else { + return 'rejected'; + } + }.property('content.isAccepted'), + + type: function() { + if (this.get('request.isPullRequest')) { + return 'pull_request'; + } else { + return 'push'; + } + }.property('request.isPullRequest'), + + status: function() { + if (this.get('request.isAccepted')) { + return 'Accepted'; + } else { + return 'Rejected'; + } + }.property('request.isAccepted'), + + hasBranchName: function() { + return this.get('request.branchName'); + }.property('request'), + + message: function() { + var message; + message = this.get('request.message'); + if (config.pro && message === "private repository") { + return ''; + } else if (!message) { + return 'Build created successfully '; + } else { + return message; + } + }.property('request.message') +}); diff --git a/app/components/running-jobs-item.coffee b/app/components/running-jobs-item.coffee deleted file mode 100644 index fb5fe7c7..00000000 --- a/app/components/running-jobs-item.coffee +++ /dev/null @@ -1,8 +0,0 @@ -`import Ember from 'ember'` -`import Polling from 'travis/mixins/polling'` - -RunningJobsItemComponent = Ember.Component.extend(Polling, - pollModels: 'job' -) - -`export default RunningJobsItemComponent` diff --git a/app/components/running-jobs-item.js b/app/components/running-jobs-item.js new file mode 100644 index 00000000..83bd5819 --- /dev/null +++ b/app/components/running-jobs-item.js @@ -0,0 +1,6 @@ +import Ember from 'ember'; +import Polling from 'travis/mixins/polling'; + +export default Ember.Component.extend(Polling, { + pollModels: 'job' +}); diff --git a/app/components/running-jobs.coffee b/app/components/running-jobs.coffee deleted file mode 100644 index 3e97c933..00000000 --- a/app/components/running-jobs.coffee +++ /dev/null @@ -1,20 +0,0 @@ -`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/components/running-jobs.js b/app/components/running-jobs.js new file mode 100644 index 00000000..68a8ebe5 --- /dev/null +++ b/app/components/running-jobs.js @@ -0,0 +1,27 @@ +import Ember from 'ember'; +import Polling from 'travis/mixins/polling'; +import config from 'travis/config/environment'; + +export default Ember.Component.extend(Polling, { + store: Ember.inject.service(), + + pollHook(store) { + return this.get('store').find('job', {}); + }, + + init() { + this._super.apply(this, arguments); + if (!Ember.testing) { + return Visibility.every(config.intervals.updateTimes, this.updateTimes.bind(this)); + } + }, + + updateTimes() { + var jobs; + if (jobs = this.get('jobs')) { + return jobs.forEach(function(job) { + return job.updateTimes(); + }); + } + } +}); diff --git a/app/components/settings-switch.coffee b/app/components/settings-switch.coffee deleted file mode 100644 index 53677cce..00000000 --- a/app/components/settings-switch.coffee +++ /dev/null @@ -1,21 +0,0 @@ -`import Ember from 'ember'` - -SettingsSwitchComponent = Ember.Component.extend - - tagName: 'a' - classNames: ['switch'] - classNameBindings: ['active'] - - click: -> - return if @get('isSaving') - @set('isSaving', true) - @toggleProperty('active') - setting = {} - setting[@get('key')] = @get('active') - @get('repo').saveSettings(setting).then => - @set('isSaving', false) - , => - @set('isSaving', false) - Travis.flash(error: 'There was an error while saving settings. Please try again.') - -`export default SettingsSwitchComponent` diff --git a/app/components/settings-switch.js b/app/components/settings-switch.js new file mode 100644 index 00000000..6daefddf --- /dev/null +++ b/app/components/settings-switch.js @@ -0,0 +1,26 @@ +import Ember from 'ember'; + +export default Ember.Component.extend({ + tagName: 'a', + classNames: ['switch'], + classNameBindings: ['active'], + + click() { + var setting; + if (this.get('isSaving')) { + return; + } + this.set('isSaving', true); + this.toggleProperty('active'); + setting = {}; + setting[this.get('key')] = this.get('active'); + return this.get('repo').saveSettings(setting).then(() => { + return this.set('isSaving', false); + }, () => { + this.set('isSaving', false); + return Travis.flash({ + error: 'There was an error while saving settings. Please try again.' + }); + }); + } +}); diff --git a/app/components/show-more-button.coffee b/app/components/show-more-button.coffee deleted file mode 100644 index 744110ae..00000000 --- a/app/components/show-more-button.coffee +++ /dev/null @@ -1,19 +0,0 @@ -`import Ember from 'ember'` - -ShowMoreButtonComponent = Ember.Component.extend - tagName: 'button' - classNames: ['showmore-button'] - classNameBindings: ['isLoading', 'showMore'] - showMore: true - attributeBindings: ['disabled'] - - disabledBinding: 'isLoading' - - buttonLabel: (-> - if @get('isLoading') then 'Loading' else 'Show more' - ).property('isLoading') - - click: -> - this.attrs.showMore() - -`export default ShowMoreButtonComponent` diff --git a/app/components/show-more-button.js b/app/components/show-more-button.js new file mode 100644 index 00000000..4c81ae9a --- /dev/null +++ b/app/components/show-more-button.js @@ -0,0 +1,22 @@ +import Ember from 'ember'; + +export default Ember.Component.extend({ + tagName: 'button', + classNames: ['showmore-button'], + classNameBindings: ['isLoading', 'showMore'], + showMore: true, + attributeBindings: ['disabled'], + disabledBinding: 'isLoading', + + buttonLabel: function() { + if (this.get('isLoading')) { + return 'Loading'; + } else { + return 'Show more'; + } + }.property('isLoading'), + + click() { + return this.attrs.showMore(); + } +}); diff --git a/app/components/ssh-key.coffee b/app/components/ssh-key.coffee deleted file mode 100644 index d17b3a03..00000000 --- a/app/components/ssh-key.coffee +++ /dev/null @@ -1,20 +0,0 @@ -`import Ember from 'ember'` - -SshKeyComponent = Ember.Component.extend - - classNames: ['settings-sshkey'] - - isDeleting: false - - actions: - delete: -> - return if @get('isDeleting') - @set('isDeleting', true) - - deletingDone = => @set('isDeleting', false) - - @get('key').deleteRecord() - @get('key').save().then(deletingDone, deletingDone).then => - @sendAction('sshKeyDeleted') - -`export default SshKeyComponent` diff --git a/app/components/ssh-key.js b/app/components/ssh-key.js new file mode 100644 index 00000000..d2126818 --- /dev/null +++ b/app/components/ssh-key.js @@ -0,0 +1,22 @@ +import Ember from 'ember'; + +export default Ember.Component.extend({ + classNames: ['settings-sshkey'], + isDeleting: false, + actions: { + "delete": function() { + var deletingDone; + if (this.get('isDeleting')) { + return; + } + this.set('isDeleting', true); + deletingDone = () => { + return this.set('isDeleting', false); + }; + this.get('key').deleteRecord(); + return this.get('key').save().then(deletingDone, deletingDone).then(() => { + return this.sendAction('sshKeyDeleted'); + }); + } + } +}); diff --git a/app/components/status-icon.coffee b/app/components/status-icon.coffee deleted file mode 100644 index 0a28162b..00000000 --- a/app/components/status-icon.coffee +++ /dev/null @@ -1,44 +0,0 @@ -`import Ember from 'ember'` - -StatusIconComponent = Ember.Component.extend - - tagName: 'span' - classNames: ['status-icon', 'icon'] - classNameBindings: ['status'] - - hasPassed: (-> - @get('status') == 'passed' || @get('status') == 'accepted' - ).property('status') - - hasFailed: (-> - @get('status') == 'failed' || @get('status') == 'rejected' - ).property('status') - - hasErrored: (-> - @get('status') == 'errored' - ).property('status') - - wasCanceled: (-> - @get('status') == 'canceled' - ).property('status') - - isRunning: (-> - @get('status') == 'started' || - @get('status') == 'queued' || - @get('status') == 'booting' || - @get('status') == 'received' || - @get('status') == 'created' - ).property('status') - - isEmpty: (-> - unless @get('status') - true - else - if @get('status') == '' - true - else - false - - ).property('status') - -`export default StatusIconComponent` diff --git a/app/components/status-icon.js b/app/components/status-icon.js new file mode 100644 index 00000000..6fee56d5 --- /dev/null +++ b/app/components/status-icon.js @@ -0,0 +1,39 @@ +import Ember from 'ember'; + +export default Ember.Component.extend({ + tagName: 'span', + classNames: ['status-icon', 'icon'], + classNameBindings: ['status'], + + hasPassed: function() { + return this.get('status') === 'passed' || this.get('status') === 'accepted'; + }.property('status'), + + hasFailed: function() { + return this.get('status') === 'failed' || this.get('status') === 'rejected'; + }.property('status'), + + hasErrored: function() { + return this.get('status') === 'errored'; + }.property('status'), + + wasCanceled: function() { + return this.get('status') === 'canceled'; + }.property('status'), + + isRunning: function() { + return this.get('status') === 'started' || this.get('status') === 'queued' || this.get('status') === 'booting' || this.get('status') === 'received' || this.get('status') === 'created'; + }.property('status'), + + isEmpty: function() { + if (!this.get('status')) { + return true; + } else { + if (this.get('status') === '') { + return true; + } else { + return false; + } + } + }.property('status') +}); diff --git a/app/components/subscribe-button.coffee b/app/components/subscribe-button.coffee deleted file mode 100644 index cc808ff4..00000000 --- a/app/components/subscribe-button.coffee +++ /dev/null @@ -1,8 +0,0 @@ -`import Ember from 'ember'` -`import config from 'travis/config/environment'` - -SubscribeButtonComponent = Ember.Component.extend - - classNames: ['cta-btn'] - -`export default SubscribeButtonComponent` diff --git a/app/components/subscribe-button.js b/app/components/subscribe-button.js new file mode 100644 index 00000000..28f2e844 --- /dev/null +++ b/app/components/subscribe-button.js @@ -0,0 +1,6 @@ +import Ember from 'ember'; +import config from 'travis/config/environment'; + +export default Ember.Component.extend({ + classNames: ['cta-btn'] +}); diff --git a/app/components/sync-button.coffee b/app/components/sync-button.coffee deleted file mode 100644 index 26825fb2..00000000 --- a/app/components/sync-button.coffee +++ /dev/null @@ -1,11 +0,0 @@ -`import Ember from 'ember'` - -Component = Ember.Component.extend - - classNames: ["sync-button"] - actions: { - sync: -> - @get('user').sync() - } - -`export default Component` diff --git a/app/components/sync-button.js b/app/components/sync-button.js new file mode 100644 index 00000000..75d83481 --- /dev/null +++ b/app/components/sync-button.js @@ -0,0 +1,10 @@ +import Ember from 'ember'; + +export default Ember.Component.extend({ + classNames: ["sync-button"], + actions: { + sync() { + return this.get('user').sync(); + } + } +}); diff --git a/app/components/team-member.coffee b/app/components/team-member.coffee deleted file mode 100644 index ced58d7c..00000000 --- a/app/components/team-member.coffee +++ /dev/null @@ -1,8 +0,0 @@ -`import Ember from 'ember'` - -TeamMemberComponent = Ember.Component.extend - - tagName: 'li' - classNames: ['team-member'] - -`export default TeamMemberComponent` diff --git a/app/components/team-member.js b/app/components/team-member.js new file mode 100644 index 00000000..efc9fd32 --- /dev/null +++ b/app/components/team-member.js @@ -0,0 +1,6 @@ +import Ember from 'ember'; + +export default Ember.Component.extend({ + tagName: 'li', + classNames: ['team-member'] +}); diff --git a/app/components/travis-status.coffee b/app/components/travis-status.coffee deleted file mode 100644 index 29269e19..00000000 --- a/app/components/travis-status.coffee +++ /dev/null @@ -1,21 +0,0 @@ -`import Ember from 'ember'` -`import config from 'travis/config/environment'` - -TravisStatusComponent = Ember.Component.extend - status: null - - statusPageStatusUrl: (-> - config.statusPageStatusUrl - ).property() - - didInsertElement: -> - if url = @get('statusPageStatusUrl') - self = this - @getStatus(url).then (response) -> - if response.status and response.status.indicator - self.set('status', response.status.indicator) - - getStatus: (url) -> - $.ajax(url) - -`export default TravisStatusComponent` diff --git a/app/components/travis-status.js b/app/components/travis-status.js new file mode 100644 index 00000000..b4708335 --- /dev/null +++ b/app/components/travis-status.js @@ -0,0 +1,26 @@ +import Ember from 'ember'; +import config from 'travis/config/environment'; + +export default Ember.Component.extend({ + status: null, + + statusPageStatusUrl: function() { + return config.statusPageStatusUrl; + }.property(), + + didInsertElement() { + var self, url; + if (url = this.get('statusPageStatusUrl')) { + self = this; + return this.getStatus(url).then(function(response) { + if (response.status && response.status.indicator) { + return self.set('status', response.status.indicator); + } + }); + } + }, + + getStatus(url) { + return $.ajax(url); + } +}); diff --git a/app/components/travis-switch.coffee b/app/components/travis-switch.coffee deleted file mode 100644 index 2f990612..00000000 --- a/app/components/travis-switch.coffee +++ /dev/null @@ -1,25 +0,0 @@ -`import Ember from 'ember'` - -Component = Ember.Component.extend - tagName: 'a' - classNames: ['travis-switch', 'switch'] - classNameBindings: ['_active:active'] - - # TODO: how to handle overriding properties to - # avoid naming it _action? - _active: (-> - @get('target.active') || @get('active') - ).property('target.active', 'active') - - click: -> - target = @get('target') - if @get('toggleAutomatically') != 'false' - if target - @set('target.active', !@get('target.active')) - else - @set('active', !@get('active')) - # allow for bindings to propagate - Ember.run.next this, -> - @sendAction('action', target) - -`export default Component` diff --git a/app/components/travis-switch.js b/app/components/travis-switch.js new file mode 100644 index 00000000..887a5f63 --- /dev/null +++ b/app/components/travis-switch.js @@ -0,0 +1,26 @@ +import Ember from 'ember'; + +export default Ember.Component.extend({ + tagName: 'a', + classNames: ['travis-switch', 'switch'], + classNameBindings: ['_active:active'], + + _active: function() { + return this.get('target.active') || this.get('active'); + }.property('target.active', 'active'), + + click() { + var target; + target = this.get('target'); + if (this.get('toggleAutomatically') !== 'false') { + if (target) { + this.set('target.active', !this.get('target.active')); + } else { + this.set('active', !this.get('active')); + } + } + return Ember.run.next(this, function() { + return this.sendAction('action', target); + }); + } +}); diff --git a/app/controllers/account.coffee b/app/controllers/account.coffee deleted file mode 100644 index c6195a19..00000000 --- a/app/controllers/account.coffee +++ /dev/null @@ -1,66 +0,0 @@ -`import Ember from 'ember'` - -Controller = Ember.Controller.extend - allHooks: [] - userBinding: 'auth.currentUser' - - init: -> - @_super.apply this, arguments - - self = this - Travis.on("user:synced", (-> - self.reloadHooks() - )) - - actions: - sync: -> - @get('user').sync() - - toggle: (hook) -> - hook.toggle() - - reloadHooks: -> - if login = @get('model.login') - hooks = @store.query('hook', all: true, owner_name: login) - - hooks.then () -> - hooks.set('isLoaded', true) - - @set('allHooks', hooks) - - accountName: (-> - @get('model.name') || @get('model.login') - ).property('model.name', 'model.login') - - hooks: (-> - @reloadHooks() unless hooks = @get('allHooks') - @get('allHooks').filter (hook) -> hook.get('admin') - ).property('allHooks.length', 'allHooks') - - hooksWithoutAdmin: (-> - @reloadHooks() unless hooks = @get('allHooks') - @get('allHooks').filter (hook) -> !hook.get('admin') - ).property('allHooks.length', 'allHooks') - - showPrivateReposHint: (-> - @config.show_repos_hint == 'private' - ).property() - - showPublicReposHint: (-> - @config.show_repos_hint == 'public' - ).property() - - billingUrl: ( -> - id = if @get('model.type') == 'user' then 'user' else @get('model.login') - "#{@config.billingEndpoint}/subscriptions/#{id}" - ).property('model.name', 'model.login') - - subscribeButtonInfo: (-> - { - billingUrl: @get('billingUrl') - subscribed: @get('model.subscribed') - education: @get('model.education') - } - ).property('model.login', 'model.type') - -`export default Controller` diff --git a/app/controllers/account.js b/app/controllers/account.js new file mode 100644 index 00000000..e57cf66c --- /dev/null +++ b/app/controllers/account.js @@ -0,0 +1,85 @@ +import Ember from 'ember'; + +export default Ember.Controller.extend({ + allHooks: [], + userBinding: 'auth.currentUser', + + init() { + var self; + this._super.apply(this, arguments); + self = this; + return Travis.on("user:synced", (function() { + return self.reloadHooks(); + })); + }, + + actions: { + sync() { + return this.get('user').sync(); + }, + + toggle(hook) { + return hook.toggle(); + } + }, + + reloadHooks() { + var hooks, login; + if (login = this.get('model.login')) { + hooks = this.store.query('hook', { + all: true, + owner_name: login + }); + hooks.then(function() { + return hooks.set('isLoaded', true); + }); + return this.set('allHooks', hooks); + } + }, + + accountName: function() { + return this.get('model.name') || this.get('model.login'); + }.property('model.name', 'model.login'), + + hooks: function() { + var hooks; + if (!(hooks = this.get('allHooks'))) { + this.reloadHooks(); + } + return this.get('allHooks').filter(function(hook) { + return hook.get('admin'); + }); + }.property('allHooks.length', 'allHooks'), + + hooksWithoutAdmin: function() { + var hooks; + if (!(hooks = this.get('allHooks'))) { + this.reloadHooks(); + } + return this.get('allHooks').filter(function(hook) { + return !hook.get('admin'); + }); + }.property('allHooks.length', 'allHooks'), + + showPrivateReposHint: function() { + return this.config.show_repos_hint === 'private'; + }.property(), + + showPublicReposHint: function() { + return this.config.show_repos_hint === 'public'; + }.property(), + + billingUrl: function() { + var id; + id = this.get('model.type') === 'user' ? 'user' : this.get('model.login'); + return this.config.billingEndpoint + "/subscriptions/" + id; + }.property('model.name', 'model.login'), + + subscribeButtonInfo: function() { + return { + billingUrl: this.get('billingUrl'), + subscribed: this.get('model.subscribed'), + education: this.get('model.education') + }; + }.property('model.login', 'model.type') +}); diff --git a/app/controllers/accounts.coffee b/app/controllers/accounts.coffee deleted file mode 100644 index 7286d5b4..00000000 --- a/app/controllers/accounts.coffee +++ /dev/null @@ -1,5 +0,0 @@ -`import Ember from 'ember'` - -Controller = Ember.ArrayController.extend() - -`export default Controller` diff --git a/app/controllers/accounts.js b/app/controllers/accounts.js new file mode 100644 index 00000000..6f6fd118 --- /dev/null +++ b/app/controllers/accounts.js @@ -0,0 +1,3 @@ +import Ember from 'ember'; + +export default Ember.ArrayController.extend(); diff --git a/app/controllers/accounts/info.coffee b/app/controllers/accounts/info.coffee deleted file mode 100644 index 179d835f..00000000 --- a/app/controllers/accounts/info.coffee +++ /dev/null @@ -1,7 +0,0 @@ -`import Ember from 'ember'` - -Controller = Ember.Controller.extend - repos: Ember.inject.controller() - userBinding: 'auth.currentUser' - -`export default Controller` diff --git a/app/controllers/accounts/info.js b/app/controllers/accounts/info.js new file mode 100644 index 00000000..f0387812 --- /dev/null +++ b/app/controllers/accounts/info.js @@ -0,0 +1,6 @@ +import Ember from 'ember'; + +export default Ember.Controller.extend({ + repos: Ember.inject.controller(), + userBinding: 'auth.currentUser' +}); diff --git a/app/controllers/auth.coffee b/app/controllers/auth.coffee deleted file mode 100644 index 90babea0..00000000 --- a/app/controllers/auth.coffee +++ /dev/null @@ -1,5 +0,0 @@ -`import Ember from 'ember'` - -Controller = Ember.Controller.extend() - -`export default Controller` diff --git a/app/controllers/auth.js b/app/controllers/auth.js new file mode 100644 index 00000000..38e5364f --- /dev/null +++ b/app/controllers/auth.js @@ -0,0 +1,3 @@ +import Ember from 'ember'; + +export default Ember.Controller.extend(); diff --git a/app/controllers/branches.coffee b/app/controllers/branches.coffee deleted file mode 100644 index 528573df..00000000 --- a/app/controllers/branches.coffee +++ /dev/null @@ -1,31 +0,0 @@ -`import Ember from 'ember'` -`import GithubUrlPropertievs from 'travis/mixins/github-url-properties'` - -BranchesController = Ember.Controller.extend - - defaultBranch: (-> - repos = @get('model') - output = repos.filter (item, index) -> - item.default_branch - if output.length - output[0] - ).property('model') - - activeBranches: (-> - repos = @get('model') - console.log repos - repos = repos.filter (item, index) -> - item.exists_on_github && !item.default_branch - .sortBy('last_build.finished_at') - .reverse() - ).property('model') - - inactiveBranches: (-> - repos = @get('model') - repos = repos.filter (item, index) -> - !item.exists_on_github && !item.default_branch - .sortBy('last_build.finished_at') - .reverse() - ).property('model') - -`export default BranchesController` diff --git a/app/controllers/branches.js b/app/controllers/branches.js new file mode 100644 index 00000000..8d71816d --- /dev/null +++ b/app/controllers/branches.js @@ -0,0 +1,31 @@ +import Ember from 'ember'; +import GithubUrlPropertievs from 'travis/mixins/github-url-properties'; + +export default Ember.Controller.extend({ + defaultBranch: function() { + var output, repos; + repos = this.get('model'); + output = repos.filter(function(item, index) { + return item.default_branch; + }); + if (output.length) { + return output[0]; + } + }.property('model'), + + activeBranches: function() { + var repos; + repos = this.get('model'); + return repos = repos.filter(function(item, index) { + return item.exists_on_github && !item.default_branch; + }).sortBy('last_build.finished_at').reverse(); + }.property('model'), + + inactiveBranches: function() { + var repos; + repos = this.get('model'); + return repos = repos.filter(function(item, index) { + return !item.exists_on_github && !item.default_branch; + }).sortBy('last_build.finished_at').reverse(); + }.property('model') +}); diff --git a/app/controllers/build.coffee b/app/controllers/build.coffee deleted file mode 100644 index fcf82f19..00000000 --- a/app/controllers/build.coffee +++ /dev/null @@ -1,28 +0,0 @@ -`import Ember from 'ember'` -`import GithubUrlPropertievs from 'travis/mixins/github-url-properties'` - -Controller = Ember.Controller.extend GithubUrlPropertievs, - repoController: Ember.inject.controller('repo') - repoBinding: 'repoController.repo' - commitBinding: 'build.commit' - currentUserBinding: 'auth.currentUser' - tabBinding: 'repoController.tab' - sendFaviconStateChanges: true - - currentItemBinding: 'build' - - jobsLoaded: (-> - if jobs = @get('build.jobs') - jobs.isEvery('config') - ).property('build.jobs.@each.config') - - loading: (-> - @get('build.isLoading') - ).property('build.isLoading') - - buildStateDidChange: (-> - if @get('sendFaviconStateChanges') - @send('faviconStateDidChange', @get('build.state')) - ).observes('build.state') - -`export default Controller` diff --git a/app/controllers/build.js b/app/controllers/build.js new file mode 100644 index 00000000..da027c99 --- /dev/null +++ b/app/controllers/build.js @@ -0,0 +1,29 @@ +import Ember from 'ember'; +import GithubUrlPropertievs from 'travis/mixins/github-url-properties'; + +export default Ember.Controller.extend(GithubUrlPropertievs, { + repoController: Ember.inject.controller('repo'), + repoBinding: 'repoController.repo', + commitBinding: 'build.commit', + currentUserBinding: 'auth.currentUser', + tabBinding: 'repoController.tab', + sendFaviconStateChanges: true, + currentItemBinding: 'build', + + jobsLoaded: function() { + var jobs; + if (jobs = this.get('build.jobs')) { + return jobs.isEvery('config'); + } + }.property('build.jobs.@each.config'), + + loading: function() { + return this.get('build.isLoading'); + }.property('build.isLoading'), + + buildStateDidChange: function() { + if (this.get('sendFaviconStateChanges')) { + return this.send('faviconStateDidChange', this.get('build.state')); + } + }.observes('build.state') +}); diff --git a/app/controllers/builds.coffee b/app/controllers/builds.coffee deleted file mode 100644 index cb561de7..00000000 --- a/app/controllers/builds.coffee +++ /dev/null @@ -1,65 +0,0 @@ -`import Ember from 'ember'` - -Controller = Ember.ArrayController.extend - sortAscending: false - sortProperties: ['number'] - - repoController: Ember.inject.controller('repo') - - repoBinding: 'repoController.repo' - tabBinding: 'repoController.tab' - isLoadedBinding: 'content.isLoaded' - isLoadingBinding: 'content.isLoading' - - showMore: -> - id = @get('repo.id') - number = @get('lastObject.number') - type = if @get('tab') == "builds" then 'push' else 'pull_request' - @get('content').load @olderThanNumber(id, number, type) - - displayShowMoreButton: (-> - @get('tab') != 'branches' and parseInt(@get('lastObject.number')) > 1 - ).property('tab', 'lastObject.number') - - displayPullRequests: (-> - if @get('tab') == 'pull_requests' - if Ember.isEmpty(@get('repo.pullRequests.content')) - true - else - false - else - false - ).property('tab', 'repo.builds', 'repo.pullRequests') - - displayBranches: (-> - if @get('tab') == 'branches' - if Ember.isEmpty(@get('repo.branches.content.content')) - true - else - false - else - false - ).property('tab', 'repo.builds', 'repo.branches') - - noticeData: (-> - return { - repo: @get('repo'), - auth: @auth.token() - } - ).property('repo') - - olderThanNumber: (id, number, type) -> - options = { repository_id: id, after_number: number } - if type? - options.event_type = type.replace(/s$/, '') # poor man's singularize - if options.event_type == 'push' - options.event_type = ['push', 'api'] - - @store.query('build', options) - - actions: - showMoreBuilds: -> - @showMore() - - -`export default Controller` diff --git a/app/controllers/builds.js b/app/controllers/builds.js new file mode 100644 index 00000000..dff591ff --- /dev/null +++ b/app/controllers/builds.js @@ -0,0 +1,75 @@ +import Ember from 'ember'; + +export default Ember.ArrayController.extend({ + sortAscending: false, + sortProperties: ['number'], + repoController: Ember.inject.controller('repo'), + repoBinding: 'repoController.repo', + tabBinding: 'repoController.tab', + isLoadedBinding: 'content.isLoaded', + isLoadingBinding: 'content.isLoading', + + showMore() { + var id, number, type; + id = this.get('repo.id'); + number = this.get('lastObject.number'); + type = this.get('tab') === "builds" ? 'push' : 'pull_request'; + return this.get('content').load(this.olderThanNumber(id, number, type)); + }, + + displayShowMoreButton: function() { + return this.get('tab') !== 'branches' && parseInt(this.get('lastObject.number')) > 1; + }.property('tab', 'lastObject.number'), + + displayPullRequests: function() { + if (this.get('tab') === 'pull_requests') { + if (Ember.isEmpty(this.get('repo.pullRequests.content'))) { + return true; + } else { + return false; + } + } else { + return false; + } + }.property('tab', 'repo.builds', 'repo.pullRequests'), + + displayBranches: function() { + if (this.get('tab') === 'branches') { + if (Ember.isEmpty(this.get('repo.branches.content.content'))) { + return true; + } else { + return false; + } + } else { + return false; + } + }.property('tab', 'repo.builds', 'repo.branches'), + + noticeData: function() { + return { + repo: this.get('repo'), + auth: this.auth.token() + }; + }.property('repo'), + + olderThanNumber(id, number, type) { + var options; + options = { + repository_id: id, + after_number: number + }; + if (type != null) { + options.event_type = type.replace(/s$/, ''); + if (options.event_type === 'push') { + options.event_type = ['push', 'api']; + } + } + return this.store.query('build', options); + }, + + actions: { + showMoreBuilds() { + return this.showMore(); + } + } +}); diff --git a/app/controllers/caches.coffee b/app/controllers/caches.coffee deleted file mode 100644 index 9827c927..00000000 --- a/app/controllers/caches.coffee +++ /dev/null @@ -1,28 +0,0 @@ -`import Ember from 'ember'` - -Controller = Ember.Controller.extend - ajax: Ember.inject.service() - - repoController: Ember.inject.controller('repo') - repo: Ember.computed.alias('repoController.repo') - - isDeleting: false - - cachesExist: (-> - @get('model.pushes.length') || @get('model.pullRequests.length') - ).property('model.pushes.length', 'model.pullRequests.length') - - actions: - deleteRepoCache: -> - return if @get('isDeleting') - - if confirm('Are you sure?') - @set('isDeleting', true) - - deletingDone = => @set('isDeleting', false) - - repo = @get('repo') - @get('ajax').ajax("/repos/#{@get('repo.id')}/caches", "DELETE").then(deletingDone, deletingDone).then => - @set('model', {}) - -`export default Controller` diff --git a/app/controllers/caches.js b/app/controllers/caches.js new file mode 100644 index 00000000..1cc1e488 --- /dev/null +++ b/app/controllers/caches.js @@ -0,0 +1,31 @@ +import Ember from 'ember'; + +export default Ember.Controller.extend({ + ajax: Ember.inject.service(), + repoController: Ember.inject.controller('repo'), + repo: Ember.computed.alias('repoController.repo'), + isDeleting: false, + + cachesExist: function() { + return this.get('model.pushes.length') || this.get('model.pullRequests.length'); + }.property('model.pushes.length', 'model.pullRequests.length'), + + actions: { + deleteRepoCache() { + var deletingDone, repo; + if (this.get('isDeleting')) { + return; + } + if (confirm('Are you sure?')) { + this.set('isDeleting', true); + deletingDone = () => { + return this.set('isDeleting', false); + }; + repo = this.get('repo'); + return this.get('ajax').ajax("/repos/" + (this.get('repo.id')) + "/caches", "DELETE").then(deletingDone, deletingDone).then(() => { + return this.set('model', {}); + }); + } + } + } +}); diff --git a/app/controllers/current-user.coffee b/app/controllers/current-user.coffee deleted file mode 100644 index b6b5d130..00000000 --- a/app/controllers/current-user.coffee +++ /dev/null @@ -1,13 +0,0 @@ -Controller = Ember.Controller.extend - sync: -> - @get('model').sync() - - model: Ember.computed.alias('auth.currentUser') - - syncingDidChange: (-> - if (user = @get('model')) && user.get('isSyncing') && !user.get('syncedAt') - Ember.run.scheduleOnce 'routerTransitions', this, -> - @container.lookup('router:main').send('renderFirstSync') - ).observes('isSyncing', 'auth.currentUser') - -`export default Controller` diff --git a/app/controllers/current-user.js b/app/controllers/current-user.js new file mode 100644 index 00000000..0ae514a2 --- /dev/null +++ b/app/controllers/current-user.js @@ -0,0 +1,17 @@ +var Controller; + +export default Ember.Controller.extend({ + sync() { + return this.get('model').sync(); + }, + + model: Ember.computed.alias('auth.currentUser'), + + syncingDidChange: function() { + if ((user = this.get('model')) && user.get('isSyncing') && !user.get('syncedAt')) { + return Ember.run.scheduleOnce('routerTransitions', this, function() { + return this.container.lookup('router:main').send('renderFirstSync'); + }); + } + }.observes('isSyncing', 'auth.currentUser') +}); diff --git a/app/controllers/dashboard/repositories.coffee b/app/controllers/dashboard/repositories.coffee deleted file mode 100644 index 0f06dbe6..00000000 --- a/app/controllers/dashboard/repositories.coffee +++ /dev/null @@ -1,71 +0,0 @@ -`import Ember from 'ember'` -`import config from 'travis/config/environment'` - -Controller = Ember.Controller.extend - queryParams: ['org'] - filter: null - org: null - - filteredRepositories: (-> - filter = @get('filter') - repos = @get('model') - org = @get('org') - - repos = repos.filter (item, index) -> - if item.get('default_branch') - item.get('default_branch.last_build') != null - .sortBy('default_branch.last_build.finished_at') - .reverse() - - if org - repos = repos.filter (item, index) -> - item.get('owner.login') == org - - if Ember.isBlank(filter) - repos - else - repos.filter (item, index) -> - item.slug.match(new RegExp(filter)) - - ).property('filter', 'model', 'org') - - updateFilter: () -> - value = @get('_lastFilterValue') - @transitionToRoute queryParams: { filter: value } - @set('filter', value) - - selectedOrg: (-> - @get('orgs').findBy('login', @get('org')) - ).property('org', 'orgs.[]') - - orgs: (-> - orgs = Ember.ArrayProxy.create( - content: [] - isLoading: true - ) - - apiEndpoint = config.apiEndpoint - $.ajax(apiEndpoint + '/v3/orgs', { - headers: { - Authorization: 'token ' + @auth.token() - } - }).then (response) -> - array = response.organizations.map( (org) -> - Ember.Object.create(org) - ) - orgs.set('content', array) - orgs.set('isLoading', false) - - orgs - ).property() - - actions: - updateFilter: (value) -> - @set('_lastFilterValue', value) - Ember.run.throttle this, @updateFilter, [], 200, false - - selectOrg: (org) -> - login = if org then org.get('login') else null - @set('org', login) - -`export default Controller` diff --git a/app/controllers/dashboard/repositories.js b/app/controllers/dashboard/repositories.js new file mode 100644 index 00000000..2d648699 --- /dev/null +++ b/app/controllers/dashboard/repositories.js @@ -0,0 +1,82 @@ +import Ember from 'ember'; +import config from 'travis/config/environment'; + +export default Ember.Controller.extend({ + queryParams: ['org'], + filter: null, + org: null, + + filteredRepositories: function() { + var filter, org, repos; + filter = this.get('filter'); + repos = this.get('model'); + org = this.get('org'); + repos = repos.filter(function(item, index) { + if (item.get('default_branch')) { + return item.get('default_branch.last_build') !== null; + } + }).sortBy('default_branch.last_build.finished_at').reverse(); + if (org) { + repos = repos.filter(function(item, index) { + return item.get('owner.login') === org; + }); + } + if (Ember.isBlank(filter)) { + return repos; + } else { + return repos.filter(function(item, index) { + return item.slug.match(new RegExp(filter)); + }); + } + }.property('filter', 'model', 'org'), + + updateFilter() { + var value; + value = this.get('_lastFilterValue'); + this.transitionToRoute({ + queryParams: { + filter: value + } + }); + return this.set('filter', value); + }, + + selectedOrg: function() { + return this.get('orgs').findBy('login', this.get('org')); + }.property('org', 'orgs.[]'), + + orgs: function() { + var apiEndpoint, orgs; + orgs = Ember.ArrayProxy.create({ + content: [], + isLoading: true + }); + apiEndpoint = config.apiEndpoint; + $.ajax(apiEndpoint + '/v3/orgs', { + headers: { + Authorization: 'token ' + this.auth.token() + } + }).then(function(response) { + var array; + array = response.organizations.map(function(org) { + return Ember.Object.create(org); + }); + orgs.set('content', array); + return orgs.set('isLoading', false); + }); + return orgs; + }.property(), + + actions: { + updateFilter(value) { + this.set('_lastFilterValue', value); + return Ember.run.throttle(this, this.updateFilter, [], 200, false); + }, + + selectOrg(org) { + var login; + login = org ? org.get('login') : null; + return this.set('org', login); + } + } +}); diff --git a/app/controllers/error.coffee b/app/controllers/error.coffee deleted file mode 100644 index 90babea0..00000000 --- a/app/controllers/error.coffee +++ /dev/null @@ -1,5 +0,0 @@ -`import Ember from 'ember'` - -Controller = Ember.Controller.extend() - -`export default Controller` diff --git a/app/controllers/error.js b/app/controllers/error.js new file mode 100644 index 00000000..38e5364f --- /dev/null +++ b/app/controllers/error.js @@ -0,0 +1,3 @@ +import Ember from 'ember'; + +export default Ember.Controller.extend(); diff --git a/app/controllers/first-sync.coffee b/app/controllers/first-sync.coffee deleted file mode 100644 index c518ebc4..00000000 --- a/app/controllers/first-sync.coffee +++ /dev/null @@ -1,8 +0,0 @@ -`import Ember from 'ember'` - -Controller = Ember.Controller.extend - user: Ember.computed.alias('auth.currentUser') - - isSyncing: Ember.computed.alias('user.isSyncing') - -`export default Controller` diff --git a/app/controllers/first-sync.js b/app/controllers/first-sync.js new file mode 100644 index 00000000..68da4920 --- /dev/null +++ b/app/controllers/first-sync.js @@ -0,0 +1,6 @@ +import Ember from 'ember'; + +export default Ember.Controller.extend({ + user: Ember.computed.alias('auth.currentUser'), + isSyncing: Ember.computed.alias('user.isSyncing') +}); diff --git a/app/controllers/home-pro.coffee b/app/controllers/home-pro.coffee deleted file mode 100644 index c05f5de9..00000000 --- a/app/controllers/home-pro.coffee +++ /dev/null @@ -1,10 +0,0 @@ -`import Ember from 'ember'` - -Controller = Ember.Controller.extend - - actions: - gaCta: (location) -> - _gaq.push(['_trackPageview', '/virtual/signup?'+ location]) - @auth.signIn() - -`export default Controller` diff --git a/app/controllers/home-pro.js b/app/controllers/home-pro.js new file mode 100644 index 00000000..99253200 --- /dev/null +++ b/app/controllers/home-pro.js @@ -0,0 +1,10 @@ +import Ember from 'ember'; + +export default Ember.Controller.extend({ + actions: { + gaCta(location) { + _gaq.push(['_trackPageview', '/virtual/signup?' + location]); + return this.auth.signIn(); + } + } +}); diff --git a/app/controllers/home.coffee b/app/controllers/home.coffee deleted file mode 100644 index 90babea0..00000000 --- a/app/controllers/home.coffee +++ /dev/null @@ -1,5 +0,0 @@ -`import Ember from 'ember'` - -Controller = Ember.Controller.extend() - -`export default Controller` diff --git a/app/controllers/home.js b/app/controllers/home.js new file mode 100644 index 00000000..38e5364f --- /dev/null +++ b/app/controllers/home.js @@ -0,0 +1,3 @@ +import Ember from 'ember'; + +export default Ember.Controller.extend(); diff --git a/app/controllers/job.coffee b/app/controllers/job.coffee deleted file mode 100644 index 42196a8a..00000000 --- a/app/controllers/job.coffee +++ /dev/null @@ -1,22 +0,0 @@ -`import Ember from 'ember'` -`import { githubCommit } from 'travis/utils/urls'` - -Controller = Ember.Controller.extend - repoController: Ember.inject.controller('repo') - - repoBinding: 'repoController.repo' - commitBinding: 'job.commit' - currentUserBinding: 'auth.currentUser' - tabBinding: 'repoController.tab' - - currentItemBinding: 'job' - - urlGithubCommit: (-> - githubCommit(@get('repo.slug'), @get('commit.sha')) - ).property('repo.slug', 'commit.sha') - - jobStateDidChange: (-> - @send('faviconStateDidChange', @get('job.state')) - ).observes('job.state') - -`export default Controller` diff --git a/app/controllers/job.js b/app/controllers/job.js new file mode 100644 index 00000000..2aaee2e8 --- /dev/null +++ b/app/controllers/job.js @@ -0,0 +1,19 @@ +import Ember from 'ember'; +import { githubCommit } from 'travis/utils/urls'; + +export default Ember.Controller.extend({ + repoController: Ember.inject.controller('repo'), + repoBinding: 'repoController.repo', + commitBinding: 'job.commit', + currentUserBinding: 'auth.currentUser', + tabBinding: 'repoController.tab', + currentItemBinding: 'job', + + urlGithubCommit: function() { + return githubCommit(this.get('repo.slug'), this.get('commit.sha')); + }.property('repo.slug', 'commit.sha'), + + jobStateDidChange: function() { + return this.send('faviconStateDidChange', this.get('job.state')); + }.observes('job.state') +}); diff --git a/app/controllers/loading.coffee b/app/controllers/loading.coffee deleted file mode 100644 index 90babea0..00000000 --- a/app/controllers/loading.coffee +++ /dev/null @@ -1,5 +0,0 @@ -`import Ember from 'ember'` - -Controller = Ember.Controller.extend() - -`export default Controller` diff --git a/app/controllers/loading.js b/app/controllers/loading.js new file mode 100644 index 00000000..38e5364f --- /dev/null +++ b/app/controllers/loading.js @@ -0,0 +1,3 @@ +import Ember from 'ember'; + +export default Ember.Controller.extend(); diff --git a/app/controllers/main/error.coffee b/app/controllers/main/error.coffee deleted file mode 100644 index 90babea0..00000000 --- a/app/controllers/main/error.coffee +++ /dev/null @@ -1,5 +0,0 @@ -`import Ember from 'ember'` - -Controller = Ember.Controller.extend() - -`export default Controller` diff --git a/app/controllers/main/error.js b/app/controllers/main/error.js new file mode 100644 index 00000000..38e5364f --- /dev/null +++ b/app/controllers/main/error.js @@ -0,0 +1,3 @@ +import Ember from 'ember'; + +export default Ember.Controller.extend(); diff --git a/app/controllers/owner.coffee b/app/controllers/owner.coffee deleted file mode 100644 index 0f3970d3..00000000 --- a/app/controllers/owner.coffee +++ /dev/null @@ -1,30 +0,0 @@ -`import Ember from 'ember'` - -Controller = Ember.Controller.extend - isLoading: false - - githubProfile: (-> - "https://github.com/#{@get('model.login')}" - ).property('model') - - avatarURL: (-> - if @get('model.avatar_url') - "#{@get('model.avatar_url')}?s=125" - else - 'https://secure.gravatar.com/avatar/?d=mm&s=125' - ).property('model') - - owner: (-> - data = @get('model') - - { - login: data.login - name: data.name - isSyncing: data.is_syncing - avatarUrl: data.avatar_url - syncedAt: data.synced_at - } - - ).property('model') - -`export default Controller` diff --git a/app/controllers/owner.js b/app/controllers/owner.js new file mode 100644 index 00000000..d2434f08 --- /dev/null +++ b/app/controllers/owner.js @@ -0,0 +1,29 @@ +import Ember from 'ember'; + +export default Ember.Controller.extend({ + isLoading: false, + + githubProfile: function() { + return "https://github.com/" + (this.get('model.login')); + }.property('model'), + + avatarURL: function() { + if (this.get('model.avatar_url')) { + return (this.get('model.avatar_url')) + "?s=125"; + } else { + return 'https://secure.gravatar.com/avatar/?d=mm&s=125'; + } + }.property('model'), + + owner: function() { + var data; + data = this.get('model'); + return { + login: data.login, + name: data.name, + isSyncing: data.is_syncing, + avatarUrl: data.avatar_url, + syncedAt: data.synced_at + }; + }.property('model') +}); diff --git a/app/controllers/owner/repositories.coffee b/app/controllers/owner/repositories.coffee deleted file mode 100644 index cf07a5b0..00000000 --- a/app/controllers/owner/repositories.coffee +++ /dev/null @@ -1,28 +0,0 @@ -`import Ember from 'ember'` - -Controller = Ember.Controller.extend - isLoading: false - - repos: (-> - data = @get('model') - repos = [] - if data.repositories - repos = data.repositories.filter((item, index) -> - if item.active - item - ).sortBy('default_branch.last_build.finished_at').reverse() - repos - ).property('model') - - # running: (-> - # data = @get('model') - - # repos = data.repositories.filter (item, index) -> - # if item.default_branch.last_build != null - # if item.default_branch.last_build.state == 'started' - # item - # repos - - # ).property('model') - -`export default Controller` diff --git a/app/controllers/owner/repositories.js b/app/controllers/owner/repositories.js new file mode 100644 index 00000000..229c9b98 --- /dev/null +++ b/app/controllers/owner/repositories.js @@ -0,0 +1,18 @@ +import Ember from 'ember'; + +export default Ember.Controller.extend({ + isLoading: false, + repos: function() { + var data, repos; + data = this.get('model'); + repos = []; + if (data.repositories) { + repos = data.repositories.filter(function(item, index) { + if (item.active) { + return item; + } + }).sortBy('default_branch.last_build.finished_at').reverse(); + } + return repos; + }.property('model') +}); diff --git a/app/controllers/owner/running.coffee b/app/controllers/owner/running.coffee deleted file mode 100644 index 3b170877..00000000 --- a/app/controllers/owner/running.coffee +++ /dev/null @@ -1,17 +0,0 @@ -`import Ember from 'ember'` - -Controller = Ember.Controller.extend - isLoading: false - - running: (-> - data = @get('model') - - repos = data.repositories.filter (item, index) -> - if item.default_branch.last_build != null - if item.default_branch.last_build.state == 'started' - item - repos - - ).property('model') - -`export default Controller` diff --git a/app/controllers/owner/running.js b/app/controllers/owner/running.js new file mode 100644 index 00000000..c71e0df6 --- /dev/null +++ b/app/controllers/owner/running.js @@ -0,0 +1,17 @@ +import Ember from 'ember'; + +export default Ember.Controller.extend({ + isLoading: false, + running: function() { + var data, repos; + data = this.get('model'); + repos = data.repositories.filter(function(item, index) { + if (item.default_branch.last_build !== null) { + if (item.default_branch.last_build.state === 'started') { + return item; + } + } + }); + return repos; + }.property('model') +}); diff --git a/app/controllers/plans.coffee b/app/controllers/plans.coffee deleted file mode 100644 index c05f5de9..00000000 --- a/app/controllers/plans.coffee +++ /dev/null @@ -1,10 +0,0 @@ -`import Ember from 'ember'` - -Controller = Ember.Controller.extend - - actions: - gaCta: (location) -> - _gaq.push(['_trackPageview', '/virtual/signup?'+ location]) - @auth.signIn() - -`export default Controller` diff --git a/app/controllers/plans.js b/app/controllers/plans.js new file mode 100644 index 00000000..99253200 --- /dev/null +++ b/app/controllers/plans.js @@ -0,0 +1,10 @@ +import Ember from 'ember'; + +export default Ember.Controller.extend({ + actions: { + gaCta(location) { + _gaq.push(['_trackPageview', '/virtual/signup?' + location]); + return this.auth.signIn(); + } + } +}); diff --git a/app/controllers/profile.coffee b/app/controllers/profile.coffee deleted file mode 100644 index bf9443f7..00000000 --- a/app/controllers/profile.coffee +++ /dev/null @@ -1,24 +0,0 @@ -`import Ember from 'ember'` - -Controller = Ember.Controller.extend - name: 'profile' - - 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('accountController').reloadHooks() - - viewUser: -> - @connectTab('user') - - connectTab: (tab) -> - @set('tab', tab) - -`export default Controller` diff --git a/app/controllers/profile.js b/app/controllers/profile.js new file mode 100644 index 00000000..0328c5d7 --- /dev/null +++ b/app/controllers/profile.js @@ -0,0 +1,26 @@ +import Ember from 'ember'; + +export default Ember.Controller.extend({ + name: 'profile', + accountController: Ember.inject.controller('account'), + accountsController: Ember.inject.controller('accounts'), + userBinding: 'auth.currentUser', + accountBinding: 'accountController.model', + + activate(action, params) { + return this[("view_" + action).camelize()](); + }, + + viewHooks() { + this.connectTab('hooks'); + return this.get('accountController').reloadHooks(); + }, + + viewUser() { + return this.connectTab('user'); + }, + + connectTab(tab) { + return this.set('tab', tab); + } +}); diff --git a/app/controllers/repo.coffee b/app/controllers/repo.coffee deleted file mode 100644 index b9acf45f..00000000 --- a/app/controllers/repo.coffee +++ /dev/null @@ -1,102 +0,0 @@ -`import Ember from 'ember'` -`import { githubRepo } from 'travis/utils/urls'` - -Controller = Ember.Controller.extend - jobController: Ember.inject.controller('job') - buildController: Ember.inject.controller('build') - buildsController: Ember.inject.controller('builds') - reposController: Ember.inject.controller('repos') - currentUserBinding: 'auth.currentUser' - - classNames: ['repo'] - - build: Ember.computed.alias('buildController.build') - builds: Ember.computed.alias('buildsController.content') - job: Ember.computed.alias('jobController.job') - - slug: (-> @get('repo.slug') ).property('repo.slug') - isLoading: (-> @get('repo.isLoading') ).property('repo.isLoading') - - init: -> - @_super.apply this, arguments - if !Ember.testing - Visibility.every @config.intervals.updateTimes, @updateTimes.bind(this) - - updateTimes: -> - Ember.run this, -> - if builds = @get('builds') - builds.forEach (b) -> b.updateTimes() - - if build = @get('build') - build.updateTimes() - - if build && jobs = build.get('jobs') - jobs.forEach (j) -> j.updateTimes() - - deactivate: -> - @stopObservingLastBuild() - - activate: (action) -> - @stopObservingLastBuild() - this["view_#{action}".camelize()]() - - viewIndex: -> - @observeLastBuild() - @connectTab('current') - - viewCurrent: -> - @observeLastBuild() - @connectTab('current') - - viewBuilds: -> - @connectTab('builds') - - viewPullRequests: -> - @connectTab('pull_requests') - - viewBranches: -> - @connectTab('branches') - - viewBuild: -> - @connectTab('build') - - viewJob: -> - @connectTab('job') - - viewRequests: -> - @connectTab('requests') - - viewCaches: -> - @connectTab('caches') - - viewRequest: -> - @connectTab('request') - - viewSettings: -> - @connectTab('settings') - - lastBuildDidChange: -> - Ember.run.scheduleOnce('actions', this, @_lastBuildDidChange); - - _lastBuildDidChange: -> - build = @get('repo.lastBuild') - @set('build', build) - - stopObservingLastBuild: -> - @removeObserver('repo.lastBuild', this, 'lastBuildDidChange') - - observeLastBuild: -> - @lastBuildDidChange() - @addObserver('repo.lastBuild', this, 'lastBuildDidChange') - - connectTab: (tab) -> - # TODO: such implementation seems weird now, because we render - # in the renderTemplate function in routes - name = if tab == 'current' then 'build' else tab - @set('tab', tab) - - urlGithub: (-> - githubRepo(@get('repo.slug')) - ).property('repo.slug') - -`export default Controller` diff --git a/app/controllers/repo.js b/app/controllers/repo.js new file mode 100644 index 00000000..bdda7a44 --- /dev/null +++ b/app/controllers/repo.js @@ -0,0 +1,134 @@ +import Ember from 'ember'; +import { githubRepo } from 'travis/utils/urls'; + +export default Ember.Controller.extend({ + jobController: Ember.inject.controller('job'), + buildController: Ember.inject.controller('build'), + buildsController: Ember.inject.controller('builds'), + reposController: Ember.inject.controller('repos'), + currentUserBinding: 'auth.currentUser', + + classNames: ['repo'], + + build: Ember.computed.alias('buildController.build'), + builds: Ember.computed.alias('buildsController.content'), + job: Ember.computed.alias('jobController.job'), + + slug: function() { + return this.get('repo.slug'); + }.property('repo.slug'), + + isLoading: function() { + return this.get('repo.isLoading'); + }.property('repo.isLoading'), + + init() { + this._super.apply(this, arguments); + if (!Ember.testing) { + return Visibility.every(this.config.intervals.updateTimes, this.updateTimes.bind(this)); + } + }, + + updateTimes() { + return Ember.run(this, function() { + var build, builds, jobs; + if (builds = this.get('builds')) { + builds.forEach(function(b) { + return b.updateTimes(); + }); + } + if (build = this.get('build')) { + build.updateTimes(); + } + if (build && (jobs = build.get('jobs'))) { + return jobs.forEach(function(j) { + return j.updateTimes(); + }); + } + }); + }, + + deactivate() { + return this.stopObservingLastBuild(); + }, + + activate(action) { + this.stopObservingLastBuild(); + return this[("view_" + action).camelize()](); + }, + + viewIndex() { + this.observeLastBuild(); + return this.connectTab('current'); + }, + + viewCurrent() { + this.observeLastBuild(); + return this.connectTab('current'); + }, + + viewBuilds() { + return this.connectTab('builds'); + }, + + viewPullRequests() { + return this.connectTab('pull_requests'); + }, + + viewBranches() { + return this.connectTab('branches'); + }, + + viewBuild() { + return this.connectTab('build'); + }, + + viewJob() { + return this.connectTab('job'); + }, + + viewRequests() { + return this.connectTab('requests'); + }, + + viewCaches() { + return this.connectTab('caches'); + }, + + viewRequest() { + return this.connectTab('request'); + }, + + viewSettings() { + return this.connectTab('settings'); + }, + + lastBuildDidChange() { + return Ember.run.scheduleOnce('actions', this, this._lastBuildDidChange); + }, + + _lastBuildDidChange() { + var build; + build = this.get('repo.lastBuild'); + return this.set('build', build); + }, + + stopObservingLastBuild() { + return this.removeObserver('repo.lastBuild', this, 'lastBuildDidChange'); + }, + + observeLastBuild() { + this.lastBuildDidChange(); + return this.addObserver('repo.lastBuild', this, 'lastBuildDidChange'); + }, + + connectTab(tab) { + var name; + name = tab === 'current' ? 'build' : tab; + return this.set('tab', tab); + }, + + urlGithub: function() { + return githubRepo(this.get('repo.slug')); + }.property('repo.slug') +}); diff --git a/app/controllers/requests.coffee b/app/controllers/requests.coffee deleted file mode 100644 index 40826f98..00000000 --- a/app/controllers/requests.coffee +++ /dev/null @@ -1,11 +0,0 @@ -`import Ember from 'ember'` - -Controller = Ember.ArrayController.extend - repoController: Ember.inject.controller('repo') - - lintUrl: (-> - slug = @get('repoController.repo.slug') - "https://lint.travis-ci.org/#{slug}" - ).property('repoController.repo.slug') - -`export default Controller` diff --git a/app/controllers/requests.js b/app/controllers/requests.js new file mode 100644 index 00000000..816c3f35 --- /dev/null +++ b/app/controllers/requests.js @@ -0,0 +1,11 @@ +import Ember from 'ember'; + +export default Ember.ArrayController.extend({ + repoController: Ember.inject.controller('repo'), + + lintUrl: function() { + var slug; + slug = this.get('repoController.repo.slug'); + return "https://lint.travis-ci.org/" + slug; + }.property('repoController.repo.slug') +}); diff --git a/app/controllers/settings.coffee b/app/controllers/settings.coffee deleted file mode 100644 index 2b2ff314..00000000 --- a/app/controllers/settings.coffee +++ /dev/null @@ -1,13 +0,0 @@ -`import Ember from 'ember'` - -SettingsController = Ember.Controller.extend - envVars: Ember.computed.filterBy('model.envVars', 'isNew', false) - - actions: - sshKeyAdded: (sshKey) -> - @set('model.customSshKey', sshKey) - - sshKeyDeleted: -> - @set('model.customSshKey', null) - -`export default SettingsController` diff --git a/app/controllers/settings.js b/app/controllers/settings.js new file mode 100644 index 00000000..c9bcff03 --- /dev/null +++ b/app/controllers/settings.js @@ -0,0 +1,14 @@ +import Ember from 'ember'; + +export default Ember.Controller.extend({ + envVars: Ember.computed.filterBy('model.envVars', 'isNew', false), + actions: { + sshKeyAdded(sshKey) { + return this.set('model.customSshKey', sshKey); + }, + + sshKeyDeleted() { + return this.set('model.customSshKey', null); + } + } +}); diff --git a/app/controllers/top.coffee b/app/controllers/top.coffee deleted file mode 100644 index 9c8f4584..00000000 --- a/app/controllers/top.coffee +++ /dev/null @@ -1,94 +0,0 @@ -`import Ember from 'ember'` -`import config from 'travis/config/environment'` - -Controller = Ember.Controller.extend - userBinding: 'auth.currentUser' - - store: Ember.inject.service() - storage: Ember.inject.service() - currentUserBinding: 'auth.currentUser' - - userName: (-> - @get('user.name') || @get('user.login') - ).property('user.login', 'user.name') - - gravatarUrl: (-> - if @get('user.gravatarId') - "#{location.protocol}//www.gravatar.com/avatar/#{@get('user.gravatarId')}?s=36&d=mm" - ).property('user.gravatarId') - - defineTowerColor: (broadcastArray) -> - return '' unless broadcastArray - - if broadcastArray.length - if broadcastArray.findBy('category', 'warning') - return 'warning' - else if broadcastArray.findBy('category', 'announcement') - return 'announcement' - else - return '' - - broadcasts: (-> - - if @get('auth.signedIn') - broadcasts = Ember.ArrayProxy.create( - content: [], - lastBroadcastStatus: '', - isLoading: true - ) - apiEndpoint = config.apiEndpoint - options = {} - options.type = 'GET' - options.headers = { Authorization: "token #{@auth.token()}" } - - seenBroadcasts = @get('storage').getItem('travis.seen_broadcasts') - if seenBroadcasts - seenBroadcasts = JSON.parse(seenBroadcasts) - else - seenBroadcasts = [] - - $.ajax("#{apiEndpoint}/v3/broadcasts", options).then (response) => - if response.broadcasts.length - receivedBroadcasts = response.broadcasts.filter((broadcast) => - unless broadcast.expired - if seenBroadcasts.indexOf(broadcast.id.toString()) == -1 - broadcast - ).map( (broadcast) -> - Ember.Object.create(broadcast) - ).reverse() - - broadcasts.set('lastBroadcastStatus', @defineTowerColor(receivedBroadcasts)) - broadcasts.set('content', receivedBroadcasts) - broadcasts.set('isLoading', false) - - broadcasts - ).property('broadcasts') - - actions: { - toggleBurgerMenu: -> - @toggleProperty('is-open') - return false - - toggleBroadcasts: -> - @toggleProperty('showBroadcasts') - return false - - markBroadcastAsSeen: (broadcast) -> - id = broadcast.get('id').toString() - seenBroadcasts = @get('storage').getItem('travis.seen_broadcasts') - if seenBroadcasts - seenBroadcasts = JSON.parse(seenBroadcasts) - else - seenBroadcasts = [] - seenBroadcasts.push(id) - @get('storage').setItem('travis.seen_broadcasts', JSON.stringify(seenBroadcasts)) - @get('broadcasts.content').removeObject(broadcast) - @set('broadcasts.lastBroadcastStatus', @defineTowerColor(@get('broadcasts.content'))) - return false - } - - showCta: (-> - !@get('auth.signedIn') && !@get('config.pro') && !@get('landingPage') - ).property('auth.signedIn', 'landingPage') - -`export default Controller` diff --git a/app/controllers/top.js b/app/controllers/top.js new file mode 100644 index 00000000..d061f752 --- /dev/null +++ b/app/controllers/top.js @@ -0,0 +1,106 @@ +import Ember from 'ember'; +import config from 'travis/config/environment'; + +export default Ember.Controller.extend({ + userBinding: 'auth.currentUser', + store: Ember.inject.service(), + storage: Ember.inject.service(), + currentUserBinding: 'auth.currentUser', + + userName: function() { + return this.get('user.name') || this.get('user.login'); + }.property('user.login', 'user.name'), + + gravatarUrl: function() { + if (this.get('user.gravatarId')) { + return location.protocol + "//www.gravatar.com/avatar/" + (this.get('user.gravatarId')) + "?s=36&d=mm"; + } + }.property('user.gravatarId'), + + defineTowerColor(broadcastArray) { + if (!broadcastArray) { + return ''; + } + if (broadcastArray.length) { + if (broadcastArray.findBy('category', 'warning')) { + return 'warning'; + } else if (broadcastArray.findBy('category', 'announcement')) { + return 'announcement'; + } else { + return ''; + } + } + }, + + broadcasts: function() { + var apiEndpoint, broadcasts, options, seenBroadcasts; + if (this.get('auth.signedIn')) { + broadcasts = Ember.ArrayProxy.create({ + content: [], + lastBroadcastStatus: '', + isLoading: true + }); + apiEndpoint = config.apiEndpoint; + options = {}; + options.type = 'GET'; + options.headers = { + Authorization: "token " + (this.auth.token()) + }; + seenBroadcasts = this.get('storage').getItem('travis.seen_broadcasts'); + if (seenBroadcasts) { + seenBroadcasts = JSON.parse(seenBroadcasts); + } else { + seenBroadcasts = []; + } + $.ajax(apiEndpoint + "/v3/broadcasts", options).then(() => { + var receivedBroadcasts; + if (response.broadcasts.length) { + receivedBroadcasts = response.broadcasts.filter(function(broadcast) { + if (!broadcast.expired) { + if (seenBroadcasts.indexOf(broadcast.id.toString()) === -1) { + return broadcast; + } + } + }).map(function(broadcast) { + return Ember.Object.create(broadcast); + }).reverse(); + } + broadcasts.set('lastBroadcastStatus', this.defineTowerColor(receivedBroadcasts)); + broadcasts.set('content', receivedBroadcasts); + return broadcasts.set('isLoading', false); + }); + return broadcasts; + } + }.property('broadcasts'), + + actions: { + toggleBurgerMenu() { + this.toggleProperty('is-open'); + return false; + }, + + toggleBroadcasts() { + this.toggleProperty('showBroadcasts'); + return false; + }, + + markBroadcastAsSeen(broadcast) { + var id, seenBroadcasts; + id = broadcast.get('id').toString(); + seenBroadcasts = this.get('storage').getItem('travis.seen_broadcasts'); + if (seenBroadcasts) { + seenBroadcasts = JSON.parse(seenBroadcasts); + } else { + seenBroadcasts = []; + } + seenBroadcasts.push(id); + this.get('storage').setItem('travis.seen_broadcasts', JSON.stringify(seenBroadcasts)); + this.get('broadcasts.content').removeObject(broadcast); + this.set('broadcasts.lastBroadcastStatus', this.defineTowerColor(this.get('broadcasts.content'))); + return false; + } + }, + showCta: function() { + return !this.get('auth.signedIn') && !this.get('config.pro') && !this.get('landingPage'); + }.property('auth.signedIn', 'landingPage') +}); diff --git a/app/helpers/filter-input.coffee b/app/helpers/filter-input.coffee deleted file mode 100644 index cab15eef..00000000 --- a/app/helpers/filter-input.coffee +++ /dev/null @@ -1,18 +0,0 @@ -`import Ember from 'ember'` - -TextField = Ember.TextField.extend - keyUp: (event) -> - @sendAction('action', @get('_value'), event) - - _elementValueDidChange: -> - @set('_value', @$().val()); - -fn = (params, hash, options, env) -> - Ember.assert('You can only pass attributes to the `input` helper, not arguments', params.length) - - onEvent = hash.on - delete hash.on - hash.onEvent = onEvent || 'enter' - env.helpers.view.helperFunction.call(this, [TextField], hash, options, env) - -`export default fn` diff --git a/app/helpers/filter-input.js b/app/helpers/filter-input.js new file mode 100644 index 00000000..05202627 --- /dev/null +++ b/app/helpers/filter-input.js @@ -0,0 +1,21 @@ +import Ember from 'ember'; +var TextField; + +TextField = Ember.TextField.extend({ + keyUp(event) { + return this.sendAction('action', this.get('_value'), event); + }, + + _elementValueDidChange() { + return this.set('_value', this.$().val()); + } +}); + +export default function(params, hash, options, env) { + var onEvent; + Ember.assert('You can only pass attributes to the `input` helper, not arguments', params.length); + onEvent = hash.on; + delete hash.on; + hash.onEvent = onEvent || 'enter'; + return env.helpers.view.helperFunction.call(this, [TextField], hash, options, env); +}; diff --git a/app/helpers/format-commit.coffee b/app/helpers/format-commit.coffee deleted file mode 100644 index 727fcf60..00000000 --- a/app/helpers/format-commit.coffee +++ /dev/null @@ -1,7 +0,0 @@ -`import { safe, formatCommit as formatCommitHelper } from 'travis/utils/helpers'` - -helper = Ember.Helper.helper (params) -> - commit = params[0] - safe formatCommitHelper(commit.get('sha'), commit.get('branch')) if commit - -`export default helper` diff --git a/app/helpers/format-commit.js b/app/helpers/format-commit.js new file mode 100644 index 00000000..1faa8014 --- /dev/null +++ b/app/helpers/format-commit.js @@ -0,0 +1,9 @@ +import { safe, formatCommit as formatCommitHelper } from 'travis/utils/helpers'; + +export default Ember.Helper.helper(function(params) { + var commit; + commit = params[0]; + if (commit) { + return safe(formatCommitHelper(commit.get('sha'), commit.get('branch'))); + } +}); diff --git a/app/helpers/format-config.coffee b/app/helpers/format-config.coffee deleted file mode 100644 index 6ab44df1..00000000 --- a/app/helpers/format-config.coffee +++ /dev/null @@ -1,6 +0,0 @@ -`import { safe, formatConfig as formatConfigHelper } from 'travis/utils/helpers'` - -formatConfig = (config, options) -> - safe formatConfigHelper(config) - -`export default helper` diff --git a/app/helpers/format-config.js b/app/helpers/format-config.js new file mode 100644 index 00000000..ade8be98 --- /dev/null +++ b/app/helpers/format-config.js @@ -0,0 +1,5 @@ +import { safe, formatConfig as formatConfigHelper } from 'travis/utils/helpers'; + +export default function(config, options) { + return safe(formatConfigHelper(config)); +}; diff --git a/app/helpers/format-duration.coffee b/app/helpers/format-duration.coffee deleted file mode 100644 index f3e8c0d4..00000000 --- a/app/helpers/format-duration.coffee +++ /dev/null @@ -1,7 +0,0 @@ -`import { timeInWords, safe } from 'travis/utils/helpers'` -`import Ember from "ember"` - -helper = Ember.Helper.helper (params) -> - safe timeInWords(params[0]) - -`export default helper` diff --git a/app/helpers/format-duration.js b/app/helpers/format-duration.js new file mode 100644 index 00000000..58956db8 --- /dev/null +++ b/app/helpers/format-duration.js @@ -0,0 +1,6 @@ +import { timeInWords, safe } from 'travis/utils/helpers'; +import Ember from "ember"; + +export default Ember.Helper.helper(function(params) { + return safe(timeInWords(params[0])); +}); diff --git a/app/helpers/format-message.coffee b/app/helpers/format-message.coffee deleted file mode 100644 index d7b84077..00000000 --- a/app/helpers/format-message.coffee +++ /dev/null @@ -1,7 +0,0 @@ -`import { formatMessage as _formatMessage, safe } from 'travis/utils/helpers'` -`import Ember from "ember"` - -helper = Ember.Helper.helper (params, hash) -> - safe _formatMessage(params[0], hash) - -`export default helper` diff --git a/app/helpers/format-message.js b/app/helpers/format-message.js new file mode 100644 index 00000000..bc5ebfdd --- /dev/null +++ b/app/helpers/format-message.js @@ -0,0 +1,6 @@ +import { formatMessage as _formatMessage, safe } from 'travis/utils/helpers'; +import Ember from "ember"; + +export default Ember.Helper.helper(function(params, hash) { + return safe(_formatMessage(params[0], hash)); +}); diff --git a/app/helpers/format-sha.coffee b/app/helpers/format-sha.coffee deleted file mode 100644 index 848379a2..00000000 --- a/app/helpers/format-sha.coffee +++ /dev/null @@ -1,7 +0,0 @@ -`import { formatSha as _formatSha, safe } from 'travis/utils/helpers'` -`import Ember from "ember"` - -helper = Ember.Helper.helper (params) -> - safe _formatSha(params[0]) - -`export default helper` diff --git a/app/helpers/format-sha.js b/app/helpers/format-sha.js new file mode 100644 index 00000000..c058413e --- /dev/null +++ b/app/helpers/format-sha.js @@ -0,0 +1,6 @@ +import { formatSha as _formatSha, safe } from 'travis/utils/helpers'; +import Ember from "ember"; + +export default Ember.Helper.helper(function(params) { + return safe(_formatSha(params[0])); +}); diff --git a/app/helpers/format-time.coffee b/app/helpers/format-time.coffee deleted file mode 100644 index fd404877..00000000 --- a/app/helpers/format-time.coffee +++ /dev/null @@ -1,7 +0,0 @@ -`import { timeAgoInWords, safe } from 'travis/utils/helpers'` -`import Ember from "ember"` - -helper = Ember.Helper.helper (params) -> - safe timeAgoInWords(params[0]) || '-' - -`export default helper` diff --git a/app/helpers/format-time.js b/app/helpers/format-time.js new file mode 100644 index 00000000..35ac9ce1 --- /dev/null +++ b/app/helpers/format-time.js @@ -0,0 +1,6 @@ +import { timeAgoInWords, safe } from 'travis/utils/helpers'; +import Ember from "ember"; + +export default Ember.Helper.helper(function(params) { + return safe(timeAgoInWords(params[0]) || '-'); +}); diff --git a/app/helpers/github-commit-link.coffee b/app/helpers/github-commit-link.coffee deleted file mode 100644 index 2b7bd197..00000000 --- a/app/helpers/github-commit-link.coffee +++ /dev/null @@ -1,14 +0,0 @@ -`import { formatCommit, safe } from 'travis/utils/helpers'` -`import { githubCommit as githubCommitUrl } from 'travis/utils/urls'` - -helper = Ember.Helper.helper (params) -> - slug = params[0] - commitSha = params[1] - return '' unless commitSha - sha = Ember.Handlebars.Utils.escapeExpression formatCommit(commitSha) - return sha unless slug - url = Ember.Handlebars.Utils.escapeExpression githubCommitUrl(slug, sha) - - safe '' + sha + '' - -`export default helper` diff --git a/app/helpers/github-commit-link.js b/app/helpers/github-commit-link.js new file mode 100644 index 00000000..569255c6 --- /dev/null +++ b/app/helpers/github-commit-link.js @@ -0,0 +1,18 @@ +import { formatCommit, safe } from 'travis/utils/helpers'; +import { githubCommit as githubCommitUrl } from 'travis/utils/urls'; + +export default Ember.Helper.helper(function(params) { + var commitSha, sha, slug, url; + + slug = params[0]; + commitSha = params[1]; + if (!commitSha) { + return ''; + } + sha = Ember.Handlebars.Utils.escapeExpression(formatCommit(commitSha)); + if (!slug) { + return sha; + } + url = Ember.Handlebars.Utils.escapeExpression(githubCommitUrl(slug, sha)); + return safe('' + sha + ''); +}); diff --git a/app/helpers/humanize-state.coffee b/app/helpers/humanize-state.coffee deleted file mode 100644 index 1a7989a4..00000000 --- a/app/helpers/humanize-state.coffee +++ /dev/null @@ -1,11 +0,0 @@ -`import { safe } from 'travis/utils/helpers'` -`import Ember from "ember"` - -helper = Ember.Helper.helper (params) -> - state = params[0] - if state == 'received' - 'booting' - else - state - -`export default helper` diff --git a/app/helpers/humanize-state.js b/app/helpers/humanize-state.js new file mode 100644 index 00000000..b0d09677 --- /dev/null +++ b/app/helpers/humanize-state.js @@ -0,0 +1,11 @@ +import { safe } from 'travis/utils/helpers'; +import Ember from "ember"; + +export default Ember.Helper.helper(function(params) { + var state = params[0]; + if (state === 'received') { + return 'booting'; + } else { + return state; + } +}); diff --git a/app/helpers/landing-page-last-build-time.coffee b/app/helpers/landing-page-last-build-time.coffee deleted file mode 100644 index 13373acd..00000000 --- a/app/helpers/landing-page-last-build-time.coffee +++ /dev/null @@ -1,7 +0,0 @@ -`import { timeAgoInWords, safe } from 'travis/utils/helpers'` -`import Ember from "ember"` - -helper = Ember.Helper.helper (params) -> - safe timeAgoInWords(params[0]) || 'currently running' - -`export default helper` diff --git a/app/helpers/landing-page-last-build-time.js b/app/helpers/landing-page-last-build-time.js new file mode 100644 index 00000000..b7e5526c --- /dev/null +++ b/app/helpers/landing-page-last-build-time.js @@ -0,0 +1,6 @@ +import { timeAgoInWords, safe } from 'travis/utils/helpers'; +import Ember from "ember"; + +export default Ember.Helper.helper(function(params) { + return safe(timeAgoInWords(params[0]) || 'currently running'); +}); diff --git a/app/helpers/pretty-date.coffee b/app/helpers/pretty-date.coffee deleted file mode 100644 index 5336ed5d..00000000 --- a/app/helpers/pretty-date.coffee +++ /dev/null @@ -1,7 +0,0 @@ -`import { timeAgoInWords, safe } from 'travis/utils/helpers'` -`import Ember from "ember"` - -helper = Ember.Helper.helper (params) -> - safe moment(params[0]).format('MMMM D, YYYY H:mm:ss') || '-' - -`export default helper` diff --git a/app/helpers/pretty-date.js b/app/helpers/pretty-date.js new file mode 100644 index 00000000..0f977651 --- /dev/null +++ b/app/helpers/pretty-date.js @@ -0,0 +1,6 @@ +import { timeAgoInWords, safe } from 'travis/utils/helpers'; +import Ember from "ember"; + +export default Ember.Helper.helper(function(params) { + return safe(moment(params[0]).format('MMMM D, YYYY H:mm:ss') || '-'); +}); diff --git a/app/helpers/short-compare-shas.coffee b/app/helpers/short-compare-shas.coffee deleted file mode 100644 index faa35ec7..00000000 --- a/app/helpers/short-compare-shas.coffee +++ /dev/null @@ -1,13 +0,0 @@ -`import { pathFrom } from 'travis/utils/helpers'` -`import Ember from "ember"` - -helper = Ember.Helper.helper (params) -> - url = params[0] - path = pathFrom(url) - if path.indexOf('...') >= 0 - shas = path.split('...') - "#{shas[0][0..6]}..#{shas[1][0..6]}" - else - path - -`export default helper` diff --git a/app/helpers/short-compare-shas.js b/app/helpers/short-compare-shas.js new file mode 100644 index 00000000..11ef7c07 --- /dev/null +++ b/app/helpers/short-compare-shas.js @@ -0,0 +1,14 @@ +import { pathFrom } from 'travis/utils/helpers'; +import Ember from "ember"; + +export default Ember.Helper.helper(function(params) { + var path, shas, url; + url = params[0]; + path = pathFrom(url); + if (path.indexOf('...') >= 0) { + shas = path.split('...'); + return shas[0].slice(0, 7) + ".." + shas[1].slice(0, 7); + } else { + return path; + } +}); diff --git a/app/helpers/travis-mb.coffee b/app/helpers/travis-mb.coffee deleted file mode 100644 index 58e14edd..00000000 --- a/app/helpers/travis-mb.coffee +++ /dev/null @@ -1,7 +0,0 @@ -`import Ember from "ember"` - -fn = (size) -> - if size - (size / 1024 / 1024).toFixed(2) - -`export default Ember.Helper.helper(fn)` diff --git a/app/helpers/travis-mb.js b/app/helpers/travis-mb.js new file mode 100644 index 00000000..e6478234 --- /dev/null +++ b/app/helpers/travis-mb.js @@ -0,0 +1,7 @@ +import Ember from "ember"; + +export default Ember.Helper.helper(function(size) { + if (size) { + return (size / 1024 / 1024).toFixed(2); + } +}); diff --git a/app/initializers/app.coffee b/app/initializers/app.coffee deleted file mode 100644 index dfb5ae06..00000000 --- a/app/initializers/app.coffee +++ /dev/null @@ -1,10 +0,0 @@ -initialize = (container, app) -> - if typeof window != 'undefined' - window.Travis = app - -Initializer = - name: 'app' - initialize: initialize - -`export {initialize}` -`export default Initializer` diff --git a/app/initializers/app.js b/app/initializers/app.js new file mode 100644 index 00000000..0d52f3a8 --- /dev/null +++ b/app/initializers/app.js @@ -0,0 +1,17 @@ +// Generated by CoffeeScript 1.10.0 +var Initializer, initialize; + +initialize = function(container, app) { + if (typeof window !== 'undefined') { + return window.Travis = app; + } +}; + +Initializer = { + name: 'app', + initialize: initialize +}; + +export {initialize}; + +export default Initializer; diff --git a/app/initializers/auth.coffee b/app/initializers/auth.coffee deleted file mode 100644 index 50e34625..00000000 --- a/app/initializers/auth.coffee +++ /dev/null @@ -1,16 +0,0 @@ -`import TestAuth from 'travis/utils/test-auth'` - -initialize = (container, app) -> - 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' - after: 'ember-data' - initialize: initialize - -`export {initialize}` -`export default AuthInitializer` diff --git a/app/initializers/auth.js b/app/initializers/auth.js new file mode 100644 index 00000000..2bc8f2f2 --- /dev/null +++ b/app/initializers/auth.js @@ -0,0 +1,21 @@ +// Generated by CoffeeScript 1.10.0 +import TestAuth from 'travis/utils/test-auth'; +var AuthInitializer, initialize; + +initialize = function(container, app) { + app.inject('route', 'auth', 'service:auth'); + app.inject('controller', 'auth', 'service:auth'); + app.inject('application', 'auth', 'service:auth'); + app.inject('component', 'auth', 'service:auth'); + return app.inject('service:flashes', 'auth', 'service:auth'); +}; + +AuthInitializer = { + name: 'auth', + after: 'ember-data', + initialize: initialize +}; + +export {initialize}; + +export default AuthInitializer; diff --git a/app/initializers/config.coffee b/app/initializers/config.coffee deleted file mode 100644 index f10eb95d..00000000 --- a/app/initializers/config.coffee +++ /dev/null @@ -1,14 +0,0 @@ -`import config from 'travis/config/environment'` - -initialize = (container, application) -> - application.register 'config:main', config, { instantiate: false } - - application.inject('controller', 'config', 'config:main') - application.inject('route', 'config', 'config:main') - -ConfigInitializer = - name: 'config' - initialize: initialize - -`export {initialize}` -`export default ConfigInitializer` diff --git a/app/initializers/config.js b/app/initializers/config.js new file mode 100644 index 00000000..50a0a0f7 --- /dev/null +++ b/app/initializers/config.js @@ -0,0 +1,20 @@ +// Generated by CoffeeScript 1.10.0 +import config from 'travis/config/environment'; +var ConfigInitializer, initialize; + +initialize = function(container, application) { + application.register('config:main', config, { + instantiate: false + }); + application.inject('controller', 'config', 'config:main'); + return application.inject('route', 'config', 'config:main'); +}; + +ConfigInitializer = { + name: 'config', + initialize: initialize +}; + +export {initialize}; + +export default ConfigInitializer; diff --git a/app/initializers/google-analytics.coffee b/app/initializers/google-analytics.coffee deleted file mode 100644 index 3ed8725f..00000000 --- a/app/initializers/google-analytics.coffee +++ /dev/null @@ -1,20 +0,0 @@ -`import config from 'travis/config/environment'` - -initialize = (container) -> - if config.gaCode - window._gaq = [] - _gaq.push(['_setAccount', config.gaCode]) - - ga = document.createElement('script') - ga.type = 'text/javascript' - ga.async = true - ga.src = 'https://ssl.google-analytics.com/ga.js' - s = document.getElementsByTagName('script')[0] - s.parentNode.insertBefore(ga, s) - -GAInitializer = - name: 'google-analytics' - initialize: initialize - -`export {initialize}` -`export default GAInitializer` diff --git a/app/initializers/google-analytics.js b/app/initializers/google-analytics.js new file mode 100644 index 00000000..084fdf95 --- /dev/null +++ b/app/initializers/google-analytics.js @@ -0,0 +1,26 @@ +// Generated by CoffeeScript 1.10.0 +import config from 'travis/config/environment'; +var GAInitializer, initialize; + +initialize = function(container) { + var ga, s; + if (config.gaCode) { + window._gaq = []; + _gaq.push(['_setAccount', config.gaCode]); + ga = document.createElement('script'); + ga.type = 'text/javascript'; + ga.async = true; + ga.src = 'https://ssl.google-analytics.com/ga.js'; + s = document.getElementsByTagName('script')[0]; + return s.parentNode.insertBefore(ga, s); + } +}; + +GAInitializer = { + name: 'google-analytics', + initialize: initialize +}; + +export {initialize}; + +export default GAInitializer; diff --git a/app/initializers/location.coffee b/app/initializers/location.coffee deleted file mode 100644 index 1177e5dd..00000000 --- a/app/initializers/location.coffee +++ /dev/null @@ -1,11 +0,0 @@ -`import TravisLocation from 'travis/utils/location'` - -initialize = (container, application) -> - application.register 'location:travis', TravisLocation - -Initializer = - name: 'location' - initialize: initialize - -`export { initialize }` -`export default Initializer` diff --git a/app/initializers/location.js b/app/initializers/location.js new file mode 100644 index 00000000..160e47b7 --- /dev/null +++ b/app/initializers/location.js @@ -0,0 +1,16 @@ +// Generated by CoffeeScript 1.10.0 +import TravisLocation from 'travis/utils/location'; +var Initializer, initialize; + +initialize = function(container, application) { + return application.register('location:travis', TravisLocation); +}; + +Initializer = { + name: 'location', + initialize: initialize +}; + +export { initialize }; + +export default Initializer; diff --git a/app/initializers/pusher.coffee b/app/initializers/pusher.coffee deleted file mode 100644 index 920c3e88..00000000 --- a/app/initializers/pusher.coffee +++ /dev/null @@ -1,13 +0,0 @@ -`import config from 'travis/config/environment'` -`import TravisPusher from 'travis/utils/pusher'` - -initialize = (registry, application) -> - null - -PusherInitializer = - name: 'pusher' - after: 'ember-data' - initialize: initialize - -`export {initialize}` -`export default PusherInitializer` diff --git a/app/initializers/pusher.js b/app/initializers/pusher.js new file mode 100644 index 00000000..110bf843 --- /dev/null +++ b/app/initializers/pusher.js @@ -0,0 +1,18 @@ +// Generated by CoffeeScript 1.10.0 +import config from 'travis/config/environment'; +import TravisPusher from 'travis/utils/pusher'; +var PusherInitializer, initialize; + +initialize = function(registry, application) { + return null; +}; + +PusherInitializer = { + name: 'pusher', + after: 'ember-data', + initialize: initialize +}; + +export {initialize}; + +export default PusherInitializer; diff --git a/app/initializers/services.coffee b/app/initializers/services.coffee deleted file mode 100644 index ce0f365b..00000000 --- a/app/initializers/services.coffee +++ /dev/null @@ -1,14 +0,0 @@ -`import Tailing from 'travis/utils/tailing'` -`import ToTop from 'travis/utils/to-top'` -`import config from 'travis/config/environment'` - -initialize = (container, application) -> - application.tailing = new Tailing($(window), '#tail', '#log') - application.toTop = new ToTop($(window), '.to-top', '#log-container') - -Initializer = - name: 'services' - initialize: initialize - -`export {initialize}` -`export default Initializer` diff --git a/app/initializers/services.js b/app/initializers/services.js new file mode 100644 index 00000000..ce09c34a --- /dev/null +++ b/app/initializers/services.js @@ -0,0 +1,19 @@ +// Generated by CoffeeScript 1.10.0 +import Tailing from 'travis/utils/tailing'; +import ToTop from 'travis/utils/to-top'; +import config from 'travis/config/environment'; +var Initializer, initialize; + +initialize = function(container, application) { + application.tailing = new Tailing($(window), '#tail', '#log'); + return application.toTop = new ToTop($(window), '.to-top', '#log-container'); +}; + +Initializer = { + name: 'services', + initialize: initialize +}; + +export {initialize}; + +export default Initializer; diff --git a/app/initializers/stylesheets-manager.coffee b/app/initializers/stylesheets-manager.coffee deleted file mode 100644 index 6b49760a..00000000 --- a/app/initializers/stylesheets-manager.coffee +++ /dev/null @@ -1,18 +0,0 @@ -stylesheetsManager = Ember.Object.create - enable: (id) -> - $("##{id}").removeAttr('disabled') - - disable: (id) -> - $("##{id}").attr('disabled', 'disabled') - -initialize = (container, application) -> - application.register 'stylesheetsManager:main', stylesheetsManager, { instantiate: false } - - application.inject('route', 'stylesheetsManager', 'stylesheetsManager:main') - -StylesheetsManagerInitializer = - name: 'inject-stylesheets-manager' - initialize: initialize - -`export {initialize}` -`export default StylesheetsManagerInitializer` diff --git a/app/initializers/stylesheets-manager.js b/app/initializers/stylesheets-manager.js new file mode 100644 index 00000000..e79add9c --- /dev/null +++ b/app/initializers/stylesheets-manager.js @@ -0,0 +1,27 @@ +// Generated by CoffeeScript 1.10.0 +var StylesheetsManagerInitializer, initialize, stylesheetsManager; + +stylesheetsManager = Ember.Object.create({ + enable: function(id) { + return $("#" + id).removeAttr('disabled'); + }, + disable: function(id) { + return $("#" + id).attr('disabled', 'disabled'); + } +}); + +initialize = function(container, application) { + application.register('stylesheetsManager:main', stylesheetsManager, { + instantiate: false + }); + return application.inject('route', 'stylesheetsManager', 'stylesheetsManager:main'); +}; + +StylesheetsManagerInitializer = { + name: 'inject-stylesheets-manager', + initialize: initialize +}; + +export {initialize}; + +export default StylesheetsManagerInitializer; diff --git a/app/initializers/userlike.coffee b/app/initializers/userlike.coffee deleted file mode 100644 index e1c02e57..00000000 --- a/app/initializers/userlike.coffee +++ /dev/null @@ -1,13 +0,0 @@ -`import config from 'travis/config/environment'` - -initialize = (container) -> - - - userlikeData = {} - -UserlikeInitializer = - name: 'userlike' - initialize: initialize - -`export {initialize}` -`export default UserlikeInitializer` diff --git a/app/initializers/userlike.js b/app/initializers/userlike.js new file mode 100644 index 00000000..360012a1 --- /dev/null +++ b/app/initializers/userlike.js @@ -0,0 +1,17 @@ +// Generated by CoffeeScript 1.10.0 +import config from 'travis/config/environment'; +var UserlikeInitializer, initialize; + +initialize = function(container) { + var userlikeData; + return userlikeData = {}; +}; + +UserlikeInitializer = { + name: 'userlike', + initialize: initialize +}; + +export {initialize}; + +export default UserlikeInitializer; diff --git a/app/instance-initializers/pusher.coffee b/app/instance-initializers/pusher.coffee deleted file mode 100644 index 9afd0788..00000000 --- a/app/instance-initializers/pusher.coffee +++ /dev/null @@ -1,22 +0,0 @@ -`import config from 'travis/config/environment'` -`import TravisPusher from 'travis/utils/pusher'` - -initialize = (data) -> - 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' - after: 'ember-data' - initialize: initialize - -`export {initialize}` -`export default PusherInitializer` diff --git a/app/instance-initializers/pusher.js b/app/instance-initializers/pusher.js new file mode 100644 index 00000000..c969ab91 --- /dev/null +++ b/app/instance-initializers/pusher.js @@ -0,0 +1,26 @@ +import config from 'travis/config/environment'; +import TravisPusher from 'travis/utils/pusher'; +var PusherInitializer, initialize; + +initialize = function(data) { + var application; + 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'); + return application.pusher.store = data.container.lookup('service:store'); + } +}; + +PusherInitializer = { + name: 'pusher', + after: 'ember-data', + initialize: initialize +}; + +export {initialize}; + +export default PusherInitializer; diff --git a/app/mixins/build-favicon.coffee b/app/mixins/build-favicon.coffee deleted file mode 100644 index 1d7bbed2..00000000 --- a/app/mixins/build-favicon.coffee +++ /dev/null @@ -1,30 +0,0 @@ -`import Ember from 'ember'` -`import { colorForState } from 'travis/utils/helpers'` -`import FaviconManager from 'travis/utils/favicon-manager'` -`import getFaviconUri from 'travis/utils/favicon-data-uris'` - -Mixin = Ember.Mixin.create - actions: - faviconStateDidChange: (state) -> - if state - @setFaviconForState(state) - else - @setDefault() - - init: -> - @faviconManager = new FaviconManager() - - @_super.apply this, arguments - - setFaviconForState: (state) -> - color = colorForState(state) - - @setFavicon(getFaviconUri(color)) - - setDefault: -> - @setFavicon(getFaviconUri('default')) - - setFavicon: (href) -> - @faviconManager.setFavicon(href) - -`export default Mixin` diff --git a/app/mixins/build-favicon.js b/app/mixins/build-favicon.js new file mode 100644 index 00000000..86a51dc9 --- /dev/null +++ b/app/mixins/build-favicon.js @@ -0,0 +1,35 @@ +import Ember from 'ember'; +import { colorForState } from 'travis/utils/helpers'; +import FaviconManager from 'travis/utils/favicon-manager'; +import getFaviconUri from 'travis/utils/favicon-data-uris'; + +export default Ember.Mixin.create({ + actions: { + faviconStateDidChange(state) { + if (state) { + return this.setFaviconForState(state); + } else { + return this.setDefault(); + } + } + }, + + init() { + this.faviconManager = new FaviconManager(); + return this._super.apply(this, arguments); + }, + + setFaviconForState(state) { + var color; + color = colorForState(state); + return this.setFavicon(getFaviconUri(color)); + }, + + setDefault() { + return this.setFavicon(getFaviconUri('default')); + }, + + setFavicon(href) { + return this.faviconManager.setFavicon(href); + } +}); diff --git a/app/mixins/github-url-properties.coffee b/app/mixins/github-url-properties.coffee deleted file mode 100644 index 76bc191c..00000000 --- a/app/mixins/github-url-properties.coffee +++ /dev/null @@ -1,12 +0,0 @@ -`import { githubCommit, githubPullRequest } from 'travis/utils/urls'` - -mixin = Ember.Mixin.create - urlGithubCommit: (-> - githubCommit(@get('repo.slug'), @get('commit.sha')) - ).property('repo.slug', 'commit.sha') - - urlGithubPullRequest: (-> - githubPullRequest(@get('repo.slug'), @get('build.pullRequestNumber')) - ).property('repo.slug', 'build.pullRequestNumber') - -`export default mixin` diff --git a/app/mixins/github-url-properties.js b/app/mixins/github-url-properties.js new file mode 100644 index 00000000..97b7a544 --- /dev/null +++ b/app/mixins/github-url-properties.js @@ -0,0 +1,11 @@ +import { githubCommit, githubPullRequest } from 'travis/utils/urls'; + +export default Ember.Mixin.create({ + urlGithubCommit: function() { + return githubCommit(this.get('repo.slug'), this.get('commit.sha')); + }.property('repo.slug', 'commit.sha'), + + urlGithubPullRequest: function() { + return githubPullRequest(this.get('repo.slug'), this.get('build.pullRequestNumber')); + }.property('repo.slug', 'build.pullRequestNumber') +}); diff --git a/app/mixins/polling.coffee b/app/mixins/polling.coffee deleted file mode 100644 index f68d3fa7..00000000 --- a/app/mixins/polling.coffee +++ /dev/null @@ -1,61 +0,0 @@ -`import Ember from 'ember'` - -mixin = Ember.Mixin.create - polling: Ember.inject.service() - - didInsertElement: -> - @_super.apply(this, arguments) - - @startPolling() - - willDestroyElement: -> - @_super.apply(this, arguments) - - @stopPolling() - - pollModelDidChange: (sender, key, value) -> - @pollModel(key) - - pollModelWillChange: (sender, key, value) -> - @stopPollingModel(key) - - pollModel: (property) -> - addToPolling = (model) => - @get('polling').startPolling(model) - - if model = @get(property) - if model.then - model.then (resolved) -> - addToPolling(resolved) - else - addToPolling(model) - - stopPollingModel: (property) -> - if model = @get(property) - @get('polling').stopPolling(model) - - startPolling: -> - pollModels = @get('pollModels') - - if pollModels - pollModels = [pollModels] unless Ember.isArray(pollModels) - - pollModels.forEach (property) => - @pollModel(property) - @addObserver(property, this, 'pollModelDidChange') - Ember.addBeforeObserver(this, property, this, 'pollModelWillChange') - - @get('polling').startPollingHook(this) if @pollHook - - stopPolling: -> - if pollModels = @get('pollModels') - pollModels = [pollModels] unless Ember.isArray(pollModels) - - pollModels.forEach (property) => - @stopPollingModel(property) - @removeObserver(property, this, 'pollModelDidChange') - Ember.removeBeforeObserver(this, property, this, 'pollModelWillChange') - - @get('polling').stopPollingHook(this) - -`export default mixin` diff --git a/app/mixins/polling.js b/app/mixins/polling.js new file mode 100644 index 00000000..f502fe07 --- /dev/null +++ b/app/mixins/polling.js @@ -0,0 +1,79 @@ +import Ember from 'ember'; + +export default Ember.Mixin.create({ + polling: Ember.inject.service(), + + didInsertElement() { + this._super.apply(this, arguments); + return this.startPolling(); + }, + + willDestroyElement() { + this._super.apply(this, arguments); + return this.stopPolling(); + }, + + pollModelDidChange(sender, key, value) { + return this.pollModel(key); + }, + + pollModelWillChange(sender, key, value) { + return this.stopPollingModel(key); + }, + + pollModel(property) { + var addToPolling, model; + addToPolling = () => { + return this.get('polling').startPolling(model); + }; + if (model = this.get(property)) { + if (model.then) { + return model.then(function(resolved) { + return addToPolling(resolved); + }); + } else { + return addToPolling(model); + } + } + }, + + stopPollingModel(property) { + var model; + if (model = this.get(property)) { + return this.get('polling').stopPolling(model); + } + }, + + startPolling() { + var pollModels; + pollModels = this.get('pollModels'); + if (pollModels) { + if (!Ember.isArray(pollModels)) { + pollModels = [pollModels]; + } + pollModels.forEach(() => { + this.pollModel(property); + this.addObserver(property, this, 'pollModelDidChange'); + return Ember.addBeforeObserver(this, property, this, 'pollModelWillChange'); + }); + } + if (this.pollHook) { + return this.get('polling').startPollingHook(this); + } + }, + + stopPolling() { + var pollModels; + if (pollModels = this.get('pollModels')) { + if (!Ember.isArray(pollModels)) { + pollModels = [pollModels]; + } + pollModels.forEach(() => { + this.stopPollingModel(property); + this.removeObserver(property, this, 'pollModelDidChange'); + return Ember.removeBeforeObserver(this, property, this, 'pollModelWillChange'); + }); + } + return this.get('polling').stopPollingHook(this); + } +}); diff --git a/app/models/account.coffee b/app/models/account.coffee deleted file mode 100644 index 5ace3ea6..00000000 --- a/app/models/account.coffee +++ /dev/null @@ -1,13 +0,0 @@ -`import Ember from 'ember'` -`import Model from 'travis/models/model'` - -Account = Model.extend - name: DS.attr() - type: DS.attr() - avatarUrl: DS.attr() - reposCount: DS.attr('number') - subscribed: DS.attr('boolean') - education: DS.attr('boolean') - loginBinding: 'id' - -`export default Account` diff --git a/app/models/account.js b/app/models/account.js new file mode 100644 index 00000000..f947a301 --- /dev/null +++ b/app/models/account.js @@ -0,0 +1,12 @@ +import Ember from 'ember'; +import Model from 'travis/models/model'; + +export default Model.extend({ + name: DS.attr(), + type: DS.attr(), + avatarUrl: DS.attr(), + reposCount: DS.attr('number'), + subscribed: DS.attr('boolean'), + education: DS.attr('boolean'), + loginBinding: 'id' +}); diff --git a/app/models/annotation.coffee b/app/models/annotation.coffee deleted file mode 100644 index 000bd85d..00000000 --- a/app/models/annotation.coffee +++ /dev/null @@ -1,13 +0,0 @@ -`import Ember from 'ember'` -`import Model from 'travis/models/model'` - -Annotation = Model.extend - jobId: DS.attr('number') - description: DS.attr() - url: DS.attr() - status: DS.attr() - providerName: DS.attr() - - job: DS.belongsTo('job') - -`export default Annotation` diff --git a/app/models/branch.coffee b/app/models/branch.coffee deleted file mode 100644 index 3a8e6405..00000000 --- a/app/models/branch.coffee +++ /dev/null @@ -1,12 +0,0 @@ -`import Ember from 'ember'` -`import Model from 'travis/models/model'` - -Branch = Model.extend - name: DS.attr('string') - defaultBranch: DS.attr('boolean') - - lastBuild: DS.belongsTo('build') - builds: DS.hasMany('builds', inverse: 'branch') - repo: DS.belongsTo('repo', inverse: 'defaultBranch') - -`export default Branch` diff --git a/app/models/branch.js b/app/models/branch.js new file mode 100644 index 00000000..d33357fe --- /dev/null +++ b/app/models/branch.js @@ -0,0 +1,11 @@ +import Ember from 'ember'; +import Model from 'travis/models/model'; + +export default Model.extend({ + name: DS.attr('string'), + defaultBranch: DS.attr('boolean'), + lastBuild: DS.belongsTo('build'), + + builds: DS.hasMany('builds', { inverse: 'branch' }), + repo: DS.belongsTo('repo', { inverse: 'defaultBranch' }) +}); diff --git a/app/models/broadcast.coffee b/app/models/broadcast.coffee deleted file mode 100644 index d4895b3b..00000000 --- a/app/models/broadcast.coffee +++ /dev/null @@ -1,29 +0,0 @@ -`import Ember from 'ember'` -`import Model from 'travis/models/model'` - -Broadcast = Model.extend - message: DS.attr() - - toObject: -> - { type: 'broadcast', id: @get('id'), message: @get('message') } - - isSeen: (-> - @get('id') in Ember.get(Broadcast, 'seen') - ).property() - - setSeen: -> - Ember.get(Broadcast, 'seen').pushObject(@get('id')) - Travis.storage.setItem('travis.seen_broadcasts', JSON.stringify(Ember.get(Broadcast, 'seen'))) - @notifyPropertyChange('isSeen') - -Broadcast.reopenClass - seen: (-> - seenBroadcasts = Travis.lookup('service:storage').getItem('travis.seen_broadcasts') - seenBroadcasts = JSON.parse(seenBroadcasts) if seenBroadcasts? - Ember.A(seenBroadcasts || []) - ).property() - - # TODO fix or monkey-patch the adapter's url and key lookup/generation crap - # url: 'users/broadcasts' - -`export default Broadcast` diff --git a/app/models/broadcast.js b/app/models/broadcast.js new file mode 100644 index 00000000..ee195cd1 --- /dev/null +++ b/app/models/broadcast.js @@ -0,0 +1,38 @@ +import Ember from 'ember'; +import Model from 'travis/models/model'; + +var indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; + +export default Model.extend({ + message: DS.attr(), + + toObject() { + return { + type: 'broadcast', + id: this.get('id'), + message: this.get('message') + }; + }, + + isSeen: function() { + var ref; + return ref = this.get('id'), indexOf.call(Ember.get(Broadcast, 'seen'), ref) >= 0; + }.property(), + + setSeen() { + Ember.get(Broadcast, 'seen').pushObject(this.get('id')); + Travis.storage.setItem('travis.seen_broadcasts', JSON.stringify(Ember.get(Broadcast, 'seen'))); + return this.notifyPropertyChange('isSeen'); + } +}); + +Broadcast.reopenClass({ + seen: function() { + var seenBroadcasts; + seenBroadcasts = Travis.lookup('service:storage').getItem('travis.seen_broadcasts'); + if (seenBroadcasts != null) { + seenBroadcasts = JSON.parse(seenBroadcasts); + } + return Ember.A(seenBroadcasts || []); + }.property() +}); diff --git a/app/models/build.coffee b/app/models/build.coffee deleted file mode 100644 index 08d9d04e..00000000 --- a/app/models/build.coffee +++ /dev/null @@ -1,105 +0,0 @@ -`import { durationFrom, configKeys, compact } from 'travis/utils/helpers'` -`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') - message: DS.attr('string') - _duration: DS.attr('number') - _config: DS.attr('object') - _startedAt: DS.attr() - _finishedAt: DS.attr('string') - pullRequest: DS.attr('boolean') - pullRequestTitle: DS.attr() - pullRequestNumber: DS.attr('number') - eventType: DS.attr('string') - - branch: DS.belongsTo('branch', async: false, inverse: 'builds') - repo: DS.belongsTo('repo', async: true) - commit: DS.belongsTo('commit', async: false) - jobs: DS.hasMany('job', async: true) - - config: (-> - if config = @get('_config') - compact(config) - else if @get('currentState.stateName') != 'root.loading' - return if @get('isFetchingConfig') - @set 'isFetchingConfig', true - - @reload() - ).property('_config') - - isPullRequest: (-> - @get('eventType') == 'pull_request' || @get('pullRequest') - ).property('eventType') - - isMatrix: (-> - @get('jobs.length') > 1 - ).property('jobs.length') - - isFinished: (-> - @get('state') in ['passed', 'failed', 'errored', 'canceled'] - ).property('state') - - notStarted: (-> - @get('state') in ['queued', 'created', 'received'] - ).property('state') - - startedAt: (-> - unless @get('notStarted') - @get('_startedAt') - ).property('_startedAt', 'notStarted') - - finishedAt: (-> - unless @get('notStarted') - @get('_finishedAt') - ).property('_finishedAt', 'notStarted') - - requiredJobs: (-> - @get('jobs').filter (data) -> !data.get('allowFailure') - ).property('jobs.@each.allowFailure') - - allowedFailureJobs: (-> - @get('jobs').filter (data) -> data.get('allowFailure') - ).property('jobs.@each.allowFailure') - - rawConfigKeys: (-> - keys = [] - - @get('jobs').forEach (job) -> - configKeys(job.get('config')).forEach (key) -> - keys.pushObject key unless keys.contains key - - keys - ).property('config', 'jobs.@each.config') - - configKeys: (-> - keys = @get('rawConfigKeys') - headers = ['Job', 'Duration', 'Finished'] - $.map(headers.concat(keys), (key) -> if configKeysMap.hasOwnProperty(key) then configKeysMap[key] else key) - ).property('rawConfigKeys.length') - - canCancel: (-> - @get('jobs').filterBy('canCancel').length - ).property('jobs.@each.canCancel') - - canRestart: Ember.computed.alias('isFinished') - - cancel: (-> - @get('ajax').post "/builds/#{@get('id')}/cancel" - ) - - restart: -> - @get('ajax').post "/builds/#{@get('id')}/restart" - - formattedFinishedAt: (-> - if finishedAt = @get('finishedAt') - moment(finishedAt).format('lll') - ).property('finishedAt') - -`export default Build` diff --git a/app/models/build.js b/app/models/build.js new file mode 100644 index 00000000..64e91f2a --- /dev/null +++ b/app/models/build.js @@ -0,0 +1,126 @@ +import { durationFrom, configKeys, compact } from 'travis/utils/helpers'; +import configKeysMap from 'travis/utils/keys-map'; +import Ember from 'ember'; +import Model from 'travis/models/model'; +import DurationCalculations from 'travis/utils/duration-calculations'; + +export default Model.extend(DurationCalculations, { + ajax: Ember.inject.service(), + state: DS.attr(), + number: DS.attr('number'), + message: DS.attr('string'), + _duration: DS.attr('number'), + _config: DS.attr('object'), + _startedAt: DS.attr(), + _finishedAt: DS.attr('string'), + pullRequest: DS.attr('boolean'), + pullRequestTitle: DS.attr(), + pullRequestNumber: DS.attr('number'), + eventType: DS.attr('string'), + branch: DS.belongsTo('branch', { async: false, inverse: 'builds' }), + repo: DS.belongsTo('repo', { async: true }), + commit: DS.belongsTo('commit', { async: false }), + jobs: DS.hasMany('job', { async: true }), + + config: function() { + var config; + if (config = this.get('_config')) { + return compact(config); + } else if (this.get('currentState.stateName') !== 'root.loading') { + if (this.get('isFetchingConfig')) { + return; + } + this.set('isFetchingConfig', true); + return this.reload(); + } + }.property('_config'), + + isPullRequest: function() { + return this.get('eventType') === 'pull_request' || this.get('pullRequest'); + }.property('eventType'), + + isMatrix: function() { + return this.get('jobs.length') > 1; + }.property('jobs.length'), + + isFinished: function() { + var ref; + return (ref = this.get('state')) === 'passed' || ref === 'failed' || ref === 'errored' || ref === 'canceled'; + }.property('state'), + + notStarted: function() { + var ref; + return (ref = this.get('state')) === 'queued' || ref === 'created' || ref === 'received'; + }.property('state'), + + startedAt: function() { + if (!this.get('notStarted')) { + return this.get('_startedAt'); + } + }.property('_startedAt', 'notStarted'), + + finishedAt: function() { + if (!this.get('notStarted')) { + return this.get('_finishedAt'); + } + }.property('_finishedAt', 'notStarted'), + + requiredJobs: function() { + return this.get('jobs').filter(function(data) { + return !data.get('allowFailure'); + }); + }.property('jobs.@each.allowFailure'), + + allowedFailureJobs: function() { + return this.get('jobs').filter(function(data) { + return data.get('allowFailure'); + }); + }.property('jobs.@each.allowFailure'), + + rawConfigKeys: function() { + var keys; + keys = []; + this.get('jobs').forEach(function(job) { + return configKeys(job.get('config')).forEach(function(key) { + if (!keys.contains(key)) { + return keys.pushObject(key); + } + }); + }); + return keys; + }.property('config', 'jobs.@each.config'), + + configKeys: function() { + var headers, keys; + keys = this.get('rawConfigKeys'); + headers = ['Job', 'Duration', 'Finished']; + return $.map(headers.concat(keys), function(key) { + if (configKeysMap.hasOwnProperty(key)) { + return configKeysMap[key]; + } else { + return key; + } + }); + }.property('rawConfigKeys.length'), + + canCancel: function() { + return this.get('jobs').filterBy('canCancel').length; + }.property('jobs.@each.canCancel'), + + canRestart: Ember.computed.alias('isFinished'), + + cancel() { + return this.get('ajax').post("/builds/" + (this.get('id')) + "/cancel"); + }, + + restart() { + return this.get('ajax').post("/builds/" + (this.get('id')) + "/restart"); + }, + + formattedFinishedAt: function() { + var finishedAt; + if (finishedAt = this.get('finishedAt')) { + return moment(finishedAt).format('lll'); + } + }.property('finishedAt') +}); diff --git a/app/models/commit.coffee b/app/models/commit.coffee deleted file mode 100644 index e942b42e..00000000 --- a/app/models/commit.coffee +++ /dev/null @@ -1,54 +0,0 @@ -`import Ember from 'ember'` -`import Model from 'travis/models/model'` -`import Build from 'travis/models/build'` -`import { gravatarImage } from 'travis/utils/urls'` - -Commit = Model.extend - sha: DS.attr() - branch: DS.attr() - message: DS.attr() - compareUrl: DS.attr() - authorName: DS.attr() - authorEmail: DS.attr() - committerName: DS.attr() - committerEmail: DS.attr() - committedAt: DS.attr() - committerAvatarUrl: DS.attr() - authorAvatarUrl: DS.attr() - - build: DS.belongsTo('build') - - subject: ( -> - @get('message').split("\n", 1)[0] - ).property('message') - - body: ( -> - message = @get('message') - if message.indexOf("\n") > 0 - message.substr(message.indexOf("\n") + 1).trim() - else - "" - ).property('message') - - authorIsCommitter: ( -> - @get('authorName') == @get('committerName') and - @get('authorEmail') == @get('committerEmail') - ).property('authorName', 'authorEmail', 'committerName', 'committerEmail') - - authorAvatarUrlOrGravatar: (-> - if url = @get('authorAvatarUrl') - url - else - email = @get('authorEmail') - gravatarImage(email, 40) - ).property('authorEmail', 'authorAvatarUrl') - - committerAvatarUrlOrGravatar: (-> - if url = @get('committerAvatarUrl') - url - else - email = @get('committerEmail') - gravatarImage(email, 40) - ).property('committerEmail', 'committerAvatarUrl') - -`export default Commit` diff --git a/app/models/commit.js b/app/models/commit.js new file mode 100644 index 00000000..e1bb2c89 --- /dev/null +++ b/app/models/commit.js @@ -0,0 +1,58 @@ +import Ember from 'ember'; +import Model from 'travis/models/model'; +import Build from 'travis/models/build'; +import { gravatarImage } from 'travis/utils/urls'; + +export default Model.extend({ + sha: DS.attr(), + branch: DS.attr(), + message: DS.attr(), + compareUrl: DS.attr(), + authorName: DS.attr(), + authorEmail: DS.attr(), + committerName: DS.attr(), + committerEmail: DS.attr(), + committedAt: DS.attr(), + committerAvatarUrl: DS.attr(), + authorAvatarUrl: DS.attr(), + + build: DS.belongsTo('build'), + + subject: function() { + return this.get('message').split("\n", 1)[0]; + }.property('message'), + + body: function() { + var message; + message = this.get('message'); + if (message.indexOf("\n") > 0) { + return message.substr(message.indexOf("\n") + 1).trim(); + } else { + return ""; + } + }.property('message'), + + authorIsCommitter: function() { + return this.get('authorName') === this.get('committerName') && this.get('authorEmail') === this.get('committerEmail'); + }.property('authorName', 'authorEmail', 'committerName', 'committerEmail'), + + authorAvatarUrlOrGravatar: function() { + var url = this.get('authorAvatarUrl'); + + if(!url) { + url = gravatarImage(this.get('authorEmail'), 40); + } + + return url; + }.property('authorEmail', 'authorAvatarUrl'), + + committerAvatarUrlOrGravatar: function() { + var url = this.get('committerAvatarUrl'); + + if(!url) { + url = gravatarImage(this.get('committerEmail'), 40); + } + + return url; + }.property('committerEmail', 'committerAvatarUrl') +}); diff --git a/app/models/env-var.coffee b/app/models/env-var.coffee deleted file mode 100644 index 3d383347..00000000 --- a/app/models/env-var.coffee +++ /dev/null @@ -1,11 +0,0 @@ -`import Ember from 'ember'` -`import Model from 'travis/models/model'` - -EnvVar = Model.extend - name: DS.attr() - value: DS.attr() - public: DS.attr('boolean') - - repo: DS.belongsTo('repo', async: true) - -`export default EnvVar` diff --git a/app/models/env-var.js b/app/models/env-var.js new file mode 100644 index 00000000..f8d8d175 --- /dev/null +++ b/app/models/env-var.js @@ -0,0 +1,9 @@ +import Ember from 'ember'; +import Model from 'travis/models/model'; + +export default Model.extend({ + name: DS.attr(), + value: DS.attr(), + "public": DS.attr('boolean'), + repo: DS.belongsTo('repo', { async: true }) +}); diff --git a/app/models/hook.coffee b/app/models/hook.coffee deleted file mode 100644 index 8f83f3e2..00000000 --- a/app/models/hook.coffee +++ /dev/null @@ -1,34 +0,0 @@ -`import Ember from 'ember'` -`import Model from 'travis/models/model'` -`import config from 'travis/config/environment'` - -Hook = Model.extend - name: DS.attr() - ownerName: DS.attr() - description: DS.attr() - active: DS.attr('boolean') - admin: DS.attr('boolean') - private: DS.attr('boolean') - - account: (-> - @get('slug').split('/')[0] - ).property('slug') - - slug: (-> - "#{@get('ownerName')}/#{@get('name')}" - ).property('ownerName', 'name') - - urlGithub: (-> - "#{config.sourceEndpoint}/#{@get('slug')}" - ).property() - - urlGithubAdmin: (-> - "#{config.sourceEndpoint}/#{@get('slug')}/settings/hooks#travis_minibucket" - ).property() - - toggle: -> - return if @get('isSaving') - @set 'active', !@get('active') - @save() - -`export default Hook` diff --git a/app/models/hook.js b/app/models/hook.js new file mode 100644 index 00000000..5c8075a1 --- /dev/null +++ b/app/models/hook.js @@ -0,0 +1,36 @@ +import Ember from 'ember'; +import Model from 'travis/models/model'; +import config from 'travis/config/environment'; + +export default Model.extend({ + name: DS.attr(), + ownerName: DS.attr(), + description: DS.attr(), + active: DS.attr('boolean'), + admin: DS.attr('boolean'), + "private": DS.attr('boolean'), + + account: function() { + return this.get('slug').split('/')[0]; + }.property('slug'), + + slug: function() { + return (this.get('ownerName')) + "/" + (this.get('name')); + }.property('ownerName', 'name'), + + urlGithub: function() { + return config.sourceEndpoint + "/" + (this.get('slug')); + }.property(), + + urlGithubAdmin: function() { + return config.sourceEndpoint + "/" + (this.get('slug')) + "/settings/hooks#travis_minibucket"; + }.property(), + + toggle() { + if (this.get('isSaving')) { + return; + } + this.set('active', !this.get('active')); + return this.save(); + } +}); diff --git a/app/models/job.coffee b/app/models/job.coffee deleted file mode 100644 index b1cd747a..00000000 --- a/app/models/job.coffee +++ /dev/null @@ -1,160 +0,0 @@ -`import { durationFrom, configKeys, compact } from 'travis/utils/helpers'` -`import configKeysMap from 'travis/utils/keys-map'` -`import Ember from 'ember'` -`import Model from 'travis/models/model'` -`import Log from 'travis/models/log'` -`import DurationCalculations from 'travis/utils/duration-calculations'` - -Job = Model.extend DurationCalculations, - ajax: Ember.inject.service() - logId: DS.attr() - - queue: DS.attr() - state: DS.attr() - number: DS.attr() - _startedAt: DS.attr() - _finishedAt: DS.attr() - allowFailure: DS.attr('boolean') - tags: DS.attr() - - repositoryPrivate: DS.attr() - - repositorySlug: DS.attr() - repo: DS.belongsTo('repo', async: true) - 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, ajax: @get('ajax')) - ).property() - - startedAt: (-> - unless @get('notStarted') - @get('_startedAt') - ).property('_startedAt', 'notStarted') - - finishedAt: (-> - unless @get('notStarted') - @get('_finishedAt') - ).property('_finishedAt', 'notStarted') - - repoSlug: (-> - @get('repositorySlug') - ).property('repositorySlug') - - config: (-> - if config = @get('_config') - compact(config) - else if @get('currentState.stateName') != 'root.loading' - return if @get('isFetchingConfig') - @set 'isFetchingConfig', true - - @reload() - ).property('_config') - - isFinished: (-> - @get('state') in ['passed', 'failed', 'errored', 'canceled'] - ).property('state') - - notStarted: (-> - @get('state') in ['queued', 'created', 'received'] - ).property('state') - - clearLog: -> - # This is needed if we don't want to fetch log just to clear it - if @get('isLogAccessed') - @get('log').clear() - - sponsor: (-> - { - name: "Blue Box" - url: "http://bluebox.net" - } - ).property() - - configValues: (-> - config = @get('config') - keys = @get('build.rawConfigKeys') - - if config && keys - keys.map (key) -> config[key] - else - [] - ).property('config', 'build.rawConfigKeys.length') - - canCancel: (-> - !@get('isFinished') - ).property('state') - - canRestart: Ember.computed.alias('isFinished') - - cancel: (-> - @get('ajax').post "/jobs/#{@get('id')}/cancel" - ) - - removeLog: -> - @get('ajax').patch("/jobs/#{@get('id')}/log").then => - @reloadLog() - - reloadLog: -> - @clearLog() - @get('log').fetch() - - restart: -> - @get('ajax').post "/jobs/#{@get('id')}/restart" - - appendLog: (part) -> - @get('log').append part - - subscribe: -> - return if @get('subscribed') - @set('subscribed', true) - if Travis.pusher - Travis.pusher.subscribe "job-#{@get('id')}" - - unsubscribe: -> - return unless @get('subscribed') - @set('subscribed', false) - if Travis.pusher - Travis.pusher.unsubscribe "job-#{@get('id')}" - - onStateChange: (-> - @unsubscribe() if @get('state') == 'finished' && Travis.pusher - ).observes('state') - - # TODO: such formattings should be done in controller, but in order - # to use it there easily, I would have to refactor job and build - # controllers - formattedFinishedAt: (-> - if finishedAt = @get('finishedAt') - moment(finishedAt).format('lll') - ).property('finishedAt') - - canRemoveLog: (-> - !@get('log.removed') - ).property('log.removed') - - slug: (-> - "#{@get('repo.slug')} ##{@get('number')}" - ).property() - - isLegacyInfrastructure: (-> - if @get('queue') == 'builds.linux' - true - ).property('queue') - - displayGceNotice: (-> - if @get('queue') == 'builds.gce' && @get('config.dist') == 'precise' - true - else - false - ).property('queue', 'config.dist') - -`export default Job` diff --git a/app/models/job.js b/app/models/job.js new file mode 100644 index 00000000..77a8514f --- /dev/null +++ b/app/models/job.js @@ -0,0 +1,184 @@ +import { durationFrom, configKeys, compact } from 'travis/utils/helpers'; +import configKeysMap from 'travis/utils/keys-map'; +import Ember from 'ember'; +import Model from 'travis/models/model'; +import Log from 'travis/models/log'; +import DurationCalculations from 'travis/utils/duration-calculations'; + +export default Model.extend(DurationCalculations, { + ajax: Ember.inject.service(), + logId: DS.attr(), + queue: DS.attr(), + state: DS.attr(), + number: DS.attr(), + _startedAt: DS.attr(), + _finishedAt: DS.attr(), + allowFailure: DS.attr('boolean'), + tags: DS.attr(), + repositoryPrivate: DS.attr(), + repositorySlug: DS.attr(), + _config: DS.attr('object'), + + repo: DS.belongsTo('repo', { async: true }), + build: DS.belongsTo('build', { async: true }), + commit: DS.belongsTo('commit', { async: true }), + branch: Ember.computed.alias('build.branch'), + annotations: DS.hasMany('annotation'), + + log: function() { + this.set('isLogAccessed', true); + return Log.create({ + job: this, + ajax: this.get('ajax') + }); + }.property(), + + startedAt: function() { + if (!this.get('notStarted')) { + return this.get('_startedAt'); + } + }.property('_startedAt', 'notStarted'), + + finishedAt: function() { + if (!this.get('notStarted')) { + return this.get('_finishedAt'); + } + }.property('_finishedAt', 'notStarted'), + + repoSlug: function() { + return this.get('repositorySlug'); + }.property('repositorySlug'), + + config: function() { + var config; + if (config = this.get('_config')) { + return compact(config); + } else if (this.get('currentState.stateName') !== 'root.loading') { + if (this.get('isFetchingConfig')) { + return; + } + this.set('isFetchingConfig', true); + return this.reload(); + } + }.property('_config'), + + isFinished: function() { + var ref; + return (ref = this.get('state')) === 'passed' || ref === 'failed' || ref === 'errored' || ref === 'canceled'; + }.property('state'), + + notStarted: function() { + var ref; + return (ref = this.get('state')) === 'queued' || ref === 'created' || ref === 'received'; + }.property('state'), + + clearLog() { + if (this.get('isLogAccessed')) { + return this.get('log').clear(); + } + }, + + sponsor: function() { + return { + name: "Blue Box", + url: "http://bluebox.net" + }; + }.property(), + + configValues: function() { + var config, keys; + config = this.get('config'); + keys = this.get('build.rawConfigKeys'); + if (config && keys) { + return keys.map(function(key) { + return config[key]; + }); + } else { + return []; + } + }.property('config', 'build.rawConfigKeys.length'), + + canCancel: function() { + return !this.get('isFinished'); + }.property('state'), + + canRestart: Ember.computed.alias('isFinished'), + + cancel() { + return this.get('ajax').post("/jobs/" + (this.get('id')) + "/cancel"); + }, + + removeLog() { + return this.get('ajax').patch("/jobs/" + (this.get('id')) + "/log").then(() => { + return this.reloadLog(); + }); + }, + + reloadLog() { + this.clearLog(); + return this.get('log').fetch(); + }, + + restart() { + return this.get('ajax').post("/jobs/" + (this.get('id')) + "/restart"); + }, + + appendLog(part) { + return this.get('log').append(part); + }, + + subscribe() { + if (this.get('subscribed')) { + return; + } + this.set('subscribed', true); + if (Travis.pusher) { + return Travis.pusher.subscribe("job-" + (this.get('id'))); + } + }, + + unsubscribe() { + if (!this.get('subscribed')) { + return; + } + this.set('subscribed', false); + if (Travis.pusher) { + return Travis.pusher.unsubscribe("job-" + (this.get('id'))); + } + }, + + onStateChange: function() { + if (this.get('state') === 'finished' && Travis.pusher) { + return this.unsubscribe(); + } + }.observes('state'), + + formattedFinishedAt: function() { + var finishedAt; + if (finishedAt = this.get('finishedAt')) { + return moment(finishedAt).format('lll'); + } + }.property('finishedAt'), + + canRemoveLog: function() { + return !this.get('log.removed'); + }.property('log.removed'), + + slug: function() { + return (this.get('repo.slug')) + " #" + (this.get('number')); + } .property(), + + isLegacyInfrastructure: function() { + if (this.get('queue') === 'builds.linux') { + return true; + } + }.property('queue'), + + displayGceNotice: function() { + if (this.get('queue') === 'builds.gce' && this.get('config.dist') === 'precise') { + return true; + } else { + return false; + } + }.property('queue', 'config.dist') +}); diff --git a/app/models/log.coffee b/app/models/log.coffee deleted file mode 100644 index bef4f2a3..00000000 --- a/app/models/log.coffee +++ /dev/null @@ -1,111 +0,0 @@ -`import Model from 'travis/models/model'` -`import Job from 'travis/models/job'` -`import Ember from 'ember'` -`import config from 'travis/config/environment'` - -Request = Ember.Object.extend - HEADERS: - accept: 'application/json; chunked=true; version=2, text/plain; version=2' - - run: -> - @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)) - - handle: (body, status, xhr) -> - if config.pro - @log.set('token', xhr.getResponseHeader('X-Log-Access-Token')) - - if xhr.status == 204 - $.ajax(url: @redirectTo(xhr), type: 'GET', success: @handlers.text) - else if @isJson(xhr, body) - @handlers.json(body) - else - @handlers.text(body) - - redirectTo: (xhr) -> - # Firefox can't see the Location header on the xhr response due to the wrong - # status code 204. Should be some redirect code but that doesn't work with CORS. - xhr.getResponseHeader('Location') - - isJson: (xhr, body) -> - # Firefox can't see the Content-Type header on the xhr response due to the wrong - # status code 204. Should be some redirect code but that doesn't work with CORS. - type = xhr.getResponseHeader('Content-Type') || '' - type.indexOf('json') > -1 - -Log = Ember.Object.extend - version: 0 # used to refresh log on requeue - isLoaded: false - length: 0 - - hasContent: Ember.computed.gt('parts.length', 0) - - fetchMissingParts: (partNumbers, after) -> - return if @get('notStarted') - - data = {} - data['part_numbers'] = partNumbers if partNumbers - data['after'] = after if after - - @get('ajax').ajax "/jobs/#{@get('job.id')}/log", 'GET', - dataType: 'json' - headers: - accept: 'application/json; chunked=true; version=2' - data: data - success: (body, status, xhr) => - Ember.run this, -> - if parts = body.log.parts - for part in parts - @append part - - parts: (-> - #if config.pusher_log_fallback - # Travis.LogChunks.create(content: [], missingPartsCallback: => @fetchMissingParts.apply(this, arguments)) - #else - Ember.ArrayProxy.create(content: []) - ).property() - - clearParts: -> - parts = @get('parts') - parts.set('content', []) - - fetch: -> - console.log 'log model: fetching log' if Log.DEBUG - @clearParts() - handlers = - json: (json) => - if json['log']['removed_at'] - @set('removed', true) - @loadParts(json['log']['parts']) - text: (text) => @loadText(text) - if id = @get('job.id') - Request.create(id: id, handlers: handlers, log: this, ajax: @get('ajax')).run() - - clear: -> - @clearParts() - @runOnClear() - - runOnClear: -> - if callback = @get('onClearCallback') - callback() - - onClear: (callback) -> - @set('onClearCallback', callback) - - append: (part) -> - return if @get('parts').isDestroying || @get('parts').isDestroyed - @get('parts').pushObject(part) - - loadParts: (parts) -> - console.log 'log model: load parts' - @append(part) for part in parts - @set('isLoaded', true) - - loadText: (text) -> - console.log 'log model: load text' - @append(number: 1, content: text, final: true) - @set('isLoaded', true) - -`export default Log` diff --git a/app/models/log.js b/app/models/log.js new file mode 100644 index 00000000..067b8f6b --- /dev/null +++ b/app/models/log.js @@ -0,0 +1,183 @@ +import Model from 'travis/models/model'; +import Job from 'travis/models/job'; +import Ember from 'ember'; +import config from 'travis/config/environment'; + +var Request = Ember.Object.extend({ + HEADERS: { + accept: 'application/json; chunked=true; version=2, text/plain; version=2' + }, + + run() { + return this.get('ajax').ajax("/jobs/" + this.id + "/log?cors_hax=true", 'GET', { + dataType: 'text', + headers: this.HEADERS, + success: () => { + return Ember.run(this, function() { + return this.handle(body, status, xhr); + }); + } + }); + }, + + handle(body, status, xhr) { + if (config.pro) { + this.log.set('token', xhr.getResponseHeader('X-Log-Access-Token')); + } + if (xhr.status === 204) { + return $.ajax({ + url: this.redirectTo(xhr), + type: 'GET', + success: this.handlers.text + }); + } else if (this.isJson(xhr, body)) { + return this.handlers.json(body); + } else { + return this.handlers.text(body); + } + }, + + redirectTo(xhr) { + // Firefox can't see the Location header on the xhr response due to the wrong + // status code 204. Should be some redirect code but that doesn't work with CORS. + return xhr.getResponseHeader('Location'); + }, + + isJson(xhr, body) { + // Firefox can't see the Content-Type header on the xhr response due to the wrong + // status code 204. Should be some redirect code but that doesn't work with CORS. + var type = xhr.getResponseHeader('Content-Type') || ''; + return type.indexOf('json') > -1; + } +}); + +var Log = Ember.Object.extend({ + version: 0, + isLoaded: false, + length: 0, + hasContent: Ember.computed.gt('parts.length', 0), + + fetchMissingParts(partNumbers, after) { + var data; + if (this.get('notStarted')) { + return; + } + data = {}; + if (partNumbers) { + data['part_numbers'] = partNumbers; + } + if (after) { + data['after'] = after; + } + return this.get('ajax').ajax("/jobs/" + (this.get('job.id')) + "/log", 'GET', { + dataType: 'json', + headers: { + accept: 'application/json; chunked=true; version=2' + }, + data: data, + success: (function(_this) { + return function(body, status, xhr) { + return Ember.run(_this, function() { + var i, len, part, parts, results; + if (parts = body.log.parts) { + results = []; + for (i = 0, len = parts.length; i < len; i++) { + part = parts[i]; + results.push(this.append(part)); + } + return results; + } + }); + }; + })(this) + }); + }, + + parts: function() { + return Ember.ArrayProxy.create({ + content: [] + }); + }.property(), + + clearParts() { + var parts; + parts = this.get('parts'); + return parts.set('content', []); + }, + + fetch() { + var handlers, id; + if (Log.DEBUG) { + console.log('log model: fetching log'); + } + this.clearParts(); + handlers = { + json: (function(_this) { + return function(json) { + if (json['log']['removed_at']) { + _this.set('removed', true); + } + return _this.loadParts(json['log']['parts']); + }; + })(this), + text: (function(_this) { + return function(text) { + return _this.loadText(text); + }; + })(this) + }; + if (id = this.get('job.id')) { + return Request.create({ + id: id, + handlers: handlers, + log: this, + ajax: this.get('ajax') + }).run(); + } + }, + + clear() { + this.clearParts(); + return this.runOnClear(); + }, + + runOnClear() { + var callback; + if (callback = this.get('onClearCallback')) { + return callback(); + } + }, + + onClear(callback) { + return this.set('onClearCallback', callback); + }, + + append(part) { + if (this.get('parts').isDestroying || this.get('parts').isDestroyed) { + return; + } + return this.get('parts').pushObject(part); + }, + + loadParts(parts) { + var i, len, part; + console.log('log model: load parts'); + for (i = 0, len = parts.length; i < len; i++) { + part = parts[i]; + this.append(part); + } + return this.set('isLoaded', true); + }, + + loadText(text) { + console.log('log model: load text'); + this.append({ + number: 1, + content: text, + final: true + }); + return this.set('isLoaded', true); + } +}); + +export default Log; diff --git a/app/models/model.coffee b/app/models/model.coffee deleted file mode 100644 index 4bf89a2b..00000000 --- a/app/models/model.coffee +++ /dev/null @@ -1,3 +0,0 @@ -`import DS from 'ember-data';` - -`export default DS.Model.extend();` diff --git a/app/models/model.js b/app/models/model.js new file mode 100644 index 00000000..9b5b8231 --- /dev/null +++ b/app/models/model.js @@ -0,0 +1,2 @@ +import DS from 'ember-data'; +export default DS.Model.extend(); diff --git a/app/models/repo.coffee b/app/models/repo.coffee deleted file mode 100644 index 783e5209..00000000 --- a/app/models/repo.coffee +++ /dev/null @@ -1,252 +0,0 @@ -`import ExpandableRecordArray from 'travis/utils/expandable-record-array'` -`import Model from 'travis/models/model'` -# 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'` -`import Config from 'travis/config/environment'` - -Repo = null - -if Config.useV3API - Repo = Model.extend - defaultBranch: DS.belongsTo('branch', async: false) - - lastBuild: Ember.computed.oneWay('defaultBranch.lastBuild') - - lastBuildFinishedAt: Ember.computed.oneWay('lastBuild.finishedAt') - lastBuildId: Ember.computed.oneWay('lastBuild.id') - lastBuildState: Ember.computed.oneWay('lastBuild.state') - lastBuildNumber: Ember.computed.oneWay('lastBuild.number') - lastBuildStartedAt: Ember.computed.oneWay('lastBuild.startedAt') - lastBuildDuration: Ember.computed.oneWay('lastBuild.duration') - - -else - Repo = Model.extend - lastBuildNumber: DS.attr('number') - lastBuildState: DS.attr() - lastBuildStartedAt: DS.attr() - lastBuildFinishedAt: DS.attr() - _lastBuildDuration: DS.attr('number') - lastBuildLanguage: DS.attr() - lastBuildId: DS.attr('number') - lastBuildHash: (-> - { - id: @get('lastBuildId') - number: @get('lastBuildNumber') - repo: this - } - ).property('lastBuildId', 'lastBuildNumber') - - lastBuild: (-> - if id = @get('lastBuildId') - @store.findRecord('build', id) - @store.recordForId('build', id) - ).property('lastBuildId') - - lastBuildDuration: (-> - duration = @get('_lastBuildDuration') - duration = durationFromHelper(@get('lastBuildStartedAt'), @get('lastBuildFinishedAt')) unless duration - duration - ).property('_lastBuildDuration', 'lastBuildStartedAt', 'lastBuildFinishedAt') - -Repo.reopen - ajax: Ember.inject.service() - - slug: DS.attr() - description: DS.attr() - private: DS.attr('boolean') - githubLanguage: DS.attr() - active: DS.attr() - - withLastBuild: -> - @filter( (repo) -> repo.get('lastBuildId') ) - - sshKey: (-> - @store.find('ssh_key', @get('id')) - @store.recordForId('ssh_key', @get('id')) - ) - - envVars: (-> - id = @get('id') - @store.filter('env_var', { repository_id: id }, (v) -> - v.get('repo.id') == id - ) - ).property() - - 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') - ) - - # TODO: move to controller - array = ExpandableRecordArray.create - type: 'build' - content: Ember.A([]) - - array.load(builds) - array.observe(builds) - - array - ).property() - - 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' - ) - - # TODO: move to controller - array = ExpandableRecordArray.create - type: 'build' - content: Ember.A([]) - - array.load(builds) - - id = @get('id') - array.observe(builds) - - array - ).property() - - branches: (-> - builds = @store.query 'build', repository_id: @get('id'), branches: true - - builds.then -> - builds.set 'isLoaded', true - - builds - ).property() - - owner: (-> - (@get('slug') || '').split('/')[0] - ).property('slug') - - name: (-> - (@get('slug') || '').split('/')[1] - ).property('slug') - - sortOrderForLandingPage: (-> - state = @get('lastBuildState') - if state != 'passed' && state != 'failed' - 0 - else - parseInt(@get('lastBuildId')) - ).property('lastBuildId', 'lastBuildState') - - stats: (-> - if @get('slug') - @get('_stats') || $.get("https://api.github.com/repos/#{@get('slug')}", (data) => - @set('_stats', data) - @notifyPropertyChange 'stats' - ) && {} - ).property('slug') - - updateTimes: -> - if Config.useV3API - if lastBuild = @get('lastBuild') - lastBuild.updateTimes() - else - @notifyPropertyChange 'lastBuildDuration' - - regenerateKey: (options) -> - @get('ajax').ajax '/repos/' + @get('id') + '/key', 'post', options - - fetchSettings: -> - @get('ajax').ajax('/repos/' + @get('id') + '/settings', 'get', forceAuth: true).then (data) -> - data['settings'] - - saveSettings: (settings) -> - @get('ajax').ajax('/repos/' + @get('id') + '/settings', 'patch', data: { settings: settings }) - -Repo.reopenClass - recent: -> - @find() - - accessibleBy: (store, reposIdsOrlogin) -> - if Config.useV3API - reposIds = reposIdsOrlogin - # 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 - ) - - promise = new Ember.RSVP.Promise (resolve, reject) -> - store.query('repo', { 'repository.active': 'true', limit: 20 }).then( -> - resolve(repos) - , -> - reject() - ) - - promise - else - login = reposIdsOrlogin - store.find('repo', { member: login, orderBy: 'name' }) - - search: (store, ajax, query) -> - if Config.useV3API - queryString = $.param(search: query, orderBy: 'name', limit: 5) - promise = ajax.ajax("/repos?#{queryString}", 'get') - result = Ember.ArrayProxy.create(content: []) - - 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 - else - store.find('repo', search: query, orderBy: 'name') - - withLastBuild: (store) -> - repos = store.filter('repo', {}, (build) -> - build.get('lastBuildId') - ) - - repos.then () -> - repos.set('isLoaded', true) - - repos - - fetchBySlug: (store, slug) -> - repos = store.peekAll('repo').filterBy('slug', slug) - if repos.get('length') > 0 - repos.get('firstObject') - else - promise = null - - if Config.useV3API - adapter = store.adapterFor('repo') - modelClass = store.modelFor('repo') - - promise = 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 - - else - promise = store.find('repo', { slug: slug }).then (repos) -> - repos.get('firstObject') || throw("no repos found") - - promise.catch -> - error = new Error('repo not found') - error.slug = slug - throw(error) - - # buildURL: (slug) -> - # if slug then slug else 'repos' - -`export default Repo` diff --git a/app/models/repo.js b/app/models/repo.js new file mode 100644 index 00000000..a4083be3 --- /dev/null +++ b/app/models/repo.js @@ -0,0 +1,317 @@ +import ExpandableRecordArray from 'travis/utils/expandable-record-array'; +import Model from 'travis/models/model'; +import { durationFrom as durationFromHelper } from 'travis/utils/helpers'; +import Build from 'travis/models/build'; +import Config from 'travis/config/environment'; +var Repo; + +if (Config.useV3API) { + Repo = Model.extend({ + defaultBranch: DS.belongsTo('branch', { + async: false + }), + lastBuild: Ember.computed.oneWay('defaultBranch.lastBuild'), + lastBuildFinishedAt: Ember.computed.oneWay('lastBuild.finishedAt'), + lastBuildId: Ember.computed.oneWay('lastBuild.id'), + lastBuildState: Ember.computed.oneWay('lastBuild.state'), + lastBuildNumber: Ember.computed.oneWay('lastBuild.number'), + lastBuildStartedAt: Ember.computed.oneWay('lastBuild.startedAt'), + lastBuildDuration: Ember.computed.oneWay('lastBuild.duration') + }); +} else { + Repo = Model.extend({ + lastBuildNumber: DS.attr('number'), + lastBuildState: DS.attr(), + lastBuildStartedAt: DS.attr(), + lastBuildFinishedAt: DS.attr(), + _lastBuildDuration: DS.attr('number'), + lastBuildLanguage: DS.attr(), + lastBuildId: DS.attr('number'), + + lastBuildHash: function() { + return { + id: this.get('lastBuildId'), + number: this.get('lastBuildNumber'), + repo: this + }; + }.property('lastBuildId', 'lastBuildNumber'), + + lastBuild: function() { + var id; + if (id = this.get('lastBuildId')) { + this.store.findRecord('build', id); + return this.store.recordForId('build', id); + } + }.property('lastBuildId'), + + lastBuildDuration: function() { + var duration; + duration = this.get('_lastBuildDuration'); + if (!duration) { + duration = durationFromHelper(this.get('lastBuildStartedAt'), this.get('lastBuildFinishedAt')); + } + return duration; + }.property('_lastBuildDuration', 'lastBuildStartedAt', 'lastBuildFinishedAt') + }); +} + +Repo.reopen({ + ajax: Ember.inject.service(), + slug: DS.attr(), + description: DS.attr(), + "private": DS.attr('boolean'), + githubLanguage: DS.attr(), + active: DS.attr(), + + withLastBuild() { + return this.filter(function(repo) { + return repo.get('lastBuildId'); + }); + }, + + sshKey: function() { + this.store.find('ssh_key', this.get('id')); + return this.store.recordForId('ssh_key', this.get('id')); + }, + + envVars: function() { + var id; + id = this.get('id'); + return this.store.filter('env_var', { + repository_id: id + }, function(v) { + return v.get('repo.id') === id; + }); + }.property(), + + builds: function() { + var array, builds, id; + id = this.get('id'); + builds = this.store.filter('build', { + event_type: ['push', 'api'], + repository_id: id + }, function(b) { + return b.get('repo.id') + '' === id + '' && (b.get('eventType') === 'push' || b.get('eventType') === 'api'); + }); + array = ExpandableRecordArray.create({ + type: 'build', + content: Ember.A([]) + }); + array.load(builds); + array.observe(builds); + return array; + }.property(), + + pullRequests: function() { + var array, builds, id; + id = this.get('id'); + builds = this.store.filter('build', { + event_type: 'pull_request', + repository_id: id + }, function(b) { + return b.get('repo.id') + '' === id + '' && b.get('eventType') === 'pull_request'; + }); + array = ExpandableRecordArray.create({ + type: 'build', + content: Ember.A([]) + }); + array.load(builds); + id = this.get('id'); + array.observe(builds); + return array; + }.property(), + + branches: function() { + var builds; + builds = this.store.query('build', { + repository_id: this.get('id'), + branches: true + }); + builds.then(function() { + return builds.set('isLoaded', true); + }); + return builds; + }.property(), + + owner: function() { + return (this.get('slug') || '').split('/')[0]; + }.property('slug'), + + name: function() { + return (this.get('slug') || '').split('/')[1]; + }.property('slug'), + + sortOrderForLandingPage: function() { + var state; + state = this.get('lastBuildState'); + if (state !== 'passed' && state !== 'failed') { + return 0; + } else { + return parseInt(this.get('lastBuildId')); + } + }.property('lastBuildId', 'lastBuildState'), + + stats: function() { + if (this.get('slug')) { + return this.get('_stats') || $.get("https://api.github.com/repos/" + this.get('slug'), () => { + this.set('_stats', data); + return this.notifyPropertyChange('stats'); + }) && {}; + } + }.property('slug'), + + updateTimes() { + var lastBuild; + if (Config.useV3API) { + if (lastBuild = this.get('lastBuild')) { + return lastBuild.updateTimes(); + } + } else { + return this.notifyPropertyChange('lastBuildDuration'); + } + }, + + regenerateKey(options) { + return this.get('ajax').ajax('/repos/' + this.get('id') + '/key', 'post', options); + }, + + fetchSettings() { + return this.get('ajax').ajax('/repos/' + this.get('id') + '/settings', 'get', { + forceAuth: true + }).then(function(data) { + return data['settings']; + }); + }, + + saveSettings(settings) { + return this.get('ajax').ajax('/repos/' + this.get('id') + '/settings', 'patch', { + data: { + settings: settings + } + }); + } +}); + +Repo.reopenClass({ + recent() { + return this.find(); + }, + + accessibleBy(store, reposIdsOrlogin) { + var login, promise, repos, reposIds; + if (Config.useV3API) { + reposIds = reposIdsOrlogin; + repos = store.filter('repo', function(repo) { + return reposIds.indexOf(parseInt(repo.get('id'))) !== -1; + }); + promise = new Ember.RSVP.Promise(function(resolve, reject) { + return store.query('repo', { + 'repository.active': 'true', + limit: 20 + }).then(function() { + return resolve(repos); + }, function() { + return reject(); + }); + }); + return promise; + } else { + login = reposIdsOrlogin; + return store.find('repo', { + member: login, + orderBy: 'name' + }); + } + }, + + search(store, ajax, query) { + var promise, queryString, result; + if (Config.useV3API) { + queryString = $.param({ + search: query, + orderBy: 'name', + limit: 5 + }); + promise = ajax.ajax("/repos?" + queryString, 'get'); + result = Ember.ArrayProxy.create({ + content: [] + }); + return promise.then(function(data, status, xhr) { + var promises; + promises = data.repos.map(function(repoData) { + return store.findRecord('repo', repoData.id).then(function(record) { + result.pushObject(record); + result.set('isLoaded', true); + return record; + }); + }); + return Ember.RSVP.allSettled(promises).then(function() { + return result; + }); + }); + } else { + return store.find('repo', { + search: query, + orderBy: 'name' + }); + } + }, + + withLastBuild(store) { + var repos; + repos = store.filter('repo', {}, function(build) { + return build.get('lastBuildId'); + }); + repos.then(function() { + return repos.set('isLoaded', true); + }); + return repos; + }, + + fetchBySlug(store, slug) { + var adapter, modelClass, promise, repos; + repos = store.peekAll('repo').filterBy('slug', slug); + if (repos.get('length') > 0) { + return repos.get('firstObject'); + } else { + promise = null; + if (Config.useV3API) { + adapter = store.adapterFor('repo'); + modelClass = store.modelFor('repo'); + promise = adapter.findRecord(store, modelClass, slug).then(function(payload) { + var i, len, r, record, ref, repo, result, serializer; + serializer = store.serializerFor('repo'); + modelClass = store.modelFor('repo'); + result = serializer.normalizeResponse(store, modelClass, payload, null, 'findRecord'); + repo = store.push({ + data: result.data + }); + ref = result.included; + for (i = 0, len = ref.length; i < len; i++) { + record = ref[i]; + r = store.push({ + data: record + }); + } + return repo; + }); + } else { + promise = store.find('repo', { + slug: slug + }).then(function(repos) { + return repos.get('firstObject') || (function() { + throw "no repos found"; + })(); + }); + } + return promise["catch"](function() { + var error; + error = new Error('repo not found'); + error.slug = slug; + throw error; + }); + } + } +}); + +export default Repo; diff --git a/app/models/request.coffee b/app/models/request.coffee deleted file mode 100644 index ba6b804f..00000000 --- a/app/models/request.coffee +++ /dev/null @@ -1,32 +0,0 @@ -`import Ember from 'ember'` -`import Model from 'travis/models/model'` - -Request = Model.extend - created_at: DS.attr() - event_type: DS.attr() - result: DS.attr() - message: DS.attr() - headCommit: DS.attr() - baseCommit: DS.attr() - branchName: DS.attr() - tagName: DS.attr() - pullRequest: DS.attr('boolean') - pullRequestTitle: DS.attr() - pullRequestNumber: DS.attr('number') - - repo: DS.belongsTo('repo', async: true) - commit: DS.belongsTo('commit', async: true) - build: DS.belongsTo('build', async: true) - - isAccepted: (-> - # For some reason some of the requests have a null result beside the fact that - # the build was created. We need to look into it, but for now we can just assume - # that if build was created, the request was accepted - @get('result') == 'accepted' || @get('build.id') - ).property('result') - - isPullRequest: (-> - @get('event_type') == 'pull_request' - ).property('event_type') - -`export default Request` diff --git a/app/models/request.js b/app/models/request.js new file mode 100644 index 00000000..858e1635 --- /dev/null +++ b/app/models/request.js @@ -0,0 +1,30 @@ +import Ember from 'ember'; +import Model from 'travis/models/model'; + +export default Model.extend({ + created_at: DS.attr(), + event_type: DS.attr(), + result: DS.attr(), + message: DS.attr(), + headCommit: DS.attr(), + baseCommit: DS.attr(), + branchName: DS.attr(), + tagName: DS.attr(), + pullRequest: DS.attr('boolean'), + pullRequestTitle: DS.attr(), + pullRequestNumber: DS.attr('number'), + repo: DS.belongsTo('repo', { async: true }), + commit: DS.belongsTo('commit', { async: true }), + build: DS.belongsTo('build', { async: true }), + + isAccepted: function() { + // For some reason some of the requests have a null result beside the fact that + // the build was created. We need to look into it, but for now we can just assume + // that if build was created, the request was accepted + return this.get('result') === 'accepted' || this.get('build.id'); + }.property('result'), + + isPullRequest: function() { + return this.get('event_type') === 'pull_request'; + }.property('event_type') +}); diff --git a/app/models/ssh-key.coffee b/app/models/ssh-key.coffee deleted file mode 100644 index 8bb1f2fd..00000000 --- a/app/models/ssh-key.coffee +++ /dev/null @@ -1,10 +0,0 @@ -`import Ember from 'ember'` -`import Model from 'travis/models/model'` - -SshKey = Model.extend - value: DS.attr() - description: DS.attr() - fingerprint: DS.attr() - isCustom: true - -`export default SshKey` diff --git a/app/models/ssh-key.js b/app/models/ssh-key.js new file mode 100644 index 00000000..bd01047d --- /dev/null +++ b/app/models/ssh-key.js @@ -0,0 +1,9 @@ +import Ember from 'ember'; +import Model from 'travis/models/model'; + +export default Model.extend({ + value: DS.attr(), + description: DS.attr(), + fingerprint: DS.attr(), + isCustom: true +}); diff --git a/app/models/user.coffee b/app/models/user.coffee deleted file mode 100644 index 910a6663..00000000 --- a/app/models/user.coffee +++ /dev/null @@ -1,103 +0,0 @@ -`import Ember from 'ember'` -`import Model from 'travis/models/model'` -`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() - token: DS.attr() - gravatarId: DS.attr() - isSyncing: DS.attr('boolean') - syncedAt: DS.attr() - repoCount: DS.attr('number') - - fullName: (-> - @get('name') || @get('login') - ).property('name', 'login') - - isSyncingDidChange: (-> - Ember.run.next this, -> - @poll() if @get('isSyncing') - ).observes('isSyncing') - - urlGithub: (-> - "#{config.sourceEndpoint}/#{@get('login')}" - ).property() - - _rawPermissions: (-> - @get('ajax').get('/users/permissions') - ).property() - - permissions: (-> - permissions = Ember.ArrayProxy.create(content: []) - @get('_rawPermissions').then (data) => permissions.set('content', data.permissions) - permissions - ).property() - - adminPermissions: (-> - permissions = Ember.ArrayProxy.create(content: []) - @get('_rawPermissions').then (data) => permissions.set('content', data.admin) - permissions - ).property() - - pullPermissions: (-> - permissions = Ember.ArrayProxy.create(content: []) - @get('_rawPermissions').then (data) => permissions.set('content', data.pull) - permissions - ).property() - - pushPermissions: (-> - permissions = Ember.ArrayProxy.create(content: []) - @get('_rawPermissions').then (data) => permissions.set('content', data.push) - permissions - ).property() - - # TODO: permissions are loading asynchronously at the moment, so this should - # be the way to return them for all types: - pushPermissionsPromise: (-> - @get('_rawPermissions').then (data) => data.pull - ).property() - - hasAccessToRepo: (repo) -> - id = if repo.get then repo.get('id') else repo - - if permissions = @get('permissions') - permissions.contains parseInt(id) - - type: (-> - 'user' - ).property() - - sync: -> - self = this - @get('ajax').post('/users/sync', {}, -> - self.setWithSession('isSyncing', true) - ) - - poll: -> - @get('ajax').get '/users', (data) => - if data.user.is_syncing - self = this - setTimeout -> - self.poll() - , 3000 - else - @set('isSyncing', false) - @setWithSession('syncedAt', data.user.synced_at) - Travis.trigger('user:synced', data.user) - - @store.query('account', {}) - - setWithSession: (name, value) -> - @set(name, value) - user = JSON.parse(@get('sessionStorage').getItem('travis.user')) - user[name.underscore()] = @get(name) - @get('sessionStorage').setItem('travis.user', JSON.stringify(user)) - -`export default User` diff --git a/app/models/user.js b/app/models/user.js new file mode 100644 index 00000000..74cc7859 --- /dev/null +++ b/app/models/user.js @@ -0,0 +1,136 @@ +import Ember from 'ember'; +import Model from 'travis/models/model'; +import config from 'travis/config/environment'; + +export default 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(), + token: DS.attr(), + gravatarId: DS.attr(), + isSyncing: DS.attr('boolean'), + syncedAt: DS.attr(), + repoCount: DS.attr('number'), + + fullName: function() { + return this.get('name') || this.get('login'); + }.property('name', 'login'), + + isSyncingDidChange: function() { + return Ember.run.next(this, function() { + if (this.get('isSyncing')) { + return this.poll(); + } + }); + }.observes('isSyncing'), + + urlGithub: function() { + return config.sourceEndpoint + "/" + (this.get('login')); + }.property(), + + _rawPermissions: function() { + return this.get('ajax').get('/users/permissions'); + }.property(), + + permissions: function() { + var permissions; + permissions = Ember.ArrayProxy.create({ + content: [] + }); + this.get('_rawPermissions').then((function(_this) { + return function(data) { + return permissions.set('content', data.permissions); + }; + })(this)); + return permissions; + }.property(), + + adminPermissions: function() { + var permissions; + permissions = Ember.ArrayProxy.create({ + content: [] + }); + this.get('_rawPermissions').then(() => { + return permissions.set('content', data.admin); + }); + return permissions; + }.property(), + + pullPermissions: function() { + var permissions; + permissions = Ember.ArrayProxy.create({ + content: [] + }); + this.get('_rawPermissions').then(() => { + return permissions.set('content', data.pull); + }); + return permissions; + }.property(), + + pushPermissions: function() { + var permissions; + permissions = Ember.ArrayProxy.create({ + content: [] + }); + this.get('_rawPermissions').then(() => { + return permissions.set('content', data.push); + }); + return permissions; + }.property(), + + pushPermissionsPromise: function() { + return this.get('_rawPermissions').then(() => { + return data.pull; + }); + }.property(), + + hasAccessToRepo(repo) { + var id, permissions; + id = repo.get ? repo.get('id') : repo; + if (permissions = this.get('permissions')) { + return permissions.contains(parseInt(id)); + } + }, + + type: function() { + return 'user'; + }.property(), + + sync() { + var self; + self = this; + return this.get('ajax').post('/users/sync', {}, function() { + return self.setWithSession('isSyncing', true); + }); + }, + + poll() { + return this.get('ajax').get('/users', () => { + var self; + if (data.user.is_syncing) { + self = this; + return setTimeout(function() { + return self.poll(); + }, 3000); + } else { + this.set('isSyncing', false); + this.setWithSession('syncedAt', data.user.synced_at); + Travis.trigger('user:synced', data.user); + return this.store.query('account', {}); + } + }); + }, + + setWithSession(name, value) { + var user; + this.set(name, value); + user = JSON.parse(this.get('sessionStorage').getItem('travis.user')); + user[name.underscore()] = this.get(name); + return this.get('sessionStorage').setItem('travis.user', JSON.stringify(user)); + } +}); diff --git a/app/router.coffee b/app/router.coffee deleted file mode 100644 index fab55d51..00000000 --- a/app/router.coffee +++ /dev/null @@ -1,85 +0,0 @@ -`import Ember from 'ember'` -`import config from './config/environment'` -`import Location from 'travis/utils/location'` - -Router = Ember.Router.extend - location: (-> - if Ember.testing - 'none' - else - # this is needed, because in the location - # we need to decide if repositories or home needs - # to be displayed, based on the current login status - # - # we should probably think about a more general way to - # do this, location should not know about auth status - Location.create(auth: @container.lookup('service:auth')) - ).property() - - # TODO: this is needed, because in the original version - # the router tries to run `this.location`, which fails - # with computed properties. It can be removed once this is - # changed in Ember.js - generate: -> - url = this.router.generate.apply(this.router, arguments) - return this.get('location').formatURL(url) - - handleURL: (url) -> - url = url.replace(/#.*?$/, '') - @_super(url) - - didTransition: -> - @_super.apply @, arguments - - if config.gaCode - _gaq.push ['_trackPageview', location.pathname] - -Router.map -> - @resource 'dashboard', -> - @route 'repositories', path: '/' - - @resource 'main', path: '/', -> - @resource 'getting_started' - @route 'recent' - @route 'repositories' - @route 'my_repositories' - @route 'search', path: '/search/:phrase' - @resource 'repo', path: '/:owner/:name', -> - @route 'index', path: '/' - @resource 'branches', path: '/branches' - @resource 'build', path: '/builds/:build_id' - @resource 'job', path: '/jobs/:job_id' - @resource 'builds', path: '/builds' - @resource 'pullRequests', path: '/pull_requests' - @resource 'requests', path: '/requests' - @resource 'caches', path: '/caches' if config.endpoints.caches - @resource 'request', path: '/requests/:request_id' - - @resource 'settings', -> - @route 'index', path: '/' - @resource 'env_vars', -> - @route 'new' - @resource 'ssh_key' if config.endpoints.sshKey - - @route 'first_sync' - @route 'insufficient_oauth_permissions' - @route 'auth' - @route 'home' - - @route 'home-pro', path: '/home-pro' - @route 'plans', path: '/plans' - @route 'team', path: '/about' - @route 'logo', path: '/logo' - - @resource 'profile', path: '/profile', -> - @resource 'accounts', path: '/', -> - @resource 'account', path: '/:login' - @route 'info', path: '/info' - - @resource 'owner', path: '/:owner', -> - @route 'repositories', path: '/' - # @route 'running', path: '/running' - - @route 'error404', path: '/404' - -`export default Router` diff --git a/app/router.js b/app/router.js new file mode 100644 index 00000000..9ee77a1f --- /dev/null +++ b/app/router.js @@ -0,0 +1,95 @@ +import Ember from 'ember'; +import config from './config/environment'; +import Location from 'travis/utils/location'; + +var Router = Ember.Router.extend({ + location: function() { + if (Ember.testing) { + return 'none'; + } else { + // this is needed, because in the location + // we need to decide if repositories or home needs + // to be displayed, based on the current login status + // + // we should probably think about a more general way to + // do this, location should not know about auth status + return Location.create({ + auth: this.container.lookup('service:auth') + }); + } + }.property(), + + generate() { + var url; + url = this.router.generate.apply(this.router, arguments); + return this.get('location').formatURL(url); + }, + + handleURL(url) { + url = url.replace(/#.*?$/, ''); + return this._super(url); + }, + + didTransition() { + this._super.apply(this, arguments); + if (config.gaCode) { + return _gaq.push(['_trackPageview', location.pathname]); + } + } +}); + +Router.map(function() { + this.resource('dashboard', function() { + this.route('repositories', { path: '/' }); + }); + this.resource('main', { path: '/' }, function() { + this.resource('getting_started'); + this.route('recent'); + this.route('repositories'); + this.route('my_repositories'); + this.route('search', { path: '/search/:phrase' }); + this.resource('repo', { path: '/:owner/:name' }, function() { + this.route('index', { path: '/' }); + this.resource('branches', { path: '/branches' }); + this.resource('build', { path: '/builds/:build_id' }); + this.resource('job', { path: '/jobs/:job_id' }); + this.resource('builds', { path: '/builds' }); + this.resource('pullRequests', { path: '/pull_requests' }); + this.resource('requests', { path: '/requests' }); + if (config.endpoints.caches) { + this.resource('caches', { path: '/caches' }); + } + this.resource('request', { path: '/requests/:request_id' }); + this.resource('settings', function() { + this.route('index', { path: '/' }); + this.resource('env_vars', function() { + this.route('new'); + }); + if (config.endpoints.sshKey) { + this.resource('ssh_key'); + } + }); + }); + }); + + this.route('first_sync'); + this.route('insufficient_oauth_permissions'); + this.route('auth'); + this.route('home'); + this.route('home-pro', { path: '/home-pro' }); + this.route('plans', { path: '/plans' }); + this.route('team', { path: '/about' }); + this.route('logo', { path: '/logo' }); + this.resource('profile', { path: '/profile' }, function() { + this.resource('accounts', { path: '/' }, function() { + this.resource('account', { path: '/:login' }); + this.route('info', { path: '/info' }); + }); + }); + this.resource('owner', { path: '/:owner' }, function() { + this.route('repositories', { path: '/' }); + }); + this.route('error404', { path: '/404' }); +}); + +export default Router; diff --git a/app/routes/abstract-builds.coffee b/app/routes/abstract-builds.coffee deleted file mode 100644 index d64f93e3..00000000 --- a/app/routes/abstract-builds.coffee +++ /dev/null @@ -1,30 +0,0 @@ -`import TravisRoute from 'travis/routes/basic'` - -Route = TravisRoute.extend - titleToken: (model) -> - @get('contentType').replace('_', ' ').capitalize() - - renderTemplate: -> - @render 'builds' - - setupController: -> - @controllerFor('repo').activate(@get('contentType')) - @contentDidChange() - @controllerFor('repo').addObserver(@get('path'), this, 'contentDidChange') - @controllerFor('build').set('contentType', @get('contentType')) - - deactivate: -> - @controllerFor('repo').removeObserver(@get('path'), this, 'contentDidChange') - - @_super.apply(this, arguments) - - contentDidChange: -> - path = @get('path') - @controllerFor('builds').set('model', @controllerFor('repo').get(path)) - - path: (-> - type = @get('contentType') - "repo.#{type.camelize()}" - ).property('contentType') - -`export default Route` diff --git a/app/routes/abstract-builds.js b/app/routes/abstract-builds.js new file mode 100644 index 00000000..61bfa9de --- /dev/null +++ b/app/routes/abstract-builds.js @@ -0,0 +1,35 @@ +import TravisRoute from 'travis/routes/basic'; + +export default TravisRoute.extend({ + titleToken(model) { + return this.get('contentType').replace('_', ' ').capitalize(); + }, + + renderTemplate() { + return this.render('builds'); + }, + + setupController() { + this.controllerFor('repo').activate(this.get('contentType')); + this.contentDidChange(); + this.controllerFor('repo').addObserver(this.get('path'), this, 'contentDidChange'); + return this.controllerFor('build').set('contentType', this.get('contentType')); + }, + + deactivate() { + this.controllerFor('repo').removeObserver(this.get('path'), this, 'contentDidChange'); + return this._super.apply(this, arguments); + }, + + contentDidChange() { + var path; + path = this.get('path'); + return this.controllerFor('builds').set('model', this.controllerFor('repo').get(path)); + }, + + path: function() { + var type; + type = this.get('contentType'); + return "repo." + (type.camelize()); + }.property('contentType') +}); diff --git a/app/routes/account.coffee b/app/routes/account.coffee deleted file mode 100644 index 3a440e03..00000000 --- a/app/routes/account.coffee +++ /dev/null @@ -1,24 +0,0 @@ -`import TravisRoute from 'travis/routes/basic'` - -Route = TravisRoute.extend - titleToken: (model) -> - if model - model.get('name') || model.get('login') - else - 'Account' - - setupController: (controller, account) -> - @_super.apply this, arguments - - @controllerFor('profile').activate 'hooks' - - model: (params) -> - @modelFor('accounts').find (account) -> account.get('login') == params.login - - serialize: (account) -> - if account && account.get - { login: account.get('login') } - else - {} - -`export default Route` diff --git a/app/routes/account.js b/app/routes/account.js new file mode 100644 index 00000000..9fde858d --- /dev/null +++ b/app/routes/account.js @@ -0,0 +1,32 @@ +import TravisRoute from 'travis/routes/basic'; + +export default TravisRoute.extend({ + titleToken(model) { + if (model) { + return model.get('name') || model.get('login'); + } else { + return 'Account'; + } + }, + + setupController(controller, account) { + this._super.apply(this, arguments); + return this.controllerFor('profile').activate('hooks'); + }, + + model(params) { + return this.modelFor('accounts').find(function(account) { + return account.get('login') === params.login; + }); + }, + + serialize(account) { + if (account && account.get) { + return { + login: account.get('login') + }; + } else { + return {}; + } + } +}); diff --git a/app/routes/accounts.coffee b/app/routes/accounts.coffee deleted file mode 100644 index dba38215..00000000 --- a/app/routes/accounts.coffee +++ /dev/null @@ -1,28 +0,0 @@ -`import TravisRoute from 'travis/routes/basic'` - -Route = TravisRoute.extend - model: -> - @store.query('account', { all: true }) - - setupController: (controller, model) -> - user = model.filterBy('type', 'user')[0] - orgs = model.filterBy('type', 'organization') - - controller.set('user', user) - controller.set('organizations', orgs) - - controller.set('model', model) - - renderTemplate: -> - @_super.apply(this, arguments) - @render 'profile_accounts', outlet: 'left', into: 'profile' - - - organizations: -> - model.filterBy('type', 'organization') - - user: -> - model.filterBy('type', 'user')[0] - - -`export default Route` diff --git a/app/routes/accounts.js b/app/routes/accounts.js new file mode 100644 index 00000000..6412e2ac --- /dev/null +++ b/app/routes/accounts.js @@ -0,0 +1,34 @@ +import TravisRoute from 'travis/routes/basic'; + +export default TravisRoute.extend({ + model() { + return this.store.query('account', { + all: true + }); + }, + + setupController(controller, model) { + var orgs, user; + user = model.filterBy('type', 'user')[0]; + orgs = model.filterBy('type', 'organization'); + controller.set('user', user); + controller.set('organizations', orgs); + return controller.set('model', model); + }, + + renderTemplate() { + this._super.apply(this, arguments); + return this.render('profile_accounts', { + outlet: 'left', + into: 'profile' + }); + }, + + organizations() { + return model.filterBy('type', 'organization'); + }, + + user() { + return model.filterBy('type', 'user')[0]; + } +}); diff --git a/app/routes/accounts/index.coffee b/app/routes/accounts/index.coffee deleted file mode 100644 index b716214f..00000000 --- a/app/routes/accounts/index.coffee +++ /dev/null @@ -1,12 +0,0 @@ -`import TravisRoute from 'travis/routes/basic'` - -Route = TravisRoute.extend - redirect: -> - # TODO: setting accounts model in ProfileRoute is wrong, but - # at this stage it's better than what we had before - accounts = @modelFor('accounts') - login = @controllerFor('currentUser').get('model.login') - account = accounts.find (account) -> account.get('login') == login - @transitionTo 'account', account - -`export default Route` diff --git a/app/routes/accounts/index.js b/app/routes/accounts/index.js new file mode 100644 index 00000000..0bc028a2 --- /dev/null +++ b/app/routes/accounts/index.js @@ -0,0 +1,15 @@ +import TravisRoute from 'travis/routes/basic'; + +export default TravisRoute.extend({ + redirect: function() { + // TODO: setting accounts model in ProfileRoute is wrong, but + // at this stage it's better than what we had before + var account, accounts, login; + accounts = this.modelFor('accounts'); + login = this.controllerFor('currentUser').get('model.login'); + account = accounts.find(function(account) { + return account.get('login') === login; + }); + return this.transitionTo('account', account); + } +}); diff --git a/app/routes/accounts/info.coffee b/app/routes/accounts/info.coffee deleted file mode 100644 index 9d20ea46..00000000 --- a/app/routes/accounts/info.coffee +++ /dev/null @@ -1,12 +0,0 @@ -`import TravisRoute from 'travis/routes/basic'` - -Route = TravisRoute.extend - setupController: -> - user = @controllerFor('currentUser').get('model') - @controllerFor('account').set('model', user) - @controllerFor('profile').activate 'user' - - renderTemplate: -> - @render 'accounts_info' - -`export default Route` diff --git a/app/routes/accounts/info.js b/app/routes/accounts/info.js new file mode 100644 index 00000000..efda4fd6 --- /dev/null +++ b/app/routes/accounts/info.js @@ -0,0 +1,14 @@ +import TravisRoute from 'travis/routes/basic'; + +export default TravisRoute.extend({ + setupController() { + var user; + user = this.controllerFor('currentUser').get('model'); + this.controllerFor('account').set('model', user); + return this.controllerFor('profile').activate('user'); + }, + + renderTemplate() { + return this.render('accounts_info'); + } +}); diff --git a/app/routes/application.coffee b/app/routes/application.coffee deleted file mode 100644 index f108409e..00000000 --- a/app/routes/application.coffee +++ /dev/null @@ -1,81 +0,0 @@ -`import TravisRoute from 'travis/routes/basic'` -`import config from 'travis/config/environment'` -`import BuildFaviconMixin from 'travis/mixins/build-favicon'` - -Route = TravisRoute.extend BuildFaviconMixin, - needsAuth: false - - beforeModel: -> - @_super.apply(this, arguments) - - @get('auth').refreshUserData().then (->), => - @get('auth').signOut() - - renderTemplate: -> - if @get('config').pro - $('body').addClass('pro') - - @_super.apply(this, arguments) - - activate: -> - @get('stylesheetsManager').disable('dashboard') - - if !config.pro - repos = @get('store').peekAll('repo') - repos.forEach (repo) => - @subscribeToRepo(repo) - - repos.addArrayObserver(this, willChange: 'reposWillChange', didChange: 'reposDidChange') - - reposWillChange: (->) - - reposDidChange: (array, start, removedCount, addedCount) -> - addedRepos = array.slice(start, start + addedCount) - addedRepos.forEach (repo) => - @subscribeToRepo(repo) - - subscribeToRepo: (repo) -> - if @pusher - @pusher.subscribe "repo-#{repo.get('id')}" - - title: (titleParts) -> - if titleParts.length - titleParts = titleParts.reverse() - titleParts.push('Travis CI') - titleParts.join(' - ') - else - config.defaultTitle - - actions: - redirectToGettingStarted: -> - # do nothing, we handle it only in index path - - renderDefaultTemplate: -> - @renderDefaultTemplate() if @renderDefaultTemplate - - error: (error) -> - if error == 'needs-auth' - authController = @container.lookup('controller:auth') - authController.set('redirected', true) - @transitionTo('auth') - else - return true - - renderFirstSync: -> - @transitionTo 'first_sync' - - afterSignIn: -> - if transition = @auth.get('afterSignInTransition') - @auth.set('afterSignInTransition', null) - transition.retry() - else - @transitionTo('main') - - afterSignOut: -> - @setDefault() - if @get('config').pro - @transitionTo('home-pro') - else - @transitionTo('home') - -`export default Route` diff --git a/app/routes/application.js b/app/routes/application.js new file mode 100644 index 00000000..2d0be412 --- /dev/null +++ b/app/routes/application.js @@ -0,0 +1,108 @@ +import TravisRoute from 'travis/routes/basic'; +import config from 'travis/config/environment'; +import BuildFaviconMixin from 'travis/mixins/build-favicon'; + +export default TravisRoute.extend(BuildFaviconMixin, { + needsAuth: false, + + beforeModel() { + this._super.apply(this, arguments); + return this.get('auth').refreshUserData().then((function() {}), (() => { + return this.get('auth').signOut(); + })); + }, + + renderTemplate: function() { + if (this.get('config').pro) { + $('body').addClass('pro'); + } + return this._super.apply(this, arguments); + }, + + activate() { + var repos; + this.get('stylesheetsManager').disable('dashboard'); + if (!config.pro) { + repos = this.get('store').peekAll('repo'); + repos.forEach(() => { + return this.subscribeToRepo(repo); + }); + return repos.addArrayObserver(this, { + willChange: 'reposWillChange', + didChange: 'reposDidChange' + }); + } + }, + + reposWillChange() {}, + + reposDidChange(array, start, removedCount, addedCount) { + var addedRepos; + addedRepos = array.slice(start, start + addedCount); + return addedRepos.forEach(() => { + return this.subscribeToRepo(repo); + }); + }, + + subscribeToRepo: function(repo) { + if (this.pusher) { + return this.pusher.subscribe("repo-" + (repo.get('id'))); + } + }, + + title(titleParts) { + if (titleParts.length) { + titleParts = titleParts.reverse(); + titleParts.push('Travis CI'); + return titleParts.join(' - '); + } else { + return config.defaultTitle; + } + }, + + actions: { + redirectToGettingStarted() { + // do nothing, we handle it only in index path + }, + + renderDefaultTemplate() { + if (this.renderDefaultTemplate) { + return this.renderDefaultTemplate(); + } + }, + + error(error) { + var authController; + if (error === 'needs-auth') { + authController = this.container.lookup('controller:auth'); + authController.set('redirected', true); + return this.transitionTo('auth'); + } else { + return true; + } + }, + + renderFirstSync() { + return this.transitionTo('first_sync'); + }, + + afterSignIn() { + var transition; + if (transition = this.auth.get('afterSignInTransition')) { + this.auth.set('afterSignInTransition', null); + return transition.retry(); + } else { + return this.transitionTo('main'); + } + }, + + afterSignOut() { + this.setDefault(); + if (this.get('config').pro) { + return this.transitionTo('home-pro'); + } else { + return this.transitionTo('home'); + } + } + } +}); diff --git a/app/routes/auth.coffee b/app/routes/auth.coffee deleted file mode 100644 index d50a84b7..00000000 --- a/app/routes/auth.coffee +++ /dev/null @@ -1,23 +0,0 @@ -`import TravisRoute from 'travis/routes/basic'` - -Route = TravisRoute.extend - needsAuth: false - - renderTemplate: -> - $('body').attr('id', 'auth') - - @render 'auth.signin' - - deactivate: -> - @controllerFor('auth').set('redirected', false) - - actions: - afterSignIn: -> - @transitionTo('main') - return true - - redirect: -> - if @signedIn() - @transitionTo('main') - -`export default Route` diff --git a/app/routes/auth.js b/app/routes/auth.js new file mode 100644 index 00000000..42b86f76 --- /dev/null +++ b/app/routes/auth.js @@ -0,0 +1,27 @@ +import TravisRoute from 'travis/routes/basic'; + +export default TravisRoute.extend({ + needsAuth: false, + + renderTemplate() { + $('body').attr('id', 'auth'); + return this.render('auth.signin'); + }, + + deactivate() { + return this.controllerFor('auth').set('redirected', false); + }, + + actions: { + afterSignIn() { + this.transitionTo('main'); + return true; + } + }, + + redirect() { + if (this.signedIn()) { + return this.transitionTo('main'); + } + } +}); diff --git a/app/routes/basic.coffee b/app/routes/basic.coffee deleted file mode 100644 index 3449337d..00000000 --- a/app/routes/basic.coffee +++ /dev/null @@ -1,27 +0,0 @@ -`import config from 'travis/config/environment'` -`import Ember from 'ember'` - -Route = Ember.Route.extend - activate: -> - if @routeName != 'error' - @controllerFor('error').set('layoutName', null) - return @_super.apply(this, arguments) - - beforeModel: (transition) -> - @auth.autoSignIn() unless @signedIn() - - if !@signedIn() && @get('needsAuth') - @auth.set('afterSignInTransition', transition) - Ember.RSVP.reject("needs-auth") - else - @_super.apply(this, arguments) - - signedIn: -> - @controllerFor('currentUser').get('model') - - needsAuth: (-> - # on pro, we need to auth on every route - config.pro - ).property() - -`export default Route` diff --git a/app/routes/basic.js b/app/routes/basic.js new file mode 100644 index 00000000..1b3a6619 --- /dev/null +++ b/app/routes/basic.js @@ -0,0 +1,32 @@ +import config from 'travis/config/environment'; +import Ember from 'ember'; + +export default Ember.Route.extend({ + activate() { + if (this.routeName !== 'error') { + this.controllerFor('error').set('layoutName', null); + } + return this._super.apply(this, arguments); + }, + + beforeModel(transition) { + if (!this.signedIn()) { + this.auth.autoSignIn(); + } + if (!this.signedIn() && this.get('needsAuth')) { + this.auth.set('afterSignInTransition', transition); + return Ember.RSVP.reject("needs-auth"); + } else { + return this._super.apply(this, arguments); + } + }, + + signedIn() { + return this.controllerFor('currentUser').get('model'); + }, + + needsAuth: function() { + // on pro, we need to auth on every route + return config.pro; + }.property() +}); diff --git a/app/routes/branches.coffee b/app/routes/branches.coffee deleted file mode 100644 index bfd60170..00000000 --- a/app/routes/branches.coffee +++ /dev/null @@ -1,29 +0,0 @@ -`import Ember from 'ember'` -`import TravisRoute from 'travis/routes/basic'` -`import config from 'travis/config/environment'` - -Route = TravisRoute.extend - - model: (params) -> - apiEndpoint = config.apiEndpoint - repoId = @modelFor('repo').get('id') - - allTheBranches = Ember.ArrayProxy.create() - - options = {} - if @get('auth.signedIn') - options.headers = { Authorization: "token #{@auth.token()}" } - - $.ajax("#{apiEndpoint}/v3/repo/#{repoId}/branches?include=build.commit&limit=100", options).then (response) -> - allTheBranches = response.branches - allTheBranches - - activate: () -> - $('.tab.tabs--main li').removeClass('active') - $('#tab_branches').addClass('active') - - deactivate: () -> - $('#tab_branches').removeClass('active') - - -`export default Route` diff --git a/app/routes/branches.js b/app/routes/branches.js new file mode 100644 index 00000000..f9136d2d --- /dev/null +++ b/app/routes/branches.js @@ -0,0 +1,31 @@ +import Ember from 'ember'; +import TravisRoute from 'travis/routes/basic'; +import config from 'travis/config/environment'; + +export default TravisRoute.extend({ + model(params) { + var allTheBranches, apiEndpoint, options, repoId; + apiEndpoint = config.apiEndpoint; + repoId = this.modelFor('repo').get('id'); + allTheBranches = Ember.ArrayProxy.create(); + options = {}; + if (this.get('auth.signedIn')) { + options.headers = { + Authorization: "token " + (this.auth.token()) + }; + } + return $.ajax(apiEndpoint + "/v3/repo/" + repoId + "/branches?include=build.commit&limit=100", options).then(function(response) { + allTheBranches = response.branches; + return allTheBranches; + }); + }, + + activate() { + $('.tab.tabs--main li').removeClass('active'); + return $('#tab_branches').addClass('active'); + }, + + deactivate() { + return $('#tab_branches').removeClass('active'); + } +}); diff --git a/app/routes/build.coffee b/app/routes/build.coffee deleted file mode 100644 index 2703be70..00000000 --- a/app/routes/build.coffee +++ /dev/null @@ -1,29 +0,0 @@ -`import TravisRoute from 'travis/routes/basic'` - -Route = TravisRoute.extend - titleToken: (model) -> - "Build ##{model.get('number')}" - - serialize: (model, params) -> - id = if model.get then model.get('id') else model - - { build_id: id } - - setupController: (controller, model) -> - if model && !model.get - model = @store.recordForId('build', model) - @store.find('build', model) - - repo = @controllerFor('repo') - @controllerFor('build').set('build', model) - repo.activate('build') - - model: (params) -> - @store.find('build', params.build_id) - - deactivate: -> - @_super.apply(this, arguments) - @controllerFor('job').set('job', null) - @controllerFor('build').set('build', null) - -`export default Route` diff --git a/app/routes/build.js b/app/routes/build.js new file mode 100644 index 00000000..bf8acb03 --- /dev/null +++ b/app/routes/build.js @@ -0,0 +1,36 @@ +import TravisRoute from 'travis/routes/basic'; + +export default TravisRoute.extend({ + titleToken(model) { + return "Build #" + (model.get('number')); + }, + + serialize(model, params) { + var id; + id = model.get ? model.get('id') : model; + return { + build_id: id + }; + }, + + setupController(controller, model) { + var repo; + if (model && !model.get) { + model = this.store.recordForId('build', model); + this.store.find('build', model); + } + repo = this.controllerFor('repo'); + this.controllerFor('build').set('build', model); + return repo.activate('build'); + }, + + model(params) { + return this.store.find('build', params.build_id); + }, + + deactivate() { + this._super.apply(this, arguments); + this.controllerFor('job').set('job', null); + return this.controllerFor('build').set('build', null); + } +}); diff --git a/app/routes/builds.coffee b/app/routes/builds.coffee deleted file mode 100644 index 1f14a47d..00000000 --- a/app/routes/builds.coffee +++ /dev/null @@ -1,7 +0,0 @@ -`import AbstractBuildsRoute from 'travis/routes/abstract-builds'` - -Route = AbstractBuildsRoute.extend( - contentType: 'builds' -) - -`export default Route` diff --git a/app/routes/builds.js b/app/routes/builds.js new file mode 100644 index 00000000..8d26c606 --- /dev/null +++ b/app/routes/builds.js @@ -0,0 +1,5 @@ +import AbstractBuildsRoute from 'travis/routes/abstract-builds'; + +export default AbstractBuildsRoute.extend({ + contentType: 'builds' +}); diff --git a/app/routes/caches.coffee b/app/routes/caches.coffee deleted file mode 100644 index 753454f2..00000000 --- a/app/routes/caches.coffee +++ /dev/null @@ -1,47 +0,0 @@ -`import Ember from 'ember'` -`import TravisRoute from 'travis/routes/basic'` - -Route = TravisRoute.extend - ajax: Ember.inject.service() - - needsAuth: true - setupController: (controller) -> - @_super.apply this, arguments - @controllerFor('repo').activate('caches') - - model: -> - repo = @modelFor('repo') - @get('ajax').get("/repos/#{repo.get('id')}/caches").then( (data) -> - caches = {} - - data["caches"].forEach (cacheData) -> - branch = cacheData.branch - cache = caches[branch] - - if cache - cache.size += cacheData.size - - if cache.last_modified < cacheData.last_modified - cache.last_modified = cacheData.last_modified - else - caches[branch] = cacheData - - pushes = [] - pullRequests = [] - - - for branch, cache of caches - if /PR./.test(branch) - cache.type = "pull_request" - pullRequests.push cache - else - cache.type = "push" - pushes.push cache - - { - pushes: pushes, - pullRequests: pullRequests - } - ) - -`export default Route` diff --git a/app/routes/caches.js b/app/routes/caches.js new file mode 100644 index 00000000..8f9043b8 --- /dev/null +++ b/app/routes/caches.js @@ -0,0 +1,51 @@ +import Ember from 'ember'; +import TravisRoute from 'travis/routes/basic'; + +export default TravisRoute.extend({ + ajax: Ember.inject.service(), + needsAuth: true, + + setupController(controller) { + this._super.apply(this, arguments); + return this.controllerFor('repo').activate('caches'); + }, + + model() { + var repo; + repo = this.modelFor('repo'); + return this.get('ajax').get("/repos/" + (repo.get('id')) + "/caches").then(function(data) { + var branch, cache, caches, pullRequests, pushes; + caches = {}; + data["caches"].forEach(function(cacheData) { + var branch, cache; + branch = cacheData.branch; + cache = caches[branch]; + if (cache) { + cache.size += cacheData.size; + if (cache.last_modified < cacheData.last_modified) { + return cache.last_modified = cacheData.last_modified; + } + } else { + return caches[branch] = cacheData; + } + }); + pushes = []; + pullRequests = []; + for (branch in caches) { + cache = caches[branch]; + if (/PR./.test(branch)) { + cache.type = "pull_request"; + pullRequests.push(cache); + } else { + cache.type = "push"; + pushes.push(cache); + } + } + return { + pushes: pushes, + pullRequests: pullRequests + }; + }); + } + +}); diff --git a/app/routes/dashboard.coffee b/app/routes/dashboard.coffee deleted file mode 100644 index e49e7838..00000000 --- a/app/routes/dashboard.coffee +++ /dev/null @@ -1,6 +0,0 @@ -`import TravisRoute from 'travis/routes/basic'` - -Route = TravisRoute.extend - needsAuth: true - -`export default Route` diff --git a/app/routes/dashboard.js b/app/routes/dashboard.js new file mode 100644 index 00000000..5e2a47c7 --- /dev/null +++ b/app/routes/dashboard.js @@ -0,0 +1,5 @@ +import TravisRoute from 'travis/routes/basic'; + +export default TravisRoute.extend({ + needsAuth: true +}); diff --git a/app/routes/dashboard/repositories.coffee b/app/routes/dashboard/repositories.coffee deleted file mode 100644 index 36ec9c4a..00000000 --- a/app/routes/dashboard/repositories.coffee +++ /dev/null @@ -1,22 +0,0 @@ -`import Ember from 'ember'` -`import TravisRoute from 'travis/routes/basic'` -`import config from 'travis/config/environment'` - -Route = TravisRoute.extend - queryParams: - filter: { replace: true } - model: -> - apiEndpoint = config.apiEndpoint - $.ajax(apiEndpoint + '/v3/repos?repository.active=true&include=repository.default_branch,build.commit', { - headers: { - Authorization: 'token ' + @auth.token() - } - }).then (response) -> - response.repositories.filter( (repo) -> - if repo.default_branch - repo.default_branch.last_build - ).map( (repo) -> - Ember.Object.create(repo) - ).sortBy('default_branch.last_build.finished_at') - -`export default Route` diff --git a/app/routes/dashboard/repositories.js b/app/routes/dashboard/repositories.js new file mode 100644 index 00000000..e283ee93 --- /dev/null +++ b/app/routes/dashboard/repositories.js @@ -0,0 +1,29 @@ +import Ember from 'ember'; +import TravisRoute from 'travis/routes/basic'; +import config from 'travis/config/environment'; + +export default TravisRoute.extend({ + queryParams: { + filter: { + replace: true + } + }, + + model() { + var apiEndpoint; + apiEndpoint = config.apiEndpoint; + return $.ajax(apiEndpoint + '/v3/repos?repository.active=true&include=repository.default_branch,build.commit', { + headers: { + Authorization: 'token ' + this.auth.token() + } + }).then(function(response) { + return response.repositories.filter(function(repo) { + if (repo.default_branch) { + return repo.default_branch.last_build; + } + }).map(function(repo) { + return Ember.Object.create(repo); + }).sortBy('default_branch.last_build.finished_at'); + }); + } +}); diff --git a/app/routes/first-sync.coffee b/app/routes/first-sync.coffee deleted file mode 100644 index 7611a866..00000000 --- a/app/routes/first-sync.coffee +++ /dev/null @@ -1,33 +0,0 @@ -`import SimpleLayoutRoute from 'travis/routes/simple-layout'` - -Route = SimpleLayoutRoute.extend - activate: -> - controller = @controllerFor('firstSync') - controller.addObserver('isSyncing', this, @isSyncingDidChange) - - deactivate: -> - controller = @controllerFor('firstSync') - controller.removeObserver('controller.isSyncing', this, @isSyncingDidChange) - - isSyncingDidChange: -> - controller = @controllerFor('firstSync') - - if !controller.get('isSyncing') - self = this - Ember.run.later this, -> - @store.query('repo', member: @get('controller.user.login')).then( (repos) -> - if repos.get('length') - self.transitionTo('main') - else - self.transitionTo('profile') - ).then(null, (e) -> - console.log('There was a problem while redirecting from first sync', e) - ) - , @get('config').syncingPageRedirectionTime - - actions: - redirectToGettingStarted: -> - # do nothing, we are showing first sync, so it's normal that there is - # no owned repos - -`export default Route` diff --git a/app/routes/first-sync.js b/app/routes/first-sync.js new file mode 100644 index 00000000..a2e1b455 --- /dev/null +++ b/app/routes/first-sync.js @@ -0,0 +1,43 @@ +import SimpleLayoutRoute from 'travis/routes/simple-layout'; + +export default SimpleLayoutRoute.extend({ + activate() { + var controller; + controller = this.controllerFor('firstSync'); + return controller.addObserver('isSyncing', this, this.isSyncingDidChange); + }, + + deactivate() { + var controller; + controller = this.controllerFor('firstSync'); + return controller.removeObserver('controller.isSyncing', this, this.isSyncingDidChange); + }, + + isSyncingDidChange() { + var controller, self; + controller = this.controllerFor('firstSync'); + if (!controller.get('isSyncing')) { + self = this; + return Ember.run.later(this, function() { + return this.store.query('repo', { + member: this.get('controller.user.login') + }).then(function(repos) { + if (repos.get('length')) { + return self.transitionTo('main'); + } else { + return self.transitionTo('profile'); + } + }).then(null, function(e) { + return console.log('There was a problem while redirecting from first sync', e); + }); + }, this.get('config').syncingPageRedirectionTime); + } + }, + + actions: { + redirectToGettingStarted: function() { + // do nothing, we are showing first sync, so it's normal that there is + // no owned repos + } + } +}); diff --git a/app/routes/getting-started.coffee b/app/routes/getting-started.coffee deleted file mode 100644 index 929e99f1..00000000 --- a/app/routes/getting-started.coffee +++ /dev/null @@ -1,7 +0,0 @@ -`import TravisRoute from 'travis/routes/basic'` - -Route = TravisRoute.extend - setupController: (controller)-> - @container.lookup('controller:repos').activate('owned') - -`export default Route` diff --git a/app/routes/getting-started.js b/app/routes/getting-started.js new file mode 100644 index 00000000..14348163 --- /dev/null +++ b/app/routes/getting-started.js @@ -0,0 +1,7 @@ +import TravisRoute from 'travis/routes/basic'; + +export default TravisRoute.extend({ + setupController(controller) { + return this.container.lookup('controller:repos').activate('owned'); + } +}); diff --git a/app/routes/home-pro.coffee b/app/routes/home-pro.coffee deleted file mode 100644 index a843adc0..00000000 --- a/app/routes/home-pro.coffee +++ /dev/null @@ -1,6 +0,0 @@ -`import TravisRoute from 'travis/routes/basic'` - -Route = TravisRoute.extend - needsAuth: false - -`export default Route` diff --git a/app/routes/home-pro.js b/app/routes/home-pro.js new file mode 100644 index 00000000..0f305d73 --- /dev/null +++ b/app/routes/home-pro.js @@ -0,0 +1,5 @@ +import TravisRoute from 'travis/routes/basic'; + +export default TravisRoute.extend({ + needsAuth: false +}); diff --git a/app/routes/home.coffee b/app/routes/home.coffee deleted file mode 100644 index a1de26bc..00000000 --- a/app/routes/home.coffee +++ /dev/null @@ -1,52 +0,0 @@ -`import BasicRoute from 'travis/routes/basic'` -`import config from 'travis/config/environment'` -`import limit from 'travis/utils/computed-limit'` - -Route = BasicRoute.extend - init: -> - store = @store - repos = Ember.ArrayProxy.extend( - isLoadedBinding: 'repos.isLoaded' - repos: [] - sorted: Ember.computed.sort('repos', 'sortedReposKeys') - content: limit('sorted', 'limit') - sortedReposKeys: ['sortOrderForLandingPage:desc'] - limit: 3 - ).create() - - @set('repos', repos) - - @loadMoreRepos() - - @_super.apply this, arguments - - loadMoreRepos: -> - @store.findAll('build').then (builds) => - repoIds = builds.mapBy('data.repo').uniq() - repos = @get('repos.repos') - @store.query('repo', ids: repoIds).then (reposFromRequest) => - reposFromRequest.toArray().forEach (repo) -> - repos.pushObject(repo) unless repos.contains(repo) - - activate: -> - @_super.apply(this, arguments) - - interval = setInterval( => - @loadMoreRepos() - , 60000) - @set('interval', interval) - - @controllerFor('top').set('landingPage', true) - - deactivate: -> - @_super.apply(this, arguments) - - if interval = @get('interval') - clearInterval(interval) - - @controllerFor('top').set('landingPage', false) - - setupController: (controller, model) -> - controller.set('repos', @get('repos')) - -`export default Route` diff --git a/app/routes/home.js b/app/routes/home.js new file mode 100644 index 00000000..baa9d6fa --- /dev/null +++ b/app/routes/home.js @@ -0,0 +1,64 @@ +import BasicRoute from 'travis/routes/basic'; +import config from 'travis/config/environment'; +import limit from 'travis/utils/computed-limit'; + +export default BasicRoute.extend({ + init: function() { + var repos, store; + + store = this.store; + repos = Ember.ArrayProxy.extend({ + isLoadedBinding: 'repos.isLoaded', + repos: [], + sorted: Ember.computed.sort('repos', 'sortedReposKeys'), + content: limit('sorted', 'limit'), + sortedReposKeys: ['sortOrderForLandingPage:desc'], + limit: 3 + }).create(); + + this.set('repos', repos); + this.loadMoreRepos(); + + return this._super.apply(this, arguments); + }, + + loadMoreRepos() { + return this.store.findAll('build').then(() => { + var repoIds, repos; + repoIds = builds.mapBy('data.repo').uniq(); + repos = this.get('repos.repos'); + return this.store.query('repo', { + ids: repoIds + }).then(function(reposFromRequest) { + return reposFromRequest.toArray().forEach(function(repo) { + if (!repos.contains(repo)) { + return repos.pushObject(repo); + } + }); + }); + }); + }, + + activate() { + var interval; + this._super.apply(this, arguments); + interval = setInterval(() => { + return this.loadMoreRepos(); + }, 60000); + this.set('interval', interval); + return this.controllerFor('top').set('landingPage', true); + }, + + deactivate() { + var interval; + this._super.apply(this, arguments); + if (interval = this.get('interval')) { + clearInterval(interval); + } + return this.controllerFor('top').set('landingPage', false); + }, + + setupController(controller, model) { + return controller.set('repos', this.get('repos')); + } +}); diff --git a/app/routes/insufficient-oauth-permissions.coffee b/app/routes/insufficient-oauth-permissions.coffee deleted file mode 100644 index 760fa8cd..00000000 --- a/app/routes/insufficient-oauth-permissions.coffee +++ /dev/null @@ -1,9 +0,0 @@ -`import SimpleLayoutRoute from 'travis/routes/simple-layout'` - -Route = SimpleLayoutRoute.extend - setupController: (controller) -> - @_super.apply this, arguments - existingUser = document.location.hash.match(/#existing[_-]user/) - controller.set('existingUser', existingUser) - -`export default Route` diff --git a/app/routes/insufficient-oauth-permissions.js b/app/routes/insufficient-oauth-permissions.js new file mode 100644 index 00000000..8998a218 --- /dev/null +++ b/app/routes/insufficient-oauth-permissions.js @@ -0,0 +1,11 @@ +import SimpleLayoutRoute from 'travis/routes/simple-layout'; + +export default SimpleLayoutRoute.extend({ + setupController(controller) { + var existingUser; + + this._super.apply(this, arguments); + existingUser = document.location.hash.match(/#existing[_-]user/); + return controller.set('existingUser', existingUser); + } +}); diff --git a/app/routes/job.coffee b/app/routes/job.coffee deleted file mode 100644 index e6320fa8..00000000 --- a/app/routes/job.coffee +++ /dev/null @@ -1,45 +0,0 @@ -`import TravisRoute from 'travis/routes/basic'` - -Route = TravisRoute.extend - titleToken: (model) -> - "Job ##{model.get('number')}" - - serialize: (model, params) -> - id = if model.get then model.get('id') else model - - { job_id: id } - - setupController: (controller, model) -> - if model && !model.get - model = @store.recordForId('job', model) - @store.find('job', model) - - repo = @controllerFor('repo') - @controllerFor('job').set('job', model) - repo.activate('job') - - 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) - - model: (params) -> - @store.find('job', params.job_id) - - deactivate: -> - buildController = @controllerFor('build') - buildController.set('sendFaviconStateChanges', true) - @controllerFor('build').set('build', null) - @controllerFor('job').set('job', null) - - @_super.apply(this, arguments) - -`export default Route` diff --git a/app/routes/job.js b/app/routes/job.js new file mode 100644 index 00000000..08e0f2bd --- /dev/null +++ b/app/routes/job.js @@ -0,0 +1,53 @@ +import TravisRoute from 'travis/routes/basic'; + +export default TravisRoute.extend({ + titleToken(model) { + return "Job #" + (model.get('number')); + }, + + serialize(model, params) { + var id; + id = model.get ? model.get('id') : model; + return { + job_id: id + }; + }, + + setupController(controller, model) { + var buildController, buildPromise, repo; + if (model && !model.get) { + model = this.store.recordForId('job', model); + this.store.find('job', model); + } + repo = this.controllerFor('repo'); + this.controllerFor('job').set('job', model); + repo.activate('job'); + buildController = this.controllerFor('build'); + model.get('repo'); + if (buildPromise = model.get('build')) { + buildPromise.then(() => { + build = this.store.recordForId('build', build.get('id')); + return 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 + return buildController.set('sendFaviconStateChanges', false); + }, + + model(params) { + return this.store.find('job', params.job_id); + }, + + deactivate() { + var buildController; + buildController = this.controllerFor('build'); + buildController.set('sendFaviconStateChanges', true); + this.controllerFor('build').set('build', null); + this.controllerFor('job').set('job', null); + return this._super.apply(this, arguments); + } + +}); diff --git a/app/routes/logo.coffee b/app/routes/logo.coffee deleted file mode 100644 index c09424b6..00000000 --- a/app/routes/logo.coffee +++ /dev/null @@ -1,7 +0,0 @@ -`import Ember from 'ember'` -`import TravisRoute from 'travis/routes/basic'` - -Route = TravisRoute.extend - needsAuth: false - -`export default Route` diff --git a/app/routes/logo.js b/app/routes/logo.js new file mode 100644 index 00000000..7c9d4827 --- /dev/null +++ b/app/routes/logo.js @@ -0,0 +1,6 @@ +import Ember from 'ember'; +import TravisRoute from 'travis/routes/basic'; + +export default TravisRoute.extend({ + needsAuth: false +}); diff --git a/app/routes/main-tab.coffee b/app/routes/main-tab.coffee deleted file mode 100644 index b98e7587..00000000 --- a/app/routes/main-tab.coffee +++ /dev/null @@ -1,35 +0,0 @@ -`import TravisRoute from 'travis/routes/basic'` - -Route = TravisRoute.extend - renderTemplate: -> - @render 'repo' - @render 'build', into: 'repo' - - setupController: -> - @_super.apply this, arguments - - @controllerFor('repo').activate('index') - @controllerFor('repos').activate(@get('reposTabName')) - - @setCurrentRepoObservers() - - deactivate: -> - if repos = @controllerFor('repos') - repos.removeObserver('repos.firstObject', this, 'currentRepoDidChange') - - @_super.apply(this, arguments) - - currentRepoDidChange: -> - 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') - -`export default Route` diff --git a/app/routes/main-tab.js b/app/routes/main-tab.js new file mode 100644 index 00000000..78c7fc9f --- /dev/null +++ b/app/routes/main-tab.js @@ -0,0 +1,46 @@ +import TravisRoute from 'travis/routes/basic'; + +export default TravisRoute.extend({ + renderTemplate() { + this.render('repo'); + return this.render('build', { + into: 'repo' + }); + }, + + setupController() { + this._super.apply(this, arguments); + this.controllerFor('repo').activate('index'); + this.controllerFor('repos').activate(this.get('reposTabName')); + return this.setCurrentRepoObservers(); + }, + + deactivate() { + var repos; + if (repos = this.controllerFor('repos')) { + repos.removeObserver('repos.firstObject', this, 'currentRepoDidChange'); + } + return this._super.apply(this, arguments); + }, + + currentRepoDidChange() { + var repo; + if (repo = this.controllerFor('repos').get('repos.firstObject')) { + return this.controllerFor('repo').set('repo', repo); + } + }, + + setCurrentRepoObservers() { + var repos; + this.currentRepoDidChange(); + if (repos = this.controllerFor('repos')) { + return repos.addObserver('repos.firstObject', this, 'currentRepoDidChange'); + } + }, + + actions: { + redirectToGettingStarted() { + return this.transitionTo('getting_started'); + } + } +}); diff --git a/app/routes/main.coffee b/app/routes/main.coffee deleted file mode 100644 index 46afa39f..00000000 --- a/app/routes/main.coffee +++ /dev/null @@ -1,19 +0,0 @@ -#require 'pusher' -#channels = Travis.Pusher.CHANNELS - -`import TravisRoute from 'travis/routes/basic'` -`import config from 'travis/config/environment'` - -Route = TravisRoute.extend - renderTemplate: -> - $('body').attr('id', 'home') - - @_super.apply this, arguments - - @render 'repos', outlet: 'left', into: 'main' - - setupController: (controller)-> - # TODO: this is redundant with repositories and recent routes - #@container.lookup('controller:repos').activate('owned') - -`export default Route` diff --git a/app/routes/main.js b/app/routes/main.js new file mode 100644 index 00000000..e791ab2d --- /dev/null +++ b/app/routes/main.js @@ -0,0 +1,20 @@ +import TravisRoute from 'travis/routes/basic'; +import config from 'travis/config/environment'; + +export default TravisRoute.extend({ + renderTemplate() { + $('body').attr('id', 'home'); + + this._super.apply(this, arguments); + + return this.render('repos', { + outlet: 'left', + into: 'main' + }); + }, + + setupController(controller) { + // TODO: this is redundant with repositories and recent routes + // @container.lookup('controller:repos').activate('owned') + } +}); diff --git a/app/routes/main/index.coffee b/app/routes/main/index.coffee deleted file mode 100644 index 6e01861f..00000000 --- a/app/routes/main/index.coffee +++ /dev/null @@ -1,10 +0,0 @@ -`import TravisRoute from 'travis/routes/basic'` - -Route = TravisRoute.extend - redirect: -> - if @signedIn() - @transitionTo('main.repositories') - else - @transitionTo('home') - -`export default Route` diff --git a/app/routes/main/index.js b/app/routes/main/index.js new file mode 100644 index 00000000..50a2818d --- /dev/null +++ b/app/routes/main/index.js @@ -0,0 +1,11 @@ +import TravisRoute from 'travis/routes/basic'; + +export default TravisRoute.extend({ + redirect() { + if (this.signedIn()) { + return this.transitionTo('main.repositories'); + } else { + return this.transitionTo('home'); + } + } +}); diff --git a/app/routes/main/my-repositories.coffee b/app/routes/main/my-repositories.coffee deleted file mode 100644 index 51bb3987..00000000 --- a/app/routes/main/my-repositories.coffee +++ /dev/null @@ -1,7 +0,0 @@ -`import TravisRoute from 'travis/routes/basic'` - -Route = TravisRoute.extend - redirect: -> - @transitionTo("main.repositories") - -`export default Route` diff --git a/app/routes/main/my-repositories.js b/app/routes/main/my-repositories.js new file mode 100644 index 00000000..eb070bf7 --- /dev/null +++ b/app/routes/main/my-repositories.js @@ -0,0 +1,7 @@ +import TravisRoute from 'travis/routes/basic'; + +export default TravisRoute.extend({ + redirect() { + return this.transitionTo("main.repositories"); + } +}); diff --git a/app/routes/main/recent.coffee b/app/routes/main/recent.coffee deleted file mode 100644 index caf6d5b9..00000000 --- a/app/routes/main/recent.coffee +++ /dev/null @@ -1,7 +0,0 @@ -`import Ember from 'ember'` - -Route = Ember.Route.extend - redirect: -> - @transitionTo('main') - -`export default Route` diff --git a/app/routes/main/recent.js b/app/routes/main/recent.js new file mode 100644 index 00000000..cf61beb5 --- /dev/null +++ b/app/routes/main/recent.js @@ -0,0 +1,7 @@ +import Ember from 'ember'; + +export default Ember.Route.extend({ + redirect() { + return this.transitionTo('main'); + } +}); diff --git a/app/routes/main/repositories.coffee b/app/routes/main/repositories.coffee deleted file mode 100644 index ed35b505..00000000 --- a/app/routes/main/repositories.coffee +++ /dev/null @@ -1,9 +0,0 @@ -`import MainTabRoute from 'travis/routes/main-tab'` - -Route = MainTabRoute.extend - needsAuth: true - reposTabName: 'owned' - afterModel: -> - @controllerFor('repos').possiblyRedirectToGettingStartedPage() - -`export default Route` diff --git a/app/routes/main/repositories.js b/app/routes/main/repositories.js new file mode 100644 index 00000000..ac6b690c --- /dev/null +++ b/app/routes/main/repositories.js @@ -0,0 +1,10 @@ +import MainTabRoute from 'travis/routes/main-tab'; + +export default MainTabRoute.extend({ + needsAuth: true, + reposTabName: 'owned', + + afterModel() { + return this.controllerFor('repos').possiblyRedirectToGettingStartedPage(); + } +}); diff --git a/app/routes/main/search.coffee b/app/routes/main/search.coffee deleted file mode 100644 index 58d48426..00000000 --- a/app/routes/main/search.coffee +++ /dev/null @@ -1,23 +0,0 @@ -`import MainTabRoute from 'travis/routes/main-tab'` - -Route = MainTabRoute.extend - renderTemplate: -> - @render 'repo' - @render 'build', into: 'repo' - - setupController: (controller, searchPhrase) -> - # TODO: this method is almost the same as _super, refactor this - @controllerFor('repo').activate('index') - @controllerFor('repos').activate('search', searchPhrase) - - @setCurrentRepoObservers() - - model: (params) -> - params.phrase.replace(/%2F/g, '/') - - deactivate: -> - @_super.apply(this, arguments) - - @controllerFor('repos').set('search', undefined) - -`export default Route` diff --git a/app/routes/main/search.js b/app/routes/main/search.js new file mode 100644 index 00000000..a930533c --- /dev/null +++ b/app/routes/main/search.js @@ -0,0 +1,25 @@ +import MainTabRoute from 'travis/routes/main-tab'; + +export default MainTabRoute.extend({ + renderTemplate() { + this.render('repo'); + return this.render('build', { + into: 'repo' + }); + }, + + setupController(controller, searchPhrase) { + this.controllerFor('repo').activate('index'); + this.controllerFor('repos').activate('search', searchPhrase); + return this.setCurrentRepoObservers(); + }, + + model(params) { + return params.phrase.replace(/%2F/g, '/'); + }, + + deactivate() { + this._super.apply(this, arguments); + return this.controllerFor('repos').set('search', void 0); + } +}); diff --git a/app/routes/not-found.coffee b/app/routes/not-found.coffee deleted file mode 100644 index 4ebc5df8..00000000 --- a/app/routes/not-found.coffee +++ /dev/null @@ -1,9 +0,0 @@ -`import TravisRoute from 'travis/routes/basic'` - -Route = TravisRoute.extend - renderTemplate: -> - $('body').attr('id', 'not-found') - - @render 'not_found' - -`export default Route` diff --git a/app/routes/not-found.js b/app/routes/not-found.js new file mode 100644 index 00000000..8c1bceba --- /dev/null +++ b/app/routes/not-found.js @@ -0,0 +1,8 @@ +import TravisRoute from 'travis/routes/basic'; + +export default TravisRoute.extend({ + renderTemplate() { + $('body').attr('id', 'not-found'); + return this.render('not_found'); + } +}); diff --git a/app/routes/owner.coffee b/app/routes/owner.coffee deleted file mode 100644 index 98a6d17a..00000000 --- a/app/routes/owner.coffee +++ /dev/null @@ -1,34 +0,0 @@ -`import Ember from 'ember'` -`import TravisRoute from 'travis/routes/basic'` -`import config from 'travis/config/environment'` - -Route = TravisRoute.extend - deactivate: -> - @controllerFor('loading').set('layoutName', null) - - model: (params) -> - options = {} - if @get('auth.signedIn') - options.headers = { Authorization: "token #{@auth.token()}" } - $.ajax(config.apiEndpoint + "/v3/owner/#{params.owner}?include=organization.repositories,repository.default_branch,build.commit", options) - - beforeModel: -> - @controllerFor('loading').set('layoutName', 'simple') - - @_super.apply(this, arguments) - - actions: - error: (error, transition, originRoute) -> - login = transition.params.owner.owner - - message = if error.status == 404 - @transitionTo('error404') - else - "There was an error while loading data, please try again." - - @controllerFor('error').set('layoutName', 'simple') - @controllerFor('error').set('message', message) - - return true - -`export default Route` diff --git a/app/routes/owner.js b/app/routes/owner.js new file mode 100644 index 00000000..9f69e017 --- /dev/null +++ b/app/routes/owner.js @@ -0,0 +1,37 @@ +import Ember from 'ember'; +import TravisRoute from 'travis/routes/basic'; +import config from 'travis/config/environment'; + +export default TravisRoute.extend({ + deactivate() { + return this.controllerFor('loading').set('layoutName', null); + }, + + model(params) { + var options; + options = {}; + if (this.get('auth.signedIn')) { + options.headers = { + Authorization: "token " + (this.auth.token()) + }; + } + return $.ajax(config.apiEndpoint + ("/v3/owner/" + params.owner + "?include=organization.repositories,repository.default_branch,build.commit"), options); + }, + + beforeModel() { + this.controllerFor('loading').set('layoutName', 'simple'); + return this._super.apply(this, arguments); + }, + actions: { + + error(error, transition, originRoute) { + var login, message; + + login = transition.params.owner.owner; + message = error.status === 404 ? this.transitionTo('error404') : "There was an error while loading data, please try again."; + this.controllerFor('error').set('layoutName', 'simple'); + this.controllerFor('error').set('message', message); + return true; + } + } +}); diff --git a/app/routes/owner/repositories.coffee b/app/routes/owner/repositories.coffee deleted file mode 100644 index 8a647b9b..00000000 --- a/app/routes/owner/repositories.coffee +++ /dev/null @@ -1,18 +0,0 @@ -`import Ember from 'ember'` -`import TravisRoute from 'travis/routes/basic'` -`import config from 'travis/config/environment'` - -Route = TravisRoute.extend - needsAuth: false - - titleToken: (model) -> - "#{model.name}" - - model: (params, transition) -> - options = {} - if @get('auth.signedIn') - options.headers = { Authorization: "token #{@auth.token()}" } - $.ajax(config.apiEndpoint + "/v3/owner/#{transition.params.owner.owner}?include=owner.repositories,repository.default_branch,build.commit", options).then (response) -> - response - -`export default Route` diff --git a/app/routes/owner/repositories.js b/app/routes/owner/repositories.js new file mode 100644 index 00000000..f6f2aeac --- /dev/null +++ b/app/routes/owner/repositories.js @@ -0,0 +1,26 @@ +import Ember from 'ember'; +import TravisRoute from 'travis/routes/basic'; +import config from 'travis/config/environment'; + +export default TravisRoute.extend({ + needsAuth: false, + + titleToken(model) { + return "" + model.name; + }, + + model(params, transition) { + var options; + options = {}; + + if (this.get('auth.signedIn')) { + options.headers = { + Authorization: "token " + (this.auth.token()) + }; + } + + return $.ajax(config.apiEndpoint + ("/v3/owner/" + transition.params.owner.owner + "?include=owner.repositories,repository.default_branch,build.commit"), options).then(function(response) { + return response; + }); + } +}); diff --git a/app/routes/owner/running.coffee b/app/routes/owner/running.coffee deleted file mode 100644 index 47ed43a3..00000000 --- a/app/routes/owner/running.coffee +++ /dev/null @@ -1,14 +0,0 @@ -`import Ember from 'ember'` -`import TravisRoute from 'travis/routes/basic'` -`import config from 'travis/config/environment'` - -Route = TravisRoute.extend - needsAuth: false - - titleToken: (model) -> - "#{model.name}" - - model: (params, transition) -> - $.get(config.apiEndpoint + "/v3/owner/#{transition.params.owner.owner}?include=user.repositories,organization.repositories,build.commit,repository.active") - -`export default Route` diff --git a/app/routes/owner/running.js b/app/routes/owner/running.js new file mode 100644 index 00000000..3f4ba7e3 --- /dev/null +++ b/app/routes/owner/running.js @@ -0,0 +1,15 @@ +import Ember from 'ember'; +import TravisRoute from 'travis/routes/basic'; +import config from 'travis/config/environment'; + +export default TravisRoute.extend({ + needsAuth: false, + + titleToken(model) { + return "" + model.name; + }, + + model(params, transition) { + return $.get(config.apiEndpoint + ("/v3/owner/" + transition.params.owner.owner + "?include=user.repositories,organization.repositories,build.commit,repository.active")); + } +}); diff --git a/app/routes/plans.coffee b/app/routes/plans.coffee deleted file mode 100644 index f075291d..00000000 --- a/app/routes/plans.coffee +++ /dev/null @@ -1,10 +0,0 @@ -`import BasicRoute from 'travis/routes/basic'` -`import config from 'travis/config/environment'` - -Route = BasicRoute.extend - needsAuth: false - redirect: -> - unless config.pro - @transitionTo('/') - -`export default Route` diff --git a/app/routes/plans.js b/app/routes/plans.js new file mode 100644 index 00000000..0be3eb15 --- /dev/null +++ b/app/routes/plans.js @@ -0,0 +1,12 @@ +import BasicRoute from 'travis/routes/basic'; +import config from 'travis/config/environment'; + +export default BasicRoute.extend({ + needsAuth: false, + + redirect() { + if (!config.pro) { + return this.transitionTo('/'); + } + } +}); diff --git a/app/routes/profile.coffee b/app/routes/profile.coffee deleted file mode 100644 index 5fdab2a2..00000000 --- a/app/routes/profile.coffee +++ /dev/null @@ -1,16 +0,0 @@ -`import TravisRoute from 'travis/routes/basic'` - -Route = TravisRoute.extend - titleToken: 'Profile' - - needsAuth: true - - setupController: (controller, model) -> - @controllerFor('accounts').set('model', model) - - renderTemplate: -> - $('body').attr('id', 'profile') - @_super.apply(this, arguments) - @render 'loading', outlet: 'left', into: 'profile' - -`export default Route` diff --git a/app/routes/profile.js b/app/routes/profile.js new file mode 100644 index 00000000..9b9c7cea --- /dev/null +++ b/app/routes/profile.js @@ -0,0 +1,20 @@ +import TravisRoute from 'travis/routes/basic'; + +export default TravisRoute.extend({ + titleToken: 'Profile', + needsAuth: true, + + setupController(controller, model) { + return this.controllerFor('accounts').set('model', model); + }, + + renderTemplate() { + $('body').attr('id', 'profile'); + this._super.apply(this, arguments); + + return this.render('loading', { + outlet: 'left', + into: 'profile' + }); + } +}); diff --git a/app/routes/pull-requests.coffee b/app/routes/pull-requests.coffee deleted file mode 100644 index 4f07d233..00000000 --- a/app/routes/pull-requests.coffee +++ /dev/null @@ -1,7 +0,0 @@ -`import AbstractBuildsRoute from 'travis/routes/abstract-builds'` - -Route = AbstractBuildsRoute.extend( - contentType: 'pull_requests' -) - -`export default Route` diff --git a/app/routes/pull-requests.js b/app/routes/pull-requests.js new file mode 100644 index 00000000..31ba3fd3 --- /dev/null +++ b/app/routes/pull-requests.js @@ -0,0 +1,5 @@ +import AbstractBuildsRoute from 'travis/routes/abstract-builds'; + +export default AbstractBuildsRoute.extend({ + contentType: 'pull_requests' +}); diff --git a/app/routes/repo.coffee b/app/routes/repo.coffee deleted file mode 100644 index 9bf034dc..00000000 --- a/app/routes/repo.coffee +++ /dev/null @@ -1,43 +0,0 @@ -`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') - - renderTemplate: -> - @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 = @get('store').find('repo', model.id) if model && !model.get - controller.set('repo', model) - - serialize: (repo) -> - slug = if repo.get then repo.get('slug') else repo.slug - [owner, name] = slug.split('/') - { owner: owner, name: name } - - model: (params) -> - slug = "#{params.owner}/#{params.name}" - Repo.fetchBySlug(@get('store'), slug) - - resetController: -> - @controllerFor('repo').deactivate() - - actions: - error: (error) -> - # if error throwed has a slug (ie. it was probably repo not found) - # set the slug on main.error controller to allow to properly - # display the repo information - if error.slug - this.controllerFor('main.error').set('slug', error.slug) - - # bubble to the top - return true - -`export default Route` diff --git a/app/routes/repo.js b/app/routes/repo.js new file mode 100644 index 00000000..0057b069 --- /dev/null +++ b/app/routes/repo.js @@ -0,0 +1,57 @@ +import TravisRoute from 'travis/routes/basic'; +import Repo from 'travis/models/repo'; +import Ember from 'ember'; + +export default TravisRoute.extend({ + store: Ember.inject.service(), + + titleToken(model) { + return model.get('slug'); + }, + + renderTemplate() { + return this.render('repo', { + into: 'main' + }); + }, + + setupController(controller, model) { + this.container.lookup('controller:repos').activate('owned'); + if (model && !model.get) { + model = this.get('store').find('repo', model.id); + } + return controller.set('repo', model); + }, + + serialize(repo) { + var name, owner, ref, slug; + slug = repo.get ? repo.get('slug') : repo.slug; + ref = slug.split('/'), owner = ref[0], name = ref[1]; + return { + owner: owner, + name: name + }; + }, + + model(params) { + var slug; + slug = params.owner + "/" + params.name; + return Repo.fetchBySlug(this.get('store'), slug); + }, + + resetController() { + return this.controllerFor('repo').deactivate(); + }, + + actions: { + error(error) { + if (error.slug) { + // if error thrown has a slug (ie. it was probably repo not found) + // set the slug on main.error controller to allow to properly + // display the repo information + this.controllerFor('main.error').set('slug', error.slug); + } + return true; + } + } +}); diff --git a/app/routes/repo/index.coffee b/app/routes/repo/index.coffee deleted file mode 100644 index d713441f..00000000 --- a/app/routes/repo/index.coffee +++ /dev/null @@ -1,22 +0,0 @@ -`import TravisRoute from 'travis/routes/basic'` -`import Config from 'travis/config/environment'` - -Route = TravisRoute.extend - setupController: (controller, model) -> - @_super.apply this, arguments - @controllerFor('repo').activate('current') - - renderTemplate: -> - if @modelFor('repo').get('lastBuildId') - @render 'build' - else - @render 'builds/not_found' - - deactivate: -> - repo = @controllerFor('repo') - @controllerFor('build').set('build', null) - @controllerFor('job').set('job', null) - - @_super.apply(this, arguments) - -`export default Route` diff --git a/app/routes/repo/index.js b/app/routes/repo/index.js new file mode 100644 index 00000000..2fc1fbd2 --- /dev/null +++ b/app/routes/repo/index.js @@ -0,0 +1,24 @@ +import TravisRoute from 'travis/routes/basic'; +import Config from 'travis/config/environment'; + +export default TravisRoute.extend({ + setupController(controller, model) { + this._super.apply(this, arguments); + return this.controllerFor('repo').activate('current'); + }, + + renderTemplate() { + if (this.modelFor('repo').get('lastBuildId')) { + return this.render('build'); + } else { + return this.render('builds/not_found'); + } + }, + deactivate() { + var repo; + repo = this.controllerFor('repo'); + this.controllerFor('build').set('build', null); + this.controllerFor('job').set('job', null); + return this._super.apply(this, arguments); + } +}); diff --git a/app/routes/request.coffee b/app/routes/request.coffee deleted file mode 100644 index 3017c198..00000000 --- a/app/routes/request.coffee +++ /dev/null @@ -1,11 +0,0 @@ -`import TravisRoute from 'travis/routes/basic'` - -Route = TravisRoute.extend - setupController: -> - @_super.apply this, arguments - @controllerFor('repo').activate('request') - - model: (params) -> - @store.find 'request', params.request_id - -`export default Route` diff --git a/app/routes/request.js b/app/routes/request.js new file mode 100644 index 00000000..3f1a0d02 --- /dev/null +++ b/app/routes/request.js @@ -0,0 +1,12 @@ +import TravisRoute from 'travis/routes/basic'; + +export default TravisRoute.extend({ + setupController() { + this._super(...arguments); + return this.controllerFor('repo').activate('request'); + }, + + model(params) { + return this.store.find('request', params.request_id); + } +}); diff --git a/app/routes/requests.coffee b/app/routes/requests.coffee deleted file mode 100644 index 2e21f91b..00000000 --- a/app/routes/requests.coffee +++ /dev/null @@ -1,12 +0,0 @@ -`import TravisRoute from 'travis/routes/basic'` - -Route = TravisRoute.extend - setupController: -> - @_super.apply this, arguments - - @controllerFor('repo').activate('requests') - - model: -> - @store.query 'request', repository_id: @modelFor('repo').get('id') - -`export default Route` diff --git a/app/routes/requests.js b/app/routes/requests.js new file mode 100644 index 00000000..38ff0ec5 --- /dev/null +++ b/app/routes/requests.js @@ -0,0 +1,14 @@ +import TravisRoute from 'travis/routes/basic'; + +export default TravisRoute.extend({ + setupController() { + this._super(...arguments); + return this.controllerFor('repo').activate('requests'); + }, + + model() { + return this.store.query('request', { + repository_id: this.modelFor('repo').get('id') + }); + } +}); diff --git a/app/routes/settings.coffee b/app/routes/settings.coffee deleted file mode 100644 index 92c6ed67..00000000 --- a/app/routes/settings.coffee +++ /dev/null @@ -1,65 +0,0 @@ -`import TravisRoute from 'travis/routes/basic'` -`import config from 'travis/config/environment'` - -Route = TravisRoute.extend - ajax: Ember.inject.service() - - needsAuth: true - setupController: (controller, model) -> - @_super.apply(this, arguments) - controller.set('repo', @modelFor('repo')) - @controllerFor('repo').activate('settings') - - controller.set('concurrentBuildsLimit', !!model.settings.maximum_number_of_builds) - - fetchEnvVars: () -> - repo = @modelFor('repo') - repo.get('envVars.promise') - - fetchCustomSshKey: () -> - repo = @modelFor('repo') - self = this - @store.find('ssh_key', repo.get('id')).then ( (result) -> - result unless result.get('isNew') - ), (xhr) -> - if xhr.status == 404 - # if there is no model, just return null. I'm not sure if this is the - # best answer, maybe we should just redirect to different route, like - # ssh_key.new or ssh_key.no_key - return false - - fetchSshKey: () -> - repo = @modelFor('repo') - @get('ajax').get "/repos/#{repo.get('id')}/key", (data) => - Ember.Object.create(fingerprint: data.fingerprint) - - fetchRepositoryActiveFlag: -> - repoId = @modelFor('repo').get('id') - apiEndpoint = config.apiEndpoint - - $.ajax("#{apiEndpoint}/v3/repo/#{repoId}", { - headers: { - Authorization: 'token ' + @auth.token() - } - }).then( (response) -> - response.active - ); - - hasPushAccess: -> - repoId = parseInt(@modelFor('repo').get('id')) - - @auth.get('currentUser').get('pushPermissionsPromise').then (permissions) -> - permissions.filter (item) -> - item == repoId - - model: () -> - return Ember.RSVP.hash({ - settings: @modelFor('repo').fetchSettings(), - envVars: this.fetchEnvVars(), - sshKey: this.fetchSshKey(), - customSshKey: this.fetchCustomSshKey(), - hasPushAccess: this.hasPushAccess(), - repositoryActive: this.fetchRepositoryActiveFlag() - }); - -`export default Route` diff --git a/app/routes/settings.js b/app/routes/settings.js new file mode 100644 index 00000000..248ceaa1 --- /dev/null +++ b/app/routes/settings.js @@ -0,0 +1,79 @@ +import TravisRoute from 'travis/routes/basic'; +import config from 'travis/config/environment'; + +export default TravisRoute.extend({ + ajax: Ember.inject.service(), + needsAuth: true, + + setupController: function(controller, model) { + this._super(...arguments); + controller.set('repo', this.modelFor('repo')); + this.controllerFor('repo').activate('settings'); + return controller.set('concurrentBuildsLimit', !!model.settings.maximum_number_of_builds); + }, + + fetchEnvVars() { + var repo; + repo = this.modelFor('repo'); + return repo.get('envVars.promise'); + }, + + fetchCustomSshKey() { + var repo, self; + repo = this.modelFor('repo'); + self = this; + return this.store.find('ssh_key', repo.get('id')).then((function(result) { + if (!result.get('isNew')) { + return result; + } + }), function(xhr) { + if (xhr.status === 404) { + return false; + } + }); + }, + + fetchSshKey() { + var repo; + repo = this.modelFor('repo'); + return this.get('ajax').get("/repos/" + (repo.get('id')) + "/key", () => { + return Ember.Object.create({ + fingerprint: data.fingerprint + }); + }); + }, + + fetchRepositoryActiveFlag() { + var apiEndpoint, repoId; + repoId = this.modelFor('repo').get('id'); + apiEndpoint = config.apiEndpoint; + return $.ajax(apiEndpoint + "/v3/repo/" + repoId, { + headers: { + Authorization: 'token ' + this.auth.token() + } + }).then(function(response) { + return response.active; + }); + }, + + hasPushAccess() { + var repoId; + repoId = parseInt(this.modelFor('repo').get('id')); + return this.auth.get('currentUser').get('pushPermissionsPromise').then(function(permissions) { + return permissions.filter(function(item) { + return item === repoId; + }); + }); + }, + + model() { + return Ember.RSVP.hash({ + settings: this.modelFor('repo').fetchSettings(), + envVars: this.fetchEnvVars(), + sshKey: this.fetchSshKey(), + customSshKey: this.fetchCustomSshKey(), + hasPushAccess: this.hasPushAccess(), + repositoryActive: this.fetchRepositoryActiveFlag() + }); + } +}); diff --git a/app/routes/settings/index.coffee b/app/routes/settings/index.coffee deleted file mode 100644 index bb33bbe5..00000000 --- a/app/routes/settings/index.coffee +++ /dev/null @@ -1,14 +0,0 @@ -`import TravisRoute from 'travis/routes/basic'` -`import config from 'travis/config/environment'` - -Route = TravisRoute.extend - titleToken: 'Settings' - - model: -> - repo = @modelFor('repo') - - repo.fetchSettings().then (settings) -> - - repo.set('settings', settings) - -`export default Route` diff --git a/app/routes/settings/index.js b/app/routes/settings/index.js new file mode 100644 index 00000000..55cf89fe --- /dev/null +++ b/app/routes/settings/index.js @@ -0,0 +1,14 @@ +import TravisRoute from 'travis/routes/basic'; +import config from 'travis/config/environment'; + +export default TravisRoute.extend({ + titleToken: 'Settings', + + model() { + var repo; + repo = this.modelFor('repo'); + return repo.fetchSettings().then(function(settings) { + return repo.set('settings', settings); + }); + } +}); diff --git a/app/routes/simple-layout.coffee b/app/routes/simple-layout.coffee deleted file mode 100644 index c6f045cc..00000000 --- a/app/routes/simple-layout.coffee +++ /dev/null @@ -1,12 +0,0 @@ -`import TravisRoute from 'travis/routes/basic'` - -Route = TravisRoute.extend - setupController: -> - $('body').attr('id', 'simple') - @container.lookup('controller:repos').activate('owned') - @_super.apply(this, arguments) - - renderTemplate: -> - @_super.apply(this, arguments) - -`export default Route` diff --git a/app/routes/simple-layout.js b/app/routes/simple-layout.js new file mode 100644 index 00000000..b231c7a4 --- /dev/null +++ b/app/routes/simple-layout.js @@ -0,0 +1,12 @@ +import TravisRoute from 'travis/routes/basic'; + +export default TravisRoute.extend({ + setupController: function() { + $('body').attr('id', 'simple'); + this.container.lookup('controller:repos').activate('owned'); + return this._super.apply(this, arguments); + }, + renderTemplate: function() { + return this._super.apply(this, arguments); + } +}); diff --git a/app/routes/ssh-key.coffee b/app/routes/ssh-key.coffee deleted file mode 100644 index 0657952d..00000000 --- a/app/routes/ssh-key.coffee +++ /dev/null @@ -1,37 +0,0 @@ -`import Ember from 'ember'` -`import TravisRoute from 'travis/routes/basic'` - -Route = TravisRoute.extend - ajax: Ember.inject.service() - - titleToken: 'Ssh Keys' - - model: (params) -> - repo = @modelFor('repo') - self = this - @store.find('ssh_key', repo.get('id')).then ( (result) -> result unless result.get('isNew') ), (xhr) -> - if xhr.status == 404 - # if there is no model, just return null. I'm not sure if this is the - # best answer, maybe we should just redirect to different route, like - # ssh_key.new or ssh_key.no_key - return null - - afterModel: (model, transition) -> - repo = @modelFor('repo') - @get('ajax').get "/repos/#{repo.get('id')}/key", (data) => - @defaultKey = Ember.Object.create(fingerprint: data.fingerprint) - - setupController: (controller, model) -> - controller.reset() - @_super.apply this, arguments - - if @defaultKey - controller.set('defaultKey', @defaultKey) - @defaultKey = null - - deactivate: -> - @_super.apply(this, arguments) - - @controllerFor('ssh_key').send('cancel') - -`export default Route` diff --git a/app/routes/team.coffee b/app/routes/team.coffee deleted file mode 100644 index bf23a4aa..00000000 --- a/app/routes/team.coffee +++ /dev/null @@ -1,193 +0,0 @@ -`import Ember from 'ember'` -`import TravisRoute from 'travis/routes/basic'` - -Route = TravisRoute.extend - needsAuth: false - - model: () -> - [ - { - name: 'Sven Fuchs' - title: 'The Original Builder' - handle: 'svenfuchs' - nationality: 'germany' - country: 'germany' - image: 'sven' - }, - { - name: 'Josh Kalderimis' - title: 'Chief Post-It Officer' - handle: 'j2h' - nationality: 'newzealand' - country: 'germany' - image: 'josh' - }, - { - name: 'Fritz Thielemann' - title: 'Admin Adventures' - handle: 'fritzek' - nationality: 'germany' - country: 'germany' - image: 'fritz' - }, - { - name: 'Konstantin Haase' - title: 'Haase of Pain' - handle: 'konstantinhaase' - nationality: 'germany' - country: 'germany' - image: 'konstantin' - }, - { - name: 'Mathias Meyer' - title: 'Director of Bacon Relations' - handle: 'roidrage' - nationality: 'germany' - country: 'germany' - image: 'mathias' - }, - { - name: 'Piotr Sarnacki' - title: 'Code Monkey' - handle: 'drogus' - nationality: 'poland' - country: 'germany' - image: 'piotr' - }, - { - name: 'Anika Lindtner' - title: 'Head Catwoman' - handle: 'langziehohr' - nationality: 'germany' - country: 'germany' - image: 'anika' - }, - { - name: 'Henrik Hodne' - title: 'Timezone Experimentalist' - handle: 'henrikhodne' - nationality: 'norway' - country: 'norway' - image: 'henrik' - }, - { - name: 'Justine Arreche' - title: 'Lead Clipart Strategist' - handle: 'saltinejustine' - nationality: 'usa' - country: 'usa' - image: 'justine' - }, - { - name: 'Hiro Asari' - title: 'International Man of IPAs' - handle: 'hiro_asari' - nationality: 'japan' - country: 'usa' - image: 'hiro' - }, - { - name: 'Dan Buch' - title: 'That\'s Numberwang' - handle: 'meatballhat' - nationality: 'usa' - country: 'usa' - image: 'dan' - }, - { - name: 'Lisa Passing' - title: 'Queen of !important' - nationality: 'germany' - country: 'germany' - image: 'lisa' - }, - { - name: 'Carla Drago' - title: 'inchworm' - handle: 'carlad' - nationality: 'italy' - country: 'germany' - image: 'carla' - }, - { - name: 'Anja Reichmann' - title: 'Tyranjasaurus Specs' - handle: '_tyranja_' - nationality: 'germany' - country: 'germany' - image: 'anja' - }, - { - name: 'Aly Fulton' - title: 'Resident Linguist' - handle: 'sinthetix' - nationality: 'usa' - country: 'usa' - image: 'aly' - }, - { - name: 'Amanda Quaranto' - title: 'Crafting Extremist' - handle: 'aquaranto' - nationality: 'usa' - country: 'usa' - image: 'amanda' - }, - { - name: 'Jen Duke' - title: 'Gastrognome' - handle: 'dukeofberlin' - nationality: 'usa' - country: 'germany' - image: 'jen' - }, - { - name: 'Brandon Burton' - title: 'Infrastructure Conductor' - handle: 'solarce' - nationality: 'usa' - country: 'usa' - image: 'brandon' - }, - { - name: 'Emma Trimble' - title: 'Lead Pungineer' - handle: 'emdantrim' - nationality: 'usa' - country: 'usa' - image: 'emma' - }, - { - name: 'María de Antón' - title: 'Sous Chef at The Bloge' - handle: 'amalulla' - nationality: 'spain' - country: 'spain' - image: 'maria' - }, - { - name: 'Danish Khan' - title: 'Red Shirt' - handle: 'danishkhan' - nationality: 'usa' - country: 'usa' - image: 'danish' - }, - { - name: 'Dominic Jodoin' - title: 'Humble Tab Hoarder' - handle: 'cotsog' - nationality: 'canada' - country: 'canada' - image: 'dominic' - }, - { - name: 'Liza Brisker' - title: 'Brainy Trainee' - nationality: 'russia' - country: 'germany' - image: 'liz' - } - ] - -`export default Route` diff --git a/app/routes/team.js b/app/routes/team.js new file mode 100644 index 00000000..acb2124d --- /dev/null +++ b/app/routes/team.js @@ -0,0 +1,171 @@ +import Ember from 'ember'; +import TravisRoute from 'travis/routes/basic'; + +export default TravisRoute.extend({ + needsAuth: false, + + model() { + return [ + { + name: 'Sven Fuchs', + title: 'The Original Builder', + handle: 'svenfuchs', + nationality: 'germany', + country: 'germany', + image: 'sven' + }, { + name: 'Josh Kalderimis', + title: 'Chief Post-It Officer', + handle: 'j2h', + nationality: 'newzealand', + country: 'germany', + image: 'josh' + }, { + name: 'Fritz Thielemann', + title: 'Admin Adventures', + handle: 'fritzek', + nationality: 'germany', + country: 'germany', + image: 'fritz' + }, { + name: 'Konstantin Haase', + title: 'Haase of Pain', + handle: 'konstantinhaase', + nationality: 'germany', + country: 'germany', + image: 'konstantin' + }, { + name: 'Mathias Meyer', + title: 'Director of Bacon Relations', + handle: 'roidrage', + nationality: 'germany', + country: 'germany', + image: 'mathias' + }, { + name: 'Piotr Sarnacki', + title: 'Code Monkey', + handle: 'drogus', + nationality: 'poland', + country: 'germany', + image: 'piotr' + }, { + name: 'Anika Lindtner', + title: 'Head Catwoman', + handle: 'langziehohr', + nationality: 'germany', + country: 'germany', + image: 'anika' + }, { + name: 'Henrik Hodne', + title: 'Timezone Experimentalist', + handle: 'henrikhodne', + nationality: 'norway', + country: 'norway', + image: 'henrik' + }, { + name: 'Justine Arreche', + title: 'Lead Clipart Strategist', + handle: 'saltinejustine', + nationality: 'usa', + country: 'usa', + image: 'justine' + }, { + name: 'Hiro Asari', + title: 'International Man of IPAs', + handle: 'hiro_asari', + nationality: 'japan', + country: 'usa', + image: 'hiro' + }, { + name: 'Dan Buch', + title: 'That\'s Numberwang', + handle: 'meatballhat', + nationality: 'usa', + country: 'usa', + image: 'dan' + }, { + name: 'Lisa Passing', + title: 'Queen of !important', + nationality: 'germany', + country: 'germany', + image: 'lisa' + }, { + name: 'Carla Drago', + title: 'inchworm', + handle: 'carlad', + nationality: 'italy', + country: 'germany', + image: 'carla' + }, { + name: 'Anja Reichmann', + title: 'Tyranjasaurus Specs', + handle: '_tyranja_', + nationality: 'germany', + country: 'germany', + image: 'anja' + }, { + name: 'Aly Fulton', + title: 'Resident Linguist', + handle: 'sinthetix', + nationality: 'usa', + country: 'usa', + image: 'aly' + }, { + name: 'Amanda Quaranto', + title: 'Crafting Extremist', + handle: 'aquaranto', + nationality: 'usa', + country: 'usa', + image: 'amanda' + }, { + name: 'Jen Duke', + title: 'Gastrognome', + handle: 'dukeofberlin', + nationality: 'usa', + country: 'germany', + image: 'jen' + }, { + name: 'Brandon Burton', + title: 'Infrastructure Conductor', + handle: 'solarce', + nationality: 'usa', + country: 'usa', + image: 'brandon' + }, { + name: 'Emma Trimble', + title: 'Lead Pungineer', + handle: 'emdantrim', + nationality: 'usa', + country: 'usa', + image: 'emma' + }, { + name: 'María de Antón', + title: 'Sous Chef at The Bloge', + handle: 'amalulla', + nationality: 'spain', + country: 'spain', + image: 'maria' + }, { + name: 'Danish Khan', + title: 'Red Shirt', + handle: 'danishkhan', + nationality: 'usa', + country: 'usa', + image: 'danish' + }, { + name: 'Dominic Jodoin', + title: 'Humble Tab Hoarder', + handle: 'cotsog', + nationality: 'canada', + country: 'canada', + image: 'dominic' + }, { + name: 'Liza Brisker', + title: 'Brainy Trainee', + nationality: 'russia', + country: 'germany', + image: 'liz' + } + ]; + } +}); diff --git a/app/serializers/account.coffee b/app/serializers/account.coffee deleted file mode 100644 index e219627d..00000000 --- a/app/serializers/account.coffee +++ /dev/null @@ -1,7 +0,0 @@ -`import Ember from 'ember'` -`import ApplicationSerializer from 'travis/serializers/application'` - -Serializer = ApplicationSerializer.extend - primaryKey: 'login' - -`export default Serializer` diff --git a/app/serializers/account.js b/app/serializers/account.js new file mode 100644 index 00000000..f6fd8967 --- /dev/null +++ b/app/serializers/account.js @@ -0,0 +1,6 @@ +import Ember from 'ember'; +import ApplicationSerializer from 'travis/serializers/application'; + +export default ApplicationSerializer.extend({ + primaryKey: 'login' +}); diff --git a/app/serializers/application.coffee b/app/serializers/application.coffee deleted file mode 100644 index 1e23b40b..00000000 --- a/app/serializers/application.coffee +++ /dev/null @@ -1,7 +0,0 @@ -`import DS from 'ember-data'` -`import V2FallbackSerializer from 'travis/serializers/v2_fallback'` - -Serializer = V2FallbackSerializer.extend - isNewSerializerAPI: true - -`export default Serializer` diff --git a/app/serializers/application.js b/app/serializers/application.js new file mode 100644 index 00000000..0d2110ef --- /dev/null +++ b/app/serializers/application.js @@ -0,0 +1,6 @@ +import DS from 'ember-data'; +import V2FallbackSerializer from 'travis/serializers/v2_fallback'; + +export default V2FallbackSerializer.extend({ + isNewSerializerAPI: true +}); diff --git a/app/serializers/env-var.coffee b/app/serializers/env-var.coffee deleted file mode 100644 index 2b1e0645..00000000 --- a/app/serializers/env-var.coffee +++ /dev/null @@ -1,16 +0,0 @@ -`import Ember from 'ember'` -`import ApplicationSerializer from 'travis/serializers/application'` - -Serializer = ApplicationSerializer.extend - attrs: { - repo: { key: 'repository_id' } - } - - serialize: (snapshot, options) -> - return { env_var: this._super(snapshot, options) } - - normalizeSingleResponse: (store, primaryModelClass, payload, id, requestType) -> - payload = payload.env_var; - return @_super(store, primaryModelClass, payload, id, requestType) - -`export default Serializer` diff --git a/app/serializers/env-var.js b/app/serializers/env-var.js new file mode 100644 index 00000000..9985f843 --- /dev/null +++ b/app/serializers/env-var.js @@ -0,0 +1,17 @@ +import Ember from 'ember'; +import ApplicationSerializer from 'travis/serializers/application'; + +export default ApplicationSerializer.extend({ + attrs: { + repo: { key: 'repository_id' } + }, + + serialize(snapshot, options) { + return { env_var: this._super(snapshot, options) }; + }, + + normalizeSingleResponse(store, primaryModelClass, payload, id, requestType) { + payload = payload.env_var; + return this._super(store, primaryModelClass, payload, id, requestType); + } +}); diff --git a/app/serializers/job.js b/app/serializers/job.js index 0e3a57b1..cfc4ef58 100644 --- a/app/serializers/job.js +++ b/app/serializers/job.js @@ -1,7 +1,7 @@ import Ember from 'ember'; import V2FallbackSerializer from 'travis/serializers/v2_fallback'; -var Serializer = V2FallbackSerializer.extend({ +export default V2FallbackSerializer.extend({ isNewSerializerAPI: true, attrs: { _config: { key: 'config' }, @@ -42,5 +42,3 @@ var Serializer = V2FallbackSerializer.extend({ }); - -export default Serializer; diff --git a/app/services/ajax.coffee b/app/services/ajax.coffee deleted file mode 100644 index b52b0eb3..00000000 --- a/app/services/ajax.coffee +++ /dev/null @@ -1,158 +0,0 @@ -`import Ember from 'ember';` -`import config from 'travis/config/environment'` - -jQuery.support.cors = true - -default_options = - accepts: - json: 'application/json; version=2' - -Ajax = Ember.Service.extend - auth: Ember.inject.service() - - publicEndpoints: [/\/repos\/?.*/, /\/builds\/?.*/, /\/jobs\/?.*/] - privateEndpoints: [/\/repos\/\d+\/caches/] - - get: (url, callback, errorCallback) -> - @ajax(url, 'get', success: callback, error: errorCallback) - - post: (url, data, callback) -> - @ajax(url, 'post', data: data, success: callback) - - patch: (url, data, callback) -> - @ajax(url, 'patch', data: data, success: callback) - - needsAuth: (method, url) -> - return true if config.pro - return true if method != 'GET' - - publicEndpoint = @publicEndpoints.find (pattern) -> - url.match(pattern) - - privateEndpoint = @privateEndpoints.find (pattern) -> - url.match(pattern) - - !publicEndpoint || privateEndpoint - - ajax: (url, method, options) -> - # TODO: we have our own ajax implementation, because jQuery didn't - # properly worked with headers on firefox, it would be nice to check - # if this is still a problem and if we can remove this - method = method || "GET" - method = method.toUpperCase() - - endpoint = config.apiEndpoint || '' - options = options || {} - - token = Ember.get(this, 'auth').token() - if token && (@needsAuth(method, url) || options.forceAuth) - options.headers ||= {} - options.headers['Authorization'] ||= "token #{token}" - - options.url = url = "#{endpoint}#{url}" - options.type = method - options.dataType = options.dataType || 'json' - options.context = this - - if options.data && method != 'GET' - options.data = JSON.stringify(options.data) - - if method != 'GET' && method != 'HEAD' - options.contentType = options.contentType || 'application/json; charset=utf-8' - - success = options.success || (->) - options.success = (data, status, xhr) => - Travis.lookup('controller:flash').loadFlashes(data.flash) if data?.flash - delete data.flash if data? - success.apply(this, arguments) - - 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? - error.apply(this, arguments) - - options = $.extend(options, default_options) - - if testMode? - console.log('Running ajax with', options.url) - - # we use jquery.mockjax for test, I don't want to hack it or rewrite it, - # so let's just pretend we still use ajax if testing mode is on - return new Ember.RSVP.Promise( (resolve, reject) -> - oldSuccess = options.success - options.success = (json, status, xhr) -> - Ember.run this, -> - oldSuccess.call(this, json, status, xhr) - Ember.run(null, resolve, json) - - oldError = options.error - options.error = (jqXHR) -> - if jqXHR - # for a context, please see https://github.com/emberjs/ember.js/issues/3051 - jqXHR.then = null - - Ember.run this, -> - oldError.call this, jqXHR - reject(jqXHR) - - $.ajax(options) - ) - - if options.data && (method == "GET" || method == "HEAD") - params = jQuery.param(options.data) - delimeter = if url.indexOf('?') == -1 then '?' else '&' - url = url + delimeter + params - - xhr = new XMLHttpRequest() - - xhr.open(method, url) - - if options.accepts && !options.headers?.accept? - accepts = [] - for key, value of options.accepts - accepts.pushObject(value) - xhr.setRequestHeader('Accept', accepts.join(', ')) - - if options.headers - for name, value of options.headers - xhr.setRequestHeader(name, value) - - if options.contentType - xhr.setRequestHeader('Content-Type', options.contentType) - - resolve = null - reject = null - promise = new Ember.RSVP.Promise( (_resolve, _reject) -> - resolve = _resolve - reject = _reject - ) - - xhr.onreadystatechange = -> - if xhr.readyState == 4 - contentType = xhr.getResponseHeader('Content-Type') - data = if contentType && contentType.match /application\/json/ - try - jQuery.parseJSON(xhr.responseText) - catch e - console.log('error while parsing a response', method, options.url, xhr.responseText) - else - xhr.responseText - - if xhr.status >= 200 && xhr.status < 300 - resolve(data) - options.success.call(options.context, data, xhr.status, xhr) - else - reject(xhr) - options.error.call(options.context, data, xhr.status, xhr) - - data = options.data - if typeof(options.data) == "object" && (Ember.isNone(options.contentType) || options.contentType.match /application\/json/) - data = JSON.stringify(data) - - xhr.send(data) - - return promise - -`export default Ajax` diff --git a/app/services/ajax.js b/app/services/ajax.js new file mode 100644 index 00000000..7d647ce1 --- /dev/null +++ b/app/services/ajax.js @@ -0,0 +1,189 @@ +import Ember from 'ember';; +import config from 'travis/config/environment'; +var default_options; + +jQuery.support.cors = true; + +default_options = { + accepts: { + json: 'application/json; version=2' + } +}; + +export default Ember.Service.extend({ + auth: Ember.inject.service(), + publicEndpoints: [/\/repos\/?.*/, /\/builds\/?.*/, /\/jobs\/?.*/], + privateEndpoints: [/\/repos\/\d+\/caches/], + + get(url, callback, errorCallback) { + return this.ajax(url, 'get', { + success: callback, + error: errorCallback + }); + }, + + post(url, data, callback) { + return this.ajax(url, 'post', { + data: data, + success: callback + }); + }, + + patch(url, data, callback) { + return this.ajax(url, 'patch', { + data: data, + success: callback + }); + }, + + needsAuth(method, url) { + var privateEndpoint, publicEndpoint; + if (config.pro) { + return true; + } + if (method !== 'GET') { + return true; + } + publicEndpoint = this.publicEndpoints.find(function(pattern) { + return url.match(pattern); + }); + privateEndpoint = this.privateEndpoints.find(function(pattern) { + return url.match(pattern); + }); + return !publicEndpoint || privateEndpoint; + }, + + ajax(url, method, options) { + var accepts, base, data, delimeter, endpoint, error, key, name, params, promise, ref, ref1, ref2, reject, resolve, success, token, value, xhr; + method = method || "GET"; + method = method.toUpperCase(); + endpoint = config.apiEndpoint || ''; + options = options || {}; + token = Ember.get(this, 'auth').token(); + if (token && (this.needsAuth(method, url) || options.forceAuth)) { + options.headers || (options.headers = {}); + (base = options.headers)['Authorization'] || (base['Authorization'] = "token " + token); + } + options.url = url = "" + endpoint + url; + options.type = method; + options.dataType = options.dataType || 'json'; + options.context = this; + if (options.data && method !== 'GET') { + options.data = JSON.stringify(options.data); + } + if (method !== 'GET' && method !== 'HEAD') { + options.contentType = options.contentType || 'application/json; charset=utf-8'; + } + success = options.success || (function() {}); + options.success = () => { + if (data != null ? data.flash : void 0) { + Travis.lookup('controller:flash').loadFlashes(data.flash); + } + if (data != null) { + delete data.flash; + } + return success.apply(this, arguments); + }; + error = options.error || function() {}; + options.error = () => { + console.log("[ERROR] API responded with an error (" + status + "): " + (JSON.stringify(data))); + if (data != null ? data.flash : void 0) { + Travis.lookup('controller:flash').pushObject(data.flash); + } + if (data != null) { + delete data.flash; + } + return error.apply(this, arguments); + }; + + options = $.extend(options, default_options); + if (typeof testMode !== "undefined" && testMode !== null) { + console.log('Running ajax with', options.url); + return new Ember.RSVP.Promise(function(resolve, reject) { + var oldError, oldSuccess; + oldSuccess = options.success; + options.success = function(json, status, xhr) { + Ember.run(this, function() { + return oldSuccess.call(this, json, status, xhr); + }); + return Ember.run(null, resolve, json); + }; + oldError = options.error; + options.error = function(jqXHR) { + if (jqXHR) { + jqXHR.then = null; + } + return Ember.run(this, function() { + oldError.call(this, jqXHR); + return reject(jqXHR); + }); + }; + return $.ajax(options); + }); + } + if (options.data && (method === "GET" || method === "HEAD")) { + params = jQuery.param(options.data); + delimeter = url.indexOf('?') === -1 ? '?' : '&'; + url = url + delimeter + params; + } + xhr = new XMLHttpRequest(); + xhr.open(method, url); + if (options.accepts && (((ref = options.headers) != null ? ref.accept : void 0) == null)) { + accepts = []; + ref1 = options.accepts; + for (key in ref1) { + value = ref1[key]; + accepts.pushObject(value); + } + xhr.setRequestHeader('Accept', accepts.join(', ')); + } + if (options.headers) { + ref2 = options.headers; + for (name in ref2) { + value = ref2[name]; + xhr.setRequestHeader(name, value); + } + } + if (options.contentType) { + xhr.setRequestHeader('Content-Type', options.contentType); + } + resolve = null; + reject = null; + promise = new Ember.RSVP.Promise(function(_resolve, _reject) { + resolve = _resolve; + return reject = _reject; + }); + xhr.onreadystatechange = function() { + var contentType, data, e; + if (xhr.readyState === 4) { + contentType = xhr.getResponseHeader('Content-Type'); + data = (function() { + var error1; + if (contentType && contentType.match(/application\/json/)) { + try { + return jQuery.parseJSON(xhr.responseText); + } catch (error1) { + e = error1; + return console.log('error while parsing a response', method, options.url, xhr.responseText); + } + } else { + return xhr.responseText; + } + })(); + if (xhr.status >= 200 && xhr.status < 300) { + resolve(data); + return options.success.call(options.context, data, xhr.status, xhr); + } else { + reject(xhr); + return options.error.call(options.context, data, xhr.status, xhr); + } + } + }; + data = options.data; + if (typeof options.data === "object" && (Ember.isNone(options.contentType) || options.contentType.match(/application\/json/))) { + data = JSON.stringify(data); + } + xhr.send(data); + return promise; + } +}); diff --git a/app/services/auth.coffee b/app/services/auth.coffee deleted file mode 100644 index 416c30b9..00000000 --- a/app/services/auth.coffee +++ /dev/null @@ -1,171 +0,0 @@ -`import config from 'travis/config/environment'` - -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}" - - init: -> - window.addEventListener('message', (e) => @receiveMessage(e)) - - token: -> - @get('sessionStorage').getItem('travis.token') - - endpoint: (-> - config.apiEndpoint - ).property(), - - signOut: -> - @get('storage').removeItem('travis.user') - @get('storage').removeItem('travis.token') - @get('sessionStorage').clear() - @set('state', 'signed-out') - @set('user', undefined) - if user = @get('currentUser') - @get('store').unloadAll('user') - @set('currentUser', null) - @sendToApp('afterSignOut') - Travis.trigger('user:signed_out') - - signIn: (data) -> - if data - @autoSignIn(data) - else - @set('state', 'signing-in') - url = "#{@get('endpoint')}/auth/post_message?origin=#{@receivingEnd}" - $('