💧 Added react-select to implement dropdown actions menu
This commit is contained in:
@@ -50,6 +50,7 @@
|
||||
"react-dom": "^17.0.1",
|
||||
"react-fast-compare": "^3.2.0",
|
||||
"react-final-form": "^6.5.3",
|
||||
"react-select": "^4.3.1",
|
||||
"react-sliding-pane": "^7.0.0",
|
||||
"react-spinners": "^0.11.0",
|
||||
"react-table": "^7.7.0",
|
||||
|
||||
@@ -55,6 +55,10 @@ export const search = (data: SearchData) => async (dispatch) => {
|
||||
"search_result_updated",
|
||||
async (groupedResult) => {
|
||||
// ...update properties of the existing result in the UI
|
||||
dispatch({
|
||||
type: AIRDCPP_SEARCH_RESULTS_RECEIVED,
|
||||
groupedResult,
|
||||
});
|
||||
},
|
||||
instance.id,
|
||||
);
|
||||
@@ -67,12 +71,7 @@ export const search = (data: SearchData) => async (dispatch) => {
|
||||
async (searchInfo) => {
|
||||
await sleep(5000);
|
||||
|
||||
// The search can now be considered to be "complete"
|
||||
dispatch({
|
||||
type: AIRDCPP_HUB_SEARCHES_SENT,
|
||||
searchInfo,
|
||||
instance,
|
||||
});
|
||||
|
||||
|
||||
// Check the number of received results (in real use cases we should know that even without calling the API)
|
||||
const currentInstance = await SocketService.get(
|
||||
@@ -82,7 +81,13 @@ export const search = (data: SearchData) => async (dispatch) => {
|
||||
// ...nothing was received, show an informative message to the user
|
||||
}
|
||||
|
||||
// The search can now be considered to be "complete"
|
||||
// If there's an "in progress" indicator in the UI, that could also be disabled here
|
||||
dispatch({
|
||||
type: AIRDCPP_HUB_SEARCHES_SENT,
|
||||
searchInfo,
|
||||
instance,
|
||||
});
|
||||
},
|
||||
instance.id,
|
||||
);
|
||||
|
||||
@@ -6,6 +6,7 @@ import ComicVineSearchForm from "./ComicVineSearchForm";
|
||||
import AcquisitionPanel from "./AcquisitionPanel";
|
||||
import DownloadsPanel from "./DownloadsPanel";
|
||||
import SlidingPane from "react-sliding-pane";
|
||||
import Select from "react-select";
|
||||
|
||||
import { css } from "@emotion/react";
|
||||
import "react-sliding-pane/dist/react-sliding-pane.css";
|
||||
@@ -37,7 +38,6 @@ type ComicDetailProps = {};
|
||||
export const ComicDetail = ({}: ComicDetailProps): ReactElement => {
|
||||
const [page, setPage] = useState(1);
|
||||
const [visible, setVisible] = useState(false);
|
||||
const [isActionDropdownCollapsed, collapseActionDropdown] = useState(false);
|
||||
|
||||
const comicVineSearchResults = useSelector(
|
||||
(state: RootState) => state.comicInfo.searchResults,
|
||||
@@ -54,8 +54,6 @@ export const ComicDetail = ({}: ComicDetailProps): ReactElement => {
|
||||
|
||||
const { comicObjectId } = useParams<{ comicObjectId: string }>();
|
||||
const dispatch = useDispatch();
|
||||
const toggleActionDropdown = () =>
|
||||
collapseActionDropdown(!isActionDropdownCollapsed);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(getComicBookDetailById(comicObjectId));
|
||||
@@ -251,13 +249,30 @@ export const ComicDetail = ({}: ComicDetailProps): ReactElement => {
|
||||
imagePath = comicBookDetailData.sourcedMetadata.comicvine.image.small_url;
|
||||
comicBookTitle = comicBookDetailData.sourcedMetadata.comicvine.name;
|
||||
}
|
||||
|
||||
// actions menu options and handler
|
||||
const actionOptions = [
|
||||
{ value: "match-on-comic-vine", label: "Match on Comic Vine" },
|
||||
{ value: "edit-metdata", label: "Edit Metadata" },
|
||||
{ value: "delete-comic", label: "Delete Comic" },
|
||||
];
|
||||
const handleActionSelection = (action) => {
|
||||
switch (action.value) {
|
||||
case "match-on-comic-vine":
|
||||
openDrawerWithCVMatches();
|
||||
break;
|
||||
default:
|
||||
console.log("No valid action selected.");
|
||||
break;
|
||||
}
|
||||
};
|
||||
return (
|
||||
<section className="container">
|
||||
<div className="section">
|
||||
{!isNil(comicBookDetailData) && !isEmpty(comicBookDetailData) && (
|
||||
<>
|
||||
<h1 className="title">{comicBookTitle}</h1>
|
||||
<div className="columns">
|
||||
<div className="columns is-multiline">
|
||||
<div className="column is-narrow">
|
||||
<Card
|
||||
imageUrl={imagePath}
|
||||
@@ -266,7 +281,7 @@ export const ComicDetail = ({}: ComicDetailProps): ReactElement => {
|
||||
/>
|
||||
</div>
|
||||
{/* raw file details */}
|
||||
<div className="column">
|
||||
<div className="column is-three-fifths">
|
||||
{!isNil(comicBookDetailData.rawFileDetails) && (
|
||||
<>
|
||||
<RawFileDetails data={comicBookDetailData.rawFileDetails} />
|
||||
@@ -279,63 +294,21 @@ export const ComicDetail = ({}: ComicDetailProps): ReactElement => {
|
||||
updatedAt={comicBookDetailData.updatedAt}
|
||||
/>
|
||||
)}
|
||||
{/* action dropdown */}
|
||||
<div
|
||||
className={
|
||||
"dropdown " + (isActionDropdownCollapsed ? "is-active" : "")
|
||||
}
|
||||
onBlur={() => toggleActionDropdown()}
|
||||
onFocus={() => toggleActionDropdown()}
|
||||
>
|
||||
<div className="dropdown-trigger">
|
||||
<button
|
||||
className="button is-small"
|
||||
aria-haspopup="true"
|
||||
aria-controls="dropdown-menu2"
|
||||
onClick={() => toggleActionDropdown()}
|
||||
>
|
||||
<span>
|
||||
<i className="fas fa-sliders-h"></i> Actions
|
||||
</span>
|
||||
|
||||
<span className="icon is-small">
|
||||
<i className="fas fa-angle-down" aria-hidden="true"></i>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
className="dropdown-menu"
|
||||
id="dropdown-menu2"
|
||||
role="menu"
|
||||
>
|
||||
<div className="dropdown-content">
|
||||
<div
|
||||
className="dropdown-item"
|
||||
onClick={openDrawerWithCVMatches}
|
||||
>
|
||||
<span className="icon">
|
||||
<i className="fas fa-magic"></i>
|
||||
</span>
|
||||
<span>Match on ComicVine</span>
|
||||
</div>
|
||||
<hr className="dropdown-divider" />
|
||||
<div className="dropdown-item">
|
||||
<span className="icon">
|
||||
<i className="fas fa-edit"></i>
|
||||
</span>
|
||||
<span>Edit Metdata</span>
|
||||
</div>
|
||||
<hr className="dropdown-divider" />
|
||||
<div className="dropdown-item">
|
||||
<span className="icon">
|
||||
<i className="fas fa-trash"></i>
|
||||
</span>
|
||||
<span>Delete Comic</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{/* action dropdown */}
|
||||
<div className="column is-one-quarter is-narrow">
|
||||
<Select
|
||||
className="basic-single"
|
||||
classNamePrefix="select"
|
||||
defaultValue={actionOptions[0]}
|
||||
name="color"
|
||||
isSearchable={false}
|
||||
options={actionOptions}
|
||||
onChange={handleActionSelection}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{isComicBookMetadataAvailable ? <MetadataTabGroup /> : null}
|
||||
|
||||
@@ -33,7 +33,7 @@ function airdcppReducer(state = initialState, action) {
|
||||
case AIRDCPP_HUB_SEARCHES_SENT:
|
||||
return {
|
||||
...state,
|
||||
isAirDCPPSearchInProgress: true,
|
||||
isAirDCPPSearchInProgress: false,
|
||||
searchInfo: action.searchInfo,
|
||||
searchInstance: action.instance,
|
||||
};
|
||||
@@ -57,10 +57,10 @@ function airdcppReducer(state = initialState, action) {
|
||||
return {
|
||||
searchResults: [],
|
||||
isAirDCPPSearchInProgress: false,
|
||||
searchInfo: null,
|
||||
searchInstance: null,
|
||||
downloadResult: null,
|
||||
bundleDBImportResult: null,
|
||||
searchInfo: null,
|
||||
searchInstance: null,
|
||||
downloadResult: null,
|
||||
bundleDBImportResult: null,
|
||||
};
|
||||
|
||||
default:
|
||||
|
||||
67
yarn.lock
67
yarn.lock
@@ -978,6 +978,13 @@
|
||||
dependencies:
|
||||
regenerator-runtime "^0.13.4"
|
||||
|
||||
"@babel/runtime@^7.12.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.7":
|
||||
version "7.15.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.15.4.tgz#fd17d16bfdf878e6dd02d19753a39fa8a8d9c84a"
|
||||
integrity sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw==
|
||||
dependencies:
|
||||
regenerator-runtime "^0.13.4"
|
||||
|
||||
"@babel/template@^7.14.5", "@babel/template@^7.3.3":
|
||||
version "7.14.5"
|
||||
resolved "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz"
|
||||
@@ -1057,6 +1064,19 @@
|
||||
resolved "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.5.tgz"
|
||||
integrity sha512-igX9a37DR2ZPGYtV6suZ6whr8pTFtyHL3K/oLUotxpSVO2ASaprmAe2Dkq7tBo7CRY7MMDrAa9nuQP9/YG8FxQ==
|
||||
|
||||
"@emotion/react@^11.1.1":
|
||||
version "11.4.1"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.4.1.tgz#a1b0b767b5bad57515ffb0cad9349614d27f4d57"
|
||||
integrity sha512-pRegcsuGYj4FCdZN6j5vqCALkNytdrKw3TZMekTzNXixRg4wkLsU5QEaBG5LC6l01Vppxlp7FE3aTHpIG5phLg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.13.10"
|
||||
"@emotion/cache" "^11.4.0"
|
||||
"@emotion/serialize" "^1.0.2"
|
||||
"@emotion/sheet" "^1.0.2"
|
||||
"@emotion/utils" "^1.0.0"
|
||||
"@emotion/weak-memoize" "^0.2.5"
|
||||
hoist-non-react-statics "^3.3.1"
|
||||
|
||||
"@emotion/react@^11.1.4":
|
||||
version "11.4.0"
|
||||
resolved "https://registry.npmjs.org/@emotion/react/-/react-11.4.0.tgz"
|
||||
@@ -1086,6 +1106,11 @@
|
||||
resolved "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.0.1.tgz"
|
||||
integrity sha512-GbIvVMe4U+Zc+929N1V7nW6YYJtidj31lidSmdYcWozwoBIObXBnaJkKNDjZrLm9Nc0BR+ZyHNaRZxqNZbof5g==
|
||||
|
||||
"@emotion/sheet@^1.0.2":
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.0.2.tgz#1d9ffde531714ba28e62dac6a996a8b1089719d0"
|
||||
integrity sha512-QQPB1B70JEVUHuNtzjHftMGv6eC3Y9wqavyarj4x4lg47RACkeSfNo5pxIOKizwS9AEFLohsqoaxGQj4p0vSIw==
|
||||
|
||||
"@emotion/unitless@^0.7.5":
|
||||
version "0.7.5"
|
||||
resolved "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz"
|
||||
@@ -4679,6 +4704,14 @@ dom-converter@^0.2.0:
|
||||
dependencies:
|
||||
utila "~0.4"
|
||||
|
||||
dom-helpers@^5.0.1:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902"
|
||||
integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.8.7"
|
||||
csstype "^3.0.2"
|
||||
|
||||
dom-serializer@0:
|
||||
version "0.2.2"
|
||||
resolved "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz"
|
||||
@@ -8655,7 +8688,7 @@ mem@^4.0.0:
|
||||
mimic-fn "^2.0.0"
|
||||
p-is-promise "^2.0.0"
|
||||
|
||||
"memoize-one@>=3.1.1 <6":
|
||||
"memoize-one@>=3.1.1 <6", memoize-one@^5.0.0:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz"
|
||||
integrity sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==
|
||||
@@ -10435,7 +10468,7 @@ promzard@^0.3.0:
|
||||
dependencies:
|
||||
read "1"
|
||||
|
||||
prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2:
|
||||
prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2:
|
||||
version "15.7.2"
|
||||
resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz"
|
||||
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
|
||||
@@ -10843,6 +10876,13 @@ react-hot-loader@^4.13.0:
|
||||
shallowequal "^1.1.0"
|
||||
source-map "^0.7.3"
|
||||
|
||||
react-input-autosize@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/react-input-autosize/-/react-input-autosize-3.0.0.tgz#6b5898c790d4478d69420b55441fcc31d5c50a85"
|
||||
integrity sha512-nL9uS7jEs/zu8sqwFE5MAPx6pPkNAriACQ2rGLlqmKr2sPGtN7TXTyDdQt4lbNXVx7Uzadb40x8qotIuru6Rhg==
|
||||
dependencies:
|
||||
prop-types "^15.5.8"
|
||||
|
||||
react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1:
|
||||
version "16.13.1"
|
||||
resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
|
||||
@@ -10909,6 +10949,19 @@ react-router@5.2.0, react-router@^5.2.0:
|
||||
tiny-invariant "^1.0.2"
|
||||
tiny-warning "^1.0.0"
|
||||
|
||||
react-select@^4.3.1:
|
||||
version "4.3.1"
|
||||
resolved "https://registry.yarnpkg.com/react-select/-/react-select-4.3.1.tgz#389fc07c9bc7cf7d3c377b7a05ea18cd7399cb81"
|
||||
integrity sha512-HBBd0dYwkF5aZk1zP81Wx5UsLIIT2lSvAY2JiJo199LjoLHoivjn9//KsmvQMEFGNhe58xyuOITjfxKCcGc62Q==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.12.0"
|
||||
"@emotion/cache" "^11.4.0"
|
||||
"@emotion/react" "^11.1.1"
|
||||
memoize-one "^5.0.0"
|
||||
prop-types "^15.6.0"
|
||||
react-input-autosize "^3.0.0"
|
||||
react-transition-group "^4.3.0"
|
||||
|
||||
react-sliding-pane@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/react-sliding-pane/-/react-sliding-pane-7.0.0.tgz#ed96400fce273e7a36bd26cfb8ffed4e1480cc29"
|
||||
@@ -10929,6 +10982,16 @@ react-table@^7.7.0:
|
||||
resolved "https://registry.npmjs.org/react-table/-/react-table-7.7.0.tgz"
|
||||
integrity sha512-jBlj70iBwOTvvImsU9t01LjFjy4sXEtclBovl3mTiqjz23Reu0DKnRza4zlLtOPACx6j2/7MrQIthIK1Wi+LIA==
|
||||
|
||||
react-transition-group@^4.3.0:
|
||||
version "4.4.2"
|
||||
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.2.tgz#8b59a56f09ced7b55cbd53c36768b922890d5470"
|
||||
integrity sha512-/RNYfRAMlZwDSr6z4zNKV6xu53/e2BuaBbGhbyYIXTrmgu/bGHzmqOs7mJSJBHy9Ud+ApHx3QjrkKSp1pxvlFg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.5.5"
|
||||
dom-helpers "^5.0.1"
|
||||
loose-envify "^1.4.0"
|
||||
prop-types "^15.6.2"
|
||||
|
||||
react-window-dynamic-list@^2.3.5:
|
||||
version "2.4.2"
|
||||
resolved "https://registry.npmjs.org/react-window-dynamic-list/-/react-window-dynamic-list-2.4.2.tgz"
|
||||
|
||||
Reference in New Issue
Block a user