@@ -122,6 +122,14 @@ type Project struct {
122122 // "projects-template", "personal", "holder-project", "tentative" or
123123 // "global-messages".
124124 Type string `json:"type"`
125+
126+ // Included contains related objects included in the response.
127+ Included struct {
128+ // ProjectCategories contains the categories associated with the project.
129+ //
130+ // The key is the string representation of the project category ID.
131+ ProjectCategories []ProjectCategory `json:"projectCategories"`
132+ }
125133}
126134
127135// ProjectCreateRequest represents the request body for creating a new project.
@@ -645,6 +653,31 @@ func ProjectClone(
645653 return twapi .Execute [ProjectCloneRequest , * ProjectCloneResponse ](ctx , engine , req )
646654}
647655
656+ // ProjectRequestSideload contains the possible sideload options when loading
657+ // projects.
658+ type ProjectRequestSideload string
659+
660+ // List of possible sideload options for ProjectRequestSideload.
661+ const (
662+ ProjectRequestSideloadProjectCategories ProjectRequestSideload = "projectCategories"
663+ )
664+
665+ // ProjectRequestFilters contains the filters for loading projects.
666+ type ProjectRequestFilters struct {
667+ // Include specifies related resources to include.
668+ Include []ProjectRequestSideload
669+ }
670+
671+ func (p ProjectRequestFilters ) apply (req * http.Request ) {
672+ query := req .URL .Query ()
673+ if len (p .Include ) > 0 {
674+ for _ , include := range p .Include {
675+ query .Add ("include" , string (include ))
676+ }
677+ }
678+ req .URL .RawQuery = query .Encode ()
679+ }
680+
648681// ProjectGetRequestPath contains the path parameters for loading a single
649682// project.
650683type ProjectGetRequestPath struct {
@@ -658,6 +691,9 @@ type ProjectGetRequestPath struct {
658691type ProjectGetRequest struct {
659692 // Path contains the path parameters for the request.
660693 Path ProjectGetRequestPath
694+
695+ // Filters contains the filters for loading a single project.
696+ Filters ProjectRequestFilters
661697}
662698
663699// NewProjectGetRequest creates a new ProjectGetRequest with the provided
@@ -678,6 +714,7 @@ func (p ProjectGetRequest) HTTPRequest(ctx context.Context, server string) (*htt
678714 if err != nil {
679715 return nil , err
680716 }
717+ p .Filters .apply (req )
681718
682719 return req , nil
683720}
@@ -715,6 +752,8 @@ func ProjectGet(
715752
716753// ProjectListRequestFilters contains the filters for loading multiple projects.
717754type ProjectListRequestFilters struct {
755+ ProjectRequestFilters
756+
718757 // ProjectCategoryIDs is an optional list of project category IDs to filter
719758 // projects by categories.
720759 ProjectCategoryIDs []int64
@@ -737,6 +776,39 @@ type ProjectListRequestFilters struct {
737776 PageSize int64
738777}
739778
779+ func (p ProjectListRequestFilters ) apply (req * http.Request ) {
780+ p .ProjectRequestFilters .apply (req )
781+
782+ query := req .URL .Query ()
783+ if len (p .ProjectCategoryIDs ) > 0 {
784+ categoryIDs := make ([]string , len (p .ProjectCategoryIDs ))
785+ for i , id := range p .ProjectCategoryIDs {
786+ categoryIDs [i ] = strconv .FormatInt (id , 10 )
787+ }
788+ query .Set ("projectCategoryIds" , strings .Join (categoryIDs , "," ))
789+ }
790+ if p .SearchTerm != "" {
791+ query .Set ("searchTerm" , p .SearchTerm )
792+ }
793+ if len (p .TagIDs ) > 0 {
794+ tagIDs := make ([]string , len (p .TagIDs ))
795+ for i , id := range p .TagIDs {
796+ tagIDs [i ] = strconv .FormatInt (id , 10 )
797+ }
798+ query .Set ("projectTagIds" , strings .Join (tagIDs , "," ))
799+ }
800+ if p .MatchAllTags != nil {
801+ query .Set ("matchAllProjectTags" , strconv .FormatBool (* p .MatchAllTags ))
802+ }
803+ if p .Page > 0 {
804+ query .Set ("page" , strconv .FormatInt (p .Page , 10 ))
805+ }
806+ if p .PageSize > 0 {
807+ query .Set ("pageSize" , strconv .FormatInt (p .PageSize , 10 ))
808+ }
809+ req .URL .RawQuery = query .Encode ()
810+ }
811+
740812// ProjectListRequest represents the request body for loading multiple projects.
741813//
742814// https://apidocs.teamwork.com/docs/teamwork/v3/projects/get-projects-api-v3-projects-json
@@ -763,35 +835,7 @@ func (p ProjectListRequest) HTTPRequest(ctx context.Context, server string) (*ht
763835 if err != nil {
764836 return nil , err
765837 }
766-
767- query := req .URL .Query ()
768- if len (p .Filters .ProjectCategoryIDs ) > 0 {
769- categoryIDs := make ([]string , len (p .Filters .ProjectCategoryIDs ))
770- for i , id := range p .Filters .ProjectCategoryIDs {
771- categoryIDs [i ] = strconv .FormatInt (id , 10 )
772- }
773- query .Set ("projectCategoryIds" , strings .Join (categoryIDs , "," ))
774- }
775- if p .Filters .SearchTerm != "" {
776- query .Set ("searchTerm" , p .Filters .SearchTerm )
777- }
778- if len (p .Filters .TagIDs ) > 0 {
779- tagIDs := make ([]string , len (p .Filters .TagIDs ))
780- for i , id := range p .Filters .TagIDs {
781- tagIDs [i ] = strconv .FormatInt (id , 10 )
782- }
783- query .Set ("projectTagIds" , strings .Join (tagIDs , "," ))
784- }
785- if p .Filters .MatchAllTags != nil {
786- query .Set ("matchAllProjectTags" , strconv .FormatBool (* p .Filters .MatchAllTags ))
787- }
788- if p .Filters .Page > 0 {
789- query .Set ("page" , strconv .FormatInt (p .Filters .Page , 10 ))
790- }
791- if p .Filters .PageSize > 0 {
792- query .Set ("pageSize" , strconv .FormatInt (p .Filters .PageSize , 10 ))
793- }
794- req .URL .RawQuery = query .Encode ()
838+ p .Filters .apply (req )
795839
796840 return req , nil
797841}
0 commit comments