Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions internal/messages/messages.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ type EntryUpdatedMsg struct {
Entry models.Entry
}

type EntryCopyStartedMsg struct {
Entry models.Entry
}

// =====================================
// Modal messages
// =====================================
Expand Down
6 changes: 6 additions & 0 deletions internal/ui/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,12 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.viewport.SetContent(m.renderContent())
return m, nil

case messages.EntryCopyStartedMsg:
m.showModal = true
m.modal = modal.CopyEntryForm(m.config, m.projects, msg.Entry)
m.viewport.SetContent(m.renderContent())
return m, nil

case messages.EntryDeleteStartedMsg:
m.showModal = true
m.modal = modal.NewDeleteConfirmation(msg.EntryId)
Expand Down
36 changes: 36 additions & 0 deletions internal/ui/components/entryform/entryform.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,42 @@ func New(cfg *config.Config, projects []models.Project) Model {
}
}

func (m Model) CopyEntry(entry models.Entry) Model {
m.editing = false

m.selectedEntry = entry

m.description.SetValue(entry.Description)

// Setup Calendar
m.calendar.SetSelectedDay(entry.TimeInterval.Start.In(time.Local))

// Pre-fill time inputs
startStr := entry.TimeInterval.Start.In(time.Local).Format("3:04 PM")
endStr := entry.TimeInterval.End.In(time.Local).Format("3:04 PM")
m.timeStart.SetValue(startStr)
m.timeEnd.SetValue(endStr)

// Find and select the project
for i, proj := range m.projects {
if proj.ID == entry.ProjectID {
m.selectedProj = proj
m.selectedProjID = i
break
}
}

// Find the cursor position for the project
for i, proj := range m.projects {
if proj.ID == entry.ProjectID {
m.cursor = i
break
}
}

return m
}

func (m Model) UpdateEntry(entry models.Entry) Model {
m.editing = true

Expand Down
5 changes: 5 additions & 0 deletions internal/ui/components/help/keybindings.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ var Global = GlobalKeyMap{
type EntryKeyMap struct {
Delete key.Binding
Edit key.Binding
Copy key.Binding
New key.Binding
Up key.Binding
Down key.Binding
Expand Down Expand Up @@ -86,6 +87,10 @@ var Entry = EntryKeyMap{
key.WithKeys("e"),
key.WithHelp("e", "Edit entry"),
),
Copy: key.NewBinding(
key.WithKeys("c"),
key.WithHelp("c", "Copy entry"),
),
Delete: key.NewBinding(
key.WithKeys("d"),
key.WithHelp("d", "Delete entry"),
Expand Down
19 changes: 19 additions & 0 deletions internal/ui/components/modal/modal.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,25 @@ func UpdateEntryForm(cfg *config.Config, projects []models.Project, entry models
}
}

func CopyEntryForm(cfg *config.Config, projects []models.Project, entry models.Entry) *Model {
form := entryform.New(cfg, projects)
form = form.CopyEntry(entry)
viewport := viewport.New(0, styles.ModalHeight)
viewport.SetContent(form.View())

if viewport.Height > viewport.TotalLineCount() {
viewport.Height = viewport.TotalLineCount()
viewport.SetContent(form.View())
}

return &Model{
modalType: EntryModal,
entryForm: &form,
viewport: viewport,
title: "Copy Entry",
}
}

func NewDeleteConfirmation(entryId string) *Model {
deleteConfirmation := confirmation.New(entryId, "entry")
viewport := viewport.New(0, 4)
Expand Down
9 changes: 9 additions & 0 deletions internal/ui/views/entries/entries.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,15 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
return messages.EntryDeleteStartedMsg{EntryId: selectedEntry.ID}
}
}
case "c":
// Copy the selected entry
if len(m.entries) > 0 {
selectedEntry := m.entries[m.list.Index()]
// Open the edit modal
return m, func() tea.Msg {
return messages.EntryCopyStartedMsg{Entry: selectedEntry}
}
}
}

case messages.EntriesLoadedMsg:
Expand Down
Loading