Commit b0b4f9e7 authored by Donald Cook's avatar Donald Cook Committed by Miguel Rincon

Removed delete iteration option for closed iterations

For iteration cadences, when viewing an iteration report the user can
no longer delete the iteration if that iteration has already been
closed.
parent 016430f6
...@@ -14,8 +14,7 @@ import { TYPE_ITERATION } from '~/graphql_shared/constants'; ...@@ -14,8 +14,7 @@ import { TYPE_ITERATION } from '~/graphql_shared/constants';
import { convertToGraphQLId } from '~/graphql_shared/utils'; import { convertToGraphQLId } from '~/graphql_shared/utils';
import { formatDate } from '~/lib/utils/datetime_utility'; import { formatDate } from '~/lib/utils/datetime_utility';
import { s__ } from '~/locale'; import { s__ } from '~/locale';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import { Namespace, iterationStates } from '../constants';
import { Namespace } from '../constants';
import deleteIteration from '../queries/destroy_iteration.mutation.graphql'; import deleteIteration from '../queries/destroy_iteration.mutation.graphql';
import query from '../queries/iteration.query.graphql'; import query from '../queries/iteration.query.graphql';
import { getIterationPeriod } from '../utils'; import { getIterationPeriod } from '../utils';
...@@ -60,7 +59,6 @@ export default { ...@@ -60,7 +59,6 @@ export default {
}, },
}, },
}, },
mixins: [glFeatureFlagsMixin()],
inject: [ inject: [
'fullPath', 'fullPath',
'hasScopedLabelsFeature', 'hasScopedLabelsFeature',
...@@ -96,6 +94,9 @@ export default { ...@@ -96,6 +94,9 @@ export default {
iterationPeriod() { iterationPeriod() {
return getIterationPeriod(this.iteration); return getIterationPeriod(this.iteration);
}, },
showDelete() {
return this.iteration.state !== iterationStates.closed;
},
}, },
methods: { methods: {
formatDate(date) { formatDate(date) {
...@@ -165,7 +166,7 @@ export default { ...@@ -165,7 +166,7 @@ export default {
><gl-icon name="ellipsis_v" /> ><gl-icon name="ellipsis_v" />
</template> </template>
<gl-dropdown-item :to="editPage">{{ __('Edit') }}</gl-dropdown-item> <gl-dropdown-item :to="editPage">{{ __('Edit') }}</gl-dropdown-item>
<gl-dropdown-item data-testid="delete-iteration" @click="showModal"> <gl-dropdown-item v-if="showDelete" @click="showModal">
{{ __('Delete') }} {{ __('Delete') }}
</gl-dropdown-item> </gl-dropdown-item>
</gl-dropdown> </gl-dropdown>
......
...@@ -13,8 +13,11 @@ import waitForPromises from 'helpers/wait_for_promises'; ...@@ -13,8 +13,11 @@ import waitForPromises from 'helpers/wait_for_promises';
import { getIdFromGraphQLId } from '~/graphql_shared/utils'; import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import IterationTitle from 'ee/iterations/components/iteration_title.vue'; import IterationTitle from 'ee/iterations/components/iteration_title.vue';
import { getIterationPeriod } from 'ee/iterations/utils'; import { getIterationPeriod } from 'ee/iterations/utils';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import { __ } from '~/locale';
import { import {
mockIterationNode, mockIterationNode,
mockPastIterationNode,
createMockGroupIterations, createMockGroupIterations,
mockIterationNodeWithoutTitle, mockIterationNodeWithoutTitle,
mockProjectIterations, mockProjectIterations,
...@@ -46,6 +49,7 @@ describe('Iterations report', () => { ...@@ -46,6 +49,7 @@ describe('Iterations report', () => {
const findHeading = () => wrapper.findComponent({ ref: 'heading' }); const findHeading = () => wrapper.findComponent({ ref: 'heading' });
const findDescription = () => wrapper.findComponent({ ref: 'description' }); const findDescription = () => wrapper.findComponent({ ref: 'description' });
const findActionsDropdown = () => wrapper.find('[data-testid="actions-dropdown"]'); const findActionsDropdown = () => wrapper.find('[data-testid="actions-dropdown"]');
const findDeleteButton = () => wrapper.findByText(__('Delete'));
const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon); const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
const findEmptyState = () => wrapper.findComponent(GlEmptyState); const findEmptyState = () => wrapper.findComponent(GlEmptyState);
...@@ -63,33 +67,35 @@ describe('Iterations report', () => { ...@@ -63,33 +67,35 @@ describe('Iterations report', () => {
[deleteIteration, deleteMutationMock], [deleteIteration, deleteMutationMock],
]); ]);
wrapper = shallowMount(IterationReport, { wrapper = extendedWrapper(
apolloProvider: mockApollo, shallowMount(IterationReport, {
propsData: props, apolloProvider: mockApollo,
provide: { propsData: props,
fullPath: props.fullPath, provide: {
groupPath: props.fullPath, fullPath: props.fullPath,
cadencesListPath: '/groups/some-group/-/cadences', groupPath: props.fullPath,
canCreateCadence: true, cadencesListPath: '/groups/some-group/-/cadences',
canEditCadence: true, canCreateCadence: true,
namespaceType: props.namespaceType, canEditCadence: true,
canEditIteration: props.canEditIteration, namespaceType: props.namespaceType,
hasScopedLabelsFeature: true, canEditIteration: props.canEditIteration,
labelsFetchPath, hasScopedLabelsFeature: true,
previewMarkdownPath: '/markdown', labelsFetchPath,
noIssuesSvgPath: '/some.svg', previewMarkdownPath: '/markdown',
}, noIssuesSvgPath: '/some.svg',
mocks: { },
$router, mocks: {
$toast, $router,
}, $toast,
stubs: { },
GlLoadingIcon, stubs: {
GlTab, GlLoadingIcon,
GlTabs, GlTab,
IterationTitle, GlTabs,
}, IterationTitle,
}); },
}),
);
}; };
describe('with mock apollo', () => { describe('with mock apollo', () => {
...@@ -149,6 +155,14 @@ describe('Iterations report', () => { ...@@ -149,6 +155,14 @@ describe('Iterations report', () => {
}); });
describe('delete iteration', () => { describe('delete iteration', () => {
it('does not show delete option for past iterations', async () => {
mountComponent({ mockQueryResponse: createMockGroupIterations(mockPastIterationNode) });
await waitForPromises();
expect(findDeleteButton().exists()).toBe(false);
});
it('deletes iteration', async () => { it('deletes iteration', async () => {
mountComponent(); mountComponent();
......
import { iterationStates } from 'ee/iterations/constants';
export const mockIterationNode = { export const mockIterationNode = {
description: 'some description', description: 'some description',
descriptionHtml: '<p>some description</p>', descriptionHtml: '<p>some description</p>',
...@@ -5,12 +7,17 @@ export const mockIterationNode = { ...@@ -5,12 +7,17 @@ export const mockIterationNode = {
id: 'gid://gitlab/Iteration/4', id: 'gid://gitlab/Iteration/4',
iid: '1', iid: '1',
startDate: '2021-02-10', startDate: '2021-02-10',
state: 'upcoming', state: iterationStates.upcoming,
title: 'top-level-iteration', title: 'top-level-iteration',
webPath: '/groups/top-level-group/-/iterations/4', webPath: '/groups/top-level-group/-/iterations/4',
__typename: 'Iteration', __typename: 'Iteration',
}; };
export const mockPastIterationNode = {
...mockIterationNode,
state: iterationStates.closed,
};
export const mockIterationNodeWithoutTitle = { export const mockIterationNodeWithoutTitle = {
...mockIterationNode, ...mockIterationNode,
title: null, title: null,
......
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