💧 Added react-select to implement dropdown actions menu

This commit is contained in:
2021-09-03 13:33:13 -07:00
parent 1f8e0d6ff6
commit e202ae45a4
5 changed files with 115 additions and 73 deletions

View File

@@ -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,
);

View File

@@ -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}

View File

@@ -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: