visuddhinanda 2 лет назад
Родитель
Сommit
232dce03dc

+ 59 - 0
dashboard/src/components/corpus/Recent.tsx

@@ -0,0 +1,59 @@
+import { Button, List, Space } from "antd";
+import { useEffect, useState } from "react";
+import { Link } from "react-router-dom";
+import { IView, IViewListResponse } from "../../pages/studio/recent/list";
+import { get } from "../../request";
+
+const Widget = () => {
+  const [listData, setListData] = useState<IView[]>([]);
+  useEffect(() => {
+    let url = `/v2/view?view=user&limit=10`;
+    get<IViewListResponse>(url).then((json) => {
+      if (json.ok) {
+        const items: IView[] = json.data.rows.map((item, id) => {
+          return {
+            sn: id + 1,
+            id: item.id,
+            title: item.title,
+            subtitle: item.org_title,
+            type: item.target_type,
+            meta: JSON.parse(item.meta),
+            updatedAt: item.updated_at,
+          };
+        });
+        setListData(items);
+      }
+    });
+  }, []);
+  return (
+    <div style={{ padding: 6 }}>
+      <List
+        itemLayout="vertical"
+        header="最近打开"
+        size="small"
+        dataSource={listData}
+        renderItem={(item) => {
+          let url = `/article/${item.type}/`;
+          switch (item.type) {
+            case "chapter":
+              url += item.meta.book + "-" + item.meta.para;
+              break;
+
+            default:
+              break;
+          }
+          return (
+            <List.Item>
+              <Link to={url} target="_blank">
+                {item.title ? item.title : item.subtitle}
+              </Link>
+            </List.Item>
+          );
+        }}
+      />
+      <Button type="link">更多</Button>
+    </div>
+  );
+};
+
+export default Widget;

+ 200 - 0
dashboard/src/components/template/Wbw/WbwDetailFm.tsx

