Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rework search Page Resources: Filter based on values from shape 3 #102

Merged
merged 33 commits into from
Oct 8, 2024

Conversation

devbysp
Copy link
Contributor

@devbysp devbysp commented Sep 20, 2024

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 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
  • increase test coverage: writiing test for functions, hooks, and components

Zoltan Magyari added 5 commits September 17, 2024 13:39
Signed-off-by: Zoltan Magyari <[email protected]>
Signed-off-by: Zoltan Magyari <[email protected]>
- in order to fetch ontologies and shacl shapes already when the app has started.

- a useSchemas hook was crated inorder to simplify the refactoring in case the context is not the right place to fetch the data.

Signed-off-by: Zoltan Magyari <[email protected]>
Signed-off-by: Zoltan Magyari <[email protected]>
@devbysp devbysp force-pushed the feature/82-filter-based-on-values-from-shape-3 branch 21 times, most recently from 16f30ff to aac4428 Compare September 25, 2024 07:35
@devbysp devbysp force-pushed the feature/82-filter-based-on-values-from-shape-3 branch from 5c891ff to e0218d2 Compare September 25, 2024 18:10
.github/workflows/branch-push.yaml Outdated Show resolved Hide resolved
.github/workflows/branch-push.yaml Outdated Show resolved Hide resolved
.github/workflows/branch-push.yaml Outdated Show resolved Hide resolved
This was referenced Sep 27, 2024
@devbysp devbysp marked this pull request as ready for review September 27, 2024 10:05
Zoltan Magyari added 12 commits September 27, 2024 13:12
in order to run jest tests.

Signed-off-by: Zoltan Magyari <[email protected]>
remove unnecessary quotes from props

Signed-off-by: Zoltan Magyari <[email protected]>
remove unnecessary quotes from props

Signed-off-by: Zoltan Magyari <[email protected]>
Copy link
Collaborator

@robertschubert robertschubert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

github action looks good, approved

Signed-off-by: Zoltan Magyari <[email protected]>
Zoltan Magyari added 2 commits October 6, 2024 19:09
By refactoring the cypher query there is no more need for data mapper.

Signed-off-by: Zoltan Magyari <[email protected]>
- select format asset (Unreal DataSmith)
- select type asset that disables the format asset (HdMap)
- deselect the same type asset (HdMap)
- the resources selected by the (Unreal DataSmith) won't appear even though the filter is selected

Signed-off-by: Zoltan Magyari <[email protected]>
@devbysp devbysp force-pushed the feature/82-filter-based-on-values-from-shape-3 branch from 74f90f6 to 229df53 Compare October 7, 2024 02:23
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would the integration of eslint make sense here? Or redundant, because it is already tested during the commit in the ide?
And do you think npm caching would be useful?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe. Please create a Task. Write those two things in it and assign it to @robertschubert. Move the task into backlog.
image

@devbysp devbysp merged commit 5e80d89 into main Oct 8, 2024
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants