Commit 2b36c841 authored by Filipa Lacerda's avatar Filipa Lacerda

Moves terminal button into Vue.

Updates permission checks to use paths instead - backend already handles permissions
parent ab44f531
<script> <script>
import detailRow from './sidebar_detail_row.vue'; import LoadingIcon from '~/vue_shared/components/loading_icon.vue';
import loadingIcon from '../../vue_shared/components/loading_icon.vue'; import timeagoMixin from '~/vue_shared/mixins/timeago';
import timeagoMixin from '../../vue_shared/mixins/timeago'; import { timeIntervalInWords } from '~/lib/utils/datetime_utility';
import { timeIntervalInWords } from '../../lib/utils/datetime_utility'; import Icon from '~/vue_shared/components/icon.vue';
import DetailRow from './sidebar_detail_row.vue';
export default { export default {
name: 'SidebarDetailsBlock', name: 'SidebarDetailsBlock',
components: { components: {
detailRow, DetailRow,
loadingIcon, LoadingIcon,
Icon,
}, },
mixins: [timeagoMixin], mixins: [timeagoMixin],
props: { props: {
...@@ -20,16 +22,16 @@ export default { ...@@ -20,16 +22,16 @@ export default {
type: Boolean, type: Boolean,
required: true, required: true,
}, },
canUserRetry: {
type: Boolean,
required: false,
default: false,
},
runnerHelpUrl: { runnerHelpUrl: {
type: String, type: String,
required: false, required: false,
default: '', default: '',
}, },
terminalPath: {
type: String,
required: false,
default: null,
},
}, },
computed: { computed: {
shouldRenderContent() { shouldRenderContent() {
...@@ -92,7 +94,7 @@ export default { ...@@ -92,7 +94,7 @@ export default {
{{ job.name }} {{ job.name }}
</strong> </strong>
<a <a
v-if="canUserRetry" v-if="job.retry_path"
:class="retryButtonClass" :class="retryButtonClass"
:href="job.retry_path" :href="job.retry_path"
data-method="post" data-method="post"
...@@ -100,6 +102,16 @@ export default { ...@@ -100,6 +102,16 @@ export default {
> >
{{ __('Retry') }} {{ __('Retry') }}
</a> </a>
<a
v-if="terminalPath"
:href="terminalPath"
class="js-terminal-link pull-right btn btn-primary
btn-inverted visible-md-block visible-lg-block"
target="_blank"
>
{{ __('Debug') }}
<icon name="external-link" />
</a>
<button <button
:aria-label="__('Toggle Sidebar')" :aria-label="__('Toggle Sidebar')"
type="button" type="button"
...@@ -125,7 +137,7 @@ export default { ...@@ -125,7 +137,7 @@ export default {
{{ __('New issue') }} {{ __('New issue') }}
</a> </a>
<a <a
v-if="canUserRetry" v-if="job.retry_path"
:href="job.retry_path" :href="job.retry_path"
class="js-retry-job btn btn-inverted-secondary" class="js-retry-job btn btn-inverted-secondary"
data-method="post" data-method="post"
......
...@@ -52,9 +52,9 @@ export default () => { ...@@ -52,9 +52,9 @@ export default () => {
return createElement('details-block', { return createElement('details-block', {
props: { props: {
isLoading: this.mediator.state.isLoading, isLoading: this.mediator.state.isLoading,
canUserRetry: !!('canUserRetry' in detailsBlockDataset),
job: this.mediator.store.state.job, job: this.mediator.store.state.job,
runnerHelpUrl: dataset.runnerHelpUrl, runnerHelpUrl: dataset.runnerHelpUrl,
terminalPath: detailsBlockDataset.terminalPath,
}, },
}); });
}, },
......
%aside.right-sidebar.right-sidebar-expanded.build-sidebar.js-build-sidebar.js-right-sidebar{ data: { "offset-top" => "101", "spy" => "affix" } } %aside.right-sidebar.right-sidebar-expanded.build-sidebar.js-build-sidebar.js-right-sidebar{ data: { "offset-top" => "101", "spy" => "affix" } }
.sidebar-container .sidebar-container
.blocks-container .blocks-container
- if can?(current_user, :create_build_terminal, @build) #js-details-block-vue{ data: { terminal_path: can?(current_user, :create_build_terminal, @build) && @build.has_terminal? ? terminal_project_job_path(@project, @build) : nil } }
.block
= link_to terminal_project_job_path(@project, @build), class: 'pull-right btn btn-primary btn-inverted visible-md-block visible-lg-block', target: '_blank' do
Debug
= icon('external-link')
#js-details-block-vue{ data: { can_user_retry: can?(current_user, :update_build, @build) && @build.retryable? } }
- if can?(current_user, :read_build, @project) && (@build.artifacts? || @build.artifacts_expired?) - if can?(current_user, :read_build, @project) && (@build.artifacts? || @build.artifacts_expired?)
.block .block
......
import Vue from 'vue'; import Vue from 'vue';
import sidebarDetailsBlock from '~/jobs/components/sidebar_details_block.vue'; import sidebarDetailsBlock from '~/jobs/components/sidebar_details_block.vue';
import job from './mock_data'; import job from './mock_data';
import mountComponent from '../helpers/vue_mount_component_helper';
describe('Sidebar details block', () => { describe('Sidebar details block', () => {
let SidebarComponent; let SidebarComponent;
...@@ -20,39 +21,53 @@ describe('Sidebar details block', () => { ...@@ -20,39 +21,53 @@ describe('Sidebar details block', () => {
describe('when it is loading', () => { describe('when it is loading', () => {
it('should render a loading spinner', () => { it('should render a loading spinner', () => {
vm = new SidebarComponent({ vm = mountComponent(SidebarComponent, {
propsData: { job: {},
job: {}, isLoading: true,
isLoading: true, });
},
}).$mount();
expect(vm.$el.querySelector('.fa-spinner')).toBeDefined(); expect(vm.$el.querySelector('.fa-spinner')).toBeDefined();
}); });
}); });
describe("when user can't retry", () => { describe('when there is no retry path retry', () => {
it('should not render a retry button', () => { it('should not render a retry button', () => {
vm = new SidebarComponent({ vm = mountComponent(SidebarComponent, {
propsData: { job: {},
job: {}, isLoading: false,
canUserRetry: false, });
isLoading: true,
},
}).$mount();
expect(vm.$el.querySelector('.js-retry-job')).toBeNull(); expect(vm.$el.querySelector('.js-retry-job')).toBeNull();
}); });
}); });
beforeEach(() => { describe('without terminal path', () => {
vm = new SidebarComponent({ it('does not render terminal link', () => {
propsData: { vm = mountComponent(SidebarComponent, {
job, job,
canUserRetry: true,
isLoading: false, isLoading: false,
}, });
}).$mount();
expect(vm.$el.querySelector('.js-terminal-link')).toBeNull();
});
});
describe('with terminal path', () => {
it('renders terminal link', () => {
vm = mountComponent(SidebarComponent, {
job,
isLoading: false,
terminalPath: 'job/43123/terminal',
});
expect(vm.$el.querySelector('.js-terminal-link')).not.toBeNull();
});
});
beforeEach(() => {
vm = mountComponent(SidebarComponent, {
job,
isLoading: false,
});
}); });
describe('actions', () => { describe('actions', () => {
...@@ -102,13 +117,15 @@ describe('Sidebar details block', () => { ...@@ -102,13 +117,15 @@ describe('Sidebar details block', () => {
}); });
it('should render runner ID', () => { it('should render runner ID', () => {
expect(trimWhitespace(vm.$el.querySelector('.js-job-runner'))).toEqual('Runner: local ci runner (#1)'); expect(trimWhitespace(vm.$el.querySelector('.js-job-runner'))).toEqual(
'Runner: local ci runner (#1)',
);
}); });
it('should render timeout information', () => { it('should render timeout information', () => {
expect( expect(trimWhitespace(vm.$el.querySelector('.js-job-timeout'))).toEqual(
trimWhitespace(vm.$el.querySelector('.js-job-timeout')), 'Timeout: 1m 40s (from runner)',
).toEqual('Timeout: 1m 40s (from runner)'); );
}); });
it('should render coverage', () => { it('should render coverage', () => {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment