From 4652d6baf3d0424d091e8e9e42660447f6259bd5 Mon Sep 17 00:00:00 2001 From: Michal Klobukowski Date: Tue, 24 Jul 2018 13:26:51 +0200 Subject: [PATCH] Add ordering of favorite list results Feature #13753 Arvados-DCO-1.1-Signed-off-by: Michal Klobukowski --- .../favorite-order-builder.ts | 48 +++++++++++++++++++ .../favorite-service/favorite-service.ts | 18 ++++--- .../favorite-panel-middleware.ts | 26 ++++++++++ 3 files changed, 85 insertions(+), 7 deletions(-) create mode 100644 src/services/favorite-service/favorite-order-builder.ts diff --git a/src/services/favorite-service/favorite-order-builder.ts b/src/services/favorite-service/favorite-order-builder.ts new file mode 100644 index 0000000000..33214a0dc8 --- /dev/null +++ b/src/services/favorite-service/favorite-order-builder.ts @@ -0,0 +1,48 @@ +// 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; + } + +} \ No newline at end of file diff --git a/src/services/favorite-service/favorite-service.ts b/src/services/favorite-service/favorite-service.ts index d25ef3d5f6..8da6eec309 100644 --- a/src/services/favorite-service/favorite-service.ts +++ b/src/services/favorite-service/favorite-service.ts @@ -7,13 +7,14 @@ import { GroupsService, GroupContentsResource } from "../groups-service/groups-s import { LinkResource, LinkClass } from "../../models/link"; import { FilterBuilder } from "../../common/api/filter-builder"; import { ListArguments, ListResults } from "../../common/api/common-resource-service"; +import { FavoriteOrderBuilder } from "./favorite-order-builder"; import { OrderBuilder } from "../../common/api/order-builder"; -export interface FavoriteListArguments extends ListArguments { +export interface FavoriteListArguments { limit?: number; offset?: number; filters?: FilterBuilder; - order?: OrderBuilder; + order?: FavoriteOrderBuilder; } export class FavoriteService { @@ -45,7 +46,7 @@ export class FavoriteService { results.items.map(item => this.linkService.delete(item.uuid)))); } - list(userUuid: string, args: FavoriteListArguments = {}): Promise> { + list(userUuid: string, { filters, limit, offset, order }: FavoriteListArguments = {}): Promise> { const listFilter = FilterBuilder .create() .addEqual('tailUuid', userUuid) @@ -53,14 +54,17 @@ export class FavoriteService { return this.linkService .list({ - ...args, - filters: args.filters ? args.filters.concat(listFilter) : listFilter + filters: filters ? filters.concat(listFilter) : listFilter, + limit, + offset, + order: order ? order.getLinkOrder() : OrderBuilder.create() }) .then(results => { const uuids = results.items.map(item => item.headUuid); return this.groupsService.contents(userUuid, { - limit: args.limit, - offset: args.offset, + limit, + offset, + order: order ? order.getContentOrder() : OrderBuilder.create(), filters: FilterBuilder.create().addIn('uuid', uuids), recursive: true }); diff --git a/src/store/favorite-panel/favorite-panel-middleware.ts b/src/store/favorite-panel/favorite-panel-middleware.ts index c5020e8920..0ce13b461c 100644 --- a/src/store/favorite-panel/favorite-panel-middleware.ts +++ b/src/store/favorite-panel/favorite-panel-middleware.ts @@ -18,6 +18,10 @@ import { import { FavoritePanelItem, resourceToDataItem } from "../../views/favorite-panel/favorite-panel-item"; import { LinkResource } from "../../models/link"; import { checkPresenceInFavorites } from "../favorites/favorites-actions"; +import { OrderBuilder } from "../../common/api/order-builder"; +import { SortDirection } from "../../components/data-table/data-column"; +import { GroupContentsResource, GroupContentsResourcePrefix } from "../../services/groups-service/groups-service"; +import { FavoriteOrderBuilder } from "../../services/favorite-service/favorite-order-builder"; export const favoritePanelMiddleware: Middleware = store => next => { next(dataExplorerActions.SET_COLUMNS({ id: FAVORITE_PANEL_ID, columns })); @@ -54,12 +58,19 @@ export const favoritePanelMiddleware: Middleware = store => next => { const state = store.getState() as RootState; const dataExplorer = getDataExplorer(state.dataExplorer, FAVORITE_PANEL_ID); const columns = dataExplorer.columns as DataColumns; + const sortColumn = dataExplorer.columns.find(({ sortDirection }) => Boolean(sortDirection && sortDirection !== "none")); const typeFilters = getColumnFilters(columns, FavoritePanelColumnNames.TYPE); + const order = FavoriteOrderBuilder.create(); if (typeFilters.length > 0) { favoriteService .list(state.projects.currentItemId, { 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() .addIsA("headUuid", typeFilters.map(filter => filter.type)) @@ -90,6 +101,21 @@ export const favoritePanelMiddleware: Middleware = store => next => { }; }; +const getOrder = (direction: SortDirection) => { + const order = OrderBuilder.create(); + const addRule = (builder: OrderBuilder, direction: SortDirection) => + direction === SortDirection.Asc + ? builder.addAsc("name") + : builder.addDesc("name"); + + return [ + OrderBuilder.create(GroupContentsResourcePrefix.Collection), + OrderBuilder.create(GroupContentsResourcePrefix.Process), + OrderBuilder.create(GroupContentsResourcePrefix.Project) + ].reduce((acc, b) => + acc.concat(addRule(b, direction)), addRule(OrderBuilder.create(), direction)); +}; + const getColumnFilters = (columns: DataColumns, columnName: string) => { const column = columns.find(c => c.name === columnName); return column && column.filters ? column.filters.filter(f => f.selected) : []; -- 2.30.2