@@ -0,0 +1,200 @@
+import { Button, Dropdown, Input, MenuProps, Space } from "antd";
+import { useEffect, useState } from "react";
+import {
+  MoreOutlined,
+  PlusOutlined,
+  EditOutlined,
+  CheckOutlined,
+  SearchOutlined,
+} from "@ant-design/icons";
+import { useAppSelector } from "../../../hooks";
+
+import { inlineDict as _inlineDict } from "../../../reducers/inline-dict";
+
+interface IWFMI {
+  pali: string;
+  meaning: string;
+  onChange?: Function;
+}
+const WbwFactorMeaningItem = ({ pali, meaning, onChange }: IWFMI) => {
+  const defaultMenu: MenuProps["items"] = [
+    {
+      key: "lookup",
+      label: (
+        <Space>
+          <SearchOutlined />
+          {"查字典"}
+        </Space>
+      ),
+    },
+    { key: pali, label: pali },
+  ];
+  const [items, setItems] = useState<MenuProps["items"]>(defaultMenu);
+
+  const inlineDict = useAppSelector(_inlineDict);
+  useEffect(() => {
+    if (inlineDict.wordIndex.includes(pali)) {
+      const result = inlineDict.wordList.filter((word) => word.word === pali);
+      //查重
+      //TODO 加入信心指数并排序
+      let myMap = new Map<string, number>();
+      let meanings: string[] = [];
+      for (const it of result) {
+        if (typeof it.mean === "string") {
+          for (const meaning of it.mean.split("$")) {
+            if (meaning !== "") {
+              myMap.set(meaning, 1);
+            }
+          }
+        }
+      }
+      myMap.forEach((value, key, map) => {
+        meanings.push(key);
+      });
+
+      const menu = meanings.map((item) => {
+        return { key: item, label: item };
+      });
+      console.log("menu", menu);
+      setItems([...defaultMenu, ...menu]);
+    }
+  }, [pali, inlineDict]);
+  return (
+    <Dropdown
+      menu={{
+        items: items,
+        onClick: (e) => {
+          if (typeof onChange !== "undefined") {
+            onChange(e.key);
+          }
+        },
+      }}
+      placement="bottomLeft"
+      trigger={["hover"]}
+    >
+      <Button
+        key={1}
+        size="small"
+        type="text"
+        icon={meaning === "" ? <MoreOutlined /> : undefined}
+      >
+        {meaning}
+      </Button>
+    </Dropdown>
+  );
+};
+
+interface IWidget {
+  factors: string[];
+  initValue?: string[];
+  onChange?: Function;
+  onOk?: Function;
+}
+const WbwDetailFmWidget = ({
+  factors,
+  initValue = [],
+  onChange,
+  onOk,
+}: IWidget) => {
+  const [factorInputEnable, setFactorInputEnable] = useState(false);
+  const [factorMeaning, setFactorMeaning] = useState<string[]>(initValue);
+
+  useEffect(() => {
+    console.log("value", initValue);
+    setFactorMeaning(initValue);
+  }, [initValue]);
+
+  const resizeArray = (input: string[]) => {
+    const newFm = factors.map((item, index) => {
+      if (index < input.length) {
+        return input[index];
+      } else {
+        return "";
+      }
+    });
+    return newFm;
+  };
+
+  useEffect(() => {
+    setFactorMeaning(resizeArray(factorMeaning));
+  }, [factors]);
+
+  return (
+    <div>
+      <div style={{ display: "flex" }}>
+        <Input
+          key="input"
+          allowClear
+          hidden={!factorInputEnable}
+          value={factorMeaning.join("+")}
+          onChange={(e) => {
+            console.log(e.target.value);
+            const newData = resizeArray(e.target.value.split("+"));
+            setFactorMeaning(newData);
+            if (typeof onChange !== "undefined") {
+              onChange(newData);
+            }
+          }}
+        />
+        {factorInputEnable ? (
+          <Button
+            key="input-button"
+            type="text"
+            icon={<CheckOutlined />}
+            onClick={() => setFactorInputEnable(false)}
+          />
+        ) : undefined}
+      </div>
+      {!factorInputEnable ? (
+        <Space size={0} key="space">
+          {factorMeaning.map((item, index) => {
+            return (
+              <>
+                <WbwFactorMeaningItem
+                  key={index}
+                  pali={factors[index]}
+                  meaning={item}
+                  onChange={(value: string) => {
+                    const newData = [...factorMeaning];
+                    newData[index] = value;
+                    setFactorMeaning(newData);
+                    if (typeof onChange !== "undefined") {
+                      onChange(newData);
+                    }
+                  }}
+                />
+
+                {index < factorMeaning.length - 1 ? (
+                  <PlusOutlined key={`icon-${index}`} />
+                ) : (
+                  <>
+                    <Button
+                      key="EditOutlined"
+                      size="small"
+                      type="text"
+                      icon={<EditOutlined />}
+                      onClick={() => setFactorInputEnable(true)}
+                    />
+                    <Button
+                      key="CheckOutlined"
+                      size="small"
+                      type="text"
+                      icon={<CheckOutlined />}
+                      onClick={() => {
+                        if (typeof onOk !== "undefined") {
+                          onOk(factorMeaning.join(""));
+                        }
+                      }}
+                    />
+                  </>
+                )}
+              </>
+            );
+          })}
+        </Space>
+      ) : undefined}
+    </div>
+  );
+};
+
+export default WbwDetailFmWidget;

+ 112 - 0
dashboard/src/components/template/Wbw/WbwDetailParent2.tsx

