gitscope
https://dev.kronoz.win/r/marzneshin.git
dashboard/src/features/hosts/dialogs/mutation/index.tsx · v0.3.0
Source
1 aa14012 Mrdn 2y ago import { useEffect } from "react";
2 aa14012 Mrdn 2y ago import type { FC } from "react";
3 3b7feef Mrdn 2y ago import {
4 3b7feef Mrdn 2y ago DialogTitle,
5 3b7feef Mrdn 2y ago DialogContent,
6 3b7feef Mrdn 2y ago Dialog,
7 3b7feef Mrdn 2y ago DialogHeader,
8 3b7feef Mrdn 2y ago Form,
9 3b7feef Mrdn 2y ago Button,
10 0b152b5 Mrdn 2y ago Accordion,
11 0b152b5 Mrdn 2y ago AccordionContent,
12 0b152b5 Mrdn 2y ago AccordionItem,
13 0b152b5 Mrdn 2y ago AccordionTrigger,
14 aa14012 Mrdn 2y ago ScrollArea,
15 aa14012 Mrdn 2y ago HStack,
16 0b152b5 Mrdn 2y ago } from "@marzneshin/components";
17 0b152b5 Mrdn 2y ago import { useForm } from "react-hook-form";
18 0b152b5 Mrdn 2y ago import { zodResolver } from "@hookform/resolvers/zod";
19 0b152b5 Mrdn 2y ago import { useTranslation } from "react-i18next";
20 3b7feef Mrdn 2y ago import {
21 3b7feef Mrdn 2y ago HostSchema,
22 3b7feef Mrdn 2y ago getDefaultValues,
23 3b7feef Mrdn 2y ago useHostsCreationMutation,
24 0b152b5 Mrdn 2y ago useHostsUpdateMutation,
25 3b7feef Mrdn 2y ago } from "@marzneshin/features/hosts";
26 aa14012 Mrdn 2y ago import type { HostType } from "@marzneshin/features/hosts";
27 7428e12 Mrdn 2y ago import { RemarkField } from "./fields/remark";
28 7428e12 Mrdn 2y ago import {
29 7428e12 Mrdn 2y ago AddressField,
30 7428e12 Mrdn 2y ago PortField,
31 7428e12 Mrdn 2y ago HostField,
32 0b152b5 Mrdn 2y ago MuxField,
33 0b152b5 Mrdn 2y ago FragmentField,
34 7428e12 Mrdn 2y ago PathField,
35 7428e12 Mrdn 2y ago SecurityFields,
36 7428e12 Mrdn 2y ago } from "./fields";
37 3b7feef Mrdn 2y ago
38 3b7feef Mrdn 2y ago interface MutationDialogProps {
39 0b152b5 Mrdn 2y ago entity: HostType | null;
40 0b152b5 Mrdn 2y ago open: boolean;
41 0b152b5 Mrdn 2y ago inboundId: number;
42 0b152b5 Mrdn 2y ago onOpenChange: (state: boolean) => void;
43 3b7feef Mrdn 2y ago }
44 3b7feef Mrdn 2y ago
45 7428e12 Mrdn 2y ago const transformFormValue = (values: HostType) => {
46 ec7410a Mardin 2y ago const port = values.port === "" ? null : values.port;
47 0b152b5 Mrdn 2y ago const alpn = values.alpn === "none" ? "" : values.alpn;
48 0b152b5 Mrdn 2y ago const fingerprint = values.fingerprint === "none" ? "" : values.fingerprint;
49 ec7410a Mardin 2y ago return { ...values, alpn, fingerprint, port };
50 0b152b5 Mrdn 2y ago };
51 3b7feef Mrdn 2y ago
52 3b7feef Mrdn 2y ago export const HostsMutationDialog: FC<MutationDialogProps> = ({
53 3b7feef Mrdn 2y ago inboundId,
54 3b7feef Mrdn 2y ago entity,
55 3b7feef Mrdn 2y ago open,
56 3b7feef Mrdn 2y ago onOpenChange,
57 3b7feef Mrdn 2y ago }) => {
58 3b7feef Mrdn 2y ago const form = useForm({
59 3b7feef Mrdn 2y ago defaultValues: entity ? entity : getDefaultValues(),
60 0b152b5 Mrdn 2y ago resolver: zodResolver(HostSchema),
61 3b7feef Mrdn 2y ago });
62 3b7feef Mrdn 2y ago const updateMutation = useHostsUpdateMutation();
63 3b7feef Mrdn 2y ago const createMutation = useHostsCreationMutation();
64 3b7feef Mrdn 2y ago const { t } = useTranslation();
65 3b7feef Mrdn 2y ago
66 3b7feef Mrdn 2y ago const submit = (values: HostType) => {
67 0b152b5 Mrdn 2y ago const host = transformFormValue(values);
68 7428e12 Mrdn 2y ago if (entity && entity.id !== undefined) {
69 7428e12 Mrdn 2y ago updateMutation.mutate({ hostId: entity.id, host });
70 3b7feef Mrdn 2y ago } else {
71 7428e12 Mrdn 2y ago createMutation.mutate({ inboundId, host });
72 3b7feef Mrdn 2y ago }
73 3b7feef Mrdn 2y ago onOpenChange(false);
74 3b7feef Mrdn 2y ago };
75 3b7feef Mrdn 2y ago
76 3b7feef Mrdn 2y ago useEffect(() => {
77 3b7feef Mrdn 2y ago if (entity) form.reset(entity);
78 3b7feef Mrdn 2y ago else form.reset(getDefaultValues());
79 f9ed408 Mardin 2y ago }, [entity, form, open]);
80 3b7feef Mrdn 2y ago
81 3b7feef Mrdn 2y ago return (
82 3b7feef Mrdn 2y ago <Dialog open={open} onOpenChange={onOpenChange} defaultOpen={true}>
83 aa14012 Mrdn 2y ago <DialogContent className="min-w-full h-full md:h-auto md:min-w-[32rem]">
84 aa14012 Mrdn 2y ago <ScrollArea className="flex flex-col h-full p-0">
85 aa14012 Mrdn 2y ago <DialogHeader className="mb-3">
86 aa14012 Mrdn 2y ago <DialogTitle className="text-primary">
87 aa14012 Mrdn 2y ago {entity
88 aa14012 Mrdn 2y ago ? t("page.hosts.dialogs.edition.title")
89 aa14012 Mrdn 2y ago : t("page.hosts.dialogs.creation.title")}
90 aa14012 Mrdn 2y ago </DialogTitle>
91 aa14012 Mrdn 2y ago </DialogHeader>
92 aa14012 Mrdn 2y ago <Form {...form}>
93 aa14012 Mrdn 2y ago <form
94 aa14012 Mrdn 2y ago onSubmit={form.handleSubmit(submit)}
95 aa14012 Mrdn 2y ago className="h-full flex flex-col justify-between"
96 3b7feef Mrdn 2y ago >
97 aa14012 Mrdn 2y ago <RemarkField />
98 aa14012 Mrdn 2y ago <HStack className="gap-2 items-start">
99 aa14012 Mrdn 2y ago <AddressField />
100 aa14012 Mrdn 2y ago <PortField />
101 aa14012 Mrdn 2y ago </HStack>
102 aa14012 Mrdn 2y ago <Accordion type="single" collapsible>
103 aa14012 Mrdn 2y ago <AccordionItem value="item-1">
104 aa14012 Mrdn 2y ago <AccordionTrigger>{t("advanced-options")}</AccordionTrigger>
105 aa14012 Mrdn 2y ago <AccordionContent>
106 aa14012 Mrdn 2y ago <div className="flex flex-row gap-2 items-start">
107 aa14012 Mrdn 2y ago <HostField />
108 aa14012 Mrdn 2y ago <PathField />
109 aa14012 Mrdn 2y ago </div>
110 aa14012 Mrdn 2y ago <FragmentField />
111 aa14012 Mrdn 2y ago <MuxField />
112 aa14012 Mrdn 2y ago <SecurityFields />
113 aa14012 Mrdn 2y ago </AccordionContent>
114 aa14012 Mrdn 2y ago </AccordionItem>
115 aa14012 Mrdn 2y ago </Accordion>
116 aa14012 Mrdn 2y ago <Button
117 aa14012 Mrdn 2y ago className="mt-3 w-full font-semibold"
118 aa14012 Mrdn 2y ago type="submit"
119 aa14012 Mrdn 2y ago disabled={form.formState.isSubmitting}
120 aa14012 Mrdn 2y ago >
121 aa14012 Mrdn 2y ago {t("submit")}
122 aa14012 Mrdn 2y ago </Button>
123 aa14012 Mrdn 2y ago </form>
124 aa14012 Mrdn 2y ago </Form>
125 aa14012 Mrdn 2y ago </ScrollArea>
126 3b7feef Mrdn 2y ago </DialogContent>
127 3b7feef Mrdn 2y ago </Dialog>
128 3b7feef Mrdn 2y ago );
129 3b7feef Mrdn 2y ago };