Moves terminal button into Vue.
Updates permission checks to use paths instead - backend already handles permissions
This commit is contained in:
parent
ab44f53199
commit
2b36c84176
|
@ -1,14 +1,16 @@
|
||||||
<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 {
|
||||||
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 {
|
||||||
{{ 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 {
|
||||||
>
|
>
|
||||||
{{ __('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 {
|
||||||
{{ __('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 () => {
|
||||||
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,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,13 +1,7 @@
|
||||||
%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
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
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', () => {
|
||||||
|
|
||||||
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', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
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', () => {
|
||||||
|
|
Loading…
Reference in New Issue