diff options
author | Kamil Trzciński <ayufan@ayufan.eu> | 2017-04-05 23:01:35 +0000 |
---|---|---|
committer | Kamil Trzciński <ayufan@ayufan.eu> | 2017-04-05 23:01:35 +0000 |
commit | e3ce5b642e3cff6920f443a34a2e9b0099e07a88 (patch) | |
tree | a4836f8df9bed0d38ebaa2ec09807be64b41ef98 | |
parent | 08393ecaa65c3db5379da06d665e4e4b0ca28be4 (diff) | |
parent | 474236e85b0386cfad003c7c7669e49ad2341bec (diff) | |
download | gitlab-ce-e3ce5b642e3cff6920f443a34a2e9b0099e07a88.tar.gz |
Merge branch 'tc-fix-unplayable-build-action-404' into 'master'
Disable pipeline & environment actions that are not playable
Closes #25385 and #24601
See merge request !10052
12 files changed, 95 insertions, 7 deletions
diff --git a/app/assets/javascripts/environments/components/environment_actions.js b/app/assets/javascripts/environments/components/environment_actions.js index 385085c03e2..4bb7920bb5e 100644 --- a/app/assets/javascripts/environments/components/environment_actions.js +++ b/app/assets/javascripts/environments/components/environment_actions.js @@ -45,11 +45,20 @@ export default { new Flash('An error occured while making the request.'); }); }, + + isActionDisabled(action) { + if (action.playable === undefined) { + return false; + } + + return !action.playable; + }, }, template: ` <div class="btn-group" role="group"> <button + type="button" class="dropdown btn btn-default dropdown-new js-dropdown-play-icon-container has-tooltip" data-container="body" data-toggle="dropdown" @@ -58,15 +67,23 @@ export default { :disabled="isLoading"> <span> <span v-html="playIconSvg"></span> - <i class="fa fa-caret-down" aria-hidden="true"></i> - <i v-if="isLoading" class="fa fa-spinner fa-spin" aria-hidden="true"></i> + <i + class="fa fa-caret-down" + aria-hidden="true"/> + <i + v-if="isLoading" + class="fa fa-spinner fa-spin" + aria-hidden="true"/> </span> <ul class="dropdown-menu dropdown-menu-align-right"> <li v-for="action in actions"> <button + type="button" + class="js-manual-action-link no-btn btn" @click="onClickAction(action.play_path)" - class="js-manual-action-link no-btn"> + :class="{ 'disabled': isActionDisabled(action) }" + :disabled="isActionDisabled(action)"> ${playIconSvg} <span> {{action.name}} diff --git a/app/assets/javascripts/environments/components/environment_item.js b/app/assets/javascripts/environments/components/environment_item.js index e44d93a30c7..d9b49287dec 100644 --- a/app/assets/javascripts/environments/components/environment_item.js +++ b/app/assets/javascripts/environments/components/environment_item.js @@ -142,6 +142,7 @@ export default { const parsedAction = { name: gl.text.humanize(action.name), play_path: action.play_path, + playable: action.playable, }; return parsedAction; }); diff --git a/app/assets/javascripts/vue_pipelines_index/components/pipelines_actions.js b/app/assets/javascripts/vue_pipelines_index/components/pipelines_actions.js index 4bb2b048884..12d80768646 100644 --- a/app/assets/javascripts/vue_pipelines_index/components/pipelines_actions.js +++ b/app/assets/javascripts/vue_pipelines_index/components/pipelines_actions.js @@ -38,6 +38,14 @@ export default { new Flash('An error occured while making the request.'); }); }, + + isActionDisabled(action) { + if (action.playable === undefined) { + return false; + } + + return !action.playable; + }, }, template: ` @@ -51,16 +59,23 @@ export default { aria-label="Manual job" :disabled="isLoading"> ${playIconSvg} - <i class="fa fa-caret-down" aria-hidden="true"></i> - <i v-if="isLoading" class="fa fa-spinner fa-spin" aria-hidden="true"></i> + <i + class="fa fa-caret-down" + aria-hidden="true" /> + <i + v-if="isLoading" + class="fa fa-spinner fa-spin" + aria-hidden="true" /> </button> <ul class="dropdown-menu dropdown-menu-align-right"> <li v-for="action in actions"> <button type="button" - class="js-pipeline-action-link no-btn" - @click="onClickAction(action.path)"> + class="js-pipeline-action-link no-btn btn" + @click="onClickAction(action.path)" + :class="{ 'disabled': isActionDisabled(action) }" + :disabled="isActionDisabled(action)"> ${playIconSvg} <span>{{action.name}}</span> </button> diff --git a/app/serializers/build_action_entity.rb b/app/serializers/build_action_entity.rb index 184f5fd4b52..184b4b7a681 100644 --- a/app/serializers/build_action_entity.rb +++ b/app/serializers/build_action_entity.rb @@ -11,4 +11,6 @@ class BuildActionEntity < Grape::Entity build.project, build) end + + expose :playable?, as: :playable end diff --git a/app/serializers/build_entity.rb b/app/serializers/build_entity.rb index fadd6c5c597..b804d6d0e8a 100644 --- a/app/serializers/build_entity.rb +++ b/app/serializers/build_entity.rb @@ -16,6 +16,7 @@ class BuildEntity < Grape::Entity path_to(:play_namespace_project_build, build) end + expose :playable?, as: :playable expose :created_at expose :updated_at expose :detailed_status, as: :status, with: StatusEntity diff --git a/changelogs/unreleased/tc-fix-unplayable-build-action-404.yml b/changelogs/unreleased/tc-fix-unplayable-build-action-404.yml new file mode 100644 index 00000000000..e5e22c1daf7 --- /dev/null +++ b/changelogs/unreleased/tc-fix-unplayable-build-action-404.yml @@ -0,0 +1,4 @@ +--- +title: Disable pipeline and environment actions that are not playable +merge_request: 10052 +author: diff --git a/spec/factories/ci/builds.rb b/spec/factories/ci/builds.rb index f78086211f7..87a0c95c4dc 100644 --- a/spec/factories/ci/builds.rb +++ b/spec/factories/ci/builds.rb @@ -192,5 +192,10 @@ FactoryGirl.define do trait :no_options do options { {} } end + + trait :non_playable do + status 'created' + self.when 'manual' + end end end diff --git a/spec/factories/environments.rb b/spec/factories/environments.rb index 0852dda6b29..3fbf24b5c7d 100644 --- a/spec/factories/environments.rb +++ b/spec/factories/environments.rb @@ -32,5 +32,10 @@ FactoryGirl.define do environment.update_attribute(:deployments, [deployment]) end end + + trait :non_playable do + status 'created' + self.when 'manual' + end end end diff --git a/spec/javascripts/environments/environment_actions_spec.js b/spec/javascripts/environments/environment_actions_spec.js index 13840b42bd6..6348d97b0a5 100644 --- a/spec/javascripts/environments/environment_actions_spec.js +++ b/spec/javascripts/environments/environment_actions_spec.js @@ -19,6 +19,11 @@ describe('Actions Component', () => { name: 'foo', play_path: '#', }, + { + name: 'foo bar', + play_path: 'url', + playable: false, + }, ]; spy = jasmine.createSpy('spy').and.returnValue(Promise.resolve()); @@ -49,4 +54,14 @@ describe('Actions Component', () => { expect(spy).toHaveBeenCalledWith(actionsMock[0].play_path); }); + + it('should render a disabled action when it\'s not playable', () => { + expect( + component.$el.querySelector('.dropdown-menu li:last-child button').getAttribute('disabled'), + ).toEqual('disabled'); + + expect( + component.$el.querySelector('.dropdown-menu li:last-child button').classList.contains('disabled'), + ).toEqual(true); + }); }); diff --git a/spec/javascripts/vue_pipelines_index/pipelines_actions_spec.js b/spec/javascripts/vue_pipelines_index/pipelines_actions_spec.js index dba998c7688..0910df61915 100644 --- a/spec/javascripts/vue_pipelines_index/pipelines_actions_spec.js +++ b/spec/javascripts/vue_pipelines_index/pipelines_actions_spec.js @@ -15,6 +15,11 @@ describe('Pipelines Actions dropdown', () => { name: 'stop_review', path: '/root/review-app/builds/1893/play', }, + { + name: 'foo', + path: '#', + playable: false, + }, ]; spy = jasmine.createSpy('spy').and.returnValue(Promise.resolve()); @@ -59,4 +64,14 @@ describe('Pipelines Actions dropdown', () => { expect(component.$el.querySelector('.fa-spinner')).toEqual(null); }); + + it('should render a disabled action when it\'s not playable', () => { + expect( + component.$el.querySelector('.dropdown-menu li:last-child button').getAttribute('disabled'), + ).toEqual('disabled'); + + expect( + component.$el.querySelector('.dropdown-menu li:last-child button').classList.contains('disabled'), + ).toEqual(true); + }); }); diff --git a/spec/serializers/build_action_entity_spec.rb b/spec/serializers/build_action_entity_spec.rb index 0f7be8b2c39..54ac17447b1 100644 --- a/spec/serializers/build_action_entity_spec.rb +++ b/spec/serializers/build_action_entity_spec.rb @@ -17,5 +17,9 @@ describe BuildActionEntity do it 'contains path to the action play' do expect(subject[:path]).to include "builds/#{build.id}/play" end + + it 'contains whether it is playable' do + expect(subject[:playable]).to eq build.playable? + end end end diff --git a/spec/serializers/build_entity_spec.rb b/spec/serializers/build_entity_spec.rb index 7dcdf54fd93..f76a5cf72d1 100644 --- a/spec/serializers/build_entity_spec.rb +++ b/spec/serializers/build_entity_spec.rb @@ -24,6 +24,10 @@ describe BuildEntity do expect(subject).not_to include(/variables/) end + it 'contains whether it is playable' do + expect(subject[:playable]).to eq build.playable? + end + it 'contains timestamps' do expect(subject).to include(:created_at, :updated_at) end |