Commit 85e0eb47 authored by Filipa Lacerda's avatar Filipa Lacerda

Makes title section collapsible

In the job log, if the user clicks the section title
the job log section will be collapsed
parent 4aa824e7
...@@ -48,9 +48,14 @@ export default { ...@@ -48,9 +48,14 @@ export default {
} }
}, },
removeEventListener() { removeEventListener() {
this.$el this.$el.querySelectorAll('.js-section-start').forEach(el => {
.querySelectorAll('.js-section-start') const titleSection = el.nextSibling;
.forEach(el => el.removeEventListener('click', this.handleSectionClick)); titleSection.removeEventListener(
'click',
this.handleHeaderClick.bind(this, el, el.dataset.section),
);
el.removeEventListener('click', this.handleSectionClick);
});
}, },
/** /**
* The collapsible rows are sent in HTML from the backend * The collapsible rows are sent in HTML from the backend
...@@ -58,9 +63,28 @@ export default { ...@@ -58,9 +63,28 @@ export default {
* *
*/ */
handleCollapsibleRows() { handleCollapsibleRows() {
this.$el this.$el.querySelectorAll('.js-section-start').forEach(el => {
.querySelectorAll('.js-section-start') const titleSection = el.nextSibling;
.forEach(el => el.addEventListener('click', this.handleSectionClick)); titleSection.addEventListener(
'click',
this.handleHeaderClick.bind(this, el, el.dataset.section),
);
el.addEventListener('click', this.handleSectionClick);
});
},
handleHeaderClick(arrowElement, section) {
this.updateToggleSection(arrowElement, section);
},
updateToggleSection(arrow, section) {
// toggle the arrow class
arrow.classList.toggle('fa-caret-right');
arrow.classList.toggle('fa-caret-down');
// hide the sections
const sibilings = this.$el.querySelectorAll(`.js-s-${section}:not(.js-section-header)`);
sibilings.forEach(row => row.classList.toggle('hidden'));
}, },
/** /**
* On click, we toggle the hidden class of * On click, we toggle the hidden class of
...@@ -68,14 +92,7 @@ export default { ...@@ -68,14 +92,7 @@ export default {
*/ */
handleSectionClick(evt) { handleSectionClick(evt) {
const clickedArrow = evt.currentTarget; const clickedArrow = evt.currentTarget;
// toggle the arrow class this.updateToggleSection(clickedArrow, clickedArrow.dataset.section);
clickedArrow.classList.toggle('fa-caret-right');
clickedArrow.classList.toggle('fa-caret-down');
const { section } = clickedArrow.dataset;
const sibilings = this.$el.querySelectorAll(`.js-s-${section}:not(.js-section-header)`);
sibilings.forEach(row => row.classList.toggle('hidden'));
}, },
}, },
}; };
......
---
title: Makes collapsible title clickable in job log
merge_request:
author:
type: added
...@@ -218,7 +218,7 @@ module Gitlab ...@@ -218,7 +218,7 @@ module Gitlab
return if @sections.include?(section) return if @sections.include?(section)
@sections << section @sections << section
write_raw %{<div class="js-section-start fa fa-caret-down append-right-8 cursor-pointer" data-timestamp="#{timestamp}" data-section="#{data_section_names}" role="button"></div>} write_raw %{<div class="js-section-start fa fa-caret-down pr-2 cursor-pointer" data-timestamp="#{timestamp}" data-section="#{data_section_names}" role="button"></div>}
@lineno_in_section = 0 @lineno_in_section = 0
end end
...@@ -306,7 +306,7 @@ module Gitlab ...@@ -306,7 +306,7 @@ module Gitlab
css_classes << "section" css_classes << "section"
css_classes << if @lineno_in_section == 0 css_classes << if @lineno_in_section == 0
"js-section-header section-header" "js-section-header section-header cursor-pointer"
else else
"line" "line"
end end
......
...@@ -50,6 +50,20 @@ describe 'User browses a job', :js do ...@@ -50,6 +50,20 @@ describe 'User browses a job', :js do
expect(page).not_to have_content(text_to_hide) expect(page).not_to have_content(text_to_hide)
expect(page).to have_content(text_to_show) expect(page).to have_content(text_to_show)
end end
it 'collapses the section header clicked' do
wait_for_requests
text_to_hide = "Cloning into '/nolith/ci-tests'"
text_to_show = 'Waiting for pod'
expect(page).to have_content(text_to_hide)
expect(page).to have_content(text_to_show)
first('.js-section-header.js-s-get-sources').click
expect(page).not_to have_content(text_to_hide)
expect(page).to have_content(text_to_show)
end
end end
context 'when job trace contains sections' do context 'when job trace contains sections' do
......
...@@ -98,5 +98,25 @@ describe('Job Log', () => { ...@@ -98,5 +98,25 @@ describe('Job Log', () => {
.then(done) .then(done)
.catch(done.fail); .catch(done.fail);
}); });
it('toggles hidden class to the sibilings rows when header section is clicked', done => {
vm.$nextTick()
.then(() => {
const { section } = vm.$el.querySelector('.js-section-header').dataset;
vm.$el.querySelector('.js-section-header').click();
vm.$el.querySelectorAll(`.js-s-${section}:not(.js-section-header)`).forEach(el => {
expect(el.classList.contains('hidden')).toEqual(true);
});
vm.$el.querySelector('.js-section-header').click();
vm.$el.querySelectorAll(`.js-s-${section}:not(.js-section-header)`).forEach(el => {
expect(el.classList.contains('hidden')).toEqual(false);
});
})
.then(done)
.catch(done.fail);
});
}); });
}); });
...@@ -209,7 +209,7 @@ describe Gitlab::Ci::Ansi2html do ...@@ -209,7 +209,7 @@ describe Gitlab::Ci::Ansi2html do
let(:section_start) { "section_start:#{section_start_time.to_i}:#{section_name}\r\033[0K"} let(:section_start) { "section_start:#{section_start_time.to_i}:#{section_name}\r\033[0K"}
let(:section_end) { "section_end:#{section_end_time.to_i}:#{section_name}\r\033[0K"} let(:section_end) { "section_end:#{section_end_time.to_i}:#{section_name}\r\033[0K"}
let(:section_start_html) do let(:section_start_html) do
'<div class="js-section-start fa fa-caret-down append-right-8 cursor-pointer"' \ '<div class="js-section-start fa fa-caret-down pr-2 cursor-pointer"' \
" data-timestamp=\"#{section_start_time.to_i}\" data-section=\"#{class_name(section_name)}\"" \ " data-timestamp=\"#{section_start_time.to_i}\" data-section=\"#{class_name(section_name)}\"" \
' role="button"></div>' ' role="button"></div>'
end end
...@@ -233,8 +233,8 @@ describe Gitlab::Ci::Ansi2html do ...@@ -233,8 +233,8 @@ describe Gitlab::Ci::Ansi2html do
it 'prints light red' do it 'prints light red' do
text = "#{section_start}\e[91mHello\e[0m\nLine 1\nLine 2\nLine 3\n#{section_end}" text = "#{section_start}\e[91mHello\e[0m\nLine 1\nLine 2\nLine 3\n#{section_end}"
header = %{<span class="term-fg-l-red section js-section-header section-header js-s-#{class_name(section_name)}">Hello</span>} header = %{<span class="term-fg-l-red section js-section-header section-header cursor-pointer js-s-#{class_name(section_name)}">Hello</span>}
line_break = %{<span class="section js-section-header section-header js-s-#{class_name(section_name)}"><br/></span>} line_break = %{<span class="section js-section-header section-header cursor-pointer js-s-#{class_name(section_name)}"><br/></span>}
output_line = %{<span class="section line js-s-#{class_name(section_name)}">Line 1<br/>Line 2<br/>Line 3<br/></span>} output_line = %{<span class="section line js-s-#{class_name(section_name)}">Line 1<br/>Line 2<br/>Line 3<br/></span>}
html = "#{section_start_html}#{header}#{line_break}#{output_line}#{section_end_html}" html = "#{section_start_html}#{header}#{line_break}#{output_line}#{section_end_html}"
......
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