mirror of
https://github.com/stashapp/stash.git
synced 2025-12-18 12:54:38 +03:00
Refactor list hook filter storag
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import queryString from "query-string";
|
import queryString from "query-string";
|
||||||
import React, { useState, useEffect, useRef } from "react";
|
import React, { useCallback, useState, useEffect } from "react";
|
||||||
import { ApolloError } from "apollo-client";
|
import { ApolloError } from "apollo-client";
|
||||||
import { useHistory, useLocation } from "react-router-dom";
|
import { useHistory, useLocation } from "react-router-dom";
|
||||||
import {
|
import {
|
||||||
@@ -79,7 +79,7 @@ const useList = <QueryResult extends IQueryResult, QueryData extends IDataItem>(
|
|||||||
options: IListHookOptions<QueryResult> & IQuery<QueryResult, QueryData>
|
options: IListHookOptions<QueryResult> & IQuery<QueryResult, QueryData>
|
||||||
): IListHookData => {
|
): IListHookData => {
|
||||||
const [interfaceState, setInterfaceState] = useInterfaceLocalForage();
|
const [interfaceState, setInterfaceState] = useInterfaceLocalForage();
|
||||||
const forageInitialised = useRef(false);
|
const [forageInitialised, setForageInitialised] = useState(false);
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const [filter, setFilter] = useState<ListFilterModel>(
|
const [filter, setFilter] = useState<ListFilterModel>(
|
||||||
@@ -96,39 +96,72 @@ const useList = <QueryResult extends IQueryResult, QueryData extends IDataItem>(
|
|||||||
const totalCount = options.getCount(result);
|
const totalCount = options.getCount(result);
|
||||||
const items = options.getData(result);
|
const items = options.getData(result);
|
||||||
|
|
||||||
|
const updateInterfaceConfig = useCallback((filter: ListFilterModel) => {
|
||||||
|
setInterfaceState(config => {
|
||||||
|
const data = { ...config } as IInterfaceConfig;
|
||||||
|
data.queries = {
|
||||||
|
[options.filterMode]: {
|
||||||
|
filter: filter.makeQueryParameters(),
|
||||||
|
itemsPerPage: filter.itemsPerPage,
|
||||||
|
currentPage: filter.currentPage
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return data;
|
||||||
|
});
|
||||||
|
}, [location.search, options.filterMode, setInterfaceState]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!forageInitialised.current && !interfaceState.loading) {
|
if(interfaceState.loading)
|
||||||
forageInitialised.current = true;
|
return;
|
||||||
|
if(!forageInitialised)
|
||||||
|
setForageInitialised(true);
|
||||||
|
|
||||||
// Don't use query parameters for sub-components
|
// Don't use query parameters for sub-components
|
||||||
if (options.subComponent) return;
|
if (options.subComponent) return;
|
||||||
// Don't read localForage if page already had query parameters
|
|
||||||
if (history.location.search) return;
|
|
||||||
|
|
||||||
const queryData = interfaceState.data?.queries?.[options.filterMode];
|
const storedQuery = interfaceState.data?.queries?.[options.filterMode];
|
||||||
if (!queryData) return;
|
if (!storedQuery) return;
|
||||||
|
|
||||||
|
const queryFilter = queryString.parse(location.search);
|
||||||
|
const storedFilter = queryString.parse(storedQuery.filter);
|
||||||
|
const query = location.search ? {
|
||||||
|
sortby: storedFilter.sortby,
|
||||||
|
sortdir: storedFilter.sortdir,
|
||||||
|
disp: storedFilter.disp,
|
||||||
|
perPage: storedFilter.perPage,
|
||||||
|
...queryFilter
|
||||||
|
} : storedFilter;
|
||||||
|
|
||||||
const newFilter = new ListFilterModel(
|
const newFilter = new ListFilterModel(
|
||||||
options.filterMode,
|
options.filterMode,
|
||||||
queryString.parse(queryData.filter)
|
query
|
||||||
);
|
);
|
||||||
newFilter.currentPage = queryData.currentPage;
|
|
||||||
newFilter.itemsPerPage = queryData.itemsPerPage;
|
|
||||||
|
|
||||||
const newLocation = { ...history.location };
|
// Compare constructed filter with current filter.
|
||||||
newLocation.search = queryData.filter;
|
// If different it's the result of navigation, and we update the filter.
|
||||||
|
const newLocation = { ...location };
|
||||||
|
newLocation.search = newFilter.makeQueryParameters();
|
||||||
|
if(newLocation.search !== filter.makeQueryParameters()) {
|
||||||
|
setFilter(newFilter);
|
||||||
|
updateInterfaceConfig(newFilter);
|
||||||
|
const newLocation = { ...location };
|
||||||
|
newLocation.search = newFilter.makeQueryParameters();
|
||||||
history.replace(newLocation);
|
history.replace(newLocation);
|
||||||
}
|
}
|
||||||
}, [
|
}, [
|
||||||
|
filter,
|
||||||
interfaceState.data,
|
interfaceState.data,
|
||||||
interfaceState.loading,
|
interfaceState.loading,
|
||||||
history,
|
location,
|
||||||
options.subComponent,
|
options.subComponent,
|
||||||
options.filterMode
|
options.filterMode,
|
||||||
|
forageInitialised,
|
||||||
|
updateInterfaceConfig
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
/*
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (options.subComponent) return;
|
if (options.subComponent || !forageInitialised) return;
|
||||||
|
|
||||||
const newFilter = new ListFilterModel(
|
const newFilter = new ListFilterModel(
|
||||||
options.filterMode,
|
options.filterMode,
|
||||||
@@ -136,20 +169,8 @@ const useList = <QueryResult extends IQueryResult, QueryData extends IDataItem>(
|
|||||||
);
|
);
|
||||||
setFilter(newFilter);
|
setFilter(newFilter);
|
||||||
|
|
||||||
if (forageInitialised.current) {
|
}, [location, options.filterMode, options.subComponent, setInterfaceState, forageInitialised]);
|
||||||
setInterfaceState(config => {
|
*/
|
||||||
const data = { ...config } as IInterfaceConfig;
|
|
||||||
data.queries = {
|
|
||||||
[options.filterMode]: {
|
|
||||||
filter: location.search,
|
|
||||||
itemsPerPage: newFilter.itemsPerPage,
|
|
||||||
currentPage: newFilter.currentPage
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return data;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, [location, options.filterMode, options.subComponent, setInterfaceState]);
|
|
||||||
|
|
||||||
function getFilter() {
|
function getFilter() {
|
||||||
if (!options.filterHook) {
|
if (!options.filterHook) {
|
||||||
@@ -161,10 +182,14 @@ const useList = <QueryResult extends IQueryResult, QueryData extends IDataItem>(
|
|||||||
return options.filterHook(newFilter);
|
return options.filterHook(newFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateQueryParams(listfilter: ListFilterModel) {
|
function updateQueryParams(listFilter: ListFilterModel) {
|
||||||
const newLocation = { ...history.location };
|
setFilter(listFilter);
|
||||||
newLocation.search = listfilter.makeQueryParameters();
|
if(!options.subComponent) {
|
||||||
|
const newLocation = { ...location };
|
||||||
|
newLocation.search = listFilter.makeQueryParameters();
|
||||||
history.replace(newLocation);
|
history.replace(newLocation);
|
||||||
|
updateInterfaceConfig(listFilter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onChangePageSize(pageSize: number) {
|
function onChangePageSize(pageSize: number) {
|
||||||
@@ -328,7 +353,7 @@ const useList = <QueryResult extends IQueryResult, QueryData extends IDataItem>(
|
|||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
let template;
|
let template;
|
||||||
if (result.loading || !forageInitialised.current) {
|
if (result.loading || !forageInitialised) {
|
||||||
template = <LoadingIndicator />;
|
template = <LoadingIndicator />;
|
||||||
} else if (result.error) {
|
} else if (result.error) {
|
||||||
template = <h1>{result.error.message}</h1>;
|
template = <h1>{result.error.message}</h1>;
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ import { makeCriteria } from "./criteria/utils";
|
|||||||
import { DisplayMode, FilterMode } from "./types";
|
import { DisplayMode, FilterMode } from "./types";
|
||||||
|
|
||||||
interface IQueryParameters {
|
interface IQueryParameters {
|
||||||
items?: string;
|
perPage?: string;
|
||||||
sortby?: string;
|
sortby?: string;
|
||||||
sortdir?: string;
|
sortdir?: string;
|
||||||
disp?: string;
|
disp?: string;
|
||||||
@@ -221,7 +221,7 @@ export class ListFilterModel {
|
|||||||
if (params.p) {
|
if (params.p) {
|
||||||
this.currentPage = Number.parseInt(params.p, 10);
|
this.currentPage = Number.parseInt(params.p, 10);
|
||||||
}
|
}
|
||||||
if (params.items) this.itemsPerPage = Number.parseInt(params.items, 10);
|
if (params.perPage) this.itemsPerPage = Number.parseInt(params.perPage, 10);
|
||||||
|
|
||||||
if (params.c !== undefined) {
|
if (params.c !== undefined) {
|
||||||
this.criteria = [];
|
this.criteria = [];
|
||||||
@@ -278,11 +278,11 @@ export class ListFilterModel {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const result = {
|
const result = {
|
||||||
items:
|
perPage:
|
||||||
this.itemsPerPage !== DEFAULT_PARAMS.itemsPerPage
|
this.itemsPerPage !== DEFAULT_PARAMS.itemsPerPage
|
||||||
? this.itemsPerPage
|
? this.itemsPerPage
|
||||||
: undefined,
|
: undefined,
|
||||||
sortby: this.getSortBy(),
|
sortby: this.sortBy !== "date" ? this.getSortBy() : undefined,
|
||||||
sortdir:
|
sortdir:
|
||||||
this.sortDirection === SortDirectionEnum.Desc ? "desc" : undefined,
|
this.sortDirection === SortDirectionEnum.Desc ? "desc" : undefined,
|
||||||
disp:
|
disp:
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ const renderHtmlSelect = (options: {
|
|||||||
<td>
|
<td>
|
||||||
<Form.Control
|
<Form.Control
|
||||||
as="select"
|
as="select"
|
||||||
readOnly={!options.isEditing}
|
disabled={!options.isEditing}
|
||||||
plaintext={!options.isEditing}
|
plaintext={!options.isEditing}
|
||||||
value={options.value?.toString()}
|
value={options.value?.toString()}
|
||||||
onChange={(event: React.FormEvent<HTMLSelectElement>) =>
|
onChange={(event: React.FormEvent<HTMLSelectElement>) =>
|
||||||
|
|||||||
Reference in New Issue
Block a user