gitscope
https://dev.kronoz.win/r/marzneshin.git
dashboard/src/features/services/dialogs/mutation.dialog.tsx · v0.3.0-alpha11
Source
1 3b7feef Mrdn 2y ago
2 3b7feef Mrdn 2y ago
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 FormItem,
10 3b7feef Mrdn 2y ago FormControl,
11 3b7feef Mrdn 2y ago FormMessage,
12 3b7feef Mrdn 2y ago FormLabel,
13 3b7feef Mrdn 2y ago Input,
14 3b7feef Mrdn 2y ago FormField,
15 3b7feef Mrdn 2y ago Button,
16 3b7feef Mrdn 2y ago Checkbox,
17 3b7feef Mrdn 2y ago Badge
18 3b7feef Mrdn 2y ago } from '@marzneshin/components'
19 857e289 Mrdn 2y ago import { FC } from 'react'
20 3b7feef Mrdn 2y ago import {
21 3b7feef Mrdn 2y ago ServiceType,
22 3b7feef Mrdn 2y ago useServicesCreationMutation,
23 3b7feef Mrdn 2y ago useServicesUpdateMutation,
24 3b7feef Mrdn 2y ago } from '@marzneshin/features/services'
25 3b7feef Mrdn 2y ago import { useInboundsQuery } from '@marzneshin/features/inbounds'
26 3b7feef Mrdn 2y ago import { useTranslation } from 'react-i18next'
27 3b7feef Mrdn 2y ago import { z } from 'zod'
28 3b7feef Mrdn 2y ago import { cn } from '@marzneshin/utils'
29 3b7feef Mrdn 2y ago import { Box, GlobeLock } from 'lucide-react'
30 857e289 Mrdn 2y ago import { useMutationDialog } from '@marzneshin/hooks'
31 3b7feef Mrdn 2y ago
32 3b7feef Mrdn 2y ago export const ServiceSchema = z.object({
33 3b7feef Mrdn 2y ago id: z.number().optional(),
34 3b7feef Mrdn 2y ago inbounds: z.array(z.number()).refine((value) => value.some((item) => item), {
35 3b7feef Mrdn 2y ago message: "You have to select at least one inbound.",
36 3b7feef Mrdn 2y ago }),
37 3b7feef Mrdn 2y ago name: z.string().trim().min(1)
38 3b7feef Mrdn 2y ago })
39 3b7feef Mrdn 2y ago type ServiceCreateType = z.infer<typeof ServiceSchema>
40 3b7feef Mrdn 2y ago
41 3b7feef Mrdn 2y ago interface MutationDialogProps {
42 3b7feef Mrdn 2y ago entity: ServiceType | null
43 3b7feef Mrdn 2y ago open: boolean
44 3b7feef Mrdn 2y ago onOpenChange: (state: boolean) => void
45 3b7feef Mrdn 2y ago }
46 3b7feef Mrdn 2y ago
47 3b7feef Mrdn 2y ago const getDefaultValues = (): ServiceCreateType => ({
48 3b7feef Mrdn 2y ago name: '',
49 3b7feef Mrdn 2y ago inbounds: [],
50 3b7feef Mrdn 2y ago })
51 3b7feef Mrdn 2y ago
52 3b7feef Mrdn 2y ago export const MutationDialog: FC<MutationDialogProps> = ({ entity, open, onOpenChange }) => {
53 3b7feef Mrdn 2y ago const isEditing = entity !== null
54 3b7feef Mrdn 2y ago const updateMutation = useServicesUpdateMutation();
55 3b7feef Mrdn 2y ago const createMutation = useServicesCreationMutation();
56 3b7feef Mrdn 2y ago const { data: inbounds } = useInboundsQuery()
57 857e289 Mrdn 2y ago const { form, handleSubmit } = useMutationDialog({
58 857e289 Mrdn 2y ago entity,
59 857e289 Mrdn 2y ago updateMutation,
60 857e289 Mrdn 2y ago createMutation,
61 857e289 Mrdn 2y ago getDefaultValue: getDefaultValues,
62 857e289 Mrdn 2y ago schema: ServiceSchema,
63 857e289 Mrdn 2y ago onOpenChange,
64 3b7feef Mrdn 2y ago })
65 857e289 Mrdn 2y ago const { t } = useTranslation()
66 3b7feef Mrdn 2y ago return (
67 3b7feef Mrdn 2y ago <Dialog open={open} onOpenChange={onOpenChange} defaultOpen={true}>
68 3b7feef Mrdn 2y ago <DialogContent>
69 3b7feef Mrdn 2y ago <DialogHeader>
70 3b7feef Mrdn 2y ago <DialogTitle className="text-primary">
71 3b7feef Mrdn 2y ago {isEditing ?
72 3b7feef Mrdn 2y ago t('page.services.dialogs.edition.title') :
73 3b7feef Mrdn 2y ago t('page.services.dialogs.creation.title')}
74 3b7feef Mrdn 2y ago </DialogTitle>
75 3b7feef Mrdn 2y ago </DialogHeader>
76 3b7feef Mrdn 2y ago <Form {...form} >
77 857e289 Mrdn 2y ago <form onSubmit={handleSubmit} >
78 3b7feef Mrdn 2y ago <FormField
79 3b7feef Mrdn 2y ago control={form.control}
80 3b7feef Mrdn 2y ago name="name"
81 3b7feef Mrdn 2y ago render={({ field }) => (
82 3b7feef Mrdn 2y ago <FormItem>
83 3b7feef Mrdn 2y ago <FormLabel>{t('name')}</FormLabel>
84 3b7feef Mrdn 2y ago <FormControl>
85 3b7feef Mrdn 2y ago <Input {...field} />
86 3b7feef Mrdn 2y ago </FormControl>
87 3b7feef Mrdn 2y ago <FormMessage />
88 3b7feef Mrdn 2y ago </FormItem>
89 3b7feef Mrdn 2y ago )}
90 3b7feef Mrdn 2y ago />
91 3b7feef Mrdn 2y ago <FormField
92 3b7feef Mrdn 2y ago control={form.control}
93 3b7feef Mrdn 2y ago name="inbounds"
94 3b7feef Mrdn 2y ago render={() => (
95 3b7feef Mrdn 2y ago <FormItem>
96 3b7feef Mrdn 2y ago <FormLabel>{t('inbounds')}</FormLabel>
97 3b7feef Mrdn 2y ago {inbounds.map((inbound) => (
98 3b7feef Mrdn 2y ago <FormField
99 3b7feef Mrdn 2y ago key={inbound.id}
100 3b7feef Mrdn 2y ago control={form.control}
101 3b7feef Mrdn 2y ago name="inbounds"
102 3b7feef Mrdn 2y ago render={({ field }) => (
103 3b7feef Mrdn 2y ago <FormItem key={inbound.id} >
104 3b7feef Mrdn 2y ago <FormControl>
105 3b7feef Mrdn 2y ago <div
106 3b7feef Mrdn 2y ago className={cn("flex flex-row items-center p-3 space-y-0 space-x-3 rounded-md border", { "bg-secondary": field.value?.includes(inbound.id) })}>
107 3b7feef Mrdn 2y ago <Checkbox
108 3b7feef Mrdn 2y ago checked={field.value?.includes(inbound.id)}
109 3b7feef Mrdn 2y ago onCheckedChange={(checked) => {
110 3b7feef Mrdn 2y ago return checked
111 3b7feef Mrdn 2y ago ? field.onChange([...field.value, inbound.id])
112 3b7feef Mrdn 2y ago : field.onChange(
113 3b7feef Mrdn 2y ago field.value?.filter(
114 857e289 Mrdn 2y ago (value: number) => value !== inbound.id
115 3b7feef Mrdn 2y ago )
116 3b7feef Mrdn 2y ago )
117 3b7feef Mrdn 2y ago }}
118 3b7feef Mrdn 2y ago />
119 3b7feef Mrdn 2y ago <FormLabel className="flex flex-row justify-between items-center w-full">
120 3b7feef Mrdn 2y ago {inbound.tag}
121 3b7feef Mrdn 2y ago <div className="flex gap-2">
122 3b7feef Mrdn 2y ago <Badge className="py-1 px-2"> <GlobeLock className="mr-1 w-4" /> {inbound.protocol} </Badge>
123 3b7feef Mrdn 2y ago <Badge className="py-1 px-2"> <Box className="mr-1 w-4" /> {inbound.node.name} </Badge>
124 3b7feef Mrdn 2y ago </div>
125 3b7feef Mrdn 2y ago </FormLabel>
126 3b7feef Mrdn 2y ago </div>
127 3b7feef Mrdn 2y ago </FormControl>
128 3b7feef Mrdn 2y ago </FormItem>
129 3b7feef Mrdn 2y ago )}
130 3b7feef Mrdn 2y ago />
131 3b7feef Mrdn 2y ago ))}
132 3b7feef Mrdn 2y ago <FormMessage />
133 3b7feef Mrdn 2y ago </FormItem>
134 3b7feef Mrdn 2y ago )}
135 3b7feef Mrdn 2y ago />
136 3b7feef Mrdn 2y ago <Button
137 3b7feef Mrdn 2y ago className="mt-3 w-full font-semibold"
138 3b7feef Mrdn 2y ago type="submit"
139 3b7feef Mrdn 2y ago disabled={form.formState.isSubmitting}>
140 3b7feef Mrdn 2y ago {t('submit')}
141 3b7feef Mrdn 2y ago </Button>
142 3b7feef Mrdn 2y ago </form>
143 3b7feef Mrdn 2y ago </Form>
144 3b7feef Mrdn 2y ago </DialogContent>
145 3b7feef Mrdn 2y ago </Dialog >
146 3b7feef Mrdn 2y ago )
147 3b7feef Mrdn 2y ago }