diff --git a/cmd/list/list.go b/cmd/list/list.go index a527414..c67459b 100644 --- a/cmd/list/list.go +++ b/cmd/list/list.go @@ -61,6 +61,15 @@ ID or a comma separated array of IDs, i.e. '7,13'. Multiple values are concatenated with a logical 'OR'. If the IDs are prefixed with an '!' the list is instead filtered to not have the specified status.`) + workPackagesCmd.Flags().BoolVarP( + &includeSubProjects, + "include-sub-projects", + "", + false, + `If listing the work packages of a project, this flag indicates if work +packages of sub projects should be included in the list. If omitting the flag, +the default is false.`) + workPackagesCmd.Flags().BoolVarP( &showTotal, "total", diff --git a/cmd/list/work_packages.go b/cmd/list/work_packages.go index fdc7172..96bed4e 100644 --- a/cmd/list/work_packages.go +++ b/cmd/list/work_packages.go @@ -20,6 +20,7 @@ var version string var showTotal bool var statusFilter string var typeFilter string +var includeSubProjects bool var workPackagesCmd = &cobra.Command{ Use: "workpackages", @@ -35,7 +36,7 @@ func listWorkPackages(_ *cobra.Command, _ []string) { return } - collection, err := work_packages.All(filterOptions()) + collection, err := work_packages.All(filterOptions(), showTotal) switch { case err == nil && showTotal: printer.Number(collection.Total) @@ -49,6 +50,8 @@ func listWorkPackages(_ *cobra.Command, _ []string) { func filterOptions() *map[work_packages.FilterOption]string { options := make(map[work_packages.FilterOption]string) + options[work_packages.IncludeSubProjects] = strconv.FormatBool(includeSubProjects) + if projectId > 0 { options[work_packages.Project] = strconv.FormatUint(projectId, 10) } diff --git a/components/requests/query.go b/components/requests/query.go index b9ddcd1..873088e 100644 --- a/components/requests/query.go +++ b/components/requests/query.go @@ -53,6 +53,10 @@ func filtersQueryAttribute(filters []Filter) string { } func NewQuery(attributes map[string]string, filters []Filter) Query { + if attributes == nil { + return Query{attributes: make(map[string]string), filters: filters} + } + return Query{attributes: attributes, filters: filters} } @@ -64,7 +68,17 @@ func NewFilterQuery(filters []Filter) Query { return Query{attributes: attributes, filters: filters} } -func NewPagedQuery(pageSize int, filters []Filter) Query { +func NewUnpaginatedQuery(attributes map[string]string, filters []Filter) Query { + var attr = attributes + if attr == nil { + attr = make(map[string]string) + } + + attr["pageSize"] = "-1" + return Query{attributes: attr, filters: filters} +} + +func NewPaginatedQuery(pageSize int, filters []Filter) Query { attributes := map[string]string{ "pageSize": fmt.Sprintf("%d", pageSize), } diff --git a/components/requests/query_test.go b/components/requests/query_test.go index 99714c8..9e7f44d 100644 --- a/components/requests/query_test.go +++ b/components/requests/query_test.go @@ -32,13 +32,26 @@ func TestFilterQuery_String_WithoutFilters(t *testing.T) { } } -func TestPagedQuery_String_WithFilters(t *testing.T) { - expectedString := "filters=%5B%7B%22status%22%3A%7B%22operator%22%3A%22%3D%22%2C%22values%22%3A%5B%221%22%2C%223%22%5D%7D%7D%5D&pageSize=-1" +func TestPaginatedQuery_String_WithFilters(t *testing.T) { + expectedString := "filters=%5B%7B%22status%22%3A%7B%22operator%22%3A%22%3D%22%2C%22values%22%3A%5B%221%22%2C%223%22%5D%7D%7D%5D&pageSize=7" filters := []requests.Filter{ work_packages.StatusFilter("1,3"), } - queryString := requests.NewPagedQuery(-1, filters).String() + queryString := requests.NewPaginatedQuery(7, filters).String() + + if queryString != expectedString { + t.Errorf("Expected %s, but got %s", expectedString, queryString) + } +} + +func TestNewUnpaginatedQuery_String_WithFilters(t *testing.T) { + expectedString := "filters=%5B%7B%22status%22%3A%7B%22operator%22%3A%22%3D%22%2C%22values%22%3A%5B%2212%22%2C%223%22%5D%7D%7D%5D&pageSize=-1" + + filters := []requests.Filter{ + work_packages.StatusFilter("12,3"), + } + queryString := requests.NewUnpaginatedQuery(nil, filters).String() if queryString != expectedString { t.Errorf("Expected %s, but got %s", expectedString, queryString) diff --git a/components/resources/projects/functions.go b/components/resources/projects/functions.go index a34a4ab..fbe631b 100644 --- a/components/resources/projects/functions.go +++ b/components/resources/projects/functions.go @@ -9,7 +9,7 @@ import ( ) func All() ([]*models.Project, error) { - query := requests.NewPagedQuery(-1, nil) + query := requests.NewPaginatedQuery(-1, nil) response, err := requests.Get(paths.Projects(), &query) if err != nil { return nil, err diff --git a/components/resources/status/functions.go b/components/resources/status/functions.go index 5ef2290..e6adf2f 100644 --- a/components/resources/status/functions.go +++ b/components/resources/status/functions.go @@ -9,7 +9,7 @@ import ( ) func All() ([]*models.Status, error) { - query := requests.NewPagedQuery(-1, nil) + query := requests.NewPaginatedQuery(-1, nil) response, err := requests.Get(paths.Status(), &query) if err != nil { return nil, err diff --git a/components/resources/types/functions.go b/components/resources/types/functions.go index 339c5d2..dfb0624 100644 --- a/components/resources/types/functions.go +++ b/components/resources/types/functions.go @@ -9,7 +9,7 @@ import ( ) func All() ([]*models.Type, error) { - query := requests.NewPagedQuery(-1, nil) + query := requests.NewPaginatedQuery(-1, nil) response, err := requests.Get(paths.Types(), &query) if err != nil { return nil, err diff --git a/components/resources/work_packages/read.go b/components/resources/work_packages/read.go index a8f63c7..902950e 100644 --- a/components/resources/work_packages/read.go +++ b/components/resources/work_packages/read.go @@ -18,6 +18,7 @@ const ( Project Status Type + IncludeSubProjects ) func Lookup(id uint64) (*models.WorkPackage, error) { @@ -29,12 +30,15 @@ func Lookup(id uint64) (*models.WorkPackage, error) { return workPackage.Convert(), nil } -func All(filterOptions *map[FilterOption]string) (*models.WorkPackageCollection, error) { +func All(filterOptions *map[FilterOption]string, showOnlyTotal bool) (*models.WorkPackageCollection, error) { var filters []requests.Filter var projectId *uint64 + var queryAttributes = make(map[string]string) for updateOpt, value := range *filterOptions { switch updateOpt { + case IncludeSubProjects: + queryAttributes["includeSubprojects"] = value case Assignee: filters = append(filters, AssigneeFilter(value)) case Version: @@ -49,7 +53,13 @@ func All(filterOptions *map[FilterOption]string) (*models.WorkPackageCollection, } } - query := requests.NewFilterQuery(filters) + if showOnlyTotal { + queryAttributes["pageSize"] = "0" + } else { + queryAttributes["pageSize"] = "-1" + } + + query := requests.NewQuery(queryAttributes, filters) requestUrl := paths.WorkPackages()