Commit 9d0092ea authored by Clement Ho's avatar Clement Ho

Merge branch 'lm-ignore-sentry-errors-from-list-view' into 'master'

Implement ability to ignore Sentry errrors from the list view

See merge request gitlab-org/gitlab!22819
parents c2c750e7 221e8b71
...@@ -47,6 +47,11 @@ export default { ...@@ -47,6 +47,11 @@ export default {
thClass: 'w-15p', thClass: 'w-15p',
tdClass: 'table-col d-flex align-items-center d-sm-table-cell', tdClass: 'table-col d-flex align-items-center d-sm-table-cell',
}, },
{
key: 'ignore',
label: '',
tdClass: 'table-col d-flex align-items-center d-sm-table-cell',
},
{ {
key: 'details', key: 'details',
tdClass: 'table-col d-sm-none d-flex align-items-center', tdClass: 'table-col d-sm-none d-flex align-items-center',
...@@ -97,6 +102,14 @@ export default { ...@@ -97,6 +102,14 @@ export default {
type: Boolean, type: Boolean,
required: true, required: true,
}, },
projectPath: {
type: String,
required: true,
},
listPath: {
type: String,
required: true,
},
}, },
hasLocalStorage: AccessorUtils.isLocalStorageAccessSafe(), hasLocalStorage: AccessorUtils.isLocalStorageAccessSafe(),
data() { data() {
...@@ -144,6 +157,7 @@ export default { ...@@ -144,6 +157,7 @@ export default {
'loadRecentSearches', 'loadRecentSearches',
'setIndexPath', 'setIndexPath',
'fetchPaginatedResults', 'fetchPaginatedResults',
'updateStatus',
]), ]),
setSearchText(text) { setSearchText(text) {
this.errorSearchQuery = text; this.errorSearchQuery = text;
...@@ -166,6 +180,16 @@ export default { ...@@ -166,6 +180,16 @@ export default {
isCurrentSortField(field) { isCurrentSortField(field) {
return field === this.sortField; return field === this.sortField;
}, },
getIssueUpdatePath(errorId) {
return `/${this.projectPath}/-/error_tracking/${errorId}.json`;
},
updateIssueStatus(errorId, status) {
this.updateStatus({
endpoint: this.getIssueUpdatePath(errorId),
redirectUrl: this.listPath,
status,
});
},
}, },
}; };
</script> </script>
...@@ -299,6 +323,16 @@ export default { ...@@ -299,6 +323,16 @@ export default {
<time-ago :time="errors.item.lastSeen" class="text-secondary" /> <time-ago :time="errors.item.lastSeen" class="text-secondary" />
</div> </div>
</template> </template>
<template v-slot:ignore="errors">
<gl-button
ref="ignoreError"
v-gl-tooltip.hover
:title="__('Ignore')"
@click="updateIssueStatus(errors.item.id, 'ignored')"
>
<gl-icon name="eye-slash" :size="12" />
</gl-button>
</template>
<template v-slot:details="errors"> <template v-slot:details="errors">
<gl-button <gl-button
:href="getDetailsLink(errors.item.id)" :href="getDetailsLink(errors.item.id)"
......
...@@ -13,7 +13,13 @@ export default () => { ...@@ -13,7 +13,13 @@ export default () => {
store, store,
render(createElement) { render(createElement) {
const domEl = document.querySelector(this.$options.el); const domEl = document.querySelector(this.$options.el);
const { indexPath, enableErrorTrackingLink, illustrationPath } = domEl.dataset; const {
indexPath,
enableErrorTrackingLink,
illustrationPath,
projectPath,
listPath,
} = domEl.dataset;
let { errorTrackingEnabled, userCanEnableErrorTracking } = domEl.dataset; let { errorTrackingEnabled, userCanEnableErrorTracking } = domEl.dataset;
errorTrackingEnabled = parseBoolean(errorTrackingEnabled); errorTrackingEnabled = parseBoolean(errorTrackingEnabled);
...@@ -26,6 +32,8 @@ export default () => { ...@@ -26,6 +32,8 @@ export default () => {
errorTrackingEnabled, errorTrackingEnabled,
illustrationPath, illustrationPath,
userCanEnableErrorTracking, userCanEnableErrorTracking,
projectPath,
listPath,
}, },
}); });
}, },
......
...@@ -21,8 +21,8 @@ export const createStore = () => ...@@ -21,8 +21,8 @@ export const createStore = () =>
list: { list: {
namespaced: true, namespaced: true,
state: listState(), state: listState(),
actions: listActions, actions: { ...actions, ...listActions },
mutations: listMutations, mutations: { ...mutations, ...listMutations },
}, },
details: { details: {
namespaced: true, namespaced: true,
......
...@@ -10,6 +10,8 @@ module Projects::ErrorTrackingHelper ...@@ -10,6 +10,8 @@ module Projects::ErrorTrackingHelper
'user-can-enable-error-tracking' => can?(current_user, :admin_operations, project).to_s, 'user-can-enable-error-tracking' => can?(current_user, :admin_operations, project).to_s,
'enable-error-tracking-link' => project_settings_operations_path(project), 'enable-error-tracking-link' => project_settings_operations_path(project),
'error-tracking-enabled' => error_tracking_enabled.to_s, 'error-tracking-enabled' => error_tracking_enabled.to_s,
'project-path' => project.full_path,
'list-path' => project_error_tracking_index_path(project),
'illustration-path' => image_path('illustrations/cluster_popover.svg') 'illustration-path' => image_path('illustrations/cluster_popover.svg')
} }
end end
......
---
title: Implement ability to ignore Sentry errrors from the list view
merge_request: 22819
author:
type: added
...@@ -31,6 +31,8 @@ describe('ErrorTrackingList', () => { ...@@ -31,6 +31,8 @@ describe('ErrorTrackingList', () => {
store, store,
propsData: { propsData: {
indexPath: '/path', indexPath: '/path',
listPath: '/error_tracking',
projectPath: 'project/test',
enableErrorTrackingLink: '/link', enableErrorTrackingLink: '/link',
userCanEnableErrorTracking, userCanEnableErrorTracking,
errorTrackingEnabled, errorTrackingEnabled,
...@@ -59,6 +61,7 @@ describe('ErrorTrackingList', () => { ...@@ -59,6 +61,7 @@ describe('ErrorTrackingList', () => {
searchByQuery: jest.fn(), searchByQuery: jest.fn(),
sortByField: jest.fn(), sortByField: jest.fn(),
fetchPaginatedResults: jest.fn(), fetchPaginatedResults: jest.fn(),
updateStatus: jest.fn(),
}; };
const state = { const state = {
...@@ -139,6 +142,14 @@ describe('ErrorTrackingList', () => { ...@@ -139,6 +142,14 @@ describe('ErrorTrackingList', () => {
}); });
}); });
it('each error in the list should have an ignore button', () => {
const error = wrapper.findAll('tbody tr');
error.wrappers.forEach((_, index) => {
expect(error.at(index).exists('glicon-stub[name="eye-slash"]')).toBe(true);
});
});
describe('filtering', () => { describe('filtering', () => {
const findSearchBox = () => wrapper.find(GlFormInput); const findSearchBox = () => wrapper.find(GlFormInput);
...@@ -205,6 +216,35 @@ describe('ErrorTrackingList', () => { ...@@ -205,6 +216,35 @@ describe('ErrorTrackingList', () => {
}); });
}); });
describe('When the ignore button on an error is clicked', () => {
beforeEach(() => {
store.state.list.loading = false;
store.state.list.errors = errorsList;
mountComponent({
stubs: {
GlTable: false,
GlLink: false,
GlButton: false,
},
});
});
it('sends the "ignored" status and error ID', () => {
const ignoreButton = wrapper.find({ ref: 'ignoreError' });
ignoreButton.trigger('click');
expect(actions.updateStatus).toHaveBeenCalledWith(
expect.anything(),
{
endpoint: '/project/test/-/error_tracking/3.json',
redirectUrl: '/error_tracking',
status: 'ignored',
},
undefined,
);
});
});
describe('When error tracking is disabled and user is not allowed to enable it', () => { describe('When error tracking is disabled and user is not allowed to enable it', () => {
beforeEach(() => { beforeEach(() => {
mountComponent({ mountComponent({
......
...@@ -11,6 +11,8 @@ describe Projects::ErrorTrackingHelper do ...@@ -11,6 +11,8 @@ describe Projects::ErrorTrackingHelper do
describe '#error_tracking_data' do describe '#error_tracking_data' do
let(:can_enable_error_tracking) { true } let(:can_enable_error_tracking) { true }
let(:setting_path) { project_settings_operations_path(project) } let(:setting_path) { project_settings_operations_path(project) }
let(:list_path) { project_error_tracking_index_path(project) }
let(:project_path) { project.full_path }
let(:index_path) do let(:index_path) do
project_error_tracking_index_path(project, format: :json) project_error_tracking_index_path(project, format: :json)
...@@ -30,6 +32,8 @@ describe Projects::ErrorTrackingHelper do ...@@ -30,6 +32,8 @@ describe Projects::ErrorTrackingHelper do
'user-can-enable-error-tracking' => 'true', 'user-can-enable-error-tracking' => 'true',
'enable-error-tracking-link' => setting_path, 'enable-error-tracking-link' => setting_path,
'error-tracking-enabled' => 'false', 'error-tracking-enabled' => 'false',
'list-path' => list_path,
'project-path' => project_path,
'illustration-path' => match_asset_path('/assets/illustrations/cluster_popover.svg') 'illustration-path' => match_asset_path('/assets/illustrations/cluster_popover.svg')
) )
end end
......
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