visuddhinanda 2 лет назад
Родитель
Сommit
34bf6443f4

+ 119 - 0
dashboard/src/components/discussion/DiscussionDrawer.tsx

@@ -0,0 +1,119 @@
+import { useState } from "react";
+import { Button, Divider, Drawer, Space } from "antd";
+import { FullscreenOutlined, FullscreenExitOutlined } from "@ant-design/icons";
+
+import DiscussionTopic from "./DiscussionTopic";
+import DiscussionListCard, { TResType } from "./DiscussionListCard";
+import { IComment } from "./DiscussionItem";
+import DiscussionAnchor from "./DiscussionAnchor";
+import { Link } from "react-router-dom";
+
+export interface IAnswerCount {
+  id: string;
+  count: number;
+}
+interface IWidget {
+  trigger?: JSX.Element;
+  resId?: string;
+  resType?: TResType;
+  onCommentCountChange?: Function;
+}
+const DiscussionDrawerWidget = ({
+  trigger,
+  resId,
+  resType,
+  onCommentCountChange,
+}: IWidget) => {
+  const [open, setOpen] = useState(false);
+  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 = (comment: IComment) => {
+    setChildrenDrawer(true);
+    setTopicComment(comment);
+  };
+
+  return (
+    <>
+      <span
+        onClick={() => {
+          setOpen(true);
+        }}
+      >
+        {trigger}
+      </span>
+      <Drawer
+        title="Discussion"
+        destroyOnClose
+        extra={
+          <Space>
+            <Link to={`/discussion/show/${resType}/${resId}`} target="_blank">
+              在新窗口打开
+            </Link>
+            {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")) {
+            document.getElementsByTagName("body")[0].removeAttribute("style");
+          }
+        }}
+        open={open}
+        maskClosable={false}
+      >
+        <DiscussionAnchor resId={resId} resType={resType} />
+        <Divider></Divider>
+        <DiscussionListCard
+          resId={resId}
+          resType={resType}
+          onSelect={(
+            e: React.MouseEvent<HTMLSpanElement, MouseEvent>,
+            comment: IComment
+          ) => showChildrenDrawer(comment)}
+          onReply={(comment: IComment) => showChildrenDrawer(comment)}
+          changedAnswerCount={answerCount}
+          onItemCountChange={(count: number) => {
+            if (typeof onCommentCountChange !== "undefined") {
+              onCommentCountChange(count);
+            }
+          }}
+        />
+        <Drawer
+          title="Answer"
+          width={700}
+          onClose={() => {
+            setChildrenDrawer(false);
+          }}
+          open={childrenDrawer}
+        >
+          <DiscussionTopic
+            topicId={topicComment?.id}
+            onItemCountChange={(count: number, parent: string) => {
+              setAnswerCount({ id: parent, count: count });
+            }}
+          />
+        </Drawer>
+      </Drawer>
+    </>
+  );
+};
+
+export default DiscussionDrawerWidget;

+ 54 - 0
dashboard/src/reducers/discussion.ts

@@ -0,0 +1,54 @@
+/**
+ * 查字典,添加术语命令
+ */
+import { createSlice, PayloadAction } from "@reduxjs/toolkit";
+
+import { TResType } from "../components/discussion/DiscussionListCard";
+
+import type { RootState } from "../store";
+
+export interface ITermCommand {}
+
+export interface IShowDiscussion {
+  type: "discussion" | "pr";
+  resType?: TResType;
+  resId?: string;
+}
+export interface ICount {
+  count: number;
+  resType?: TResType;
+  resId?: string;
+}
+interface IState {
+  message?: IShowDiscussion;
+  count?: ICount;
+  anchor?: IShowDiscussion;
+}
+
+const initialState: IState = {};
+
+export const slice = createSlice({
+  name: "discussion",
+  initialState,
+  reducers: {
+    show: (state, action: PayloadAction<IShowDiscussion>) => {
+      state.message = action.payload;
+    },
+    countChange: (state, action: PayloadAction<ICount>) => {
+      state.count = action.payload;
+    },
+    showAnchor: (state, action: PayloadAction<IShowDiscussion>) => {
+      state.anchor = action.payload;
+    },
+  },
+});
+
+export const { show, countChange, showAnchor } = slice.actions;
+
+export const message = (state: RootState): IShowDiscussion | undefined =>
+  state.discussion.message;
+export const count = (state: RootState): ICount | undefined =>
+  state.discussion.count;
+export const anchor = (state: RootState): IShowDiscussion | undefined =>
+  state.discussion.anchor;
+export default slice.reducer;