Commit dbae9d73 authored by Phil Hughes's avatar Phil Hughes

Merge branch 'kp-update-issuable-show-for-requirements' into 'master'

Update Issuable Show app components to use with Requirements

See merge request gitlab-org/gitlab!49925
parents fc5035f3 8b99ee5b
......@@ -36,10 +36,18 @@ export default {
type: Boolean,
required: true,
},
enableAutosave: {
type: Boolean,
required: true,
},
editFormVisible: {
type: Boolean,
required: true,
},
showFieldTitle: {
type: Boolean,
required: true,
},
descriptionPreviewPath: {
type: String,
required: true,
......@@ -57,6 +65,14 @@ export default {
return this.issuable.updatedBy;
},
},
methods: {
handleKeydownTitle(e, issuableMeta) {
this.$emit('keydown-title', e, issuableMeta);
},
handleKeydownDescription(e, issuableMeta) {
this.$emit('keydown-description', e, issuableMeta);
},
},
};
</script>
......@@ -67,8 +83,12 @@ export default {
v-if="editFormVisible"
:issuable="issuable"
:enable-autocomplete="enableAutocomplete"
:enable-autosave="enableAutosave"
:show-field-title="showFieldTitle"
:description-preview-path="descriptionPreviewPath"
:description-help-path="descriptionHelpPath"
@keydown-title="handleKeydownTitle"
@keydown-description="handleKeydownDescription"
>
<template #edit-form-actions="issuableMeta">
<slot name="edit-form-actions" v-bind="issuableMeta"></slot>
......
......@@ -23,6 +23,14 @@ export default {
type: Boolean,
required: true,
},
enableAutosave: {
type: Boolean,
required: true,
},
showFieldTitle: {
type: Boolean,
required: true,
},
descriptionPreviewPath: {
type: String,
required: true,
......@@ -33,19 +41,27 @@ export default {
},
},
data() {
const { title, description } = this.issuable;
return {
title,
description,
title: '',
description: '',
};
},
watch: {
issuable: {
handler(value) {
this.title = value?.title || '';
this.description = value?.description || '';
},
deep: true,
immediate: true,
},
},
created() {
eventHub.$on('update.issuable', this.resetAutosave);
eventHub.$on('close.form', this.resetAutosave);
},
mounted() {
this.initAutosave();
if (this.enableAutosave) this.initAutosave();
},
beforeDestroy() {
eventHub.$off('update.issuable', this.resetAutosave);
......@@ -73,6 +89,12 @@ export default {
this.autosaveTitle.reset();
this.autosaveDescription.reset();
},
handleKeydown(e, inputType) {
this.$emit(`keydown-${inputType}`, e, {
issuableTitle: this.title,
issuableDescription: this.description,
});
},
},
};
</script>
......@@ -82,9 +104,9 @@ export default {
<gl-form-group
data-testid="title"
:label="__('Title')"
:label-sr-only="true"
:label-sr-only="!showFieldTitle"
label-for="issuable-title"
class="col-12"
class="col-12 gl-px-0"
>
<gl-form-input
id="issuable-title"
......@@ -94,14 +116,16 @@ export default {
:aria-label="__('Title')"
:autofocus="true"
class="qa-title-input"
@keydown="handleKeydown($event, 'title')"
/>
</gl-form-group>
<gl-form-group
data-testid="description"
:label="__('Description')"
:label-sr-only="true"
:label-sr-only="!showFieldTitle"
label-for="issuable-description"
class="col-12 common-note-form"
label-class="gl-pb-0!"
class="col-12 gl-px-0 common-note-form"
>
<markdown-field
:markdown-preview-path="descriptionPreviewPath"
......@@ -120,11 +144,12 @@ export default {
class="note-textarea js-gfm-input js-autosize markdown-area
qa-description-textarea"
dir="auto"
@keydown="handleKeydown($event, 'description')"
></textarea>
</template>
</markdown-field>
</gl-form-group>
<div data-testid="actions" class="col-12 gl-mt-3 gl-mb-3 clearfix">
<div data-testid="actions" class="col-12 gl-mt-3 gl-mb-3 gl-px-0 clearfix">
<slot
name="edit-form-actions"
:issuable-title="title"
......
......@@ -35,11 +35,21 @@ export default {
required: false,
default: false,
},
enableAutosave: {
type: Boolean,
required: false,
default: true,
},
editFormVisible: {
type: Boolean,
required: false,
default: false,
},
showFieldTitle: {
type: Boolean,
required: false,
default: false,
},
descriptionPreviewPath: {
type: String,
required: false,
......@@ -51,6 +61,14 @@ export default {
default: '',
},
},
methods: {
handleKeydownTitle(e, issuableMeta) {
this.$emit('keydown-title', e, issuableMeta);
},
handleKeydownDescription(e, issuableMeta) {
this.$emit('keydown-description', e, issuableMeta);
},
},
};
</script>
......@@ -77,10 +95,14 @@ export default {
:status-icon="statusIcon"
:enable-edit="enableEdit"
:enable-autocomplete="enableAutocomplete"
:enable-autosave="enableAutosave"
:edit-form-visible="editFormVisible"
:show-field-title="showFieldTitle"
:description-preview-path="descriptionPreviewPath"
:description-help-path="descriptionHelpPath"
@edit-issuable="$emit('edit-issuable', $event)"
@keydown-title="handleKeydownTitle"
@keydown-description="handleKeydownDescription"
>
<template #status-badge>
<slot name="status-badge"></slot>
......
......@@ -135,6 +135,33 @@ describe('IssuableBody', () => {
expect(wrapper.emitted('edit-issuable')).toBeTruthy();
});
it.each(['keydown-title', 'keydown-description'])(
'component emits `%s` event with event object and issuableMeta params via issuable-edit-form',
async eventName => {
const eventObj = {
preventDefault: jest.fn(),
stopPropagation: jest.fn(),
};
const issuableMeta = {
issuableTitle: 'foo',
issuableDescription: 'foobar',
};
wrapper.setProps({
editFormVisible: true,
});
await wrapper.vm.$nextTick();
const issuableEditForm = wrapper.find(IssuableEditForm);
issuableEditForm.vm.$emit(eventName, eventObj, issuableMeta);
expect(wrapper.emitted(eventName)).toBeTruthy();
expect(wrapper.emitted(eventName)[0]).toMatchObject([eventObj, issuableMeta]);
},
);
});
});
});
......@@ -41,6 +41,40 @@ describe('IssuableEditForm', () => {
wrapper.destroy();
});
describe('watch', () => {
describe('issuable', () => {
it('sets title and description to `issuable.title` and `issuable.description` when those values are available', async () => {
wrapper.setProps({
issuable: {
...issuableEditFormProps.issuable,
title: 'Foo',
description: 'Foobar',
},
});
await wrapper.vm.$nextTick();
expect(wrapper.vm.title).toBe('Foo');
expect(wrapper.vm.description).toBe('Foobar');
});
it('sets title and description to empty string when `issuable.title` and `issuable.description` is unavailable', async () => {
wrapper.setProps({
issuable: {
...issuableEditFormProps.issuable,
title: null,
description: null,
},
});
await wrapper.vm.$nextTick();
expect(wrapper.vm.title).toBe('');
expect(wrapper.vm.description).toBe('');
});
});
});
describe('created', () => {
it('binds `update.issuable` and `close.form` event listeners', () => {
const eventOnSpy = jest.spyOn(IssuableEventHub, '$on');
......@@ -118,5 +152,42 @@ describe('IssuableEditForm', () => {
expect(actionsEl.find('button.js-save').exists()).toBe(true);
expect(actionsEl.find('button.js-cancel').exists()).toBe(true);
});
describe('events', () => {
const eventObj = {
preventDefault: jest.fn(),
stopPropagation: jest.fn(),
};
it('component emits `keydown-title` event with event object and issuableMeta params via gl-form-input', async () => {
const titleInputEl = wrapper.find(GlFormInput);
titleInputEl.vm.$emit('keydown', eventObj, 'title');
expect(wrapper.emitted('keydown-title')).toBeTruthy();
expect(wrapper.emitted('keydown-title')[0]).toMatchObject([
eventObj,
{
issuableTitle: wrapper.vm.title,
issuableDescription: wrapper.vm.description,
},
]);
});
it('component emits `keydown-description` event with event object and issuableMeta params via textarea', async () => {
const descriptionInputEl = wrapper.find('[data-testid="description"] textarea');
descriptionInputEl.trigger('keydown', eventObj, 'description');
expect(wrapper.emitted('keydown-description')).toBeTruthy();
expect(wrapper.emitted('keydown-description')[0]).toMatchObject([
eventObj,
{
issuableTitle: wrapper.vm.title,
issuableDescription: wrapper.vm.description,
},
]);
});
});
});
});
......@@ -118,6 +118,27 @@ describe('IssuableShowRoot', () => {
expect(wrapper.emitted('sidebar-toggle')).toBeTruthy();
});
it.each(['keydown-title', 'keydown-description'])(
'component emits `%s` event with event object and issuableMeta params via issuable-body',
eventName => {
const eventObj = {
preventDefault: jest.fn(),
stopPropagation: jest.fn(),
};
const issuableMeta = {
issuableTitle: 'foo',
issuableDescription: 'foobar',
};
const issuableBody = wrapper.find(IssuableBody);
issuableBody.vm.$emit(eventName, eventObj, issuableMeta);
expect(wrapper.emitted(eventName)).toBeTruthy();
expect(wrapper.emitted(eventName)[0]).toMatchObject([eventObj, issuableMeta]);
},
);
});
});
});
......@@ -28,7 +28,9 @@ export const mockIssuableShowProps = {
descriptionPreviewPath: '/gitlab-org/gitlab-shell/preview_markdown',
editFormVisible: false,
enableAutocomplete: true,
enableAutosave: true,
enableEdit: true,
showFieldTitle: false,
statusBadgeClass: 'status-box-open',
statusIcon: 'issue-open-m',
};
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