Commit 507f5c2f authored by Nicolò Maria Mezzopera's avatar Nicolò Maria Mezzopera

Merge branch 'psi-empty-cadences' into 'master'

Better empty state messages for cadences

See merge request gitlab-org/gitlab!69828
parents 7ebcc9eb 05753725
...@@ -21,8 +21,12 @@ import TimeboxStatusBadge from './timebox_status_badge.vue'; ...@@ -21,8 +21,12 @@ import TimeboxStatusBadge from './timebox_status_badge.vue';
const pageSize = 20; const pageSize = 20;
const i18n = Object.freeze({ const i18n = Object.freeze({
noResults: s__('Iterations|No iterations in cadence.'), noResults: {
createFirstIteration: s__('Iterations|Create your first iteration'), opened: s__('Iterations|No open iterations.'),
closed: s__('Iterations|No closed iterations.'),
all: s__('Iterations|No iterations in cadence.'),
},
createIteration: s__('Iterations|Create iteration'),
error: __('Error loading iterations'), error: __('Error loading iterations'),
deleteCadence: s__('Iterations|Delete cadence'), deleteCadence: s__('Iterations|Delete cadence'),
...@@ -65,7 +69,7 @@ export default { ...@@ -65,7 +69,7 @@ export default {
}, },
}, },
}, },
inject: ['fullPath', 'canEditCadence', 'namespaceType'], inject: ['fullPath', 'canEditCadence', 'canCreateIteration', 'namespaceType'],
props: { props: {
title: { title: {
type: String, type: String,
...@@ -305,16 +309,16 @@ export default { ...@@ -305,16 +309,16 @@ export default {
</template> </template>
</gl-infinite-scroll> </gl-infinite-scroll>
<template v-else-if="!loading"> <template v-else-if="!loading">
<p class="gl-px-7">{{ i18n.noResults }}</p> <p class="gl-px-7">{{ i18n.noResults[iterationState] }}</p>
<gl-button <gl-button
v-if="!automatic" v-if="!automatic && canCreateIteration"
variant="confirm" variant="confirm"
category="secondary" category="secondary"
class="gl-mb-5 gl-ml-7" class="gl-mb-5 gl-ml-7"
data-qa-selector="create_cadence_cta" data-qa-selector="create_cadence_cta"
:to="newIteration" :to="newIteration"
> >
{{ i18n.createFirstIteration }} {{ i18n.createIteration }}
</gl-button> </gl-button>
</template> </template>
</gl-collapse> </gl-collapse>
......
...@@ -12,6 +12,7 @@ import { mountExtended as mount } from 'helpers/vue_test_utils_helper'; ...@@ -12,6 +12,7 @@ import { mountExtended as mount } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises'; import waitForPromises from 'helpers/wait_for_promises';
import { getIdFromGraphQLId } from '~/graphql_shared/utils'; import { getIdFromGraphQLId } from '~/graphql_shared/utils';
const { i18n } = IterationCadenceListItem;
const push = jest.fn(); const push = jest.fn();
const $router = { const $router = {
push, push,
...@@ -86,7 +87,7 @@ describe('Iteration cadence list item', () => { ...@@ -86,7 +87,7 @@ describe('Iteration cadence list item', () => {
}; };
function createComponent({ function createComponent({
props = {}, props = {},
canCreateCadence, canCreateIteration,
canEditCadence, canEditCadence,
currentRoute, currentRoute,
namespaceType = Namespace.Group, namespaceType = Namespace.Group,
...@@ -109,14 +110,14 @@ describe('Iteration cadence list item', () => { ...@@ -109,14 +110,14 @@ describe('Iteration cadence list item', () => {
}, },
provide: { provide: {
fullPath, fullPath,
canCreateCadence, canCreateIteration,
canEditCadence, canEditCadence,
namespaceType, namespaceType,
}, },
propsData: { propsData: {
title: cadence.title, title: cadence.title,
cadenceId: cadence.id, cadenceId: cadence.id,
iterationState: 'open', iterationState: 'opened',
...props, ...props,
}, },
}); });
...@@ -125,6 +126,8 @@ describe('Iteration cadence list item', () => { ...@@ -125,6 +126,8 @@ describe('Iteration cadence list item', () => {
} }
const findLoader = () => wrapper.findComponent(GlSkeletonLoader); const findLoader = () => wrapper.findComponent(GlSkeletonLoader);
const findCreateIterationButton = () =>
wrapper.findByRole('link', { text: i18n.createIteration });
const expand = () => wrapper.findByRole('button', { text: cadence.title }).trigger('click'); const expand = () => wrapper.findByRole('button', { text: cadence.title }).trigger('click');
afterEach(() => { afterEach(() => {
...@@ -142,9 +145,14 @@ describe('Iteration cadence list item', () => { ...@@ -142,9 +145,14 @@ describe('Iteration cadence list item', () => {
expect(resolverMock).not.toHaveBeenCalled(); expect(resolverMock).not.toHaveBeenCalled();
}); });
it('shows empty text and CTA when no results', async () => { it.each(['opened', 'closed', 'all'])(
'shows empty text when no results for list of %s iterations',
async (iterationState) => {
await createComponent({ await createComponent({
resolverMock: jest.fn().mockResolvedValue(queryEmptyResponse), resolverMock: jest.fn().mockResolvedValue(queryEmptyResponse),
props: {
iterationState,
},
}); });
expand(); expand();
...@@ -152,8 +160,24 @@ describe('Iteration cadence list item', () => { ...@@ -152,8 +160,24 @@ describe('Iteration cadence list item', () => {
await waitForPromises(); await waitForPromises();
expect(findLoader().exists()).toBe(false); expect(findLoader().exists()).toBe(false);
expect(wrapper.text()).toContain(IterationCadenceListItem.i18n.noResults); expect(wrapper.text()).toContain(i18n.noResults[iterationState]);
expect(wrapper.text()).toContain(IterationCadenceListItem.i18n.createFirstIteration); },
);
it.each([
['hides', false],
['shows', true],
])('%s Create iteration button when canCreateIteration is %s', async (_, canCreateIteration) => {
await createComponent({
canCreateIteration,
resolverMock: jest.fn().mockResolvedValue(queryEmptyResponse),
});
expand();
await waitForPromises();
expect(findCreateIterationButton().exists()).toBe(canCreateIteration);
}); });
it('shows iterations after loading', async () => { it('shows iterations after loading', async () => {
...@@ -205,7 +229,7 @@ describe('Iteration cadence list item', () => { ...@@ -205,7 +229,7 @@ describe('Iteration cadence list item', () => {
await waitForPromises(); await waitForPromises();
expect(findLoader().exists()).toBe(false); expect(findLoader().exists()).toBe(false);
expect(wrapper.text()).toContain(IterationCadenceListItem.i18n.error); expect(wrapper.text()).toContain(i18n.error);
}); });
it('calls fetchMore after scrolling down', async () => { it('calls fetchMore after scrolling down', async () => {
......
...@@ -112,6 +112,7 @@ describe('Iteration cadences list', () => { ...@@ -112,6 +112,7 @@ describe('Iteration cadences list', () => {
namespaceType, namespaceType,
cadencesListPath, cadencesListPath,
canCreateCadence, canCreateCadence,
canCreateIteration: false,
canEditCadence, canEditCadence,
}, },
}); });
......
...@@ -18940,7 +18940,7 @@ msgstr "" ...@@ -18940,7 +18940,7 @@ msgstr ""
msgid "Iterations|Create cadence" msgid "Iterations|Create cadence"
msgstr "" msgstr ""
msgid "Iterations|Create your first iteration" msgid "Iterations|Create iteration"
msgstr "" msgstr ""
msgid "Iterations|Delete cadence" msgid "Iterations|Delete cadence"
...@@ -18985,12 +18985,18 @@ msgstr "" ...@@ -18985,12 +18985,18 @@ msgstr ""
msgid "Iterations|New iteration cadence" msgid "Iterations|New iteration cadence"
msgstr "" msgstr ""
msgid "Iterations|No closed iterations."
msgstr ""
msgid "Iterations|No iteration cadences to show." msgid "Iterations|No iteration cadences to show."
msgstr "" msgstr ""
msgid "Iterations|No iterations in cadence." msgid "Iterations|No iterations in cadence."
msgstr "" msgstr ""
msgid "Iterations|No open iterations."
msgstr ""
msgid "Iterations|Number of future iterations you would like to have scheduled" msgid "Iterations|Number of future iterations you would like to have scheduled"
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