Commit 4b9426ed authored by Kushal Pandya's avatar Kushal Pandya

Merge branch '229534-incidents-sorting-FE' into 'master'

Column sorting for Incident list

See merge request gitlab-org/gitlab!43121
parents ed7e4180 ae6cc206
...@@ -33,9 +33,15 @@ import getIncidents from '../graphql/queries/get_incidents.query.graphql'; ...@@ -33,9 +33,15 @@ import getIncidents from '../graphql/queries/get_incidents.query.graphql';
import getIncidentsCountByStatus from '../graphql/queries/get_count_by_status.query.graphql'; import getIncidentsCountByStatus from '../graphql/queries/get_count_by_status.query.graphql';
import SeverityToken from '~/sidebar/components/severity/severity.vue'; import SeverityToken from '~/sidebar/components/severity/severity.vue';
import { INCIDENT_SEVERITY } from '~/sidebar/components/severity/constants'; import { INCIDENT_SEVERITY } from '~/sidebar/components/severity/constants';
import { I18N, DEFAULT_PAGE_SIZE, INCIDENT_STATUS_TABS } from '../constants'; import {
I18N,
DEFAULT_PAGE_SIZE,
INCIDENT_STATUS_TABS,
TH_CREATED_AT_TEST_ID,
TH_SEVERITY_TEST_ID,
TH_PUBLISHED_TEST_ID,
} from '../constants';
const TH_TEST_ID = { 'data-testid': 'incident-management-created-at-sort' };
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';
const thClass = 'gl-hover-bg-blue-50'; const thClass = 'gl-hover-bg-blue-50';
...@@ -57,8 +63,10 @@ export default { ...@@ -57,8 +63,10 @@ export default {
{ {
key: 'severity', key: 'severity',
label: s__('IncidentManagement|Severity'), label: s__('IncidentManagement|Severity'),
thClass: `gl-pointer-events-none`, thClass,
tdClass, tdClass: `${tdClass} sortable-cell`,
sortable: true,
thAttr: TH_SEVERITY_TEST_ID,
}, },
{ {
key: 'title', key: 'title',
...@@ -72,7 +80,7 @@ export default { ...@@ -72,7 +80,7 @@ export default {
thClass, thClass,
tdClass: `${tdClass} sortable-cell`, tdClass: `${tdClass} sortable-cell`,
sortable: true, sortable: true,
thAttr: TH_TEST_ID, thAttr: TH_CREATED_AT_TEST_ID,
}, },
{ {
key: 'assignees', key: 'assignees',
...@@ -226,7 +234,10 @@ export default { ...@@ -226,7 +234,10 @@ export default {
{ {
key: 'published', key: 'published',
label: s__('IncidentManagement|Published'), label: s__('IncidentManagement|Published'),
thClass: 'gl-pointer-events-none', thClass,
tdClass: `${tdClass} sortable-cell`,
sortable: true,
thAttr: TH_PUBLISHED_TEST_ID,
}, },
], ],
] ]
...@@ -312,6 +323,7 @@ export default { ...@@ -312,6 +323,7 @@ export default {
}, },
methods: { methods: {
filterIncidentsByStatus(tabIndex) { filterIncidentsByStatus(tabIndex) {
this.resetPagination();
const { filters, status } = this.$options.statusTabs[tabIndex]; const { filters, status } = this.$options.statusTabs[tabIndex];
this.statusFilter = filters; this.statusFilter = filters;
this.filteredByStatus = status; this.filteredByStatus = status;
...@@ -345,15 +357,19 @@ export default { ...@@ -345,15 +357,19 @@ export default {
this.pagination = initialPaginationState; this.pagination = initialPaginationState;
}, },
fetchSortedData({ sortBy, sortDesc }) { fetchSortedData({ sortBy, sortDesc }) {
const sortingDirection = sortDesc ? 'desc' : 'asc'; const sortingDirection = sortDesc ? 'DESC' : 'ASC';
const sortingColumn = convertToSnakeCase(sortBy).replace(/_.*/, ''); const sortingColumn = convertToSnakeCase(sortBy)
.replace(/_.*/, '')
.toUpperCase();
this.resetPagination();
this.sort = `${sortingColumn}_${sortingDirection}`; this.sort = `${sortingColumn}_${sortingDirection}`;
}, },
getSeverity(severity) { getSeverity(severity) {
return INCIDENT_SEVERITY[severity]; return INCIDENT_SEVERITY[severity];
}, },
handleFilterIncidents(filters) { handleFilterIncidents(filters) {
this.resetPagination();
const filterParams = { authorUsername: '', assigneeUsername: '', search: '' }; const filterParams = { authorUsername: '', assigneeUsername: '', search: '' };
filters.forEach(filter => { filters.forEach(filter => {
......
...@@ -35,3 +35,6 @@ export const INCIDENT_STATUS_TABS = [ ...@@ -35,3 +35,6 @@ export const INCIDENT_STATUS_TABS = [
]; ];
export const DEFAULT_PAGE_SIZE = 20; export const DEFAULT_PAGE_SIZE = 20;
export const TH_CREATED_AT_TEST_ID = { 'data-testid': 'incident-management-created-at-sort' };
export const TH_SEVERITY_TEST_ID = { 'data-testid': 'incident-management-severity-sort' };
export const TH_PUBLISHED_TEST_ID = { 'data-testid': 'incident-management-published-sort' };
---
title: Sort incidents list by severity and published columns
merge_request: 43121
author:
type: added
...@@ -16,7 +16,13 @@ import SeverityToken from '~/sidebar/components/severity/severity.vue'; ...@@ -16,7 +16,13 @@ import SeverityToken from '~/sidebar/components/severity/severity.vue';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue'; import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import FilteredSearchBar from '~/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue'; import FilteredSearchBar from '~/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue';
import AuthorToken from '~/vue_shared/components/filtered_search_bar/tokens/author_token.vue'; import AuthorToken from '~/vue_shared/components/filtered_search_bar/tokens/author_token.vue';
import { I18N, INCIDENT_STATUS_TABS } from '~/incidents/constants'; import {
I18N,
INCIDENT_STATUS_TABS,
TH_CREATED_AT_TEST_ID,
TH_SEVERITY_TEST_ID,
TH_PUBLISHED_TEST_ID,
} from '~/incidents/constants';
import mockIncidents from '../mocks/incidents.json'; import mockIncidents from '../mocks/incidents.json';
import mockFilters from '../mocks/incidents_filter.json'; import mockFilters from '../mocks/incidents_filter.json';
...@@ -45,8 +51,6 @@ describe('Incidents List', () => { ...@@ -45,8 +51,6 @@ describe('Incidents List', () => {
const findAlert = () => wrapper.find(GlAlert); const findAlert = () => wrapper.find(GlAlert);
const findLoader = () => wrapper.find(GlLoadingIcon); const findLoader = () => wrapper.find(GlLoadingIcon);
const findTimeAgo = () => wrapper.findAll(TimeAgoTooltip); const findTimeAgo = () => wrapper.findAll(TimeAgoTooltip);
const findDateColumnHeader = () =>
wrapper.find('[data-testid="incident-management-created-at-sort"]');
const findSearch = () => wrapper.find(FilteredSearchBar); const findSearch = () => wrapper.find(FilteredSearchBar);
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"]');
...@@ -437,13 +441,25 @@ describe('Incidents List', () => { ...@@ -437,13 +441,25 @@ describe('Incidents List', () => {
}); });
}); });
it('updates sort with new direction and column key', () => { const descSort = 'descending';
expect(findDateColumnHeader().attributes('aria-sort')).toBe('descending'); const ascSort = 'ascending';
const noneSort = 'none';
findDateColumnHeader().trigger('click'); it.each`
return wrapper.vm.$nextTick(() => { selector | initialSort | firstSort | nextSort
expect(findDateColumnHeader().attributes('aria-sort')).toBe('ascending'); ${TH_CREATED_AT_TEST_ID} | ${descSort} | ${ascSort} | ${descSort}
}); ${TH_SEVERITY_TEST_ID} | ${noneSort} | ${descSort} | ${ascSort}
${TH_PUBLISHED_TEST_ID} | ${noneSort} | ${descSort} | ${ascSort}
`('updates sort with new direction', async ({ selector, initialSort, firstSort, nextSort }) => {
const [[attr, value]] = Object.entries(selector);
const columnHeader = () => wrapper.find(`[${attr}="${value}"]`);
expect(columnHeader().attributes('aria-sort')).toBe(initialSort);
columnHeader().trigger('click');
await wrapper.vm.$nextTick();
expect(columnHeader().attributes('aria-sort')).toBe(firstSort);
columnHeader().trigger('click');
await wrapper.vm.$nextTick();
expect(columnHeader().attributes('aria-sort')).toBe(nextSort);
}); });
}); });
}); });
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