Skip to content
Snippets Groups Projects
Commit cfadd694 authored by xaralis's avatar xaralis
Browse files

refactor: simplify action handlers

parent e13b26d7
No related branches found
No related tags found
No related merge requests found
import React, { useCallback, useState } from "react"; import React from "react";
import { import {
deleteAnnouncement, deleteAnnouncement,
...@@ -11,13 +11,10 @@ import AnnouncementList from "components/annoucements/AnnouncementList"; ...@@ -11,13 +11,10 @@ import AnnouncementList from "components/annoucements/AnnouncementList";
import { CardBody } from "components/cards"; import { CardBody } from "components/cards";
import ErrorMessage from "components/ErrorMessage"; import ErrorMessage from "components/ErrorMessage";
import ModalConfirm from "components/modals/ModalConfirm"; import ModalConfirm from "components/modals/ModalConfirm";
import { useActionState, useItemActionConfirm } from "hooks"; import { useItemActionConfirm } from "hooks";
import { AnnouncementStore, AuthStore } from "stores"; import { AnnouncementStore, AuthStore } from "stores";
const AnnoucementsContainer = ({ className }) => { const AnnoucementsContainer = ({ className }) => {
const [itemToEdit, setItemToEdit] = useState(null);
const [confirmingEdit, setConfirmingEdit] = useState(false);
const [editError, setEditError] = useState(null);
const { 2: loadResult } = loadAnnouncements.useWatch(); const { 2: loadResult } = loadAnnouncements.useWatch();
const [ const [
...@@ -25,45 +22,25 @@ const AnnoucementsContainer = ({ className }) => { ...@@ -25,45 +22,25 @@ const AnnoucementsContainer = ({ className }) => {
setItemToDelete, setItemToDelete,
onDeleteConfirm, onDeleteConfirm,
onDeleteCancel, onDeleteCancel,
deleteState,
] = useItemActionConfirm(deleteAnnouncement); ] = useItemActionConfirm(deleteAnnouncement);
const [deletingAnnouncement, deletingAnnouncementError] = useActionState( const [
deleteAnnouncement, itemToEdit,
itemToDelete setItemToEdit,
); onEditConfirm,
onEditCancel,
editState,
] = useItemActionConfirm(updateAnnouncement, (item, payload) => ({
item,
payload,
}));
const { isAuthenticated, user } = AuthStore.useState(); const { isAuthenticated, user } = AuthStore.useState();
const items = AnnouncementStore.useState((state) => const items = AnnouncementStore.useState((state) =>
state.itemIds.map((id) => state.items[id]) state.itemIds.map((id) => state.items[id])
); );
const confirmEdit = useCallback(
async (payload) => {
if (itemToEdit && payload) {
setConfirmingEdit(true);
const result = await updateAnnouncement.run({
item: itemToEdit,
payload,
});
if (!result.error) {
setItemToEdit(null);
setEditError(null);
} else {
setEditError(result.message);
}
setConfirmingEdit(false);
}
},
[itemToEdit, setItemToEdit]
);
const cancelEdit = useCallback(() => {
setItemToEdit(null);
}, [setItemToEdit]);
return ( return (
<div className={className}> <div className={className}>
{loadResult && loadResult.error && ( {loadResult && loadResult.error && (
...@@ -84,8 +61,8 @@ const AnnoucementsContainer = ({ className }) => { ...@@ -84,8 +61,8 @@ const AnnoucementsContainer = ({ className }) => {
isOpen={!!itemToDelete} isOpen={!!itemToDelete}
onConfirm={onDeleteConfirm} onConfirm={onDeleteConfirm}
onCancel={onDeleteCancel} onCancel={onDeleteCancel}
confirming={deletingAnnouncement} confirming={deleteState.loading}
error={deletingAnnouncementError} error={deleteState.error}
title="Opravdu smazat?" title="Opravdu smazat?"
yesActionLabel="Smazat" yesActionLabel="Smazat"
> >
...@@ -95,10 +72,10 @@ const AnnoucementsContainer = ({ className }) => { ...@@ -95,10 +72,10 @@ const AnnoucementsContainer = ({ className }) => {
<AnnouncementEditModal <AnnouncementEditModal
isOpen={true} isOpen={true}
announcement={itemToEdit} announcement={itemToEdit}
onConfirm={confirmEdit} onConfirm={onEditConfirm}
onCancel={cancelEdit} onCancel={onEditCancel}
confirming={confirmingEdit} confirming={editState.loading}
error={editError} error={editState.error}
/> />
)} )}
</div> </div>
......
import React, { useCallback, useState } from "react"; import React from "react";
import pick from "lodash/pick"; import pick from "lodash/pick";
import { import {
...@@ -25,46 +25,58 @@ import { useActionState, useItemActionConfirm } from "hooks"; ...@@ -25,46 +25,58 @@ import { useActionState, useItemActionConfirm } from "hooks";
import { AuthStore, PostStore } from "stores"; import { AuthStore, PostStore } from "stores";
const PostsContainer = ({ className, showAddPostCta }) => { const PostsContainer = ({ className, showAddPostCta }) => {
const [postToEdit, setPostToEdit] = useState(null);
const [confirmingEdit, setConfirmingEdit] = useState(false);
const [editError, setEditError] = useState(null);
const [ const [
userToBan, userToBan,
setUserToBan, setUserToBan,
onBanUserConfirm, onBanUserConfirm,
onBanUserCancel, onBanUserCancel,
banUserState,
] = useItemActionConfirm(ban); ] = useItemActionConfirm(ban);
const [ const [
userToUnban, userToUnban,
setUserToUnban, setUserToUnban,
onUnbanUserConfirm, onUnbanUserConfirm,
onUnbanUserCancel, onUnbanUserCancel,
unbanUserState,
] = useItemActionConfirm(unban); ] = useItemActionConfirm(unban);
const [ const [
postToHide, postToHide,
setPostToHide, setPostToHide,
onPostHideConfirm, onPostHideConfirm,
onPostHideCancel, onPostHideCancel,
postHideState,
] = useItemActionConfirm(hide); ] = useItemActionConfirm(hide);
const [ const [
postToArchive, postToArchive,
setPostToArchive, setPostToArchive,
onPostArchiveConfirm, onPostArchiveConfirm,
onPostArchiveCancel, onPostArchiveCancel,
postArchiveState,
] = useItemActionConfirm(archive); ] = useItemActionConfirm(archive);
const [ const [
postToAnnounce, postToAnnounce,
setPostToAnnounce, setPostToAnnounce,
onAnnounceConfirm, onAnnounceConfirm,
onAnnounceCancel, onAnnounceCancel,
announceState,
] = useItemActionConfirm(announceProposal); ] = useItemActionConfirm(announceProposal);
const [ const [
postToAccept, postToAccept,
setPostToAccept, setPostToAccept,
onAcceptConfirm, onAcceptConfirm,
onAcceptCancel, onAcceptCancel,
acceptState,
] = useItemActionConfirm(acceptProposal); ] = useItemActionConfirm(acceptProposal);
const [
postToEdit,
setPostToEdit,
onEditConfirm,
onEditCancel,
editState,
] = useItemActionConfirm(edit, (item, newContent) => ({
post: item,
newContent,
}));
const [ const [
postToReject, postToReject,
setPostToReject, setPostToReject,
...@@ -92,24 +104,6 @@ const PostsContainer = ({ className, showAddPostCta }) => { ...@@ -92,24 +104,6 @@ const PostsContainer = ({ className, showAddPostCta }) => {
(state) => state.filters.flags === "archived" (state) => state.filters.flags === "archived"
); );
const [banningUser, banningUserError] = useActionState(ban, userToBan);
const [unbanningUser, unbanningUserError] = useActionState(
unban,
userToUnban
);
const [hidingPost, hidingPostError] = useActionState(hide, postToHide);
const [archivingPost, archivingPostError] = useActionState(
archive,
postToArchive
);
const [announcingProposal, announcingProposalError] = useActionState(
announceProposal,
postToAnnounce
);
const [acceptingProposal, acceptingProposalError] = useActionState(
acceptProposal,
postToAccept
);
const [rejectingProposal, rejectingProposalError] = useActionState( const [rejectingProposal, rejectingProposalError] = useActionState(
rejectProposal, rejectProposal,
{ {
...@@ -138,30 +132,6 @@ const PostsContainer = ({ className, showAddPostCta }) => { ...@@ -138,30 +132,6 @@ const PostsContainer = ({ className, showAddPostCta }) => {
const { 2: loadResult } = loadPosts.useWatch(); const { 2: loadResult } = loadPosts.useWatch();
const confirmEdit = useCallback(
async (newContent) => {
if (postToEdit && newContent) {
setConfirmingEdit(true);
const result = await edit.run({ post: postToEdit, newContent });
if (!result.error) {
setPostToEdit(null);
setEditError(null);
} else {
setEditError(result.message);
}
setConfirmingEdit(false);
}
},
[postToEdit, setPostToEdit, setConfirmingEdit]
);
const cancelEdit = useCallback(() => {
setPostToEdit(null);
}, [setPostToEdit]);
/** /**
* Ban a post's author. * Ban a post's author.
* @param {CF2021.Post} post * @param {CF2021.Post} post
...@@ -212,8 +182,8 @@ const PostsContainer = ({ className, showAddPostCta }) => { ...@@ -212,8 +182,8 @@ const PostsContainer = ({ className, showAddPostCta }) => {
isOpen={!!userToBan} isOpen={!!userToBan}
onConfirm={onBanUserConfirm} onConfirm={onBanUserConfirm}
onCancel={onBanUserCancel} onCancel={onBanUserCancel}
confirming={banningUser} confirming={banUserState.loading}
error={banningUserError} error={banUserState.error}
title={`Zablokovat uživatele ${userToBan ? userToBan.name : null}?`} title={`Zablokovat uživatele ${userToBan ? userToBan.name : null}?`}
yesActionLabel="Zablokovat" yesActionLabel="Zablokovat"
> >
...@@ -224,8 +194,8 @@ const PostsContainer = ({ className, showAddPostCta }) => { ...@@ -224,8 +194,8 @@ const PostsContainer = ({ className, showAddPostCta }) => {
isOpen={!!userToUnban} isOpen={!!userToUnban}
onConfirm={onUnbanUserConfirm} onConfirm={onUnbanUserConfirm}
onCancel={onUnbanUserCancel} onCancel={onUnbanUserCancel}
confirming={unbanningUser} confirming={unbanUserState.loading}
error={unbanningUserError} error={unbanUserState.error}
title={`Odblokovat uživatele ${userToUnban ? userToUnban.name : null}?`} title={`Odblokovat uživatele ${userToUnban ? userToUnban.name : null}?`}
yesActionLabel="Odblokovat" yesActionLabel="Odblokovat"
> >
...@@ -237,8 +207,8 @@ const PostsContainer = ({ className, showAddPostCta }) => { ...@@ -237,8 +207,8 @@ const PostsContainer = ({ className, showAddPostCta }) => {
isOpen={!!postToHide} isOpen={!!postToHide}
onConfirm={onPostHideConfirm} onConfirm={onPostHideConfirm}
onCancel={onPostHideCancel} onCancel={onPostHideCancel}
confirming={hidingPost} confirming={postHideState.loading}
error={hidingPostError} error={postHideState.error}
title="Skrýt příspěvek?" title="Skrýt příspěvek?"
yesActionLabel="Potvrdit" yesActionLabel="Potvrdit"
> >
...@@ -248,8 +218,8 @@ const PostsContainer = ({ className, showAddPostCta }) => { ...@@ -248,8 +218,8 @@ const PostsContainer = ({ className, showAddPostCta }) => {
isOpen={!!postToArchive} isOpen={!!postToArchive}
onConfirm={onPostArchiveConfirm} onConfirm={onPostArchiveConfirm}
onCancel={onPostArchiveCancel} onCancel={onPostArchiveCancel}
confirming={archivingPost} confirming={postArchiveState.loading}
error={archivingPostError} error={postArchiveState.error}
title="Archivovat příspěvek?" title="Archivovat příspěvek?"
yesActionLabel="Potvrdit" yesActionLabel="Potvrdit"
> >
...@@ -260,8 +230,8 @@ const PostsContainer = ({ className, showAddPostCta }) => { ...@@ -260,8 +230,8 @@ const PostsContainer = ({ className, showAddPostCta }) => {
isOpen={!!postToAnnounce} isOpen={!!postToAnnounce}
onConfirm={onAnnounceConfirm} onConfirm={onAnnounceConfirm}
onCancel={onAnnounceCancel} onCancel={onAnnounceCancel}
confirming={announcingProposal} confirming={announceState.loading}
error={announcingProposalError} error={announceState.errror}
title="Vyhlásit procedurální návrh?" title="Vyhlásit procedurální návrh?"
yesActionLabel="Vyhlásit návrh" yesActionLabel="Vyhlásit návrh"
> >
...@@ -271,8 +241,8 @@ const PostsContainer = ({ className, showAddPostCta }) => { ...@@ -271,8 +241,8 @@ const PostsContainer = ({ className, showAddPostCta }) => {
isOpen={!!postToAccept} isOpen={!!postToAccept}
onConfirm={onAcceptConfirm} onConfirm={onAcceptConfirm}
onCancel={onAcceptCancel} onCancel={onAcceptCancel}
confirming={acceptingProposal} confirming={acceptState.loading}
error={acceptingProposalError} error={acceptState.error}
title="Schválit procedurální návrh?" title="Schválit procedurální návrh?"
yesActionLabel="Schválit návrh" yesActionLabel="Schválit návrh"
> >
...@@ -364,10 +334,10 @@ const PostsContainer = ({ className, showAddPostCta }) => { ...@@ -364,10 +334,10 @@ const PostsContainer = ({ className, showAddPostCta }) => {
<PostEditModal <PostEditModal
isOpen={true} isOpen={true}
post={postToEdit} post={postToEdit}
onConfirm={confirmEdit} onConfirm={onEditConfirm}
onCancel={cancelEdit} onCancel={onEditCancel}
confirming={confirmingEdit} confirming={editState.loading}
error={editError} error={editState.error}
/> />
)} )}
</> </>
......
...@@ -6,27 +6,34 @@ const baseActionParamsBuilder = (item, args) => { ...@@ -6,27 +6,34 @@ const baseActionParamsBuilder = (item, args) => {
export const useItemActionConfirm = (actionFn, actionParamsBuilder = null) => { export const useItemActionConfirm = (actionFn, actionParamsBuilder = null) => {
const [item, setItem] = useState(null); const [item, setItem] = useState(null);
const [actionArgs, setActionArgs] = useState(null);
const onActionConfirm = useCallback( const onActionConfirm = useCallback(
async (args) => { async (args) => {
if (item) { if (item) {
const result = await actionFn.run( const newActionArgs = (actionParamsBuilder || baseActionParamsBuilder)(
(actionParamsBuilder || baseActionParamsBuilder)(item, args) item,
args
); );
setActionArgs(newActionArgs);
const result = await actionFn.run(newActionArgs);
if (!result.error) { if (!result.error) {
setItem(null); setItem(null);
} }
} }
}, },
[item, setItem, actionFn, actionParamsBuilder] [item, setItem, actionFn, actionParamsBuilder, setActionArgs]
); );
const onActionCancel = useCallback(() => { const onActionCancel = useCallback(() => {
setItem(null); setItem(null);
}, [setItem]); }, [setItem]);
return [item, setItem, onActionConfirm, onActionCancel]; const [loading, error] = useActionState(actionFn, actionArgs);
const unwrappedActionState = { loading, error };
return [item, setItem, onActionConfirm, onActionCancel, unwrappedActionState];
}; };
export const useActionConfirm = (actionFn, actionArgs) => { export const useActionConfirm = (actionFn, actionArgs) => {
......
import has from "lodash/has"; import has from "lodash/has";
import { markdownConverter } from "markdown";
import { AnnouncementStore } from "stores"; import { AnnouncementStore } from "stores";
import { parseRawAnnouncement, syncAnnoucementItemIds } from "utils"; import { parseRawAnnouncement, syncAnnoucementItemIds } from "utils";
...@@ -8,6 +9,9 @@ export const handleAnnouncementChanged = (payload) => { ...@@ -8,6 +9,9 @@ export const handleAnnouncementChanged = (payload) => {
if (state.items[payload.id]) { if (state.items[payload.id]) {
if (has(payload, "content")) { if (has(payload, "content")) {
state.items[payload.id].content = payload.content; state.items[payload.id].content = payload.content;
state.items[payload.id].contentHtml = markdownConverter.makeHtml(
payload.content
);
} }
if (has(payload, "link")) { if (has(payload, "link")) {
state.items[payload.id].link = payload.link; state.items[payload.id].link = payload.link;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment