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