mirror of
https://github.com/stashapp/stash.git
synced 2025-12-17 12:24:38 +03:00
* Add query options for tags, performers, studios * Remove errant log * Apply expanded query criteria to scene markers
This commit is contained in:
@@ -28,11 +28,11 @@ input SceneMarkerFilterType {
|
|||||||
"""Filter to only include scene markers with this tag"""
|
"""Filter to only include scene markers with this tag"""
|
||||||
tag_id: ID
|
tag_id: ID
|
||||||
"""Filter to only include scene markers with these tags"""
|
"""Filter to only include scene markers with these tags"""
|
||||||
tags: [ID!]
|
tags: MultiCriterionInput
|
||||||
"""Filter to only include scene markers attached to a scene with these tags"""
|
"""Filter to only include scene markers attached to a scene with these tags"""
|
||||||
scene_tags: [ID!]
|
scene_tags: MultiCriterionInput
|
||||||
"""Filter to only include scene markers with these performers"""
|
"""Filter to only include scene markers with these performers"""
|
||||||
performers: [ID!]
|
performers: MultiCriterionInput
|
||||||
}
|
}
|
||||||
|
|
||||||
input SceneFilterType {
|
input SceneFilterType {
|
||||||
@@ -45,11 +45,11 @@ input SceneFilterType {
|
|||||||
"""Filter to only include scenes missing this property"""
|
"""Filter to only include scenes missing this property"""
|
||||||
is_missing: String
|
is_missing: String
|
||||||
"""Filter to only include scenes with this studio"""
|
"""Filter to only include scenes with this studio"""
|
||||||
studio_id: ID
|
studios: MultiCriterionInput
|
||||||
"""Filter to only include scenes with these tags"""
|
"""Filter to only include scenes with these tags"""
|
||||||
tags: [ID!]
|
tags: MultiCriterionInput
|
||||||
"""Filter to only include scenes with this performer"""
|
"""Filter to only include scenes with these performers"""
|
||||||
performer_id: ID
|
performers: MultiCriterionInput
|
||||||
}
|
}
|
||||||
|
|
||||||
enum CriterionModifier {
|
enum CriterionModifier {
|
||||||
@@ -65,6 +65,8 @@ enum CriterionModifier {
|
|||||||
IS_NULL,
|
IS_NULL,
|
||||||
"""IS NOT NULL"""
|
"""IS NOT NULL"""
|
||||||
NOT_NULL,
|
NOT_NULL,
|
||||||
|
"""INCLUDES ALL"""
|
||||||
|
INCLUDES_ALL,
|
||||||
INCLUDES,
|
INCLUDES,
|
||||||
EXCLUDES,
|
EXCLUDES,
|
||||||
}
|
}
|
||||||
@@ -73,3 +75,8 @@ input IntCriterionInput {
|
|||||||
value: Int!
|
value: Int!
|
||||||
modifier: CriterionModifier!
|
modifier: CriterionModifier!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input MultiCriterionInput {
|
||||||
|
value: [ID!]
|
||||||
|
modifier: CriterionModifier!
|
||||||
|
}
|
||||||
@@ -218,23 +218,34 @@ func (qb *SceneQueryBuilder) Query(sceneFilter *SceneFilterType, findFilter *Fin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if tagsFilter := sceneFilter.Tags; len(tagsFilter) > 0 {
|
if tagsFilter := sceneFilter.Tags; tagsFilter != nil && len(tagsFilter.Value) > 0 {
|
||||||
for _, tagID := range tagsFilter {
|
for _, tagID := range tagsFilter.Value {
|
||||||
args = append(args, tagID)
|
args = append(args, tagID)
|
||||||
}
|
}
|
||||||
|
|
||||||
whereClauses = append(whereClauses, "tags.id IN "+getInBinding(len(tagsFilter)))
|
whereClause, havingClause := getMultiCriterionClause("tags", "scenes_tags", "tag_id", tagsFilter)
|
||||||
havingClauses = append(havingClauses, "count(distinct tags.id) IS "+strconv.Itoa(len(tagsFilter)))
|
whereClauses = appendClause(whereClauses, whereClause)
|
||||||
|
havingClauses = appendClause(havingClauses, havingClause)
|
||||||
}
|
}
|
||||||
|
|
||||||
if performerID := sceneFilter.PerformerID; performerID != nil {
|
if performersFilter := sceneFilter.Performers; performersFilter != nil && len(performersFilter.Value) > 0 {
|
||||||
whereClauses = append(whereClauses, "performers.id = ?")
|
for _, performerID := range performersFilter.Value {
|
||||||
args = append(args, *performerID)
|
args = append(args, performerID)
|
||||||
}
|
}
|
||||||
|
|
||||||
if studioID := sceneFilter.StudioID; studioID != nil {
|
whereClause, havingClause := getMultiCriterionClause("performers", "performers_scenes", "performer_id", performersFilter)
|
||||||
whereClauses = append(whereClauses, "studio.id = ?")
|
whereClauses = appendClause(whereClauses, whereClause)
|
||||||
args = append(args, *studioID)
|
havingClauses = appendClause(havingClauses, havingClause)
|
||||||
|
}
|
||||||
|
|
||||||
|
if studiosFilter := sceneFilter.Studios; studiosFilter != nil && len(studiosFilter.Value) > 0 {
|
||||||
|
for _, studioID := range studiosFilter.Value {
|
||||||
|
args = append(args, studioID)
|
||||||
|
}
|
||||||
|
|
||||||
|
whereClause, havingClause := getMultiCriterionClause("studio", "", "studio_id", studiosFilter)
|
||||||
|
whereClauses = appendClause(whereClauses, whereClause)
|
||||||
|
havingClauses = appendClause(havingClauses, havingClause)
|
||||||
}
|
}
|
||||||
|
|
||||||
sortAndPagination := qb.getSceneSort(findFilter) + getPagination(findFilter)
|
sortAndPagination := qb.getSceneSort(findFilter) + getPagination(findFilter)
|
||||||
@@ -249,6 +260,37 @@ func (qb *SceneQueryBuilder) Query(sceneFilter *SceneFilterType, findFilter *Fin
|
|||||||
return scenes, countResult
|
return scenes, countResult
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func appendClause(clauses []string, clause string) []string {
|
||||||
|
if clause != "" {
|
||||||
|
return append(clauses, clause)
|
||||||
|
}
|
||||||
|
|
||||||
|
return clauses
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns where clause and having clause
|
||||||
|
func getMultiCriterionClause(table string, joinTable string, joinTableField string, criterion *MultiCriterionInput) (string, string) {
|
||||||
|
whereClause := ""
|
||||||
|
havingClause := ""
|
||||||
|
if criterion.Modifier == CriterionModifierIncludes {
|
||||||
|
// includes any of the provided ids
|
||||||
|
whereClause = table + ".id IN "+ getInBinding(len(criterion.Value))
|
||||||
|
} else if criterion.Modifier == CriterionModifierIncludesAll {
|
||||||
|
// includes all of the provided ids
|
||||||
|
whereClause = table + ".id IN "+ getInBinding(len(criterion.Value))
|
||||||
|
havingClause = "count(distinct " + table + ".id) IS " + strconv.Itoa(len(criterion.Value))
|
||||||
|
} else if criterion.Modifier == CriterionModifierExcludes {
|
||||||
|
// excludes all of the provided ids
|
||||||
|
if (joinTable != "") {
|
||||||
|
whereClause = "not exists (select " + joinTable + ".scene_id from " + joinTable + " where " + joinTable + ".scene_id = scenes.id and " + joinTable + "." + joinTableField + " in " + getInBinding(len(criterion.Value)) + ")"
|
||||||
|
} else {
|
||||||
|
whereClause = "not exists (select s.id from scenes as s where s.id = scenes.id and s." + joinTableField + " in " + getInBinding(len(criterion.Value)) + ")"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return whereClause, havingClause
|
||||||
|
}
|
||||||
|
|
||||||
func (qb *SceneQueryBuilder) getSceneSort(findFilter *FindFilterType) string {
|
func (qb *SceneQueryBuilder) getSceneSort(findFilter *FindFilterType) string {
|
||||||
if findFilter == nil {
|
if findFilter == nil {
|
||||||
return " ORDER BY scenes.path, scenes.date ASC "
|
return " ORDER BY scenes.path, scenes.date ASC "
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ func (qb *SceneMarkerQueryBuilder) Query(sceneMarkerFilter *SceneMarkerFilterTyp
|
|||||||
left join tags on tags_join.tag_id = tags.id
|
left join tags on tags_join.tag_id = tags.id
|
||||||
`
|
`
|
||||||
|
|
||||||
if tagIDs := sceneMarkerFilter.Tags; tagIDs != nil {
|
if tagsFilter := sceneMarkerFilter.Tags; tagsFilter != nil && len(tagsFilter.Value) > 0 {
|
||||||
//select `scene_markers`.* from `scene_markers`
|
//select `scene_markers`.* from `scene_markers`
|
||||||
//left join `tags` as `primary_tags_join`
|
//left join `tags` as `primary_tags_join`
|
||||||
// on `primary_tags_join`.`id` = `scene_markers`.`primary_tag_id`
|
// on `primary_tags_join`.`id` = `scene_markers`.`primary_tag_id`
|
||||||
@@ -145,32 +145,82 @@ func (qb *SceneMarkerQueryBuilder) Query(sceneMarkerFilter *SceneMarkerFilterTyp
|
|||||||
//group by `scene_markers`.`id`
|
//group by `scene_markers`.`id`
|
||||||
//having ((count(distinct `primary_tags_join`.`id`) + count(distinct `tags_join`.`tag_id`)) = 4)
|
//having ((count(distinct `primary_tags_join`.`id`) + count(distinct `tags_join`.`tag_id`)) = 4)
|
||||||
|
|
||||||
length := len(tagIDs)
|
length := len(tagsFilter.Value)
|
||||||
|
|
||||||
|
if tagsFilter.Modifier == CriterionModifierIncludes || tagsFilter.Modifier == CriterionModifierIncludesAll {
|
||||||
body += " LEFT JOIN tags AS ptj ON ptj.id = scene_markers.primary_tag_id AND ptj.id IN " + getInBinding(length)
|
body += " LEFT JOIN tags AS ptj ON ptj.id = scene_markers.primary_tag_id AND ptj.id IN " + getInBinding(length)
|
||||||
body += " LEFT JOIN scene_markers_tags AS tj ON tj.scene_marker_id = scene_markers.id AND tj.tag_id IN " + getInBinding(length)
|
body += " LEFT JOIN scene_markers_tags AS tj ON tj.scene_marker_id = scene_markers.id AND tj.tag_id IN " + getInBinding(length)
|
||||||
havingClauses = append(havingClauses, "((COUNT(DISTINCT ptj.id) + COUNT(DISTINCT tj.tag_id)) = "+strconv.Itoa(length)+")")
|
|
||||||
for _, tagID := range tagIDs {
|
// only one required for include any
|
||||||
|
requiredCount := 1
|
||||||
|
|
||||||
|
// all required for include all
|
||||||
|
if tagsFilter.Modifier == CriterionModifierIncludesAll {
|
||||||
|
requiredCount = length
|
||||||
|
}
|
||||||
|
|
||||||
|
havingClauses = append(havingClauses, "((COUNT(DISTINCT ptj.id) + COUNT(DISTINCT tj.tag_id)) >= "+strconv.Itoa(requiredCount)+")")
|
||||||
|
} else if tagsFilter.Modifier == CriterionModifierExcludes {
|
||||||
|
// excludes all of the provided ids
|
||||||
|
whereClauses = append(whereClauses, "scene_markers.primary_tag_id not in " + getInBinding(length))
|
||||||
|
whereClauses = append(whereClauses, "not exists (select smt.scene_marker_id from scene_markers_tags as smt where smt.scene_marker_id = scene_markers.id and smt.tag_id in " + getInBinding(length) + ")")
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tagID := range tagsFilter.Value {
|
||||||
args = append(args, tagID)
|
args = append(args, tagID)
|
||||||
}
|
}
|
||||||
for _, tagID := range tagIDs {
|
for _, tagID := range tagsFilter.Value {
|
||||||
args = append(args, tagID)
|
args = append(args, tagID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if sceneTagIDs := sceneMarkerFilter.SceneTags; sceneTagIDs != nil {
|
if sceneTagsFilter := sceneMarkerFilter.SceneTags; sceneTagsFilter != nil && len(sceneTagsFilter.Value) > 0 {
|
||||||
length := len(sceneTagIDs)
|
length := len(sceneTagsFilter.Value)
|
||||||
|
|
||||||
|
if sceneTagsFilter.Modifier == CriterionModifierIncludes || sceneTagsFilter.Modifier == CriterionModifierIncludesAll {
|
||||||
body += " LEFT JOIN scenes_tags AS scene_tags_join ON scene_tags_join.scene_id = scene.id AND scene_tags_join.tag_id IN " + getInBinding(length)
|
body += " LEFT JOIN scenes_tags AS scene_tags_join ON scene_tags_join.scene_id = scene.id AND scene_tags_join.tag_id IN " + getInBinding(length)
|
||||||
havingClauses = append(havingClauses, "COUNT(DISTINCT scene_tags_join.tag_id) = "+strconv.Itoa(length))
|
|
||||||
for _, tagID := range sceneTagIDs {
|
// only one required for include any
|
||||||
|
requiredCount := 1
|
||||||
|
|
||||||
|
// all required for include all
|
||||||
|
if sceneTagsFilter.Modifier == CriterionModifierIncludesAll {
|
||||||
|
requiredCount = length
|
||||||
|
}
|
||||||
|
|
||||||
|
havingClauses = append(havingClauses, "COUNT(DISTINCT scene_tags_join.tag_id) >= "+strconv.Itoa(requiredCount))
|
||||||
|
} else if sceneTagsFilter.Modifier == CriterionModifierExcludes {
|
||||||
|
// excludes all of the provided ids
|
||||||
|
whereClauses = append(whereClauses, "not exists (select st.scene_id from scenes_tags as st where st.scene_id = scene.id AND st.tag_id IN " + getInBinding(length) + ")")
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tagID := range sceneTagsFilter.Value {
|
||||||
args = append(args, tagID)
|
args = append(args, tagID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if performerIDs := sceneMarkerFilter.Performers; performerIDs != nil {
|
if performersFilter := sceneMarkerFilter.Performers; performersFilter != nil && len(performersFilter.Value) > 0 {
|
||||||
length := len(performerIDs)
|
length := len(performersFilter.Value)
|
||||||
|
|
||||||
|
if performersFilter.Modifier == CriterionModifierIncludes || performersFilter.Modifier == CriterionModifierIncludesAll {
|
||||||
body += " LEFT JOIN performers_scenes as scene_performers ON scene.id = scene_performers.scene_id"
|
body += " LEFT JOIN performers_scenes as scene_performers ON scene.id = scene_performers.scene_id"
|
||||||
whereClauses = append(whereClauses, "scene_performers.performer_id IN "+getInBinding(length))
|
whereClauses = append(whereClauses, "scene_performers.performer_id IN "+getInBinding(length))
|
||||||
for _, performerID := range performerIDs {
|
|
||||||
|
// only one required for include any
|
||||||
|
requiredCount := 1
|
||||||
|
|
||||||
|
// all required for include all
|
||||||
|
if performersFilter.Modifier == CriterionModifierIncludesAll {
|
||||||
|
requiredCount = length
|
||||||
|
}
|
||||||
|
|
||||||
|
havingClauses = append(havingClauses, "COUNT(DISTINCT scene_performers.performer_id) >= "+strconv.Itoa(requiredCount))
|
||||||
|
} else if performersFilter.Modifier == CriterionModifierExcludes {
|
||||||
|
// excludes all of the provided ids
|
||||||
|
whereClauses = append(whereClauses, "not exists (select sp.scene_id from performers_scenes as sp where sp.scene_id = scene.id AND sp.performer_id IN " + getInBinding(length) + ")")
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, performerID := range performersFilter.Value {
|
||||||
args = append(args, performerID)
|
args = append(args, performerID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ func getSort(sort string, direction string, tableName string) string {
|
|||||||
if tableName == "scenes" {
|
if tableName == "scenes" {
|
||||||
additional = ", bitrate DESC, framerate DESC, rating DESC, duration DESC"
|
additional = ", bitrate DESC, framerate DESC, rating DESC, duration DESC"
|
||||||
} else if tableName == "scene_markers" {
|
} else if tableName == "scene_markers" {
|
||||||
additional = ", scene_id ASC, seconds ASC"
|
additional = ", scene_markers.scene_id ASC, scene_markers.seconds ASC"
|
||||||
}
|
}
|
||||||
return " ORDER BY " + colName + " " + direction + additional
|
return " ORDER BY " + colName + " " + direction + additional
|
||||||
}
|
}
|
||||||
@@ -204,9 +204,11 @@ func executeFindQuery(tableName string, body string, args []interface{}, sortAnd
|
|||||||
idsResult, idsErr := runIdsQuery(idsQuery, args)
|
idsResult, idsErr := runIdsQuery(idsQuery, args)
|
||||||
|
|
||||||
if countErr != nil {
|
if countErr != nil {
|
||||||
|
logger.Errorf("Error executing count query with SQL: %s, args: %v, error: %s", countQuery, args, countErr.Error())
|
||||||
panic(countErr)
|
panic(countErr)
|
||||||
}
|
}
|
||||||
if idsErr != nil {
|
if idsErr != nil {
|
||||||
|
logger.Errorf("Error executing find query with SQL: %s, args: %v, error: %s", idsQuery, args, idsErr.Error())
|
||||||
panic(idsErr)
|
panic(idsErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,9 +53,6 @@ export const Stats: FunctionComponent = () => {
|
|||||||
<pre>
|
<pre>
|
||||||
{`
|
{`
|
||||||
This is still an early version, some things are still a work in progress.
|
This is still an early version, some things are still a work in progress.
|
||||||
|
|
||||||
* Filters for performers and studios only supports one item, even though it's a multi select.
|
|
||||||
|
|
||||||
`}
|
`}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -130,10 +130,14 @@ export const AddFilter: FunctionComponent<IAddFilterProps> = (props: IAddFilterP
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
{renderModifier()}
|
{renderModifier()}
|
||||||
|
</FormGroup>
|
||||||
|
<FormGroup>
|
||||||
{renderSelect()}
|
{renderSelect()}
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ export abstract class Criterion<Option = any, Value = any> {
|
|||||||
case CriterionModifier.LessThan: return {value: CriterionModifier.LessThan, label: "Less Than"};
|
case CriterionModifier.LessThan: return {value: CriterionModifier.LessThan, label: "Less Than"};
|
||||||
case CriterionModifier.IsNull: return {value: CriterionModifier.IsNull, label: "Is NULL"};
|
case CriterionModifier.IsNull: return {value: CriterionModifier.IsNull, label: "Is NULL"};
|
||||||
case CriterionModifier.NotNull: return {value: CriterionModifier.NotNull, label: "Not NULL"};
|
case CriterionModifier.NotNull: return {value: CriterionModifier.NotNull, label: "Not NULL"};
|
||||||
|
case CriterionModifier.IncludesAll: return {value: CriterionModifier.IncludesAll, label: "Includes All"};
|
||||||
case CriterionModifier.Includes: return {value: CriterionModifier.Includes, label: "Includes"};
|
case CriterionModifier.Includes: return {value: CriterionModifier.Includes, label: "Includes"};
|
||||||
case CriterionModifier.Excludes: return {value: CriterionModifier.Excludes, label: "Excludes"};
|
case CriterionModifier.Excludes: return {value: CriterionModifier.Excludes, label: "Excludes"};
|
||||||
}
|
}
|
||||||
@@ -60,7 +61,8 @@ export abstract class Criterion<Option = any, Value = any> {
|
|||||||
case CriterionModifier.IsNull: modifierString = "is null"; break;
|
case CriterionModifier.IsNull: modifierString = "is null"; break;
|
||||||
case CriterionModifier.NotNull: modifierString = "is not null"; break;
|
case CriterionModifier.NotNull: modifierString = "is not null"; break;
|
||||||
case CriterionModifier.Includes: modifierString = "includes"; break;
|
case CriterionModifier.Includes: modifierString = "includes"; break;
|
||||||
case CriterionModifier.Excludes: modifierString = "exculdes"; break;
|
case CriterionModifier.IncludesAll: modifierString = "includes all"; break;
|
||||||
|
case CriterionModifier.Excludes: modifierString = "excludes"; break;
|
||||||
default: modifierString = "";
|
default: modifierString = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,8 +15,12 @@ interface IOptionType {
|
|||||||
export class PerformersCriterion extends Criterion<IOptionType, ILabeledId[]> {
|
export class PerformersCriterion extends Criterion<IOptionType, ILabeledId[]> {
|
||||||
public type: CriterionType = "performers";
|
public type: CriterionType = "performers";
|
||||||
public parameterName: string = "performers";
|
public parameterName: string = "performers";
|
||||||
public modifier = CriterionModifier.Equals;
|
public modifier = CriterionModifier.IncludesAll;
|
||||||
public modifierOptions = [];
|
public modifierOptions = [
|
||||||
|
Criterion.getModifierOption(CriterionModifier.IncludesAll),
|
||||||
|
Criterion.getModifierOption(CriterionModifier.Includes),
|
||||||
|
Criterion.getModifierOption(CriterionModifier.Excludes),
|
||||||
|
];
|
||||||
public options: IOptionType[] = [];
|
public options: IOptionType[] = [];
|
||||||
public value: ILabeledId[] = [];
|
public value: ILabeledId[] = [];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,8 +15,11 @@ interface IOptionType {
|
|||||||
export class StudiosCriterion extends Criterion<IOptionType, ILabeledId[]> {
|
export class StudiosCriterion extends Criterion<IOptionType, ILabeledId[]> {
|
||||||
public type: CriterionType = "studios";
|
public type: CriterionType = "studios";
|
||||||
public parameterName: string = "studios";
|
public parameterName: string = "studios";
|
||||||
public modifier = CriterionModifier.Equals;
|
public modifier = CriterionModifier.Includes;
|
||||||
public modifierOptions = [];
|
public modifierOptions = [
|
||||||
|
Criterion.getModifierOption(CriterionModifier.Includes),
|
||||||
|
Criterion.getModifierOption(CriterionModifier.Excludes),
|
||||||
|
];
|
||||||
public options: IOptionType[] = [];
|
public options: IOptionType[] = [];
|
||||||
public value: ILabeledId[] = [];
|
public value: ILabeledId[] = [];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,8 +10,12 @@ import {
|
|||||||
export class TagsCriterion extends Criterion<GQL.AllTagsForFilterAllTags, ILabeledId[]> {
|
export class TagsCriterion extends Criterion<GQL.AllTagsForFilterAllTags, ILabeledId[]> {
|
||||||
public type: CriterionType;
|
public type: CriterionType;
|
||||||
public parameterName: string;
|
public parameterName: string;
|
||||||
public modifier = CriterionModifier.Equals;
|
public modifier = CriterionModifier.IncludesAll;
|
||||||
public modifierOptions = [];
|
public modifierOptions = [
|
||||||
|
Criterion.getModifierOption(CriterionModifier.IncludesAll),
|
||||||
|
Criterion.getModifierOption(CriterionModifier.Includes),
|
||||||
|
Criterion.getModifierOption(CriterionModifier.Excludes),
|
||||||
|
];
|
||||||
public options: GQL.AllTagsForFilterAllTags[] = [];
|
public options: GQL.AllTagsForFilterAllTags[] = [];
|
||||||
public value: ILabeledId[] = [];
|
public value: ILabeledId[] = [];
|
||||||
|
|
||||||
|
|||||||
@@ -202,8 +202,8 @@ export class ListFilterModel {
|
|||||||
this.criteria.forEach((criterion) => {
|
this.criteria.forEach((criterion) => {
|
||||||
switch (criterion.type) {
|
switch (criterion.type) {
|
||||||
case "rating":
|
case "rating":
|
||||||
const crit = criterion as RatingCriterion;
|
const ratingCrit = criterion as RatingCriterion;
|
||||||
result.rating = { value: crit.value, modifier: crit.modifier };
|
result.rating = { value: ratingCrit.value, modifier: ratingCrit.modifier };
|
||||||
break;
|
break;
|
||||||
case "resolution": {
|
case "resolution": {
|
||||||
switch ((criterion as ResolutionCriterion).value) {
|
switch ((criterion as ResolutionCriterion).value) {
|
||||||
@@ -222,13 +222,16 @@ export class ListFilterModel {
|
|||||||
result.is_missing = (criterion as IsMissingCriterion).value;
|
result.is_missing = (criterion as IsMissingCriterion).value;
|
||||||
break;
|
break;
|
||||||
case "tags":
|
case "tags":
|
||||||
result.tags = (criterion as TagsCriterion).value.map((tag) => tag.id);
|
const tagsCrit = criterion as TagsCriterion;
|
||||||
|
result.tags = { value: tagsCrit.value.map((tag) => tag.id), modifier: tagsCrit.modifier };
|
||||||
break;
|
break;
|
||||||
case "performers":
|
case "performers":
|
||||||
result.performer_id = (criterion as PerformersCriterion).value[0].id; // TODO: Allow multiple
|
const perfCrit = criterion as PerformersCriterion;
|
||||||
|
result.performers = { value: perfCrit.value.map((perf) => perf.id), modifier: perfCrit.modifier };
|
||||||
break;
|
break;
|
||||||
case "studios":
|
case "studios":
|
||||||
result.studio_id = (criterion as StudiosCriterion).value[0].id; // TODO: Allow multiple
|
const studCrit = criterion as StudiosCriterion;
|
||||||
|
result.studios = { value: studCrit.value.map((studio) => studio.id), modifier: studCrit.modifier };
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -252,13 +255,16 @@ export class ListFilterModel {
|
|||||||
this.criteria.forEach((criterion) => {
|
this.criteria.forEach((criterion) => {
|
||||||
switch (criterion.type) {
|
switch (criterion.type) {
|
||||||
case "tags":
|
case "tags":
|
||||||
result.tags = (criterion as TagsCriterion).value.map((tag) => tag.id);
|
const tagsCrit = criterion as TagsCriterion;
|
||||||
|
result.tags = { value: tagsCrit.value.map((tag) => tag.id), modifier: tagsCrit.modifier };
|
||||||
break;
|
break;
|
||||||
case "sceneTags":
|
case "sceneTags":
|
||||||
result.scene_tags = (criterion as TagsCriterion).value.map((tag) => tag.id);
|
const sceneTagsCrit = criterion as TagsCriterion;
|
||||||
|
result.scene_tags = { value: sceneTagsCrit.value.map((tag) => tag.id), modifier: sceneTagsCrit.modifier };
|
||||||
break;
|
break;
|
||||||
case "performers":
|
case "performers":
|
||||||
result.performers = (criterion as PerformersCriterion).value.map((performer) => performer.id);
|
const performersCrit = criterion as PerformersCriterion;
|
||||||
|
result.performers = { value: performersCrit.value.map((performer) => performer.id), modifier: performersCrit.modifier };
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user