Refactor scrape dialog (#4069)

* Fix performer select showing blank values after scrape
* Move and separate scrape dialog
* Separate row components from scene scrape dialog
* Refactor object creation
* Refactor gallery scrape dialog
This commit is contained in:
WithoutPants
2023-09-01 09:59:06 +10:00
committed by GitHub
parent 8abb3c0d08
commit fca162f1ca
12 changed files with 724 additions and 829 deletions

View File

@@ -0,0 +1,269 @@
import React, { useMemo } from "react";
import * as GQL from "src/core/generated-graphql";
import {
MovieSelect,
TagSelect,
StudioSelect,
} from "src/components/Shared/Select";
import {
ScrapeDialogRow,
IHasName,
} from "src/components/Shared/ScrapeDialog/ScrapeDialog";
import { PerformerSelect } from "src/components/Performers/PerformerSelect";
import { ScrapeResult } from "src/components/Shared/ScrapeDialog/scrapeResult";
interface IScrapedStudioRow {
title: string;
result: ScrapeResult<string>;
onChange: (value: ScrapeResult<string>) => void;
newStudio?: GQL.ScrapedStudio;
onCreateNew?: (value: GQL.ScrapedStudio) => void;
}
export const ScrapedStudioRow: React.FC<IScrapedStudioRow> = ({
title,
result,
onChange,
newStudio,
onCreateNew,
}) => {
function renderScrapedStudio(
scrapeResult: ScrapeResult<string>,
isNew?: boolean,
onChangeFn?: (value: string) => void
) {
const resultValue = isNew
? scrapeResult.newValue
: scrapeResult.originalValue;
const value = resultValue ? [resultValue] : [];
return (
<StudioSelect
className="form-control react-select"
isDisabled={!isNew}
onSelect={(items) => {
if (onChangeFn) {
onChangeFn(items[0]?.id);
}
}}
ids={value}
/>
);
}
return (
<ScrapeDialogRow
title={title}
result={result}
renderOriginalField={() => renderScrapedStudio(result)}
renderNewField={() =>
renderScrapedStudio(result, true, (value) =>
onChange(result.cloneWithValue(value))
)
}
onChange={onChange}
newValues={newStudio ? [newStudio] : undefined}
onCreateNew={() => {
if (onCreateNew && newStudio) onCreateNew(newStudio);
}}
/>
);
};
interface IScrapedObjectsRow<T, R> {
title: string;
result: ScrapeResult<R[]>;
onChange: (value: ScrapeResult<R[]>) => void;
newObjects?: T[];
onCreateNew?: (value: T) => void;
renderObjects: (
result: ScrapeResult<R[]>,
isNew?: boolean,
onChange?: (value: R[]) => void
) => JSX.Element;
}
export const ScrapedObjectsRow = <T extends IHasName, R>(
props: IScrapedObjectsRow<T, R>
) => {
const { title, result, onChange, newObjects, onCreateNew, renderObjects } =
props;
return (
<ScrapeDialogRow
title={title}
result={result}
renderOriginalField={() => renderObjects(result)}
renderNewField={() =>
renderObjects(result, true, (value) =>
onChange(result.cloneWithValue(value))
)
}
onChange={onChange}
newValues={newObjects}
onCreateNew={(i) => {
if (onCreateNew) onCreateNew(newObjects![i]);
}}
/>
);
};
type IScrapedObjectRowImpl<T, R> = Omit<
IScrapedObjectsRow<T, R>,
"renderObjects"
>;
export const ScrapedPerformersRow: React.FC<
IScrapedObjectRowImpl<GQL.ScrapedPerformer, GQL.ScrapedPerformer>
> = ({ title, result, onChange, newObjects, onCreateNew }) => {
const performersCopy = useMemo(() => {
return (
newObjects?.map((p) => {
const name: string = p.name ?? "";
return { ...p, name };
}) ?? []
);
}, [newObjects]);
function renderScrapedPerformers(
scrapeResult: ScrapeResult<GQL.ScrapedPerformer[]>,
isNew?: boolean,
onChangeFn?: (value: GQL.ScrapedPerformer[]) => void
) {
const resultValue = isNew
? scrapeResult.newValue
: scrapeResult.originalValue;
const value = resultValue ?? [];
const selectValue = value.map((p) => {
const alias_list: string[] = [];
return {
id: p.stored_id ?? "",
name: p.name ?? "",
alias_list,
};
});
return (
<PerformerSelect
isMulti
className="form-control react-select"
isDisabled={!isNew}
onSelect={(items) => {
if (onChangeFn) {
onChangeFn(items);
}
}}
values={selectValue}
/>
);
}
type PerformerType = GQL.ScrapedPerformer & {
name: string;
};
return (
<ScrapedObjectsRow<PerformerType, GQL.ScrapedPerformer>
title={title}
result={result}
renderObjects={renderScrapedPerformers}
onChange={onChange}
newObjects={performersCopy}
onCreateNew={onCreateNew}
/>
);
};
export const ScrapedMoviesRow: React.FC<
IScrapedObjectRowImpl<GQL.ScrapedMovie, string>
> = ({ title, result, onChange, newObjects, onCreateNew }) => {
const moviesCopy = useMemo(() => {
return (
newObjects?.map((p) => {
const name: string = p.name ?? "";
return { ...p, name };
}) ?? []
);
}, [newObjects]);
type MovieType = GQL.ScrapedMovie & {
name: string;
};
function renderScrapedMovies(
scrapeResult: ScrapeResult<string[]>,
isNew?: boolean,
onChangeFn?: (value: string[]) => void
) {
const resultValue = isNew
? scrapeResult.newValue
: scrapeResult.originalValue;
const value = resultValue ?? [];
return (
<MovieSelect
isMulti
className="form-control react-select"
isDisabled={!isNew}
onSelect={(items) => {
if (onChangeFn) {
onChangeFn(items.map((i) => i.id));
}
}}
ids={value}
/>
);
}
return (
<ScrapedObjectsRow<MovieType, string>
title={title}
result={result}
renderObjects={renderScrapedMovies}
onChange={onChange}
newObjects={moviesCopy}
onCreateNew={onCreateNew}
/>
);
};
export const ScrapedTagsRow: React.FC<
IScrapedObjectRowImpl<GQL.ScrapedTag, string>
> = ({ title, result, onChange, newObjects, onCreateNew }) => {
function renderScrapedTags(
scrapeResult: ScrapeResult<string[]>,
isNew?: boolean,
onChangeFn?: (value: string[]) => void
) {
const resultValue = isNew
? scrapeResult.newValue
: scrapeResult.originalValue;
const value = resultValue ?? [];
return (
<TagSelect
isMulti
className="form-control react-select"
isDisabled={!isNew}
onSelect={(items) => {
if (onChangeFn) {
onChangeFn(items.map((i) => i.id));
}
}}
ids={value}
/>
);
}
return (
<ScrapedObjectsRow<GQL.ScrapedTag, string>
title={title}
result={result}
renderObjects={renderScrapedTags}
onChange={onChange}
newObjects={newObjects}
onCreateNew={onCreateNew}
/>
);
};