Explorar o código

Merge pull request #2045 from visuddhinanda/agile

不能建立时隐藏建立按钮
visuddhinanda %!s(int64=2) %!d(string=hai) anos
pai
achega
cba52a9815

+ 2 - 0
dashboard/src/components/api/Dict.ts

@@ -20,6 +20,7 @@ export interface IDictRequest {
   creator_id?: number;
   creator_id?: number;
   editor?: IUser;
   editor?: IUser;
   studio?: IStudio;
   studio?: IStudio;
+  status?: number;
   updated_at?: string;
   updated_at?: string;
 }
 }
 export interface IUserDictCreate {
 export interface IUserDictCreate {
@@ -58,6 +59,7 @@ export interface IApiResponseDictData {
   updated_at: string;
   updated_at: string;
   exp?: number;
   exp?: number;
   editor?: IUser;
   editor?: IUser;
+  status?: number;
 }
 }
 export interface IApiResponseDict {
 export interface IApiResponseDict {
   ok: boolean;
   ok: boolean;

+ 7 - 1
dashboard/src/components/auth/Avatar.tsx

@@ -82,7 +82,13 @@ const AvatarWidget = ({ style, placement = "bottomRight" }: IWidget) => {
       </ProCard>
       </ProCard>
     );
     );
   };
   };
-  const Login = () => <Link to="/anonymous/users/sign-in">登录/注册</Link>;
+  const Login = () => (
+    <Link to="/anonymous/users/sign-in">
+      {intl.formatMessage({
+        id: "nut.users.sign-in-up.title",
+      })}
+    </Link>
+  );
   return (
   return (
     <>
     <>
       <Popover content={user ? <UserCard /> : <Login />} placement={placement}>
       <Popover content={user ? <UserCard /> : <Login />} placement={placement}>

+ 7 - 1
dashboard/src/components/auth/SignInAvatar.tsx

@@ -39,7 +39,13 @@ const SignInAvatarWidget = ({ style, placement = "bottomRight" }: IWidget) => {
   }, [user]);
   }, [user]);
 
 
   if (typeof user === "undefined") {
   if (typeof user === "undefined") {
-    return <Link to="/anonymous/users/sign-in">登录/注册</Link>;
+    return (
+      <Link to="/anonymous/users/sign-in">
+        {intl.formatMessage({
+          id: "nut.users.sign-in-up.title",
+        })}
+      </Link>
+    );
   } else {
   } else {
     return (
     return (
       <>
       <>

+ 0 - 6
dashboard/src/components/channel/ChannelTable.tsx

@@ -300,12 +300,6 @@ const ChannelTableWidget = ({
                 }),
                 }),
                 status: "Default",
                 status: "Default",
               },
               },
-              general: {
-                text: intl.formatMessage({
-                  id: "channel.type.general.label",
-                }),
-                status: "Default",
-              },
             },
             },
           },
           },
           {
           {

+ 0 - 4
dashboard/src/components/channel/ChannelTypeSelect.tsx

@@ -25,10 +25,6 @@ const ChannelTypeSelectWidget = ({ readonly }: IWidget) => {
       value: "original",
       value: "original",
       label: intl.formatMessage({ id: "channel.type.original.label" }),
       label: intl.formatMessage({ id: "channel.type.original.label" }),
     },
     },
-    {
-      value: "general",
-      label: intl.formatMessage({ id: "channel.type.general.label" }),
-    },
   ];
   ];
   return (
   return (
     <ProFormSelect
     <ProFormSelect

+ 6 - 0
dashboard/src/components/dict/MyCreate.tsx

@@ -18,6 +18,7 @@ import { add, updateIndex, wordIndex } from "../../reducers/inline-dict";
 import store from "../../store";
 import store from "../../store";
 import { get as getUiLang } from "../../locales";
 import { get as getUiLang } from "../../locales";
 import { myDictDirty } from "../../reducers/command";
 import { myDictDirty } from "../../reducers/command";
+import { currentUser } from "../../reducers/current-user";
 
 
 export const UserWbwPost = (data: IDictRequest[], view: string) => {
 export const UserWbwPost = (data: IDictRequest[], view: string) => {
   let wordData: IDictRequest[] = data;
   let wordData: IDictRequest[] = data;
@@ -52,6 +53,7 @@ export const UserWbwPost = (data: IDictRequest[], view: string) => {
           factormean: pFm,
           factormean: pFm,
           confidence: value.confidence,
           confidence: value.confidence,
           language: value.language,
           language: value.language,
+          status: value.status,
         });
         });
       }
       }
     }
     }
