🔍 CV search metadata wrangling
This commit is contained in:
@@ -21,13 +21,15 @@ export const Dashboard = (): ReactElement => {
|
||||
limit: 5,
|
||||
sort: { updatedAt: "-1" },
|
||||
},
|
||||
predicate: { "acquisition.source.wanted": false },
|
||||
predicate: {
|
||||
wanted: { $exists: false },
|
||||
},
|
||||
comicStatus: "recent",
|
||||
},
|
||||
}),
|
||||
queryKey: ["recentComics"],
|
||||
});
|
||||
|
||||
// Wanted Comics
|
||||
const { data: wantedComics } = useQuery({
|
||||
queryFn: async () =>
|
||||
await axios({
|
||||
@@ -39,7 +41,9 @@ export const Dashboard = (): ReactElement => {
|
||||
limit: 5,
|
||||
sort: { updatedAt: "-1" },
|
||||
},
|
||||
predicate: { "acquisition.source.wanted": true },
|
||||
predicate: {
|
||||
wanted: { $exists: true, $ne: null },
|
||||
},
|
||||
},
|
||||
}),
|
||||
queryKey: ["wantedComics"],
|
||||
|
||||
@@ -18,6 +18,7 @@ type RecentlyImportedProps = {
|
||||
export const RecentlyImported = (
|
||||
comics: RecentlyImportedProps,
|
||||
): ReactElement => {
|
||||
console.log(comics);
|
||||
return (
|
||||
<div>
|
||||
<Header
|
||||
@@ -33,9 +34,7 @@ export const RecentlyImported = (
|
||||
rawFileDetails,
|
||||
sourcedMetadata: { comicvine, comicInfo, locg },
|
||||
inferredMetadata,
|
||||
acquisition: {
|
||||
source: { name },
|
||||
},
|
||||
wanted: { source } = {},
|
||||
},
|
||||
idx,
|
||||
) => {
|
||||
@@ -45,11 +44,14 @@ export const RecentlyImported = (
|
||||
comicInfo,
|
||||
locg,
|
||||
});
|
||||
const { issue, coverURL, icon } = determineExternalMetadata(name, {
|
||||
comicvine,
|
||||
comicInfo,
|
||||
locg,
|
||||
});
|
||||
const { issue, coverURL, icon } = determineExternalMetadata(
|
||||
source,
|
||||
{
|
||||
comicvine,
|
||||
comicInfo,
|
||||
locg,
|
||||
},
|
||||
);
|
||||
const isComicVineMetadataAvailable =
|
||||
!isUndefined(comicvine) &&
|
||||
!isUndefined(comicvine.volumeInformation);
|
||||
|
||||
@@ -31,10 +31,9 @@ export const WantedComicsList = ({
|
||||
_id,
|
||||
rawFileDetails,
|
||||
sourcedMetadata: { comicvine, comicInfo, locg },
|
||||
wanted,
|
||||
}) => {
|
||||
const isComicBookMetadataAvailable =
|
||||
!isUndefined(comicvine) &&
|
||||
!isUndefined(comicvine.volumeInformation);
|
||||
const isComicBookMetadataAvailable = !isUndefined(comicvine);
|
||||
const consolidatedComicMetadata = {
|
||||
rawFileDetails,
|
||||
comicvine,
|
||||
@@ -42,12 +41,15 @@ export const WantedComicsList = ({
|
||||
locg,
|
||||
};
|
||||
|
||||
const { issueName, url } = determineCoverFile(
|
||||
consolidatedComicMetadata,
|
||||
);
|
||||
const {
|
||||
issueName,
|
||||
url,
|
||||
publisher = null,
|
||||
} = determineCoverFile(consolidatedComicMetadata);
|
||||
const titleElement = (
|
||||
<Link to={"/comic/details/" + _id}>
|
||||
{ellipsize(issueName, 20)}
|
||||
<p>{publisher}</p>
|
||||
</Link>
|
||||
);
|
||||
return (
|
||||
@@ -61,9 +63,7 @@ export const WantedComicsList = ({
|
||||
<div className="pb-1">
|
||||
{/* Issue type */}
|
||||
{isComicBookMetadataAvailable &&
|
||||
!isNil(
|
||||
detectIssueTypes(comicvine.volumeInformation.description),
|
||||
) ? (
|
||||
!isNil(detectIssueTypes(comicvine.description)) ? (
|
||||
<div className="my-2">
|
||||
<span className="inline-flex items-center bg-slate-50 text-slate-800 text-xs font-medium px-2.5 py-0.5 rounded-md dark:text-slate-900 dark:bg-slate-400">
|
||||
<span className="pr-1 pt-1">
|
||||
@@ -71,11 +71,7 @@ export const WantedComicsList = ({
|
||||
</span>
|
||||
|
||||
<span className="text-md text-slate-500 dark:text-slate-900">
|
||||
{
|
||||
detectIssueTypes(
|
||||
comicvine.volumeInformation.description,
|
||||
).displayName
|
||||
}
|
||||
{detectIssueTypes(comicvine.description).displayName}
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -49,7 +49,7 @@ export const Search = ({}: ISearchProps): ReactElement => {
|
||||
limit: "10",
|
||||
offset: "0",
|
||||
field_list:
|
||||
"id,name,deck,api_detail_url,image,description,volume,cover_date,start_year,count_of_issues",
|
||||
"id,name,deck,api_detail_url,image,description,volume,cover_date,start_year,count_of_issues,publisher",
|
||||
resources: resource,
|
||||
},
|
||||
});
|
||||
@@ -57,17 +57,49 @@ export const Search = ({}: ISearchProps): ReactElement => {
|
||||
});
|
||||
|
||||
// add to library
|
||||
const { data: additionResult } = useQuery({
|
||||
queryFn: async () =>
|
||||
await axios({
|
||||
const { data: additionResult, mutate: addToWantedList } = useMutation({
|
||||
mutationFn: async ({
|
||||
source,
|
||||
comicObject,
|
||||
markEntireVolumeWanted,
|
||||
resourceType,
|
||||
}) => {
|
||||
console.log("jigni", comicObject);
|
||||
let volumeInformation = {};
|
||||
let issues = [];
|
||||
switch (resourceType) {
|
||||
case "issue":
|
||||
const { id, api_detail_url, image } = comicObject;
|
||||
// Add issue metadata
|
||||
issues.push({ id, api_detail_url, image });
|
||||
// Get volume metadata from CV
|
||||
console.log("volume", comicObject.volume.id);
|
||||
const response = await axios({
|
||||
url: `${COMICVINE_SERVICE_URI}/getVolumes`,
|
||||
method: "POST",
|
||||
data: {
|
||||
volumeURI: comicObject.volume.api_detail_url,
|
||||
fieldList:
|
||||
"id,name,deck,api_detail_url,image,description,start_year,count_of_issues,publisher,first_issue,last_issue",
|
||||
},
|
||||
});
|
||||
console.log("boogie", response.data);
|
||||
volumeInformation = response.data?.results;
|
||||
break;
|
||||
|
||||
case "volume":
|
||||
volumeInformation = comicObject;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return await axios({
|
||||
url: `${LIBRARY_SERVICE_BASE_URI}/rawImportToDb`,
|
||||
method: "POST",
|
||||
data: {
|
||||
importType: "new",
|
||||
payload: {
|
||||
rawFileDetails: {
|
||||
name: "",
|
||||
},
|
||||
importStatus: {
|
||||
isImported: true,
|
||||
tagged: false,
|
||||
@@ -75,14 +107,17 @@ export const Search = ({}: ISearchProps): ReactElement => {
|
||||
score: "0",
|
||||
},
|
||||
},
|
||||
sourcedMetadata:
|
||||
{ comicvine: comicVineMetadata?.comicData } || null,
|
||||
acquisition: { source: { wanted: true, name: "comicvine" } },
|
||||
wanted: {
|
||||
source,
|
||||
markEntireVolumeWanted,
|
||||
issues,
|
||||
volume: {},
|
||||
},
|
||||
sourcedMetadata: { comicvine: volumeInformation } || null,
|
||||
},
|
||||
},
|
||||
}),
|
||||
queryKey: ["additionResult"],
|
||||
enabled: !isNil(comicVineMetadata.comicData),
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
const addToLibrary = (sourceName: string, comicData) =>
|
||||
@@ -93,11 +128,9 @@ export const Search = ({}: ISearchProps): ReactElement => {
|
||||
};
|
||||
|
||||
const onSubmit = async (values) => {
|
||||
// Include the selected resource value in the form data
|
||||
const formData = { ...values, resource: selectedResource };
|
||||
try {
|
||||
mutate(formData);
|
||||
// Handle response
|
||||
} catch (error) {
|
||||
// Handle error
|
||||
}
|
||||
@@ -260,13 +293,17 @@ export const Search = ({}: ISearchProps): ReactElement => {
|
||||
)}
|
||||
</p>
|
||||
<div className="mt-2">
|
||||
<button
|
||||
className="flex space-x-1 sm:mt-0 sm:flex-row sm:items-center rounded-lg border border-green-400 dark:border-green-200 bg-green-200 px-2 py-2 text-gray-500 hover:bg-transparent hover:text-green-600 focus:outline-none focus:ring active:text-indigo-500"
|
||||
onClick={() => addToLibrary("comicvine", result)}
|
||||
>
|
||||
<i className="icon-[solar--add-square-bold-duotone] w-6 h-6 mr-2"></i>{" "}
|
||||
Mark as Wanted
|
||||
</button>
|
||||
<PopoverButton
|
||||
content={`This will add ${result.volume.name} to your wanted list.`}
|
||||
clickHandler={() =>
|
||||
addToWantedList({
|
||||
source: "comicvine",
|
||||
comicObject: result,
|
||||
markEntireVolumeWanted: false,
|
||||
resourceType: "issue",
|
||||
})
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -365,8 +402,15 @@ export const Search = ({}: ISearchProps): ReactElement => {
|
||||
count: result.count_of_issues,
|
||||
},
|
||||
)} to your wanted list.`}
|
||||
clickHandler={() =>
|
||||
addToWantedList({
|
||||
source: "comicvine",
|
||||
comicObject: result,
|
||||
markEntireVolumeWanted: true,
|
||||
resourceType: "volume",
|
||||
})
|
||||
}
|
||||
/>
|
||||
{/* onClick={() => addToLibrary("comicvine", result) */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -3,7 +3,7 @@ import { useFloating, offset, flip } from "@floating-ui/react-dom";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import "../../shared/utils/i18n.util"; // Ensure you import your i18n configuration
|
||||
|
||||
const PopoverButton = ({ content }) => {
|
||||
const PopoverButton = ({ content, clickHandler }) => {
|
||||
const [isVisible, setIsVisible] = useState(false);
|
||||
// Use destructuring to obtain the reference and floating setters, among other values.
|
||||
const { x, y, refs, strategy, floatingStyles } = useFloating({
|
||||
@@ -23,6 +23,7 @@ const PopoverButton = ({ content }) => {
|
||||
onBlur={() => setIsVisible(false)}
|
||||
aria-describedby="popover"
|
||||
className="flex space-x-1 sm:mt-0 sm:flex-row sm:items-center rounded-lg border border-green-400 dark:border-green-200 bg-green-200 px-2 py-2 text-gray-500 hover:bg-transparent hover:text-green-600 focus:outline-none focus:ring active:text-indigo-500"
|
||||
onClick={clickHandler}
|
||||
>
|
||||
<i className="icon-[solar--add-square-bold-duotone] w-6 h-6 mr-2"></i>{" "}
|
||||
Mark as Wanted
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { filter, isEmpty, isUndefined, min, minBy } from "lodash";
|
||||
import { filter, isEmpty, isNil, isUndefined, min, minBy } from "lodash";
|
||||
import { LIBRARY_SERVICE_HOST } from "../../constants/endpoints";
|
||||
import { escapePoundSymbol } from "./formatting.utils";
|
||||
|
||||
export const determineCoverFile = (data) => {
|
||||
export const determineCoverFile = (data): any => {
|
||||
/* For a payload like this:
|
||||
const foo = {
|
||||
rawFileDetails: {}, // #1
|
||||
wanted: {},
|
||||
comicInfo: {},
|
||||
comicvine: {}, // #2
|
||||
locg: {}, // #3
|
||||
@@ -19,36 +20,44 @@ export const determineCoverFile = (data) => {
|
||||
issueName: "",
|
||||
publisher: "",
|
||||
},
|
||||
wanted: {
|
||||
objectReference: "wanted",
|
||||
priority: 2,
|
||||
url: "",
|
||||
issueName: "",
|
||||
publisher: "",
|
||||
},
|
||||
comicvine: {
|
||||
objectReference: "comicvine",
|
||||
priority: 2,
|
||||
priority: 3,
|
||||
url: "",
|
||||
issueName: "",
|
||||
publisher: "",
|
||||
},
|
||||
locg: {
|
||||
objectReference: "locg",
|
||||
priority: 3,
|
||||
priority: 4,
|
||||
url: "",
|
||||
issueName: "",
|
||||
publisher: "",
|
||||
},
|
||||
};
|
||||
if (
|
||||
!isUndefined(data.comicvine) &&
|
||||
!isUndefined(data.comicvine.volumeInformation)
|
||||
) {
|
||||
coverFile.comicvine.url = data.comicvine.image.small_url;
|
||||
// comicvine
|
||||
if (!isUndefined(data.comicvine)) {
|
||||
coverFile.comicvine.url = data?.comicvine?.image.small_url;
|
||||
coverFile.comicvine.issueName = data.comicvine.name;
|
||||
coverFile.comicvine.publisher = data.comicvine.volumeInformation.publisher;
|
||||
coverFile.comicvine.publisher = data.comicvine.publisher.name;
|
||||
}
|
||||
if (!isEmpty(data.rawFileDetails.cover)) {
|
||||
// rawFileDetails
|
||||
if (!isEmpty(data.rawFileDetails)) {
|
||||
const encodedFilePath = encodeURI(
|
||||
`${LIBRARY_SERVICE_HOST}/${data.rawFileDetails.cover.filePath}`,
|
||||
);
|
||||
coverFile.rawFile.url = escapePoundSymbol(encodedFilePath);
|
||||
coverFile.rawFile.issueName = data.rawFileDetails.name;
|
||||
}
|
||||
// wanted
|
||||
|
||||
if (!isUndefined(data.locg)) {
|
||||
coverFile.locg.url = data.locg.cover;
|
||||
coverFile.locg.issueName = data.locg.name;
|
||||
@@ -69,25 +78,30 @@ export const determineCoverFile = (data) => {
|
||||
|
||||
export const determineExternalMetadata = (
|
||||
metadataSource: string,
|
||||
source: any
|
||||
) => {
|
||||
switch (metadataSource) {
|
||||
case "comicvine":
|
||||
return {
|
||||
coverURL: source.comicvine.image.small_url,
|
||||
issue: source.comicvine.name,
|
||||
icon: "cvlogo.svg",
|
||||
};
|
||||
case "locg":
|
||||
return {
|
||||
coverURL: source.locg.cover,
|
||||
issue: source.locg.name,
|
||||
icon: "locglogo.svg",
|
||||
};
|
||||
case undefined:
|
||||
return {};
|
||||
source: any,
|
||||
): any => {
|
||||
if (!isNil(source)) {
|
||||
switch (metadataSource) {
|
||||
case "comicvine":
|
||||
return {
|
||||
coverURL:
|
||||
source.comicvine?.image.small_url ||
|
||||
source.comicvine.volumeInformation?.image.small_url,
|
||||
issue: source.comicvine.name,
|
||||
icon: "cvlogo.svg",
|
||||
};
|
||||
case "locg":
|
||||
return {
|
||||
coverURL: source.locg.cover,
|
||||
issue: source.locg.name,
|
||||
icon: "locglogo.svg",
|
||||
};
|
||||
case undefined:
|
||||
return {};
|
||||
|
||||
default:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
return null;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user