Commit 89b27c7f authored by Kushal Pandya's avatar Kushal Pandya

Merge branch '229403-incident-search-bar' into 'master'

Add search bar for incidents

Closes #229403

See merge request gitlab-org/gitlab!37885
parents da733b07 08890e60
...@@ -8,12 +8,14 @@ import { ...@@ -8,12 +8,14 @@ import {
GlAvatar, GlAvatar,
GlTooltipDirective, GlTooltipDirective,
GlButton, GlButton,
GlSearchBoxByType,
} from '@gitlab/ui'; } from '@gitlab/ui';
import { debounce } from 'lodash';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue'; import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import { s__ } from '~/locale'; import { s__ } from '~/locale';
import { mergeUrlParams, joinPaths, visitUrl } from '~/lib/utils/url_utility'; import { mergeUrlParams, joinPaths, visitUrl } from '~/lib/utils/url_utility';
import getIncidents from '../graphql/queries/get_incidents.query.graphql'; import getIncidents from '../graphql/queries/get_incidents.query.graphql';
import { I18N } from '../constants'; import { I18N, INCIDENT_SEARCH_DELAY } from '../constants';
const tdClass = const tdClass =
'table-col gl-display-flex d-md-table-cell gl-align-items-center gl-white-space-nowrap'; 'table-col gl-display-flex d-md-table-cell gl-align-items-center gl-white-space-nowrap';
...@@ -52,6 +54,7 @@ export default { ...@@ -52,6 +54,7 @@ export default {
GlAvatar, GlAvatar,
GlButton, GlButton,
TimeAgoTooltip, TimeAgoTooltip,
GlSearchBoxByType,
}, },
directives: { directives: {
GlTooltip: GlTooltipDirective, GlTooltip: GlTooltipDirective,
...@@ -62,6 +65,7 @@ export default { ...@@ -62,6 +65,7 @@ export default {
query: getIncidents, query: getIncidents,
variables() { variables() {
return { return {
searchTerm: this.searchTerm,
projectPath: this.projectPath, projectPath: this.projectPath,
labelNames: ['incident'], labelNames: ['incident'],
}; };
...@@ -77,11 +81,12 @@ export default { ...@@ -77,11 +81,12 @@ export default {
errored: false, errored: false,
isErrorAlertDismissed: false, isErrorAlertDismissed: false,
redirecting: false, redirecting: false,
searchTerm: '',
}; };
}, },
computed: { computed: {
showErrorMsg() { showErrorMsg() {
return this.errored && !this.isErrorAlertDismissed; return this.errored && !this.isErrorAlertDismissed && !this.searchTerm;
}, },
loading() { loading() {
return this.$apollo.queries.incidents.loading; return this.$apollo.queries.incidents.loading;
...@@ -98,6 +103,13 @@ export default { ...@@ -98,6 +103,13 @@ export default {
return mergeUrlParams({ issuable_template: this.incidentTemplateName }, this.newIssuePath); return mergeUrlParams({ issuable_template: this.incidentTemplateName }, this.newIssuePath);
}, },
}, },
watch: {
searchTerm: debounce(function debounceSearch(input) {
if (input !== this.searchTerm) {
this.searchTerm = input;
}
}, INCIDENT_SEARCH_DELAY),
},
methods: { methods: {
hasAssignees(assignees) { hasAssignees(assignees) {
return Boolean(assignees.nodes?.length); return Boolean(assignees.nodes?.length);
...@@ -116,7 +128,7 @@ export default { ...@@ -116,7 +128,7 @@ export default {
<div class="gl-display-flex gl-justify-content-end"> <div class="gl-display-flex gl-justify-content-end">
<gl-button <gl-button
class="gl-mt-3 create-incident-button" class="gl-mt-3 gl-mb-3 create-incident-button"
data-testid="createIncidentBtn" data-testid="createIncidentBtn"
:loading="redirecting" :loading="redirecting"
:disabled="redirecting" :disabled="redirecting"
...@@ -129,6 +141,14 @@ export default { ...@@ -129,6 +141,14 @@ export default {
</gl-button> </gl-button>
</div> </div>
<div class="gl-bg-gray-10 gl-p-5 gl-border-b-solid gl-border-b-1 gl-border-gray-100">
<gl-search-box-by-type
v-model.trim="searchTerm"
class="gl-bg-white"
:placeholder="$options.i18n.searchPlaceholder"
/>
</div>
<h4 class="gl-display-block d-md-none my-3"> <h4 class="gl-display-block d-md-none my-3">
{{ s__('IncidentManagement|Incidents') }} {{ s__('IncidentManagement|Incidents') }}
</h4> </h4>
......
/* eslint-disable import/prefer-default-export */ import { s__, __ } from '~/locale';
import { s__ } from '~/locale';
export const I18N = { export const I18N = {
errorMsg: s__('IncidentManagement|There was an error displaying the incidents.'), errorMsg: s__('IncidentManagement|There was an error displaying the incidents.'),
noIncidents: s__('IncidentManagement|No incidents to display.'), noIncidents: s__('IncidentManagement|No incidents to display.'),
unassigned: s__('IncidentManagement|Unassigned'), unassigned: s__('IncidentManagement|Unassigned'),
createIncidentBtnLabel: s__('IncidentManagement|Create incident'), createIncidentBtnLabel: s__('IncidentManagement|Create incident'),
searchPlaceholder: __('Search or filter results...'),
}; };
export const INCIDENT_SEARCH_DELAY = 300;
query getIncidents($projectPath: ID!, $labelNames: [String], $state: IssuableState) { query getIncidents(
$searchTerm: String
$projectPath: ID!
$labelNames: [String]
$state: IssuableState
) {
project(fullPath: $projectPath) { project(fullPath: $projectPath) {
issues(state: $state, labelName: $labelNames) { issues(search: $searchTerm, state: $state, labelName: $labelNames) {
nodes { nodes {
iid iid
title title
......
---
title: Add search bar for incidents
merge_request: 37885
author:
type: changed
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import { GlAlert, GlLoadingIcon, GlTable, GlAvatar } from '@gitlab/ui';
import { visitUrl, joinPaths } from '~/lib/utils/url_utility'; import { visitUrl, joinPaths } from '~/lib/utils/url_utility';
import { GlAlert, GlLoadingIcon, GlTable, GlAvatar, GlSearchBoxByType } from '@gitlab/ui';
import IncidentsList from '~/incidents/components/incidents_list.vue'; import IncidentsList from '~/incidents/components/incidents_list.vue';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue'; import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import { I18N } from '~/incidents/constants'; import { I18N } from '~/incidents/constants';
...@@ -24,6 +24,7 @@ describe('Incidents List', () => { ...@@ -24,6 +24,7 @@ describe('Incidents List', () => {
const findTimeAgo = () => wrapper.findAll(TimeAgoTooltip); const findTimeAgo = () => wrapper.findAll(TimeAgoTooltip);
const findAssingees = () => wrapper.findAll('[data-testid="incident-assignees"]'); const findAssingees = () => wrapper.findAll('[data-testid="incident-assignees"]');
const findCreateIncidentBtn = () => wrapper.find('[data-testid="createIncidentBtn"]'); const findCreateIncidentBtn = () => wrapper.find('[data-testid="createIncidentBtn"]');
const findSearch = () => wrapper.find(GlSearchBoxByType);
function mountComponent({ data = { incidents: [] }, loading = false }) { function mountComponent({ data = { incidents: [] }, loading = false }) {
wrapper = mount(IncidentsList, { wrapper = mount(IncidentsList, {
...@@ -148,4 +149,25 @@ describe('Incidents List', () => { ...@@ -148,4 +149,25 @@ describe('Incidents List', () => {
}); });
}); });
}); });
describe('Search', () => {
beforeEach(() => {
mountComponent({
data: { incidents: mockIncidents },
loading: false,
});
});
it('renders the search component for incidents', () => {
expect(findSearch().exists()).toBe(true);
});
it('sets the `searchTerm` graphql variable', () => {
const SEARCH_TERM = 'Simple Incident';
findSearch().vm.$emit('input', SEARCH_TERM);
expect(wrapper.vm.$data.searchTerm).toBe(SEARCH_TERM);
});
});
}); });
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