Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

index.tsx 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. import ListFilterBar from '@/components/list-filter-bar';
  2. import { Input } from '@/components/originui/input';
  3. import { Button } from '@/components/ui/button';
  4. import {
  5. Form,
  6. FormControl,
  7. FormField,
  8. FormItem,
  9. FormLabel,
  10. FormMessage,
  11. } from '@/components/ui/form';
  12. import { Modal } from '@/components/ui/modal/modal';
  13. import { RAGFlowPagination } from '@/components/ui/ragflow-pagination';
  14. import { useTranslate } from '@/hooks/common-hooks';
  15. import { zodResolver } from '@hookform/resolvers/zod';
  16. import { pick } from 'lodash';
  17. import { Plus, Search } from 'lucide-react';
  18. import { useState } from 'react';
  19. import { useForm } from 'react-hook-form';
  20. import { z } from 'zod';
  21. import { useCreateSearch, useFetchSearchList } from './hooks';
  22. import { SearchCard } from './search-card';
  23. const searchFormSchema = z.object({
  24. name: z.string().min(1, {
  25. message: 'Name is required',
  26. }),
  27. });
  28. type SearchFormValues = z.infer<typeof searchFormSchema>;
  29. export default function SearchList() {
  30. // const { data } = useFetchFlowList();
  31. const { t } = useTranslate('search');
  32. const { isLoading, createSearch } = useCreateSearch();
  33. const {
  34. data: list,
  35. searchParams,
  36. setSearchListParams,
  37. } = useFetchSearchList();
  38. const [openCreateModal, setOpenCreateModal] = useState(false);
  39. const form = useForm<SearchFormValues>({
  40. resolver: zodResolver(searchFormSchema),
  41. defaultValues: {
  42. name: '',
  43. },
  44. });
  45. const handleSearchChange = (value: string) => {
  46. console.log(value);
  47. };
  48. const onSubmit = async (values: SearchFormValues) => {
  49. await createSearch({ name: values.name });
  50. if (!isLoading) {
  51. setOpenCreateModal(false);
  52. }
  53. form.reset({ name: '' });
  54. };
  55. const openCreateModalFun = () => {
  56. setOpenCreateModal(true);
  57. };
  58. const handlePageChange = (page: number, pageSize: number) => {
  59. setSearchListParams({ ...searchParams, page, page_size: pageSize });
  60. };
  61. return (
  62. <section>
  63. <div className="px-8 pt-8">
  64. <ListFilterBar
  65. icon={
  66. <div className="rounded-sm bg-emerald-400 bg-gradient-to-t from-emerald-400 via-emerald-400 to-emerald-200 p-1 size-6 flex justify-center items-center">
  67. <Search size={14} className="font-bold m-auto" />
  68. </div>
  69. }
  70. title="Search apps"
  71. showFilter={false}
  72. onSearchChange={(e) => handleSearchChange(e.target.value)}
  73. >
  74. <Button
  75. variant={'default'}
  76. onClick={() => {
  77. openCreateModalFun();
  78. }}
  79. >
  80. <Plus className="mr-2 h-4 w-4" />
  81. {t('createSearch')}
  82. </Button>
  83. </ListFilterBar>
  84. </div>
  85. <div className="grid gap-6 sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5 max-h-[84vh] overflow-auto px-8">
  86. {list?.data.search_apps.map((x) => {
  87. return <SearchCard key={x.id} data={x}></SearchCard>;
  88. })}
  89. {/* {data.map((x) => {
  90. return <SearchCard key={x.id} data={x}></SearchCard>;
  91. })} */}
  92. </div>
  93. {list?.data.total && (
  94. <RAGFlowPagination
  95. {...pick(searchParams, 'current', 'pageSize')}
  96. total={list?.data.total}
  97. onChange={handlePageChange}
  98. on
  99. />
  100. )}
  101. <Modal
  102. open={openCreateModal}
  103. onOpenChange={(open) => {
  104. setOpenCreateModal(open);
  105. }}
  106. title={
  107. <div className="rounded-sm bg-emerald-400 bg-gradient-to-t from-emerald-400 via-emerald-400 to-emerald-200 p-1 size-6 flex justify-center items-center">
  108. <Search size={14} className="font-bold m-auto" />
  109. </div>
  110. }
  111. className="!w-[480px] rounded-xl"
  112. titleClassName="border-none"
  113. footerClassName="border-none"
  114. showfooter={false}
  115. maskClosable={false}
  116. >
  117. <Form {...form}>
  118. <form onSubmit={form.handleSubmit(onSubmit)}>
  119. <div className="text-base mb-4">{t('createSearch')}</div>
  120. <FormField
  121. control={form.control}
  122. name="name"
  123. render={({ field }) => (
  124. <FormItem>
  125. <FormLabel>
  126. <span className="text-destructive mr-1"> *</span>Name
  127. </FormLabel>
  128. <FormControl>
  129. <Input {...field} />
  130. </FormControl>
  131. <FormMessage />
  132. </FormItem>
  133. )}
  134. />
  135. <div className="flex justify-end gap-2 mt-8 mb-6">
  136. <Button
  137. type="button"
  138. variant="outline"
  139. onClick={() => setOpenCreateModal(false)}
  140. >
  141. Cancel
  142. </Button>
  143. <Button type="submit" disabled={isLoading}>
  144. {isLoading ? 'Confirm...' : 'Confirm'}
  145. </Button>
  146. </div>
  147. </form>
  148. </Form>
  149. </Modal>
  150. </section>
  151. );
  152. }