working on simManage

This commit is contained in:
STEINNI
2026-06-21 21:09:21 +00:00
parent 06a7868882
commit e2f8766b9f
17 changed files with 484 additions and 51 deletions
+192 -2
View File
@@ -1,14 +1,204 @@
class ManageSimView extends WindozDomContent {
#lifecycleEventTypes = [
'onYourMarks',
'bigBang',
'simulationPaused',
'simulationResumed',
'simulationStopped',
'simulationPrepareFailed',
]
constructor() {
super()
Object.assign(this, app.helpers.basicDialogs)
Object.assign(this, app.helpers.activeAttributes, app.helpers.basicDialogs)
this.lifecycleChan = app.Assets.Store.json.busChannels.maestro.lifecycleChannel
this.lifecycleChan = this.lifecycleChan.replace(/\[UID\]/g, app.User.identity.uuid)
}
async DOMContentLoaded(options) {
this.models = options.models
this.wasBlured = false
this._refreshSeq = 0
this.lifecycleSubscribed = false
ui.eicfy(this.el)
// TODO: implement
const view = this
this.simGrid = new DataGrid(this.find('.sim-list'), {
headers: [
{ label: 'Simulation', sortable: true },
{ label: 'Primordial frame', sortable: true },
{ label: 'Owner', sortable: true },
{ label: 'Status', sortable: true },
{ label: '', sortable: false },
],
height: '480px',
rowActions: [
{
icon: '<i class="icon-play"></i>',
title: 'Start simulation',
severity: 'success',
callback: async function(event) {
await view.onPlaySim(this, event.currentTarget)
},
},
{
icon: '<i class="icon-pause"></i>',
title: 'Pause simulation',
severity: 'secondary',
callback: async function(event) {
await view.onPauseSim(this, event.currentTarget)
},
},
{
icon: '<i class="icon-stop"></i>',
title: 'Stop simulation',
severity: 'danger',
callback: async function(event) {
await view.onStopSim(this, event.currentTarget)
},
},
],
})
this.simGrid.enableFooter = false
await this.refreshSimList()
}
async DOMContentFocused() {
await this.subscribeLifecycle()
if(!this.wasBlured) return
this.wasBlured = false
this.refreshSimList()
}
async DOMContentBlured() {
this.wasBlured = true
await this.unsubscribeLifecycle()
}
async subscribeLifecycle() {
if(this.lifecycleSubscribed || !app.MessageBus?.connected) return
await app.MessageBus.subscribe([this.lifecycleChan])
for(const eventType of this.#lifecycleEventTypes) {
app.MessageBus.addBusListener(eventType, [this.lifecycleChan], this.lifecycleListener, 'ManageSimView')
}
this.lifecycleSubscribed = true
}
async unsubscribeLifecycle() {
if(!this.lifecycleSubscribed || !app.MessageBus?.connected) return
for(const eventType of this.#lifecycleEventTypes) {
app.MessageBus.removeBusListener(eventType, this.lifecycleListener, 'ManageSimView')
}
await app.MessageBus.unSubscribe([this.lifecycleChan])
this.lifecycleSubscribed = false
}
lifecycleListener(realChan, payload, sender) {
console.log('[ManageSimView] maestro lifecycle', { realChan, payload, sender })
}
async refreshSimList() {
const seq = ++this._refreshSeq
this.simGrid.loading = true
this.simGrid.clear()
try {
const data = await this.models.sims.list()
if(seq !== this._refreshSeq) return
const sims = data?.payload ?? []
this.simGrid.clear()
for(const sim of sims) {
const row = this.simGrid.addRow(
{ simulationUuid: sim.simulationUuid },
[
sim.sim_name ?? '',
sim.ekf_name ?? '',
sim.usr_name ?? '',
sim.state ?? 'idle',
],
true
)
this.updateSimButtons(sim.state ?? 'idle', row)
}
this.simGrid.updateFilters()
} finally {
if(seq === this._refreshSeq) this.simGrid.loading = false
}
}
updateSimButtons(state, rowEl) {
const buttons = rowEl?.querySelectorAll('.cell.actions button[eicbutton]')
if(!buttons || buttons.length < 3) return
const enabledByState = {
idle: [true, false, false],
preparing: [false, false, false],
live: [false, true, true],
paused: [true, false, true],
}
const enabled = enabledByState[state] ?? [false, false, false]
for(let i = 0; i < 3; i++) {
buttons[i].disabled = !enabled[i]
}
}
async onPlaySim(rowId, button) {
const simulationUuid = rowId?.simulationUuid
if(!simulationUuid) return
const row = button.closest('.row')
button.disabled = true
try {
const result = await this.models.sims.startSimulation(simulationUuid)
ui.growl.append(
`Simulation started (${result.agentIds?.length ?? 0} agent(s))`,
'success',
4000
)
await this.refreshSimList()
} catch(err) {
ui.growl.append(String(err), 'error', 6000)
const state = row?.querySelectorAll('.cell')[4]?.innerText?.trim() || 'idle'
this.updateSimButtons(state, row)
}
}
async onPauseSim(rowId, button) {
const simulationUuid = rowId?.simulationUuid
if(!simulationUuid) return
const row = button.closest('.row')
button.disabled = true
try {
await this.models.sims.pauseSimulation(simulationUuid)
ui.growl.append('Simulation paused', 'success', 3000)
await this.refreshSimList()
} catch(err) {
ui.growl.append(String(err), 'error', 6000)
const state = row?.querySelectorAll('.cell')[4]?.innerText?.trim() || 'idle'
this.updateSimButtons(state, row)
}
}
async onStopSim(rowId, button) {
const simulationUuid = rowId?.simulationUuid
if(!simulationUuid) return
const row = button.closest('.row')
button.disabled = true
try {
await this.models.sims.stopSimulation(simulationUuid)
ui.growl.append('Simulation stopped', 'success', 3000)
await this.refreshSimList()
} catch(err) {
ui.growl.append(String(err), 'error', 6000)
const state = row?.querySelectorAll('.cell')[4]?.innerText?.trim() || 'idle'
this.updateSimButtons(state, row)
}
}
}