Merge branch 'master' into lp-no-builds
This commit is contained in:
commit
8795a932d0
|
@ -7,6 +7,15 @@ JobsItemComponent = Ember.Component.extend
|
||||||
classNameBindings: ['job.state']
|
classNameBindings: ['job.state']
|
||||||
classNames: ['tile', 'tile--jobs', 'row']
|
classNames: ['tile', 'tile--jobs', 'row']
|
||||||
|
|
||||||
|
isAnimating: (->
|
||||||
|
state = @get('job.state')
|
||||||
|
animationStates = ['received', 'queued', 'started', 'booting']
|
||||||
|
|
||||||
|
unless animationStates.indexOf(state) == -1
|
||||||
|
true
|
||||||
|
|
||||||
|
).property('job.state')
|
||||||
|
|
||||||
languages: (->
|
languages: (->
|
||||||
output = []
|
output = []
|
||||||
|
|
||||||
|
|
|
@ -42,12 +42,31 @@ Route = TravisRoute.extend
|
||||||
response.active
|
response.active
|
||||||
);
|
);
|
||||||
|
|
||||||
|
hasPushAccess: ->
|
||||||
|
repoId = parseInt @modelFor('repo').get('id')
|
||||||
|
pushAccess = true
|
||||||
|
|
||||||
|
Ajax.get '/users/permissions', (data) =>
|
||||||
|
|
||||||
|
admin = data.admin.filter (item) ->
|
||||||
|
return item == repoId
|
||||||
|
push = data.push.filter (item) ->
|
||||||
|
return item == repoId
|
||||||
|
pull = data.pull.filter (item) ->
|
||||||
|
return item == repoId
|
||||||
|
|
||||||
|
if Ember.isEmpty admin && Ember.isEmpty push && !Ember.isEmpty pull
|
||||||
|
pushAccess = false
|
||||||
|
|
||||||
|
pushAccess
|
||||||
|
|
||||||
model: () ->
|
model: () ->
|
||||||
return Ember.RSVP.hash({
|
return Ember.RSVP.hash({
|
||||||
settings: @modelFor('repo').fetchSettings(),
|
settings: @modelFor('repo').fetchSettings(),
|
||||||
envVars: this.fetchEnvVars(),
|
envVars: this.fetchEnvVars(),
|
||||||
sshKey: this.fetchSshKey(),
|
sshKey: this.fetchSshKey(),
|
||||||
customSshKey: this.fetchCustomSshKey(),
|
customSshKey: this.fetchCustomSshKey(),
|
||||||
|
hasPushAccess: this.hasPushAccess(),
|
||||||
repositoryActive: this.fetchRepositoryActiveFlag()
|
repositoryActive: this.fetchRepositoryActiveFlag()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,9 @@
|
||||||
.tile-status--job
|
.tile-status--job
|
||||||
width: 2em
|
width: 2em
|
||||||
|
|
||||||
|
.svg-booting
|
||||||
|
margin: 0.7em 0.3em
|
||||||
|
|
||||||
.jobs-item
|
.jobs-item
|
||||||
padding: .1em 0
|
padding: .1em 0
|
||||||
.icon
|
.icon
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
.requests-time
|
.requests-time
|
||||||
@media #{$medium-up}
|
@media #{$medium-up}
|
||||||
padding-left: 2em
|
padding-left: 2em
|
||||||
border-left: 1px solid $grey-lighter
|
border-left: 1px solid $cream-dark
|
||||||
|
|
||||||
.tile--jobs
|
.tile--jobs
|
||||||
padding-left: 2.5em
|
padding-left: 2.5em
|
||||||
|
|
|
@ -121,22 +121,19 @@
|
||||||
|
|
||||||
.icon--env
|
.icon--env
|
||||||
background-image: inline-image('svg/icon-environment-dark2.svg')
|
background-image: inline-image('svg/icon-environment-dark2.svg')
|
||||||
.icon--cross-red,
|
|
||||||
.icon--job.failed,
|
.icon--job.failed,
|
||||||
.icon--job.rejected
|
.icon--job.rejected
|
||||||
background-image: inline-image('svg/icon-job-failed.svg')
|
background-image: inline-image('svg/icon-job-failed.svg')
|
||||||
.icon--check-green,
|
|
||||||
.icon--job.passed,
|
.icon--job.passed,
|
||||||
.icon--job.accepted
|
.icon--job.accepted
|
||||||
background-image: inline-image('svg/icon-job-passed.svg')
|
background-image: inline-image('svg/icon-job-passed.svg')
|
||||||
.icon--error-grey,
|
|
||||||
.icon--job.errored
|
.icon--job.errored
|
||||||
background-image: inline-image('svg/icon-job-errored.svg')
|
background-image: inline-image('svg/icon-job-errored.svg')
|
||||||
.icon--job.started,
|
.icon--job.started,
|
||||||
.icon--job.created,
|
|
||||||
.icon--job.received,
|
|
||||||
.icon--job.queued,
|
.icon--job.queued,
|
||||||
.icon--started-yellow
|
.icon--job.booting,
|
||||||
|
.icon--job.received,
|
||||||
|
.icon--job.created,
|
||||||
background-image: inline-image('svg/icon-job-started.svg')
|
background-image: inline-image('svg/icon-job-started.svg')
|
||||||
.icon--job.canceled
|
.icon--job.canceled
|
||||||
background-image: inline-image('svg/icon-job-canceled.svg')
|
background-image: inline-image('svg/icon-job-canceled.svg')
|
||||||
|
@ -210,3 +207,29 @@
|
||||||
|
|
||||||
.icon-flag
|
.icon-flag
|
||||||
background-image: inline-image('svg/notice-flag.svg')
|
background-image: inline-image('svg/notice-flag.svg')
|
||||||
|
|
||||||
|
|
||||||
|
.icon-receiving
|
||||||
|
margin: 0.3rem 0.5rem;
|
||||||
|
display: inline-block;
|
||||||
|
i
|
||||||
|
width: 4px
|
||||||
|
height: 4px
|
||||||
|
border-radius: 50%
|
||||||
|
display: inline-block
|
||||||
|
background-color: $start-bg-color
|
||||||
|
transform-origin: center center
|
||||||
|
animation: bubbleScale 1.2s infinite linear
|
||||||
|
i:nth-of-type(2)
|
||||||
|
animation-delay: 0.35s
|
||||||
|
i:nth-of-type(3)
|
||||||
|
animation-delay: 0.7s
|
||||||
|
|
||||||
|
|
||||||
|
@keyframes bubbleScale
|
||||||
|
0%, 80%, 100%
|
||||||
|
transform: scale(0)
|
||||||
|
|
||||||
|
40%
|
||||||
|
transform: scale(1.0)
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,4 @@
|
||||||
%tooltip
|
%tooltip
|
||||||
&:hover .tooltip-bubble
|
|
||||||
transform: translateY(0)
|
|
||||||
opacity: 1
|
|
||||||
|
|
||||||
.tooltip-bubble
|
.tooltip-bubble
|
||||||
position: absolute
|
position: absolute
|
||||||
top: -2.8em
|
top: -2.8em
|
||||||
|
@ -18,6 +14,7 @@
|
||||||
line-height: 1.3
|
line-height: 1.3
|
||||||
text-align: center
|
text-align: center
|
||||||
white-space: nowrap
|
white-space: nowrap
|
||||||
|
visibility: hidden
|
||||||
|
|
||||||
transition: all 100ms ease
|
transition: all 100ms ease
|
||||||
transform: translateY(20%)
|
transform: translateY(20%)
|
||||||
|
@ -27,7 +24,6 @@
|
||||||
color: $white
|
color: $white
|
||||||
&:hover
|
&:hover
|
||||||
text-decoration: underline
|
text-decoration: underline
|
||||||
|
|
||||||
&:before
|
&:before
|
||||||
content: ""
|
content: ""
|
||||||
position: absolute
|
position: absolute
|
||||||
|
@ -38,6 +34,11 @@
|
||||||
z-index: -1
|
z-index: -1
|
||||||
background-color: #818383
|
background-color: #818383
|
||||||
|
|
||||||
|
&:hover .tooltip-bubble
|
||||||
|
transform: translateY(0)
|
||||||
|
opacity: 1
|
||||||
|
visibility: visible
|
||||||
|
|
||||||
.tooltip
|
.tooltip
|
||||||
@extend %tooltip
|
@extend %tooltip
|
||||||
.tooltip-bubble
|
.tooltip-bubble
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
.feedback-button
|
.feedback-button
|
||||||
display: none
|
display: none
|
||||||
position: fixed
|
position: fixed
|
||||||
right: 4%
|
right: 9%
|
||||||
left: auto
|
left: auto
|
||||||
bottom: 0
|
bottom: 0
|
||||||
margin: 0
|
margin: 0
|
||||||
|
@ -17,6 +17,9 @@
|
||||||
color: #399399
|
color: #399399
|
||||||
z-index: 89
|
z-index: 89
|
||||||
|
|
||||||
|
@media #{$medium-up}
|
||||||
|
right: 5%
|
||||||
|
|
||||||
.feedback-button:hover
|
.feedback-button:hover
|
||||||
transform: translateY(5%)
|
transform: translateY(5%)
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
{{#link-to "job" repo job}}
|
{{#link-to "job" repo job}}
|
||||||
<div class="tile-status tile-status--job">
|
<div class="tile-status tile-status--job">
|
||||||
<span class="icon icon--job {{job.state}}"></span>
|
{{#if isAnimating}}
|
||||||
|
<span class="icon-receiving"><i></i><i></i><i></i></span>
|
||||||
|
{{else}}
|
||||||
|
<span class="icon icon--job {{job.state}}"></span>
|
||||||
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p class="job-id jobs-item build-status">
|
<p class="job-id jobs-item build-status">
|
||||||
|
|
|
@ -11,12 +11,19 @@
|
||||||
{{#if isDeleting}}
|
{{#if isDeleting}}
|
||||||
{{loading-indicator}}
|
{{loading-indicator}}
|
||||||
{{else}}
|
{{else}}
|
||||||
<div class="tooltip">
|
{{#if pushAccess}}
|
||||||
<a href="#" title="" {{action "delete"}}>
|
<div class="tooltip">
|
||||||
<span class="icon-delete"></span>
|
<a href="#" title="" {{action "delete"}}>
|
||||||
</a>
|
<span class="icon-delete"></span>
|
||||||
<div class="tooltip-bubble">Delete</div>
|
</a>
|
||||||
</div>
|
<div class="tooltip-bubble">Delete</div>
|
||||||
|
</div>
|
||||||
|
{{else}}
|
||||||
|
<div class="tooltip--height">
|
||||||
|
<span class="icon-delete-disabled"></span>
|
||||||
|
<div class="tooltip-bubble">You can't<br>delete keys</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
|
|
|
@ -30,12 +30,19 @@
|
||||||
<h2 class="small-title">SSH Key</h2>
|
<h2 class="small-title">SSH Key</h2>
|
||||||
|
|
||||||
{{#if model.customSshKey}}
|
{{#if model.customSshKey}}
|
||||||
{{ssh-key key=model.customSshKey sshKeyDeleted="sshKeyDeleted"}}
|
{{ssh-key key=model.customSshKey sshKeyDeleted="sshKeyDeleted" pushAccess=model.hasPushAccess}}
|
||||||
{{else}}
|
{{else}}
|
||||||
{{ssh-key key=model.sshKey}}
|
{{ssh-key key=model.sshKey}}
|
||||||
{{add-ssh-key repo=repo sshKeyAdded="sshKeyAdded"}}
|
|
||||||
|
{{#if model.hasPushAccess}}
|
||||||
|
{{add-ssh-key repo=repo sshKeyAdded="sshKeyAdded"}}
|
||||||
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
{{#unless model.hasPushAccess}}
|
||||||
|
<p>You don't have sufficient permissons to add or remove ssh keys on this repository.</p>
|
||||||
|
{{/unless}}
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{!-- <section class="settings-section">
|
{{!-- <section class="settings-section">
|
||||||
|
|
|
@ -41,7 +41,7 @@ test('it renders the custom ssh key if custom key is set', function(assert) {
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
test('it deletes a custom key', function(assert) {
|
test('it deletes a custom key if permissions are right', function(assert) {
|
||||||
assert.expect(1);
|
assert.expect(1);
|
||||||
|
|
||||||
var store = this.container.lookup('store:main');
|
var store = this.container.lookup('store:main');
|
||||||
|
@ -52,7 +52,7 @@ test('it deletes a custom key', function(assert) {
|
||||||
});
|
});
|
||||||
|
|
||||||
this.set('key', key);
|
this.set('key', key);
|
||||||
this.render(hbs`{{ssh-key key=key sshKeyDeleted="sshKeyDeleted"}}`);
|
this.render(hbs`{{ssh-key key=key sshKeyDeleted="sshKeyDeleted" pushAccess=true}}`);
|
||||||
this.on('sshKeyDeleted', function() {});
|
this.on('sshKeyDeleted', function() {});
|
||||||
|
|
||||||
this.$('.ssh-key-action a').click();
|
this.$('.ssh-key-action a').click();
|
||||||
|
@ -60,3 +60,20 @@ test('it deletes a custom key', function(assert) {
|
||||||
assert.ok(key.get('isDeleted'), 'key should be deleted');
|
assert.ok(key.get('isDeleted'), 'key should be deleted');
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('it does not delete the custom key if permissions are insufficient', function(assert) {
|
||||||
|
assert.expect(1);
|
||||||
|
|
||||||
|
var store = this.container.lookup('store:main');
|
||||||
|
|
||||||
|
var key;
|
||||||
|
Ember.run(function() {
|
||||||
|
key = store.push('sshKey', {description: 'fookey', fingerprint: 'somethingthing', id: 1});
|
||||||
|
});
|
||||||
|
|
||||||
|
this.set('key', key);
|
||||||
|
this.render(hbs`{{ssh-key key=key sshKeyDeleted="sshKeyDeleted" pushAccess=false}}`);
|
||||||
|
|
||||||
|
assert.ok(Ember.isEmpty(this.$('.ssh-key-action').find('a')), 'delete link should not be displayed');
|
||||||
|
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user