Commit 37f2fc45 authored by Olena Horal-Koretska's avatar Olena Horal-Koretska Committed by Natalia Tepluhina

Empty state for alerts list

parent db2d5289
<script> <script>
import { GlEmptyState, GlButton, GlLoadingIcon } from '@gitlab/ui'; import { mapState } from 'vuex';
import { GlEmptyState, GlButton, GlLoadingIcon, GlTable, GlAlert } from '@gitlab/ui';
import { __ } from '~/locale';
const tdClass = 'table-col d-flex';
export default { export default {
fields: [
{
key: 'severity',
label: __('Severity'),
tdClass,
},
{
key: 'start_time',
label: __('Start Time'),
tdClass,
},
{
key: 'end_time',
label: __('End Time'),
tdClass,
},
{
key: 'alert',
label: __('Alert'),
thClass: 'w-30p',
tdClass,
},
{
key: 'events',
label: __('Events'),
tdClass,
},
{
key: 'status',
label: __('Status'),
tdClass,
},
],
components: { components: {
GlEmptyState, GlEmptyState,
GlButton, GlButton,
GlLoadingIcon, GlLoadingIcon,
GlTable,
GlAlert,
}, },
props: { props: {
indexPath: { indexPath: {
type: String, type: String,
required: true, required: true,
}, },
// TODO: Handle alertManagementEnabled depending on resolution - https://gitlab.com/gitlab-org/gitlab/-/merge_requests/30024.
alertManagementEnabled: {
type: Boolean,
required: false,
default: true,
},
enableAlertManagementPath: { enableAlertManagementPath: {
type: String, type: String,
required: true, required: true,
...@@ -23,19 +68,45 @@ export default { ...@@ -23,19 +68,45 @@ export default {
}, },
data() { data() {
return { return {
alerts: [], isAlertDismissed: false,
loading: false,
}; };
}, },
computed: {
...mapState('list', ['alerts', 'loading']),
showNoAlertsMsg() {
return !this.alerts.length && !this.isAlertDismissed;
},
},
}; };
</script> </script>
<template> <template>
<div> <div>
<div v-if="alerts.length > 0" class="alert-management-list"> <div v-if="alertManagementEnabled" class="alert-management-list">
<gl-alert v-if="showNoAlertsMsg" @dismiss="isAlertDismissed = true">
{{
__(
`No alerts available to display. If you think you're seeing this message in error, refresh the page.`,
)
}}
</gl-alert>
<div v-if="loading" class="py-3"> <div v-if="loading" class="py-3">
<gl-loading-icon size="md" /> <gl-loading-icon size="md" />
</div> </div>
<gl-table
class="mt-3"
:items="alerts"
:fields="$options.fields"
:show-empty="true"
fixed
stacked="sm"
tbody-tr-class="table-row mb-4"
>
<template #empty>
{{ __('No alerts to display.') }}
</template>
</gl-table>
</div> </div>
<template v-else> <template v-else>
<gl-empty-state :title="__('Surface alerts in GitLab')" :svg-path="emptyAlertSvgPath"> <gl-empty-state :title="__('Surface alerts in GitLab')" :svg-path="emptyAlertSvgPath">
...@@ -51,9 +122,9 @@ export default { ...@@ -51,9 +122,9 @@ export default {
</a> </a>
</div> </div>
<div class="d-block center pt-4"> <div class="d-block center pt-4">
<gl-button category="primary" variant="success" :href="enableAlertManagementPath">{{ <gl-button category="primary" variant="success" :href="enableAlertManagementPath">
__('Authorize external service') {{ __('Authorize external service') }}
}}</gl-button> </gl-button>
</div> </div>
</template> </template>
</gl-empty-state> </gl-empty-state>
......
import Vue from 'vue'; import Vue from 'vue';
import store from './store';
import AlertManagementList from './components/alert_management_list.vue'; import AlertManagementList from './components/alert_management_list.vue';
export default () => { export default () => {
...@@ -12,6 +13,7 @@ export default () => { ...@@ -12,6 +13,7 @@ export default () => {
components: { components: {
AlertManagementList, AlertManagementList,
}, },
store,
render(createElement) { render(createElement) {
return createElement('alert-management-list', { return createElement('alert-management-list', {
props: { props: {
......
import Vue from 'vue';
import Vuex from 'vuex';
import * as listActions from './list/actions';
import listMutations from './list/mutations';
import listState from './list/state';
Vue.use(Vuex);
export const createStore = () =>
new Vuex.Store({
modules: {
list: {
namespaced: true,
state: listState(),
actions: listActions,
mutations: listMutations,
},
},
});
export default createStore();
import * as types from './mutation_types';
export const setAlerts = ({ commit }, alerts) => {
commit(types.SET_ALERTS, alerts);
};
export const setLoading = ({ commit }, loading) => {
commit(types.SET_LOADING, loading);
};
export const SET_ALERTS = 'SET_ALERTS';
export const SET_LOADING = 'SET_LOADING';
import * as types from './mutation_types';
export default {
[types.SET_ALERTS](state, alerts) {
state.alerts = alerts;
},
[types.SET_LOADING](state, loading) {
state.loading = loading;
},
};
export default () => ({
alerts: [],
loading: false,
});
// these styles need to be deleted once GlTable component looks in GitLab same as in @gitlab/ui
.alert-management-list {
table {
color: $gray-700;
tr {
td,
th {
@include gl-p-4;
}
th {
background-color: transparent;
font-weight: $gl-font-weight-bold;
color: $gl-gray-600;
@include gl-border-b-1;
@include gl-border-b-solid;
border-color: $gray-100;
}
td {
@include gl-border-0;
}
}
}
}
---
title: Empty state for alerts list
merge_request: 30215
author:
type: added
...@@ -7835,6 +7835,9 @@ msgstr "" ...@@ -7835,6 +7835,9 @@ msgstr ""
msgid "Encountered an error while rendering: %{err}" msgid "Encountered an error while rendering: %{err}"
msgstr "" msgstr ""
msgid "End Time"
msgstr ""
msgid "End date" msgid "End date"
msgstr "" msgstr ""
...@@ -13658,6 +13661,12 @@ msgstr "" ...@@ -13658,6 +13661,12 @@ msgstr ""
msgid "No activities found" msgid "No activities found"
msgstr "" msgstr ""
msgid "No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "No alerts to display."
msgstr ""
msgid "No application_settings found" msgid "No application_settings found"
msgstr "" msgstr ""
...@@ -18765,6 +18774,9 @@ msgstr "" ...@@ -18765,6 +18774,9 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings." msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr "" msgstr ""
msgid "Severity"
msgstr ""
msgid "Severity: %{severity}" msgid "Severity: %{severity}"
msgstr "" msgstr ""
...@@ -19547,6 +19559,9 @@ msgstr "" ...@@ -19547,6 +19559,9 @@ msgstr ""
msgid "Start GitLab Ultimate trial" msgid "Start GitLab Ultimate trial"
msgstr "" msgstr ""
msgid "Start Time"
msgstr ""
msgid "Start Web Terminal" msgid "Start Web Terminal"
msgstr "" msgstr ""
......
import { mount } from '@vue/test-utils'; import { createLocalVue, mount } from '@vue/test-utils';
import { GlEmptyState } from '@gitlab/ui'; import { GlEmptyState, GlTable, GlAlert } from '@gitlab/ui';
import Vuex from 'vuex';
import stubChildren from 'helpers/stub_children'; import stubChildren from 'helpers/stub_children';
import AlertManagementList from '~/alert_management/components/alert_management_list.vue'; import AlertManagementList from '~/alert_management/components/alert_management_list.vue';
const localVue = createLocalVue();
localVue.use(Vuex);
describe('AlertManagementList', () => { describe('AlertManagementList', () => {
let wrapper; let wrapper;
let store;
const findAlertsTable = () => wrapper.find(GlTable);
const findAlert = () => wrapper.find(GlAlert);
function mountComponent({ stubs = {} } = {}) { function mountComponent({ stubs = {}, alertManagementEnabled = false } = {}) {
wrapper = mount(AlertManagementList, { wrapper = mount(AlertManagementList, {
localVue,
store,
propsData: { propsData: {
indexPath: '/path', indexPath: '/path',
enableAlertManagementPath: '/link', enableAlertManagementPath: '/link',
emptyAlertSvgPath: 'illustration/path', emptyAlertSvgPath: 'illustration/path',
alertManagementEnabled,
}, },
stubs: { stubs: {
...stubChildren(AlertManagementList), ...stubChildren(AlertManagementList),
...@@ -20,19 +31,43 @@ describe('AlertManagementList', () => { ...@@ -20,19 +31,43 @@ describe('AlertManagementList', () => {
}); });
} }
beforeEach(() => {
store = new Vuex.Store({
modules: {
list: {
namespaced: true,
},
},
});
mountComponent();
});
afterEach(() => { afterEach(() => {
if (wrapper) { if (wrapper) {
wrapper.destroy(); wrapper.destroy();
store = null;
} }
}); });
describe('alert management feature renders empty state', () => { describe('alert management feature renders empty state', () => {
beforeEach(() => {
mountComponent();
});
it('shows empty state', () => { it('shows empty state', () => {
expect(wrapper.find(GlEmptyState).exists()).toBe(true); expect(wrapper.find(GlEmptyState).exists()).toBe(true);
}); });
}); });
describe('Alerts table', () => {
it('shows empty list', () => {
store.state.list = {
alerts: [],
loading: false,
};
mountComponent({ alertManagementEnabled: true });
return wrapper.vm.$nextTick().then(() => {
expect(findAlertsTable().exists()).toBe(true);
expect(findAlert().text()).toContain('No alerts available to display');
});
});
});
}); });
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