visuddhinanda пре 2 година
родитељ
комит
b820130f28

+ 22 - 8
dashboard/src/components/discussion/DiscussionItem.tsx

@@ -1,8 +1,8 @@
 import { Avatar } from "antd";
 import { useState } from "react";
 import { IUser } from "../auth/User";
-import CommentShow from "./DiscussionShow";
-import CommentEdit from "./DiscussionEdit";
+import DiscussionShow from "./DiscussionShow";
+import DiscussionEdit from "./DiscussionEdit";
 import { TResType } from "./DiscussionListCard";
 
 export interface IComment {
@@ -10,7 +10,7 @@ export interface IComment {
   resId?: string;
   resType?: TResType;
   user: IUser;
-  parent?: string;
+  parent?: string | null;
   title?: string;
   content?: string;
   children?: IComment[];
@@ -25,27 +25,41 @@ interface IWidget {
 }
 const DiscussionItemWidget = ({ data, onSelect, onCreated }: IWidget) => {
   const [edit, setEdit] = useState(false);
+  const [currData, setCurrData] = useState<IComment>(data);
   return (
-    <div style={{ display: "flex" }}>
+    <div style={{ display: "flex", width: "100%" }}>
       <div style={{ width: "2em" }}>
         <Avatar size="small">{data.user?.nickName?.slice(0, 1)}</Avatar>
       </div>
       <div style={{ width: "100%" }}>
         {edit ? (
-          <CommentEdit
-            data={data}
+          <DiscussionEdit
+            data={currData}
+            onUpdated={(e: IComment) => {
+              setCurrData(e);
+              setEdit(false);
+            }}
             onCreated={(e: IComment) => {
               if (typeof onCreated !== "undefined") {
                 onCreated(e);
               }
             }}
+            onClose={() => setEdit(false)}
           />
         ) : (
-          <CommentShow
-            data={data}
+          <DiscussionShow
+            data={currData}
             onEdit={() => {
               setEdit(true);
             }}
+            onSelect={(
+              e: React.MouseEvent<HTMLSpanElement, MouseEvent>,
+              data: IComment
+            ) => {
+              if (typeof onSelect !== "undefined") {
+                onSelect(e, data);
+              }
+            }}
           />
         )}
       </div>

+ 128 - 23
dashboard/src/components/discussion/DiscussionShow.tsx

@@ -1,18 +1,81 @@
 import { useIntl } from "react-intl";
-import { Button, Card, Dropdown, Space } from "antd";
-import { MoreOutlined } from "@ant-design/icons";
+import {
+  Button,
+  Card,
+  Dropdown,
+  message,
+  Modal,
+  Space,
+  Typography,
+} from "antd";
+import {
+  MoreOutlined,
+  EditOutlined,
+  DeleteOutlined,
+  LinkOutlined,
+  CommentOutlined,
+  MessageOutlined,
+  ExclamationCircleOutlined,
+} from "@ant-design/icons";
 import type { MenuProps } from "antd";
 
 import { IComment } from "./DiscussionItem";
 import TimeShow from "../general/TimeShow";
+import Marked from "../general/Marked";
+import { delete_ } from "../../request";
+import { IDeleteResponse } from "../api/Article";
+
+const { Text } = Typography;
 
 interface IWidget {
   data: IComment;
   onEdit?: Function;
   onSelect?: Function;
+  onDelete?: Function;
 }
-const DiscussionShowWidget = ({ data, onEdit, onSelect }: IWidget) => {
+const DiscussionShowWidget = ({
+  data,
+  onEdit,
+  onSelect,
+  onDelete,
+}: IWidget) => {
   const intl = useIntl();
+  const showDeleteConfirm = (id: string, title: string) => {
+    Modal.confirm({
+      icon: <ExclamationCircleOutlined />,
+      title:
+        intl.formatMessage({
+          id: "message.delete.sure",
+        }) +
+        intl.formatMessage({
+          id: "message.irrevocable",
+        }),
+
+      content: title,
+      okText: intl.formatMessage({
+        id: "buttons.delete",
+      }),
+      okType: "danger",
+      cancelText: intl.formatMessage({
+        id: "buttons.no",
+      }),
+      onOk() {
+        console.log("delete", id);
+        return delete_<IDeleteResponse>(`/v2/discussion/${id}`)
+          .then((json) => {
+            if (json.ok) {
+              message.success("删除成功");
+              if (typeof onDelete !== "undefined") {
+                onDelete(id);
+              }
+            } else {
+              message.error(json.message);
+            }
+          })
+          .catch((e) => console.log("Oops errors!", e));
+      },
+    });
+  };
   const onClick: MenuProps["onClick"] = (e) => {
     console.log("click ", e);
     switch (e.key) {
@@ -21,6 +84,11 @@ const DiscussionShowWidget = ({ data, onEdit, onSelect }: IWidget) => {
           onEdit();
         }
         break;
+      case "delete":
+        if (data.id) {
+          showDeleteConfirm(data.id, data.title ? data.title : "");
+        }
+        break;
       default:
         break;
     }
@@ -30,10 +98,13 @@ const DiscussionShowWidget = ({ data, onEdit, onSelect }: IWidget) => {
     {
       key: "copy-link",
       label: "复制链接",
+      icon: <LinkOutlined />,
     },
     {
       key: "reply",
       label: "回复",
+      icon: <CommentOutlined />,
+      disabled: data.parent ? true : false,
     },
     {
       type: "divider",
@@ -41,10 +112,14 @@ const DiscussionShowWidget = ({ data, onEdit, onSelect }: IWidget) => {
     {
       key: "edit",
       label: "编辑",
+      icon: <EditOutlined />,
     },
     {
       key: "delete",
       label: "删除",
+      icon: <DeleteOutlined />,
+      danger: true,
+      disabled: data.childrenCount ? true : false,
     },
     {
       type: "divider",
@@ -58,32 +133,62 @@ const DiscussionShowWidget = ({ data, onEdit, onSelect }: IWidget) => {
     <Card
       size="small"
       title={
-        <Space>
-          {data.user.nickName}
-          <TimeShow
-            time={data.updatedAt}
-            title={intl.formatMessage({
-              id: "labels.updated-at",
-            })}
-          />
+        <Space direction="vertical">
+          <Text
+            strong
+            onClick={(e) => {
+              if (typeof onSelect !== "undefined") {
+                onSelect(e, data);
+              }
+            }}
+          >
+            {data.title}
+          </Text>
+          <Text type="secondary">
+            <Space>
+              {data.user.nickName}
+              <TimeShow
+                type="secondary"
+                time={data.updatedAt}
+                title={intl.formatMessage({
+                  id: "labels.updated-at",
+                })}
+              />
+            </Space>
+          </Text>
         </Space>
       }
       extra={
-        <Dropdown menu={{ items, onClick }} placement="bottomRight">
-          <Button shape="circle" size="small" icon={<MoreOutlined />}></Button>
-        </Dropdown>
+        <Space>
+          <span
+            style={{
+              display: data.childrenCount === 0 ? "none" : "inline",
+              cursor: "pointer",
+            }}
+            onClick={(e) => {
+              if (typeof onSelect !== "undefined") {
+                onSelect(e, data);
+              }
+            }}
+          >
+            {data.childrenCount ? (
+              <>
+                <MessageOutlined /> {data.childrenCount}
+              </>
+            ) : undefined}
+          </span>
+          <Dropdown menu={{ items, onClick }} placement="bottomRight">
+            <Button
+              shape="circle"
+              size="small"
+              icon={<MoreOutlined />}
+            ></Button>
+          </Dropdown>
+        </Space>
       }
       style={{ width: "100%" }}
     >
-      <span
-        onClick={(e) => {
-          if (typeof onSelect !== "undefined") {
-            onSelect();
-          }
-        }}
-      >
-        {data.content}
-      </span>
+      <Marked text={data.content} />
     </Card>
   );
 };