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

feat: report action errors

parent f3fce328
No related branches found
No related tags found
No related merge requests found
Pipeline #1858 passed
...@@ -8,6 +8,7 @@ import { ...@@ -8,6 +8,7 @@ import {
CardBodyText, CardBodyText,
CardHeadline, CardHeadline,
} from "components/cards"; } from "components/cards";
import ErrorMessage from "components/ErrorMessage";
import Modal from "./Modal"; import Modal from "./Modal";
...@@ -19,6 +20,7 @@ const ModalConfirm = ({ ...@@ -19,6 +20,7 @@ const ModalConfirm = ({
onCancel, onCancel,
onConfirm, onConfirm,
confirming, confirming,
error,
...props ...props
}) => { }) => {
return ( return (
...@@ -32,6 +34,11 @@ const ModalConfirm = ({ ...@@ -32,6 +34,11 @@ const ModalConfirm = ({
</button> </button>
</div> </div>
<CardBodyText>{children}</CardBodyText> <CardBodyText>{children}</CardBodyText>
{error && (
<ErrorMessage className="mt-2">
Při provádění akce došlo k problému: error
</ErrorMessage>
)}
</CardBody> </CardBody>
<CardActions right className="space-x-1"> <CardActions right className="space-x-1">
<Button <Button
......
...@@ -3,7 +3,8 @@ import classNames from "classnames"; ...@@ -3,7 +3,8 @@ import classNames from "classnames";
import { addAnnouncement } from "actions/announcements"; import { addAnnouncement } from "actions/announcements";
import Button from "components/Button"; import Button from "components/Button";
import { useActionLoading } from "hooks"; import ErrorMessage from "components/ErrorMessage";
import { useActionState } from "hooks";
const urlRegex = /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/; const urlRegex = /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/;
...@@ -13,7 +14,7 @@ const AddAnnouncementForm = ({ className }) => { ...@@ -13,7 +14,7 @@ const AddAnnouncementForm = ({ className }) => {
const [linkValid, setLinkValid] = useState(false); const [linkValid, setLinkValid] = useState(false);
const [type, setType] = useState("announcement"); const [type, setType] = useState("announcement");
const addingAnnouncement = useActionLoading(addAnnouncement, { const [adding, addingError] = useActionState(addAnnouncement, {
content: text, content: text,
link, link,
type, type,
...@@ -44,6 +45,11 @@ const AddAnnouncementForm = ({ className }) => { ...@@ -44,6 +45,11 @@ const AddAnnouncementForm = ({ className }) => {
return ( return (
<div className={className}> <div className={className}>
{addingError && (
<ErrorMessage>
Při přidávání oznámení došlo k problému: {addingError}.
</ErrorMessage>
)}
<div className="grid grid-cols-1 gap-4"> <div className="grid grid-cols-1 gap-4">
<div <div
className="form-field" className="form-field"
...@@ -112,10 +118,8 @@ const AddAnnouncementForm = ({ className }) => { ...@@ -112,10 +118,8 @@ const AddAnnouncementForm = ({ className }) => {
onClick={onAdd} onClick={onAdd}
className="text-sm mt-4" className="text-sm mt-4"
hoverActive hoverActive
loading={addingAnnouncement} loading={adding}
disabled={ disabled={!text || (type === "voting" && !linkValid) || adding}
!text || (type === "voting" && !linkValid) || addingAnnouncement
}
> >
Přidat oznámení Přidat oznámení
</Button> </Button>
......
...@@ -2,12 +2,17 @@ import React, { useState } from "react"; ...@@ -2,12 +2,17 @@ import React, { useState } from "react";
import { addPost, addProposal } from "actions/posts"; import { addPost, addProposal } from "actions/posts";
import Button from "components/Button"; import Button from "components/Button";
import { useActionLoading } from "hooks"; import ErrorMessage from "components/ErrorMessage";
import { useActionState } from "hooks";
const AddPostForm = ({ className }) => { const AddPostForm = ({ className }) => {
const [text, setText] = useState(""); const [text, setText] = useState("");
const addingPost = useActionLoading(addPost, { content: text }); const [addingPost, addingPostError] = useActionState(addPost, {
const addingProposal = useActionLoading(addPost, { content: text }); content: text,
});
const [addingProposal, addingProposalError] = useActionState(addPost, {
content: text,
});
const onTextInput = (evt) => { const onTextInput = (evt) => {
setText(evt.target.value); setText(evt.target.value);
...@@ -47,6 +52,16 @@ const AddPostForm = ({ className }) => { ...@@ -47,6 +52,16 @@ const AddPostForm = ({ className }) => {
return ( return (
<div className={className}> <div className={className}>
{addingPostError && (
<ErrorMessage>
Při přidávání příspěvku došlo k problému: {addingPostError}.
</ErrorMessage>
)}
{addingProposalError && (
<ErrorMessage>
Při přidávání příspěvku došlo k problému: {addingProposalError}.
</ErrorMessage>
)}
<div className="form-field"> <div className="form-field">
<div className="form-field__wrapper form-field__wrapper--shadowed"> <div className="form-field__wrapper form-field__wrapper--shadowed">
<textarea <textarea
......
...@@ -10,7 +10,7 @@ import AnnouncementList from "components/annoucements/AnnouncementList"; ...@@ -10,7 +10,7 @@ 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 { useActionLoading, useItemActionConfirm } from "hooks"; import { useActionState, useItemActionConfirm } from "hooks";
import { AnnouncementStore, AuthStore } from "stores"; import { AnnouncementStore, AuthStore } from "stores";
const AnnoucementsContainer = () => { const AnnoucementsContainer = () => {
...@@ -24,7 +24,7 @@ const AnnoucementsContainer = () => { ...@@ -24,7 +24,7 @@ const AnnoucementsContainer = () => {
onDeleteCancel, onDeleteCancel,
] = useItemActionConfirm(deleteAnnouncement); ] = useItemActionConfirm(deleteAnnouncement);
const deletingAnnouncement = useActionLoading( const [deletingAnnouncement, deletingAnnouncementError] = useActionState(
deleteAnnouncement, deleteAnnouncement,
itemToDelete itemToDelete
); );
...@@ -79,6 +79,7 @@ const AnnoucementsContainer = () => { ...@@ -79,6 +79,7 @@ const AnnoucementsContainer = () => {
onConfirm={onDeleteConfirm} onConfirm={onDeleteConfirm}
onCancel={onDeleteCancel} onCancel={onDeleteCancel}
confirming={deletingAnnouncement} confirming={deletingAnnouncement}
error={deletingAnnouncementError}
title="Opravdu smazat?" title="Opravdu smazat?"
yesActionLabel="Smazat" yesActionLabel="Smazat"
> >
......
...@@ -17,7 +17,7 @@ import ErrorMessage from "components/ErrorMessage"; ...@@ -17,7 +17,7 @@ import ErrorMessage from "components/ErrorMessage";
import ModalConfirm from "components/modals/ModalConfirm"; import ModalConfirm from "components/modals/ModalConfirm";
import PostEditModal from "components/posts/PostEditModal"; import PostEditModal from "components/posts/PostEditModal";
import PostList from "components/posts/PostList"; import PostList from "components/posts/PostList";
import { useActionLoading, useItemActionConfirm } from "hooks"; import { useActionState, useItemActionConfirm } from "hooks";
import { AuthStore, PostStore } from "stores"; import { AuthStore, PostStore } from "stores";
const PostsContainer = ({ className }) => { const PostsContainer = ({ className }) => {
...@@ -68,15 +68,24 @@ const PostsContainer = ({ className }) => { ...@@ -68,15 +68,24 @@ const PostsContainer = ({ className }) => {
(state) => state.filters.flags === "archived" (state) => state.filters.flags === "archived"
); );
const banningUser = useActionLoading(ban, userToBan); const [banningUser, banningUserError] = useActionState(ban, userToBan);
const hidingPost = useActionLoading(hide, postToHide); const [hidingPost, hidingPostError] = useActionState(hide, postToHide);
const announcingProposal = useActionLoading(announceProposal, postToAnnounce); const [announcingProposal, announcingProposalError] = useActionState(
const acceptingProposal = useActionLoading(acceptProposal, postToAccept); announceProposal,
const rejectingProposal = useActionLoading(rejectProposal, postToReject); postToAnnounce
const rejectingProposalByChairman = useActionLoading( );
rejectProposalByChairman, const [acceptingProposal, acceptingProposalError] = useActionState(
postToRejectByChairman acceptProposal,
postToAccept
); );
const [rejectingProposal, rejectingProposalError] = useActionState(
rejectProposal,
postToReject
);
const [
rejectingProposalByChairman,
rejectingProposalByChairmanError,
] = useActionState(rejectProposalByChairman, postToRejectByChairman);
const { 2: loadResult } = loadPosts.useWatch(); const { 2: loadResult } = loadPosts.useWatch();
...@@ -146,6 +155,7 @@ const PostsContainer = ({ className }) => { ...@@ -146,6 +155,7 @@ const PostsContainer = ({ className }) => {
onConfirm={onBanUserConfirm} onConfirm={onBanUserConfirm}
onCancel={onBanUserCancel} onCancel={onBanUserCancel}
confirming={banningUser} confirming={banningUser}
error={banningUserError}
title={`Zablokovat uživatele ${userToBan ? userToBan.name : null}?`} title={`Zablokovat uživatele ${userToBan ? userToBan.name : null}?`}
yesActionLabel="Zablokovat" yesActionLabel="Zablokovat"
> >
...@@ -157,6 +167,7 @@ const PostsContainer = ({ className }) => { ...@@ -157,6 +167,7 @@ const PostsContainer = ({ className }) => {
onConfirm={onPostHideConfirm} onConfirm={onPostHideConfirm}
onCancel={onPostHideCancel} onCancel={onPostHideCancel}
confirming={hidingPost} confirming={hidingPost}
error={hidingPostError}
title="Skrýt příspěvek?" title="Skrýt příspěvek?"
yesActionLabel="Potvrdit" yesActionLabel="Potvrdit"
> >
...@@ -167,6 +178,7 @@ const PostsContainer = ({ className }) => { ...@@ -167,6 +178,7 @@ const PostsContainer = ({ className }) => {
onConfirm={onAnnounceConfirm} onConfirm={onAnnounceConfirm}
onCancel={onAnnounceCancel} onCancel={onAnnounceCancel}
confirming={announcingProposal} confirming={announcingProposal}
error={announcingProposalError}
title="Vyhlásit procedurální návrh?" title="Vyhlásit procedurální návrh?"
yesActionLabel="Vyhlásit návrh" yesActionLabel="Vyhlásit návrh"
> >
...@@ -177,6 +189,7 @@ const PostsContainer = ({ className }) => { ...@@ -177,6 +189,7 @@ const PostsContainer = ({ className }) => {
onConfirm={onAcceptConfirm} onConfirm={onAcceptConfirm}
onCancel={onAcceptCancel} onCancel={onAcceptCancel}
confirming={acceptingProposal} confirming={acceptingProposal}
error={acceptingProposalError}
title="Schválit procedurální návrh?" title="Schválit procedurální návrh?"
yesActionLabel="Schválit návrh" yesActionLabel="Schválit návrh"
> >
...@@ -187,6 +200,7 @@ const PostsContainer = ({ className }) => { ...@@ -187,6 +200,7 @@ const PostsContainer = ({ className }) => {
onConfirm={onRejectConfirm} onConfirm={onRejectConfirm}
onCancel={onRejectCancel} onCancel={onRejectCancel}
confirming={rejectingProposal} confirming={rejectingProposal}
error={rejectingProposalError}
title="Zamítnout procedurální návrh?" title="Zamítnout procedurální návrh?"
yesActionLabel="Zamítnout návrh" yesActionLabel="Zamítnout návrh"
> >
...@@ -197,6 +211,7 @@ const PostsContainer = ({ className }) => { ...@@ -197,6 +211,7 @@ const PostsContainer = ({ className }) => {
onConfirm={onRejectByChairmanConfirm} onConfirm={onRejectByChairmanConfirm}
onCancel={onRejectByChairmanCancel} onCancel={onRejectByChairmanCancel}
confirming={rejectingProposalByChairman} confirming={rejectingProposalByChairman}
error={rejectingProposalByChairmanError}
title="Zamítnout procedurální návrh předsedajícícm?" title="Zamítnout procedurální návrh předsedajícícm?"
yesActionLabel="Zamítnout návrh předsedajícím" yesActionLabel="Zamítnout návrh předsedajícím"
> >
......
...@@ -40,7 +40,7 @@ export const useActionConfirm = (actionFn, actionArgs) => { ...@@ -40,7 +40,7 @@ export const useActionConfirm = (actionFn, actionArgs) => {
return [showConfirm, setShowConfirm, onActionConfirm, onActionCancel]; return [showConfirm, setShowConfirm, onActionConfirm, onActionCancel];
}; };
export const useActionLoading = (actionFn, actionArgs) => { export const useActionState = (actionFn, actionArgs) => {
const { 0: started, 1: finished } = actionFn.useWatch(actionArgs); const { 0: started, 1: finished, 2: result } = actionFn.useWatch(actionArgs);
return started && !finished; return [started && !finished, result.error ? result.message : null];
}; };
...@@ -7,7 +7,7 @@ import { activateProgramPoint } from "actions/program"; ...@@ -7,7 +7,7 @@ import { activateProgramPoint } from "actions/program";
import Button from "components/Button"; import Button from "components/Button";
import Chip from "components/Chip"; import Chip from "components/Chip";
import ModalConfirm from "components/modals/ModalConfirm"; import ModalConfirm from "components/modals/ModalConfirm";
import { useActionLoading, useItemActionConfirm } from "hooks"; import { useActionState, useItemActionConfirm } from "hooks";
import { AuthStore, ProgramStore } from "stores"; import { AuthStore, ProgramStore } from "stores";
const Schedule = () => { const Schedule = () => {
...@@ -20,7 +20,10 @@ const Schedule = () => { ...@@ -20,7 +20,10 @@ const Schedule = () => {
onActivateCancel, onActivateCancel,
] = useItemActionConfirm(activateProgramPoint); ] = useItemActionConfirm(activateProgramPoint);
const activating = useActionLoading(activateProgramPoint, entryToActivate); const [activating, activationError] = useActionState(
activateProgramPoint,
entryToActivate
);
return ( return (
<article className="container container--wide py-8 lg:py-24"> <article className="container container--wide py-8 lg:py-24">
...@@ -87,6 +90,7 @@ const Schedule = () => { ...@@ -87,6 +90,7 @@ const Schedule = () => {
onConfirm={onActivateConfirm} onConfirm={onActivateConfirm}
onCancel={onActivateCancel} onCancel={onActivateCancel}
confirming={activating} confirming={activating}
error={activationError}
title="Aktivovat bod programu?" title="Aktivovat bod programu?"
yesActionLabel="Aktivovat" yesActionLabel="Aktivovat"
> >
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment