Commit 133b4528 authored by David O'Regan's avatar David O'Regan Committed by Natalia Tepluhina

Split out empty state

We split the empty state from the table
of alerts and use the list wrapper as
a interface component.
parent 7c6d5829
<script>
import { GlEmptyState, GlButton } from '@gitlab/ui';
export default {
components: {
GlEmptyState,
GlButton,
},
props: {
enableAlertManagementPath: {
type: String,
required: true,
},
userCanEnableAlertManagement: {
type: Boolean,
required: true,
},
emptyAlertSvgPath: {
type: String,
required: true,
},
},
};
</script>
<template>
<div>
<gl-empty-state
:title="s__('AlertManagement|Surface alerts in GitLab')"
:svg-path="emptyAlertSvgPath"
>
<template #description>
<div class="d-block">
<span>{{
s__(
'AlertManagement|Display alerts from all your monitoring tools directly within GitLab. Streamline the investigation of your alerts and the escalation of alerts to incidents.',
)
}}</span>
<a href="/help/user/project/operations/alert_management.html" target="_blank">
{{ s__('AlertManagement|More information') }}
</a>
</div>
<div v-if="userCanEnableAlertManagement" class="d-block center pt-4">
<gl-button category="primary" variant="success" :href="enableAlertManagementPath">
{{ s__('AlertManagement|Authorize external service') }}
</gl-button>
</div>
</template>
</gl-empty-state>
</div>
</template>
<script>
import Tracking from '~/tracking';
import { trackAlertListViewsOptions } from '../constants';
import AlertManagementEmptyState from './alert_management_empty_state.vue';
import AlertManagementTable from './alert_management_table.vue';
export default {
components: {
AlertManagementEmptyState,
AlertManagementTable,
},
props: {
projectPath: {
type: String,
required: true,
},
alertManagementEnabled: {
type: Boolean,
required: true,
},
enableAlertManagementPath: {
type: String,
required: true,
},
populatingAlertsHelpUrl: {
type: String,
required: true,
},
userCanEnableAlertManagement: {
type: Boolean,
required: true,
},
emptyAlertSvgPath: {
type: String,
required: true,
},
},
mounted() {
this.trackPageViews();
},
methods: {
trackPageViews() {
const { category, action } = trackAlertListViewsOptions;
Tracking.event(category, action);
},
},
};
</script>
<template>
<div>
<alert-management-table
v-if="alertManagementEnabled"
:populating-alerts-help-url="populatingAlertsHelpUrl"
:project-path="projectPath"
/>
<alert-management-empty-state
v-else
:empty-alert-svg-path="emptyAlertSvgPath"
:enable-alert-management-path="enableAlertManagementPath"
:user-can-enable-alert-management="userCanEnableAlertManagement"
/>
</div>
</template>
<script> <script>
import { import {
GlEmptyState,
GlDeprecatedButton,
GlLoadingIcon, GlLoadingIcon,
GlTable, GlTable,
GlAlert, GlAlert,
...@@ -108,11 +106,9 @@ export default { ...@@ -108,11 +106,9 @@ export default {
severityLabels: ALERTS_SEVERITY_LABELS, severityLabels: ALERTS_SEVERITY_LABELS,
statusTabs: ALERTS_STATUS_TABS, statusTabs: ALERTS_STATUS_TABS,
components: { components: {
GlEmptyState,
GlLoadingIcon, GlLoadingIcon,
GlTable, GlTable,
GlAlert, GlAlert,
GlDeprecatedButton,
TimeAgo, TimeAgo,
GlIcon, GlIcon,
GlLink, GlLink,
...@@ -129,26 +125,10 @@ export default { ...@@ -129,26 +125,10 @@ export default {
type: String, type: String,
required: true, required: true,
}, },
alertManagementEnabled: {
type: Boolean,
required: true,
},
enableAlertManagementPath: {
type: String,
required: true,
},
populatingAlertsHelpUrl: { populatingAlertsHelpUrl: {
type: String, type: String,
required: true, required: true,
}, },
userCanEnableAlertManagement: {
type: Boolean,
required: true,
},
emptyAlertSvgPath: {
type: String,
required: true,
},
}, },
apollo: { apollo: {
alerts: { alerts: {
...@@ -323,7 +303,7 @@ export default { ...@@ -323,7 +303,7 @@ export default {
</script> </script>
<template> <template>
<div> <div>
<div v-if="alertManagementEnabled" class="alert-management-list"> <div class="alert-management-list">
<gl-alert v-if="showNoAlertsMsg" @dismiss="isAlertDismissed = true"> <gl-alert v-if="showNoAlertsMsg" @dismiss="isAlertDismissed = true">
<gl-sprintf :message="$options.i18n.noAlertsMsg"> <gl-sprintf :message="$options.i18n.noAlertsMsg">
<template #link="{ content }"> <template #link="{ content }">
...@@ -453,32 +433,5 @@ export default { ...@@ -453,32 +433,5 @@ export default {
@input="handlePageChange" @input="handlePageChange"
/> />
</div> </div>
<gl-empty-state
v-else
:title="s__('AlertManagement|Surface alerts in GitLab')"
:svg-path="emptyAlertSvgPath"
>
<template #description>
<div class="d-block">
<span>{{
s__(
'AlertManagement|Display alerts from all your monitoring tools directly within GitLab. Streamline the investigation of your alerts and the escalation of alerts to incidents.',
)
}}</span>
<a href="/help/user/project/operations/alert_management.html" target="_blank">
{{ s__('AlertManagement|More information') }}
</a>
</div>
<div v-if="userCanEnableAlertManagement" class="d-block center pt-4">
<gl-deprecated-button
category="primary"
variant="success"
:href="enableAlertManagementPath"
>
{{ s__('AlertManagement|Authorize external service') }}
</gl-deprecated-button>
</div>
</template>
</gl-empty-state>
</div> </div>
</template> </template>
...@@ -3,7 +3,7 @@ import VueApollo from 'vue-apollo'; ...@@ -3,7 +3,7 @@ import VueApollo from 'vue-apollo';
import createDefaultClient from '~/lib/graphql'; import createDefaultClient from '~/lib/graphql';
import { defaultDataIdFromObject } from 'apollo-cache-inmemory'; import { defaultDataIdFromObject } from 'apollo-cache-inmemory';
import { parseBoolean } from '~/lib/utils/common_utils'; import { parseBoolean } from '~/lib/utils/common_utils';
import AlertManagementList from './components/alert_management_list.vue'; import AlertManagementList from './components/alert_management_list_wrapper.vue';
Vue.use(VueApollo); Vue.use(VueApollo);
......
import { shallowMount } from '@vue/test-utils';
import { GlEmptyState } from '@gitlab/ui';
import AlertManagementEmptyState from '~/alert_management/components/alert_management_empty_state.vue';
describe('AlertManagementEmptyState', () => {
let wrapper;
function mountComponent({
props = {
alertManagementEnabled: false,
userCanEnableAlertManagement: false,
},
} = {}) {
wrapper = shallowMount(AlertManagementEmptyState, {
propsData: {
enableAlertManagementPath: '/link',
emptyAlertSvgPath: 'illustration/path',
...props,
},
});
}
beforeEach(() => {
mountComponent();
});
afterEach(() => {
if (wrapper) {
wrapper.destroy();
}
});
describe('Empty state', () => {
it('shows empty state', () => {
expect(wrapper.find(GlEmptyState).exists()).toBe(true);
});
});
});
import { shallowMount } from '@vue/test-utils';
import AlertManagementList from '~/alert_management/components/alert_management_list_wrapper.vue';
import { trackAlertListViewsOptions } from '~/alert_management/constants';
import mockAlerts from '../mocks/alerts.json';
import Tracking from '~/tracking';
describe('AlertManagementList', () => {
let wrapper;
function mountComponent({
props = {
alertManagementEnabled: false,
userCanEnableAlertManagement: false,
},
data = {},
stubs = {},
} = {}) {
wrapper = shallowMount(AlertManagementList, {
propsData: {
projectPath: 'gitlab-org/gitlab',
enableAlertManagementPath: '/link',
populatingAlertsHelpUrl: '/help/help-page.md#populating-alert-data',
emptyAlertSvgPath: 'illustration/path',
...props,
},
data() {
return data;
},
stubs,
});
}
beforeEach(() => {
mountComponent();
});
afterEach(() => {
if (wrapper) {
wrapper.destroy();
}
});
describe('Snowplow tracking', () => {
beforeEach(() => {
jest.spyOn(Tracking, 'event');
mountComponent({
props: { alertManagementEnabled: true, userCanEnableAlertManagement: true },
data: { alerts: { list: mockAlerts } },
});
});
it('should track alert list page views', () => {
const { category, action } = trackAlertListViewsOptions;
expect(Tracking.event).toHaveBeenCalledWith(category, action);
});
});
});
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import { import {
GlEmptyState,
GlTable, GlTable,
GlAlert, GlAlert,
GlLoadingIcon, GlLoadingIcon,
...@@ -15,12 +14,8 @@ import { ...@@ -15,12 +14,8 @@ import {
} from '@gitlab/ui'; } from '@gitlab/ui';
import { visitUrl } from '~/lib/utils/url_utility'; import { visitUrl } from '~/lib/utils/url_utility';
import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue'; import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue';
import AlertManagementList from '~/alert_management/components/alert_management_list.vue'; import AlertManagementTable from '~/alert_management/components/alert_management_table.vue';
import { import { ALERTS_STATUS_TABS, trackAlertStatusUpdateOptions } from '~/alert_management/constants';
ALERTS_STATUS_TABS,
trackAlertListViewsOptions,
trackAlertStatusUpdateOptions,
} from '~/alert_management/constants';
import updateAlertStatus from '~/alert_management/graphql/mutations/update_alert_status.mutation.graphql'; import updateAlertStatus from '~/alert_management/graphql/mutations/update_alert_status.mutation.graphql';
import mockAlerts from '../mocks/alerts.json'; import mockAlerts from '../mocks/alerts.json';
import Tracking from '~/tracking'; import Tracking from '~/tracking';
...@@ -30,7 +25,7 @@ jest.mock('~/lib/utils/url_utility', () => ({ ...@@ -30,7 +25,7 @@ jest.mock('~/lib/utils/url_utility', () => ({
joinPaths: jest.requireActual('~/lib/utils/url_utility').joinPaths, joinPaths: jest.requireActual('~/lib/utils/url_utility').joinPaths,
})); }));
describe('AlertManagementList', () => { describe('AlertManagementTable', () => {
let wrapper; let wrapper;
const findAlertsTable = () => wrapper.find(GlTable); const findAlertsTable = () => wrapper.find(GlTable);
...@@ -66,12 +61,10 @@ describe('AlertManagementList', () => { ...@@ -66,12 +61,10 @@ describe('AlertManagementList', () => {
loading = false, loading = false,
stubs = {}, stubs = {},
} = {}) { } = {}) {
wrapper = mount(AlertManagementList, { wrapper = mount(AlertManagementTable, {
propsData: { propsData: {
projectPath: 'gitlab-org/gitlab', projectPath: 'gitlab-org/gitlab',
enableAlertManagementPath: '/link',
populatingAlertsHelpUrl: '/help/help-page.md#populating-alert-data', populatingAlertsHelpUrl: '/help/help-page.md#populating-alert-data',
emptyAlertSvgPath: 'illustration/path',
...props, ...props,
}, },
data() { data() {
...@@ -93,7 +86,7 @@ describe('AlertManagementList', () => { ...@@ -93,7 +86,7 @@ describe('AlertManagementList', () => {
} }
beforeEach(() => { beforeEach(() => {
mountComponent(); mountComponent({ data: { alerts: mockAlerts, alertsCount } });
}); });
afterEach(() => { afterEach(() => {
...@@ -102,12 +95,6 @@ describe('AlertManagementList', () => { ...@@ -102,12 +95,6 @@ describe('AlertManagementList', () => {
} }
}); });
describe('Empty state', () => {
it('shows empty state', () => {
expect(wrapper.find(GlEmptyState).exists()).toBe(true);
});
});
describe('Status Filter Tabs', () => { describe('Status Filter Tabs', () => {
beforeEach(() => { beforeEach(() => {
mountComponent({ mountComponent({
...@@ -450,11 +437,6 @@ describe('AlertManagementList', () => { ...@@ -450,11 +437,6 @@ describe('AlertManagementList', () => {
}); });
}); });
it('should track alert list page views', () => {
const { category, action } = trackAlertListViewsOptions;
expect(Tracking.event).toHaveBeenCalledWith(category, action);
});
it('should track alert status updates', () => { it('should track alert status updates', () => {
Tracking.event.mockClear(); Tracking.event.mockClear();
jest.spyOn(wrapper.vm.$apollo, 'mutate').mockResolvedValue({}); jest.spyOn(wrapper.vm.$apollo, 'mutate').mockResolvedValue({});
......
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