Commit db3a4dc4 authored by Peter Leitzen's avatar Peter Leitzen

Merge branch '213880-Basic-alert-list-view' into 'master'

Displays basic alerts list view

See merge request gitlab-org/gitlab!30395
parents bc55b37b 52aab9eb
<script> <script>
import { GlEmptyState, GlDeprecatedButton, GlLoadingIcon, GlTable, GlAlert } from '@gitlab/ui'; import { GlEmptyState, GlDeprecatedButton, GlLoadingIcon, GlTable, GlAlert } from '@gitlab/ui';
import { s__ } from '~/locale'; import { s__ } from '~/locale';
import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue';
import getAlerts from '../graphql/queries/getAlerts.query.graphql'; import getAlerts from '../graphql/queries/getAlerts.query.graphql';
const tdClass = 'table-col d-flex';
export default { export default {
i18n: { i18n: {
noAlertsMsg: s__( noAlertsMsg: s__(
...@@ -18,33 +17,29 @@ export default { ...@@ -18,33 +17,29 @@ export default {
{ {
key: 'severity', key: 'severity',
label: s__('AlertManagement|Severity'), label: s__('AlertManagement|Severity'),
tdClass,
}, },
{ {
key: 'start_time', key: 'startedAt',
label: s__('AlertManagement|Start Time'), label: s__('AlertManagement|Start time'),
tdClass,
}, },
{ {
key: 'end_time', key: 'endedAt',
label: s__('AlertManagement|End Time'), label: s__('AlertManagement|End time'),
tdClass,
}, },
{ {
key: 'alert', key: 'title',
label: s__('AlertManagement|Alert'), label: s__('AlertManagement|Alert'),
thClass: 'w-30p', thClass: 'w-30p',
tdClass,
}, },
{ {
key: 'events', key: 'eventCount',
label: s__('AlertManagement|Events'), label: s__('AlertManagement|Events'),
tdClass, thClass: 'text-right event-count',
tdClass: 'text-right event-count',
}, },
{ {
key: 'status', key: 'status',
label: s__('AlertManagement|Status'), label: s__('AlertManagement|Status'),
tdClass,
}, },
], ],
components: { components: {
...@@ -53,9 +48,10 @@ export default { ...@@ -53,9 +48,10 @@ export default {
GlTable, GlTable,
GlAlert, GlAlert,
GlDeprecatedButton, GlDeprecatedButton,
TimeAgo,
}, },
props: { props: {
indexPath: { projectPath: {
type: String, type: String,
required: true, required: true,
}, },
...@@ -81,9 +77,12 @@ export default { ...@@ -81,9 +77,12 @@ export default {
query: getAlerts, query: getAlerts,
variables() { variables() {
return { return {
projectPath: this.indexPath, projectPath: this.projectPath,
}; };
}, },
update(data) {
return data.project.alertManagementAlerts.nodes;
},
error() { error() {
this.errored = true; this.errored = true;
}, },
...@@ -128,18 +127,34 @@ export default { ...@@ -128,18 +127,34 @@ export default {
:show-empty="true" :show-empty="true"
:busy="loading" :busy="loading"
fixed fixed
stacked="sm" stacked="md"
tbody-tr-class="table-row mb-4"
> >
<template #cell(startedAt)="{ item }">
<time-ago :time="item.startedAt" />
</template>
<template #cell(endedAt)="{ item }">
<time-ago :time="item.endedAt" />
</template>
<template #cell(title)="{ item }">
<div class="gl-max-w-full text-truncate">{{ item.title }}</div>
</template>
<template #empty> <template #empty>
{{ s__('AlertManagement|No alerts to display.') }} {{ s__('AlertManagement|No alerts to display.') }}
</template> </template>
<template #table-busy> <template #table-busy>
<gl-loading-icon size="lg" color="dark" class="mt-3" /> <gl-loading-icon size="lg" color="dark" class="mt-3" />
</template> </template>
</gl-table> </gl-table>
</div> </div>
<gl-empty-state v-else :title="__('Surface alerts in GitLab')" :svg-path="emptyAlertSvgPath"> <gl-empty-state
v-else
:title="__('AlertManagement|Surface alerts in GitLab')"
:svg-path="emptyAlertSvgPath"
>
<template #description> <template #description>
<div class="d-block"> <div class="d-block">
<span>{{ <span>{{
......
fragment AlertListItem on Alert { fragment AlertListItem on AlertManagementAlert {
iid iid
title title
severity severity
status status
started_at startedAt
ended_at endedAt
event_count eventCount
} }
#import "../fragments/listItem.fragment.graphql" #import "../fragments/listItem.fragment.graphql"
query getAlerts( query getAlerts($projectPath: ID!) {
$projectPath: ID!
) {
project(fullPath: $projectPath) { project(fullPath: $projectPath) {
alerts { alertManagementAlerts {
nodes {
...AlertListItem ...AlertListItem
} }
} }
}
} }
...@@ -10,7 +10,7 @@ export default () => { ...@@ -10,7 +10,7 @@ export default () => {
const selector = '#js-alert_management'; const selector = '#js-alert_management';
const domEl = document.querySelector(selector); const domEl = document.querySelector(selector);
const { indexPath, enableAlertManagementPath, emptyAlertSvgPath } = domEl.dataset; const { projectPath, enableAlertManagementPath, emptyAlertSvgPath } = domEl.dataset;
let { alertManagementEnabled, userCanEnableAlertManagement } = domEl.dataset; let { alertManagementEnabled, userCanEnableAlertManagement } = domEl.dataset;
alertManagementEnabled = parseBoolean(alertManagementEnabled); alertManagementEnabled = parseBoolean(alertManagementEnabled);
...@@ -29,7 +29,7 @@ export default () => { ...@@ -29,7 +29,7 @@ export default () => {
render(createElement) { render(createElement) {
return createElement('alert-management-list', { return createElement('alert-management-list', {
props: { props: {
indexPath, projectPath,
enableAlertManagementPath, enableAlertManagementPath,
emptyAlertSvgPath, emptyAlertSvgPath,
alertManagementEnabled, alertManagementEnabled,
......
// these styles need to be deleted once GlTable component looks in GitLab same as in @gitlab/ui
.alert-management-list { .alert-management-list {
// these styles need to be deleted once GlTable component looks in GitLab same as in @gitlab/ui
table { table {
color: $gray-700; color: $gray-700;
tr { tr {
td, td,
th { th {
@include gl-p-4; @include gl-p-5;
&.event-count {
@include gl-pr-9;
}
} }
th { th {
...@@ -18,9 +22,11 @@ ...@@ -18,9 +22,11 @@
border-color: $gray-100; border-color: $gray-100;
} }
&:last-child {
td { td {
@include gl-border-0; @include gl-border-0;
} }
} }
} }
}
} }
...@@ -3,8 +3,7 @@ ...@@ -3,8 +3,7 @@
module Projects::AlertManagementHelper module Projects::AlertManagementHelper
def alert_management_data(current_user, project) def alert_management_data(current_user, project)
{ {
'index-path' => project_alert_management_index_path(project, 'project-path' => project.full_path,
format: :json),
'enable-alert-management-path' => project_settings_operations_path(project), 'enable-alert-management-path' => project_settings_operations_path(project),
'empty-alert-svg-path' => image_path('illustrations/alert-management-empty-state.svg'), 'empty-alert-svg-path' => image_path('illustrations/alert-management-empty-state.svg'),
'user-can-enable-alert-management' => 'false', 'user-can-enable-alert-management' => 'false',
......
...@@ -1701,7 +1701,7 @@ msgstr "" ...@@ -1701,7 +1701,7 @@ msgstr ""
msgid "AlertManagement|Display alerts from all your monitoring tools directly within GitLab. Streamline the investigation of your alerts and the escalation of alerts to incidents." msgid "AlertManagement|Display alerts from all your monitoring tools directly within GitLab. Streamline the investigation of your alerts and the escalation of alerts to incidents."
msgstr "" msgstr ""
msgid "AlertManagement|End Time" msgid "AlertManagement|End time"
msgstr "" msgstr ""
msgid "AlertManagement|Events" msgid "AlertManagement|Events"
...@@ -1719,12 +1719,15 @@ msgstr "" ...@@ -1719,12 +1719,15 @@ msgstr ""
msgid "AlertManagement|Severity" msgid "AlertManagement|Severity"
msgstr "" msgstr ""
msgid "AlertManagement|Start Time" msgid "AlertManagement|Start time"
msgstr "" msgstr ""
msgid "AlertManagement|Status" msgid "AlertManagement|Status"
msgstr "" msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear." msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr "" msgstr ""
...@@ -20174,9 +20177,6 @@ msgstr "" ...@@ -20174,9 +20177,6 @@ msgstr ""
msgid "Support page URL" msgid "Support page URL"
msgstr "" msgstr ""
msgid "Surface alerts in GitLab"
msgstr ""
msgid "Switch branch/tag" msgid "Switch branch/tag"
msgstr "" msgstr ""
......
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import { GlEmptyState, GlTable, GlAlert, GlLoadingIcon } from '@gitlab/ui'; import { GlEmptyState, GlTable, GlAlert, GlLoadingIcon } from '@gitlab/ui';
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';
import mockAlerts from '../mocks/alerts.json';
describe('AlertManagementList', () => { describe('AlertManagementList', () => {
let wrapper; let wrapper;
const findAlertsTable = () => wrapper.find(GlTable); const findAlertsTable = () => wrapper.find(GlTable);
const findAlerts = () => wrapper.findAll('table tbody tr');
const findAlert = () => wrapper.find(GlAlert); const findAlert = () => wrapper.find(GlAlert);
const findLoader = () => wrapper.find(GlLoadingIcon); const findLoader = () => wrapper.find(GlLoadingIcon);
function mountComponent({ function mountComponent({
stubs = {},
props = { props = {
alertManagementEnabled: false, alertManagementEnabled: false,
userCanEnableAlertManagement: false, userCanEnableAlertManagement: false,
...@@ -21,7 +22,7 @@ describe('AlertManagementList', () => { ...@@ -21,7 +22,7 @@ describe('AlertManagementList', () => {
} = {}) { } = {}) {
wrapper = mount(AlertManagementList, { wrapper = mount(AlertManagementList, {
propsData: { propsData: {
indexPath: '/path', projectPath: 'gitlab-org/gitlab',
enableAlertManagementPath: '/link', enableAlertManagementPath: '/link',
emptyAlertSvgPath: 'illustration/path', emptyAlertSvgPath: 'illustration/path',
...props, ...props,
...@@ -38,10 +39,6 @@ describe('AlertManagementList', () => { ...@@ -38,10 +39,6 @@ describe('AlertManagementList', () => {
}, },
}, },
}, },
stubs: {
...stubChildren(AlertManagementList),
...stubs,
},
}); });
} }
...@@ -64,7 +61,6 @@ describe('AlertManagementList', () => { ...@@ -64,7 +61,6 @@ describe('AlertManagementList', () => {
describe('Alerts table', () => { describe('Alerts table', () => {
it('loading state', () => { it('loading state', () => {
mountComponent({ mountComponent({
stubs: { GlTable },
props: { alertManagementEnabled: true, userCanEnableAlertManagement: true }, props: { alertManagementEnabled: true, userCanEnableAlertManagement: true },
data: { alerts: null }, data: { alerts: null },
loading: true, loading: true,
...@@ -75,7 +71,6 @@ describe('AlertManagementList', () => { ...@@ -75,7 +71,6 @@ describe('AlertManagementList', () => {
it('error state', () => { it('error state', () => {
mountComponent({ mountComponent({
stubs: { GlTable },
props: { alertManagementEnabled: true, userCanEnableAlertManagement: true }, props: { alertManagementEnabled: true, userCanEnableAlertManagement: true },
data: { alerts: null, errored: true }, data: { alerts: null, errored: true },
loading: false, loading: false,
...@@ -88,7 +83,6 @@ describe('AlertManagementList', () => { ...@@ -88,7 +83,6 @@ describe('AlertManagementList', () => {
it('empty state', () => { it('empty state', () => {
mountComponent({ mountComponent({
stubs: { GlTable },
props: { alertManagementEnabled: true, userCanEnableAlertManagement: true }, props: { alertManagementEnabled: true, userCanEnableAlertManagement: true },
data: { alerts: [], errored: false }, data: { alerts: [], errored: false },
loading: false, loading: false,
...@@ -98,5 +92,16 @@ describe('AlertManagementList', () => { ...@@ -98,5 +92,16 @@ describe('AlertManagementList', () => {
expect(findLoader().exists()).toBe(false); expect(findLoader().exists()).toBe(false);
expect(findAlert().props().variant).toBe('info'); expect(findAlert().props().variant).toBe('info');
}); });
it('has data state', () => {
mountComponent({
props: { alertManagementEnabled: true, userCanEnableAlertManagement: true },
data: { alerts: mockAlerts, errored: false },
loading: false,
});
expect(findLoader().exists()).toBe(false);
expect(findAlertsTable().exists()).toBe(true);
expect(findAlerts()).toHaveLength(mockAlerts.length);
});
}); });
}); });
[
{
"iid": "1527542",
"title": "SyntaxError: Invalid or unexpected token",
"severity": "Critical",
"eventCount": 7,
"startedAt": "2020-04-17T23:18:14.996Z",
"endedAt": "2020-04-17T23:18:14.996Z",
"status": "triggered"
},
{
"iid": "1527542",
"title": "Some otherr alert Some otherr alert Some otherr alert Some otherr alert Some otherr alert Some otherr alert",
"severity": "Medium",
"eventCount": 1,
"startedAt": "2020-04-17T23:18:14.996Z",
"endedAt": "2020-04-17T23:18:14.996Z",
"status": "acknowledged"
},
{
"iid": "1527542",
"title": "SyntaxError: Invalid or unexpected token",
"severity": "Low",
"eventCount": 4,
"startedAt": "2020-04-17T23:18:14.996Z",
"endedAt": "2020-04-17T23:18:14.996Z",
"status": "resolved"
}
]
...@@ -11,10 +11,7 @@ describe Projects::AlertManagementHelper do ...@@ -11,10 +11,7 @@ describe Projects::AlertManagementHelper do
describe '#alert_management_data' do describe '#alert_management_data' do
let(:user_can_enable_alert_management) { false } let(:user_can_enable_alert_management) { false }
let(:setting_path) { project_settings_operations_path(project) } let(:setting_path) { project_settings_operations_path(project) }
let(:project_path) { project.full_path }
let(:index_path) do
project_alert_management_index_path(project, format: :json)
end
before do before do
allow(helper) allow(helper)
...@@ -26,9 +23,9 @@ describe Projects::AlertManagementHelper do ...@@ -26,9 +23,9 @@ describe Projects::AlertManagementHelper do
context 'without alert_managements_setting' do context 'without alert_managements_setting' do
it 'returns frontend configuration' do it 'returns frontend configuration' do
expect(alert_management_data(current_user, project)).to eq( expect(alert_management_data(current_user, project)).to eq(
'index-path' => index_path, 'project-path' => project_path,
'enable-alert-management-path' => setting_path, 'enable-alert-management-path' => setting_path,
"empty-alert-svg-path" => "/images/illustrations/alert-management-empty-state.svg", 'empty-alert-svg-path' => '/images/illustrations/alert-management-empty-state.svg',
'user-can-enable-alert-management' => 'false', 'user-can-enable-alert-management' => 'false',
'alert-management-enabled' => 'true' 'alert-management-enabled' => 'true'
) )
......
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