Commit 461f4589 authored by Fatih Acet's avatar Fatih Acet

Merge branch...

Merge branch '61933-toggling-a-task-inside-a-collapsible-section-collapses-all-sections-ee' into 'master'

Fix toggling a task inside a collapsible section collapses all sections

Closes #28785

See merge request gitlab-org/gitlab!16153
parents 65acf407 77996621
import _ from 'underscore';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import updateDescription from '../utils/update_description';
export default class Store {
constructor(initialState) {
......@@ -19,8 +21,15 @@ export default class Store {
}
Object.assign(this.state, convertObjectPropsToCamelCase(data));
// find if there is an open details node inside of the issue description.
const descriptionSection = document.body.querySelector(
'.detail-page-description.content-block',
);
const details =
!_.isNull(descriptionSection) && descriptionSection.getElementsByTagName('details');
this.state.descriptionHtml = updateDescription(data.description, details);
this.state.titleHtml = data.title;
this.state.descriptionHtml = data.description;
this.state.lock_version = data.lock_version;
}
......
import _ from 'underscore';
/**
* Function that replaces the open attribute for the <details> element.
*
* @param {String} descriptionHtml - The html string passed back from the server as a result of polling
* @param {Array} details - All detail nodes inside of the issue description.
*/
const updateDescription = (descriptionHtml = '', details) => {
let detailNodes = details;
if (_.isEmpty(details)) {
detailNodes = [];
}
const placeholder = document.createElement('div');
placeholder.innerHTML = descriptionHtml;
const newDetails = placeholder.getElementsByTagName('details');
if (newDetails.length !== detailNodes.length) {
return descriptionHtml;
}
Array.from(newDetails).forEach((el, i) => {
/*
* <details> has an open attribute that can have a value, "", "true", "false"
* and will show the dropdown, which is why we are setting the attribute
* explicitly to true.
*/
if (detailNodes[i].open) el.setAttribute('open', true);
});
return placeholder.innerHTML;
};
export default updateDescription;
---
title: When user toggles task list item, keep details open until user closes the details
manually
merge_request: 16153
author:
type: fixed
import Store from '~/issue_show/stores';
import updateDescription from '~/issue_show/utils/update_description';
jest.mock('~/issue_show/utils/update_description');
describe('Store', () => {
let store;
beforeEach(() => {
store = new Store({
descriptionHtml: '<p>This is a description</p>',
});
});
describe('updateState', () => {
beforeEach(() => {
document.body.innerHTML = `
<div class="detail-page-description content-block">
<details open>
<summary>One</summary>
</details>
<details>
<summary>Two</summary>
</details>
</div>
`;
});
afterEach(() => {
document.getElementsByTagName('html')[0].innerHTML = '';
});
it('calls updateDetailsState', () => {
store.updateState({ description: '' });
expect(updateDescription).toHaveBeenCalledTimes(1);
});
});
});
import updateDescription from '~/issue_show/utils/update_description';
describe('updateDescription', () => {
it('returns the correct value to be set as descriptionHtml', () => {
const actual = updateDescription(
'<details><summary>One</summary></details><details><summary>Two</summary></details>',
[{ open: true }, { open: false }], // mocking NodeList from the dom.
);
expect(actual).toEqual(
'<details open="true"><summary>One</summary></details><details><summary>Two</summary></details>',
);
});
describe('when description details returned from api is different then whats currently on the dom', () => {
it('returns the description from the api', () => {
const dataDescription = '<details><summary>One</summary></details>';
const actual = updateDescription(dataDescription, []);
expect(actual).toEqual(dataDescription);
});
});
});
......@@ -23,6 +23,14 @@ describe('Issuable output', () => {
beforeEach(done => {
setFixtures(`
<div>
<div class="detail-page-description content-block">
<details open>
<summary>One</summary>
</details>
<details>
<summary>Two</summary>
</details>
</div>
<div class="flash-container"></div>
<span id="task_status"></span>
</div>
......
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