mirror of
https://github.com/stashapp/stash.git
synced 2025-12-17 04:14:39 +03:00
Filter improvement exploration
Changed the rating filter to allow for more than just an equality check. This progresses #29.
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -10858,6 +10858,35 @@ func (e *executableSchema) GenerateMetadataInputMiddleware(ctx context.Context,
|
||||
return obj, nil
|
||||
}
|
||||
|
||||
func UnmarshalIntCriterionInput(v interface{}) (IntCriterionInput, error) {
|
||||
var it IntCriterionInput
|
||||
var asMap = v.(map[string]interface{})
|
||||
|
||||
for k, v := range asMap {
|
||||
switch k {
|
||||
case "value":
|
||||
var err error
|
||||
it.Value, err = graphql.UnmarshalInt(v)
|
||||
if err != nil {
|
||||
return it, err
|
||||
}
|
||||
case "modifier":
|
||||
var err error
|
||||
err = (&it.Modifier).UnmarshalGQL(v)
|
||||
if err != nil {
|
||||
return it, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return it, nil
|
||||
}
|
||||
|
||||
func (e *executableSchema) IntCriterionInputMiddleware(ctx context.Context, obj *IntCriterionInput) (*IntCriterionInput, error) {
|
||||
|
||||
return obj, nil
|
||||
}
|
||||
|
||||
func UnmarshalPerformerCreateInput(v interface{}) (PerformerCreateInput, error) {
|
||||
var it PerformerCreateInput
|
||||
var asMap = v.(map[string]interface{})
|
||||
@@ -11303,9 +11332,9 @@ func UnmarshalSceneFilterType(v interface{}) (SceneFilterType, error) {
|
||||
switch k {
|
||||
case "rating":
|
||||
var err error
|
||||
var ptr1 int
|
||||
var ptr1 IntCriterionInput
|
||||
if v != nil {
|
||||
ptr1, err = graphql.UnmarshalInt(v)
|
||||
ptr1, err = UnmarshalIntCriterionInput(v)
|
||||
it.Rating = &ptr1
|
||||
}
|
||||
|
||||
@@ -11392,6 +11421,14 @@ func UnmarshalSceneFilterType(v interface{}) (SceneFilterType, error) {
|
||||
|
||||
func (e *executableSchema) SceneFilterTypeMiddleware(ctx context.Context, obj *SceneFilterType) (*SceneFilterType, error) {
|
||||
|
||||
if obj.Rating != nil {
|
||||
var err error
|
||||
obj.Rating, err = e.IntCriterionInputMiddleware(ctx, obj.Rating)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return obj, nil
|
||||
}
|
||||
|
||||
@@ -12301,7 +12338,7 @@ input SceneMarkerFilterType {
|
||||
|
||||
input SceneFilterType {
|
||||
"""Filter by rating"""
|
||||
rating: Int
|
||||
rating: IntCriterionInput
|
||||
"""Filter by resolution"""
|
||||
resolution: ResolutionEnum
|
||||
"""Filter to only include scenes which have markers. ` + "`" + `true` + "`" + ` or ` + "`" + `false` + "`" + `"""
|
||||
@@ -12316,6 +12353,28 @@ input SceneFilterType {
|
||||
performer_id: ID
|
||||
}
|
||||
|
||||
enum CriterionModifier {
|
||||
"""="""
|
||||
EQUALS,
|
||||
"""!="""
|
||||
NOT_EQUALS,
|
||||
""">"""
|
||||
GREATER_THAN,
|
||||
"""<"""
|
||||
LESS_THAN,
|
||||
"""IS NULL"""
|
||||
IS_NULL,
|
||||
"""IS NOT NULL"""
|
||||
NOT_NULL,
|
||||
INCLUDES,
|
||||
EXCLUDES,
|
||||
}
|
||||
|
||||
input IntCriterionInput {
|
||||
value: Int!
|
||||
modifier: CriterionModifier!
|
||||
}
|
||||
|
||||
#######################################
|
||||
# Config
|
||||
#######################################
|
||||
|
||||
@@ -77,6 +77,11 @@ type GenerateMetadataInput struct {
|
||||
Transcodes bool `json:"transcodes"`
|
||||
}
|
||||
|
||||
type IntCriterionInput struct {
|
||||
Value int `json:"value"`
|
||||
Modifier CriterionModifier `json:"modifier"`
|
||||
}
|
||||
|
||||
type MarkerStringsResultType struct {
|
||||
Count int `json:"count"`
|
||||
ID string `json:"id"`
|
||||
@@ -144,7 +149,7 @@ type SceneFileType struct {
|
||||
|
||||
type SceneFilterType struct {
|
||||
// Filter by rating
|
||||
Rating *int `json:"rating"`
|
||||
Rating *IntCriterionInput `json:"rating"`
|
||||
// Filter by resolution
|
||||
Resolution *ResolutionEnum `json:"resolution"`
|
||||
// Filter to only include scenes which have markers. `true` or `false`
|
||||
@@ -270,6 +275,65 @@ type TagUpdateInput struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type CriterionModifier string
|
||||
|
||||
const (
|
||||
// =
|
||||
CriterionModifierEquals CriterionModifier = "EQUALS"
|
||||
// !=
|
||||
CriterionModifierNotEquals CriterionModifier = "NOT_EQUALS"
|
||||
// >
|
||||
CriterionModifierGreaterThan CriterionModifier = "GREATER_THAN"
|
||||
// <
|
||||
CriterionModifierLessThan CriterionModifier = "LESS_THAN"
|
||||
// IS NULL
|
||||
CriterionModifierIsNull CriterionModifier = "IS_NULL"
|
||||
// IS NOT NULL
|
||||
CriterionModifierNotNull CriterionModifier = "NOT_NULL"
|
||||
CriterionModifierIncludes CriterionModifier = "INCLUDES"
|
||||
CriterionModifierExcludes CriterionModifier = "EXCLUDES"
|
||||
)
|
||||
|
||||
var AllCriterionModifier = []CriterionModifier{
|
||||
CriterionModifierEquals,
|
||||
CriterionModifierNotEquals,
|
||||
CriterionModifierGreaterThan,
|
||||
CriterionModifierLessThan,
|
||||
CriterionModifierIsNull,
|
||||
CriterionModifierNotNull,
|
||||
CriterionModifierIncludes,
|
||||
CriterionModifierExcludes,
|
||||
}
|
||||
|
||||
func (e CriterionModifier) IsValid() bool {
|
||||
switch e {
|
||||
case CriterionModifierEquals, CriterionModifierNotEquals, CriterionModifierGreaterThan, CriterionModifierLessThan, CriterionModifierIsNull, CriterionModifierNotNull, CriterionModifierIncludes, CriterionModifierExcludes:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (e CriterionModifier) String() string {
|
||||
return string(e)
|
||||
}
|
||||
|
||||
func (e *CriterionModifier) UnmarshalGQL(v interface{}) error {
|
||||
str, ok := v.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("enums must be strings")
|
||||
}
|
||||
|
||||
*e = CriterionModifier(str)
|
||||
if !e.IsValid() {
|
||||
return fmt.Errorf("%s is not a valid CriterionModifier", str)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e CriterionModifier) MarshalGQL(w io.Writer) {
|
||||
fmt.Fprint(w, strconv.Quote(e.String()))
|
||||
}
|
||||
|
||||
type ResolutionEnum string
|
||||
|
||||
const (
|
||||
|
||||
@@ -164,8 +164,11 @@ func (qb *SceneQueryBuilder) Query(sceneFilter *SceneFilterType, findFilter *Fin
|
||||
}
|
||||
|
||||
if rating := sceneFilter.Rating; rating != nil {
|
||||
whereClauses = append(whereClauses, "rating = ?")
|
||||
args = append(args, *sceneFilter.Rating)
|
||||
clause, count := getIntCriterionWhereClause("rating", *sceneFilter.Rating)
|
||||
whereClauses = append(whereClauses, clause)
|
||||
if count == 1 {
|
||||
args = append(args, sceneFilter.Rating.Value)
|
||||
}
|
||||
}
|
||||
|
||||
if resolutionFilter := sceneFilter.Resolution; resolutionFilter != nil {
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"github.com/jmoiron/sqlx"
|
||||
"github.com/stashapp/stash/pkg/database"
|
||||
"github.com/stashapp/stash/pkg/logger"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -104,6 +105,48 @@ func getInBinding(length int) string {
|
||||
return "(" + bindings + ")"
|
||||
}
|
||||
|
||||
func getCriterionModifierBinding(criterionModifier CriterionModifier, value interface{}) (string, int) {
|
||||
var length int
|
||||
switch x := value.(type) {
|
||||
case []string:
|
||||
length = len(x)
|
||||
case []int:
|
||||
length = len(x)
|
||||
default:
|
||||
length = 1
|
||||
logger.Debugf("unsupported type: %T\n", x)
|
||||
}
|
||||
if modifier := criterionModifier.String(); criterionModifier.IsValid() {
|
||||
switch modifier {
|
||||
case "EQUALS":
|
||||
return "= ?", 1
|
||||
case "NOT_EQUALS":
|
||||
return "!= ?", 1
|
||||
case "GREATER_THAN":
|
||||
return "> ?", 1
|
||||
case "LESS_THAN":
|
||||
return "< ?", 1
|
||||
case "IS_NULL":
|
||||
return "IS NULL", 0
|
||||
case "NOT_NULL":
|
||||
return "IS NOT NULL", 0
|
||||
case "INCLUDES":
|
||||
return "IN "+getInBinding(length), length // TODO?
|
||||
case "EXCLUDES":
|
||||
return "NOT IN "+getInBinding(length), length // TODO?
|
||||
default:
|
||||
logger.Errorf("todo")
|
||||
return "= ?", 1 // TODO
|
||||
}
|
||||
}
|
||||
return "= ?", 1 // TODO
|
||||
}
|
||||
|
||||
func getIntCriterionWhereClause(column string, input IntCriterionInput) (string, int) {
|
||||
binding, count := getCriterionModifierBinding(input.Modifier, input.Value)
|
||||
return column+" "+binding, count
|
||||
}
|
||||
|
||||
func runIdsQuery(query string, args []interface{}) ([]int, error) {
|
||||
var result []struct {
|
||||
Int int `db:"id"`
|
||||
|
||||
@@ -357,7 +357,7 @@ input SceneMarkerFilterType {
|
||||
|
||||
input SceneFilterType {
|
||||
"""Filter by rating"""
|
||||
rating: Int
|
||||
rating: IntCriterionInput
|
||||
"""Filter by resolution"""
|
||||
resolution: ResolutionEnum
|
||||
"""Filter to only include scenes which have markers. `true` or `false`"""
|
||||
@@ -372,6 +372,28 @@ input SceneFilterType {
|
||||
performer_id: ID
|
||||
}
|
||||
|
||||
enum CriterionModifier {
|
||||
"""="""
|
||||
EQUALS,
|
||||
"""!="""
|
||||
NOT_EQUALS,
|
||||
""">"""
|
||||
GREATER_THAN,
|
||||
"""<"""
|
||||
LESS_THAN,
|
||||
"""IS NULL"""
|
||||
IS_NULL,
|
||||
"""IS NOT NULL"""
|
||||
NOT_NULL,
|
||||
INCLUDES,
|
||||
EXCLUDES,
|
||||
}
|
||||
|
||||
input IntCriterionInput {
|
||||
value: Int!
|
||||
modifier: CriterionModifier!
|
||||
}
|
||||
|
||||
#######################################
|
||||
# Config
|
||||
#######################################
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
import _ from "lodash";
|
||||
import React, { FunctionComponent, useEffect, useRef, useState } from "react";
|
||||
import { isArray } from "util";
|
||||
import { CriterionModifier } from "../../core/generated-graphql";
|
||||
import { Criterion, CriterionType } from "../../models/list-filter/criteria/criterion";
|
||||
import { NoneCriterion } from "../../models/list-filter/criteria/none";
|
||||
import { PerformersCriterion } from "../../models/list-filter/criteria/performers";
|
||||
@@ -18,7 +19,7 @@ import { ListFilterModel } from "../../models/list-filter/filter";
|
||||
import { FilterMultiSelect } from "../select/FilterMultiSelect";
|
||||
|
||||
interface IAddFilterProps {
|
||||
onAddCriterion: (criterion: Criterion) => void;
|
||||
onAddCriterion: (criterion: Criterion, oldId?: string) => void;
|
||||
onCancel: () => void;
|
||||
filter: ListFilterModel;
|
||||
editingCriterion?: Criterion;
|
||||
@@ -43,6 +44,12 @@ export const AddFilter: FunctionComponent<IAddFilterProps> = (props: IAddFilterP
|
||||
setCriterion(newCriterion);
|
||||
}
|
||||
|
||||
function onChangedModifierSelect(event: React.ChangeEvent<HTMLSelectElement>) {
|
||||
const newCriterion = _.cloneDeep(criterion);
|
||||
newCriterion.modifier = event.target.value as any;
|
||||
setCriterion(newCriterion);
|
||||
}
|
||||
|
||||
function onChangedSingleSelect(event: React.ChangeEvent<HTMLSelectElement>) {
|
||||
const newCriterion = _.cloneDeep(criterion);
|
||||
newCriterion.value = event.target.value;
|
||||
@@ -54,7 +61,8 @@ export const AddFilter: FunctionComponent<IAddFilterProps> = (props: IAddFilterP
|
||||
const value = singleValueSelect.current.props.defaultValue;
|
||||
if (value === undefined || value === "" || typeof value === "number") { criterion.value = criterion.options[0]; }
|
||||
}
|
||||
props.onAddCriterion(criterion);
|
||||
const oldId = !!props.editingCriterion ? props.editingCriterion.getId() : undefined;
|
||||
props.onAddCriterion(criterion, oldId);
|
||||
onToggle();
|
||||
}
|
||||
|
||||
@@ -69,7 +77,25 @@ export const AddFilter: FunctionComponent<IAddFilterProps> = (props: IAddFilterP
|
||||
const maybeRenderFilterPopoverContents = () => {
|
||||
if (criterion.type === "none") { return; }
|
||||
|
||||
function renderModifier() {
|
||||
if (criterion.modifierOptions.length === 0) { return; }
|
||||
return (
|
||||
<div>
|
||||
<HTMLSelect
|
||||
options={criterion.modifierOptions}
|
||||
onChange={onChangedModifierSelect}
|
||||
defaultValue={criterion.modifier}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function renderSelect() {
|
||||
// Hide the value select if the modifier is "IsNull" or "NotNull"
|
||||
if (criterion.modifier === CriterionModifier.IsNull || criterion.modifier === CriterionModifier.NotNull) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isArray(criterion.value)) {
|
||||
let type: "performers" | "studios" | "tags" | "" = "";
|
||||
if (criterion instanceof PerformersCriterion) {
|
||||
@@ -103,7 +129,12 @@ export const AddFilter: FunctionComponent<IAddFilterProps> = (props: IAddFilterP
|
||||
);
|
||||
}
|
||||
}
|
||||
return <FormGroup>{renderSelect()}</FormGroup>;
|
||||
return (
|
||||
<FormGroup>
|
||||
{renderModifier()}
|
||||
{renderSelect()}
|
||||
</FormGroup>
|
||||
);
|
||||
};
|
||||
|
||||
function maybeRenderFilterSelect() {
|
||||
|
||||
@@ -23,7 +23,7 @@ interface IListFilterProps {
|
||||
onChangeSortDirection: (sortDirection: "asc" | "desc") => void;
|
||||
onChangeSortBy: (sortBy: string) => void;
|
||||
onChangeDisplayMode: (displayMode: DisplayMode) => void;
|
||||
onAddCriterion: (criterion: Criterion) => void;
|
||||
onAddCriterion: (criterion: Criterion, oldId?: string) => void;
|
||||
onRemoveCriterion: (criterion: Criterion) => void;
|
||||
filter: ListFilterModel;
|
||||
}
|
||||
@@ -67,8 +67,8 @@ export const ListFilter: FunctionComponent<IListFilterProps> = (props: IListFilt
|
||||
props.onChangeDisplayMode(displayMode);
|
||||
}
|
||||
|
||||
function onAddCriterion(criterion: Criterion) {
|
||||
props.onAddCriterion(criterion);
|
||||
function onAddCriterion(criterion: Criterion, oldId?: string) {
|
||||
props.onAddCriterion(criterion, oldId);
|
||||
}
|
||||
|
||||
function onCancelAddCriterion() {
|
||||
@@ -122,7 +122,7 @@ export const ListFilter: FunctionComponent<IListFilterProps> = (props: IListFilt
|
||||
function renderFilterTags() {
|
||||
return props.filter.criteria.map((criterion) => (
|
||||
<Tag
|
||||
key={criterion.type}
|
||||
key={criterion.getId()}
|
||||
className="tag-item"
|
||||
itemID={criterion.getId()}
|
||||
interactive={true}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/* tslint:disable */
|
||||
// Generated in 2019-03-24T09:16:39-07:00
|
||||
// Generated in 2019-03-24T13:29:34-07:00
|
||||
export type Maybe<T> = T | undefined;
|
||||
|
||||
export interface SceneFilterType {
|
||||
/** Filter by rating */
|
||||
rating?: Maybe<number>;
|
||||
rating?: Maybe<IntCriterionInput>;
|
||||
/** Filter by resolution */
|
||||
resolution?: Maybe<ResolutionEnum>;
|
||||
/** Filter to only include scenes which have markers. `true` or `false` */
|
||||
@@ -19,6 +19,12 @@ export interface SceneFilterType {
|
||||
performer_id?: Maybe<string>;
|
||||
}
|
||||
|
||||
export interface IntCriterionInput {
|
||||
value: number;
|
||||
|
||||
modifier: CriterionModifier;
|
||||
}
|
||||
|
||||
export interface FindFilterType {
|
||||
q?: Maybe<string>;
|
||||
|
||||
@@ -222,6 +228,17 @@ export interface ConfigGeneralInput {
|
||||
generatedPath?: Maybe<string>;
|
||||
}
|
||||
|
||||
export enum CriterionModifier {
|
||||
Equals = "EQUALS",
|
||||
NotEquals = "NOT_EQUALS",
|
||||
GreaterThan = "GREATER_THAN",
|
||||
LessThan = "LESS_THAN",
|
||||
IsNull = "IS_NULL",
|
||||
NotNull = "NOT_NULL",
|
||||
Includes = "INCLUDES",
|
||||
Excludes = "EXCLUDES"
|
||||
}
|
||||
|
||||
export enum ResolutionEnum {
|
||||
Low = "LOW",
|
||||
Standard = "STANDARD",
|
||||
|
||||
@@ -117,14 +117,26 @@ export class ListHook {
|
||||
setFilter(newFilter);
|
||||
}
|
||||
|
||||
function onAddCriterion(criterion: Criterion) {
|
||||
function onAddCriterion(criterion: Criterion, oldId?: string) {
|
||||
const newFilter = _.cloneDeep(filter);
|
||||
const existingIndex = newFilter.criteria.findIndex((c) => c.getId() === criterion.getId());
|
||||
|
||||
// Find if we are editing an existing criteria, then modify that. Or create a new one.
|
||||
const existingIndex = newFilter.criteria.findIndex((c) => {
|
||||
// If we modified an existing criterion, then look for the old id.
|
||||
const id = !!oldId ? oldId : criterion.getId();
|
||||
return c.getId() === id;
|
||||
});
|
||||
if (existingIndex === -1) {
|
||||
newFilter.criteria.push(criterion);
|
||||
} else {
|
||||
newFilter.criteria[existingIndex] = criterion;
|
||||
}
|
||||
|
||||
// Remove duplicate modifiers
|
||||
newFilter.criteria = newFilter.criteria.filter((obj, pos, arr) => {
|
||||
return arr.map((mapObj: any) => mapObj.getId()).indexOf(obj.getId()) === pos;
|
||||
});
|
||||
|
||||
newFilter.currentPage = 1;
|
||||
setFilter(newFilter);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { isArray } from "util";
|
||||
import { ILabeledId } from "../types";
|
||||
import { CriterionModifier } from "../../../core/generated-graphql";
|
||||
import { ILabeledId, ILabeledValue } from "../types";
|
||||
|
||||
export type CriterionType =
|
||||
"none" |
|
||||
@@ -13,15 +14,6 @@ export type CriterionType =
|
||||
"performers" |
|
||||
"studios";
|
||||
|
||||
export enum CriterionModifier {
|
||||
Equals,
|
||||
NotEquals,
|
||||
GreaterThan,
|
||||
LessThan,
|
||||
Inclusive,
|
||||
Exclusive,
|
||||
}
|
||||
|
||||
export abstract class Criterion<Option = any, Value = any> {
|
||||
public static getLabel(type: CriterionType = "none"): string {
|
||||
switch (type) {
|
||||
@@ -38,9 +30,23 @@ export abstract class Criterion<Option = any, Value = any> {
|
||||
}
|
||||
}
|
||||
|
||||
public static getModifierOption(modifier: CriterionModifier = CriterionModifier.Equals): ILabeledValue {
|
||||
switch (modifier) {
|
||||
case CriterionModifier.Equals: return {value: CriterionModifier.Equals, label: "Equals"};
|
||||
case CriterionModifier.NotEquals: return {value: CriterionModifier.NotEquals, label: "Not Equals"};
|
||||
case CriterionModifier.GreaterThan: return {value: CriterionModifier.GreaterThan, label: "Greater Than"};
|
||||
case CriterionModifier.LessThan: return {value: CriterionModifier.LessThan, label: "Less Than"};
|
||||
case CriterionModifier.IsNull: return {value: CriterionModifier.IsNull, label: "Is NULL"};
|
||||
case CriterionModifier.NotNull: return {value: CriterionModifier.NotNull, label: "Not NULL"};
|
||||
case CriterionModifier.Includes: return {value: CriterionModifier.Includes, label: "Includes"};
|
||||
case CriterionModifier.Excludes: return {value: CriterionModifier.Excludes, label: "Excludes"};
|
||||
}
|
||||
}
|
||||
|
||||
public abstract type: CriterionType;
|
||||
public abstract parameterName: string;
|
||||
public abstract modifier: CriterionModifier;
|
||||
public abstract modifierOptions: ILabeledValue[];
|
||||
public abstract options: Option[];
|
||||
public abstract value: Value;
|
||||
|
||||
@@ -51,13 +57,17 @@ export abstract class Criterion<Option = any, Value = any> {
|
||||
case CriterionModifier.NotEquals: modifierString = "is not"; break;
|
||||
case CriterionModifier.GreaterThan: modifierString = "is greater than"; break;
|
||||
case CriterionModifier.LessThan: modifierString = "is less than"; break;
|
||||
case CriterionModifier.Inclusive: modifierString = "includes"; break;
|
||||
case CriterionModifier.Exclusive: modifierString = "exculdes"; break;
|
||||
case CriterionModifier.IsNull: modifierString = "is null"; break;
|
||||
case CriterionModifier.NotNull: modifierString = "is not null"; break;
|
||||
case CriterionModifier.Includes: modifierString = "includes"; break;
|
||||
case CriterionModifier.Excludes: modifierString = "exculdes"; break;
|
||||
default: modifierString = "";
|
||||
}
|
||||
|
||||
let valueString: string;
|
||||
if (isArray(this.value) && this.value.length > 0) {
|
||||
if (this.modifier === CriterionModifier.IsNull || this.modifier === CriterionModifier.NotNull) {
|
||||
valueString = "";
|
||||
} else if (isArray(this.value) && this.value.length > 0) {
|
||||
let items = this.value;
|
||||
if ((this.value as ILabeledId[])[0].label) {
|
||||
items = this.value.map((item) => item.label) as any;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { CriterionModifier } from "../../../core/generated-graphql";
|
||||
import {
|
||||
Criterion,
|
||||
CriterionModifier,
|
||||
CriterionType,
|
||||
ICriterionOption,
|
||||
} from "./criterion";
|
||||
@@ -9,6 +9,7 @@ export class FavoriteCriterion extends Criterion<string, string> {
|
||||
public type: CriterionType = "favorite";
|
||||
public parameterName: string = "filter_favorites";
|
||||
public modifier = CriterionModifier.Equals;
|
||||
public modifierOptions = [];
|
||||
public options: string[] = [true.toString(), false.toString()];
|
||||
public value: string = "";
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { CriterionModifier } from "../../../core/generated-graphql";
|
||||
import {
|
||||
Criterion,
|
||||
CriterionModifier,
|
||||
CriterionType,
|
||||
ICriterionOption,
|
||||
} from "./criterion";
|
||||
@@ -9,6 +9,7 @@ export class HasMarkersCriterion extends Criterion<string, string> {
|
||||
public type: CriterionType = "hasMarkers";
|
||||
public parameterName: string = "has_markers";
|
||||
public modifier = CriterionModifier.Equals;
|
||||
public modifierOptions = [];
|
||||
public options: string[] = [true.toString(), false.toString()];
|
||||
public value: string = "";
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { CriterionModifier } from "../../../core/generated-graphql";
|
||||
import {
|
||||
Criterion,
|
||||
CriterionModifier,
|
||||
CriterionType,
|
||||
ICriterionOption,
|
||||
} from "./criterion";
|
||||
@@ -9,6 +9,7 @@ export class IsMissingCriterion extends Criterion<string, string> {
|
||||
public type: CriterionType = "isMissing";
|
||||
public parameterName: string = "is_missing";
|
||||
public modifier = CriterionModifier.Equals;
|
||||
public modifierOptions = [];
|
||||
public options: string[] = ["title", "url", "date", "gallery", "studio", "performers"];
|
||||
public value: string = "";
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { CriterionModifier } from "../../../core/generated-graphql";
|
||||
import {
|
||||
Criterion,
|
||||
CriterionModifier,
|
||||
CriterionType,
|
||||
ICriterionOption,
|
||||
} from "./criterion";
|
||||
@@ -9,6 +9,7 @@ export class NoneCriterion extends Criterion<any, any> {
|
||||
public type: CriterionType = "none";
|
||||
public parameterName: string = "";
|
||||
public modifier = CriterionModifier.Equals;
|
||||
public modifierOptions = [];
|
||||
public options: any;
|
||||
public value: any;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { CriterionModifier } from "../../../core/generated-graphql";
|
||||
import { ILabeledId } from "../types";
|
||||
import {
|
||||
Criterion,
|
||||
CriterionModifier,
|
||||
CriterionType,
|
||||
ICriterionOption,
|
||||
} from "./criterion";
|
||||
@@ -16,6 +16,7 @@ export class PerformersCriterion extends Criterion<IOptionType, ILabeledId[]> {
|
||||
public type: CriterionType = "performers";
|
||||
public parameterName: string = "performers";
|
||||
public modifier = CriterionModifier.Equals;
|
||||
public modifierOptions = [];
|
||||
public options: IOptionType[] = [];
|
||||
public value: ILabeledId[] = [];
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { CriterionModifier } from "../../../core/generated-graphql";
|
||||
import {
|
||||
Criterion,
|
||||
CriterionModifier,
|
||||
CriterionType,
|
||||
ICriterionOption,
|
||||
} from "./criterion";
|
||||
@@ -9,6 +9,14 @@ export class RatingCriterion extends Criterion<number, number> { // TODO <number
|
||||
public type: CriterionType = "rating";
|
||||
public parameterName: string = "rating";
|
||||
public modifier = CriterionModifier.Equals;
|
||||
public modifierOptions = [
|
||||
Criterion.getModifierOption(CriterionModifier.Equals),
|
||||
Criterion.getModifierOption(CriterionModifier.NotEquals),
|
||||
Criterion.getModifierOption(CriterionModifier.GreaterThan),
|
||||
Criterion.getModifierOption(CriterionModifier.LessThan),
|
||||
Criterion.getModifierOption(CriterionModifier.IsNull),
|
||||
Criterion.getModifierOption(CriterionModifier.NotNull),
|
||||
];
|
||||
public options: number[] = [1, 2, 3, 4, 5];
|
||||
public value: number = 0;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { CriterionModifier } from "../../../core/generated-graphql";
|
||||
import {
|
||||
Criterion,
|
||||
CriterionModifier,
|
||||
CriterionType,
|
||||
ICriterionOption,
|
||||
} from "./criterion";
|
||||
@@ -9,6 +9,7 @@ export class ResolutionCriterion extends Criterion<string, string> { // TODO <st
|
||||
public type: CriterionType = "resolution";
|
||||
public parameterName: string = "resolution";
|
||||
public modifier = CriterionModifier.Equals;
|
||||
public modifierOptions = [];
|
||||
public options: string[] = ["240p", "480p", "720p", "1080p", "4k"];
|
||||
public value: string = "";
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { CriterionModifier } from "../../../core/generated-graphql";
|
||||
import { ILabeledId } from "../types";
|
||||
import {
|
||||
Criterion,
|
||||
CriterionModifier,
|
||||
CriterionType,
|
||||
ICriterionOption,
|
||||
} from "./criterion";
|
||||
@@ -16,6 +16,7 @@ export class StudiosCriterion extends Criterion<IOptionType, ILabeledId[]> {
|
||||
public type: CriterionType = "studios";
|
||||
public parameterName: string = "studios";
|
||||
public modifier = CriterionModifier.Equals;
|
||||
public modifierOptions = [];
|
||||
public options: IOptionType[] = [];
|
||||
public value: ILabeledId[] = [];
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import * as GQL from "../../../core/generated-graphql";
|
||||
import { CriterionModifier } from "../../../core/generated-graphql";
|
||||
import { ILabeledId } from "../types";
|
||||
import {
|
||||
Criterion,
|
||||
CriterionModifier,
|
||||
CriterionType,
|
||||
ICriterionOption,
|
||||
} from "./criterion";
|
||||
@@ -11,6 +11,7 @@ export class TagsCriterion extends Criterion<GQL.AllTagsForFilterAllTags, ILabel
|
||||
public type: CriterionType;
|
||||
public parameterName: string;
|
||||
public modifier = CriterionModifier.Equals;
|
||||
public modifierOptions = [];
|
||||
public options: GQL.AllTagsForFilterAllTags[] = [];
|
||||
public value: ILabeledId[] = [];
|
||||
|
||||
|
||||
@@ -157,6 +157,7 @@ export class ListFilterModel {
|
||||
const encodedCriterion = JSON.parse(jsonString);
|
||||
const criterion = makeCriteria(encodedCriterion.type);
|
||||
criterion.value = encodedCriterion.value;
|
||||
criterion.modifier = encodedCriterion.modifier;
|
||||
this.criteria.push(criterion);
|
||||
}
|
||||
}
|
||||
@@ -168,6 +169,7 @@ export class ListFilterModel {
|
||||
const encodedCriterion: any = {};
|
||||
encodedCriterion.type = criterion.type;
|
||||
encodedCriterion.value = criterion.value;
|
||||
encodedCriterion.modifier = criterion.modifier;
|
||||
const jsonCriterion = JSON.stringify(encodedCriterion);
|
||||
encodedCriteria.push(jsonCriterion);
|
||||
});
|
||||
@@ -200,7 +202,8 @@ export class ListFilterModel {
|
||||
this.criteria.forEach((criterion) => {
|
||||
switch (criterion.type) {
|
||||
case "rating":
|
||||
result.rating = (criterion as RatingCriterion).value;
|
||||
const crit = criterion as RatingCriterion;
|
||||
result.rating = { value: crit.value, modifier: crit.modifier };
|
||||
break;
|
||||
case "resolution": {
|
||||
switch ((criterion as ResolutionCriterion).value) {
|
||||
|
||||
@@ -16,3 +16,8 @@ export interface ILabeledId {
|
||||
id: string;
|
||||
label: string;
|
||||
}
|
||||
|
||||
export interface ILabeledValue {
|
||||
label: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user