From 0b5e5e9784493070c16012a7b60409df9ca69609 Mon Sep 17 00:00:00 2001
From: Ken Hibino <ken.hibino7@gmail.com>
Date: Wed, 30 Mar 2022 18:34:15 -0700
Subject: [PATCH] Add redux actions/reducer for aggregating task actions

---
 ui/src/actions/tasksActions.ts              | 201 +++++++++++++++++++-
 ui/src/components/AggregatingTasksTable.tsx |  15 +-
 ui/src/reducers/tasksReducer.ts             |  41 ++++
 3 files changed, 254 insertions(+), 3 deletions(-)

diff --git a/ui/src/actions/tasksActions.ts b/ui/src/actions/tasksActions.ts
index 4334fff..de2b510 100644
--- a/ui/src/actions/tasksActions.ts
+++ b/ui/src/actions/tasksActions.ts
@@ -50,6 +50,7 @@ import {
   archiveAllPendingTasks,
   TaskInfo,
   getTaskInfo,
+  deleteAllAggregatingTasks,
 } from "../api";
 import { Dispatch } from "redux";
 import { toErrorString, toErrorStringWithHttpStatus } from "../utils";
@@ -235,6 +236,42 @@ export const BATCH_DELETE_COMPLETED_TASKS_SUCCESS =
   "BATCH_DELETE_COMPLETED_TASKS_SUCCESS";
 export const BATCH_DELETE_COMPLETED_TASKS_ERROR =
   "BATCH_DELETE_COMPLETED_TASKS_ERROR";
