Commit 08890e60 authored by David O'Regan's avatar David O'Regan Committed by Kushal Pandya

Add search box

Add a search bar for incidents
that allows a user to search
for dedicated incidents
parent 8f37b22a
......@@ -8,12 +8,14 @@ import {
GlAvatar,
GlTooltipDirective,
GlButton,
GlSearchBoxByType,
} from '@gitlab/ui';
import { debounce } from 'lodash';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import { s__ } from '~/locale';
import { mergeUrlParams, joinPaths, visitUrl } from '~/lib/utils/url_utility';
import getIncidents from '../graphql/queries/get_incidents.query.graphql';
import { I18N } from '../constants';
import { I18N, INCIDENT_SEARCH_DELAY } from '../constants';
const tdClass =
'table-col gl-display-flex d-md-table-cell gl-align-items-center gl-white-space-nowrap';
......@@ -52,6 +54,7 @@ export default {
GlAvatar,
GlButton,
TimeAgoTooltip,
GlSearchBoxByType,
},
directives: {
GlTooltip: GlTooltipDirective,
......@@ -62,6 +65,7 @@ export default {
query: getIncidents,
variables() {
return {
searchTerm: this.searchTerm,
projectPath: this.projectPath,
labelNames: ['incident'],
};
......@@ -77,11 +81,12 @@ export default {
errored: false,
isErrorAlertDismissed: false,
redirecting: false,
searchTerm: '',
};
},
computed: {
showErrorMsg() {
return this.errored && !this.isErrorAlertDismissed;
return this.errored && !this.isErrorAlertDismissed && !this.searchTerm;
},
loading() {
return this.$apollo.queries.incidents.loading;
......@@ -98,6 +103,13 @@ export default {
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: {
hasAssignees(assignees) {
return Boolean(assignees.nodes?.length);
......@@ -116,7 +128,7 @@ export default {
<div class="gl-display-flex gl-justify-content-end">
<gl-button
class="gl-mt-3 create-incident-button"
class="gl-mt-3 gl-mb-3 create-incident-button"
data-testid="createIncidentBtn"
:loading="redirecting"
:disabled="redirecting"
......@@ -129,6 +141,14 @@ export default {
</gl-button>
</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">
{{ s__('IncidentManagement|Incidents') }}
</h4>
......
/* eslint-disable import/prefer-default-export */
import { s__ } from '~/locale';
import { s__, __ } from '~/locale';
export const I18N = {
errorMsg: s__('IncidentManagement|There was an error displaying the incidents.'),
noIncidents: s__('IncidentManagement|No incidents to display.'),
unassigned: s__('IncidentManagement|Unassigned'),
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) {
issues(state: $state, labelName: $labelNames) {
issues(search: $searchTerm, state: $state, labelName: $labelNames) {
nodes {
iid
title
......
---
title: Add search bar for incidents
merge_request: 37885
author:
type: changed
import { mount } from '@vue/test-utils';
import { GlAlert, GlLoadingIcon, GlTable, GlAvatar } from '@gitlab/ui';
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 TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import { I18N } from '~/incidents/constants';
......@@ -24,6 +24,7 @@ describe('Incidents List', () => {
const findTimeAgo = () => wrapper.findAll(TimeAgoTooltip);
const findAssingees = () => wrapper.findAll('[data-testid="incident-assignees"]');
const findCreateIncidentBtn = () => wrapper.find('[data-testid="createIncidentBtn"]');
const findSearch = () => wrapper.find(GlSearchBoxByType);
function mountComponent({ data = { incidents: [] }, loading = false }) {
wrapper = mount(IncidentsList, {
......@@ -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