WbwDetailBasic.tsx 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. import { useEffect, useState } from "react";
  2. import { useIntl } from "react-intl";
  3. import { Divider, Form, Select, Input, AutoComplete } from "antd";
  4. import { Collapse } from "antd";
  5. import SelectCase from "../../dict/SelectCase";
  6. import { IWbw } from "./WbwWord";
  7. import WbwMeaningSelect from "./WbwMeaningSelect";
  8. import { useAppSelector } from "../../../hooks";
  9. import { inlineDict as _inlineDict } from "../../../reducers/inline-dict";
  10. import { getFactorsInDict } from "./WbwFactors";
  11. const { Option } = Select;
  12. const { Panel } = Collapse;
  13. interface ValueType {
  14. key?: string;
  15. label: React.ReactNode;
  16. value: string | number;
  17. }
  18. export interface IWordBasic {
  19. meaning?: string[];
  20. case?: string;
  21. factors?: string;
  22. factorMeaning?: string;
  23. parent?: string;
  24. }
  25. interface IWidget {
  26. data: IWbw;
  27. onChange?: Function;
  28. }
  29. const Widget = ({ data, onChange }: IWidget) => {
  30. const [form] = Form.useForm();
  31. const intl = useIntl();
  32. const [items, setItems] = useState<string[]>([]);
  33. const inlineDict = useAppSelector(_inlineDict);
  34. const [factorOptions, setFactorOptions] = useState<ValueType[]>([]);
  35. const onMeaningChange = (value: string | string[]) => {
  36. console.log(`Selected: ${value}`);
  37. if (typeof onChange !== "undefined") {
  38. if (typeof value === "string") {
  39. onChange({ field: "meaning", value: value });
  40. } else {
  41. onChange({ field: "meaning", value: value.join("$") });
  42. }
  43. }
  44. };
  45. useEffect(() => {
  46. const factors = getFactorsInDict(
  47. data.word.value,
  48. inlineDict.wordIndex,
  49. inlineDict.wordList
  50. );
  51. const options = factors.map((item) => {
  52. return {
  53. label: item,
  54. value: item,
  55. };
  56. });
  57. setFactorOptions(options);
  58. }, [inlineDict, data]);
  59. return (
  60. <>
  61. <Form
  62. labelCol={{ span: 4 }}
  63. wrapperCol={{ span: 20 }}
  64. className="wbw_detail_basic"
  65. name="basic"
  66. form={form}
  67. initialValues={{
  68. meaning: data.meaning?.value,
  69. factors: data.factors?.value,
  70. factorMeaning: data.factorMeaning?.value,
  71. parent: data.parent?.value,
  72. case: data.case?.value,
  73. }}
  74. >
  75. <Form.Item
  76. style={{ marginBottom: 6 }}
  77. name="meaning"
  78. label={intl.formatMessage({ id: "forms.fields.meaning.label" })}
  79. tooltip={intl.formatMessage({ id: "forms.fields.meaning.tooltip" })}
  80. >
  81. <Select
  82. allowClear
  83. mode="tags"
  84. onChange={onMeaningChange}
  85. style={{ width: "100%" }}
  86. placeholder={intl.formatMessage({
  87. id: "forms.fields.meaning.label",
  88. })}
  89. options={items.map((item) => ({ label: item, value: item }))}
  90. dropdownRender={(menu) => (
  91. <>
  92. {menu}
  93. <Divider style={{ margin: "8px 0" }}>更多</Divider>
  94. <WbwMeaningSelect
  95. data={data}
  96. onSelect={(meaning: string) => {
  97. const currMeanings = form.getFieldValue("meaning") || [];
  98. console.log(meaning);
  99. if (!items.includes(meaning)) {
  100. setItems([...items, meaning]);
  101. }
  102. if (!currMeanings.includes(meaning)) {
  103. currMeanings.push(meaning);
  104. console.log("it push", meaning);
  105. }
  106. form.setFieldsValue({
  107. meaning: currMeanings,
  108. });
  109. onMeaningChange(currMeanings);
  110. }}
  111. />
  112. </>
  113. )}
  114. />
  115. </Form.Item>
  116. <Form.Item
  117. style={{ marginBottom: 6 }}
  118. name="factors"
  119. label={intl.formatMessage({ id: "forms.fields.factors.label" })}
  120. tooltip={intl.formatMessage({ id: "forms.fields.factors.tooltip" })}
  121. >
  122. <AutoComplete options={factorOptions}>
  123. <Input
  124. allowClear
  125. placeholder={intl.formatMessage({
  126. id: "forms.fields.factors.label",
  127. })}
  128. />
  129. </AutoComplete>
  130. </Form.Item>
  131. <Form.Item
  132. style={{ marginBottom: 6 }}
  133. name="factorMeaning"
  134. label={intl.formatMessage({
  135. id: "forms.fields.factor.meaning.label",
  136. })}
  137. tooltip={intl.formatMessage({
  138. id: "forms.fields.factor.meaning.tooltip",
  139. })}
  140. >
  141. <Input
  142. allowClear
  143. placeholder={intl.formatMessage({
  144. id: "forms.fields.factor.meaning.label",
  145. })}
  146. />
  147. </Form.Item>
  148. <Form.Item
  149. style={{ marginBottom: 6 }}
  150. label={intl.formatMessage({ id: "forms.fields.case.label" })}
  151. tooltip={intl.formatMessage({ id: "forms.fields.case.tooltip" })}
  152. name="case"
  153. >
  154. <SelectCase
  155. onCaseChange={(value: (string | number)[]) => {
  156. if (typeof onChange !== "undefined") {
  157. onChange({ field: "case", value: value.join("$") });
  158. }
  159. }}
  160. />
  161. </Form.Item>
  162. <Form.Item
  163. style={{ marginBottom: 6 }}
  164. name="parent"
  165. label={intl.formatMessage({
  166. id: "forms.fields.parent.label",
  167. })}
  168. tooltip={intl.formatMessage({
  169. id: "forms.fields.parent.tooltip",
  170. })}
  171. >
  172. <Input
  173. allowClear
  174. placeholder={intl.formatMessage({
  175. id: "forms.fields.parent.label",
  176. })}
  177. />
  178. </Form.Item>
  179. <Collapse bordered={false}>
  180. <Panel header="词源" key="1">
  181. <Form.Item
  182. name="parent1"
  183. label={intl.formatMessage({ id: "forms.fields.parent.label" })}
  184. tooltip={intl.formatMessage({
  185. id: "forms.fields.parent.tooltip",
  186. })}
  187. >
  188. <Input
  189. allowClear
  190. placeholder={intl.formatMessage({
  191. id: "forms.fields.parent.label",
  192. })}
  193. addonAfter={
  194. <Form.Item name="suffix" noStyle>
  195. <Select style={{ width: 100 }} allowClear>
  196. <Option value="prp">现在分词</Option>
  197. <Option value="pp">过去分词</Option>
  198. <Option value="fpp">未来分词</Option>
  199. </Select>
  200. </Form.Item>
  201. }
  202. />
  203. </Form.Item>
  204. </Panel>
  205. <Panel header="关系" key="2">
  206. 关系语法
  207. </Panel>
  208. </Collapse>
  209. </Form>
  210. </>
  211. );
  212. };
  213. export default Widget;