Merge branch '50101-truncated-job-information' into 'master'
Creates a vue component for the top bar with controllers in job log view See merge request gitlab-org/gitlab-ce!21164
This commit is contained in:
commit
1f71bb4c40
4 changed files with 379 additions and 0 deletions
139
app/assets/javascripts/jobs/components/job_log_controllers.vue
Normal file
139
app/assets/javascripts/jobs/components/job_log_controllers.vue
Normal file
|
@ -0,0 +1,139 @@
|
|||
<script>
|
||||
import Icon from '~/vue_shared/components/icon.vue';
|
||||
import tooltip from '~/vue_shared/directives/tooltip';
|
||||
import { numberToHumanSize } from '~/lib/utils/number_utils';
|
||||
import { s__, sprintf } from '~/locale';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Icon,
|
||||
},
|
||||
directives: {
|
||||
tooltip,
|
||||
},
|
||||
props: {
|
||||
canEraseJob: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
size: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
rawTracePath: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
canScrollToTop: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
canScrollToBottom: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
jobLogSize() {
|
||||
return sprintf('Showing last %{startSpanTag} %{size} %{endSpanTag} of log -', {
|
||||
startSpanTag: '<span class="s-truncated-info-size truncated-info-size">',
|
||||
endSpanTag: '</span>',
|
||||
size: numberToHumanSize(this.size),
|
||||
});
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleEraseJobClick() {
|
||||
// eslint-disable-next-line no-alert
|
||||
if (window.confirm(s__('Job|Are you sure you want to erase this job?'))) {
|
||||
this.$emit('eraseJob');
|
||||
}
|
||||
},
|
||||
handleScrollToTop() {
|
||||
this.$emit('scrollJobLogTop');
|
||||
},
|
||||
handleScrollToBottom() {
|
||||
this.$emit('scrollJobLogBottom');
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<div class="top-bar">
|
||||
<!-- truncate information -->
|
||||
<div class="js-truncated-info truncated-info d-none d-sm-block float-left">
|
||||
<p v-html="jobLogSize"></p>
|
||||
|
||||
<a
|
||||
v-if="rawTracePath"
|
||||
:href="rawTracePath"
|
||||
class="js-raw-link raw-link"
|
||||
>
|
||||
{{ s__("Job|Complete Raw") }}
|
||||
</a>
|
||||
</div>
|
||||
<!-- eo truncate information -->
|
||||
|
||||
<div class="controllers float-right">
|
||||
<!-- links -->
|
||||
<a
|
||||
v-tooltip
|
||||
v-if="rawTracePath"
|
||||
:title="s__('Job|Show complete raw')"
|
||||
:href="rawTracePath"
|
||||
class="js-raw-link-controller controllers-buttons"
|
||||
data-container="body"
|
||||
>
|
||||
<icon name="doc-text" />
|
||||
</a>
|
||||
|
||||
<button
|
||||
v-tooltip
|
||||
v-if="canEraseJob"
|
||||
:title="s__('Job|Erase job log')"
|
||||
type="button"
|
||||
class="js-erase-link controllers-buttons"
|
||||
data-container="body"
|
||||
@click="handleEraseJobClick"
|
||||
>
|
||||
<icon name="remove" />
|
||||
</button>
|
||||
<!-- eo links -->
|
||||
|
||||
<!-- scroll buttons -->
|
||||
<div
|
||||
v-tooltip
|
||||
:title="s__('Job|Scroll to top')"
|
||||
class="controllers-buttons"
|
||||
data-container="body"
|
||||
>
|
||||
<button
|
||||
:disabled="!canScrollToTop"
|
||||
type="button"
|
||||
class="js-scroll-top btn-scroll btn-transparent btn-blank"
|
||||
@click="handleScrollToTop"
|
||||
>
|
||||
<icon name="scroll_up"/>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-tooltip
|
||||
:title="s__('Job|Scroll to bottom')"
|
||||
class="controllers-buttons"
|
||||
data-container="body"
|
||||
>
|
||||
<button
|
||||
:disabled="!canScrollToBottom"
|
||||
type="button"
|
||||
class="js-scroll-bottom btn-scroll btn-transparent btn-blank"
|
||||
@click="handleScrollToBottom"
|
||||
>
|
||||
<icon name="scroll_down"/>
|
||||
</button>
|
||||
</div>
|
||||
<!-- eo scroll buttons -->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Creates vue component for job log top bar with controllers
|
||||
merge_request:
|
||||
author:
|
||||
type: other
|
|
@ -3139,12 +3139,21 @@ msgstr ""
|
|||
msgid "Jobs"
|
||||
msgstr ""
|
||||
|
||||
msgid "Job|Are you sure you want to erase this job?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Job|Browse"
|
||||
msgstr ""
|
||||
|
||||
msgid "Job|Complete Raw"
|
||||
msgstr ""
|
||||
|
||||
msgid "Job|Download"
|
||||
msgstr ""
|
||||
|
||||
msgid "Job|Erase job log"
|
||||
msgstr ""
|
||||
|
||||
msgid "Job|Job artifacts"
|
||||
msgstr ""
|
||||
|
||||
|
@ -3157,6 +3166,15 @@ msgstr ""
|
|||
msgid "Job|Keep"
|
||||
msgstr ""
|
||||
|
||||
msgid "Job|Scroll to bottom"
|
||||
msgstr ""
|
||||
|
||||
msgid "Job|Scroll to top"
|
||||
msgstr ""
|
||||
|
||||
msgid "Job|Show complete raw"
|
||||
msgstr ""
|
||||
|
||||
msgid "Job|The artifacts were removed"
|
||||
msgstr ""
|
||||
|
||||
|
|
217
spec/javascripts/jobs/components/job_log_controllers_spec.js
Normal file
217
spec/javascripts/jobs/components/job_log_controllers_spec.js
Normal file
|
@ -0,0 +1,217 @@
|
|||
import Vue from 'vue';
|
||||
import component from '~/jobs/components/job_log_controllers.vue';
|
||||
import mountComponent from '../../helpers/vue_mount_component_helper';
|
||||
|
||||
describe('Job log controllers', () => {
|
||||
const Component = Vue.extend(component);
|
||||
let vm;
|
||||
|
||||
afterEach(() => {
|
||||
vm.$destroy();
|
||||
});
|
||||
|
||||
describe('Truncate information', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
vm = mountComponent(Component, {
|
||||
rawTracePath: '/raw',
|
||||
canEraseJob: true,
|
||||
size: 511952,
|
||||
canScrollToTop: true,
|
||||
canScrollToBottom: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('renders size information', () => {
|
||||
expect(vm.$el.querySelector('.js-truncated-info').textContent).toContain('499.95 KiB');
|
||||
});
|
||||
|
||||
it('renders link to raw trace', () => {
|
||||
expect(vm.$el.querySelector('.js-raw-link').getAttribute('href')).toEqual('/raw');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('links section', () => {
|
||||
describe('with raw trace path', () => {
|
||||
it('renders raw trace link', () => {
|
||||
vm = mountComponent(Component, {
|
||||
rawTracePath: '/raw',
|
||||
canEraseJob: true,
|
||||
size: 511952,
|
||||
canScrollToTop: true,
|
||||
canScrollToBottom: true,
|
||||
});
|
||||
|
||||
expect(vm.$el.querySelector('.js-raw-link-controller').getAttribute('href')).toEqual('/raw');
|
||||
});
|
||||
});
|
||||
|
||||
describe('without raw trace path', () => {
|
||||
it('does not render raw trace link', () => {
|
||||
vm = mountComponent(Component, {
|
||||
canEraseJob: true,
|
||||
size: 511952,
|
||||
canScrollToTop: true,
|
||||
canScrollToBottom: true,
|
||||
});
|
||||
|
||||
expect(vm.$el.querySelector('.js-raw-link-controller')).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when is erasable', () => {
|
||||
beforeEach(() => {
|
||||
vm = mountComponent(Component, {
|
||||
rawTracePath: '/raw',
|
||||
canEraseJob: true,
|
||||
size: 511952,
|
||||
canScrollToTop: true,
|
||||
canScrollToBottom: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('renders erase job button', () => {
|
||||
expect(vm.$el.querySelector('.js-erase-link')).not.toBeNull();
|
||||
});
|
||||
|
||||
describe('on click', () => {
|
||||
describe('when user confirms action', () => {
|
||||
it('emits eraseJob event', () => {
|
||||
spyOn(window, 'confirm').and.returnValue(true);
|
||||
spyOn(vm, '$emit');
|
||||
|
||||
vm.$el.querySelector('.js-erase-link').click();
|
||||
|
||||
expect(vm.$emit).toHaveBeenCalledWith('eraseJob');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when user does not confirm action', () => {
|
||||
it('does not emit eraseJob event', () => {
|
||||
spyOn(window, 'confirm').and.returnValue(false);
|
||||
spyOn(vm, '$emit');
|
||||
|
||||
vm.$el.querySelector('.js-erase-link').click();
|
||||
|
||||
expect(vm.$emit).not.toHaveBeenCalledWith('eraseJob');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when it is not erasable', () => {
|
||||
it('does not render erase button', () => {
|
||||
vm = mountComponent(Component, {
|
||||
rawTracePath: '/raw',
|
||||
canEraseJob: false,
|
||||
size: 511952,
|
||||
canScrollToTop: true,
|
||||
canScrollToBottom: true,
|
||||
});
|
||||
|
||||
expect(vm.$el.querySelector('.js-erase-link')).toBeNull();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('scroll buttons', () => {
|
||||
describe('scroll top button', () => {
|
||||
describe('when user can scroll top', () => {
|
||||
beforeEach(() => {
|
||||
vm = mountComponent(Component, {
|
||||
rawTracePath: '/raw',
|
||||
canEraseJob: true,
|
||||
size: 511952,
|
||||
canScrollToTop: true,
|
||||
canScrollToBottom: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('renders enabled scroll top button', () => {
|
||||
expect(vm.$el.querySelector('.js-scroll-top').getAttribute('disabled')).toBeNull();
|
||||
});
|
||||
|
||||
it('emits scrollJobLogTop event on click', () => {
|
||||
spyOn(vm, '$emit');
|
||||
vm.$el.querySelector('.js-scroll-top').click();
|
||||
|
||||
expect(vm.$emit).toHaveBeenCalledWith('scrollJobLogTop');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when user can not scroll top', () => {
|
||||
beforeEach(() => {
|
||||
vm = mountComponent(Component, {
|
||||
rawTracePath: '/raw',
|
||||
canEraseJob: true,
|
||||
size: 511952,
|
||||
canScrollToTop: false,
|
||||
canScrollToBottom: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('renders disabled scroll top button', () => {
|
||||
expect(vm.$el.querySelector('.js-scroll-top').getAttribute('disabled')).toEqual('disabled');
|
||||
});
|
||||
|
||||
it('does not emit scrollJobLogTop event on click', () => {
|
||||
spyOn(vm, '$emit');
|
||||
vm.$el.querySelector('.js-scroll-top').click();
|
||||
|
||||
expect(vm.$emit).not.toHaveBeenCalledWith('scrollJobLogTop');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('scroll bottom button', () => {
|
||||
describe('when user can scroll bottom', () => {
|
||||
beforeEach(() => {
|
||||
vm = mountComponent(Component, {
|
||||
rawTracePath: '/raw',
|
||||
canEraseJob: true,
|
||||
size: 511952,
|
||||
canScrollToTop: true,
|
||||
canScrollToBottom: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('renders enabled scroll bottom button', () => {
|
||||
expect(vm.$el.querySelector('.js-scroll-bottom').getAttribute('disabled')).toBeNull();
|
||||
});
|
||||
|
||||
it('emits scrollJobLogBottom event on click', () => {
|
||||
spyOn(vm, '$emit');
|
||||
vm.$el.querySelector('.js-scroll-bottom').click();
|
||||
|
||||
expect(vm.$emit).toHaveBeenCalledWith('scrollJobLogBottom');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when user can not scroll bottom', () => {
|
||||
beforeEach(() => {
|
||||
vm = mountComponent(Component, {
|
||||
rawTracePath: '/raw',
|
||||
canEraseJob: true,
|
||||
size: 511952,
|
||||
canScrollToTop: true,
|
||||
canScrollToBottom: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('renders disabled scroll bottom button', () => {
|
||||
expect(vm.$el.querySelector('.js-scroll-bottom').getAttribute('disabled')).toEqual('disabled');
|
||||
|
||||
});
|
||||
|
||||
it('does not emit scrollJobLogBottom event on click', () => {
|
||||
spyOn(vm, '$emit');
|
||||
vm.$el.querySelector('.js-scroll-bottom').click();
|
||||
|
||||
expect(vm.$emit).not.toHaveBeenCalledWith('scrollJobLogBottom');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in a new issue