Add delete-all action button to DeadTasksTable

This commit is contained in:
Ken Hibino 2020-12-16 06:55:51 -08:00
parent fa231aa713
commit 226cfc3b82
6 changed files with 129 additions and 4 deletions

View File

@ -4,6 +4,7 @@ import {
batchRunDeadTasks,
BatchRunTasksResponse,
cancelActiveTask,
deleteAllDeadTasks,
deleteDeadTask,
deleteRetryTask,
deleteScheduledTask,
@ -60,6 +61,9 @@ export const BATCH_DELETE_DEAD_TASKS_BEGIN = "BATCH_DELETE_DEAD_TASKS_BEGIN";
export const BATCH_DELETE_DEAD_TASKS_SUCCESS =
"BATCH_DELETE_DEAD_TASKS_SUCCESS";
export const BATCH_DELETE_DEAD_TASKS_ERROR = "BATCH_DELETE_DEAD_TASKS_ERROR";
export const DELETE_ALL_DEAD_TASKS_BEGIN = "DELETE_ALL_DEAD_TASKS_BEGIN";
export const DELETE_ALL_DEAD_TASKS_SUCCESS = "DELETE_ALL_DEAD_TASKS_SUCCESS";
export const DELETE_ALL_DEAD_TASKS_ERROR = "DELETE_ALL_DEAD_TASKS_ERROR";
interface ListActiveTasksBeginAction {
type: typeof LIST_ACTIVE_TASKS_BEGIN;
@ -279,6 +283,22 @@ interface BatchRunDeadTasksErrorAction {
error: string;
}
interface DeleteAllDeadTasksBeginAction {
type: typeof DELETE_ALL_DEAD_TASKS_BEGIN;
queue: string;
}
interface DeleteAllDeadTasksSuccessAction {
type: typeof DELETE_ALL_DEAD_TASKS_SUCCESS;
queue: string;
}
interface DeleteAllDeadTasksErrorAction {
type: typeof DELETE_ALL_DEAD_TASKS_ERROR;
queue: string;
error: string;
}
// Union of all tasks related action types.
export type TasksActionTypes =
| ListActiveTasksBeginAction
@ -316,7 +336,10 @@ export type TasksActionTypes =
| BatchDeleteDeadTasksErrorAction
| BatchRunDeadTasksBeginAction
| BatchRunDeadTasksSuccessAction
| BatchRunDeadTasksErrorAction;
| BatchRunDeadTasksErrorAction
| DeleteAllDeadTasksBeginAction
| DeleteAllDeadTasksSuccessAction
| DeleteAllDeadTasksErrorAction;
export function listActiveTasksAsync(
qname: string,
@ -565,3 +588,20 @@ export function batchRunDeadTasksAsync(queue: string, taskKeys: string[]) {
}
};
}
export function deleteAllDeadTasksAsync(queue: string) {
return async (dispatch: Dispatch<TasksActionTypes>) => {
dispatch({ type: DELETE_ALL_DEAD_TASKS_BEGIN, queue });
try {
await deleteAllDeadTasks(queue);
dispatch({ type: DELETE_ALL_DEAD_TASKS_SUCCESS, queue });
} catch (error) {
console.error("deleteAllDeadTasksAsync: ", error);
dispatch({
type: DELETE_ALL_DEAD_TASKS_ERROR,
error: `Could not delete all dead tasks`,
queue,
});
}
};
}

View File

@ -307,6 +307,13 @@ export async function batchDeleteDeadTasks(
return resp.data;
}
export async function deleteAllDeadTasks(qname: string): Promise<void> {
await axios({
method: "delete",
url: `${BASE_URL}/queues/${qname}/dead_tasks:delete_all`,
});
}
export async function batchRunDeadTasks(
qname: string,
taskKeys: string[]

View File

@ -31,6 +31,7 @@ import {
batchDeleteDeadTasksAsync,
batchRunDeadTasksAsync,
deleteDeadTaskAsync,
deleteAllDeadTasksAsync,
listDeadTasksAsync,
runDeadTaskAsync,
} from "../actions/tasksActions";
@ -67,6 +68,7 @@ function mapStateToProps(state: AppState) {
loading: state.tasks.deadTasks.loading,
tasks: state.tasks.deadTasks.data,
batchActionPending: state.tasks.deadTasks.batchActionPending,
deleteAllRequestPending: state.tasks.deadTasks.deleteAllRequestPending,
pollInterval: state.settings.pollInterval,
};
}
@ -75,6 +77,7 @@ const mapDispatchToProps = {
listDeadTasksAsync,
runDeadTaskAsync,
deleteDeadTaskAsync,
deleteAllDeadTasksAsync,
batchRunDeadTasksAsync,
batchDeleteDeadTasksAsync,
};
@ -125,6 +128,11 @@ function DeadTasksTable(props: Props & ReduxProps) {
const handleMenuClose = () => setMenuAnchor(null);
const handleDeleteAllClick = () => {
props.deleteAllDeadTasksAsync(queue);
setMenuAnchor(null);
};
const fetchData = useCallback(() => {
const pageOpts = { page: page + 1, size: pageSize };
listDeadTasksAsync(queue, pageOpts);
@ -170,7 +178,12 @@ function DeadTasksTable(props: Props & ReduxProps) {
onClose={handleMenuClose}
>
<MenuItem onClick={handleMenuClose}>Run All</MenuItem>
<MenuItem onClick={handleMenuClose}>Delete All</MenuItem>
<MenuItem
onClick={handleDeleteAllClick}
disabled={props.deleteAllRequestPending}
>
Delete All
</MenuItem>
</Menu>
{numSelected > 0 && (
<ButtonGroup
@ -245,6 +258,7 @@ function DeadTasksTable(props: Props & ReduxProps) {
onDeleteClick={() => {
props.deleteDeadTaskAsync(queue, task.key);
}}
deleteAllRequestPending={props.deleteAllRequestPending}
/>
))}
</TableBody>
@ -278,6 +292,7 @@ interface RowProps {
onSelectChange: (checked: boolean) => void;
onRunClick: () => void;
onDeleteClick: () => void;
deleteAllRequestPending: boolean;
}
function Row(props: RowProps) {
@ -314,10 +329,16 @@ function Row(props: RowProps) {
<TableCell>{timeAgo(task.last_failed_at)}</TableCell>
<TableCell>{task.error_message}</TableCell>
<TableCell>
<Button onClick={props.onRunClick} disabled={task.requestPending}>
<Button
onClick={props.onRunClick}
disabled={task.requestPending || props.deleteAllRequestPending}
>
Run
</Button>
<Button onClick={props.onDeleteClick} disabled={task.requestPending}>
<Button
onClick={props.onDeleteClick}
disabled={task.requestPending || props.deleteAllRequestPending}
>
Delete
</Button>
</TableCell>

View File

@ -16,6 +16,7 @@ import {
import {
BATCH_DELETE_DEAD_TASKS_SUCCESS,
BATCH_RUN_DEAD_TASKS_SUCCESS,
DELETE_ALL_DEAD_TASKS_SUCCESS,
DELETE_DEAD_TASK_SUCCESS,
DELETE_RETRY_TASK_SUCCESS,
DELETE_SCHEDULED_TASK_SUCCESS,
@ -255,6 +256,22 @@ function queuesReducer(
return { ...state, data: newData };
}
case DELETE_ALL_DEAD_TASKS_SUCCESS: {
const newData = state.data.map((queueInfo) => {
if (queueInfo.name !== action.queue) {
return queueInfo;
}
return {
...queueInfo,
currentStats: {
...queueInfo.currentStats,
dead: 0,
},
};
});
return { ...state, data: newData };
}
default:
return state;
}

View File

@ -5,6 +5,7 @@ import {
import {
BATCH_DELETE_DEAD_TASKS_SUCCESS,
BATCH_RUN_DEAD_TASKS_SUCCESS,
DELETE_ALL_DEAD_TASKS_SUCCESS,
DELETE_DEAD_TASK_SUCCESS,
DELETE_RETRY_TASK_SUCCESS,
DELETE_SCHEDULED_TASK_SUCCESS,
@ -79,6 +80,12 @@ function snackbarReducer(
};
}
case DELETE_ALL_DEAD_TASKS_SUCCESS:
return {
isOpen: true,
message: `All dead tasks delete`,
};
default:
return state;
}

View File

@ -36,6 +36,9 @@ import {
BATCH_RUN_DEAD_TASKS_BEGIN,
BATCH_RUN_DEAD_TASKS_ERROR,
BATCH_RUN_DEAD_TASKS_SUCCESS,
DELETE_ALL_DEAD_TASKS_BEGIN,
DELETE_ALL_DEAD_TASKS_SUCCESS,
DELETE_ALL_DEAD_TASKS_ERROR,
} from "../actions/tasksActions";
import {
ActiveTask,
@ -97,6 +100,7 @@ interface TasksState {
deadTasks: {
loading: boolean;
batchActionPending: boolean;
deleteAllRequestPending: boolean;
error: string;
data: DeadTaskExtended[];
};
@ -126,6 +130,7 @@ const initialState: TasksState = {
deadTasks: {
loading: false,
batchActionPending: false,
deleteAllRequestPending: false,
error: "",
data: [],
},
@ -467,6 +472,34 @@ function tasksReducer(
},
};
case DELETE_ALL_DEAD_TASKS_BEGIN:
return {
...state,
deadTasks: {
...state.deadTasks,
deleteAllRequestPending: true,
},
};
case DELETE_ALL_DEAD_TASKS_SUCCESS:
return {
...state,
deadTasks: {
...state.deadTasks,
deleteAllRequestPending: false,
data: [],
},
};
case DELETE_ALL_DEAD_TASKS_ERROR:
return {
...state,
deadTasks: {
...state.deadTasks,
deleteAllRequestPending: false,
},
};
case BATCH_RUN_DEAD_TASKS_BEGIN:
case BATCH_DELETE_DEAD_TASKS_BEGIN:
return {