Compare commits
295 Commits
chrome-for
...
master
Author | SHA1 | Date | |
---|---|---|---|
![]() |
1f5eb7f525 | ||
![]() |
812bf1a4f5 | ||
![]() |
b9688352f4 | ||
![]() |
2701581c12 | ||
![]() |
1ff47c63c4 | ||
![]() |
dbedf34be1 | ||
![]() |
5733d14ae4 | ||
![]() |
4cb225d578 | ||
![]() |
249deb0eff | ||
![]() |
446a9bc9b1 | ||
![]() |
ee4b26a7d7 | ||
![]() |
7601173aaa | ||
![]() |
e74b29c313 | ||
![]() |
eb7a746549 | ||
![]() |
d85469c98e | ||
![]() |
fe8a5a13e1 | ||
![]() |
f8d05dea78 | ||
![]() |
dc34ab38e7 | ||
![]() |
5c3d905424 | ||
![]() |
f00a899e74 | ||
![]() |
1c49615a2d | ||
![]() |
d6c4f1beea | ||
![]() |
f459fed279 | ||
![]() |
8de13d1949 | ||
![]() |
35f9d00a7d | ||
![]() |
17f200081a | ||
![]() |
a17556baf6 | ||
![]() |
575d78e38d | ||
![]() |
d6d1b7c738 | ||
![]() |
3fa2fcea93 | ||
![]() |
67104fc1f1 | ||
![]() |
ebb451d70c | ||
![]() |
e14003eb53 | ||
![]() |
bc8efb758f | ||
![]() |
8cd14b8952 | ||
![]() |
f62143217e | ||
![]() |
2c56238de0 | ||
![]() |
286b59c8ed | ||
![]() |
c5f3cc4873 | ||
![]() |
36e1f9b30e | ||
![]() |
7035b3f763 | ||
![]() |
862b14bad3 | ||
![]() |
38e45810e9 | ||
![]() |
bf636b05f2 | ||
![]() |
fa000b80c9 | ||
![]() |
ae57f3903e | ||
![]() |
6505a058d6 | ||
![]() |
e3efe7d7fc | ||
![]() |
703cdbd598 | ||
![]() |
217618ea71 | ||
![]() |
919857dfad | ||
![]() |
c74fa87016 | ||
![]() |
1cfb9d37be | ||
![]() |
cbd0c46e37 | ||
![]() |
e66efc1cbc | ||
![]() |
71c55779a1 | ||
![]() |
fa62539a40 | ||
![]() |
26ca2875ae | ||
![]() |
65cf81169b | ||
![]() |
2220334265 | ||
![]() |
3618488151 | ||
![]() |
ae8092ddc0 | ||
![]() |
d9c7ada46d | ||
![]() |
e1500d76a1 | ||
![]() |
a940e176e7 | ||
![]() |
381bdc98b5 | ||
![]() |
2c1c1a000e | ||
![]() |
935092c8d7 | ||
![]() |
fdd07e83b4 | ||
![]() |
f482c8be36 | ||
![]() |
b859386fda | ||
![]() |
07d241bdc2 | ||
![]() |
e35e01747a | ||
![]() |
8c374cde93 | ||
![]() |
8fb479c3e0 | ||
![]() |
c65a88a23a | ||
![]() |
521fb30b42 | ||
![]() |
38398588bb | ||
![]() |
79b456e511 | ||
![]() |
c6ec02429d | ||
![]() |
fa7c275eaa | ||
![]() |
bfb1b69374 | ||
![]() |
5dc64c4937 | ||
![]() |
ab0a2af471 | ||
![]() |
7292d6f53e | ||
![]() |
de26ed2091 | ||
![]() |
0dc7e0e045 | ||
![]() |
725d3b00da | ||
![]() |
09637d5e07 | ||
![]() |
7ad66ac83e | ||
![]() |
c31d87871b | ||
![]() |
adb8753b60 | ||
![]() |
a3ce77831d | ||
![]() |
57dec8f2fc | ||
![]() |
df325866f1 | ||
![]() |
20b72e5f10 | ||
![]() |
51f91c3748 | ||
![]() |
0f99defb25 | ||
![]() |
8211dd716a | ||
![]() |
55005b1b13 | ||
![]() |
4fc13503d5 | ||
![]() |
dad5950142 | ||
![]() |
101a0ec71f | ||
![]() |
192ebce0c3 | ||
![]() |
77dcbacd5e | ||
![]() |
3a211b8a73 | ||
![]() |
b0d1ac8463 | ||
![]() |
a09ec1c264 | ||
![]() |
546a678712 | ||
![]() |
645daffd10 | ||
![]() |
e436dbaeac | ||
![]() |
0a5b7465d8 | ||
![]() |
90dc71694e | ||
![]() |
9f636b986c | ||
![]() |
2ae61562ea | ||
![]() |
c118153f2f | ||
![]() |
08bc13aedd | ||
![]() |
f8ce0b494f | ||
![]() |
af4b85ab24 | ||
![]() |
d55147ee04 | ||
![]() |
be6bfda455 | ||
![]() |
ae1719b5f4 | ||
![]() |
a343815476 | ||
![]() |
7a6bb1cdd9 | ||
![]() |
eda72b785c | ||
![]() |
92eec06b6e | ||
![]() |
707c77aeee | ||
![]() |
20e8a47576 | ||
![]() |
238969bc51 | ||
![]() |
a27131015f | ||
![]() |
c65841e7ce | ||
![]() |
24aa541616 | ||
![]() |
1091385aab | ||
![]() |
a6e850ecea | ||
![]() |
9c9f161c26 | ||
![]() |
c07709139c | ||
![]() |
4347c1efe4 | ||
![]() |
9d429966d0 | ||
![]() |
243bd4aed5 | ||
![]() |
38be0fc90c | ||
![]() |
534714e7e9 | ||
![]() |
21cbc96e77 | ||
![]() |
90408dfb47 | ||
![]() |
1d0fb6468e | ||
![]() |
8e610a6191 | ||
![]() |
768963efc6 | ||
![]() |
1b00bc72a1 | ||
![]() |
4443dc9ddd | ||
![]() |
788bcfa0d4 | ||
![]() |
b481946000 | ||
![]() |
3fef8fdd0e | ||
![]() |
1c4f748b2e | ||
![]() |
cd7ab9b719 | ||
![]() |
ac4f5ed193 | ||
![]() |
84e207641e | ||
![]() |
620632500b | ||
![]() |
92896aa8e1 | ||
![]() |
58955469c6 | ||
![]() |
4b9d9fda1e | ||
![]() |
6deae83a1b | ||
![]() |
7764479c14 | ||
![]() |
24465e634f | ||
![]() |
b1aead7577 | ||
![]() |
41884ff9d2 | ||
![]() |
6639a29411 | ||
![]() |
22c938489e | ||
![]() |
c0df9d03e1 | ||
![]() |
84660db9d2 | ||
![]() |
9a9d3805d8 | ||
![]() |
f6d6e9150a | ||
![]() |
5d74d57ac6 | ||
![]() |
4f394ad72e | ||
![]() |
d82ff49359 | ||
![]() |
9cff29ce80 | ||
![]() |
0570a86035 | ||
![]() |
e919906f99 | ||
![]() |
2882c8ca96 | ||
![]() |
069f7ddbeb | ||
![]() |
add716945f | ||
![]() |
5c0697ed85 | ||
![]() |
7cfa83deb8 | ||
![]() |
35961e3c63 | ||
![]() |
3e7a8b694e | ||
![]() |
1fc82577b1 | ||
![]() |
05b85eb37f | ||
![]() |
6efb2ac449 | ||
![]() |
2d0aee4e68 | ||
![]() |
b0df09fb22 | ||
![]() |
4bbf114e82 | ||
![]() |
e1a2f42030 | ||
![]() |
5ddbde82f1 | ||
![]() |
a7e2099829 | ||
![]() |
c70ed06848 | ||
![]() |
557797ab19 | ||
![]() |
0a872e25a7 | ||
![]() |
8eaee33d6d | ||
![]() |
660752ec78 | ||
![]() |
93deb7f4e2 | ||
![]() |
f9dde74f59 | ||
![]() |
0c15a09d54 | ||
![]() |
ed71aa133e | ||
![]() |
efaae492c4 | ||
![]() |
c96a4602cd | ||
![]() |
99b7ce4a9d | ||
![]() |
c694ab24f6 | ||
![]() |
76749e2250 | ||
![]() |
9a7508e25d | ||
![]() |
5163e5129b | ||
![]() |
a63188ae13 | ||
![]() |
34ca0cc386 | ||
![]() |
fb1b820837 | ||
![]() |
ee5f842d51 | ||
![]() |
271b8f89ea | ||
![]() |
13d2eba016 | ||
![]() |
21f25cd2bf | ||
![]() |
c3ef9ac5d9 | ||
![]() |
becde631d5 | ||
![]() |
1c33475ff6 | ||
![]() |
dcac5d4150 | ||
![]() |
ea79bb1625 | ||
![]() |
bd7e4a001d | ||
![]() |
e3b77b4b5a | ||
![]() |
6eed891a1a | ||
![]() |
bbf0b7459f | ||
![]() |
cebaa0e8d1 | ||
![]() |
982d13e897 | ||
![]() |
b8f8071f98 | ||
![]() |
253a56f47d | ||
![]() |
f9df4b1896 | ||
![]() |
85b2837c52 | ||
![]() |
39cf0b3044 | ||
![]() |
4b71704b1c | ||
![]() |
e7ca2c8bfe | ||
![]() |
a920ae9cd7 | ||
![]() |
4e3a755908 | ||
![]() |
a6087d4fcd | ||
![]() |
131a09c9c5 | ||
![]() |
f5823669b2 | ||
![]() |
03332a8654 | ||
![]() |
16da227dd9 | ||
![]() |
bde3b7375a | ||
![]() |
7649c180dd | ||
![]() |
561e671e0d | ||
![]() |
0606aff5b8 | ||
![]() |
e6520ff7cc | ||
![]() |
959da82d91 | ||
![]() |
0b8c032c21 | ||
![]() |
ac7c92d0c4 | ||
![]() |
f349321024 | ||
![]() |
040932d676 | ||
![]() |
b57adacf02 | ||
![]() |
6ee82c0cf8 | ||
![]() |
5bf4e4ffe4 | ||
![]() |
f4aa705b51 | ||
![]() |
341296aaaa | ||
![]() |
01bcfb8a8c | ||
![]() |
493bf72605 | ||
![]() |
1233eba3e8 | ||
![]() |
8d2ca774d0 | ||
![]() |
f445690fb5 | ||
![]() |
10b0c62fc2 | ||
![]() |
8e2b3a86c6 | ||
![]() |
5a0618b22e | ||
![]() |
4edd1feaad | ||
![]() |
f5211f1fdc | ||
![]() |
dbd124852d | ||
![]() |
7aa77b4f6f | ||
![]() |
00d448c231 | ||
![]() |
0813d8cd45 | ||
![]() |
d8160614bf | ||
![]() |
737685a7c0 | ||
![]() |
ece4141cc5 | ||
![]() |
e60b0a0224 | ||
![]() |
fafaf65043 | ||
![]() |
09e4f52dac | ||
![]() |
e27a19101d | ||
![]() |
ab54733723 | ||
![]() |
9e94643dc4 | ||
![]() |
4e720519fe | ||
![]() |
e5763ee2d6 | ||
![]() |
ca3a24e686 | ||
![]() |
ac576077ab | ||
![]() |
b68ae942a6 | ||
![]() |
83bb882475 | ||
![]() |
8abc24f04b | ||
![]() |
573ebfd406 | ||
![]() |
ae704df6bf | ||
![]() |
f6b95a9a9a | ||
![]() |
7f74787b91 | ||
![]() |
f01b95f886 | ||
![]() |
8cf9be6adc | ||
![]() |
a751145fef | ||
![]() |
f9263fc8f3 | ||
![]() |
21285bbe8b | ||
![]() |
6e73923fbb |
11
.jshintrc
11
.jshintrc
|
@ -1,10 +1,19 @@
|
||||||
{
|
{
|
||||||
"predef": [
|
"predef": [
|
||||||
|
"server",
|
||||||
"document",
|
"document",
|
||||||
"window",
|
"window",
|
||||||
"-Promise",
|
"-Promise",
|
||||||
"jQuery",
|
"jQuery",
|
||||||
"Visibility"
|
"Visibility",
|
||||||
|
"$",
|
||||||
|
"Travis",
|
||||||
|
"_cio",
|
||||||
|
"_gaq",
|
||||||
|
"Log",
|
||||||
|
"moment",
|
||||||
|
"Pusher",
|
||||||
|
"md5"
|
||||||
],
|
],
|
||||||
"browser": true,
|
"browser": true,
|
||||||
"boss": true,
|
"boss": true,
|
||||||
|
|
|
@ -39,9 +39,6 @@ install:
|
||||||
- npm install
|
- npm install
|
||||||
- bower install
|
- bower install
|
||||||
|
|
||||||
before_script:
|
|
||||||
- ruby ci/prepare_testem.rb
|
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- ember try $EMBER_VERSION
|
- ember try $EMBER_VERSION
|
||||||
|
|
||||||
|
|
|
@ -65,3 +65,6 @@ DEPENDENCIES
|
||||||
sinatra
|
sinatra
|
||||||
sinatra-contrib
|
sinatra-contrib
|
||||||
travis-web!
|
travis-web!
|
||||||
|
|
||||||
|
BUNDLED WITH
|
||||||
|
1.10.1
|
||||||
|
|
33
README.md
33
README.md
|
@ -18,6 +18,37 @@ And open http://localhost:4200 in the browser.
|
||||||
|
|
||||||
Alternatively you can run `ember build --watch` and start the server with `waiter/script/server`
|
Alternatively you can run `ember build --watch` and start the server with `waiter/script/server`
|
||||||
|
|
||||||
|
### Running the app in private repos mode
|
||||||
|
|
||||||
|
At the moment Travis CI is available as two separate sites - https://travis-ci.org for Open Source
|
||||||
|
projects and https://travis-ci.com for private projects. travis-web will connect
|
||||||
|
to the Open Source version by default. In order to connect it to the API for private projects
|
||||||
|
you need to run:
|
||||||
|
|
||||||
|
```
|
||||||
|
TRAVIS_PRO=true ember serve --ssl --ssl-key=ssl/server.key --ssl-cert=ssl/server.crt
|
||||||
|
```
|
||||||
|
|
||||||
|
One caveat here is that the command will start server with SSL, so the page will
|
||||||
|
be accessible at https://localhost:4200 (note `https` part).
|
||||||
|
|
||||||
|
### Running on SSL in general
|
||||||
|
|
||||||
|
Sometimes there is a need to test the app with an SSL connection. This is required
|
||||||
|
to make Pusher work when running Travis CI Pro, but it may also be needed in other
|
||||||
|
situations.
|
||||||
|
|
||||||
|
There's already an SSL certificate in the `ssl` directory, which is set for `localhost`
|
||||||
|
host. If you want to use it, you can start the server with:
|
||||||
|
|
||||||
|
```
|
||||||
|
ember serve --ssl --ssl-key=ssl/server.key --ssl-cert=ssl/server.crt
|
||||||
|
```
|
||||||
|
|
||||||
|
In case you want your own certificate, you can follow the instructions posted
|
||||||
|
here: https://gist.github.com/trcarden/3295935 and then point the server to your
|
||||||
|
certificate with `--ssl-key` and `--ssl-cert`.
|
||||||
|
|
||||||
### Running tests
|
### Running tests
|
||||||
|
|
||||||
To run a test suite execute:
|
To run a test suite execute:
|
||||||
|
@ -31,7 +62,7 @@ You can also start an interactive test runner for easier development:
|
||||||
|
|
||||||
### Updating the team page
|
### Updating the team page
|
||||||
|
|
||||||
The team information can be found in `app/routes/team.coffee`.
|
The team information can be found in `app/routes/team.js`.
|
||||||
To add another member just add the info in the same style as the previous ones. Like so
|
To add another member just add the info in the same style as the previous ones. Like so
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
Sometimes there is a need to test the app with an SSL connection, for example for
|
|
||||||
testing pusher on Travis CI Pro.
|
|
||||||
|
|
||||||
In order to run the app with SSL enabled you need to:
|
|
||||||
|
|
||||||
* generate self signed certificate as described here: https://gist.github.com/trcarden/3295935
|
|
||||||
* one difference is that you need to use localhost.ssl, because travis-api
|
|
||||||
doesn't whitelist localhost.ssl at the moment
|
|
||||||
* run Ember app with ssl options: `TRAVIS_PRO=true ember serve --ssl --ssl-key=ssl/server.key --ssl-cert=ssl/server.crt`
|
|
|
@ -1,30 +0,0 @@
|
||||||
`import DS from 'ember-data'`
|
|
||||||
`import config from 'travis/config/environment'`
|
|
||||||
|
|
||||||
Adapter = DS.ActiveModelAdapter.extend
|
|
||||||
auth: Ember.inject.service()
|
|
||||||
|
|
||||||
host: config.apiEndpoint
|
|
||||||
coalesceFindRequests: true
|
|
||||||
|
|
||||||
ajaxOptions: (url, type, options) ->
|
|
||||||
hash = @_super(url, type, options)
|
|
||||||
|
|
||||||
hash.headers ||= {}
|
|
||||||
|
|
||||||
hash.headers['accept'] = 'application/json; version=2'
|
|
||||||
|
|
||||||
if token = @get('auth').token()
|
|
||||||
hash.headers['Authorization'] ||= "token #{token}"
|
|
||||||
|
|
||||||
hash
|
|
||||||
|
|
||||||
findMany: (store, type, ids) ->
|
|
||||||
@ajax(@buildURL(type.modelName), 'GET', data: { ids: ids })
|
|
||||||
|
|
||||||
handleResponse: (status, headers, payload) ->
|
|
||||||
if status > 299
|
|
||||||
console.log "[ERROR] API responded with an error (#{status}): #{JSON.stringify(payload)}"
|
|
||||||
return @_super.apply(this, arguments)
|
|
||||||
|
|
||||||
`export default Adapter`
|
|
57
app/adapters/application.js
Normal file
57
app/adapters/application.js
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
import config from 'travis/config/environment';
|
||||||
|
import Ember from 'ember';
|
||||||
|
import ActiveModelAdapter from 'active-model-adapter';
|
||||||
|
|
||||||
|
export default ActiveModelAdapter.extend({
|
||||||
|
auth: Ember.inject.service(),
|
||||||
|
host: config.apiEndpoint,
|
||||||
|
coalesceFindRequests: true,
|
||||||
|
|
||||||
|
// Before Ember Data 2.0 the default behaviour of running `findAll` was to get
|
||||||
|
// new records only when there're no records in the store. This will change
|
||||||
|
// to a different strategy in 2.0: when you run `findAll` it will not get any
|
||||||
|
// new data initially, but it will try loading new data in the background.
|
||||||
|
//
|
||||||
|
// I'm disabling the new behaviour for now.
|
||||||
|
shouldBackgroundReloadRecord() {
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
ajaxOptions(url, type, options) {
|
||||||
|
var base, hash, token;
|
||||||
|
|
||||||
|
hash = this._super(...arguments);
|
||||||
|
hash.headers = hash.headers || {};
|
||||||
|
hash.headers['accept'] = 'application/json; version=2';
|
||||||
|
|
||||||
|
if (token = this.get('auth').token()) {
|
||||||
|
if(!hash.headers['Authorization']) {
|
||||||
|
hash.headers['Authorization'] = "token " + token;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return hash;
|
||||||
|
},
|
||||||
|
|
||||||
|
findMany(store, type, ids) {
|
||||||
|
return this.ajax(this.buildURL(type.modelName), 'GET', {
|
||||||
|
data: {
|
||||||
|
ids: ids
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
handleResponse(status, headers, payload) {
|
||||||
|
if (status > 299) {
|
||||||
|
console.log("[ERROR] API responded with an error (" + status + "): " + (JSON.stringify(payload)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._super(...arguments);
|
||||||
|
},
|
||||||
|
|
||||||
|
// this can be removed once this PR is merged and live:
|
||||||
|
// https://github.com/emberjs/data/pull/4204
|
||||||
|
findRecord(store, type, id, snapshot) {
|
||||||
|
return this.ajax(this.buildURL(type.modelName, id, snapshot, 'findRecord'), 'GET');
|
||||||
|
}
|
||||||
|
});
|
|
@ -1,26 +0,0 @@
|
||||||
`import Ember from 'ember'`
|
|
||||||
`import ApplicationAdapter from 'travis/adapters/application'`
|
|
||||||
|
|
||||||
Adapter = ApplicationAdapter.extend
|
|
||||||
namespace: 'settings'
|
|
||||||
|
|
||||||
buildURL: (type, id, record) ->
|
|
||||||
url = @_super.apply this, arguments
|
|
||||||
|
|
||||||
if record && (repoId = Ember.get(record, 'repo.id'))
|
|
||||||
delimiter = if url.indexOf('?') != -1 then '&' else '?'
|
|
||||||
url = "#{url}#{delimiter}repository_id=#{repoId}"
|
|
||||||
|
|
||||||
url
|
|
||||||
|
|
||||||
updateRecord: (store, type, record) ->
|
|
||||||
data = {};
|
|
||||||
serializer = store.serializerFor(type.typeKey);
|
|
||||||
|
|
||||||
serializer.serializeIntoHash(data, type, record);
|
|
||||||
|
|
||||||
id = Ember.get(record, 'id');
|
|
||||||
|
|
||||||
this.ajax(this.buildURL(type.typeKey, id, record), "PATCH", { data: data })
|
|
||||||
|
|
||||||
`export default Adapter`
|
|
27
app/adapters/env-var.js
Normal file
27
app/adapters/env-var.js
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
import ApplicationAdapter from 'travis/adapters/application';
|
||||||
|
|
||||||
|
export default ApplicationAdapter.extend({
|
||||||
|
namespace: 'settings',
|
||||||
|
|
||||||
|
buildURL(type, id, record) {
|
||||||
|
var delimiter, repoId, url;
|
||||||
|
url = this._super.apply(this, arguments);
|
||||||
|
if (record && record.belongsTo('repo') && (repoId = record.belongsTo('repo').id)) {
|
||||||
|
delimiter = url.indexOf('?') !== -1 ? '&' : '?';
|
||||||
|
url = "" + url + delimiter + "repository_id=" + repoId;
|
||||||
|
}
|
||||||
|
return url;
|
||||||
|
},
|
||||||
|
|
||||||
|
updateRecord(store, type, record) {
|
||||||
|
var data, serializer;
|
||||||
|
data = {};
|
||||||
|
serializer = store.serializerFor(type.modelName);
|
||||||
|
serializer.serializeIntoHash(data, type, record);
|
||||||
|
var id = record.id;
|
||||||
|
return this.ajax(this.buildURL(type.modelName, id, record), "PATCH", {
|
||||||
|
data: data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
|
@ -1,24 +0,0 @@
|
||||||
`import Ember from 'ember'`
|
|
||||||
`import ApplicationAdapter from 'travis/adapters/application'`
|
|
||||||
|
|
||||||
Adapter = ApplicationAdapter.extend
|
|
||||||
namespace: 'settings'
|
|
||||||
|
|
||||||
find: (store, type, id, record) ->
|
|
||||||
@ajax(this.urlPrefix() + '/ssh_key/' + id, 'GET')
|
|
||||||
|
|
||||||
deleteRecord: (store, type, record) ->
|
|
||||||
id = Ember.get(record, 'id')
|
|
||||||
|
|
||||||
@ajax(this.urlPrefix() + '/ssh_key/' + id, "DELETE");
|
|
||||||
|
|
||||||
createRecord: (store, type, record) ->
|
|
||||||
data = {};
|
|
||||||
serializer = store.serializerFor(type.typeKey);
|
|
||||||
serializer.serializeIntoHash(data, type, record, { includeId: true });
|
|
||||||
|
|
||||||
id = Ember.get(record, 'id')
|
|
||||||
|
|
||||||
this.ajax(this.urlPrefix() + '/ssh_key/' + id, "PATCH", { data: data })
|
|
||||||
|
|
||||||
`export default Adapter`
|
|
29
app/adapters/ssh-key.js
Normal file
29
app/adapters/ssh-key.js
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
import ApplicationAdapter from 'travis/adapters/application';
|
||||||
|
|
||||||
|
export default ApplicationAdapter.extend({
|
||||||
|
namespace: 'settings',
|
||||||
|
|
||||||
|
findRecord(store, type, id, record) {
|
||||||
|
return this.ajax(this.urlPrefix() + '/ssh_key/' + id, 'GET');
|
||||||
|
},
|
||||||
|
|
||||||
|
deleteRecord(store, type, record) {
|
||||||
|
var id = record.id;
|
||||||
|
return this.ajax(this.urlPrefix() + '/ssh_key/' + id, "DELETE");
|
||||||
|
},
|
||||||
|
|
||||||
|
createRecord(store, type, record) {
|
||||||
|
var data, serializer;
|
||||||
|
data = {};
|
||||||
|
serializer = store.serializerFor(type.modelName);
|
||||||
|
serializer.serializeIntoHash(data, type, record, {
|
||||||
|
includeId: true
|
||||||
|
});
|
||||||
|
|
||||||
|
var id = record.id;
|
||||||
|
return this.ajax(this.urlPrefix() + '/ssh_key/' + id, "PATCH", {
|
||||||
|
data: data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
|
@ -1,8 +1,8 @@
|
||||||
import Ember from 'ember';
|
import Ember from 'ember';
|
||||||
import DS from 'ember-data';
|
|
||||||
import config from 'travis/config/environment';
|
import config from 'travis/config/environment';
|
||||||
|
import RESTAdapter from 'ember-data/adapters/rest';
|
||||||
|
|
||||||
export default DS.RESTAdapter.extend({
|
export default RESTAdapter.extend({
|
||||||
auth: Ember.inject.service(),
|
auth: Ember.inject.service(),
|
||||||
host: config.apiEndpoint,
|
host: config.apiEndpoint,
|
||||||
|
|
||||||
|
@ -54,5 +54,11 @@ export default DS.RESTAdapter.extend({
|
||||||
pathForType: function(modelName, id) {
|
pathForType: function(modelName, id) {
|
||||||
var underscored = Ember.String.underscore(modelName);
|
var underscored = Ember.String.underscore(modelName);
|
||||||
return id ? underscored : Ember.String.pluralize(underscored);
|
return id ? underscored : Ember.String.pluralize(underscored);
|
||||||
|
},
|
||||||
|
|
||||||
|
// this can be removed once this PR is merged and live:
|
||||||
|
// https://github.com/emberjs/data/pull/4204
|
||||||
|
findRecord(store, type, id, snapshot) {
|
||||||
|
return this.ajax(this.buildURL(type.modelName, id, snapshot, 'findRecord'), 'GET');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
111
app/app.coffee
111
app/app.coffee
|
@ -1,111 +0,0 @@
|
||||||
`import Ember from 'ember'`
|
|
||||||
`import Resolver from 'ember/resolver'`
|
|
||||||
`import loadInitializers from 'ember/load-initializers'`
|
|
||||||
`import config from './config/environment'`
|
|
||||||
|
|
||||||
Ember.MODEL_FACTORY_INJECTIONS = true
|
|
||||||
|
|
||||||
Ember.LinkView.reopen(
|
|
||||||
attributeBindings: ['alt']
|
|
||||||
);
|
|
||||||
|
|
||||||
App = Ember.Application.extend(Ember.Evented,
|
|
||||||
LOG_TRANSITIONS: true
|
|
||||||
LOG_TRANSITIONS_INTERNAL: true
|
|
||||||
LOG_ACTIVE_GENERATION: true
|
|
||||||
LOG_MODULE_RESOLVER: true
|
|
||||||
LOG_VIEW_LOOKUPS: true
|
|
||||||
#LOG_RESOLVER: true
|
|
||||||
|
|
||||||
modulePrefix: config.modulePrefix
|
|
||||||
podModulePrefix: config.podModulePrefix
|
|
||||||
Resolver: Resolver
|
|
||||||
|
|
||||||
lookup: ->
|
|
||||||
@__container__.lookup.apply @__container__, arguments
|
|
||||||
|
|
||||||
flash: (options) ->
|
|
||||||
Travis.lookup('controller:flash').loadFlashes([options])
|
|
||||||
|
|
||||||
toggleSidebar: ->
|
|
||||||
$('body').toggleClass('maximized')
|
|
||||||
# TODO gotta force redraws here :/
|
|
||||||
element = $('<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:refreshed', (user) ->
|
|
||||||
Travis.onUserUpdate(user)
|
|
||||||
|
|
||||||
@on 'user:synced', (user) ->
|
|
||||||
Travis.onUserUpdate(user)
|
|
||||||
|
|
||||||
@on 'user:signed_out', () ->
|
|
||||||
if config.userlike
|
|
||||||
Travis.removeUserlike()
|
|
||||||
|
|
||||||
currentDate: ->
|
|
||||||
new Date()
|
|
||||||
|
|
||||||
onUserUpdate: (user) ->
|
|
||||||
if config.pro
|
|
||||||
@identifyCustomer(user)
|
|
||||||
if config.userlike
|
|
||||||
@setupUserlike(user)
|
|
||||||
|
|
||||||
@subscribePusher(user)
|
|
||||||
|
|
||||||
subscribePusher: (user) ->
|
|
||||||
return unless user.channels
|
|
||||||
channels = user.channels
|
|
||||||
if config.pro
|
|
||||||
channels = channels.map (channel) ->
|
|
||||||
if channel.match /^private-/
|
|
||||||
channel
|
|
||||||
else
|
|
||||||
"private-#{channel}"
|
|
||||||
|
|
||||||
Travis.pusher.subscribeAll(channels)
|
|
||||||
|
|
||||||
setupUserlike: (user) ->
|
|
||||||
|
|
||||||
btn = document.getElementById('userlikeCustomTab')
|
|
||||||
btn.classList.add("logged-in")
|
|
||||||
|
|
||||||
userlikeData = window.userlikeData = {}
|
|
||||||
userlikeData.user = {}
|
|
||||||
|
|
||||||
userlikeData.user.name= user.login;
|
|
||||||
userlikeData.user.email = user.email;
|
|
||||||
|
|
||||||
unless document.getElementById('userlike-script')
|
|
||||||
s = document.createElement('script')
|
|
||||||
s.id = 'userlike-script'
|
|
||||||
s.src = '//userlike-cdn-widgets.s3-eu-west-1.amazonaws.com/0327dbb23382ccbbb91b445b76e8a91d4b37d90ef9f2faf84e11177847ff7bb9.js'
|
|
||||||
document.body.appendChild(s)
|
|
||||||
|
|
||||||
removeUserlike: () ->
|
|
||||||
btn = document.getElementById('userlikeCustomTab')
|
|
||||||
btn.classList.remove("logged-in")
|
|
||||||
|
|
||||||
identifyCustomer: (user) ->
|
|
||||||
if _cio && _cio.identify
|
|
||||||
_cio.identify
|
|
||||||
id: user.id
|
|
||||||
email: user.email
|
|
||||||
name: user.name
|
|
||||||
created_at: (Date.parse(user.created_at) / 1000) || null
|
|
||||||
login: user.login
|
|
||||||
)
|
|
||||||
loadInitializers(App, config.modulePrefix)
|
|
||||||
|
|
||||||
`export default App`
|
|
130
app/app.js
Normal file
130
app/app.js
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
import Resolver from './resolver';
|
||||||
|
import loadInitializers from 'ember-load-initializers';
|
||||||
|
import config from './config/environment';
|
||||||
|
|
||||||
|
Ember.MODEL_FACTORY_INJECTIONS = true;
|
||||||
|
|
||||||
|
Ember.LinkComponent.reopen({
|
||||||
|
attributeBindings: ['alt']
|
||||||
|
});
|
||||||
|
|
||||||
|
var App = Ember.Application.extend(Ember.Evented, {
|
||||||
|
LOG_TRANSITIONS: true,
|
||||||
|
LOG_TRANSITIONS_INTERNAL: true,
|
||||||
|
LOG_ACTIVE_GENERATION: true,
|
||||||
|
LOG_MODULE_RESOLVER: true,
|
||||||
|
LOG_VIEW_LOOKUPS: true,
|
||||||
|
modulePrefix: config.modulePrefix,
|
||||||
|
podModulePrefix: config.podModulePrefix,
|
||||||
|
Resolver: Resolver,
|
||||||
|
|
||||||
|
flash(options) {
|
||||||
|
return Ember.getOwner(Travis).lookup('controller:flash').loadFlashes([options]);
|
||||||
|
},
|
||||||
|
|
||||||
|
toggleSidebar() {
|
||||||
|
var element;
|
||||||
|
$('body').toggleClass('maximized');
|
||||||
|
element = $('<span></span>');
|
||||||
|
$('#top .profile').append(element);
|
||||||
|
Ember.run.later((function() {
|
||||||
|
return element.remove();
|
||||||
|
}), 10);
|
||||||
|
element = $('<span></span>');
|
||||||
|
$('#repo').append(element);
|
||||||
|
return Ember.run.later((function() {
|
||||||
|
return element.remove();
|
||||||
|
}), 10);
|
||||||
|
},
|
||||||
|
|
||||||
|
ready() {
|
||||||
|
if (location.hash.slice(0, 2) === '#!') {
|
||||||
|
location.href = location.href.replace('#!/', '');
|
||||||
|
}
|
||||||
|
this.on('user:signed_in', function(user) {
|
||||||
|
return Travis.onUserUpdate(user);
|
||||||
|
});
|
||||||
|
this.on('user:refreshed', function(user) {
|
||||||
|
return Travis.onUserUpdate(user);
|
||||||
|
});
|
||||||
|
this.on('user:synced', function(user) {
|
||||||
|
return Travis.onUserUpdate(user);
|
||||||
|
});
|
||||||
|
return this.on('user:signed_out', function() {
|
||||||
|
if (config.userlike) {
|
||||||
|
return Travis.removeUserlike();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
currentDate() {
|
||||||
|
return new Date();
|
||||||
|
},
|
||||||
|
|
||||||
|
onUserUpdate(user) {
|
||||||
|
if (config.pro) {
|
||||||
|
this.identifyCustomer(user);
|
||||||
|
}
|
||||||
|
if (config.userlike) {
|
||||||
|
this.setupUserlike(user);
|
||||||
|
}
|
||||||
|
return this.subscribePusher(user);
|
||||||
|
},
|
||||||
|
|
||||||
|
subscribePusher(user) {
|
||||||
|
var channels;
|
||||||
|
if (!user.channels) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
channels = user.channels;
|
||||||
|
if (config.pro) {
|
||||||
|
channels = channels.map(function(channel) {
|
||||||
|
if (channel.match(/^private-/)) {
|
||||||
|
return channel;
|
||||||
|
} else {
|
||||||
|
return "private-" + channel;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return Travis.pusher.subscribeAll(channels);
|
||||||
|
},
|
||||||
|
|
||||||
|
setupUserlike(user) {
|
||||||
|
var btn, s, userlikeData;
|
||||||
|
btn = document.getElementById('userlikeCustomTab');
|
||||||
|
btn.classList.add("logged-in");
|
||||||
|
userlikeData = window.userlikeData = {};
|
||||||
|
userlikeData.user = {};
|
||||||
|
userlikeData.user.name = user.login;
|
||||||
|
userlikeData.user.email = user.email;
|
||||||
|
if (!document.getElementById('userlike-script')) {
|
||||||
|
s = document.createElement('script');
|
||||||
|
s.id = 'userlike-script';
|
||||||
|
s.src = '//userlike-cdn-widgets.s3-eu-west-1.amazonaws.com/0327dbb23382ccbbb91b445b76e8a91d4b37d90ef9f2faf84e11177847ff7bb9.js';
|
||||||
|
return document.body.appendChild(s);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
removeUserlike() {
|
||||||
|
var btn;
|
||||||
|
btn = document.getElementById('userlikeCustomTab');
|
||||||
|
return btn.classList.remove("logged-in");
|
||||||
|
},
|
||||||
|
|
||||||
|
identifyCustomer(user) {
|
||||||
|
if (_cio && _cio.identify) {
|
||||||
|
return _cio.identify({
|
||||||
|
id: user.id,
|
||||||
|
email: user.email,
|
||||||
|
name: user.name,
|
||||||
|
created_at: (Date.parse(user.created_at) / 1000) || null,
|
||||||
|
login: user.login
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
loadInitializers(App, config.modulePrefix);
|
||||||
|
|
||||||
|
export default App;
|
|
@ -1,46 +0,0 @@
|
||||||
`import Ember from 'ember'`
|
|
||||||
|
|
||||||
AddEnvVarComponent = Ember.Component.extend
|
|
||||||
|
|
||||||
classNames: ['form--envvar']
|
|
||||||
classNameBindings: ['nameIsBlank:form-error']
|
|
||||||
|
|
||||||
store: Ember.inject.service()
|
|
||||||
|
|
||||||
isValid: () ->
|
|
||||||
if Ember.isBlank(@get('name'))
|
|
||||||
this.set('nameIsBlank', true)
|
|
||||||
false
|
|
||||||
else
|
|
||||||
true
|
|
||||||
|
|
||||||
reset: ->
|
|
||||||
@setProperties(name: null, value: null, public: null)
|
|
||||||
|
|
||||||
actions:
|
|
||||||
save: ->
|
|
||||||
return if @get('isSaving')
|
|
||||||
@set('isSaving', true)
|
|
||||||
|
|
||||||
if @isValid()
|
|
||||||
env_var = @get('store').createRecord('env_var',
|
|
||||||
name: @get('name')
|
|
||||||
value: @get('value')
|
|
||||||
public: @get('public')
|
|
||||||
repo: @get('repo')
|
|
||||||
)
|
|
||||||
|
|
||||||
self = this
|
|
||||||
env_var.save().then =>
|
|
||||||
@set('isSaving', false)
|
|
||||||
@reset()
|
|
||||||
, =>
|
|
||||||
@set('isSaving', false)
|
|
||||||
else
|
|
||||||
@set('isSaving', false)
|
|
||||||
|
|
||||||
nameChanged: ->
|
|
||||||
this.set('nameIsBlank', false)
|
|
||||||
|
|
||||||
|
|
||||||
`export default AddEnvVarComponent`
|
|
55
app/components/add-env-var.js
Normal file
55
app/components/add-env-var.js
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
classNames: ['form--envvar'],
|
||||||
|
classNameBindings: ['nameIsBlank:form-error'],
|
||||||
|
store: Ember.inject.service(),
|
||||||
|
|
||||||
|
isValid() {
|
||||||
|
if (Ember.isBlank(this.get('name'))) {
|
||||||
|
this.set('nameIsBlank', true);
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
reset() {
|
||||||
|
return this.setProperties({
|
||||||
|
name: null,
|
||||||
|
value: null,
|
||||||
|
"public": null
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
save() {
|
||||||
|
var env_var, self;
|
||||||
|
if (this.get('isSaving')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.set('isSaving', true);
|
||||||
|
if (this.isValid()) {
|
||||||
|
env_var = this.get('store').createRecord('env_var', {
|
||||||
|
name: this.get('name'),
|
||||||
|
value: this.get('value'),
|
||||||
|
"public": this.get('public'),
|
||||||
|
repo: this.get('repo')
|
||||||
|
});
|
||||||
|
self = this;
|
||||||
|
return env_var.save().then(() => {
|
||||||
|
this.set('isSaving', false);
|
||||||
|
return this.reset();
|
||||||
|
}, () => {
|
||||||
|
return this.set('isSaving', false);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return this.set('isSaving', false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
nameChanged() {
|
||||||
|
return this.set('nameIsBlank', false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
|
@ -1,73 +0,0 @@
|
||||||
# `import Ember from 'ember'`
|
|
||||||
|
|
||||||
AddSshKeyComponent = Ember.Component.extend
|
|
||||||
|
|
||||||
classNames: ['form--sshkey']
|
|
||||||
classNameBindings: ['valueError:form-error']
|
|
||||||
|
|
||||||
store: Ember.inject.service()
|
|
||||||
isSaving: false
|
|
||||||
|
|
||||||
didInsertElement: () ->
|
|
||||||
id = @get('repo.id')
|
|
||||||
model = @get('store').recordForId('ssh_key', id)
|
|
||||||
# TODO: this can be removed in favor of simply unloading record
|
|
||||||
# once https://github.com/emberjs/data/pull/2867
|
|
||||||
# and https://github.com/emberjs/data/pull/2870 are merged
|
|
||||||
if model
|
|
||||||
@get('store').dematerializeRecord(model._internalModel)
|
|
||||||
typeMap = @get('store').typeMapFor(model.constructor)
|
|
||||||
idToRecord = typeMap.idToRecord
|
|
||||||
delete idToRecord[id]
|
|
||||||
|
|
||||||
model = @get('store').createRecord('ssh_key', id: id)
|
|
||||||
@set('model', model)
|
|
||||||
|
|
||||||
isValid: () ->
|
|
||||||
if Ember.isBlank(@get('value'))
|
|
||||||
this.set('valueError', 'Value can\'t be blank.')
|
|
||||||
false
|
|
||||||
else
|
|
||||||
true
|
|
||||||
|
|
||||||
reset: ->
|
|
||||||
@setProperties(description: null, value: null)
|
|
||||||
|
|
||||||
valueChanged: (->
|
|
||||||
this.set('valueError', false)
|
|
||||||
).observes('value')
|
|
||||||
|
|
||||||
addErrorsFromResponse: (errArr) ->
|
|
||||||
error = errArr[0].detail
|
|
||||||
if error.code == 'not_a_private_key'
|
|
||||||
this.set('valueError', 'This key is not a private key.')
|
|
||||||
else if error.code == 'key_with_a_passphrase'
|
|
||||||
this.set('valueError', 'The key can\'t have a passphrase.')
|
|
||||||
|
|
||||||
actions:
|
|
||||||
|
|
||||||
save: ->
|
|
||||||
this.set('valueError', false)
|
|
||||||
return if @get('isSaving')
|
|
||||||
@set('isSaving', true)
|
|
||||||
if @isValid()
|
|
||||||
|
|
||||||
ssh_key = @get('model').setProperties(
|
|
||||||
description: @get('description')
|
|
||||||
value: @get('value')
|
|
||||||
)
|
|
||||||
|
|
||||||
ssh_key.save().then =>
|
|
||||||
@set('isSaving', false)
|
|
||||||
@reset()
|
|
||||||
|
|
||||||
@sendAction('sshKeyAdded', ssh_key)
|
|
||||||
, (error) =>
|
|
||||||
@set('isSaving', false)
|
|
||||||
if error.errors
|
|
||||||
@addErrorsFromResponse(error.errors)
|
|
||||||
|
|
||||||
else
|
|
||||||
@set('isSaving', false)
|
|
||||||
|
|
||||||
`export default AddSshKeyComponent`
|
|
85
app/components/add-ssh-key.js
Normal file
85
app/components/add-ssh-key.js
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
classNames: ['form--sshkey'],
|
||||||
|
classNameBindings: ['valueError:form-error'],
|
||||||
|
store: Ember.inject.service(),
|
||||||
|
isSaving: false,
|
||||||
|
|
||||||
|
didInsertElement() {
|
||||||
|
var id = this.get('repo.id');
|
||||||
|
var model = this.get('store').recordForId('ssh_key', id);
|
||||||
|
|
||||||
|
if (model) {
|
||||||
|
this.get('store').unloadRecord(model);
|
||||||
|
var typeMap = this.get('store').typeMapFor(model.constructor);
|
||||||
|
var idToRecord = typeMap.idToRecord;
|
||||||
|
delete idToRecord[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
model = this.get('store').createRecord('ssh_key', { id: id });
|
||||||
|
|
||||||
|
return this.set('model', model);
|
||||||
|
},
|
||||||
|
|
||||||
|
isValid() {
|
||||||
|
if (Ember.isBlank(this.get('value'))) {
|
||||||
|
this.set('valueError', 'Value can\'t be blank.');
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
reset() {
|
||||||
|
return this.setProperties({
|
||||||
|
description: null,
|
||||||
|
value: null
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
valueChanged: function() {
|
||||||
|
return this.set('valueError', false);
|
||||||
|
}.observes('value'),
|
||||||
|
|
||||||
|
addErrorsFromResponse(errArr) {
|
||||||
|
var error = errArr[0].detail;
|
||||||
|
|
||||||
|
if (error.code === 'not_a_private_key') {
|
||||||
|
return this.set('valueError', 'This key is not a private key.');
|
||||||
|
} else if (error.code === 'key_with_a_passphrase') {
|
||||||
|
return this.set('valueError', 'The key can\'t have a passphrase.');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
save() {
|
||||||
|
var ssh_key;
|
||||||
|
|
||||||
|
this.set('valueError', false);
|
||||||
|
if (this.get('isSaving')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.set('isSaving', true);
|
||||||
|
if (this.isValid()) {
|
||||||
|
ssh_key = this.get('model');
|
||||||
|
ssh_key.setProperties({
|
||||||
|
description: this.get('description'),
|
||||||
|
value: this.get('value')
|
||||||
|
});
|
||||||
|
return ssh_key.save().then(() => {
|
||||||
|
this.set('isSaving', false);
|
||||||
|
this.reset();
|
||||||
|
return this.sendAction('sshKeyAdded', ssh_key);
|
||||||
|
}, (error) => {
|
||||||
|
this.set('isSaving', false);
|
||||||
|
if (error.errors) {
|
||||||
|
return this.addErrorsFromResponse(error.errors);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return this.set('isSaving', false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
|
@ -1,91 +0,0 @@
|
||||||
`import Ember from 'ember'`
|
|
||||||
`import { gravatarImage } from 'travis/utils/urls'`
|
|
||||||
`import { githubCommit as githubCommitUrl } from 'travis/utils/urls'`
|
|
||||||
`import TravisRoute from 'travis/routes/basic'`
|
|
||||||
`import config from 'travis/config/environment'`
|
|
||||||
|
|
||||||
BranchRowComponent = Ember.Component.extend
|
|
||||||
routing: Ember.inject.service('-routing')
|
|
||||||
tagName: 'li'
|
|
||||||
classNameBindings: ['build.last_build.state']
|
|
||||||
classNames: ['branch-row', 'row-li']
|
|
||||||
isLoading: false
|
|
||||||
isTriggering: false
|
|
||||||
hasTriggered: false
|
|
||||||
|
|
||||||
urlGithubCommit: (->
|
|
||||||
githubCommitUrl(@get('build.repository.slug'), @get('build.last_build.commit.sha'))
|
|
||||||
).property('build.last_build')
|
|
||||||
|
|
||||||
getLast5Builds: (->
|
|
||||||
|
|
||||||
lastBuilds = Ember.ArrayProxy.create(
|
|
||||||
content: [{}, {}, {}, {}, {}]
|
|
||||||
isLoading: true,
|
|
||||||
count: 0
|
|
||||||
)
|
|
||||||
|
|
||||||
if !@get('build.last_build')
|
|
||||||
lastBuilds.set('isLoading', false)
|
|
||||||
else
|
|
||||||
apiEndpoint = config.apiEndpoint
|
|
||||||
repoId = @get('build.repository.id')
|
|
||||||
branchName = @get('build.name')
|
|
||||||
|
|
||||||
options = {}
|
|
||||||
if @get('auth.signedIn')
|
|
||||||
options.headers = { Authorization: "token #{@auth.token()}" }
|
|
||||||
|
|
||||||
$.ajax("#{apiEndpoint}/v3/repo/#{repoId}/builds?branch.name=#{branchName}&limit=5&build.event_type=push,api", options).then (response) ->
|
|
||||||
array = response.builds.map( (build) ->
|
|
||||||
Ember.Object.create(build)
|
|
||||||
)
|
|
||||||
if array.length < 5
|
|
||||||
for i in [1..5 - array.length] by 1
|
|
||||||
array.push({})
|
|
||||||
|
|
||||||
lastBuilds.set('count', response['@pagination'].count)
|
|
||||||
lastBuilds.set('content', array)
|
|
||||||
lastBuilds.set('isLoading', false)
|
|
||||||
|
|
||||||
lastBuilds
|
|
||||||
).property()
|
|
||||||
|
|
||||||
canTrigger: (->
|
|
||||||
if !@get('auth.signedIn')
|
|
||||||
false
|
|
||||||
else
|
|
||||||
permissions = @get('auth.currentUser.permissions')
|
|
||||||
if permissions.contains parseInt(@get('build.repository.id'))
|
|
||||||
true
|
|
||||||
else
|
|
||||||
false
|
|
||||||
).property()
|
|
||||||
|
|
||||||
triggerBuild: (->
|
|
||||||
apiEndpoint = config.apiEndpoint
|
|
||||||
repoId = @get('build.repository.id')
|
|
||||||
options = {
|
|
||||||
type: 'POST',
|
|
||||||
body: {
|
|
||||||
request: {
|
|
||||||
branch: @get('build.name')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if @get('auth.signedIn')
|
|
||||||
options.headers = { Authorization: "token #{@auth.token()}" }
|
|
||||||
$.ajax("#{apiEndpoint}/v3/repo/#{repoId}/requests", options).then (response) =>
|
|
||||||
@set('isTriggering', false)
|
|
||||||
@set('hasTriggered', true)
|
|
||||||
)
|
|
||||||
|
|
||||||
actions:
|
|
||||||
tiggerBuild: (branch) ->
|
|
||||||
@set('isTriggering', true)
|
|
||||||
@triggerBuild()
|
|
||||||
|
|
||||||
viewAllBuilds: (branch) ->
|
|
||||||
@get('routing').transitionTo('builds')
|
|
||||||
|
|
||||||
`export default BranchRowComponent`
|
|
103
app/components/branch-row.js
Normal file
103
app/components/branch-row.js
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
import { githubCommit as githubCommitUrl } from 'travis/utils/urls';
|
||||||
|
import TravisRoute from 'travis/routes/basic';
|
||||||
|
import config from 'travis/config/environment';
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
routing: Ember.inject.service('-routing'),
|
||||||
|
tagName: 'li',
|
||||||
|
classNameBindings: ['build.last_build.state'],
|
||||||
|
classNames: ['branch-row', 'row-li'],
|
||||||
|
isLoading: false,
|
||||||
|
isTriggering: false,
|
||||||
|
hasTriggered: false,
|
||||||
|
|
||||||
|
urlGithubCommit: function() {
|
||||||
|
return githubCommitUrl(this.get('build.repository.slug'), this.get('build.last_build.commit.sha'));
|
||||||
|
}.property('build.last_build'),
|
||||||
|
|
||||||
|
getLast5Builds: function() {
|
||||||
|
var apiEndpoint, branchName, lastBuilds, options, repoId;
|
||||||
|
lastBuilds = Ember.ArrayProxy.create({
|
||||||
|
content: [{}, {}, {}, {}, {}],
|
||||||
|
isLoading: true,
|
||||||
|
count: 0
|
||||||
|
});
|
||||||
|
if (!this.get('build.last_build')) {
|
||||||
|
lastBuilds.set('isLoading', false);
|
||||||
|
} else {
|
||||||
|
apiEndpoint = config.apiEndpoint;
|
||||||
|
repoId = this.get('build.repository.id');
|
||||||
|
branchName = this.get('build.name');
|
||||||
|
options = {};
|
||||||
|
if (this.get('auth.signedIn')) {
|
||||||
|
options.headers = {
|
||||||
|
Authorization: "token " + (this.auth.token())
|
||||||
|
};
|
||||||
|
}
|
||||||
|
$.ajax(apiEndpoint + "/v3/repo/" + repoId + "/builds?branch.name=" + branchName + "&limit=5&build.event_type=push,api", options).then(function(response) {
|
||||||
|
var array, i, j, ref;
|
||||||
|
array = response.builds.map(function(build) {
|
||||||
|
return Ember.Object.create(build);
|
||||||
|
});
|
||||||
|
if (array.length < 5) {
|
||||||
|
for (i = j = 1, ref = 5 - array.length; j <= ref; i = j += 1) {
|
||||||
|
array.push({});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lastBuilds.set('count', response['@pagination'].count);
|
||||||
|
lastBuilds.set('content', array);
|
||||||
|
return lastBuilds.set('isLoading', false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return lastBuilds;
|
||||||
|
}.property(),
|
||||||
|
|
||||||
|
canTrigger: function() {
|
||||||
|
var permissions;
|
||||||
|
if (!this.get('auth.signedIn')) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
permissions = this.get('auth.currentUser.permissions');
|
||||||
|
if (permissions.contains(parseInt(this.get('build.repository.id')))) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.property(),
|
||||||
|
|
||||||
|
triggerBuild: function() {
|
||||||
|
var apiEndpoint, options, repoId;
|
||||||
|
apiEndpoint = config.apiEndpoint;
|
||||||
|
repoId = this.get('build.repository.id');
|
||||||
|
options = {
|
||||||
|
type: 'POST',
|
||||||
|
body: {
|
||||||
|
request: {
|
||||||
|
branch: this.get('build.name')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (this.get('auth.signedIn')) {
|
||||||
|
options.headers = {
|
||||||
|
Authorization: "token " + (this.auth.token())
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return $.ajax(apiEndpoint + "/v3/repo/" + repoId + "/requests", options).then(() => {
|
||||||
|
this.set('isTriggering', false);
|
||||||
|
return this.set('hasTriggered', true);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
tiggerBuild(branch) {
|
||||||
|
this.set('isTriggering', true);
|
||||||
|
return this.triggerBuild();
|
||||||
|
},
|
||||||
|
|
||||||
|
viewAllBuilds(branch) {
|
||||||
|
return this.get('routing').transitionTo('builds');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
|
@ -1,24 +0,0 @@
|
||||||
`import Ember from 'ember'`
|
|
||||||
|
|
||||||
BroadcastTowerComponent = Ember.Component.extend
|
|
||||||
|
|
||||||
classNames: ['broadcast']
|
|
||||||
|
|
||||||
isOpen: false
|
|
||||||
timeoutId: ''
|
|
||||||
|
|
||||||
actions:
|
|
||||||
toggleBroadcasts:() ->
|
|
||||||
@toggleProperty('isOpen')
|
|
||||||
@sendAction('toggleBroadcasts')
|
|
||||||
|
|
||||||
if @get('isOpen') == true
|
|
||||||
@set('timeoutId', setTimeout =>
|
|
||||||
@toggleProperty('isOpen')
|
|
||||||
@sendAction('toggleBroadcasts')
|
|
||||||
, 10000
|
|
||||||
)
|
|
||||||
else
|
|
||||||
clearTimeout(@get('timeoutId'))
|
|
||||||
|
|
||||||
`export default BroadcastTowerComponent`
|
|
21
app/components/broadcast-tower.js
Normal file
21
app/components/broadcast-tower.js
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
classNames: ['broadcast'],
|
||||||
|
isOpen: false,
|
||||||
|
timeoutId: '',
|
||||||
|
actions: {
|
||||||
|
toggleBroadcasts() {
|
||||||
|
this.toggleProperty('isOpen');
|
||||||
|
this.sendAction('toggleBroadcasts');
|
||||||
|
if (this.get('isOpen') === true) {
|
||||||
|
return this.set('timeoutId', setTimeout(() => {
|
||||||
|
this.toggleProperty('isOpen');
|
||||||
|
return this.sendAction('toggleBroadcasts');
|
||||||
|
}, 10000));
|
||||||
|
} else {
|
||||||
|
return clearTimeout(this.get('timeoutId'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
|
@ -1,41 +0,0 @@
|
||||||
`import Ember from 'ember'`
|
|
||||||
`import { gravatarImage } from 'travis/utils/urls'`
|
|
||||||
`import GithubUrlPropertievs from 'travis/mixins/github-url-properties'`
|
|
||||||
`import { durationFrom, safe } from 'travis/utils/helpers'`
|
|
||||||
`import { githubCommit } from 'travis/utils/urls'`
|
|
||||||
|
|
||||||
BuildHeaderComponent = Ember.Component.extend
|
|
||||||
|
|
||||||
tagName: 'section'
|
|
||||||
classNames: ['build-header']
|
|
||||||
classNameBindings: ['item.state']
|
|
||||||
|
|
||||||
committerAvatarUrl: (->
|
|
||||||
if url = @get('commit.committerAvatarUrl')
|
|
||||||
url
|
|
||||||
else
|
|
||||||
email = @get('commit.committerEmail')
|
|
||||||
gravatarImage(email, 40)
|
|
||||||
).property('commit.committerEmail', 'commit.committerAvatarUrl')
|
|
||||||
|
|
||||||
authorAvatarUrl: (->
|
|
||||||
if url = @get('commit.authorAvatarUrl')
|
|
||||||
url
|
|
||||||
else
|
|
||||||
email = @get('commit.authorEmail')
|
|
||||||
gravatarImage(email, 40)
|
|
||||||
).property('commit.authorEmail', 'commit.authorAvatarUrl')
|
|
||||||
|
|
||||||
isJob: (->
|
|
||||||
if @get('item.build') then true else false
|
|
||||||
).property('item')
|
|
||||||
|
|
||||||
urlGithubCommit: (->
|
|
||||||
githubCommit(@get('repo.slug'), @get('commit.sha'))
|
|
||||||
).property('item')
|
|
||||||
|
|
||||||
elapsedTime: (->
|
|
||||||
durationFrom(@get('item.startedAt'), @get('item.finishedAt'))
|
|
||||||
).property('item.startedAt', 'item.finishedAt', 'item.duration')
|
|
||||||
|
|
||||||
`export default BuildHeaderComponent`
|
|
27
app/components/build-header.js
Normal file
27
app/components/build-header.js
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
import { gravatarImage } from 'travis/utils/urls';
|
||||||
|
import GithubUrlProperties from 'travis/mixins/github-url-properties';
|
||||||
|
import { durationFrom, safe } from 'travis/utils/helpers';
|
||||||
|
import { githubCommit } from 'travis/utils/urls';
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
tagName: 'section',
|
||||||
|
classNames: ['build-header'],
|
||||||
|
classNameBindings: ['item.state'],
|
||||||
|
|
||||||
|
isJob: function() {
|
||||||
|
if (this.get('item.build')) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}.property('item'),
|
||||||
|
|
||||||
|
urlGithubCommit: function() {
|
||||||
|
return githubCommit(this.get('repo.slug'), this.get('commit.sha'));
|
||||||
|
}.property('item'),
|
||||||
|
|
||||||
|
elapsedTime: function() {
|
||||||
|
return durationFrom(this.get('item.startedAt'), this.get('item.finishedAt'));
|
||||||
|
}.property('item.startedAt', 'item.finishedAt', 'item.duration')
|
||||||
|
});
|
|
@ -1,9 +0,0 @@
|
||||||
`import Ember from 'ember'`
|
|
||||||
`import RepoActionsItemComponentMixin from 'travis/utils/repo-actions-item-component-mixin'`
|
|
||||||
|
|
||||||
BuildRepoActionsComponent = Ember.Component.extend(RepoActionsItemComponentMixin,
|
|
||||||
item: Ember.computed.alias('build')
|
|
||||||
type: 'build'
|
|
||||||
)
|
|
||||||
|
|
||||||
`export default BuildRepoActionsComponent`
|
|
7
app/components/build-repo-actions.js
Normal file
7
app/components/build-repo-actions.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
import RepoActionsItemComponentMixin from 'travis/utils/repo-actions-item-component-mixin';
|
||||||
|
|
||||||
|
export default Ember.Component.extend(RepoActionsItemComponentMixin, {
|
||||||
|
item: Ember.computed.alias('build'),
|
||||||
|
type: 'build'
|
||||||
|
});
|
|
@ -1,14 +0,0 @@
|
||||||
`import Ember from 'ember'`
|
|
||||||
|
|
||||||
BuildTileComponent = Ember.Component.extend
|
|
||||||
|
|
||||||
tagName: 'li'
|
|
||||||
classNameBindings: ['build.state']
|
|
||||||
attributeBindings: ['title'],
|
|
||||||
|
|
||||||
title: (->
|
|
||||||
num = @get('build.number')
|
|
||||||
"##{num}"
|
|
||||||
).property('build')
|
|
||||||
|
|
||||||
`export default BuildTileComponent`
|
|
14
app/components/build-tile.js
Normal file
14
app/components/build-tile.js
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
tagName: 'li',
|
||||||
|
classNameBindings: ['build.state'],
|
||||||
|
attributeBindings: ['title'],
|
||||||
|
|
||||||
|
title: function() {
|
||||||
|
var num, state;
|
||||||
|
num = this.get('build.number');
|
||||||
|
state = this.get('build.state');
|
||||||
|
return "Build #" + num + " " + state;
|
||||||
|
}.property('build')
|
||||||
|
});
|
12
app/components/build-wrapper.js
Normal file
12
app/components/build-wrapper.js
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
import { colorForState } from 'travis/utils/helpers';
|
||||||
|
import Polling from 'travis/mixins/polling';
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
classNameBindings: ['color'],
|
||||||
|
pollModels: 'build',
|
||||||
|
|
||||||
|
color: function() {
|
||||||
|
return colorForState(this.get('build.state'));
|
||||||
|
}.property('build.state')
|
||||||
|
});
|
|
@ -1,22 +0,0 @@
|
||||||
`import Ember from 'ember'`
|
|
||||||
`import { gravatarImage } from 'travis/utils/urls'`
|
|
||||||
`import { githubCommit as githubCommitUrl } from 'travis/utils/urls'`
|
|
||||||
|
|
||||||
BuildsItemComponent = Ember.Component.extend
|
|
||||||
tagName: 'li'
|
|
||||||
classNameBindings: ['build.state']
|
|
||||||
classNames: ['row-li', 'pr-row']
|
|
||||||
|
|
||||||
authorAvatarUrl: (->
|
|
||||||
if url = @get('build.commit.authorAvatarUrl')
|
|
||||||
url
|
|
||||||
else
|
|
||||||
email = @get('build.commit.authorEmail')
|
|
||||||
gravatarImage(email, 40)
|
|
||||||
).property('build.commit.authorEmail', 'build.commit.authorAvatarUrl')
|
|
||||||
|
|
||||||
urlGithubCommit: (->
|
|
||||||
githubCommitUrl(@get('build.repo.slug'), @get('build.commit.sha'))
|
|
||||||
).property('build.commit.sha')
|
|
||||||
|
|
||||||
`export default BuildsItemComponent`
|
|
12
app/components/builds-item.js
Normal file
12
app/components/builds-item.js
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
import { githubCommit as githubCommitUrl } from 'travis/utils/urls';
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
tagName: 'li',
|
||||||
|
classNameBindings: ['build.state'],
|
||||||
|
classNames: ['row-li', 'pr-row'],
|
||||||
|
|
||||||
|
urlGithubCommit: function() {
|
||||||
|
return githubCommitUrl(this.get('build.repo.slug'), this.get('build.commit.sha'));
|
||||||
|
}.property('build.commit.sha')
|
||||||
|
});
|
30
app/components/builds-wrapper.js
Normal file
30
app/components/builds-wrapper.js
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
import Polling from 'travis/mixins/polling';
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
store: Ember.inject.service('store'),
|
||||||
|
|
||||||
|
pollHook: function(store) {
|
||||||
|
var contentType, repositoryId;
|
||||||
|
contentType = this.get('contentType');
|
||||||
|
repositoryId = this.get('repo.id');
|
||||||
|
store = this.get('store');
|
||||||
|
|
||||||
|
if (contentType === 'builds') {
|
||||||
|
return store.query('build', {
|
||||||
|
event_type: 'push',
|
||||||
|
repository_id: repositoryId
|
||||||
|
});
|
||||||
|
} else if (contentType === 'pull_requests') {
|
||||||
|
return store.filter('build', {
|
||||||
|
event_type: 'pull_request',
|
||||||
|
repository_id: repositoryId
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return store.query('build', {
|
||||||
|
repository_id: repositoryId,
|
||||||
|
branches: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
|
@ -1,27 +0,0 @@
|
||||||
`import Ember from 'ember'`
|
|
||||||
|
|
||||||
CachesItemComponent = Ember.Component.extend
|
|
||||||
ajax: Ember.inject.service()
|
|
||||||
|
|
||||||
tagName: 'li'
|
|
||||||
classNames: ['cache-item']
|
|
||||||
classNameBindings: ['cache.type']
|
|
||||||
isDeleting: false
|
|
||||||
|
|
||||||
actions:
|
|
||||||
delete: ->
|
|
||||||
return if @get('isDeleting')
|
|
||||||
|
|
||||||
if confirm('Are you sure?')
|
|
||||||
@set('isDeleting', true)
|
|
||||||
|
|
||||||
data = { branch: @get('cache.branch') }
|
|
||||||
|
|
||||||
deletingDone = => @set('isDeleting', false)
|
|
||||||
|
|
||||||
repo = @get('repo')
|
|
||||||
@get('ajax').ajax("/repos/#{repo.get('id')}/caches", "DELETE", data: data).then(deletingDone, deletingDone).then =>
|
|
||||||
@get('caches').removeObject(@get('cache'))
|
|
||||||
|
|
||||||
|
|
||||||
`export default CachesItemComponent`
|
|
33
app/components/caches-item.js
Normal file
33
app/components/caches-item.js
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
ajax: Ember.inject.service(),
|
||||||
|
tagName: 'li',
|
||||||
|
classNames: ['cache-item'],
|
||||||
|
classNameBindings: ['cache.type'],
|
||||||
|
isDeleting: false,
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
"delete": function() {
|
||||||
|
var data, deletingDone, repo;
|
||||||
|
if (this.get('isDeleting')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (confirm('Are you sure?')) {
|
||||||
|
this.set('isDeleting', true);
|
||||||
|
data = {
|
||||||
|
branch: this.get('cache.branch')
|
||||||
|
};
|
||||||
|
deletingDone = () => {
|
||||||
|
return this.set('isDeleting', false);
|
||||||
|
};
|
||||||
|
repo = this.get('repo');
|
||||||
|
return this.get('ajax').ajax("/repos/" + (repo.get('id')) + "/caches", "DELETE", {
|
||||||
|
data: data
|
||||||
|
}).then(deletingDone, deletingDone).then(() => {
|
||||||
|
return this.get('caches').removeObject(this.get('cache'));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
|
@ -1,10 +0,0 @@
|
||||||
`import Ember from 'ember'`
|
|
||||||
|
|
||||||
Component = Ember.Component.extend(
|
|
||||||
actions:
|
|
||||||
close: ->
|
|
||||||
$('.popup').removeClass('display')
|
|
||||||
return false
|
|
||||||
)
|
|
||||||
|
|
||||||
`export default Component`
|
|
|
@ -1,55 +0,0 @@
|
||||||
`import Ember from 'ember'`
|
|
||||||
`import { githubCommit as githubCommitUrl } from 'travis/utils/urls'`
|
|
||||||
`import config from 'travis/config/environment'`
|
|
||||||
|
|
||||||
DashboardRowComponent = Ember.Component.extend
|
|
||||||
|
|
||||||
tagName: 'li'
|
|
||||||
classNameBindings: ['repo.default_branch.last_build.state']
|
|
||||||
classNames: ['dashboard-row', 'row-li']
|
|
||||||
isLoading: false
|
|
||||||
isTriggering: false
|
|
||||||
hasTriggered: false
|
|
||||||
|
|
||||||
urlGithubCommit: (->
|
|
||||||
githubCommitUrl(@get('repo.slug'), @get('repo.default_branch.last_build.commit.sha'))
|
|
||||||
).property('repo')
|
|
||||||
|
|
||||||
# canTrigger: (->
|
|
||||||
# if !@get('auth.signedIn')
|
|
||||||
# false
|
|
||||||
# else
|
|
||||||
# permissions = @get('auth.currentUser.permissions')
|
|
||||||
# if permissions.contains parseInt(@get('build.repository.id'))
|
|
||||||
# true
|
|
||||||
# else
|
|
||||||
# false
|
|
||||||
# ).property()
|
|
||||||
|
|
||||||
# triggerBuild: (->
|
|
||||||
# apiEndpoint = config.apiEndpoint
|
|
||||||
# repoId = @get('build.repository.id')
|
|
||||||
# options = {
|
|
||||||
# type: 'POST',
|
|
||||||
# body: {
|
|
||||||
# request: {
|
|
||||||
# branch: @get('build.name')
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
# if @get('auth.signedIn')
|
|
||||||
# options.headers = { Authorization: "token #{@auth.token()}" }
|
|
||||||
# $.ajax("#{apiEndpoint}/v3/repo/#{repoId}/requests", options).then (response) =>
|
|
||||||
# @set('isTriggering', false)
|
|
||||||
# @set('hasTriggered', true)
|
|
||||||
# )
|
|
||||||
|
|
||||||
actions:
|
|
||||||
tiggerBuild: (branch) ->
|
|
||||||
@set('isTriggering', true)
|
|
||||||
@triggerBuild()
|
|
||||||
|
|
||||||
# viewAllBuilds: (branch) ->
|
|
||||||
# @get('routing').transitionTo('builds')
|
|
||||||
|
|
||||||
`export default DashboardRowComponent`
|
|
36
app/components/dashboard-row.js
Normal file
36
app/components/dashboard-row.js
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
import { githubCommit as githubCommitUrl } from 'travis/utils/urls';
|
||||||
|
import config from 'travis/config/environment';
|
||||||
|
import { hasAdminPermission, hasPushPermission } from 'travis/utils/permission';
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
tagName: 'li',
|
||||||
|
classNameBindings: ['repo.default_branch.last_build.state'],
|
||||||
|
classNames: ['rows', 'rows--dashboard'],
|
||||||
|
isLoading: false,
|
||||||
|
isTriggering: false,
|
||||||
|
hasTriggered: false,
|
||||||
|
dropupIsOpen: false,
|
||||||
|
|
||||||
|
urlGithubCommit: function() {
|
||||||
|
return githubCommitUrl(this.get('repo.slug'), this.get('repo.default_branch.last_build.commit.sha'));
|
||||||
|
}.property('repo'),
|
||||||
|
|
||||||
|
displayMenuTofu: function() {
|
||||||
|
return hasPushPermission(this.get('currentUser'), this.get('repo.id'));
|
||||||
|
},
|
||||||
|
|
||||||
|
displayActivateLink: function() {
|
||||||
|
return hasAdminPermission(this.get('currentUser'), this.get('repo.id'));
|
||||||
|
},
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
tiggerBuild(branch) {
|
||||||
|
this.set('isTriggering', true);
|
||||||
|
return this.triggerBuild();
|
||||||
|
},
|
||||||
|
openDropup() {
|
||||||
|
this.toggleProperty('dropupIsOpen');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
|
@ -1,29 +0,0 @@
|
||||||
`import Ember from 'ember'`
|
|
||||||
|
|
||||||
EnvVarComponent = Ember.Component.extend
|
|
||||||
|
|
||||||
classNames: ['settings-envvar']
|
|
||||||
classNameBindings: ['envVar.public:is-public']
|
|
||||||
|
|
||||||
isDeleting: false
|
|
||||||
|
|
||||||
validates:
|
|
||||||
name: ['presence']
|
|
||||||
|
|
||||||
actionType: 'Save'
|
|
||||||
showValueField: Ember.computed.alias('public')
|
|
||||||
|
|
||||||
value: ( (key, value) ->
|
|
||||||
if @get('envVar.public')
|
|
||||||
@get('envVar.value')
|
|
||||||
else
|
|
||||||
'••••••••••••••••'
|
|
||||||
).property('envVar.value', 'envVar.public')
|
|
||||||
|
|
||||||
actions:
|
|
||||||
delete: ->
|
|
||||||
return if @get('isDeleting')
|
|
||||||
@set('isDeleting', true)
|
|
||||||
@get('envVar').destroyRecord()
|
|
||||||
|
|
||||||
`export default EnvVarComponent`
|
|
28
app/components/env-var.js
Normal file
28
app/components/env-var.js
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
classNames: ['settings-envvar'],
|
||||||
|
classNameBindings: ['envVar.public:is-public'],
|
||||||
|
isDeleting: false,
|
||||||
|
validates: { name: ['presence'] },
|
||||||
|
actionType: 'Save',
|
||||||
|
showValueField: Ember.computed.alias('public'),
|
||||||
|
|
||||||
|
value: function(key) {
|
||||||
|
if (this.get('envVar.public')) {
|
||||||
|
return this.get('envVar.value');
|
||||||
|
} else {
|
||||||
|
return '••••••••••••••••';
|
||||||
|
}
|
||||||
|
}.property('envVar.value', 'envVar.public'),
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
"delete": function() {
|
||||||
|
if (this.get('isDeleting')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.set('isDeleting', true);
|
||||||
|
return this.get('envVar').destroyRecord();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
|
@ -1,8 +0,0 @@
|
||||||
`import Ember from 'ember'`
|
|
||||||
|
|
||||||
EyeIconComponent = Ember.Component.extend
|
|
||||||
|
|
||||||
tagName: 'span'
|
|
||||||
classNames: ['icon-eye']
|
|
||||||
|
|
||||||
`export default EyeIconComponent`
|
|
6
app/components/eye-icon.js
Normal file
6
app/components/eye-icon.js
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
tagName: 'span',
|
||||||
|
classNames: ['icon-eye']
|
||||||
|
});
|
|
@ -1,15 +0,0 @@
|
||||||
`import Ember from 'ember'`
|
|
||||||
|
|
||||||
FlashDisplayComponent = Ember.Component.extend
|
|
||||||
flashes: Ember.inject.service()
|
|
||||||
|
|
||||||
classNames: ['flash']
|
|
||||||
tagName: 'ul'
|
|
||||||
|
|
||||||
messagesBinding: 'flashes.messages'
|
|
||||||
|
|
||||||
actions:
|
|
||||||
closeMessage: (msg) ->
|
|
||||||
@get('flashes').close(msg)
|
|
||||||
|
|
||||||
`export default FlashDisplayComponent`
|
|
14
app/components/flash-display.js
Normal file
14
app/components/flash-display.js
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
flashes: Ember.inject.service(),
|
||||||
|
classNames: ['flash'],
|
||||||
|
tagName: 'ul',
|
||||||
|
messagesBinding: 'flashes.messages',
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
closeMessage(msg) {
|
||||||
|
return this.get('flashes').close(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
|
@ -1,15 +0,0 @@
|
||||||
`import Ember from 'ember'`
|
|
||||||
|
|
||||||
FlashItemComponent = Ember.Component.extend
|
|
||||||
tagName: 'li'
|
|
||||||
classNameBindings: ['type']
|
|
||||||
|
|
||||||
type: (->
|
|
||||||
@get('flash.type') || 'broadcast'
|
|
||||||
).property('flash.type')
|
|
||||||
|
|
||||||
actions:
|
|
||||||
close: ->
|
|
||||||
this.attrs.close(@get('flash'))
|
|
||||||
|
|
||||||
`export default FlashItemComponent`
|
|
16
app/components/flash-item.js
Normal file
16
app/components/flash-item.js
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
tagName: 'li',
|
||||||
|
classNameBindings: ['type'],
|
||||||
|
|
||||||
|
type: function() {
|
||||||
|
return this.get('flash.type') || 'broadcast';
|
||||||
|
}.property('flash.type'),
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
close() {
|
||||||
|
return this.attrs.close(this.get('flash'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
|
@ -1,18 +0,0 @@
|
||||||
`import Ember from 'ember'`
|
|
||||||
|
|
||||||
HookSwitchComponent = Ember.Component.extend
|
|
||||||
tagName: 'a'
|
|
||||||
classNames: ['switch--icon']
|
|
||||||
classNameBindings: ['active']
|
|
||||||
activeBinding: "hook.active"
|
|
||||||
|
|
||||||
click: ->
|
|
||||||
@sendAction('onToggle')
|
|
||||||
hook = @get('hook')
|
|
||||||
hook.toggle().then( (->), =>
|
|
||||||
@toggleProperty('hook.active')
|
|
||||||
@sendAction('onToggleError', hook)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
`export default HookSwitchComponent`
|
|
17
app/components/hook-switch.js
Normal file
17
app/components/hook-switch.js
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
tagName: 'a',
|
||||||
|
classNames: ['switch--icon'],
|
||||||
|
classNameBindings: ['active'],
|
||||||
|
activeBinding: "hook.active",
|
||||||
|
click() {
|
||||||
|
var hook;
|
||||||
|
this.sendAction('onToggle');
|
||||||
|
hook = this.get('hook');
|
||||||
|
return hook.toggle().then((function() {}), () => {
|
||||||
|
this.toggleProperty('hook.active');
|
||||||
|
return this.sendAction('onToggleError', hook);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
|
@ -1,21 +0,0 @@
|
||||||
`import Ember from 'ember'`
|
|
||||||
`import config from 'travis/config/environment'`
|
|
||||||
|
|
||||||
HooksListItemComponent = Ember.Component.extend
|
|
||||||
tagName: 'li'
|
|
||||||
classNames: ['row']
|
|
||||||
classNameBindings: ['hook.active:active']
|
|
||||||
|
|
||||||
githubOrgsOauthAccessSettingsUrl: config.githubOrgsOauthAccessSettingsUrl
|
|
||||||
|
|
||||||
actions:
|
|
||||||
handleToggleError: ->
|
|
||||||
@set("showError", true)
|
|
||||||
|
|
||||||
close: ->
|
|
||||||
@send('resetErrors')
|
|
||||||
|
|
||||||
resetErrors: ->
|
|
||||||
@set("showError", false)
|
|
||||||
|
|
||||||
`export default HooksListItemComponent`
|
|
23
app/components/hooks-list-item.js
Normal file
23
app/components/hooks-list-item.js
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
import config from 'travis/config/environment';
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
tagName: 'li',
|
||||||
|
classNames: ['row'],
|
||||||
|
classNameBindings: ['hook.active:active'],
|
||||||
|
githubOrgsOauthAccessSettingsUrl: config.githubOrgsOauthAccessSettingsUrl,
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
handleToggleError() {
|
||||||
|
return this.set("showError", true);
|
||||||
|
},
|
||||||
|
|
||||||
|
close() {
|
||||||
|
return this.send('resetErrors');
|
||||||
|
},
|
||||||
|
|
||||||
|
resetErrors() {
|
||||||
|
return this.set("showError", false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
|
@ -1,30 +0,0 @@
|
||||||
`import Ember from 'ember'`
|
|
||||||
|
|
||||||
JobLogComponent = Ember.Component.extend
|
|
||||||
logBinding: 'job.log'
|
|
||||||
|
|
||||||
didInsertElement: ->
|
|
||||||
@setupLog()
|
|
||||||
|
|
||||||
logDidChange: (->
|
|
||||||
@setupLog()
|
|
||||||
).observes('log')
|
|
||||||
|
|
||||||
logWillChange: (->
|
|
||||||
@teardownLog()
|
|
||||||
).observesBefore('log')
|
|
||||||
|
|
||||||
willDestroyElement: ->
|
|
||||||
@teardownLog()
|
|
||||||
|
|
||||||
teardownLog: ->
|
|
||||||
job = @get('job')
|
|
||||||
job.unsubscribe() if job
|
|
||||||
|
|
||||||
setupLog: ->
|
|
||||||
job = @get('job')
|
|
||||||
if job
|
|
||||||
job.get('log').fetch()
|
|
||||||
job.subscribe()
|
|
||||||
|
|
||||||
`export default JobLogComponent`
|
|
35
app/components/job-log.js
Normal file
35
app/components/job-log.js
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
logBinding: 'job.log',
|
||||||
|
classNames: ['job-log'],
|
||||||
|
|
||||||
|
didReceiveAttrs: function(options) {
|
||||||
|
this._super(...arguments);
|
||||||
|
|
||||||
|
let oldJob = options.oldAttrs && options.oldAttrs.job && options.oldAttrs.job.value,
|
||||||
|
newJob = options.newAttrs && options.newAttrs.job && options.newAttrs.job.value;
|
||||||
|
|
||||||
|
if(newJob !== oldJob) {
|
||||||
|
if(newJob) {
|
||||||
|
this.setupLog(newJob);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(oldJob) {
|
||||||
|
this.teardownLog(oldJob);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
teardownLog(job) {
|
||||||
|
job.unsubscribe();
|
||||||
|
},
|
||||||
|
|
||||||
|
setupLog(job) {
|
||||||
|
this.set('error', false);
|
||||||
|
job.get('log').fetch().then(function() { }, () => {
|
||||||
|
this.set('error', true);
|
||||||
|
});
|
||||||
|
job.subscribe();
|
||||||
|
}
|
||||||
|
});
|
|
@ -1,9 +0,0 @@
|
||||||
`import Ember from 'ember'`
|
|
||||||
`import RepoActionsItemComponentMixin from 'travis/utils/repo-actions-item-component-mixin'`
|
|
||||||
|
|
||||||
JobRepoActionsComponent = Ember.Component.extend(RepoActionsItemComponentMixin,
|
|
||||||
item: Ember.computed.alias('job')
|
|
||||||
type: 'job'
|
|
||||||
)
|
|
||||||
|
|
||||||
`export default JobRepoActionsComponent`
|
|
7
app/components/job-repo-actions.js
Normal file
7
app/components/job-repo-actions.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
import RepoActionsItemComponentMixin from 'travis/utils/repo-actions-item-component-mixin';
|
||||||
|
|
||||||
|
export default Ember.Component.extend(RepoActionsItemComponentMixin, {
|
||||||
|
item: Ember.computed.alias('job'),
|
||||||
|
type: 'job'
|
||||||
|
});
|
18
app/components/job-wrapper.js
Normal file
18
app/components/job-wrapper.js
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
import { colorForState } from 'travis/utils/helpers';
|
||||||
|
import { githubCommit } from 'travis/utils/urls';
|
||||||
|
import Polling from 'travis/mixins/polling';
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
pollModels: 'job.build',
|
||||||
|
commitBinding: 'job.commit',
|
||||||
|
currentItemBinding: 'job',
|
||||||
|
|
||||||
|
color: function() {
|
||||||
|
return colorForState(this.get('job.state'));
|
||||||
|
}.property('job.state'),
|
||||||
|
|
||||||
|
urlGithubCommit: function() {
|
||||||
|
return githubCommit(this.get('repo.slug'), this.get('commit.sha'));
|
||||||
|
}.property('repo.slug', 'commit.sha')
|
||||||
|
});
|
|
@ -1,32 +0,0 @@
|
||||||
`import Ember from 'ember'`
|
|
||||||
`import { colorForState } from 'travis/utils/helpers'`
|
|
||||||
`import { languageConfigKeys } from 'travis/utils/keys-map';`
|
|
||||||
|
|
||||||
JobsItemComponent = Ember.Component.extend
|
|
||||||
tagName: 'li'
|
|
||||||
classNameBindings: ['job.state']
|
|
||||||
classNames: ['jobs-item']
|
|
||||||
|
|
||||||
languages: (->
|
|
||||||
output = []
|
|
||||||
|
|
||||||
if config = @get('job.config')
|
|
||||||
for key, languageName of languageConfigKeys
|
|
||||||
if version = config[key]
|
|
||||||
output.push(languageName + ': ' + version)
|
|
||||||
|
|
||||||
gemfile = @get('job.config.gemfile')
|
|
||||||
if gemfile && @get('job.config.env')
|
|
||||||
output.push "Gemfile: #{gemfile}"
|
|
||||||
|
|
||||||
output.join(' ')
|
|
||||||
).property('job.config')
|
|
||||||
|
|
||||||
environment: (->
|
|
||||||
if env = @get('job.config.env')
|
|
||||||
env
|
|
||||||
else if gemfile = @get('job.config.gemfile')
|
|
||||||
"Gemfile: #{gemfile}"
|
|
||||||
).property('job.config.env', 'job.config.gemfile')
|
|
||||||
|
|
||||||
`export default JobsItemComponent`
|
|
36
app/components/jobs-item.js
Normal file
36
app/components/jobs-item.js
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
import { colorForState } from 'travis/utils/helpers';
|
||||||
|
import { languageConfigKeys } from 'travis/utils/keys-map';
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
tagName: 'li',
|
||||||
|
classNameBindings: ['job.state'],
|
||||||
|
classNames: ['jobs-item'],
|
||||||
|
|
||||||
|
languages: function() {
|
||||||
|
var config, gemfile, key, languageName, output, version;
|
||||||
|
output = [];
|
||||||
|
if (config = this.get('job.config')) {
|
||||||
|
for (key in languageConfigKeys) {
|
||||||
|
languageName = languageConfigKeys[key];
|
||||||
|
if (version = config[key]) {
|
||||||
|
output.push(languageName + ': ' + version);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gemfile = this.get('job.config.gemfile');
|
||||||
|
if (gemfile && this.get('job.config.env')) {
|
||||||
|
output.push("Gemfile: " + gemfile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return output.join(' ');
|
||||||
|
}.property('job.config'),
|
||||||
|
|
||||||
|
environment: function() {
|
||||||
|
var env, gemfile;
|
||||||
|
if (env = this.get('job.config.env')) {
|
||||||
|
return env;
|
||||||
|
} else if (gemfile = this.get('job.config.gemfile')) {
|
||||||
|
return "Gemfile: " + gemfile;
|
||||||
|
}
|
||||||
|
}.property('job.config.env', 'job.config.gemfile')
|
||||||
|
});
|
|
@ -1,15 +0,0 @@
|
||||||
`import Ember from 'ember'`
|
|
||||||
|
|
||||||
JobsListComponent = Ember.Component.extend
|
|
||||||
|
|
||||||
tagName: 'section'
|
|
||||||
classNames: ['jobs']
|
|
||||||
|
|
||||||
jobTableId: Ember.computed(->
|
|
||||||
if @get('required')
|
|
||||||
'jobs'
|
|
||||||
else
|
|
||||||
'allowed_failure_jobs'
|
|
||||||
)
|
|
||||||
|
|
||||||
`export default JobsListComponent`
|
|
13
app/components/jobs-list.js
Normal file
13
app/components/jobs-list.js
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
tagName: 'section',
|
||||||
|
classNames: ['jobs'],
|
||||||
|
jobTableId: Ember.computed(function() {
|
||||||
|
if (this.get('required')) {
|
||||||
|
return 'jobs';
|
||||||
|
} else {
|
||||||
|
return 'allowed_failure_jobs';
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
|
@ -1,12 +0,0 @@
|
||||||
`import Ember from 'ember'`
|
|
||||||
`import { githubCommit as githubCommitUrl } from 'travis/utils/urls'`
|
|
||||||
`import TravisRoute from 'travis/routes/basic'`
|
|
||||||
`import config from 'travis/config/environment'`
|
|
||||||
|
|
||||||
LandingRowComponent = Ember.Component.extend
|
|
||||||
|
|
||||||
tagName: 'li'
|
|
||||||
classNameBindings: ['repo.lastBuildState']
|
|
||||||
classNames: ['landing-row', 'row-li']
|
|
||||||
|
|
||||||
`export default LandingRowComponent`
|
|
8
app/components/lastbuild-tile.js
Normal file
8
app/components/lastbuild-tile.js
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
|
||||||
|
tagName: 'li',
|
||||||
|
classNameBindings: ['build.state']
|
||||||
|
|
||||||
|
});
|
|
@ -1,40 +0,0 @@
|
||||||
`import Ember from 'ember'`
|
|
||||||
|
|
||||||
LimitConcurrentBuildsComponent = Ember.Component.extend
|
|
||||||
|
|
||||||
classNames: ['limit-concurrent-builds']
|
|
||||||
|
|
||||||
description: (->
|
|
||||||
description = "Limit concurrent jobs"
|
|
||||||
if @get('enabled')
|
|
||||||
description += " "
|
|
||||||
description
|
|
||||||
).property('enabled')
|
|
||||||
|
|
||||||
limitChanged: ->
|
|
||||||
repo = @get('repo')
|
|
||||||
limit = parseInt(@get('value'))
|
|
||||||
if limit
|
|
||||||
@set('isSaving', true)
|
|
||||||
savingFinished = =>
|
|
||||||
@set('isSaving', false)
|
|
||||||
|
|
||||||
repo.saveSettings(maximum_number_of_builds: limit).
|
|
||||||
then(savingFinished, savingFinished)
|
|
||||||
actions:
|
|
||||||
toggle: ->
|
|
||||||
unless @get('enabled')
|
|
||||||
return if @get('value') == 0
|
|
||||||
return if @get('isSaving')
|
|
||||||
@set('isSaving', true)
|
|
||||||
|
|
||||||
savingFinished = =>
|
|
||||||
@set('isSaving', false)
|
|
||||||
|
|
||||||
@get('repo').saveSettings(maximum_number_of_builds: 0).then(savingFinished, savingFinished)
|
|
||||||
@set('value', 0)
|
|
||||||
|
|
||||||
limitChanged: ->
|
|
||||||
Ember.run.debounce(this, 'limitChanged', 1000)
|
|
||||||
|
|
||||||
`export default LimitConcurrentBuildsComponent`
|
|
55
app/components/limit-concurrent-builds.js
Normal file
55
app/components/limit-concurrent-builds.js
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
classNames: ['limit-concurrent-builds'],
|
||||||
|
|
||||||
|
description: function() {
|
||||||
|
var description;
|
||||||
|
description = "Limit concurrent jobs";
|
||||||
|
if (this.get('enabled')) {
|
||||||
|
description += " ";
|
||||||
|
}
|
||||||
|
return description;
|
||||||
|
}.property('enabled'),
|
||||||
|
|
||||||
|
limitChanged() {
|
||||||
|
var limit, repo, savingFinished;
|
||||||
|
repo = this.get('repo');
|
||||||
|
limit = parseInt(this.get('value'));
|
||||||
|
if (limit) {
|
||||||
|
this.set('isSaving', true);
|
||||||
|
savingFinished = () => {
|
||||||
|
return this.set('isSaving', false);
|
||||||
|
};
|
||||||
|
return repo.saveSettings({
|
||||||
|
maximum_number_of_builds: limit
|
||||||
|
}).then(savingFinished, savingFinished);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
toggle() {
|
||||||
|
var savingFinished;
|
||||||
|
if (!this.get('enabled')) {
|
||||||
|
if (this.get('value') === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.get('isSaving')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.set('isSaving', true);
|
||||||
|
savingFinished = () => {
|
||||||
|
return this.set('isSaving', false);
|
||||||
|
};
|
||||||
|
this.get('repo').saveSettings({
|
||||||
|
maximum_number_of_builds: 0
|
||||||
|
}).then(savingFinished, savingFinished);
|
||||||
|
return this.set('value', 0);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
limitChanged() {
|
||||||
|
return Ember.run.debounce(this, 'limitChanged', 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
|
@ -1,8 +0,0 @@
|
||||||
`import Ember from 'ember'`
|
|
||||||
|
|
||||||
LoadingIndicatorComponent = Ember.Component.extend
|
|
||||||
tagName: 'div'
|
|
||||||
classNameBindings: ['center:loading-container', 'inline:inline-block', 'height:icon-height']
|
|
||||||
center: false
|
|
||||||
|
|
||||||
`export default LoadingIndicatorComponent`
|
|
7
app/components/loading-indicator.js
Normal file
7
app/components/loading-indicator.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
tagName: 'div',
|
||||||
|
classNameBindings: ['center:loading-container', 'inline:inline-block', 'height:icon-height'],
|
||||||
|
center: false
|
||||||
|
});
|
|
@ -1,157 +0,0 @@
|
||||||
`import Ember from 'ember'`
|
|
||||||
`import LinesSelector from 'travis/utils/lines-selector'`
|
|
||||||
`import LogFolder from 'travis/utils/log-folder'`
|
|
||||||
`import config from 'travis/config/environment'`
|
|
||||||
`import { plainTextLog as plainTextLogUrl } from 'travis/utils/urls'`
|
|
||||||
|
|
||||||
Log.DEBUG = false
|
|
||||||
Log.LIMIT = 10000
|
|
||||||
|
|
||||||
Log.Scroll = (options) ->
|
|
||||||
options ||= {}
|
|
||||||
@beforeScroll = options.beforeScroll
|
|
||||||
this
|
|
||||||
Log.Scroll.prototype = $.extend new Log.Listener,
|
|
||||||
insert: (log, data, pos) ->
|
|
||||||
@tryScroll() if @numbers
|
|
||||||
true
|
|
||||||
|
|
||||||
tryScroll: ->
|
|
||||||
if element = $("#log p:visible.highlight:first")
|
|
||||||
if @beforeScroll
|
|
||||||
@beforeScroll()
|
|
||||||
$('#main').scrollTop(0)
|
|
||||||
$('html, body').scrollTop(element.offset()?.top - (window.innerHeight / 3)) # weird, html works in chrome, body in firefox
|
|
||||||
|
|
||||||
Log.Limit = (max_lines, limitedLogCallback) ->
|
|
||||||
@max_lines = max_lines || 1000
|
|
||||||
@limitedLogCallback = limitedLogCallback || (->)
|
|
||||||
this
|
|
||||||
|
|
||||||
Log.Limit.prototype = Log.extend new Log.Listener,
|
|
||||||
count: 0,
|
|
||||||
insert: (log, node, pos) ->
|
|
||||||
if node.type == 'paragraph' && !node.hidden
|
|
||||||
@count += 1
|
|
||||||
if @limited
|
|
||||||
@limitedLogCallback()
|
|
||||||
return @count
|
|
||||||
|
|
||||||
Object.defineProperty Log.Limit.prototype, 'limited',
|
|
||||||
get: ->
|
|
||||||
@count >= @max_lines
|
|
||||||
|
|
||||||
LogContentComponent = Ember.Component.extend
|
|
||||||
popup: Ember.inject.service()
|
|
||||||
|
|
||||||
currentUserBinding: 'auth.currentUser'
|
|
||||||
|
|
||||||
didInsertElement: ->
|
|
||||||
console.log 'log view: did insert' if Log.DEBUG
|
|
||||||
@_super.apply this, arguments
|
|
||||||
@createEngine()
|
|
||||||
|
|
||||||
willDestroyElement: ->
|
|
||||||
console.log 'log view: will destroy' if Log.DEBUG
|
|
||||||
@teardownLog()
|
|
||||||
|
|
||||||
teardownLog: (log) ->
|
|
||||||
if log || log = @get('log')
|
|
||||||
parts = log.get('parts')
|
|
||||||
parts.removeArrayObserver(@, didChange: 'partsDidChange', willChange: 'noop')
|
|
||||||
parts.destroy()
|
|
||||||
log.notifyPropertyChange('parts')
|
|
||||||
@lineSelector?.willDestroy()
|
|
||||||
if logElement = this.$('#log')
|
|
||||||
logElement.empty()
|
|
||||||
|
|
||||||
createEngine: (log) ->
|
|
||||||
if log || log = @get('log')
|
|
||||||
if logElement = this.$('#log')
|
|
||||||
logElement.empty()
|
|
||||||
|
|
||||||
log.onClear =>
|
|
||||||
@teardownLog()
|
|
||||||
@createEngine()
|
|
||||||
|
|
||||||
@scroll = new Log.Scroll beforeScroll: =>
|
|
||||||
@unfoldHighlight()
|
|
||||||
@limit = new Log.Limit Log.LIMIT, =>
|
|
||||||
@set('limited', true)
|
|
||||||
@engine = Log.create(listeners: [@scroll, @limit])
|
|
||||||
@engine.limit = @limit
|
|
||||||
@logFolder = new LogFolder(@$('#log'))
|
|
||||||
@lineSelector = new LinesSelector(@$('#log'), @scroll, @logFolder)
|
|
||||||
@observeParts(log)
|
|
||||||
|
|
||||||
didUpdateAttrs: (changes) ->
|
|
||||||
@_super.apply(this, arguments)
|
|
||||||
|
|
||||||
return unless changes.oldAttrs
|
|
||||||
|
|
||||||
if changes.newAttrs.job.value && changes.oldAttrs.job.value &&
|
|
||||||
changes.newAttrs.job.value != changes.oldAttrs.job.value
|
|
||||||
|
|
||||||
@teardownLog(changes.oldAttrs.job.value.get('log'))
|
|
||||||
@createEngine(changes.newAttrs.job.value.get('log'))
|
|
||||||
|
|
||||||
unfoldHighlight: ->
|
|
||||||
@lineSelector.unfoldLines()
|
|
||||||
|
|
||||||
observeParts: (log) ->
|
|
||||||
if log || log = @get('log')
|
|
||||||
parts = log.get('parts')
|
|
||||||
parts.addArrayObserver(@, didChange: 'partsDidChange', willChange: 'noop')
|
|
||||||
parts = parts.slice(0)
|
|
||||||
@partsDidChange(parts, 0, null, parts.length)
|
|
||||||
|
|
||||||
partsDidChange: (parts, start, _, added) ->
|
|
||||||
console.log 'log view: parts did change' if Log.DEBUG
|
|
||||||
return unless @get('state') == 'inDOM'
|
|
||||||
|
|
||||||
for part, i in parts.slice(start, start + added)
|
|
||||||
# console.log "limit in log view: #{@get('limited')}"
|
|
||||||
break if @engine?.limit?.limited
|
|
||||||
@engine.set(part.number, part.content)
|
|
||||||
|
|
||||||
plainTextLogUrl: (->
|
|
||||||
if id = @get('log.job.id')
|
|
||||||
url = plainTextLogUrl(id)
|
|
||||||
if config.pro
|
|
||||||
url += "&access_token=#{@get('job.log.token')}"
|
|
||||||
url
|
|
||||||
).property('job.log.id', 'job.log.token')
|
|
||||||
|
|
||||||
hasPermission: (->
|
|
||||||
if permissions = @get('currentUser.permissions')
|
|
||||||
permissions.contains parseInt(@get('job.repo.id'))
|
|
||||||
).property('currentUser.permissions.length', 'job.repo.id')
|
|
||||||
|
|
||||||
canRemoveLog: (->
|
|
||||||
if job = @get('job')
|
|
||||||
job.get('canRemoveLog') && @get('hasPermission')
|
|
||||||
).property('job.canRemoveLog', 'hasPermission')
|
|
||||||
|
|
||||||
showToTop: (->
|
|
||||||
@get('log.hasContent') && @get('job.canRemoveLog')
|
|
||||||
).property('log.hasContent', 'job.canRemoveLog')
|
|
||||||
showTailing: Ember.computed.alias('showToTop')
|
|
||||||
|
|
||||||
actions:
|
|
||||||
toTop: () ->
|
|
||||||
Travis.tailing.stop()
|
|
||||||
$(window).scrollTop(0)
|
|
||||||
|
|
||||||
toggleTailing: ->
|
|
||||||
Travis.tailing.toggle()
|
|
||||||
@engine.autoCloseFold = !Travis.tailing.isActive()
|
|
||||||
event.preventDefault()
|
|
||||||
|
|
||||||
removeLogPopup: ->
|
|
||||||
if @get('canRemoveLog')
|
|
||||||
@get('popup').open('remove-log-popup')
|
|
||||||
return false
|
|
||||||
|
|
||||||
noop: -> # TODO required?
|
|
||||||
|
|
||||||
`export default LogContentComponent`
|
|
238
app/components/log-content.js
Normal file
238
app/components/log-content.js
Normal file
|
@ -0,0 +1,238 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
import LinesSelector from 'travis/utils/lines-selector';
|
||||||
|
import LogFolder from 'travis/utils/log-folder';
|
||||||
|
import config from 'travis/config/environment';
|
||||||
|
import { plainTextLog as plainTextLogUrl } from 'travis/utils/urls';
|
||||||
|
|
||||||
|
Log.DEBUG = false;
|
||||||
|
|
||||||
|
Log.LIMIT = 10000;
|
||||||
|
|
||||||
|
Log.Scroll = function(options) {
|
||||||
|
options = options || {};
|
||||||
|
this.beforeScroll = options.beforeScroll;
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
Log.Scroll.prototype = $.extend(new Log.Listener(), {
|
||||||
|
insert: function(log, data, pos) {
|
||||||
|
if (this.numbers) {
|
||||||
|
this.tryScroll();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
tryScroll: function() {
|
||||||
|
var element, ref;
|
||||||
|
if (element = $("#log p:visible.highlight:first")) {
|
||||||
|
if (this.beforeScroll) {
|
||||||
|
this.beforeScroll();
|
||||||
|
}
|
||||||
|
$('#main').scrollTop(0);
|
||||||
|
return $('html, body').scrollTop(((ref = element.offset()) != null ? ref.top : void 0) - (window.innerHeight / 3));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Log.Limit = function(max_lines, limitedLogCallback) {
|
||||||
|
this.max_lines = max_lines || 1000;
|
||||||
|
this.limitedLogCallback = limitedLogCallback || (function() {});
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
Log.Limit.prototype = Log.extend(new Log.Listener(), {
|
||||||
|
count: 0,
|
||||||
|
insert: function(log, node, pos) {
|
||||||
|
if (node.type === 'paragraph' && !node.hidden) {
|
||||||
|
this.count += 1;
|
||||||
|
if (this.limited) {
|
||||||
|
this.limitedLogCallback();
|
||||||
|
}
|
||||||
|
return this.count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.defineProperty(Log.Limit.prototype, 'limited', {
|
||||||
|
get: function() {
|
||||||
|
return this.count >= this.max_lines;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
popup: Ember.inject.service(),
|
||||||
|
classNameBindings: ['logIsVisible:is-open'],
|
||||||
|
logIsVisible: false,
|
||||||
|
currentUserBinding: 'auth.currentUser',
|
||||||
|
|
||||||
|
didInsertElement() {
|
||||||
|
if (Log.DEBUG) {
|
||||||
|
console.log('log view: did insert');
|
||||||
|
}
|
||||||
|
this._super.apply(this, arguments);
|
||||||
|
Ember.run.scheduleOnce('afterRender', this, 'createEngine');
|
||||||
|
},
|
||||||
|
|
||||||
|
willDestroyElement() {
|
||||||
|
if (Log.DEBUG) {
|
||||||
|
console.log('log view: will destroy');
|
||||||
|
}
|
||||||
|
Ember.run.scheduleOnce('afterRender', this, 'teardownLog');
|
||||||
|
},
|
||||||
|
|
||||||
|
teardownLog(log) {
|
||||||
|
var parts, ref;
|
||||||
|
if (log || (log = this.get('log'))) {
|
||||||
|
parts = log.get('parts');
|
||||||
|
parts.removeArrayObserver(this, {
|
||||||
|
didChange: 'partsDidChange',
|
||||||
|
willChange: 'noop'
|
||||||
|
});
|
||||||
|
parts.destroy();
|
||||||
|
log.notifyPropertyChange('parts');
|
||||||
|
if ((ref = this.lineSelector) != null) {
|
||||||
|
ref.willDestroy();
|
||||||
|
}
|
||||||
|
this.clearLogElement();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
clearLogElement() {
|
||||||
|
var logElement = this.$('#log');
|
||||||
|
if (logElement && logElement[0]) {
|
||||||
|
logElement[0].innerHTML = '';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
createEngine(log) {
|
||||||
|
if (log || (log = this.get('log'))) {
|
||||||
|
this.clearLogElement();
|
||||||
|
log.onClear(() => {
|
||||||
|
this.teardownLog();
|
||||||
|
return this.createEngine();
|
||||||
|
});
|
||||||
|
this.scroll = new Log.Scroll({
|
||||||
|
beforeScroll: () => {
|
||||||
|
return this.unfoldHighlight();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.limit = new Log.Limit(Log.LIMIT, () => {
|
||||||
|
return this.set('limited', true);
|
||||||
|
});
|
||||||
|
this.engine = Log.create({
|
||||||
|
listeners: [this.scroll, this.limit]
|
||||||
|
});
|
||||||
|
this.engine.limit = this.limit;
|
||||||
|
this.logFolder = new LogFolder(this.$('#log'));
|
||||||
|
this.lineSelector = new LinesSelector(this.$('#log'), this.scroll, this.logFolder);
|
||||||
|
this.observeParts(log);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
didUpdateAttrs(changes) {
|
||||||
|
this._super.apply(this, arguments);
|
||||||
|
if (!changes.oldAttrs) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (changes.newAttrs.job.value && changes.oldAttrs.job.value && changes.newAttrs.job.value !== changes.oldAttrs.job.value) {
|
||||||
|
this.teardownLog(changes.oldAttrs.job.value.get('log'));
|
||||||
|
return this.createEngine(changes.newAttrs.job.value.get('log'));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
unfoldHighlight() {
|
||||||
|
return this.lineSelector.unfoldLines();
|
||||||
|
},
|
||||||
|
|
||||||
|
observeParts(log) {
|
||||||
|
var parts;
|
||||||
|
if (log || (log = this.get('log'))) {
|
||||||
|
parts = log.get('parts');
|
||||||
|
parts.addArrayObserver(this, {
|
||||||
|
didChange: 'partsDidChange',
|
||||||
|
willChange: 'noop'
|
||||||
|
});
|
||||||
|
parts = parts.slice(0);
|
||||||
|
this.partsDidChange(parts, 0, null, parts.length);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
partsDidChange(parts, start, _, added) {
|
||||||
|
Ember.run.schedule('afterRender', this, function() {
|
||||||
|
var i, j, len, part, ref, ref1, ref2, results;
|
||||||
|
if (Log.DEBUG) {
|
||||||
|
console.log('log view: parts did change');
|
||||||
|
}
|
||||||
|
if (this.get('_state') !== 'inDOM') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ref = parts.slice(start, start + added);
|
||||||
|
results = [];
|
||||||
|
for (i = j = 0, len = ref.length; j < len; i = ++j) {
|
||||||
|
part = ref[i];
|
||||||
|
if ((ref1 = this.engine) != null ? (ref2 = ref1.limit) != null ? ref2.limited : void 0 : void 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
results.push(this.engine.set(part.number, part.content));
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
plainTextLogUrl: function() {
|
||||||
|
var id, url;
|
||||||
|
if (id = this.get('log.job.id')) {
|
||||||
|
url = plainTextLogUrl(id);
|
||||||
|
if (config.pro) {
|
||||||
|
url += "&access_token=" + (this.get('job.log.token'));
|
||||||
|
}
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
}.property('job.log.id', 'job.log.token'),
|
||||||
|
|
||||||
|
hasPermission: function() {
|
||||||
|
var permissions;
|
||||||
|
if (permissions = this.get('currentUser.permissions')) {
|
||||||
|
return permissions.contains(parseInt(this.get('job.repo.id')));
|
||||||
|
}
|
||||||
|
}.property('currentUser.permissions.length', 'job.repo.id'),
|
||||||
|
|
||||||
|
canRemoveLog: function() {
|
||||||
|
var job;
|
||||||
|
if (job = this.get('job')) {
|
||||||
|
return job.get('canRemoveLog') && this.get('hasPermission');
|
||||||
|
}
|
||||||
|
}.property('job.canRemoveLog', 'hasPermission'),
|
||||||
|
|
||||||
|
showToTop: function() {
|
||||||
|
return this.get('log.hasContent') && this.get('job.canRemoveLog');
|
||||||
|
}.property('log.hasContent', 'job.canRemoveLog'),
|
||||||
|
|
||||||
|
showTailing: Ember.computed.alias('showToTop'),
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
toTop() {
|
||||||
|
Travis.tailing.stop();
|
||||||
|
return $(window).scrollTop(0);
|
||||||
|
},
|
||||||
|
|
||||||
|
toggleTailing() {
|
||||||
|
Travis.tailing.toggle();
|
||||||
|
this.engine.autoCloseFold = !Travis.tailing.isActive();
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
removeLogPopup() {
|
||||||
|
if (this.get('canRemoveLog')) {
|
||||||
|
this.get('popup').open('remove-log-popup');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
toggleLog() {
|
||||||
|
this.toggleProperty('logIsVisible');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// don't remove this, it's needed as an empty willChange callback
|
||||||
|
noop: function() {}
|
||||||
|
});
|
|
@ -1,19 +0,0 @@
|
||||||
`import Ember from 'ember'`
|
|
||||||
`import config from 'travis/config/environment'`
|
|
||||||
|
|
||||||
NoBuildsComponent = Ember.Component.extend
|
|
||||||
actions:
|
|
||||||
triggerBuild: () ->
|
|
||||||
@set('isLoading', true)
|
|
||||||
apiEndpoint = config.apiEndpoint
|
|
||||||
$.ajax(apiEndpoint + "/v3/repo/#{@get('repo.repo.id')}/requests", {
|
|
||||||
headers: {
|
|
||||||
Authorization: 'token ' + @get('repo.auth')
|
|
||||||
},
|
|
||||||
type: "POST"
|
|
||||||
}).then( =>
|
|
||||||
@set('isLoading', false)
|
|
||||||
# @transitionToRoute('repo')
|
|
||||||
);
|
|
||||||
|
|
||||||
`export default NoBuildsComponent`
|
|
20
app/components/no-builds.js
Normal file
20
app/components/no-builds.js
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
import config from 'travis/config/environment';
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
actions: {
|
||||||
|
triggerBuild() {
|
||||||
|
var apiEndpoint;
|
||||||
|
this.set('isLoading', true);
|
||||||
|
apiEndpoint = config.apiEndpoint;
|
||||||
|
return $.ajax(apiEndpoint + ("/v3/repo/" + (this.get('repo.repo.id')) + "/requests"), {
|
||||||
|
headers: {
|
||||||
|
Authorization: 'token ' + this.get('repo.auth')
|
||||||
|
},
|
||||||
|
type: "POST"
|
||||||
|
}).then(() => {
|
||||||
|
return this.set('isLoading', false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
|
@ -1,5 +0,0 @@
|
||||||
`import Ember from 'ember'`
|
|
||||||
|
|
||||||
NoReposComponent = Ember.Component.extend()
|
|
||||||
|
|
||||||
`export default NoReposComponent`
|
|
3
app/components/no-repos.js
Normal file
3
app/components/no-repos.js
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
|
||||||
|
export default Ember.Component.extend();
|
|
@ -1,5 +0,0 @@
|
||||||
`import Ember from 'ember'`
|
|
||||||
|
|
||||||
NotActiveComponent = Ember.Component.extend()
|
|
||||||
|
|
||||||
`export default NotActiveComponent`
|
|
3
app/components/not-active.js
Normal file
3
app/components/not-active.js
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
|
||||||
|
export default Ember.Component.extend();
|
|
@ -1,28 +0,0 @@
|
||||||
`import Ember from 'ember'`
|
|
||||||
|
|
||||||
OrgItemComponent = Ember.Component.extend
|
|
||||||
|
|
||||||
classNames: ['media', 'account']
|
|
||||||
tagName: 'li'
|
|
||||||
classNameBindings: ['type', 'selected']
|
|
||||||
typeBinding: 'account.type'
|
|
||||||
selectedBinding: 'account.selected'
|
|
||||||
tokenIsVisible: false
|
|
||||||
|
|
||||||
name: (->
|
|
||||||
@get('account.name') || @get('account.login')
|
|
||||||
).property('account')
|
|
||||||
|
|
||||||
avatarUrl: (->
|
|
||||||
@get('account.avatarUrl') || false
|
|
||||||
).property('account')
|
|
||||||
|
|
||||||
isUser: (->
|
|
||||||
@get('account.type') == 'user'
|
|
||||||
).property('account')
|
|
||||||
|
|
||||||
actions:
|
|
||||||
tokenVisibility: () ->
|
|
||||||
@toggleProperty('tokenIsVisible')
|
|
||||||
|
|
||||||
`export default OrgItemComponent`
|
|
28
app/components/org-item.js
Normal file
28
app/components/org-item.js
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
classNames: ['media', 'account'],
|
||||||
|
tagName: 'li',
|
||||||
|
classNameBindings: ['type', 'selected'],
|
||||||
|
typeBinding: 'account.type',
|
||||||
|
selectedBinding: 'account.selected',
|
||||||
|
tokenIsVisible: false,
|
||||||
|
|
||||||
|
name: function() {
|
||||||
|
return this.get('account.name') || this.get('account.login');
|
||||||
|
}.property('account'),
|
||||||
|
|
||||||
|
avatarUrl: function() {
|
||||||
|
return this.get('account.avatarUrl') || false;
|
||||||
|
}.property('account'),
|
||||||
|
|
||||||
|
isUser: function() {
|
||||||
|
return this.get('account.type') === 'user';
|
||||||
|
}.property('account'),
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
tokenVisibility() {
|
||||||
|
return this.toggleProperty('tokenIsVisible');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
|
@ -1,13 +0,0 @@
|
||||||
`import Ember from 'ember'`
|
|
||||||
|
|
||||||
Component = Ember.Component.extend
|
|
||||||
|
|
||||||
actions:
|
|
||||||
toggleOrgFilter: () ->
|
|
||||||
@toggleProperty('showFilter')
|
|
||||||
false
|
|
||||||
select: (org) ->
|
|
||||||
@toggleProperty('showFilter')
|
|
||||||
@sendAction('action', org)
|
|
||||||
|
|
||||||
`export default Component`
|
|
17
app/components/orgs-filter.js
Normal file
17
app/components/orgs-filter.js
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
|
||||||
|
classNames: ['organisation-filter'],
|
||||||
|
actions: {
|
||||||
|
toggleOrgFilter() {
|
||||||
|
this.toggleProperty('showFilter');
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
select(org) {
|
||||||
|
this.toggleProperty('showFilter');
|
||||||
|
return this.sendAction('action', org);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
|
@ -1,29 +0,0 @@
|
||||||
`import Ember from 'ember'`
|
|
||||||
|
|
||||||
OwnerRepoTileComponent = Ember.Component.extend
|
|
||||||
|
|
||||||
tagName: 'li'
|
|
||||||
classNames: ['owner-tile', 'row-li']
|
|
||||||
classNameBindings: ['repo.default_branch.last_build.state']
|
|
||||||
|
|
||||||
ownerName: (->
|
|
||||||
@get('repo.slug').split(/\//)[0]
|
|
||||||
).property('repo.slug')
|
|
||||||
|
|
||||||
repoName: (->
|
|
||||||
@get('repo.slug').split(/\//)[1]
|
|
||||||
).property('repo.slug')
|
|
||||||
|
|
||||||
isAnimating: (->
|
|
||||||
state = @get('repo.default_branch.last_build.state')
|
|
||||||
animationStates = ['received', 'queued', 'started', 'booting']
|
|
||||||
|
|
||||||
unless animationStates.indexOf(state) == -1
|
|
||||||
true
|
|
||||||
|
|
||||||
).property('repo.default_branch.last_build.state')
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
`export default OwnerRepoTileComponent`
|
|
24
app/components/owner-repo-tile.js
Normal file
24
app/components/owner-repo-tile.js
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
tagName: 'li',
|
||||||
|
classNames: ['owner-tile', 'row-li'],
|
||||||
|
classNameBindings: ['repo.default_branch.last_build.state'],
|
||||||
|
|
||||||
|
ownerName: function() {
|
||||||
|
return this.get('repo.slug').split(/\//)[0];
|
||||||
|
}.property('repo.slug'),
|
||||||
|
|
||||||
|
repoName: function() {
|
||||||
|
return this.get('repo.slug').split(/\//)[1];
|
||||||
|
}.property('repo.slug'),
|
||||||
|
|
||||||
|
isAnimating: function() {
|
||||||
|
var animationStates, state;
|
||||||
|
state = this.get('repo.default_branch.last_build.state');
|
||||||
|
animationStates = ['received', 'queued', 'started', 'booting'];
|
||||||
|
if (animationStates.indexOf(state) !== -1) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}.property('repo.default_branch.last_build.state')
|
||||||
|
});
|
|
@ -1,6 +0,0 @@
|
||||||
`import Ember from 'ember'`
|
|
||||||
`import SyncButton from 'travis/components/sync-button'`
|
|
||||||
|
|
||||||
Component = SyncButton.extend()
|
|
||||||
|
|
||||||
`export default Component`
|
|
4
app/components/owner-sync-button.js
Normal file
4
app/components/owner-sync-button.js
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
import SyncButton from 'travis/components/sync-button';
|
||||||
|
|
||||||
|
export default SyncButton.extend();
|
17
app/components/popup-click-handler.js
Normal file
17
app/components/popup-click-handler.js
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
popup: Ember.inject.service(),
|
||||||
|
classNames: ['application'],
|
||||||
|
|
||||||
|
click(event) {
|
||||||
|
var targetAndParents = $(event.target).parents().andSelf();
|
||||||
|
|
||||||
|
if (!(targetAndParents.hasClass('open-popup') || targetAndParents.hasClass('popup'))) {
|
||||||
|
this.get('popup').close();
|
||||||
|
}
|
||||||
|
if (!targetAndParents.hasClass('menu') && !targetAndParents.is('#tools > a')) {
|
||||||
|
$('.menu').removeClass('display');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
6
app/components/profile-accounts-wrapper.js
Normal file
6
app/components/profile-accounts-wrapper.js
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
classNames: ['profile-orglist', 'columns', 'medium-4'],
|
||||||
|
tagName: 'aside',
|
||||||
|
});
|
|
@ -1,16 +0,0 @@
|
||||||
`import Ember from 'ember'`
|
|
||||||
`import config from 'travis/config/environment'`
|
|
||||||
|
|
||||||
QueuedJobsComponent = Ember.Component.extend
|
|
||||||
store: Ember.inject.service()
|
|
||||||
|
|
||||||
init: ->
|
|
||||||
@_super.apply this, arguments
|
|
||||||
if !Ember.testing
|
|
||||||
Visibility.every config.intervals.updateTimes, @updateTimes.bind(this)
|
|
||||||
|
|
||||||
updateTimes: ->
|
|
||||||
if jobs = @get('jobs')
|
|
||||||
jobs.forEach (job) -> job.updateTimes()
|
|
||||||
|
|
||||||
`export default QueuedJobsComponent`
|
|
18
app/components/queued-jobs.js
Normal file
18
app/components/queued-jobs.js
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
import config from 'travis/config/environment';
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
store: Ember.inject.service(),
|
||||||
|
updateTimesService: Ember.inject.service('updateTimes'),
|
||||||
|
|
||||||
|
init() {
|
||||||
|
this._super.apply(this, arguments);
|
||||||
|
if (!Ember.testing) {
|
||||||
|
return Visibility.every(config.intervals.updateTimes, this.updateTimes.bind(this));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
updateTimes() {
|
||||||
|
this.get('updateTimesService').push(this.get('jobs'));
|
||||||
|
}
|
||||||
|
});
|
|
@ -1,23 +0,0 @@
|
||||||
`import Ember from 'ember'`
|
|
||||||
|
|
||||||
Component = Ember.Component.extend(
|
|
||||||
actions:
|
|
||||||
close: ->
|
|
||||||
$('.popup').removeClass('display')
|
|
||||||
return false
|
|
||||||
|
|
||||||
removeLog: ->
|
|
||||||
$('.popup').removeClass('display')
|
|
||||||
job = @get('job')
|
|
||||||
job.removeLog().then ->
|
|
||||||
Travis.flash(success: 'Log has been successfully removed.')
|
|
||||||
, (xhr) ->
|
|
||||||
if xhr.status == 409
|
|
||||||
Travis.flash(error: 'Log can\'t be removed')
|
|
||||||
else if xhr.status == 401
|
|
||||||
Travis.flash(error: 'You don\'t have sufficient access to remove the log')
|
|
||||||
else
|
|
||||||
Travis.flash(error: 'An error occured when removing the log')
|
|
||||||
)
|
|
||||||
|
|
||||||
`export default Component`
|
|
27
app/components/remove-log-popup.js
Normal file
27
app/components/remove-log-popup.js
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
actions: {
|
||||||
|
close() {
|
||||||
|
$('.popup').removeClass('display');
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
removeLog() {
|
||||||
|
var job = this.get('job');
|
||||||
|
$('.popup').removeClass('display');
|
||||||
|
|
||||||
|
return job.removeLog().then(function() {
|
||||||
|
return Travis.flash({ success: 'Log has been successfully removed.' });
|
||||||
|
}, function(xhr) {
|
||||||
|
if (xhr.status === 409) {
|
||||||
|
return Travis.flash({ error: 'Log can\'t be removed' });
|
||||||
|
} else if (xhr.status === 401) {
|
||||||
|
return Travis.flash({ error: 'You don\'t have sufficient access to remove the log' });
|
||||||
|
} else {
|
||||||
|
return Travis.flash({ error: 'An error occured when removing the log' });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
|
@ -1,15 +0,0 @@
|
||||||
`import Ember from 'ember'`
|
|
||||||
|
|
||||||
RepoActionsComponent = Ember.Component.extend(
|
|
||||||
displayCodeClimate: (->
|
|
||||||
@get('repo.githubLanguage') == 'Ruby'
|
|
||||||
).property('repo.githubLanguage')
|
|
||||||
|
|
||||||
actions:
|
|
||||||
codeClimatePopup: ->
|
|
||||||
$('.popup').removeClass('display')
|
|
||||||
$('#code-climate').addClass('display')
|
|
||||||
return false
|
|
||||||
)
|
|
||||||
|
|
||||||
`export default RepoActionsComponent`
|
|
7
app/components/repo-actions.js
Normal file
7
app/components/repo-actions.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
|
||||||
|
classNames: ['repo-main-tools']
|
||||||
|
|
||||||
|
});
|
|
@ -1,55 +0,0 @@
|
||||||
`import Ember from 'ember'`
|
|
||||||
|
|
||||||
RepoShowTabsComponent = Ember.Component.extend
|
|
||||||
|
|
||||||
tagName: 'nav'
|
|
||||||
classNames: ['tabnav']
|
|
||||||
ariaRole: 'tablist'
|
|
||||||
|
|
||||||
# hrm. how to parametrize bind-attr?
|
|
||||||
classCurrent: (->
|
|
||||||
'active' if @get('tab') == 'current'
|
|
||||||
).property('tab')
|
|
||||||
|
|
||||||
classBuilds: (->
|
|
||||||
'active' if @get('tab') == 'builds'
|
|
||||||
).property('tab')
|
|
||||||
|
|
||||||
classPullRequests: (->
|
|
||||||
'active' if @get('tab') == 'pull_requests'
|
|
||||||
).property('tab')
|
|
||||||
|
|
||||||
classBranches: (->
|
|
||||||
'active' if @get('tab') == 'branches'
|
|
||||||
).property('tab')
|
|
||||||
|
|
||||||
classBuild: (->
|
|
||||||
tab = @get('tab')
|
|
||||||
classes = []
|
|
||||||
classes.push('active') if tab == 'build'
|
|
||||||
classes.push('display-inline') if tab == 'build' || tab == 'job'
|
|
||||||
classes.join(' ')
|
|
||||||
).property('tab')
|
|
||||||
|
|
||||||
# TODO: refactor tabs, most of the things here are not really DRY
|
|
||||||
classJob: (->
|
|
||||||
'active' if @get('tab') == 'job'
|
|
||||||
).property('tab')
|
|
||||||
|
|
||||||
classRequests: (->
|
|
||||||
'active' if @get('tab') == 'requests'
|
|
||||||
).property('tab')
|
|
||||||
|
|
||||||
classCaches: (->
|
|
||||||
'active' if @get('tab') == 'caches'
|
|
||||||
).property('tab')
|
|
||||||
|
|
||||||
classSettings: (->
|
|
||||||
'active' if @get('tab') == 'settings'
|
|
||||||
).property('tab')
|
|
||||||
|
|
||||||
classRequest: (->
|
|
||||||
'active' if @get('tab') == 'request'
|
|
||||||
).property('tab')
|
|
||||||
|
|
||||||
`export default RepoShowTabsComponent`
|
|
74
app/components/repo-show-tabs.js
Normal file
74
app/components/repo-show-tabs.js
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
tagName: 'nav',
|
||||||
|
classNames: ['tabnav'],
|
||||||
|
ariaRole: 'tablist',
|
||||||
|
|
||||||
|
classCurrent: function() {
|
||||||
|
if (this.get('tab') === 'current') {
|
||||||
|
return 'active';
|
||||||
|
}
|
||||||
|
}.property('tab'),
|
||||||
|
|
||||||
|
classBuilds: function() {
|
||||||
|
if (this.get('tab') === 'builds') {
|
||||||
|
return 'active';
|
||||||
|
}
|
||||||
|
}.property('tab'),
|
||||||
|
|
||||||
|
classPullRequests: function() {
|
||||||
|
if (this.get('tab') === 'pull_requests') {
|
||||||
|
return 'active';
|
||||||
|
}
|
||||||
|
}.property('tab'),
|
||||||
|
|
||||||
|
classBranches: function() {
|
||||||
|
if (this.get('tab') === 'branches') {
|
||||||
|
return 'active';
|
||||||
|
}
|
||||||
|
}.property('tab'),
|
||||||
|
|
||||||
|
classBuild: function() {
|
||||||
|
var classes, tab;
|
||||||
|
tab = this.get('tab');
|
||||||
|
classes = [];
|
||||||
|
if (tab === 'build') {
|
||||||
|
classes.push('active');
|
||||||
|
}
|
||||||
|
if (tab === 'build' || tab === 'job') {
|
||||||
|
classes.push('display-inline');
|
||||||
|
}
|
||||||
|
return classes.join(' ');
|
||||||
|
}.property('tab'),
|
||||||
|
|
||||||
|
classJob: function() {
|
||||||
|
if (this.get('tab') === 'job') {
|
||||||
|
return 'active';
|
||||||
|
}
|
||||||
|
}.property('tab'),
|
||||||
|
|
||||||
|
classRequests: function() {
|
||||||
|
if (this.get('tab') === 'requests') {
|
||||||
|
return 'active';
|
||||||
|
}
|
||||||
|
}.property('tab'),
|
||||||
|
|
||||||
|
classCaches: function() {
|
||||||
|
if (this.get('tab') === 'caches') {
|
||||||
|
return 'active';
|
||||||
|
}
|
||||||
|
}.property('tab'),
|
||||||
|
|
||||||
|
classSettings: function() {
|
||||||
|
if (this.get('tab') === 'settings') {
|
||||||
|
return 'active';
|
||||||
|
}
|
||||||
|
}.property('tab'),
|
||||||
|
|
||||||
|
classRequest: function() {
|
||||||
|
if (this.get('tab') === 'request') {
|
||||||
|
return 'active';
|
||||||
|
}
|
||||||
|
}.property('tab')
|
||||||
|
});
|
|
@ -1,49 +0,0 @@
|
||||||
`import Ember from 'ember'`
|
|
||||||
`import config from 'travis/config/environment'`
|
|
||||||
|
|
||||||
RepoShowToolsComponent = Ember.Component.extend
|
|
||||||
popup: Ember.inject.service()
|
|
||||||
|
|
||||||
classNames: ['settings-menu']
|
|
||||||
classNameBindings: ['isOpen:display']
|
|
||||||
isOpen: false
|
|
||||||
|
|
||||||
click: (event) ->
|
|
||||||
if $(event.target).is('a') && $(event.target).parents('.settings-dropdown').length
|
|
||||||
@closeMenu()
|
|
||||||
|
|
||||||
closeMenu: ->
|
|
||||||
@toggleProperty('isOpen')
|
|
||||||
|
|
||||||
actions:
|
|
||||||
menu: ->
|
|
||||||
@toggleProperty('isOpen')
|
|
||||||
|
|
||||||
hasPermission: (->
|
|
||||||
if permissions = @get('currentUser.permissions')
|
|
||||||
permissions.contains parseInt(@get('repo.id'))
|
|
||||||
).property('currentUser.permissions.length', 'repo.id')
|
|
||||||
|
|
||||||
hasPushPermission: (->
|
|
||||||
if permissions = @get('currentUser.pushPermissions')
|
|
||||||
permissions.contains parseInt(@get('repo.id'))
|
|
||||||
).property('currentUser.pushPermissions.length', 'repo.id')
|
|
||||||
|
|
||||||
hasAdminPermission: (->
|
|
||||||
if permissions = @get('currentUser.adminPermissions')
|
|
||||||
permissions.contains parseInt(@get('repo.id'))
|
|
||||||
).property('currentUser.adminPermissions.length', 'repo.id')
|
|
||||||
|
|
||||||
displaySettingsLink: (->
|
|
||||||
@get('hasPushPermission')
|
|
||||||
).property('hasPushPermission')
|
|
||||||
|
|
||||||
displayCachesLink: (->
|
|
||||||
@get('hasPushPermission') && config.endpoints.caches
|
|
||||||
).property('hasPushPermission')
|
|
||||||
|
|
||||||
displayStatusImages: (->
|
|
||||||
@get('hasPermission')
|
|
||||||
).property('hasPermission')
|
|
||||||
|
|
||||||
`export default RepoShowToolsComponent`
|
|
38
app/components/repo-show-tools.js
Normal file
38
app/components/repo-show-tools.js
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
import config from 'travis/config/environment';
|
||||||
|
import { hasPermission, hasPushPermission } from 'travis/utils/permission';
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
popup: Ember.inject.service(),
|
||||||
|
classNames: ['option-button'],
|
||||||
|
classNameBindings: ['isOpen:display'],
|
||||||
|
isOpen: false,
|
||||||
|
|
||||||
|
click(event) {
|
||||||
|
if ($(event.target).is('a') && $(event.target).parents('.settings-dropdown').length) {
|
||||||
|
return this.closeMenu();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
closeMenu() {
|
||||||
|
return this.toggleProperty('isOpen');
|
||||||
|
},
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
menu() {
|
||||||
|
return this.toggleProperty('isOpen');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
displaySettingsLink: function() {
|
||||||
|
return hasPushPermission(this.get('currentUser'), this.get('repo.id'));
|
||||||
|
}.property('currentUser.pushPermissions.length', 'repo'),
|
||||||
|
|
||||||
|
displayCachesLink: function() {
|
||||||
|
return hasPushPermission(this.get('currentUser'), this.get('repo.id')) && config.endpoints.caches;
|
||||||
|
}.property('currentUser.pushPermissions.length', 'repo'),
|
||||||
|
|
||||||
|
displayStatusImages: function() {
|
||||||
|
return hasPermission(this.get('currentUser'), this.get('repo.id'));
|
||||||
|
}.property('currentUser.permissions.length', 'repo.id')
|
||||||
|
|
||||||
|
});
|
7
app/components/repo-wrapper.js
Normal file
7
app/components/repo-wrapper.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import Polling from 'travis/mixins/polling';
|
||||||
|
import Ember from 'ember';
|
||||||
|
|
||||||
|
export default Ember.Component.extend(Polling, {
|
||||||
|
pollModels: 'repo',
|
||||||
|
classNameBindings: ['isLoading:loading']
|
||||||
|
});
|
|
@ -1,5 +0,0 @@
|
||||||
`import Ember from 'ember'`
|
|
||||||
|
|
||||||
ReposEmptyComponent = Ember.Component.extend()
|
|
||||||
|
|
||||||
`export default ReposEmptyComponent`
|
|
3
app/components/repos-empty.js
Normal file
3
app/components/repos-empty.js
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
|
||||||
|
export default Ember.Component.extend();
|
|
@ -1,31 +0,0 @@
|
||||||
`import Ember from 'ember'`
|
|
||||||
`import Polling from 'travis/mixins/polling'`
|
|
||||||
`import { colorForState } from 'travis/utils/helpers'`
|
|
||||||
|
|
||||||
ReposListItemComponent = Ember.Component.extend Polling,
|
|
||||||
routing: Ember.inject.service('-routing')
|
|
||||||
|
|
||||||
tagName: 'li'
|
|
||||||
|
|
||||||
pollModels: 'repo'
|
|
||||||
|
|
||||||
classNames: ['repo']
|
|
||||||
classNameBindings: ['selected']
|
|
||||||
selected: (->
|
|
||||||
@get('repo') == @get('selectedRepo')
|
|
||||||
).property('selectedRepo')
|
|
||||||
|
|
||||||
color: (->
|
|
||||||
colorForState(@get('repo.lastBuildState'))
|
|
||||||
).property('repo.lastBuildState')
|
|
||||||
|
|
||||||
scrollTop: (->
|
|
||||||
if (window.scrollY > 0)
|
|
||||||
$('html, body').animate({scrollTop: 0}, 200)
|
|
||||||
)
|
|
||||||
|
|
||||||
click: ->
|
|
||||||
@scrollTop()
|
|
||||||
@get('routing').transitionTo('repo', @get('repo.slug').split('/'))
|
|
||||||
|
|
||||||
`export default ReposListItemComponent`
|
|
27
app/components/repos-list-item.js
Normal file
27
app/components/repos-list-item.js
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
import Polling from 'travis/mixins/polling';
|
||||||
|
import { colorForState } from 'travis/utils/helpers';
|
||||||
|
|
||||||
|
export default Ember.Component.extend(Polling, {
|
||||||
|
routing: Ember.inject.service('-routing'),
|
||||||
|
tagName: 'li',
|
||||||
|
pollModels: 'repo',
|
||||||
|
classNames: ['repo'],
|
||||||
|
classNameBindings: ['selected'],
|
||||||
|
|
||||||
|
selected: function() {
|
||||||
|
return this.get('repo') === this.get('selectedRepo');
|
||||||
|
}.property('selectedRepo'),
|
||||||
|
|
||||||
|
color: function() {
|
||||||
|
return colorForState(this.get('repo.lastBuildState'));
|
||||||
|
}.property('repo.lastBuildState'),
|
||||||
|
|
||||||
|
scrollTop: function() {
|
||||||
|
if (window.scrollY > 0) {
|
||||||
|
return $('html, body').animate({
|
||||||
|
scrollTop: 0
|
||||||
|
}, 200);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
48
app/components/repos-list-tabs.js
Normal file
48
app/components/repos-list-tabs.js
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
auth: Ember.inject.service(),
|
||||||
|
|
||||||
|
currentUserBinding: 'auth.currentUser',
|
||||||
|
|
||||||
|
classRecent: function() {
|
||||||
|
if (this.get('tab') === 'recent') {
|
||||||
|
return 'active';
|
||||||
|
} else if (this.get('tab') === 'search' && this.get('auth.signedIn')) {
|
||||||
|
return 'hidden';
|
||||||
|
}
|
||||||
|
}.property('tab'),
|
||||||
|
|
||||||
|
classRunning: function() {
|
||||||
|
var classes;
|
||||||
|
classes = [];
|
||||||
|
if (this.get('tab') === 'running') {
|
||||||
|
classes.push('active');
|
||||||
|
}
|
||||||
|
return classes.join(' ');
|
||||||
|
}.property('tab'),
|
||||||
|
|
||||||
|
classOwned: function() {
|
||||||
|
var classes;
|
||||||
|
classes = [];
|
||||||
|
if (this.get('tab') === 'owned') {
|
||||||
|
classes.push('active');
|
||||||
|
}
|
||||||
|
if (this.get('currentUser')) {
|
||||||
|
classes.push('display-inline');
|
||||||
|
}
|
||||||
|
return classes.join(' ');
|
||||||
|
}.property('tab', 'currentUser'),
|
||||||
|
|
||||||
|
classSearch: function() {
|
||||||
|
if (this.get('tab') === 'search') {
|
||||||
|
return 'active';
|
||||||
|
}
|
||||||
|
}.property('tab'),
|
||||||
|
|
||||||
|
classNew: function() {
|
||||||
|
if (this.get('currentUser')) {
|
||||||
|
return 'display-inline';
|
||||||
|
}
|
||||||
|
}.property('currentUser')
|
||||||
|
});
|
|
@ -1,25 +0,0 @@
|
||||||
`import Ember from 'ember'`
|
|
||||||
|
|
||||||
RequestIconComponent = Ember.Component.extend
|
|
||||||
|
|
||||||
tagName: 'span'
|
|
||||||
classNames: ['status-icon', 'icon']
|
|
||||||
classNameBindings: ['event', 'state']
|
|
||||||
|
|
||||||
isPush: (->
|
|
||||||
@get('event') == 'push'
|
|
||||||
).property('event')
|
|
||||||
|
|
||||||
isPR: (->
|
|
||||||
@get('event') == 'pull_request'
|
|
||||||
).property('event')
|
|
||||||
|
|
||||||
isAPI: (->
|
|
||||||
@get('event') == 'api'
|
|
||||||
).property('event')
|
|
||||||
|
|
||||||
isEmpty: (->
|
|
||||||
true if @get('event') == null || @get('event') == null
|
|
||||||
).property('event')
|
|
||||||
|
|
||||||
`export default RequestIconComponent`
|
|
25
app/components/request-icon.js
Normal file
25
app/components/request-icon.js
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
import Ember from 'ember';
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
tagName: 'span',
|
||||||
|
classNames: ['request-icon', 'icon'],
|
||||||
|
classNameBindings: ['event', 'state'],
|
||||||
|
|
||||||
|
isPush: function() {
|
||||||
|
return this.get('event') === 'push';
|
||||||
|
}.property('event'),
|
||||||
|
|
||||||
|
isPR: function() {
|
||||||
|
return this.get('event') === 'pull_request';
|
||||||
|
}.property('event'),
|
||||||
|
|
||||||
|
isAPI: function() {
|
||||||
|
return this.get('event') === 'api';
|
||||||
|
}.property('event'),
|
||||||
|
|
||||||
|
isEmpty: function() {
|
||||||
|
if (this.get('event') === null || this.get('event') === null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}.property('event')
|
||||||
|
});
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user