From 96b6bf5ac045e8b11e00a2cd73f6ecfbd7040cca Mon Sep 17 00:00:00 2001 From: Daniel Kos Date: Wed, 15 Aug 2018 17:18:49 +0200 Subject: [PATCH] Simplify order and filter builder Arvados-DCO-1.1-Signed-off-by: Daniel Kos --- src/common/api/common-resource-service.ts | 10 ++-- src/common/api/filter-builder.test.ts | 56 +++++++------------ src/common/api/filter-builder.ts | 48 +++++++--------- src/common/api/order-builder.test.ts | 14 +---- src/common/api/order-builder.ts | 36 ++++-------- .../collection-service/collection-service.ts | 4 +- .../favorite-order-builder.ts | 48 ---------------- .../favorite-service/favorite-service.test.ts | 11 ++-- .../favorite-service/favorite-service.ts | 37 ++++++------ src/services/groups-service/groups-service.ts | 10 ++-- .../project-service/project-service.test.ts | 5 +- .../project-service/project-service.ts | 20 +++---- src/services/tag-service/tag-service.ts | 12 ++-- .../favorite-panel-middleware-service.ts | 36 ++++++++---- .../project-panel-middleware-service.ts | 52 +++++++---------- src/store/project/project-action.ts | 6 +- .../project-tree-picker.tsx | 6 +- 17 files changed, 150 insertions(+), 261 deletions(-) delete mode 100644 src/services/favorite-service/favorite-order-builder.ts diff --git a/src/common/api/common-resource-service.ts b/src/common/api/common-resource-service.ts index 36017f0f..caa4d760 100644 --- a/src/common/api/common-resource-service.ts +++ b/src/common/api/common-resource-service.ts @@ -3,16 +3,14 @@ // SPDX-License-Identifier: AGPL-3.0 import * as _ from "lodash"; -import { FilterBuilder } from "./filter-builder"; -import { OrderBuilder } from "./order-builder"; import { AxiosInstance, AxiosPromise } from "axios"; import { Resource } from "~/models/resource"; export interface ListArguments { limit?: number; offset?: number; - filters?: FilterBuilder; - order?: OrderBuilder; + filters?: string; + order?: string; select?: string[]; distinct?: boolean; count?: string; @@ -90,8 +88,8 @@ export class CommonResourceService { const { filters, order, ...other } = args; const params = { ...other, - filters: filters ? filters.serialize() : undefined, - order: order ? order.getOrder() : undefined + filters: filters ? `[${filters}]` : undefined, + order: order ? order : undefined }; return CommonResourceService.defaultResponse( this.serverApi diff --git a/src/common/api/filter-builder.test.ts b/src/common/api/filter-builder.test.ts index d129a806..de2ba4cb 100644 --- a/src/common/api/filter-builder.test.ts +++ b/src/common/api/filter-builder.test.ts @@ -9,49 +9,49 @@ describe("FilterBuilder", () => { let filters: FilterBuilder; beforeEach(() => { - filters = FilterBuilder.create(); + filters = new FilterBuilder(); }); it("should add 'equal' rule", () => { expect( - filters.addEqual("etag", "etagValue").serialize() - ).toEqual(`[["etag","=","etagValue"]]`); + filters.addEqual("etag", "etagValue").getFilters() + ).toEqual(`["etag","=","etagValue"]`); }); it("should add 'like' rule", () => { expect( - filters.addLike("etag", "etagValue").serialize() - ).toEqual(`[["etag","like","%etagValue%"]]`); + filters.addLike("etag", "etagValue").getFilters() + ).toEqual(`["etag","like","%etagValue%"]`); }); it("should add 'ilike' rule", () => { expect( - filters.addILike("etag", "etagValue").serialize() - ).toEqual(`[["etag","ilike","%etagValue%"]]`); + filters.addILike("etag", "etagValue").getFilters() + ).toEqual(`["etag","ilike","%etagValue%"]`); }); it("should add 'is_a' rule", () => { expect( - filters.addIsA("etag", "etagValue").serialize() - ).toEqual(`[["etag","is_a","etagValue"]]`); + filters.addIsA("etag", "etagValue").getFilters() + ).toEqual(`["etag","is_a","etagValue"]`); }); it("should add 'is_a' rule for set", () => { expect( - filters.addIsA("etag", ["etagValue1", "etagValue2"]).serialize() - ).toEqual(`[["etag","is_a",["etagValue1","etagValue2"]]]`); + filters.addIsA("etag", ["etagValue1", "etagValue2"]).getFilters() + ).toEqual(`["etag","is_a",["etagValue1","etagValue2"]]`); }); it("should add 'in' rule", () => { expect( - filters.addIn("etag", "etagValue").serialize() - ).toEqual(`[["etag","in","etagValue"]]`); + filters.addIn("etag", "etagValue").getFilters() + ).toEqual(`["etag","in","etagValue"]`); }); it("should add 'in' rule for set", () => { expect( - filters.addIn("etag", ["etagValue1", "etagValue2"]).serialize() - ).toEqual(`[["etag","in",["etagValue1","etagValue2"]]]`); + filters.addIn("etag", ["etagValue1", "etagValue2"]).getFilters() + ).toEqual(`["etag","in",["etagValue1","etagValue2"]]`); }); it("should add multiple rules", () => { @@ -59,28 +59,14 @@ describe("FilterBuilder", () => { filters .addIn("etag", ["etagValue1", "etagValue2"]) .addEqual("href", "hrefValue") - .serialize() - ).toEqual(`[["etag","in",["etagValue1","etagValue2"]],["href","=","hrefValue"]]`); - }); - - it("should concatenate multiple builders", () => { - expect( - filters - .concat(FilterBuilder.create().addIn("etag", ["etagValue1", "etagValue2"])) - .concat(FilterBuilder.create().addEqual("href", "hrefValue")) - .serialize() - ).toEqual(`[["etag","in",["etagValue1","etagValue2"]],["href","=","hrefValue"]]`); + .getFilters() + ).toEqual(`["etag","in",["etagValue1","etagValue2"]],["href","=","hrefValue"]`); }); it("should add attribute prefix", () => { - expect(FilterBuilder - .create("myPrefix") - .addIn("etag", ["etagValue1", "etagValue2"]) - .serialize()) - .toEqual(`[["my_prefix.etag","in",["etagValue1","etagValue2"]]]`); + expect(new FilterBuilder() + .addIn("etag", ["etagValue1", "etagValue2"], "myPrefix") + .getFilters()) + .toEqual(`["my_prefix.etag","in",["etagValue1","etagValue2"]]`); }); - - - - }); diff --git a/src/common/api/filter-builder.ts b/src/common/api/filter-builder.ts index e5aab3ac..b5558dbb 100644 --- a/src/common/api/filter-builder.ts +++ b/src/common/api/filter-builder.ts @@ -4,58 +4,48 @@ import * as _ from "lodash"; -export class FilterBuilder { - static create(resourcePrefix = "") { - return new FilterBuilder(resourcePrefix); - } - - constructor( - private resourcePrefix = "", - private filters = "") { } +export function joinFilters(filters0?: string, filters1?: string) { + return [filters0, filters1].filter(s => s).join(","); +} - public addEqual(field: string, value?: string) { - return this.addCondition(field, "=", value); - } +export class FilterBuilder { + constructor(private filters = "") { } - public addLike(field: string, value?: string) { - return this.addCondition(field, "like", value, "%", "%"); + public addEqual(field: string, value?: string, resourcePrefix?: string) { + return this.addCondition(field, "=", value, "", "", resourcePrefix ); } - public addILike(field: string, value?: string) { - return this.addCondition(field, "ilike", value, "%", "%"); + public addLike(field: string, value?: string, resourcePrefix?: string) { + return this.addCondition(field, "like", value, "%", "%", resourcePrefix); } - public addIsA(field: string, value?: string | string[]) { - return this.addCondition(field, "is_a", value); + public addILike(field: string, value?: string, resourcePrefix?: string) { + return this.addCondition(field, "ilike", value, "%", "%", resourcePrefix); } - public addIn(field: string, value?: string | string[]) { - return this.addCondition(field, "in", value); + public addIsA(field: string, value?: string | string[], resourcePrefix?: string) { + return this.addCondition(field, "is_a", value, "", "", resourcePrefix); } - public concat(filterBuilder: FilterBuilder) { - return new FilterBuilder(this.resourcePrefix, this.filters + (this.filters && filterBuilder.filters ? "," : "") + filterBuilder.getFilters()); + public addIn(field: string, value?: string | string[], resourcePrefix?: string) { + return this.addCondition(field, "in", value, "", "", resourcePrefix); } public getFilters() { return this.filters; } - public serialize() { - return "[" + this.filters + "]"; - } - - private addCondition(field: string, cond: string, value?: string | string[], prefix: string = "", postfix: string = "") { + private addCondition(field: string, cond: string, value?: string | string[], prefix: string = "", postfix: string = "", resourcePrefix?: string) { if (value) { value = typeof value === "string" ? `"${prefix}${value}${postfix}"` : `["${value.join(`","`)}"]`; - const resourcePrefix = this.resourcePrefix - ? _.snakeCase(this.resourcePrefix) + "." + const resPrefix = resourcePrefix + ? _.snakeCase(resourcePrefix) + "." : ""; - this.filters += `${this.filters ? "," : ""}["${resourcePrefix}${_.snakeCase(field.toString())}","${cond}",${value}]`; + this.filters += `${this.filters ? "," : ""}["${resPrefix}${_.snakeCase(field)}","${cond}",${value}]`; } return this; } diff --git a/src/common/api/order-builder.test.ts b/src/common/api/order-builder.test.ts index f53bddb5..56b66f3b 100644 --- a/src/common/api/order-builder.test.ts +++ b/src/common/api/order-builder.test.ts @@ -6,22 +6,10 @@ import { OrderBuilder } from "./order-builder"; describe("OrderBuilder", () => { it("should build correct order query", () => { - const order = OrderBuilder - .create() + const order = new OrderBuilder() .addAsc("kind") .addDesc("modifiedAt") .getOrder(); expect(order).toEqual(["kind asc", "modified_at desc"]); }); - - it("should combine results with other builder", () => { - const order = OrderBuilder - .create() - .addAsc("kind") - .concat(OrderBuilder - .create("properties") - .addDesc("modifiedAt")) - .getOrder(); - expect(order).toEqual(["kind asc", "properties.modified_at desc"]); - }); }); diff --git a/src/common/api/order-builder.ts b/src/common/api/order-builder.ts index ed990541..196b0695 100644 --- a/src/common/api/order-builder.ts +++ b/src/common/api/order-builder.ts @@ -3,40 +3,28 @@ // SPDX-License-Identifier: AGPL-3.0 import * as _ from "lodash"; -import { Resource } from "../../models/resource"; +import { Resource } from "~/models/resource"; -export class OrderBuilder { - - static create(prefix?: string){ - return new OrderBuilder([], prefix); - } +export enum OrderDirection { ASC, DESC } - private constructor( - private order: string[] = [], - private prefix = ""){} +export class OrderBuilder { - private addRule (direction: string, attribute: keyof T) { - const prefix = this.prefix ? this.prefix + "." : ""; - const order = [...this.order, `${prefix}${_.snakeCase(attribute.toString())} ${direction}`]; - return new OrderBuilder(order, prefix); - } + constructor(private order: string[] = []) {} - addAsc(attribute: keyof T) { - return this.addRule("asc", attribute); + addOrder(direction: OrderDirection, attribute: keyof T, prefix?: string) { + this.order.push(`${prefix ? prefix + "." : ""}${_.snakeCase(attribute.toString())} ${direction === OrderDirection.ASC ? "asc" : "desc"}`); + return this; } - addDesc(attribute: keyof T) { - return this.addRule("desc", attribute); + addAsc(attribute: keyof T, prefix?: string) { + return this.addOrder(OrderDirection.ASC, attribute, prefix); } - concat(orderBuilder: OrderBuilder){ - return new OrderBuilder( - this.order.concat(orderBuilder.getOrder()), - this.prefix - ); + addDesc(attribute: keyof T, prefix?: string) { + return this.addOrder(OrderDirection.DESC, attribute, prefix); } getOrder() { - return this.order.slice(); + return this.order.join(","); } } diff --git a/src/services/collection-service/collection-service.ts b/src/services/collection-service/collection-service.ts index f60e81f1..1c8eb5e9 100644 --- a/src/services/collection-service/collection-service.ts +++ b/src/services/collection-service/collection-service.ts @@ -84,10 +84,10 @@ export class CollectionService extends CommonResourceService } uploadFiles(collectionUuid: string, files: File[], onProgress?: UploadProgress): Promise { - const filters = FilterBuilder.create() + const filters = new FilterBuilder() .addEqual("service_type", "proxy"); - return this.keepService.list({ filters }).then(data => { + return this.keepService.list({ filters: filters.getFilters() }).then(data => { if (data.items && data.items.length > 0) { const serviceHost = (data.items[0].serviceSslFlag ? "https://" : "http://") + diff --git a/src/services/favorite-service/favorite-order-builder.ts b/src/services/favorite-service/favorite-order-builder.ts deleted file mode 100644 index fc6cbdcf..00000000 --- a/src/services/favorite-service/favorite-order-builder.ts +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (C) The Arvados Authors. All rights reserved. -// -// SPDX-License-Identifier: AGPL-3.0 - -import { LinkResource } from "~/models/link"; -import { GroupContentsResource, GroupContentsResourcePrefix } from "../groups-service/groups-service"; -import { OrderBuilder } from "~/common/api/order-builder"; - -export class FavoriteOrderBuilder { - - static create( - linkOrder = OrderBuilder.create(), - contentOrder = OrderBuilder.create()) { - return new FavoriteOrderBuilder(linkOrder, contentOrder); - } - - private constructor( - private linkOrder: OrderBuilder, - private contentOrder: OrderBuilder - ) { } - - addAsc(attribute: "name") { - const linkOrder = this.linkOrder.addAsc(attribute); - const contentOrder = this.contentOrder - .concat(OrderBuilder.create(GroupContentsResourcePrefix.COLLECTION).addAsc(attribute)) - .concat(OrderBuilder.create(GroupContentsResourcePrefix.PROCESS).addAsc(attribute)) - .concat(OrderBuilder.create(GroupContentsResourcePrefix.PROJECT).addAsc(attribute)); - return FavoriteOrderBuilder.create(linkOrder, contentOrder); - } - - addDesc(attribute: "name") { - const linkOrder = this.linkOrder.addDesc(attribute); - const contentOrder = this.contentOrder - .concat(OrderBuilder.create(GroupContentsResourcePrefix.COLLECTION).addDesc(attribute)) - .concat(OrderBuilder.create(GroupContentsResourcePrefix.PROCESS).addDesc(attribute)) - .concat(OrderBuilder.create(GroupContentsResourcePrefix.PROJECT).addDesc(attribute)); - return FavoriteOrderBuilder.create(linkOrder, contentOrder); - } - - getLinkOrder() { - return this.linkOrder; - } - - getContentOrder() { - return this.contentOrder; - } - -} diff --git a/src/services/favorite-service/favorite-service.test.ts b/src/services/favorite-service/favorite-service.test.ts index de59ff8d..47211fed 100644 --- a/src/services/favorite-service/favorite-service.test.ts +++ b/src/services/favorite-service/favorite-service.test.ts @@ -38,8 +38,7 @@ describe("FavoriteService", () => { it("unmarks resource as favorite", async () => { const list = jest.fn().mockReturnValue(Promise.resolve({ items: [{ uuid: "linkUuid" }] })); - const filters = FilterBuilder - .create() + const filters = new FilterBuilder() .addEqual('tailUuid', "userUuid") .addEqual('headUuid', "resourceUuid") .addEqual('linkClass', LinkClass.STAR); @@ -56,12 +55,11 @@ describe("FavoriteService", () => { it("lists favorite resources", async () => { const list = jest.fn().mockReturnValue(Promise.resolve({ items: [{ headUuid: "headUuid" }] })); - const listFilters = FilterBuilder - .create() + const listFilters = new FilterBuilder() .addEqual('tailUuid', "userUuid") .addEqual('linkClass', LinkClass.STAR); const contents = jest.fn().mockReturnValue(Promise.resolve({ items: [{ uuid: "resourceUuid" }] })); - const contentFilters = FilterBuilder.create().addIn('uuid', ["headUuid"]); + const contentFilters = new FilterBuilder().addIn('uuid', ["headUuid"]); linkService.list = list; groupService.contents = contents; const favoriteService = new FavoriteService(linkService, groupService); @@ -76,8 +74,7 @@ describe("FavoriteService", () => { it("checks if resources are present in favorites", async () => { const list = jest.fn().mockReturnValue(Promise.resolve({ items: [{ headUuid: "foo" }] })); - const listFilters = FilterBuilder - .create() + const listFilters = new FilterBuilder() .addIn("headUuid", ["foo", "oof"]) .addEqual("tailUuid", "userUuid") .addEqual("linkClass", LinkClass.STAR); diff --git a/src/services/favorite-service/favorite-service.ts b/src/services/favorite-service/favorite-service.ts index d9488195..7a49c8cc 100644 --- a/src/services/favorite-service/favorite-service.ts +++ b/src/services/favorite-service/favorite-service.ts @@ -4,24 +4,23 @@ import { LinkService } from "../link-service/link-service"; import { GroupsService, GroupContentsResource } from "../groups-service/groups-service"; -import { LinkResource, LinkClass } from "~/models/link"; -import { FilterBuilder } from "~/common/api/filter-builder"; +import { LinkClass } from "~/models/link"; +import { FilterBuilder, joinFilters } from "~/common/api/filter-builder"; import { ListResults } from "~/common/api/common-resource-service"; -import { FavoriteOrderBuilder } from "./favorite-order-builder"; -import { OrderBuilder } from "~/common/api/order-builder"; export interface FavoriteListArguments { limit?: number; offset?: number; - filters?: FilterBuilder; - order?: FavoriteOrderBuilder; + filters?: string; + linkOrder?: string; + contentOrder?: string; } export class FavoriteService { constructor( private linkService: LinkService, private groupsService: GroupsService - ) { } + ) {} create(data: { userUuid: string; resource: { uuid: string; name: string } }) { return this.linkService.create({ @@ -36,36 +35,36 @@ export class FavoriteService { delete(data: { userUuid: string; resourceUuid: string; }) { return this.linkService .list({ - filters: FilterBuilder - .create() + filters: new FilterBuilder() .addEqual('tailUuid', data.userUuid) .addEqual('headUuid', data.resourceUuid) .addEqual('linkClass', LinkClass.STAR) + .getFilters() }) .then(results => Promise.all( results.items.map(item => this.linkService.delete(item.uuid)))); } - list(userUuid: string, { filters, limit, offset, order }: FavoriteListArguments = {}): Promise> { - const listFilter = FilterBuilder - .create() + list(userUuid: string, { filters, limit, offset, linkOrder, contentOrder }: FavoriteListArguments = {}): Promise> { + const listFilters = new FilterBuilder() .addEqual('tailUuid', userUuid) - .addEqual('linkClass', LinkClass.STAR); + .addEqual('linkClass', LinkClass.STAR) + .getFilters(); return this.linkService .list({ - filters: filters ? filters.concat(listFilter) : listFilter, + filters: joinFilters(filters, listFilters), limit, offset, - order: order ? order.getLinkOrder() : OrderBuilder.create() + order: linkOrder }) .then(results => { const uuids = results.items.map(item => item.headUuid); return this.groupsService.contents(userUuid, { limit, offset, - order: order ? order.getContentOrder() : OrderBuilder.create(), - filters: FilterBuilder.create().addIn('uuid', uuids), + order: contentOrder, + filters: new FilterBuilder().addIn('uuid', uuids).getFilters(), recursive: true }); }); @@ -74,11 +73,11 @@ export class FavoriteService { checkPresenceInFavorites(userUuid: string, resourceUuids: string[]): Promise> { return this.linkService .list({ - filters: FilterBuilder - .create() + filters: new FilterBuilder() .addIn("headUuid", resourceUuids) .addEqual("tailUuid", userUuid) .addEqual("linkClass", LinkClass.STAR) + .getFilters() }) .then(({ items }) => resourceUuids.reduce((results, uuid) => { const isFavorite = items.some(item => item.headUuid === uuid); diff --git a/src/services/groups-service/groups-service.ts b/src/services/groups-service/groups-service.ts index e4c31675..822c810e 100644 --- a/src/services/groups-service/groups-service.ts +++ b/src/services/groups-service/groups-service.ts @@ -4,8 +4,6 @@ import * as _ from "lodash"; import { CommonResourceService, ListResults } from "~/common/api/common-resource-service"; -import { FilterBuilder } from "~/common/api/filter-builder"; -import { OrderBuilder } from "~/common/api/order-builder"; import { AxiosInstance } from "axios"; import { GroupResource } from "~/models/group"; import { CollectionResource } from "~/models/collection"; @@ -15,8 +13,8 @@ import { ProcessResource } from "~/models/process"; export interface ContentsArguments { limit?: number; offset?: number; - order?: OrderBuilder; - filters?: FilterBuilder; + order?: string; + filters?: string; recursive?: boolean; } @@ -35,8 +33,8 @@ export class GroupsService extends Comm const { filters, order, ...other } = args; const params = { ...other, - filters: filters ? filters.serialize() : undefined, - order: order ? order.getOrder() : undefined + filters: filters ? `[${filters}]` : undefined, + order: order ? order : undefined }; return this.serverApi .get(this.resourceType + `${uuid}/contents/`, { diff --git a/src/services/project-service/project-service.test.ts b/src/services/project-service/project-service.test.ts index 688a476b..93063462 100644 --- a/src/services/project-service/project-service.test.ts +++ b/src/services/project-service/project-service.test.ts @@ -25,10 +25,9 @@ describe("CommonResourceService", () => { const resource = await projectService.list(); expect(axiosInstance.get).toHaveBeenCalledWith("/groups/", { params: { - filters: FilterBuilder - .create() + filters: new FilterBuilder() .addEqual("groupClass", "project") - .serialize() + .getFilters() } }); }); diff --git a/src/services/project-service/project-service.ts b/src/services/project-service/project-service.ts index 3ffaa35f..e916f3c0 100644 --- a/src/services/project-service/project-service.ts +++ b/src/services/project-service/project-service.ts @@ -6,7 +6,7 @@ import { GroupsService } from "../groups-service/groups-service"; import { ProjectResource } from "~/models/project"; import { GroupClass } from "~/models/group"; import { ListArguments } from "~/common/api/common-resource-service"; -import { FilterBuilder } from "~/common/api/filter-builder"; +import { FilterBuilder, joinFilters } from "~/common/api/filter-builder"; export class ProjectService extends GroupsService { @@ -18,18 +18,12 @@ export class ProjectService extends GroupsService { list(args: ListArguments = {}) { return super.list({ ...args, - filters: this.addProjectFilter(args.filters) + filters: joinFilters( + args.filters, + new FilterBuilder() + .addEqual("groupClass", GroupClass.PROJECT) + .getFilters() + ) }); } - - private addProjectFilter(filters?: FilterBuilder) { - return FilterBuilder - .create() - .concat(filters - ? filters - : FilterBuilder.create()) - .concat(FilterBuilder - .create() - .addEqual("groupClass", GroupClass.PROJECT)); - } } diff --git a/src/services/tag-service/tag-service.ts b/src/services/tag-service/tag-service.ts index 78fdceed..52e481a7 100644 --- a/src/services/tag-service/tag-service.ts +++ b/src/services/tag-service/tag-service.ts @@ -25,15 +25,15 @@ export class TagService { } list(uuid: string) { - const filters = FilterBuilder - .create() + const filters = new FilterBuilder() .addEqual("headUuid", uuid) .addEqual("tailUuid", TagTailType.COLLECTION) - .addEqual("linkClass", LinkClass.TAG); + .addEqual("linkClass", LinkClass.TAG) + .getFilters(); - const order = OrderBuilder - .create() - .addAsc('createdAt'); + const order = new OrderBuilder() + .addAsc('createdAt') + .getOrder(); return this.linkService .list({ filters, order }) diff --git a/src/store/favorite-panel/favorite-panel-middleware-service.ts b/src/store/favorite-panel/favorite-panel-middleware-service.ts index 65318410..76a10a71 100644 --- a/src/store/favorite-panel/favorite-panel-middleware-service.ts +++ b/src/store/favorite-panel/favorite-panel-middleware-service.ts @@ -3,17 +3,19 @@ // SPDX-License-Identifier: AGPL-3.0 import { DataExplorerMiddlewareService } from "../data-explorer/data-explorer-middleware-service"; -import { FavoritePanelFilter, FavoritePanelColumnNames } from "~/views/favorite-panel/favorite-panel"; +import { FavoritePanelColumnNames, FavoritePanelFilter } from "~/views/favorite-panel/favorite-panel"; import { RootState } from "../store"; import { DataColumns } from "~/components/data-table/data-table"; import { FavoritePanelItem, resourceToDataItem } from "~/views/favorite-panel/favorite-panel-item"; -import { FavoriteOrderBuilder } from "~/services/favorite-service/favorite-order-builder"; import { ServiceRepository } from "~/services/services"; import { SortDirection } from "~/components/data-table/data-column"; import { FilterBuilder } from "~/common/api/filter-builder"; import { checkPresenceInFavorites } from "../favorites/favorites-actions"; import { favoritePanelActions } from "./favorite-panel-action"; import { Dispatch, MiddlewareAPI } from "redux"; +import { OrderBuilder, OrderDirection } from "~/common/api/order-builder"; +import { LinkResource } from "~/models/link"; +import { GroupContentsResource, GroupContentsResourcePrefix } from "~/services/groups-service/groups-service"; export class FavoritePanelMiddlewareService extends DataExplorerMiddlewareService { constructor(private services: ServiceRepository, id: string) { @@ -24,24 +26,36 @@ export class FavoritePanelMiddlewareService extends DataExplorerMiddlewareServic const dataExplorer = api.getState().dataExplorer[this.getId()]; const columns = dataExplorer.columns as DataColumns; const sortColumn = dataExplorer.columns.find( - ({ sortDirection }) => sortDirection !== undefined && sortDirection !== "none" + c => c.sortDirection !== undefined && c.sortDirection !== "none" ); const typeFilters = getColumnFilters(columns, FavoritePanelColumnNames.TYPE); - const order = FavoriteOrderBuilder.create(); + + const linkOrder = new OrderBuilder(); + const contentOrder = new OrderBuilder(); + + if (sortColumn && sortColumn.name === FavoritePanelColumnNames.NAME) { + const direction = sortColumn.sortDirection === SortDirection.ASC + ? OrderDirection.ASC + : OrderDirection.DESC; + + linkOrder.addOrder(direction, "name"); + contentOrder + .addOrder(direction, "name", GroupContentsResourcePrefix.COLLECTION) + .addOrder(direction, "name", GroupContentsResourcePrefix.PROCESS) + .addOrder(direction, "name", GroupContentsResourcePrefix.PROJECT); + } + if (typeFilters.length > 0) { this.services.favoriteService .list(this.services.authService.getUuid()!, { limit: dataExplorer.rowsPerPage, offset: dataExplorer.page * dataExplorer.rowsPerPage, - order: sortColumn!.name === FavoritePanelColumnNames.NAME - ? sortColumn!.sortDirection === SortDirection.ASC - ? order.addDesc("name") - : order.addAsc("name") - : order, - filters: FilterBuilder - .create() + linkOrder: linkOrder.getOrder(), + contentOrder: contentOrder.getOrder(), + filters: new FilterBuilder() .addIsA("headUuid", typeFilters.map(filter => filter.type)) .addILike("name", dataExplorer.searchValue) + .getFilters() }) .then(response => { api.dispatch(favoritePanelActions.SET_ITEMS({ diff --git a/src/store/project-panel/project-panel-middleware-service.ts b/src/store/project-panel/project-panel-middleware-service.ts index cc5207b8..e46ef944 100644 --- a/src/store/project-panel/project-panel-middleware-service.ts +++ b/src/store/project-panel/project-panel-middleware-service.ts @@ -9,12 +9,13 @@ import { DataColumns } from "~/components/data-table/data-table"; import { ServiceRepository } from "~/services/services"; import { ProjectPanelItem, resourceToDataItem } from "~/views/project-panel/project-panel-item"; import { SortDirection } from "~/components/data-table/data-column"; -import { OrderBuilder } from "~/common/api/order-builder"; +import { OrderBuilder, OrderDirection } from "~/common/api/order-builder"; import { FilterBuilder } from "~/common/api/filter-builder"; -import { GroupContentsResourcePrefix, GroupContentsResource } from "~/services/groups-service/groups-service"; +import { GroupContentsResourcePrefix } from "~/services/groups-service/groups-service"; import { checkPresenceInFavorites } from "../favorites/favorites-actions"; import { projectPanelActions } from "./project-panel-action"; import { Dispatch, MiddlewareAPI } from "redux"; +import { ProjectResource } from "~/models/project"; export class ProjectPanelMiddlewareService extends DataExplorerMiddlewareService { constructor(private services: ServiceRepository, id: string) { @@ -27,8 +28,8 @@ export class ProjectPanelMiddlewareService extends DataExplorerMiddlewareService const columns = dataExplorer.columns as DataColumns; const typeFilters = getColumnFilters(columns, ProjectPanelColumnNames.TYPE); const statusFilters = getColumnFilters(columns, ProjectPanelColumnNames.STATUS); - const sortColumn = dataExplorer.columns.find(({ sortDirection }) => Boolean(sortDirection && sortDirection !== "none")); - const sortDirection = sortColumn && sortColumn.sortDirection === SortDirection.ASC ? SortDirection.ASC : SortDirection.DESC; + const sortColumn = dataExplorer.columns.find(c => c.sortDirection !== undefined && c.sortDirection !== "none"); + const sortDirection = sortColumn && sortColumn.sortDirection === SortDirection.ASC ? OrderDirection.ASC : OrderDirection.DESC; if (typeFilters.length > 0) { this.services.groupsService .contents(state.projects.currentItemId, { @@ -38,16 +39,14 @@ export class ProjectPanelMiddlewareService extends DataExplorerMiddlewareService ? sortColumn.name === ProjectPanelColumnNames.NAME ? getOrder("name", sortDirection) : getOrder("createdAt", sortDirection) - : OrderBuilder.create(), - filters: FilterBuilder - .create() - .concat(FilterBuilder - .create() - .addIsA("uuid", typeFilters.map(f => f.type))) - .concat(FilterBuilder - .create(GroupContentsResourcePrefix.PROCESS) - .addIn("state", statusFilters.map(f => f.type))) - .concat(getSearchFilter(dataExplorer.searchValue)) + : "", + filters: new FilterBuilder() + .addIsA("uuid", typeFilters.map(f => f.type)) + .addIn("state", statusFilters.map(f => f.type), GroupContentsResourcePrefix.PROCESS) + .addILike("name", dataExplorer.searchValue, GroupContentsResourcePrefix.COLLECTION) + .addILike("name", dataExplorer.searchValue, GroupContentsResourcePrefix.PROCESS) + .addILike("name", dataExplorer.searchValue, GroupContentsResourcePrefix.PROJECT) + .getFilters() }) .then(response => { api.dispatch(projectPanelActions.SET_ITEMS({ @@ -74,22 +73,9 @@ const getColumnFilters = (columns: DataColumns f.selected) : []; }; -const getOrder = (attribute: "name" | "createdAt", direction: SortDirection) => - [ - OrderBuilder.create(GroupContentsResourcePrefix.COLLECTION), - OrderBuilder.create(GroupContentsResourcePrefix.PROCESS), - OrderBuilder.create(GroupContentsResourcePrefix.PROJECT) - ].reduce((acc, b) => - acc.concat(direction === SortDirection.ASC - ? b.addAsc(attribute) - : b.addDesc(attribute)), OrderBuilder.create()); - -const getSearchFilter = (searchValue: string) => - searchValue - ? [ - FilterBuilder.create(GroupContentsResourcePrefix.COLLECTION), - FilterBuilder.create(GroupContentsResourcePrefix.PROCESS), - FilterBuilder.create(GroupContentsResourcePrefix.PROJECT)] - .reduce((acc, b) => - acc.concat(b.addILike("name", searchValue)), FilterBuilder.create()) - : FilterBuilder.create(); +const getOrder = (attribute: "name" | "createdAt", direction: OrderDirection) => + new OrderBuilder() + .addOrder(direction, attribute, GroupContentsResourcePrefix.COLLECTION) + .addOrder(direction, attribute, GroupContentsResourcePrefix.PROCESS) + .addOrder(direction, attribute, GroupContentsResourcePrefix.PROJECT) + .getOrder(); diff --git a/src/store/project/project-action.ts b/src/store/project/project-action.ts index bef50d11..3ba3e051 100644 --- a/src/store/project/project-action.ts +++ b/src/store/project/project-action.ts @@ -26,13 +26,13 @@ export const projectActions = unionize({ value: 'payload' }); -export const getProjectList = (parentUuid: string = '') => +export const getProjectList = (parentUuid: string = '') => (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { dispatch(projectActions.PROJECTS_REQUEST(parentUuid)); return services.projectService.list({ - filters: FilterBuilder - .create() + filters: new FilterBuilder() .addEqual("ownerUuid", parentUuid) + .getFilters() }).then(({ items: projects }) => { dispatch(projectActions.PROJECTS_SUCCESS({ projects, parentItemId: parentUuid })); dispatch(checkPresenceInFavorites(projects.map(project => project.uuid))); diff --git a/src/views-components/project-tree-picker/project-tree-picker.tsx b/src/views-components/project-tree-picker/project-tree-picker.tsx index e09d78ab..9143c47a 100644 --- a/src/views-components/project-tree-picker/project-tree-picker.tsx +++ b/src/views-components/project-tree-picker/project-tree-picker.tsx @@ -48,9 +48,9 @@ export const loadProjectTreePickerProjects = (id: string) => const ownerUuid = id.length === 0 ? services.authService.getUuid() || '' : id; - const filters = FilterBuilder - .create() - .addEqual('ownerUuid', ownerUuid); + const filters = new FilterBuilder() + .addEqual('ownerUuid', ownerUuid) + .getFilters(); const { items } = await services.projectService.list({ filters }); -- 2.30.2