@@ -71,6 +73,7 @@ export const UserWbwPost = (data: IDictRequest[], view: string) => {
             mean: meaning,
             mean: meaning,
             confidence: value.confidence,
             confidence: value.confidence,
             language: value.language,
             language: value.language,
+            status: value.status,
           });
           });
         }
         }
 
 
@@ -84,6 +87,7 @@ export const UserWbwPost = (data: IDictRequest[], view: string) => {
               mean: subFactorsMeaning[index1],
               mean: subFactorsMeaning[index1],
               confidence: value.confidence,
               confidence: value.confidence,
               language: value.language,
               language: value.language,
+              status: value.status,
             });
             });
           }
           }
         });
         });
@@ -115,6 +119,7 @@ const MyCreateWidget = ({ word, onSave }: IWidget) => {
   });
   });
   const [loading, setLoading] = useState(false);
   const [loading, setLoading] = useState(false);
   const inlineWordIndex = useAppSelector(wordIndex);
   const inlineWordIndex = useAppSelector(wordIndex);
+  const user = useAppSelector(currentUser);
 
 
   useEffect(() => setWordSpell(word), [word]);
   useEffect(() => setWordSpell(word), [word]);
 
 
@@ -270,6 +275,7 @@ const MyCreateWidget = ({ word, onSave }: IWidget) => {
                 factors: editWord.factors?.value,
                 factors: editWord.factors?.value,
                 factormean: editWord.factorMeaning?.value,
                 factormean: editWord.factorMeaning?.value,
                 language: getUiLang(),
                 language: getUiLang(),
+                status: user?.roles?.includes("basic") ? 5 : 30,
                 confidence: 100,
                 confidence: 100,
               },
               },
             ];
             ];

+ 9 - 3
dashboard/src/components/dict/UserDictList.tsx

@@ -46,6 +46,7 @@ export interface IWord {
   note?: string | null;
   note?: string | null;
   factors?: string | null;
   factors?: string | null;
   dict?: IDictInfo;
   dict?: IDictInfo;
+  status?: number;
   updated_at?: string;
   updated_at?: string;
   created_at?: string;
   created_at?: string;
 }
 }
