15012: Adds process status filtering to all_processes page.
authorLucas Di Pentima <lucas@di-pentima.com.ar>
Tue, 21 Jan 2020 17:56:15 +0000 (14:56 -0300)
committerLucas Di Pentima <lucas@di-pentima.com.ar>
Tue, 21 Jan 2020 17:56:15 +0000 (14:56 -0300)
Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima <lucas@di-pentima.com.ar>

src/store/all-processes-panel/all-processes-panel-middleware-service.ts
src/store/resource-type-filters/resource-type-filters.ts
src/store/subprocess-panel/subprocess-panel-middleware-service.ts
src/views/all-processes-panel/all-processes-panel.tsx

index be8c9c49ec63e5abed043886fddf1161070fb455..43432cfd6edf2180384093fed909ce64784a4247 100644 (file)
@@ -2,17 +2,19 @@
 //
 // SPDX-License-Identifier: AGPL-3.0
 
 //
 // SPDX-License-Identifier: AGPL-3.0
 
-import { DataExplorerMiddlewareService } from "~/store/data-explorer/data-explorer-middleware-service";
+import { DataExplorerMiddlewareService, dataExplorerToListParams, getDataExplorerColumnFilters } from "~/store/data-explorer/data-explorer-middleware-service";
 import { RootState } from "../store";
 import { ServiceRepository } from "~/services/services";
 import { RootState } from "../store";
 import { ServiceRepository } from "~/services/services";
-import { FilterBuilder } from "~/services/api/filter-builder";
+import { FilterBuilder, joinFilters } from "~/services/api/filter-builder";
 import { allProcessesPanelActions } from "./all-processes-panel-action";
 import { Dispatch, MiddlewareAPI } from "redux";
 import { resourcesActions } from "~/store/resources/resources-actions";
 import { snackbarActions, SnackbarKind } from '~/store/snackbar/snackbar-actions';
 import { progressIndicatorActions } from '~/store/progress-indicator/progress-indicator-actions.ts';
 import { allProcessesPanelActions } from "./all-processes-panel-action";
 import { Dispatch, MiddlewareAPI } from "redux";
 import { resourcesActions } from "~/store/resources/resources-actions";
 import { snackbarActions, SnackbarKind } from '~/store/snackbar/snackbar-actions';
 import { progressIndicatorActions } from '~/store/progress-indicator/progress-indicator-actions.ts';
-import { getDataExplorer } from "~/store/data-explorer/data-explorer-reducer";
+import { getDataExplorer, DataExplorer } from "~/store/data-explorer/data-explorer-reducer";
 import { loadMissingProcessesInformation } from "~/store/project-panel/project-panel-middleware-service";
 import { loadMissingProcessesInformation } from "~/store/project-panel/project-panel-middleware-service";
+import { DataColumns } from "~/components/data-table/data-table";
+import { ProcessStatusFilter, buildProcessStatusFilters } from "../resource-type-filters/resource-type-filters";
 
 export class AllProcessesPanelMiddlewareService extends DataExplorerMiddlewareService {
     constructor(private services: ServiceRepository, id: string) {
 
 export class AllProcessesPanelMiddlewareService extends DataExplorerMiddlewareService {
     constructor(private services: ServiceRepository, id: string) {
@@ -26,11 +28,8 @@ export class AllProcessesPanelMiddlewareService extends DataExplorerMiddlewareSe
         } else {
             try {
                 api.dispatch(progressIndicatorActions.START_WORKING(this.getId()));
         } else {
             try {
                 api.dispatch(progressIndicatorActions.START_WORKING(this.getId()));
-                const processItems: any = await this.services.containerRequestService.list({
-                    filters: new FilterBuilder()
-                        .addILike("name", dataExplorer.searchValue)
-                        .getFilters()
-                });
+                const processItems = await this.services.containerRequestService.list(
+                    { ...getParams(dataExplorer) });
 
                 api.dispatch(progressIndicatorActions.PERSIST_STOP_WORKING(this.getId()));
                 api.dispatch(resourcesActions.SET_RESOURCES(processItems.items));
 
                 api.dispatch(progressIndicatorActions.PERSIST_STOP_WORKING(this.getId()));
                 api.dispatch(resourcesActions.SET_RESOURCES(processItems.items));
@@ -41,7 +40,7 @@ export class AllProcessesPanelMiddlewareService extends DataExplorerMiddlewareSe
                     page: Math.floor(processItems.offset / processItems.limit),
                     rowsPerPage: processItems.limit
                 }));
                     page: Math.floor(processItems.offset / processItems.limit),
                     rowsPerPage: processItems.limit
                 }));
