Commit a021ab46 authored by Simon Knox's avatar Simon Knox

Merge branch...

Merge branch '355978-refactor-issue-description-task-work-item-conversion-using-task-button-2' into 'master'

Replace create task popover with button

See merge request gitlab-org/gitlab!83200
parents cefd430d 750621ed
<script>
import {
GlSafeHtmlDirective as SafeHtml,
GlModal,
GlModalDirective,
GlPopover,
GlButton,
} from '@gitlab/ui';
import { GlSafeHtmlDirective as SafeHtml, GlModal, GlTooltip, GlModalDirective } from '@gitlab/ui';
import $ from 'jquery';
import { convertToGraphQLId } from '~/graphql_shared/utils';
import { TYPE_WORK_ITEM } from '~/graphql_shared/constants';
import createFlash from '~/flash';
import { __, sprintf } from '~/locale';
import { __, s__, sprintf } from '~/locale';
import TaskList from '~/task_list';
import Tracking from '~/tracking';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
......@@ -25,9 +19,8 @@ export default {
},
components: {
GlModal,
GlPopover,
CreateWorkItem,
GlButton,
GlTooltip,
WorkItemDetailModal,
},
mixins: [animateMixin, glFeatureFlagMixin(), Tracking.mixin()],
......@@ -216,9 +209,11 @@ export default {
this.taskButtons.push(button.id);
button.innerHTML = `
<svg data-testid="ellipsis_v-icon" role="img" aria-hidden="true" class="dropdown-icon gl-icon s14">
<use href="${gon.sprite_icons}#ellipsis_v"></use>
<use href="${gon.sprite_icons}#doc-new"></use>
</svg>
`;
button.setAttribute('aria-label', s__('WorkItem|Convert to work item'));
button.addEventListener('click', () => this.openCreateTaskModal(button.id));
item.prepend(button);
});
},
......@@ -246,9 +241,6 @@ export default {
this.$emit('updateDescription', description);
this.closeCreateTaskModal();
},
focusButton() {
this.$refs.convertButton[0].$el.focus();
},
},
safeHtmlConfig: { ADD_TAGS: ['gl-emoji', 'copy-code'] },
};
......@@ -309,23 +301,9 @@ export default {
@error="handleWorkItemDetailModalError"
/>
<template v-if="workItemsEnabled">
<gl-popover
v-for="item in taskButtons"
:key="item"
:target="item"
placement="top"
triggers="focus"
@shown="focusButton"
>
<gl-button
ref="convertButton"
variant="link"
data-testid="convert-to-task"
class="gl-text-gray-900! gl-text-decoration-none! gl-outline-0!"
@click="openCreateTaskModal(item)"
>{{ s__('WorkItem|Convert to work item') }}</gl-button
>
</gl-popover>
<gl-tooltip v-for="item in taskButtons" :key="item" :target="item">
{{ s__('WorkItem|Convert to work item') }}
</gl-tooltip>
</template>
</div>
</template>
......@@ -87,10 +87,7 @@ export default {
return this.selectedWorkItemType?.name || s__('WorkItem|Type');
},
formOptions() {
return [
{ value: null, text: s__('WorkItem|Please select work item type') },
...this.workItemTypes,
];
return [{ value: null, text: s__('WorkItem|Select type') }, ...this.workItemTypes];
},
isButtonDisabled() {
return this.title.trim().length === 0 || !this.selectedWorkItemType;
......
......@@ -311,7 +311,7 @@ ul.related-merge-requests > li gl-emoji {
.description.work-items-enabled {
ul.task-list {
> li.task-list-item {
padding-inline-start: 2.25rem;
padding-inline-start: 2.5rem;
.js-add-task {
svg {
......@@ -324,7 +324,7 @@ ul.related-merge-requests > li gl-emoji {
}
> input.task-list-item-checkbox {
left: 0.875rem;
left: 1.25rem;
}
&:hover,
......
......@@ -42374,7 +42374,7 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
msgid "WorkItem|Please select work item type"
msgid "WorkItem|Select type"
msgstr ""
msgid "WorkItem|Something went wrong when creating a work item. Please try again"
......
import $ from 'jquery';
import { nextTick } from 'vue';
import '~/behaviors/markdown/render_gfm';
import { GlPopover, GlModal } from '@gitlab/ui';
import { GlTooltip, GlModal } from '@gitlab/ui';
import { stubComponent } from 'helpers/stub_component';
import { TEST_HOST } from 'helpers/test_constants';
import { mockTracking } from 'helpers/tracking_helper';
......@@ -29,9 +29,9 @@ describe('Description component', () => {
const findGfmContent = () => wrapper.find('[data-testid="gfm-content"]');
const findTextarea = () => wrapper.find('[data-testid="textarea"]');
const findTaskActionButtons = () => wrapper.findAll('.js-add-task');
const findConvertToTaskButton = () => wrapper.find('[data-testid="convert-to-task"]');
const findConvertToTaskButton = () => wrapper.find('.js-add-task');
const findPopovers = () => wrapper.findAllComponents(GlPopover);
const findTooltips = () => wrapper.findAllComponents(GlTooltip);
const findModal = () => wrapper.findComponent(GlModal);
const findCreateWorkItem = () => wrapper.findComponent(CreateWorkItem);
const findWorkItemDetailModal = () => wrapper.findComponent(WorkItemDetailModal);
......@@ -51,7 +51,6 @@ describe('Description component', () => {
hide: hideModal,
},
}),
GlPopover,
},
});
}
......@@ -254,9 +253,9 @@ describe('Description component', () => {
expect(findTaskActionButtons()).toHaveLength(3);
});
it('renders a list of popovers corresponding to checkboxes in description HTML', () => {
expect(findPopovers()).toHaveLength(3);
expect(findPopovers().at(0).props('target')).toBe(
it('renders a list of tooltips corresponding to checkboxes in description HTML', () => {
expect(findTooltips()).toHaveLength(3);
expect(findTooltips().at(0).props('target')).toBe(
findTaskActionButtons().at(0).attributes('id'),
);
});
......@@ -265,20 +264,18 @@ describe('Description component', () => {
expect(findModal().props('visible')).toBe(false);
});
it('opens a modal when a button on popover is clicked and displays correct title', async () => {
findConvertToTaskButton().vm.$emit('click');
expect(showModal).toHaveBeenCalled();
await nextTick();
it('opens a modal when a button is clicked and displays correct title', async () => {
await findConvertToTaskButton().trigger('click');
expect(findCreateWorkItem().props('initialTitle').trim()).toBe('todo 1');
});
it('closes the modal on `closeCreateTaskModal` event', () => {
findConvertToTaskButton().vm.$emit('click');
it('closes the modal on `closeCreateTaskModal` event', async () => {
await findConvertToTaskButton().trigger('click');
findCreateWorkItem().vm.$emit('closeModal');
expect(hideModal).toHaveBeenCalled();
});
it('emits `updateDescription` on `onCreate` event', async () => {
it('emits `updateDescription` on `onCreate` event', () => {
const newDescription = `<p>New description</p>`;
findCreateWorkItem().vm.$emit('onCreate', newDescription);
expect(hideModal).toHaveBeenCalled();
......
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