Script execution list
This commit is contained in:
parent
13a5b9a973
commit
55724b36b5
8 changed files with 517 additions and 14 deletions
|
|
@ -10,6 +10,7 @@ export class App {
|
|||
this.typesList = null
|
||||
this.scriptsList = null
|
||||
this.scriptEditor = null
|
||||
this.scriptExecutionList = null
|
||||
|
||||
this.currentNode = null
|
||||
this.currentNodeID = null
|
||||
|
|
@ -21,6 +22,7 @@ export class App {
|
|||
|
||||
const events = [
|
||||
'EDITOR_NODE_SAVE',
|
||||
'EXECUTIONS_LIST_FETCHED',
|
||||
'MENU_ITEM_SELECTED',
|
||||
'NODE_CONNECT',
|
||||
'NODE_COPY_PATH',
|
||||
|
|
@ -102,6 +104,11 @@ export class App {
|
|||
this.nodeUpdate()
|
||||
break
|
||||
|
||||
case 'EXECUTIONS_LIST_FETCHED':
|
||||
const executions = document.getElementById('script-executions')
|
||||
executions.replaceChildren(this.scriptExecutionList.render())
|
||||
break
|
||||
|
||||
case 'TYPES_LIST_FETCHED':
|
||||
const types = document.getElementById('types')
|
||||
types.replaceChildren(this.typesList.render())
|
||||
|
|
@ -258,6 +265,18 @@ export class App {
|
|||
this.scriptsList.fetchScripts()
|
||||
.catch(err => showError(err))
|
||||
break
|
||||
|
||||
case 'script-execution':
|
||||
document.getElementById('script-executions').classList.add('show')
|
||||
|
||||
if (this.scriptExecutionList === null)
|
||||
this.scriptExecutionList = new ScriptExecutionList()
|
||||
this.scriptExecutionList.fetchExecutions()
|
||||
.then(() => {
|
||||
mbus.dispatch('EXECUTIONS_LIST_FETCHED')
|
||||
})
|
||||
.catch(err => showError(err))
|
||||
break
|
||||
}
|
||||
}// }}}
|
||||
|
||||
|
|
@ -1532,4 +1551,164 @@ class ScriptHookDialog extends Component {
|
|||
}// }}}
|
||||
}
|
||||
|
||||
class ScriptExecutionList extends Component {
|
||||
constructor() {// {{{
|
||||
super()
|
||||
this.executions = []
|
||||
}// }}}
|
||||
async fetchExecutions() {// {{{
|
||||
return new Promise((resolve, reject) => {
|
||||
window._app.query('/scriptexecutions/')
|
||||
.then(data => {
|
||||
this.executions = data.ScriptExecutions
|
||||
resolve()
|
||||
})
|
||||
.catch(err => reject(err))
|
||||
})
|
||||
}// }}}
|
||||
renderComponent() {// {{{
|
||||
const tmpl = document.createElement('template')
|
||||
tmpl.innerHTML = `
|
||||
<div class="label">Script executions</div>
|
||||
<div class="executions">
|
||||
<div class="header">ID</div>
|
||||
<div class="header">SSH</div>
|
||||
<div class="header">Script</div>
|
||||
<div class="header">Start</div>
|
||||
<div class="header">End</div>
|
||||
<div class="header">Script</div>
|
||||
<div class="header">Data</div>
|
||||
<div class="header">Env</div>
|
||||
<div class="header">Out</div>
|
||||
<div class="header">Err</div>
|
||||
<div class="header">Exitcode</div>
|
||||
</div>
|
||||
`
|
||||
const executions = tmpl.content.querySelector('.executions')
|
||||
|
||||
for (const e of this.executions) {
|
||||
const se = new ScriptExecution(e)
|
||||
executions.append(se.render())
|
||||
}
|
||||
|
||||
return tmpl.content
|
||||
}// }}}
|
||||
}
|
||||
|
||||
class ScriptExecution extends Component {
|
||||
constructor(execution) {// {{{
|
||||
super()
|
||||
this.execution = execution
|
||||
}// }}}
|
||||
formatTime(t) {// {{{
|
||||
const d = new Date(t)
|
||||
const year = d.getYear() + 1900
|
||||
const month = `0${d.getMonth() + 1}`.slice(-2)
|
||||
const date = `0${d.getDate()}`.slice(-2)
|
||||
const hour = `0${d.getHours()}`.slice(-2)
|
||||
const min = `0${d.getMinutes()}`.slice(-2)
|
||||
const sec = `0${d.getSeconds()}`.slice(-2)
|
||||
return `<span class="date">${year}-${month}-${date}</span> <span class="time">${hour}:${min}:${sec}</span>`
|
||||
}// }}}
|
||||
icon(name) {// {{{
|
||||
return `<img src="/images/${_VERSION}/node_modules/@mdi/svg/svg/${name}.svg" />`
|
||||
}// }}}
|
||||
renderComponent() {// {{{
|
||||
const tmpl = document.createElement('template')
|
||||
|
||||
tmpl.innerHTML = `
|
||||
<div class="id">${this.execution.ID}</div>
|
||||
<div class="ssh">${this.execution.SSH}</div>
|
||||
<div class="name">${this.execution.ScriptName}</div>
|
||||
<div class="start">${this.formatTime(this.execution.TimeStart.Time)}</div>
|
||||
<div class="end">${this.formatTime(this.execution.TimeEnd.Time)}</div>
|
||||
<div class="source">${this.execution.HasSource ? this.icon('bash') : ''}</div>
|
||||
<div class="data">${this.execution.HasData ? this.icon('code-json') : ''}</div>
|
||||
<div class="env">${this.execution.HasEnv ? this.icon('application-braces-outline') : ''}</div>
|
||||
<div class="stdout">${this.execution.HasOutputStdout ? this.icon('text-box-check-outline') : ''}</div>
|
||||
<div class="stderr">${this.execution.HasOutputStderr ? this.icon('text-box-remove-outline') : ''}</div>
|
||||
<div class="exitcode"><div class="code-${this.execution.ExitCode.Int16 == 0 ? 'ok' : 'error'}">${this.execution.ExitCode.Int16}</div></div>
|
||||
`
|
||||
|
||||
const classValues = new Map()
|
||||
classValues.set('source', 'Source')
|
||||
classValues.set('data', 'Data')
|
||||
classValues.set('env', 'Env')
|
||||
classValues.set('stdout', 'OutputStdout')
|
||||
classValues.set('stderr', 'OutputStderr')
|
||||
|
||||
for (const [cls, value] of classValues) {
|
||||
tmpl.content.querySelector(`.${cls}`).addEventListener('click', () => {
|
||||
new ScriptExecutionValueDialog(this.execution, value).render()
|
||||
})
|
||||
}
|
||||
|
||||
return tmpl.content
|
||||
}// }}}
|
||||
}
|
||||
|
||||
class ScriptExecutionValueDialog extends Component {
|
||||
constructor(execution, valueName) {// {{{
|
||||
super()
|
||||
this.execution = execution
|
||||
this.valueName = valueName
|
||||
|
||||
this.dlg = document.createElement('dialog')
|
||||
this.dlg.id = 'script-execution-value-dialog'
|
||||
this.dlg.addEventListener('close', () => this.dlg.remove())
|
||||
|
||||
this.value = null
|
||||
}// }}}
|
||||
getValue(execution) {
|
||||
switch (this.valueName) {
|
||||
case 'Source':
|
||||
return execution.Source
|
||||
|
||||
case 'Data':
|
||||
case 'Env':
|
||||
return JSON.stringify(
|
||||
JSON.parse(execution[this.valueName])
|
||||
,
|
||||
null,
|
||||
' '
|
||||
)
|
||||
|
||||
case 'OutputStdout':
|
||||
case 'OutputStderr':
|
||||
return execution[this.valueName]?.String
|
||||
}
|
||||
}
|
||||
renderComponent() {// {{{
|
||||
const div = document.createElement('div')
|
||||
div.innerHTML = `
|
||||
<div class="top">
|
||||
<div class="header">${this.valueName}</div>
|
||||
<img class="copy" src="/images/${_VERSION}/node_modules/@mdi/svg/svg/content-copy.svg" />
|
||||
</div>
|
||||
<div class="label">${this.execution.ID}</div>
|
||||
<div class="value"></div>
|
||||
`
|
||||
|
||||
this.value = div.querySelector('.value')
|
||||
div.querySelector('.copy').addEventListener('click', event=>{
|
||||
event.target.classList.add('clicked')
|
||||
setTimeout(()=>event.target.classList.remove('clicked'), 250)
|
||||
navigator.clipboard.writeText(this.value.innerText)
|
||||
})
|
||||
|
||||
window._app.query(`/scriptexecutions/${this.execution.ID}`)
|
||||
.then(data => {
|
||||
this.value.innerText = this.getValue(data.ScriptExecution)
|
||||
})
|
||||
.catch(err => showError(err))
|
||||
|
||||
this.dlg.append(...div.children)
|
||||
document.body.append(this.dlg)
|
||||
this.dlg.showModal()
|
||||
|
||||
return []
|
||||
}// }}}
|
||||
}
|
||||
|
||||
|
||||
// vim: foldmethod=marker
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue