🤼‍♀️ Wiring up ES-powered issue detection

This commit is contained in:
2022-02-01 23:19:43 -08:00
parent d819bac7f2
commit 1d317abbdb
7 changed files with 131 additions and 49 deletions

View File

@@ -13,6 +13,7 @@ import {
IMS_COMIC_BOOK_ARCHIVE_EXTRACTION_CALL_IN_PROGRESS,
CV_ISSUES_METADATA_CALL_IN_PROGRESS,
CV_ISSUES_METADATA_FETCH_SUCCESS,
CV_CLEANUP,
} from "../constants/action-types";
import {
COMICBOOKINFO_SERVICE_URI,
@@ -64,24 +65,24 @@ export const comicinfoAPICall = (options) => async (dispatch) => {
});
}
};
export const getIssuesForSeries = (comicObjectID: any) => async (dispatch) => {
dispatch({
type: CV_ISSUES_METADATA_CALL_IN_PROGRESS,
});
export const findIssuesForSeriesInLibrary =
(comicObjectID: any) => async (dispatch) => {
dispatch({
type: CV_ISSUES_METADATA_CALL_IN_PROGRESS,
});
dispatch({
type: CV_CLEANUP,
});
await axios({
url: `${IMPORT_SERVICE_BASE_URI}/findIssuesForSeriesInLibrary`,
method: "POST",
params: {
comicObjectID,
},
});
};
const issues = await axios({
url: `${IMPORT_SERVICE_BASE_URI}/getIssuesForSeries`,
method: "POST",
params: {
comicObjectID,
},
});
console.log(issues);
dispatch({
type: CV_ISSUES_METADATA_FETCH_SUCCESS,
issues,
});
};
export const getComicBookDetailById =
(comicBookObjectId: string) => async (dispatch) => {
dispatch({

View File

@@ -128,6 +128,11 @@ $size-8: 0.9rem;
border-bottom-right-radius: 0.3rem;
box-shadow: 1px 8px 23px 7px rgba(0, 0, 0, 0.12);
.green-border {
border:2px dotted #999;
border-radius: 0.3rem;
}
.truncate {
width: 100px;
white-space: nowrap;

View File

@@ -8,6 +8,9 @@ interface ICardProps {
hasDetails: boolean;
title?: PropTypes.ReactElementLike | null;
children?: PropTypes.ReactNodeLike;
borderColorClass?: string;
backgroundColor?: string;
onClick?: (event: React.MouseEvent<HTMLElement>) => void;
}
const renderCard = (props): ReactElement => {
@@ -16,9 +19,15 @@ const renderCard = (props): ReactElement => {
return <>horiztonal</>;
case "vertical":
return (
<div>
<div onClick={props.onClick}>
<div className="generic-card">
<div>
<div
className={
!isNil(props.borderColorClass)
? `${props.borderColorClass}`
: ""
}
>
<div
className={
props.hasDetails
@@ -31,10 +40,15 @@ const renderCard = (props): ReactElement => {
</figure>
</div>
{props.hasDetails && (
<div className="card-content">
<div className="card-title is-size-8 is-family-secondary">
{isNil(props.title) ? "No Name" : props.title}
</div>
<div
className="card-content"
style={{ backgroundColor: props.backgroundColor }}
>
{!isNil(props.title) ? (
<div className="card-title is-size-8 is-family-secondary">
{props.title}
</div>
) : null}
{props.children}
</div>
)}

View File

@@ -1,13 +1,14 @@
import { isEmpty, isNil, isUndefined } from "lodash";
import React, { useEffect, ReactElement } from "react";
import { isEmpty, isNil, isUndefined, map } from "lodash";
import React, { useEffect, ReactElement, useState, useCallback } from "react";
import { useDispatch, useSelector } from "react-redux";
import { useParams } from "react-router";
import {
getComicBookDetailById,
getIssuesForSeries,
findIssuesForSeriesInLibrary,
} from "../../actions/comicinfo.actions";
import Masonry from "react-masonry-css";
import { Card } from "../Carda";
import SlidingPane from "react-sliding-pane";
const VolumeDetails = (props): ReactElement => {
const breakpointColumnsObj = {
@@ -16,15 +17,45 @@ const VolumeDetails = (props): ReactElement => {
700: 2,
600: 1,
};
// sliding panel config
const [visible, setVisible] = useState(false);
const [slidingPanelContentId, setSlidingPanelContentId] = useState("");
const [matches, setMatches] = useState([]);
// sliding panel init
const contentForSlidingPanel = {
potentialMatchesInLibrary: {
content: () => {
console.log(matches);
return (
<div className="mt-10">
{map(matches, (match) => (
<pre>{JSON.stringify(match, undefined, 2)}</pre>
))}
</div>
);
},
},
};
// sliding panel handlers
const openPotentialLibraryMatchesPanel = useCallback((potentialMatches) => {
setSlidingPanelContentId("potentialMatchesInLibrary");
setMatches(potentialMatches);
setVisible(true);
}, []);
const comicBookDetails = useSelector(
(state: RootState) => state.comicInfo.comicBookDetail,
);
const issues = useSelector(
const issuesForVolume = useSelector(
(state: RootState) => state.comicInfo.issuesForVolume,
);
const dispatch = useDispatch();
useEffect(() => {
dispatch(getIssuesForSeries(comicObjectId));
dispatch(findIssuesForSeriesInLibrary(comicObjectId));
dispatch(getComicBookDetailById(comicObjectId));
}, []);
@@ -56,27 +87,50 @@ const VolumeDetails = (props): ReactElement => {
className="issues-container"
columnClassName="issues-column"
>
{!isUndefined(issues) && !isEmpty(issues)
? issues.map((issue) => {
{!isUndefined(issuesForVolume) && !isEmpty(issuesForVolume)
? issuesForVolume.map((issue) => {
return (
<>
<Card
key={issue.id}
imageUrl={issue.image.thumb_url}
key={issue.issue.id}
imageUrl={issue.issue.image.thumb_url}
orientation={"vertical"}
hasDetails={false}
/>
{!isEmpty(issue.potentialMatches)
? "matches available"
: null}
hasDetails={!isEmpty(issue.matches) ? true : false}
borderColorClass={
!isEmpty(issue.matches) ? "green-border" : ""
}
backgroundColor={
!isEmpty(issue.matches) ? "#e0f5d0" : ""
}
onClick={() =>
openPotentialLibraryMatchesPanel(issue.matches)
}
>
{!isEmpty(issue.matches) ? (
<span className="icon is-success">
<i className="fa-solid fa-hands-asl-interpreting"></i>
</span>
) : null}
</Card>
{/* { JSON.stringify(issue, undefined, 2)} */}
</>
);
})
: "loading"}
</Masonry>
{/* <pre>{JSON.stringify(comicBookDetails, undefined, 2)}</pre> */}
{/* <pre>{JSON.stringify(issuesForVolume, undefined, 2)}</pre> */}
</div>
</div>
<SlidingPane
isOpen={visible}
onRequestClose={() => setVisible(false)}
title={"Potential Matches in Library"}
width={"600px"}
>
{slidingPanelContentId !== "" &&
contentForSlidingPanel[slidingPanelContentId].content()}
</SlidingPane>
</div>
);
} else {

View File

@@ -41,9 +41,13 @@ export const IMS_COMIC_BOOK_GROUPS_CALL_FAILED =
// issues for a given volume
export const CV_ISSUES_METADATA_CALL_IN_PROGRESS =
"ISSUES_METADATA_CALL_IN_PROGRESS";
export const CV_ISSUES_METADATA_FETCH_SUCCESS = "ISSUES_METADATA_FETCH_SUCCESS";
export const CV_ISSUES_METADATA_FETCH_FAILED = "ISSUES_METADATA_FETCH_FAILED";
"CV_ISSUES_METADATA_CALL_IN_PROGRESS";
export const CV_ISSUES_METADATA_FETCH_SUCCESS =
"CV_ISSUES_METADATA_FETCH_SUCCESS";
export const CV_ISSUES_METADATA_FETCH_FAILED =
"CV_ISSUES_METADATA_FETCH_FAILED";
export const CV_ISSUES_FOR_VOLUME_IN_LIBRARY_SUCCESS =
"CV_ISSUES_FOR_VOLUME_IN_LIBRARY_SUCCESS";
// extracted comic archive
export const IMS_COMIC_BOOK_ARCHIVE_EXTRACTION_SUCCESS =

View File

@@ -4,10 +4,11 @@ import {
CV_CLEANUP,
IMS_COMIC_BOOK_DB_OBJECT_FETCHED,
IMS_COMIC_BOOK_DB_OBJECT_CALL_IN_PROGRESS,
IMS_COMIC_BOOK_DB_OBJECT_CALL_FAILED,
CV_ISSUES_METADATA_CALL_IN_PROGRESS,
CV_ISSUES_METADATA_FETCH_SUCCESS,
CV_ISSUES_FOR_VOLUME_IN_LIBRARY_SUCCESS,
} from "../constants/action-types";
const initialState = {
searchResults: [],
searchQuery: {},
@@ -48,17 +49,20 @@ function comicinfoReducer(state = initialState, action) {
...state,
searchResults: [],
searchQuery: {},
issuesForVolume: [],
};
case CV_ISSUES_METADATA_CALL_IN_PROGRESS:
return {
inProgress: true,
...state,
};
case CV_ISSUES_METADATA_FETCH_SUCCESS:
console.log(action);
case CV_ISSUES_FOR_VOLUME_IN_LIBRARY_SUCCESS:
console.log("jagan", action);
return {
...state,
issuesForVolume: action.issues.data,
issuesForVolume: [...state.issuesForVolume, action.result],
inProgress: false,
};
default:
return state;

View File

@@ -12857,10 +12857,10 @@ text-table@^0.2.0, text-table@~0.2.0:
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=
threetwo-ui-typings@^1.0.11:
version "1.0.11"
resolved "https://registry.yarnpkg.com/threetwo-ui-typings/-/threetwo-ui-typings-1.0.11.tgz#796f58230ce1cb15a654bbc1d8dbcc400fd8335b"
integrity sha512-jRI1rUttoJDqsKFUPd4MM56NErftl2NSEo8MkeqllOtVf38Wy+wVvAT+OW6AoSguA5cLxSpOiA25c31FWjOvOw==
threetwo-ui-typings@^1.0.12:
version "1.0.12"
resolved "https://registry.yarnpkg.com/threetwo-ui-typings/-/threetwo-ui-typings-1.0.12.tgz#9f05542d7fa67b2349e20b0555ab196521fa8448"
integrity sha512-lKADNpD2Oa3Wmf6tdZhaPSNfIFa0KtstsZLE0yalTjqKmtQZM7Ct2OnlCkH7aonDuVn+jgcRMwkcP9krCqa2fw==
dependencies:
typescript "^4.3.2"