You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

parameter-dialog.tsx 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. import { Button } from '@/components/ui/button';
  2. import {
  3. Dialog,
  4. DialogContent,
  5. DialogFooter,
  6. DialogHeader,
  7. DialogTitle,
  8. } from '@/components/ui/dialog';
  9. import {
  10. Form,
  11. FormControl,
  12. FormField,
  13. FormItem,
  14. FormLabel,
  15. FormMessage,
  16. } from '@/components/ui/form';
  17. import { Input } from '@/components/ui/input';
  18. import { RAGFlowSelect, RAGFlowSelectOptionType } from '@/components/ui/select';
  19. import { Switch } from '@/components/ui/switch';
  20. import { useTranslate } from '@/hooks/common-hooks';
  21. import { IModalProps } from '@/interfaces/common';
  22. import { zodResolver } from '@hookform/resolvers/zod';
  23. import { isEmpty } from 'lodash';
  24. import { ChangeEvent, useEffect, useMemo } from 'react';
  25. import { useForm, useWatch } from 'react-hook-form';
  26. import { useTranslation } from 'react-i18next';
  27. import { z } from 'zod';
  28. import { BeginQueryType, BeginQueryTypeIconMap } from '../../constant';
  29. import { BeginQuery } from '../../interface';
  30. import { BeginDynamicOptions } from './begin-dynamic-options';
  31. type ModalFormProps = {
  32. initialValue: BeginQuery;
  33. otherThanCurrentQuery: BeginQuery[];
  34. submit(values: any): void;
  35. };
  36. const FormId = 'BeginParameterForm';
  37. function ParameterForm({
  38. initialValue,
  39. otherThanCurrentQuery,
  40. submit,
  41. }: ModalFormProps) {
  42. const { t } = useTranslate('flow');
  43. const FormSchema = z.object({
  44. type: z.string(),
  45. key: z
  46. .string()
  47. .trim()
  48. .min(1)
  49. .refine(
  50. (value) =>
  51. !value || !otherThanCurrentQuery.some((x) => x.key === value),
  52. { message: 'The key cannot be repeated!' },
  53. ),
  54. optional: z.boolean(),
  55. name: z.string().trim().min(1),
  56. options: z
  57. .array(z.object({ value: z.string().or(z.boolean()).or(z.number()) }))
  58. .optional(),
  59. });
  60. const form = useForm<z.infer<typeof FormSchema>>({
  61. resolver: zodResolver(FormSchema),
  62. mode: 'onChange',
  63. defaultValues: {
  64. type: BeginQueryType.Line,
  65. optional: false,
  66. key: '',
  67. name: '',
  68. options: [],
  69. },
  70. });
  71. const options = useMemo(() => {
  72. return Object.values(BeginQueryType).reduce<RAGFlowSelectOptionType[]>(
  73. (pre, cur) => {
  74. const Icon = BeginQueryTypeIconMap[cur];
  75. return [
  76. ...pre,
  77. {
  78. label: (
  79. <div className="flex items-center gap-2">
  80. <Icon
  81. className={`size-${cur === BeginQueryType.Options ? 4 : 5}`}
  82. ></Icon>
  83. {t(cur.toLowerCase())}
  84. </div>
  85. ),
  86. value: cur,
  87. },
  88. ];
  89. },
  90. [],
  91. );
  92. }, []);
  93. const type = useWatch({
  94. control: form.control,
  95. name: 'type',
  96. });
  97. useEffect(() => {
  98. if (!isEmpty(initialValue)) {
  99. form.reset({
  100. ...initialValue,
  101. options: initialValue.options?.map((x) => ({ value: x })),
  102. });
  103. }
  104. }, [form, initialValue]);
  105. function onSubmit(data: z.infer<typeof FormSchema>) {
  106. const values = { ...data, options: data.options?.map((x) => x.value) };
  107. console.log('🚀 ~ onSubmit ~ values:', values);
  108. submit(values);
  109. }
  110. const handleKeyChange = (e: ChangeEvent<HTMLInputElement>) => {
  111. const name = form.getValues().name || '';
  112. form.setValue('key', e.target.value.trim());
  113. if (!name) {
  114. form.setValue('name', e.target.value.trim());
  115. }
  116. };
  117. return (
  118. <Form {...form}>
  119. <form
  120. onSubmit={form.handleSubmit(onSubmit)}
  121. id={FormId}
  122. className="space-y-5"
  123. autoComplete="off"
  124. >
  125. <FormField
  126. name="type"
  127. control={form.control}
  128. render={({ field }) => (
  129. <FormItem>
  130. <FormLabel>Type</FormLabel>
  131. <FormControl>
  132. <RAGFlowSelect {...field} options={options} />
  133. </FormControl>
  134. <FormMessage />
  135. </FormItem>
  136. )}
  137. />
  138. <FormField
  139. name="key"
  140. control={form.control}
  141. render={({ field }) => (
  142. <FormItem>
  143. <FormLabel>Key</FormLabel>
  144. <FormControl>
  145. <Input {...field} autoComplete="off" onBlur={handleKeyChange} />
  146. </FormControl>
  147. <FormMessage />
  148. </FormItem>
  149. )}
  150. />
  151. <FormField
  152. name="name"
  153. control={form.control}
  154. render={({ field }) => (
  155. <FormItem>
  156. <FormLabel>Name</FormLabel>
  157. <FormControl>
  158. <Input {...field} />
  159. </FormControl>
  160. <FormMessage />
  161. </FormItem>
  162. )}
  163. />
  164. <FormField
  165. name="optional"
  166. control={form.control}
  167. render={({ field }) => (
  168. <FormItem>
  169. <FormLabel>Optional</FormLabel>
  170. <FormControl>
  171. <Switch
  172. checked={field.value}
  173. onCheckedChange={field.onChange}
  174. />
  175. </FormControl>
  176. <FormMessage />
  177. </FormItem>
  178. )}
  179. />
  180. {type === BeginQueryType.Options && (
  181. <BeginDynamicOptions></BeginDynamicOptions>
  182. )}
  183. </form>
  184. </Form>
  185. );
  186. }
  187. export function ParameterDialog({
  188. initialValue,
  189. hideModal,
  190. otherThanCurrentQuery,
  191. submit,
  192. }: ModalFormProps & IModalProps<BeginQuery>) {
  193. const { t } = useTranslation();
  194. return (
  195. <Dialog open onOpenChange={hideModal}>
  196. <DialogContent>
  197. <DialogHeader>
  198. <DialogTitle>{t('flow.variableSettings')}</DialogTitle>
  199. </DialogHeader>
  200. <ParameterForm
  201. initialValue={initialValue}
  202. otherThanCurrentQuery={otherThanCurrentQuery}
  203. submit={submit}
  204. ></ParameterForm>
  205. <DialogFooter>
  206. <Button type="submit" form={FormId}>
  207. Confirm
  208. </Button>
  209. </DialogFooter>
  210. </DialogContent>
  211. </Dialog>
  212. );
  213. }