summaryrefslogtreecommitdiffhomepage
path: root/frontend/src/components/async/MutateAction.tsx
blob: 92c102ea90ee5332ccc5ca21e08c160771ba0b7e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import { useCallback, useState } from "react";
import { UseMutationResult } from "@tanstack/react-query";
import { Action } from "@/components/inputs";
import { ActionProps } from "@/components/inputs/Action";

type MutateActionProps<DATA, VAR> = Omit<
  ActionProps,
  "onClick" | "loading" | "color"
> & {
  mutation: UseMutationResult<DATA, unknown, VAR>;
  args: () => VAR | null;
  onSuccess?: (args: DATA) => void;
  onError?: () => void;
  noReset?: boolean;
};

function MutateAction<DATA, VAR>({
  mutation,
  onSuccess,
  onError,
  args,
  ...props
}: MutateActionProps<DATA, VAR>) {
  const { mutateAsync } = mutation;

  const [isLoading, setLoading] = useState(false);

  const onClick = useCallback(async () => {
    setLoading(true);
    try {
      const argument = args();
      if (argument !== null) {
        const data = await mutateAsync(argument);
        onSuccess?.(data);
      } else {
        onError?.();
      }
    } catch (error) {
      onError?.();
    }
    setLoading(false);
  }, [args, mutateAsync, onError, onSuccess]);

  return <Action {...props} loading={isLoading} onClick={onClick}></Action>;
}

export default MutateAction;