@@ -204,19 +205,21 @@ const UserDictListWidget = ({
           },
           },
           description: {
           description: {
             dataIndex: "meaning",
             dataIndex: "meaning",
-            title: "整体意思",
-            search: word ? false : undefined,
+            title: "description",
+            search: false,
             render(dom, entity, index, action, schema) {
             render(dom, entity, index, action, schema) {
               return (
               return (
                 <div>
                 <div>
                   <Space>
                   <Space>
                     {entity.meaning}
                     {entity.meaning}
-
+                    {"|"}
                     <TimeShow
                     <TimeShow
                       updatedAt={entity.updated_at}
                       updatedAt={entity.updated_at}
                       createdAt={entity.updated_at}
                       createdAt={entity.updated_at}
                       type="secondary"
                       type="secondary"
                     />
                     />
+                    {"|"}
+                    {entity.status === 5 ? "私有" : "公开"}
                   </Space>
                   </Space>
                   {compact ? (
                   {compact ? (
                     <div>
                     <div>
@@ -232,6 +235,7 @@ const UserDictListWidget = ({
           content: compact
           content: compact
             ? undefined
             ? undefined
             : {
             : {
+                search: false,
                 render(dom, entity, index, action, schema) {
                 render(dom, entity, index, action, schema) {
                   return (
                   return (
                     <div>
                     <div>
@@ -506,6 +510,7 @@ const UserDictListWidget = ({
               note: item.note,
               note: item.note,
               factors: item.factors,
               factors: item.factors,
               dict: item.dict,
               dict: item.dict,
+              status: item.status,
               updated_at: item.updated_at,
               updated_at: item.updated_at,
             };
             };
           });
           });
@@ -568,6 +573,7 @@ const UserDictListWidget = ({
       </Drawer>
       </Drawer>
       <Drawer
       <Drawer
         title={drawerTitle}
         title={drawerTitle}
+        width={500}
         placement="right"
         placement="right"
         open={isEditOpen}
         open={isEditOpen}
         onClose={() => {
         onClose={() => {

+ 1 - 1
dashboard/src/components/library/HeadBar.tsx

@@ -22,7 +22,7 @@ export const mainMenuItems: MenuProps["items"] = [
   {
   {
     label: (
     label: (
       <a href="/" rel="noreferrer">
       <a href="/" rel="noreferrer">
-        首页
+        <FormattedMessage id="columns.library.home.title" />
       </a>
       </a>
     ),
     ),
     key: "home",
     key: "home",

+ 3 - 1
dashboard/src/components/nut/users/SignUp.tsx

@@ -46,7 +46,9 @@ const SignUpWidget = ({ token }: IWidget) => {
           type="primary"
           type="primary"
           onClick={() => navigate("/anonymous/users/sign-in")}
           onClick={() => navigate("/anonymous/users/sign-in")}
         >
         >
-          登录
+          {intl.formatMessage({
+            id: "nut.users.sign-up.title",
+          })}
         </Button>
         </Button>
       }
       }
     />
     />

+ 1 - 3
dashboard/src/components/studio/HeadBar.tsx

@@ -34,9 +34,7 @@ const HeadBarWidget = () => {
         }}
         }}
       >
       >
         <div style={{ display: "flex" }}>
         <div style={{ display: "flex" }}>
-          <Link to="/">
-            <img alt="code" style={{ height: 36 }} src={img_banner} />
-          </Link>
+          <img alt="code" style={{ height: 36 }} src={img_banner} />
           <SoftwareEdition style={{ color: "white" }} />
           <SoftwareEdition style={{ color: "white" }} />
         </div>
         </div>
         <div style={{ width: 500, lineHeight: 44 }}>
         <div style={{ width: 500, lineHeight: 44 }}>

+ 2 - 0
dashboard/src/components/studio/LeftSider.tsx

@@ -178,6 +178,7 @@ const LeftSiderWidget = ({ selectedKeys = "" }: IWidgetHeadBar) => {
             </Link>
             </Link>
           ),
           ),
           key: "group",
           key: "group",
+          disabled: user?.roles?.includes("basic"),
         },
         },
         {
         {
           label: (
           label: (
@@ -188,6 +189,7 @@ const LeftSiderWidget = ({ selectedKeys = "" }: IWidgetHeadBar) => {
             </Link>
             </Link>
           ),
           ),
           key: "invite",
           key: "invite",
+          disabled: user?.roles?.includes("basic"),
         },
         },
         {
         {
           label: (
           label: (

+ 14 - 2
dashboard/src/components/template/Wbw/WbwDetail.tsx

@@ -16,6 +16,8 @@ import {
 import { IAttachmentRequest } from "../../api/Attachments";
 import { IAttachmentRequest } from "../../api/Attachments";
 import WbwDetailAttachment from "./WbwDetailAttachment";
 import WbwDetailAttachment from "./WbwDetailAttachment";
 import CommentBox from "../../discussion/DiscussionDrawer";
 import CommentBox from "../../discussion/DiscussionDrawer";
+import { useAppSelector } from "../../../hooks";
+import { currentUser } from "../../../reducers/current-user";
 
 
 interface IWidget {
 interface IWidget {
   data: IWbw;
   data: IWbw;
@@ -38,6 +40,7 @@ const WbwDetailWidget = ({
     JSON.parse(JSON.stringify(data))
     JSON.parse(JSON.stringify(data))
   );
   );
   const [tabKey, setTabKey] = useState<string>("basic");
   const [tabKey, setTabKey] = useState<string>("basic");
+  const currUser = useAppSelector(currentUser);
 
 
   useEffect(() => {
   useEffect(() => {
     console.debug("input data", data);
     console.debug("input data", data);
@@ -266,14 +269,23 @@ const WbwDetailWidget = ({
           menu={{
           menu={{
             items: [
             items: [
               {
               {
-                key: "user-dict",
+                key: "user-dict-public",
                 label: intl.formatMessage({ id: "buttons.save.publish" }),
                 label: intl.formatMessage({ id: "buttons.save.publish" }),
+                disabled: currUser?.roles?.includes("basic"),
+              },
+              {
+                key: "user-dict-private",
+                label: intl.formatMessage({ id: "buttons.save.my.dict" }),
               },
               },
             ],
             ],
             onClick: (e) => {
             onClick: (e) => {
               if (typeof onSave !== "undefined") {
               if (typeof onSave !== "undefined") {
                 //保存并发布
                 //保存并发布
-                onSave(currWbwData, true);
+                if (e.key === "user-dict-public") {
+                  onSave(currWbwData, true, true);
+                } else {
+                  onSave(currWbwData, true, false);
+                }
               }
               }
             },
             },
           }}
           }}

+ 2 - 2
dashboard/src/components/template/Wbw/WbwPali.tsx

@@ -174,9 +174,9 @@ const WbwPaliWidget = ({ data, channelId, mode, display, onSave }: IWidget) => {
         setPaliColor("unset");
         setPaliColor("unset");
         setPopOpen(false);
         setPopOpen(false);
       }}
       }}
-      onSave={(e: IWbw, isPublish: boolean) => {
+      onSave={(e: IWbw, isPublish: boolean, isPublic: boolean) => {
         if (typeof onSave !== "undefined") {
         if (typeof onSave !== "undefined") {
-          onSave(e, isPublish);
+          onSave(e, isPublish, isPublic);
           setPopOpen(false);
           setPopOpen(false);
           setPaliColor("unset");
           setPaliColor("unset");
         }
         }

+ 2 - 2
dashboard/src/components/template/Wbw/WbwWord.tsx

@@ -249,11 +249,11 @@ const WbwWordWidget = ({
           channelId={channelId}
           channelId={channelId}
           mode={mode}
           mode={mode}
           display={display}
           display={display}
-          onSave={(e: IWbw, isPublish: boolean) => {
+          onSave={(e: IWbw, isPublish: boolean, isPublic: boolean) => {
             const newData: IWbw = JSON.parse(JSON.stringify(e));
             const newData: IWbw = JSON.parse(JSON.stringify(e));
             setWordData(newData);
             setWordData(newData);
             if (typeof onChange !== "undefined") {
             if (typeof onChange !== "undefined") {
-              onChange(e, isPublish);
+              onChange(e, isPublish, isPublic);
             }
             }
           }}
           }}
         />
         />

+ 11 - 5
dashboard/src/components/template/WbwSent.tsx

@@ -23,6 +23,7 @@ import { GetUserSetting } from "../auth/setting/default";
 import { getGrammar } from "../../reducers/term-vocabulary";
 import { getGrammar } from "../../reducers/term-vocabulary";
 import modal from "antd/lib/modal";
 import modal from "antd/lib/modal";
 import { UserWbwPost } from "../dict/MyCreate";
 import { UserWbwPost } from "../dict/MyCreate";
+import { currentUser } from "../../reducers/current-user";
 
 
 export const paraMark = (wbwData: IWbw[]): IWbw[] => {
 export const paraMark = (wbwData: IWbw[]): IWbw[] => {
   //处理段落标记,支持点击段落引用弹窗
   //处理段落标记,支持点击段落引用弹窗
@@ -176,6 +177,7 @@ export const WbwSentCtl = ({
   const [loading, setLoading] = useState(false);
   const [loading, setLoading] = useState(false);
   const [progress, setProgress] = useState(0);
   const [progress, setProgress] = useState(0);
   const [showProgress, setShowProgress] = useState(false);
   const [showProgress, setShowProgress] = useState(false);
+  const user = useAppSelector(currentUser);
 
 
   console.debug("wbw sent lang", channelLang);
   console.debug("wbw sent lang", channelLang);
 
 
@@ -479,7 +481,7 @@ export const WbwSentCtl = ({
     }
     }
   };
   };
 
 
-  const wbwPublish = (wbwData: IWbw[]) => {
+  const wbwPublish = (wbwData: IWbw[], isPublic: boolean) => {
     let wordData: IDictRequest[] = [];
     let wordData: IDictRequest[] = [];
 
 
     wbwData.forEach((data) => {
     wbwData.forEach((data) => {
@@ -507,6 +509,7 @@ export const WbwSentCtl = ({
           note: data.note?.value,
           note: data.note?.value,
           confidence: conf,
           confidence: conf,
           language: channelLang,
           language: channelLang,
+          status: isPublic ? 30 : 5,
         });
         });
       }
       }
     });
     });
@@ -534,7 +537,7 @@ export const WbwSentCtl = ({
         mode={displayMode}
         mode={displayMode}
         display={wbwMode}
         display={wbwMode}
         fields={fieldDisplay}
         fields={fieldDisplay}
-        onChange={(e: IWbw, isPublish?: boolean) => {
+        onChange={(e: IWbw, isPublish: boolean, isPublic: boolean) => {
           let newData = [...wordData];
           let newData = [...wordData];
           newData.forEach((value, index, array) => {
           newData.forEach((value, index, array) => {
             //把新的数据更新到数组
             //把新的数据更新到数组
@@ -582,8 +585,8 @@ export const WbwSentCtl = ({
           }
           }
           update(newData);
           update(newData);
           saveWord(newData, e.sn[0]);
           saveWord(newData, e.sn[0]);
-          if (isPublish) {
-            wbwPublish([e]);
+          if (isPublish === true) {
+            wbwPublish([e], isPublic);
           }
           }
         }}
         }}
         onSplit={() => {
         onSplit={() => {
@@ -708,7 +711,10 @@ export const WbwSentCtl = ({
                   magicDictLookup();
                   magicDictLookup();
                   break;
                   break;
                 case "wbw-dict-publish-all":
                 case "wbw-dict-publish-all":
-                  wbwPublish(wordData);
+                  wbwPublish(
+                    wordData,
+                    user?.roles?.includes("basic") ? false : true
+                  );
                   break;
                   break;
                 case "copy-text":
                 case "copy-text":
                   const paliText = wordData
                   const paliText = wordData

+ 9 - 1
dashboard/src/components/term/TermList.tsx

@@ -20,6 +20,8 @@ import TermExport from "./TermExport";
 import DataImport from "../admin/relation/DataImport";
 import DataImport from "../admin/relation/DataImport";
 import TermModal from "./TermModal";
 import TermModal from "./TermModal";
 import { getSorterUrl } from "../../utils";
 import { getSorterUrl } from "../../utils";
+import { useAppSelector } from "../../hooks";
+import { currentUser } from "../../reducers/current-user";
 
 
 interface IItem {
 interface IItem {
   sn: number;
   sn: number;
@@ -39,6 +41,7 @@ interface IWidget {
 }
 }
 const TermListWidget = ({ studioName, channelId }: IWidget) => {
 const TermListWidget = ({ studioName, channelId }: IWidget) => {
   const intl = useIntl();
   const intl = useIntl();
+  const currUser = useAppSelector(currentUser);
 
 
   const showDeleteConfirm = (id: string[], title: string) => {
   const showDeleteConfirm = (id: string[], title: string) => {
     Modal.confirm({
     Modal.confirm({
@@ -319,7 +322,12 @@ const TermListWidget = ({ studioName, channelId }: IWidget) => {
           <TermExport channelId={channelId} studioName={studioName} />,
           <TermExport channelId={channelId} studioName={studioName} />,
           <TermModal
           <TermModal
             trigger={
             trigger={
-              <Button key="button" icon={<PlusOutlined />} type="primary">
+              <Button
+                key="button"
+                icon={<PlusOutlined />}
+                type="primary"
+                disabled={currUser?.roles?.includes("basic")}
+              >
                 {intl.formatMessage({ id: "buttons.create" })}
                 {intl.formatMessage({ id: "buttons.create" })}
               </Button>
               </Button>
             }
             }

+ 1 - 0
dashboard/src/locales/en-US/buttons.ts

@@ -14,6 +14,7 @@ const items = {
   "buttons.option": "operation",
   "buttons.option": "operation",
   "buttons.save": "save",
   "buttons.save": "save",
   "buttons.save.publish": "save & publish",
   "buttons.save.publish": "save & publish",
+  "buttons.save.my.dict": "save & my dict",
   "buttons.cancel": "cancel",
   "buttons.cancel": "cancel",
   "buttons.setting": "setting",
   "buttons.setting": "setting",
   "buttons.sign-in": "sign in",
   "buttons.sign-in": "sign in",

+ 0 - 1
dashboard/src/locales/en-US/channel/index.ts

@@ -8,7 +8,6 @@ const items = {
   "channel.type.nissaya.label": "Nissaya",
   "channel.type.nissaya.label": "Nissaya",
   "channel.type.commentary.label": "commentary",
   "channel.type.commentary.label": "commentary",
   "channel.type.original.label": "original",
   "channel.type.original.label": "original",
-  "channel.type.general.label": "general",
   "channel.type.message.required": "请输入版本类型",
   "channel.type.message.required": "请输入版本类型",
   "channel.lang": "language",
   "channel.lang": "language",
   "channel.fields.lang.label": "语言",
   "channel.fields.lang.label": "语言",

+ 1 - 0
dashboard/src/locales/en-US/index.ts

@@ -15,6 +15,7 @@ import message from "./message";
 import label from "./label";
 import label from "./label";
 const items = {
 const items = {
   "columns.library.title": "Library",
   "columns.library.title": "Library",
+  "columns.library.home.title": "Home",
   "columns.library.community.title": "Community",
   "columns.library.community.title": "Community",
   "columns.library.palicanon.title": "Palicanon",
   "columns.library.palicanon.title": "Palicanon",
   "columns.library.course.title": "Course",
   "columns.library.course.title": "Course",

+ 5 - 4
dashboard/src/locales/en-US/nut/index.ts

@@ -1,8 +1,9 @@
 const items = {
 const items = {
-  "nut.users.sign-in.title": "登录",
-  "nut.users.sign-up.title": "新用户注册",
-  "nut.users.logs.title": "日志列表",
-  "nut.users.forgot-password.title": "忘记密码",
+  "nut.users.sign-in.title": "sign in",
+  "nut.users.sign-up.title": "sign up",
+  "nut.users.sign-in-up.title": "sign in/sign up",
+  "nut.users.logs.title": "logs",
+  "nut.users.forgot-password.title": "forgot password",
 };
 };
 
 
 export default items;
 export default items;

+ 2 - 1
dashboard/src/locales/zh-Hans/buttons.ts

@@ -13,7 +13,8 @@ const items = {
   "buttons.unselect": "全不选",
   "buttons.unselect": "全不选",
   "buttons.option": "操作",
   "buttons.option": "操作",
   "buttons.save": "保存",
   "buttons.save": "保存",
-  "buttons.save.publish": "保存并公开",
+  "buttons.save.publish": "保存并公开到社区词典",
+  "buttons.save.my.dict": "保存并添加到个人单词本",
   "buttons.cancel": "取消",
   "buttons.cancel": "取消",
   "buttons.setting": "设置",
   "buttons.setting": "设置",
   "buttons.sign-in": "登录",
   "buttons.sign-in": "登录",

+ 14 - 15
dashboard/src/locales/zh-Hans/channel/index.ts

@@ -1,19 +1,18 @@
 const items = {
 const items = {
-	"channel.title": "版本风格",
-	"channel.type": "类型",
-	"channel.name": "名称",
-	"channel.create.message.noname": "请输入版本名称",
-	"channel.type.all.title": "全部",
-	"channel.type.translation.label": "译文",
-	"channel.type.nissaya.label": "Nissaya",
-	"channel.type.commentary.label": "注疏",
-	"channel.type.original.label": "原文",
-	"channel.type.general.label": "通用",
-	"channel.type.message.required": "请输入版本类型",
-	"channel.lang": "语言",
-	"channel.fields.lang.label": "语言",
-	"channel.fields.type.label": "类型",
-	"channel.fields.name.label": "名称",
+  "channel.title": "版本风格",
+  "channel.type": "类型",
+  "channel.name": "名称",
+  "channel.create.message.noname": "请输入版本名称",
+  "channel.type.all.title": "全部",
+  "channel.type.translation.label": "译文",
+  "channel.type.nissaya.label": "Nissaya",
+  "channel.type.commentary.label": "注疏",
+  "channel.type.original.label": "原文",
+  "channel.type.message.required": "请输入版本类型",
+  "channel.lang": "语言",
+  "channel.fields.lang.label": "语言",
+  "channel.fields.type.label": "类型",
+  "channel.fields.name.label": "名称",
 };
 };
 
 
 export default items;
 export default items;

+ 1 - 0
dashboard/src/locales/zh-Hans/index.ts

@@ -17,6 +17,7 @@ import error from "./error";
 
 
 const items = {
 const items = {
   "columns.library.title": "藏经阁",
   "columns.library.title": "藏经阁",
+  "columns.library.home.title": "首页",
   "columns.library.community.title": "社区",
   "columns.library.community.title": "社区",
   "columns.library.palicanon.title": "圣典",
   "columns.library.palicanon.title": "圣典",
   "columns.library.course.title": "课程",
   "columns.library.course.title": "课程",

+ 2 - 1
dashboard/src/locales/zh-Hans/nut/index.ts

@@ -1,6 +1,7 @@
 const items = {
 const items = {
   "nut.users.sign-in.title": "登录",
   "nut.users.sign-in.title": "登录",
-  "nut.users.sign-up.title": "新用户注册",
+  "nut.users.sign-up.title": "注册",
+  "nut.users.sign-in-up.title": "登录/注册",
   "nut.users.logs.title": "日志列表",
   "nut.users.logs.title": "日志列表",
   "nut.users.forgot-password.title": "忘记密码",
   "nut.users.forgot-password.title": "忘记密码",
 };
 };

+ 7 - 1
dashboard/src/pages/nut/users/sign-in.tsx

@@ -1,11 +1,17 @@
 import SignInForm from "../../../components/nut/users/SignIn";
 import SignInForm from "../../../components/nut/users/SignIn";
 import SharedLinks from "../../../components/nut/users/NonSignInSharedLinks";
 import SharedLinks from "../../../components/nut/users/NonSignInSharedLinks";
 import { Card, Space } from "antd";
 import { Card, Space } from "antd";
+import { useIntl } from "react-intl";
 
 
 const Widget = () => {
 const Widget = () => {
+  const intl = useIntl();
   return (
   return (
     <div>
     <div>
-      <Card title="登录">
+      <Card
+        title={intl.formatMessage({
+          id: "nut.users.sign-up.title",
+        })}
+      >
         <Space direction="vertical">
         <Space direction="vertical">
           <SignInForm />
           <SignInForm />
           <SharedLinks />
           <SharedLinks />

+ 29 - 30
dashboard/src/pages/studio/course/list.tsx

@@ -140,6 +140,8 @@ const Widget = () => {
     });
     });
   };
   };
 
 
+  const canCreate = !(activeKey !== "create" || user?.roles?.includes("basic"));
+
   return (
   return (
     <>
     <>
       <ProTable<DataItem>
       <ProTable<DataItem>
@@ -436,38 +438,35 @@ const Widget = () => {
           search: true,
           search: true,
         }}
         }}
         toolBarRender={() => [
         toolBarRender={() => [
-          <Popover
-            content={
-              <CourseCreate
-                studio={studioname}
-                onCreate={() => {
-                  //新建课程成功后刷新
-                  setActiveKey("create");
-                  setCreateNumber(createNumber + 1);
-                  ref.current?.reload();
-                  setOpenCreate(false);
-                }}
-              />
-            }
-            title="Create"
-            placement="bottomRight"
-            trigger="click"
-            open={openCreate}
-            onOpenChange={(newOpen: boolean) => {
-              setOpenCreate(newOpen);
-            }}
-          >
-            <Button
-              disabled={
-                activeKey !== "create" || user?.roles?.includes("basic")
+          canCreate ? (
+            <Popover
+              content={
+                <CourseCreate
+                  studio={studioname}
+                  onCreate={() => {
+                    //新建课程成功后刷新
+                    setActiveKey("create");
+                    setCreateNumber(createNumber + 1);
+                    ref.current?.reload();
+                    setOpenCreate(false);
+                  }}
+                />
               }
               }
-              key="button"
-              icon={<PlusOutlined />}
-              type="primary"
+              title="Create"
+              placement="bottomRight"
+              trigger="click"
+              open={openCreate}
+              onOpenChange={(newOpen: boolean) => {
+                setOpenCreate(newOpen);
+              }}
             >
             >
-              {intl.formatMessage({ id: "buttons.create" })}
-            </Button>
-          </Popover>,
+              <Button key="button" icon={<PlusOutlined />} type="primary">
+                {intl.formatMessage({ id: "buttons.create" })}
+              </Button>
+            </Popover>
+          ) : (
+            <></>
+          ),
         ]}
         ]}
         toolbar={{
         toolbar={{
           menu: {
           menu: {