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