mirror of
https://gitea.com/gitea/tea.git
synced 2026-10-26 11:01:25 +01:00
feat(milestone): milestone tables, views, forms and one selection model
milestone view printed the list row, and milestone list hid the due date and progress. milestone list now shows ID TITLE [STATE] DUE PROGRESS, open milestones first and by due date; milestone view shows the state, due date, progress, description and the milestone's web page (also --web). Every milestone command addresses milestones by title or ID. Mutations report ✓ lines: milestone create also prints the new milestone's URL and takes the title as an argument; close and reopen skip milestones already in that state; delete names the milestone in its confirmation; milestone issue add and remove report one line such as "✓ Added #1, #2 to milestone "v1.0" in alice/x". milestone issue list uses the issue table. milestone edit without flags on a terminal opens the milestone form with the current values, and every milestone command completes milestone titles and has help text with examples. Signed-off-by: bircni <bircni@icloud.com>
This commit is contained in:
14 files changed
+606
-257
No files matched your search
@@ -11,25 +11,30 @@ import (
|
||||
"charm.land/huh/v2"
|
||||
)
|
||||
|
||||
// MilestoneFormValues holds interactively collected milestone create fields.
|
||||
// MilestoneFormValues holds interactively collected milestone fields.
|
||||
type MilestoneFormValues struct {
|
||||
Title, Description string
|
||||
Deadline *time.Time
|
||||
}
|
||||
|
||||
// MilestoneForm collects interactive milestone create input.
|
||||
// MilestoneForm collects interactive milestone input.
|
||||
type MilestoneForm interface {
|
||||
CreateMilestone(context.Context) (MilestoneFormValues, error)
|
||||
// EditMilestone asks for the fields of a milestone, starting from current, under heading, such
|
||||
// as "Editing milestone v1.0". Empty values create a milestone.
|
||||
EditMilestone(ctx context.Context, heading string, current MilestoneFormValues) (MilestoneFormValues, error)
|
||||
}
|
||||
|
||||
// CreateMilestone runs the interactive milestone create form on stderr.
|
||||
func (p *FormPrompter) CreateMilestone(ctx context.Context) (MilestoneFormValues, error) {
|
||||
title, description, deadline := "", "", ""
|
||||
// EditMilestone runs the interactive milestone form on stderr.
|
||||
func (p *FormPrompter) EditMilestone(ctx context.Context, heading string, current MilestoneFormValues) (MilestoneFormValues, error) {
|
||||
title, description, deadline := current.Title, current.Description, ""
|
||||
if current.Deadline != nil {
|
||||
deadline = current.Deadline.Format(time.DateOnly)
|
||||
}
|
||||
if err := p.runForm(ctx, huh.NewForm(huh.NewGroup(
|
||||
huh.NewInput().Title("Milestone title (required):").Value(&title).Validate(huh.ValidateNotEmpty()),
|
||||
huh.NewText().Title("Milestone description (markdown):").Value(&description),
|
||||
bodyField("Milestone description (markdown):", &description),
|
||||
dueDateInput("Milestone deadline:", &deadline),
|
||||
))); err != nil {
|
||||
).Title(heading))); err != nil {
|
||||
return MilestoneFormValues{}, err
|
||||
}
|
||||
parsed, err := parseDueDate(deadline)
|
||||
|
||||
@@ -5,14 +5,26 @@ package terminal
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestMilestoneFormMarksTitleRequired(t *testing.T) {
|
||||
p, rendered := accessiblePrompter(t, "v1\n\n\n")
|
||||
_, err := p.CreateMilestone(context.Background())
|
||||
_, err := p.EditMilestone(context.Background(), "", MilestoneFormValues{})
|
||||
require.NoError(t, err)
|
||||
require.Contains(t, rendered.String(), "Milestone title (required):")
|
||||
}
|
||||
|
||||
func TestMilestoneFormStartsFromCurrentValues(t *testing.T) {
|
||||
due := time.Date(2026, 12, 31, 0, 0, 0, 0, time.UTC)
|
||||
p, _ := testPrompter(strings.NewReader("\r\r\r"))
|
||||
values, err := p.EditMilestone(context.Background(), "Editing milestone v1.0", MilestoneFormValues{Title: "v1.0", Description: "First", Deadline: &due})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "v1.0", values.Title)
|
||||
require.Equal(t, "First", values.Description)
|
||||
require.Equal(t, due, *values.Deadline)
|
||||
}
|
||||
Reference in new issue
Block a user