Commit 71a09d24 authored by Natalia Tepluhina's avatar Natalia Tepluhina

Merge branch 'alert-management-empty-state' into 'master'

Split out empty state

See merge request gitlab-org/gitlab!36456
parents 09773394 133b4528
<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