feat(tui): add interactive run mode for checklists and fill mode for templates
Run mode (r key on checklist cards): cursor navigates steps, space toggles done/undone, r resets all, esc saves changes to DB and exits. Persists step state — improvement over web which discards on exit. Fill mode (f key on template cards): tab/shift-tab navigates slots, type to fill values, enter resolves template and copies to clipboard with use count increment. Esc cancels without copying. Both modes are sub-states of detail view, keeping architecture simple.
This commit is contained in:
+60
-11
@@ -216,6 +216,16 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
m.state = stateAbsorb
|
||||
return m, nil
|
||||
|
||||
case stepsPersistedMsg:
|
||||
m.status = "steps saved"
|
||||
m.detail.mode = detailPreview
|
||||
return m, m.reloadDetail(m.detail.entity.ID)
|
||||
|
||||
case templateCopiedMsg:
|
||||
m.status = "copied resolved"
|
||||
m.detail.mode = detailPreview
|
||||
return m, loadEntities(m.store, m.listParams())
|
||||
|
||||
case tagsLoadedMsg:
|
||||
m.filter.setTags(msg.tags)
|
||||
m.state = stateTagFilter
|
||||
@@ -328,6 +338,18 @@ func (m model) updateKeys(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
|
||||
|
||||
case "esc":
|
||||
if m.state == stateDetail {
|
||||
if m.detail.mode == detailRun {
|
||||
var cmd tea.Cmd
|
||||
if m.detail.run.dirty {
|
||||
cmd = persistSteps(m.store, m.detail.run.entityID, m.detail.run.stepsJSON())
|
||||
}
|
||||
m.detail.mode = detailPreview
|
||||
return m, cmd
|
||||
}
|
||||
if m.detail.mode == detailFill {
|
||||
m.detail.mode = detailPreview
|
||||
return m, nil
|
||||
}
|
||||
m.state = stateList
|
||||
return m, nil
|
||||
}
|
||||
@@ -349,15 +371,6 @@ func (m model) updateKeys(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
|
||||
}
|
||||
return m, nil
|
||||
|
||||
case "enter":
|
||||
if m.state == stateList {
|
||||
if e := m.selectedEntity(); e != nil {
|
||||
m.detail.setEntity(e)
|
||||
m.state = stateDetail
|
||||
}
|
||||
}
|
||||
return m, nil
|
||||
|
||||
case "d":
|
||||
if m.state == stateList {
|
||||
if e := m.selectedEntity(); e != nil {
|
||||
@@ -435,10 +448,44 @@ func (m model) updateKeys(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
|
||||
return m, nil
|
||||
|
||||
case "e":
|
||||
if m.state == stateDetail && m.detail.entity != nil {
|
||||
if m.state == stateDetail && m.detail.entity != nil && m.detail.mode == detailPreview {
|
||||
return m, editInEditor(m.store, m.detail.entity)
|
||||
}
|
||||
return m, nil
|
||||
|
||||
case "r":
|
||||
if m.state == stateDetail && m.detail.entity != nil && m.detail.mode == detailPreview {
|
||||
if m.detail.entity.CardType != nil && *m.detail.entity.CardType == db.CardChecklist {
|
||||
m.detail.run = newRunModel(m.detail.entity.ID, m.detail.entity.CardData)
|
||||
m.detail.mode = detailRun
|
||||
return m, nil
|
||||
}
|
||||
}
|
||||
return m, nil
|
||||
|
||||
case "f":
|
||||
if m.state == stateDetail && m.detail.entity != nil && m.detail.mode == detailPreview {
|
||||
if m.detail.entity.CardType != nil && *m.detail.entity.CardType == db.CardTemplate {
|
||||
m.detail.fill = newFillModel(m.detail.entity.ID, m.detail.entity.Body)
|
||||
m.detail.mode = detailFill
|
||||
return m, m.detail.fill.ti.Focus()
|
||||
}
|
||||
}
|
||||
return m, nil
|
||||
|
||||
case "enter":
|
||||
if m.state == stateDetail && m.detail.mode == detailFill {
|
||||
m.detail.fill.commitActive()
|
||||
resolved := m.detail.fill.resolve()
|
||||
return m, copyResolved(m.store, m.detail.fill.entityID, resolved)
|
||||
}
|
||||
if m.state == stateList {
|
||||
if e := m.selectedEntity(); e != nil {
|
||||
m.detail.setEntity(e)
|
||||
m.state = stateDetail
|
||||
}
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
switch m.state {
|
||||
@@ -449,7 +496,9 @@ func (m model) updateKeys(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
|
||||
m.list = m.list.update(msg)
|
||||
}
|
||||
case stateDetail:
|
||||
m.detail = m.detail.update(msg)
|
||||
var cmd tea.Cmd
|
||||
m.detail, cmd = m.detail.update(msg)
|
||||
return m, cmd
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user