Msot recent execution output on the dashboard. (#238)
* feature: Support for most recent action output on dashboard * feature: Support for most recent action output on dashboard
This commit is contained in:
parent
471d5726f6
commit
f15235d120
|
|
@ -137,6 +137,7 @@ message WatchExecutionUpdate {
|
||||||
|
|
||||||
message ExecutionStatusRequest {
|
message ExecutionStatusRequest {
|
||||||
string execution_tracking_id = 1;
|
string execution_tracking_id = 1;
|
||||||
|
string action_id = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message ExecutionStatusResponse {
|
message ExecutionStatusResponse {
|
||||||
|
|
|
||||||
|
|
@ -142,16 +142,40 @@ func internalLogEntryToPb(logEntry *executor.InternalLogEntry) *pb.LogEntry {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getExecutionStatusByTrackingID(api *oliveTinAPI, executionTrackingId string) *executor.InternalLogEntry {
|
||||||
|
logEntry, ok := api.executor.Logs[executionTrackingId]
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return logEntry
|
||||||
|
}
|
||||||
|
|
||||||
|
func getMostRecentExecutionStatusById(api *oliveTinAPI, actionId string) *executor.InternalLogEntry {
|
||||||
|
var ile *executor.InternalLogEntry
|
||||||
|
|
||||||
|
for _, candidateLe := range api.executor.Logs {
|
||||||
|
if actionId == candidateLe.ActionId {
|
||||||
|
ile = candidateLe
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ile
|
||||||
|
}
|
||||||
|
|
||||||
func (api *oliveTinAPI) ExecutionStatus(ctx ctx.Context, req *pb.ExecutionStatusRequest) (*pb.ExecutionStatusResponse, error) {
|
func (api *oliveTinAPI) ExecutionStatus(ctx ctx.Context, req *pb.ExecutionStatusRequest) (*pb.ExecutionStatusResponse, error) {
|
||||||
res := &pb.ExecutionStatusResponse{}
|
res := &pb.ExecutionStatusResponse{}
|
||||||
|
|
||||||
logEntry, ok := api.executor.Logs[req.ExecutionTrackingId]
|
var ile *executor.InternalLogEntry
|
||||||
|
|
||||||
if !ok {
|
if req.ExecutionTrackingId != "" {
|
||||||
return res, nil
|
ile = getExecutionStatusByTrackingID(api, req.ExecutionTrackingId)
|
||||||
|
} else {
|
||||||
|
ile = getMostRecentExecutionStatusById(api, req.ActionId)
|
||||||
}
|
}
|
||||||
|
|
||||||
res.LogEntry = internalLogEntryToPb(logEntry)
|
res.LogEntry = internalLogEntryToPb(ile)
|
||||||
|
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package grpcapi
|
||||||
import (
|
import (
|
||||||
pb "github.com/OliveTin/OliveTin/gen/grpc"
|
pb "github.com/OliveTin/OliveTin/gen/grpc"
|
||||||
config "github.com/OliveTin/OliveTin/internal/config"
|
config "github.com/OliveTin/OliveTin/internal/config"
|
||||||
|
"golang.org/x/exp/slices"
|
||||||
)
|
)
|
||||||
|
|
||||||
func dashboardCfgToPb(res *pb.GetDashboardComponentsResponse, dashboards []*config.DashboardComponent) {
|
func dashboardCfgToPb(res *pb.GetDashboardComponentsResponse, dashboards []*config.DashboardComponent) {
|
||||||
|
|
@ -37,14 +38,19 @@ func getDashboardComponentContents(dashboard *config.DashboardComponent) []*pb.D
|
||||||
}
|
}
|
||||||
|
|
||||||
func getDashboardComponentType(item *config.DashboardComponent) string {
|
func getDashboardComponentType(item *config.DashboardComponent) string {
|
||||||
|
allowedTypes := []string{
|
||||||
|
"stdout-most-recent-execution",
|
||||||
|
"display",
|
||||||
|
}
|
||||||
|
|
||||||
if len(item.Contents) > 0 {
|
if len(item.Contents) > 0 {
|
||||||
if item.Type != "fieldset" {
|
if item.Type != "fieldset" {
|
||||||
return "directory"
|
return "directory"
|
||||||
}
|
}
|
||||||
|
|
||||||
return "fieldset"
|
return "fieldset"
|
||||||
} else if item.Type == "display" {
|
} else if slices.Contains(allowedTypes, item.Type) {
|
||||||
return "display"
|
return item.Type
|
||||||
}
|
}
|
||||||
|
|
||||||
return "link"
|
return "link"
|
||||||
|
|
|
||||||
|
|
@ -199,6 +199,50 @@ function marshalLink (item, fieldset) {
|
||||||
fieldset.appendChild(btn)
|
fieldset.appendChild(btn)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function marshalMreOutput (dashboardComponent, fieldset) {
|
||||||
|
const pre = document.createElement('pre')
|
||||||
|
pre.classList.add('mre-output')
|
||||||
|
pre.innerHTML = 'Waiting...'
|
||||||
|
|
||||||
|
const executionStatus = {
|
||||||
|
actionId: dashboardComponent.title
|
||||||
|
}
|
||||||
|
|
||||||
|
window.fetch(window.restBaseUrl + 'ExecutionStatus', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify(executionStatus)
|
||||||
|
}).then((res) => {
|
||||||
|
if (res.ok) {
|
||||||
|
return res.json()
|
||||||
|
} else {
|
||||||
|
pre.innerHTML = 'error'
|
||||||
|
|
||||||
|
throw new Error(res.statusText)
|
||||||
|
}
|
||||||
|
}).then((json) => {
|
||||||
|
updateMre(pre, json.logEntry)
|
||||||
|
})
|
||||||
|
|
||||||
|
const updateMre = (pre, json) => {
|
||||||
|
pre.innerHTML = json.stdout
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('ExecutionFinished', (e) => {
|
||||||
|
// The dashboard component "title" field is used for lots of things
|
||||||
|
// and in this context for MreOutput it's just to refer an an actionId.
|
||||||
|
//
|
||||||
|
// So this is not a typo.
|
||||||
|
if (e.payload.actionId === dashboardComponent.title) {
|
||||||
|
updateMre(pre, e.payload)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
fieldset.appendChild(pre)
|
||||||
|
}
|
||||||
|
|
||||||
function marshalContainerContents (json, section, fieldset, parentDashboard) {
|
function marshalContainerContents (json, section, fieldset, parentDashboard) {
|
||||||
for (const item of json.contents) {
|
for (const item of json.contents) {
|
||||||
switch (item.type) {
|
switch (item.type) {
|
||||||
|
|
@ -212,6 +256,9 @@ function marshalContainerContents (json, section, fieldset, parentDashboard) {
|
||||||
case 'display':
|
case 'display':
|
||||||
marshalDisplay(item, fieldset)
|
marshalDisplay(item, fieldset)
|
||||||
break
|
break
|
||||||
|
case 'stdout-most-recent-execution':
|
||||||
|
marshalMreOutput(item, fieldset)
|
||||||
|
break
|
||||||
case 'link':
|
case 'link':
|
||||||
marshalLink(item, fieldset)
|
marshalLink(item, fieldset)
|
||||||
break
|
break
|
||||||
|
|
|
||||||
|
|
@ -429,6 +429,7 @@ pre {
|
||||||
padding: 1em;
|
padding: 1em;
|
||||||
min-height: 1em;
|
min-height: 1em;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
td.exit-code {
|
td.exit-code {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue