submitview

package
v0.0.7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 30, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package submitview implements the interactive single-screen TUI used by `gh stack submit` to create a stack of pull requests. A left-hand timeline lists the stack and lets the user choose which branches without a PR should become PRs; the right-hand editor drafts each PR's title, description, and ready/draft state before a single batch submit.

The package builds on the shared Charm components in internal/tui/shared and reuses the branch display data loaded by internal/tui/stackview. The submit command supplies the per-PR overrides this package produces; the underlying push/create/relink engine is unchanged.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func BuildDrafts

func BuildDrafts(nodes []SubmitNode) map[string]*PRDraft

BuildDrafts returns the per-branch overrides for every NEW branch, keyed by branch name. Non-NEW branches are omitted because their PRs are never modified by the TUI.

func ClosedBranches

func ClosedBranches(nodes []SubmitNode) []string

ClosedBranches returns the names of branches with a closed PR, in list order.

func CountNew

func CountNew(nodes []SubmitNode) int

CountNew returns the number of NEW (creatable) branches in the list.

func CountSelected

func CountSelected(nodes []SubmitNode) int

CountSelected returns the number of NEW branches currently marked for inclusion.

func HasClosed

func HasClosed(nodes []SubmitNode) bool

HasClosed reports whether any branch in the list has a closed PR, which blocks the stack and triggers the closed-branch callout.

func PrefillDescription

func PrefillDescription(node stackview.BranchNode, template string) string

PrefillDescription returns the default PR description for a new branch: the repo PR template if one exists, otherwise the body of the branch's single commit, otherwise empty. Multi-commit branches with no template get an empty description (no bulleted commit list). This mirrors the non-TUI submit. The attribution footer is appended later, at submit time.

func PrefillTitle

func PrefillTitle(node stackview.BranchNode) string

PrefillTitle returns the default PR title for a new branch: the subject of its single commit when the branch has exactly one commit, otherwise the humanized branch name. This mirrors the non-TUI submit's defaultPRTitleBody.

func RenderBadge

func RenderBadge(s BranchState) string

RenderBadge renders a state as a pill badge: the uppercase label in the state color on a tinted background with single-column horizontal padding.

func RenderDot

func RenderDot(s BranchState) string

RenderDot renders the state's legend glyph in the state color.

Types

type BranchState

type BranchState int

BranchState classifies a branch by the status of its pull request. The state determines whether a branch is selectable and editable in the TUI, and which badge color it renders with.

const (
	// StateNew is a branch with no PR yet. It is the only interactive state:
	// selectable (default on) and editable.
	StateNew BranchState = iota
	// StateOpen is a branch with an open (non-draft) PR. Locked, shown for context.
	StateOpen
	// StateDraft is a branch with a draft PR. Locked, shown for context.
	StateDraft
	// StateQueued is a branch whose PR is in a merge queue. Locked.
	StateQueued
	// StateMerged is a branch whose PR has merged. Locked, historical context.
	StateMerged
	// StateClosed is a branch with a closed PR. It blocks the stack and is
	// neither selectable nor editable.
	StateClosed
)

func DeriveState

func DeriveState(node stackview.BranchNode) BranchState

DeriveState classifies a branch node into a BranchState using both the stack's tracked PR reference and any freshly fetched PR details. Merged and queued states take priority, followed by closed, draft, and open. A branch with no PR at all is NEW. A branch that tracks a PR but for which no fresh details are available is treated as open (locked) rather than NEW, so it is never presented as editable.

func (BranchState) Blocks

func (s BranchState) Blocks() bool

Blocks reports whether a branch in this state blocks the stack. Only closed PRs block.

func (BranchState) Color

Color returns the foreground color associated with a state.

func (BranchState) Dot

func (s BranchState) Dot() string

Dot returns the compact status glyph for a state.

func (BranchState) Editable

func (s BranchState) Editable() bool

Editable reports whether a branch in this state opens the editor. Only NEW branches are editable.

func (BranchState) Label

func (s BranchState) Label() string

Label returns the uppercase badge text for a state (e.g. "NEW").

