diff --git a/graphql/schema/types/filters.graphql b/graphql/schema/types/filters.graphql index c0b47f7cf..075e40372 100644 --- a/graphql/schema/types/filters.graphql +++ b/graphql/schema/types/filters.graphql @@ -455,6 +455,8 @@ input GroupFilterType { containing_group_count: IntCriterionInput "Filter by number of sub-groups the group has" sub_group_count: IntCriterionInput + "Filter by number of scenes the group has" + scene_count: IntCriterionInput "Filter by related scenes that meet this criteria" scenes_filter: SceneFilterType diff --git a/pkg/models/group.go b/pkg/models/group.go index 6943b1055..ec550eea8 100644 --- a/pkg/models/group.go +++ b/pkg/models/group.go @@ -33,6 +33,8 @@ type GroupFilterType struct { ContainingGroupCount *IntCriterionInput `json:"containing_group_count"` // Filter by number of sub-groups the group has SubGroupCount *IntCriterionInput `json:"sub_group_count"` + // Filter by number of scenes the group has + SceneCount *IntCriterionInput `json:"scene_count"` // Filter by related scenes that meet this criteria ScenesFilter *SceneFilterType `json:"scenes_filter"` // Filter by related studios that meet this criteria diff --git a/pkg/sqlite/group_filter.go b/pkg/sqlite/group_filter.go index f29023785..f81783374 100644 --- a/pkg/sqlite/group_filter.go +++ b/pkg/sqlite/group_filter.go @@ -75,6 +75,7 @@ func (qb *groupFilterHandler) criterionHandler() criterionHandler { qb.tagsCriterionHandler(groupFilter.Tags), qb.tagCountCriterionHandler(groupFilter.TagCount), qb.groupOCounterCriterionHandler(groupFilter.OCounter), + qb.sceneCountCriterionHandler(groupFilter.SceneCount), &dateCriterionHandler{groupFilter.Date, "groups.date", nil}, groupHierarchyHandler.ParentsCriterionHandler(groupFilter.ContainingGroups), groupHierarchyHandler.ChildrenCriterionHandler(groupFilter.SubGroups), @@ -204,6 +205,16 @@ func (qb *groupFilterHandler) tagCountCriterionHandler(count *models.IntCriterio return h.handler(count) } +func (qb *groupFilterHandler) sceneCountCriterionHandler(count *models.IntCriterionInput) criterionHandlerFunc { + h := countCriterionHandlerBuilder{ + primaryTable: groupTable, + joinTable: groupsScenesTable, + primaryFK: groupIDColumn, + } + + return h.handler(count) +} + // used for sorting and filtering on group o-count var selectGroupOCountSQL = utils.StrFormat( "SELECT SUM(o_counter) "+ diff --git a/pkg/sqlite/group_test.go b/pkg/sqlite/group_test.go index d4a177e86..db293dd92 100644 --- a/pkg/sqlite/group_test.go +++ b/pkg/sqlite/group_test.go @@ -669,6 +669,32 @@ func TestGroupQuery(t *testing.T) { nil, false, }, + { + "scene count equals 1", + nil, + &models.GroupFilterType{ + SceneCount: &models.IntCriterionInput{ + Value: 1, + Modifier: models.CriterionModifierEquals, + }, + }, + []int{groupIdxWithScene}, + []int{groupIdxWithParentAndChild}, + false, + }, + { + "scene count less than 1", + nil, + &models.GroupFilterType{ + SceneCount: &models.IntCriterionInput{ + Value: 1, + Modifier: models.CriterionModifierLessThan, + }, + }, + []int{groupIdxWithParentAndChild}, + []int{groupIdxWithScene}, + false, + }, } for _, tt := range tests { diff --git a/ui/v2.5/src/models/list-filter/groups.ts b/ui/v2.5/src/models/list-filter/groups.ts index 5a263b272..ee0c90d73 100644 --- a/ui/v2.5/src/models/list-filter/groups.ts +++ b/ui/v2.5/src/models/list-filter/groups.ts @@ -63,6 +63,7 @@ const criterionOptions = [ createMandatoryNumberCriterionOption("sub_group_count"), TagsCriterionOption, createMandatoryNumberCriterionOption("tag_count"), + createMandatoryNumberCriterionOption("scene_count"), createMandatoryTimestampCriterionOption("created_at"), createMandatoryTimestampCriterionOption("updated_at"), ];