in commands/issue/board/view/issue_board_view.go [48:196]
func NewCmdView(f *cmdutils.Factory) *cobra.Command {
opts := &issueBoardViewOptions{}
viewCmd := &cobra.Command{
Use: "view [flags]",
Short: `View project issue board.`,
Long: ``,
RunE: func(cmd *cobra.Command, args []string) error {
var err error
a := tview.NewApplication()
defer recoverPanic(a)
apiClient, err = f.HttpClient()
if err != nil {
return err
}
repo, err = f.BaseRepo()
if err != nil {
return err
}
project, err = api.GetProject(apiClient, repo.FullName())
if err != nil {
return fmt.Errorf("failed to get project: %w", err)
}
// list the groups that are ancestors to project:
// https://docs.gitlab.com/api/projects/#list-groups
projectGroups, err := api.ListProjectsGroups(
apiClient,
project.ID,
&gitlab.ListProjectGroupOptions{},
)
if err != nil {
return err
}
// get issue boards related to project and parent groups
// https://docs.gitlab.com/api/group_boards/#list-group-issue-board-lists
projectIssueBoards, err := getProjectIssueBoards()
if err != nil {
return fmt.Errorf("getting project issue boards: %w", err)
}
projectGroupIssueBoards, err := getGroupIssueBoards(projectGroups, apiClient)
if err != nil {
return fmt.Errorf("getting project issue boards: %w", err)
}
// prompt user to select issue board
menuOptions, boardMetaMap := mapBoardData(projectIssueBoards, projectGroupIssueBoards)
selection, err := selectBoard(menuOptions)
if err != nil {
return fmt.Errorf("selecting issue board: %w", err)
}
selectedBoard := boardMetaMap[selection]
boardLists, err := getBoardLists(selectedBoard)
if err != nil {
return fmt.Errorf("getting issue board lists: %w", err)
}
root := tview.NewFlex()
root.SetBackgroundColor(tcell.ColorDefault)
for _, l := range boardLists {
opts.state = ""
var boardIssues, listTitle, listColor string
if l.Label == nil {
continue
}
if l.Label != nil {
listTitle = l.Label.Name
listColor = l.Label.Color
}
// automatically request using state for default "open" and "closed" lists
// this is required as these lists aren't returned with the board lists api call
switch l.Label.Name {
case "Closed":
opts.state = closed
case "Open":
opts.state = opened
}
issues := []*gitlab.Issue{}
if selectedBoard.group != nil {
groupID := selectedBoard.group.ID
issues, err = getGroupBoardIssues(groupID, opts)
if err != nil {
return fmt.Errorf("getting issue board lists: %w", err)
}
}
if selectedBoard.group == nil {
issues, err = getProjectBoardIssues(opts)
if err != nil {
return fmt.Errorf("getting issue board lists: %w", err)
}
}
boardIssues = filterIssues(boardLists, issues, l, opts)
bx := tview.NewTextView()
bx.
SetDynamicColors(true).
SetText(boardIssues).
SetWrap(true).
SetBackgroundColor(tcell.ColorDefault).
SetBorder(true).
SetTitle(listTitle).
SetTitleColor(tcell.GetColor(listColor))
root.AddItem(bx, 0, 1, false)
}
// format table title
caser := cases.Title(language.English)
var boardType, boardContext string
if selectedBoard.group != nil {
boardType = caser.String("group")
boardContext = project.Namespace.Name
} else {
boardType = caser.String("project")
boardContext = project.NameWithNamespace
}
root.SetBorderPadding(1, 1, 2, 2).SetBorder(true).SetTitle(
fmt.Sprintf(" %s • %s ", caser.String(boardType+" issue board"), boardContext),
)
screen, err := tcell.NewScreen()
if err != nil {
return err
}
if err := a.SetScreen(screen).SetRoot(root, true).Run(); err != nil {
return err
}
return nil
},
}
viewCmd.Flags().
StringVarP(&opts.assignee, "assignee", "a", "", "Filter board issues by assignee username.")
viewCmd.Flags().
StringSliceVarP(&opts.labels, "labels", "l", []string{}, "Filter board issues by labels, comma separated.")
viewCmd.Flags().
StringVarP(&opts.milestone, "milestone", "m", "", "Filter board issues by milestone.")
return viewCmd
}