Skip to content

Commit 1d3f382

Browse files
authored
✨ Add task dashboard report. (#720)
Better support succeeded with errors. closes #725 needed by: konveyor/tackle2-ui#1997 Example: GET /tasks/report/dashboard ``` - id: 7 createUser: admin.noauth createTime: 2024-07-15T15:35:53.198405073Z name: Daytrader7.1.windup kind: analyzer addon: analyzer state: Succeeded application: id: 1 name: Daytrader7 started: 2024-07-15T15:35:53.514805251Z terminated: 2024-07-15T15:39:40.54619695Z - id: 8 createTime: 2024-07-15T18:29:25.26836735Z name: Daytrader8- kind: language-discovery addon: language-discovery state: Failed application: id: 2 name: Daytrader8 started: 2024-07-15T18:29:25.648121267Z terminated: 2024-07-15T18:29:29.798022283Z errors: 1 - id: 9 createTime: 2024-07-15T18:29:25.26883083Z name: Daytrader8- kind: tech-discovery addon: tech-discovery state: Failed application: id: 2 name: Daytrader8 started: 2024-07-15T18:29:29.798635671Z terminated: 2024-07-15T18:29:32.944556989Z errors: 1 ``` Signed-off-by: Jeff Ortel <[email protected]>
1 parent 662cccf commit 1d3f382

File tree

1 file changed

+118
-10
lines changed

1 file changed

+118
-10
lines changed

api/task.go

Lines changed: 118 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,17 @@ import (
2121

2222
// Routes
2323
const (
24-
TasksRoot = "/tasks"
25-
TasksReportRoot = TasksRoot + "/report"
26-
TasksReportQueueRoot = TasksReportRoot + "/queue"
27-
TaskRoot = TasksRoot + "/:" + ID
28-
TaskReportRoot = TaskRoot + "/report"
29-
TaskAttachedRoot = TaskRoot + "/attached"
30-
TaskBucketRoot = TaskRoot + "/bucket"
31-
TaskBucketContentRoot = TaskBucketRoot + "/*" + Wildcard
32-
TaskSubmitRoot = TaskRoot + "/submit"
33-
TaskCancelRoot = TaskRoot + "/cancel"
24+
TasksRoot = "/tasks"
25+
TasksReportRoot = TasksRoot + "/report"
26+
TasksReportQueueRoot = TasksReportRoot + "/queue"
27+
TasksReportDashboardRoot = TasksReportRoot + "/dashboard"
28+
TaskRoot = TasksRoot + "/:" + ID
29+
TaskReportRoot = TaskRoot + "/report"
30+
TaskAttachedRoot = TaskRoot + "/attached"
31+
TaskBucketRoot = TaskRoot + "/bucket"
32+
TaskBucketContentRoot = TaskBucketRoot + "/*" + Wildcard
33+
TaskSubmitRoot = TaskRoot + "/submit"
34+
TaskCancelRoot = TaskRoot + "/cancel"
3435
)
3536

3637
const (
@@ -54,6 +55,7 @@ func (h TaskHandler) AddRoutes(e *gin.Engine) {
5455
routeGroup.PATCH(TaskRoot, Transaction, h.Update)
5556
routeGroup.DELETE(TaskRoot, h.Delete)
5657
routeGroup.GET(TasksReportQueueRoot, h.Queued)
58+
routeGroup.GET(TasksReportDashboardRoot, h.Dashboard)
5759
// Actions
5860
routeGroup.PUT(TaskSubmitRoot, Transaction, h.Submit)
5961
routeGroup.PUT(TaskCancelRoot, h.Cancel)
@@ -181,6 +183,7 @@ func (h TaskHandler) List(ctx *gin.Context) {
181183
db := h.DB(ctx)
182184
db = db.Model(&model.Task{})
183185
db = db.Joins("Application")
186+
db = db.Joins("Report")
184187
db = sort.Sorted(db)
185188
db = filter.Where(db)
186189
var m model.Task
@@ -272,6 +275,83 @@ func (h TaskHandler) Queued(ctx *gin.Context) {
272275
h.Respond(ctx, http.StatusOK, r)
273276
}
274277

278+
// Dashboard godoc
279+
// @summary List all task dashboard resources.
280+
// @description List all task dashboard resources.
281+
// @description Filters:
282+
// @description - kind
283+
// @description - createUser
284+
// @description - addon
285+
// @description - name
286+
// @description - locator
287+
// @description - state
288+
// @description - application.id
289+
// @description - application.name
290+
// @tags tasks
291+
// @produce json
292+
// @success 200 {object} []api.TaskDashboard
293+
// @router /tasks [get]
294+
func (h TaskHandler) Dashboard(ctx *gin.Context) {
295+
resources := []TaskDashboard{}
296+
// filter
297+
filter, err := qf.New(ctx,
298+
[]qf.Assert{
299+
{Field: "id", Kind: qf.LITERAL},
300+
{Field: "createUser", Kind: qf.STRING},
301+
{Field: "kind", Kind: qf.STRING},
302+
{Field: "addon", Kind: qf.STRING},
303+
{Field: "name", Kind: qf.STRING},
304+
{Field: "locator", Kind: qf.STRING},
305+
{Field: "state", Kind: qf.STRING},
306+
{Field: "application.id", Kind: qf.STRING},
307+
{Field: "application.name", Kind: qf.STRING},
308+
})
309+
if err != nil {
310+
_ = ctx.Error(err)
311+
return
312+
}
313+
filter = filter.Renamed("application.id", "application__id")
314+
filter = filter.Renamed("application.name", "application__name")
315+
filter = filter.Renamed("createUser", "task\\.createUser")
316+
filter = filter.Renamed("id", "task\\.id")
317+
filter = filter.Renamed("name", "task\\.name")
318+
// sort
319+
sort := Sort{}
320+
sort.Add("task.id", "id")
321+
sort.Add("task.createUser", "createUser")
322+
sort.Add("task.name", "name")
323+
sort.Add("application__id", "application.id")
324+
sort.Add("application__name", "application.name")
325+
err = sort.With(ctx, &model.Task{})
326+
if err != nil {
327+
_ = ctx.Error(err)
328+
return
329+
}
330+
// Fetch
331+
db := h.DB(ctx)
332+
db = db.Model(&model.Task{})
333+
db = db.Joins("Application")
334+
db = db.Joins("Report")
335+
db = sort.Sorted(db)
336+
db = filter.Where(db)
337+
var list []model.Task
338+
page := Page{}
339+
page.With(ctx)
340+
err = db.Find(&list).Error
341+
if err != nil {
342+
_ = ctx.Error(err)
343+
return
344+
}
345+
for i := range list {
346+
m := &list[i]
347+
r := TaskDashboard{}
348+
r.With(m)
349+
resources = append(resources, r)
350+
}
351+
352+
h.Respond(ctx, http.StatusOK, resources)
353+
}
354+
275355
// Create godoc
276356
// @summary Create a task.
277357
// @description Create a task.
@@ -496,6 +576,7 @@ func (h TaskHandler) CreateReport(ctx *gin.Context) {
496576
report := &TaskReport{}
497577
err := h.Bind(ctx, report)
498578
if err != nil {
579+
_ = ctx.Error(err)
499580
return
500581
}
501582
report.TaskID = id
@@ -827,3 +908,30 @@ type TaskQueue struct {
827908
Pending int `json:"pending"`
828909
Running int `json:"running"`
829910
}
911+
912+
// TaskDashboard report.
913+
type TaskDashboard struct {
914+
Resource `yaml:",inline"`
915+
Name string `json:"name,omitempty" yaml:",omitempty"`
916+
Kind string `json:"kind,omitempty" yaml:",omitempty"`
917+
Addon string `json:"addon,omitempty" yaml:",omitempty"`
918+
State string `json:"state,omitempty" yaml:",omitempty"`
919+
Locator string `json:"locator,omitempty" yaml:",omitempty"`
920+
Application *Ref `json:"application,omitempty" yaml:",omitempty"`
921+
Started *time.Time `json:"started,omitempty" yaml:",omitempty"`
922+
Terminated *time.Time `json:"terminated,omitempty" yaml:",omitempty"`
923+
Errors int `json:"errors,omitempty" yaml:",omitempty"`
924+
}
925+
926+
func (r *TaskDashboard) With(m *model.Task) {
927+
r.Resource.With(&m.Model)
928+
r.Name = m.Name
929+
r.Kind = m.Kind
930+
r.Addon = m.Addon
931+
r.State = m.State
932+
r.Locator = m.Locator
933+
r.Application = r.refPtr(m.ApplicationID, m.Application)
934+
r.Started = m.Started
935+
r.Terminated = m.Terminated
936+
r.Errors = len(m.Errors)
937+
}

0 commit comments

Comments
 (0)