Commit 8d4c8375 authored by Jose Ivan Vargas's avatar Jose Ivan Vargas

Merge branch '229636-incident-empty-state-polish' into 'master'

Update empty state behavior for incidents list

See merge request gitlab-org/gitlab!40872
parents 44ea3a4c 9235a1d4
...@@ -208,6 +208,31 @@ export default { ...@@ -208,6 +208,31 @@ export default {
isEmpty() { isEmpty() {
return !this.incidents.list?.length; return !this.incidents.list?.length;
}, },
showList() {
return !this.isEmpty || this.errored || this.loading;
},
activeClosedTabHasNoIncidents() {
const { all, closed } = this.incidentsCount || {};
const isClosedTabActive = this.statusFilter === this.$options.statusTabs[1].filters;
return isClosedTabActive && all && !closed;
},
emptyStateData() {
const {
emptyState: { title, emptyClosedTabTitle, description },
createIncidentBtnLabel,
} = this.$options.i18n;
if (this.activeClosedTabHasNoIncidents) {
return { title: emptyClosedTabTitle };
}
return {
title,
description,
btnLink: this.newIncidentPath,
btnText: createIncidentBtnLabel,
};
},
}, },
methods: { methods: {
onInputChange: debounce(function debounceSearch(input) { onInputChange: debounce(function debounceSearch(input) {
...@@ -279,7 +304,7 @@ export default { ...@@ -279,7 +304,7 @@ export default {
</gl-tabs> </gl-tabs>
<gl-button <gl-button
v-if="!isEmpty" v-if="!isEmpty || activeClosedTabHasNoIncidents"
class="gl-my-3 gl-mr-5 create-incident-button" class="gl-my-3 gl-mr-5 create-incident-button"
data-testid="createIncidentBtn" data-testid="createIncidentBtn"
data-qa-selector="create_incident_button" data-qa-selector="create_incident_button"
...@@ -307,6 +332,7 @@ export default { ...@@ -307,6 +332,7 @@ export default {
{{ s__('IncidentManagement|Incidents') }} {{ s__('IncidentManagement|Incidents') }}
</h4> </h4>
<gl-table <gl-table
v-if="showList"
:items="incidents.list || []" :items="incidents.list || []"
:fields="availableFields" :fields="availableFields"
:show-empty="true" :show-empty="true"
...@@ -379,21 +405,20 @@ export default { ...@@ -379,21 +405,20 @@ export default {
<gl-loading-icon size="lg" color="dark" class="mt-3" /> <gl-loading-icon size="lg" color="dark" class="mt-3" />
</template> </template>
<template #empty> <template v-if="errored" #empty>
<gl-empty-state
v-if="!errored"
:title="$options.i18n.emptyState.title"
:svg-path="emptyListSvgPath"
:description="$options.i18n.emptyState.description"
:primary-button-link="newIncidentPath"
:primary-button-text="$options.i18n.createIncidentBtnLabel"
/>
<span v-else>
{{ $options.i18n.noIncidents }} {{ $options.i18n.noIncidents }}
</span>
</template> </template>
</gl-table> </gl-table>
<gl-empty-state
v-else
:title="emptyStateData.title"
:svg-path="emptyListSvgPath"
:description="emptyStateData.description"
:primary-button-link="emptyStateData.btnLink"
:primary-button-text="emptyStateData.btnText"
/>
<gl-pagination <gl-pagination
v-if="showPaginationControls" v-if="showPaginationControls"
:value="pagination.currentPage" :value="pagination.currentPage"
......
...@@ -9,6 +9,7 @@ export const I18N = { ...@@ -9,6 +9,7 @@ export const I18N = {
searchPlaceholder: __('Search results…'), searchPlaceholder: __('Search results…'),
emptyState: { emptyState: {
title: s__('IncidentManagement|Display your incidents in a dedicated view'), title: s__('IncidentManagement|Display your incidents in a dedicated view'),
emptyClosedTabTitle: s__('IncidentManagement|There are no closed incidents'),
description: s__( description: s__(
'IncidentManagement|All alerts promoted to incidents will automatically be displayed within the list. You can also create a new incident using the button below.', 'IncidentManagement|All alerts promoted to incidents will automatically be displayed within the list. You can also create a new incident using the button below.',
), ),
......
---
title: Update empty state behavior for incidents list
merge_request: 40872
author:
type: other
...@@ -13115,6 +13115,9 @@ msgstr "" ...@@ -13115,6 +13115,9 @@ msgstr ""
msgid "IncidentManagement|Published to status page" msgid "IncidentManagement|Published to status page"
msgstr "" msgstr ""
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
msgid "IncidentManagement|There was an error displaying the incidents." msgid "IncidentManagement|There was an error displaying the incidents."
msgstr "" msgstr ""
......
...@@ -78,6 +78,7 @@ describe('Incidents List', () => { ...@@ -78,6 +78,7 @@ describe('Incidents List', () => {
stubs: { stubs: {
GlButton: true, GlButton: true,
GlAvatar: true, GlAvatar: true,
GlEmptyState: true,
}, },
}); });
} }
...@@ -96,12 +97,30 @@ describe('Incidents List', () => { ...@@ -96,12 +97,30 @@ describe('Incidents List', () => {
expect(findLoader().exists()).toBe(true); expect(findLoader().exists()).toBe(true);
}); });
it('shows empty state', () => { describe('empty state', () => {
const {
emptyState: { title, emptyClosedTabTitle, description },
} = I18N;
it.each`
statusFilter | all | closed | expectedTitle | expectedDescription
${'all'} | ${2} | ${1} | ${title} | ${description}
${'open'} | ${2} | ${0} | ${title} | ${description}
${'closed'} | ${0} | ${0} | ${title} | ${description}
${'closed'} | ${2} | ${0} | ${emptyClosedTabTitle} | ${undefined}
`(
`when active tab is $statusFilter and there are $all incidents in total and $closed closed incidents, the empty state
has title: $expectedTitle and description: $expectedDescription`,
({ statusFilter, all, closed, expectedTitle, expectedDescription }) => {
mountComponent({ mountComponent({
data: { incidents: { list: [] }, incidentsCount: {} }, data: { incidents: { list: [] }, incidentsCount: { all, closed }, statusFilter },
loading: false, loading: false,
}); });
expect(findEmptyState().exists()).toBe(true); expect(findEmptyState().exists()).toBe(true);
expect(findEmptyState().attributes('title')).toBe(expectedTitle);
expect(findEmptyState().attributes('description')).toBe(expectedDescription);
},
);
}); });
it('shows error state', () => { it('shows error state', () => {
...@@ -188,6 +207,14 @@ describe('Incidents List', () => { ...@@ -188,6 +207,14 @@ describe('Incidents List', () => {
expect(findCreateIncidentBtn().attributes('loading')).toBe('true'); expect(findCreateIncidentBtn().attributes('loading')).toBe('true');
}); });
}); });
it("doesn't show the button when list is empty", () => {
mountComponent({
data: { incidents: { list: [] }, incidentsCount: {} },
loading: false,
});
expect(findCreateIncidentBtn().exists()).toBe(false);
});
}); });
describe('Pagination', () => { describe('Pagination', () => {
...@@ -313,7 +340,7 @@ describe('Incidents List', () => { ...@@ -313,7 +340,7 @@ describe('Incidents List', () => {
describe('Status Filter Tabs', () => { describe('Status Filter Tabs', () => {
beforeEach(() => { beforeEach(() => {
mountComponent({ mountComponent({
data: { incidents: mockIncidents, incidentsCount }, data: { incidents: { list: mockIncidents }, incidentsCount },
loading: false, loading: false,
stubs: { stubs: {
GlTab: true, GlTab: true,
...@@ -345,7 +372,7 @@ describe('Incidents List', () => { ...@@ -345,7 +372,7 @@ describe('Incidents List', () => {
describe('sorting the incident list by column', () => { describe('sorting the incident list by column', () => {
beforeEach(() => { beforeEach(() => {
mountComponent({ mountComponent({
data: { incidents: mockIncidents, incidentsCount }, data: { incidents: { list: mockIncidents }, incidentsCount },
loading: false, loading: false,
}); });
}); });
......
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