[ARVADOS-WORKBENCH2] created: 1.1.4-600-g96b6bf5

Git user git at public.curoverse.com
Wed Aug 15 11:19:02 EDT 2018


        at  96b6bf5ac045e8b11e00a2cd73f6ecfbd7040cca (commit)


commit 96b6bf5ac045e8b11e00a2cd73f6ecfbd7040cca
Author: Daniel Kos <daniel.kos at contractors.roche.com>
Date:   Wed Aug 15 17:18:49 2018 +0200

    Simplify order and filter builder
    
    Arvados-DCO-1.1-Signed-off-by: Daniel Kos <daniel.kos at contractors.roche.com>

diff --git a/src/common/api/common-resource-service.ts b/src/common/api/common-resource-service.ts
index 36017f0..caa4d76 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<T extends Resource> {
         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 d129a80..de2ba4c 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 e5aab3a..b5558db 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 f53bddb..56b66f3 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 ed99054..196b069 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<T extends Resource = Resource> {
-
-    static create<T extends Resource = Resource>(prefix?: string){
-        return new OrderBuilder<T>([], prefix);
-    }
+export enum OrderDirection { ASC, DESC }
 
-    private constructor(
-        private order: string[] = [],
-        private prefix = ""){}
+export class OrderBuilder<T extends Resource = Resource> {
 
-    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<T>(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<T>(
-            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 f60e81f..1c8eb5e 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<CollectionResource>
     }
 
     uploadFiles(collectionUuid: string, files: File[], onProgress?: UploadProgress): Promise<CollectionResource | never> {
-        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 fc6cbdc..0000000
--- 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<LinkResource>(),
-        contentOrder = OrderBuilder.create<GroupContentsResource>()) {
-        return new FavoriteOrderBuilder(linkOrder, contentOrder);
-    }
-
-    private constructor(
-        private linkOrder: OrderBuilder<LinkResource>,
-        private contentOrder: OrderBuilder<GroupContentsResource>
-    ) { }
-
-    addAsc(attribute: "name") {
-        const linkOrder = this.linkOrder.addAsc(attribute);
-        const contentOrder = this.contentOrder
-            .concat(OrderBuilder.create<GroupContentsResource>(GroupContentsResourcePrefix.COLLECTION).addAsc(attribute))
-            .concat(OrderBuilder.create<GroupContentsResource>(GroupContentsResourcePrefix.PROCESS).addAsc(attribute))
-            .concat(OrderBuilder.create<GroupContentsResource>(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<GroupContentsResource>(GroupContentsResourcePrefix.COLLECTION).addDesc(attribute))
-            .concat(OrderBuilder.create<GroupContentsResource>(GroupContentsResourcePrefix.PROCESS).addDesc(attribute))
-            .concat(OrderBuilder.create<GroupContentsResource>(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 de59ff8..47211fe 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 d948819..7a49c8c 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<ListResults<GroupContentsResource>> {
-        const listFilter = FilterBuilder
-            .create()
+    list(userUuid: string, { filters, limit, offset, linkOrder, contentOrder }: FavoriteListArguments = {}): Promise<ListResults<GroupContentsResource>> {
+        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<LinkResource>()
+                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<GroupContentsResource>(),
-                    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<Record<string, boolean>> {
         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 e4c3167..822c810 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<T extends GroupResource = GroupResource> 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 688a476..9306346 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 3ffaa35..e916f3c 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<ProjectResource> {
 
@@ -18,18 +18,12 @@ export class ProjectService extends GroupsService<ProjectResource> {
     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 78fdcee..52e481a 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<TagResource>()
-            .addAsc('createdAt');
+        const order = new OrderBuilder<TagResource>()
+            .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 6531841..76a10a7 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<FavoritePanelItem, FavoritePanelFilter>;
         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<LinkResource>();
+        const contentOrder = new OrderBuilder<GroupContentsResource>();
+
+        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 cc5207b..e46ef94 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<ProjectPanelItem, ProjectPanelFilter>;
         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<ProjectPanelItem, ProjectPanelFil
     return column && column.filters ? column.filters.filter(f => f.selected) : [];
 };
 
-const getOrder = (attribute: "name" | "createdAt", direction: SortDirection) =>
-    [
-        OrderBuilder.create<GroupContentsResource>(GroupContentsResourcePrefix.COLLECTION),
-        OrderBuilder.create<GroupContentsResource>(GroupContentsResourcePrefix.PROCESS),
-        OrderBuilder.create<GroupContentsResource>(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<ProjectResource>()
+        .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 bef50d1..3ba3e05 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<any>(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 e09d78a..9143c47 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 });
 

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list