mirror of
https://github.com/stashapp/stash.git
synced 2025-12-18 04:44:37 +03:00
Fix infinite load issue (#756)
* Remove subcomponents to resolve infinite load issue
This commit is contained in:
@@ -29,7 +29,6 @@ interface IListFilterOperation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface IListFilterProps {
|
interface IListFilterProps {
|
||||||
subComponent?: boolean;
|
|
||||||
onFilterUpdate: (newFilter: ListFilterModel) => void;
|
onFilterUpdate: (newFilter: ListFilterModel) => void;
|
||||||
zoomIndex?: number;
|
zoomIndex?: number;
|
||||||
onChangeZoom?: (zoomIndex: number) => void;
|
onChangeZoom?: (zoomIndex: number) => void;
|
||||||
@@ -105,7 +104,7 @@ export const ListFilter: React.FC<IListFilterProps> = (
|
|||||||
Mousetrap.bind("s a", () => onSelectAll());
|
Mousetrap.bind("s a", () => onSelectAll());
|
||||||
Mousetrap.bind("s n", () => onSelectNone());
|
Mousetrap.bind("s n", () => onSelectNone());
|
||||||
|
|
||||||
if (!props.subComponent && props.itemsSelected) {
|
if (props.itemsSelected) {
|
||||||
Mousetrap.bind("e", () => {
|
Mousetrap.bind("e", () => {
|
||||||
if (props.onEdit) {
|
if (props.onEdit) {
|
||||||
props.onEdit();
|
props.onEdit();
|
||||||
@@ -130,7 +129,7 @@ export const ListFilter: React.FC<IListFilterProps> = (
|
|||||||
Mousetrap.unbind("s a");
|
Mousetrap.unbind("s a");
|
||||||
Mousetrap.unbind("s n");
|
Mousetrap.unbind("s n");
|
||||||
|
|
||||||
if (!props.subComponent && props.itemsSelected) {
|
if (props.itemsSelected) {
|
||||||
Mousetrap.unbind("e");
|
Mousetrap.unbind("e");
|
||||||
Mousetrap.unbind("d d");
|
Mousetrap.unbind("d d");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
/* eslint-disable react/no-this-in-sfc */
|
|
||||||
import React, { useEffect, useState, useCallback } from "react";
|
import React, { useEffect, useState, useCallback } from "react";
|
||||||
import { useIntl } from "react-intl";
|
import { useIntl } from "react-intl";
|
||||||
import * as GQL from "src/core/generated-graphql";
|
import * as GQL from "src/core/generated-graphql";
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ export const MovieScenesPanel: React.FC<IMovieScenesPanel> = ({ movie }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (movie && movie.id) {
|
if (movie && movie.id) {
|
||||||
return <SceneList subComponent filterHook={filterHook} />;
|
return <SceneList filterHook={filterHook} />;
|
||||||
}
|
}
|
||||||
return <></>;
|
return <></>;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { MovieCard } from "./MovieCard";
|
|||||||
export const MovieList: React.FC = () => {
|
export const MovieList: React.FC = () => {
|
||||||
const listData = useMoviesList({
|
const listData = useMoviesList({
|
||||||
renderContent,
|
renderContent,
|
||||||
|
persistState: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
function renderContent(
|
function renderContent(
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { MovieList } from "./MovieList";
|
|||||||
const Movies = () => (
|
const Movies = () => (
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route exact path="/movies" component={MovieList} />
|
<Route exact path="/movies" component={MovieList} />
|
||||||
<Route path="/movies/:id" component={Movie} />
|
<Route path="/movies/:id/:tab?" component={Movie} />
|
||||||
</Switch>
|
</Switch>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import { PerformerScenesPanel } from "./PerformerScenesPanel";
|
|||||||
export const Performer: React.FC = () => {
|
export const Performer: React.FC = () => {
|
||||||
const Toast = useToast();
|
const Toast = useToast();
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const { id = "new" } = useParams();
|
const { tab = "details", id = "new" } = useParams();
|
||||||
const isNew = id === "new";
|
const isNew = id === "new";
|
||||||
|
|
||||||
// Performer state
|
// Performer state
|
||||||
@@ -42,13 +42,22 @@ export const Performer: React.FC = () => {
|
|||||||
// Network state
|
// Network state
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
|
||||||
const [activeTabKey, setActiveTabKey] = useState("details");
|
|
||||||
|
|
||||||
const { data, error } = useFindPerformer(id);
|
const { data, error } = useFindPerformer(id);
|
||||||
const [updatePerformer] = usePerformerUpdate();
|
const [updatePerformer] = usePerformerUpdate();
|
||||||
const [createPerformer] = usePerformerCreate();
|
const [createPerformer] = usePerformerCreate();
|
||||||
const [deletePerformer] = usePerformerDestroy();
|
const [deletePerformer] = usePerformerDestroy();
|
||||||
|
|
||||||
|
const activeTabKey =
|
||||||
|
tab === "scenes" || tab === "edit" || tab === "operations"
|
||||||
|
? tab
|
||||||
|
: "details";
|
||||||
|
const setActiveTabKey = (newTab: string) => {
|
||||||
|
if (tab !== newTab) {
|
||||||
|
const tabParam = newTab === "details" ? "" : `/${newTab}`;
|
||||||
|
history.replace(`/performers/${id}${tabParam}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
if (data?.findPerformer) setPerformer(data.findPerformer);
|
if (data?.findPerformer) setPerformer(data.findPerformer);
|
||||||
@@ -128,7 +137,7 @@ export const Performer: React.FC = () => {
|
|||||||
const renderTabs = () => (
|
const renderTabs = () => (
|
||||||
<Tabs
|
<Tabs
|
||||||
activeKey={activeTabKey}
|
activeKey={activeTabKey}
|
||||||
onSelect={(k: string) => setActiveTabKey(k)}
|
onSelect={setActiveTabKey}
|
||||||
id="performer-details"
|
id="performer-details"
|
||||||
unmountOnExit
|
unmountOnExit
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
/* eslint-disable react/no-this-in-sfc */
|
|
||||||
|
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { useIntl } from "react-intl";
|
import { useIntl } from "react-intl";
|
||||||
import { Button, Popover, OverlayTrigger, Table } from "react-bootstrap";
|
import { Button, Popover, OverlayTrigger, Table } from "react-bootstrap";
|
||||||
|
|||||||
@@ -43,5 +43,5 @@ export const PerformerScenesPanel: React.FC<IPerformerDetailsProps> = ({
|
|||||||
return filter;
|
return filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
return <SceneList subComponent filterHook={filterHook} />;
|
return <SceneList filterHook={filterHook} />;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ export const PerformerList: React.FC = () => {
|
|||||||
otherOperations,
|
otherOperations,
|
||||||
renderContent,
|
renderContent,
|
||||||
addKeybinds,
|
addKeybinds,
|
||||||
|
persistState: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
async function getRandom(
|
async function getRandom(
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { PerformerList } from "./PerformerList";
|
|||||||
const Performers = () => (
|
const Performers = () => (
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route exact path="/performers" component={PerformerList} />
|
<Route exact path="/performers" component={PerformerList} />
|
||||||
<Route path="/performers/:id" component={Performer} />
|
<Route path="/performers/:id/:tab?" component={Performer} />
|
||||||
</Switch>
|
</Switch>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
/* eslint-disable react/no-this-in-sfc */
|
|
||||||
|
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
|
|||||||
@@ -18,13 +18,13 @@ import { DeleteScenesDialog } from "./DeleteScenesDialog";
|
|||||||
import { SceneGenerateDialog } from "./SceneGenerateDialog";
|
import { SceneGenerateDialog } from "./SceneGenerateDialog";
|
||||||
|
|
||||||
interface ISceneList {
|
interface ISceneList {
|
||||||
subComponent?: boolean;
|
|
||||||
filterHook?: (filter: ListFilterModel) => ListFilterModel;
|
filterHook?: (filter: ListFilterModel) => ListFilterModel;
|
||||||
|
persistState?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SceneList: React.FC<ISceneList> = ({
|
export const SceneList: React.FC<ISceneList> = ({
|
||||||
subComponent,
|
|
||||||
filterHook,
|
filterHook,
|
||||||
|
persistState,
|
||||||
}) => {
|
}) => {
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const [isGenerateDialogOpen, setIsGenerateDialogOpen] = useState(false);
|
const [isGenerateDialogOpen, setIsGenerateDialogOpen] = useState(false);
|
||||||
@@ -61,9 +61,9 @@ export const SceneList: React.FC<ISceneList> = ({
|
|||||||
renderContent,
|
renderContent,
|
||||||
renderEditDialog: renderEditScenesDialog,
|
renderEditDialog: renderEditScenesDialog,
|
||||||
renderDeleteDialog: renderDeleteScenesDialog,
|
renderDeleteDialog: renderDeleteScenesDialog,
|
||||||
subComponent,
|
|
||||||
filterHook,
|
filterHook,
|
||||||
addKeybinds,
|
addKeybinds,
|
||||||
|
persistState,
|
||||||
});
|
});
|
||||||
|
|
||||||
async function playRandom(
|
async function playRandom(
|
||||||
|
|||||||
@@ -10,14 +10,10 @@ import { DisplayMode } from "src/models/list-filter/types";
|
|||||||
import { WallPanel } from "../Wall/WallPanel";
|
import { WallPanel } from "../Wall/WallPanel";
|
||||||
|
|
||||||
interface ISceneMarkerList {
|
interface ISceneMarkerList {
|
||||||
subComponent?: boolean;
|
|
||||||
filterHook?: (filter: ListFilterModel) => ListFilterModel;
|
filterHook?: (filter: ListFilterModel) => ListFilterModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SceneMarkerList: React.FC<ISceneMarkerList> = ({
|
export const SceneMarkerList: React.FC<ISceneMarkerList> = ({ filterHook }) => {
|
||||||
subComponent,
|
|
||||||
filterHook,
|
|
||||||
}) => {
|
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const otherOperations = [
|
const otherOperations = [
|
||||||
{
|
{
|
||||||
@@ -42,7 +38,6 @@ export const SceneMarkerList: React.FC<ISceneMarkerList> = ({
|
|||||||
const listData = useSceneMarkersList({
|
const listData = useSceneMarkersList({
|
||||||
otherOperations,
|
otherOperations,
|
||||||
renderContent,
|
renderContent,
|
||||||
subComponent,
|
|
||||||
filterHook,
|
filterHook,
|
||||||
addKeybinds,
|
addKeybinds,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -6,7 +6,11 @@ import { SceneMarkerList } from "./SceneMarkerList";
|
|||||||
|
|
||||||
const Scenes = () => (
|
const Scenes = () => (
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route exact path="/scenes" component={SceneList} />
|
<Route
|
||||||
|
exact
|
||||||
|
path="/scenes"
|
||||||
|
render={(props) => <SceneList persistState {...props} />}
|
||||||
|
/>
|
||||||
<Route exact path="/scenes/markers" component={SceneMarkerList} />
|
<Route exact path="/scenes/markers" component={SceneMarkerList} />
|
||||||
<Route path="/scenes/:id" component={Scene} />
|
<Route path="/scenes/:id" component={Scene} />
|
||||||
</Switch>
|
</Switch>
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
/* eslint-disable react/no-this-in-sfc */
|
|
||||||
|
|
||||||
import { Table, Tabs, Tab } from "react-bootstrap";
|
import { Table, Tabs, Tab } from "react-bootstrap";
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { useParams, useHistory } from "react-router-dom";
|
import { useParams, useHistory } from "react-router-dom";
|
||||||
@@ -27,7 +25,7 @@ import { StudioChildrenPanel } from "./StudioChildrenPanel";
|
|||||||
export const Studio: React.FC = () => {
|
export const Studio: React.FC = () => {
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const Toast = useToast();
|
const Toast = useToast();
|
||||||
const { id = "new" } = useParams();
|
const { tab = "details", id = "new" } = useParams();
|
||||||
const isNew = id === "new";
|
const isNew = id === "new";
|
||||||
|
|
||||||
// Editing state
|
// Editing state
|
||||||
@@ -192,6 +190,14 @@ export const Studio: React.FC = () => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const activeTabKey = tab === "childstudios" ? tab : "scenes";
|
||||||
|
const setActiveTabKey = (newTab: string) => {
|
||||||
|
if (tab !== newTab) {
|
||||||
|
const tabParam = newTab === "scenes" ? "" : `/${newTab}`;
|
||||||
|
history.replace(`/studios/${id}${tabParam}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div
|
<div
|
||||||
@@ -257,11 +263,17 @@ export const Studio: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
{!isNew && (
|
{!isNew && (
|
||||||
<div className="col col-md-8">
|
<div className="col col-md-8">
|
||||||
<Tabs id="studio-tabs" mountOnEnter>
|
<Tabs
|
||||||
<Tab eventKey="studio-scenes-panel" title="Scenes">
|
id="studio-tabs"
|
||||||
|
mountOnEnter
|
||||||
|
unmountOnExit
|
||||||
|
activeKey={activeTabKey}
|
||||||
|
onSelect={setActiveTabKey}
|
||||||
|
>
|
||||||
|
<Tab eventKey="scenes" title="Scenes">
|
||||||
<StudioScenesPanel studio={studio} />
|
<StudioScenesPanel studio={studio} />
|
||||||
</Tab>
|
</Tab>
|
||||||
<Tab eventKey="studio-children-panel" title="Child Studios">
|
<Tab eventKey="childstudios" title="Child Studios">
|
||||||
<StudioChildrenPanel studio={studio} />
|
<StudioChildrenPanel studio={studio} />
|
||||||
</Tab>
|
</Tab>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|||||||
@@ -41,5 +41,5 @@ export const StudioScenesPanel: React.FC<IStudioScenesPanel> = ({ studio }) => {
|
|||||||
return filter;
|
return filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
return <SceneList subComponent filterHook={filterHook} />;
|
return <SceneList filterHook={filterHook} />;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ export const StudioList: React.FC<IStudioList> = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const listData = useStudiosList({
|
const listData = useStudiosList({
|
||||||
renderContent,
|
renderContent,
|
||||||
subComponent: fromParent,
|
|
||||||
filterHook,
|
filterHook,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { StudioList } from "./StudioList";
|
|||||||
const Studios = () => (
|
const Studios = () => (
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route exact path="/studios" component={StudioList} />
|
<Route exact path="/studios" component={StudioList} />
|
||||||
<Route path="/studios/:id" component={Studio} />
|
<Route path="/studios/:id/:tab?" component={Studio} />
|
||||||
</Switch>
|
</Switch>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
/* eslint-disable react/no-this-in-sfc */
|
|
||||||
|
|
||||||
import { Table, Tabs, Tab } from "react-bootstrap";
|
import { Table, Tabs, Tab } from "react-bootstrap";
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { useParams, useHistory } from "react-router-dom";
|
import { useParams, useHistory } from "react-router-dom";
|
||||||
@@ -26,7 +24,7 @@ import { TagMarkersPanel } from "./TagMarkersPanel";
|
|||||||
export const Tag: React.FC = () => {
|
export const Tag: React.FC = () => {
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const Toast = useToast();
|
const Toast = useToast();
|
||||||
const { id = "new" } = useParams();
|
const { tab = "scenes", id = "new" } = useParams();
|
||||||
const isNew = id === "new";
|
const isNew = id === "new";
|
||||||
|
|
||||||
// Editing state
|
// Editing state
|
||||||
@@ -46,6 +44,14 @@ export const Tag: React.FC = () => {
|
|||||||
const [createTag] = useTagCreate(getTagInput() as GQL.TagUpdateInput);
|
const [createTag] = useTagCreate(getTagInput() as GQL.TagUpdateInput);
|
||||||
const [deleteTag] = useTagDestroy(getTagInput() as GQL.TagUpdateInput);
|
const [deleteTag] = useTagDestroy(getTagInput() as GQL.TagUpdateInput);
|
||||||
|
|
||||||
|
const activeTabKey = tab === "markers" ? tab : "scenes";
|
||||||
|
const setActiveTabKey = (newTab: string) => {
|
||||||
|
if (tab !== newTab) {
|
||||||
|
const tabParam = newTab === "scenes" ? "" : `/${newTab}`;
|
||||||
|
history.replace(`/tags/${id}${tabParam}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// set up hotkeys
|
// set up hotkeys
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isEditing) {
|
if (isEditing) {
|
||||||
@@ -222,11 +228,16 @@ export const Tag: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
{!isNew && (
|
{!isNew && (
|
||||||
<div className="col col-md-8">
|
<div className="col col-md-8">
|
||||||
<Tabs id="tag-tabs" mountOnEnter>
|
<Tabs
|
||||||
<Tab eventKey="tag-scenes-panel" title="Scenes">
|
id="tag-tabs"
|
||||||
|
mountOnEnter
|
||||||
|
activeKey={activeTabKey}
|
||||||
|
onSelect={setActiveTabKey}
|
||||||
|
>
|
||||||
|
<Tab eventKey="scenes" title="Scenes">
|
||||||
<TagScenesPanel tag={tag} />
|
<TagScenesPanel tag={tag} />
|
||||||
</Tab>
|
</Tab>
|
||||||
<Tab eventKey="tag-markers-panel" title="Markers">
|
<Tab eventKey="markers" title="Markers">
|
||||||
<TagMarkersPanel tag={tag} />
|
<TagMarkersPanel tag={tag} />
|
||||||
</Tab>
|
</Tab>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|||||||
@@ -41,5 +41,5 @@ export const TagMarkersPanel: React.FC<ITagMarkersPanel> = ({ tag }) => {
|
|||||||
return filter;
|
return filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
return <SceneMarkerList subComponent filterHook={filterHook} />;
|
return <SceneMarkerList filterHook={filterHook} />;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -41,5 +41,5 @@ export const TagScenesPanel: React.FC<ITagScenesPanel> = ({ tag }) => {
|
|||||||
return filter;
|
return filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
return <SceneList subComponent filterHook={filterHook} />;
|
return <SceneList filterHook={filterHook} />;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ export const TagList: React.FC<ITagList> = ({ filterHook }) => {
|
|||||||
filterHook,
|
filterHook,
|
||||||
zoomable: true,
|
zoomable: true,
|
||||||
defaultZoomIndex: 0,
|
defaultZoomIndex: 0,
|
||||||
|
persistState: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
function getDeleteTagInput() {
|
function getDeleteTagInput() {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { TagList } from "./TagList";
|
|||||||
const Tags = () => (
|
const Tags = () => (
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route exact path="/tags" component={TagList} />
|
<Route exact path="/tags" component={TagList} />
|
||||||
<Route path="/tags/:id" component={Tag} />
|
<Route path="/tags/:id/:tab?" component={Tag} />
|
||||||
</Switch>
|
</Switch>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import queryString from "query-string";
|
import queryString from "query-string";
|
||||||
import React, { useCallback, useState, useEffect } from "react";
|
import React, { useCallback, useRef, 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 {
|
||||||
@@ -59,7 +59,7 @@ interface IListHookOperation<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface IListHookOptions<T, E> {
|
interface IListHookOptions<T, E> {
|
||||||
subComponent?: boolean;
|
persistState?: boolean;
|
||||||
filterHook?: (filter: ListFilterModel) => ListFilterModel;
|
filterHook?: (filter: ListFilterModel) => ListFilterModel;
|
||||||
zoomable?: boolean;
|
zoomable?: boolean;
|
||||||
selectable?: boolean;
|
selectable?: boolean;
|
||||||
@@ -112,10 +112,7 @@ const useList = <QueryResult extends IQueryResult, QueryData extends IDataItem>(
|
|||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const [filter, setFilter] = useState<ListFilterModel>(
|
const [filter, setFilter] = useState<ListFilterModel>(
|
||||||
new ListFilterModel(
|
new ListFilterModel(options.filterMode, queryString.parse(location.search))
|
||||||
options.filterMode,
|
|
||||||
options.subComponent ? undefined : queryString.parse(location.search)
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
const [isEditDialogOpen, setIsEditDialogOpen] = useState(false);
|
const [isEditDialogOpen, setIsEditDialogOpen] = useState(false);
|
||||||
const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false);
|
const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false);
|
||||||
@@ -124,6 +121,8 @@ const useList = <QueryResult extends IQueryResult, QueryData extends IDataItem>(
|
|||||||
const [zoomIndex, setZoomIndex] = useState<number>(
|
const [zoomIndex, setZoomIndex] = useState<number>(
|
||||||
options.defaultZoomIndex ?? 1
|
options.defaultZoomIndex ?? 1
|
||||||
);
|
);
|
||||||
|
// Store initial pathname to prevent hooks from operating outside this page
|
||||||
|
const originalPathName = useRef(location.pathname);
|
||||||
|
|
||||||
const result = options.useData(getFilter());
|
const result = options.useData(getFilter());
|
||||||
const totalCount = options.getCount(result);
|
const totalCount = options.getCount(result);
|
||||||
@@ -194,11 +193,15 @@ const useList = <QueryResult extends IQueryResult, QueryData extends IDataItem>(
|
|||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (interfaceState.loading) return;
|
if (
|
||||||
|
interfaceState.loading ||
|
||||||
|
// Only update query params on page the hook was mounted on
|
||||||
|
history.location.pathname !== originalPathName.current
|
||||||
|
)
|
||||||
|
return;
|
||||||
if (!forageInitialised) setForageInitialised(true);
|
if (!forageInitialised) setForageInitialised(true);
|
||||||
|
|
||||||
// Don't use query parameters for sub-components
|
if (!options.persistState) return;
|
||||||
if (options.subComponent) return;
|
|
||||||
|
|
||||||
const storedQuery = interfaceState.data?.queries?.[options.filterMode];
|
const storedQuery = interfaceState.data?.queries?.[options.filterMode];
|
||||||
if (!storedQuery) return;
|
if (!storedQuery) return;
|
||||||
@@ -236,10 +239,10 @@ const useList = <QueryResult extends IQueryResult, QueryData extends IDataItem>(
|
|||||||
interfaceState.loading,
|
interfaceState.loading,
|
||||||
history,
|
history,
|
||||||
location.search,
|
location.search,
|
||||||
options.subComponent,
|
|
||||||
options.filterMode,
|
options.filterMode,
|
||||||
forageInitialised,
|
forageInitialised,
|
||||||
updateInterfaceConfig,
|
updateInterfaceConfig,
|
||||||
|
options.persistState,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
function getFilter() {
|
function getFilter() {
|
||||||
@@ -254,10 +257,10 @@ const useList = <QueryResult extends IQueryResult, QueryData extends IDataItem>(
|
|||||||
|
|
||||||
function updateQueryParams(listFilter: ListFilterModel) {
|
function updateQueryParams(listFilter: ListFilterModel) {
|
||||||
setFilter(listFilter);
|
setFilter(listFilter);
|
||||||
if (!options.subComponent) {
|
const newLocation = { ...location };
|
||||||
const newLocation = { ...location };
|
newLocation.search = listFilter.makeQueryParameters();
|
||||||
newLocation.search = listFilter.makeQueryParameters();
|
history.replace(newLocation);
|
||||||
history.replace(newLocation);
|
if (options.persistState) {
|
||||||
updateInterfaceConfig(listFilter);
|
updateInterfaceConfig(listFilter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -425,7 +428,6 @@ const useList = <QueryResult extends IQueryResult, QueryData extends IDataItem>(
|
|||||||
const template = (
|
const template = (
|
||||||
<div>
|
<div>
|
||||||
<ListFilter
|
<ListFilter
|
||||||
subComponent={options.subComponent}
|
|
||||||
onFilterUpdate={updateQueryParams}
|
onFilterUpdate={updateQueryParams}
|
||||||
onSelectAll={options.selectable ? onSelectAll : undefined}
|
onSelectAll={options.selectable ? onSelectAll : undefined}
|
||||||
onSelectNone={options.selectable ? onSelectNone : undefined}
|
onSelectNone={options.selectable ? onSelectNone : undefined}
|
||||||
|
|||||||
Reference in New Issue
Block a user