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
17 changes: 8 additions & 9 deletions internal/commands/checkouts/checkouts.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,12 +179,11 @@ func listCheckouts(ctx context.Context, cmd *cli.Command) error {
})
}

return display.RenderTable(
appCtx.Output,
"Checkouts",
[]string{"ID", "Reference", "Amount", "Status", "Merchant", "Created At"},
rows,
)
return display.RenderTableWithOptions(appCtx.Output, []string{"ID", "Reference", "Amount", "Status", "Merchant", "Created At"}, rows, display.TableOptions{
Title: "Checkouts",
EmptyText: "No items to display",
IdentifierColumns: []int{0},
})
}

func createCheckout(ctx context.Context, cmd *cli.Command) error {
Expand Down Expand Up @@ -364,9 +363,9 @@ func listPaymentMethods(ctx context.Context, cmd *cli.Command) error {
}

return display.RenderTableWithOptions(appCtx.Output, []string{"ID"}, rows, display.TableOptions{
Title: "Checkout Payment Methods",
EmptyText: "No payment methods available",
HighlightIDColumns: true,
Title: "Checkout Payment Methods",
EmptyText: "No payment methods available",
IdentifierColumns: []int{0},
})
}

Expand Down
11 changes: 5 additions & 6 deletions internal/commands/customers/customers.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,12 +238,11 @@ func listPaymentInstruments(ctx context.Context, cmd *cli.Command) error {
})
}

return display.RenderTable(
appCtx.Output,
"Payment Instruments",
[]string{"Token", "Type", "Card", "Active", "Created At"},
rows,
)
return display.RenderTableWithOptions(appCtx.Output, []string{"Token", "Type", "Card", "Active", "Created At"}, rows, display.TableOptions{
Title: "Payment Instruments",
EmptyText: "No items to display",
IdentifierColumns: []int{0},
})
}

func deactivatePaymentInstrument(ctx context.Context, cmd *cli.Command) error {
Expand Down
11 changes: 5 additions & 6 deletions internal/commands/members/members.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,12 +227,11 @@ func listMembers(ctx context.Context, cmd *cli.Command) error {
})
}

return display.RenderTable(
appCtx.Output,
"Members",
[]string{"ID", "Email", "Roles", "Status", "Created At"},
rows,
)
return display.RenderTableWithOptions(appCtx.Output, []string{"ID", "Email", "Roles", "Status", "Created At"}, rows, display.TableOptions{
Title: "Members",
EmptyText: "No items to display",
IdentifierColumns: []int{0},
})
}

func createMember(ctx context.Context, cmd *cli.Command) error {
Expand Down
11 changes: 5 additions & 6 deletions internal/commands/memberships/memberships.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,12 +117,11 @@ func listMemberships(ctx context.Context, cmd *cli.Command) error {
})
}

return display.RenderTable(
appCtx.Output,
"Memberships",
[]string{"ID", "Resource", "Type", "Roles", "Status", "Created At"},
rows,
)
return display.RenderTableWithOptions(appCtx.Output, []string{"ID", "Resource", "Type", "Roles", "Status", "Created At"}, rows, display.TableOptions{
Title: "Memberships",
EmptyText: "No items to display",
IdentifierColumns: []int{0},
})
}

func parseMembershipStatus(value string) (sumup.MembershipStatus, error) {
Expand Down
11 changes: 5 additions & 6 deletions internal/commands/payouts/payouts.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,12 +117,11 @@ func listPayouts(ctx context.Context, cmd *cli.Command) error {
})
}

return display.RenderTable(
appCtx.Output,
"Payouts",
[]string{"ID", "Date", "Amount", "Fee", "Status", "Type", "Reference"},
rows,
)
return display.RenderTableWithOptions(appCtx.Output, []string{"ID", "Date", "Amount", "Fee", "Status", "Type", "Reference"}, rows, display.TableOptions{
Title: "Payouts",
EmptyText: "No items to display",
IdentifierColumns: []int{0},
})
}

func parseDateArg(value string) (datetime.Date, error) {
Expand Down
11 changes: 5 additions & 6 deletions internal/commands/readers/readers.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,12 +233,11 @@ func listReaders(ctx context.Context, cmd *cli.Command) error {
})
}

