Commit 1a0a2a8f authored by Ezekiel Kigbo's avatar Ezekiel Kigbo

Merge branch '287755-add-status-change-to-drawer' into 'master'

Add alert status change dropdown to drawer

See merge request gitlab-org/gitlab!61832
parents 4088b7ad f246c452
...@@ -65,6 +65,8 @@ export default { ...@@ -65,6 +65,8 @@ export default {
:project-path="projectPath" :project-path="projectPath"
:alert="alert" :alert="alert"
:sidebar-collapsed="sidebarStatus" :sidebar-collapsed="sidebarStatus"
text-class="gl-text-gray-500"
class="gl-w-70p"
@toggle-sidebar="$emit('toggle-sidebar')" @toggle-sidebar="$emit('toggle-sidebar')"
@alert-error="$emit('alert-error', $event)" @alert-error="$emit('alert-error', $event)"
/> />
......
...@@ -34,6 +34,11 @@ export default { ...@@ -34,6 +34,11 @@ export default {
type: Boolean, type: Boolean,
required: false, required: false,
}, },
textClass: {
type: String,
required: false,
default: '',
},
}, },
data() { data() {
return { return {
...@@ -57,8 +62,11 @@ export default { ...@@ -57,8 +62,11 @@ export default {
dropdown.show(); dropdown.show();
} }
}, },
handleUpdating(updating) { handleUpdating(isMutationInProgress) {
this.isUpdating = updating; if (!isMutationInProgress) {
this.$emit('alert-update');
}
this.isUpdating = isMutationInProgress;
}, },
}, },
}; };
...@@ -66,7 +74,7 @@ export default { ...@@ -66,7 +74,7 @@ export default {
<template> <template>
<div <div
class="alert-status gl-py-5 gl-w-70p" class="alert-status gl-py-5"
:class="{ 'gl-border-b-1 gl-border-b-solid gl-border-b-gray-100': !sidebarCollapsed }" :class="{ 'gl-border-b-1 gl-border-b-solid gl-border-b-gray-100': !sidebarCollapsed }"
> >
<template v-if="sidebarCollapsed"> <template v-if="sidebarCollapsed">
...@@ -118,7 +126,7 @@ export default { ...@@ -118,7 +126,7 @@ export default {
class="value gl-m-0" class="value gl-m-0"
:class="{ 'no-value': !statuses[alert.status] }" :class="{ 'no-value': !statuses[alert.status] }"
> >
<span v-if="statuses[alert.status]" class="gl-text-gray-500" data-testid="status"> <span v-if="statuses[alert.status]" :class="textClass" data-testid="status">
{{ statuses[alert.status] }} {{ statuses[alert.status] }}
</span> </span>
<span v-else> <span v-else>
......
...@@ -228,7 +228,7 @@ By default, the list doesn't display resolved or dismissed alerts. ...@@ -228,7 +228,7 @@ By default, the list doesn't display resolved or dismissed alerts.
![Policy Alert List](img/threat_monitoring_policy_alert_list_v13_12.png) ![Policy Alert List](img/threat_monitoring_policy_alert_list_v13_12.png)
Clicking an alert's row opens the alert drawer, which shows more information about the alert. A user Clicking an alert's row opens the alert drawer, which shows more information about the alert. A user
can also create an incident from the alert in the alert drawer. can also create an incident from the alert and update the alert status in the alert drawer.
Clicking an alert's name takes the user to the [alert details page](../../../operations/incident_management/alerts.md#alert-details-page). Clicking an alert's name takes the user to the [alert details page](../../../operations/incident_management/alerts.md#alert-details-page).
......
...@@ -4,6 +4,7 @@ import * as Sentry from '@sentry/browser'; ...@@ -4,6 +4,7 @@ import * as Sentry from '@sentry/browser';
import { capitalizeFirstCharacter, splitCamelCase } from '~/lib/utils/text_utility'; import { capitalizeFirstCharacter, splitCamelCase } from '~/lib/utils/text_utility';
import { visitUrl } from '~/lib/utils/url_utility'; import { visitUrl } from '~/lib/utils/url_utility';
import { __ } from '~/locale'; import { __ } from '~/locale';
import SidebarStatus from '~/vue_shared/alert_details/components/sidebar/sidebar_status.vue';
import createIssueMutation from '~/vue_shared/alert_details/graphql/mutations/alert_issue_create.mutation.graphql'; import createIssueMutation from '~/vue_shared/alert_details/graphql/mutations/alert_issue_create.mutation.graphql';
import getAlertDetailsQuery from '~/vue_shared/alert_details/graphql/queries/alert_details.query.graphql'; import getAlertDetailsQuery from '~/vue_shared/alert_details/graphql/queries/alert_details.query.graphql';
import { getContentWrapperHeight } from '../../utils'; import { getContentWrapperHeight } from '../../utils';
...@@ -16,6 +17,7 @@ export default { ...@@ -16,6 +17,7 @@ export default {
ERRORS: { ...DRAWER_ERRORS }, ERRORS: { ...DRAWER_ERRORS },
}, },
components: { components: {
SidebarStatus,
GlAlert, GlAlert,
GlButton, GlButton,
GlDrawer, GlDrawer,
...@@ -115,6 +117,9 @@ export default { ...@@ -115,6 +117,9 @@ export default {
getDrawerHeaderHeight() { getDrawerHeaderHeight() {
return getContentWrapperHeight('.js-threat-monitoring-container-wrapper'); return getContentWrapperHeight('.js-threat-monitoring-container-wrapper');
}, },
handleAlertUpdate() {
this.$emit('alert-update');
},
handleAlertError({ type, error }) { handleAlertError({ type, error }) {
this.errorMessage = this.$options.i18n.ERRORS[type]; this.errorMessage = this.$options.i18n.ERRORS[type];
Sentry.captureException(error); Sentry.captureException(error);
...@@ -154,6 +159,12 @@ export default { ...@@ -154,6 +159,12 @@ export default {
<gl-alert v-if="errored" variant="danger" :dismissible="false" contained> <gl-alert v-if="errored" variant="danger" :dismissible="false" contained>
{{ errorMessage }} {{ errorMessage }}
</gl-alert> </gl-alert>
<sidebar-status
:alert="selectedAlert"
:project-path="projectPath"
text-class="gl-font-weight-bold"
@alert-update="handleAlertUpdate"
/>
<div v-if="isLoadingDetails"> <div v-if="isLoadingDetails">
<div v-for="row in $options.ALERT_DETAILS_LOADING_ROWS" :key="row" class="gl-mb-5"> <div v-for="row in $options.ALERT_DETAILS_LOADING_ROWS" :key="row" class="gl-mb-5">
<gl-skeleton-loader :lines="2" :width="400" /> <gl-skeleton-loader :lines="2" :width="400" />
......
...@@ -58,6 +58,9 @@ export default { ...@@ -58,6 +58,9 @@ export default {
directives: { directives: {
GlTooltip: GlTooltipDirective, GlTooltip: GlTooltipDirective,
}, },
provide: {
statuses: STATUSES,
},
inject: ['documentationPath', 'projectPath'], inject: ['documentationPath', 'projectPath'],
apollo: { apollo: {
alerts: { alerts: {
...@@ -74,6 +77,11 @@ export default { ...@@ -74,6 +77,11 @@ export default {
update: ({ project }) => project?.alertManagementAlerts.nodes || [], update: ({ project }) => project?.alertManagementAlerts.nodes || [],
result({ data }) { result({ data }) {
this.pageInfo = data?.project?.alertManagementAlerts?.pageInfo || {}; this.pageInfo = data?.project?.alertManagementAlerts?.pageInfo || {};
if (this.selectedAlert) {
this.selectedAlert = data?.project?.alertManagementAlerts?.nodes?.find(
(alert) => alert.iid === this.selectedAlert.iid,
);
}
}, },
error() { error() {
this.errored = true; this.errored = true;
...@@ -143,7 +151,7 @@ export default { ...@@ -143,7 +151,7 @@ export default {
}, },
handleAlertDeselect() { handleAlertDeselect() {
this.isAlertDrawerOpen = false; this.isAlertDrawerOpen = false;
this.selectedAlert = {}; this.selectedAlert = null;
}, },
handleAlertError(msg) { handleAlertError(msg) {
this.errored = true; this.errored = true;
...@@ -312,6 +320,7 @@ export default { ...@@ -312,6 +320,7 @@ export default {
v-if="selectedAlert" v-if="selectedAlert"
:is-alert-drawer-open="isAlertDrawerOpen" :is-alert-drawer-open="isAlertDrawerOpen"
:selected-alert="selectedAlert" :selected-alert="selectedAlert"
@alert-update="handleStatusUpdate"
@deselect-alert="handleAlertDeselect" @deselect-alert="handleAlertDeselect"
/> />
</div> </div>
......
---
title: Add alert status change dropdown to drawer
merge_request: 61832
author:
type: added
...@@ -8,6 +8,7 @@ import createMockApollo from 'helpers/mock_apollo_helper'; ...@@ -8,6 +8,7 @@ import createMockApollo from 'helpers/mock_apollo_helper';
import { mountExtended, shallowMountExtended } from 'helpers/vue_test_utils_helper'; import { mountExtended, shallowMountExtended } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises'; import waitForPromises from 'helpers/wait_for_promises';
import { visitUrl } from '~/lib/utils/url_utility'; import { visitUrl } from '~/lib/utils/url_utility';
import SidebarStatus from '~/vue_shared/alert_details/components/sidebar/sidebar_status.vue';
import getAlertDetailsQuery from '~/vue_shared/alert_details/graphql/queries/alert_details.query.graphql'; import getAlertDetailsQuery from '~/vue_shared/alert_details/graphql/queries/alert_details.query.graphql';
import { import {
erroredGetAlertDetailsQuerySpy, erroredGetAlertDetailsQuerySpy,
...@@ -48,6 +49,7 @@ describe('Alert Drawer', () => { ...@@ -48,6 +49,7 @@ describe('Alert Drawer', () => {
const findIssueLink = () => wrapper.findByTestId('issue-link'); const findIssueLink = () => wrapper.findByTestId('issue-link');
const findSkeletonLoader = () => wrapper.findComponent(GlSkeletonLoader); const findSkeletonLoader = () => wrapper.findComponent(GlSkeletonLoader);
const findDetails = () => wrapper.findByTestId('details-list'); const findDetails = () => wrapper.findByTestId('details-list');
const findStatus = () => wrapper.findComponent(SidebarStatus);
const createWrapper = ({ const createWrapper = ({
$apollo, $apollo,
...@@ -160,4 +162,11 @@ describe('Alert Drawer', () => { ...@@ -160,4 +162,11 @@ describe('Alert Drawer', () => {
expect(captureExceptionSpy.mock.calls[0][0].message).toBe(errorMessage); expect(captureExceptionSpy.mock.calls[0][0].message).toBe(errorMessage);
}); });
}); });
it('handles an alert status update', () => {
createWrapper({ props: { selectedAlert: mockAlerts[0] } });
expect(wrapper.emitted('alert-update')).toBeUndefined();
findStatus().vm.$emit('alert-update');
expect(wrapper.emitted('alert-update')).toEqual([[]]);
});
}); });
...@@ -121,6 +121,13 @@ describe('Alert Details Sidebar Status', () => { ...@@ -121,6 +121,13 @@ describe('Alert Details Sidebar Status', () => {
expect(findStatus().text()).toBe('Triggered'); expect(findStatus().text()).toBe('Triggered');
}); });
it('emits "alert-update" when the status has been updated', () => {
mountComponent({ sidebarCollapsed: false });
expect(wrapper.emitted('alert-update')).toBeUndefined();
findAlertStatus().vm.$emit('handle-updating');
expect(wrapper.emitted('alert-update')).toEqual([[]]);
});
it('renders translated statuses', () => { it('renders translated statuses', () => {
const status = 'TEST'; const status = 'TEST';
const statuses = { [status]: 'Test' }; const statuses = { [status]: 'Test' };
......
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