mirror of
https://github.com/stashapp/stash.git
synced 2025-12-17 20:34:37 +03:00
Fix various console errors and graphql loading issues (#760)
* Refactor listhook to resolve loading issues * Fix graphql loading race conditions * Various console spam * Fix scene card overlay hierarchy * Fix modal and manual borders
This commit is contained in:
@@ -38,6 +38,24 @@ import {
|
||||
import { ListFilterModel } from "src/models/list-filter/filter";
|
||||
import { FilterMode } from "src/models/list-filter/types";
|
||||
|
||||
const getSelectedData = <I extends IDataItem>(
|
||||
result: I[],
|
||||
selectedIds: Set<string>
|
||||
) => {
|
||||
// find the selected items from the ids
|
||||
const selectedResults: I[] = [];
|
||||
|
||||
selectedIds.forEach((id) => {
|
||||
const item = result.find((s) => s.id === id);
|
||||
|
||||
if (item) {
|
||||
selectedResults.push(item);
|
||||
}
|
||||
});
|
||||
|
||||
return selectedResults;
|
||||
};
|
||||
|
||||
interface IListHookData {
|
||||
filter: ListFilterModel;
|
||||
template: JSX.Element;
|
||||
@@ -99,34 +117,45 @@ interface IQuery<T extends IQueryResult, T2 extends IDataItem> {
|
||||
filterMode: FilterMode;
|
||||
useData: (filter: ListFilterModel) => T;
|
||||
getData: (data: T) => T2[];
|
||||
getSelectedData: (data: T, selectedIds: Set<string>) => T2[];
|
||||
getCount: (data: T) => number;
|
||||
}
|
||||
|
||||
const useList = <QueryResult extends IQueryResult, QueryData extends IDataItem>(
|
||||
options: IListHookOptions<QueryResult, QueryData> &
|
||||
IQuery<QueryResult, QueryData>
|
||||
): IListHookData => {
|
||||
const [interfaceState, setInterfaceState] = useInterfaceLocalForage();
|
||||
const [forageInitialised, setForageInitialised] = useState(false);
|
||||
const history = useHistory();
|
||||
const location = useLocation();
|
||||
const [filter, setFilter] = useState<ListFilterModel>(
|
||||
new ListFilterModel(options.filterMode, queryString.parse(location.search))
|
||||
);
|
||||
interface IRenderListProps {
|
||||
filter: ListFilterModel;
|
||||
onChangePage: (page: number) => void;
|
||||
updateQueryParams: (filter: ListFilterModel) => void;
|
||||
}
|
||||
|
||||
const RenderList = <
|
||||
QueryResult extends IQueryResult,
|
||||
QueryData extends IDataItem
|
||||
>({
|
||||
defaultZoomIndex,
|
||||
filter,
|
||||
onChangePage,
|
||||
addKeybinds,
|
||||
useData,
|
||||
getCount,
|
||||
getData,
|
||||
otherOperations,
|
||||
renderContent,
|
||||
zoomable,
|
||||
selectable,
|
||||
renderEditDialog,
|
||||
renderDeleteDialog,
|
||||
updateQueryParams,
|
||||
}: IListHookOptions<QueryResult, QueryData> &
|
||||
IQuery<QueryResult, QueryData> &
|
||||
IRenderListProps) => {
|
||||
const [isEditDialogOpen, setIsEditDialogOpen] = useState(false);
|
||||
const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false);
|
||||
const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set());
|
||||
const [lastClickedId, setLastClickedId] = useState<string | undefined>();
|
||||
const [zoomIndex, setZoomIndex] = useState<number>(
|
||||
options.defaultZoomIndex ?? 1
|
||||
);
|
||||
// Store initial pathname to prevent hooks from operating outside this page
|
||||
const originalPathName = useRef(location.pathname);
|
||||
const [zoomIndex, setZoomIndex] = useState<number>(defaultZoomIndex ?? 1);
|
||||
|
||||
const result = options.useData(getFilter());
|
||||
const totalCount = options.getCount(result);
|
||||
const items = options.getData(result);
|
||||
const result = useData(filter);
|
||||
const totalCount = getCount(result);
|
||||
const items = getData(result);
|
||||
|
||||
useEffect(() => {
|
||||
Mousetrap.bind("right", () => {
|
||||
@@ -140,7 +169,6 @@ const useList = <QueryResult extends IQueryResult, QueryData extends IDataItem>(
|
||||
onChangePage(filter.currentPage - 1);
|
||||
}
|
||||
});
|
||||
|
||||
Mousetrap.bind("shift+right", () => {
|
||||
const maxPage = totalCount / filter.itemsPerPage + 1;
|
||||
onChangePage(Math.min(maxPage, filter.currentPage + 10));
|
||||
@@ -157,8 +185,8 @@ const useList = <QueryResult extends IQueryResult, QueryData extends IDataItem>(
|
||||
});
|
||||
|
||||
let unbindExtras: () => void;
|
||||
if (options.addKeybinds) {
|
||||
unbindExtras = options.addKeybinds(result, filter, selectedIds);
|
||||
if (addKeybinds) {
|
||||
unbindExtras = addKeybinds(result, filter, selectedIds);
|
||||
}
|
||||
|
||||
return () => {
|
||||
@@ -175,102 +203,6 @@ const useList = <QueryResult extends IQueryResult, QueryData extends IDataItem>(
|
||||
};
|
||||
});
|
||||
|
||||
const updateInterfaceConfig = useCallback(
|
||||
(updatedFilter: ListFilterModel) => {
|
||||
setInterfaceState((config) => {
|
||||
const data = { ...config } as IInterfaceConfig;
|
||||
data.queries = {
|
||||
[options.filterMode]: {
|
||||
filter: updatedFilter.makeQueryParameters(),
|
||||
itemsPerPage: updatedFilter.itemsPerPage,
|
||||
currentPage: updatedFilter.currentPage,
|
||||
},
|
||||
};
|
||||
return data;
|
||||
});
|
||||
},
|
||||
[options.filterMode, setInterfaceState]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
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 (!options.persistState) return;
|
||||
|
||||
const storedQuery = interfaceState.data?.queries?.[options.filterMode];
|
||||
if (!storedQuery) return;
|
||||
|
||||
const queryFilter = queryString.parse(history.location.search);
|
||||
const storedFilter = queryString.parse(storedQuery.filter);
|
||||
const query = history.location.search
|
||||
? {
|
||||
sortby: storedFilter.sortby,
|
||||
sortdir: storedFilter.sortdir,
|
||||
disp: storedFilter.disp,
|
||||
perPage: storedFilter.perPage,
|
||||
...queryFilter,
|
||||
}
|
||||
: storedFilter;
|
||||
|
||||
const newFilter = new ListFilterModel(options.filterMode, query);
|
||||
|
||||
// Compare constructed filter with current filter.
|
||||
// If different it's the result of navigation, and we update the filter.
|
||||
const newLocation = { ...history.location };
|
||||
newLocation.search = newFilter.makeQueryParameters();
|
||||
if (newLocation.search !== filter.makeQueryParameters()) {
|
||||
setFilter(newFilter);
|
||||
updateInterfaceConfig(newFilter);
|
||||
}
|
||||
// If constructed search is different from current, update it as well
|
||||
if (newLocation.search !== location.search) {
|
||||
newLocation.search = newFilter.makeQueryParameters();
|
||||
history.replace(newLocation);
|
||||
}
|
||||
}, [
|
||||
filter,
|
||||
interfaceState.data,
|
||||
interfaceState.loading,
|
||||
history,
|
||||
location.search,
|
||||
options.filterMode,
|
||||
forageInitialised,
|
||||
updateInterfaceConfig,
|
||||
options.persistState,
|
||||
]);
|
||||
|
||||
function getFilter() {
|
||||
if (!options.filterHook) {
|
||||
return filter;
|
||||
}
|
||||
|
||||
// make a copy of the filter and call the hook
|
||||
const newFilter = _.cloneDeep(filter);
|
||||
return options.filterHook(newFilter);
|
||||
}
|
||||
|
||||
function updateQueryParams(listFilter: ListFilterModel) {
|
||||
setFilter(listFilter);
|
||||
const newLocation = { ...location };
|
||||
newLocation.search = listFilter.makeQueryParameters();
|
||||
history.replace(newLocation);
|
||||
if (options.persistState) {
|
||||
updateInterfaceConfig(listFilter);
|
||||
}
|
||||
}
|
||||
|
||||
function onChangePage(page: number) {
|
||||
const newFilter = _.cloneDeep(filter);
|
||||
newFilter.currentPage = page;
|
||||
updateQueryParams(newFilter);
|
||||
}
|
||||
|
||||
function singleSelect(id: string, selected: boolean) {
|
||||
setLastClickedId(id);
|
||||
|
||||
@@ -348,54 +280,21 @@ const useList = <QueryResult extends IQueryResult, QueryData extends IDataItem>(
|
||||
setZoomIndex(newZoomIndex);
|
||||
}
|
||||
|
||||
const otherOperations = options.otherOperations
|
||||
? options.otherOperations.map((o) => {
|
||||
return {
|
||||
text: o.text,
|
||||
onClick: () => {
|
||||
o.onClick(result, filter, selectedIds);
|
||||
},
|
||||
isDisplayed: () => {
|
||||
if (o.isDisplayed) {
|
||||
return o.isDisplayed(result, filter, selectedIds);
|
||||
}
|
||||
const operations =
|
||||
otherOperations &&
|
||||
otherOperations.map((o) => ({
|
||||
text: o.text,
|
||||
onClick: () => {
|
||||
o.onClick(result, filter, selectedIds);
|
||||
},
|
||||
isDisplayed: () => {
|
||||
if (o.isDisplayed) {
|
||||
return o.isDisplayed(result, filter, selectedIds);
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
};
|
||||
})
|
||||
: undefined;
|
||||
|
||||
function maybeRenderContent() {
|
||||
if (!result.loading && !result.error) {
|
||||
return options.renderContent(result, filter, selectedIds, zoomIndex);
|
||||
}
|
||||
}
|
||||
|
||||
function maybeRenderPaginationIndex() {
|
||||
if (!result.loading && !result.error) {
|
||||
return (
|
||||
<PaginationIndex
|
||||
itemsPerPage={filter.itemsPerPage}
|
||||
currentPage={filter.currentPage}
|
||||
totalItems={totalCount}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function maybeRenderPagination() {
|
||||
if (!result.loading && !result.error) {
|
||||
return (
|
||||
<Pagination
|
||||
itemsPerPage={filter.itemsPerPage}
|
||||
currentPage={filter.currentPage}
|
||||
totalItems={totalCount}
|
||||
onChangePage={onChangePage}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
}));
|
||||
|
||||
function onEdit() {
|
||||
setIsEditDialogOpen(true);
|
||||
@@ -425,60 +324,189 @@ const useList = <QueryResult extends IQueryResult, QueryData extends IDataItem>(
|
||||
result.refetch();
|
||||
}
|
||||
|
||||
const template = (
|
||||
<div>
|
||||
<ListFilter
|
||||
onFilterUpdate={updateQueryParams}
|
||||
onSelectAll={options.selectable ? onSelectAll : undefined}
|
||||
onSelectNone={options.selectable ? onSelectNone : undefined}
|
||||
zoomIndex={options.zoomable ? zoomIndex : undefined}
|
||||
onChangeZoom={options.zoomable ? onChangeZoom : undefined}
|
||||
otherOperations={otherOperations}
|
||||
itemsSelected={selectedIds.size > 0}
|
||||
onEdit={options.renderEditDialog ? onEdit : undefined}
|
||||
onDelete={options.renderDeleteDialog ? onDelete : undefined}
|
||||
filter={filter}
|
||||
/>
|
||||
{isEditDialogOpen && options.renderEditDialog
|
||||
? options.renderEditDialog(
|
||||
options.getSelectedData(result, selectedIds),
|
||||
(applied) => onEditDialogClosed(applied)
|
||||
)
|
||||
: undefined}
|
||||
{isDeleteDialogOpen && options.renderDeleteDialog
|
||||
? options.renderDeleteDialog(
|
||||
options.getSelectedData(result, selectedIds),
|
||||
(deleted) => onDeleteDialogClosed(deleted)
|
||||
)
|
||||
: undefined}
|
||||
{(result.loading || !forageInitialised) && <LoadingIndicator />}
|
||||
{result.error && <h1>{result.error.message}</h1>}
|
||||
{maybeRenderPagination()}
|
||||
{maybeRenderContent()}
|
||||
{maybeRenderPaginationIndex()}
|
||||
{maybeRenderPagination()}
|
||||
</div>
|
||||
const renderPagination = () => (
|
||||
<Pagination
|
||||
itemsPerPage={filter.itemsPerPage}
|
||||
currentPage={filter.currentPage}
|
||||
totalItems={totalCount}
|
||||
onChangePage={onChangePage}
|
||||
/>
|
||||
);
|
||||
|
||||
return { filter, template, onSelectChange };
|
||||
let content;
|
||||
if (result.loading) {
|
||||
content = <LoadingIndicator />;
|
||||
} else if (result.error) {
|
||||
content = <h1>{result.error.message}</h1>;
|
||||
} else {
|
||||
content = (
|
||||
<div>
|
||||
<ListFilter
|
||||
onFilterUpdate={updateQueryParams}
|
||||
onSelectAll={selectable ? onSelectAll : undefined}
|
||||
onSelectNone={selectable ? onSelectNone : undefined}
|
||||
zoomIndex={zoomable ? zoomIndex : undefined}
|
||||
onChangeZoom={zoomable ? onChangeZoom : undefined}
|
||||
otherOperations={operations}
|
||||
itemsSelected={selectedIds.size > 0}
|
||||
onEdit={renderEditDialog ? onEdit : undefined}
|
||||
onDelete={renderDeleteDialog ? onDelete : undefined}
|
||||
filter={filter}
|
||||
/>
|
||||
{isEditDialogOpen &&
|
||||
renderEditDialog &&
|
||||
renderEditDialog(
|
||||
getSelectedData(getData(result), selectedIds),
|
||||
(applied) => onEditDialogClosed(applied)
|
||||
)}
|
||||
{isDeleteDialogOpen &&
|
||||
renderDeleteDialog &&
|
||||
renderDeleteDialog(
|
||||
getSelectedData(getData(result), selectedIds),
|
||||
(deleted) => onDeleteDialogClosed(deleted)
|
||||
)}
|
||||
{renderPagination()}
|
||||
{renderContent(result, filter, selectedIds, zoomIndex)}
|
||||
<PaginationIndex
|
||||
itemsPerPage={filter.itemsPerPage}
|
||||
currentPage={filter.currentPage}
|
||||
totalItems={totalCount}
|
||||
/>
|
||||
{renderPagination()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return { contentTemplate: content, onSelectChange };
|
||||
};
|
||||
|
||||
const getSelectedData = <I extends IDataItem>(
|
||||
result: I[],
|
||||
selectedIds: Set<string>
|
||||
) => {
|
||||
// find the selected items from the ids
|
||||
const selectedResults: I[] = [];
|
||||
const useList = <QueryResult extends IQueryResult, QueryData extends IDataItem>(
|
||||
options: IListHookOptions<QueryResult, QueryData> &
|
||||
IQuery<QueryResult, QueryData>
|
||||
): IListHookData => {
|
||||
const history = useHistory();
|
||||
const location = useLocation();
|
||||
const [interfaceState, setInterfaceState] = useInterfaceLocalForage();
|
||||
// If persistState is false we don't care about forage and consider it initialised
|
||||
const [forageInitialised, setForageInitialised] = useState(
|
||||
!options.persistState
|
||||
);
|
||||
// Store initial pathname to prevent hooks from operating outside this page
|
||||
const originalPathName = useRef(location.pathname);
|
||||
|
||||
selectedIds.forEach((id) => {
|
||||
const item = result.find((s) => s.id === id);
|
||||
const [filter, setFilter] = useState<ListFilterModel>(
|
||||
new ListFilterModel(options.filterMode, queryString.parse(location.search))
|
||||
);
|
||||
|
||||
if (item) {
|
||||
selectedResults.push(item);
|
||||
const updateInterfaceConfig = useCallback(
|
||||
(updatedFilter: ListFilterModel) => {
|
||||
setInterfaceState((config) => {
|
||||
const data = { ...config } as IInterfaceConfig;
|
||||
data.queries = {
|
||||
[options.filterMode]: {
|
||||
filter: updatedFilter.makeQueryParameters(),
|
||||
itemsPerPage: updatedFilter.itemsPerPage,
|
||||
currentPage: updatedFilter.currentPage,
|
||||
},
|
||||
};
|
||||
return data;
|
||||
});
|
||||
},
|
||||
[options.filterMode, setInterfaceState]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
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 (!options.persistState) return;
|
||||
|
||||
const storedQuery = interfaceState.data?.queries?.[options.filterMode];
|
||||
if (!storedQuery) return;
|
||||
|
||||
const queryFilter = queryString.parse(history.location.search);
|
||||
const storedFilter = queryString.parse(storedQuery.filter);
|
||||
const query = history.location.search
|
||||
? {
|
||||
sortby: storedFilter.sortby,
|
||||
sortdir: storedFilter.sortdir,
|
||||
disp: storedFilter.disp,
|
||||
perPage: storedFilter.perPage,
|
||||
...queryFilter,
|
||||
}
|
||||
: storedFilter;
|
||||
|
||||
const newFilter = new ListFilterModel(options.filterMode, query);
|
||||
|
||||
// Compare constructed filter with current filter.
|
||||
// If different it's the result of navigation, and we update the filter.
|
||||
const newLocation = { ...history.location };
|
||||
newLocation.search = newFilter.makeQueryParameters();
|
||||
if (newLocation.search !== filter.makeQueryParameters()) {
|
||||
setFilter(newFilter);
|
||||
updateInterfaceConfig(newFilter);
|
||||
}
|
||||
// If constructed search is different from current, update it as well
|
||||
if (newLocation.search !== location.search) {
|
||||
newLocation.search = newFilter.makeQueryParameters();
|
||||
history.replace(newLocation);
|
||||
}
|
||||
}, [
|
||||
filter,
|
||||
interfaceState.data,
|
||||
interfaceState.loading,
|
||||
history,
|
||||
location.search,
|
||||
options.filterMode,
|
||||
forageInitialised,
|
||||
updateInterfaceConfig,
|
||||
options.persistState,
|
||||
]);
|
||||
|
||||
function updateQueryParams(listFilter: ListFilterModel) {
|
||||
setFilter(listFilter);
|
||||
const newLocation = { ...location };
|
||||
newLocation.search = listFilter.makeQueryParameters();
|
||||
history.replace(newLocation);
|
||||
if (options.persistState) {
|
||||
updateInterfaceConfig(listFilter);
|
||||
}
|
||||
}
|
||||
|
||||
const onChangePage = (page: number) => {
|
||||
const newFilter = _.cloneDeep(filter);
|
||||
newFilter.currentPage = page;
|
||||
updateQueryParams(newFilter);
|
||||
};
|
||||
|
||||
const renderFilter = !options.filterHook
|
||||
? filter
|
||||
: options.filterHook(_.cloneDeep(filter));
|
||||
|
||||
const { contentTemplate, onSelectChange } = RenderList({
|
||||
...options,
|
||||
filter: renderFilter,
|
||||
onChangePage,
|
||||
updateQueryParams,
|
||||
});
|
||||
|
||||
return selectedResults;
|
||||
const template = !forageInitialised ? (
|
||||
<LoadingIndicator />
|
||||
) : (
|
||||
<>{contentTemplate}</>
|
||||
);
|
||||
|
||||
return {
|
||||
filter,
|
||||
template,
|
||||
onSelectChange,
|
||||
};
|
||||
};
|
||||
|
||||
export const useScenesList = (
|
||||
@@ -492,10 +520,6 @@ export const useScenesList = (
|
||||
result?.data?.findScenes?.scenes ?? [],
|
||||
getCount: (result: FindScenesQueryResult) =>
|
||||
result?.data?.findScenes?.count ?? 0,
|
||||
getSelectedData: (
|
||||
result: FindScenesQueryResult,
|
||||
selectedIds: Set<string>
|
||||
) => getSelectedData(result?.data?.findScenes?.scenes ?? [], selectedIds),
|
||||
});
|
||||
|
||||
export const useSceneMarkersList = (
|
||||
@@ -509,14 +533,6 @@ export const useSceneMarkersList = (
|
||||
result?.data?.findSceneMarkers?.scene_markers ?? [],
|
||||
getCount: (result: FindSceneMarkersQueryResult) =>
|
||||
result?.data?.findSceneMarkers?.count ?? 0,
|
||||
getSelectedData: (
|
||||
result: FindSceneMarkersQueryResult,
|
||||
selectedIds: Set<string>
|
||||
) =>
|
||||
getSelectedData(
|
||||
result?.data?.findSceneMarkers?.scene_markers ?? [],
|
||||
selectedIds
|
||||
),
|
||||
});
|
||||
|
||||
export const useGalleriesList = (
|
||||
@@ -530,14 +546,6 @@ export const useGalleriesList = (
|
||||
result?.data?.findGalleries?.galleries ?? [],
|
||||
getCount: (result: FindGalleriesQueryResult) =>
|
||||
result?.data?.findGalleries?.count ?? 0,
|
||||
getSelectedData: (
|
||||
result: FindGalleriesQueryResult,
|
||||
selectedIds: Set<string>
|
||||
) =>
|
||||
getSelectedData(
|
||||
result?.data?.findGalleries?.galleries ?? [],
|
||||
selectedIds
|
||||
),
|
||||
});
|
||||
|
||||
export const useStudiosList = (
|
||||
@@ -551,10 +559,6 @@ export const useStudiosList = (
|
||||
result?.data?.findStudios?.studios ?? [],
|
||||
getCount: (result: FindStudiosQueryResult) =>
|
||||
result?.data?.findStudios?.count ?? 0,
|
||||
getSelectedData: (
|
||||
result: FindStudiosQueryResult,
|
||||
selectedIds: Set<string>
|
||||
) => getSelectedData(result?.data?.findStudios?.studios ?? [], selectedIds),
|
||||
});
|
||||
|
||||
export const usePerformersList = (
|
||||
@@ -568,14 +572,6 @@ export const usePerformersList = (
|
||||
result?.data?.findPerformers?.performers ?? [],
|
||||
getCount: (result: FindPerformersQueryResult) =>
|
||||
result?.data?.findPerformers?.count ?? 0,
|
||||
getSelectedData: (
|
||||
result: FindPerformersQueryResult,
|
||||
selectedIds: Set<string>
|
||||
) =>
|
||||
getSelectedData(
|
||||
result?.data?.findPerformers?.performers ?? [],
|
||||
selectedIds
|
||||
),
|
||||
});
|
||||
|
||||
export const useMoviesList = (
|
||||
@@ -589,10 +585,6 @@ export const useMoviesList = (
|
||||
result?.data?.findMovies?.movies ?? [],
|
||||
getCount: (result: FindMoviesQueryResult) =>
|
||||
result?.data?.findMovies?.count ?? 0,
|
||||
getSelectedData: (
|
||||
result: FindMoviesQueryResult,
|
||||
selectedIds: Set<string>
|
||||
) => getSelectedData(result?.data?.findMovies?.movies ?? [], selectedIds),
|
||||
});
|
||||
|
||||
export const useTagsList = (
|
||||
@@ -606,13 +598,11 @@ export const useTagsList = (
|
||||
result?.data?.findTags?.tags ?? [],
|
||||
getCount: (result: FindTagsQueryResult) =>
|
||||
result?.data?.findTags?.count ?? 0,
|
||||
getSelectedData: (result: FindTagsQueryResult, selectedIds: Set<string>) =>
|
||||
getSelectedData(result?.data?.findTags?.tags ?? [], selectedIds),
|
||||
});
|
||||
|
||||
export const showWhenSelected = (
|
||||
result: FindScenesQueryResult,
|
||||
filter: ListFilterModel,
|
||||
_result: FindScenesQueryResult,
|
||||
_filter: ListFilterModel,
|
||||
selectedIds: Set<string>
|
||||
) => {
|
||||
return selectedIds.size > 0;
|
||||
|
||||
Reference in New Issue
Block a user