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