gitscope
https://dev.kronoz.win/r/marzneshin.git
dashboard/src/features/hosts/dialogs/mutation/fields/fragment.tsx · v0.3.0
Source
1 0b152b5 Mrdn 2y ago import {
2 aa14012 Mrdn 2y ago FormControl,
3 aa14012 Mrdn 2y ago FormField,
4 aa14012 Mrdn 2y ago FormItem,
5 aa14012 Mrdn 2y ago FormLabel,
6 aa14012 Mrdn 2y ago Input,
7 aa14012 Mrdn 2y ago Button,
8 aa14012 Mrdn 2y ago Popover,
9 aa14012 Mrdn 2y ago PopoverContent,
10 aa14012 Mrdn 2y ago PopoverTrigger,
11 0b152b5 Mrdn 2y ago } from "@marzneshin/components";
12 aa14012 Mrdn 2y ago import type { FieldErrors, FieldError } from "react-hook-form";
13 aa14012 Mrdn 2y ago import { useWatch, useFormContext } from "react-hook-form";
14 0b152b5 Mrdn 2y ago import { useTranslation } from "react-i18next";
15 0b152b5 Mrdn 2y ago import { MailWarning, TrashIcon } from "lucide-react";
16 aa14012 Mrdn 2y ago import type { FC } from "react";
17 0b152b5 Mrdn 2y ago
18 0b152b5 Mrdn 2y ago interface FragmentForm {
19 aa14012 Mrdn 2y ago fragment: {
20 aa14012 Mrdn 2y ago packets: FieldError;
21 aa14012 Mrdn 2y ago length: FieldError;
22 aa14012 Mrdn 2y ago interval: FieldError;
23 aa14012 Mrdn 2y ago };
24 0b152b5 Mrdn 2y ago }
25 0b152b5 Mrdn 2y ago
26 0b152b5 Mrdn 2y ago const FragmentErrorPopover: FC = () => {
27 aa14012 Mrdn 2y ago const form = useFormContext();
28 aa14012 Mrdn 2y ago const { t } = useTranslation();
29 aa14012 Mrdn 2y ago const errors = form.formState.errors as FieldErrors<FragmentForm>;
30 aa14012 Mrdn 2y ago return (
31 aa14012 Mrdn 2y ago <Popover>
32 aa14012 Mrdn 2y ago <PopoverTrigger>
33 aa14012 Mrdn 2y ago <MailWarning className="p-0 size-5 text-destructive bg-primary-background" />
34 aa14012 Mrdn 2y ago </PopoverTrigger>
35 aa14012 Mrdn 2y ago <PopoverContent className="bg-destructive-accent text-sm">
36 aa14012 Mrdn 2y ago <ul className="my-6 ml-3 list-disc [&>li]:mt-1 mt-0">
37 aa14012 Mrdn 2y ago {errors.fragment?.length?.message && (
38 aa14012 Mrdn 2y ago <li>
39 aa14012 Mrdn 2y ago <b>Length:</b> {t(errors.fragment.length.message as string)}
40 aa14012 Mrdn 2y ago </li>
41 aa14012 Mrdn 2y ago )}
42 aa14012 Mrdn 2y ago {errors.fragment?.packets?.message && (
43 aa14012 Mrdn 2y ago <li>
44 aa14012 Mrdn 2y ago <b>Packets:</b> {t(errors.fragment.packets.message as string)}
45 aa14012 Mrdn 2y ago </li>
46 aa14012 Mrdn 2y ago )}
47 aa14012 Mrdn 2y ago {errors.fragment?.interval?.message && (
48 aa14012 Mrdn 2y ago <li>
49 aa14012 Mrdn 2y ago <b>Interval:</b> {t(errors.fragment.interval.message as string)}
50 aa14012 Mrdn 2y ago </li>
51 aa14012 Mrdn 2y ago )}
52 aa14012 Mrdn 2y ago </ul>
53 aa14012 Mrdn 2y ago </PopoverContent>
54 aa14012 Mrdn 2y ago </Popover>
55 aa14012 Mrdn 2y ago );
56 0b152b5 Mrdn 2y ago };
57 0b152b5 Mrdn 2y ago
58 0b152b5 Mrdn 2y ago export const FragmentField = () => {
59 aa14012 Mrdn 2y ago const { t } = useTranslation();
60 aa14012 Mrdn 2y ago const form = useFormContext();
61 aa14012 Mrdn 2y ago const errors = form.formState.errors as FieldErrors<FragmentForm>;
62 aa14012 Mrdn 2y ago const fragment = useWatch({ name: "fragment" });
63 aa14012 Mrdn 2y ago const disabled = fragment === null || fragment === undefined;
64 0b152b5 Mrdn 2y ago
65 aa14012 Mrdn 2y ago const enable = () => {
66 aa14012 Mrdn 2y ago form.setValue(
67 aa14012 Mrdn 2y ago "fragment",
68 aa14012 Mrdn 2y ago { length: "", packets: "", interval: "" },
69 aa14012 Mrdn 2y ago {
70 aa14012 Mrdn 2y ago shouldTouch: true,
71 aa14012 Mrdn 2y ago shouldDirty: true,
72 aa14012 Mrdn 2y ago },
73 aa14012 Mrdn 2y ago );
74 aa14012 Mrdn 2y ago };
75 0b152b5 Mrdn 2y ago
76 aa14012 Mrdn 2y ago const disable = () => {
77 aa14012 Mrdn 2y ago form.setValue("fragment.length", "");
78 aa14012 Mrdn 2y ago form.setValue("fragment.packets", "");
79 aa14012 Mrdn 2y ago form.setValue("fragment.interval", "");
80 aa14012 Mrdn 2y ago form.setValue("fragment", null, {
81 aa14012 Mrdn 2y ago shouldValidate: true,
82 aa14012 Mrdn 2y ago shouldTouch: false,
83 aa14012 Mrdn 2y ago shouldDirty: false,
84 aa14012 Mrdn 2y ago });
85 aa14012 Mrdn 2y ago };
86 0b152b5 Mrdn 2y ago
87 aa14012 Mrdn 2y ago const hasFragmentErrors = (errors: FieldErrors<FragmentForm>) =>
88 aa14012 Mrdn 2y ago errors.fragment?.packets ||
89 aa14012 Mrdn 2y ago errors.fragment?.length ||
90 aa14012 Mrdn 2y ago errors.fragment?.interval;
91 0b152b5 Mrdn 2y ago
92 aa14012 Mrdn 2y ago return (
93 aa14012 Mrdn 2y ago <FormField
94 aa14012 Mrdn 2y ago control={form.control}
95 aa14012 Mrdn 2y ago name="fragment"
96 aa14012 Mrdn 2y ago render={() => (
97 aa14012 Mrdn 2y ago <FormItem className="my-2 w-full">
98 aa14012 Mrdn 2y ago <FormLabel className="flex flex-row justify-between items-center">
99 aa14012 Mrdn 2y ago {t("fragment")}
100 aa14012 Mrdn 2y ago <div className="flex flex-row items-center gap-2">
101 aa14012 Mrdn 2y ago {hasFragmentErrors(errors) && <FragmentErrorPopover />}
102 aa14012 Mrdn 2y ago {!disabled && (
103 aa14012 Mrdn 2y ago <Button
104 aa14012 Mrdn 2y ago variant="destructive"
105 aa14012 Mrdn 2y ago className="p-0 size-5 bg-primary-background"
106 aa14012 Mrdn 2y ago onClick={(e) => {
107 aa14012 Mrdn 2y ago e.preventDefault();
108 aa14012 Mrdn 2y ago disable();
109 aa14012 Mrdn 2y ago }}
110 aa14012 Mrdn 2y ago >
111 aa14012 Mrdn 2y ago <TrashIcon className="text-red-400" />
112 aa14012 Mrdn 2y ago </Button>
113 aa14012 Mrdn 2y ago )}
114 aa14012 Mrdn 2y ago </div>
115 aa14012 Mrdn 2y ago </FormLabel>
116 0b152b5 Mrdn 2y ago
117 aa14012 Mrdn 2y ago <FormControl>
118 aa14012 Mrdn 2y ago <div className="flex flex-row w-full items-center">
119 aa14012 Mrdn 2y ago {!disabled ? (
120 aa14012 Mrdn 2y ago <>
121 aa14012 Mrdn 2y ago <FormField
122 aa14012 Mrdn 2y ago name="fragment.packets"
123 aa14012 Mrdn 2y ago render={({ field }) => (
124 aa14012 Mrdn 2y ago <div className="flex flex-col">
125 aa14012 Mrdn 2y ago <FormItem>
126 aa14012 Mrdn 2y ago <FormLabel className="font-medium">
127 aa14012 Mrdn 2y ago {t("page.hosts.fragment.packets")}
128 aa14012 Mrdn 2y ago </FormLabel>
129 aa14012 Mrdn 2y ago <FormControl>
130 aa14012 Mrdn 2y ago <Input
131 aa14012 Mrdn 2y ago className="border rounded-none rounded-s-lg p-2 w-full"
132 aa14012 Mrdn 2y ago {...field}
133 aa14012 Mrdn 2y ago />
134 aa14012 Mrdn 2y ago </FormControl>
135 aa14012 Mrdn 2y ago </FormItem>
136 aa14012 Mrdn 2y ago </div>
137 aa14012 Mrdn 2y ago )}
138 aa14012 Mrdn 2y ago />
139 aa14012 Mrdn 2y ago <FormField
140 aa14012 Mrdn 2y ago name="fragment.length"
141 aa14012 Mrdn 2y ago render={({ field }) => (
142 aa14012 Mrdn 2y ago <div className="flex flex-col">
143 aa14012 Mrdn 2y ago <FormItem>
144 aa14012 Mrdn 2y ago <FormLabel className="font-medium">
145 aa14012 Mrdn 2y ago {t("page.hosts.fragment.length")}
146 aa14012 Mrdn 2y ago </FormLabel>
147 aa14012 Mrdn 2y ago <FormControl>
148 aa14012 Mrdn 2y ago <Input
149 aa14012 Mrdn 2y ago className="rounded-none w-full p-2"
150 aa14012 Mrdn 2y ago {...field}
151 aa14012 Mrdn 2y ago />
152 aa14012 Mrdn 2y ago </FormControl>
153 aa14012 Mrdn 2y ago </FormItem>
154 aa14012 Mrdn 2y ago </div>
155 aa14012 Mrdn 2y ago )}
156 aa14012 Mrdn 2y ago />
157 aa14012 Mrdn 2y ago <FormField
158 aa14012 Mrdn 2y ago name="fragment.interval"
159 aa14012 Mrdn 2y ago render={({ field }) => (
160 aa14012 Mrdn 2y ago <div className="flex flex-col">
161 aa14012 Mrdn 2y ago <FormItem>
162 aa14012 Mrdn 2y ago <FormLabel className="font-medium">
163 aa14012 Mrdn 2y ago {t("page.hosts.fragment.interval")}
164 aa14012 Mrdn 2y ago </FormLabel>
165 aa14012 Mrdn 2y ago <FormControl>
166 aa14012 Mrdn 2y ago <Input
167 aa14012 Mrdn 2y ago className="border w-full rounded-none rounded-e-lg p-2"
168 aa14012 Mrdn 2y ago {...field}
169 aa14012 Mrdn 2y ago />
170 aa14012 Mrdn 2y ago </FormControl>
171 aa14012 Mrdn 2y ago </FormItem>
172 aa14012 Mrdn 2y ago </div>
173 aa14012 Mrdn 2y ago )}
174 aa14012 Mrdn 2y ago />
175 aa14012 Mrdn 2y ago </>
176 aa14012 Mrdn 2y ago ) : (
177 aa14012 Mrdn 2y ago <Button
178 aa14012 Mrdn 2y ago className="border w-full"
179 aa14012 Mrdn 2y ago variant="ghost"
180 aa14012 Mrdn 2y ago onClick={(e) => {
181 aa14012 Mrdn 2y ago e.preventDefault();
182 aa14012 Mrdn 2y ago enable();
183 aa14012 Mrdn 2y ago }}
184 aa14012 Mrdn 2y ago >
185 aa14012 Mrdn 2y ago {t("disabled")}
186 aa14012 Mrdn 2y ago </Button>
187 aa14012 Mrdn 2y ago )}
188 aa14012 Mrdn 2y ago </div>
189 aa14012 Mrdn 2y ago </FormControl>
190 aa14012 Mrdn 2y ago </FormItem>
191 aa14012 Mrdn 2y ago )}
192 aa14012 Mrdn 2y ago />
193 aa14012 Mrdn 2y ago );
194 0b152b5 Mrdn 2y ago };