Bladeren bron

Merge pull request #1891 from visuddhinanda/agile

添加 Qa 模版
visuddhinanda 2 jaren geleden
bovenliggende
commit
f89d7f3050

+ 14 - 0
dashboard/src/components/discussion/DiscussionShow.tsx

@@ -147,6 +147,12 @@ const DiscussionShowWidget = ({
           message.success("链接地址已经拷贝到剪贴板");
         });
         break;
+      case "copy-tpl":
+        const tpl = `{{qa|id=${data.id}|style=collapse}}`;
+        navigator.clipboard.writeText(tpl).then(() => {
+          notification.success({ message: "链接地址已经拷贝到剪贴板" });
+        });
+        break;
       case "edit":
         if (typeof onEdit !== "undefined") {
           onEdit();
@@ -185,6 +191,14 @@ const DiscussionShowWidget = ({
       }),
       icon: <LinkOutlined />,
     },
+    {
+      key: "copy-tpl",
+      label: intl.formatMessage({
+        id: "buttons.copy.tpl",
+      }),
+      icon: <LinkOutlined />,
+      disabled: data.type !== "qa",
+    },
     {
       type: "divider",
     },

+ 3 - 0
dashboard/src/components/discussion/DiscussionTopic.tsx

@@ -12,6 +12,7 @@ interface IWidget {
   topic?: IComment;
   focus?: string;
   hideTitle?: boolean;
+  hideReply?: boolean;
   onItemCountChange?: Function;
   onTopicReady?: Function;
   onTopicDelete?: Function;
@@ -23,6 +24,7 @@ const DiscussionTopicWidget = ({
   topic,
   focus,
   hideTitle = false,
+  hideReply = false,
   onTopicReady,
   onItemCountChange,
   onTopicDelete,
@@ -68,6 +70,7 @@ const DiscussionTopicWidget = ({
         resType={resType}
         focus={focus}
         topicId={topicId}
+        hideReply={hideReply}
         onItemCountChange={(count: number, e: string) => {
           //把新建回答的消息传出去。
           setCount(count);

+ 26 - 20
dashboard/src/components/discussion/DiscussionTopicChildren.tsx

@@ -28,6 +28,7 @@ interface IWidget {
   resType?: TResType;
   topicId?: string;
   focus?: string;
+  hideReply?: boolean;
   onItemCountChange?: Function;
   onTopicCreate?: Function;
 }
@@ -37,6 +38,7 @@ const DiscussionTopicChildrenWidget = ({
   resType,
   topicId,
   focus,
+  hideReply = false,
   onItemCountChange,
   onTopicCreate,
 }: IWidget) => {
@@ -223,26 +225,30 @@ const DiscussionTopicChildrenWidget = ({
           }}
         />
       )}
-      <DiscussionCreate
-        resId={resId}
-        resType={resType}
-        contentType="markdown"
-        parent={topicId}
-        topicId={topicId}
-        topic={topic}
-        onCreated={(value: IComment) => {
-          const newData = JSON.parse(JSON.stringify(value));
-          setData([...data, newData]);
-          if (typeof onItemCountChange !== "undefined") {
-            onItemCountChange(data.length + 1, value.parent);
-          }
-        }}
-        onTopicCreated={(value: IconType) => {
-          if (typeof onTopicCreate !== "undefined") {
-            onTopicCreate(value);
-          }
-        }}
-      />
+      {hideReply ? (
+        <></>
+      ) : (
+        <DiscussionCreate
+          resId={resId}
+          resType={resType}
+          contentType="markdown"
+          parent={topicId}
+          topicId={topicId}
+          topic={topic}
+          onCreated={(value: IComment) => {
+            const newData = JSON.parse(JSON.stringify(value));
+            setData([...data, newData]);
+            if (typeof onItemCountChange !== "undefined") {
+              onItemCountChange(data.length + 1, value.parent);
+            }
+          }}
+          onTopicCreated={(value: IconType) => {
+            if (typeof onTopicCreate !== "undefined") {
+              onTopicCreate(value);
+            }
+          }}
+        />
+      )}
     </div>
   );
 };

+ 4 - 7
dashboard/src/components/discussion/InteractiveArea.tsx

@@ -1,9 +1,10 @@
+import { useEffect, useState } from "react";
 import { Tabs } from "antd";
+
 import { TResType } from "./DiscussionListCard";
 import Discussion from "./Discussion";
-import { useEffect, useState } from "react";
 import { get } from "../../request";
-import QaList from "./QaList";
+import QaBox from "./QaBox";
 
 interface IInteractive {
   ok: boolean;
@@ -78,11 +79,7 @@ const InteractiveAreaWidget = ({ resId, resType }: IWidget) => {
         {
           label: `问答`,
           key: "qa",
-          children: qaCanEdit ? (
-            <Discussion resId={resId} resType={resType} type="qa" />
-          ) : (
-            <QaList resId={resId} resType={resType} />
-          ),
+          children: <QaBox resId={resId} resType={resType} />,
         },
         {
           label: `求助`,

+ 104 - 0
dashboard/src/components/discussion/QaBox.tsx

@@ -0,0 +1,104 @@
+import { useEffect, useState } from "react";
+import { ArrowLeftOutlined } from "@ant-design/icons";
+
+import DiscussionTopic from "./DiscussionTopic";
+import { TResType } from "./DiscussionListCard";
+import { IComment } from "./DiscussionItem";
+
+import { Button, Space, Typography } from "antd";
+import { TDiscussionType } from "./Discussion";
+import QaList from "./QaList";
+
+const { Text } = Typography;
+
+interface IWidget {
+  resId?: string;
+  resType?: TResType;
+  showTopicId?: string;
+  focus?: string;
+  onTopicReady?: Function;
+}
+
+const DiscussionWidget = ({
+  resId,
+  resType,
+  showTopicId,
+  focus,
+  onTopicReady,
+}: IWidget) => {
+  const [childrenDrawer, setChildrenDrawer] = useState(false);
+  const [topicId, setTopicId] = useState<string>();
+  const [topic, setTopic] = useState<IComment>();
+  const [topicTitle, setTopicTitle] = useState<string>();
+
+  useEffect(() => {
+    if (showTopicId) {
+      setChildrenDrawer(true);
+      setTopicId(showTopicId);
+    } else {
+      setChildrenDrawer(false);
+    }
+  }, [showTopicId]);
+
+  const showChildrenDrawer = (comment: IComment) => {
+    console.debug("discussion comment", comment);
+    setChildrenDrawer(true);
+    if (comment.id) {
+      setTopicId(comment.id);
+      setTopic(undefined);
+    } else {
+      setTopicId(undefined);
+      setTopic(comment);
+    }
+  };
+
+  return (
+    <>
+      {childrenDrawer ? (
+        <div>
+          <Space>
+            <Button
+              shape="circle"
+              icon={<ArrowLeftOutlined />}
+              onClick={() => setChildrenDrawer(false)}
+            />
+            <Text strong style={{ fontSize: 16 }}>
+              {topic ? topic.title : topicTitle}
+            </Text>
+          </Space>
+          <DiscussionTopic
+            resType={resType}
+            topicId={topicId}
+            topic={topic}
+            focus={focus}
+            hideTitle
+            onTopicReady={(value: IComment) => {
+              setTopicTitle(value.title);
+              if (typeof onTopicReady !== "undefined") {
+                onTopicReady(value);
+              }
+            }}
+            onTopicDelete={() => {
+              setChildrenDrawer(false);
+            }}
+            onConvert={(value: TDiscussionType) => {
+              setChildrenDrawer(false);
+            }}
+          />
+        </div>
+      ) : (
+        <QaList
+          resId={resId}
+          resType={resType}
+          onSelect={(
+            e: React.MouseEvent<HTMLSpanElement, MouseEvent>,
+            comment: IComment
+          ) => showChildrenDrawer(comment)}
+          onReply={(comment: IComment) => showChildrenDrawer(comment)}
+        />
+      )}
+    </>
+  );
+};
+
+export default DiscussionWidget;

+ 16 - 3
dashboard/src/components/discussion/QaList.tsx

@@ -7,8 +7,10 @@ import DiscussionItem, { IComment } from "./DiscussionItem";
 interface IWidget {
   resId?: string;
   resType?: TResType;
+  onSelect?: Function;
+  onReply?: Function;
 }
-const QaListWidget = ({ resId, resType }: IWidget) => {
+const QaListWidget = ({ resId, resType, onSelect, onReply }: IWidget) => {
   const [data, setData] = useState<IComment[]>();
 
   useEffect(() => {
@@ -16,7 +18,7 @@ const QaListWidget = ({ resId, resType }: IWidget) => {
       return;
     }
     let url: string = `/v2/discussion?res_type=${resType}&view=res_id&id=${resId}`;
-    url += "&dir=asc&type=qa&status=close";
+    url += "&dir=asc&type=qa&status=active,close";
     console.log("url", url);
     get<ICommentListResponse>(url).then((json) => {
       if (json.ok) {
@@ -51,7 +53,18 @@ const QaListWidget = ({ resId, resType }: IWidget) => {
         .map((question, index) => {
           return (
             <div key={`div_${index}`}>
-              <DiscussionItem key={index} data={question} />
+              <DiscussionItem
+                key={index}
+                data={question}
+                onSelect={(
+                  e: React.MouseEvent<HTMLSpanElement, MouseEvent>,
+                  value: IComment
+                ) => {
+                  if (typeof onSelect !== "undefined") {
+                    onSelect(e, value);
+                  }
+                }}
+              />
               <div
                 style={{
                   marginLeft: 16,

+ 3 - 0
dashboard/src/components/template/MdTpl.tsx

@@ -6,6 +6,7 @@ import Nissaya from "./Nissaya";
 import Note from "./Note";
 import ParaHandle from "./ParaHandle";
 import ParaShell from "./ParaShell";
+import Qa from "./Qa";
 import Quote from "./Quote";
 import QuoteLink from "./QuoteLink";
 import SentEdit from "./SentEdit";
@@ -54,6 +55,8 @@ const Widget = ({ tpl, props, children }: IWidgetMdTpl) => {
       return <QuoteLink props={props ? props : ""} />;
     case "para-shell":
       return <ParaShell props={props ? props : ""}>{children}</ParaShell>;
+    case "qa":
+      return <Qa props={props ? props : ""} />;
     default:
       return <>未定义模版({tpl})</>;
   }

+ 41 - 0
dashboard/src/components/template/Qa.tsx

@@ -0,0 +1,41 @@
+import { Collapse } from "antd";
+
+import DiscussionTopic from "../discussion/DiscussionTopic";
+import { TResType } from "../discussion/DiscussionListCard";
+
+const { Panel } = Collapse;
+
+interface IQaCtl {
+  id: string;
+  title?: string;
+  resId?: string;
+  resType?: TResType;
+}
+const QaCtl = ({ id, title, resId, resType }: IQaCtl) => {
+  return (
+    <Collapse bordered={false}>
+      <Panel header={title} key="1">
+        {resType ? (
+          <DiscussionTopic resType={resType} topicId={id} hideTitle hideReply />
+        ) : (
+          "resType error"
+        )}
+      </Panel>
+    </Collapse>
+  );
+};
+
+interface IWidget {
+  props: string;
+}
+const Widget = ({ props }: IWidget) => {
+  const prop = JSON.parse(atob(props)) as IQaCtl;
+  console.log(prop);
+  return (
+    <>
+      <QaCtl {...prop} />
+    </>
+  );
+};
+
+export default Widget;

+ 1 - 0
dashboard/src/locales/en-US/buttons.ts

@@ -80,6 +80,7 @@ const items = {
   "buttons.statistic": "statistic",
   "buttons.relate": "relate",
   "buttons.convert": "convert",
+  "buttons.copy.tpl": "copy template",
 };
 
 export default items;

+ 1 - 0
dashboard/src/locales/zh-Hans/buttons.ts

@@ -80,6 +80,7 @@ const items = {
   "buttons.statistic": "统计",
   "buttons.relate": "关联",
   "buttons.convert": "转换",
+  "buttons.copy.tpl": "复制模版",
 };
 
 export default items;