(ui): Add action buttons to AggregatingTasksTable

This commit is contained in:
Ken Hibino 2022-03-30 19:18:16 -07:00
parent ad20a8a7e7
commit 33e76f263d
5 changed files with 811 additions and 18 deletions

View File

@ -51,6 +51,14 @@ import {
TaskInfo, TaskInfo,
getTaskInfo, getTaskInfo,
deleteAllAggregatingTasks, deleteAllAggregatingTasks,
archiveAllAggregatingTasks,
runAllAggregatingTasks,
batchDeleteAggregatingTasks,
batchArchiveAggregatingTasks,
batchRunAggregatingTasks,
deleteAggregatingTask,
runAggregatingTask,
archiveAggregatingTask,
} from "../api"; } from "../api";
import { Dispatch } from "redux"; import { Dispatch } from "redux";
import { toErrorString, toErrorStringWithHttpStatus } from "../utils"; import { toErrorString, toErrorStringWithHttpStatus } from "../utils";
@ -117,6 +125,17 @@ export const ARCHIVE_SCHEDULED_TASK_ERROR = "ARCHIVE_SCHEDULED_TASK_ERROR";
export const ARCHIVE_RETRY_TASK_BEGIN = "ARCHIVE_RETRY_TASK_BEGIN"; export const ARCHIVE_RETRY_TASK_BEGIN = "ARCHIVE_RETRY_TASK_BEGIN";
export const ARCHIVE_RETRY_TASK_SUCCESS = "ARCHIVE_RETRY_TASK_SUCCESS"; export const ARCHIVE_RETRY_TASK_SUCCESS = "ARCHIVE_RETRY_TASK_SUCCESS";
export const ARCHIVE_RETRY_TASK_ERROR = "ARCHIVE_RETRY_TASK_ERROR"; export const ARCHIVE_RETRY_TASK_ERROR = "ARCHIVE_RETRY_TASK_ERROR";
export const RUN_AGGREGATING_TASK_BEGIN = "RUN_AGGREGATING_TASK_BEGIN";
export const RUN_AGGREGATING_TASK_SUCCESS = "RUN_AGGREGATING_TASK_SUCCESS";
export const RUN_AGGREGATING_TASK_ERROR = "RUN_AGGREGATING_TASK_ERROR";
export const DELETE_AGGREGATING_TASK_BEGIN = "DELETE_AGGREGATING_TASK_BEGIN";
export const DELETE_AGGREGATING_TASK_SUCCESS =
"DELETE_AGGREGATING_TASK_SUCCESS";
export const DELETE_AGGREGATING_TASK_ERROR = "DELETE_AGGREGATING_TASK_ERROR";
export const ARCHIVE_AGGREGATING_TASK_BEGIN = "ARCHIVE_AGGREGATING_TASK_BEGIN";
export const ARCHIVE_AGGREGATING_TASK_SUCCESS =
"ARCHIVE_AGGREGATING_TASK_SUCCESS";
export const ARCHIVE_AGGREGATING_TASK_ERROR = "ARCHIVE_AGGREGATING_TASK_ERROR";
export const BATCH_ARCHIVE_PENDING_TASKS_BEGIN = export const BATCH_ARCHIVE_PENDING_TASKS_BEGIN =
"BATCH_ARCHIVE_PENDING_TASKS_BEGIN"; "BATCH_ARCHIVE_PENDING_TASKS_BEGIN";
export const BATCH_ARCHIVE_PENDING_TASKS_SUCCESS = export const BATCH_ARCHIVE_PENDING_TASKS_SUCCESS =
@ -1062,21 +1081,81 @@ interface DeleteAllCompletedTasksErrorAction {
error: string; error: string;
} }
interface DeleteAggregatingTaskBeginAction {
type: typeof DELETE_AGGREGATING_TASK_BEGIN;
queue: string;
taskId: string;
}
interface DeleteAggregatingTaskSuccessAction {
type: typeof DELETE_AGGREGATING_TASK_SUCCESS;
queue: string;
taskId: string;
}
interface DeleteAggregatingTaskErrorAction {
type: typeof DELETE_AGGREGATING_TASK_ERROR;
queue: string;
taskId: string;
error: string;
}
interface RunAggregatingTaskBeginAction {
type: typeof RUN_AGGREGATING_TASK_BEGIN;
queue: string;
taskId: string;
}
interface RunAggregatingTaskSuccessAction {
type: typeof RUN_AGGREGATING_TASK_SUCCESS;
queue: string;
taskId: string;
}
interface RunAggregatingTaskErrorAction {
type: typeof RUN_AGGREGATING_TASK_ERROR;
queue: string;
taskId: string;
error: string;
}
interface ArchiveAggregatingTaskBeginAction {
type: typeof ARCHIVE_AGGREGATING_TASK_BEGIN;
queue: string;
taskId: string;
}
interface ArchiveAggregatingTaskSuccessAction {
type: typeof ARCHIVE_AGGREGATING_TASK_SUCCESS;
queue: string;
taskId: string;
}
interface ArchiveAggregatingTaskErrorAction {
type: typeof ARCHIVE_AGGREGATING_TASK_ERROR;
queue: string;
taskId: string;
error: string;
}
interface BatchDeleteAggregatingTasksBeginAction { interface BatchDeleteAggregatingTasksBeginAction {
type: typeof BATCH_DELETE_AGGREGATING_TASKS_BEGIN; type: typeof BATCH_DELETE_AGGREGATING_TASKS_BEGIN;
queue: string; queue: string;
group: string;
taskIds: string[]; taskIds: string[];
} }
interface BatchDeleteAggregatingTasksSuccessAction { interface BatchDeleteAggregatingTasksSuccessAction {
type: typeof BATCH_DELETE_AGGREGATING_TASKS_SUCCESS; type: typeof BATCH_DELETE_AGGREGATING_TASKS_SUCCESS;
queue: string; queue: string;
group: string;
payload: BatchDeleteTasksResponse; payload: BatchDeleteTasksResponse;
} }
interface BatchDeleteAggregatingTasksErrorAction { interface BatchDeleteAggregatingTasksErrorAction {
type: typeof BATCH_DELETE_AGGREGATING_TASKS_ERROR; type: typeof BATCH_DELETE_AGGREGATING_TASKS_ERROR;
queue: string; queue: string;
group: string;
taskIds: string[]; taskIds: string[];
error: string; error: string;
} }
@ -1084,18 +1163,21 @@ interface BatchDeleteAggregatingTasksErrorAction {
interface BatchRunAggregatingTasksBeginAction { interface BatchRunAggregatingTasksBeginAction {
type: typeof BATCH_RUN_AGGREGATING_TASKS_BEGIN; type: typeof BATCH_RUN_AGGREGATING_TASKS_BEGIN;
queue: string; queue: string;
group: string;
taskIds: string[]; taskIds: string[];
} }
interface BatchRunAggregatingTasksSuccessAction { interface BatchRunAggregatingTasksSuccessAction {
type: typeof BATCH_RUN_AGGREGATING_TASKS_SUCCESS; type: typeof BATCH_RUN_AGGREGATING_TASKS_SUCCESS;
queue: string; queue: string;
group: string;
payload: BatchRunTasksResponse; payload: BatchRunTasksResponse;
} }
interface BatchRunAggregatingTasksErrorAction { interface BatchRunAggregatingTasksErrorAction {
type: typeof BATCH_RUN_AGGREGATING_TASKS_ERROR; type: typeof BATCH_RUN_AGGREGATING_TASKS_ERROR;
queue: string; queue: string;
group: string;
taskIds: string[]; taskIds: string[];
error: string; error: string;
} }
@ -1108,6 +1190,7 @@ interface RunAllAggregatingTasksBeginAction {
interface RunAllAggregatingTasksSuccessAction { interface RunAllAggregatingTasksSuccessAction {
type: typeof RUN_ALL_AGGREGATING_TASKS_SUCCESS; type: typeof RUN_ALL_AGGREGATING_TASKS_SUCCESS;
scheduled: number;
queue: string; queue: string;
group: string; group: string;
} }
@ -1151,6 +1234,7 @@ interface ArchiveAllAggregatingTasksSuccessAction {
type: typeof ARCHIVE_ALL_AGGREGATING_TASKS_SUCCESS; type: typeof ARCHIVE_ALL_AGGREGATING_TASKS_SUCCESS;
queue: string; queue: string;
group: string; group: string;
archived: number;
} }
interface ArchiveAllAggregatingTasksErrorAction { interface ArchiveAllAggregatingTasksErrorAction {
@ -1331,7 +1415,16 @@ export type TasksActionTypes =
| ArchiveAllAggregatingTasksErrorAction | ArchiveAllAggregatingTasksErrorAction
| DeleteAllAggregatingTasksBeginAction | DeleteAllAggregatingTasksBeginAction
| DeleteAllAggregatingTasksSuccessAction | DeleteAllAggregatingTasksSuccessAction
| DeleteAllAggregatingTasksErrorAction; | DeleteAllAggregatingTasksErrorAction
| DeleteAggregatingTaskBeginAction
| DeleteAggregatingTaskSuccessAction
| DeleteAggregatingTaskErrorAction
| RunAggregatingTaskBeginAction
| RunAggregatingTaskSuccessAction
| RunAggregatingTaskErrorAction
| ArchiveAggregatingTaskBeginAction
| ArchiveAggregatingTaskSuccessAction
| ArchiveAggregatingTaskErrorAction;
export function getTaskInfoAsync(qname: string, id: string) { export function getTaskInfoAsync(qname: string, id: string) {
return async (dispatch: Dispatch<TasksActionTypes>) => { return async (dispatch: Dispatch<TasksActionTypes>) => {
@ -1913,6 +2006,121 @@ export function batchArchivePendingTasksAsync(
}; };
} }
export function deleteAggregatingTaskAsync(
queue: string,
group: string,
taskId: string
) {
return async (dispatch: Dispatch<TasksActionTypes>) => {
dispatch({ type: DELETE_AGGREGATING_TASK_BEGIN, queue, taskId });
try {
await deleteAggregatingTask(queue, group, taskId);
dispatch({ type: DELETE_AGGREGATING_TASK_SUCCESS, queue, taskId });
} catch (error) {
console.error(
"deleteAggregatingTaskAsync: ",
toErrorStringWithHttpStatus(error)
);
dispatch({
type: DELETE_AGGREGATING_TASK_ERROR,
error: toErrorString(error),
queue,
taskId,
});
}
};
}
export function runAggregatingTaskAsync(
queue: string,
group: string,
taskId: string
) {
return async (dispatch: Dispatch<TasksActionTypes>) => {
dispatch({ type: RUN_AGGREGATING_TASK_BEGIN, queue, taskId });
try {
await runAggregatingTask(queue, group, taskId);
dispatch({ type: RUN_AGGREGATING_TASK_SUCCESS, queue, taskId });
} catch (error) {
console.error(
"runAggregatingTaskAsync: ",
toErrorStringWithHttpStatus(error)
);
dispatch({
type: RUN_AGGREGATING_TASK_ERROR,
error: toErrorString(error),
queue,
taskId,
});
}
};
}
export function archiveAggregatingTaskAsync(
queue: string,
group: string,
taskId: string
) {
return async (dispatch: Dispatch<TasksActionTypes>) => {
dispatch({ type: ARCHIVE_AGGREGATING_TASK_BEGIN, queue, taskId });
try {
await archiveAggregatingTask(queue, group, taskId);
dispatch({ type: ARCHIVE_AGGREGATING_TASK_SUCCESS, queue, taskId });
} catch (error) {
console.error(
"archiveAggregatingTaskAsync: ",
toErrorStringWithHttpStatus(error)
);
dispatch({
type: ARCHIVE_AGGREGATING_TASK_ERROR,
error: toErrorString(error),
queue,
taskId,
});
}
};
}
export function batchArchiveAggregatingTasksAsync(
queue: string,
group: string,
taskIds: string[]
) {
return async (dispatch: Dispatch<TasksActionTypes>) => {
dispatch({
type: BATCH_ARCHIVE_AGGREGATING_TASKS_BEGIN,
queue,
group,
taskIds,
});
try {
const response = await batchArchiveAggregatingTasks(
queue,
group,
taskIds
);
dispatch({
type: BATCH_ARCHIVE_AGGREGATING_TASKS_SUCCESS,
payload: response,
queue,
group,
});
} catch (error) {
console.error(
"batchArchiveAggregatingTasksAsync: ",
toErrorStringWithHttpStatus(error)
);
dispatch({
type: BATCH_ARCHIVE_AGGREGATING_TASKS_ERROR,
error: toErrorString(error),
queue,
group,
taskIds,
});
}
};
}
export function archiveAllPendingTasksAsync(queue: string) { export function archiveAllPendingTasksAsync(queue: string) {
return async (dispatch: Dispatch<TasksActionTypes>) => { return async (dispatch: Dispatch<TasksActionTypes>) => {
dispatch({ type: ARCHIVE_ALL_PENDING_TASKS_BEGIN, queue }); dispatch({ type: ARCHIVE_ALL_PENDING_TASKS_BEGIN, queue });
@ -2047,6 +2255,58 @@ export function archiveAllScheduledTasksAsync(queue: string) {
}; };
} }
export function archiveAllAggregatingTasksAsync(queue: string, group: string) {
return async (dispatch: Dispatch<TasksActionTypes>) => {
dispatch({ type: ARCHIVE_ALL_AGGREGATING_TASKS_BEGIN, queue, group });
try {
const response = await archiveAllAggregatingTasks(queue, group);
dispatch({
type: ARCHIVE_ALL_AGGREGATING_TASKS_SUCCESS,
archived: response.archived,
queue,
group,
});
} catch (error) {
console.error(
"archiveAllAggregatingTasksAsync: ",
toErrorStringWithHttpStatus(error)
);
dispatch({
type: ARCHIVE_ALL_AGGREGATING_TASKS_ERROR,
error: toErrorString(error),
queue,
group,
});
}
};
}
export function runAllAggregatingTasksAsync(queue: string, group: string) {
return async (dispatch: Dispatch<TasksActionTypes>) => {
dispatch({ type: RUN_ALL_AGGREGATING_TASKS_BEGIN, queue, group });
try {
const resp = await runAllAggregatingTasks(queue, group);
dispatch({
type: RUN_ALL_AGGREGATING_TASKS_SUCCESS,
scheduled: resp.scheduled,
queue,
group,
});
} catch (error) {
console.error(
"runAllAggregatingTasksAsync: ",
toErrorStringWithHttpStatus(error)
);
dispatch({
type: RUN_ALL_AGGREGATING_TASKS_ERROR,
error: toErrorString(error),
queue,
group,
});
}
};
}
export function deleteRetryTaskAsync(queue: string, taskId: string) { export function deleteRetryTaskAsync(queue: string, taskId: string) {
return async (dispatch: Dispatch<TasksActionTypes>) => { return async (dispatch: Dispatch<TasksActionTypes>) => {
dispatch({ type: DELETE_RETRY_TASK_BEGIN, queue, taskId }); dispatch({ type: DELETE_RETRY_TASK_BEGIN, queue, taskId });
@ -2118,6 +2378,42 @@ export function batchRunRetryTasksAsync(queue: string, taskIds: string[]) {
}; };
} }
export function batchRunAggregatingTasksAsync(
queue: string,
group: string,
taskIds: string[]
) {
return async (dispatch: Dispatch<TasksActionTypes>) => {
dispatch({
type: BATCH_RUN_AGGREGATING_TASKS_BEGIN,
queue,
group,
taskIds,
});
try {
const response = await batchRunAggregatingTasks(queue, group, taskIds);
dispatch({
type: BATCH_RUN_AGGREGATING_TASKS_SUCCESS,
payload: response,
queue,
group,
});
} catch (error) {
console.error(
"batchRunAggregatingTasksAsync: ",
toErrorStringWithHttpStatus(error)
);
dispatch({
type: BATCH_RUN_AGGREGATING_TASKS_ERROR,
error: toErrorString(error),
queue,
group,
taskIds,
});
}
};
}
export function batchArchiveRetryTasksAsync(queue: string, taskIds: string[]) { export function batchArchiveRetryTasksAsync(queue: string, taskIds: string[]) {
return async (dispatch: Dispatch<TasksActionTypes>) => { return async (dispatch: Dispatch<TasksActionTypes>) => {
dispatch({ type: BATCH_ARCHIVE_RETRY_TASKS_BEGIN, queue, taskIds }); dispatch({ type: BATCH_ARCHIVE_RETRY_TASKS_BEGIN, queue, taskIds });
@ -2374,6 +2670,42 @@ export function batchDeleteCompletedTasksAsync(
}; };
} }
export function batchDeleteAggregatingTasksAsync(
queue: string,
group: string,
taskIds: string[]
) {
return async (dispatch: Dispatch<TasksActionTypes>) => {
dispatch({
type: BATCH_DELETE_AGGREGATING_TASKS_BEGIN,
queue,
group,
taskIds,
});
try {
const response = await batchDeleteAggregatingTasks(queue, group, taskIds);
dispatch({
type: BATCH_DELETE_AGGREGATING_TASKS_SUCCESS,
payload: response,
queue,
group,
});
} catch (error) {
console.error(
"batchDeleteAggregatingTasksAsync: ",
toErrorStringWithHttpStatus(error)
);
dispatch({
type: BATCH_DELETE_AGGREGATING_TASKS_ERROR,
error: toErrorString(error),
queue,
group,
taskIds,
});
}
};
}
export function deleteAllCompletedTasksAsync(queue: string) { export function deleteAllCompletedTasksAsync(queue: string) {
return async (dispatch: Dispatch<TasksActionTypes>) => { return async (dispatch: Dispatch<TasksActionTypes>) => {
dispatch({ type: DELETE_ALL_COMPLETED_TASKS_BEGIN, queue }); dispatch({ type: DELETE_ALL_COMPLETED_TASKS_BEGIN, queue });

View File

@ -54,6 +54,14 @@ export interface DeleteAllTasksResponse {
deleted: number; deleted: number;
} }
export interface ArchiveAllTasksResponse {
archived: number;
}
export interface RunAllTasksResponse {
scheduled: number;
}
export interface ListQueueStatsResponse { export interface ListQueueStatsResponse {
stats: { [qname: string]: DailyStat[] }; stats: { [qname: string]: DailyStat[] };
} }
@ -674,11 +682,12 @@ export async function batchRunAggregatingTasks(
export async function runAllAggregatingTasks( export async function runAllAggregatingTasks(
qname: string, qname: string,
gname: string gname: string
): Promise<void> { ): Promise<RunAllTasksResponse> {
await axios({ const resp = await axios({
method: "post", method: "post",
url: `${getBaseUrl()}/queues/${qname}/groups/${gname}/aggregating_tasks:run_all`, url: `${getBaseUrl()}/queues/${qname}/groups/${gname}/aggregating_tasks:run_all`,
}); });
return resp.data;
} }
export async function archiveAggregatingTask( export async function archiveAggregatingTask(
@ -710,11 +719,12 @@ export async function batchArchiveAggregatingTasks(
export async function archiveAllAggregatingTasks( export async function archiveAllAggregatingTasks(
qname: string, qname: string,
gname: string gname: string
): Promise<void> { ): Promise<ArchiveAllTasksResponse> {
await axios({ const resp = await axios({
method: "post", method: "post",
url: `${getBaseUrl()}/queues/${qname}/groups/${gname}/aggregating_tasks:archive_all`, url: `${getBaseUrl()}/queues/${qname}/groups/${gname}/aggregating_tasks:archive_all`,
}); });
return resp.data;
} }
export async function runScheduledTask( export async function runScheduledTask(

View File

@ -16,6 +16,7 @@ import Tooltip from "@material-ui/core/Tooltip";
import ArchiveIcon from "@material-ui/icons/Archive"; import ArchiveIcon from "@material-ui/icons/Archive";
import DeleteIcon from "@material-ui/icons/Delete"; import DeleteIcon from "@material-ui/icons/Delete";
import MoreHorizIcon from "@material-ui/icons/MoreHoriz"; import MoreHorizIcon from "@material-ui/icons/MoreHoriz";
import PlayArrowIcon from "@material-ui/icons/PlayArrow";
import FileCopyOutlinedIcon from "@material-ui/icons/FileCopyOutlined"; import FileCopyOutlinedIcon from "@material-ui/icons/FileCopyOutlined";
import Alert from "@material-ui/lab/Alert"; import Alert from "@material-ui/lab/Alert";
import AlertTitle from "@material-ui/lab/AlertTitle"; import AlertTitle from "@material-ui/lab/AlertTitle";
@ -37,6 +38,14 @@ import TablePaginationActions, {
import { import {
listAggregatingTasksAsync, listAggregatingTasksAsync,
deleteAllAggregatingTasksAsync, deleteAllAggregatingTasksAsync,
archiveAllAggregatingTasksAsync,
runAllAggregatingTasksAsync,
batchDeleteAggregatingTasksAsync,
batchRunAggregatingTasksAsync,
batchArchiveAggregatingTasksAsync,
deleteAggregatingTaskAsync,
runAggregatingTaskAsync,
archiveAggregatingTaskAsync,
} from "../actions/tasksActions"; } from "../actions/tasksActions";
import { taskRowsPerPageChange } from "../actions/settingsActions"; import { taskRowsPerPageChange } from "../actions/settingsActions";
@ -67,6 +76,8 @@ function mapStateToProps(state: AppState) {
groups: state.groups.data, groups: state.groups.data,
groupsError: state.groups.error, groupsError: state.groups.error,
loading: state.tasks.aggregatingTasks.loading, loading: state.tasks.aggregatingTasks.loading,
allActionPending: state.tasks.aggregatingTasks.allActionPending,
batchActionPending: state.tasks.aggregatingTasks.batchActionPending,
error: state.tasks.aggregatingTasks.error, error: state.tasks.aggregatingTasks.error,
group: state.tasks.aggregatingTasks.group, group: state.tasks.aggregatingTasks.group,
tasks: state.tasks.aggregatingTasks.data, tasks: state.tasks.aggregatingTasks.data,
@ -79,6 +90,14 @@ const mapDispatchToProps = {
listGroupsAsync, listGroupsAsync,
listAggregatingTasksAsync, listAggregatingTasksAsync,
deleteAllAggregatingTasksAsync, deleteAllAggregatingTasksAsync,
archiveAllAggregatingTasksAsync,
runAllAggregatingTasksAsync,
batchDeleteAggregatingTasksAsync,
batchRunAggregatingTasksAsync,
batchArchiveAggregatingTasksAsync,
deleteAggregatingTaskAsync,
runAggregatingTaskAsync,
archiveAggregatingTaskAsync,
taskRowsPerPageChange, taskRowsPerPageChange,
}; };
@ -142,6 +161,51 @@ function AggregatingTasksTable(
props.deleteAllAggregatingTasksAsync(queue, selectedGroup.group); props.deleteAllAggregatingTasksAsync(queue, selectedGroup.group);
}; };
const handleArchiveAllClick = () => {
if (selectedGroup === null) {
return;
}
props.archiveAllAggregatingTasksAsync(queue, selectedGroup.group);
};
const handleRunAllClick = () => {
if (selectedGroup === null) {
return;
}
props.runAllAggregatingTasksAsync(queue, selectedGroup.group);
};
const handleBatchRunClick = () => {
if (selectedGroup === null) {
return;
}
props
.batchRunAggregatingTasksAsync(queue, selectedGroup.group, selectedIds)
.then(() => setSelectedIds([]));
};
const handleBatchDeleteClick = () => {
if (selectedGroup === null) {
return;
}
props
.batchDeleteAggregatingTasksAsync(queue, selectedGroup.group, selectedIds)
.then(() => setSelectedIds([]));
};
const handleBatchArchiveClick = () => {
if (selectedGroup === null) {
return;
}
props
.batchArchiveAggregatingTasksAsync(
queue,
selectedGroup.group,
selectedIds
)
.then(() => setSelectedIds([]));
};
const fetchGroups = useCallback(() => { const fetchGroups = useCallback(() => {
listGroupsAsync(queue); listGroupsAsync(queue);
}, [listGroupsAsync, queue]); }, [listGroupsAsync, queue]);
@ -192,26 +256,37 @@ function AggregatingTasksTable(
{ {
tooltip: "Delete", tooltip: "Delete",
icon: <DeleteIcon />, icon: <DeleteIcon />,
onClick: () => {}, // TODO: handleBatchDeleteClick, onClick: handleBatchDeleteClick,
disabled: false, //TODO: props.batchActionPending, disabled: props.batchActionPending,
}, },
{ {
tooltip: "Archive", tooltip: "Archive",
icon: <ArchiveIcon />, icon: <ArchiveIcon />,
onClick: () => {}, //TODO: handleBatchArchiveClick, onClick: handleBatchArchiveClick,
disabled: false, //TODO: props.batchActionPending, disabled: props.batchActionPending,
},
{
tooltip: "Run",
icon: <PlayArrowIcon />,
onClick: handleBatchRunClick,
disabled: props.batchActionPending,
}, },
]} ]}
menuItemActions={[ menuItemActions={[
{ {
label: "Delete All", label: "Delete All",
onClick: handleDeleteAllClick, onClick: handleDeleteAllClick,
disabled: false, // TODO: props.allActionPending, disabled: props.allActionPending,
}, },
{ {
label: "Archive All", label: "Archive All",
onClick: () => {}, // TODO: handleArchiveAllClick, onClick: handleArchiveAllClick,
disabled: false, // TODO: props.allActionPending, disabled: props.allActionPending,
},
{
label: "Run All",
onClick: handleRunAllClick,
disabled: props.allActionPending,
}, },
]} ]}
/> />
@ -276,13 +351,30 @@ function AggregatingTasksTable(
); );
} }
}} }}
allActionPending={false /* TODO: props.allActionPending */} allActionPending={props.allActionPending}
onDeleteClick={ onDeleteClick={() => {
() => {} if (selectedGroup === null) return;
//TODO: props.deletePendingTaskAsync(queue, task.id) props.deleteAggregatingTaskAsync(
} queue,
selectedGroup.group,
task.id
);
}}
onArchiveClick={() => { onArchiveClick={() => {
// TODO: props.archivePendingTaskAsync(queue, task.id); if (selectedGroup === null) return;
props.archiveAggregatingTaskAsync(
queue,
selectedGroup.group,
task.id
);
}}
onRunClick={() => {
if (selectedGroup === null) return;
props.runAggregatingTaskAsync(
queue,
selectedGroup.group,
task.id
);
}} }}
onActionCellEnter={() => setActiveTaskId(task.id)} onActionCellEnter={() => setActiveTaskId(task.id)}
onActionCellLeave={() => setActiveTaskId("")} onActionCellLeave={() => setActiveTaskId("")}
@ -360,6 +452,7 @@ interface RowProps {
onSelectChange: (checked: boolean) => void; onSelectChange: (checked: boolean) => void;
onDeleteClick: () => void; onDeleteClick: () => void;
onArchiveClick: () => void; onArchiveClick: () => void;
onRunClick: () => void;
allActionPending: boolean; allActionPending: boolean;
showActions: boolean; showActions: boolean;
onActionCellEnter: () => void; onActionCellEnter: () => void;
@ -446,6 +539,16 @@ function Row(props: RowProps) {
<ArchiveIcon fontSize="small" /> <ArchiveIcon fontSize="small" />
</IconButton> </IconButton>
</Tooltip> </Tooltip>
<Tooltip title="Run">
<IconButton
onClick={props.onRunClick}
disabled={task.requestPending || props.allActionPending}
size="small"
className={classes.actionButton}
>
<PlayArrowIcon fontSize="small" />
</IconButton>
</Tooltip>
</React.Fragment> </React.Fragment>
) : ( ) : (
<IconButton size="small" onClick={props.onActionCellEnter}> <IconButton size="small" onClick={props.onActionCellEnter}>

View File

@ -53,6 +53,15 @@ import {
DELETE_COMPLETED_TASK_SUCCESS, DELETE_COMPLETED_TASK_SUCCESS,
DELETE_ALL_COMPLETED_TASKS_SUCCESS, DELETE_ALL_COMPLETED_TASKS_SUCCESS,
BATCH_DELETE_COMPLETED_TASKS_SUCCESS, BATCH_DELETE_COMPLETED_TASKS_SUCCESS,
DELETE_ALL_AGGREGATING_TASKS_SUCCESS,
ARCHIVE_ALL_AGGREGATING_TASKS_SUCCESS,
RUN_ALL_AGGREGATING_TASKS_SUCCESS,
BATCH_DELETE_AGGREGATING_TASKS_SUCCESS,
BATCH_RUN_AGGREGATING_TASKS_SUCCESS,
BATCH_ARCHIVE_AGGREGATING_TASKS_SUCCESS,
DELETE_AGGREGATING_TASK_SUCCESS,
RUN_AGGREGATING_TASK_SUCCESS,
ARCHIVE_AGGREGATING_TASK_SUCCESS,
} from "../actions/tasksActions"; } from "../actions/tasksActions";
import { Queue } from "../api"; import { Queue } from "../api";
@ -175,6 +184,23 @@ function queuesReducer(
return { ...state, data: newData }; return { ...state, data: newData };
} }
case RUN_AGGREGATING_TASK_SUCCESS: {
const newData = state.data.map((queueInfo) => {
if (queueInfo.name !== action.queue) {
return queueInfo;
}
return {
...queueInfo,
currentStats: {
...queueInfo.currentStats,
pending: queueInfo.currentStats.pending + 1,
aggregating: queueInfo.currentStats.aggregating - 1,
},
};
});
return { ...state, data: newData };
}
case RUN_SCHEDULED_TASK_SUCCESS: { case RUN_SCHEDULED_TASK_SUCCESS: {
const newData = state.data.map((queueInfo) => { const newData = state.data.map((queueInfo) => {
if (queueInfo.name !== action.queue) { if (queueInfo.name !== action.queue) {
@ -243,6 +269,23 @@ function queuesReducer(
return { ...state, data: newData }; return { ...state, data: newData };
} }
case ARCHIVE_AGGREGATING_TASK_SUCCESS: {
const newData = state.data.map((queueInfo) => {
if (queueInfo.name !== action.queue) {
return queueInfo;
}
return {
...queueInfo,
currentStats: {
...queueInfo.currentStats,
archived: queueInfo.currentStats.archived + 1,
aggregating: queueInfo.currentStats.aggregating - 1,
},
};
});
return { ...state, data: newData };
}
case ARCHIVE_SCHEDULED_TASK_SUCCESS: { case ARCHIVE_SCHEDULED_TASK_SUCCESS: {
const newData = state.data.map((queueInfo) => { const newData = state.data.map((queueInfo) => {
if (queueInfo.name !== action.queue) { if (queueInfo.name !== action.queue) {
@ -311,6 +354,23 @@ function queuesReducer(
return { ...state, data: newData }; return { ...state, data: newData };
} }
case DELETE_AGGREGATING_TASK_SUCCESS: {
const newData = state.data.map((queueInfo) => {
if (queueInfo.name !== action.queue) {
return queueInfo;
}
return {
...queueInfo,
currentStats: {
...queueInfo.currentStats,
size: queueInfo.currentStats.size - 1,
aggregating: queueInfo.currentStats.aggregating - 1,
},
};
});
return { ...state, data: newData };
}
case BATCH_ARCHIVE_PENDING_TASKS_SUCCESS: { case BATCH_ARCHIVE_PENDING_TASKS_SUCCESS: {
const newData = state.data.map((queueInfo) => { const newData = state.data.map((queueInfo) => {
if (queueInfo.name !== action.queue) { if (queueInfo.name !== action.queue) {
@ -370,6 +430,24 @@ function queuesReducer(
return { ...state, data: newData }; return { ...state, data: newData };
} }
case ARCHIVE_ALL_AGGREGATING_TASKS_SUCCESS: {
const newData = state.data.map((queueInfo) => {
if (queueInfo.name !== action.queue) {
return queueInfo;
}
return {
...queueInfo,
currentStats: {
...queueInfo.currentStats,
groups: queueInfo.currentStats.groups - 1,
archived: queueInfo.currentStats.archived + action.archived,
aggregating: queueInfo.currentStats.aggregating - action.archived,
},
};
});
return { ...state, data: newData };
}
case DELETE_ALL_PENDING_TASKS_SUCCESS: { case DELETE_ALL_PENDING_TASKS_SUCCESS: {
const newData = state.data.map((queueInfo) => { const newData = state.data.map((queueInfo) => {
if (queueInfo.name !== action.queue) { if (queueInfo.name !== action.queue) {
@ -449,6 +527,24 @@ function queuesReducer(
return { ...state, data: newData }; return { ...state, data: newData };
} }
case RUN_ALL_AGGREGATING_TASKS_SUCCESS: {
const newData = state.data.map((queueInfo) => {
if (queueInfo.name !== action.queue) {
return queueInfo;
}
return {
...queueInfo,
currentStats: {
...queueInfo.currentStats,
groups: queueInfo.currentStats.groups - 1,
pending: queueInfo.currentStats.pending + action.scheduled,
aggregating: queueInfo.currentStats.aggregating - action.scheduled,
},
};
});
return { ...state, data: newData };
}
case RUN_ALL_SCHEDULED_TASKS_SUCCESS: { case RUN_ALL_SCHEDULED_TASKS_SUCCESS: {
const newData = state.data.map((queueInfo) => { const newData = state.data.map((queueInfo) => {
if (queueInfo.name !== action.queue) { if (queueInfo.name !== action.queue) {
@ -486,6 +582,24 @@ function queuesReducer(
return { ...state, data: newData }; return { ...state, data: newData };
} }
case DELETE_ALL_AGGREGATING_TASKS_SUCCESS: {
const newData = state.data.map((queueInfo) => {
if (queueInfo.name !== action.queue) {
return queueInfo;
}
return {
...queueInfo,
currentStats: {
...queueInfo.currentStats,
size: queueInfo.currentStats.size - action.deleted,
groups: queueInfo.currentStats.groups - 1,
aggregating: queueInfo.currentStats.aggregating - action.deleted,
},
};
});
return { ...state, data: newData };
}
case DELETE_ALL_SCHEDULED_TASKS_SUCCESS: { case DELETE_ALL_SCHEDULED_TASKS_SUCCESS: {
const newData = state.data.map((queueInfo) => { const newData = state.data.map((queueInfo) => {
if (queueInfo.name !== action.queue) { if (queueInfo.name !== action.queue) {
@ -579,6 +693,68 @@ function queuesReducer(
return { ...state, data: newData }; return { ...state, data: newData };
} }
case BATCH_RUN_AGGREGATING_TASKS_SUCCESS: {
const newData = state.data.map((queueInfo) => {
if (queueInfo.name !== action.queue) {
return queueInfo;
}
return {
...queueInfo,
currentStats: {
...queueInfo.currentStats,
pending:
queueInfo.currentStats.pending +
action.payload.pending_ids.length,
aggregating:
queueInfo.currentStats.aggregating -
action.payload.pending_ids.length,
},
};
});
return { ...state, data: newData };
}
case BATCH_ARCHIVE_AGGREGATING_TASKS_SUCCESS: {
const newData = state.data.map((queueInfo) => {
if (queueInfo.name !== action.queue) {
return queueInfo;
}
return {
...queueInfo,
currentStats: {
...queueInfo.currentStats,
archived:
queueInfo.currentStats.archived +
action.payload.archived_ids.length,
aggregating:
queueInfo.currentStats.aggregating -
action.payload.archived_ids.length,
},
};
});
return { ...state, data: newData };
}
case BATCH_DELETE_AGGREGATING_TASKS_SUCCESS: {
const newData = state.data.map((queueInfo) => {
if (queueInfo.name !== action.queue) {
return queueInfo;
}
return {
...queueInfo,
currentStats: {
...queueInfo.currentStats,
size:
queueInfo.currentStats.size - action.payload.deleted_ids.length,
aggregating:
queueInfo.currentStats.aggregating -
action.payload.deleted_ids.length,
},
};
});
return { ...state, data: newData };
}
case RUN_ALL_RETRY_TASKS_SUCCESS: { case RUN_ALL_RETRY_TASKS_SUCCESS: {
const newData = state.data.map((queueInfo) => { const newData = state.data.map((queueInfo) => {
if (queueInfo.name !== action.queue) { if (queueInfo.name !== action.queue) {

View File

@ -135,6 +135,30 @@ import {
DELETE_ALL_AGGREGATING_TASKS_BEGIN, DELETE_ALL_AGGREGATING_TASKS_BEGIN,
DELETE_ALL_AGGREGATING_TASKS_SUCCESS, DELETE_ALL_AGGREGATING_TASKS_SUCCESS,
DELETE_ALL_AGGREGATING_TASKS_ERROR, DELETE_ALL_AGGREGATING_TASKS_ERROR,
ARCHIVE_ALL_AGGREGATING_TASKS_BEGIN,
ARCHIVE_ALL_AGGREGATING_TASKS_SUCCESS,
ARCHIVE_ALL_AGGREGATING_TASKS_ERROR,
RUN_ALL_AGGREGATING_TASKS_BEGIN,
RUN_ALL_AGGREGATING_TASKS_SUCCESS,
RUN_ALL_AGGREGATING_TASKS_ERROR,
BATCH_ARCHIVE_AGGREGATING_TASKS_BEGIN,
BATCH_RUN_AGGREGATING_TASKS_BEGIN,
BATCH_DELETE_AGGREGATING_TASKS_BEGIN,
BATCH_RUN_AGGREGATING_TASKS_ERROR,
BATCH_ARCHIVE_AGGREGATING_TASKS_ERROR,
BATCH_DELETE_AGGREGATING_TASKS_ERROR,
BATCH_DELETE_AGGREGATING_TASKS_SUCCESS,
BATCH_RUN_AGGREGATING_TASKS_SUCCESS,
BATCH_ARCHIVE_AGGREGATING_TASKS_SUCCESS,
RUN_AGGREGATING_TASK_BEGIN,
ARCHIVE_AGGREGATING_TASK_BEGIN,
DELETE_AGGREGATING_TASK_BEGIN,
RUN_AGGREGATING_TASK_ERROR,
ARCHIVE_AGGREGATING_TASK_ERROR,
DELETE_AGGREGATING_TASK_ERROR,
RUN_AGGREGATING_TASK_SUCCESS,
ARCHIVE_AGGREGATING_TASK_SUCCESS,
DELETE_AGGREGATING_TASK_SUCCESS,
} from "../actions/tasksActions"; } from "../actions/tasksActions";
import { TaskInfo } from "../api"; import { TaskInfo } from "../api";
@ -1105,6 +1129,148 @@ function tasksReducer(
}, },
}; };
case RUN_AGGREGATING_TASK_BEGIN:
case ARCHIVE_AGGREGATING_TASK_BEGIN:
case DELETE_AGGREGATING_TASK_BEGIN:
return {
...state,
aggregatingTasks: {
...state.aggregatingTasks,
data: state.aggregatingTasks.data.map((task) => {
if (task.id !== action.taskId) {
return task;
}
return { ...task, requestPending: true };
}),
},
};
case RUN_AGGREGATING_TASK_ERROR:
case ARCHIVE_AGGREGATING_TASK_ERROR:
case DELETE_AGGREGATING_TASK_ERROR:
return {
...state,
aggregatingTasks: {
...state.aggregatingTasks,
data: state.aggregatingTasks.data.map((task) => {
if (task.id !== action.taskId) {
return task;
}
return { ...task, requestPending: false };
}),
},
};
case RUN_AGGREGATING_TASK_SUCCESS:
case ARCHIVE_AGGREGATING_TASK_SUCCESS:
case DELETE_AGGREGATING_TASK_SUCCESS:
return {
...state,
aggregatingTasks: {
...state.aggregatingTasks,
data: state.aggregatingTasks.data.filter(
(task) => task.id !== action.taskId
),
},
};
case BATCH_RUN_AGGREGATING_TASKS_BEGIN:
case BATCH_ARCHIVE_AGGREGATING_TASKS_BEGIN:
case BATCH_DELETE_AGGREGATING_TASKS_BEGIN:
if (action.group !== state.aggregatingTasks.group) {
return state;
}
return {
...state,
aggregatingTasks: {
...state.aggregatingTasks,
batchActionPending: true,
data: state.aggregatingTasks.data.map((task) => {
if (!action.taskIds.includes(task.id)) {
return task;
}
return {
...task,
requestPending: true,
};
}),
},
};
case BATCH_RUN_AGGREGATING_TASKS_ERROR:
case BATCH_ARCHIVE_AGGREGATING_TASKS_ERROR:
case BATCH_DELETE_AGGREGATING_TASKS_ERROR:
if (action.group !== state.aggregatingTasks.group) {
return state;
}
return {
...state,
aggregatingTasks: {
...state.aggregatingTasks,
batchActionPending: false,
data: state.scheduledTasks.data.map((task) => {
if (!action.taskIds.includes(task.id)) {
return task;
}
return {
...task,
requestPending: false,
};
}),
},
};
case BATCH_DELETE_AGGREGATING_TASKS_SUCCESS: {
if (action.group !== state.aggregatingTasks.group) {
return state;
}
const newData = state.aggregatingTasks.data.filter(
(task) => !action.payload.deleted_ids.includes(task.id)
);
return {
...state,
aggregatingTasks: {
...state.aggregatingTasks,
batchActionPending: false,
data: newData,
},
};
}
case BATCH_RUN_AGGREGATING_TASKS_SUCCESS: {
if (action.group !== state.aggregatingTasks.group) {
return state;
}
const newData = state.aggregatingTasks.data.filter(
(task) => !action.payload.pending_ids.includes(task.id)
);
return {
...state,
aggregatingTasks: {
...state.aggregatingTasks,
batchActionPending: false,
data: newData,
},
};
}
case BATCH_ARCHIVE_AGGREGATING_TASKS_SUCCESS: {
if (action.group !== state.aggregatingTasks.group) {
return state;
}
const newData = state.aggregatingTasks.data.filter(
(task) => !action.payload.archived_ids.includes(task.id)
);
return {
...state,
aggregatingTasks: {
...state.aggregatingTasks,
batchActionPending: false,
data: newData,
},
};
}
case RUN_RETRY_TASK_BEGIN: case RUN_RETRY_TASK_BEGIN:
case ARCHIVE_RETRY_TASK_BEGIN: case ARCHIVE_RETRY_TASK_BEGIN:
case DELETE_RETRY_TASK_BEGIN: case DELETE_RETRY_TASK_BEGIN:
@ -1405,6 +1571,8 @@ function tasksReducer(
}, },
}; };
case RUN_ALL_AGGREGATING_TASKS_BEGIN:
case ARCHIVE_ALL_AGGREGATING_TASKS_BEGIN:
case DELETE_ALL_AGGREGATING_TASKS_BEGIN: case DELETE_ALL_AGGREGATING_TASKS_BEGIN:
if (state.aggregatingTasks.group !== action.group) { if (state.aggregatingTasks.group !== action.group) {
return state; return state;
@ -1417,6 +1585,8 @@ function tasksReducer(
}, },
}; };
case RUN_ALL_AGGREGATING_TASKS_SUCCESS:
case ARCHIVE_ALL_AGGREGATING_TASKS_SUCCESS:
case DELETE_ALL_AGGREGATING_TASKS_SUCCESS: case DELETE_ALL_AGGREGATING_TASKS_SUCCESS:
if (state.aggregatingTasks.group !== action.group) { if (state.aggregatingTasks.group !== action.group) {
return state; return state;
@ -1430,6 +1600,8 @@ function tasksReducer(
}, },
}; };
case RUN_ALL_AGGREGATING_TASKS_ERROR:
case ARCHIVE_ALL_AGGREGATING_TASKS_ERROR:
case DELETE_ALL_AGGREGATING_TASKS_ERROR: case DELETE_ALL_AGGREGATING_TASKS_ERROR:
if (state.aggregatingTasks.group !== action.group) { if (state.aggregatingTasks.group !== action.group) {
return state; return state;