@@ -19,40 +19,109 @@ import (
1919 "fmt"
2020 "time"
2121
22+ "github.com/chainloop-dev/chainloop/app/cli/cmd/options"
2223 "github.com/chainloop-dev/chainloop/app/cli/internal/action"
24+
2325 "github.com/jedib0t/go-pretty/v6/table"
2426 "github.com/spf13/cobra"
2527)
2628
2729func newOrganizationMemberList () * cobra.Command {
30+ var (
31+ paginationOpts = & options.OffsetPaginationOpts {}
32+ name string
33+ email string
34+ role string
35+ )
36+
2837 cmd := & cobra.Command {
2938 Use : "list" ,
3039 Aliases : []string {"ls" },
3140 Short : "List the members of the current organization" ,
41+ Example : ` # Let the default pagination apply
42+ chainloop organization member list
43+
44+ # Specify the page and page size
45+ chainloop organization member list --page 2 --limit 10
46+
47+ # Filter by name
48+ chainloop organization member list --name alice
49+
50+ # Filter by email
51+ chainloop organization member list --email alice@example.com
52+
53+ # Filter by role
54+ chainloop organization member list --role admin
55+
56+ # Combine filters and pagination
57+ chainloop organization member list --role admin --page 2 --limit 5
58+ ` ,
59+ PreRunE : func (_ * cobra.Command , _ []string ) error {
60+ if paginationOpts .Page < 1 {
61+ return fmt .Errorf ("--page must be greater or equal than 1" )
62+ }
63+ if paginationOpts .Limit < 1 {
64+ return fmt .Errorf ("--limit must be greater or equal than 1" )
65+ }
66+
67+ return nil
68+ },
3269 RunE : func (cmd * cobra.Command , args []string ) error {
33- res , err := action .NewMembershipList (actionOpts ).ListMembers (cmd .Context ())
70+ opts := & action.ListMembersOpts {}
71+
72+ switch {
73+ case name != "" :
74+ opts .Name = & name
75+ case email != "" :
76+ opts .Email = & email
77+ case role != "" :
78+ opts .Role = & role
79+ }
80+
81+ res , err := action .NewMembershipList (actionOpts ).ListMembers (cmd .Context (), paginationOpts .Page , paginationOpts .Limit , opts )
3482 if err != nil {
3583 return err
3684 }
3785
38- return encodeOutput (res , orgMembershipsTableOutput )
86+ if err := encodeOutput (res , orgMembershipsTableOutput ); err != nil {
87+ return err
88+ }
89+
90+ pgResponse := res .PaginationMeta
91+
92+ if pgResponse .TotalPages >= paginationOpts .Page {
93+ inPage := min (paginationOpts .Limit , len (res .Memberships ))
94+ lowerBound := (paginationOpts .Page - 1 ) * paginationOpts .Limit
95+ logger .Info ().Msg (fmt .Sprintf ("Showing [%d-%d] out of %d" , lowerBound + 1 , lowerBound + inPage , pgResponse .TotalCount ))
96+ }
97+
98+ if pgResponse .TotalCount > pgResponse .Page * pgResponse .PageSize {
99+ logger .Info ().Msg (fmt .Sprintf ("Next page available: %d" , pgResponse .Page + 1 ))
100+ }
101+
102+ return nil
39103 },
40104 }
41105
106+ cmd .Flags ().StringVar (& name , "name" , "" , "Filter by member name or last name" )
107+ cmd .Flags ().StringVar (& email , "email" , "" , "Filter by member email" )
108+ cmd .Flags ().StringVar (& role , "role" , "" , fmt .Sprintf ("Role of the user in the organization, available %s" , action .AvailableRoles [:3 ]))
109+ paginationOpts .AddFlags (cmd )
110+
42111 return cmd
43112}
44113
45- func orgMembershipsTableOutput (items []* action.MembershipItem ) error {
46- if len (items ) == 0 {
47- fmt .Println (UserWithNoOrganizationMsg )
48- return nil
49- }
50-
114+ func orgMembershipsTableOutput (res * action.ListMembershipResult ) error {
51115 t := newTableWriter ()
52116 t .AppendHeader (table.Row {"ID" , "Email" , "Role" , "Joined At" })
53117
54- for _ , i := range items {
55- t .AppendRow (table.Row {i .ID , i .User .PrintUserProfileWithEmail (), i .Role , i .CreatedAt .Format (time .RFC822 )})
118+ for _ , m := range res .Memberships {
119+ t .AppendRow (table.Row {
120+ m .ID ,
121+ m .User .PrintUserProfileWithEmail (),
122+ m .Role ,
123+ m .CreatedAt .Format (time .RFC822 ),
124+ })
56125 t .AppendSeparator ()
57126 }
58127
0 commit comments