Merge pull request #327 from travis-ci/ember-cli
Switch to Ember CLI and Ember Data; refactor CSS.
This commit is contained in:
commit
1105981e7d
4
.bowerrc
Normal file
4
.bowerrc
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"directory": "bower_components",
|
||||||
|
"analytics": false
|
||||||
|
}
|
|
@ -1,2 +1,2 @@
|
||||||
https://github.com/heroku/heroku-buildpack-ruby.git
|
https://github.com/heroku/heroku-buildpack-ruby.git
|
||||||
https://github.com/travis-ci/travis-web-buildpack.git
|
https://github.com/travis-ci/travis-web-ember-cli-buildpack.git
|
||||||
|
|
33
.editorconfig
Normal file
33
.editorconfig
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
# EditorConfig helps developers define and maintain consistent
|
||||||
|
# coding styles between different editors and IDEs
|
||||||
|
# editorconfig.org
|
||||||
|
|
||||||
|
root = true
|
||||||
|
|
||||||
|
|
||||||
|
[*]
|
||||||
|
end_of_line = lf
|
||||||
|
charset = utf-8
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
insert_final_newline = true
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
[*.js]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
[*.hbs]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
[*.css]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
[*.html]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
[*.{diff,md}]
|
||||||
|
trim_trailing_whitespace = false
|
9
.ember-cli
Normal file
9
.ember-cli
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
Ember CLI sends analytics information by default. The data is completely
|
||||||
|
anonymous, but there are times when you might want to disable this behavior.
|
||||||
|
|
||||||
|
Setting `disableAnalytics` to true will prevent any data from being sent.
|
||||||
|
*/
|
||||||
|
"disableAnalytics": false
|
||||||
|
}
|
27
.gitignore
vendored
27
.gitignore
vendored
|
@ -1,14 +1,15 @@
|
||||||
/.bundle
|
# compiled output
|
||||||
/config/travis.yml
|
dist
|
||||||
/tmp
|
tmp
|
||||||
.sass-cache
|
|
||||||
.localeapp/key
|
|
||||||
/assets/scripts/config/locales.js
|
|
||||||
.DS_Store
|
|
||||||
*.sw[op]
|
|
||||||
|
|
||||||
/public/images
|
# dependencies
|
||||||
/public/scripts
|
node_modules
|
||||||
/public/styles/app.css
|
bower_components
|
||||||
/public/version
|
|
||||||
vendor/bundle
|
# misc
|
||||||
|
.sass-cache
|
||||||
|
connect.lock
|
||||||
|
coverage/*
|
||||||
|
libpeerconnection.log
|
||||||
|
npm-debug.log
|
||||||
|
testem.log
|
||||||
|
|
32
.jshintrc
Normal file
32
.jshintrc
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
{
|
||||||
|
"predef": [
|
||||||
|
"document",
|
||||||
|
"window",
|
||||||
|
"-Promise"
|
||||||
|
],
|
||||||
|
"browser": true,
|
||||||
|
"boss": true,
|
||||||
|
"curly": true,
|
||||||
|
"debug": false,
|
||||||
|
"devel": true,
|
||||||
|
"eqeqeq": true,
|
||||||
|
"evil": true,
|
||||||
|
"forin": false,
|
||||||
|
"immed": false,
|
||||||
|
"laxbreak": false,
|
||||||
|
"newcap": true,
|
||||||
|
"noarg": true,
|
||||||
|
"noempty": false,
|
||||||
|
"nonew": false,
|
||||||
|
"nomen": false,
|
||||||
|
"onevar": false,
|
||||||
|
"plusplus": false,
|
||||||
|
"regexp": false,
|
||||||
|
"undef": true,
|
||||||
|
"sub": true,
|
||||||
|
"strict": false,
|
||||||
|
"white": false,
|
||||||
|
"eqnull": true,
|
||||||
|
"esnext": true,
|
||||||
|
"unused": true
|
||||||
|
}
|
54
.travis.yml
54
.travis.yml
|
@ -1,47 +1,27 @@
|
||||||
language: ruby
|
---
|
||||||
rvm:
|
language: node_js
|
||||||
- 2.1.2
|
|
||||||
|
addons:
|
||||||
|
sauce_connect: true
|
||||||
|
|
||||||
sudo: false
|
sudo: false
|
||||||
|
|
||||||
cache:
|
cache:
|
||||||
bundler: true
|
directories:
|
||||||
|
- node_modules
|
||||||
matrix:
|
|
||||||
fast_finish: true
|
|
||||||
allow_failures:
|
|
||||||
- rvm: 2.1.2
|
|
||||||
env: 'TEST_SUITE=phantomjs'
|
|
||||||
- rvm: 2.1.2
|
|
||||||
env: "TEST_SUITE=saucelabs BROWSER='firefox::Windows XP'"
|
|
||||||
|
|
||||||
env:
|
|
||||||
global:
|
|
||||||
- secure: "RFuCOppyjWHC4XWKtQlgS4zO4B6KVxytdX8+G5jRY3XM+OEGte8VDD88gZLM\nKDpkqMFDbNJAVTsh1kMANCTct2ONi30RTxuJWLtRyK7RE5zCcaGbAkTNZgXo\nOR5OWLEPJZbNfbh17H6J7izTy6yiLR+CsVP1wMgeVusP0eoDhCA="
|
|
||||||
- secure: "duqMXPALumXB3e2j/kM2uCaCGwgZsRrU0GCDY+3Zk6a+PK+s0mE9BftcXdxm\n6u87ld2PvCBO0inpe5YeS9LOZsT+OFS4jj+GGTsRI6rmGz+kok0N+ATLTdcj\nu15zhLhUUlhoKW0DZURrDv/iTiC/FKvJ0u5Rft0XbjfTY+0go/M="
|
|
||||||
# SAUCE_ACCESS_KEY
|
|
||||||
- secure: "vf+RnbxcpCZcJYCcJdlT/EbPm9go5BnyyGKHCBwdPqb3+w+k0XyYnUkO5V9pIewIFAKof50i2YlAT8DG9GiUmKrX8z54dqSDlA+R1arMxgZRCHJohLxBjcxHVZe05aVZm/9U7YMOl3DuX88gISG91XC6nr8jnmmp2xGNQR8MkaU="
|
|
||||||
# SAUCE_USERNAME
|
|
||||||
- secure: "tg6TWOS7ZtS4/SXezv4mK482rR+F2MPKCe6PCp+U4oYidm5Jj0NPw/lVog26HSVxxLpayMq35WrBJPwR+7DiNLc+RyBS+yeL8zsLnDlBdGFqSYg6L0j3QK3mVUhQi/ivgvd5NiTcxLROKBie+NJ58HKbenwFFTfvVCy/WjK+dPA="
|
|
||||||
|
|
||||||
matrix:
|
|
||||||
- "TEST_SUITE=ruby ARTIFACTS_S3_BUCKET=travis-web-production"
|
|
||||||
- "TEST_SUITE=phantomjs"
|
|
||||||
- "TEST_SUITE=saucelabs BROWSER='firefox::Windows XP'"
|
|
||||||
- "TEST_SUITE=saucelabs BROWSER='chrome::Windows XP'"
|
|
||||||
|
|
||||||
script: "script/ci"
|
|
||||||
|
|
||||||
before_install:
|
before_install:
|
||||||
- "gem install bundler"
|
- "npm config set spin false"
|
||||||
before_script:
|
- "npm install -g npm@^2"
|
||||||
- "test $TEST_SUITE = \"ruby\" && gem install travis-artifacts || true"
|
|
||||||
- "bundle exec rakep"
|
install:
|
||||||
- "phantomjs --version"
|
- npm install -g bower
|
||||||
after_script:
|
- npm install
|
||||||
- "test $TEST_SUITE = \"ruby\" && test $TRAVIS_PULL_REQUEST = \"false\" && travis-artifacts upload --target-path assets/$TRAVIS_BRANCH --path public/scripts:scripts --path public/styles:styles || true"
|
- bower install
|
||||||
|
|
||||||
|
script:
|
||||||
|
- npm test
|
||||||
|
|
||||||
notifications:
|
notifications:
|
||||||
irc: "irc.freenode.org#travis"
|
|
||||||
campfire:
|
campfire:
|
||||||
secure: "JJezWGD9KJY/LC2aznI3Zyohy31VTIhcTKX7RWR4C/C8YKbW9kZv3xV6Vn11\nSHxJTeZo6st2Bpv6tjlWZ+HCR09kyCNavIChedla3+oHOiuL0D4gSo+gkTNW\nUKYZz9mcQUd9RoQpTeyxvdvX+l7z62/7JwFA7txHOqxbTS8jrjc="
|
secure: "JJezWGD9KJY/LC2aznI3Zyohy31VTIhcTKX7RWR4C/C8YKbW9kZv3xV6Vn11\nSHxJTeZo6st2Bpv6tjlWZ+HCR09kyCNavIChedla3+oHOiuL0D4gSo+gkTNW\nUKYZz9mcQUd9RoQpTeyxvdvX+l7z62/7JwFA7txHOqxbTS8jrjc="
|
||||||
|
|
92
Assetfile
92
Assetfile
|
@ -1,92 +0,0 @@
|
||||||
$: << 'lib'
|
|
||||||
|
|
||||||
require 'rake-pipeline-web-filters'
|
|
||||||
require 'travis/assets'
|
|
||||||
require 'compass'
|
|
||||||
|
|
||||||
Encoding.default_external = Encoding::UTF_8
|
|
||||||
Encoding.default_internal = Encoding::UTF_8
|
|
||||||
|
|
||||||
assets ||= Travis::Assets.new
|
|
||||||
assets.setup_compass
|
|
||||||
assets.update_version
|
|
||||||
|
|
||||||
output 'public/scripts'
|
|
||||||
input assets.scripts do
|
|
||||||
match '**/*.hbs' do
|
|
||||||
travis_handlebars :precompile => false # assets.production?
|
|
||||||
concat 'templates.js'
|
|
||||||
end
|
|
||||||
|
|
||||||
match '**/*.coffee' do
|
|
||||||
coffee_script
|
|
||||||
end
|
|
||||||
|
|
||||||
match 'vendor/**/*.js' do
|
|
||||||
if assets.production?
|
|
||||||
reject 'ember.js'
|
|
||||||
else
|
|
||||||
reject 'ember.prod.js'
|
|
||||||
end
|
|
||||||
safe_concat assets.vendor_order, 'vendor.js'
|
|
||||||
end
|
|
||||||
|
|
||||||
match '{spec,spec/integration,spec/unit,spec/unit/views}/*.js' do
|
|
||||||
concat 'spec/specs.js'
|
|
||||||
end
|
|
||||||
|
|
||||||
match 'spec/support/*.js' do
|
|
||||||
concat 'spec/support.js'
|
|
||||||
end
|
|
||||||
|
|
||||||
match 'spec/vendor/*.js' do
|
|
||||||
concat assets.spec_vendor_order, 'spec/vendor.js'
|
|
||||||
end
|
|
||||||
|
|
||||||
match 'spec/{vendor,support,specs}.js' do
|
|
||||||
concat ['spec/vendor.js', 'spec/support.js', 'spec/specs.js'], 'specs.js'
|
|
||||||
end
|
|
||||||
|
|
||||||
match %r(^(?!vendor|spec).*\.js$) do
|
|
||||||
modules = proc { |input| input.path.gsub(%r((^app/|lib/|\.js$)), '') }
|
|
||||||
# why did we use the string strategy for development? makes it impossible to set breakpoints
|
|
||||||
# minispade(string: assets.development?, rewrite_requires: true, module_id_generator: modules)
|
|
||||||
minispade(string: false, rewrite_requires: true, module_id_generator: modules)
|
|
||||||
end
|
|
||||||
|
|
||||||
match %r(^(?!spec).*\.js$) do
|
|
||||||
paths = ['min/app.js']
|
|
||||||
paths.push 'app.js' unless assets.production?
|
|
||||||
concat ['vendor.js'], paths
|
|
||||||
end
|
|
||||||
|
|
||||||
if assets.production?
|
|
||||||
match 'min/app.js' do
|
|
||||||
strip_debug
|
|
||||||
# uglify squeeze: true
|
|
||||||
concat 'app.js'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
output 'public/styles'
|
|
||||||
input assets.styles do
|
|
||||||
match '**/*.{scss,sass,css}' do
|
|
||||||
sass assets.production? ? { style: :compressed } : {}
|
|
||||||
concat assets.styles_order, ['app.css']
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
output 'public/images'
|
|
||||||
input assets.images do
|
|
||||||
match '**/*' do
|
|
||||||
copy
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# output 'public'
|
|
||||||
# input assets.static do
|
|
||||||
# match '**/*' do
|
|
||||||
# copy
|
|
||||||
# end
|
|
||||||
# end
|
|
43
Brocfile.js
Normal file
43
Brocfile.js
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
/* global require, module */
|
||||||
|
|
||||||
|
var EmberApp = require('ember-cli/lib/broccoli/ember-app');
|
||||||
|
|
||||||
|
var fingerprint = {
|
||||||
|
extensions: ['js', 'css', 'png', 'jpg', 'gif', 'map', 'svg']
|
||||||
|
},
|
||||||
|
assetsHost;
|
||||||
|
|
||||||
|
if (assetsHost = process.env.ASSETS_HOST) {
|
||||||
|
if (assetsHost.substr(-1) !== '/') {
|
||||||
|
assetsHost = assetsHost + '/'
|
||||||
|
}
|
||||||
|
fingerprint.prepend = assetsHost
|
||||||
|
}
|
||||||
|
|
||||||
|
var app = new EmberApp({
|
||||||
|
fingerprint: fingerprint
|
||||||
|
});
|
||||||
|
|
||||||
|
app.import('bower_components/pusher/dist/pusher.js');
|
||||||
|
app.import('bower_components/jquery-timeago/jquery.timeago.js');
|
||||||
|
app.import('bower_components/visibilityjs/lib/visibility.core.js');
|
||||||
|
app.import('bower_components/visibilityjs/lib/visibility.timers.js');
|
||||||
|
app.import('bower_components/JavaScript-MD5/js/md5.js');
|
||||||
|
app.import('vendor/ansiparse.js');
|
||||||
|
app.import('vendor/log.js');
|
||||||
|
app.import('vendor/customerio.js');
|
||||||
|
app.import('bower_components/moment/moment.js');
|
||||||
|
// Use `app.import` to add additional libraries to the generated
|
||||||
|
// output files.
|
||||||
|
//
|
||||||
|
// If you need to use different assets in different
|
||||||
|
// environments, specify an object as the first parameter. That
|
||||||
|
// object's keys should be the environment name and the values
|
||||||
|
// should be the asset to use in that environment.
|
||||||
|
//
|
||||||
|
// If the library that you are including contains AMD or ES6
|
||||||
|
// modules that you would like to import into your application
|
||||||
|
// please specify an object with the list of modules as keys
|
||||||
|
// along with the exports of each module as its value.
|
||||||
|
|
||||||
|
module.exports = app.toTree();
|
13
Gemfile
13
Gemfile
|
@ -1,6 +1,7 @@
|
||||||
source 'http://rubygems.org'
|
source 'http://rubygems.org'
|
||||||
ruby '2.1.2'
|
ruby '2.1.2'
|
||||||
|
|
||||||
|
gem 'travis-web', path: 'waiter'
|
||||||
gem 'puma'
|
gem 'puma'
|
||||||
gem 'rack-ssl', '~> 1.3'
|
gem 'rack-ssl', '~> 1.3'
|
||||||
gem 'rack-protection', '~> 1.3'
|
gem 'rack-protection', '~> 1.3'
|
||||||
|
@ -8,15 +9,6 @@ gem 'rack-mobile-detect'
|
||||||
gem 'sinatra'
|
gem 'sinatra'
|
||||||
gem 'hashr'
|
gem 'hashr'
|
||||||
|
|
||||||
gem 'rake-pipeline', github: 'livingsocial/rake-pipeline'
|
|
||||||
gem 'rake-pipeline-web-filters', github: 'wycats/rake-pipeline-web-filters'
|
|
||||||
gem 'coffee-script'
|
|
||||||
gem 'compass'
|
|
||||||
gem 'tilt'
|
|
||||||
gem 'uglifier'
|
|
||||||
gem 'yui-compressor'
|
|
||||||
gem 'libv8', '~> 3.16.0'
|
|
||||||
|
|
||||||
group :development, :test do
|
group :development, :test do
|
||||||
gem 'rake'
|
gem 'rake'
|
||||||
end
|
end
|
||||||
|
@ -25,9 +17,6 @@ end
|
||||||
group :development do
|
group :development do
|
||||||
# gem 'debugger'
|
# gem 'debugger'
|
||||||
gem 'foreman'
|
gem 'foreman'
|
||||||
gem 'rerun', '~> 0.10.0'
|
|
||||||
gem 'guard'
|
|
||||||
gem 'rb-fsevent', '~> 0.9.1'
|
|
||||||
end
|
end
|
||||||
|
|
||||||
group :test do
|
group :test do
|
||||||
|
|
85
Gemfile.lock
85
Gemfile.lock
|
@ -1,75 +1,21 @@
|
||||||
GIT
|
PATH
|
||||||
remote: git://github.com/livingsocial/rake-pipeline.git
|
remote: waiter
|
||||||
revision: a75d96fbadcc659a35a0ae59212e0bc60b58cc54
|
|
||||||
specs:
|
specs:
|
||||||
rake-pipeline (0.8.0)
|
travis-web (0.0.1)
|
||||||
json
|
|
||||||
rake (~> 10.1.0)
|
|
||||||
thor
|
|
||||||
|
|
||||||
GIT
|
|
||||||
remote: git://github.com/wycats/rake-pipeline-web-filters.git
|
|
||||||
revision: 7bd283aac83d7c46a8908f089033a6087d7cd68f
|
|
||||||
specs:
|
|
||||||
rake-pipeline-web-filters (0.6.0)
|
|
||||||
rack
|
|
||||||
rake-pipeline (~> 0.6)
|
|
||||||
|
|
||||||
GEM
|
GEM
|
||||||
remote: http://rubygems.org/
|
remote: http://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
backports (3.6.3)
|
backports (3.6.3)
|
||||||
celluloid (0.16.0)
|
|
||||||
timers (~> 4.0.0)
|
|
||||||
chunky_png (1.3.1)
|
|
||||||
coderay (1.1.0)
|
|
||||||
coffee-script (2.3.0)
|
|
||||||
coffee-script-source
|
|
||||||
execjs
|
|
||||||
coffee-script-source (1.8.0)
|
|
||||||
compass (1.0.1)
|
|
||||||
chunky_png (~> 1.2)
|
|
||||||
compass-core (~> 1.0.1)
|
|
||||||
compass-import-once (~> 1.0.5)
|
|
||||||
rb-fsevent (>= 0.9.3)
|
|
||||||
rb-inotify (>= 0.9)
|
|
||||||
sass (>= 3.3.13, < 3.5)
|
|
||||||
compass-core (1.0.1)
|
|
||||||
multi_json (~> 1.0)
|
|
||||||
sass (>= 3.3.0, < 3.5)
|
|
||||||
compass-import-once (1.0.5)
|
|
||||||
sass (>= 3.2, < 3.5)
|
|
||||||
diff-lcs (1.2.5)
|
diff-lcs (1.2.5)
|
||||||
dotenv (0.11.1)
|
dotenv (0.11.1)
|
||||||
dotenv-deployment (~> 0.0.2)
|
dotenv-deployment (~> 0.0.2)
|
||||||
dotenv-deployment (0.0.2)
|
dotenv-deployment (0.0.2)
|
||||||
execjs (2.2.1)
|
|
||||||
ffi (1.9.6)
|
|
||||||
foreman (0.75.0)
|
foreman (0.75.0)
|
||||||
dotenv (~> 0.11.1)
|
dotenv (~> 0.11.1)
|
||||||
thor (~> 0.19.1)
|
thor (~> 0.19.1)
|
||||||
formatador (0.2.5)
|
|
||||||
guard (2.6.1)
|
|
||||||
formatador (>= 0.2.4)
|
|
||||||
listen (~> 2.7)
|
|
||||||
lumberjack (~> 1.0)
|
|
||||||
pry (>= 0.9.12)
|
|
||||||
thor (>= 0.18.1)
|
|
||||||
hashr (0.0.22)
|
hashr (0.0.22)
|
||||||
hitimes (1.2.2)
|
|
||||||
json (1.8.1)
|
|
||||||
libv8 (3.16.14.7)
|
|
||||||
listen (2.7.11)
|
|
||||||
celluloid (>= 0.15.2)
|
|
||||||
rb-fsevent (>= 0.9.3)
|
|
||||||
rb-inotify (>= 0.9)
|
|
||||||
lumberjack (1.0.9)
|
|
||||||
method_source (0.8.2)
|
|
||||||
multi_json (1.10.1)
|
multi_json (1.10.1)
|
||||||
pry (0.10.1)
|
|
||||||
coderay (~> 1.1.0)
|
|
||||||
method_source (~> 0.8.1)
|
|
||||||
slop (~> 3.4)
|
|
||||||
puma (2.9.1)
|
puma (2.9.1)
|
||||||
rack (>= 1.1, < 2.0)
|
rack (>= 1.1, < 2.0)
|
||||||
rack (1.5.2)
|
rack (1.5.2)
|
||||||
|
@ -82,11 +28,6 @@ GEM
|
||||||
rack-test (0.6.2)
|
rack-test (0.6.2)
|
||||||
rack (>= 1.0)
|
rack (>= 1.0)
|
||||||
rake (10.1.1)
|
rake (10.1.1)
|
||||||
rb-fsevent (0.9.4)
|
|
||||||
rb-inotify (0.9.5)
|
|
||||||
ffi (>= 0.5.0)
|
|
||||||
rerun (0.10.0)
|
|
||||||
listen (~> 2.7, >= 2.7.3)
|
|
||||||
rspec (2.99.0)
|
rspec (2.99.0)
|
||||||
rspec-core (~> 2.99.0)
|
rspec-core (~> 2.99.0)
|
||||||
rspec-expectations (~> 2.99.0)
|
rspec-expectations (~> 2.99.0)
|
||||||
|
@ -95,7 +36,6 @@ GEM
|
||||||
rspec-expectations (2.99.2)
|
rspec-expectations (2.99.2)
|
||||||
diff-lcs (>= 1.1.3, < 2.0)
|
diff-lcs (>= 1.1.3, < 2.0)
|
||||||
rspec-mocks (2.99.2)
|
rspec-mocks (2.99.2)
|
||||||
sass (3.4.5)
|
|
||||||
sinatra (1.4.5)
|
sinatra (1.4.5)
|
||||||
rack (~> 1.4)
|
rack (~> 1.4)
|
||||||
rack-protection (~> 1.4)
|
rack-protection (~> 1.4)
|
||||||
|
@ -107,38 +47,21 @@ GEM
|
||||||
rack-test
|
rack-test
|
||||||
sinatra (~> 1.4.0)
|
sinatra (~> 1.4.0)
|
||||||
tilt (~> 1.3)
|
tilt (~> 1.3)
|
||||||
slop (3.6.0)
|
|
||||||
thor (0.19.1)
|
thor (0.19.1)
|
||||||
tilt (1.4.1)
|
tilt (1.4.1)
|
||||||
timers (4.0.1)
|
|
||||||
hitimes
|
|
||||||
uglifier (2.5.3)
|
|
||||||
execjs (>= 0.3.0)
|
|
||||||
json (>= 1.8.0)
|
|
||||||
yui-compressor (0.12.0)
|
|
||||||
|
|
||||||
PLATFORMS
|
PLATFORMS
|
||||||
ruby
|
ruby
|
||||||
|
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
coffee-script
|
|
||||||
compass
|
|
||||||
foreman
|
foreman
|
||||||
guard
|
|
||||||
hashr
|
hashr
|
||||||
libv8 (~> 3.16.0)
|
|
||||||
puma
|
puma
|
||||||
rack-mobile-detect
|
rack-mobile-detect
|
||||||
rack-protection (~> 1.3)
|
rack-protection (~> 1.3)
|
||||||
rack-ssl (~> 1.3)
|
rack-ssl (~> 1.3)
|
||||||
rake
|
rake
|
||||||
rake-pipeline!
|
|
||||||
rake-pipeline-web-filters!
|
|
||||||
rb-fsevent (~> 0.9.1)
|
|
||||||
rerun (~> 0.10.0)
|
|
||||||
rspec (~> 2.11)
|
rspec (~> 2.11)
|
||||||
sinatra
|
sinatra
|
||||||
sinatra-contrib
|
sinatra-contrib
|
||||||
tilt
|
travis-web!
|
||||||
uglifier
|
|
||||||
yui-compressor
|
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
$: << 'lib'
|
|
||||||
|
|
||||||
guard 'assets' do
|
|
||||||
watch(%r(^Assetfile))
|
|
||||||
watch(%r(^assets))
|
|
||||||
end
|
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
$: << 'lib'
|
|
||||||
|
|
||||||
guard 'specs' do
|
|
||||||
watch(%r(^public))
|
|
||||||
end
|
|
||||||
|
|
2
Procfile
2
Procfile
|
@ -1,3 +1,3 @@
|
||||||
web: bundle exec rackup -s puma -p $PORT
|
web: bundle exec rackup -s puma -p $PORT waiter/config.ru
|
||||||
assets: rerun -x -p 'assets/**/*' 'bundle exec rakep'
|
assets: rerun -x -p 'assets/**/*' 'bundle exec rakep'
|
||||||
#specs: rerun -x -p 'public/**/*' './run_jasmine.coffee public/spec.html'
|
#specs: rerun -x -p 'public/**/*' './run_jasmine.coffee public/spec.html'
|
||||||
|
|
56
README.md
56
README.md
|
@ -2,56 +2,26 @@
|
||||||
[](https://travis-ci.org/travis-ci/travis-web)
|
[](https://travis-ci.org/travis-ci/travis-web)
|
||||||
### Running the app
|
### Running the app
|
||||||
|
|
||||||
|
The app is developed using [http://ember-cli.com](Ember CLI). It requires nodejs
|
||||||
|
with npm installed.
|
||||||
|
|
||||||
In order to run the app you need to install dependencies with:
|
In order to run the app you need to install dependencies with:
|
||||||
|
|
||||||
bundle install
|
bower install
|
||||||
|
npm install
|
||||||
|
|
||||||
Then you have to run the server, the easiest way to do this is to
|
Now you can run the server:
|
||||||
use foreman:
|
|
||||||
|
|
||||||
bundle exec foreman start
|
ember serve
|
||||||
|
|
||||||
Now you can open [localhost:5000](http://localhost:5000)
|
And open http://localhost:4200 in the browser.
|
||||||
|
|
||||||
By default it uses the official API at `https://api.travis-ci.org`, but you
|
### Running tests
|
||||||
can customize the API server URL using:
|
|
||||||
|
|
||||||
|
To run a test suite execute:
|
||||||
|
|
||||||
API_ENDPOINT="http://localhost:3000/" bundle exec foreman start
|
ember test
|
||||||
|
|
||||||
This will run against API run locally.
|
You can also start an interactive test runner for easier development:
|
||||||
|
|
||||||
### Compiling assets manually
|
ember test --serve
|
||||||
|
|
||||||
bundle exec rakep
|
|
||||||
ENV=production bundle exec rakep
|
|
||||||
|
|
||||||
### Running the spec suite
|
|
||||||
|
|
||||||
First, start the app (see above).
|
|
||||||
|
|
||||||
bundle exec foreman start
|
|
||||||
|
|
||||||
To run the Ruby specs, run rspec against the spec/ directory:
|
|
||||||
|
|
||||||
bundle exec rspec spec/
|
|
||||||
|
|
||||||
To run the Jasmine specs, open the spec page: [localhost:5000/spec.html](http://localhost:5000/spec.html)
|
|
||||||
|
|
||||||
### i18n
|
|
||||||
|
|
||||||
Localization for travis-web is managed via [localeapp](http://localeapp.com).
|
|
||||||
If you are interested in improving the existing localizations or adding
|
|
||||||
a new locale, please contact us on irc (#travis) and we will set you up.
|
|
||||||
|
|
||||||
Please do **not** edit the YAML files directly.
|
|
||||||
|
|
||||||
Localization data can be synced with the following rake task:
|
|
||||||
|
|
||||||
bundle exec localeapp:update
|
|
||||||
|
|
||||||
This will publish any new keys in en.yml, as well as any missing keys
|
|
||||||
from your handlebars templates and pull down the latest localizations.
|
|
||||||
|
|
||||||
*note*: You will need to have the localeapp api key exported to
|
|
||||||
LOCALEAPP_API_KEY
|
|
||||||
|
|
36
Rakefile
36
Rakefile
|
@ -1,36 +0,0 @@
|
||||||
$: << 'lib'
|
|
||||||
namespace :localeapp do
|
|
||||||
desc "syncs localeapp, yaml and handlebars"
|
|
||||||
task :update do
|
|
||||||
require 'localeapp-handlebars_i18n'
|
|
||||||
Localeapp::HandlebarsI18n.configure($stdout) do |config|
|
|
||||||
config.hbs_load_path = Dir[File.expand_path '../assets/scripts/app/templates/**/*.hbs', __FILE__]
|
|
||||||
config.yml_load_path = File.expand_path '../locales/', __FILE__
|
|
||||||
config.localeapp_api_key = ENV['LOCALEAPP_API_KEY']
|
|
||||||
end
|
|
||||||
system "localeapp push locales/#{Localeapp::HandlebarsI18n.default_locale}.yml"
|
|
||||||
Localeapp::HandlebarsI18n.send_missing_translations
|
|
||||||
system "localeapp pull"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
namespace :ember do
|
|
||||||
desc 'update ember'
|
|
||||||
task :update do
|
|
||||||
if File.exists?('tmp/ember.js')
|
|
||||||
system 'cd tmp/ember.js; git fetch origin; git reset --hard origin/master'
|
|
||||||
else
|
|
||||||
system 'git clone https://github.com/emberjs/ember.js.git tmp/ember.js'
|
|
||||||
end
|
|
||||||
|
|
||||||
system 'cd tmp/ember.js; bundle update'
|
|
||||||
system 'cd tmp/ember.js; rake dist'
|
|
||||||
system 'cp tmp/ember.js/dist/ember.js assets/javascripts/vendor/ember.js'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
task :update_emojis do
|
|
||||||
s = Dir.glob('assets/images/emoji/*.png').map {|png| png.split('/', 4)[3].gsub('.png', '')}.map{|png| "'#{png}'"}.join(", ")
|
|
||||||
e = "@EmojiDictionary = [#{s}]"
|
|
||||||
File.open("assets/scripts/config/emoij.coffee", "w") {|f| f.write(e) }
|
|
||||||
end
|
|
23
app/adapters/application.coffee
Normal file
23
app/adapters/application.coffee
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
`import DS from 'ember-data'`
|
||||||
|
`import config from 'travis/config/environment'`
|
||||||
|
|
||||||
|
Adapter = DS.ActiveModelAdapter.extend
|
||||||
|
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 = Travis.sessionStorage.getItem('travis.token')
|
||||||
|
hash.headers['Authorization'] ||= "token #{token}"
|
||||||
|
|
||||||
|
hash
|
||||||
|
|
||||||
|
findMany: (store, type, ids) ->
|
||||||
|
@ajax(@buildURL(type.typeKey), 'GET', data: { ids: ids })
|
||||||
|
|
||||||
|
`export default Adapter`
|
26
app/adapters/env-var.coffee
Normal file
26
app/adapters/env-var.coffee
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
`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`
|
24
app/adapters/ssh-key.coffee
Normal file
24
app/adapters/ssh-key.coffee
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
`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`
|
98
app/app.coffee
Normal file
98
app/app.coffee
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
`import Ember from 'ember'`
|
||||||
|
`import Resolver from 'ember/resolver'`
|
||||||
|
`import loadInitializers from 'ember/load-initializers'`
|
||||||
|
`import config from './config/environment'`
|
||||||
|
|
||||||
|
`import mb from 'travis/helpers/mb'`
|
||||||
|
`import label from 'travis/helpers/label'`
|
||||||
|
`import travisField from 'travis/helpers/travis-field'`
|
||||||
|
`import travisErrors from 'travis/helpers/travis-errors'`
|
||||||
|
`import tipsy from 'travis/helpers/tipsy'`
|
||||||
|
#`import input from 'travis/helpers/input'`
|
||||||
|
`import filterInput from 'travis/helpers/filter-input'`
|
||||||
|
Ember.Handlebars.registerHelper('label', label)
|
||||||
|
Ember.Handlebars.registerHelper('travis-field', travisField)
|
||||||
|
Ember.Handlebars.registerHelper('travis-errors', travisErrors)
|
||||||
|
Ember.Handlebars.registerHelper('tipsy', tipsy)
|
||||||
|
#Ember.Handlebars.registerHelper('input', input)
|
||||||
|
Ember.Handlebars.registerHelper('filter-input', filterInput)
|
||||||
|
Ember.Handlebars.registerBoundHelper('mb', mb)
|
||||||
|
|
||||||
|
Ember.MODEL_FACTORY_INJECTIONS = true
|
||||||
|
|
||||||
|
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 = $('<span></span>')
|
||||||
|
$('#top .profile').append(element)
|
||||||
|
Em.run.later (-> element.remove()), 10
|
||||||
|
element = $('<span></span>')
|
||||||
|
$('#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:synced', (user) ->
|
||||||
|
Travis.onUserUpdate(user)
|
||||||
|
|
||||||
|
currentDate: ->
|
||||||
|
new Date()
|
||||||
|
|
||||||
|
onUserUpdate: (user) ->
|
||||||
|
if config.pro
|
||||||
|
@identifyCustomer(user)
|
||||||
|
@subscribePusher(user)
|
||||||
|
@setupCharm(user)
|
||||||
|
|
||||||
|
subscribePusher: (user) ->
|
||||||
|
channels = user.channels
|
||||||
|
channels = channels.map (channel) ->
|
||||||
|
if channel.match /^private-/
|
||||||
|
channel
|
||||||
|
else
|
||||||
|
"private-#{channel}"
|
||||||
|
Travis.pusher.subscribeAll(channels)
|
||||||
|
|
||||||
|
setupCharm: (user) ->
|
||||||
|
$.extend window.__CHARM,
|
||||||
|
customer: user.login,
|
||||||
|
customer_id: user.id,
|
||||||
|
email: user.email
|
||||||
|
|
||||||
|
displayCharm: ->
|
||||||
|
__CHARM.show()
|
||||||
|
|
||||||
|
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`
|
|
@ -1,4 +1,6 @@
|
||||||
Travis.TravisSwitchComponent = Ember.Component.extend
|
`import Ember from 'ember'`
|
||||||
|
|
||||||
|
Component = Ember.Component.extend
|
||||||
tagName: 'a'
|
tagName: 'a'
|
||||||
classNames: ['travis-switch']
|
classNames: ['travis-switch']
|
||||||
classNameBindings: ['_active:active']
|
classNameBindings: ['_active:active']
|
||||||
|
@ -19,3 +21,5 @@ Travis.TravisSwitchComponent = Ember.Component.extend
|
||||||
# allow for bindings to propagate
|
# allow for bindings to propagate
|
||||||
Ember.run.next this, ->
|
Ember.run.next this, ->
|
||||||
@sendAction('action', target)
|
@sendAction('action', target)
|
||||||
|
|
||||||
|
`export default Component`
|
|
@ -1,4 +1,6 @@
|
||||||
Travis.AccountController = Ember.ObjectController.extend
|
`import Ember from 'ember'`
|
||||||
|
|
||||||
|
Controller = Ember.ObjectController.extend
|
||||||
allHooks: []
|
allHooks: []
|
||||||
needs: ['currentUser']
|
needs: ['currentUser']
|
||||||
userBinding: 'controllers.currentUser'
|
userBinding: 'controllers.currentUser'
|
||||||
|
@ -20,7 +22,12 @@ Travis.AccountController = Ember.ObjectController.extend
|
||||||
|
|
||||||
reloadHooks: ->
|
reloadHooks: ->
|
||||||
if login = @get('login')
|
if login = @get('login')
|
||||||
@set('allHooks', Travis.Hook.find(all: true, owner_name: login))
|
hooks = @store.find('hook', all: true, owner_name: login)
|
||||||
|
|
||||||
|
hooks.then () ->
|
||||||
|
hooks.set('isLoaded', true)
|
||||||
|
|
||||||
|
@set('allHooks', hooks)
|
||||||
|
|
||||||
hooks: (->
|
hooks: (->
|
||||||
@reloadHooks() unless hooks = @get('allHooks')
|
@reloadHooks() unless hooks = @get('allHooks')
|
||||||
|
@ -33,9 +40,11 @@ Travis.AccountController = Ember.ObjectController.extend
|
||||||
).property('allHooks.length', 'allHooks')
|
).property('allHooks.length', 'allHooks')
|
||||||
|
|
||||||
showPrivateReposHint: (->
|
showPrivateReposHint: (->
|
||||||
Travis.config.show_repos_hint == 'private'
|
@config.show_repos_hint == 'private'
|
||||||
) .property()
|
) .property()
|
||||||
|
|
||||||
showPublicReposHint: (->
|
showPublicReposHint: (->
|
||||||
Travis.config.show_repos_hint == 'public'
|
@config.show_repos_hint == 'public'
|
||||||
) .property()
|
) .property()
|
||||||
|
|
||||||
|
`export default Controller`
|
6
app/controllers/accounts.coffee
Normal file
6
app/controllers/accounts.coffee
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
`import Ember from 'ember'`
|
||||||
|
|
||||||
|
Controller = Ember.ArrayController.extend
|
||||||
|
tab: 'accounts'
|
||||||
|
|
||||||
|
`export default Controller`
|
7
app/controllers/accounts/info.coffee
Normal file
7
app/controllers/accounts/info.coffee
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
`import Ember from 'ember'`
|
||||||
|
|
||||||
|
Controller = Ember.Controller.extend
|
||||||
|
needs: ['currentUser', 'repos']
|
||||||
|
userBinding: 'controllers.currentUser'
|
||||||
|
|
||||||
|
`export default Controller`
|
5
app/controllers/auth.coffee
Normal file
5
app/controllers/auth.coffee
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
`import Ember from 'ember'`
|
||||||
|
|
||||||
|
Controller = Ember.Controller.extend()
|
||||||
|
|
||||||
|
`export default Controller`
|
26
app/controllers/build.coffee
Normal file
26
app/controllers/build.coffee
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
`import Ember from 'ember'`
|
||||||
|
`import { gravatarImage } from 'travis/utils/urls'`
|
||||||
|
`import GithubUrlPropertievs from 'travis/mixins/github-url-properties'`
|
||||||
|
|
||||||
|
Controller = Ember.Controller.extend GithubUrlPropertievs,
|
||||||
|
needs: ['repo']
|
||||||
|
repoBinding: 'controllers.repo.repo'
|
||||||
|
commitBinding: 'build.commit'
|
||||||
|
currentUserBinding: 'controllers.repo.currentUser'
|
||||||
|
tabBinding: 'controllers.repo.tab'
|
||||||
|
|
||||||
|
currentItemBinding: 'build'
|
||||||
|
|
||||||
|
loading: (->
|
||||||
|
@get('build.isLoading')
|
||||||
|
).property('build.isLoading')
|
||||||
|
|
||||||
|
urlCommitterGravatarImage: (->
|
||||||
|
gravatarImage(@get('commit.committerEmail'), 40)
|
||||||
|
).property('commit.committerEmail')
|
||||||
|
|
||||||
|
urlAuthorGravatarImage: (->
|
||||||
|
gravatarImage(@get('commit.authorEmail'), 40)
|
||||||
|
).property('commit.authorEmail')
|
||||||
|
|
||||||
|
`export default Controller`
|
15
app/controllers/builds-item.coffee
Normal file
15
app/controllers/builds-item.coffee
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
`import Ember from 'ember'`
|
||||||
|
`import { colorForState } from 'travis/utils/helpers'`
|
||||||
|
`import GithubUrlProperties from 'travis/mixins/github-url-properties'`
|
||||||
|
|
||||||
|
Controller = Ember.ObjectController.extend(GithubUrlProperties,
|
||||||
|
needs: ['builds']
|
||||||
|
isPullRequestsListBinding: 'controllers.builds.isPullRequestsList'
|
||||||
|
buildBinding: 'content'
|
||||||
|
|
||||||
|
color: (->
|
||||||
|
colorForState(@get('build.state'))
|
||||||
|
).property('build.state')
|
||||||
|
)
|
||||||
|
|
||||||
|
`export default Controller`
|
|
@ -1,4 +1,6 @@
|
||||||
Travis.BuildsController = Em.ArrayController.extend
|
`import Ember from 'ember'`
|
||||||
|
|
||||||
|
Controller = Ember.ArrayController.extend
|
||||||
isPullRequestsList: false
|
isPullRequestsList: false
|
||||||
|
|
||||||
sortAscending: false
|
sortAscending: false
|
||||||
|
@ -14,8 +16,17 @@ Travis.BuildsController = Em.ArrayController.extend
|
||||||
showMore: ->
|
showMore: ->
|
||||||
id = @get('repo.id')
|
id = @get('repo.id')
|
||||||
number = @get('lastObject.number')
|
number = @get('lastObject.number')
|
||||||
@get('content').load Travis.Build.olderThanNumber(id, number, @get('tab'))
|
@get('content').load @olderThanNumber(id, number, @get('tab'))
|
||||||
|
|
||||||
displayShowMoreButton: (->
|
displayShowMoreButton: (->
|
||||||
@get('tab') != 'branches' and parseInt(@get('lastObject.number')) > 1
|
@get('tab') != 'branches' and parseInt(@get('lastObject.number')) > 1
|
||||||
).property('tab', 'lastObject.number')
|
).property('tab', 'lastObject.number')
|
||||||
|
|
||||||
|
olderThanNumber: (id, number, type) ->
|
||||||
|
options = { repository_id: id, after_number: number }
|
||||||
|
if type?
|
||||||
|
options.event_type = type.replace(/s$/, '') # poor man's singularize
|
||||||
|
|
||||||
|
@store.find('build', options)
|
||||||
|
|
||||||
|
`export default Controller`
|
25
app/controllers/caches-by-branch.coffee
Normal file
25
app/controllers/caches-by-branch.coffee
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
`import Ember from 'ember'`
|
||||||
|
`import Ajax from 'travis/utils/ajax'`
|
||||||
|
|
||||||
|
Controller = Ember.ObjectController.extend
|
||||||
|
isDeleting: false
|
||||||
|
needs: ['repo', 'caches']
|
||||||
|
repo: Ember.computed.alias('controllers.repo.repo')
|
||||||
|
|
||||||
|
actions:
|
||||||
|
delete: ->
|
||||||
|
return if @get('isDeleting')
|
||||||
|
|
||||||
|
if confirm('Are you sure?')
|
||||||
|
@set('isDeleting', true)
|
||||||
|
|
||||||
|
data = { branch: @get('branch') }
|
||||||
|
|
||||||
|
deletingDone = => @set('isDeleting', false)
|
||||||
|
|
||||||
|
repo = @get('repo')
|
||||||
|
Ajax.ajax("/repos/#{repo.get('id')}/caches", "DELETE", data: data).then(deletingDone, deletingDone).then =>
|
||||||
|
model = @get('model')
|
||||||
|
@get('controllers.caches').removeObject(model)
|
||||||
|
|
||||||
|
`export default Controller`
|
27
app/controllers/caches-item.coffee
Normal file
27
app/controllers/caches-item.coffee
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
`import Ember from 'ember'`
|
||||||
|
`import Ajax from 'travis/utils/ajax'`
|
||||||
|
|
||||||
|
Controller = Ember.ObjectController.extend
|
||||||
|
isDeleting: false
|
||||||
|
needs: ['repo', 'caches']
|
||||||
|
repo: Ember.computed.alias('controllers.repo.repo')
|
||||||
|
|
||||||
|
actions:
|
||||||
|
delete: ->
|
||||||
|
return if @get('isDeleting')
|
||||||
|
|
||||||
|
if confirm('Are you sure?')
|
||||||
|
@set('isDeleting', true)
|
||||||
|
|
||||||
|
data = { branch: @get('branch'), match: @get('slug') }
|
||||||
|
|
||||||
|
deletingDone = => @set('isDeleting', false)
|
||||||
|
|
||||||
|
repo = @get('repo')
|
||||||
|
Ajax.ajax("/repos/#{repo.get('id')}/caches", "DELETE", data: data).then(deletingDone, deletingDone).then =>
|
||||||
|
model = @get('model')
|
||||||
|
@get('parent.caches').removeObject(model)
|
||||||
|
if @get('parent.caches.length') == 0
|
||||||
|
@get('controllers.caches').removeObject(@get('parent'))
|
||||||
|
|
||||||
|
`export default Controller`
|
22
app/controllers/caches.coffee
Normal file
22
app/controllers/caches.coffee
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
`import Ember from 'ember'`
|
||||||
|
`import Ajax from 'travis/utils/ajax'`
|
||||||
|
|
||||||
|
Controller = Ember.ArrayController.extend
|
||||||
|
isDeleting: false
|
||||||
|
needs: ['repo']
|
||||||
|
repo: Ember.computed.alias('controllers.repo.repo')
|
||||||
|
|
||||||
|
actions:
|
||||||
|
deleteRepoCache: ->
|
||||||
|
return if @get('isDeleting')
|
||||||
|
|
||||||
|
if confirm('Are you sure?')
|
||||||
|
@set('isDeleting', true)
|
||||||
|
|
||||||
|
deletingDone = => @set('isDeleting', false)
|
||||||
|
|
||||||
|
repo = @get('repo')
|
||||||
|
Ajax.ajax("/repos/#{repo.get('id')}/caches", "DELETE").then(deletingDone, deletingDone).then =>
|
||||||
|
@clear()
|
||||||
|
|
||||||
|
`export default Controller`
|
|
@ -1,4 +1,4 @@
|
||||||
Travis.CurrentUserController = Em.ObjectController.extend
|
Controller = Ember.ObjectController.extend
|
||||||
sync: ->
|
sync: ->
|
||||||
@get('model').sync()
|
@get('model').sync()
|
||||||
|
|
||||||
|
@ -9,3 +9,5 @@ Travis.CurrentUserController = Em.ObjectController.extend
|
||||||
Ember.run.scheduleOnce 'routerTransitions', this, ->
|
Ember.run.scheduleOnce 'routerTransitions', this, ->
|
||||||
@container.lookup('router:main').send('renderFirstSync')
|
@container.lookup('router:main').send('renderFirstSync')
|
||||||
).observes('isSyncing', 'auth.currentUser')
|
).observes('isSyncing', 'auth.currentUser')
|
||||||
|
|
||||||
|
`export default Controller`
|
29
app/controllers/dashboard/repositories.coffee
Normal file
29
app/controllers/dashboard/repositories.coffee
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
`import Ember from 'ember'`
|
||||||
|
|
||||||
|
Controller = Ember.Controller.extend
|
||||||
|
#queryParams: ['filter']
|
||||||
|
filter: null
|
||||||
|
|
||||||
|
filteredRepositories: (->
|
||||||
|
filter = @get('filter')
|
||||||
|
repos = @get('model')
|
||||||
|
|
||||||
|
if Ember.isBlank(filter)
|
||||||
|
repos
|
||||||
|
else
|
||||||
|
repos.filter (item, index) ->
|
||||||
|
item.slug.match(new RegExp(filter))
|
||||||
|
|
||||||
|
).property('filter', 'model')
|
||||||
|
|
||||||
|
updateFilter: () ->
|
||||||
|
value = @get('_lastFilterValue')
|
||||||
|
@transitionToRoute queryParams: { filter: value }
|
||||||
|
@set('filter', value)
|
||||||
|
|
||||||
|
actions:
|
||||||
|
updateFilter: (value) ->
|
||||||
|
@set('_lastFilterValue', value)
|
||||||
|
Ember.run.throttle this, @updateFilter, [], 200, false
|
||||||
|
|
||||||
|
`export default Controller`
|
|
@ -1,6 +1,7 @@
|
||||||
require 'travis/validations'
|
`import Ember from 'ember'`
|
||||||
|
`import Validations from 'travis/utils/validations'`
|
||||||
|
|
||||||
Travis.EnvVarController = Ember.ObjectController.extend Travis.Validations,
|
Controller = Ember.ObjectController.extend Validations,
|
||||||
isEditing: false
|
isEditing: false
|
||||||
isDeleting: false
|
isDeleting: false
|
||||||
|
|
||||||
|
@ -25,8 +26,7 @@ Travis.EnvVarController = Ember.ObjectController.extend Travis.Validations,
|
||||||
return if @get('isDeleting')
|
return if @get('isDeleting')
|
||||||
@set('isDeleting', true)
|
@set('isDeleting', true)
|
||||||
|
|
||||||
deletingDone = => @set('isDeleting', false)
|
@get('model').destroyRecord()
|
||||||
@get('model').deleteRecord().then deletingDone, deletingDone
|
|
||||||
|
|
||||||
edit: ->
|
edit: ->
|
||||||
@set('isEditing', true)
|
@set('isEditing', true)
|
||||||
|
@ -37,7 +37,6 @@ Travis.EnvVarController = Ember.ObjectController.extend Travis.Validations,
|
||||||
|
|
||||||
save: ->
|
save: ->
|
||||||
return if @get('isSaving')
|
return if @get('isSaving')
|
||||||
@set('isSaving', true)
|
|
||||||
|
|
||||||
if @isValid()
|
if @isValid()
|
||||||
env_var = @get('model')
|
env_var = @get('model')
|
||||||
|
@ -45,8 +44,5 @@ Travis.EnvVarController = Ember.ObjectController.extend Travis.Validations,
|
||||||
# TODO: handle errors
|
# TODO: handle errors
|
||||||
env_var.save().then =>
|
env_var.save().then =>
|
||||||
@set('isEditing', false)
|
@set('isEditing', false)
|
||||||
@set('isSaving', false)
|
|
||||||
, =>
|
`export default Controller`
|
||||||
@set('isSaving', false)
|
|
||||||
else
|
|
||||||
@set('isSaving', false)
|
|
6
app/controllers/env-vars.coffee
Normal file
6
app/controllers/env-vars.coffee
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
`import Ember from 'ember'`
|
||||||
|
|
||||||
|
Controller = Ember.ArrayController.extend
|
||||||
|
vars: Ember.computed.alias('model')
|
||||||
|
|
||||||
|
`export default Controller`
|
|
@ -1,9 +1,11 @@
|
||||||
require 'travis/validations'
|
`import Validations from 'travis/utils/validations'`
|
||||||
|
|
||||||
Travis.EnvVarsNewController = Travis.Controller.extend Travis.Validations,
|
Controller = Ember.Controller.extend Validations,
|
||||||
needs: ['repo']
|
needs: ['repo']
|
||||||
repo: Ember.computed.alias('controllers.repo.repo')
|
repo: Ember.computed.alias('controllers.repo.repo')
|
||||||
|
|
||||||
|
isSaving: false
|
||||||
|
|
||||||
validates:
|
validates:
|
||||||
name: ['presence']
|
name: ['presence']
|
||||||
|
|
||||||
|
@ -23,7 +25,7 @@ Travis.EnvVarsNewController = Travis.Controller.extend Travis.Validations,
|
||||||
@set('isSaving', true)
|
@set('isSaving', true)
|
||||||
|
|
||||||
if @isValid()
|
if @isValid()
|
||||||
env_var = Travis.EnvVar.create(
|
env_var = @store.createRecord('env_var',
|
||||||
name: @get('name')
|
name: @get('name')
|
||||||
value: @get('value')
|
value: @get('value')
|
||||||
public: @get('public')
|
public: @get('public')
|
||||||
|
@ -39,3 +41,5 @@ Travis.EnvVarsNewController = Travis.Controller.extend Travis.Validations,
|
||||||
@set('isSaving', false)
|
@set('isSaving', false)
|
||||||
else
|
else
|
||||||
@set('isSaving', false)
|
@set('isSaving', false)
|
||||||
|
|
||||||
|
`export default Controller`
|
9
app/controllers/first-sync.coffee
Normal file
9
app/controllers/first-sync.coffee
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
`import Ember from 'ember'`
|
||||||
|
|
||||||
|
Controller = Ember.Controller.extend
|
||||||
|
needs: ['currentUser']
|
||||||
|
user: Ember.computed.alias('controllers.currentUser')
|
||||||
|
|
||||||
|
isSyncing: Ember.computed.alias('user.isSyncing')
|
||||||
|
|
||||||
|
`export default Controller`
|
|
@ -1,10 +1,14 @@
|
||||||
Travis.FlashController = Ember.ArrayController.extend
|
`import Ember from 'ember'`
|
||||||
|
`import LimitedArray from 'travis/utils/limited-array'`
|
||||||
|
`import Broadcast from 'travis/models/broadcast'`
|
||||||
|
|
||||||
|
Controller = Ember.ArrayController.extend
|
||||||
needs: ['currentUser']
|
needs: ['currentUser']
|
||||||
currentUserBinding: 'controllers.currentUser'
|
currentUserBinding: 'controllers.currentUser'
|
||||||
|
|
||||||
init: ->
|
init: ->
|
||||||
@_super.apply this, arguments
|
@_super.apply this, arguments
|
||||||
@set('flashes', Travis.LimitedArray.create(limit: 2, content: []))
|
@set('flashes', LimitedArray.create(limit: 2, content: []))
|
||||||
|
|
||||||
model: (->
|
model: (->
|
||||||
broadcasts = @get('unseenBroadcasts')
|
broadcasts = @get('unseenBroadcasts')
|
||||||
|
@ -20,7 +24,7 @@ Travis.FlashController = Ember.ArrayController.extend
|
||||||
).property('broadcasts.isLoaded', 'broadcasts.length')
|
).property('broadcasts.isLoaded', 'broadcasts.length')
|
||||||
|
|
||||||
broadcasts: (->
|
broadcasts: (->
|
||||||
if @get('currentUser.id') then Travis.Broadcast.find() else Ember.A()
|
if @get('currentUser.id') then @store.find('broadcast') else Ember.A()
|
||||||
).property('currentUser.id')
|
).property('currentUser.id')
|
||||||
|
|
||||||
loadFlashes: (msgs) ->
|
loadFlashes: (msgs) ->
|
||||||
|
@ -31,7 +35,7 @@ Travis.FlashController = Ember.ArrayController.extend
|
||||||
Ember.run.later(this, (-> @get('flashes.content').removeObject(msg)), 15000)
|
Ember.run.later(this, (-> @get('flashes.content').removeObject(msg)), 15000)
|
||||||
|
|
||||||
close: (msg) ->
|
close: (msg) ->
|
||||||
if msg instanceof Travis.Broadcast
|
if msg instanceof Broadcast
|
||||||
msg.setSeen()
|
msg.setSeen()
|
||||||
@notifyPropertyChange('unseenBroadcasts')
|
@notifyPropertyChange('unseenBroadcasts')
|
||||||
else
|
else
|
||||||
|
@ -40,3 +44,5 @@ Travis.FlashController = Ember.ArrayController.extend
|
||||||
actions:
|
actions:
|
||||||
close: (msg) ->
|
close: (msg) ->
|
||||||
@close(msg)
|
@close(msg)
|
||||||
|
|
||||||
|
`export default Controller`
|
|
@ -1,4 +1,7 @@
|
||||||
Travis.JobController = Em.Controller.extend
|
`import Ember from 'ember'`
|
||||||
|
`import { githubCommit } from 'travis/utils/urls'`
|
||||||
|
|
||||||
|
Controller = Ember.Controller.extend
|
||||||
needs: ['repo']
|
needs: ['repo']
|
||||||
|
|
||||||
repoBinding: 'controllers.repo.repo'
|
repoBinding: 'controllers.repo.repo'
|
||||||
|
@ -10,5 +13,7 @@ Travis.JobController = Em.Controller.extend
|
||||||
currentItemBinding: 'job'
|
currentItemBinding: 'job'
|
||||||
|
|
||||||
urlGithubCommit: (->
|
urlGithubCommit: (->
|
||||||
Travis.Urls.githubCommit(@get('repo.slug'), @get('commit.sha'))
|
githubCommit(@get('repo.slug'), @get('commit.sha'))
|
||||||
).property('repo.slug', 'commit.sha')
|
).property('repo.slug', 'commit.sha')
|
||||||
|
|
||||||
|
`export default Controller`
|
5
app/controllers/main/error.coffee
Normal file
5
app/controllers/main/error.coffee
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
`import Ember from 'ember'`
|
||||||
|
|
||||||
|
Controller = Ember.Controller.extend()
|
||||||
|
|
||||||
|
`export default Controller`
|
|
@ -1,4 +1,6 @@
|
||||||
Travis.ProfileController = Travis.Controller.extend
|
`import Ember from 'ember'`
|
||||||
|
|
||||||
|
Controller = Ember.Controller.extend
|
||||||
name: 'profile'
|
name: 'profile'
|
||||||
|
|
||||||
needs: ['currentUser', 'accounts', 'account']
|
needs: ['currentUser', 'accounts', 'account']
|
||||||
|
@ -6,7 +8,7 @@ Travis.ProfileController = Travis.Controller.extend
|
||||||
accountBinding: 'controllers.account'
|
accountBinding: 'controllers.account'
|
||||||
|
|
||||||
activate: (action, params) ->
|
activate: (action, params) ->
|
||||||
this["view#{$.camelize(action)}"]()
|
this["view_#{action}".camelize()]()
|
||||||
|
|
||||||
viewHooks: ->
|
viewHooks: ->
|
||||||
@connectTab('hooks')
|
@connectTab('hooks')
|
||||||
|
@ -16,14 +18,11 @@ Travis.ProfileController = Travis.Controller.extend
|
||||||
@connectTab('user')
|
@connectTab('user')
|
||||||
|
|
||||||
connectTab: (tab) ->
|
connectTab: (tab) ->
|
||||||
if tab == 'user'
|
|
||||||
view = 'AccountsInfoView'
|
|
||||||
else
|
|
||||||
view = "#{$.camelize(tab)}View"
|
|
||||||
viewClass = Travis[view]
|
|
||||||
@set('tab', tab)
|
@set('tab', tab)
|
||||||
|
|
||||||
billingUrl: (->
|
billingUrl: (->
|
||||||
id = if @get('account.type') == 'user' then 'user' else @get('account.login')
|
id = if @get('account.type') == 'user' then 'user' else @get('account.login')
|
||||||
"#{Travis.config.billing_endpoint}/subscriptions/#{id}"
|
"#{@get('config').billingEndpoint}/subscriptions/#{id}"
|
||||||
).property('account.login', 'account.type')
|
).property('account.login', 'account.type')
|
||||||
|
|
||||||
|
`export default Controller`
|
9
app/controllers/queue.coffee
Normal file
9
app/controllers/queue.coffee
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
`import Ember from 'ember'`
|
||||||
|
|
||||||
|
Controller = Ember.ArrayController.extend
|
||||||
|
content: (->
|
||||||
|
@store.filter 'job', {}, (job) ->
|
||||||
|
['created', 'queued'].indexOf(job.get('state')) != -1
|
||||||
|
).property()
|
||||||
|
|
||||||
|
`export default Controller`
|
|
@ -1,4 +1,7 @@
|
||||||
Travis.RepoController = Travis.Controller.extend
|
`import Ember from 'ember'`
|
||||||
|
`import { githubRepo } from 'travis/utils/urls'`
|
||||||
|
|
||||||
|
Controller = Ember.Controller.extend
|
||||||
needs: ['repos', 'currentUser', 'build', 'request', 'job']
|
needs: ['repos', 'currentUser', 'build', 'request', 'job']
|
||||||
currentUserBinding: 'controllers.currentUser'
|
currentUserBinding: 'controllers.currentUser'
|
||||||
|
|
||||||
|
@ -12,7 +15,7 @@ Travis.RepoController = Travis.Controller.extend
|
||||||
init: ->
|
init: ->
|
||||||
@_super.apply this, arguments
|
@_super.apply this, arguments
|
||||||
if !Ember.testing
|
if !Ember.testing
|
||||||
Visibility.every Travis.INTERVALS.updateTimes, @updateTimes.bind(this)
|
Visibility.every @config.intervals.updateTimes, @updateTimes.bind(this)
|
||||||
|
|
||||||
updateTimes: ->
|
updateTimes: ->
|
||||||
Ember.run this, ->
|
Ember.run this, ->
|
||||||
|
@ -30,7 +33,7 @@ Travis.RepoController = Travis.Controller.extend
|
||||||
|
|
||||||
activate: (action) ->
|
activate: (action) ->
|
||||||
@stopObservingLastBuild()
|
@stopObservingLastBuild()
|
||||||
this["view#{$.camelize(action)}"]()
|
this["view_#{action}".camelize()]()
|
||||||
|
|
||||||
viewIndex: ->
|
viewIndex: ->
|
||||||
@observeLastBuild()
|
@observeLastBuild()
|
||||||
|
@ -68,7 +71,7 @@ Travis.RepoController = Travis.Controller.extend
|
||||||
@connectTab('settings')
|
@connectTab('settings')
|
||||||
|
|
||||||
lastBuildDidChange: ->
|
lastBuildDidChange: ->
|
||||||
Ember.run.scheduleOnce('data', this, @_lastBuildDidChange);
|
Ember.run.scheduleOnce('actions', this, @_lastBuildDidChange);
|
||||||
|
|
||||||
_lastBuildDidChange: ->
|
_lastBuildDidChange: ->
|
||||||
build = @get('repo.lastBuild')
|
build = @get('repo.lastBuild')
|
||||||
|
@ -88,5 +91,7 @@ Travis.RepoController = Travis.Controller.extend
|
||||||
@set('tab', tab)
|
@set('tab', tab)
|
||||||
|
|
||||||
urlGithub: (->
|
urlGithub: (->
|
||||||
Travis.Urls.githubRepo(@get('repo.slug'))
|
githubRepo(@get('repo.slug'))
|
||||||
).property('repo.slug')
|
).property('repo.slug')
|
||||||
|
|
||||||
|
`export default Controller`
|
|
@ -1,6 +1,8 @@
|
||||||
require 'travis/limited_array'
|
`import Ember from 'ember'`
|
||||||
|
`import limit from 'travis/utils/computed-limit'`
|
||||||
|
`import Repo from 'travis/models/repo'`
|
||||||
|
|
||||||
Travis.ReposController = Ember.ArrayController.extend
|
Controller = Ember.ArrayController.extend
|
||||||
actions:
|
actions:
|
||||||
activate: (name) ->
|
activate: (name) ->
|
||||||
@activate(name)
|
@activate(name)
|
||||||
|
@ -27,14 +29,14 @@ Travis.ReposController = Ember.ArrayController.extend
|
||||||
init: ->
|
init: ->
|
||||||
@_super.apply this, arguments
|
@_super.apply this, arguments
|
||||||
if !Ember.testing
|
if !Ember.testing
|
||||||
Visibility.every Travis.INTERVALS.updateTimes, @updateTimes.bind(this)
|
Visibility.every @config.intervals.updateTimes, @updateTimes.bind(this)
|
||||||
|
|
||||||
recentRepos: (->
|
recentRepos: (->
|
||||||
Ember.ArrayProxy.extend(
|
Ember.ArrayProxy.extend(
|
||||||
isLoadedBinding: 'repos.isLoaded'
|
isLoadedBinding: 'repos.isLoaded'
|
||||||
repos: Travis.Repo.withLastBuild()
|
repos: Repo.withLastBuild(@store)
|
||||||
sorted: Ember.computed.sort('repos', 'sortedReposKeys')
|
sorted: Ember.computed.sort('repos', 'sortedReposKeys')
|
||||||
content: Ember.computed.limit('sorted', 'limit')
|
content: limit('sorted', 'limit')
|
||||||
sortedReposKeys: ['sortOrder:asc']
|
sortedReposKeys: ['sortOrder:asc']
|
||||||
limit: 30
|
limit: 30
|
||||||
).create()
|
).create()
|
||||||
|
@ -47,7 +49,7 @@ Travis.ReposController = Ember.ArrayController.extend
|
||||||
activate: (tab, params) ->
|
activate: (tab, params) ->
|
||||||
@set('sortProperties', ['sortOrder'])
|
@set('sortProperties', ['sortOrder'])
|
||||||
@set('tab', tab)
|
@set('tab', tab)
|
||||||
this["view#{$.camelize(tab)}"](params)
|
this["view_#{tab}".camelize()](params)
|
||||||
|
|
||||||
viewRecent: ->
|
viewRecent: ->
|
||||||
@set('content', @get('recentRepos'))
|
@set('content', @get('recentRepos'))
|
||||||
|
@ -57,14 +59,14 @@ Travis.ReposController = Ember.ArrayController.extend
|
||||||
|
|
||||||
userRepos: (->
|
userRepos: (->
|
||||||
if login = @get('currentUser.login')
|
if login = @get('currentUser.login')
|
||||||
Travis.Repo.accessibleBy(login)
|
Repo.accessibleBy(@store, login)
|
||||||
else
|
else
|
||||||
[]
|
[]
|
||||||
).property('currentUser.login')
|
).property('currentUser.login')
|
||||||
|
|
||||||
viewSearch: (phrase) ->
|
viewSearch: (phrase) ->
|
||||||
@set('search', phrase)
|
@set('search', phrase)
|
||||||
@set('content', Travis.Repo.search(phrase))
|
@set('content', Repo.search(@store, phrase))
|
||||||
|
|
||||||
searchObserver: (->
|
searchObserver: (->
|
||||||
search = @get('search')
|
search = @get('search')
|
||||||
|
@ -88,3 +90,5 @@ Travis.ReposController = Ember.ArrayController.extend
|
||||||
else
|
else
|
||||||
'Could not find any repos'
|
'Could not find any repos'
|
||||||
).property('tab')
|
).property('tab')
|
||||||
|
|
||||||
|
`export default Controller`
|
|
@ -1,4 +1,6 @@
|
||||||
Travis.RequestController = Ember.ObjectController.extend
|
`import Ember from 'ember'`
|
||||||
|
|
||||||
|
Controller = Ember.ObjectController.extend
|
||||||
requestClass: (->
|
requestClass: (->
|
||||||
if @get('content.isAccepted')
|
if @get('content.isAccepted')
|
||||||
'accepted'
|
'accepted'
|
||||||
|
@ -22,10 +24,10 @@ Travis.RequestController = Ember.ObjectController.extend
|
||||||
|
|
||||||
message: (->
|
message: (->
|
||||||
message = @get('model.message')
|
message = @get('model.message')
|
||||||
if Travis.config.pro && message == "private repository"
|
if @config.pro && message == "private repository"
|
||||||
''
|
''
|
||||||
else
|
else
|
||||||
message
|
message
|
||||||
).property('model.message')
|
).property('model.message')
|
||||||
|
|
||||||
|
`export default Controller`
|
|
@ -1,4 +1,6 @@
|
||||||
Travis.RequestsController = Ember.ArrayController.extend
|
`import Ember from 'ember'`
|
||||||
|
|
||||||
|
Controller = Ember.ArrayController.extend
|
||||||
needs: ['repo']
|
needs: ['repo']
|
||||||
repo: Ember.computed.alias('controllers.repo.repo')
|
repo: Ember.computed.alias('controllers.repo.repo')
|
||||||
|
|
||||||
|
@ -6,3 +8,5 @@ Travis.RequestsController = Ember.ArrayController.extend
|
||||||
slug = @get('repo.slug')
|
slug = @get('repo.slug')
|
||||||
"https://lint.travis-ci.org/#{slug}"
|
"https://lint.travis-ci.org/#{slug}"
|
||||||
).property('repo.slug')
|
).property('repo.slug')
|
||||||
|
|
||||||
|
`export default Controller`
|
9
app/controllers/running-jobs.coffee
Normal file
9
app/controllers/running-jobs.coffee
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
`import Ember from 'ember'`
|
||||||
|
|
||||||
|
Controller = Ember.ArrayController.extend
|
||||||
|
content: (->
|
||||||
|
@store.filter 'job', { state: 'started' }, (job) ->
|
||||||
|
['started', 'received'].indexOf(job.get('state')) != -1
|
||||||
|
).property()
|
||||||
|
|
||||||
|
`export default Controller`
|
|
@ -1,4 +1,6 @@
|
||||||
Travis.SettingsIndexController = Em.ObjectController.extend
|
`import Ember from 'ember'`
|
||||||
|
|
||||||
|
Controller = Ember.ObjectController.extend
|
||||||
settings: Ember.computed.alias('model.settings')
|
settings: Ember.computed.alias('model.settings')
|
||||||
|
|
||||||
settingsChanged: (->
|
settingsChanged: (->
|
||||||
|
@ -16,3 +18,5 @@ Travis.SettingsIndexController = Em.ObjectController.extend
|
||||||
save: ->
|
save: ->
|
||||||
@get('model').saveSettings(@get('settings')).then null, ->
|
@get('model').saveSettings(@get('settings')).then null, ->
|
||||||
Travis.flash(error: 'There was an error while saving settings. Please try again.')
|
Travis.flash(error: 'There was an error while saving settings. Please try again.')
|
||||||
|
|
||||||
|
`export default Controller`
|
19
app/controllers/sidebar.coffee
Normal file
19
app/controllers/sidebar.coffee
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
`import Ember from 'ember'`
|
||||||
|
|
||||||
|
Controller = Ember.ArrayController.extend
|
||||||
|
init: ->
|
||||||
|
@_super.apply this, arguments
|
||||||
|
@tickables = []
|
||||||
|
|
||||||
|
tips: [
|
||||||
|
"Did you know that you can parallelize tests on Travis CI? <a href=\"http://docs.travis-ci.com/user/speeding-up-the-build/#Paralellizing-your-build-on-one-VM?utm_source=tips\">Learn more</a>"
|
||||||
|
"Did you know that you can split a build into several smaller pieces? <a href=\"http://docs.travis-ci.com/user/speeding-up-the-build/#Parallelizing-your-builds-across-virtual-machines?utm_source=tips\">Learn more</a>"
|
||||||
|
"Did you know that you can skip a build? <a href=\"http://docs.travis-ci.com/user/how-to-skip-a-build/?utm_source=tips\">Learn more</a>"
|
||||||
|
]
|
||||||
|
|
||||||
|
tip: (->
|
||||||
|
if tips = @get('tips')
|
||||||
|
tips[Math.floor(Math.random()*tips.length)]
|
||||||
|
).property().volatile()
|
||||||
|
|
||||||
|
`export default Controller`
|
67
app/controllers/ssh-key.coffee
Normal file
67
app/controllers/ssh-key.coffee
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
`import Ember from 'ember'`
|
||||||
|
`import Validations from 'travis/utils/validations'`
|
||||||
|
|
||||||
|
Controller = Ember.ObjectController.extend Validations,
|
||||||
|
isEditing: false
|
||||||
|
isSaving: false
|
||||||
|
isDeleting: false
|
||||||
|
defaultKey: null
|
||||||
|
|
||||||
|
needs: ['repo']
|
||||||
|
repo: Ember.computed.alias('controllers.repo.repo')
|
||||||
|
|
||||||
|
validates:
|
||||||
|
value: ['presence']
|
||||||
|
|
||||||
|
reset: ->
|
||||||
|
@set('isEditing', false)
|
||||||
|
|
||||||
|
actions:
|
||||||
|
add: ->
|
||||||
|
id = @get('repo.id')
|
||||||
|
model = @store.recordForId('sshKey', id)
|
||||||
|
if model.get('currentState.stateName') == 'root.empty'
|
||||||
|
@store.dematerializeRecord(model)
|
||||||
|
|
||||||
|
model = @store.createRecord('sshKey', id: id)
|
||||||
|
@set('model', model)
|
||||||
|
@set('isEditing', true)
|
||||||
|
|
||||||
|
save: ->
|
||||||
|
return if @get('isSaving')
|
||||||
|
@set('isSaving', true)
|
||||||
|
|
||||||
|
if @isValid()
|
||||||
|
@get('model').save().then =>
|
||||||
|
@set('isEditing', false)
|
||||||
|
@set('isSaving', false)
|
||||||
|
, (error) =>
|
||||||
|
@set('isSaving', false)
|
||||||
|
if error.errors
|
||||||
|
@addErrorsFromResponse(error.errors)
|
||||||
|
else
|
||||||
|
@set('isSaving', false)
|
||||||
|
|
||||||
|
delete: ->
|
||||||
|
return if @get('isDeleting')
|
||||||
|
@set('isDeleting', true)
|
||||||
|
|
||||||
|
deletingDone = => @set('isDeleting', false)
|
||||||
|
|
||||||
|
@get('model').deleteRecord()
|
||||||
|
@get('model').save().then(deletingDone, deletingDone).then =>
|
||||||
|
@set('model', null)
|
||||||
|
|
||||||
|
cancel: ->
|
||||||
|
if model = @get('model')
|
||||||
|
if model.get('currentState.stateName') == 'root.empty' ||
|
||||||
|
model.get('currentState.stateName').indexOf('root.loaded.created') != -1
|
||||||
|
@store.dematerializeRecord(model)
|
||||||
|
|
||||||
|
@set('model', null)
|
||||||
|
@set('isEditing', false)
|
||||||
|
|
||||||
|
edit: ->
|
||||||
|
@set('isEditing', true)
|
||||||
|
|
||||||
|
`export default Controller`
|
21
app/controllers/top.coffee
Normal file
21
app/controllers/top.coffee
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
`import Ember from 'ember'`
|
||||||
|
|
||||||
|
Controller = Ember.Controller.extend
|
||||||
|
needs: ['currentUser']
|
||||||
|
userBinding: 'controllers.currentUser'
|
||||||
|
|
||||||
|
userName: (->
|
||||||
|
@get('user.name') || @get('user.login')
|
||||||
|
).property('user.login', 'user.name')
|
||||||
|
|
||||||
|
gravatarUrl: (->
|
||||||
|
"#{location.protocol}//www.gravatar.com/avatar/#{@get('user.gravatarId')}?s=48&d=mm"
|
||||||
|
).property('user.gravatarId')
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
toggleBurgerMenu: ->
|
||||||
|
@toggleProperty('is-open')
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
`export default Controller`
|
10
app/helpers/capitalize.coffee
Normal file
10
app/helpers/capitalize.coffee
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
`import { safe } from 'travis/utils/helpers'`
|
||||||
|
`import Ember from "ember"`
|
||||||
|
|
||||||
|
helper = Ember.Handlebars.makeBoundHelper (value, options) ->
|
||||||
|
if value?
|
||||||
|
safe $.capitalize(value)
|
||||||
|
else
|
||||||
|
''
|
||||||
|
|
||||||
|
`export default helper`
|
18
app/helpers/filter-input.coffee
Normal file
18
app/helpers/filter-input.coffee
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
`import Ember from 'ember'`
|
||||||
|
|
||||||
|
TextField = Ember.TextField.extend
|
||||||
|
keyUp: (event) ->
|
||||||
|
@sendAction('action', @get('_value'), event)
|
||||||
|
|
||||||
|
_elementValueDidChange: ->
|
||||||
|
@set('_value', @$().val());
|
||||||
|
|
||||||
|
fn = (options) ->
|
||||||
|
Ember.assert('You can only pass attributes to the `input` helper, not arguments', arguments.length < 2)
|
||||||
|
|
||||||
|
onEvent = options.hash.on
|
||||||
|
delete options.hash.on
|
||||||
|
options.hash.onEvent = onEvent || 'enter'
|
||||||
|
return Ember.Handlebars.helpers.view.call(this, TextField, options)
|
||||||
|
|
||||||
|
`export default fn`
|
6
app/helpers/format-commit.coffee
Normal file
6
app/helpers/format-commit.coffee
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
`import { safe, formatCommit as formatCommitHelper } from 'travis/utils/helpers'`
|
||||||
|
|
||||||
|
helper = Ember.Handlebars.makeBoundHelper (commit) ->
|
||||||
|
safe formatCommitHelper(commit.get('sha'), commit.get('branch')) if commit
|
||||||
|
|
||||||
|
`export default helper`
|
6
app/helpers/format-config.coffee
Normal file
6
app/helpers/format-config.coffee
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
`import { safe, formatConfig as formatConfigHelper } from 'travis/utils/helpers'`
|
||||||
|
|
||||||
|
formatConfig = (config, options) ->
|
||||||
|
safe formatConfigHelper(config)
|
||||||
|
|
||||||
|
`export default helper`
|
7
app/helpers/format-duration.coffee
Normal file
7
app/helpers/format-duration.coffee
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
`import { timeInWords, safe } from 'travis/utils/helpers'`
|
||||||
|
`import Ember from "ember"`
|
||||||
|
|
||||||
|
helper = Ember.Handlebars.makeBoundHelper (duration, options) ->
|
||||||
|
safe timeInWords(duration)
|
||||||
|
|
||||||
|
`export default helper`
|
7
app/helpers/format-message.coffee
Normal file
7
app/helpers/format-message.coffee
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
`import { formatMessage as _formatMessage, safe } from 'travis/utils/helpers'`
|
||||||
|
`import Ember from "ember"`
|
||||||
|
|
||||||
|
helper = Ember.Handlebars.makeBoundHelper (message, options) ->
|
||||||
|
safe _formatMessage(message, options.hash)
|
||||||
|
|
||||||
|
`export default helper`
|
7
app/helpers/format-sha.coffee
Normal file
7
app/helpers/format-sha.coffee
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
`import { formatSha as _formatSha, safe } from 'travis/utils/helpers'`
|
||||||
|
`import Ember from "ember"`
|
||||||
|
|
||||||
|
helper = Ember.Handlebars.makeBoundHelper (sha) ->
|
||||||
|
safe _formatSha(sha)
|
||||||
|
|
||||||
|
`export default helper`
|
7
app/helpers/format-time.coffee
Normal file
7
app/helpers/format-time.coffee
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
`import { timeAgoInWords, safe } from 'travis/utils/helpers'`
|
||||||
|
`import Ember from "ember"`
|
||||||
|
|
||||||
|
helper = Ember.Handlebars.makeBoundHelper (value, options) ->
|
||||||
|
safe timeAgoInWords(value) || '-'
|
||||||
|
|
||||||
|
`export default helper`
|
12
app/helpers/github-commit-link.coffee
Normal file
12
app/helpers/github-commit-link.coffee
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
`import { formatCommit, safe } from 'travis/utils/helpers'`
|
||||||
|
`import { githubCommit as githubCommitUrl } from 'travis/utils/urls'`
|
||||||
|
|
||||||
|
helper = Ember.Handlebars.makeBoundHelper (slug, commitSha) ->
|
||||||
|
return '' unless commitSha
|
||||||
|
sha = Handlebars.Utils.escapeExpression formatCommit(commitSha)
|
||||||
|
return sha unless slug
|
||||||
|
url = Handlebars.Utils.escapeExpression githubCommitUrl(slug, sha)
|
||||||
|
|
||||||
|
safe '<a class="github-link only-on-hover" href="' + url + '">' + sha + '</a>'
|
||||||
|
|
||||||
|
`export default helper`
|
10
app/helpers/humanize-state.coffee
Normal file
10
app/helpers/humanize-state.coffee
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
`import { safe } from 'travis/utils/helpers'`
|
||||||
|
`import Ember from "ember"`
|
||||||
|
|
||||||
|
helper = Ember.Handlebars.makeBoundHelper (state) ->
|
||||||
|
if state == 'received'
|
||||||
|
'booting'
|
||||||
|
else
|
||||||
|
state
|
||||||
|
|
||||||
|
`export default helper`
|
30
app/helpers/input.coffee
Normal file
30
app/helpers/input.coffee
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
`import Ember from 'ember'`
|
||||||
|
|
||||||
|
originalInputHelper = Ember.Handlebars.helpers.input
|
||||||
|
|
||||||
|
input = (options) ->
|
||||||
|
# for now I can match label only with the property name
|
||||||
|
# passed here matches the label
|
||||||
|
name = (options.hash.value || options.hash.checked)
|
||||||
|
id = options.hash.id
|
||||||
|
|
||||||
|
# generate id only if it's not given
|
||||||
|
if name && !name.match(/\./) && !id
|
||||||
|
labels = @get('_labels')
|
||||||
|
unless labels
|
||||||
|
labels = Ember.Object.create()
|
||||||
|
@set('_labels', labels)
|
||||||
|
|
||||||
|
# for now I support only label + input in their own context
|
||||||
|
id = labels.get(name)
|
||||||
|
unless id
|
||||||
|
id = "#{name}-#{Math.round(Math.random() * 1000000)}"
|
||||||
|
labels.set(name, id)
|
||||||
|
|
||||||
|
options.hash.id = id
|
||||||
|
options.hashTypes.id = 'STRING'
|
||||||
|
options.hashContexts.id = this
|
||||||
|
|
||||||
|
originalInputHelper.call(this, options)
|
||||||
|
|
||||||
|
`export default input`
|
34
app/helpers/label.coffee
Normal file
34
app/helpers/label.coffee
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
`import Ember from 'ember'`
|
||||||
|
|
||||||
|
LabelView = Ember.View.extend(
|
||||||
|
tagName: 'label'
|
||||||
|
|
||||||
|
attributeBindings: ['for', 'accesskey', 'form']
|
||||||
|
classNameBindings: ['class']
|
||||||
|
)
|
||||||
|
|
||||||
|
label = (options) ->
|
||||||
|
view = LabelView
|
||||||
|
|
||||||
|
name = options.hash.for
|
||||||
|
if name
|
||||||
|
labels = @get('_labels')
|
||||||
|
unless labels
|
||||||
|
labels = Ember.Object.create()
|
||||||
|
@set('_labels', labels)
|
||||||
|
|
||||||
|
# for now I support only label + input in their own context
|
||||||
|
id = labels.get(name)
|
||||||
|
unless id
|
||||||
|
id = "#{name}-#{Math.round(Math.random() * 1000000)}"
|
||||||
|
labels.set(name, id)
|
||||||
|
|
||||||
|
options.hash.for = id
|
||||||
|
options.hashTypes.for = 'STRING'
|
||||||
|
options.hashContexts.for = this
|
||||||
|
if options.hash.content
|
||||||
|
view = view.extend(templateName: 'helpers/label')
|
||||||
|
|
||||||
|
Ember.Handlebars.helpers.view.call(this, view, options)
|
||||||
|
|
||||||
|
`export default label`
|
7
app/helpers/mb.coffee
Normal file
7
app/helpers/mb.coffee
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
`import Ember from "ember"`
|
||||||
|
|
||||||
|
fn = (size) ->
|
||||||
|
if size
|
||||||
|
(size / 1024 / 1024).toFixed(2)
|
||||||
|
|
||||||
|
`export default fn`
|
12
app/helpers/short-compare-shas.coffee
Normal file
12
app/helpers/short-compare-shas.coffee
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
`import { pathFrom } from 'travis/utils/helpers'`
|
||||||
|
`import Ember from "ember"`
|
||||||
|
|
||||||
|
helper = Ember.Handlebars.makeBoundHelper (url, options) ->
|
||||||
|
path = pathFrom(url)
|
||||||
|
if path.indexOf('...') >= 0
|
||||||
|
shas = path.split('...')
|
||||||
|
"#{shas[0][0..6]}..#{shas[1][0..6]}"
|
||||||
|
else
|
||||||
|
path
|
||||||
|
|
||||||
|
`export default helper`
|
7
app/helpers/tipsy.coffee
Normal file
7
app/helpers/tipsy.coffee
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
`import { safe } from 'travis/utils/helpers'`
|
||||||
|
`import Ember from "ember"`
|
||||||
|
|
||||||
|
helper = Ember.Handlebars.makeBoundHelper (text, tip) ->
|
||||||
|
safe '<span class="tool-tip" original-title="' + tip + '">' + text + '</span>'
|
||||||
|
|
||||||
|
`export default helper`
|
23
app/helpers/travis-errors.coffee
Normal file
23
app/helpers/travis-errors.coffee
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
`import Ember from 'ember'`
|
||||||
|
|
||||||
|
ErrorsView = Ember.View.extend
|
||||||
|
tagName: 'span'
|
||||||
|
templateName: 'helpers/travis-errors'
|
||||||
|
classNames: ['error']
|
||||||
|
classNameBindings: ['codes', 'show']
|
||||||
|
codes: (->
|
||||||
|
@get('errors').mapBy('code')
|
||||||
|
).property('@errors', 'errors.length')
|
||||||
|
show: Ember.computed.notEmpty('errors.[]')
|
||||||
|
|
||||||
|
fn = (name, options) ->
|
||||||
|
errors = @get('errors').for(name)
|
||||||
|
window[name + 'Errors'] = errors
|
||||||
|
view = ErrorsView.create(
|
||||||
|
controller: this
|
||||||
|
errors: errors
|
||||||
|
)
|
||||||
|
|
||||||
|
Ember.Handlebars.helpers.view.call(this, view, options)
|
||||||
|
|
||||||
|
`export default fn`
|
23
app/helpers/travis-field.coffee
Normal file
23
app/helpers/travis-field.coffee
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
`import Ember from 'ember'`
|
||||||
|
|
||||||
|
FormFieldRowView = Ember.View.extend
|
||||||
|
invalid: Ember.computed.notEmpty('errors.[]')
|
||||||
|
classNameBindings: ['invalid']
|
||||||
|
classNames: 'field'
|
||||||
|
|
||||||
|
fn = (name, options) ->
|
||||||
|
errors = @get('errors').for(name)
|
||||||
|
template = options.fn
|
||||||
|
delete options.fn
|
||||||
|
|
||||||
|
view = FormFieldRowView.create(
|
||||||
|
controller: this
|
||||||
|
template: template
|
||||||
|
errors: errors
|
||||||
|
name: name
|
||||||
|
classNameBindings: ['name']
|
||||||
|
)
|
||||||
|
|
||||||
|
Ember.Handlebars.helpers.view.call(this, view, options)
|
||||||
|
|
||||||
|
`export default fn`
|
26
app/index.html
Normal file
26
app/index.html
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<title>{{title}}</title>
|
||||||
|
<meta name="description" content="">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
|
{{content-for 'head'}}
|
||||||
|
|
||||||
|
<link href='https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,800' rel='stylesheet' type='text/css'>
|
||||||
|
<link rel="stylesheet" href="assets/vendor.css">
|
||||||
|
<link rel="stylesheet" href="assets/travis.css">
|
||||||
|
|
||||||
|
{{content-for 'head-footer'}}
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
{{content-for 'body'}}
|
||||||
|
|
||||||
|
<script src="assets/vendor.js"></script>
|
||||||
|
<script src="assets/travis.js"></script>
|
||||||
|
|
||||||
|
{{content-for 'body-footer'}}
|
||||||
|
</body>
|
||||||
|
</html>
|
10
app/initializers/app.coffee
Normal file
10
app/initializers/app.coffee
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
initialize = (container, app) ->
|
||||||
|
if typeof window != 'undefined'
|
||||||
|
window.Travis = app
|
||||||
|
|
||||||
|
Initializer =
|
||||||
|
name: 'app'
|
||||||
|
initialize: initialize
|
||||||
|
|
||||||
|
`export {initialize}`
|
||||||
|
`export default Initializer`
|
19
app/initializers/auth.coffee
Normal file
19
app/initializers/auth.coffee
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
`import Auth from 'travis/utils/auth'`
|
||||||
|
`import TestAuth from 'travis/utils/test-auth'`
|
||||||
|
|
||||||
|
initialize = (container, app) ->
|
||||||
|
app.register 'auth:main', if Ember.testing then TestAuth else Auth
|
||||||
|
|
||||||
|
app.inject('route', 'auth', 'auth:main')
|
||||||
|
app.inject('controller', 'auth', 'auth:main')
|
||||||
|
app.inject('application', 'auth', 'auth:main')
|
||||||
|
|
||||||
|
app.inject('auth', 'store', 'store:main')
|
||||||
|
|
||||||
|
AuthInitializer =
|
||||||
|
name: 'auth'
|
||||||
|
after: 'ember-data'
|
||||||
|
initialize: initialize
|
||||||
|
|
||||||
|
`export {initialize}`
|
||||||
|
`export default AuthInitializer`
|
16
app/initializers/charm.coffee
Normal file
16
app/initializers/charm.coffee
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
`import config from 'travis/config/environment'`
|
||||||
|
|
||||||
|
initialize = (container, app) ->
|
||||||
|
if config.charmKey
|
||||||
|
window.__CHARM =
|
||||||
|
key: config.charmKey
|
||||||
|
url: "https://charmscout.herokuapp.com/feedback"
|
||||||
|
|
||||||
|
$('head').append $('<script src="https://charmscout.herokuapp.com/charmeur.js?v=2" async defer></script>')
|
||||||
|
|
||||||
|
Initializer =
|
||||||
|
name: 'charm'
|
||||||
|
initialize: initialize
|
||||||
|
|
||||||
|
`export {initialize}`
|
||||||
|
`export default Initializer`
|
14
app/initializers/config.coffee
Normal file
14
app/initializers/config.coffee
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
`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`
|
20
app/initializers/google-analytics.coffee
Normal file
20
app/initializers/google-analytics.coffee
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
`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`
|
11
app/initializers/location.coffee
Normal file
11
app/initializers/location.coffee
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
`import TravisLocation from 'travis/utils/location'`
|
||||||
|
|
||||||
|
initialize = (container, application) ->
|
||||||
|
application.register 'location:travis', TravisLocation
|
||||||
|
|
||||||
|
Initializer =
|
||||||
|
name: 'location'
|
||||||
|
initialize: initialize
|
||||||
|
|
||||||
|
`export { initialize }`
|
||||||
|
`export default Initializer`
|
21
app/initializers/pusher.coffee
Normal file
21
app/initializers/pusher.coffee
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
`import config from 'travis/config/environment'`
|
||||||
|
`import TravisPusher from 'travis/utils/pusher'`
|
||||||
|
|
||||||
|
initialize = (container, application) ->
|
||||||
|
if config.pusher.key
|
||||||
|
application.pusher = new TravisPusher(config.pusher)
|
||||||
|
|
||||||
|
application.register 'pusher:main', application.pusher, { instantiate: false }
|
||||||
|
|
||||||
|
application.inject('route', 'pusher', 'pusher:main')
|
||||||
|
|
||||||
|
application.pusher.store = container.lookup('store:main')
|
||||||
|
|
||||||
|
|
||||||
|
PusherInitializer =
|
||||||
|
name: 'pusher'
|
||||||
|
after: 'ember-data'
|
||||||
|
initialize: initialize
|
||||||
|
|
||||||
|
`export {initialize}`
|
||||||
|
`export default PusherInitializer`
|
19
app/initializers/services.coffee
Normal file
19
app/initializers/services.coffee
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
`import Slider from 'travis/utils/slider'`
|
||||||
|
`import Tailing from 'travis/utils/tailing'`
|
||||||
|
`import ToTop from 'travis/utils/to-top'`
|
||||||
|
`import config from 'travis/config/environment'`
|
||||||
|
|
||||||
|
initialize = (container, application) ->
|
||||||
|
application.slider = new Slider(application.storage)
|
||||||
|
application.tailing = new Tailing($(window), '#tail', '#log')
|
||||||
|
application.toTop = new ToTop($(window), '.to-top', '#log-container')
|
||||||
|
|
||||||
|
application.register 'slider:main', application.slider, { instantiate: false }
|
||||||
|
application.inject('controller', 'slider', 'slider:main')
|
||||||
|
|
||||||
|
Initializer =
|
||||||
|
name: 'services'
|
||||||
|
initialize: initialize
|
||||||
|
|
||||||
|
`export {initialize}`
|
||||||
|
`export default Initializer`
|
58
app/initializers/storage.coffee
Normal file
58
app/initializers/storage.coffee
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
`import Ember from 'ember'`
|
||||||
|
|
||||||
|
Storage = Em.Object.extend
|
||||||
|
init: ->
|
||||||
|
@set('storage', {})
|
||||||
|
key: (key) ->
|
||||||
|
"__#{key.replace('.', '__')}"
|
||||||
|
getItem: (k) ->
|
||||||
|
return @get("storage.#{@key(k)}")
|
||||||
|
setItem: (k,v) ->
|
||||||
|
@set("storage.#{@key(k)}", v)
|
||||||
|
removeItem: (k) ->
|
||||||
|
@setItem(k, null)
|
||||||
|
clear: ->
|
||||||
|
@set('storage', {})
|
||||||
|
|
||||||
|
sessionStorage = (->
|
||||||
|
storage = null
|
||||||
|
try
|
||||||
|
# firefox will not throw error on access for sessionStorage var,
|
||||||
|
# you need to actually get something from session
|
||||||
|
sessionStorage.getItem('foo')
|
||||||
|
storage = sessionStorage
|
||||||
|
catch err
|
||||||
|
storage = Storage.create()
|
||||||
|
|
||||||
|
storage
|
||||||
|
)()
|
||||||
|
|
||||||
|
storage = (->
|
||||||
|
storage = null
|
||||||
|
try
|
||||||
|
storage = window.localStorage || throw('no storage')
|
||||||
|
catch err
|
||||||
|
storage = Storage.create()
|
||||||
|
|
||||||
|
storage
|
||||||
|
)()
|
||||||
|
|
||||||
|
initialize = (container, application) ->
|
||||||
|
application.register 'storage:main', storage, { instantiate: false }
|
||||||
|
application.register 'sessionStorage:main', sessionStorage, { instantiate: false }
|
||||||
|
|
||||||
|
application.inject('auth', 'storage', 'storage:main')
|
||||||
|
application.inject('auth', 'sessionStorage', 'sessionStorage:main')
|
||||||
|
|
||||||
|
# I still use Travis.storage in some places which are not that easy to
|
||||||
|
# refactor
|
||||||
|
application.storage = storage
|
||||||
|
application.sessionStorage = sessionStorage
|
||||||
|
|
||||||
|
StorageInitializer =
|
||||||
|
name: 'storage'
|
||||||
|
before: 'services'
|
||||||
|
initialize: initialize
|
||||||
|
|
||||||
|
`export {initialize}`
|
||||||
|
`export default StorageInitializer`
|
18
app/initializers/stylesheets-manager.coffee
Normal file
18
app/initializers/stylesheets-manager.coffee
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
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`
|
12
app/mixins/github-url-properties.coffee
Normal file
12
app/mixins/github-url-properties.coffee
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
`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`
|
0
app/models/.gitkeep
Normal file
0
app/models/.gitkeep
Normal file
12
app/models/account.coffee
Normal file
12
app/models/account.coffee
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
`import Ember from 'ember'`
|
||||||
|
`import Model from 'travis/models/model'`
|
||||||
|
|
||||||
|
Account = Model.extend
|
||||||
|
name: DS.attr()
|
||||||
|
type: DS.attr()
|
||||||
|
reposCount: DS.attr('number')
|
||||||
|
subscribed: DS.attr('boolean')
|
||||||
|
education: DS.attr('boolean')
|
||||||
|
loginBinding: 'id'
|
||||||
|
|
||||||
|
`export default Account`
|
13
app/models/annotation.coffee
Normal file
13
app/models/annotation.coffee
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
`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`
|
26
app/models/branch.coffee
Normal file
26
app/models/branch.coffee
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
`import Ember from 'ember'`
|
||||||
|
`import Model from 'travis/models/model'`
|
||||||
|
|
||||||
|
Branch = Model.extend
|
||||||
|
repositoryId: DS.attr('number')
|
||||||
|
commitId: DS.attr('number')
|
||||||
|
state: DS.attr()
|
||||||
|
number: DS.attr('number')
|
||||||
|
branch: DS.attr()
|
||||||
|
message: DS.attr()
|
||||||
|
result: DS.attr('number')
|
||||||
|
duration: DS.attr('number')
|
||||||
|
startedAt: DS.attr()
|
||||||
|
finishedAt: DS.attr()
|
||||||
|
|
||||||
|
commit: DS.belongsTo('commit')
|
||||||
|
|
||||||
|
repo: (->
|
||||||
|
@store.find('repo', @get('repositoryId')) if @get('repositoryId')
|
||||||
|
).property('repositoryId')
|
||||||
|
|
||||||
|
updateTimes: ->
|
||||||
|
@notifyPropertyChange 'started_at'
|
||||||
|
@notifyPropertyChange 'finished_at'
|
||||||
|
|
||||||
|
`export default Branch`
|
|
@ -1,27 +1,29 @@
|
||||||
require 'travis/model'
|
`import Ember from 'ember'`
|
||||||
|
`import Model from 'travis/models/model'`
|
||||||
|
|
||||||
@Travis.Broadcast = Travis.Model.extend
|
Broadcast = Model.extend
|
||||||
message: Ember.attr('string')
|
message: DS.attr()
|
||||||
|
|
||||||
toObject: ->
|
toObject: ->
|
||||||
{ type: 'broadcast', id: @get('id'), message: @get('message') }
|
{ type: 'broadcast', id: @get('id'), message: @get('message') }
|
||||||
|
|
||||||
isSeen: (->
|
isSeen: (->
|
||||||
@get('id') in Travis.Broadcast.seen
|
@get('id') in Broadcast.get('seen')
|
||||||
).property()
|
).property()
|
||||||
|
|
||||||
setSeen: ->
|
setSeen: ->
|
||||||
Travis.Broadcast.seen.pushObject(@get('id'))
|
Broadcast.get('seen').pushObject(@get('id'))
|
||||||
Travis.storage.setItem('travis.seen_broadcasts', JSON.stringify(Travis.Broadcast.seen))
|
Travis.storage.setItem('travis.seen_broadcasts', JSON.stringify(Broadcast.get('seen')))
|
||||||
@notifyPropertyChange('isSeen')
|
@notifyPropertyChange('isSeen')
|
||||||
|
|
||||||
@Travis.Broadcast.reopenClass
|
Broadcast.reopenClass
|
||||||
seen: (->
|
seen: (->
|
||||||
seenBroadcasts = Travis.storage.getItem('travis.seen_broadcasts')
|
seenBroadcasts = Travis.storage.getItem('travis.seen_broadcasts')
|
||||||
seenBroadcasts = JSON.parse(seenBroadcasts) if seenBroadcasts?
|
seenBroadcasts = JSON.parse(seenBroadcasts) if seenBroadcasts?
|
||||||
Ember.A(seenBroadcasts || [])
|
Ember.A(seenBroadcasts || [])
|
||||||
)()
|
).property()
|
||||||
|
|
||||||
# TODO fix or monkey-patch the adapter's url and key lookup/generation crap
|
# TODO fix or monkey-patch the adapter's url and key lookup/generation crap
|
||||||
# url: 'users/broadcasts'
|
# url: 'users/broadcasts'
|
||||||
|
|
||||||
|
`export default Broadcast`
|
|
@ -1,32 +1,32 @@
|
||||||
require 'travis/model'
|
`import { durationFrom, configKeys, compact } from 'travis/utils/helpers'`
|
||||||
|
`import Ajax from 'travis/utils/ajax'`
|
||||||
|
`import configKeysMap from 'travis/utils/keys-map'`
|
||||||
|
`import Ember from 'ember'`
|
||||||
|
`import Model from 'travis/models/model'`
|
||||||
|
`import DurationCalculations from 'travis/utils/duration-calculations'`
|
||||||
|
|
||||||
@Travis.Build = Travis.Model.extend Travis.DurationCalculations,
|
Build = Model.extend DurationCalculations,
|
||||||
repositoryId: Ember.attr('number')
|
state: DS.attr()
|
||||||
commitId: Ember.attr('number')
|
number: DS.attr('number')
|
||||||
|
branch: DS.attr('string')
|
||||||
|
message: DS.attr('string')
|
||||||
|
_duration: DS.attr('number')
|
||||||
|
_config: DS.attr('object')
|
||||||
|
_startedAt: DS.attr()
|
||||||
|
_finishedAt: DS.attr()
|
||||||
|
pullRequest: DS.attr('boolean')
|
||||||
|
pullRequestTitle: DS.attr()
|
||||||
|
pullRequestNumber: DS.attr('number')
|
||||||
|
|
||||||
state: Ember.attr('string')
|
repo: DS.belongsTo('repo', async: true)
|
||||||
number: Ember.attr(Number)
|
commit: DS.belongsTo('commit', async: true)
|
||||||
branch: Ember.attr('string')
|
jobs: DS.hasMany('job', async: true)
|
||||||
message: Ember.attr('string')
|
|
||||||
_duration: Ember.attr(Number, key: 'duration')
|
|
||||||
_config: Ember.attr('object', key: 'config')
|
|
||||||
_startedAt: Ember.attr('string', key: 'started_at')
|
|
||||||
_finishedAt: Ember.attr('string', key: 'finished_at')
|
|
||||||
pullRequest: Ember.attr('boolean')
|
|
||||||
pullRequestTitle: Ember.attr('string')
|
|
||||||
pullRequestNumber: Ember.attr(Number)
|
|
||||||
# TODO add eventType to the api for api build requests
|
|
||||||
# eventType: Ember.attr('string')
|
|
||||||
|
|
||||||
repo: Ember.belongsTo('Travis.Repo', key: 'repository_id')
|
|
||||||
commit: Ember.belongsTo('Travis.Commit')
|
|
||||||
jobs: Ember.hasMany('Travis.Job')
|
|
||||||
|
|
||||||
config: (->
|
config: (->
|
||||||
console.log('config')
|
console.log('config')
|
||||||
if config = @get('_config')
|
if config = @get('_config')
|
||||||
Travis.Helpers.compact(config)
|
compact(config)
|
||||||
else
|
else if @get('currentState.stateName') != 'root.loading'
|
||||||
return if @get('isFetchingConfig')
|
return if @get('isFetchingConfig')
|
||||||
@set 'isFetchingConfig', true
|
@set 'isFetchingConfig', true
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ require 'travis/model'
|
||||||
keys = []
|
keys = []
|
||||||
|
|
||||||
@get('jobs').forEach (job) ->
|
@get('jobs').forEach (job) ->
|
||||||
Travis.Helpers.configKeys(job.get('config')).forEach (key) ->
|
configKeys(job.get('config')).forEach (key) ->
|
||||||
keys.pushObject key unless keys.contains key
|
keys.pushObject key unless keys.contains key
|
||||||
|
|
||||||
keys
|
keys
|
||||||
|
@ -85,7 +85,7 @@ require 'travis/model'
|
||||||
configKeys: (->
|
configKeys: (->
|
||||||
keys = @get('rawConfigKeys')
|
keys = @get('rawConfigKeys')
|
||||||
headers = ['Job', 'Duration', 'Finished']
|
headers = ['Job', 'Duration', 'Finished']
|
||||||
$.map(headers.concat(keys), (key) -> if Travis.CONFIG_KEYS_MAP.hasOwnProperty(key) then Travis.CONFIG_KEYS_MAP[key] else key)
|
$.map(headers.concat(keys), (key) -> if configKeysMap.hasOwnProperty(key) then configKeysMap[key] else key)
|
||||||
).property('rawConfigKeys.length')
|
).property('rawConfigKeys.length')
|
||||||
|
|
||||||
canCancel: (->
|
canCancel: (->
|
||||||
|
@ -93,29 +93,15 @@ require 'travis/model'
|
||||||
).property('isFinished', 'jobs.@each.canCancel')
|
).property('isFinished', 'jobs.@each.canCancel')
|
||||||
|
|
||||||
cancel: (->
|
cancel: (->
|
||||||
Travis.ajax.post "/builds/#{@get('id')}/cancel"
|
Ajax.post "/builds/#{@get('id')}/cancel"
|
||||||
)
|
)
|
||||||
|
|
||||||
requeue: ->
|
requeue: ->
|
||||||
Travis.ajax.post "/builds/#{@get('id')}/restart"
|
Ajax.post "/builds/#{@get('id')}/restart"
|
||||||
|
|
||||||
formattedFinishedAt: (->
|
formattedFinishedAt: (->
|
||||||
if finishedAt = @get('finishedAt')
|
if finishedAt = @get('finishedAt')
|
||||||
moment(finishedAt).format('lll')
|
moment(finishedAt).format('lll')
|
||||||
).property('finishedAt')
|
).property('finishedAt')
|
||||||
|
|
||||||
@Travis.Build.reopenClass
|
`export default Build`
|
||||||
byRepoId: (id, parameters) ->
|
|
||||||
@find($.extend(parameters || {}, repository_id: id))
|
|
||||||
|
|
||||||
branches: (options) ->
|
|
||||||
@find repository_id: options.repoId, branches: true
|
|
||||||
|
|
||||||
olderThanNumber: (id, build_number, type) ->
|
|
||||||
console.log type
|
|
||||||
# TODO fix this api and use some kind of pagination scheme
|
|
||||||
options = { repository_id: id, after_number: build_number }
|
|
||||||
if type?
|
|
||||||
options.event_type = type.replace(/s$/, '') # poor man's singularize
|
|
||||||
|
|
||||||
@find(options)
|
|
35
app/models/commit.coffee
Normal file
35
app/models/commit.coffee
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
`import Ember from 'ember'`
|
||||||
|
`import Model from 'travis/models/model'`
|
||||||
|
`import Build from 'travis/models/build'`
|
||||||
|
|
||||||
|
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()
|
||||||
|
|
||||||
|
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')
|
||||||
|
|
||||||
|
`export default Commit`
|
11
app/models/env-var.coffee
Normal file
11
app/models/env-var.coffee
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
`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`
|
34
app/models/hook.coffee
Normal file
34
app/models/hook.coffee
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
`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`
|
|
@ -1,30 +1,36 @@
|
||||||
require 'travis/model'
|
`import { durationFrom, configKeys, compact } from 'travis/utils/helpers'`
|
||||||
|
`import Ajax from 'travis/utils/ajax'`
|
||||||
|
`import configKeysMap from 'travis/utils/keys-map'`
|
||||||
|
`import Ember from 'ember'`
|
||||||
|
`import Model from 'travis/models/model'`
|
||||||
|
`import Log from 'travis/models/log'`
|
||||||
|
`import DurationCalculations from 'travis/utils/duration-calculations'`
|
||||||
|
|
||||||
@Travis.Job = Travis.Model.extend Travis.DurationCalculations,
|
Job = Model.extend DurationCalculations,
|
||||||
repoId: Ember.attr('string', key: 'repository_id')
|
logId: DS.attr()
|
||||||
buildId: Ember.attr('string')
|
|
||||||
commitId: Ember.attr('string')
|
|
||||||
logId: Ember.attr('string')
|
|
||||||
|
|
||||||
queue: Ember.attr('string')
|
queue: DS.attr()
|
||||||
state: Ember.attr('string')
|
state: DS.attr()
|
||||||
number: Ember.attr('string')
|
number: DS.attr()
|
||||||
_startedAt: Ember.attr('string', key: 'started_at')
|
_startedAt: DS.attr()
|
||||||
_finishedAt: Ember.attr('string', key: 'finished_at')
|
_finishedAt: DS.attr()
|
||||||
allowFailure: Ember.attr('boolean')
|
allowFailure: DS.attr('boolean')
|
||||||
|
tags: DS.attr()
|
||||||
|
|
||||||
repositorySlug: Ember.attr('string')
|
repositoryPrivate: DS.attr()
|
||||||
repo: Ember.belongsTo('Travis.Repo', key: 'repository_id')
|
|
||||||
build: Ember.belongsTo('Travis.Build')
|
|
||||||
commit: Ember.belongsTo('Travis.Commit')
|
|
||||||
|
|
||||||
annotations: Ember.hasMany('Travis.Annotation')
|
repositorySlug: DS.attr()
|
||||||
|
repo: DS.belongsTo('repo', async: true)
|
||||||
|
build: DS.belongsTo('build', async: true)
|
||||||
|
commit: DS.belongsTo('commit', async: true)
|
||||||
|
|
||||||
_config: Ember.attr('object', key: 'config')
|
annotations: DS.hasMany('annotation')
|
||||||
|
|
||||||
|
_config: DS.attr('object')
|
||||||
|
|
||||||
log: ( ->
|
log: ( ->
|
||||||
@set('isLogAccessed', true)
|
@set('isLogAccessed', true)
|
||||||
Travis.Log.create(job: this)
|
Log.create(job: this)
|
||||||
).property()
|
).property()
|
||||||
|
|
||||||
startedAt: (->
|
startedAt: (->
|
||||||
|
@ -43,8 +49,8 @@ require 'travis/model'
|
||||||
|
|
||||||
config: (->
|
config: (->
|
||||||
if config = @get('_config')
|
if config = @get('_config')
|
||||||
Travis.Helpers.compact(config)
|
compact(config)
|
||||||
else
|
else if @get('currentState.stateName') != 'root.loading'
|
||||||
return if @get('isFetchingConfig')
|
return if @get('isFetchingConfig')
|
||||||
@set 'isFetchingConfig', true
|
@set 'isFetchingConfig', true
|
||||||
|
|
||||||
|
@ -86,11 +92,11 @@ require 'travis/model'
|
||||||
).property('state')
|
).property('state')
|
||||||
|
|
||||||
cancel: (->
|
cancel: (->
|
||||||
Travis.ajax.post "/jobs/#{@get('id')}/cancel"
|
Ajax.post "/jobs/#{@get('id')}/cancel"
|
||||||
)
|
)
|
||||||
|
|
||||||
removeLog: ->
|
removeLog: ->
|
||||||
Travis.ajax.patch("/jobs/#{@get('id')}/log").then =>
|
Ajax.patch("/jobs/#{@get('id')}/log").then =>
|
||||||
@reloadLog()
|
@reloadLog()
|
||||||
|
|
||||||
reloadLog: ->
|
reloadLog: ->
|
||||||
|
@ -98,7 +104,7 @@ require 'travis/model'
|
||||||
@get('log').fetch()
|
@get('log').fetch()
|
||||||
|
|
||||||
requeue: ->
|
requeue: ->
|
||||||
Travis.ajax.post "/jobs/#{@get('id')}/restart"
|
Ajax.post "/jobs/#{@get('id')}/restart"
|
||||||
|
|
||||||
appendLog: (part) ->
|
appendLog: (part) ->
|
||||||
@get('log').append part
|
@get('log').append part
|
||||||
|
@ -119,10 +125,6 @@ require 'travis/model'
|
||||||
@unsubscribe() if @get('state') == 'finished' && Travis.pusher
|
@unsubscribe() if @get('state') == 'finished' && Travis.pusher
|
||||||
).observes('state')
|
).observes('state')
|
||||||
|
|
||||||
isFinished: (->
|
|
||||||
@get('state') in ['passed', 'failed', 'errored', 'canceled']
|
|
||||||
).property('state')
|
|
||||||
|
|
||||||
# TODO: such formattings should be done in controller, but in order
|
# TODO: such formattings should be done in controller, but in order
|
||||||
# to use it there easily, I would have to refactor job and build
|
# to use it there easily, I would have to refactor job and build
|
||||||
# controllers
|
# controllers
|
||||||
|
@ -139,33 +141,4 @@ require 'travis/model'
|
||||||
"#{@get('repo.slug')} ##{@get('number')}"
|
"#{@get('repo.slug')} ##{@get('number')}"
|
||||||
).property()
|
).property()
|
||||||
|
|
||||||
@Travis.Job.reopenClass
|
`export default Job`
|
||||||
queued: ->
|
|
||||||
filtered = Ember.FilteredRecordArray.create(
|
|
||||||
modelClass: Travis.Job
|
|
||||||
filterFunction: (job) ->
|
|
||||||
['created', 'queued'].indexOf(job.get('state')) != -1
|
|
||||||
filterProperties: ['state', 'queue']
|
|
||||||
)
|
|
||||||
|
|
||||||
@fetch().then (array) ->
|
|
||||||
filtered.updateFilter()
|
|
||||||
filtered.set('isLoaded', true)
|
|
||||||
|
|
||||||
filtered
|
|
||||||
|
|
||||||
running: ->
|
|
||||||
filtered = Ember.FilteredRecordArray.create(
|
|
||||||
modelClass: Travis.Job
|
|
||||||
filterFunction: (job) ->
|
|
||||||
['started', 'received'].indexOf(job.get('state')) != -1
|
|
||||||
filterProperties: ['state']
|
|
||||||
)
|
|
||||||
|
|
||||||
@fetch(state: 'started').then (array) ->
|
|
||||||
filtered.updateFilter()
|
|
||||||
filtered.set('isLoaded', true)
|
|
||||||
|
|
||||||
filtered
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,42 @@
|
||||||
require 'travis/model'
|
`import Model from 'travis/models/model'`
|
||||||
require 'travis/log_chunks'
|
`import Ajax from 'travis/utils/ajax'`
|
||||||
|
`import Job from 'travis/models/job'`
|
||||||
|
`import Ember from 'ember'`
|
||||||
|
`import config from 'travis/config/environment'`
|
||||||
|
|
||||||
@Travis.Log = Em.Object.extend
|
Request = Ember.Object.extend
|
||||||
|
HEADERS:
|
||||||
|
accept: 'application/json; chunked=true; version=2, text/plain; version=2'
|
||||||
|
|
||||||
|
run: ->
|
||||||
|
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
|
version: 0 # used to refresh log on requeue
|
||||||
isLoaded: false
|
isLoaded: false
|
||||||
length: 0
|
length: 0
|
||||||
|
@ -13,7 +48,7 @@ require 'travis/log_chunks'
|
||||||
data['part_numbers'] = partNumbers if partNumbers
|
data['part_numbers'] = partNumbers if partNumbers
|
||||||
data['after'] = after if after
|
data['after'] = after if after
|
||||||
|
|
||||||
Travis.ajax.ajax "/jobs/#{@get('job.id')}/log", 'GET',
|
Ajax.ajax "/jobs/#{@get('job.id')}/log", 'GET',
|
||||||
dataType: 'json'
|
dataType: 'json'
|
||||||
headers:
|
headers:
|
||||||
accept: 'application/json; chunked=true; version=2'
|
accept: 'application/json; chunked=true; version=2'
|
||||||
|
@ -25,7 +60,7 @@ require 'travis/log_chunks'
|
||||||
@append part
|
@append part
|
||||||
|
|
||||||
parts: (->
|
parts: (->
|
||||||
#if Travis.config.pusher_log_fallback
|
#if config.pusher_log_fallback
|
||||||
# Travis.LogChunks.create(content: [], missingPartsCallback: => @fetchMissingParts.apply(this, arguments))
|
# Travis.LogChunks.create(content: [], missingPartsCallback: => @fetchMissingParts.apply(this, arguments))
|
||||||
#else
|
#else
|
||||||
Ember.ArrayProxy.create(content: [])
|
Ember.ArrayProxy.create(content: [])
|
||||||
|
@ -44,7 +79,7 @@ require 'travis/log_chunks'
|
||||||
@set('removed', true)
|
@set('removed', true)
|
||||||
@loadParts(json['log']['parts'])
|
@loadParts(json['log']['parts'])
|
||||||
text: (text) => @loadText(text)
|
text: (text) => @loadText(text)
|
||||||
Travis.Log.Request.create(id: id, handlers: handlers).run() if id = @get('job.id')
|
Request.create(id: id, handlers: handlers, log: this).run() if id = @get('job.id')
|
||||||
|
|
||||||
clear: ->
|
clear: ->
|
||||||
@clearParts()
|
@clearParts()
|
||||||
|
@ -64,34 +99,4 @@ require 'travis/log_chunks'
|
||||||
@append(number: 1, content: text, final: true)
|
@append(number: 1, content: text, final: true)
|
||||||
@set('isLoaded', true)
|
@set('isLoaded', true)
|
||||||
|
|
||||||
Travis.Log.Request = Em.Object.extend
|
`export default Log`
|
||||||
HEADERS:
|
|
||||||
accept: 'application/json; chunked=true; version=2, text/plain; version=2'
|
|
||||||
|
|
||||||
run: ->
|
|
||||||
Travis.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 Travis.config.pro
|
|
||||||
Travis.Job.find(@get('id')).get('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
|
|
3
app/models/model.coffee
Normal file
3
app/models/model.coffee
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
`import DS from 'ember-data';`
|
||||||
|
|
||||||
|
`export default DS.Model.extend();`
|
192
app/models/repo.coffee
Normal file
192
app/models/repo.coffee
Normal file
|
@ -0,0 +1,192 @@
|
||||||
|
`import ExpandableRecordArray from 'travis/utils/expandable-record-array'`
|
||||||
|
`import Model from 'travis/models/model'`
|
||||||
|
`import Ajax from 'travis/utils/ajax'`
|
||||||
|
# TODO: Investigate for some weird reason if I use durationFrom here not durationFromHelper,
|
||||||
|
# the function stops being visible inside computed properties.
|
||||||
|
`import { durationFrom as durationFromHelper } from 'travis/utils/helpers'`
|
||||||
|
`import Build from 'travis/models/build'`
|
||||||
|
|
||||||
|
Repo = Model.extend
|
||||||
|
slug: DS.attr()
|
||||||
|
description: DS.attr()
|
||||||
|
private: DS.attr('boolean')
|
||||||
|
lastBuildNumber: DS.attr('number')
|
||||||
|
lastBuildState: DS.attr()
|
||||||
|
lastBuildStartedAt: DS.attr()
|
||||||
|
lastBuildFinishedAt: DS.attr()
|
||||||
|
githubLanguage: DS.attr()
|
||||||
|
_lastBuildDuration: DS.attr('number')
|
||||||
|
lastBuildLanguage: DS.attr()
|
||||||
|
active: DS.attr()
|
||||||
|
lastBuildId: DS.attr('number')
|
||||||
|
lastBuildHash: (->
|
||||||
|
{
|
||||||
|
id: @get('lastBuildId')
|
||||||
|
number: @get('lastBuildNumber')
|
||||||
|
repo: this
|
||||||
|
}
|
||||||
|
).property('lastBuildId', 'lastBuildNumber')
|
||||||
|
|
||||||
|
lastBuild: (->
|
||||||
|
if id = @get('lastBuildId')
|
||||||
|
@store.find('build', id)
|
||||||
|
@store.recordForId('build', id)
|
||||||
|
).property('lastBuildId')
|
||||||
|
|
||||||
|
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', repository_id: id, (b) ->
|
||||||
|
b.get('repo.id') == id && b.get('eventType') == 'push'
|
||||||
|
)
|
||||||
|
|
||||||
|
# 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.find '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')
|
||||||
|
|
||||||
|
lastBuildDuration: (->
|
||||||
|
duration = @get('_lastBuildDuration')
|
||||||
|
duration = durationFromHelper(@get('lastBuildStartedAt'), @get('lastBuildFinishedAt')) unless duration
|
||||||
|
duration
|
||||||
|
).property('_lastBuildDuration', 'lastBuildStartedAt', 'lastBuildFinishedAt')
|
||||||
|
|
||||||
|
sortOrder: (->
|
||||||
|
# cuz sortAscending seems buggy when set to false
|
||||||
|
if lastBuildFinishedAt = @get('lastBuildFinishedAt')
|
||||||
|
- new Date(lastBuildFinishedAt).getTime()
|
||||||
|
else
|
||||||
|
- new Date('9999').getTime() - parseInt(@get('lastBuildId'))
|
||||||
|
).property('lastBuildFinishedAt', 'lastBuildId')
|
||||||
|
|
||||||
|
stats: (->
|
||||||
|
if @get('slug')
|
||||||
|
@get('_stats') || $.get("https://api.github.com/repos/#{@get('slug')}", (data) =>
|
||||||
|
@set('_stats', data)
|
||||||
|
@notifyPropertyChange 'stats'
|
||||||
|
) && {}
|
||||||
|
).property('slug')
|
||||||
|
|
||||||
|
updateTimes: ->
|
||||||
|
@notifyPropertyChange 'lastBuildDuration'
|
||||||
|
|
||||||
|
regenerateKey: (options) ->
|
||||||
|
Ajax.ajax '/repos/' + @get('id') + '/key', 'post', options
|
||||||
|
|
||||||
|
fetchSettings: ->
|
||||||
|
Ajax.ajax('/repos/' + @get('id') + '/settings', 'get', forceAuth: true).then (data) ->
|
||||||
|
data['settings']
|
||||||
|
|
||||||
|
saveSettings: (settings) ->
|
||||||
|
Ajax.ajax('/repos/' + @get('id') + '/settings', 'patch', data: { settings: settings })
|
||||||
|
|
||||||
|
Repo.reopenClass
|
||||||
|
recent: ->
|
||||||
|
@find()
|
||||||
|
|
||||||
|
accessibleBy: (store, login) ->
|
||||||
|
repos = store.find('repo', { member: login, orderBy: 'name' })
|
||||||
|
|
||||||
|
repos.then () ->
|
||||||
|
repos.set('isLoaded', true)
|
||||||
|
|
||||||
|
repos
|
||||||
|
|
||||||
|
search: (store, query) ->
|
||||||
|
promise = store.find('repo', search: query, orderBy: 'name')
|
||||||
|
result = Ember.ArrayProxy.create(content: [])
|
||||||
|
|
||||||
|
promise.then ->
|
||||||
|
result.pushObjects(promise.get('content').toArray())
|
||||||
|
result.set('isLoaded', true)
|
||||||
|
|
||||||
|
result
|
||||||
|
|
||||||
|
withLastBuild: (store) ->
|
||||||
|
repos = store.filter('repo', {}, (build) ->
|
||||||
|
build.get('lastBuildId')
|
||||||
|
)
|
||||||
|
|
||||||
|
repos.then () ->
|
||||||
|
repos.set('isLoaded', true)
|
||||||
|
|
||||||
|
repos
|
||||||
|
|
||||||
|
bySlug: (store, slug) ->
|
||||||
|
# first check if there is a repo with a given slug already ordered
|
||||||
|
repos = store.all('repo').filterBy('slug', slug)
|
||||||
|
if repos.get('length') > 0
|
||||||
|
repos
|
||||||
|
else
|
||||||
|
store.find('repo', { slug: slug })
|
||||||
|
|
||||||
|
fetchBySlug: (store, slug) ->
|
||||||
|
repos = @bySlug(store, slug)
|
||||||
|
if repos.get('length') > 0
|
||||||
|
repos.get('firstObject')
|
||||||
|
else
|
||||||
|
repos.then (repos) ->
|
||||||
|
error = new Error('repo not found')
|
||||||
|
error.slug = slug
|
||||||
|
Ember.get(repos, 'firstObject') || throw(error)
|
||||||
|
|
||||||
|
# buildURL: (slug) ->
|
||||||
|
# if slug then slug else 'repos'
|
||||||
|
|
||||||
|
`export default Repo`
|
32
app/models/request.coffee
Normal file
32
app/models/request.coffee
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
`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`
|
9
app/models/ssh-key.coffee
Normal file
9
app/models/ssh-key.coffee
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
`import Ember from 'ember'`
|
||||||
|
`import Model from 'travis/models/model'`
|
||||||
|
|
||||||
|
SshKey = Model.extend
|
||||||
|
value: DS.attr()
|
||||||
|
description: DS.attr()
|
||||||
|
fingerprint: DS.attr()
|
||||||
|
|
||||||
|
`export default SshKey`
|
|
@ -1,24 +1,21 @@
|
||||||
require 'travis/ajax'
|
`import Ember from 'ember'`
|
||||||
require 'travis/model'
|
`import Model from 'travis/models/model'`
|
||||||
|
`import Ajax from 'travis/utils/ajax'`
|
||||||
|
`import config from 'travis/config/environment'`
|
||||||
|
|
||||||
@Travis.User = Travis.Model.extend
|
User = Model.extend
|
||||||
_name: Ember.attr('string', key: 'name')
|
name: DS.attr()
|
||||||
email: Ember.attr('string')
|
email: DS.attr()
|
||||||
login: Ember.attr('string')
|
login: DS.attr()
|
||||||
token: Ember.attr('string')
|
token: DS.attr()
|
||||||
gravatarId: Ember.attr('string')
|
gravatarId: DS.attr()
|
||||||
isSyncing: Ember.attr('boolean')
|
isSyncing: DS.attr('boolean')
|
||||||
syncedAt: Ember.attr('string')
|
syncedAt: DS.attr()
|
||||||
repoCount: Ember.attr('number')
|
repoCount: DS.attr('number')
|
||||||
|
|
||||||
# This is the only way I found to override the attribue created with Ember.attr
|
fullName: (->
|
||||||
name: Ember.computed( (key, value) ->
|
@get('name') || @get('login')
|
||||||
if arguments.length == 1
|
).property('name', 'login')
|
||||||
@get('_name') || @get('login')
|
|
||||||
else
|
|
||||||
@set('_name', value)
|
|
||||||
value
|
|
||||||
).property('login', '_name')
|
|
||||||
|
|
||||||
isSyncingDidChange: (->
|
isSyncingDidChange: (->
|
||||||
Ember.run.next this, ->
|
Ember.run.next this, ->
|
||||||
|
@ -26,11 +23,11 @@ require 'travis/model'
|
||||||
).observes('isSyncing')
|
).observes('isSyncing')
|
||||||
|
|
||||||
urlGithub: (->
|
urlGithub: (->
|
||||||
"#{Travis.config.source_endpoint}/#{@get('login')}"
|
"#{config.sourceEndpoint}/#{@get('login')}"
|
||||||
).property()
|
).property()
|
||||||
|
|
||||||
_rawPermissions: (->
|
_rawPermissions: (->
|
||||||
Travis.ajax.get('/users/permissions')
|
Ajax.get('/users/permissions')
|
||||||
).property()
|
).property()
|
||||||
|
|
||||||
permissions: (->
|
permissions: (->
|
||||||
|
@ -63,12 +60,12 @@ require 'travis/model'
|
||||||
|
|
||||||
sync: ->
|
sync: ->
|
||||||
self = this
|
self = this
|
||||||
Travis.ajax.post('/users/sync', {}, ->
|
Ajax.post('/users/sync', {}, ->
|
||||||
self.setWithSession('isSyncing', true)
|
self.setWithSession('isSyncing', true)
|
||||||
)
|
)
|
||||||
|
|
||||||
poll: ->
|
poll: ->
|
||||||
Travis.ajax.get '/users', (data) =>
|
Ajax.get '/users', (data) =>
|
||||||
if data.user.is_syncing
|
if data.user.is_syncing
|
||||||
self = this
|
self = this
|
||||||
setTimeout ->
|
setTimeout ->
|
||||||
|
@ -79,11 +76,12 @@ require 'travis/model'
|
||||||
@setWithSession('syncedAt', data.user.synced_at)
|
@setWithSession('syncedAt', data.user.synced_at)
|
||||||
Travis.trigger('user:synced', data.user)
|
Travis.trigger('user:synced', data.user)
|
||||||
|
|
||||||
# need to pass any param to trigger findQuery
|
@store.findQuery('account', {})
|
||||||
Travis.Account.find(foo: '')
|
|
||||||
|
|
||||||
setWithSession: (name, value) ->
|
setWithSession: (name, value) ->
|
||||||
@set(name, value)
|
@set(name, value)
|
||||||
user = JSON.parse(Travis.sessionStorage.getItem('travis.user'))
|
user = JSON.parse(Travis.sessionStorage.getItem('travis.user'))
|
||||||
user[$.underscore(name)] = @get(name)
|
user[name.underscore()] = @get(name)
|
||||||
Travis.sessionStorage.setItem('travis.user', JSON.stringify(user))
|
Travis.sessionStorage.setItem('travis.user', JSON.stringify(user))
|
||||||
|
|
||||||
|
`export default User`
|
58
app/router.coffee
Normal file
58
app/router.coffee
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
`import Ember from 'ember'`
|
||||||
|
`import config from './config/environment'`
|
||||||
|
`import Location from 'travis/utils/location'`
|
||||||
|
|
||||||
|
Router = Ember.Router.extend
|
||||||
|
# TODO: we should use TravisLocation here
|
||||||
|
location: if Ember.testing then 'none' else 'travis'
|
||||||
|
|
||||||
|
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 'build', path: '/builds/:build_id'
|
||||||
|
@resource 'job', path: '/jobs/:job_id'
|
||||||
|
@resource 'builds', path: '/builds'
|
||||||
|
@resource 'pullRequests', path: '/pull_requests'
|
||||||
|
@resource 'branches', path: '/branches'
|
||||||
|
@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', path: '/auth'
|
||||||
|
|
||||||
|
@resource 'profile', path: '/profile', ->
|
||||||
|
@resource 'accounts', path: '/', ->
|
||||||
|
@resource 'account', path: '/:login'
|
||||||
|
@route 'info', path: '/info'
|
||||||
|
|
||||||
|
@route 'maintenance', path: "/maintenance"
|
||||||
|
@route 'error404', path: "/*path"
|
||||||
|
|
||||||
|
`export default Router`
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user