@@ -0,0 +1,112 @@
+import { AutoComplete, Form, Input, Select } from "antd";
+import { useEffect, useState } from "react";
+import { useIntl } from "react-intl";
+import { useAppSelector } from "../../../hooks";
+import { IApiResponseDictData } from "../../api/Dict";
+import { IWbw } from "./WbwWord";
+import { inlineDict as _inlineDict } from "../../../reducers/inline-dict";
+
+const { Option } = Select;
+
+interface ValueType {
+  key?: string;
+  label: React.ReactNode;
+  value: string | number;
+}
+
+interface IWidget {
+  data: IWbw;
+  onChange?: Function;
+}
+const WbwParent2Widget = ({ data, onChange }: IWidget) => {
+  const intl = useIntl();
+  const [parentOptions, setParentOptions] = useState<ValueType[]>([]);
+  const inlineDict = useAppSelector(_inlineDict);
+
+  const getParentInDict = (
+    wordIn: string,
+    wordIndex: string[],
+    wordList: IApiResponseDictData[]
+  ): string[] => {
+    if (wordIndex.includes(wordIn)) {
+      const result = wordList.filter((word) => word.word === wordIn);
+      //查重
+      //TODO 加入信心指数并排序
+      let myMap = new Map<string, number>();
+      let parent: string[] = [];
+      for (const iterator of result) {
+        myMap.set(iterator.parent, 1);
+      }
+      myMap.forEach((value, key, map) => {
+        parent.push(key);
+      });
+      return parent;
+    } else {
+      return [];
+    }
+  };
+
+  useEffect(() => {
+    if (typeof data.parent === "undefined") {
+      return;
+    }
+    const parent = getParentInDict(
+      data.parent.value,
+      inlineDict.wordIndex,
+      inlineDict.wordList
+    );
+    const parentOptions = parent.map((item) => {
+      return {
+        label: item,
+        value: item,
+      };
+    });
+    setParentOptions(parentOptions);
+  }, [inlineDict, data]);
+
+  const grammar = ["prp", "pp", "fpp", "pass", "caus"];
+  const options = grammar.map((item) => {
+    return {
+      value: `.${item}.`,
+      label: intl.formatMessage({ id: `dict.fields.type.${item}.label` }),
+    };
+  });
+  return (
+    <>
+      <div style={{ display: "flex" }}>
+        <Form.Item
+          name="parent2"
+          label={intl.formatMessage({ id: "forms.fields.parent.label" })}
+          tooltip={intl.formatMessage({
+            id: "forms.fields.parent.tooltip",
+          })}
+        >
+          <AutoComplete
+            options={parentOptions}
+            onChange={(value: any) => {
+              if (typeof onChange !== "undefined") {
+                onChange({ field: "parent2", value: value });
+              }
+            }}
+          >
+            <Input allowClear />
+          </AutoComplete>
+        </Form.Item>
+        <Form.Item name="grammar2" noStyle>
+          <Select
+            style={{ width: 100 }}
+            allowClear
+            options={options}
+            onChange={(value: string) => {
+              if (typeof onChange !== "undefined") {
+                onChange({ field: "grammar2", value: value });
+              }
+            }}
+          />
+        </Form.Item>
+      </div>
+    </>
+  );
+};
+
+export default WbwParent2Widget;

+ 42 - 0
dashboard/src/components/template/Wbw/WbwDetailRelation.tsx

@@ -0,0 +1,42 @@
+import { List, Space } from "antd";
+import { useEffect, useState } from "react";
+import { IWbw } from "./WbwWord";
+
+interface IRelation {
+  sour_id: string;
+  sour_spell: string;
+  dest_id: string;
+  dest_spell: string;
+  relation: string;
+}
+interface IWidget {
+  data: IWbw;
+  onChange?: Function;
+}
+const WbwParent2Widget = ({ data, onChange }: IWidget) => {
+  const [relation, setRelation] = useState<IRelation[]>();
+  useEffect(() => {
+    if (typeof data.relation === "undefined") {
+      return;
+    }
+    const arrRelation: IRelation[] = JSON.parse(data.relation?.value);
+    setRelation(arrRelation);
+  }, [data.relation]);
+
+  return (
+    <List
+      itemLayout="vertical"
+      size="small"
+      dataSource={relation}
+      renderItem={(item) => (
+        <List.Item>
+          <Space>
+            {item.dest_spell}-{item.relation}
+          </Space>
+        </List.Item>
+      )}
+    />
+  );
+};
+
+export default WbwParent2Widget;

+ 30 - 0
dashboard/src/components/template/Wbw/WbwParent2.tsx

@@ -0,0 +1,30 @@
+import { Tag, Tooltip } from "antd";
+import { useIntl } from "react-intl";
+import { IWbw } from "./WbwWord";
+
+interface IWidget {
+  data: IWbw;
+}
+const WbwParent2Widget = ({ data }: IWidget) => {
+  const intl = useIntl();
+  return data.grammar2 ? (
+    data.grammar2.value !== "" ? (
+      <Tooltip title={data.parent2?.value}>
+        <Tag color={"yellow"}>
+          {intl.formatMessage({
+            id:
+              "dict.fields.type." +
+              data.grammar2.value.replaceAll(".", "") +
+              ".short.label",
+          })}
+        </Tag>
+      </Tooltip>
+    ) : (
+      <></>
+    )
+  ) : (
+    <></>
+  );
+};
+
+export default WbwParent2Widget;