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 {
:project-path="projectPath"
:alert="alert"
:sidebar-collapsed="sidebarStatus"
text-class="gl-text-gray-500"
class="gl-w-70p"
@toggle-sidebar="$emit('toggle-sidebar')"
@alert-error="$emit('alert-error', $event)"
/>
......
......@@ -34,6 +34,11 @@ export default {
type: Boolean,
required: false,
},
textClass: {
type: String,
required: false,
default: '',
},
},
data() {
return {
......@@ -57,8 +62,11 @@ export default {
dropdown.show();
}
},
handleUpdating(updating) {
this.isUpdating = updating;
handleUpdating(isMutationInProgress) {
if (!isMutationInProgress) {
this.$emit('alert-update');
}
this.isUpdating = isMutationInProgress;
},
},
};
......@@ -66,7 +74,7 @@ export default {
<template>
<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 }"
>
<template v-if="sidebarCollapsed">
......@@ -118,7 +126,7 @@ export default {
class="value gl-m-0"
: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] }}
</span>
<span v-else>
......
......@@ -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)
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).
......
......@@ -4,6 +4,7 @@ import * as Sentry from '@sentry/browser';
import { capitalizeFirstCharacter, splitCamelCase } from '~/lib/utils/text_utility';
import { visitUrl } from '~/lib/utils/url_utility';
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 getAlertDetailsQuery from '~/vue_shared/alert_details/graphql/queries/alert_details.query.graphql';
import { getContentWrapperHeight } from '../../utils';
......@@ -16,6 +17,7 @@ export default {
ERRORS: { ...DRAWER_ERRORS },
},
components: {
SidebarStatus,
GlAlert,
GlButton,
GlDrawer,
......@@ -115,6 +117,9 @@ export default {
getDrawerHeaderHeight() {
return getContentWrapperHeight('.js-threat-monitoring-container-wrapper');
},
handleAlertUpdate() {
this.$emit('alert-update');
},
handleAlertError({ type, error }) {
this.errorMessage = this.$options.i18n.ERRORS[type];
Sentry.captureException(error);
......@@ -154,6 +159,12 @@ export default {
<gl-alert v-if="errored" variant="danger" :dismissible="false" contained>
{{ errorMessage }}
</gl-alert>
<sidebar-status
:alert="selectedAlert"
:project-path="projectPath"
text-class="gl-font-weight-bold"
@alert-update="handleAlertUpdate"
/>
<div v-if="isLoadingDetails">
<div v-for="row in $options.ALERT_DETAILS_LOADING_ROWS" :key="row" class="gl-mb-5">
<gl-skeleton-loader :lines="2" :width="400" />
......
......@@ -58,6 +58,9 @@ export default {
directives: {
GlTooltip: GlTooltipDirective,
},
provide: {
statuses: STATUSES,
},
inject: ['documentationPath', 'projectPath'],
apollo: {
alerts: {
......@@ -74,6 +77,11 @@ export default {
update: ({ project }) => project?.alertManagementAlerts.nodes || [],
result({ data }) {
this.pageInfo = data?.project?.alertManagementAlerts?.pageInfo || {};
if (this.selectedAlert) {
this.selectedAlert = data?.project?.alertManagementAlerts?.nodes?.find(
(alert) => alert.iid === this.selectedAlert.iid,
);
}
},
error() {
this.errored = true;
......@@ -143,7 +151,7 @@ export default {
},
handleAlertDeselect() {
this.isAlertDrawerOpen = false;
this.selectedAlert = {};
this.selectedAlert = null;
},
handleAlertError(msg) {
this.errored = true;
......@@ -312,6 +320,7 @@ export default {
v-if="selectedAlert"
:is-alert-drawer-open="isAlertDrawerOpen"
:selected-alert="selectedAlert"
@alert-update="handleStatusUpdate"
@deselect-alert="handleAlertDeselect"
/>
</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';
import { mountExtended, shallowMountExtended } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises';
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 {
erroredGetAlertDetailsQuerySpy,
......@@ -48,6 +49,7 @@ describe('Alert Drawer', () => {
const findIssueLink = () => wrapper.findByTestId('issue-link');
const findSkeletonLoader = () => wrapper.findComponent(GlSkeletonLoader);
const findDetails = () => wrapper.findByTestId('details-list');
const findStatus = () => wrapper.findComponent(SidebarStatus);
const createWrapper = ({
$apollo,
......@@ -160,4 +162,11 @@ describe('Alert Drawer', () => {
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', () => {
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', () => {
const 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