Browse Source

Merge pull request #2082 from visuddhinanda/agile

课程模式获取学生discussion
visuddhinanda 1 year ago
parent
commit
4857de8304

+ 25 - 0
dashboard/src/assets/icon/index.tsx

@@ -777,6 +777,27 @@ const LockFillSvg = () => (
     ></path>
     ></path>
   </svg>
   </svg>
 );
 );
+
+const ShortcutSvg = () => (
+  <svg
+    viewBox="0 0 1024 1024"
+    version="1.1"
+    xmlns="http://www.w3.org/2000/svg"
+    p-id="4427"
+    width="1em"
+    height="1em"
+    fill="currentColor"
+  >
+    <path
+      d="M474.325333 180.992a32 32 0 0 1 3.072 64H324.992a80 80 0 0 0-79.872 75.733333v377.6a80 80 0 0 0 75.605333 80h377.6a80 80 0 0 0 80-75.733333v-153.6a32 32 0 0 1 64-3.072v152.405333a144 144 0 0 1-138.965333 143.914667H324.992a144 144 0 0 1-144-138.88V324.992a144 144 0 0 1 138.965333-144h5.034667z"
+      p-id="4428"
+    ></path>
+    <path
+      d="M748.16 215.509333l2.474667 2.176 54.272 52.522667 2.048 2.176a32 32 0 0 1-15.658667 57.813333H724.949333a181.333333 181.333333 0 0 0-181.248 175.872v16.128a32 32 0 0 1-64 3.072v-13.738666a245.376 245.376 0 0 1 229.76-244.864l-3.285333-3.114667a32 32 0 0 1 42.026667-48.170667z"
+      p-id="4429"
+    ></path>
+  </svg>
+);
 export const DictIcon = (props: Partial<CustomIconComponentProps>) => (
 export const DictIcon = (props: Partial<CustomIconComponentProps>) => (
   <Icon component={DictSvg} {...props} />
   <Icon component={DictSvg} {...props} />
 );
 );
