Commit 6b0e2bd5 authored by Jose Ivan Vargas's avatar Jose Ivan Vargas

Merge branch '296712-policy-name-search' into 'master'

Add policy name filter to threat alerts

See merge request gitlab-org/gitlab!56708
parents 3d339e40 206258c6
<script> <script>
import { GlFormCheckbox, GlFormGroup } from '@gitlab/ui'; import { GlFormCheckbox, GlFormGroup, GlSearchBoxByType } from '@gitlab/ui';
import { s__ } from '~/locale'; import { s__ } from '~/locale';
import { DEFAULT_FILTERS } from './constants'; import { DEBOUNCE, DEFAULT_FILTERS } from './constants';
export default { export default {
DEBOUNCE,
DEFAULT_DISMISSED_FILTER: true, DEFAULT_DISMISSED_FILTER: true,
components: { GlFormCheckbox, GlFormGroup }, components: { GlFormCheckbox, GlFormGroup, GlSearchBoxByType },
props: {
filters: {
type: Object,
required: false,
default: () => {},
},
},
data() {
return {
showMinimumSearchQueryMessage: false,
};
},
i18n: { i18n: {
HIDE_DISMISSED_TITLE: s__('ThreatMonitoring|Hide dismissed alerts'), HIDE_DISMISSED_TITLE: s__('ThreatMonitoring|Hide dismissed alerts'),
POLICY_NAME_FILTER_PLACEHOLDER: s__('NetworkPolicy|Search by policy name'),
POLICY_NAME_FILTER_TITLE: s__('NetworkPolicy|Policy'),
}, },
methods: { methods: {
changeDismissedFilter(filtered) { changeDismissedFilter(filtered) {
const newFilters = filtered ? DEFAULT_FILTERS : {}; const newFilters = filtered ? DEFAULT_FILTERS : { statuses: [] };
this.$emit('filter-change', newFilters); this.handleFilterChange(newFilters);
},
handleSearch(searchTerm) {
const newFilters = { searchTerm };
this.handleFilterChange(newFilters);
},
handleFilterChange(newFilters) {
this.$emit('filter-change', { ...this.filters, ...newFilters });
}, },
}, },
}; };
...@@ -20,9 +42,17 @@ export default { ...@@ -20,9 +42,17 @@ export default {
<template> <template>
<div <div
class="gl-pt-3 gl-px-3 gl-bg-gray-10 gl-display-flex gl-justify-content-end gl-align-items-center" class="gl-p-4 gl-bg-gray-10 gl-display-flex gl-justify-content-space-between gl-align-items-center"
> >
<gl-form-group label-size="sm"> <div>
<h5 class="gl-mt-0">{{ $options.i18n.POLICY_NAME_FILTER_TITLE }}</h5>
<gl-search-box-by-type
:debounce="$options.DEBOUNCE"
:placeholder="$options.i18n.POLICY_NAME_FILTER_PLACEHOLDER"
@input="handleSearch"
/>
</div>
<gl-form-group label-size="sm" class="gl-mb-0">
<gl-form-checkbox <gl-form-checkbox
class="gl-mt-3" class="gl-mt-3"
:checked="$options.DEFAULT_DISMISSED_FILTER" :checked="$options.DEFAULT_DISMISSED_FILTER"
......
...@@ -137,7 +137,7 @@ export default { ...@@ -137,7 +137,7 @@ export default {
</script> </script>
<template> <template>
<div> <div>
<alert-filters @filter-change="handleFilterChange" /> <alert-filters :filters="filters" @filter-change="handleFilterChange" />
<gl-alert v-if="showNoAlertsMsg" data-testid="threat-alerts-unconfigured" :dismissible="false"> <gl-alert v-if="showNoAlertsMsg" data-testid="threat-alerts-unconfigured" :dismissible="false">
<gl-sprintf :message="$options.i18n.MESSAGES.CONFIGURE"> <gl-sprintf :message="$options.i18n.MESSAGES.CONFIGURE">
<template #link="{ content }"> <template #link="{ content }">
......
...@@ -56,3 +56,5 @@ export const PAGE_SIZE = 20; ...@@ -56,3 +56,5 @@ export const PAGE_SIZE = 20;
export const DEFAULT_FILTERS = { statuses: ['TRIGGERED', 'ACKNOWLEDGED'] }; export const DEFAULT_FILTERS = { statuses: ['TRIGGERED', 'ACKNOWLEDGED'] };
export const DOMAIN = 'threat_monitoring'; export const DOMAIN = 'threat_monitoring';
export const DEBOUNCE = 250;
...@@ -105,7 +105,7 @@ export default { ...@@ -105,7 +105,7 @@ export default {
</h2> </h2>
</header> </header>
<gl-tabs> <gl-tabs content-class="gl-pt-0">
<gl-tab <gl-tab
v-if="showAlertsTab" v-if="showAlertsTab"
:title="s__('ThreatMonitoring|Alerts')" :title="s__('ThreatMonitoring|Alerts')"
......
...@@ -178,23 +178,22 @@ export default { ...@@ -178,23 +178,22 @@ export default {
<template> <template>
<div> <div>
<div class="mb-2">
<gl-alert <gl-alert
v-if="hasAutoDevopsPolicy" v-if="hasAutoDevopsPolicy"
data-testid="autodevopsAlert" data-testid="autodevopsAlert"
variant="info" variant="info"
:dismissible="false" :dismissible="false"
class="gl-mb-3"
> >
<gl-sprintf :message="$options.autodevopsNoticeDescription"> <gl-sprintf :message="$options.autodevopsNoticeDescription">
<template #monospaced="{ content }"> <template #monospaced="{ content }">
<span class="monospace">{{ content }}</span> <span class="gl-font-monospace">{{ content }}</span>
</template> </template>
<template #link="{ content }"> <template #link="{ content }">
<gl-link :href="documentationFullPath">{{ content }}</gl-link> <gl-link :href="documentationFullPath">{{ content }}</gl-link>
</template> </template>
</gl-sprintf> </gl-sprintf>
</gl-alert> </gl-alert>
</div>
<div class="pt-3 px-3 bg-gray-light"> <div class="pt-3 px-3 bg-gray-light">
<div class="row justify-content-between align-items-center"> <div class="row justify-content-between align-items-center">
......
---
title: Add policy name filter to threat alerts
merge_request: 56708
author:
type: added
import { GlFormCheckbox } from '@gitlab/ui'; import { GlFormCheckbox, GlSearchBoxByType } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import AlertFilters from 'ee/threat_monitoring/components/alerts/alert_filters.vue'; import AlertFilters from 'ee/threat_monitoring/components/alerts/alert_filters.vue';
import { DEFAULT_FILTERS } from 'ee/threat_monitoring/components/alerts/constants'; import { DEFAULT_FILTERS } from 'ee/threat_monitoring/components/alerts/constants';
...@@ -7,9 +7,10 @@ describe('AlertFilters component', () => { ...@@ -7,9 +7,10 @@ describe('AlertFilters component', () => {
let wrapper; let wrapper;
const findGlFormCheckbox = () => wrapper.find(GlFormCheckbox); const findGlFormCheckbox = () => wrapper.find(GlFormCheckbox);
const findGlSearch = () => wrapper.find(GlSearchBoxByType);
const createWrapper = () => { const createWrapper = (filters = DEFAULT_FILTERS) => {
wrapper = shallowMount(AlertFilters); wrapper = shallowMount(AlertFilters, { propsData: { filters } });
}; };
afterEach(() => { afterEach(() => {
...@@ -17,6 +18,31 @@ describe('AlertFilters component', () => { ...@@ -17,6 +18,31 @@ describe('AlertFilters component', () => {
wrapper = null; wrapper = null;
}); });
describe('Policy Name Filter', () => {
beforeEach(() => {
createWrapper();
});
describe('default state', () => {
it('shows policy name search box', () => {
const search = findGlSearch();
expect(search.exists()).toBe(true);
expect(search.attributes('value')).toBe('');
});
it('does emit an event with a user-defined string', async () => {
const searchTerm = 'abc';
const search = findGlSearch();
search.vm.$emit('input', searchTerm);
await wrapper.vm.$nextTick();
expect(wrapper.emitted('filter-change')).toStrictEqual([
[{ ...DEFAULT_FILTERS, searchTerm }],
]);
});
});
});
describe('Hide Dismissed Filter', () => {
describe('default state', () => { describe('default state', () => {
it('"hide dismissed checkbox" is checked', () => { it('"hide dismissed checkbox" is checked', () => {
createWrapper(); createWrapper();
...@@ -27,22 +53,21 @@ describe('AlertFilters component', () => { ...@@ -27,22 +53,21 @@ describe('AlertFilters component', () => {
}); });
describe('dismissed alerts filter', () => { describe('dismissed alerts filter', () => {
beforeEach(() => {
createWrapper();
});
it('emits an event with no filters on filter deselect', async () => { it('emits an event with no filters on filter deselect', async () => {
createWrapper();
const checkbox = findGlFormCheckbox(); const checkbox = findGlFormCheckbox();
checkbox.vm.$emit('change', false); checkbox.vm.$emit('change', false);
await wrapper.vm.$nextTick(); await wrapper.vm.$nextTick();
expect(wrapper.emitted('filter-change')).toEqual([[{}]]); expect(wrapper.emitted('filter-change')).toStrictEqual([[{ statuses: [] }]]);
}); });
it('emits an event with the default filters on filter select', async () => { it('emits an event with the default filters on filter select', async () => {
createWrapper({});
const checkbox = findGlFormCheckbox(); const checkbox = findGlFormCheckbox();
checkbox.vm.$emit('change', true); checkbox.vm.$emit('change', true);
await wrapper.vm.$nextTick(); await wrapper.vm.$nextTick();
expect(wrapper.emitted('filter-change')).toEqual([[DEFAULT_FILTERS]]); expect(wrapper.emitted('filter-change')).toEqual([[DEFAULT_FILTERS]]);
}); });
}); });
});
}); });
...@@ -101,6 +101,7 @@ describe('AlertsList component', () => { ...@@ -101,6 +101,7 @@ describe('AlertsList component', () => {
it('shows threat monitoring alert filters', () => { it('shows threat monitoring alert filters', () => {
expect(findAlertFilters().exists()).toBe(true); expect(findAlertFilters().exists()).toBe(true);
expect(findAlertFilters().props('filters')).toBe(DEFAULT_FILTERS);
}); });
it('does have the default filters initially', () => { it('does have the default filters initially', () => {
......
...@@ -20403,6 +20403,12 @@ msgstr "" ...@@ -20403,6 +20403,12 @@ msgstr ""
msgid "NetworkPolicies|ports/protocols" msgid "NetworkPolicies|ports/protocols"
msgstr "" msgstr ""
msgid "NetworkPolicy|Policy"
msgstr ""
msgid "NetworkPolicy|Search by policy name"
msgstr ""
msgid "Never" msgid "Never"
msgstr "" msgstr ""
......
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