Skip to content

Commit

Permalink
feat: admin report page improvements (#545)
Browse files Browse the repository at this point in the history
  • Loading branch information
banders committed Jun 20, 2024
1 parent e09880b commit e1f7719
Show file tree
Hide file tree
Showing 14 changed files with 517 additions and 308 deletions.
19 changes: 10 additions & 9 deletions admin-frontend/src/components/ReportSearchFilters.vue
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,8 @@ export default {
import { storeToRefs } from 'pinia';
import { ref, onMounted } from 'vue';
import VueDatePicker from '@vuepic/vue-datepicker';
import { useCodeStore } from '../store/modules/codeStore.ts';
import { useReportSearchStore } from '../store/modules/reportSearchStore.ts';
import { useCodeStore } from '../store/modules/codeStore';
import { useReportSearchStore } from '../store/modules/reportSearchStore';
import '@vuepic/vue-datepicker/dist/main.css';
import { ReportFilterType } from '../types';
import {
Expand All @@ -223,8 +223,8 @@ import {
const reportSearchStore = useReportSearchStore();
const codeStore = useCodeStore();
const searchText = ref(undefined);
const submissionDateRange = ref(undefined);
const searchText = ref<string | undefined>(undefined);
const submissionDateRange = ref<any[] | undefined>(undefined);
const areSecondaryFiltersVisible = ref<boolean>(false);
const maxSelectedNaicsCodesShown = ref(3);
const selectedNaicsCodes = ref([]);
Expand All @@ -237,7 +237,7 @@ const reportYearOptions = ref([null, 2024, 2023]);
const lockedOptions = ref([null, 'Locked', 'Unlocked']);
function getReportSearchFilters(): ReportFilterType {
const filters = [];
const filters: any[] = [];
if (searchText.value) {
filters.push({
key: 'company_name',
Expand All @@ -247,7 +247,7 @@ function getReportSearchFilters(): ReportFilterType {
}
if (submissionDateRange.value) {
filters.push({
key: 'create_date',
key: 'update_date',
operation: 'between',
value: submissionDateRange.value.map((d, i) => {
const jodaZonedDateTime = ZonedDateTime.from(
Expand All @@ -273,7 +273,7 @@ function getReportSearchFilters(): ReportFilterType {
filters.push({
key: 'naics_code',
operation: 'in',
value: selectedNaicsCodes.value?.map((d) => d.naics_code),
value: selectedNaicsCodes.value?.map((d: any) => d.naics_code),
});
}
if (selectedReportYear.value) {
Expand All @@ -287,7 +287,9 @@ function getReportSearchFilters(): ReportFilterType {
filters.push({
key: 'employee_count_range_id',
operation: 'in',
value: selectedEmployeeCount.value?.map((d) => d.employee_count_range_id),
value: selectedEmployeeCount.value?.map(
(d: any) => d.employee_count_range_id,
),
});
}
if (selectedLockedValues.value) {
Expand Down Expand Up @@ -317,7 +319,6 @@ Determines whether any of the original state has been changed.
function isDirty() {
return (
(searchText.value != undefined && searchText.value.trim() != '') ||
reportSearchStore.isDirty ||
areSecondaryFiltersVisible.value ||
areSecondaryFiltersDirty()
);
Expand Down
4 changes: 2 additions & 2 deletions admin-frontend/src/components/ReportsPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export default {
import { storeToRefs } from 'pinia';
import { ref } from 'vue';
import ReportSearchFilters from './ReportSearchFilters.vue';
import { useReportSearchStore } from '../store/modules/reportSearchStore.ts';
import { useReportSearchStore } from '../store/modules/reportSearchStore';
import { ReportKeys } from '../types';
import ApiService from '../services/apiService';
import { LocalDate, DateTimeFormatter } from '@js-joda/core';
Expand All @@ -109,7 +109,7 @@ const itemsPerPageOptions = ref([
{ value: 150, title: '150' },
]);
const headers = ref([
const headers = ref<any>([
{
title: 'Submission date',
align: 'start',
Expand Down
19 changes: 0 additions & 19 deletions admin-frontend/src/components/__tests__/ReportsPage.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,22 +31,6 @@ describe('ReportsPage', () => {
pinia = createTestingPinia({
initialState: {},
});
/*
wrapper = mount(
{
template: '<v-layout><ReportsPage/></v-layout>',
},
{
props: {},
global: {
components: {
ReportsPage,
},
plugins: [vuetify, pinia],
},
},
);
*/
wrapper = mount(ReportsPage, {
global: {
plugins: [vuetify, pinia],
Expand All @@ -55,9 +39,6 @@ describe('ReportsPage', () => {

//wait for the async component to load
await flushPromises();

console.log('****');
console.log(wrapper);
};

beforeEach(async () => {
Expand Down
146 changes: 146 additions & 0 deletions admin-frontend/src/components/__tests__/ReportsSearchFilters.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
import { createTestingPinia } from '@pinia/testing';
import { flushPromises, mount } from '@vue/test-utils';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { createVuetify } from 'vuetify';
import * as components from 'vuetify/components';
import * as directives from 'vuetify/directives';
import ReportSearchFilters from '../ReportSearchFilters.vue';

// Mock the ResizeObserver
const ResizeObserverMock = vi.fn(() => ({
observe: vi.fn(),
unobserve: vi.fn(),
disconnect: vi.fn(),
}));

// Stub blobal objects needed for testing
vi.stubGlobal('ResizeObserver', ResizeObserverMock);
vi.stubGlobal('URL', { createObjectURL: vi.fn() });

describe('ReportSearchFilters', () => {
let wrapper;
let pinia;

const initWrapper = async (options: any = {}) => {
const vuetify = createVuetify({
components,
directives,
});

pinia = createTestingPinia({
initialState: {},
});
wrapper = mount(ReportSearchFilters, {
global: {
plugins: [vuetify, pinia],
},
});

//wait for the async component to load
await flushPromises();
};

beforeEach(async () => {
await initWrapper();
});

afterEach(() => {
if (wrapper) {
wrapper.unmount();
}
});

describe('getReportSearchFilters', () => {
describe(`after 'clear' is called`, () => {
it('produces an empty filters array', async () => {
wrapper.vm.clear();
const filters = wrapper.vm.getReportSearchFilters();
expect(filters).toStrictEqual([]);
});
});
describe(`when the naics code list has two items selected (and all other filters in the UI are empty)`, () => {
it('produces a valid filters array', async () => {
wrapper.vm.clear();
const twoMockNaicsObjects = [
{ naics_code: 'mock-naics-1', naics_label: 'mock-naics-label-1' },
{ naics_code: 'mock-naics-2', naics_label: 'mock-naics-label-2' },
];
wrapper.vm.selectedNaicsCodes = twoMockNaicsObjects;
const filters = wrapper.vm.getReportSearchFilters();
const naicsFilters = filters.filter((d) => d.key == 'naics_code');
expect(naicsFilters.length).toBe(1);
expect(naicsFilters[0].operation).toBe('in');
expect(naicsFilters[0].value).toStrictEqual(
twoMockNaicsObjects.map((d) => d.naics_code),
);
});
});
describe(`when the submission date range is specified (and all other filters in the UI are empty)`, () => {
it('produces a valid filters array', async () => {
wrapper.vm.clear();
const d1 = '2024-04-17T00:00:00Z';
const d2 = '2024-05-17T00:00:00Z';
const dateRange = [new Date(d1), new Date(d2)];
wrapper.vm.submissionDateRange = dateRange;
const filters = wrapper.vm.getReportSearchFilters();
const submissonDateFilters = filters.filter(
(d) => d.key == 'update_date',
);
expect(submissonDateFilters.length).toBe(1);
expect(submissonDateFilters[0].operation).toBe('between');
expect(submissonDateFilters[0].value.length).toBe(2);
});
});
describe(`when the report year is specified (and all other filters in the UI are empty)`, () => {
it('produces a valid filters array', async () => {
wrapper.vm.clear();
const mockYear = 2024;
wrapper.vm.selectedReportYear = mockYear;
const filters = wrapper.vm.getReportSearchFilters();
const reportYearFilters = filters.filter(
(d) => d.key == 'reporting_year',
);
expect(reportYearFilters.length).toBe(1);
expect(reportYearFilters[0].operation).toBe('eq');
expect(reportYearFilters[0].value).toBe(mockYear);
});
});
describe(`when the employee count is specified (and all other filters in the UI are empty)`, () => {
it('produces a valid filters array', async () => {
wrapper.vm.clear();
const twoMockEmpCountRanges = [
{
employee_count_range: '1-50',
employee_count_range_id: 'mock-emp-count-range-id-1',
},
{
employee_count_range: '51-100',
employee_count_range_id: 'mock-emp-count-range-id-2',
},
];
wrapper.vm.selectedEmployeeCount = twoMockEmpCountRanges;
const filters = wrapper.vm.getReportSearchFilters();
const empCountFilters = filters.filter(
(d) => d.key == 'employee_count_range_id',
);
expect(empCountFilters.length).toBe(1);
expect(empCountFilters[0].operation).toBe('in');
expect(empCountFilters[0].value).toStrictEqual(
twoMockEmpCountRanges.map((d) => d.employee_count_range_id),
);
});
});
describe(`when the report year is specified (and all other filters in the UI are empty)`, () => {
it('produces a valid filters array', async () => {
wrapper.vm.clear();
const isUnlocked = false;
wrapper.vm.selectedLockedValues = isUnlocked ? 'Unlocked' : 'Locked';
const filters = wrapper.vm.getReportSearchFilters();
const reportYearFilters = filters.filter((d) => d.key == 'is_unlocked');
expect(reportYearFilters.length).toBe(1);
expect(reportYearFilters[0].operation).toBe('eq');
expect(reportYearFilters[0].value).toBe(isUnlocked);
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ import { createTestingPinia } from '@pinia/testing';
import { setActivePinia } from 'pinia';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { IReportSearchParams, IReportSearchUpdateParams } from '../../../types';
import { DEFAULT_PAGE_SIZE, useReportSearchStore } from '../reportSearchStore';
import {
DEFAULT_PAGE_SIZE,
DEFAULT_SEARCH_PARAMS,
useReportSearchStore,
} from '../reportSearchStore';

const mockGetReports = vi.fn();
vi.mock('../../../services/apiService', () => ({
Expand Down Expand Up @@ -62,7 +66,6 @@ describe('reportSearchStore', () => {
);
expect(reportSearchStore.totalNum).toBe(mockGetReportsResponse.total);
expect(reportSearchStore.isSearching).toBeFalsy();
expect(reportSearchStore.isDirty).toBeTruthy();
expect(reportSearchStore.lastSubmittedReportSearchParams).toStrictEqual(
params,
);
Expand All @@ -71,7 +74,7 @@ describe('reportSearchStore', () => {

describe('updateSearch', () => {
it('should update the store with reports matching the search params', async () => {
const prevSearchParams: IReportSearchParams = {
const prevSearchParams = {
page: 1,
itemsPerPage: 1,
filter: [],
Expand Down Expand Up @@ -104,7 +107,6 @@ describe('reportSearchStore', () => {
);
expect(reportSearchStore.totalNum).toBe(mockGetReportsResponse.total);
expect(reportSearchStore.isSearching).toBeFalsy();
expect(reportSearchStore.isDirty).toBeTruthy();
expect(reportSearchStore.lastSubmittedReportSearchParams).toStrictEqual({
page: updateParams.page,
itemsPerPage: updateParams.itemsPerPage,
Expand Down Expand Up @@ -157,18 +159,34 @@ describe('reportSearchStore', () => {
});

describe('reset', () => {
it('the store should be returned to its original state', () => {
reportSearchStore.searchResults = [{}, {}];
it('the store should be returned to its original state', async () => {
reportSearchStore.searchResults = [{}, {}, {}];
reportSearchStore.pageSize = 5;
reportSearchStore.totalNum = reportSearchStore.searchResults.length;
reportSearchStore.lastSubmittedReportSearchParams = 123;
reportSearchStore.lastSubmittedReportSearchParams = {};

reportSearchStore.reset();
const mockGetReportsResponse = {
reports: [
{
report_id: '1119e398-22e7-4d10-93aa-8b2112b4e74f',
},
{
report_id: '24df5544-78e2-aa1c-97aa-8b2112b4556a',
},
],
total: 2,
};
mockGetReports.mockResolvedValue(mockGetReportsResponse);

await reportSearchStore.reset();

expect(reportSearchStore.searchResults).toBe(undefined);
expect(reportSearchStore.pageSize).toBe(DEFAULT_PAGE_SIZE);
expect(reportSearchStore.totalNum).toBe(0);
expect(reportSearchStore.lastSubmittedReportSearchParams).toBe(undefined);
expect(reportSearchStore.totalNum).toStrictEqual(
mockGetReportsResponse.total,
);
expect(reportSearchStore.lastSubmittedReportSearchParams).toStrictEqual(
DEFAULT_SEARCH_PARAMS,
);
});
});
});
Loading

0 comments on commit e1f7719

Please sign in to comment.