mirror of
https://github.com/stashapp/stash.git
synced 2025-12-18 04:44:37 +03:00
Refactor ItemList code and re-enable viewing sub-tag/studio content (#5080)
* Refactor list filter to use contexts * Refactor FilteredListToolbar * Move components into separate files * Convert ItemList hook into components * Fix criteria clone functions * Add toggle for sub-studio content * Add toggle for sub-tag content * Make LoadingIndicator height smaller and fade in.
This commit is contained in:
@@ -89,6 +89,15 @@ export abstract class Criterion<V extends CriterionValue> {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public clone(): Criterion<V> {
|
||||
const newCriterion = new (this.constructor as new (
|
||||
type: CriterionOption,
|
||||
value: V
|
||||
) => Criterion<V>)(this.criterionOption, this.value);
|
||||
newCriterion.modifier = this.modifier;
|
||||
return newCriterion;
|
||||
}
|
||||
|
||||
public static getModifierLabel(intl: IntlShape, modifier: CriterionModifier) {
|
||||
const modifierMessageID = modifierMessageIDs[modifier];
|
||||
|
||||
@@ -251,6 +260,19 @@ export class ILabeledIdCriterionOption extends CriterionOption {
|
||||
}
|
||||
|
||||
export class ILabeledIdCriterion extends Criterion<ILabeledId[]> {
|
||||
constructor(type: CriterionOption, value: ILabeledId[] = []) {
|
||||
super(type, value);
|
||||
}
|
||||
|
||||
public clone(): Criterion<ILabeledId[]> {
|
||||
const newCriterion = new ILabeledIdCriterion(
|
||||
this.criterionOption,
|
||||
this.value.map((v) => ({ ...v }))
|
||||
);
|
||||
newCriterion.modifier = this.modifier;
|
||||
return newCriterion;
|
||||
}
|
||||
|
||||
protected getLabelValue(_intl: IntlShape): string {
|
||||
return this.value.map((v) => v.label).join(", ");
|
||||
}
|
||||
@@ -272,23 +294,33 @@ export class ILabeledIdCriterion extends Criterion<ILabeledId[]> {
|
||||
|
||||
return this.value.length > 0;
|
||||
}
|
||||
|
||||
constructor(type: CriterionOption) {
|
||||
super(type, []);
|
||||
}
|
||||
}
|
||||
|
||||
export class IHierarchicalLabeledIdCriterion extends Criterion<IHierarchicalLabelValue> {
|
||||
constructor(type: CriterionOption) {
|
||||
const value: IHierarchicalLabelValue = {
|
||||
constructor(
|
||||
type: CriterionOption,
|
||||
value: IHierarchicalLabelValue = {
|
||||
items: [],
|
||||
excluded: [],
|
||||
depth: 0,
|
||||
};
|
||||
|
||||
}
|
||||
) {
|
||||
super(type, value);
|
||||
}
|
||||
|
||||
public clone(): Criterion<IHierarchicalLabelValue> {
|
||||
const newCriterion = new IHierarchicalLabeledIdCriterion(
|
||||
this.criterionOption,
|
||||
{
|
||||
...this.value,
|
||||
items: this.value.items.map((v) => ({ ...v })),
|
||||
excluded: this.value.excluded.map((v) => ({ ...v })),
|
||||
}
|
||||
);
|
||||
newCriterion.modifier = this.modifier;
|
||||
return newCriterion;
|
||||
}
|
||||
|
||||
override get modifier(): CriterionModifier {
|
||||
return this._modifier;
|
||||
}
|
||||
@@ -501,8 +533,17 @@ export class StringCriterion extends Criterion<string> {
|
||||
}
|
||||
|
||||
export class MultiStringCriterion extends Criterion<string[]> {
|
||||
constructor(type: CriterionOption) {
|
||||
super(type, []);
|
||||
constructor(type: CriterionOption, value: string[] = []) {
|
||||
super(type, value);
|
||||
}
|
||||
|
||||
public clone(): Criterion<string[]> {
|
||||
const newCriterion = new MultiStringCriterion(
|
||||
this.criterionOption,
|
||||
this.value.slice()
|
||||
);
|
||||
newCriterion.modifier = this.modifier;
|
||||
return newCriterion;
|
||||
}
|
||||
|
||||
protected getLabelValue(_intl: IntlShape) {
|
||||
|
||||
@@ -67,26 +67,48 @@ export class ListFilterModel {
|
||||
public constructor(
|
||||
mode: FilterMode,
|
||||
config?: ConfigDataFragment,
|
||||
defaultZoomIndex?: number
|
||||
options?: {
|
||||
defaultZoomIndex?: number;
|
||||
defaultSortBy?: string;
|
||||
defaultSortDir?: SortDirectionEnum;
|
||||
}
|
||||
) {
|
||||
this.mode = mode;
|
||||
this.config = config;
|
||||
this.options = getFilterOptions(mode);
|
||||
const { defaultSortBy, displayModeOptions } = this.options;
|
||||
|
||||
this.sortBy = defaultSortBy;
|
||||
if (this.sortBy === "date") {
|
||||
this.sortDirection = SortDirectionEnum.Desc;
|
||||
if (options?.defaultSortBy) {
|
||||
this.sortBy = options.defaultSortBy;
|
||||
if (options.defaultSortDir) {
|
||||
this.sortDirection = options.defaultSortDir;
|
||||
}
|
||||
} else {
|
||||
this.sortBy = defaultSortBy;
|
||||
if (this.sortBy === "date") {
|
||||
this.sortDirection = SortDirectionEnum.Desc;
|
||||
}
|
||||
}
|
||||
this.displayMode = displayModeOptions[0];
|
||||
if (defaultZoomIndex !== undefined) {
|
||||
this.defaultZoomIndex = defaultZoomIndex;
|
||||
this.zoomIndex = defaultZoomIndex;
|
||||
if (options?.defaultZoomIndex !== undefined) {
|
||||
this.defaultZoomIndex = options.defaultZoomIndex;
|
||||
this.zoomIndex = options.defaultZoomIndex;
|
||||
}
|
||||
}
|
||||
|
||||
public clone() {
|
||||
return Object.assign(new ListFilterModel(this.mode, this.config), this);
|
||||
const ret = Object.assign(
|
||||
new ListFilterModel(this.mode, this.config),
|
||||
this
|
||||
);
|
||||
ret.criteria = this.criteria.map((c) => c.clone());
|
||||
return ret;
|
||||
}
|
||||
|
||||
public empty() {
|
||||
return new ListFilterModel(this.mode, this.config, {
|
||||
defaultZoomIndex: this.defaultZoomIndex,
|
||||
});
|
||||
}
|
||||
|
||||
// returns the number of filters applied
|
||||
@@ -443,4 +465,44 @@ export class ListFilterModel {
|
||||
zoom_index: this.zoomIndex,
|
||||
};
|
||||
}
|
||||
|
||||
public clearCriteria() {
|
||||
const ret = this.clone();
|
||||
ret.criteria = [];
|
||||
ret.currentPage = 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
public removeCriterion(type: CriterionType) {
|
||||
const ret = this.clone();
|
||||
const c = ret.criteria.find((cc) => cc.criterionOption.type === type);
|
||||
|
||||
if (!c) return ret;
|
||||
|
||||
const newCriteria = ret.criteria.filter((cc) => {
|
||||
return cc.getId() !== c.getId();
|
||||
});
|
||||
|
||||
ret.criteria = newCriteria;
|
||||
ret.currentPage = 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
public changePage(page: number) {
|
||||
const ret = this.clone();
|
||||
ret.currentPage = page;
|
||||
return ret;
|
||||
}
|
||||
|
||||
public setZoom(zoomIndex: number) {
|
||||
const ret = this.clone();
|
||||
ret.zoomIndex = zoomIndex;
|
||||
return ret;
|
||||
}
|
||||
|
||||
public setDisplayMode(displayMode: DisplayMode) {
|
||||
const ret = this.clone();
|
||||
ret.displayMode = displayMode;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user