Rendering vendor filters dynamically from fetched resources. (Hint: The vendor information is stored in a node linked to a DataResource node via the copyrightOwnedBy property.)
/**
* Returns all resources of type included in the type asset list passed in as parameter.
*
* @param types the list of requested resource types
*/
async getAllResources(types: string[]): Promise<ResourceInput> {
if (!types.length) {
return { items: [] };
}
const typeLabels = types.join('\', \'');
return cypherQuery({
statement: `
MATCH (resource)
WHERE ANY (label IN labels(resource) WHERE label IN [ '${typeLabels}'])
AND 'DataResource' IN labels(resource)
AND NOT resource.uri STARTS WITH 'bnode://'
OPTIONAL MATCH(formatProperty)
WHERE resource.uri IN formatProperty.claimsGraphUri
AND ANY(label IN labels(formatProperty) WHERE label CONTAINS 'Format')
OPTIONAL MATCH(copyrightOwner)
WHERE copyrightOwner.uri = resource.copyrightOwnedBy
RETURN
properties(resource) AS properties,
labels(resource) AS labels,
properties(formatProperty).type AS format,
properties(copyrightOwner).legalName AS vendor`,
})
},
Filtering business logic
Full description
All ontologies and shacl shape are fetched.
The type filter assets are calculated from the ontologies and shacl shapes.
The disabled property of the type filters are set based on the available resources.
The format assets are also calculated from the ontologies and shacl shapes.
The disabled property of the format filter assets are calculated from the available resources after the type filters have been applied.
The vedors filter assets are calculated from the fetched resources.
The disabled property of the vendor filter assets is dependent on the available resources after the type and format filters have been applied to the fetched resources.
/**
* Calculates the filter assets from ontologies and resources. Calculates the new filtered resource list also.
*
* @param ontologies list of ontologies from which the filter assets should be calculated.
* @param resources list of resources from which the filter assets should be calculated.
* @param filters previous filter assets state in order to preserve an existing selection during the update of an asset.
* @return the new state of the {@link useResourceFilter} hook.
*/
export const calculateResourceFiltersAssetState = (
ontologies: Ontology[],
resources: Resource[],
filters: ResourceFilterState
) => {
const resourceTypes = Array.from(getResourceTypes(ontologies));
const typeAssets = createTypeAssets(resourceTypes, resources)
.map(typeAsset => filters.typeAssets
.find(item => item.id === typeAsset.id) || typeAsset);
const resourcesWithTypeFilterApplied = resources
.filter((resource) => {
const selectedAssets = getSelectedAssets(filters.typeAssets)
return selectedAssets === 'NOTHING' || selectedAssets
.some(type => resource.labels.includes(type))
});
const resourceFormats = Array.from(getResourceFormats(ontologies));
const formatAssets = createFormatAssets(resourceFormats, filters.formatAssets, resourcesWithTypeFilterApplied);
const resourcesWithFormatFilterApplied = resourcesWithTypeFilterApplied
.filter(resource => {
const selectedAssets = getSelectedAssets(filters.formatAssets)
return selectedAssets === 'NOTHING' || selectedAssets
.some(format => resource.format === format)
});
const resourceVendors = Array.from(getResourceVendors(resources));
const vendorAssets = createVendorAssets(resourceVendors, filters.vendorAssets, resourcesWithFormatFilterApplied);
const resourcesWithVendorFilterApplied = resourcesWithFormatFilterApplied
.filter(resource => {
const selectedAssets = getSelectedAssets(filters.vendorAssets)
return selectedAssets === 'NOTHING' || selectedAssets
.some(vendor => resource.vendor === vendor)
});
const resourcesWithSearchTextFilterApplied = resourcesWithVendorFilterApplied
.filter(resource => Object
.entries(resource)
.some(property => !filters.searchText ||
getPropertyValue(property).toLowerCase()
.includes(filters.searchText.toLowerCase()))
);
return {
typeAssets,
formatAssets,
vendorAssets,
filteredResources: resourcesWithSearchTextFilterApplied
};
}
Other things solved
Solve the problem of circular dependency and re-rendering. The filter assets modify the fetched resource list and the modified (filtered) resource list will affect the filter assets. This is a cicular dependency and has the potential to trigger an infinite rerendering cycle.
separation of concerns
ontologies fetched in the hook: useSchemas
resources fetched in the loadResources method
filter assets are managed in the useResourceFilter hook
using useReduces in order to minimize the rerenderings. (A useThunkReducer was also created in order to support dispatching of thunks)
configuring: jest
configuring: git workflow for running test coverage on pull requests
Task: Rework search Page Resources: Filter based on values from shape
Description
Required
Rendering vendor filters dynamically from fetched resources. (Hint: The vendor information is stored in a node linked to a
DataResource
node via thecopyrightOwnedBy
property.)Filtering business logic
Full description
type
filter assets are calculated from the ontologies and shacl shapes.type
filters are set based on the available resources.format
assets are also calculated from the ontologies and shacl shapes.format
filter assets are calculated from the available resources after thetype
filters have been applied.vedors
filter assets are calculated from the fetched resources.The disabled property of the
vendor
filter assets is dependent on the available resources after thetype
andformat
filters have been applied to the fetched resources.Other things solved
useSchemas
loadResources
methoduseResourceFilter
hookuseReduces
in order to minimize the rerenderings. (AuseThunkReducer
was also created in order to support dispatching of thunks)