textarea.tsx 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. import type { FC } from "react";
  2. import { useContext } from 'use-context-selector'
  3. import { DocumentTextIcon } from "@heroicons/react/24/solid";
  4. import { useTranslation } from "react-i18next";
  5. import { hitTesting } from "@/service/datasets";
  6. import DatasetDetailContext from '@/context/dataset-detail'
  7. import { HitTestingResponse } from "@/models/datasets";
  8. import cn from "classnames";
  9. import Button from "../../base/button";
  10. import Tag from "../../base/tag";
  11. import Tooltip from "../../base/tooltip";
  12. import s from "./style.module.css";
  13. import { asyncRunSafe } from "@/utils";
  14. type Props = {
  15. datasetId: string;
  16. onUpdateList: () => void;
  17. setHitResult: (res: HitTestingResponse) => void;
  18. loading: boolean;
  19. setLoading: (v: boolean) => void;
  20. text: string;
  21. setText: (v: string) => void;
  22. };
  23. const TextAreaWithButton: FC<Props> = ({
  24. datasetId,
  25. onUpdateList,
  26. setHitResult,
  27. setLoading,
  28. loading,
  29. text,
  30. setText,
  31. }) => {
  32. const { t } = useTranslation();
  33. const { indexingTechnique } = useContext(DatasetDetailContext)
  34. // 处理文本框内容变化的函数
  35. function handleTextChange(event: any) {
  36. setText(event.target.value);
  37. }
  38. // 处理按钮点击的函数
  39. const onSubmit = async () => {
  40. setLoading(true);
  41. const [e, res] = await asyncRunSafe<HitTestingResponse>(
  42. hitTesting({ datasetId, queryText: text }) as Promise<HitTestingResponse>
  43. );
  44. if (!e) {
  45. setHitResult(res);
  46. onUpdateList?.();
  47. }
  48. setLoading(false);
  49. };
  50. return (
  51. <>
  52. <div className={s.wrapper}>
  53. <div className="flex items-center mb-3">
  54. <DocumentTextIcon className="w-4 h-4 text-primary-600 mr-2" />
  55. <span className="text-gray-800 font-semibold text-sm">
  56. {t("datasetHitTesting.input.title")}
  57. </span>
  58. </div>
  59. <textarea
  60. value={text}
  61. onChange={handleTextChange}
  62. placeholder={t("datasetHitTesting.input.placeholder") as string}
  63. className={s.textarea}
  64. />
  65. <div className="absolute inset-x-0 bottom-0 flex items-center justify-between mx-4 mt-2 mb-4">
  66. {text?.length > 200 ? (
  67. <Tooltip
  68. content={t("datasetHitTesting.input.countWarning") as string}
  69. selector="hit-testing-warning"
  70. >
  71. <div>
  72. <Tag color="red" className="!text-red-600">
  73. {text?.length}
  74. <span className="text-red-300 mx-0.5">/</span>
  75. 200
  76. </Tag>
  77. </div>
  78. </Tooltip>
  79. ) : (
  80. <Tag
  81. color="gray"
  82. className={cn("!text-gray-500", text?.length ? "" : "opacity-50")}
  83. >
  84. {text?.length}
  85. <span className="text-gray-300 mx-0.5">/</span>
  86. 200
  87. </Tag>
  88. )}
  89. <Tooltip
  90. selector="hit-testing-submit"
  91. disabled={indexingTechnique === 'high_quality'}
  92. content={t("datasetHitTesting.input.indexWarning") as string}
  93. >
  94. <div>
  95. <Button
  96. onClick={onSubmit}
  97. type="primary"
  98. loading={loading}
  99. disabled={indexingTechnique !== 'high_quality' ? true : (!text?.length || text?.length > 200)}
  100. >
  101. {t("datasetHitTesting.input.testing")}
  102. </Button>
  103. </div>
  104. </Tooltip>
  105. </div>
  106. </div>
  107. </>
  108. );
  109. };
  110. export default TextAreaWithButton;