Add filter by assignee

This commit is contained in:
kolaente 2020-12-19 18:24:51 +01:00
parent cbdfba8b6f
commit fa99eadb15
Signed by: konrad
GPG Key ID: F40E70337AB24C9B
3 changed files with 70 additions and 18 deletions

View File

@ -164,8 +164,16 @@ func getValueForField(field reflect.StructField, rawValue string) (value interfa
value = value.(time.Time).In(config.GetTimeZone())
}
case reflect.Slice:
t := reflect.SliceOf(schemas.TimeType)
if t != nil {
// If this is a slice of pointers we're dealing with some property which is a relation
// In that case we don't really care about what the actual type is, we just cast the value to an
// int64 since we need the id - yes, this assumes we only ever have int64 IDs, but this is fine.
if field.Type.Elem().Kind() == reflect.Ptr {
value, err = strconv.ParseInt(rawValue, 10, 64)
return
}
// There are probably better ways to do this - please let me know if you have one.
if field.Type.Elem().String() == "time.Time" {
value, err = time.Parse(time.RFC3339, rawValue)
value = value.(time.Time).In(config.GetTimeZone())
return

View File

@ -906,6 +906,32 @@ func TestTaskCollection_ReadAll(t *testing.T) {
},
wantErr: false,
},
{
name: "filter assignees",
fields: fields{
FilterBy: []string{"assignees"},
FilterValue: []string{"1"},
FilterComparator: []string{"equals"},
},
args: defaultArgs,
want: []*Task{
task30,
},
wantErr: false,
},
{
name: "filter assignees in",
fields: fields{
FilterBy: []string{"assignees"},
FilterValue: []string{"1,2"},
FilterComparator: []string{"in"},
},
args: defaultArgs,
want: []*Task{
task30,
},
wantErr: false,
},
}
for _, tt := range tests {

View File

@ -190,6 +190,24 @@ func getFilterCond(f *taskFilter, includeNulls bool) (cond builder.Cond, err err
return
}
func getFilterCondForSeparateTable(table string, concat taskFilterConcatinator, conds []builder.Cond) builder.Cond {
var filtercond builder.Cond
if concat == filterConcatOr {
filtercond = builder.Or(conds...)
}
if concat == filterConcatAnd {
filtercond = builder.And(conds...)
}
return builder.In(
"id",
builder.
Select("task_id").
From(table).
Where(filtercond),
)
}
//nolint:gocyclo
func getRawTasksForLists(lists []*List, a web.Auth, opts *taskOptions) (tasks []*Task, resultCount int, totalItems int64, err error) {
@ -249,8 +267,9 @@ func getRawTasksForLists(lists []*List, a web.Auth, opts *taskOptions) (tasks []
}
}
// Reminder filters need a special treatment since they are in a separate database
// Some filters need a special treatment since they are in a separate table
reminderFilters := []builder.Cond{}
assigneeFilters := []builder.Cond{}
var filters = make([]builder.Cond, 0, len(opts.filters))
// To still find tasks with nil values, we exclude 0s when comparing with >/< values.
@ -265,6 +284,16 @@ func getRawTasksForLists(lists []*List, a web.Auth, opts *taskOptions) (tasks []
continue
}
if f.field == "assignees" {
f.field = "user_id"
filter, err := getFilterCond(f, opts.filterIncludeNulls)
if err != nil {
return nil, 0, 0, err
}
assigneeFilters = append(assigneeFilters, filter)
continue
}
filter, err := getFilterCond(f, opts.filterIncludeNulls)
if err != nil {
return nil, 0, 0, err
@ -318,22 +347,11 @@ func getRawTasksForLists(lists []*List, a web.Auth, opts *taskOptions) (tasks []
}
if len(reminderFilters) > 0 {
var filtercond builder.Cond
if opts.filterConcat == filterConcatOr {
filtercond = builder.Or(reminderFilters...)
}
if opts.filterConcat == filterConcatAnd {
filtercond = builder.And(reminderFilters...)
}
reminderFilter := builder.In(
"id",
builder.
Select("task_id").
From("task_reminders").
Where(filtercond),
)
filters = append(filters, getFilterCondForSeparateTable("task_reminders", opts.filterConcat, reminderFilters))
}
filters = append(filters, reminderFilter)
if len(assigneeFilters) > 0 {
filters = append(filters, getFilterCondForSeparateTable("task_assignees", opts.filterConcat, assigneeFilters))
}
query = query.Where(listCond)