gitscope
https://dev.kronoz.win/r/marzneshin.git
dashboard/src/modules/hosts/dialogs/mutation/index.tsx · v0.7.0
Source
1 d42c6e6 Mardin 2y ago import { type FC, useEffect } from "react";
2 3b7feef Mrdn 2y ago import {
3 4056c66 Dawsh 1y ago Button,
4 3b7feef Mrdn 2y ago Dialog,
5 4056c66 Dawsh 1y ago DialogContent,
6 3b7feef Mrdn 2y ago DialogHeader,
7 4056c66 Dawsh 1y ago DialogTitle,
8 3b7feef Mrdn 2y ago Form,
9 aa14012 Mrdn 2y ago ScrollArea,
10 7389ad0 Mardin 2y ago } from "@marzneshin/common/components";
11 0b152b5 Mrdn 2y ago import { useForm } from "react-hook-form";
12 0b152b5 Mrdn 2y ago import { zodResolver } from "@hookform/resolvers/zod";
13 0b152b5 Mrdn 2y ago import { useTranslation } from "react-i18next";
14 3b7feef Mrdn 2y ago import {
15 4056c66 Dawsh 1y ago type HostWithProfileSchemaType,
16 4056c66 Dawsh 1y ago type HostWithProfileType,
17 3b7feef Mrdn 2y ago useHostsCreationMutation,
18 0b152b5 Mrdn 2y ago useHostsUpdateMutation,
19 d636f3f Dawsh 2y ago } from "@marzneshin/modules/hosts";
20 4056c66 Dawsh 1y ago import { type MutationDialogProps, useDialog } from "@marzneshin/common/hooks";
21 d636f3f Dawsh 2y ago import { ProtocolType } from "@marzneshin/modules/inbounds";
22 d636f3f Dawsh 2y ago import { useProfileStrategy } from "./profiles";
23 4056c66 Dawsh 1y ago import {
24 4056c66 Dawsh 1y ago transformToDictionary,
25 4056c66 Dawsh 1y ago transformToFields,
26 4056c66 Dawsh 1y ago } from "@marzneshin/libs/dynamic-field";
27 3b7feef Mrdn 2y ago
28 4056c66 Dawsh 1y ago interface HostMutationDialogProps
29 4056c66 Dawsh 1y ago extends MutationDialogProps<HostWithProfileType> {
30 03b3dbc Mardin 2y ago inboundId?: number;
31 d636f3f Dawsh 2y ago protocol?: ProtocolType;
32 3b7feef Mrdn 2y ago }
33 3b7feef Mrdn 2y ago
34 d636f3f Dawsh 2y ago const transformFormValue = (values: any) => {
35 4056c66 Dawsh 1y ago if (!(values.alpn && values.fingerprint)) return values;
36 ec7410a Mardin 2y ago const port = values.port === "" ? null : values.port;
37 0b152b5 Mrdn 2y ago const alpn = values.alpn === "none" ? "" : values.alpn;
38 0b152b5 Mrdn 2y ago const fingerprint = values.fingerprint === "none" ? "" : values.fingerprint;
39 4056c66 Dawsh 1y ago const http_headers = values.http_headers;
40 4056c66 Dawsh 1y ago return { ...values, alpn, fingerprint, port, http_headers };
41 4056c66 Dawsh 1y ago };
42 4056c66 Dawsh 1y ago
43 4056c66 Dawsh 1y ago const transformFormValueHttpHeaders = (values: any) => {
44 4056c66 Dawsh 1y ago const http_headers = values.http_headers
45 4056c66 Dawsh 1y ago ? transformToDictionary(values.http_headers)
46 4056c66 Dawsh 1y ago : undefined;
47 4056c66 Dawsh 1y ago return { ...values, http_headers };
48 4056c66 Dawsh 1y ago };
49 4056c66 Dawsh 1y ago
50 4056c66 Dawsh 1y ago const formMutationToAPIAdapter = (values: HostWithProfileType) => {
51 4056c66 Dawsh 1y ago if (values.http_headers)
52 4056c66 Dawsh 1y ago return {
53 4056c66 Dawsh 1y ago ...values,
54 4056c66 Dawsh 1y ago http_headers: transformToFields(values.http_headers),
55 4056c66 Dawsh 1y ago };
56 4056c66 Dawsh 1y ago return values;
57 0b152b5 Mrdn 2y ago };
58 3b7feef Mrdn 2y ago
59 d42c6e6 Mardin 2y ago export const HostsMutationDialog: FC<HostMutationDialogProps> = ({
60 3b7feef Mrdn 2y ago entity,
61 d636f3f Dawsh 2y ago inboundId,
62 03b3dbc Mardin 2y ago onClose,
63 d636f3f Dawsh 2y ago protocol,
64 3b7feef Mrdn 2y ago }) => {
65 d42c6e6 Mardin 2y ago const [open, onOpenChange] = useDialog(true);
66 4056c66 Dawsh 1y ago const [Schema, ProfileFields, defaultValue] = useProfileStrategy(protocol);
67 d636f3f Dawsh 2y ago const form = useForm<HostWithProfileSchemaType>({
68 4056c66 Dawsh 1y ago defaultValues: entity ? formMutationToAPIAdapter(entity) : defaultValue,
69 d636f3f Dawsh 2y ago resolver: zodResolver(Schema),
70 3b7feef Mrdn 2y ago });
71 3b7feef Mrdn 2y ago const updateMutation = useHostsUpdateMutation();
72 3b7feef Mrdn 2y ago const createMutation = useHostsCreationMutation();
73 3b7feef Mrdn 2y ago const { t } = useTranslation();
74 3b7feef Mrdn 2y ago
75 4056c66 Dawsh 1y ago // TODO: Refactor value transformation for api using of
76 4056c66 Dawsh 1y ago // function composition to pipes and port-adapter patterns.
77 4056c66 Dawsh 1y ago // - [ ] ALPN and fingerprint
78 4056c66 Dawsh 1y ago // - [ ] HTTP headers (duplex adaptation)
79 d636f3f Dawsh 2y ago const submit = (values: HostWithProfileSchemaType) => {
80 4056c66 Dawsh 1y ago const host = transformFormValueHttpHeaders(transformFormValue(values));
81 7428e12 Mrdn 2y ago if (entity && entity.id !== undefined) {
82 7428e12 Mrdn 2y ago updateMutation.mutate({ hostId: entity.id, host });
83 03b3dbc Mardin 2y ago onOpenChange(false);
84 03b3dbc Mardin 2y ago } else if (inboundId !== undefined) {
85 7428e12 Mrdn 2y ago createMutation.mutate({ inboundId, host });
86 03b3dbc Mardin 2y ago onOpenChange(false);
87 3b7feef Mrdn 2y ago }
88 3b7feef Mrdn 2y ago };
89 3b7feef Mrdn 2y ago
90 03b3dbc Mardin 2y ago useEffect(() => {
91 03b3dbc Mardin 2y ago if (!open) onClose();
92 03b3dbc Mardin 2y ago }, [open, onClose]);
93 03b3dbc Mardin 2y ago
94 3b7feef Mrdn 2y ago useEffect(() => {
95 4056c66 Dawsh 1y ago if (entity) form.reset(formMutationToAPIAdapter(entity));
96 d636f3f Dawsh 2y ago else form.reset(defaultValue);
97 d636f3f Dawsh 2y ago }, [entity, form, open, defaultValue]);
98 3b7feef Mrdn 2y ago
99 3b7feef Mrdn 2y ago return (
100 3b7feef Mrdn 2y ago <Dialog open={open} onOpenChange={onOpenChange} defaultOpen={true}>
101 aa14012 Mrdn 2y ago <DialogContent className="min-w-full h-full md:h-auto md:min-w-[32rem]">
102 aa14012 Mrdn 2y ago <ScrollArea className="flex flex-col h-full p-0">
103 aa14012 Mrdn 2y ago <DialogHeader className="mb-3">
104 aa14012 Mrdn 2y ago <DialogTitle className="text-primary">
105 aa14012 Mrdn 2y ago {entity
106 aa14012 Mrdn 2y ago ? t("page.hosts.dialogs.edition.title")
107 aa14012 Mrdn 2y ago : t("page.hosts.dialogs.creation.title")}
108 aa14012 Mrdn 2y ago </DialogTitle>
109 aa14012 Mrdn 2y ago </DialogHeader>
110 aa14012 Mrdn 2y ago <Form {...form}>
111 aa14012 Mrdn 2y ago <form
112 aa14012 Mrdn 2y ago onSubmit={form.handleSubmit(submit)}
113 aa14012 Mrdn 2y ago className="h-full flex flex-col justify-between"
114 3b7feef Mrdn 2y ago >
115 d636f3f Dawsh 2y ago <ProfileFields />
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 };