Explorar el Código

句子块紧凑模式

visuddhinanda hace 2 años
padre
commit
193f564437

+ 6 - 0
dashboard/src/components/template/SentEdit.tsx

@@ -55,6 +55,7 @@ export interface IWidgetSentEditInner {
   commNum?: number;
   originNum: number;
   simNum?: number;
+  compact?: boolean;
 }
 export const SentEditInner = ({
   id,
@@ -72,10 +73,12 @@ export const SentEditInner = ({
   commNum,
   originNum,
   simNum,
+  compact = false,
 }: IWidgetSentEditInner) => {
   const [wbwData, setWbwData] = useState<IWbw[]>();
   const [magicDict, setMagicDict] = useState<string>();
   const [magicDictLoading, setMagicDictLoading] = useState(false);
+  const [isCompact, setIsCompact] = useState(compact);
 
   useEffect(() => {
     const content = origin?.find(
@@ -104,6 +107,7 @@ export const SentEditInner = ({
         translation={translation}
         layout={layout}
         magicDict={magicDict}
+        compact={isCompact}
         onWbwChange={(data: IWbw[]) => {
           setWbwData(data);
         }}
@@ -127,10 +131,12 @@ export const SentEditInner = ({
         simNum={simNum}
         wbwData={wbwData}
         magicDictLoading={magicDictLoading}
+        compact={isCompact}
         onMagicDict={(type: string) => {
           setMagicDict(type);
           setMagicDictLoading(true);
         }}
+        onCompact={(value: boolean) => setIsCompact(value)}
       />
     </Card>
   );

+ 25 - 15
dashboard/src/components/template/SentEdit/EditInfo.tsx

@@ -12,28 +12,38 @@ const { Text } = Typography;
 interface IWidget {
   data: ISentence;
   isPr?: boolean;
+  compact?: boolean;
 }
-const EditInfoWidget = ({ data, isPr = false }: IWidget) => {
+const EditInfoWidget = ({ data, isPr = false, compact = false }: IWidget) => {
+  const details = (
+    <Space>
+      <Channel {...data.channel} />
+      <User {...data.editor} showAvatar={isPr ? true : false} />
+      <span>edit</span>
+      {data.prEditAt ? (
+        <TimeShow time={data.prEditAt} />
+      ) : (
+        <TimeShow time={data.updateAt} />
+      )}
+      {data.acceptor ? (
+        <User {...data.acceptor} showAvatar={false} />
+      ) : undefined}
+      {data.acceptor ? "accept at" : undefined}
+      {data.prEditAt ? <TimeShow time={data.updateAt} /> : undefined}
+    </Space>
+  );
   return (
     <div style={{ fontSize: "80%" }}>
       <Text type="secondary">
         <Space>
           {isPr ? undefined : (
-            <StudioName data={data.studio} showName={false} />
-          )}
-          <Channel {...data.channel} />
-          <User {...data.editor} showAvatar={isPr ? true : false} />
-          <span>edit</span>
-          {data.prEditAt ? (
-            <TimeShow time={data.prEditAt} />
-          ) : (
-            <TimeShow time={data.updateAt} />
+            <StudioName
+              data={data.studio}
+              showName={false}
+              popOver={compact ? details : undefined}
+            />
           )}
-          {data.acceptor ? (
-            <User {...data.acceptor} showAvatar={false} />
-          ) : undefined}
-          {data.acceptor ? "accept at" : undefined}
-          {data.prEditAt ? <TimeShow time={data.updateAt} /> : undefined}
+          {compact ? undefined : details}
         </Space>
       </Text>
     </div>

+ 58 - 37
dashboard/src/components/template/SentEdit/SentCell.tsx

@@ -6,7 +6,7 @@ import SentCellEditable from "./SentCellEditable";
 import MdView from "../MdView";
 import EditInfo from "./EditInfo";
 import SuggestionToolbar from "./SuggestionToolbar";
-import { Divider } from "antd";
+import { Divider, Space } from "antd";
 import { useAppSelector } from "../../../hooks";
 import { sentence } from "../../../reducers/accept-pr";
 import { IWbw } from "../Wbw/WbwWord";
@@ -21,18 +21,21 @@ interface IWidget {
   wordWidget?: boolean;
   isPr?: boolean;
   editMode?: boolean;
+  compact?: boolean;
 }
 const SentCellWidget = ({
   data,
   wordWidget = false,
   isPr = false,
   editMode = false,
+  compact = false,
 }: IWidget) => {
   const intl = useIntl();
   const [isEditMode, setIsEditMode] = useState(editMode);
   const [sentData, setSentData] = useState<ISentence>(data);
   const endings = useAppSelector(getEnding);
   const acceptPr = useAppSelector(sentence);
+  const [prOpen, setPrOpen] = useState(false);
 
   useEffect(() => {
     setSentData(data);
@@ -68,6 +71,16 @@ const SentCellWidget = ({
             setIsEditMode(true);
           }
         }}
+        onMenuClick={(key: string) => {
+          switch (key) {
+            case "suggestion":
+              setPrOpen(true);
+              break;
+
+            default:
+              break;
+          }
+        }}
         onConvert={(format: string) => {
           switch (format) {
             case "json":
@@ -130,47 +143,55 @@ const SentCellWidget = ({
           }
         }}
       >
-        <EditInfo data={sentData} />
-        {isEditMode ? (
-          <div>
-            {sentData.contentType === "json" ? (
-              <SentWbwEdit
-                data={sentData}
-                onClose={() => {
-                  setIsEditMode(false);
-                }}
-                onSave={(data: ISentence) => {
-                  setSentData(data);
-                }}
-              />
-            ) : (
-              <SentCellEditable
-                data={sentData}
-                isPr={isPr}
-                onClose={() => {
-                  setIsEditMode(false);
-                }}
-                onSave={(data: ISentence) => {
-                  setSentData(data);
-                  setIsEditMode(false);
-                }}
-              />
-            )}
-          </div>
-        ) : (
-          <div style={{ marginLeft: "2em" }}>
+        <Space
+          direction={compact ? "horizontal" : "vertical"}
+          style={{ alignItems: "flex-start" }}
+        >
+          <EditInfo data={sentData} compact={compact} />
+          {isEditMode ? (
+            <div>
+              {sentData.contentType === "json" ? (
+                <SentWbwEdit
+                  data={sentData}
+                  onClose={() => {
+                    setIsEditMode(false);
+                  }}
+                  onSave={(data: ISentence) => {
+                    setSentData(data);
+                  }}
+                />
+              ) : (
+                <SentCellEditable
+                  data={sentData}
+                  isPr={isPr}
+                  onClose={() => {
+                    setIsEditMode(false);
+                  }}
+                  onSave={(data: ISentence) => {
+                    setSentData(data);
+                    setIsEditMode(false);
+                  }}
+                />
+              )}
+            </div>
+          ) : (
             <MdView
+              style={{ marginLeft: compact ? 0 : "2em" }}
               html={sentData.html !== "" ? sentData.html : "请输入"}
               wordWidget={wordWidget}
             />
-          </div>
-        )}
-
-        <div style={{ marginLeft: "2em" }}>
-          <SuggestionToolbar data={sentData} isPr={isPr} />
-        </div>
+          )}
+          <SuggestionToolbar
+            style={{ marginLeft: "2em" }}
+            compact={compact}
+            data={sentData}
+            isPr={isPr}
+            prOpen={prOpen}
+            onPrClose={() => setPrOpen(false)}
+          />
+        </Space>
       </SentEditMenu>
-      <Divider style={{ margin: "10px 0" }} />
+      {compact ? undefined : <Divider style={{ margin: "10px 0" }} />}
     </div>
   );
 };

+ 4 - 2
dashboard/src/components/template/SentEdit/SentContent.tsx

@@ -23,6 +23,7 @@ interface IWidgetSentContent {
   translation?: ISentence[];
   layout?: TDirection;
   magicDict?: string;
+  compact?: boolean;
   onWbwChange?: Function;
   onMagicDictDone?: Function;
 }
@@ -35,6 +36,7 @@ const SentContentWidget = ({
   origin,
   translation,
   layout = "column",
+  compact = false,
   magicDict,
   onWbwChange,
   onMagicDictDone,
@@ -97,7 +99,7 @@ const SentContentWidget = ({
       style={{
         display: "flex",
         flexDirection: layoutDirection,
-        marginBottom: 10,
+        marginBottom: 0,
       }}
     >
       <div
@@ -137,7 +139,7 @@ const SentContentWidget = ({
       </div>
       <div style={{ flex: layoutFlex.right }}>
         {translation?.map((item, id) => {
-          return <SentCell key={id} data={item} />;
+          return <SentCell key={id} data={item} compact={compact} />;
         })}
       </div>
     </div>

+ 38 - 7
dashboard/src/components/template/SentEdit/SentEditMenu.tsx

@@ -1,4 +1,4 @@
-import { Button, Dropdown } from "antd";
+import { Button, Dropdown, message } from "antd";
 import { useState } from "react";
 import {
   EditOutlined,
@@ -6,28 +6,35 @@ import {
   MoreOutlined,
   FieldTimeOutlined,
   LinkOutlined,
+  CommentOutlined,
+  FileMarkdownOutlined,
 } from "@ant-design/icons";
 import type { MenuProps } from "antd";
 import { ISentence } from "../SentEdit";
 import SentHistoryModal from "../../corpus/SentHistoryModal";
+import { HandOutlinedIcon, JsonOutlinedIcon } from "../../../assets/icon";
 
 interface IWidget {
   data: ISentence;
   children?: React.ReactNode;
   onModeChange?: Function;
   onConvert?: Function;
+  onMenuClick?: Function;
 }
 const SentEditMenuWidget = ({
   data,
   children,
   onModeChange,
   onConvert,
+  onMenuClick,
 }: IWidget) => {
   const [isHover, setIsHover] = useState(false);
   const [timelineOpen, setTimelineOpen] = useState(false);
 
   const onClick: MenuProps["onClick"] = (e) => {
-    console.log(e);
+    if (typeof onMenuClick !== "undefined") {
+      onMenuClick(e.key);
+    }
     switch (e.key) {
       case "json":
         if (typeof onConvert !== "undefined") {
@@ -55,14 +62,29 @@ const SentEditMenuWidget = ({
     {
       type: "divider",
     },
+    {
+      key: "suggestion",
+      label: "suggestion",
+      icon: <HandOutlinedIcon />,
+    },
+    {
+      key: "discussion",
+      label: "discussion",
+      icon: <CommentOutlined />,
+    },
+    {
+      type: "divider",
+    },
     {
       key: "markdown",
-      label: "Markdown",
+      label: "To Markdown",
+      icon: <FileMarkdownOutlined />,
       disabled: data.contentType === "markdown",
     },
     {
       key: "json",
-      label: "Json",
+      label: "To Json",
+      icon: <JsonOutlinedIcon />,
       disabled: data.contentType === "json",
     },
     {
@@ -91,8 +113,8 @@ const SentEditMenuWidget = ({
       />
       <div
         style={{
-          marginTop: "-1.2em",
-          right: "0",
+          marginTop: "-4.2em",
+          right: 30,
           position: "absolute",
           display: isHover ? "block" : "none",
         }}
@@ -100,13 +122,22 @@ const SentEditMenuWidget = ({
         <Button
           icon={<EditOutlined />}
           size="small"
+          title="edit"
           onClick={() => {
             if (typeof onModeChange !== "undefined") {
               onModeChange("edit");
             }
           }}
         />
-        <Button icon={<CopyOutlined />} size="small" />
+        <Button
+          icon={<CopyOutlined />}
+          size="small"
+          onClick={() => {
+            navigator.clipboard.writeText(data.content).then(() => {
+              message.success("已经拷贝到剪贴板");
+            });
+          }}
+        />
         <Dropdown menu={{ items, onClick }} placement="bottomRight">
           <Button icon={<MoreOutlined />} size="small" />
         </Dropdown>

+ 22 - 2
dashboard/src/components/template/SentEdit/SentMenu.tsx

@@ -1,4 +1,4 @@
-import { Button, Dropdown } from "antd";
+import { Badge, Button, Dropdown, Space } from "antd";
 import { MoreOutlined } from "@ant-design/icons";
 import type { MenuProps } from "antd";
 import RelatedPara from "../../corpus/RelatedPara";
@@ -8,12 +8,14 @@ interface ISentMenu {
   para?: number;
   loading?: boolean;
   onMagicDict?: Function;
+  onMenuClick?: Function;
 }
 const SentMenuWidget = ({
   book,
   para,
   loading = false,
   onMagicDict,
+  onMenuClick,
 }: ISentMenu) => {
   const items: MenuProps["items"] = [
     {
@@ -36,16 +38,34 @@ const SentMenuWidget = ({
       key: "copy-link",
       label: "复制句子链接",
     },
+    {
+      type: "divider",
+    },
+    {
+      key: "compact",
+      label: (
+        <Space>
+          {"紧凑"}
+          <Badge count="Beta" showZero color="#faad14" />
+        </Space>
+      ),
+    },
+    {
+      key: "normal",
+      label: "正常",
+    },
   ];
   const onClick: MenuProps["onClick"] = ({ key }) => {
     console.log(`Click on item ${key}`);
+    if (typeof onMenuClick !== "undefined") {
+      onMenuClick(key);
+    }
     switch (key) {
       case "magic-dict-current":
         if (typeof onMagicDict !== "undefined") {
           onMagicDict("current");
         }
         break;
-
       default:
         break;
     }

+ 27 - 0
dashboard/src/components/template/SentEdit/SentTab.tsx

@@ -16,6 +16,7 @@ import SentMenu from "./SentMenu";
 import { IChapter } from "../../corpus/BookViewer";
 import store from "../../../store";
 import { change } from "../../../reducers/para-change";
+import { useEffect, useState } from "react";
 
 const { Text } = Typography;
 
@@ -35,7 +36,9 @@ interface IWidget {
   simNum?: number;
   wbwData?: IWbw[];
   magicDictLoading?: boolean;
+  compact?: boolean;
   onMagicDict?: Function;
+  onCompact?: Function;
 }
 const SentTabWidget = ({
   id,
@@ -52,9 +55,14 @@ const SentTabWidget = ({
   simNum = 0,
   wbwData,
   magicDictLoading = false,
+  compact = false,
   onMagicDict,
+  onCompact,
 }: IWidget) => {
   const intl = useIntl();
+  const [isCompact, setIsCompact] = useState(compact);
+
+  useEffect(() => setIsCompact(compact), [compact]);
   const mPath = path
     ? [
         ...path,
@@ -70,6 +78,7 @@ const SentTabWidget = ({
   return (
     <>
       <Tabs
+        style={isCompact ? { position: "absolute", marginTop: -32 } : undefined}
         tabBarStyle={{ marginBottom: 0 }}
         size="small"
         tabBarGutter={0}
@@ -101,6 +110,24 @@ const SentTabWidget = ({
                   onMagicDict(type);
                 }
               }}
+              onMenuClick={(key: string) => {
+                switch (key) {
+                  case "compact" || "normal":
+                    if (typeof onCompact !== "undefined") {
+                      setIsCompact(true);
+                      onCompact(true);
+                    }
+                    break;
+                  case "normal":
+                    if (typeof onCompact !== "undefined") {
+                      setIsCompact(false);
+                      onCompact(false);
+                    }
+                    break;
+                  default:
+                    break;
+                }
+              }}
             />
           </Space>
         }

+ 18 - 7
dashboard/src/components/template/SentEdit/SuggestionBox.tsx

@@ -13,13 +13,21 @@ export interface IAnswerCount {
 interface IWidget {
   data: ISentence;
   trigger?: JSX.Element;
+  open?: boolean;
+  onClose?: Function;
 }
-const SuggestionBoxWidget = ({ trigger, data }: IWidget) => {
-  const [open, setOpen] = useState(false);
+const SuggestionBoxWidget = ({
+  trigger,
+  data,
+  open = false,
+  onClose,
+}: IWidget) => {
+  const [isOpen, setIsOpen] = useState(open);
   const [reload, setReload] = useState(false);
   const [openNotification, setOpenNotification] = useState(false);
   const [prNumber, setPrNumber] = useState(data.suggestionCount?.suggestion);
 
+  useEffect(() => setIsOpen(open), [open]);
   useEffect(() => {
     if (localStorage.getItem("read_pr_Notification") === "ok") {
       setOpenNotification(false);
@@ -28,11 +36,14 @@ const SuggestionBoxWidget = ({ trigger, data }: IWidget) => {
     }
   }, []);
   const showDrawer = () => {
-    setOpen(true);
+    setIsOpen(true);
   };
 
-  const onClose = () => {
-    setOpen(false);
+  const onBoxClose = () => {
+    setIsOpen(false);
+    if (typeof onClose !== "undefined") {
+      onClose();
+    }
   };
 
   return (
@@ -45,8 +56,8 @@ const SuggestionBoxWidget = ({ trigger, data }: IWidget) => {
       <Drawer
         title="修改建议"
         width={520}
-        onClose={onClose}
-        open={open}
+        onClose={onBoxClose}
+        open={isOpen}
         maskClosable={false}
       >
         <Space direction="vertical" style={{ width: "100%" }}>

+ 29 - 7
dashboard/src/components/template/SentEdit/SuggestionToolbar.tsx

@@ -7,14 +7,26 @@ import SuggestionBox from "./SuggestionBox";
 import PrAcceptButton from "./PrAcceptButton";
 import { HandOutlinedIcon } from "../../../assets/icon";
 
-const { Text } = Typography;
+const { Text, Paragraph } = Typography;
 
 interface IWidget {
   data: ISentence;
   isPr?: boolean;
+  style?: React.CSSProperties;
+  compact?: boolean;
+  prOpen?: boolean;
+  onPrClose?: Function;
   onAccept?: Function;
 }
-const SuggestionToolbarWidget = ({ data, isPr = false, onAccept }: IWidget) => {
+const SuggestionToolbarWidget = ({
+  data,
+  isPr = false,
+  onAccept,
+  style,
+  prOpen = false,
+  compact = false,
+  onPrClose,
+}: IWidget) => {
   const [CommentCount, setCommentCount] = useState<number | undefined>(
     data.suggestionCount?.discussion
   );
@@ -33,8 +45,14 @@ const SuggestionToolbarWidget = ({ data, isPr = false, onAccept }: IWidget) => {
     </Space>
   );
   const normalButton = (
-    <Space>
+    <Space size={"small"}>
       <SuggestionBox
+        open={prOpen}
+        onClose={() => {
+          if (typeof onPrClose !== "undefined") {
+            onPrClose();
+          }
+        }}
         data={data}
         trigger={
           <Tooltip title="修改建议">
@@ -42,7 +60,7 @@ const SuggestionToolbarWidget = ({ data, isPr = false, onAccept }: IWidget) => {
           </Tooltip>
         }
       />
-      <Divider type="vertical" />
+      {compact ? undefined : <Divider type="vertical" />}
       <CommentBox
         resId={data.id}
         resType="sentence"
@@ -56,11 +74,15 @@ const SuggestionToolbarWidget = ({ data, isPr = false, onAccept }: IWidget) => {
         }}
       />
       {CommentCount}
-      <Divider type="vertical" />
-      <Text copyable={{ text: data.content }}></Text>
+      {compact ? undefined : <Divider type="vertical" />}
+      {compact ? undefined : <Text copyable={{ text: data.content }}></Text>}
     </Space>
   );
-  return <Text type="secondary">{isPr ? prButton : normalButton}</Text>;
+  return (
+    <Paragraph type="secondary" style={style}>
+      {isPr ? prButton : normalButton}
+    </Paragraph>
+  );
 };
 
 export default SuggestionToolbarWidget;