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