From: Michal Klobukowski Date: Wed, 21 Nov 2018 15:19:03 +0000 (+0100) Subject: Create resource-type-filters X-Git-Tag: 1.3.0~12^2^2~1^2~4^2~1 X-Git-Url: https://git.arvados.org/arvados-workbench2.git/commitdiff_plain/b5dde550c7dd67f0b90841d6b92930e56c625dcd Create resource-type-filters Feature #14258 Arvados-DCO-1.1-Signed-off-by: Michal Klobukowski --- diff --git a/src/store/resource-type-filters/resource-type-filters.test.ts b/src/store/resource-type-filters/resource-type-filters.test.ts new file mode 100644 index 00000000..3e345860 --- /dev/null +++ b/src/store/resource-type-filters/resource-type-filters.test.ts @@ -0,0 +1,37 @@ +// Copyright (C) The Arvados Authors. All rights reserved. +// +// SPDX-License-Identifier: AGPL-3.0 + +import { getInitialResourceTypeFilters, serializeResourceTypeFilters, ObjectTypeFilter, CollectionTypeFilter } from './resource-type-filters'; +import { ResourceKind } from '~/models/resource'; +import { deselectNode } from '~/models/tree'; +import { pipe } from 'lodash/fp'; + +describe("serializeResourceTypeFilters", () => { + it("should serialize all filters", () => { + const filters = getInitialResourceTypeFilters(); + const serializedFilters = serializeResourceTypeFilters(filters); + expect(serializedFilters) + .toEqual(`["uuid","is_a",["${ResourceKind.PROJECT}","${ResourceKind.PROCESS}","${ResourceKind.COLLECTION}"]],["collections.properties.type","in",["nil","output","log"]]`); + }); + + it("should serialize all but collection filters", () => { + const filters = deselectNode(ObjectTypeFilter.COLLECTION)(getInitialResourceTypeFilters()); + const serializedFilters = serializeResourceTypeFilters(filters); + expect(serializedFilters) + .toEqual(`["uuid","is_a",["${ResourceKind.PROJECT}","${ResourceKind.PROCESS}"]]`); + }); + + it("should serialize output collections and projects", () => { + const filters = pipe( + () => getInitialResourceTypeFilters(), + deselectNode(ObjectTypeFilter.PROCESS), + deselectNode(CollectionTypeFilter.GENERAL_COLLECTION), + deselectNode(CollectionTypeFilter.LOG_COLLECTION), + )(); + + const serializedFilters = serializeResourceTypeFilters(filters); + expect(serializedFilters) + .toEqual(`["uuid","is_a",["${ResourceKind.PROJECT}","${ResourceKind.COLLECTION}"]],["collections.properties.type","in",["output"]]`); + }); +}); diff --git a/src/store/resource-type-filters/resource-type-filters.ts b/src/store/resource-type-filters/resource-type-filters.ts new file mode 100644 index 00000000..d95ae5a4 --- /dev/null +++ b/src/store/resource-type-filters/resource-type-filters.ts @@ -0,0 +1,113 @@ +// Copyright (C) The Arvados Authors. All rights reserved. +// +// SPDX-License-Identifier: AGPL-3.0 + +import { pipe, values, includes, __ } from 'lodash/fp'; +import { createTree, setNode, TreeNodeStatus, TreeNode } from '~/models/tree'; +import { DataTableFilterItem, DataTableFilters } from '~/components/data-table-filters/data-table-filters-tree'; +import { ResourceKind } from '~/models/resource'; +import { FilterBuilder } from '~/services/api/filter-builder'; +import { getSelectedNodes } from '~/models/tree'; +import { CollectionType } from '~/models/collection'; +import { GroupContentsResourcePrefix } from '~/services/groups-service/groups-service'; + +export enum ObjectTypeFilter { + PROJECT = 'Project', + PROCESS = 'Process', + COLLECTION = 'Data Collection', +} + +export enum CollectionTypeFilter { + GENERAL_COLLECTION = 'General', + OUTPUT_COLLECTION = 'Output', + LOG_COLLECTION = 'Log', +} + +const initFilter = (name: string, parent = '') => + setNode({ + id: name, + value: { name }, + parent, + children: [], + active: false, + selected: true, + expanded: false, + status: TreeNodeStatus.LOADED, + }); + +export const getInitialResourceTypeFilters = pipe( + (): DataTableFilters => createTree(), + initFilter(ObjectTypeFilter.PROJECT), + initFilter(ObjectTypeFilter.PROCESS), + initFilter(ObjectTypeFilter.COLLECTION), + initFilter(CollectionTypeFilter.GENERAL_COLLECTION, ObjectTypeFilter.COLLECTION), + initFilter(CollectionTypeFilter.OUTPUT_COLLECTION, ObjectTypeFilter.COLLECTION), + initFilter(CollectionTypeFilter.LOG_COLLECTION, ObjectTypeFilter.COLLECTION), +); + + +const createFiltersBuilder = (filters: DataTableFilters) => + ({ fb: new FilterBuilder(), selectedFilters: getSelectedNodes(filters) }); + +const getMatchingFilters = (values: string[], filters: TreeNode[]) => + filters + .map(f => f.id) + .filter(includes(__, values)); + +const objectTypeToResourceKind = (type: ObjectTypeFilter) => { + switch (type) { + case ObjectTypeFilter.PROJECT: + return ResourceKind.PROJECT; + case ObjectTypeFilter.PROCESS: + return ResourceKind.PROCESS; + case ObjectTypeFilter.COLLECTION: + return ResourceKind.COLLECTION; + } +}; + +const serializeObjectTypeFilters = ({ fb, selectedFilters }: ReturnType) => { + const collectionFilters = getMatchingFilters(values(CollectionTypeFilter), selectedFilters); + const typeFilters = pipe( + () => new Set(getMatchingFilters(values(ObjectTypeFilter), selectedFilters)), + set => collectionFilters.length > 0 + ? set.add(ObjectTypeFilter.COLLECTION) + : set, + set => Array.from(set) + )(); + + return { + fb: typeFilters.length > 0 + ? fb.addIsA('uuid', typeFilters.map(objectTypeToResourceKind)) + : fb, + selectedFilters, + }; +}; + +const collectionTypeToPropertyValue = (type: CollectionTypeFilter) => { + switch (type) { + case CollectionTypeFilter.GENERAL_COLLECTION: + return CollectionType.GENERAL; + case CollectionTypeFilter.OUTPUT_COLLECTION: + return CollectionType.OUTPUT; + case CollectionTypeFilter.LOG_COLLECTION: + return CollectionType.LOG; + } +}; + +const serializeCollectionTypeFilters = ({ fb, selectedFilters }: ReturnType) => pipe( + () => getMatchingFilters(values(CollectionTypeFilter), selectedFilters), + filters => filters.map(collectionTypeToPropertyValue), + mappedFilters => ({ + fb: mappedFilters.length > 0 + ? fb.addIn('type', mappedFilters, `${GroupContentsResourcePrefix.COLLECTION}.properties`) + : fb, + selectedFilters + }) +)(); + +export const serializeResourceTypeFilters = pipe( + createFiltersBuilder, + serializeObjectTypeFilters, + serializeCollectionTypeFilters, + ({ fb }) => fb.getFilters(), +);