mirror of
https://github.com/RWejlgaard/org.git
synced 2026-09-02 01:15:35 +00:00
feat: add DONE state option and done marker to settings
This commit is contained in:
parent
517b60ecd9
commit
5d8e64f8a1
4 changed files with 74 additions and 4 deletions
|
|
@ -498,6 +498,18 @@ func (c *Config) AddState(name, color string) {
|
|||
c.States.States = append(c.States.States, StateConfig{Name: name, Color: color})
|
||||
}
|
||||
|
||||
// AddDoneState adds (or upgrades) a state and marks it as a done state.
|
||||
func (c *Config) AddDoneState(name, color string) {
|
||||
for i := range c.States.States {
|
||||
if c.States.States[i].Name == name {
|
||||
c.States.States[i].Color = color
|
||||
c.States.States[i].Done = true
|
||||
return
|
||||
}
|
||||
}
|
||||
c.States.States = append(c.States.States, StateConfig{Name: name, Color: color, Done: true})
|
||||
}
|
||||
|
||||
// RemoveState removes a state from the configuration
|
||||
func (c *Config) RemoveState(name string) {
|
||||
for i, state := range c.States.States {
|
||||
|
|
|
|||
|
|
@ -49,3 +49,25 @@ func TestFillDefaultsLeavesExplicitDoneFlagsAlone(t *testing.T) {
|
|||
t.Error("last state (TODO) must NOT be auto-flagged when a done state already exists")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAddDoneState(t *testing.T) {
|
||||
c := &Config{}
|
||||
c.AddDoneState("CANCELLED", "240")
|
||||
|
||||
if len(c.States.States) != 1 {
|
||||
t.Fatalf("expected 1 state, got %d", len(c.States.States))
|
||||
}
|
||||
s := c.States.States[0]
|
||||
if s.Name != "CANCELLED" || s.Color != "240" || !s.Done {
|
||||
t.Fatalf("unexpected state: %+v", s)
|
||||
}
|
||||
|
||||
// Adding an existing name upgrades it to done.
|
||||
c.AddState("REVIEW", "99")
|
||||
c.AddDoneState("REVIEW", "99")
|
||||
for _, st := range c.States.States {
|
||||
if st.Name == "REVIEW" && !st.Done {
|
||||
t.Fatal("expected REVIEW upgraded to done")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ type uiModel struct {
|
|||
captureCursor int // Store cursor position when entering capture mode
|
||||
datepicker datepicker.Model
|
||||
dateTextFocused bool // within set-date modes: text field focused vs. calendar
|
||||
addingDoneState bool // within add-state flow: create a done state
|
||||
}
|
||||
|
||||
func InitialModel(orgFile *model.OrgFile, cfg *config.Config, captureMode bool, captureText string) uiModel {
|
||||
|
|
|
|||
|
|
@ -107,7 +107,12 @@ func (m *uiModel) updateSettings(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||
case settingsSectionTags:
|
||||
m.addNewTag()
|
||||
case settingsSectionStates:
|
||||
m.addNewState()
|
||||
// Rows: [0]=default state, [1..N]=states, [N+1]=add state, [N+2]=add DONE state.
|
||||
if m.settingsCursor == len(m.config.States.States)+2 {
|
||||
m.addNewDoneState()
|
||||
} else {
|
||||
m.addNewState()
|
||||
}
|
||||
case settingsSectionKeybindings:
|
||||
// Cannot add keybindings yet
|
||||
}
|
||||
|
|
@ -136,7 +141,7 @@ func (m *uiModel) getSettingsItemCount() int {
|
|||
case settingsSectionTags:
|
||||
return len(m.config.Tags.Tags) + 1 // +1 for "Add new tag" option
|
||||
case settingsSectionStates:
|
||||
return len(m.config.States.States) + 2 // +1 for "Default new task state" setting, +1 for "Add new state" option
|
||||
return len(m.config.States.States) + 3 // default state + "Add new state" + "Add new DONE state"
|
||||
case settingsSectionKeybindings:
|
||||
return len(m.config.GetAllKeybindings())
|
||||
default:
|
||||
|
|
@ -474,6 +479,7 @@ func (m *uiModel) addNewTag() {
|
|||
|
||||
// addNewState adds a new state
|
||||
func (m *uiModel) addNewState() {
|
||||
m.addingDoneState = false
|
||||
m.textinput.SetValue("")
|
||||
m.textinput.Placeholder = "Enter state name"
|
||||
m.textinput.Focus()
|
||||
|
|
@ -483,6 +489,16 @@ func (m *uiModel) addNewState() {
|
|||
m.mode = modeSettingsAddState
|
||||
}
|
||||
|
||||
// addNewDoneState adds a new state that is marked as done.
|
||||
func (m *uiModel) addNewDoneState() {
|
||||
m.addingDoneState = true
|
||||
m.textinput.SetValue("")
|
||||
m.textinput.Placeholder = "Enter DONE state name"
|
||||
m.textinput.Focus()
|
||||
m.textinput.Blur()
|
||||
m.mode = modeSettingsAddState
|
||||
}
|
||||
|
||||
// viewSettings renders the settings view
|
||||
func (m *uiModel) viewSettings() string {
|
||||
var content strings.Builder
|
||||
|
|
@ -697,7 +713,7 @@ func (m *uiModel) viewSettingsStates() string {
|
|||
}
|
||||
|
||||
endIdx := m.settingsScroll + availableHeight
|
||||
totalItems := len(m.config.States.States) + 2 // +1 for default state, +1 for "Add new state"
|
||||
totalItems := len(m.config.States.States) + 3 // +1 for default state, +1 for "Add new state", +1 for "Add new DONE state"
|
||||
|
||||
// First show the default new task state setting (item 0)
|
||||
if 0 >= m.settingsScroll && 0 < endIdx {
|
||||
|
|
@ -741,6 +757,9 @@ func (m *uiModel) viewSettingsStates() string {
|
|||
stateStyle := lipgloss.NewStyle().Foreground(lipgloss.Color(state.Color))
|
||||
line += stateStyle.Render(state.Name)
|
||||
line += fmt.Sprintf(" (color: %s)", state.Color)
|
||||
if state.Done {
|
||||
line += m.styles.statusStyle.Render(" ✓done")
|
||||
}
|
||||
|
||||
content.WriteString(line + "\n")
|
||||
}
|
||||
|
|
@ -756,6 +775,17 @@ func (m *uiModel) viewSettingsStates() string {
|
|||
content.WriteString(m.styles.statusStyle.Render("+ Add new state (press 'c')") + "\n")
|
||||
}
|
||||
|
||||
// Add new DONE state option
|
||||
addDoneIdx := len(m.config.States.States) + 2
|
||||
if addDoneIdx >= m.settingsScroll && addDoneIdx < endIdx {
|
||||
if m.settingsCursor == addDoneIdx && !m.textinput.Focused() {
|
||||
content.WriteString("▶ ")
|
||||
} else {
|
||||
content.WriteString(" ")
|
||||
}
|
||||
content.WriteString(m.styles.statusStyle.Render("+ Add new DONE state (press 'c')") + "\n")
|
||||
}
|
||||
|
||||
// Add scroll indicator if needed
|
||||
if totalItems > availableHeight {
|
||||
scrollInfo := fmt.Sprintf("\n[Showing %d-%d of %d]",
|
||||
|
|
@ -916,7 +946,11 @@ func (m *uiModel) updateSettingsAddState(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||
stateName := m.textinput.Value()
|
||||
if stateName != "" {
|
||||
// Default color
|
||||
m.config.AddState(stateName, "99")
|
||||
if m.addingDoneState {
|
||||
m.config.AddDoneState(stateName, "99")
|
||||
} else {
|
||||
m.config.AddState(stateName, "99")
|
||||
}
|
||||
// Auto-save
|
||||
if err := m.config.Save(); err != nil {
|
||||
m.setStatus(fmt.Sprintf("Error saving: %v", err))
|
||||
|
|
@ -924,6 +958,7 @@ func (m *uiModel) updateSettingsAddState(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||
m.setStatus(fmt.Sprintf("Added state '%s' (saved)", stateName))
|
||||
}
|
||||
}
|
||||
m.addingDoneState = false
|
||||
m.textinput.Blur()
|
||||
m.mode = modeSettings
|
||||
return m, nil
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue