Commit 12c0a7f7 authored by Alexander Turinske's avatar Alexander Turinske

Generalize alert details status

- allow for configuration of statues in the
  sidebar and details table of alerts
- update tests
parent f6c065c0
......@@ -21,7 +21,7 @@ import Tracking from '~/tracking';
import initUserPopovers from '~/user_popovers';
import AlertDetailsTable from '~/vue_shared/components/alert_details_table.vue';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import { SEVERITY_LEVELS } from '../constants';
import { PAGE_CONFIG, SEVERITY_LEVELS } from '../constants';
import createIssueMutation from '../graphql/mutations/alert_issue_create.mutation.graphql';
import toggleSidebarStatusMutation from '../graphql/mutations/alert_sidebar_status.mutation.graphql';
import alertQuery from '../graphql/queries/alert_details.query.graphql';
......@@ -92,6 +92,9 @@ export default {
projectIssuesPath: {
default: '',
},
statuses: {
default: PAGE_CONFIG.OPERATIONS.STATUSES,
},
trackAlertsDetailsViewsOptions: {
default: null,
},
......@@ -367,7 +370,7 @@ export default {
>
{{ alert.runbook }}
</alert-summary-row>
<alert-details-table :alert="alert" :loading="loading" />
<alert-details-table :alert="alert" :loading="loading" :statuses="statuses" />
</gl-tab>
<gl-tab
v-if="!isThreatMonitoringPage"
......
......@@ -19,10 +19,6 @@ export default {
projectId: {
default: '',
},
// TODO remove this limitation in https://gitlab.com/gitlab-org/gitlab/-/issues/296717
isThreatMonitoringPage: {
default: false,
},
},
props: {
alert: {
......@@ -66,7 +62,6 @@ export default {
@alert-error="$emit('alert-error', $event)"
/>
<sidebar-status
v-if="!isThreatMonitoringPage"
:project-path="projectPath"
:alert="alert"
@toggle-sidebar="$emit('toggle-sidebar')"
......
......@@ -3,6 +3,7 @@ import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
import updateAlertStatusMutation from '~/graphql_shared/mutations/alert_status_update.mutation.graphql';
import { s__ } from '~/locale';
import Tracking from '~/tracking';
import { PAGE_CONFIG } from '../constants';
export default {
i18n: {
......@@ -11,11 +12,6 @@ export default {
),
UPDATE_ALERT_STATUS_INSTRUCTION: s__('AlertManagement|Please try again.'),
},
statuses: {
TRIGGERED: s__('AlertManagement|Triggered'),
ACKNOWLEDGED: s__('AlertManagement|Acknowledged'),
RESOLVED: s__('AlertManagement|Resolved'),
},
components: {
GlDropdown,
GlDropdownItem,
......@@ -24,6 +20,9 @@ export default {
trackAlertStatusUpdateOptions: {
default: null,
},
statuses: {
default: PAGE_CONFIG.OPERATIONS.STATUSES,
},
},
props: {
projectPath: {
......@@ -57,13 +56,13 @@ export default {
mutation: updateAlertStatusMutation,
variables: {
iid: this.alert.iid,
status: status.toUpperCase(),
status,
projectPath: this.projectPath,
},
})
.then((resp) => {
if (this.trackAlertStatusUpdateOptions) {
this.trackStatusUpdate(status);
this.trackStatusUpdate(this.statuses[status]);
}
const errors = resp.data?.updateAlertStatus?.errors || [];
......@@ -99,7 +98,7 @@ export default {
<gl-dropdown
ref="dropdown"
right
:text="$options.statuses[alert.status]"
:text="statuses[alert.status]"
class="w-100"
toggle-class="dropdown-menu-toggle"
@keydown.esc.native="$emit('hide-dropdown')"
......@@ -110,12 +109,12 @@ export default {
</p>
<div class="dropdown-content dropdown-body">
<gl-dropdown-item
v-for="(label, field) in $options.statuses"
v-for="(label, field) in statuses"
:key="field"
data-testid="statusDropdownItem"
:active="label.toUpperCase() === alert.status"
:active="field === alert.status"
:active-class="'is-active'"
@click="updateAlertStatus(label)"
@click="updateAlertStatus(field)"
>
{{ label }}
</gl-dropdown-item>
......
<script>
import { GlIcon, GlLoadingIcon, GlTooltip, GlSprintf } from '@gitlab/ui';
import { s__ } from '~/locale';
import { PAGE_CONFIG } from '../../constants';
import AlertStatus from '../alert_status.vue';
export default {
statuses: {
TRIGGERED: s__('AlertManagement|Triggered'),
ACKNOWLEDGED: s__('AlertManagement|Acknowledged'),
RESOLVED: s__('AlertManagement|Resolved'),
},
components: {
GlIcon,
GlLoadingIcon,
......@@ -16,6 +11,11 @@ export default {
GlSprintf,
AlertStatus,
},
inject: {
statuses: {
default: PAGE_CONFIG.OPERATIONS.STATUSES,
},
},
props: {
projectPath: {
type: String,
......@@ -103,14 +103,11 @@ export default {
<p
v-else-if="!isDropdownShowing"
class="value gl-m-0"
:class="{ 'no-value': !$options.statuses[alert.status] }"
:class="{ 'no-value': !statuses[alert.status] }"
>
<span
v-if="$options.statuses[alert.status]"
class="gl-text-gray-500"
data-testid="status"
>{{ $options.statuses[alert.status] }}</span
>
<span v-if="statuses[alert.status]" class="gl-text-gray-500" data-testid="status">
{{ statuses[alert.status] }}
</span>
<span v-else>
{{ s__('AlertManagement|None') }}
</span>
......
......@@ -13,6 +13,11 @@ export const SEVERITY_LEVELS = {
export const PAGE_CONFIG = {
OPERATIONS: {
TITLE: 'OPERATIONS',
STATUSES: {
TRIGGERED: s__('AlertManagement|Triggered'),
ACKNOWLEDGED: s__('AlertManagement|Acknowledged'),
RESOLVED: s__('AlertManagement|Resolved'),
},
// Tracks snowplow event when user views alert details
TRACK_ALERTS_DETAILS_VIEWS_OPTIONS: {
category: 'Alert Management',
......@@ -27,5 +32,11 @@ export const PAGE_CONFIG = {
},
THREAT_MONITORING: {
TITLE: 'THREAT_MONITORING',
STATUSES: {
TRIGGERED: s__('ThreatMonitoring|Unreviewed'),
ACKNOWLEDGED: s__('ThreatMonitoring|In review'),
RESOLVED: s__('ThreatMonitoring|Resolved'),
IGNORED: s__('ThreatMonitoring|Dismissed'),
},
},
};
......@@ -55,6 +55,7 @@ export default (selector) => {
page,
projectIssuesPath,
projectId,
statuses: PAGE_CONFIG[page].STATUSES,
};
if (page === PAGE_CONFIG.OPERATIONS.TITLE) {
......
......@@ -42,6 +42,11 @@ export default {
type: Boolean,
required: true,
},
statuses: {
type: Object,
required: false,
default: () => ({}),
},
},
fields: [
{
......@@ -71,6 +76,8 @@ export default {
let value;
if (fieldName === 'environment') {
value = fieldValue?.name;
} else if (fieldName === 'status') {
value = this.statuses[fieldValue] || fieldValue;
} else {
value = fieldValue;
}
......
---
title: Generalize alert details status
merge_request: 56800
author:
type: added
......@@ -8,7 +8,7 @@ import { joinPaths } from '~/lib/utils/url_utility';
import Tracking from '~/tracking';
import AlertDetails from '~/vue_shared/alert_details/components/alert_details.vue';
import AlertSummaryRow from '~/vue_shared/alert_details/components/alert_summary_row.vue';
import { SEVERITY_LEVELS } from '~/vue_shared/alert_details/constants';
import { PAGE_CONFIG, SEVERITY_LEVELS } from '~/vue_shared/alert_details/constants';
import createIssueMutation from '~/vue_shared/alert_details/graphql/mutations/alert_issue_create.mutation.graphql';
import AlertDetailsTable from '~/vue_shared/components/alert_details_table.vue';
import mockAlerts from './mocks/alerts.json';
......@@ -271,7 +271,13 @@ describe('AlertDetails', () => {
});
it('should display a table of raw alert details data', () => {
expect(findDetailsTable().exists()).toBe(true);
const details = findDetailsTable();
expect(details.exists()).toBe(true);
expect(details.props()).toStrictEqual({
alert: mockAlert,
statuses: PAGE_CONFIG.OPERATIONS.STATUSES,
loading: false,
});
});
});
......
......@@ -76,20 +76,4 @@ describe('Alert Details Sidebar', () => {
expect(wrapper.find(SidebarStatus).exists()).toBe(true);
});
});
describe('the sidebar renders for threat monitoring', () => {
beforeEach(() => {
mock = new MockAdapter(axios);
mountComponent();
});
it('should not render side bar status dropdown', () => {
mountComponent({
mountMethod: mount,
alert: mockAlert,
provide: { isThreatMonitoringPage: true },
});
expect(wrapper.find(SidebarStatus).exists()).toBe(false);
});
});
});
import { GlLoadingIcon, GlTable } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import { PAGE_CONFIG } from '~/vue_shared/alert_details/constants';
import AlertDetailsTable from '~/vue_shared/components/alert_details_table.vue';
const mockAlert = {
......@@ -115,6 +116,15 @@ describe('AlertDetails', () => {
expect(findTableFieldValueByKey('Environment').text()).toBeFalsy();
});
it('should show the provided status if statuses prop is not provided', () => {
expect(findTableFieldValueByKey('Status').text()).toBe('TRIGGERED');
});
it('should show the translated status if statuses prop is provided', () => {
mountComponent({ statuses: PAGE_CONFIG.OPERATIONS.STATUSES });
expect(findTableFieldValueByKey('Status').text()).toBe('Triggered');
});
});
});
});
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