Commit 6f17d227 authored by Phil Hughes's avatar Phil Hughes

Merge branch '229706-requirement-create-edit-drawer' into 'master'

Use Drawer for Requirement Create/Edit form UI

Closes #229706

See merge request gitlab-org/gitlab!37943
parents abf47a37 1680a7e5
<script> <script>
import { GlFormGroup, GlFormTextarea, GlDeprecatedButton } from '@gitlab/ui'; import { GlDrawer, GlFormGroup, GlFormTextarea, GlDeprecatedButton } from '@gitlab/ui';
import { isEmpty } from 'lodash'; import { isEmpty } from 'lodash';
import { __, sprintf } from '~/locale'; import { __, sprintf } from '~/locale';
...@@ -10,11 +10,16 @@ export default { ...@@ -10,11 +10,16 @@ export default {
limit: MAX_TITLE_LENGTH, limit: MAX_TITLE_LENGTH,
}), }),
components: { components: {
GlDrawer,
GlFormGroup, GlFormGroup,
GlFormTextarea, GlFormTextarea,
GlDeprecatedButton, GlDeprecatedButton,
}, },
props: { props: {
drawerOpen: {
type: Boolean,
required: true,
},
requirement: { requirement: {
type: Object, type: Object,
required: false, required: false,
...@@ -27,13 +32,15 @@ export default { ...@@ -27,13 +32,15 @@ export default {
}, },
data() { data() {
return { return {
isCreate: isEmpty(this.requirement),
title: this.requirement?.title || '', title: this.requirement?.title || '',
}; };
}, },
computed: { computed: {
isCreate() {
return isEmpty(this.requirement);
},
fieldLabel() { fieldLabel() {
return this.isCreate ? __('New requirement') : __('Requirement'); return this.isCreate ? __('New Requirement') : __('Edit Requirement');
}, },
saveButtonLabel() { saveButtonLabel() {
return this.isCreate ? __('Create requirement') : __('Save changes'); return this.isCreate ? __('Create requirement') : __('Save changes');
...@@ -48,7 +55,24 @@ export default { ...@@ -48,7 +55,24 @@ export default {
return `REQ-${this.requirement?.iid}`; return `REQ-${this.requirement?.iid}`;
}, },
}, },
watch: {
requirement: {
handler(value) {
this.title = value?.title || '';
},
deep: true,
},
},
methods: { methods: {
getDrawerHeaderHeight() {
const wrapperEl = document.querySelector('.js-requirements-container-wrapper');
if (wrapperEl) {
return `${wrapperEl.offsetTop}px`;
}
return '';
},
handleSave() { handleSave() {
if (this.isCreate) { if (this.isCreate) {
this.$emit('save', this.title); this.$emit('save', this.title);
...@@ -64,14 +88,16 @@ export default { ...@@ -64,14 +88,16 @@ export default {
</script> </script>
<template> <template>
<div <gl-drawer :open="drawerOpen" :header-height="getDrawerHeaderHeight()" @close="$emit('cancel')">
class="requirement-form" <template #header>
:class="{ 'p-3 border-bottom': isCreate, 'd-block d-sm-flex': !isCreate }" <h4 class="m-0">{{ fieldLabel }}</h4>
> </template>
<span v-if="!isCreate" class="text-muted mr-1">{{ reference }}</span> <template>
<div class="requirement-form-container" :class="{ 'flex-grow-1 ml-sm-1 mt-1': !isCreate }"> <div class="requirement-form">
<span v-if="!isCreate" class="text-muted">{{ reference }}</span>
<div class="requirement-form-container" :class="{ 'flex-grow-1 mt-1': !isCreate }">
<gl-form-group <gl-form-group
:label="fieldLabel" :label="__('Title')"
:invalid-feedback="$options.titleInvalidMessage" :invalid-feedback="$options.titleInvalidMessage"
:state="!titleInvalid" :state="!titleInvalid"
class="gl-show-field-errors" class="gl-show-field-errors"
...@@ -100,10 +126,12 @@ export default { ...@@ -100,10 +126,12 @@ export default {
@click="handleSave" @click="handleSave"
>{{ saveButtonLabel }}</gl-deprecated-button >{{ saveButtonLabel }}</gl-deprecated-button
> >
<gl-deprecated-button class="js-requirement-cancel" @click="$emit('cancel')">{{ <gl-deprecated-button class="js-requirement-cancel" @click="$emit('cancel')">
__('Cancel') {{ __('Cancel') }}
}}</gl-deprecated-button> </gl-deprecated-button>
</div> </div>
</div> </div>
</div> </div>
</template>
</gl-drawer>
</template> </template>
...@@ -13,7 +13,6 @@ import { __, sprintf } from '~/locale'; ...@@ -13,7 +13,6 @@ import { __, sprintf } from '~/locale';
import { getTimeago } from '~/lib/utils/datetime_utility'; import { getTimeago } from '~/lib/utils/datetime_utility';
import timeagoMixin from '~/vue_shared/mixins/timeago'; import timeagoMixin from '~/vue_shared/mixins/timeago';
import RequirementForm from './requirement_form.vue';
import RequirementStatusBadge from './requirement_status_badge.vue'; import RequirementStatusBadge from './requirement_status_badge.vue';
import { FilterState } from '../constants'; import { FilterState } from '../constants';
...@@ -26,7 +25,6 @@ export default { ...@@ -26,7 +25,6 @@ export default {
GlDeprecatedButton, GlDeprecatedButton,
GlIcon, GlIcon,
GlLoadingIcon, GlLoadingIcon,
RequirementForm,
RequirementStatusBadge, RequirementStatusBadge,
}, },
directives: { directives: {
...@@ -49,16 +47,6 @@ export default { ...@@ -49,16 +47,6 @@ export default {
'testReports', 'testReports',
].every(prop => value[prop]), ].every(prop => value[prop]),
}, },
showUpdateForm: {
type: Boolean,
required: false,
default: false,
},
updateRequirementRequestActive: {
type: Boolean,
required: false,
default: false,
},
stateChangeRequestActive: { stateChangeRequestActive: {
type: Boolean, type: Boolean,
required: false, required: false,
...@@ -110,9 +98,6 @@ export default { ...@@ -110,9 +98,6 @@ export default {
} }
return ''; return '';
}, },
handleUpdateRequirementSave(params) {
this.$emit('updateSave', params);
},
handleArchiveClick() { handleArchiveClick() {
this.$emit('archiveClick', { this.$emit('archiveClick', {
iid: this.requirement.iid, iid: this.requirement.iid,
...@@ -131,14 +116,7 @@ export default { ...@@ -131,14 +116,7 @@ export default {
<template> <template>
<li class="issue requirement" :class="{ 'disabled-content': stateChangeRequestActive }"> <li class="issue requirement" :class="{ 'disabled-content': stateChangeRequestActive }">
<requirement-form <div class="issue-box">
v-if="showUpdateForm"
:requirement="requirement"
:requirement-request-active="updateRequirementRequestActive"
@save="handleUpdateRequirementSave"
@cancel="$emit('updateCancel')"
/>
<div v-else class="issue-box">
<div class="issuable-info-container"> <div class="issuable-info-container">
<span class="issuable-reference text-muted d-none d-sm-block mr-2">{{ reference }}</span> <span class="issuable-reference text-muted d-none d-sm-block mr-2">{{ reference }}</span>
<div class="issuable-main-info"> <div class="issuable-main-info">
...@@ -185,7 +163,7 @@ export default { ...@@ -185,7 +163,7 @@ export default {
size="sm" size="sm"
class="border-0" class="border-0"
:title="__('Edit')" :title="__('Edit')"
@click="$emit('editClick', requirement.iid)" @click="$emit('editClick', requirement)"
> >
<gl-icon name="pencil" /> <gl-icon name="pencil" />
</gl-deprecated-button> </gl-deprecated-button>
......
...@@ -34,7 +34,8 @@ export default { ...@@ -34,7 +34,8 @@ export default {
RequirementsLoading, RequirementsLoading,
RequirementsEmptyState, RequirementsEmptyState,
RequirementItem, RequirementItem,
RequirementForm, RequirementCreateForm: RequirementForm,
RequirementEditForm: RequirementForm,
}, },
props: { props: {
projectPath: { projectPath: {
...@@ -174,7 +175,8 @@ export default { ...@@ -174,7 +175,8 @@ export default {
authorUsernames: this.initialAuthorUsernames, authorUsernames: this.initialAuthorUsernames,
sortBy: this.initialSortBy, sortBy: this.initialSortBy,
showCreateForm: false, showCreateForm: false,
showUpdateFormForRequirement: 0, showEditForm: false,
editedRequirement: null,
createRequirementRequestActive: false, createRequirementRequestActive: false,
stateChangeRequestActiveFor: 0, stateChangeRequestActiveFor: 0,
currentPage: this.page, currentPage: this.page,
...@@ -367,8 +369,9 @@ export default { ...@@ -367,8 +369,9 @@ export default {
handleNewRequirementClick() { handleNewRequirementClick() {
this.showCreateForm = true; this.showCreateForm = true;
}, },
handleEditRequirementClick(iid) { handleEditRequirementClick(requirement) {
this.showUpdateFormForRequirement = iid; this.showEditForm = true;
this.editedRequirement = requirement;
}, },
handleNewRequirementSave(title) { handleNewRequirementSave(title) {
this.createRequirementRequestActive = true; this.createRequirementRequestActive = true;
...@@ -415,7 +418,8 @@ export default { ...@@ -415,7 +418,8 @@ export default {
}) })
.then(({ data }) => { .then(({ data }) => {
if (!data.updateRequirement.errors.length) { if (!data.updateRequirement.errors.length) {
this.showUpdateFormForRequirement = 0; this.showEditForm = false;
this.editedRequirement = null;
this.$toast.show( this.$toast.show(
sprintf(__('Requirement %{reference} has been updated'), { sprintf(__('Requirement %{reference} has been updated'), {
reference: `REQ-${data.updateRequirement.requirement.iid}`, reference: `REQ-${data.updateRequirement.requirement.iid}`,
...@@ -458,7 +462,8 @@ export default { ...@@ -458,7 +462,8 @@ export default {
}); });
}, },
handleUpdateRequirementCancel() { handleUpdateRequirementCancel() {
this.showUpdateFormForRequirement = 0; this.showEditForm = false;
this.editedRequirement = null;
}, },
handleFilterRequirements(filters = []) { handleFilterRequirements(filters = []) {
const authors = []; const authors = [];
...@@ -529,12 +534,19 @@ export default { ...@@ -529,12 +534,19 @@ export default {
@onFilter="handleFilterRequirements" @onFilter="handleFilterRequirements"
@onSort="handleSortRequirements" @onSort="handleSortRequirements"
/> />
<requirement-form <requirement-create-form
v-if="showCreateForm" :drawer-open="showCreateForm"
:requirement-request-active="createRequirementRequestActive" :requirement-request-active="createRequirementRequestActive"
@save="handleNewRequirementSave" @save="handleNewRequirementSave"
@cancel="handleNewRequirementCancel" @cancel="handleNewRequirementCancel"
/> />
<requirement-edit-form
:drawer-open="showEditForm"
:requirement="editedRequirement"
:requirement-request-active="createRequirementRequestActive"
@save="handleUpdateRequirementSave"
@cancel="handleUpdateRequirementCancel"
/>
<requirements-empty-state <requirements-empty-state
v-if="showEmptyState" v-if="showEmptyState"
:filter-by="filterBy" :filter-by="filterBy"
...@@ -557,11 +569,7 @@ export default { ...@@ -557,11 +569,7 @@ export default {
v-for="requirement in requirementsList" v-for="requirement in requirementsList"
:key="requirement.iid" :key="requirement.iid"
:requirement="requirement" :requirement="requirement"
:show-update-form="showUpdateFormForRequirement === requirement.iid"
:update-requirement-request-active="createRequirementRequestActive"
:state-change-request-active="stateChangeRequestActiveFor === requirement.iid" :state-change-request-active="stateChangeRequestActiveFor === requirement.iid"
@updateSave="handleUpdateRequirementSave"
@updateCancel="handleUpdateRequirementCancel"
@editClick="handleEditRequirementClick" @editClick="handleEditRequirementClick"
@archiveClick="handleRequirementStateChange" @archiveClick="handleRequirementStateChange"
@reopenClick="handleRequirementStateChange" @reopenClick="handleRequirementStateChange"
......
...@@ -23,6 +23,12 @@ ...@@ -23,6 +23,12 @@
} }
.requirements-list-container { .requirements-list-container {
.gl-search-box-by-click {
.gl-filtered-search-scrollable {
border-radius: 0;
}
}
.requirements-list { .requirements-list {
li .issuable-main-info { li .issuable-main-info {
// These rules prevent adjecant REQ ID from wrapping // These rules prevent adjecant REQ ID from wrapping
...@@ -64,6 +70,28 @@ ...@@ -64,6 +70,28 @@
} }
} }
} }
.gl-drawer {
width: 480px;
padding-left: $gl-padding;
padding-right: $gl-padding;
box-shadow: none;
background-color: $gray-10;
border-left: 1px solid $gray-100;
@include media-breakpoint-down(sm) {
width: 100%;
}
// These overrides should not happen here,
// we should ideally have support for custom
// header and body classes in `GlDrawer`.
.gl-drawer-header,
.gl-drawer-body > * {
padding-left: 0;
padding-right: 0;
}
}
} }
.requirement-status-tooltip { .requirement-status-tooltip {
......
- page_title _('Requirements') - page_title _('Requirements')
- @content_wrapper_class = 'js-requirements-container-wrapper'
- @content_class = 'requirements-container' - @content_class = 'requirements-container'
-# We'd prefer to have following declarations be part of -# We'd prefer to have following declarations be part of
......
---
title: Use Drawer for Requirement Create/Edit form UI
merge_request: 37943
author:
type: changed
...@@ -133,10 +133,11 @@ RSpec.describe 'Requirements list', :js do ...@@ -133,10 +133,11 @@ RSpec.describe 'Requirements list', :js do
end end
it 'shows edit form when edit button is clicked for a requirement' do it 'shows edit form when edit button is clicked for a requirement' do
page.within('.requirements-list li.requirement', match: :first) do
requirement_title = 'Foobar' requirement_title = 'Foobar'
page.within('.requirements-list li.requirement', match: :first) do
find('li.requirement-edit button[title="Edit"]').click find('li.requirement-edit button[title="Edit"]').click
end
page.within('.requirement-form') do page.within('.requirement-form') do
find('textarea#requirementTitle').native.send_keys requirement_title find('textarea#requirementTitle').native.send_keys requirement_title
...@@ -145,6 +146,7 @@ RSpec.describe 'Requirements list', :js do ...@@ -145,6 +146,7 @@ RSpec.describe 'Requirements list', :js do
wait_for_all_requests wait_for_all_requests
end end
page.within('.requirements-list li.requirement', match: :first) do
expect(page.find('.issue-title-text')).to have_content(requirement_title) expect(page.find('.issue-title-text')).to have_content(requirement_title)
end end
end end
...@@ -152,6 +154,7 @@ RSpec.describe 'Requirements list', :js do ...@@ -152,6 +154,7 @@ RSpec.describe 'Requirements list', :js do
it 'saves updated title for requirement using edit form' do it 'saves updated title for requirement using edit form' do
page.within('.requirements-list li.requirement', match: :first) do page.within('.requirements-list li.requirement', match: :first) do
find('li.requirement-edit button[title="Edit"]').click find('li.requirement-edit button[title="Edit"]').click
end
page.within('.requirement-form') do page.within('.requirement-form') do
expect(page.find('span')).to have_content("REQ-#{requirement1.iid}") expect(page.find('span')).to have_content("REQ-#{requirement1.iid}")
...@@ -159,7 +162,6 @@ RSpec.describe 'Requirements list', :js do ...@@ -159,7 +162,6 @@ RSpec.describe 'Requirements list', :js do
expect(page.find('.js-requirement-save')).to have_content('Save changes') expect(page.find('.js-requirement-save')).to have_content('Save changes')
end end
end end
end
it 'archives a requirement' do it 'archives a requirement' do
page.within('.requirements-list li.requirement', match: :first) do page.within('.requirements-list li.requirement', match: :first) do
......
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { GlFormGroup, GlFormTextarea } from '@gitlab/ui'; import { GlDrawer, GlFormGroup, GlFormTextarea } from '@gitlab/ui';
import RequirementForm from 'ee/requirements/components/requirement_form.vue'; import RequirementForm from 'ee/requirements/components/requirement_form.vue';
import { MAX_TITLE_LENGTH } from 'ee/requirements/constants'; import { MAX_TITLE_LENGTH } from 'ee/requirements/constants';
import { mockRequirementsOpen } from '../mock_data'; import { mockRequirementsOpen } from '../mock_data';
const createComponent = ({ requirement = null, requirementRequestActive = false } = {}) => const createComponent = ({
drawerOpen = true,
requirement = null,
requirementRequestActive = false,
} = {}) =>
shallowMount(RequirementForm, { shallowMount(RequirementForm, {
propsData: { propsData: {
drawerOpen,
requirement, requirement,
requirementRequestActive, requirementRequestActive,
}, },
...@@ -31,13 +36,23 @@ describe('RequirementForm', () => { ...@@ -31,13 +36,23 @@ describe('RequirementForm', () => {
}); });
describe('computed', () => { describe('computed', () => {
describe('isCreate', () => {
it('returns true when `requirement` prop is null', () => {
expect(wrapper.vm.isCreate).toBe(true);
});
it('returns false when `requirement` prop is not null', () => {
expect(wrapperWithRequirement.vm.isCreate).toBe(false);
});
});
describe('fieldLabel', () => { describe('fieldLabel', () => {
it('returns string "New requirement" when `requirement` prop is null', () => { it('returns string "New Requirement" when `requirement` prop is null', () => {
expect(wrapper.vm.fieldLabel).toBe('New requirement'); expect(wrapper.vm.fieldLabel).toBe('New Requirement');
}); });
it('returns string "Requirement" when `requirement` prop is defined', () => { it('returns string "Edit Requirement" when `requirement` prop is defined', () => {
expect(wrapperWithRequirement.vm.fieldLabel).toBe('Requirement'); expect(wrapperWithRequirement.vm.fieldLabel).toBe('Edit Requirement');
}); });
}); });
...@@ -77,6 +92,30 @@ describe('RequirementForm', () => { ...@@ -77,6 +92,30 @@ describe('RequirementForm', () => {
}); });
}); });
describe('watchers', () => {
describe('requirement', () => {
it('sets `title` to the value of `requirement.title` when requirement is not null', async () => {
wrapper.setProps({
requirement: mockRequirementsOpen[0],
});
await wrapper.vm.$nextTick();
expect(wrapper.vm.title).toBe(mockRequirementsOpen[0].title);
});
it('sets `title` to empty string when requirement is null', async () => {
wrapperWithRequirement.setProps({
requirement: null,
});
await wrapperWithRequirement.vm.$nextTick();
expect(wrapperWithRequirement.vm.title).toBe('');
});
});
});
describe('methods', () => { describe('methods', () => {
describe('handleSave', () => { describe('handleSave', () => {
it('emits `save` event on component with `title` as param when form is in create mode', () => { it('emits `save` event on component with `title` as param when form is in create mode', () => {
...@@ -109,18 +148,8 @@ describe('RequirementForm', () => { ...@@ -109,18 +148,8 @@ describe('RequirementForm', () => {
}); });
describe('template', () => { describe('template', () => {
it('renders component container element with classes `p-3 border-bottom` when form is in create mode', () => { it('renders gl-drawer as component container element', () => {
const wrapperClasses = wrapper.classes(); expect(wrapper.contains(GlDrawer)).toBe(true);
expect(wrapperClasses).toContain('p-3');
expect(wrapperClasses).toContain('border-bottom');
});
it('renders component container element with classes `d-block d-sm-flex` when form is in edit mode', () => {
const wrapperClasses = wrapperWithRequirement.classes();
expect(wrapperClasses).toContain('d-block');
expect(wrapperClasses).toContain('d-sm-flex');
}); });
it('renders element containing requirement reference when form is in edit mode', () => { it('renders element containing requirement reference when form is in edit mode', () => {
...@@ -131,7 +160,7 @@ describe('RequirementForm', () => { ...@@ -131,7 +160,7 @@ describe('RequirementForm', () => {
const glFormGroup = wrapper.find(GlFormGroup); const glFormGroup = wrapper.find(GlFormGroup);
expect(glFormGroup.exists()).toBe(true); expect(glFormGroup.exists()).toBe(true);
expect(glFormGroup.attributes('label')).toBe('New requirement'); expect(glFormGroup.attributes('label')).toBe('Title');
expect(glFormGroup.attributes('label-for')).toBe('requirementTitle'); expect(glFormGroup.attributes('label-for')).toBe('requirementTitle');
expect(glFormGroup.attributes('invalid-feedback')).toBe( expect(glFormGroup.attributes('invalid-feedback')).toBe(
`Requirement title cannot have more than ${MAX_TITLE_LENGTH} characters.`, `Requirement title cannot have more than ${MAX_TITLE_LENGTH} characters.`,
......
...@@ -2,7 +2,6 @@ import { shallowMount } from '@vue/test-utils'; ...@@ -2,7 +2,6 @@ import { shallowMount } from '@vue/test-utils';
import { GlLink, GlDeprecatedButton, GlIcon, GlLoadingIcon } from '@gitlab/ui'; import { GlLink, GlDeprecatedButton, GlIcon, GlLoadingIcon } from '@gitlab/ui';
import RequirementItem from 'ee/requirements/components/requirement_item.vue'; import RequirementItem from 'ee/requirements/components/requirement_item.vue';
import RequirementForm from 'ee/requirements/components/requirement_form.vue';
import RequirementStatusBadge from 'ee/requirements/components/requirement_status_badge.vue'; import RequirementStatusBadge from 'ee/requirements/components/requirement_status_badge.vue';
import { import {
...@@ -92,17 +91,6 @@ describe('RequirementItem', () => { ...@@ -92,17 +91,6 @@ describe('RequirementItem', () => {
}); });
describe('methods', () => { describe('methods', () => {
describe('handleUpdateRequirementSave', () => {
it('emits `updateSave` event on component with params passed as it is', () => {
wrapper.vm.handleUpdateRequirementSave('foo');
return wrapper.vm.$nextTick(() => {
expect(wrapper.emitted('updateSave')).toBeTruthy();
expect(wrapper.emitted('updateSave')[0]).toEqual(['foo']);
});
});
});
describe('handleArchiveClick', () => { describe('handleArchiveClick', () => {
it('emits `archiveClick` event on component with object containing `requirement.iid` & `state` as "ARCHIVED" as param', () => { it('emits `archiveClick` event on component with object containing `requirement.iid` & `state` as "ARCHIVED" as param', () => {
wrapper.vm.handleArchiveClick(); wrapper.vm.handleArchiveClick();
...@@ -151,16 +139,6 @@ describe('RequirementItem', () => { ...@@ -151,16 +139,6 @@ describe('RequirementItem', () => {
}); });
}); });
it('renders requirement-form component', () => {
wrapper.setProps({
showUpdateForm: true,
});
return wrapper.vm.$nextTick(() => {
expect(wrapper.find(RequirementForm).exists()).toBe(true);
});
});
it('renders element containing requirement reference', () => { it('renders element containing requirement reference', () => {
expect(wrapper.find('.issuable-reference').text()).toBe(`REQ-${requirement1.iid}`); expect(wrapper.find('.issuable-reference').text()).toBe(`REQ-${requirement1.iid}`);
}); });
......
...@@ -12,7 +12,6 @@ import RequirementsTabs from 'ee/requirements/components/requirements_tabs.vue'; ...@@ -12,7 +12,6 @@ import RequirementsTabs from 'ee/requirements/components/requirements_tabs.vue';
import RequirementsLoading from 'ee/requirements/components/requirements_loading.vue'; import RequirementsLoading from 'ee/requirements/components/requirements_loading.vue';
import RequirementsEmptyState from 'ee/requirements/components/requirements_empty_state.vue'; import RequirementsEmptyState from 'ee/requirements/components/requirements_empty_state.vue';
import RequirementItem from 'ee/requirements/components/requirement_item.vue'; import RequirementItem from 'ee/requirements/components/requirement_item.vue';
import RequirementForm from 'ee/requirements/components/requirement_form.vue';
import createRequirement from 'ee/requirements/queries/createRequirement.mutation.graphql'; import createRequirement from 'ee/requirements/queries/createRequirement.mutation.graphql';
import updateRequirement from 'ee/requirements/queries/updateRequirement.mutation.graphql'; import updateRequirement from 'ee/requirements/queries/updateRequirement.mutation.graphql';
...@@ -378,10 +377,11 @@ describe('RequirementsRoot', () => { ...@@ -378,10 +377,11 @@ describe('RequirementsRoot', () => {
}); });
describe('handleEditRequirementClick', () => { describe('handleEditRequirementClick', () => {
it('sets `showUpdateFormForRequirement` prop to value of passed param', () => { it('sets `showEditForm` prop to `true` and `editedRequirement` to value of passed param', () => {
wrapper.vm.handleEditRequirementClick('10'); wrapper.vm.handleEditRequirementClick(mockRequirementsOpen[0]);
expect(wrapper.vm.showUpdateFormForRequirement).toBe('10'); expect(wrapper.vm.showEditForm).toBe(true);
expect(wrapper.vm.editedRequirement).toBe(mockRequirementsOpen[0]);
}); });
}); });
...@@ -494,7 +494,7 @@ describe('RequirementsRoot', () => { ...@@ -494,7 +494,7 @@ describe('RequirementsRoot', () => {
); );
}); });
it('sets `showUpdateFormForRequirement` to `0` and `createRequirementRequestActive` prop to `false` when request is successful', () => { it('sets `showEditForm` to `true`, `editedRequirement` to `null` and `createRequirementRequestActive` prop to `false` when request is successful', () => {
jest.spyOn(wrapper.vm, 'updateRequirement').mockResolvedValue(mockUpdateMutationResult); jest.spyOn(wrapper.vm, 'updateRequirement').mockResolvedValue(mockUpdateMutationResult);
return wrapper.vm return wrapper.vm
...@@ -503,7 +503,8 @@ describe('RequirementsRoot', () => { ...@@ -503,7 +503,8 @@ describe('RequirementsRoot', () => {
title: 'foo', title: 'foo',
}) })
.then(() => { .then(() => {
expect(wrapper.vm.showUpdateFormForRequirement).toBe(0); expect(wrapper.vm.showEditForm).toBe(false);
expect(wrapper.vm.editedRequirement).toBe(null);
expect(wrapper.vm.createRequirementRequestActive).toBe(false); expect(wrapper.vm.createRequirementRequestActive).toBe(false);
}); });
}); });
...@@ -649,10 +650,11 @@ describe('RequirementsRoot', () => { ...@@ -649,10 +650,11 @@ describe('RequirementsRoot', () => {
}); });
describe('handleUpdateRequirementCancel', () => { describe('handleUpdateRequirementCancel', () => {
it('sets `showUpdateFormForRequirement` prop to `0`', () => { it('sets `showEditForm` prop to `false` and `editedRequirement` to `null`', () => {
wrapper.vm.handleUpdateRequirementCancel(); wrapper.vm.handleUpdateRequirementCancel();
expect(wrapper.vm.showUpdateFormForRequirement).toBe(0); expect(wrapper.vm.showEditForm).toBe(false);
expect(wrapper.vm.editedRequirement).toBe(null);
}); });
}); });
...@@ -793,14 +795,12 @@ describe('RequirementsRoot', () => { ...@@ -793,14 +795,12 @@ describe('RequirementsRoot', () => {
wrapperLoading.destroy(); wrapperLoading.destroy();
}); });
it('renders requirement-form component when `showCreateForm` prop is `true`', () => { it('renders requirement-create-form component', () => {
wrapper.setData({ expect(wrapper.contains('requirement-create-form-stub')).toBe(true);
showCreateForm: true,
}); });
return wrapper.vm.$nextTick(() => { it('renders requirement-edit-form component', () => {
expect(wrapper.contains(RequirementForm)).toBe(true); expect(wrapper.contains('requirement-edit-form-stub')).toBe(true);
});
}); });
it('does not render requirement-empty-state component when `showCreateForm` prop is `true`', () => { it('does not render requirement-empty-state component when `showCreateForm` prop is `true`', () => {
......
...@@ -8653,6 +8653,9 @@ msgstr "" ...@@ -8653,6 +8653,9 @@ msgstr ""
msgid "Edit Release" msgid "Edit Release"
msgstr "" msgstr ""
msgid "Edit Requirement"
msgstr ""
msgid "Edit Slack integration" msgid "Edit Slack integration"
msgstr "" msgstr ""
...@@ -15812,6 +15815,9 @@ msgstr "" ...@@ -15812,6 +15815,9 @@ msgstr ""
msgid "New Project" msgid "New Project"
msgstr "" msgstr ""
msgid "New Requirement"
msgstr ""
msgid "New Snippet" msgid "New Snippet"
msgstr "" msgstr ""
...@@ -20344,9 +20350,6 @@ msgstr "" ...@@ -20344,9 +20350,6 @@ msgstr ""
msgid "Required in this project." msgid "Required in this project."
msgstr "" msgstr ""
msgid "Requirement"
msgstr ""
msgid "Requirement %{reference} has been added" msgid "Requirement %{reference} has been added"
msgstr "" msgstr ""
......
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