func (BranchState) Locked

func (s BranchState) Locked() bool

Locked reports whether a branch is shown for context only (open, draft, queued, or merged). Closed is handled separately because it blocks the stack.

func (BranchState) Selectable

func (s BranchState) Selectable() bool

Selectable reports whether a branch in this state can be toggled for inclusion. Only NEW branches are selectable.

type Model

type Model struct {
	// contains filtered or unexported fields
}

Model is the Bubble Tea model backing the interactive `gh stack submit` TUI.

func New

func New(opts Options) Model

New constructs a submit TUI model from the given options. The single screen opens immediately with the first branch focused (preferring the first NEW branch) and the title field ready for editing.

func (Model) Cancelled

func (m Model) Cancelled() bool

Cancelled reports whether the user quit without submitting.

func (Model) Init

func (m Model) Init() tea.Cmd

func (Model) Nodes

func (m Model) Nodes() []SubmitNode

Nodes returns the current per-branch state, from which the command builds the per-PR overrides.

func (Model) SubmitRequested

func (m Model) SubmitRequested() bool

SubmitRequested reports whether the user confirmed the batch submit.

func (Model) Update

func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd)

func (Model) View

func (m Model) View() string

type Options

type Options struct {
	// Nodes is the branch list in display order (index 0 = top of stack).
	Nodes []SubmitNode
	// Trunk is the stack's trunk branch, shown for context.
	Trunk stack.BranchRef
	// RepoLabel is the "owner/repo" string shown in the header.
	RepoLabel string
	// Version is the CLI version string.
	Version string
}

Options configures a new submit TUI model.

type PRDraft

type PRDraft struct {
	// Branch is the head branch the PR will be created from.
	Branch string
	// Include reports whether to create a PR for this branch. Deselected NEW
	// branches are still pushed for stack consistency but get no PR.
	Include bool
	// Title is the PR title.
	Title string
	// Body is the user-authored PR description, without the attribution footer.
	Body string
	// Draft reports whether the PR should be created as a draft.
	Draft bool
}

PRDraft is the per-branch override the TUI hands back to the submit command. The command's create path consumes these instead of auto-generating titles and bodies. The attribution footer is appended by the command at submit time, so Body holds only the user-authored description.

type SubmitNode

type SubmitNode struct {
	stackview.BranchNode

	// State is the derived PR state for this branch.
	State BranchState

	// Included reports whether a PR should be created for this branch on
	// submit. Only meaningful for StateNew branches; defaults to true.
	Included bool

	// Title and Description hold the in-progress PR draft, prefilled from the
	// branch's commits and the repo PR template (see data.go).
	Title       string
	Description string

	// Draft is the per-PR "Open as draft" toggle.
	Draft bool

	// Submitted is set once this branch's PR has been created during the
	// current session. It drives the inline "✓ready" tag in the stack map.
	Submitted bool
	// contains filtered or unexported fields
}

SubmitNode wraps a stackview.BranchNode with the per-branch UI state used by the submit TUI: its derived state, inclusion, the in-progress title and description draft, and the draft toggle. Prefill snapshots are retained so the model can detect unsaved edits for the quit confirmation.

func NewSubmitNodes

func NewSubmitNodes(nodes []stackview.BranchNode, template string) []SubmitNode

NewSubmitNodes builds the per-branch UI state for the submit TUI from loaded branch display data. NEW branches default to included; new PRs have their title and description prefilled from commits and the PR template, while existing PRs show their real title and description fetched from the API. New PRs default to ready for review; the per-PR draft toggle starts off. The prefill snapshots are retained for edit detection.

func (SubmitNode) Edited

func (n SubmitNode) Edited() bool

Edited reports whether the user has changed any field of this NEW branch from its prefilled defaults: title, description, draft toggle, or inclusion. Non-NEW branches are never editable and so are never considered edited.

func (SubmitNode) ToDraft

func (n SubmitNode) ToDraft() PRDraft

ToDraft converts a SubmitNode into the command-layer PRDraft override.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL