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.

next-paramater-modal.tsx 4.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. import { toast } from '@/components/hooks/use-toast';
  2. import { Button } from '@/components/ui/button';
  3. import {
  4. Dialog,
  5. DialogContent,
  6. DialogFooter,
  7. DialogHeader,
  8. DialogTitle,
  9. } from '@/components/ui/dialog';
  10. import {
  11. Form,
  12. FormControl,
  13. FormField,
  14. FormItem,
  15. FormLabel,
  16. FormMessage,
  17. } from '@/components/ui/form';
  18. import { Input } from '@/components/ui/input';
  19. import { RAGFlowSelect, RAGFlowSelectOptionType } from '@/components/ui/select';
  20. import { Switch } from '@/components/ui/switch';
  21. import { IModalProps } from '@/interfaces/common';
  22. import { zodResolver } from '@hookform/resolvers/zod';
  23. import { useEffect, useMemo } from 'react';
  24. import { useForm, useWatch } from 'react-hook-form';
  25. import { useTranslation } from 'react-i18next';
  26. import { z } from 'zod';
  27. import { BeginQueryType, BeginQueryTypeIconMap } from '../../constant';
  28. import { BeginQuery } from '../../interface';
  29. import { BeginDynamicOptions } from './next-begin-dynamic-options';
  30. type ModalFormProps = {
  31. initialValue: BeginQuery;
  32. otherThanCurrentQuery: BeginQuery[];
  33. };
  34. const FormId = 'BeginParameterForm';
  35. function ParameterForm({
  36. initialValue,
  37. otherThanCurrentQuery,
  38. }: ModalFormProps) {
  39. const FormSchema = z.object({
  40. type: z.string(),
  41. key: z
  42. .string()
  43. .trim()
  44. .refine(
  45. (value) =>
  46. !value || !otherThanCurrentQuery.some((x) => x.key === value),
  47. { message: 'The key cannot be repeated!' },
  48. ),
  49. optional: z.boolean(),
  50. options: z.array(z.string().or(z.boolean()).or(z.number())),
  51. });
  52. const form = useForm<z.infer<typeof FormSchema>>({
  53. resolver: zodResolver(FormSchema),
  54. defaultValues: {
  55. type: BeginQueryType.Line,
  56. optional: false,
  57. },
  58. });
  59. const options = useMemo(() => {
  60. return Object.values(BeginQueryType).reduce<RAGFlowSelectOptionType[]>(
  61. (pre, cur) => {
  62. const Icon = BeginQueryTypeIconMap[cur];
  63. return [
  64. ...pre,
  65. {
  66. label: (
  67. <div className="flex items-center gap-2">
  68. <Icon
  69. className={`size-${cur === BeginQueryType.Options ? 4 : 5}`}
  70. ></Icon>
  71. {cur}
  72. </div>
  73. ),
  74. value: cur,
  75. },
  76. ];
  77. },
  78. [],
  79. );
  80. }, []);
  81. const type = useWatch({
  82. control: form.control,
  83. name: 'type',
  84. });
  85. useEffect(() => {
  86. form.reset(initialValue);
  87. }, [form, initialValue]);
  88. function onSubmit(data: z.infer<typeof FormSchema>) {
  89. toast({
  90. title: 'You submitted the following values:',
  91. description: (
  92. <pre className="mt-2 w-[340px] rounded-md bg-slate-950 p-4">
  93. <code className="text-white">{JSON.stringify(data, null, 2)}</code>
  94. </pre>
  95. ),
  96. });
  97. }
  98. return (
  99. <Form {...form}>
  100. <form onSubmit={form.handleSubmit(onSubmit)} id={FormId}>
  101. <FormField
  102. name="type"
  103. control={form.control}
  104. render={({ field }) => (
  105. <FormItem>
  106. <FormLabel>Type</FormLabel>
  107. <FormControl>
  108. <RAGFlowSelect {...field} options={options} />
  109. </FormControl>
  110. <FormMessage />
  111. </FormItem>
  112. )}
  113. />
  114. <FormField
  115. name="key"
  116. control={form.control}
  117. render={({ field }) => (
  118. <FormItem>
  119. <FormLabel>Key</FormLabel>
  120. <FormControl>
  121. <Input {...field} />
  122. </FormControl>
  123. <FormMessage />
  124. </FormItem>
  125. )}
  126. />
  127. <FormField
  128. name="optional"
  129. control={form.control}
  130. render={({ field }) => (
  131. <FormItem>
  132. <FormLabel>Optional</FormLabel>
  133. <FormControl>
  134. <Switch
  135. checked={field.value}
  136. onCheckedChange={field.onChange}
  137. />
  138. </FormControl>
  139. <FormMessage />
  140. </FormItem>
  141. )}
  142. />
  143. {type === BeginQueryType.Options && (
  144. <BeginDynamicOptions></BeginDynamicOptions>
  145. )}
  146. </form>
  147. </Form>
  148. );
  149. }
  150. export function ParameterDialog({
  151. initialValue,
  152. hideModal,
  153. otherThanCurrentQuery,
  154. }: ModalFormProps & IModalProps<BeginQuery>) {
  155. const { t } = useTranslation();
  156. return (
  157. <Dialog open onOpenChange={hideModal}>
  158. <DialogContent>
  159. <DialogHeader>
  160. <DialogTitle>{t('flow.variableSettings')}</DialogTitle>
  161. </DialogHeader>
  162. <ParameterForm
  163. initialValue={initialValue}
  164. otherThanCurrentQuery={otherThanCurrentQuery}
  165. ></ParameterForm>
  166. </DialogContent>
  167. <DialogFooter>
  168. <Button type="submit" id={FormId}>
  169. Confirm
  170. </Button>
  171. </DialogFooter>
  172. </Dialog>
  173. );
  174. }