+export const BATCH_RUN_AGGREGATING_TASKS_BEGIN =
+  "BATCH_RUN_AGGREGATING_TASKS_BEGIN";
+export const BATCH_RUN_AGGREGATING_TASKS_SUCCESS =
+  "BATCH_RUN_AGGREGATING_TASKS_SUCCESS";
+export const BATCH_RUN_AGGREGATING_TASKS_ERROR =
+  "BATCH_RUN_AGGREGATING_TASKS_ERROR";
+export const BATCH_ARCHIVE_AGGREGATING_TASKS_BEGIN =
+  "BATCH_ARCHIVE_AGGREGATING_TASKS_BEGIN";
+export const BATCH_ARCHIVE_AGGREGATING_TASKS_SUCCESS =
+  "BATCH_ARCHIVE_AGGREGATING_TASKS_SUCCESS";
+export const BATCH_ARCHIVE_AGGREGATING_TASKS_ERROR =
+  "BATCH_RUN_AGGREGATING_TASKS_ERROR";
+export const BATCH_DELETE_AGGREGATING_TASKS_BEGIN =
+  "BATCH_DELETE_AGGREGATING_TASKS_BEGIN";
+export const BATCH_DELETE_AGGREGATING_TASKS_SUCCESS =
+  "BATCH_DELETE_AGGREGATING_TASKS_SUCCESS";
+export const BATCH_DELETE_AGGREGATING_TASKS_ERROR =
+  "BATCH_DELETE_AGGREGATING_TASKS_ERROR";
+export const RUN_ALL_AGGREGATING_TASKS_BEGIN =
+  "RUN_ALL_AGGREGATING_TASKS_BEGIN";
+export const RUN_ALL_AGGREGATING_TASKS_SUCCESS =
+  "RUN_ALL_AGGREGATING_TASKS_SUCCESS";
+export const RUN_ALL_AGGREGATING_TASKS_ERROR =
+  "RUN_ALL_AGGREGATING_TASKS_ERROR";
+export const ARCHIVE_ALL_AGGREGATING_TASKS_BEGIN =
+  "ARCHIVE_ALL_AGGREGATING_TASKS_BEGIN";
+export const ARCHIVE_ALL_AGGREGATING_TASKS_SUCCESS =
+  "ARCHIVE_ALL_AGGREGATING_TASKS_SUCCESS";
+export const ARCHIVE_ALL_AGGREGATING_TASKS_ERROR =
+  "ARCHIVE_ALL_AGGREGATING_TASKS_ERROR";
+export const DELETE_ALL_AGGREGATING_TASKS_BEGIN =
+  "DELETE_ALL_AGGREGATING_TASKS_BEGIN";
+export const DELETE_ALL_AGGREGATING_TASKS_SUCCESS =
+  "DELETE_ALL_AGGREGATING_TASKS_SUCCESS";
+export const DELETE_ALL_AGGREGATING_TASKS_ERROR =
+  "DELETE_ALL_AGGREGATING_TASKS_ERROR";
 
 interface GetTaskInfoBeginAction {
   type: typeof GET_TASK_INFO_BEGIN;
@@ -1025,6 +1062,124 @@ interface DeleteAllCompletedTasksErrorAction {
   error: string;
 }
 
+interface BatchDeleteAggregatingTasksBeginAction {
+  type: typeof BATCH_DELETE_AGGREGATING_TASKS_BEGIN;
+  queue: string;
+  taskIds: string[];
+}
+
+interface BatchDeleteAggregatingTasksSuccessAction {
+  type: typeof BATCH_DELETE_AGGREGATING_TASKS_SUCCESS;
+  queue: string;
+  payload: BatchDeleteTasksResponse;
+}
+
+interface BatchDeleteAggregatingTasksErrorAction {
+  type: typeof BATCH_DELETE_AGGREGATING_TASKS_ERROR;
+  queue: string;
+  taskIds: string[];
+  error: string;
+}
+
+interface BatchRunAggregatingTasksBeginAction {
+  type: typeof BATCH_RUN_AGGREGATING_TASKS_BEGIN;
+  queue: string;
+  taskIds: string[];
+}
+
+interface BatchRunAggregatingTasksSuccessAction {
+  type: typeof BATCH_RUN_AGGREGATING_TASKS_SUCCESS;
+  queue: string;
+  payload: BatchRunTasksResponse;
+}
+
+interface BatchRunAggregatingTasksErrorAction {
+  type: typeof BATCH_RUN_AGGREGATING_TASKS_ERROR;
+  queue: string;
+  taskIds: string[];
+  error: string;
+}
+
+interface RunAllAggregatingTasksBeginAction {
+  type: typeof RUN_ALL_AGGREGATING_TASKS_BEGIN;
+  queue: string;
+  group: string;
+}
+
+interface RunAllAggregatingTasksSuccessAction {
+  type: typeof RUN_ALL_AGGREGATING_TASKS_SUCCESS;
+  queue: string;
+  group: string;
+}
+
+interface RunAllAggregatingTasksErrorAction {
+  type: typeof RUN_ALL_AGGREGATING_TASKS_ERROR;
+  queue: string;
+  group: string;
+  error: string;
+}
+
+interface BatchArchiveAggregatingTasksBeginAction {
+  type: typeof BATCH_ARCHIVE_AGGREGATING_TASKS_BEGIN;
+  queue: string;
+  group: string;
+  taskIds: string[];
+}
+
+interface BatchArchiveAggregatingTasksSuccessAction {
+  type: typeof BATCH_ARCHIVE_AGGREGATING_TASKS_SUCCESS;
+  queue: string;
+  group: string;
+  payload: BatchArchiveTasksResponse;
+}
+
+interface BatchArchiveAggregatingTasksErrorAction {
+  type: typeof BATCH_ARCHIVE_AGGREGATING_TASKS_ERROR;
+  queue: string;
+  group: string;
+  taskIds: string[];
+  error: string;
+}
+
+interface ArchiveAllAggregatingTasksBeginAction {
+  type: typeof ARCHIVE_ALL_AGGREGATING_TASKS_BEGIN;
+  queue: string;
+  group: string;
+}
+
+interface ArchiveAllAggregatingTasksSuccessAction {
+  type: typeof ARCHIVE_ALL_AGGREGATING_TASKS_SUCCESS;
+  queue: string;
+  group: string;
+}
+
+interface ArchiveAllAggregatingTasksErrorAction {
+  type: typeof ARCHIVE_ALL_AGGREGATING_TASKS_ERROR;
+  queue: string;
+  group: string;
+  error: string;
+}
+
+interface DeleteAllAggregatingTasksBeginAction {
+  type: typeof DELETE_ALL_AGGREGATING_TASKS_BEGIN;
+  queue: string;
+  group: string;
+}
+
+interface DeleteAllAggregatingTasksSuccessAction {
+  type: typeof DELETE_ALL_AGGREGATING_TASKS_SUCCESS;
+  queue: string;
+  group: string;
+  deleted: number;
+}
+
+interface DeleteAllAggregatingTasksErrorAction {
+  type: typeof DELETE_ALL_AGGREGATING_TASKS_ERROR;
+  queue: string;
+  group: string;
+  error: string;
+}
+
 // Union of all tasks related action types.
 export type TasksActionTypes =
   | GetTaskInfoBeginAction
@@ -1158,7 +1313,25 @@ export type TasksActionTypes =
   | BatchDeleteCompletedTasksErrorAction
   | DeleteAllCompletedTasksBeginAction
   | DeleteAllCompletedTasksSuccessAction
-  | DeleteAllCompletedTasksErrorAction;
+  | DeleteAllCompletedTasksErrorAction
+  | BatchDeleteAggregatingTasksBeginAction
+  | BatchDeleteAggregatingTasksSuccessAction
+  | BatchDeleteAggregatingTasksErrorAction
+  | BatchRunAggregatingTasksBeginAction
+  | BatchRunAggregatingTasksSuccessAction
+  | BatchRunAggregatingTasksErrorAction
+  | RunAllAggregatingTasksBeginAction
+  | RunAllAggregatingTasksSuccessAction
+  | RunAllAggregatingTasksErrorAction
+  | BatchArchiveAggregatingTasksBeginAction
+  | BatchArchiveAggregatingTasksSuccessAction
+  | BatchArchiveAggregatingTasksErrorAction
+  | ArchiveAllAggregatingTasksBeginAction
+  | ArchiveAllAggregatingTasksSuccessAction
+  | ArchiveAllAggregatingTasksErrorAction
+  | DeleteAllAggregatingTasksBeginAction
+  | DeleteAllAggregatingTasksSuccessAction
+  | DeleteAllAggregatingTasksErrorAction;
 
 export function getTaskInfoAsync(qname: string, id: string) {
   return async (dispatch: Dispatch<TasksActionTypes>) => {
@@ -1784,6 +1957,32 @@ export function deleteAllPendingTasksAsync(queue: string) {
   };
 }
 
+export function deleteAllAggregatingTasksAsync(queue: string, group: string) {
+  return async (dispatch: Dispatch<TasksActionTypes>) => {
+    dispatch({ type: DELETE_ALL_AGGREGATING_TASKS_BEGIN, queue, group });
+    try {
+      const response = await deleteAllAggregatingTasks(queue, group);
+      dispatch({
+        type: DELETE_ALL_AGGREGATING_TASKS_SUCCESS,
+        deleted: response.deleted,
+        queue,
+        group,
+      });
+    } catch (error) {
+      console.error(
+        "deleteAllAggregatingTasksAsync: ",
+        toErrorStringWithHttpStatus(error)
+      );
+      dispatch({
+        type: DELETE_ALL_AGGREGATING_TASKS_ERROR,
+        error: toErrorString(error),
+        queue,
+        group,
+      });
+    }
+  };
+}
+
 export function deleteAllScheduledTasksAsync(queue: string) {
   return async (dispatch: Dispatch<TasksActionTypes>) => {
     dispatch({ type: DELETE_ALL_SCHEDULED_TASKS_BEGIN, queue });
diff --git a/ui/src/components/AggregatingTasksTable.tsx b/ui/src/components/AggregatingTasksTable.tsx
index e34bc5c..9fbe216 100644
--- a/ui/src/components/AggregatingTasksTable.tsx
+++ b/ui/src/components/AggregatingTasksTable.tsx
@@ -34,7 +34,10 @@ import { TableColumn } from "../types/table";
 import TablePaginationActions, {
   rowsPerPageOptions,
 } from "./TablePaginationActions";
-import { listAggregatingTasksAsync } from "../actions/tasksActions";
+import {
+  listAggregatingTasksAsync,
+  deleteAllAggregatingTasksAsync,
+} from "../actions/tasksActions";
 import { taskRowsPerPageChange } from "../actions/settingsActions";
 
 const useStyles = makeStyles((theme) => ({
@@ -75,6 +78,7 @@ function mapStateToProps(state: AppState) {
 const mapDispatchToProps = {
   listGroupsAsync,
   listAggregatingTasksAsync,
+  deleteAllAggregatingTasksAsync,
   taskRowsPerPageChange,
 };
 
@@ -131,6 +135,13 @@ function AggregatingTasksTable(
     }
   };
 
+  const handleDeleteAllClick = () => {
+    if (selectedGroup === null) {
+      return;
+    }
+    props.deleteAllAggregatingTasksAsync(queue, selectedGroup.group);
+  };
+
   const fetchGroups = useCallback(() => {
     listGroupsAsync(queue);
   }, [listGroupsAsync, queue]);
@@ -194,7 +205,7 @@ function AggregatingTasksTable(
           menuItemActions={[
             {
               label: "Delete All",
-              onClick: () => {}, //TODO: handleDeleteAllClick,
+              onClick: handleDeleteAllClick,
               disabled: false, // TODO: props.allActionPending,
             },
             {
diff --git a/ui/src/reducers/tasksReducer.ts b/ui/src/reducers/tasksReducer.ts
index 833f6d1..301db04 100644
--- a/ui/src/reducers/tasksReducer.ts
+++ b/ui/src/reducers/tasksReducer.ts
@@ -132,6 +132,9 @@ import {
   LIST_AGGREGATING_TASKS_BEGIN,
   LIST_AGGREGATING_TASKS_SUCCESS,
   LIST_AGGREGATING_TASKS_ERROR,
+  DELETE_ALL_AGGREGATING_TASKS_BEGIN,
+  DELETE_ALL_AGGREGATING_TASKS_SUCCESS,
+  DELETE_ALL_AGGREGATING_TASKS_ERROR,
 } from "../actions/tasksActions";
 import { TaskInfo } from "../api";
 
@@ -1402,6 +1405,44 @@ function tasksReducer(
         },
       };
 
+    case DELETE_ALL_AGGREGATING_TASKS_BEGIN:
+      if (state.aggregatingTasks.group !== action.group) {
+        return state;
+      }
+      return {
+        ...state,
+        aggregatingTasks: {
+          ...state.aggregatingTasks,
+          allActionPending: true,
+        },
+      };
+
+    case DELETE_ALL_AGGREGATING_TASKS_SUCCESS:
+      if (state.aggregatingTasks.group !== action.group) {
+        return state;
+      }
+      return {
+        ...state,
+        aggregatingTasks: {
+          ...state.aggregatingTasks,
+          allActionPending: false,
+          data: [],
+        },
+      };
+
+    case DELETE_ALL_AGGREGATING_TASKS_ERROR:
+      if (state.aggregatingTasks.group !== action.group) {
+        return state;
+      }
+      return {
+        ...state,
+        aggregatingTasks: {
+          ...state.aggregatingTasks,
+          allActionPending: false,
+          error: action.error,
+        },
+      };
+
     default:
       return state;
   }