Browse Source

Merge pull request #1294 from visuddhinanda/agile

修复术语无法提交的bug
visuddhinanda 2 years ago
parent
commit
c2c622268c

+ 1 - 1
dashboard/src/components/api/Term.ts

@@ -21,7 +21,7 @@ export interface ITermDataResponse {
   tag: string;
   meaning: string;
   other_meaning: string;
-  note: string;
+  note: string | null;
   html?: string;
   channal: string;
   channel?: IChannel;

+ 5 - 1
dashboard/src/components/channel/ChannelSelect.tsx

@@ -7,6 +7,7 @@ import { IApiResponseChannelList } from "../api/Channel";
 interface IOption {
   value: string;
   label: string;
+  lang?: string;
 }
 
 interface IWidget {
@@ -17,6 +18,7 @@ interface IWidget {
   label?: string;
   parentChannelId?: string;
   parentStudioId?: string;
+  placeholder?: string;
   onSelect?: Function;
 }
 const ChannelSelectWidget = ({
@@ -27,6 +29,7 @@ const ChannelSelectWidget = ({
   label,
   parentChannelId,
   parentStudioId,
+  placeholder,
   onSelect,
 }: IWidget) => {
   return (
@@ -35,6 +38,7 @@ const ChannelSelectWidget = ({
       name={name}
       tooltip={tooltip}
       label={label}
+      placeholder={placeholder}
       request={async ({ keyWords }) => {
         console.log("keyWord", keyWords);
         const json = await get<IApiResponseChannelList>(
@@ -60,7 +64,7 @@ const ChannelSelectWidget = ({
               children: json.data.rows
                 .filter((value) => value.studio.id === key)
                 .map((item) => {
-                  return { value: item.uid, label: item.name };
+                  return { value: item.uid, label: item.name, lang: item.lang };
                 }),
             };
             channels.push(node);

+ 24 - 2
dashboard/src/components/discussion/DiscussionBox.tsx

@@ -1,5 +1,7 @@
 import { useState } from "react";
-import { Divider, Drawer } from "antd";
+import { Button, Divider, Drawer, Space } from "antd";
+import { FullscreenOutlined, FullscreenExitOutlined } from "@ant-design/icons";
+
 import CommentTopic from "./DiscussionTopic";
 import CommentListCard, { TResType } from "./DiscussionListCard";
 import { IComment } from "./DiscussionItem";
@@ -25,7 +27,10 @@ const DiscussionBoxWidget = ({
   const [childrenDrawer, setChildrenDrawer] = useState(false);
   const [topicComment, setTopicComment] = useState<IComment>();
   const [answerCount, setAnswerCount] = useState<IAnswerCount>();
+  const drawerMinWidth = 720;
+  const drawerMaxWidth = 1100;
 
+  const [drawerWidth, setDrawerWidth] = useState(drawerMinWidth);
   const showChildrenDrawer = (
     e: React.MouseEvent<HTMLSpanElement, MouseEvent>,
     comment: IComment
@@ -45,7 +50,24 @@ const DiscussionBoxWidget = ({
       </span>
       <Drawer
         title="Discussion"
-        width={520}
+        extra={
+          <Space>
+            {drawerWidth === drawerMinWidth ? (
+              <Button
+                type="link"
+                icon={<FullscreenOutlined />}
+                onClick={() => setDrawerWidth(drawerMaxWidth)}
+              />
+            ) : (
+              <Button
+                type="link"
+                icon={<FullscreenExitOutlined />}
+                onClick={() => setDrawerWidth(drawerMinWidth)}
+              />
+            )}
+          </Space>
+        }
+        width={drawerWidth}
         onClose={() => {
           setOpen(false);
           if (document.getElementsByTagName("body")[0].hasAttribute("style")) {

+ 3 - 1
dashboard/src/components/general/LangSelect.tsx

@@ -26,8 +26,9 @@ export const LangValueEnum = () => {
 interface IWidget {
   width?: number | "md" | "sm" | "xl" | "xs" | "lg";
   label?: string;
+  disabled?: boolean;
 }
-const LangSelectWidget = ({ width, label }: IWidget) => {
+const LangSelectWidget = ({ width, label, disabled = false }: IWidget) => {
   const intl = useIntl();
 
   const langOptions = [
@@ -56,6 +57,7 @@ const LangSelectWidget = ({ width, label }: IWidget) => {
       showSearch
       debounceTime={300}
       allowClear={false}
+      disabled={disabled}
       label={
         label ? label : intl.formatMessage({ id: "forms.fields.lang.label" })
       }

+ 52 - 25
dashboard/src/components/general/NissayaCardTable.tsx

@@ -1,6 +1,10 @@
-import { recordKeyToString } from "@ant-design/pro-components";
 import { Button, Space, Table, Tag } from "antd";
+import lodash from "lodash";
 import { useEffect, useState } from "react";
+import { ArrowRightOutlined } from "@ant-design/icons";
+
+const randomString = () =>
+  lodash.times(20, () => lodash.random(35).toString(36)).join("");
 
 interface ICaseItem {
   label: string;
@@ -11,13 +15,14 @@ interface IRelationNode {
   spell?: string;
 }
 interface DataType {
-  key: React.ReactNode;
+  key: string;
   relation: string;
   localRelation?: string;
   to?: IRelationNode;
   from?: IRelationNode;
   category?: { name: string; note: string; meaning: string };
   translation?: string;
+  isChildren?: boolean;
   children?: DataType[];
 }
 export interface INissayaRelation {
@@ -39,50 +44,61 @@ const NissayaCardTableWidget = ({ data }: IWidget) => {
       setTableData(undefined);
       return;
     }
+    console.log("data", data);
     let category: string[] = [];
     let newData: DataType[] = [];
-    let id = 0;
-    for (const item of data) {
-      id++;
+    data.forEach((item, index) => {
       if (item.category && item.category.name) {
-        if (category.includes(item.category.name)) {
-          continue;
-        } else {
-          category.push(item.category.name);
+        const key = `${item.from?.spell}-${item.from?.case
+          ?.map((item) => item.label)
+          .join()}-${item.relation}-${item.category}`;
+        if (!category.includes(key)) {
+          category.push(key);
+          console.log("category", category);
           //处理children
           const children = data
-            .filter((value) => value.category?.name === item.category?.name)
+            .filter(
+              (value) =>
+                `${value.from?.spell}-${value.from?.case
+                  ?.map((item) => item.label)
+                  .join()}-${value.relation}-${value.category}` === key
+            )
             .map((item, index) => {
               return {
-                key: `c_${index}`,
+                key: randomString(),
                 relation: item.relation,
+                localRelation: item.local_relation,
                 from: item.from,
                 to: item.to,
                 category: item.category,
                 translation: item.local_ending,
+                isChildren: true,
               };
             });
+          console.log("children", children);
           newData.push({
-            key: id,
+            key: randomString(),
             relation: item.relation,
-            to: item.to,
+            localRelation: item.local_relation,
             from: item.from,
+            to: item.to,
             category: item.category,
             translation: item.local_ending,
-            children: children,
+            children: children.length > 1 ? [...children] : undefined,
           });
         }
       } else {
         newData.push({
-          key: id,
+          key: randomString(),
           relation: item.relation,
+          localRelation: item.local_relation,
           from: item.to,
           to: item.to,
           category: item.category,
           translation: item.local_ending,
         });
       }
-    }
+    });
 
     setTableData(newData);
   }, [data]);
@@ -90,7 +106,7 @@ const NissayaCardTableWidget = ({ data }: IWidget) => {
     <Table
       columns={[
         {
-          title: "本词",
+          title: "本词特征",
           dataIndex: "from",
           key: "from",
           render: (value, record, index) => {
@@ -117,9 +133,14 @@ const NissayaCardTableWidget = ({ data }: IWidget) => {
           title: "关系",
           dataIndex: "relation",
           key: "relation",
-          width: "12%",
+          width: "16%",
           render: (value, record, index) => {
-            return <>{record.relation}</>;
+            return (
+              <Space direction="vertical">
+                {record.relation}
+                {record.localRelation}
+              </Space>
+            );
           },
         },
         {
@@ -127,11 +148,10 @@ const NissayaCardTableWidget = ({ data }: IWidget) => {
           dataIndex: "to",
           key: "to",
           render: (value, record, index) => {
-            if (record.children) {
-              return <>{record.category?.meaning}</>;
-            } else {
+            if (record.isChildren) {
               return (
                 <Space>
+                  <ArrowRightOutlined />
                   {record.to?.case?.map((item, id) => {
                     return (
                       <Button
@@ -147,6 +167,13 @@ const NissayaCardTableWidget = ({ data }: IWidget) => {
                   {record.to?.spell}
                 </Space>
               );
+            } else {
+              return (
+                <Space>
+                  <ArrowRightOutlined />
+                  {record.category?.meaning}
+                </Space>
+              );
             }
           },
         },
@@ -156,10 +183,10 @@ const NissayaCardTableWidget = ({ data }: IWidget) => {
           width: "30%",
           key: "address",
           render: (value, record, index) => {
-            if (record.children) {
-              return <>{record.category?.note}</>;
-            } else {
+            if (record.isChildren) {
               return undefined;
+            } else {
+              return <>{record.category?.note}</>;
             }
           },
         },

+ 18 - 17
dashboard/src/components/template/Term.tsx

@@ -11,8 +11,9 @@ import { ITermDataResponse } from "../api/Term";
 import { changedTerm, refresh } from "../../reducers/term-change";
 import { useAppSelector } from "../../hooks";
 import { get } from "../../request";
+import { Link } from "react-router-dom";
 
-const { Text, Link } = Typography;
+const { Text } = Typography;
 
 interface ITermSummary {
   ok: boolean;
@@ -25,9 +26,9 @@ interface IWidgetTermCtl {
   word?: string;
   meaning?: string;
   meaning2?: string;
-  channel?: string;
-  parentChannelId?: string;
-  parentStudioId?: string;
+  channel?: string /**该术语在term表中的channel_id */;
+  parentChannelId?: string /**该术语所在译文的channel_id */;
+  parentStudioId?: string /**该术语所在译文的studio_id */;
   summary?: string;
   isCommunity?: string;
 }
@@ -57,7 +58,7 @@ const TermCtl = ({
       summary: summary,
       channelId: channel,
     });
-  }, []);
+  }, [id, meaning, meaning2, channel, summary, word]);
 
   useEffect(() => {
     if (newTerm?.word === word) {
@@ -66,11 +67,11 @@ const TermCtl = ({
         word: newTerm?.word,
         meaning: newTerm?.meaning,
         meaning2: newTerm?.other_meaning?.split(","),
-        summary: newTerm?.note,
+        summary: newTerm?.note ? newTerm?.note : "",
         channelId: newTerm?.channal,
       });
     }
-  }, [newTerm]);
+  }, [newTerm, word]);
 
   const onModalClose = () => {
     if (document.getElementsByTagName("body")[0].hasAttribute("style")) {
@@ -111,10 +112,9 @@ const TermCtl = ({
               style={{ maxWidth: 500, minWidth: 300 }}
               actions={[
                 <Button type="link" size="small" icon={<SearchOutlined />}>
-                  更多
-                </Button>,
-                <Button type="link" size="small" icon={<SearchOutlined />}>
-                  详情
+                  <Link to={`/term/list/āraññika`} target="_blank">
+                    详情
+                  </Link>
                 </Button>,
                 <TermModal
                   onUpdate={(value: ITermDataResponse) => {
@@ -159,13 +159,13 @@ const TermCtl = ({
           }
           placement="bottom"
         >
-          <Link style={{ color: isCommunity ? "green" : undefined }}>
+          <Typography.Link style={{ color: isCommunity ? "green" : undefined }}>
             {termData?.meaning
               ? termData?.meaning
               : termData?.word
               ? termData?.word
               : "unknown"}
-          </Link>
+          </Typography.Link>
         </Popover>
         {"("}
         <Text italic>{word}</Text>
@@ -187,12 +187,13 @@ const TermCtl = ({
           onModalClose();
         }}
         trigger={
-          <Link>
+          <Typography.Link>
             <Text type="danger">{termData?.word}</Text>
-          </Link>
+          </Typography.Link>
         }
-        word={word}
-        channelId={channel}
+        word={termData?.word}
+        parentChannelId={parentChannelId}
+        parentStudioId={parentStudioId}
       />
     );
   }

+ 23 - 8
dashboard/src/components/term/TermEdit.tsx

@@ -1,6 +1,7 @@
 import { useIntl } from "react-intl";
 import {
   ProForm,
+  ProFormDependency,
   ProFormInstance,
   ProFormSelect,
   ProFormText,
@@ -57,10 +58,8 @@ const TermEditWidget = ({
   onUpdate,
 }: IWidget) => {
   const intl = useIntl();
-  const [meaningOptions, setMeaningOptions] = useState<ValueType[]>([
-    { label: "dd", value: "dd" },
-  ]);
-  console.log("channel", channelId);
+  const [meaningOptions, setMeaningOptions] = useState<ValueType[]>([]);
+  //console.log("word", id, word, channelId, studioName);
 
   const [form] = Form.useForm<ITerm>();
   const formRef = useRef<ProFormInstance>();
@@ -119,11 +118,14 @@ const TermEditWidget = ({
           note: values.note,
           channal: values.channel
             ? values.channel[values.channel.length - 1]
+              ? values.channel[values.channel.length - 1]
+              : undefined
             : undefined,
           studioName: studioName,
           studioId: parentStudioId,
           language: values.lang,
         };
+        console.log("value", newValue);
         let res: ITermResponse;
         if (typeof values.id === "undefined") {
           res = await post<ITermDataRequest, ITermResponse>(
@@ -151,7 +153,7 @@ const TermEditWidget = ({
       request={async () => {
         let url: string;
         let data: ITerm = {
-          word: "",
+          word: word ? word : "",
           tag: "",
           meaning: "",
           meaning2: [],
@@ -162,7 +164,7 @@ const TermEditWidget = ({
         if (typeof id !== "undefined") {
           // 如果是编辑,就从服务器拉取数据。
           url = "/v2/terms/" + id;
-          console.log("url", url);
+          console.log("有id", url);
           const res = await get<ITermResponse>(url);
           console.log("request", res);
           let meaning2: string[] = [];
@@ -176,7 +178,7 @@ const TermEditWidget = ({
             tag: res.data.tag,
             meaning: res.data.meaning,
             meaning2: meaning2,
-            note: res.data.note,
+            note: res.data.note ? res.data.note : "",
             lang: res.data.language,
             channel: res.data.channel
               ? [res.data.studio.id, res.data.channel?.id]
@@ -185,6 +187,7 @@ const TermEditWidget = ({
         } else if (typeof channelId !== "undefined") {
           //在channel新建
           url = `/v2/terms?view=create-by-channel&channel=${channelId}&word=${word}`;
+          console.log("在channel新建", url);
           const res = await get<ITermCreateResponse>(url);
           console.log(res);
           data = {
@@ -199,6 +202,7 @@ const TermEditWidget = ({
         } else if (typeof studioName !== "undefined") {
           //在studio新建
           url = `/v2/terms?view=create-by-studio&studio=${studioName}&word=${word}`;
+          console.log("在 studio 新建", url);
         }
 
         return data;
@@ -281,6 +285,7 @@ const TermEditWidget = ({
           parentChannelId={parentChannelId}
           width="md"
           name="channel"
+          placeholder="通用于此Studio"
           tooltip={intl.formatMessage({
             id: "term.fields.channel.tooltip",
           })}
@@ -288,7 +293,17 @@ const TermEditWidget = ({
             id: "term.fields.channel.label",
           })}
         />
-        <LangSelect />
+        <ProFormDependency name={["channel"]}>
+          {({ channel }) => {
+            console.log("channel", channel);
+
+            return (
+              <LangSelect
+                disabled={channel ? (channel[0] === "" ? false : true) : false}
+              />
+            );
+          }}
+        </ProFormDependency>
       </ProForm.Group>
       <ProForm.Group>
         <Form.Item

+ 1 - 1
dashboard/src/components/term/TermList.tsx

@@ -28,7 +28,7 @@ interface IItem {
   channel?: IChannel;
   meaning: string;
   meaning2: string;
-  note: string;
+  note: string | null;
   createdAt: number;
 }