return display.RenderTable(
appCtx.Output,
"Readers",
[]string{"ID", "Name", "Status", "Model", "Identifier"},
rows,
)
return display.RenderTableWithOptions(appCtx.Output, []string{"ID", "Name", "Status", "Model", "Identifier"}, rows, display.TableOptions{
Title: "Readers",
EmptyText: "No items to display",
IdentifierColumns: []int{0},
})
}

func addReader(ctx context.Context, cmd *cli.Command) error {
Expand Down
11 changes: 5 additions & 6 deletions internal/commands/transactions/transactions.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,12 +158,11 @@ func listTransactions(ctx context.Context, cmd *cli.Command) error {
return display.PrintJSON(appCtx.Output, items)
}

return display.RenderTable(
appCtx.Output,
"Transactions",
[]string{"ID", "Code", "Amount", "Status", "Payment Type", "Created At"},
transactionRows(appCtx, items),
)
return display.RenderTableWithOptions(appCtx.Output, []string{"ID", "Code", "Amount", "Status", "Payment Type", "Created At"}, transactionRows(appCtx, items), display.TableOptions{
Title: "Transactions",
EmptyText: "No items to display",
IdentifierColumns: []int{0},
})
}

func getTransaction(ctx context.Context, cmd *cli.Command) error {
Expand Down
16 changes: 16 additions & 0 deletions internal/display/output_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,22 @@ func TestRenderTableWithOptionsSupportsEmptyTextWithoutTitle(t *testing.T) {
})
}

func TestRenderTableWithOptions(t *testing.T) {
t.Run("styles identifier columns explicitly instead of inferring from headers", func(t *testing.T) {
var out bytes.Buffer

err := display.RenderTableWithOptions(&out, []string{"Token"}, [][]attribute.Value{
{attribute.ValueOf("tok_123")},
}, display.TableOptions{
Title: "Tokens",
IdentifierColumns: []int{0},
})

require.NoError(t, err)
assert.Equal(t, normalizeOutput("Tokens\nToken\ntok_123"), normalizeOutput(out.String()))
})
}

var ansiPattern = regexp.MustCompile(`\x1b\[[0-9;]*m`)

func normalizeOutput(value string) string {
Expand Down
27 changes: 10 additions & 17 deletions internal/display/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,16 @@ const fallbackWidth = 120

// TableOptions customizes human-readable table rendering.
type TableOptions struct {
Title string
EmptyText string
HighlightIDColumns bool
Title string
EmptyText string
IdentifierColumns []int
}

// RenderTable prints rows in a table using the terminal width to wrap columns.
func RenderTable(w io.Writer, title string, headers []string, rows [][]attribute.Value) error {
return RenderTableWithOptions(w, headers, rows, TableOptions{
Title: title,
EmptyText: "No items to display",
HighlightIDColumns: true,
Title: title,
EmptyText: "No items to display",
})
}

Expand All @@ -49,12 +48,10 @@ func RenderTableWithOptions(w io.Writer, headers []string, rows [][]attribute.Va
idStyle := basePadding.Foreground(SumUpPink).Bold(true)
defaultStyle := basePadding

idColumns := make([]bool, len(headers))
if opts.HighlightIDColumns {
for i, header := range headers {
if isIDHeader(header) {
idColumns[i] = true
}
identifierColumns := make(map[int]struct{}, len(opts.IdentifierColumns))
for _, idx := range opts.IdentifierColumns {
if idx >= 0 && idx < len(headers) {
identifierColumns[idx] = struct{}{}
}
}

Expand Down Expand Up @@ -87,7 +84,7 @@ func RenderTableWithOptions(w io.Writer, headers []string, rows [][]attribute.Va
if rowIndex := row - 1; rowIndex >= 0 && rowIndex < len(rows) && col >= 0 && col < len(rows[rowIndex]) {
style = style.Inherit(rows[rowIndex][col].Style)
}
if col >= 0 && col < len(idColumns) && idColumns[col] {
if _, ok := identifierColumns[col]; ok {
style = style.Inherit(idStyle)
}
return style
Expand All @@ -104,7 +101,3 @@ func RenderTableWithOptions(w io.Writer, headers []string, rows [][]attribute.Va
}
return nil
}

func isIDHeader(header string) bool {
return strings.EqualFold(strings.TrimSpace(header), "id")
}