|
|
@@ -1,10 +1,12 @@
|
|
|
// The package defines an extensible TUI via the bubbletea framework.
|
|
|
//
|
|
|
+// While the package remains in v0.0.X releases, this TUI may be undocumented.
|
|
|
+//
|
|
|
// TODO enable collection recursing (i.e, embedded collections)
|
|
|
//
|
|
|
// TODO enable scroll/viewport logic
|
|
|
//
|
|
|
-// While the package remains in v0.0.X releases, this TUI may be undocumented.
|
|
|
+// TODO enable create new issue from collection browser
|
|
|
package issues
|
|
|
|
|
|
import (
|
|
|
@@ -90,6 +92,15 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|
|
case loadPath:
|
|
|
m.Path = string(msg)
|
|
|
return m, m.load
|
|
|
+ case createInCollectionMsg:
|
|
|
+ wg := createInCollection{Path: string(msg)}
|
|
|
+ i := textinput.New()
|
|
|
+ i.Placeholder = "a short title"
|
|
|
+ i.Focus()
|
|
|
+ i.CharLimit = 80
|
|
|
+ i.Width = 30
|
|
|
+ wg.input = i
|
|
|
+ return m, func() tea.Msg { return wg }
|
|
|
case string:
|
|
|
m.content = msg
|
|
|
}
|
|
|
@@ -106,6 +117,9 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|
|
case IssueCollection:
|
|
|
m.widget, cmd = w.update(msg)
|
|
|
cmds = append(cmds, cmd)
|
|
|
+ case createInCollection:
|
|
|
+ m.widget, cmd = w.update(msg)
|
|
|
+ cmds = append(cmds, cmd, w.render)
|
|
|
}
|
|
|
|
|
|
return m, tea.Batch(cmds...)
|
|
|
@@ -390,6 +404,8 @@ func (c create) editBlankDescription(issue Issue) tea.Cmd {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+func (c create) editExistingDescription(issue Issue) tea.Cmd { return func() tea.Msg { return "" } }
|
|
|
+
|
|
|
// render cmd for create widget
|
|
|
func (c create) render() tea.Msg {
|
|
|
if c.err != nil {
|
|
|
@@ -493,7 +509,8 @@ func (i Issue) keyhelp() string {
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
type ( // Type definitions for use in tea.Msg life cycle for IssueCollection widget.
|
|
|
- loadPath string // thrown when user selects a path to load.
|
|
|
+ loadPath string // thrown when user selects a path to load.
|
|
|
+ createInCollectionMsg string //thrown when user opts to create new issue in collection
|
|
|
)
|
|
|
|
|
|
// enforce widget interface compliance
|
|
|
@@ -520,6 +537,8 @@ func (ic IssueCollection) update(msg tea.Msg) (widget, tea.Cmd) {
|
|
|
return ic, ic.sendLoad
|
|
|
case "q":
|
|
|
return ic, tea.Quit
|
|
|
+ case "c":
|
|
|
+ return ic, ic.newIssueInCollection
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -528,9 +547,13 @@ func (ic IssueCollection) update(msg tea.Msg) (widget, tea.Cmd) {
|
|
|
|
|
|
func (ic IssueCollection) sendLoad() tea.Msg { return loadPath(ic.Path) }
|
|
|
|
|
|
+func (ic IssueCollection) newIssueInCollection() tea.Msg { return createInCollectionMsg(ic.Path) }
|
|
|
+
|
|
|
// render cmd for IssueCollection widget
|
|
|
func (ic IssueCollection) render() tea.Msg {
|
|
|
var output string
|
|
|
+ if ic.selection == -1 {
|
|
|
+ }
|
|
|
var left string
|
|
|
output = output + "Issues in " + ic.Path + "...\n\n"
|
|
|
for i, issue := range ic.Collection {
|
|
|
@@ -554,10 +577,50 @@ func (ic IssueCollection) render() tea.Msg {
|
|
|
// keyhelp cmd for IssueCollection widget
|
|
|
func (ic IssueCollection) keyhelp() string {
|
|
|
var output string
|
|
|
- output = output + "\nj/k: down/up\t\tenter: select\t\tq/ctrl+c: quit"
|
|
|
+ output = output + "\nj/k: down/up\t\tc: create new issue\t\tenter: select\t\tq/ctrl+c: quit"
|
|
|
return output
|
|
|
}
|
|
|
|
|
|
+// -------- createInCollection widget definitions -----------------------------
|
|
|
+// ----------------------------------------------------------------------------
|
|
|
+
|
|
|
+type createInCollection struct {
|
|
|
+ Path string // base path for the new issue
|
|
|
+ name string // the name input by the user
|
|
|
+ input textinput.Model // the input widget
|
|
|
+}
|
|
|
+
|
|
|
+func (w createInCollection) update(msg tea.Msg) (widget, tea.Cmd) {
|
|
|
+ var cmds []tea.Cmd
|
|
|
+
|
|
|
+ switch msg := msg.(type) {
|
|
|
+ case tea.KeyMsg:
|
|
|
+ switch msg.String() {
|
|
|
+ case "enter":
|
|
|
+ cmds = append(cmds, w.create)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ var inputCmd tea.Cmd
|
|
|
+ w.input, inputCmd = w.input.Update(msg)
|
|
|
+ cmds = append(cmds, inputCmd)
|
|
|
+
|
|
|
+ w.name = w.input.Value()
|
|
|
+
|
|
|
+ return w, tea.Batch(cmds...)
|
|
|
+}
|
|
|
+
|
|
|
+func (w createInCollection) create() tea.Msg {
|
|
|
+ w.Path = filepath.Join(w.Path, w.name)
|
|
|
+ return initialCreateWidget(w.Path, "lorem ipsum")
|
|
|
+}
|
|
|
+
|
|
|
+func (w createInCollection) render() tea.Msg {
|
|
|
+ return borderStyle.Render(fmt.Sprintf("Creating new issue in %s\ntitle: %s", w.Path, w.input.View()))
|
|
|
+}
|
|
|
+
|
|
|
+func (w createInCollection) keyhelp() string { return "enter: submit\t\tctrl+c: quit" }
|
|
|
+
|
|
|
// tea.Cmd definitions --------------------------------------------------------
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|