-            } catch (e) {
+            } catch {
                 api.dispatch(progressIndicatorActions.PERSIST_STOP_WORKING(this.getId()));
                 api.dispatch(allProcessesPanelActions.SET_ITEMS({
                     items: [],
                 api.dispatch(progressIndicatorActions.PERSIST_STOP_WORKING(this.getId()));
                 api.dispatch(allProcessesPanelActions.SET_ITEMS({
                     items: [],
@@ -55,6 +54,27 @@ export class AllProcessesPanelMiddlewareService extends DataExplorerMiddlewareSe
     }
 }
 
     }
 }
 
+const getParams = ( dataExplorer: DataExplorer ) => ({
+    ...dataExplorerToListParams(dataExplorer),
+    filters: getFilters(dataExplorer)
+});
+
+const getFilters = ( dataExplorer: DataExplorer ) => {
+    const columns = dataExplorer.columns as DataColumns<string>;
+    const statusColumnFilters = getDataExplorerColumnFilters(columns, 'Status');
+    const activeStatusFilter = Object.keys(statusColumnFilters).find(
+        filterName => statusColumnFilters[filterName].selected
+    ) || ProcessStatusFilter.ALL;
+
+    const nameFilter = new FilterBuilder().addILike("name", dataExplorer.searchValue).getFilters();
+    const statusFilter = buildProcessStatusFilters(new FilterBuilder(), activeStatusFilter).getFilters();
+
+    return joinFilters(
+        nameFilter,
+        statusFilter
+    );
+};
+
 const allProcessesPanelDataExplorerIsNotSet = () =>
     snackbarActions.OPEN_SNACKBAR({
         message: 'All Processes panel is not ready.',
 const allProcessesPanelDataExplorerIsNotSet = () =>
     snackbarActions.OPEN_SNACKBAR({
         message: 'All Processes panel is not ready.',
index 4ee9c5f32b313fc16e4a04d230f2a09d3cacfee9..6766bfca10eb2a075fe97b88b40970bd5f65fb3f 100644 (file)
@@ -213,3 +213,27 @@ export const serializeSimpleObjectTypeFilters = (filters: Tree<DataTableFilterIt
         .map(f => f.id)
         .map(objectTypeToResourceKind);
 };
         .map(f => f.id)
         .map(objectTypeToResourceKind);
 };
+
+export const buildProcessStatusFilters = ( fb:FilterBuilder, activeStatusFilter:string ): FilterBuilder => {
+    switch (activeStatusFilter) {
+        case ProcessStatusFilter.COMPLETED: {
+            fb.addEqual('container.state', 'Complete');
+            fb.addEqual('container.exit_code', '0');
+            break;
+        }
+        case ProcessStatusFilter.FAILED: {
+            fb.addEqual('container.state', 'Complete');
+            fb.addDistinct('container.exit_code', '0');
+            break;
+        }
+        case ProcessStatusFilter.CANCELLED:
+        case ProcessStatusFilter.FAILED:
+        case ProcessStatusFilter.LOCKED:
+        case ProcessStatusFilter.QUEUED:
+        case ProcessStatusFilter.RUNNING: {
+            fb.addEqual('container.state', activeStatusFilter);
+            break;
+        }
+    }
+    return fb;
+};
\ No newline at end of file
index 4363bb7c280fb16a9f830d749bbdd8331190a5e1..6fdb8de24ea40a34bf1948707c1b86dbe1b73cc8 100644 (file)
@@ -20,7 +20,7 @@ import { SubprocessPanelColumnNames } from '~/views/subprocess-panel/subprocess-
 import { FilterBuilder, joinFilters } from '~/services/api/filter-builder';
 import { subprocessPanelActions } from './subprocess-panel-actions';
 import { DataColumns } from '~/components/data-table/data-table';
 import { FilterBuilder, joinFilters } from '~/services/api/filter-builder';
 import { subprocessPanelActions } from './subprocess-panel-actions';
 import { DataColumns } from '~/components/data-table/data-table';
-import { ProcessStatusFilter } from '../resource-type-filters/resource-type-filters';
+import { ProcessStatusFilter, buildProcessStatusFilters } from '../resource-type-filters/resource-type-filters';
 import { ContainerRequestResource } from '~/models/container-request';
 import { progressIndicatorActions } from '../progress-indicator/progress-indicator-actions';
 import { loadMissingProcessesInformation } from '../project-panel/project-panel-middleware-service';
 import { ContainerRequestResource } from '~/models/container-request';
 import { progressIndicatorActions } from '../progress-indicator/progress-indicator-actions';
 import { loadMissingProcessesInformation } from '../project-panel/project-panel-middleware-service';
@@ -85,31 +85,11 @@ export const getFilters = (
         const statusColumnFilters = getDataExplorerColumnFilters(columns, 'Status');
         const activeStatusFilter = Object.keys(statusColumnFilters).find(
             filterName => statusColumnFilters[filterName].selected
         const statusColumnFilters = getDataExplorerColumnFilters(columns, 'Status');
         const activeStatusFilter = Object.keys(statusColumnFilters).find(
             filterName => statusColumnFilters[filterName].selected
-        );
+        ) || ProcessStatusFilter.ALL;
 
         // Get all the subprocess' container requests and containers.
         const fb = new FilterBuilder().addEqual('requesting_container_uuid', parentContainerRequest.containerUuid);
 
         // Get all the subprocess' container requests and containers.
         const fb = new FilterBuilder().addEqual('requesting_container_uuid', parentContainerRequest.containerUuid);
-        switch (activeStatusFilter) {
-            case ProcessStatusFilter.COMPLETED: {
-                fb.addEqual('container.state', 'Complete');
-                fb.addEqual('container.exit_code', '0');
-                break;
-            }
-            case ProcessStatusFilter.FAILED: {
-                fb.addEqual('container.state', 'Complete');
-                fb.addDistinct('container.exit_code', '0');
-                break;
-            }
-            case ProcessStatusFilter.CANCELLED:
-            case ProcessStatusFilter.FAILED:
-            case ProcessStatusFilter.LOCKED:
-            case ProcessStatusFilter.QUEUED:
-            case ProcessStatusFilter.RUNNING: {
-                fb.addEqual('container.state', activeStatusFilter);
-                break;
-            }
-        }
-        const statusFilters = fb.getFilters();
+        const statusFilters = buildProcessStatusFilters(fb, activeStatusFilter).getFilters();
 
         const nameFilters = dataExplorer.searchValue
             ? new FilterBuilder()
 
         const nameFilters = dataExplorer.searchValue
             ? new FilterBuilder()
index 4bd4597382efa46c795a4472d45b741e98ae2063..79575c74626455579ee60d44c75e420209b2c6ef 100644 (file)
@@ -28,7 +28,7 @@ import { ContainerRequestState } from "~/models/container-request";
 import { RootState } from '~/store/store';
 import { DataTableDefaultView } from '~/components/data-table-default-view/data-table-default-view';
 import { createTree } from '~/models/tree';
 import { RootState } from '~/store/store';
 import { DataTableDefaultView } from '~/components/data-table-default-view/data-table-default-view';
 import { createTree } from '~/models/tree';
-import { getSimpleObjectTypeFilters } from '~/store/resource-type-filters/resource-type-filters';
+import { getSimpleObjectTypeFilters, getInitialProcessStatusFilters } from '~/store/resource-type-filters/resource-type-filters';
 
 type CssRules = "toolbar" | "button";
 
 
 type CssRules = "toolbar" | "button";
 
@@ -67,7 +67,8 @@ export const allProcessesPanelColumns: DataColumns<string> = [
         name: AllProcessesPanelColumnNames.STATUS,
         selected: true,
         configurable: true,
         name: AllProcessesPanelColumnNames.STATUS,
         selected: true,
         configurable: true,
-        filters: createTree(),
+        mutuallyExclusiveFilters: true,
+        filters: getInitialProcessStatusFilters(),
         render: uuid => <ProcessStatus uuid={uuid} />
     },
     {
         render: uuid => <ProcessStatus uuid={uuid} />
     },
     {