@@ -925,3 +946,7 @@ export const LockFillIcon = (props: Partial<CustomIconComponentProps>) => (
 export const UnLockFillIcon = (props: Partial<CustomIconComponentProps>) => (
 export const UnLockFillIcon = (props: Partial<CustomIconComponentProps>) => (
   <Icon component={UnLockFillSvg} {...props} />
   <Icon component={UnLockFillSvg} {...props} />
 );
 );
+
+export const ShortcutIcon = (props: Partial<CustomIconComponentProps>) => (
+  <Icon component={ShortcutSvg} {...props} />
+);

+ 32 - 15
dashboard/src/components/discussion/DiscussionListCard.tsx

@@ -1,5 +1,6 @@
 import { useEffect, useRef, useState } from "react";
 import { useEffect, useRef, useState } from "react";
 import { Button, Space, Typography } from "antd";
 import { Button, Space, Typography } from "antd";
+import { LinkOutlined } from "@ant-design/icons";
 
 
 import { get } from "../../request";
 import { get } from "../../request";
 import { ICommentListResponse } from "../api/Comment";
 import { ICommentListResponse } from "../api/Comment";
@@ -15,6 +16,8 @@ import { currentUser as _currentUser } from "../../reducers/current-user";
 import { CommentOutlinedIcon, TemplateOutlinedIcon } from "../../assets/icon";
 import { CommentOutlinedIcon, TemplateOutlinedIcon } from "../../assets/icon";
 import { ISentenceResponse } from "../api/Corpus";
 import { ISentenceResponse } from "../api/Corpus";
 import { TDiscussionType } from "./Discussion";
 import { TDiscussionType } from "./Discussion";
+import { courseInfo, memberInfo } from "../../reducers/current-course";
+import { courseUser } from "../../reducers/course-user";
 
 
 export type TResType =
 export type TResType =
   | "article"
   | "article"
@@ -57,6 +60,10 @@ const DiscussionListCardWidget = ({
   const [count, setCount] = useState<number>(0);
   const [count, setCount] = useState<number>(0);
   const [canCreate, setCanCreate] = useState(false);
   const [canCreate, setCanCreate] = useState(false);
 
 
+  const course = useAppSelector(courseInfo);
+  const courseMember = useAppSelector(memberInfo);
+  const myCourse = useAppSelector(courseUser);
+
   const user = useAppSelector(_currentUser);
   const user = useAppSelector(_currentUser);
 
 
   useEffect(() => {
   useEffect(() => {
@@ -97,19 +104,22 @@ const DiscussionListCardWidget = ({
           title: {
           title: {
             render(dom, entity, index, action, schema) {
             render(dom, entity, index, action, schema) {
               return (
               return (
-                <Button
-                  key={index}
-                  size="small"
-                  type="link"
-                  icon={entity.newTpl ? <TemplateOutlinedIcon /> : undefined}
-                  onClick={(event) => {
-                    if (typeof onSelect !== "undefined") {
-                      onSelect(event, entity);
-                    }
-                  }}
-                >
-                  {entity.title}
-                </Button>
+                <>
+                  {entity.resId !== resId ? <LinkOutlined /> : <></>}
+                  <Button
+                    key={index}
+                    size="small"
+                    type="link"
+                    icon={entity.newTpl ? <TemplateOutlinedIcon /> : undefined}
+                    onClick={(event) => {
+                      if (typeof onSelect !== "undefined") {
+                        onSelect(event, entity);
+                      }
+                    }}
+                  >
+                    {entity.title}
+                  </Button>
+                </>
               );
               );
             },
             },
           },
           },
@@ -155,9 +165,16 @@ const DiscussionListCardWidget = ({
           url += `&limit=${params.pageSize}&offset=${offset}`;
           url += `&limit=${params.pageSize}&offset=${offset}`;
           url += params.keyword ? "&search=" + params.keyword : "";
           url += params.keyword ? "&search=" + params.keyword : "";
           url += activeKey ? "&status=" + activeKey : "";
           url += activeKey ? "&status=" + activeKey : "";
-          console.log("DiscussionListCard api request", url);
+
+          if (myCourse && course) {
+            if (myCourse.role !== "student") {
+              url += `&course=${course.courseId}`;
+            }
+          }
+
+          console.info("DiscussionListCard api request", url);
           const res = await get<ICommentListResponse>(url);
           const res = await get<ICommentListResponse>(url);
-          console.debug("DiscussionListCard api response", res);
+          console.info("DiscussionListCard api response", res);
           setCount(res.data.active);
           setCount(res.data.active);
           setCanCreate(res.data.can_create);
           setCanCreate(res.data.can_create);
           const items: IComment[] = res.data.rows.map((item, id) => {
           const items: IComment[] = res.data.rows.map((item, id) => {

+ 2 - 2
dashboard/src/components/discussion/DiscussionShow.tsx

@@ -129,9 +129,9 @@ const DiscussionShowWidget = ({
       status: data.status,
       status: data.status,
       type: newType,
       type: newType,
     };
     };
-    console.debug("api response", url, newData);
+    console.info("api response", url, newData);
     put<ICommentRequest, ICommentResponse>(url, newData).then((json) => {
     put<ICommentRequest, ICommentResponse>(url, newData).then((json) => {
-      console.debug("api response", json);
+      console.info("api response", json);
       if (json.ok) {
       if (json.ok) {
         notification.info({ message: "转换成功" });
         notification.info({ message: "转换成功" });
         if (typeof onConvert !== "undefined") {
         if (typeof onConvert !== "undefined") {

+ 19 - 4
dashboard/src/components/template/SentEdit/SentWbw.tsx

@@ -1,5 +1,6 @@
-import { List, Space, message } from "antd";
+import { Button, List, Space, message } from "antd";
 import { useEffect, useState } from "react";
 import { useEffect, useState } from "react";
+import { ReloadOutlined } from "@ant-design/icons";
 
 
 import { get } from "../../../request";
 import { get } from "../../../request";
 import { ISentenceWbwListResponse } from "../../api/Corpus";
 import { ISentenceWbwListResponse } from "../../api/Corpus";
@@ -29,9 +30,9 @@ const SentWbwWidget = ({
   wbwProgress = false,
   wbwProgress = false,
   onReload,
   onReload,
 }: IWidget) => {
 }: IWidget) => {
-  const [initLoading, setInitLoading] = useState(true);
   const [sentData, setSentData] = useState<IWidgetSentEditInner[]>([]);
   const [sentData, setSentData] = useState<IWidgetSentEditInner[]>([]);
   const [answer, setAnswer] = useState<ISentence>();
   const [answer, setAnswer] = useState<ISentence>();
+  const [loading, setLoading] = useState<boolean>(false);
   const course = useAppSelector(courseInfo);
   const course = useAppSelector(courseInfo);
   const courseMember = useAppSelector(memberInfo);
   const courseMember = useAppSelector(memberInfo);
 
 
@@ -68,6 +69,7 @@ const SentWbwWidget = ({
       }
       }
     }
     }
 
 
+    setLoading(true);
     console.info("wbw sentence api request", url);
     console.info("wbw sentence api request", url);
     get<ISentenceWbwListResponse>(url)
     get<ISentenceWbwListResponse>(url)
       .then((json) => {
       .then((json) => {
@@ -102,7 +104,7 @@ const SentWbwWidget = ({
         }
         }
       })
       })
       .finally(() => {
       .finally(() => {
-        setInitLoading(false);
+        setLoading(false);
         if (reload && typeof onReload !== "undefined") {
         if (reload && typeof onReload !== "undefined") {
           onReload();
           onReload();
         }
         }
@@ -134,7 +136,20 @@ const SentWbwWidget = ({
   return (
   return (
     <>
     <>
       <List
       <List
-        loading={initLoading}
+        loading={loading}
+        header={
+          <div style={{ display: "flex", justifyContent: "space-between" }}>
+            <span></span>
+            <Space>
+              <Button
+                type="link"
+                shape="round"
+                icon={<ReloadOutlined />}
+                onClick={() => load()}
+              />
+            </Space>
+          </div>
+        }
         itemLayout="horizontal"
         itemLayout="horizontal"
         split={false}
         split={false}
         dataSource={sentData}
         dataSource={sentData}

+ 3 - 2
dashboard/src/components/template/Wbw/WbwDetailCase.tsx

@@ -19,7 +19,7 @@ interface IWidget {
 const WbwDetailCaseWidget = ({ data, readonly = false, onChange }: IWidget) => {
 const WbwDetailCaseWidget = ({ data, readonly = false, onChange }: IWidget) => {
   const inlineDict = useAppSelector(_inlineDict);
   const inlineDict = useAppSelector(_inlineDict);
   const intl = useIntl();
   const intl = useIntl();
-
+  console.debug("readonly", readonly);
   return (
   return (
     <div style={{ display: "flex", width: "100%" }}>
     <div style={{ display: "flex", width: "100%" }}>
       <SelectCase
       <SelectCase
@@ -32,6 +32,7 @@ const WbwDetailCaseWidget = ({ data, readonly = false, onChange }: IWidget) => {
         }}
         }}
       />
       />
       <Dropdown
       <Dropdown
+        trigger={readonly ? [] : ["click"]}
         menu={{
         menu={{
           items: data.real.value
           items: data.real.value
             ? caseInDict(
             ? caseInDict(
@@ -50,7 +51,7 @@ const WbwDetailCaseWidget = ({ data, readonly = false, onChange }: IWidget) => {
         }}
         }}
         placement="bottomRight"
         placement="bottomRight"
       >
       >
-        <Button type="text" icon={<MoreOutlined />} />
+        <Button disabled={readonly} type="text" icon={<MoreOutlined />} />
       </Dropdown>
       </Dropdown>
     </div>
     </div>
   );
   );

+ 6 - 2
dashboard/src/components/template/Wbw/WbwDetailFm.tsx

@@ -133,6 +133,7 @@ const WbwFactorMeaningItem = ({
     />
     />
   ) : (
   ) : (
     <Button
     <Button
+      disabled={readonly}
       key={1}
       key={1}
       size="small"
       size="small"
       type="text"
       type="text"
@@ -145,7 +146,7 @@ const WbwFactorMeaningItem = ({
     </Button>
     </Button>
   );
   );
 
 
-  return editable ? (
+  return editable || readonly ? (
     meaningInner
     meaningInner
   ) : (
   ) : (
     <Dropdown
     <Dropdown
@@ -265,6 +266,7 @@ const WbwDetailFmWidget = ({
                 {factors[index]?.split("-").map((item1, index1) => {
                 {factors[index]?.split("-").map((item1, index1) => {
                   return (
                   return (
                     <WbwFactorMeaningItem
                     <WbwFactorMeaningItem
+                      readonly={readonly}
                       key={index1}
                       key={index1}
                       pali={item1}
                       pali={item1}
                       meaning={fm[index1]}
                       meaning={fm[index1]}
@@ -291,11 +293,12 @@ const WbwDetailFmWidget = ({
                 })}
                 })}
 
 
                 {index < currValue.length - 1 ? (
                 {index < currValue.length - 1 ? (
-                  <PlusOutlined key={`icon-${index}`} />
+                  <PlusOutlined disabled={readonly} key={`icon-${index}`} />
                 ) : (
                 ) : (
                   <>
                   <>
                     <Tooltip title="在文本框中编辑">
                     <Tooltip title="在文本框中编辑">
                       <Button
                       <Button
+                        disabled={readonly}
                         key="EditOutlined"
                         key="EditOutlined"
                         size="small"
                         size="small"
                         type="text"
                         type="text"
@@ -305,6 +308,7 @@ const WbwDetailFmWidget = ({
                     </Tooltip>
                     </Tooltip>
                     <Tooltip title="合并后替换含义">
                     <Tooltip title="合并后替换含义">
                       <Button
                       <Button
+                        disabled={readonly}
                         key="CheckOutlined"
                         key="CheckOutlined"
                         size="small"
                         size="small"
                         type="text"
                         type="text"