Skip to content

Commit c925f5d

Browse files
committed
Enhancement: Allow sideloading custom fields
When requesting information from tasks, companies or projects, allow side loading custom fields. Related to: #81
1 parent 77418d4 commit c925f5d

3 files changed

Lines changed: 147 additions & 1 deletion

File tree

projects/company.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,32 @@ func CompanyDelete(
425425
return twapi.Execute[CompanyDeleteRequest, *CompanyDeleteResponse](ctx, engine, req)
426426
}
427427

428+
// CompanyRequestSideload contains the possible sideload options when loading
429+
// companies.
430+
type CompanyRequestSideload string
431+
432+
// List of possible sideload options for CompanyRequestSideload.
433+
const (
434+
CompanyRequestSideloadCompanyCustomFields CompanyRequestSideload = "customfields"
435+
CompanyRequestSideloadCompanyCustomFieldValues CompanyRequestSideload = "customfieldcompanies"
436+
)
437+
438+
// CompanyRequestFilters contains the filters for loading companies.
439+
type CompanyRequestFilters struct {
440+
// Include specifies related resources to include.
441+
Include []CompanyRequestSideload
442+
}
443+
444+
func (p CompanyRequestFilters) apply(req *http.Request) {
445+
query := req.URL.Query()
446+
if len(p.Include) > 0 {
447+
for _, include := range p.Include {
448+
query.Add("include", string(include))
449+
}
450+
}
451+
req.URL.RawQuery = query.Encode()
452+
}
453+
428454
// CompanyGetRequestPath contains the path parameters for loading a single company.
429455
type CompanyGetRequestPath struct {
430456
// ID is the unique identifier of the company to be retrieved.
@@ -438,6 +464,9 @@ type CompanyGetRequestPath struct {
438464
type CompanyGetRequest struct {
439465
// Path contains the path parameters for the request.
440466
Path CompanyGetRequestPath
467+
468+
// Filters contains the filters for loading a single company.
469+
Filters CompanyRequestFilters
441470
}
442471

443472
// NewCompanyGetRequest creates a new CompanyGetRequest with the provided
@@ -458,6 +487,7 @@ func (c CompanyGetRequest) HTTPRequest(ctx context.Context, server string) (*htt
458487
if err != nil {
459488
return nil, err
460489
}
490+
c.Filters.apply(req)
461491

462492
return req, nil
463493
}
@@ -467,6 +497,19 @@ func (c CompanyGetRequest) HTTPRequest(ctx context.Context, server string) (*htt
467497
// https://apidocs.teamwork.com/docs/teamwork/v3/companies/get-projects-api-v3-companies-company-id-json
468498
type CompanyGetResponse struct {
469499
Company Company `json:"company"`
500+
501+
// Included contains related objects included in the response.
502+
Included struct {
503+
// CustomFields contains the custom fields associated with the company.
504+
//
505+
// The key is the string representation of the custom field ID.
506+
CustomFields map[string]CustomField `json:"customfields,omitempty"`
507+
// CustomFieldValues contains the values of the custom fields associated
508+
// with the company.
509+
//
510+
// The key is the string representation of the custom field value ID.
511+
CustomFieldValues map[string]CustomFieldValue `json:"customfieldCompanies,omitempty"`
512+
} `json:"included"`
470513
}
471514

472515
// HandleHTTPResponse handles the HTTP response for the CompanyGetResponse. If
@@ -496,6 +539,8 @@ func CompanyGet(
496539
// CompanyListRequestFilters contains the filters for loading multiple
497540
// clients/companies.
498541
type CompanyListRequestFilters struct {
542+
CompanyRequestFilters
543+
499544
// SearchTerm is an optional search term to filter clients/companies by name.
500545
SearchTerm string
501546

@@ -514,6 +559,8 @@ type CompanyListRequestFilters struct {
514559
}
515560

516561
func (c CompanyListRequestFilters) apply(req *http.Request) {
562+
c.CompanyRequestFilters.apply(req)
563+
517564
query := req.URL.Query()
518565
if c.SearchTerm != "" {
519566
query.Set("searchTerm", c.SearchTerm)
@@ -576,12 +623,28 @@ func (c CompanyListRequest) HTTPRequest(ctx context.Context, server string) (*ht
576623
type CompanyListResponse struct {
577624
request CompanyListRequest
578625

626+
// Meta contains metadata about the response, including pagination details.
579627
Meta struct {
580628
Page struct {
581629
HasMore bool `json:"hasMore"`
582630
} `json:"page"`
583631
} `json:"meta"`
632+
633+
// Companies is the list of companies matching the request filters.
584634
Companies []Company `json:"companies"`
635+
636+
// Included contains related objects included in the response.
637+
Included struct {
638+
// CustomFields contains the custom fields associated with the company.
639+
//
640+
// The key is the string representation of the custom field ID.
641+
CustomFields map[string]CustomField `json:"customfields,omitempty"`
642+
// CustomFieldValues contains the values of the custom fields associated
643+
// with the company.
644+
//
645+
// The key is the string representation of the custom field value ID.
646+
CustomFieldValues map[string]CustomFieldValue `json:"customfieldCompanies,omitempty"`
647+
} `json:"included"`
585648
}
586649

587650
// HandleHTTPResponse handles the HTTP response for the CompanyListResponse. If

projects/project.go

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -651,7 +651,9 @@ type ProjectRequestSideload string
651651

652652
// List of possible sideload options for ProjectRequestSideload.
653653
const (
654-
ProjectRequestSideloadProjectCategories ProjectRequestSideload = "projectCategories"
654+
ProjectRequestSideloadProjectCategories ProjectRequestSideload = "projectCategories"
655+
ProjectRequestSideloadProjectCustomFields ProjectRequestSideload = "customfields"
656+
ProjectRequestSideloadProjectCustomFieldValues ProjectRequestSideload = "customfieldprojects"
655657
)
656658

657659
// ProjectRequestFilters contains the filters for loading projects.
@@ -723,6 +725,15 @@ type ProjectGetResponse struct {
723725
//
724726
// The key is the string representation of the project category ID.
725727
ProjectCategories map[string]ProjectCategory `json:"projectCategories,omitempty"`
728+
// CustomFields contains the custom fields associated with the project.
729+
//
730+
// The key is the string representation of the custom field ID.
731+
CustomFields map[string]CustomField `json:"customfields,omitempty"`
732+
// CustomFieldValues contains the values of the custom fields associated
733+
// with the project.
734+
//
735+
// The key is the string representation of the custom field value ID.
736+
CustomFieldValues map[string]CustomFieldValue `json:"customfieldProjects,omitempty"`
726737
} `json:"included"`
727738
}
728739

@@ -863,6 +874,15 @@ type ProjectListResponse struct {
863874
//
864875
// The key is the string representation of the project category ID.
865876
ProjectCategories map[string]ProjectCategory `json:"projectCategories,omitempty"`
877+
// CustomFields contains the custom fields associated with the project.
878+
//
879+
// The key is the string representation of the custom field ID.
880+
CustomFields map[string]CustomField `json:"customfields,omitempty"`
881+
// CustomFieldValues contains the values of the custom fields associated
882+
// with the project.
883+
//
884+
// The key is the string representation of the custom field value ID.
885+
CustomFieldValues map[string]CustomFieldValue `json:"customfieldProjects,omitempty"`
866886
} `json:"included"`
867887
}
868888

projects/task.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,32 @@ func TaskComplete(
593593
return twapi.Execute[TaskCompleteRequest, *TaskCompleteResponse](ctx, engine, req)
594594
}
595595

596+
// TaskRequestSideload contains the possible sideload options when loading
597+
// tasks.
598+
type TaskRequestSideload string
599+
600+
// List of possible sideload options for TaskRequestSideload.
601+
const (
602+
TaskRequestSideloadTaskCustomFields TaskRequestSideload = "customfields"
603+
TaskRequestSideloadTaskCustomFieldValues TaskRequestSideload = "customfieldtasks"
604+
)
605+
606+
// TaskRequestFilters contains the filters for loading tasks.
607+
type TaskRequestFilters struct {
608+
// Include specifies related resources to include.
609+
Include []TaskRequestSideload
610+
}
611+
612+
func (p TaskRequestFilters) apply(req *http.Request) {
613+
query := req.URL.Query()
614+
if len(p.Include) > 0 {
615+
for _, include := range p.Include {
616+
query.Add("include", string(include))
617+
}
618+
}
619+
req.URL.RawQuery = query.Encode()
620+
}
621+
596622
// TaskGetRequestPath contains the path parameters for loading a single task.
597623
type TaskGetRequestPath struct {
598624
// ID is the unique identifier of the task to be retrieved.
@@ -605,6 +631,9 @@ type TaskGetRequestPath struct {
605631
type TaskGetRequest struct {
606632
// Path contains the path parameters for the request.
607633
Path TaskGetRequestPath
634+
635+
// Filters contains the filters for loading a single task.
636+
Filters TaskRequestFilters
608637
}
609638

610639
// NewTaskGetRequest creates a new TaskGetRequest with the provided
@@ -625,6 +654,7 @@ func (t TaskGetRequest) HTTPRequest(ctx context.Context, server string) (*http.R
625654
if err != nil {
626655
return nil, err
627656
}
657+
t.Filters.apply(req)
628658

629659
return req, nil
630660
}
@@ -634,6 +664,19 @@ func (t TaskGetRequest) HTTPRequest(ctx context.Context, server string) (*http.R
634664
// https://apidocs.teamwork.com/docs/teamwork/v3/tasks/get-projects-api-v3-tasks-task-id-json
635665
type TaskGetResponse struct {
636666
Task Task `json:"task"`
667+
668+
// Included contains related objects included in the response.
669+
Included struct {
670+
// CustomFields contains the custom fields associated with the task.
671+
//
672+
// The key is the string representation of the custom field ID.
673+
CustomFields map[string]CustomField `json:"customfields,omitempty"`
674+
// CustomFieldValues contains the values of the custom fields associated
675+
// with the task.
676+
//
677+
// The key is the string representation of the custom field value ID.
678+
CustomFieldValues map[string]CustomFieldValue `json:"customfieldTasks,omitempty"`
679+
} `json:"included"`
637680
}
638681

639682
// HandleHTTPResponse handles the HTTP response for the TaskGetResponse. If some
@@ -672,6 +715,8 @@ type TaskListRequestPath struct {
672715

673716
// TaskListRequestFilters contains the filters for loading multiple tasks.
674717
type TaskListRequestFilters struct {
718+
TaskRequestFilters
719+
675720
// SearchTerm is an optional search term to filter tasks by name, description
676721
// or tasklist's name.
677722
SearchTerm string
@@ -722,6 +767,8 @@ type TaskListRequestFilters struct {
722767
}
723768

724769
func (t TaskListRequestFilters) apply(req *http.Request) {
770+
t.TaskRequestFilters.apply(req)
771+
725772
query := req.URL.Query()
726773
if t.SearchTerm != "" {
727774
query.Set("searchTerm", t.SearchTerm)
@@ -830,12 +877,28 @@ func (t TaskListRequest) HTTPRequest(ctx context.Context, server string) (*http.
830877
type TaskListResponse struct {
831878
request TaskListRequest
832879

880+
// Meta contains metadata about the response, including pagination details.
833881
Meta struct {
834882
Page struct {
835883
HasMore bool `json:"hasMore"`
836884
} `json:"page"`
837885
} `json:"meta"`
886+
887+
// Tasks is the list of tasks matching the request filters.
838888
Tasks []Task `json:"tasks"`
889+
890+
// Included contains related objects included in the response.
891+
Included struct {
892+
// CustomFields contains the custom fields associated with the task.
893+
//
894+
// The key is the string representation of the custom field ID.
895+
CustomFields map[string]CustomField `json:"customfields,omitempty"`
896+
// CustomFieldValues contains the values of the custom fields associated
897+
// with the task.
898+
//
899+
// The key is the string representation of the custom field value ID.
900+
CustomFieldValues map[string]CustomFieldValue `json:"customfieldTasks,omitempty"`
901+
} `json:"included"`
839902
}
840903

841904
// HandleHTTPResponse handles the HTTP response for the TaskListResponse. If

0 commit comments

Comments
 (0)