mirror of
https://github.com/stashapp/stash.git
synced 2025-12-18 12:54:38 +03:00
Saved filters (#1474)
* Refactor list filter * Filter/criterion refactor * Rename option value to type * Remove None from options * Add saved filter button * Integrate default filters
This commit is contained in:
@@ -1,6 +1,10 @@
|
||||
import { CriterionOption, StringCriterion } from "./criterion";
|
||||
import { StringCriterion, StringCriterionOption } from "./criterion";
|
||||
|
||||
const countryCriterionOption = new CriterionOption("country", "country");
|
||||
const countryCriterionOption = new StringCriterionOption(
|
||||
"country",
|
||||
"country",
|
||||
"country"
|
||||
);
|
||||
|
||||
export class CountryCriterion extends StringCriterion {
|
||||
constructor() {
|
||||
|
||||
@@ -16,106 +16,58 @@ import {
|
||||
IHierarchicalLabelValue,
|
||||
} from "../types";
|
||||
|
||||
type Option = string | number | IOptionType;
|
||||
export type Option = string | number | IOptionType;
|
||||
export type CriterionValue =
|
||||
| string
|
||||
| number
|
||||
| ILabeledId[]
|
||||
| IHierarchicalLabelValue;
|
||||
|
||||
const modifierMessageIDs = {
|
||||
[CriterionModifier.Equals]: "criterion_modifier.equals",
|
||||
[CriterionModifier.NotEquals]: "criterion_modifier.not_equals",
|
||||
[CriterionModifier.GreaterThan]: "criterion_modifier.greater_than",
|
||||
[CriterionModifier.LessThan]: "criterion_modifier.less_than",
|
||||
[CriterionModifier.IsNull]: "criterion_modifier.is_null",
|
||||
[CriterionModifier.NotNull]: "criterion_modifier.not_null",
|
||||
[CriterionModifier.Includes]: "criterion_modifier.includes",
|
||||
[CriterionModifier.IncludesAll]: "criterion_modifier.includes_all",
|
||||
[CriterionModifier.Excludes]: "criterion_modifier.excludes",
|
||||
[CriterionModifier.MatchesRegex]: "criterion_modifier.matches_regex",
|
||||
[CriterionModifier.NotMatchesRegex]: "criterion_modifier.not_matches_regex",
|
||||
};
|
||||
|
||||
// V = criterion value type
|
||||
export abstract class Criterion<V extends CriterionValue> {
|
||||
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.IncludesAll:
|
||||
return { value: CriterionModifier.IncludesAll, label: "Includes All" };
|
||||
case CriterionModifier.Includes:
|
||||
return { value: CriterionModifier.Includes, label: "Includes" };
|
||||
case CriterionModifier.Excludes:
|
||||
return { value: CriterionModifier.Excludes, label: "Excludes" };
|
||||
case CriterionModifier.MatchesRegex:
|
||||
return {
|
||||
value: CriterionModifier.MatchesRegex,
|
||||
label: "Matches Regex",
|
||||
};
|
||||
case CriterionModifier.NotMatchesRegex:
|
||||
return {
|
||||
value: CriterionModifier.NotMatchesRegex,
|
||||
label: "Not Matches Regex",
|
||||
};
|
||||
}
|
||||
const messageID = modifierMessageIDs[modifier];
|
||||
return { value: modifier, label: messageID };
|
||||
}
|
||||
|
||||
public criterionOption: CriterionOption;
|
||||
public abstract modifier: CriterionModifier;
|
||||
public abstract modifierOptions: ILabeledValue[];
|
||||
public abstract options: Option[] | undefined;
|
||||
public abstract value: V;
|
||||
public inputType: "number" | "text" | undefined;
|
||||
public modifier: CriterionModifier;
|
||||
public value: V;
|
||||
|
||||
public abstract getLabelValue(): string;
|
||||
|
||||
constructor(type: CriterionOption) {
|
||||
constructor(type: CriterionOption, value: V) {
|
||||
this.criterionOption = type;
|
||||
this.modifier = type.defaultModifier;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static getModifierLabel(intl: IntlShape, modifier: CriterionModifier) {
|
||||
const modifierMessageID = modifierMessageIDs[modifier];
|
||||
|
||||
return modifierMessageID
|
||||
? intl.formatMessage({ id: modifierMessageID })
|
||||
: "";
|
||||
}
|
||||
|
||||
public getLabel(intl: IntlShape): string {
|
||||
let modifierMessageID: string;
|
||||
switch (this.modifier) {
|
||||
case CriterionModifier.Equals:
|
||||
modifierMessageID = "criterion_modifier.equals";
|
||||
break;
|
||||
case CriterionModifier.NotEquals:
|
||||
modifierMessageID = "criterion_modifier.not_equals";
|
||||
break;
|
||||
case CriterionModifier.GreaterThan:
|
||||
modifierMessageID = "criterion_modifier.greater_than";
|
||||
break;
|
||||
case CriterionModifier.LessThan:
|
||||
modifierMessageID = "criterion_modifier.less_than";
|
||||
break;
|
||||
case CriterionModifier.IsNull:
|
||||
modifierMessageID = "criterion_modifier.is_null";
|
||||
break;
|
||||
case CriterionModifier.NotNull:
|
||||
modifierMessageID = "criterion_modifier.not_null";
|
||||
break;
|
||||
case CriterionModifier.Includes:
|
||||
modifierMessageID = "criterion_modifier.includes";
|
||||
break;
|
||||
case CriterionModifier.IncludesAll:
|
||||
modifierMessageID = "criterion_modifier.includes_all";
|
||||
break;
|
||||
case CriterionModifier.Excludes:
|
||||
modifierMessageID = "criterion_modifier.excludes";
|
||||
break;
|
||||
case CriterionModifier.MatchesRegex:
|
||||
modifierMessageID = "criterion_modifier.matches_regex";
|
||||
break;
|
||||
case CriterionModifier.NotMatchesRegex:
|
||||
modifierMessageID = "criterion_modifier.not_matches_regex";
|
||||
break;
|
||||
default:
|
||||
modifierMessageID = "";
|
||||
}
|
||||
|
||||
const modifierString = modifierMessageID
|
||||
? intl.formatMessage({ id: modifierMessageID })
|
||||
: "";
|
||||
const modifierString = Criterion.getModifierLabel(intl, this.modifier);
|
||||
let valueString = "";
|
||||
|
||||
if (
|
||||
@@ -145,7 +97,7 @@ export abstract class Criterion<V extends CriterionValue> {
|
||||
|
||||
public toJSON() {
|
||||
const encodedCriterion = {
|
||||
type: this.criterionOption.value,
|
||||
type: this.criterionOption.type,
|
||||
// #394 - the presence of a # symbol results in the query URL being
|
||||
// malformed. We could set encode: true in the queryString.stringify
|
||||
// call below, but this results in a URL that gets pretty long and ugly.
|
||||
@@ -171,37 +123,72 @@ export abstract class Criterion<V extends CriterionValue> {
|
||||
}
|
||||
}
|
||||
|
||||
export type InputType = "number" | "text" | undefined;
|
||||
|
||||
interface ICriterionOptionsParams {
|
||||
messageID: string;
|
||||
type: CriterionType;
|
||||
inputType?: InputType;
|
||||
parameterName?: string;
|
||||
modifierOptions?: CriterionModifier[];
|
||||
defaultModifier?: CriterionModifier;
|
||||
options?: Option[];
|
||||
}
|
||||
export class CriterionOption {
|
||||
public readonly messageID: string;
|
||||
public readonly value: CriterionType;
|
||||
public readonly type: CriterionType;
|
||||
public readonly parameterName: string;
|
||||
public readonly modifierOptions: ILabeledValue[];
|
||||
public readonly defaultModifier: CriterionModifier;
|
||||
public readonly options: Option[] | undefined;
|
||||
public readonly inputType: InputType;
|
||||
|
||||
constructor(messageID: string, value: CriterionType, parameterName?: string) {
|
||||
this.messageID = messageID;
|
||||
this.value = value;
|
||||
this.parameterName = parameterName ?? value;
|
||||
constructor(options: ICriterionOptionsParams) {
|
||||
this.messageID = options.messageID;
|
||||
this.type = options.type;
|
||||
this.parameterName = options.parameterName ?? options.type;
|
||||
this.modifierOptions = (options.modifierOptions ?? []).map((o) =>
|
||||
Criterion.getModifierOption(o)
|
||||
);
|
||||
this.defaultModifier = options.defaultModifier ?? CriterionModifier.Equals;
|
||||
this.options = options.options;
|
||||
this.inputType = options.inputType;
|
||||
}
|
||||
}
|
||||
|
||||
export function createCriterionOption(value: CriterionType) {
|
||||
return new CriterionOption(value, value);
|
||||
export class StringCriterionOption extends CriterionOption {
|
||||
constructor(
|
||||
messageID: string,
|
||||
value: CriterionType,
|
||||
parameterName?: string,
|
||||
options?: Option[]
|
||||
) {
|
||||
super({
|
||||
messageID,
|
||||
type: value,
|
||||
parameterName,
|
||||
modifierOptions: [
|
||||
CriterionModifier.Equals,
|
||||
CriterionModifier.NotEquals,
|
||||
CriterionModifier.Includes,
|
||||
CriterionModifier.Excludes,
|
||||
CriterionModifier.IsNull,
|
||||
CriterionModifier.NotNull,
|
||||
CriterionModifier.MatchesRegex,
|
||||
CriterionModifier.NotMatchesRegex,
|
||||
],
|
||||
defaultModifier: CriterionModifier.Equals,
|
||||
options,
|
||||
inputType: "text",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function createStringCriterionOption(value: CriterionType) {
|
||||
return new StringCriterionOption(value, value, value);
|
||||
}
|
||||
|
||||
export class StringCriterion extends Criterion<string> {
|
||||
public modifier = CriterionModifier.Equals;
|
||||
public modifierOptions = [
|
||||
StringCriterion.getModifierOption(CriterionModifier.Equals),
|
||||
StringCriterion.getModifierOption(CriterionModifier.NotEquals),
|
||||
StringCriterion.getModifierOption(CriterionModifier.Includes),
|
||||
StringCriterion.getModifierOption(CriterionModifier.Excludes),
|
||||
StringCriterion.getModifierOption(CriterionModifier.IsNull),
|
||||
StringCriterion.getModifierOption(CriterionModifier.NotNull),
|
||||
StringCriterion.getModifierOption(CriterionModifier.MatchesRegex),
|
||||
StringCriterion.getModifierOption(CriterionModifier.NotMatchesRegex),
|
||||
];
|
||||
public options: string[] | undefined;
|
||||
public value: string = "";
|
||||
|
||||
public getLabelValue() {
|
||||
return this.value;
|
||||
}
|
||||
@@ -218,74 +205,125 @@ export class StringCriterion extends Criterion<string> {
|
||||
return str.replaceAll(c, encodeURIComponent(c));
|
||||
}
|
||||
|
||||
constructor(type: CriterionOption, options?: string[]) {
|
||||
super(type);
|
||||
|
||||
this.options = options;
|
||||
this.inputType = "text";
|
||||
constructor(type: CriterionOption) {
|
||||
super(type, "");
|
||||
}
|
||||
}
|
||||
|
||||
export class MandatoryStringCriterion extends StringCriterion {
|
||||
public modifierOptions = [
|
||||
StringCriterion.getModifierOption(CriterionModifier.Equals),
|
||||
StringCriterion.getModifierOption(CriterionModifier.NotEquals),
|
||||
StringCriterion.getModifierOption(CriterionModifier.Includes),
|
||||
StringCriterion.getModifierOption(CriterionModifier.Excludes),
|
||||
StringCriterion.getModifierOption(CriterionModifier.MatchesRegex),
|
||||
StringCriterion.getModifierOption(CriterionModifier.NotMatchesRegex),
|
||||
];
|
||||
export class MandatoryStringCriterionOption extends CriterionOption {
|
||||
constructor(
|
||||
messageID: string,
|
||||
value: CriterionType,
|
||||
parameterName?: string,
|
||||
options?: Option[]
|
||||
) {
|
||||
super({
|
||||
messageID,
|
||||
type: value,
|
||||
parameterName,
|
||||
modifierOptions: [
|
||||
CriterionModifier.Equals,
|
||||
CriterionModifier.NotEquals,
|
||||
CriterionModifier.Includes,
|
||||
CriterionModifier.Excludes,
|
||||
CriterionModifier.MatchesRegex,
|
||||
CriterionModifier.NotMatchesRegex,
|
||||
],
|
||||
defaultModifier: CriterionModifier.Equals,
|
||||
options,
|
||||
inputType: "text",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export class BooleanCriterionOption extends CriterionOption {
|
||||
constructor(messageID: string, value: CriterionType, parameterName?: string) {
|
||||
super({
|
||||
messageID,
|
||||
type: value,
|
||||
parameterName,
|
||||
modifierOptions: [],
|
||||
defaultModifier: CriterionModifier.Equals,
|
||||
options: [true.toString(), false.toString()],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export class BooleanCriterion extends StringCriterion {
|
||||
public modifier = CriterionModifier.Equals;
|
||||
public modifierOptions = [];
|
||||
|
||||
constructor(type: CriterionOption) {
|
||||
super(type, [true.toString(), false.toString()]);
|
||||
}
|
||||
|
||||
protected toCriterionInput(): boolean {
|
||||
return this.value === "true";
|
||||
}
|
||||
}
|
||||
|
||||
export class NumberCriterion extends Criterion<number> {
|
||||
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[] | undefined;
|
||||
public value: number = 0;
|
||||
export class NumberCriterionOption extends CriterionOption {
|
||||
constructor(
|
||||
messageID: string,
|
||||
value: CriterionType,
|
||||
parameterName?: string,
|
||||
options?: Option[]
|
||||
) {
|
||||
super({
|
||||
messageID,
|
||||
type: value,
|
||||
parameterName,
|
||||
modifierOptions: [
|
||||
CriterionModifier.Equals,
|
||||
CriterionModifier.NotEquals,
|
||||
CriterionModifier.GreaterThan,
|
||||
CriterionModifier.LessThan,
|
||||
CriterionModifier.IsNull,
|
||||
CriterionModifier.NotNull,
|
||||
],
|
||||
defaultModifier: CriterionModifier.Equals,
|
||||
options,
|
||||
inputType: "number",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function createNumberCriterionOption(value: CriterionType) {
|
||||
return new NumberCriterionOption(value, value, value);
|
||||
}
|
||||
|
||||
export class NumberCriterion extends Criterion<number> {
|
||||
public getLabelValue() {
|
||||
return this.value.toString();
|
||||
}
|
||||
|
||||
constructor(type: CriterionOption, options?: number[]) {
|
||||
super(type);
|
||||
|
||||
this.options = options;
|
||||
this.inputType = "number";
|
||||
constructor(type: CriterionOption) {
|
||||
super(type, 0);
|
||||
}
|
||||
}
|
||||
|
||||
export abstract class ILabeledIdCriterion extends Criterion<ILabeledId[]> {
|
||||
public modifier = CriterionModifier.IncludesAll;
|
||||
public modifierOptions = [
|
||||
Criterion.getModifierOption(CriterionModifier.IncludesAll),
|
||||
Criterion.getModifierOption(CriterionModifier.Includes),
|
||||
Criterion.getModifierOption(CriterionModifier.Excludes),
|
||||
];
|
||||
export class ILabeledIdCriterionOption extends CriterionOption {
|
||||
constructor(
|
||||
messageID: string,
|
||||
value: CriterionType,
|
||||
parameterName: string,
|
||||
includeAll: boolean
|
||||
) {
|
||||
const modifierOptions = [
|
||||
CriterionModifier.Includes,
|
||||
CriterionModifier.Excludes,
|
||||
];
|
||||
|
||||
public options: IOptionType[] = [];
|
||||
public value: ILabeledId[] = [];
|
||||
let defaultModifier = CriterionModifier.Includes;
|
||||
if (includeAll) {
|
||||
modifierOptions.unshift(CriterionModifier.IncludesAll);
|
||||
defaultModifier = CriterionModifier.IncludesAll;
|
||||
}
|
||||
|
||||
super({
|
||||
messageID,
|
||||
type: value,
|
||||
parameterName,
|
||||
modifierOptions,
|
||||
defaultModifier,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export class ILabeledIdCriterion extends Criterion<ILabeledId[]> {
|
||||
public getLabelValue(): string {
|
||||
return this.value.map((v) => v.label).join(", ");
|
||||
}
|
||||
@@ -303,33 +341,12 @@ export abstract class ILabeledIdCriterion extends Criterion<ILabeledId[]> {
|
||||
});
|
||||
}
|
||||
|
||||
constructor(type: CriterionOption, includeAll: boolean) {
|
||||
super(type);
|
||||
|
||||
if (!includeAll) {
|
||||
this.modifier = CriterionModifier.Includes;
|
||||
this.modifierOptions = [
|
||||
Criterion.getModifierOption(CriterionModifier.Includes),
|
||||
Criterion.getModifierOption(CriterionModifier.Excludes),
|
||||
];
|
||||
}
|
||||
constructor(type: CriterionOption) {
|
||||
super(type, []);
|
||||
}
|
||||
}
|
||||
|
||||
export abstract class IHierarchicalLabeledIdCriterion extends Criterion<IHierarchicalLabelValue> {
|
||||
public modifier = CriterionModifier.IncludesAll;
|
||||
public modifierOptions = [
|
||||
Criterion.getModifierOption(CriterionModifier.IncludesAll),
|
||||
Criterion.getModifierOption(CriterionModifier.Includes),
|
||||
Criterion.getModifierOption(CriterionModifier.Excludes),
|
||||
];
|
||||
|
||||
public options: IOptionType[] = [];
|
||||
public value: IHierarchicalLabelValue = {
|
||||
items: [],
|
||||
depth: 0,
|
||||
};
|
||||
|
||||
export class IHierarchicalLabeledIdCriterion extends Criterion<IHierarchicalLabelValue> {
|
||||
public encodeValue() {
|
||||
return {
|
||||
items: this.value.items.map((o) => {
|
||||
@@ -357,52 +374,41 @@ export abstract class IHierarchicalLabeledIdCriterion extends Criterion<IHierarc
|
||||
return `${labels} (+${this.value.depth > 0 ? this.value.depth : "all"})`;
|
||||
}
|
||||
|
||||
public toJSON() {
|
||||
const encodedCriterion = {
|
||||
type: this.criterionOption.value,
|
||||
value: this.encodeValue(),
|
||||
modifier: this.modifier,
|
||||
constructor(type: CriterionOption) {
|
||||
const value: IHierarchicalLabelValue = {
|
||||
items: [],
|
||||
depth: 0,
|
||||
};
|
||||
return JSON.stringify(encodedCriterion);
|
||||
}
|
||||
|
||||
constructor(type: CriterionOption, includeAll: boolean) {
|
||||
super(type);
|
||||
|
||||
if (!includeAll) {
|
||||
this.modifier = CriterionModifier.Includes;
|
||||
this.modifierOptions = [
|
||||
Criterion.getModifierOption(CriterionModifier.Includes),
|
||||
Criterion.getModifierOption(CriterionModifier.Excludes),
|
||||
];
|
||||
}
|
||||
super(type, value);
|
||||
}
|
||||
}
|
||||
|
||||
export class MandatoryNumberCriterion extends NumberCriterion {
|
||||
public modifierOptions = [
|
||||
Criterion.getModifierOption(CriterionModifier.Equals),
|
||||
Criterion.getModifierOption(CriterionModifier.NotEquals),
|
||||
Criterion.getModifierOption(CriterionModifier.GreaterThan),
|
||||
Criterion.getModifierOption(CriterionModifier.LessThan),
|
||||
];
|
||||
export class MandatoryNumberCriterionOption extends CriterionOption {
|
||||
constructor(messageID: string, value: CriterionType, parameterName?: string) {
|
||||
super({
|
||||
messageID,
|
||||
type: value,
|
||||
parameterName,
|
||||
modifierOptions: [
|
||||
CriterionModifier.Equals,
|
||||
CriterionModifier.NotEquals,
|
||||
CriterionModifier.GreaterThan,
|
||||
CriterionModifier.LessThan,
|
||||
],
|
||||
defaultModifier: CriterionModifier.Equals,
|
||||
inputType: "number",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function createMandatoryNumberCriterionOption(value: CriterionType) {
|
||||
return new MandatoryNumberCriterionOption(value, value, value);
|
||||
}
|
||||
|
||||
export class DurationCriterion extends Criterion<number> {
|
||||
public modifier = CriterionModifier.Equals;
|
||||
public modifierOptions = [
|
||||
Criterion.getModifierOption(CriterionModifier.Equals),
|
||||
Criterion.getModifierOption(CriterionModifier.NotEquals),
|
||||
Criterion.getModifierOption(CriterionModifier.GreaterThan),
|
||||
Criterion.getModifierOption(CriterionModifier.LessThan),
|
||||
];
|
||||
public options: number[] | undefined;
|
||||
public value: number = 0;
|
||||
|
||||
constructor(type: CriterionOption, options?: number[]) {
|
||||
super(type);
|
||||
|
||||
this.options = options;
|
||||
constructor(type: CriterionOption) {
|
||||
super(type, 0);
|
||||
}
|
||||
|
||||
public getLabelValue() {
|
||||
|
||||
@@ -3,25 +3,27 @@ import {
|
||||
StringCriterion,
|
||||
NumberCriterion,
|
||||
DurationCriterion,
|
||||
MandatoryStringCriterion,
|
||||
MandatoryNumberCriterion,
|
||||
CriterionOption,
|
||||
NumberCriterionOption,
|
||||
MandatoryStringCriterionOption,
|
||||
MandatoryNumberCriterionOption,
|
||||
StringCriterionOption,
|
||||
ILabeledIdCriterion,
|
||||
} from "./criterion";
|
||||
import { OrganizedCriterion } from "./organized";
|
||||
import { FavoriteCriterion } from "./favorite";
|
||||
import { HasMarkersCriterion } from "./has-markers";
|
||||
import {
|
||||
PerformerIsMissingCriterion,
|
||||
SceneIsMissingCriterion,
|
||||
GalleryIsMissingCriterion,
|
||||
TagIsMissingCriterion,
|
||||
StudioIsMissingCriterion,
|
||||
MovieIsMissingCriterion,
|
||||
ImageIsMissingCriterion,
|
||||
PerformerIsMissingCriterionOption,
|
||||
ImageIsMissingCriterionOption,
|
||||
TagIsMissingCriterionOption,
|
||||
SceneIsMissingCriterionOption,
|
||||
IsMissingCriterion,
|
||||
GalleryIsMissingCriterionOption,
|
||||
StudioIsMissingCriterionOption,
|
||||
MovieIsMissingCriterionOption,
|
||||
} from "./is-missing";
|
||||
import { NoneCriterion } from "./none";
|
||||
import { PerformersCriterion } from "./performers";
|
||||
import { RatingCriterion } from "./rating";
|
||||
import { AverageResolutionCriterion, ResolutionCriterion } from "./resolution";
|
||||
import { StudiosCriterion, ParentStudiosCriterion } from "./studios";
|
||||
import {
|
||||
@@ -31,19 +33,22 @@ import {
|
||||
TagsCriterionOption,
|
||||
} from "./tags";
|
||||
import { GenderCriterion } from "./gender";
|
||||
import { MoviesCriterion } from "./movies";
|
||||
import { MoviesCriterionOption } from "./movies";
|
||||
import { GalleriesCriterion } from "./galleries";
|
||||
import { CriterionType } from "../types";
|
||||
import { InteractiveCriterion } from "./interactive";
|
||||
import { RatingCriterionOption } from "./rating";
|
||||
|
||||
export function makeCriteria(type: CriterionType = "none") {
|
||||
switch (type) {
|
||||
case "none":
|
||||
return new NoneCriterion();
|
||||
case "path":
|
||||
return new MandatoryStringCriterion(new CriterionOption(type, type));
|
||||
return new StringCriterion(
|
||||
new MandatoryStringCriterionOption(type, type)
|
||||
);
|
||||
case "rating":
|
||||
return new RatingCriterion();
|
||||
return new NumberCriterion(RatingCriterionOption);
|
||||
case "organized":
|
||||
return new OrganizedCriterion();
|
||||
case "o_counter":
|
||||
@@ -53,31 +58,33 @@ export function makeCriteria(type: CriterionType = "none") {
|
||||
case "gallery_count":
|
||||
case "performer_count":
|
||||
case "tag_count":
|
||||
return new MandatoryNumberCriterion(new CriterionOption(type, type));
|
||||
return new NumberCriterion(
|
||||
new MandatoryNumberCriterionOption(type, type)
|
||||
);
|
||||
case "resolution":
|
||||
return new ResolutionCriterion();
|
||||
case "average_resolution":
|
||||
return new AverageResolutionCriterion();
|
||||
case "duration":
|
||||
return new DurationCriterion(new CriterionOption(type, type));
|
||||
return new DurationCriterion(new NumberCriterionOption(type, type));
|
||||
case "favorite":
|
||||
return new FavoriteCriterion();
|
||||
case "hasMarkers":
|
||||
return new HasMarkersCriterion();
|
||||
case "sceneIsMissing":
|
||||
return new SceneIsMissingCriterion();
|
||||
return new IsMissingCriterion(SceneIsMissingCriterionOption);
|
||||
case "imageIsMissing":
|
||||
return new ImageIsMissingCriterion();
|
||||
return new IsMissingCriterion(ImageIsMissingCriterionOption);
|
||||
case "performerIsMissing":
|
||||
return new PerformerIsMissingCriterion();
|
||||
return new IsMissingCriterion(PerformerIsMissingCriterionOption);
|
||||
case "galleryIsMissing":
|
||||
return new GalleryIsMissingCriterion();
|
||||
return new IsMissingCriterion(GalleryIsMissingCriterionOption);
|
||||
case "tagIsMissing":
|
||||
return new TagIsMissingCriterion();
|
||||
return new IsMissingCriterion(TagIsMissingCriterionOption);
|
||||
case "studioIsMissing":
|
||||
return new StudioIsMissingCriterion();
|
||||
return new IsMissingCriterion(StudioIsMissingCriterionOption);
|
||||
case "movieIsMissing":
|
||||
return new MovieIsMissingCriterion();
|
||||
return new IsMissingCriterion(MovieIsMissingCriterionOption);
|
||||
case "tags":
|
||||
return new TagsCriterion(TagsCriterionOption);
|
||||
case "sceneTags":
|
||||
@@ -91,15 +98,17 @@ export function makeCriteria(type: CriterionType = "none") {
|
||||
case "parent_studios":
|
||||
return new ParentStudiosCriterion();
|
||||
case "movies":
|
||||
return new MoviesCriterion();
|
||||
return new ILabeledIdCriterion(MoviesCriterionOption);
|
||||
case "galleries":
|
||||
return new GalleriesCriterion();
|
||||
case "birth_year":
|
||||
case "death_year":
|
||||
case "weight":
|
||||
return new NumberCriterion(new CriterionOption(type, type));
|
||||
return new NumberCriterion(new NumberCriterionOption(type, type));
|
||||
case "age":
|
||||
return new MandatoryNumberCriterion(new CriterionOption(type, type));
|
||||
return new NumberCriterion(
|
||||
new MandatoryNumberCriterionOption(type, type)
|
||||
);
|
||||
case "gender":
|
||||
return new GenderCriterion();
|
||||
case "ethnicity":
|
||||
@@ -115,7 +124,7 @@ export function makeCriteria(type: CriterionType = "none") {
|
||||
case "aliases":
|
||||
case "url":
|
||||
case "stash_id":
|
||||
return new StringCriterion(new CriterionOption(type, type));
|
||||
return new StringCriterion(new StringCriterionOption(type, type));
|
||||
case "interactive":
|
||||
return new InteractiveCriterion();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { BooleanCriterion, CriterionOption } from "./criterion";
|
||||
import { BooleanCriterion, BooleanCriterionOption } from "./criterion";
|
||||
|
||||
export const FavoriteCriterionOption = new CriterionOption(
|
||||
export const FavoriteCriterionOption = new BooleanCriterionOption(
|
||||
"favourite",
|
||||
"favorite",
|
||||
"filter_favorites"
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
import { CriterionOption, ILabeledIdCriterion } from "./criterion";
|
||||
import { ILabeledIdCriterion, ILabeledIdCriterionOption } from "./criterion";
|
||||
|
||||
const galleriesCriterionOption = new CriterionOption("galleries", "galleries");
|
||||
const galleriesCriterionOption = new ILabeledIdCriterionOption(
|
||||
"galleries",
|
||||
"galleries",
|
||||
"galleries",
|
||||
true
|
||||
);
|
||||
|
||||
export class GalleriesCriterion extends ILabeledIdCriterion {
|
||||
constructor() {
|
||||
super(galleriesCriterionOption, true);
|
||||
super(galleriesCriterionOption);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
import {
|
||||
CriterionModifier,
|
||||
GenderCriterionInput,
|
||||
} from "src/core/generated-graphql";
|
||||
import { getGenderStrings, stringToGender } from "src/core/StashService";
|
||||
import { GenderCriterionInput } from "src/core/generated-graphql";
|
||||
import { genderStrings, stringToGender } from "src/utils/gender";
|
||||
import { CriterionOption, StringCriterion } from "./criterion";
|
||||
|
||||
export const GenderCriterionOption = new CriterionOption("gender", "gender");
|
||||
export const GenderCriterionOption = new CriterionOption({
|
||||
messageID: "gender",
|
||||
type: "gender",
|
||||
options: genderStrings,
|
||||
});
|
||||
|
||||
export class GenderCriterion extends StringCriterion {
|
||||
public modifier = CriterionModifier.Equals;
|
||||
public modifierOptions = [];
|
||||
|
||||
constructor() {
|
||||
super(GenderCriterionOption, getGenderStrings());
|
||||
super(GenderCriterionOption);
|
||||
}
|
||||
|
||||
protected toCriterionInput(): GenderCriterionInput {
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
import { CriterionOption, StringCriterion } from "./criterion";
|
||||
|
||||
export const HasMarkersCriterionOption = new CriterionOption(
|
||||
"hasMarkers",
|
||||
"hasMarkers",
|
||||
"has_markers"
|
||||
);
|
||||
export const HasMarkersCriterionOption = new CriterionOption({
|
||||
messageID: "hasMarkers",
|
||||
type: "hasMarkers",
|
||||
parameterName: "has_markers",
|
||||
options: [true.toString(), false.toString()],
|
||||
});
|
||||
|
||||
export class HasMarkersCriterion extends StringCriterion {
|
||||
constructor() {
|
||||
super(HasMarkersCriterionOption, [true.toString(), false.toString()]);
|
||||
super(HasMarkersCriterionOption);
|
||||
}
|
||||
|
||||
protected toCriterionInput(): string {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { BooleanCriterion, CriterionOption } from "./criterion";
|
||||
import { BooleanCriterion, BooleanCriterionOption } from "./criterion";
|
||||
|
||||
export const InteractiveCriterionOption = new CriterionOption(
|
||||
export const InteractiveCriterionOption = new BooleanCriterionOption(
|
||||
"interactive",
|
||||
"interactive"
|
||||
);
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { CriterionModifier } from "src/core/generated-graphql";
|
||||
import { CriterionOption, StringCriterion } from "./criterion";
|
||||
import { CriterionType } from "../types";
|
||||
import { CriterionOption, StringCriterion, Option } from "./criterion";
|
||||
|
||||
export abstract class IsMissingCriterion extends StringCriterion {
|
||||
export class IsMissingCriterion extends StringCriterion {
|
||||
public modifierOptions = [];
|
||||
public modifier = CriterionModifier.Equals;
|
||||
|
||||
@@ -10,136 +11,98 @@ export abstract class IsMissingCriterion extends StringCriterion {
|
||||
}
|
||||
}
|
||||
|
||||
export const SceneIsMissingCriterionOption = new CriterionOption(
|
||||
class IsMissingCriterionOptionClass extends CriterionOption {
|
||||
constructor(
|
||||
messageID: string,
|
||||
value: CriterionType,
|
||||
parameterName: string,
|
||||
options: Option[]
|
||||
) {
|
||||
super({
|
||||
messageID,
|
||||
type: value,
|
||||
parameterName,
|
||||
options,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const SceneIsMissingCriterionOption = new IsMissingCriterionOptionClass(
|
||||
"isMissing",
|
||||
"sceneIsMissing",
|
||||
"is_missing"
|
||||
"is_missing",
|
||||
[
|
||||
"title",
|
||||
"details",
|
||||
"url",
|
||||
"date",
|
||||
"galleries",
|
||||
"studio",
|
||||
"movie",
|
||||
"performers",
|
||||
"tags",
|
||||
"stash_id",
|
||||
]
|
||||
);
|
||||
|
||||
export class SceneIsMissingCriterion extends IsMissingCriterion {
|
||||
constructor() {
|
||||
super(SceneIsMissingCriterionOption, [
|
||||
"title",
|
||||
"details",
|
||||
"url",
|
||||
"date",
|
||||
"galleries",
|
||||
"studio",
|
||||
"movie",
|
||||
"performers",
|
||||
"tags",
|
||||
"stash_id",
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
export const ImageIsMissingCriterionOption = new CriterionOption(
|
||||
export const ImageIsMissingCriterionOption = new IsMissingCriterionOptionClass(
|
||||
"isMissing",
|
||||
"imageIsMissing",
|
||||
"is_missing"
|
||||
"is_missing",
|
||||
["title", "galleries", "studio", "performers", "tags"]
|
||||
);
|
||||
|
||||
export class ImageIsMissingCriterion extends IsMissingCriterion {
|
||||
constructor() {
|
||||
super(ImageIsMissingCriterionOption, [
|
||||
"title",
|
||||
"galleries",
|
||||
"studio",
|
||||
"performers",
|
||||
"tags",
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
export const PerformerIsMissingCriterionOption = new CriterionOption(
|
||||
export const PerformerIsMissingCriterionOption = new IsMissingCriterionOptionClass(
|
||||
"isMissing",
|
||||
"performerIsMissing",
|
||||
"is_missing"
|
||||
"is_missing",
|
||||
[
|
||||
"url",
|
||||
"twitter",
|
||||
"instagram",
|
||||
"ethnicity",
|
||||
"country",
|
||||
"hair_color",
|
||||
"eye_color",
|
||||
"height",
|
||||
"weight",
|
||||
"measurements",
|
||||
"fake_tits",
|
||||
"career_length",
|
||||
"tattoos",
|
||||
"piercings",
|
||||
"aliases",
|
||||
"gender",
|
||||
"image",
|
||||
"details",
|
||||
"stash_id",
|
||||
]
|
||||
);
|
||||
|
||||
export class PerformerIsMissingCriterion extends IsMissingCriterion {
|
||||
constructor() {
|
||||
super(PerformerIsMissingCriterionOption, [
|
||||
"url",
|
||||
"twitter",
|
||||
"instagram",
|
||||
"ethnicity",
|
||||
"country",
|
||||
"hair_color",
|
||||
"eye_color",
|
||||
"height",
|
||||
"weight",
|
||||
"measurements",
|
||||
"fake_tits",
|
||||
"career_length",
|
||||
"tattoos",
|
||||
"piercings",
|
||||
"aliases",
|
||||
"gender",
|
||||
"image",
|
||||
"details",
|
||||
"stash_id",
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
export const GalleryIsMissingCriterionOption = new CriterionOption(
|
||||
export const GalleryIsMissingCriterionOption = new IsMissingCriterionOptionClass(
|
||||
"isMissing",
|
||||
"galleryIsMissing",
|
||||
"is_missing"
|
||||
"is_missing",
|
||||
["title", "details", "url", "date", "studio", "performers", "tags", "scenes"]
|
||||
);
|
||||
|
||||
export class GalleryIsMissingCriterion extends IsMissingCriterion {
|
||||
constructor() {
|
||||
super(GalleryIsMissingCriterionOption, [
|
||||
"title",
|
||||
"details",
|
||||
"url",
|
||||
"date",
|
||||
"studio",
|
||||
"performers",
|
||||
"tags",
|
||||
"scenes",
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
export const TagIsMissingCriterionOption = new CriterionOption(
|
||||
export const TagIsMissingCriterionOption = new IsMissingCriterionOptionClass(
|
||||
"isMissing",
|
||||
"tagIsMissing",
|
||||
"is_missing"
|
||||
"is_missing",
|
||||
["image"]
|
||||
);
|
||||
|
||||
export class TagIsMissingCriterion extends IsMissingCriterion {
|
||||
constructor() {
|
||||
super(TagIsMissingCriterionOption, ["image"]);
|
||||
}
|
||||
}
|
||||
|
||||
export const StudioIsMissingCriterionOption = new CriterionOption(
|
||||
export const StudioIsMissingCriterionOption = new IsMissingCriterionOptionClass(
|
||||
"isMissing",
|
||||
"studioIsMissing",
|
||||
"is_missing"
|
||||
"is_missing",
|
||||
["image", "stash_id", "details"]
|
||||
);
|
||||
|
||||
export class StudioIsMissingCriterion extends IsMissingCriterion {
|
||||
constructor() {
|
||||
super(StudioIsMissingCriterionOption, ["image", "stash_id", "details"]);
|
||||
}
|
||||
}
|
||||
|
||||
export const MovieIsMissingCriterionOption = new CriterionOption(
|
||||
export const MovieIsMissingCriterionOption = new IsMissingCriterionOptionClass(
|
||||
"isMissing",
|
||||
"movieIsMissing",
|
||||
"is_missing"
|
||||
"is_missing",
|
||||
["front_image", "back_image", "scenes"]
|
||||
);
|
||||
|
||||
export class MovieIsMissingCriterion extends IsMissingCriterion {
|
||||
constructor() {
|
||||
super(MovieIsMissingCriterionOption, [
|
||||
"front_image",
|
||||
"back_image",
|
||||
"scenes",
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
import { CriterionOption, ILabeledIdCriterion } from "./criterion";
|
||||
import { ILabeledIdCriterion, ILabeledIdCriterionOption } from "./criterion";
|
||||
|
||||
export const MoviesCriterionOption = new CriterionOption("movies", "movies");
|
||||
export const MoviesCriterionOption = new ILabeledIdCriterionOption(
|
||||
"movies",
|
||||
"movies",
|
||||
"movies",
|
||||
false
|
||||
);
|
||||
|
||||
export class MoviesCriterion extends ILabeledIdCriterion {
|
||||
constructor() {
|
||||
super(MoviesCriterionOption, false);
|
||||
super(MoviesCriterionOption);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
import { CriterionModifier } from "src/core/generated-graphql";
|
||||
import { Criterion, CriterionOption } from "./criterion";
|
||||
import { Criterion, StringCriterionOption } from "./criterion";
|
||||
|
||||
export const NoneCriterionOption = new CriterionOption("none", "none");
|
||||
export const NoneCriterionOption = new StringCriterionOption(
|
||||
"none",
|
||||
"none",
|
||||
"none"
|
||||
);
|
||||
export class NoneCriterion extends Criterion<string> {
|
||||
public modifier = CriterionModifier.Equals;
|
||||
public modifierOptions = [];
|
||||
public options: undefined;
|
||||
public value: string = "none";
|
||||
|
||||
constructor() {
|
||||
super(NoneCriterionOption);
|
||||
super(NoneCriterionOption, "none");
|
||||
}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { BooleanCriterion, CriterionOption } from "./criterion";
|
||||
import { BooleanCriterion, BooleanCriterionOption } from "./criterion";
|
||||
|
||||
export const OrganizedCriterionOption = new CriterionOption(
|
||||
export const OrganizedCriterionOption = new BooleanCriterionOption(
|
||||
"organized",
|
||||
"organized",
|
||||
"organized"
|
||||
);
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
import { CriterionOption, ILabeledIdCriterion } from "./criterion";
|
||||
import { ILabeledIdCriterion, ILabeledIdCriterionOption } from "./criterion";
|
||||
|
||||
export const PerformersCriterionOption = new CriterionOption(
|
||||
export const PerformersCriterionOption = new ILabeledIdCriterionOption(
|
||||
"performers",
|
||||
"performers"
|
||||
"performers",
|
||||
"performers",
|
||||
true
|
||||
);
|
||||
|
||||
export class PerformersCriterion extends ILabeledIdCriterion {
|
||||
constructor() {
|
||||
super(PerformersCriterionOption, true);
|
||||
super(PerformersCriterionOption);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,8 @@
|
||||
import { CriterionModifier } from "src/core/generated-graphql";
|
||||
import { Criterion, CriterionOption, NumberCriterion } from "./criterion";
|
||||
import { NumberCriterionOption } from "./criterion";
|
||||
|
||||
export const RatingCriterionOption = new CriterionOption("rating", "rating");
|
||||
|
||||
export class RatingCriterion extends NumberCriterion {
|
||||
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),
|
||||
];
|
||||
|
||||
constructor() {
|
||||
super(RatingCriterionOption, [1, 2, 3, 4, 5]);
|
||||
}
|
||||
}
|
||||
export const RatingCriterionOption = new NumberCriterionOption(
|
||||
"rating",
|
||||
"rating",
|
||||
"rating",
|
||||
[1, 2, 3, 4, 5]
|
||||
);
|
||||
|
||||
@@ -1,27 +1,8 @@
|
||||
import { CriterionModifier, ResolutionEnum } from "src/core/generated-graphql";
|
||||
import { ResolutionEnum } from "src/core/generated-graphql";
|
||||
import { CriterionType } from "../types";
|
||||
import { CriterionOption, StringCriterion } from "./criterion";
|
||||
|
||||
abstract class AbstractResolutionCriterion extends StringCriterion {
|
||||
public modifier = CriterionModifier.Equals;
|
||||
public modifierOptions = [];
|
||||
|
||||
constructor(type: CriterionOption) {
|
||||
super(type, [
|
||||
"144p",
|
||||
"240p",
|
||||
"360p",
|
||||
"480p",
|
||||
"540p",
|
||||
"720p",
|
||||
"1080p",
|
||||
"1440p",
|
||||
"4k",
|
||||
"5k",
|
||||
"6k",
|
||||
"8k",
|
||||
]);
|
||||
}
|
||||
|
||||
protected toCriterionInput(): ResolutionEnum | undefined {
|
||||
switch (this.value) {
|
||||
case "144p":
|
||||
@@ -55,21 +36,40 @@ abstract class AbstractResolutionCriterion extends StringCriterion {
|
||||
}
|
||||
}
|
||||
|
||||
export const ResolutionCriterionOption = new CriterionOption(
|
||||
"resolution",
|
||||
class ResolutionCriterionOptionType extends CriterionOption {
|
||||
constructor(value: CriterionType) {
|
||||
super({
|
||||
messageID: value,
|
||||
type: value,
|
||||
parameterName: value,
|
||||
options: [
|
||||
"144p",
|
||||
"240p",
|
||||
"360p",
|
||||
"480p",
|
||||
"540p",
|
||||
"720p",
|
||||
"1080p",
|
||||
"1440p",
|
||||
"4k",
|
||||
"5k",
|
||||
"6k",
|
||||
"8k",
|
||||
],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const ResolutionCriterionOption = new ResolutionCriterionOptionType(
|
||||
"resolution"
|
||||
);
|
||||
export class ResolutionCriterion extends AbstractResolutionCriterion {
|
||||
public modifier = CriterionModifier.Equals;
|
||||
public modifierOptions = [];
|
||||
|
||||
constructor() {
|
||||
super(ResolutionCriterionOption);
|
||||
}
|
||||
}
|
||||
|
||||
export const AverageResolutionCriterionOption = new CriterionOption(
|
||||
"average_resolution",
|
||||
export const AverageResolutionCriterionOption = new ResolutionCriterionOptionType(
|
||||
"average_resolution"
|
||||
);
|
||||
|
||||
|
||||
@@ -1,23 +1,30 @@
|
||||
import {
|
||||
CriterionOption,
|
||||
IHierarchicalLabeledIdCriterion,
|
||||
ILabeledIdCriterion,
|
||||
ILabeledIdCriterionOption,
|
||||
} from "./criterion";
|
||||
|
||||
export const StudiosCriterionOption = new CriterionOption("studios", "studios");
|
||||
export const StudiosCriterionOption = new ILabeledIdCriterionOption(
|
||||
"studios",
|
||||
"studios",
|
||||
"studios",
|
||||
false
|
||||
);
|
||||
|
||||
export class StudiosCriterion extends IHierarchicalLabeledIdCriterion {
|
||||
constructor() {
|
||||
super(StudiosCriterionOption, false);
|
||||
super(StudiosCriterionOption);
|
||||
}
|
||||
}
|
||||
|
||||
export const ParentStudiosCriterionOption = new CriterionOption(
|
||||
export const ParentStudiosCriterionOption = new ILabeledIdCriterionOption(
|
||||
"parent_studios",
|
||||
"parent_studios",
|
||||
"parents"
|
||||
"parents",
|
||||
false
|
||||
);
|
||||
export class ParentStudiosCriterion extends ILabeledIdCriterion {
|
||||
constructor() {
|
||||
super(ParentStudiosCriterionOption, false);
|
||||
super(ParentStudiosCriterionOption);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,22 @@
|
||||
import { CriterionOption, ILabeledIdCriterion } from "./criterion";
|
||||
import { ILabeledIdCriterion, ILabeledIdCriterionOption } from "./criterion";
|
||||
|
||||
export class TagsCriterion extends ILabeledIdCriterion {
|
||||
constructor(type: CriterionOption) {
|
||||
super(type, true);
|
||||
}
|
||||
}
|
||||
export class TagsCriterion extends ILabeledIdCriterion {}
|
||||
|
||||
export const TagsCriterionOption = new CriterionOption("tags", "tags");
|
||||
export const SceneTagsCriterionOption = new CriterionOption(
|
||||
export const TagsCriterionOption = new ILabeledIdCriterionOption(
|
||||
"tags",
|
||||
"tags",
|
||||
"tags",
|
||||
true
|
||||
);
|
||||
export const SceneTagsCriterionOption = new ILabeledIdCriterionOption(
|
||||
"sceneTags",
|
||||
"sceneTags",
|
||||
"scene_tags"
|
||||
"scene_tags",
|
||||
true
|
||||
);
|
||||
export const PerformerTagsCriterionOption = new CriterionOption(
|
||||
export const PerformerTagsCriterionOption = new ILabeledIdCriterionOption(
|
||||
"performerTags",
|
||||
"performerTags",
|
||||
"performer_tags"
|
||||
"performer_tags",
|
||||
true
|
||||
);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { FilterMode } from "src/core/generated-graphql";
|
||||
import { ListFilterOptions } from "./filter-options";
|
||||
import { GalleryListFilterOptions } from "./galleries";
|
||||
import { ImageListFilterOptions } from "./images";
|
||||
@@ -7,7 +8,6 @@ import { SceneMarkerListFilterOptions } from "./scene-markers";
|
||||
import { SceneListFilterOptions } from "./scenes";
|
||||
import { StudioListFilterOptions } from "./studios";
|
||||
import { TagListFilterOptions } from "./tags";
|
||||
import { FilterMode } from "./types";
|
||||
|
||||
export function getFilterOptions(mode: FilterMode): ListFilterOptions {
|
||||
switch (mode) {
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import queryString, { ParsedQuery } from "query-string";
|
||||
import { FindFilterType, SortDirectionEnum } from "src/core/generated-graphql";
|
||||
import {
|
||||
FilterMode,
|
||||
FindFilterType,
|
||||
SortDirectionEnum,
|
||||
} from "src/core/generated-graphql";
|
||||
import { Criterion, CriterionValue } from "./criteria/criterion";
|
||||
import { makeCriteria } from "./criteria/factory";
|
||||
import { DisplayMode } from "./types";
|
||||
@@ -23,6 +27,7 @@ const DEFAULT_PARAMS = {
|
||||
|
||||
// TODO: handle customCriteria
|
||||
export class ListFilterModel {
|
||||
public mode: FilterMode;
|
||||
public searchTerm?: string;
|
||||
public currentPage = DEFAULT_PARAMS.currentPage;
|
||||
public itemsPerPage = DEFAULT_PARAMS.itemsPerPage;
|
||||
@@ -33,16 +38,22 @@ export class ListFilterModel {
|
||||
public randomSeed = -1;
|
||||
|
||||
public constructor(
|
||||
mode: FilterMode,
|
||||
rawParms?: ParsedQuery<string>,
|
||||
defaultSort?: string,
|
||||
defaultDisplayMode?: DisplayMode
|
||||
) {
|
||||
this.mode = mode;
|
||||
const params = rawParms as IQueryParameters;
|
||||
this.sortBy = defaultSort;
|
||||
if (defaultDisplayMode !== undefined) this.displayMode = defaultDisplayMode;
|
||||
if (params) this.configureFromQueryParameters(params);
|
||||
}
|
||||
|
||||
public clone() {
|
||||
return Object.assign(new ListFilterModel(this.mode), this);
|
||||
}
|
||||
|
||||
public configureFromQueryParameters(params: IQueryParameters) {
|
||||
if (params.sortby !== undefined) {
|
||||
this.sortBy = params.sortby;
|
||||
@@ -64,7 +75,7 @@ export class ListFilterModel {
|
||||
params.sortdir === "desc"
|
||||
? SortDirectionEnum.Desc
|
||||
: SortDirectionEnum.Asc;
|
||||
if (params.disp) {
|
||||
if (params.disp !== undefined) {
|
||||
this.displayMode = Number.parseInt(params.disp, 10);
|
||||
}
|
||||
if (params.q) {
|
||||
@@ -153,6 +164,24 @@ export class ListFilterModel {
|
||||
return result;
|
||||
}
|
||||
|
||||
public getSavedQueryParameters() {
|
||||
const encodedCriteria: string[] = this.criteria.map((criterion) =>
|
||||
criterion.toJSON()
|
||||
);
|
||||
|
||||
const result = {
|
||||
perPage: this.itemsPerPage,
|
||||
sortby: this.getSortBy() ?? undefined,
|
||||
sortdir:
|
||||
this.sortDirection === SortDirectionEnum.Desc ? "desc" : undefined,
|
||||
disp: this.displayMode,
|
||||
q: this.searchTerm,
|
||||
c: encodedCriteria,
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public makeQueryParameters(): string {
|
||||
return queryString.stringify(this.getQueryParameters(), { encode: false });
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { createCriterionOption } from "./criteria/criterion";
|
||||
import { createStringCriterionOption } from "./criteria/criterion";
|
||||
import { GalleryIsMissingCriterionOption } from "./criteria/is-missing";
|
||||
import { NoneCriterionOption } from "./criteria/none";
|
||||
import { OrganizedCriterionOption } from "./criteria/organized";
|
||||
import { PerformersCriterionOption } from "./criteria/performers";
|
||||
import { RatingCriterionOption } from "./criteria/rating";
|
||||
@@ -39,20 +38,19 @@ const displayModeOptions = [
|
||||
];
|
||||
|
||||
const criterionOptions = [
|
||||
NoneCriterionOption,
|
||||
createCriterionOption("path"),
|
||||
createStringCriterionOption("path"),
|
||||
RatingCriterionOption,
|
||||
OrganizedCriterionOption,
|
||||
AverageResolutionCriterionOption,
|
||||
GalleryIsMissingCriterionOption,
|
||||
TagsCriterionOption,
|
||||
createCriterionOption("tag_count"),
|
||||
createStringCriterionOption("tag_count"),
|
||||
PerformerTagsCriterionOption,
|
||||
PerformersCriterionOption,
|
||||
createCriterionOption("performer_count"),
|
||||
createCriterionOption("image_count"),
|
||||
createStringCriterionOption("performer_count"),
|
||||
createStringCriterionOption("image_count"),
|
||||
StudiosCriterionOption,
|
||||
createCriterionOption("url"),
|
||||
createStringCriterionOption("url"),
|
||||
];
|
||||
|
||||
export const GalleryListFilterOptions = new ListFilterOptions(
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { createCriterionOption } from "./criteria/criterion";
|
||||
import {
|
||||
createMandatoryNumberCriterionOption,
|
||||
createStringCriterionOption,
|
||||
} from "./criteria/criterion";
|
||||
import { ImageIsMissingCriterionOption } from "./criteria/is-missing";
|
||||
import { NoneCriterionOption } from "./criteria/none";
|
||||
import { OrganizedCriterionOption } from "./criteria/organized";
|
||||
import { PerformersCriterionOption } from "./criteria/performers";
|
||||
import { RatingCriterionOption } from "./criteria/rating";
|
||||
@@ -29,18 +31,17 @@ const sortByOptions = [
|
||||
|
||||
const displayModeOptions = [DisplayMode.Grid, DisplayMode.Wall];
|
||||
const criterionOptions = [
|
||||
NoneCriterionOption,
|
||||
createCriterionOption("path"),
|
||||
createStringCriterionOption("path"),
|
||||
RatingCriterionOption,
|
||||
OrganizedCriterionOption,
|
||||
createCriterionOption("o_counter"),
|
||||
createMandatoryNumberCriterionOption("o_counter"),
|
||||
ResolutionCriterionOption,
|
||||
ImageIsMissingCriterionOption,
|
||||
TagsCriterionOption,
|
||||
createCriterionOption("tag_count"),
|
||||
createMandatoryNumberCriterionOption("tag_count"),
|
||||
PerformerTagsCriterionOption,
|
||||
PerformersCriterionOption,
|
||||
createCriterionOption("performer_count"),
|
||||
createMandatoryNumberCriterionOption("performer_count"),
|
||||
StudiosCriterionOption,
|
||||
];
|
||||
export const ImageListFilterOptions = new ListFilterOptions(
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { createCriterionOption } from "./criteria/criterion";
|
||||
import { createStringCriterionOption } from "./criteria/criterion";
|
||||
import { MovieIsMissingCriterionOption } from "./criteria/is-missing";
|
||||
import { NoneCriterionOption } from "./criteria/none";
|
||||
import { StudiosCriterionOption } from "./criteria/studios";
|
||||
import { ListFilterOptions } from "./filter-options";
|
||||
import { DisplayMode } from "./types";
|
||||
@@ -17,10 +16,9 @@ const sortByOptions = ["name", "random"]
|
||||
]);
|
||||
const displayModeOptions = [DisplayMode.Grid];
|
||||
const criterionOptions = [
|
||||
NoneCriterionOption,
|
||||
StudiosCriterionOption,
|
||||
MovieIsMissingCriterionOption,
|
||||
createCriterionOption("url"),
|
||||
createStringCriterionOption("url"),
|
||||
];
|
||||
|
||||
export const MovieListFilterOptions = new ListFilterOptions(
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import { createCriterionOption } from "./criteria/criterion";
|
||||
import {
|
||||
createNumberCriterionOption,
|
||||
createMandatoryNumberCriterionOption,
|
||||
createStringCriterionOption,
|
||||
} from "./criteria/criterion";
|
||||
import { FavoriteCriterionOption } from "./criteria/favorite";
|
||||
import { GenderCriterionOption } from "./criteria/gender";
|
||||
import { PerformerIsMissingCriterionOption } from "./criteria/is-missing";
|
||||
import { NoneCriterionOption } from "./criteria/none";
|
||||
import { RatingCriterionOption } from "./criteria/rating";
|
||||
import { StudiosCriterionOption } from "./criteria/studios";
|
||||
import { TagsCriterionOption } from "./criteria/tags";
|
||||
@@ -55,19 +58,19 @@ const stringCriteria: CriterionType[] = [
|
||||
];
|
||||
|
||||
const criterionOptions = [
|
||||
NoneCriterionOption,
|
||||
FavoriteCriterionOption,
|
||||
GenderCriterionOption,
|
||||
PerformerIsMissingCriterionOption,
|
||||
TagsCriterionOption,
|
||||
RatingCriterionOption,
|
||||
StudiosCriterionOption,
|
||||
createCriterionOption("url"),
|
||||
createCriterionOption("tag_count"),
|
||||
createCriterionOption("scene_count"),
|
||||
createCriterionOption("image_count"),
|
||||
createCriterionOption("gallery_count"),
|
||||
...numberCriteria.concat(stringCriteria).map((c) => createCriterionOption(c)),
|
||||
createStringCriterionOption("url"),
|
||||
createMandatoryNumberCriterionOption("tag_count"),
|
||||
createMandatoryNumberCriterionOption("scene_count"),
|
||||
createMandatoryNumberCriterionOption("image_count"),
|
||||
createMandatoryNumberCriterionOption("gallery_count"),
|
||||
...numberCriteria.map((c) => createNumberCriterionOption(c)),
|
||||
...stringCriteria.map((c) => createStringCriterionOption(c)),
|
||||
];
|
||||
export const PerformerListFilterOptions = new ListFilterOptions(
|
||||
defaultSortBy,
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { NoneCriterionOption } from "./criteria/none";
|
||||
import { PerformersCriterionOption } from "./criteria/performers";
|
||||
import { SceneTagsCriterionOption, TagsCriterionOption } from "./criteria/tags";
|
||||
import { ListFilterOptions } from "./filter-options";
|
||||
@@ -14,7 +13,6 @@ const sortByOptions = [
|
||||
].map(ListFilterOptions.createSortBy);
|
||||
const displayModeOptions = [DisplayMode.Wall];
|
||||
const criterionOptions = [
|
||||
NoneCriterionOption,
|
||||
TagsCriterionOption,
|
||||
SceneTagsCriterionOption,
|
||||
PerformersCriterionOption,
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import { createCriterionOption } from "./criteria/criterion";
|
||||
import {
|
||||
createMandatoryNumberCriterionOption,
|
||||
createStringCriterionOption,
|
||||
} from "./criteria/criterion";
|
||||
import { HasMarkersCriterionOption } from "./criteria/has-markers";
|
||||
import { SceneIsMissingCriterionOption } from "./criteria/is-missing";
|
||||
import { MoviesCriterionOption } from "./criteria/movies";
|
||||
import { NoneCriterionOption } from "./criteria/none";
|
||||
import { OrganizedCriterionOption } from "./criteria/organized";
|
||||
import { PerformersCriterionOption } from "./criteria/performers";
|
||||
import { RatingCriterionOption } from "./criteria/rating";
|
||||
@@ -44,24 +46,23 @@ const displayModeOptions = [
|
||||
];
|
||||
|
||||
const criterionOptions = [
|
||||
NoneCriterionOption,
|
||||
createCriterionOption("path"),
|
||||
createStringCriterionOption("path"),
|
||||
RatingCriterionOption,
|
||||
OrganizedCriterionOption,
|
||||
createCriterionOption("o_counter"),
|
||||
createMandatoryNumberCriterionOption("o_counter"),
|
||||
ResolutionCriterionOption,
|
||||
createCriterionOption("duration"),
|
||||
createMandatoryNumberCriterionOption("duration"),
|
||||
HasMarkersCriterionOption,
|
||||
SceneIsMissingCriterionOption,
|
||||
TagsCriterionOption,
|
||||
createCriterionOption("tag_count"),
|
||||
createMandatoryNumberCriterionOption("tag_count"),
|
||||
PerformerTagsCriterionOption,
|
||||
PerformersCriterionOption,
|
||||
createCriterionOption("performer_count"),
|
||||
createMandatoryNumberCriterionOption("performer_count"),
|
||||
StudiosCriterionOption,
|
||||
MoviesCriterionOption,
|
||||
createCriterionOption("url"),
|
||||
createCriterionOption("stash_id"),
|
||||
createStringCriterionOption("url"),
|
||||
createStringCriterionOption("stash_id"),
|
||||
InteractiveCriterionOption,
|
||||
];
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { createCriterionOption } from "./criteria/criterion";
|
||||
import {
|
||||
createMandatoryNumberCriterionOption,
|
||||
createStringCriterionOption,
|
||||
} from "./criteria/criterion";
|
||||
import { StudioIsMissingCriterionOption } from "./criteria/is-missing";
|
||||
import { NoneCriterionOption } from "./criteria/none";
|
||||
import { RatingCriterionOption } from "./criteria/rating";
|
||||
import { ParentStudiosCriterionOption } from "./criteria/studios";
|
||||
import { ListFilterOptions } from "./filter-options";
|
||||
@@ -26,15 +28,14 @@ const sortByOptions = ["name", "random", "rating"]
|
||||
|
||||
const displayModeOptions = [DisplayMode.Grid];
|
||||
const criterionOptions = [
|
||||
NoneCriterionOption,
|
||||
ParentStudiosCriterionOption,
|
||||
StudioIsMissingCriterionOption,
|
||||
RatingCriterionOption,
|
||||
createCriterionOption("scene_count"),
|
||||
createCriterionOption("image_count"),
|
||||
createCriterionOption("gallery_count"),
|
||||
createCriterionOption("url"),
|
||||
createCriterionOption("stash_id"),
|
||||
createMandatoryNumberCriterionOption("scene_count"),
|
||||
createMandatoryNumberCriterionOption("image_count"),
|
||||
createMandatoryNumberCriterionOption("gallery_count"),
|
||||
createStringCriterionOption("url"),
|
||||
createStringCriterionOption("stash_id"),
|
||||
];
|
||||
|
||||
export const StudioListFilterOptions = new ListFilterOptions(
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { createCriterionOption } from "./criteria/criterion";
|
||||
import { createMandatoryNumberCriterionOption } from "./criteria/criterion";
|
||||
import { TagIsMissingCriterionOption } from "./criteria/is-missing";
|
||||
import { NoneCriterionOption } from "./criteria/none";
|
||||
import { ListFilterOptions } from "./filter-options";
|
||||
import { DisplayMode } from "./types";
|
||||
|
||||
@@ -34,12 +33,11 @@ const sortByOptions = [
|
||||
|
||||
const displayModeOptions = [DisplayMode.Grid, DisplayMode.List];
|
||||
const criterionOptions = [
|
||||
NoneCriterionOption,
|
||||
TagIsMissingCriterionOption,
|
||||
createCriterionOption("scene_count"),
|
||||
createCriterionOption("image_count"),
|
||||
createCriterionOption("gallery_count"),
|
||||
createCriterionOption("performer_count"),
|
||||
createMandatoryNumberCriterionOption("scene_count"),
|
||||
createMandatoryNumberCriterionOption("image_count"),
|
||||
createMandatoryNumberCriterionOption("gallery_count"),
|
||||
createMandatoryNumberCriterionOption("performer_count"),
|
||||
// marker count has been disabled for now due to performance issues
|
||||
// ListFilterModel.createCriterionOption("marker_count"),
|
||||
];
|
||||
|
||||
@@ -8,17 +8,6 @@ export enum DisplayMode {
|
||||
Tagger,
|
||||
}
|
||||
|
||||
export enum FilterMode {
|
||||
Scenes,
|
||||
Performers,
|
||||
Studios,
|
||||
Galleries,
|
||||
SceneMarkers,
|
||||
Movies,
|
||||
Tags,
|
||||
Images,
|
||||
}
|
||||
|
||||
export interface ILabeledId {
|
||||
id: string;
|
||||
label: string;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import queryString from "query-string";
|
||||
import { RouteComponentProps } from "react-router-dom";
|
||||
import { FilterMode } from "src/core/generated-graphql";
|
||||
import { ListFilterModel } from "./list-filter/filter";
|
||||
import { SceneListFilterOptions } from "./list-filter/scenes";
|
||||
|
||||
@@ -27,7 +28,7 @@ export class SceneQueue {
|
||||
public static fromListFilterModel(filter: ListFilterModel) {
|
||||
const ret = new SceneQueue();
|
||||
|
||||
const filterCopy = Object.assign(new ListFilterModel(), filter);
|
||||
const filterCopy = filter.clone();
|
||||
filterCopy.itemsPerPage = 40;
|
||||
|
||||
ret.originalQueryPage = filter.currentPage;
|
||||
@@ -95,6 +96,7 @@ export class SceneQueue {
|
||||
|
||||
if (parsed.qfp) {
|
||||
const query = new ListFilterModel(
|
||||
FilterMode.Scenes,
|
||||
translated as queryString.ParsedQuery,
|
||||
SceneListFilterOptions.defaultSortBy
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user