Skip to content

Commit

Permalink
US 6 // Show resources that contain a specific value
Browse files Browse the repository at this point in the history
Signed-off-by: Dinika Saxena <[email protected]>
  • Loading branch information
Dinika committed Jul 5, 2023
1 parent 39d36d5 commit e00d2a3
Show file tree
Hide file tree
Showing 8 changed files with 353 additions and 19 deletions.
3 changes: 1 addition & 2 deletions src/shared/hooks/useAccessDataForTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import { addColumnsForES, rowRender } from '../utils/parseESResults';
import { sparqlQueryExecutor } from '../utils/querySparqlView';
import { CartContext } from './useDataCart';
import PromisePool from '@supercharge/promise-pool';
import { normalizeString } from '../../utils/stringUtils';

export const EXPORT_CSV_FILENAME = 'nexus-query-result.csv';
export const CSV_MEDIATYPE = 'text/csv';
Expand Down Expand Up @@ -126,8 +127,6 @@ type ColumnSorter = (
b: Record<string, any>
) => -1 | 1 | 0;

const normalizeString = (str: string) => str.trim().toLowerCase();

const sorter = (dataIndex: string): ColumnSorter => {
return (
a: {
Expand Down
146 changes: 145 additions & 1 deletion src/subapps/dataExplorer/DataExplorer-utils.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { getAllPaths, isPathMissing } from './PredicateSelector';
import {
doesResourceContain,
getAllPaths,
isPathMissing,
} from './PredicateSelector';

describe('DataExplorerSpec-Utils', () => {
it('shows all paths for resources', () => {
Expand Down Expand Up @@ -157,4 +161,144 @@ describe('DataExplorerSpec-Utils', () => {
true
);
});

it('checks if array strings can be checked for contains', () => {
const resource = {
'@id':
'https://bluebrain.github.io/nexus/vocabulary/defaultElasticSearchIndex',
'@type': ['ElasticSearchView', 'View'],
};
expect(doesResourceContain(resource, '@type', '')).toEqual(true);
expect(doesResourceContain(resource, '@type', 'ElasticSearchView')).toEqual(
true
);
expect(doesResourceContain(resource, '@type', 'File')).toEqual(false);
});

it('checks if path has a specific value', () => {
const resource = {
foo: 'some value',
bar: 42,
distribution: [
{
name: 'sally',
filename: 'billy',
label: {
official: 'official',
unofficial: 'rebel',
extended: [{ prefix: '1', suffix: 2 }, { prefix: '1' }],
},
},
{
name: 'sally',
sillyname: 'soliloquy',
filename: 'bolly',
label: [
{
official: 'official',
extended: [{ prefix: '1', suffix: 2 }, { prefix: '1' }],
},
{
official: 'official',
unofficial: 'rebel',
extended: [{ prefix: 1, suffix: '2' }, { prefix: '1' }],
},
],
},
],
};
expect(doesResourceContain(resource, 'foo', '')).toEqual(true);
expect(doesResourceContain(resource, 'foo', 'some value')).toEqual(true);
expect(doesResourceContain(resource, 'foo', '2')).toEqual(false);
expect(doesResourceContain(resource, 'bar', '42')).toEqual(true);
expect(doesResourceContain(resource, 'distribution.name', 'sally')).toEqual(
true
);
expect(
doesResourceContain(resource, 'distribution.sillyname', 'sally')
).toEqual(false);
expect(
doesResourceContain(resource, 'distribution.filename', 'billy')
).toEqual(true);
expect(
doesResourceContain(resource, 'distribution.label', 'madeUpLabel')
).toEqual(false);
expect(
doesResourceContain(resource, 'distribution.official', 'official')
).toEqual(false);
expect(
doesResourceContain(resource, 'distribution.label.official', 'official')
).toEqual(true);
expect(
doesResourceContain(resource, 'distribution.label.unofficial', 'official')
).toEqual(false);
expect(
doesResourceContain(resource, 'distribution.label.unofficial', 'rebel')
).toEqual(true);
expect(
doesResourceContain(resource, 'distribution.label.extended.prefix', '1')
).toEqual(true);
expect(
doesResourceContain(resource, 'distribution.label.extended.prefix', '10')
).toEqual(false);
expect(
doesResourceContain(resource, 'distribution.label.extended.suffix', '1')
).toEqual(false);
expect(
doesResourceContain(resource, 'distribution.label.extended.suffix', '2')
).toEqual(true);
expect(
doesResourceContain(
resource,
'distribution.label.extended.nonexisting',
'2'
)
).toEqual(false);
});

it('ignores case when checking for contains value', () => {
const resource = {
distribution: [
{
name: 'sally',
filename: 'billy',
label: ['ChiPmunK'],
},
{
name: 'sally',
sillyname: 'soliloquy',
filename: 'bolly',
},
],
};
expect(
doesResourceContain(resource, 'distribution.filename', 'BiLLy')
).toEqual(true);
expect(
doesResourceContain(resource, 'distribution.filename', 'Lilly')
).toEqual(false);
expect(
doesResourceContain(resource, 'distribution.label', 'chipmunk')
).toEqual(true);
});

it('checks if value is a substring in existing path when checking for contains', () => {
const resource = {
distribution: [
{
name: 'sally',
filename: 'billy',
label: ['ChiPmunK'],
},
{
name: 'sally',
sillyname: 'soliloquy',
filename: 'bolly',
},
],
};
expect(
doesResourceContain(resource, 'distribution.filename', 'lly')
).toEqual(true);
});
});
43 changes: 43 additions & 0 deletions src/subapps/dataExplorer/DataExplorer.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ describe('DataExplorer', () => {
const expectRowCountToBe = async (expectedRowsCount: number) => {
return await waitFor(() => {
const rows = visibleTableRows();
rows.forEach(row => console.log('Inner html', row.innerHTML));
expect(rows.length).toEqual(expectedRowsCount);
return rows;
});
Expand Down Expand Up @@ -175,6 +176,7 @@ describe('DataExplorer', () => {
optionLabel: string
) => {
await openMenuFor(menuAriaLabel);
console.log('Lookig for option ', optionLabel, ' in menu ', menuAriaLabel);
const option = await getDropdownOption(optionLabel);
await userEvent.click(option, { pointerEventsCheck: 0 });
};
Expand Down Expand Up @@ -403,4 +405,45 @@ describe('DataExplorer', () => {
await selectOptionFromMenu(PredicateMenuLabel, 'Empty value');
await expectRowCountToBe(2);
});

it('shows resources that contains value provided by user', async () => {
await expectRowCountToBe(10);
const mockResourcesForNextPage = [
getMockResource('self1', { author: 'piggy', edition: 1 }),
getMockResource('self2', { author: ['iggy', 'twinky'] }),
getMockResource('self3', { year: 2013 }),
];

await getRowsForNextPage(mockResourcesForNextPage);
await expectRowCountToBe(3);

await selectOptionFromMenu(PathMenuLabel, 'author');
await userEvent.click(container);
await selectOptionFromMenu(PredicateMenuLabel, 'Contains');
const valueInput = await screen.getByPlaceholderText('type the value...');
await userEvent.type(valueInput, 'iggy');
await expectRowCountToBe(2);

await userEvent.clear(valueInput);

await userEvent.type(valueInput, 'goldilocks');
await expectRowCountToBe(0);
});

it('shows all resources when the user has not typed anything in the value filter', async () => {
await expectRowCountToBe(10);
const mockResourcesForNextPage = [
getMockResource('self1', { author: 'piggy', edition: 1 }),
getMockResource('self2', { author: ['iggy', 'twinky'] }),
getMockResource('self3', { year: 2013 }),
];

await getRowsForNextPage(mockResourcesForNextPage);
await expectRowCountToBe(3);

await selectOptionFromMenu(PathMenuLabel, 'author');
await userEvent.click(container);
await selectOptionFromMenu(PredicateMenuLabel, 'Contains');
await expectRowCountToBe(3);
});
});
40 changes: 34 additions & 6 deletions src/subapps/dataExplorer/DataExplorer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,37 @@ import { getResourceLabel } from '../../shared/utils';
import { DataExplorerTable } from './DataExplorerTable';
import './styles.less';
import { ProjectSelector } from './ProjectSelector';
import { PredicateSelector, isPathMissing } from './PredicateSelector';
import {
CONTAINS,
EMPTY_VALUE,
PredicateFilterT,
PredicateSelector,
doesResourceContain,
isPathMissing,
} from './PredicateSelector';
import { normalizeString } from 'utils/stringUtils';

export interface DataExplorerConfiguration {
pageSize: number;
offset: number;
orgAndProject?: [string, string];
predicatePath: string | null;
predicateFilter: string | null;
predicateFilter: PredicateFilterT | null;
predicateValue: string | null;
}

export const DataExplorer: React.FC<{}> = () => {
const nexus = useNexusContext();

const [
{ pageSize, offset, orgAndProject, predicatePath, predicateFilter },
{
pageSize,
offset,
orgAndProject,
predicatePath,
predicateFilter,
predicateValue,
},
updateTableConfiguration,
] = useReducer(
(
Expand All @@ -35,6 +51,7 @@ export const DataExplorer: React.FC<{}> = () => {
orgAndProject: undefined,
predicatePath: null,
predicateFilter: null,
predicateValue: '',
}
);

Expand Down Expand Up @@ -68,9 +85,20 @@ export const DataExplorer: React.FC<{}> = () => {

const displayedDataSource =
predicatePath && predicateFilter
? currentPageDataSource.filter(resource =>
isPathMissing(resource, predicatePath)
)
? currentPageDataSource.filter(resource => {
switch (predicateFilter) {
case EMPTY_VALUE:
return isPathMissing(resource, predicatePath);
case CONTAINS:
return doesResourceContain(
resource,
predicatePath,
predicateValue ?? ''
);
default:
return true;
}
})
: currentPageDataSource;

return (
Expand Down
Loading

0 comments on commit e00d2a3

Please sign in to comment.