Skip to content

Commit

Permalink
Add null option to range facets (#2492)
Browse files Browse the repository at this point in the history
  • Loading branch information
RFSH authored Jul 30, 2024
1 parent 34f0506 commit 09339f8
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 56 deletions.
57 changes: 39 additions & 18 deletions src/components/faceting/facet-range-picker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import { LogService } from '@isrd-isi-edu/chaise/src/services/log';

// utilities
import { dataFormats } from '@isrd-isi-edu/chaise/src/utils/constants';
import { getNotNullFacetCheckBoxRow } from '@isrd-isi-edu/chaise/src/utils/faceting-utils';
import { getNotNullFacetCheckBoxRow, getNullFacetCheckBoxRow } from '@isrd-isi-edu/chaise/src/utils/faceting-utils';
import { windowRef } from '@isrd-isi-edu/chaise/src/utils/window-ref';
import { ResizeSensor } from 'css-element-queries';
import { getInputType } from '@isrd-isi-edu/chaise/src/utils/input-utils';
Expand All @@ -53,9 +53,16 @@ const FacetRangePicker = ({
getFacetLogAction,
getFacetLogStack,
}: FacetRangePickerProps): JSX.Element => {
const [ranges, setRanges, rangesRef] = useStateRef<FacetCheckBoxRow[]>(
(!facetColumn.hideNotNullChoice && !facetColumn.hasNotNullFilter) ? [getNotNullFacetCheckBoxRow(false)] : []
);
const [ranges, setRanges, rangesRef] = useStateRef<FacetCheckBoxRow[]>(() => {
const res: FacetCheckBoxRow[] = [];
if (!facetColumn.hideNotNullChoice) {
res.push(getNotNullFacetCheckBoxRow(facetColumn.hasNotNullFilter));
}
if (!facetColumn.hideNullChoice) {
res.push(getNullFacetCheckBoxRow(facetColumn.hasNullFilter));
}
return res;
});

/**
* We must create references for the state and local variables that
Expand Down Expand Up @@ -105,7 +112,7 @@ const FacetRangePicker = ({
yaxis: {
fixedrange: true,
zeroline: true
// removed tickformat: ',d' since it would cause small data sets to show [0, 1, 1, 2, 2]
// removed tickformat: ',d' since it would cause small data sets to show [0, 1, 1, 2, 2]
// when the yaxis labels were really [0, 0.5, 1, 1.5, 2] by rounding non whole numbers
},
bargap: 0
Expand Down Expand Up @@ -198,10 +205,16 @@ const FacetRangePicker = ({

// if we have the not-null filter, other filters are not important and can be ignored
if (facetColumnRef.current.hasNotNullFilter) {
setRanges([getNotNullFacetCheckBoxRow(true)]);
setRanges(() => {
const res = [getNotNullFacetCheckBoxRow(true)];
if (!facetColumn.hideNullChoice) {
res.push(getNullFacetCheckBoxRow(facetColumn.hasNullFilter));
}
return res;
});
defer.resolve(true);
} else {
// default handles whether notNull option should be present
// default value of ranges already handles whether null and notNull option should be present
const updatedRows: FacetCheckBoxRow[] = [...rangesRef.current];

for (let i = 0; i < facetColumnRef.current.rangeFilters.length; i++) {
Expand Down Expand Up @@ -312,16 +325,24 @@ const FacetRangePicker = ({
res.reference = facetColumn.removeNotNullFilter();
}
$log.debug(`faceting: request for facet (index=${facetIndex}) choice add. Not null filter.`);
} else {
if (row.metaData) {
if (checked) {
res = facetColumn.addRangeFilter(row.metaData.min, row.metaData.minExclusive, row.metaData.max, row.metaData.maxExclusive);
} else {
res = facetColumn.removeRangeFilter(row.metaData.min, row.metaData.minExclusive, row.metaData.max, row.metaData.maxExclusive);
}
$log.debug(`faceting: request for facet (index=${facetColumn.index}) range ${row.selected ? 'add' : 'remove'}.
min=${row.metaData.min}, max=${row.metaData.max}`);
}
else if (row.metaData) {
if (checked) {
res = facetColumn.addRangeFilter(row.metaData.min, row.metaData.minExclusive, row.metaData.max, row.metaData.maxExclusive);
} else {
res = facetColumn.removeRangeFilter(row.metaData.min, row.metaData.minExclusive, row.metaData.max, row.metaData.maxExclusive);
}
$log.debug(`faceting: request for facet (index=${facetColumn.index}) range ${row.selected ? 'add' : 'remove'}.
min=${row.metaData.min}, max=${row.metaData.max}`);
}
// this is the null filter
else {
if (checked) {
res.reference = facetColumn.addChoiceFilters([row.uniqueId]);
} else {
res.reference = facetColumn.removeChoiceFilters([row.uniqueId]);
}
$log.debug(`faceting: request for facet (index=${facetIndex}) range ${row.selected ? 'add' : 'remove'}. uniqueId='${row.uniqueId}`);
}

// this function checks the URL length as well and might fails
Expand Down Expand Up @@ -660,7 +681,7 @@ const FacetRangePicker = ({
const minDate = windowRef.moment(min);
const maxDate = windowRef.moment(max);
const limitedRange = windowRef.moment.duration((maxDate.diff(minDate))).asDays();

if (limitedRange <= 4) {
const minDateDisplay = minDate.subtract(2, 'days').format(dataFormats.date);
const maxDateDisplay = maxDate.add(2, 'days').format(dataFormats.date);
Expand All @@ -669,7 +690,7 @@ const FacetRangePicker = ({
} else if (isColumnOfType('int')) {
const intMax = max as number;
const intMin = min as number;
if ((intMax-intMin) <= 4) return [intMin-2, intMax+2];
if ((intMax - intMin) <= 4) return [intMin - 2, intMax + 2];
}

return [min, max];
Expand Down
106 changes: 68 additions & 38 deletions test/e2e/specs/delete-prohibited/recordset/individual-facet.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const testParams: any = {
name: 'int_col',
type: 'numeric',
notNullNumRows: 20,
nullNumRows: 10,
listElems: 1,
invalid: '1.1',
initialMin: '3',
Expand Down Expand Up @@ -114,6 +115,7 @@ const testParams: any = {
type: 'timestamp',
listElems: 0,
notNullNumRows: 20,
nullNumRows: 10,
// invalid removed since mask protects against bad input values, clear date input to test validator
// invalid: {...}
initialMin: {
Expand Down Expand Up @@ -344,7 +346,7 @@ test.describe('Testing individual facet types', () => {
await openFacetAndTestFilterOptions(page, facet, index, facetParams.options, 1);

await expect.soft(RecordsetLocators.getCheckedFacetOptions(facet)).toHaveCount(0);

if (!facetParams.isBoolean) {
// make sure search placeholder is correct
let placeholder = 'Search';
Expand All @@ -360,11 +362,11 @@ test.describe('Testing individual facet types', () => {

await test.step('select a value to filter on and update the search criteria', async () => {
await testSelectFacetOptionThenClear(
page,
index,
facetParams.option,
facetParams.filter,
facetParams.numRows,
page,
index,
facetParams.option,
facetParams.filter,
facetParams.numRows,
testParams.defaults.pageSize
);

Expand All @@ -380,9 +382,9 @@ test.describe('Testing individual facet types', () => {
const rangeInputs = RecordsetLocators.getFacetRangeInputs(facet);
await test.step('should open the facet, test validators, filter on a range, and update the search criteria.', async () => {
await expect.soft(RecordsetLocators.getClosedFacets(page)).toHaveCount(testParams.totalNumFacets);
await openFacet(page, facet, index, facetParams.listElems + 1, 1);
// wait for facet to open
await openFacet(page, facet, index, facetParams.listElems + 2, 1);

// wait for facet to open
await expect.soft(rangeInputs.submit).toBeVisible();
await expect.soft(RecordsetLocators.getCheckedFacetOptions(facet)).toHaveCount(0);

Expand Down Expand Up @@ -413,9 +415,9 @@ test.describe('Testing individual facet types', () => {
await testRangeInputSubmitThenClear(
page,
facet,
rangeInputs.submit,
facetParams.range.filter,
facetParams.range.numRows,
rangeInputs.submit,
facetParams.range.filter,
facetParams.range.numRows,
testParams.defaults.pageSize
);
await testDefaultRangePickerInitialValues(rangeInputs, facetParams);
Expand All @@ -428,7 +430,7 @@ test.describe('Testing individual facet types', () => {
if (facetParams.notNullNumRows) {
await test.step('should be able to filter not-null values.', async () => {
await testSelectFacetOption(page, facet, 0, facetParams.notNullNumRows, 1);

// make sure submit is disabled
await expect.soft(rangeInputs.submit).toHaveAttribute('disabled');

Expand All @@ -441,21 +443,34 @@ test.describe('Testing individual facet types', () => {
});
}

if (facetParams.nullNumRows) {
await test.step('should be able to filter null values.', async () => {
await testSelectFacetOption(page, facet, 1, facetParams.nullNumRows, 1);

await testClearAllFilters(page, testParams.defaults.pageSize, facet, 1);
await testDefaultRangePickerInitialValues(rangeInputs, facetParams);

// clear inputs
await clearRangeInput(rangeInputs.minInput);
await clearRangeInput(rangeInputs.maxInput);
});
}

await test.step('should filter on just a min value and update the search criteria.', async () => {
// test just min being set
await fillRangeInput(rangeInputs.minInput, facetParams.justMin.min);

// let validation message disappear
await expect.soft(RecordsetLocators.getRangeInputValidationError(facet)).not.toBeVisible();
await testRangeInputSubmitThenClear(
page,
facet,
rangeInputs.submit,
facetParams.justMin.filter,
facetParams.justMin.numRows,
page,
facet,
rangeInputs.submit,
facetParams.justMin.filter,
facetParams.justMin.numRows,
testParams.defaults.pageSize
);

await testDefaultRangePickerInitialValues(rangeInputs, facetParams);

await clearRangeInput(rangeInputs.minInput);
Expand All @@ -469,14 +484,14 @@ test.describe('Testing individual facet types', () => {
// let validation message disappear
await expect.soft(RecordsetLocators.getRangeInputValidationError(facet)).not.toBeVisible();
await testRangeInputSubmitThenClear(
page,
facet,
rangeInputs.submit,
facetParams.justMax.filter,
facetParams.justMax.numRows,
page,
facet,
rangeInputs.submit,
facetParams.justMax.filter,
facetParams.justMax.numRows,
testParams.defaults.pageSize
);

await testDefaultRangePickerInitialValues(rangeInputs, facetParams);

// close the facet
Expand All @@ -491,8 +506,8 @@ test.describe('Testing individual facet types', () => {
const rangeInputs = RecordsetLocators.getFacetRangeTimestampInputs(facet);
await test.step('should open the facet, test validators, filter on a range, and update the search criteria.', async () => {
await expect.soft(RecordsetLocators.getClosedFacets(page)).toHaveCount(testParams.totalNumFacets);
await openFacet(page, facet, index, facetParams.listElems + 1, 1);
await openFacet(page, facet, index, facetParams.listElems + 2, 1);

// wait for facet to open
await expect.soft(rangeInputs.submit).toBeVisible();
await expect.soft(RecordsetLocators.getCheckedFacetOptions(facet)).toHaveCount(0);
Expand Down Expand Up @@ -558,6 +573,21 @@ test.describe('Testing individual facet types', () => {
});
}

if (facetParams.nullNumRows) {
await test.step('should be able to filter not-null values.', async () => {
await testSelectFacetOption(page, facet, 1, facetParams.nullNumRows, 1);

await testClearAllFilters(page, testParams.defaults.pageSize, facet, 1);
await testTimestampRangePickerInitialValues(rangeInputs, facetParams);

// clear the inputs
await clearRangeInput(rangeInputs.minDateInput);
await clearRangeInput(rangeInputs.maxDateInput);
await clearRangeInput(rangeInputs.minTimeInput);
await clearRangeInput(rangeInputs.maxTimeInput);
});
}

await test.step('should filter on just a min value and update the search criteria.', async () => {
// test just min being set
await fillRangeInput(rangeInputs.minDateInput, facetParams.justMin.date);
Expand Down Expand Up @@ -620,22 +650,22 @@ test.describe('Testing individual facet types', () => {

await test.step('selecting the not-null option, should only show the applicable rows.', async () => {
await testSelectFacetOptionThenClear(
page,
index,
0,
facetParams.notNullFilter,
facetParams.notNullNumRows,
page,
index,
0,
facetParams.notNullFilter,
facetParams.notNullNumRows,
testParams.defaults.pageSize
);
});

await test.step('selecting the null option, should only show the applicable rows.', async () => {
await testSelectFacetOptionThenClear(
page,
index,
1,
facetParams.nullFilter,
facetParams.nullNumRows,
page,
index,
1,
facetParams.nullFilter,
facetParams.nullNumRows,
testParams.defaults.pageSize
);

Expand All @@ -649,4 +679,4 @@ test.describe('Testing individual facet types', () => {
}
});
}
});
});

0 comments on commit 09339f8

Please sign in to comment.