Use gql for "mangas" VI - source mangas filter
This commit is contained in:
@@ -10,7 +10,7 @@ import FilterListIcon from '@mui/icons-material/FilterList';
|
|||||||
import { Button, Stack, Box } from '@mui/material';
|
import { Button, Stack, Box } from '@mui/material';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { ISourceFilters, IState } from '@/typings';
|
import { SourceFilters } from '@/typings';
|
||||||
import OptionsPanel from '@/components/molecules/OptionsPanel';
|
import OptionsPanel from '@/components/molecules/OptionsPanel';
|
||||||
import CheckBoxFilter from '@/components/source/filters/CheckBoxFilter';
|
import CheckBoxFilter from '@/components/source/filters/CheckBoxFilter';
|
||||||
import HeaderFilter from '@/components/source/filters/HeaderFilter';
|
import HeaderFilter from '@/components/source/filters/HeaderFilter';
|
||||||
@@ -25,14 +25,14 @@ import SeperatorFilter from '@/components/source/filters/SeparatorFilter';
|
|||||||
import StyledFab from '@/components/util/StyledFab';
|
import StyledFab from '@/components/util/StyledFab';
|
||||||
|
|
||||||
interface IFilters {
|
interface IFilters {
|
||||||
sourceFilter: ISourceFilters[];
|
sourceFilter: SourceFilters[];
|
||||||
updateFilterValue: Function;
|
updateFilterValue: Function;
|
||||||
group: number | undefined;
|
group: number | undefined;
|
||||||
update: any;
|
update: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IFilters1 {
|
interface IFilters1 {
|
||||||
sourceFilter: ISourceFilters[];
|
sourceFilter: SourceFilters[];
|
||||||
updateFilterValue: Function;
|
updateFilterValue: Function;
|
||||||
resetFilterValue: Function;
|
resetFilterValue: Function;
|
||||||
setTriggerUpdate: Function;
|
setTriggerUpdate: Function;
|
||||||
@@ -42,85 +42,89 @@ interface IFilters1 {
|
|||||||
export function Options({ sourceFilter, group, updateFilterValue, update }: IFilters) {
|
export function Options({ sourceFilter, group, updateFilterValue, update }: IFilters) {
|
||||||
return (
|
return (
|
||||||
<Stack key={`filters ${group}`}>
|
<Stack key={`filters ${group}`}>
|
||||||
{sourceFilter.map((e: ISourceFilters, index) => {
|
{sourceFilter.map((e, index) => {
|
||||||
let checkif = update.find(
|
let checkif = update.find(
|
||||||
(el: { group: number | undefined; position: number }) =>
|
(el: { group: number | undefined; position: number }) =>
|
||||||
el.group === group && el.position === index,
|
el.group === group && el.position === index,
|
||||||
);
|
);
|
||||||
checkif = checkif ? checkif.state : checkif;
|
checkif = checkif ? checkif.state : checkif;
|
||||||
switch (e.type) {
|
switch (e.type) {
|
||||||
case 'CheckBox':
|
case 'CheckBoxFilter':
|
||||||
return (
|
return (
|
||||||
<CheckBoxFilter
|
<CheckBoxFilter
|
||||||
key={`filters ${e.filter.name}`}
|
key={`filters ${e.name}`}
|
||||||
name={e.filter.name}
|
name={e.name}
|
||||||
state={checkif != null ? checkif === 'true' : (e.filter.state as boolean)}
|
state={checkif ?? e.CheckBoxFilterDefault}
|
||||||
position={index}
|
position={index}
|
||||||
group={group}
|
group={group}
|
||||||
updateFilterValue={updateFilterValue}
|
updateFilterValue={updateFilterValue}
|
||||||
update={update}
|
update={update}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
case 'Group':
|
case 'GroupFilter':
|
||||||
return (
|
return (
|
||||||
<GroupFilter
|
<GroupFilter
|
||||||
key={`filters ${e.filter.name}`}
|
key={`filters ${e.name}`}
|
||||||
name={e.filter.name}
|
name={e.name}
|
||||||
state={e.filter.state as ISourceFilters[]}
|
state={e.filters}
|
||||||
position={index}
|
position={index}
|
||||||
updateFilterValue={updateFilterValue}
|
updateFilterValue={updateFilterValue}
|
||||||
update={update}
|
update={update}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
case 'Header':
|
case 'HeaderFilter':
|
||||||
return <HeaderFilter key={`filters ${e.filter.name}`} name={e.filter.name} />;
|
return <HeaderFilter key={`filters ${e.name}`} name={e.name} />;
|
||||||
case 'Select':
|
case 'SelectFilter':
|
||||||
return (
|
return (
|
||||||
<SelectFilter
|
<SelectFilter
|
||||||
key={`filters ${e.filter.name}`}
|
key={`filters ${e.name}`}
|
||||||
name={e.filter.name}
|
name={e.name}
|
||||||
values={e.filter.displayValues}
|
values={e.values}
|
||||||
state={checkif != null ? parseInt(checkif, 10) : (e.filter.state as number)}
|
state={checkif != null ? parseInt(checkif, 10) : e.SelectFilterDefault}
|
||||||
selected={e.filter.selected}
|
|
||||||
position={index}
|
position={index}
|
||||||
group={group}
|
group={group}
|
||||||
updateFilterValue={updateFilterValue}
|
updateFilterValue={updateFilterValue}
|
||||||
update={update}
|
update={update}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
case 'Separator':
|
case 'SeparatorFilter':
|
||||||
return <SeperatorFilter key={`filters ${e.filter.name}`} name={e.filter.name} />;
|
return <SeperatorFilter key={`filters ${e.name}`} name={e.name} />;
|
||||||
case 'Sort':
|
case 'SortFilter':
|
||||||
return (
|
return (
|
||||||
<SortFilter
|
<SortFilter
|
||||||
key={`filters ${e.filter.name}`}
|
key={`filters ${e.name}`}
|
||||||
name={e.filter.name}
|
name={e.name}
|
||||||
values={e.filter.values}
|
values={e.values}
|
||||||
state={checkif ? JSON.parse(checkif) : { ...(e.filter.state as IState) }}
|
state={
|
||||||
|
checkif ?? {
|
||||||
|
ascending: e.SortFilterDefault?.ascending,
|
||||||
|
index: e.SortFilterDefault?.index,
|
||||||
|
}
|
||||||
|
}
|
||||||
position={index}
|
position={index}
|
||||||
group={group}
|
group={group}
|
||||||
updateFilterValue={updateFilterValue}
|
updateFilterValue={updateFilterValue}
|
||||||
update={update}
|
update={update}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
case 'Text':
|
case 'TextFilter':
|
||||||
return (
|
return (
|
||||||
<TextFilter
|
<TextFilter
|
||||||
key={`filters ${e.filter.name}`}
|
key={`filters ${e.name}`}
|
||||||
name={e.filter.name}
|
name={e.name}
|
||||||
state={checkif ?? (e.filter.state as string)}
|
state={checkif ?? e.TextFilterDefault}
|
||||||
position={index}
|
position={index}
|
||||||
group={group}
|
group={group}
|
||||||
updateFilterValue={updateFilterValue}
|
updateFilterValue={updateFilterValue}
|
||||||
update={update}
|
update={update}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
case 'TriState':
|
case 'TriStateFilter':
|
||||||
return (
|
return (
|
||||||
<TriStateFilter
|
<TriStateFilter
|
||||||
key={`filters ${e.filter.name}`}
|
key={`filters ${e.name}`}
|
||||||
name={e.filter.name}
|
name={e.name}
|
||||||
state={checkif != null ? parseInt(checkif, 10) : (e.filter.state as number)}
|
state={checkif != null ? checkif : e.TriStateFilterDefault}
|
||||||
position={index}
|
position={index}
|
||||||
group={group}
|
group={group}
|
||||||
updateFilterValue={updateFilterValue}
|
updateFilterValue={updateFilterValue}
|
||||||
@@ -128,7 +132,7 @@ export function Options({ sourceFilter, group, updateFilterValue, update }: IFil
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
default:
|
default:
|
||||||
return <Box key={`${e.filter.name}null`} />;
|
throw new Error(`Unknown source filter "${e}"`);
|
||||||
}
|
}
|
||||||
})}
|
})}
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ const CheckBoxFilter: React.FC<Props> = (props: Props) => {
|
|||||||
const upd = update.filter(
|
const upd = update.filter(
|
||||||
(e: { position: number; group: number | undefined }) => !(position === e.position && group === e.group),
|
(e: { position: number; group: number | undefined }) => !(position === e.position && group === e.group),
|
||||||
);
|
);
|
||||||
updateFilterValue([...upd, { position, state: event.target.checked.toString(), group }]);
|
updateFilterValue([...upd, { type: 'checkBoxState', position, state: event.target.checked, group }]);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (state !== undefined) {
|
if (state !== undefined) {
|
||||||
|
|||||||
@@ -10,11 +10,14 @@ import { ExpandLess, ExpandMore } from '@mui/icons-material';
|
|||||||
import { Collapse, ListItemButton, ListItemText, Stack, Box } from '@mui/material';
|
import { Collapse, ListItemButton, ListItemText, Stack, Box } from '@mui/material';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
// eslint-disable-next-line import/no-cycle
|
// eslint-disable-next-line import/no-cycle
|
||||||
import { ISourceFilters } from '@/typings';
|
import { SourceFilters } from '@/typings';
|
||||||
import { Options } from '@/components/source/SourceOptions';
|
import { Options } from '@/components/source/SourceOptions';
|
||||||
|
|
||||||
|
// type ExcludeByName<T, K extends string> = T extends { __typename?: K } ? never : T;
|
||||||
|
type PickByName<T, K extends string> = T extends { __typename?: K } ? T : never;
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
state: ISourceFilters[];
|
state: PickByName<SourceFilters, 'GroupFilter'>['filters'];
|
||||||
name: string;
|
name: string;
|
||||||
position: number;
|
position: number;
|
||||||
updateFilterValue: Function;
|
updateFilterValue: Function;
|
||||||
@@ -36,7 +39,7 @@ const GroupFilter: React.FC<Props> = (props: Props) => {
|
|||||||
{/* Container is moved outside 2, so content has to go inside 4 */}
|
{/* Container is moved outside 2, so content has to go inside 4 */}
|
||||||
<Stack sx={{ mx: 4 }}>
|
<Stack sx={{ mx: 4 }}>
|
||||||
<Options
|
<Options
|
||||||
sourceFilter={state}
|
sourceFilter={state as SourceFilters[]}
|
||||||
group={position}
|
group={position}
|
||||||
updateFilterValue={updateFilterValue}
|
updateFilterValue={updateFilterValue}
|
||||||
update={update}
|
update={update}
|
||||||
|
|||||||
@@ -16,56 +16,12 @@ interface Props {
|
|||||||
values: any;
|
values: any;
|
||||||
name: string;
|
name: string;
|
||||||
state: number;
|
state: number;
|
||||||
selected: Selected | undefined;
|
|
||||||
position: number;
|
position: number;
|
||||||
updateFilterValue: Function;
|
updateFilterValue: Function;
|
||||||
group: number | undefined;
|
group: number | undefined;
|
||||||
update: any;
|
update: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Selected {
|
|
||||||
displayname: string;
|
|
||||||
value: string;
|
|
||||||
_value: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
function hasSelect(
|
|
||||||
values: Selected[],
|
|
||||||
name: string,
|
|
||||||
state: number,
|
|
||||||
position: number,
|
|
||||||
updateFilterValue: Function,
|
|
||||||
update: any,
|
|
||||||
group?: number,
|
|
||||||
) {
|
|
||||||
const [val, setval] = React.useState(state);
|
|
||||||
if (values) {
|
|
||||||
const handleChange = (event: { target: { name: any; value: any } }) => {
|
|
||||||
const vall = values.map((e) => e.displayname).indexOf(`${event.target.value}`);
|
|
||||||
setval(vall);
|
|
||||||
const upd = update.filter(
|
|
||||||
(e: { position: number; group: number | undefined }) => !(position === e.position && group === e.group),
|
|
||||||
);
|
|
||||||
updateFilterValue([...upd, { position, state: vall.toString(), group }]);
|
|
||||||
};
|
|
||||||
|
|
||||||
const rett = values.map((e: Selected) => (
|
|
||||||
<MenuItem key={`${name} ${e.displayname}`} value={e.displayname}>
|
|
||||||
{e.displayname}
|
|
||||||
</MenuItem>
|
|
||||||
));
|
|
||||||
return (
|
|
||||||
<FormControl sx={{ my: 1 }} variant="standard">
|
|
||||||
<InputLabel>{name}</InputLabel>
|
|
||||||
<Select name={name} value={values[val].displayname} label={name} onChange={handleChange}>
|
|
||||||
{rett}
|
|
||||||
</Select>
|
|
||||||
</FormControl>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function noSelect(
|
function noSelect(
|
||||||
values: string[],
|
values: string[],
|
||||||
name: string,
|
name: string,
|
||||||
@@ -84,7 +40,7 @@ function noSelect(
|
|||||||
const upd = update.filter(
|
const upd = update.filter(
|
||||||
(e: { position: number; group: number | undefined }) => !(position === e.position && group === e.group),
|
(e: { position: number; group: number | undefined }) => !(position === e.position && group === e.group),
|
||||||
);
|
);
|
||||||
updateFilterValue([...upd, { position, state: vall.toString(), group }]);
|
updateFilterValue([...upd, { type: 'selectState', position, state: vall, group }]);
|
||||||
};
|
};
|
||||||
|
|
||||||
const rett = values.map((value: string) => (
|
const rett = values.map((value: string) => (
|
||||||
@@ -104,21 +60,7 @@ function noSelect(
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SelectFilter: React.FC<Props> = ({
|
const SelectFilter: React.FC<Props> = ({ values, name, state, position, updateFilterValue, update, group }) =>
|
||||||
values,
|
noSelect(values, name, state, position, updateFilterValue, update, group);
|
||||||
name,
|
|
||||||
state,
|
|
||||||
selected,
|
|
||||||
position,
|
|
||||||
updateFilterValue,
|
|
||||||
update,
|
|
||||||
group,
|
|
||||||
}) => {
|
|
||||||
if (selected === undefined) {
|
|
||||||
return noSelect(values, name, state, position, updateFilterValue, update, group);
|
|
||||||
}
|
|
||||||
|
|
||||||
return hasSelect(values, name, state, position, updateFilterValue, update, group);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default SelectFilter;
|
export default SelectFilter;
|
||||||
|
|||||||
@@ -9,13 +9,13 @@
|
|||||||
import { ExpandLess, ExpandMore } from '@mui/icons-material';
|
import { ExpandLess, ExpandMore } from '@mui/icons-material';
|
||||||
import { Collapse, ListItemButton, ListItemText, Stack, Box } from '@mui/material';
|
import { Collapse, ListItemButton, ListItemText, Stack, Box } from '@mui/material';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { IState } from '@/typings';
|
|
||||||
import SortRadioInput from '@/components/atoms/SortRadioInput';
|
import SortRadioInput from '@/components/atoms/SortRadioInput';
|
||||||
|
import { SortSelectionInput } from '@/lib/graphql/generated/graphql.ts';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
values: any;
|
values: any;
|
||||||
name: string;
|
name: string;
|
||||||
state: IState;
|
state: SortSelectionInput;
|
||||||
position: number;
|
position: number;
|
||||||
group: number | undefined;
|
group: number | undefined;
|
||||||
updateFilterValue: Function;
|
updateFilterValue: Function;
|
||||||
@@ -45,7 +45,7 @@ const SortFilter: React.FC<Props> = (props: Props) => {
|
|||||||
const upd = update.filter(
|
const upd = update.filter(
|
||||||
(e: { position: number; group: number | undefined }) => !(position === e.position && group === e.group),
|
(e: { position: number; group: number | undefined }) => !(position === e.position && group === e.group),
|
||||||
);
|
);
|
||||||
updateFilterValue([...upd, { position, state: JSON.stringify(tmp), group }]);
|
updateFilterValue([...upd, { type: 'sortState', position, state: tmp, group }]);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ const TextFilter: React.FC<Props> = (props) => {
|
|||||||
const upd = update.filter(
|
const upd = update.filter(
|
||||||
(el: { position: number; group: number | undefined }) => !(position === el.position && group === el.group),
|
(el: { position: number; group: number | undefined }) => !(position === el.position && group === el.group),
|
||||||
);
|
);
|
||||||
updateFilterValue([...upd, { position, state: inputText, group }]);
|
updateFilterValue([...upd, { type: 'textState', position, state: inputText, group }]);
|
||||||
}, [inputText]);
|
}, [inputText]);
|
||||||
|
|
||||||
if (state !== undefined) {
|
if (state !== undefined) {
|
||||||
|
|||||||
@@ -8,9 +8,10 @@
|
|||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ThreeStateCheckboxInput from '@/components/atoms/ThreeStateCheckboxInput';
|
import ThreeStateCheckboxInput from '@/components/atoms/ThreeStateCheckboxInput';
|
||||||
|
import { TriState } from '@/lib/graphql/generated/graphql.ts';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
state: number;
|
state: TriState;
|
||||||
name: string;
|
name: string;
|
||||||
position: number;
|
position: number;
|
||||||
group: number | undefined;
|
group: number | undefined;
|
||||||
@@ -18,9 +19,35 @@ interface Props {
|
|||||||
update: any;
|
update: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const convertTriStateToNumber = (triState: TriState): number => {
|
||||||
|
switch (triState) {
|
||||||
|
case TriState.Ignore:
|
||||||
|
return 0;
|
||||||
|
case TriState.Include:
|
||||||
|
return 1;
|
||||||
|
case TriState.Exclude:
|
||||||
|
return 2;
|
||||||
|
default:
|
||||||
|
throw new Error(`Unexpected TriState ${triState}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const convertNumberToTriState = (state: number): TriState => {
|
||||||
|
switch (state) {
|
||||||
|
case 0:
|
||||||
|
return TriState.Ignore;
|
||||||
|
case 1:
|
||||||
|
return TriState.Include;
|
||||||
|
case 2:
|
||||||
|
return TriState.Exclude;
|
||||||
|
default:
|
||||||
|
throw new Error(`Unexpected state number ${state}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const TriStateFilter: React.FC<Props> = (props) => {
|
const TriStateFilter: React.FC<Props> = (props) => {
|
||||||
const { state, name, position, group, updateFilterValue, update } = props;
|
const { state, name, position, group, updateFilterValue, update } = props;
|
||||||
const [val, setval] = React.useState<number>(Number(state));
|
const [val, setval] = React.useState(convertTriStateToNumber(state));
|
||||||
|
|
||||||
const handleChange = (checked: boolean | null | undefined) => {
|
const handleChange = (checked: boolean | null | undefined) => {
|
||||||
// eslint-disable-next-line no-nested-ternary
|
// eslint-disable-next-line no-nested-ternary
|
||||||
@@ -32,8 +59,9 @@ const TriStateFilter: React.FC<Props> = (props) => {
|
|||||||
updateFilterValue([
|
updateFilterValue([
|
||||||
...upd,
|
...upd,
|
||||||
{
|
{
|
||||||
|
type: 'triState',
|
||||||
position,
|
position,
|
||||||
state: newState.toString(),
|
state: convertNumberToTriState(newState),
|
||||||
group,
|
group,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|||||||
@@ -28,10 +28,8 @@ import {
|
|||||||
BackupValidationResult,
|
BackupValidationResult,
|
||||||
IChapter,
|
IChapter,
|
||||||
IMangaChapter,
|
IMangaChapter,
|
||||||
ISourceFilters,
|
|
||||||
PaginatedList,
|
PaginatedList,
|
||||||
SourcePreferences,
|
SourcePreferences,
|
||||||
SourceSearchResult,
|
|
||||||
} from '@/typings.ts';
|
} from '@/typings.ts';
|
||||||
import { HttpMethod as DefaultHttpMethod, IRestClient, RestClient } from '@/lib/requests/client/RestClient.ts';
|
import { HttpMethod as DefaultHttpMethod, IRestClient, RestClient } from '@/lib/requests/client/RestClient.ts';
|
||||||
import storage from '@/util/localStorage.tsx';
|
import storage from '@/util/localStorage.tsx';
|
||||||
@@ -1208,22 +1206,6 @@ export class RequestManager {
|
|||||||
return this.doRequest(HttpMethod.POST, `source/${sourceId}/preferences`, { data: { position, value } });
|
return this.doRequest(HttpMethod.POST, `source/${sourceId}/preferences`, { data: { position, value } });
|
||||||
}
|
}
|
||||||
|
|
||||||
public useGetSourceFilters(
|
|
||||||
sourceId: string,
|
|
||||||
reset?: boolean,
|
|
||||||
swrOptions?: SWROptions<ISourceFilters[]>,
|
|
||||||
): AbortableSWRResponse<ISourceFilters[]> {
|
|
||||||
return this.doRequest(HttpMethod.SWR_GET, `source/${sourceId}/filters`, { swrOptions });
|
|
||||||
}
|
|
||||||
|
|
||||||
public setSourceFilters(sourceId: string, filters: { position: number; state: string }[]): AbortableAxiosResponse {
|
|
||||||
return this.doRequest(HttpMethod.POST, `source/${sourceId}/filters`, { data: filters });
|
|
||||||
}
|
|
||||||
|
|
||||||
public resetSourceFilters(sourceId: string): AbortableAxiosResponse {
|
|
||||||
return this.doRequest(HttpMethod.GET, `source/${sourceId}/filters?reset=true`);
|
|
||||||
}
|
|
||||||
|
|
||||||
public useSourceSearch(
|
public useSourceSearch(
|
||||||
source: string,
|
source: string,
|
||||||
query?: string,
|
query?: string,
|
||||||
@@ -1241,26 +1223,6 @@ export class RequestManager {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public useSourceQuickSearch(
|
|
||||||
sourceId: string,
|
|
||||||
searchTerm: string,
|
|
||||||
filters: { position: number; state: string }[],
|
|
||||||
initialPages?: number,
|
|
||||||
swrOptions?: SWRInfiniteOptions<SourceSearchResult>,
|
|
||||||
): AbortableSWRInfiniteResponse<SourceSearchResult> {
|
|
||||||
return this.doRequest(HttpMethod.SWR_POST_INFINITE, '', {
|
|
||||||
data: { searchTerm, filter: filters },
|
|
||||||
swrOptions: {
|
|
||||||
getEndpoint: (page, previousData) =>
|
|
||||||
previousData?.hasNextPage ?? true
|
|
||||||
? `source/${sourceId}/quick-search?searchTerm=${searchTerm}&pageNum=${page + 1}`
|
|
||||||
: null,
|
|
||||||
initialSize: initialPages,
|
|
||||||
...swrOptions,
|
|
||||||
} as typeof swrOptions,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public useGetManga(
|
public useGetManga(
|
||||||
mangaId: number | string,
|
mangaId: number | string,
|
||||||
options?: QueryHookOptions<GetMangaQuery, GetMangaQueryVariables>,
|
options?: QueryHookOptions<GetMangaQuery, GetMangaQueryVariables>,
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ export enum SourceContentType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface IPos {
|
interface IPos {
|
||||||
|
type: 'selectState' | 'textState' | 'checkBoxState' | 'triState' | 'sortState';
|
||||||
position: number;
|
position: number;
|
||||||
state: any;
|
state: any;
|
||||||
group?: number;
|
group?: number;
|
||||||
@@ -127,30 +128,30 @@ const useSourceManga = (
|
|||||||
result = requestManager.useSourceSearch(sourceId, searchTerm ?? '', undefined, initialPages);
|
result = requestManager.useSourceSearch(sourceId, searchTerm ?? '', undefined, initialPages);
|
||||||
break;
|
break;
|
||||||
case SourceContentType.FILTER:
|
case SourceContentType.FILTER:
|
||||||
result = requestManager.useSourceSearch(sourceId, undefined, [], initialPages);
|
result = requestManager.useSourceSearch(
|
||||||
// TODO - update filters to gql
|
sourceId,
|
||||||
// result = requestManager.useSourceQuickSearch(
|
undefined,
|
||||||
// sourceId,
|
filters.map((filter) => {
|
||||||
// '',
|
const { position, state, group } = filter;
|
||||||
// filters.map((filter) => {
|
|
||||||
// const { position, state, group } = filter;
|
const isPartOfGroup = group !== undefined;
|
||||||
//
|
if (isPartOfGroup) {
|
||||||
// const isPartOfGroup = group !== undefined;
|
return {
|
||||||
// if (isPartOfGroup) {
|
position: group,
|
||||||
// return {
|
groupChange: {
|
||||||
// position: group,
|
position,
|
||||||
// state: JSON.stringify({
|
[filter.type]: state,
|
||||||
// position,
|
},
|
||||||
// state,
|
};
|
||||||
// }),
|
}
|
||||||
// };
|
|
||||||
// }
|
return {
|
||||||
//
|
position,
|
||||||
// return filter;
|
[filter.type]: state,
|
||||||
// }),
|
};
|
||||||
// initialPages,
|
}),
|
||||||
// { disableCache: true },
|
initialPages,
|
||||||
// );
|
);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new Error(`Unknown ContentType "${contentType}"`);
|
throw new Error(`Unknown ContentType "${contentType}"`);
|
||||||
@@ -222,10 +223,9 @@ export default function SourceMangas() {
|
|||||||
const mangas = (data?.fetchSourceManga.mangas as MangaType[]) ?? [];
|
const mangas = (data?.fetchSourceManga.mangas as MangaType[]) ?? [];
|
||||||
const hasNextPage = data?.fetchSourceManga.hasNextPage ?? false;
|
const hasNextPage = data?.fetchSourceManga.hasNextPage ?? false;
|
||||||
|
|
||||||
const { data: filters = [], mutate: mutateFilters } = requestManager.useGetSourceFilters(sourceId);
|
|
||||||
const { data: sourceData } = requestManager.useGetSource(sourceId);
|
const { data: sourceData } = requestManager.useGetSource(sourceId);
|
||||||
const source = sourceData?.source;
|
const source = sourceData?.source;
|
||||||
const [triggerDataRefresh, setTriggerDataRefresh] = useState(false);
|
const filters = source?.filters ?? [];
|
||||||
|
|
||||||
const message = !isLoading ? t(SOURCE_CONTENT_TYPE_TO_ERROR_MSG_KEY[contentType]) : undefined;
|
const message = !isLoading ? t(SOURCE_CONTENT_TYPE_TO_ERROR_MSG_KEY[contentType]) : undefined;
|
||||||
const isLocalSource = sourceId === '0';
|
const isLocalSource = sourceId === '0';
|
||||||
@@ -272,14 +272,6 @@ export default function SourceMangas() {
|
|||||||
const resetFilters = useCallback(async () => {
|
const resetFilters = useCallback(async () => {
|
||||||
setDialogFiltersToApply([]);
|
setDialogFiltersToApply([]);
|
||||||
setFiltersToApply([]);
|
setFiltersToApply([]);
|
||||||
try {
|
|
||||||
// required since previous implementation used to set the filters on server side (server caches them), thus, it has to be made sure that they are reset
|
|
||||||
await requestManager.resetSourceFilters(sourceId);
|
|
||||||
mutateFilters();
|
|
||||||
} catch (error) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
setTriggerDataRefresh(true);
|
|
||||||
}, [sourceId]);
|
}, [sourceId]);
|
||||||
|
|
||||||
useEffect(
|
useEffect(
|
||||||
@@ -297,16 +289,6 @@ export default function SourceMangas() {
|
|||||||
[searchTerm, contentType],
|
[searchTerm, contentType],
|
||||||
);
|
);
|
||||||
|
|
||||||
// TODO - check when fixing filters
|
|
||||||
useEffect(() => {
|
|
||||||
if (!triggerDataRefresh) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// refreshData();
|
|
||||||
setTriggerDataRefresh(false);
|
|
||||||
}, [triggerDataRefresh]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setTitle(source?.displayName ?? t('source.title'));
|
setTitle(source?.displayName ?? t('source.title'));
|
||||||
setAction(
|
setAction(
|
||||||
@@ -378,7 +360,6 @@ export default function SourceMangas() {
|
|||||||
updateFilterValue={setDialogFiltersToApply}
|
updateFilterValue={setDialogFiltersToApply}
|
||||||
setTriggerUpdate={() => {
|
setTriggerUpdate={() => {
|
||||||
setFiltersToApply(dialogFiltersToApply);
|
setFiltersToApply(dialogFiltersToApply);
|
||||||
setTriggerDataRefresh(true);
|
|
||||||
}}
|
}}
|
||||||
resetFilterValue={resetFilters}
|
resetFilterValue={resetFilters}
|
||||||
update={dialogFiltersToApply}
|
update={dialogFiltersToApply}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import { OverridableComponent } from '@mui/material/OverridableComponent';
|
|||||||
import { SvgIconTypeMap } from '@mui/material/SvgIcon/SvgIcon';
|
import { SvgIconTypeMap } from '@mui/material/SvgIcon/SvgIcon';
|
||||||
import { ParseKeys } from 'i18next';
|
import { ParseKeys } from 'i18next';
|
||||||
import { Location } from 'react-router-dom';
|
import { Location } from 'react-router-dom';
|
||||||
import { ExtensionType, MangaType, MetaType } from '@/lib/graphql/generated/graphql.ts';
|
import { ExtensionType, GetSourceQuery, MangaType, MetaType } from '@/lib/graphql/generated/graphql.ts';
|
||||||
|
|
||||||
export type RecursivePartial<T> = {
|
export type RecursivePartial<T> = {
|
||||||
[P in keyof T]?: T[P] extends (infer U)[]
|
[P in keyof T]?: T[P] extends (infer U)[]
|
||||||
@@ -43,29 +43,7 @@ export interface ISource {
|
|||||||
displayName: string;
|
displayName: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ISourceFilters {
|
export type SourceFilters = GetSourceQuery['source']['filters'][number];
|
||||||
type: string;
|
|
||||||
filter: ISourceFilter;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ISourceFilter {
|
|
||||||
name: string;
|
|
||||||
state: number | string | boolean | ISourceFilters[] | IState;
|
|
||||||
values?: string[];
|
|
||||||
displayValues?: string[];
|
|
||||||
selected?: ISelected;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ISelected {
|
|
||||||
displayname: string;
|
|
||||||
value: string;
|
|
||||||
_value: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IState {
|
|
||||||
ascending: boolean;
|
|
||||||
index: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IMetadataMigration {
|
export interface IMetadataMigration {
|
||||||
appKeyPrefix?: { oldPrefix: string; newPrefix: string };
|
appKeyPrefix?: { oldPrefix: string; newPrefix: string };
|
||||||
|
|||||||
Reference in New Issue
Block a user