diff --git a/tools/asynq/cmd/dash/dash.go b/tools/asynq/cmd/dash/dash.go index bf6d47a..233fbb3 100644 --- a/tools/asynq/cmd/dash/dash.go +++ b/tools/asynq/cmd/dash/dash.go @@ -37,6 +37,7 @@ type State struct { taskTableRowIdx int // highlighted row in task table groupTableRowIdx int // highlighted row in group table taskState asynq.TaskState // highlighted task state in queue details view + taskID string // selected task ID selectedQueue *asynq.QueueInfo // queue shown on queue details view selectedGroup *asynq.GroupInfo diff --git a/tools/asynq/cmd/dash/draw.go b/tools/asynq/cmd/dash/draw.go index 8df1123..4868a61 100644 --- a/tools/asynq/cmd/dash/draw.go +++ b/tools/asynq/cmd/dash/draw.go @@ -442,6 +442,9 @@ func drawTaskStateBreakdown(d *ScreenDrawer, style tcell.Style, state *State) { } func drawTaskModal(d *ScreenDrawer, state *State) { + if state.taskID == "" { + return + } contents := []*rowContent{ {" === Task Summary ===", baseStyle.Bold(true)}, {"", baseStyle}, diff --git a/tools/asynq/cmd/dash/key_event.go b/tools/asynq/cmd/dash/key_event.go index 90ea37e..04d8a18 100644 --- a/tools/asynq/cmd/dash/key_event.go +++ b/tools/asynq/cmd/dash/key_event.go @@ -71,8 +71,15 @@ func (h *keyEventHandler) goBack() { state.view = state.prevView // exit help d.draw(state) } else if state.view == viewTypeQueueDetails { - state.view = viewTypeQueues - d.draw(state) + // if task modal is open close it; otherwise go back to the previous view + if state.taskID != "" { + state.taskID = "" + state.selectedTask = nil + d.draw(state) + } else { + state.view = viewTypeQueues + d.draw(state) + } } else { h.quit() } @@ -191,7 +198,14 @@ func (h *keyEventHandler) enterKeyQueueDetails() { state.pageNum = 1 f.fetchAggregatingTasks(state.selectedQueue.Queue, state.selectedGroup.Group, taskPageSize(s), state.pageNum) d.draw(state) + } else if !shouldShowGroupTable(state) && state.taskTableRowIdx != 0 { + task := state.tasks[state.taskTableRowIdx-1] + state.taskID = task.ID + state.selectedTask = task + // TODO: go fetch task info + d.draw(state) } + } func (h *keyEventHandler) handleLeftKey() { diff --git a/tools/asynq/cmd/dash/key_event_test.go b/tools/asynq/cmd/dash/key_event_test.go index 2dbcf3c..f784175 100644 --- a/tools/asynq/cmd/dash/key_event_test.go +++ b/tools/asynq/cmd/dash/key_event_test.go @@ -78,6 +78,87 @@ func TestKeyEventHandler(t *testing.T) { queueTableRowIdx: 0, }, }, + { + desc: "opens task info modal", + state: &State{ + view: viewTypeQueueDetails, + queues: []*asynq.QueueInfo{ + {Queue: "default", Size: 500, Active: 10, Pending: 40}, + }, + queueTableRowIdx: 1, + selectedQueue: &asynq.QueueInfo{Queue: "default", Size: 50, Active: 10, Pending: 40}, + taskState: asynq.TaskStatePending, + pageNum: 1, + tasks: []*asynq.TaskInfo{ + {ID: "xxxx", Type: "foo"}, + {ID: "yyyy", Type: "bar"}, + {ID: "zzzz", Type: "baz"}, + }, + taskTableRowIdx: 2, + }, + events: []*tcell.EventKey{ + tcell.NewEventKey(tcell.KeyEnter, '\n', tcell.ModNone), // Enter + }, + wantState: State{ + view: viewTypeQueueDetails, + queues: []*asynq.QueueInfo{ + {Queue: "default", Size: 500, Active: 10, Pending: 40}, + }, + queueTableRowIdx: 1, + selectedQueue: &asynq.QueueInfo{Queue: "default", Size: 50, Active: 10, Pending: 40}, + taskState: asynq.TaskStatePending, + pageNum: 1, + tasks: []*asynq.TaskInfo{ + {ID: "xxxx", Type: "foo"}, + {ID: "yyyy", Type: "bar"}, + {ID: "zzzz", Type: "baz"}, + }, + taskTableRowIdx: 2, + // new states + taskID: "yyyy", + selectedTask: &asynq.TaskInfo{ID: "yyyy", Type: "bar"}, + }, + }, + { + desc: "Esc closes task info modal", + state: &State{ + view: viewTypeQueueDetails, + queues: []*asynq.QueueInfo{ + {Queue: "default", Size: 500, Active: 10, Pending: 40}, + }, + queueTableRowIdx: 1, + selectedQueue: &asynq.QueueInfo{Queue: "default", Size: 50, Active: 10, Pending: 40}, + taskState: asynq.TaskStatePending, + pageNum: 1, + tasks: []*asynq.TaskInfo{ + {ID: "xxxx", Type: "foo"}, + {ID: "yyyy", Type: "bar"}, + {ID: "zzzz", Type: "baz"}, + }, + taskTableRowIdx: 2, + taskID: "yyyy", // presence of this field opens the modal + }, + events: []*tcell.EventKey{ + tcell.NewEventKey(tcell.KeyEscape, ' ', tcell.ModNone), // Esc + }, + wantState: State{ + view: viewTypeQueueDetails, + queues: []*asynq.QueueInfo{ + {Queue: "default", Size: 500, Active: 10, Pending: 40}, + }, + queueTableRowIdx: 1, + selectedQueue: &asynq.QueueInfo{Queue: "default", Size: 50, Active: 10, Pending: 40}, + taskState: asynq.TaskStatePending, + pageNum: 1, + tasks: []*asynq.TaskInfo{ + {ID: "xxxx", Type: "foo"}, + {ID: "yyyy", Type: "bar"}, + {ID: "zzzz", Type: "baz"}, + }, + taskTableRowIdx: 2, + taskID: "", // this field should be unset + }, + }, // TODO: Add more tests }