Commit 648a9061 authored by Laura Montemayor's avatar Laura Montemayor Committed by Natalia Tepluhina

Adds getters to filter results

* Moves search bar next to the button
* Adds minimal styling
parent 6506ff4d
<script> <script>
import { mapActions, mapState } from 'vuex'; import { mapActions, mapState, mapGetters } from 'vuex';
import { GlEmptyState, GlButton, GlLink, GlLoadingIcon, GlTable } from '@gitlab/ui'; import {
GlEmptyState,
GlButton,
GlLink,
GlLoadingIcon,
GlTable,
GlSearchBoxByType,
} from '@gitlab/ui';
import Icon from '~/vue_shared/components/icon.vue'; import Icon from '~/vue_shared/components/icon.vue';
import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue'; import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue';
import { __ } from '~/locale'; import { __ } from '~/locale';
...@@ -20,6 +27,7 @@ export default { ...@@ -20,6 +27,7 @@ export default {
GlLink, GlLink,
GlLoadingIcon, GlLoadingIcon,
GlTable, GlTable,
GlSearchBoxByType,
Icon, Icon,
TimeAgo, TimeAgo,
}, },
...@@ -48,8 +56,17 @@ export default { ...@@ -48,8 +56,17 @@ export default {
required: true, required: true,
}, },
}, },
data() {
return {
errorSearchQuery: '',
};
},
computed: { computed: {
...mapState(['errors', 'externalUrl', 'loading']), ...mapState(['errors', 'externalUrl', 'loading']),
...mapGetters(['filterErrorsByTitle']),
filteredErrors() {
return this.errorSearchQuery ? this.filterErrorsByTitle(this.errorSearchQuery) : this.errors;
},
}, },
created() { created() {
if (this.errorTrackingEnabled) { if (this.errorTrackingEnabled) {
...@@ -71,10 +88,17 @@ export default { ...@@ -71,10 +88,17 @@ export default {
<gl-loading-icon :size="3" /> <gl-loading-icon :size="3" />
</div> </div>
<div v-else> <div v-else>
<div class="d-flex justify-content-end"> <div class="d-flex flex-row justify-content-around bg-secondary border">
<gl-search-box-by-type
v-model="errorSearchQuery"
class="col-lg-10 m-3 p-0"
:placeholder="__('Search or filter results...')"
type="search"
autofocus
/>
<gl-button <gl-button
v-track-event="trackViewInSentryOptions(externalUrl)" v-track-event="trackViewInSentryOptions(externalUrl)"
class="my-3 ml-auto" class="m-3"
variant="primary" variant="primary"
:href="externalUrl" :href="externalUrl"
target="_blank" target="_blank"
...@@ -84,7 +108,14 @@ export default { ...@@ -84,7 +108,14 @@ export default {
</gl-button> </gl-button>
</div> </div>
<gl-table :items="errors" :fields="$options.fields" :show-empty="true" fixed stacked="sm"> <gl-table
class="mt-3"
:items="filteredErrors"
:fields="$options.fields"
:show-empty="true"
fixed
stacked="sm"
>
<template slot="HEAD_events" slot-scope="data"> <template slot="HEAD_events" slot-scope="data">
<div class="text-md-right">{{ data.label }}</div> <div class="text-md-right">{{ data.label }}</div>
</template> </template>
......
export const filterErrorsByTitle = state => errorQuery =>
state.errors.filter(error => error.title.match(new RegExp(`${errorQuery}`, 'i')));
export default () => {};
import Vue from 'vue'; import Vue from 'vue';
import Vuex from 'vuex'; import Vuex from 'vuex';
import * as actions from './actions'; import * as actions from './actions';
import * as getters from './getters';
import mutations from './mutations'; import mutations from './mutations';
Vue.use(Vuex); Vue.use(Vuex);
...@@ -14,6 +15,7 @@ export const createStore = () => ...@@ -14,6 +15,7 @@ export const createStore = () =>
}, },
actions, actions,
mutations, mutations,
getters,
}); });
export default createStore(); export default createStore();
---
title: Search list of Sentry errors by title in Gitlab
merge_request: 18772
author:
type: added
...@@ -41,5 +41,6 @@ NOTE: **Note:** ...@@ -41,5 +41,6 @@ NOTE: **Note:**
You will need at least Reporter [permissions](../../permissions.md) to view the Error Tracking list. You will need at least Reporter [permissions](../../permissions.md) to view the Error Tracking list.
The Error Tracking list may be found at **Operations > Error Tracking** in your project's sidebar. The Error Tracking list may be found at **Operations > Error Tracking** in your project's sidebar.
Errors can be filtered by title.
![Error Tracking list](img/error_tracking_list.png) ![Error Tracking list](img/error_tracking_list.png)
import * as getters from '~/error_tracking/store/getters';
describe('Error Tracking getters', () => {
let state;
const mockErrors = [
{ title: 'ActiveModel::MissingAttributeError: missing attribute: encrypted_password' },
{ title: 'Grape::Exceptions::MethodNotAllowed: Grape::Exceptions::MethodNotAllowed' },
{ title: 'NoMethodError: undefined method `sanitize_http_headers=' },
{ title: 'NoMethodError: undefined method `pry' },
];
beforeEach(() => {
state = {
errors: mockErrors,
};
});
describe('search results', () => {
it('should return errors filtered by words in title matching the query', () => {
const filteredErrors = getters.filterErrorsByTitle(state)('NoMethod');
expect(filteredErrors).not.toContainEqual(mockErrors[0]);
expect(filteredErrors.length).toBe(2);
});
it('should not return results if there is no matching query', () => {
const filteredErrors = getters.filterErrorsByTitle(state)('GitLab');
expect(filteredErrors.length).toBe(0);
});
});
});
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