Просмотр исходного кода

Merge pull request #2007 from visuddhinanda/agile

✨ 中间的导航菜单
visuddhinanda 2 лет назад
Родитель
Сommit
a4337556dc

+ 1 - 1
dashboard/src/components/article/AnthologyDetail.tsx

@@ -43,7 +43,7 @@ const AnthologyDetailWidget = ({
 
   function fetchData(id?: string) {
     const url = `/v2/anthology/${id}`;
-    console.log("url", url);
+    console.info("url", url);
     if (typeof onLoading !== "undefined") {
       onLoading(true);
     }

+ 8 - 7
dashboard/src/components/article/Article.tsx

@@ -91,7 +91,7 @@ const ArticleWidget = ({
       {type === "article" ? (
         <TypeArticle
           type={type}
-          articleId={currId}
+          articleId={onArticleChange ? articleId : currId}
           channelId={channelId}
           mode={mode}
           anthologyId={anthologyId}
@@ -122,7 +122,8 @@ const ArticleWidget = ({
         />
       ) : type === "anthology" ? (
         <TypeAnthology
-          articleId={currId}
+          type={type}
+          articleId={onArticleChange ? articleId : currId}
           channelId={channelId}
           mode={mode}
           onArticleChange={(type: ArticleType, id: string, target: string) => {
@@ -138,7 +139,7 @@ const ArticleWidget = ({
         />
       ) : type === "term" ? (
         <TypeTerm
-          articleId={currId}
+          articleId={onArticleChange ? articleId : currId}
           channelId={channelId}
           mode={mode}
           onArticleChange={(type: ArticleType, id: string, target: string) => {
@@ -150,7 +151,7 @@ const ArticleWidget = ({
       ) : type === "chapter" || type === "para" ? (
         <TypePali
           type={type}
-          articleId={currId}
+          articleId={onArticleChange ? articleId : currId}
           channelId={channelId}
           mode={mode}
           book={book}
@@ -179,7 +180,7 @@ const ArticleWidget = ({
         />
       ) : type === "page" ? (
         <TypePage
-          articleId={currId}
+          articleId={onArticleChange ? articleId : currId}
           channelId={channelId}
           focus={focus}
           mode={mode}
@@ -201,7 +202,7 @@ const ArticleWidget = ({
         />
       ) : type === "cs-para" ? (
         <TypeCSPara
-          articleId={currId}
+          articleId={onArticleChange ? articleId : currId}
           channelId={channelId}
           mode={mode}
           onArticleChange={(type: ArticleType, id: string, target: string) => {
@@ -213,7 +214,7 @@ const ArticleWidget = ({
       ) : type === "textbook" ? (
         <TypeCourse
           type={type}
-          articleId={currId}
+          articleId={onArticleChange ? articleId : currId}
           channelId={channelId}
           courseId={courseId}
           mode={mode}

+ 39 - 16
dashboard/src/components/article/NavigateButton.tsx

@@ -1,15 +1,16 @@
-import { Button, Space, Typography } from "antd";
+import { Button, Dropdown, Popover, Space, Typography } from "antd";
 import { DoubleRightOutlined, DoubleLeftOutlined } from "@ant-design/icons";
+import { ITocPathNode } from "../corpus/TocPath";
 
 const { Paragraph, Text } = Typography;
 
 const EllipsisMiddle: React.FC<{
   suffixCount: number;
   maxWidth: number;
-  children?: string;
-}> = ({ suffixCount, maxWidth = 500, children = "" }) => {
-  const start = children.slice(0, children.length - suffixCount).trim();
-  const suffix = children.slice(-suffixCount).trim();
+  text?: string;
+}> = ({ suffixCount, maxWidth = 500, text = "" }) => {
+  const start = text.slice(0, text.length - suffixCount).trim();
+  const suffix = text.slice(-suffixCount).trim();
   return (
     <Text style={{ maxWidth: maxWidth }} ellipsis={{ suffix }}>
       {start}
@@ -18,19 +19,22 @@ const EllipsisMiddle: React.FC<{
 };
 
 interface IWidget {
-  title?: string;
   prevTitle?: string;
   nextTitle?: string;
+  path?: ITocPathNode[];
   onPrev?: Function;
   onNext?: Function;
+  onPathChange?: Function;
 }
 const NavigateButtonWidget = ({
-  title,
   prevTitle,
   nextTitle,
+  path,
   onPrev,
   onNext,
+  onPathChange,
 }: IWidget) => {
+  const currTitle = path && path.length > 0 ? path[path.length - 1].title : "";
   return (
     <Paragraph style={{ display: "flex", justifyContent: "space-between" }}>
       <Button
@@ -43,13 +47,29 @@ const NavigateButtonWidget = ({
         }}
       >
         <Space>
-          <DoubleLeftOutlined />
-          <EllipsisMiddle maxWidth={300} suffixCount={7}>
-            {prevTitle}
-          </EllipsisMiddle>
+          <DoubleLeftOutlined key="icon" />
+          <EllipsisMiddle maxWidth={300} suffixCount={7} text={prevTitle} />
         </Space>
       </Button>
-      <Text>{title}</Text>
+      <div>
+        <Dropdown
+          placement="top"
+          trigger={["hover"]}
+          menu={{
+            items: path?.map((item, id) => {
+              return { label: item.title, key: item.key ?? item.title };
+            }),
+            onClick: (e) => {
+              console.debug("onPathChange", e.key);
+              if (typeof onPathChange !== "undefined") {
+                onPathChange(e.key);
+              }
+            },
+          }}
+        >
+          <span>{currTitle}</span>
+        </Dropdown>
+      </div>
       <Button
         size="large"
         disabled={typeof nextTitle === "undefined"}
@@ -60,10 +80,13 @@ const NavigateButtonWidget = ({
         }}
       >
         <Space>
-          <EllipsisMiddle maxWidth={300} suffixCount={7}>
-            {nextTitle}
-          </EllipsisMiddle>
-          <DoubleRightOutlined />
+          <EllipsisMiddle
+            key="title"
+            maxWidth={300}
+            suffixCount={7}
+            text={nextTitle}
+          />
+          <DoubleRightOutlined key="icon" />
         </Space>
       </Button>
     </Paragraph>

+ 15 - 0
dashboard/src/components/article/TypeArticleReader.tsx

@@ -230,6 +230,7 @@ const TypeArticleReaderWidget = ({
           <NavigateButton
             prevTitle={nav?.prev?.title}
             nextTitle={nav?.next?.title}
+            path={currPath}
             onNext={() => {
               if (typeof onArticleChange !== "undefined") {
                 onArticleChange("article", nav?.next?.article_id);
@@ -240,6 +241,20 @@ const TypeArticleReaderWidget = ({
                 onArticleChange("article", nav?.prev?.article_id);
               }
             }}
+            onPathChange={(key: string) => {
+              if (typeof onArticleChange !== "undefined") {
+                const node = currPath?.find((value) => value.key === key);
+                if (node) {
+                  let newType = type;
+                  if (node.level === 0) {
+                    newType = "anthology";
+                  } else {
+                    newType = "article";
+                  }
+                  onArticleChange(newType, node.key, "_self");
+                }
+              }
+            }}
           />
 
           <InteractiveArea resType={"article"} resId={articleId} />

+ 4 - 4
dashboard/src/components/article/article.css

@@ -8,20 +8,20 @@ h6 {
 }
 .pcd_article h2 {
   margin-top: 1em;
-  font-size: 200%;
+  font-size: 28px;
   border-bottom: 1px solid gray;
 }
 .pcd_article h2 {
   margin-top: 1em;
-  font-size: 150%;
+  font-size: 22px;
   border-bottom: 1px solid gray;
 }
 .pcd_article h3 {
   margin-top: 0.5em;
-  font-size: 130%;
+  font-size: 16px;
 }
 .pcd_article h4 {
-  font-size: 110%;
+  font-size: 100%;
 }
 .pcd_article h5 {
   font-size: 100%;

+ 14 - 26
dashboard/src/pages/library/article/show.tsx

@@ -173,23 +173,6 @@ const Widget = () => {
               style={{ display: "flex", height: 44, alignItems: "center" }}
               key="right"
             >
-              {type === "article" && loadedArticleData ? (
-                <>
-                  <Button
-                    ghost
-                    onClick={(event) => {
-                      const url = `/studio/${loadedArticleData.studio?.realName}/article/edit/${loadedArticleData.uid}`;
-                      if (event.ctrlKey || event.metaKey) {
-                        window.open(fullUrl(url), "_blank");
-                      } else {
-                        navigate(url);
-                      }
-                    }}
-                  >
-                    Edit
-                  </Button>
-                </>
-              ) : undefined}
               <ShareButton
                 type={type as ArticleType}
                 book={searchParams.get("book")}
@@ -384,17 +367,22 @@ const Widget = () => {
                 console.log("article change", newType, article, target);
                 scrollToTop();
                 let url = `/article/${newType}/${article}?mode=${currMode}`;
+                if (type === "anthology" && newType === "article") {
+                  url += `&anthology=${id}`;
+                }
                 searchParams.forEach((value, key) => {
                   console.log(value, key);
-                  if (key !== "mode") {
-                    const paramValue = param?.find(
-                      (value) => value.key === key
-                    );
-                    if (paramValue) {
-                      url += `&${key}=${paramValue.value}`;
-                    } else {
-                      url += `&${key}=${value}`;
-                    }
+                  if (key === "mode") {
+                    return;
+                  }
+                  if (newType === "anthology" && key === "anthology") {
+                    return;
+                  }
+                  const paramValue = param?.find((value) => value.key === key);
+                  if (paramValue) {
+                    url += `&${key}=${paramValue.value}`;
+                  } else {
+                    url += `&${key}=${value}`;
                   }
                 });
                 if (target === "_blank") {