Przeglądaj źródła

Merge pull request #1358 from visuddhinanda/agile

 #1348 #1345
visuddhinanda 2 lat temu
rodzic
commit
3ae85071fc

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

@@ -288,6 +288,23 @@ const JsonOutlined = () => (
   </svg>
   </svg>
 );
 );
 
 
+const ThemeOutlined = () => (
+  <svg
+    viewBox="190 190 750 750"
+    version="1.1"
+    xmlns="http://www.w3.org/2000/svg"
+    p-id="1557"
+    width="1em"
+    height="1em"
+  >
+    <path
+      d="M512 853.333333c-55.466667 0-21.333333-38.4-85.333333-102.4-59.733333-64-256-25.6-256-238.933333 0-187.733333 153.6-341.333333 341.333333-341.333333s341.333333 153.6 341.333333 341.333333-153.6 341.333333-341.333333 341.333333z m256-341.333333c0-140.8-115.2-256-256-256s-256 115.2-256 256c0 68.266667 21.333333 89.6 81.066667 110.933333 4.266667 0 12.8 4.266667 21.333333 4.266667 4.266667 0 17.066667 4.266667 21.333333 8.533333 55.466667 17.066667 81.066667 29.866667 106.666667 55.466667 21.333333 21.333333 34.133333 42.666667 46.933333 64 0 4.266667 4.266667 8.533333 4.266667 12.8 128-12.8 230.4-123.733333 230.4-256z m-128-85.333333c-25.6 0-42.666667-17.066667-42.666667-42.666667s17.066667-42.666667 42.666667-42.666667 42.666667 17.066667 42.666667 42.666667-17.066667 42.666667-42.666667 42.666667z m-119.466667-55.466667c-25.6 0-42.666667-17.066667-42.666666-42.666667s17.066667-42.666667 42.666666-42.666666 42.666667 17.066667 42.666667 42.666666-17.066667 42.666667-42.666667 42.666667z m183.466667 162.133333c-25.6 0-42.666667-17.066667-42.666667-42.666666s17.066667-42.666667 42.666667-42.666667 42.666667 17.066667 42.666667 42.666667-17.066667 42.666667-42.666667 42.666666zM392.533333 413.866667c-25.6 0-42.666667-17.066667-42.666666-42.666667s17.066667-42.666667 42.666666-42.666667 42.666667 17.066667 42.666667 42.666667-17.066667 42.666667-42.666667 42.666667z m196.266667 298.666666c-34.133333 0-64-29.866667-64-64s29.866667-64 64-64 64 29.866667 64 64c-4.266667 34.133333-29.866667 64-64 64z"
+      fill="currentColor"
+      p-id="3496"
+    ></path>
+  </svg>
+);
+
 export const DictIcon = (props: Partial<CustomIconComponentProps>) => (
 export const DictIcon = (props: Partial<CustomIconComponentProps>) => (
   <Icon component={DictSvg} {...props} />
   <Icon component={DictSvg} {...props} />
 );
 );
@@ -345,3 +362,7 @@ export const TermIcon2 = (props: Partial<CustomIconComponentProps>) => (
 export const JsonOutlinedIcon = (props: Partial<CustomIconComponentProps>) => (
 export const JsonOutlinedIcon = (props: Partial<CustomIconComponentProps>) => (
   <Icon component={JsonOutlined} {...props} />
   <Icon component={JsonOutlined} {...props} />
 );
 );
+
+export const ThemeOutlinedIcon = (props: Partial<CustomIconComponentProps>) => (
+  <Icon component={ThemeOutlined} {...props} />
+);

+ 1 - 0
dashboard/src/components/article/ModeSwitch.tsx

@@ -64,6 +64,7 @@ const ModeSwitchWidget = ({
       />
       />
       <ChannelPicker
       <ChannelPicker
         open={channelPickerOpen}
         open={channelPickerOpen}
+        defaultOwner="my"
         onClose={() => setChannelPickerOpen(false)}
         onClose={() => setChannelPickerOpen(false)}
         onSelect={(channels: IChannel[]) => {
         onSelect={(channels: IChannel[]) => {
           if (newMode) {
           if (newMode) {

+ 3 - 0
dashboard/src/components/channel/ChannelPicker.tsx

@@ -11,6 +11,7 @@ interface IWidget {
   articleId?: string;
   articleId?: string;
   multiSelect?: boolean;
   multiSelect?: boolean;
   open?: boolean;
   open?: boolean;
+  defaultOwner?: string;
   onClose?: Function;
   onClose?: Function;
   onSelect?: Function;
   onSelect?: Function;
 }
 }
@@ -20,6 +21,7 @@ const ChannelPickerWidget = ({
   articleId,
   articleId,
   multiSelect = true,
   multiSelect = true,
   open = false,
   open = false,
+  defaultOwner,
   onClose,
   onClose,
   onSelect,
   onSelect,
 }: IWidget) => {
 }: IWidget) => {
@@ -61,6 +63,7 @@ const ChannelPickerWidget = ({
           type={type}
           type={type}
           articleId={articleId}
           articleId={articleId}
           multiSelect={multiSelect}
           multiSelect={multiSelect}
+          defaultOwner={defaultOwner}
           onSelect={(channels: IChannel[]) => {
           onSelect={(channels: IChannel[]) => {
             console.log(channels);
             console.log(channels);
             handleCancel();
             handleCancel();

+ 38 - 10
dashboard/src/components/channel/ChannelPickerTable.tsx

@@ -1,7 +1,7 @@
 import { useEffect, useRef, useState } from "react";
 import { useEffect, useRef, useState } from "react";
 import { useIntl } from "react-intl";
 import { useIntl } from "react-intl";
 import { ActionType, ProList } from "@ant-design/pro-components";
 import { ActionType, ProList } from "@ant-design/pro-components";
-import { Button } from "antd";
+import { Alert, Button } from "antd";
 import { Badge, Dropdown, Space, Table, Typography } from "antd";
 import { Badge, Dropdown, Space, Table, Typography } from "antd";
 import {
 import {
   GlobalOutlined,
   GlobalOutlined,
@@ -23,7 +23,7 @@ import CopyToModal from "./CopyToModal";
 import { useAppSelector } from "../../hooks";
 import { useAppSelector } from "../../hooks";
 import { currentUser as _currentUser } from "../../reducers/current-user";
 import { currentUser as _currentUser } from "../../reducers/current-user";
 
 
-const { Link } = Typography;
+const { Link, Text } = Typography;
 
 
 interface IParams {
 interface IParams {
   owner?: string;
   owner?: string;
@@ -54,6 +54,7 @@ interface IWidget {
   selectedKeys?: string[];
   selectedKeys?: string[];
   reload?: boolean;
   reload?: boolean;
   disableChannelId?: string;
   disableChannelId?: string;
+  defaultOwner?: string;
   onSelect?: Function;
   onSelect?: Function;
 }
 }
 const ChannelPickerTableWidget = ({
 const ChannelPickerTableWidget = ({
@@ -63,6 +64,7 @@ const ChannelPickerTableWidget = ({
   selectedKeys = [],
   selectedKeys = [],
   onSelect,
   onSelect,
   disableChannelId,
   disableChannelId,
+  defaultOwner = "all",
   reload = false,
   reload = false,
 }: IWidget) => {
 }: IWidget) => {
   const intl = useIntl();
   const intl = useIntl();
@@ -71,6 +73,8 @@ const ChannelPickerTableWidget = ({
   const [showCheckBox, setShowCheckBox] = useState<boolean>(false);
   const [showCheckBox, setShowCheckBox] = useState<boolean>(false);
   const [copyChannel, setCopyChannel] = useState<IChannel>();
   const [copyChannel, setCopyChannel] = useState<IChannel>();
   const [copyOpen, setCopyOpen] = useState<boolean>(false);
   const [copyOpen, setCopyOpen] = useState<boolean>(false);
+  const [ownerChanged, setOwnerChanged] = useState<boolean>(false);
+
   const user = useAppSelector(_currentUser);
   const user = useAppSelector(_currentUser);
   const ref = useRef<ActionType>();
   const ref = useRef<ActionType>();
 
 
@@ -81,7 +85,24 @@ const ChannelPickerTableWidget = ({
   }, [reload]);
   }, [reload]);
 
 
   return (
   return (
-    <>
+    <Space direction="vertical" style={{ width: "100%" }}>
+      {defaultOwner !== "all" && ownerChanged === false ? (
+        <Alert
+          message={
+            <>
+              {"目前仅显示了版本"}
+              <Text keyboard>
+                {intl.formatMessage({ id: `buttons.channel.${defaultOwner}` })}
+              </Text>
+              {"可以点"}
+              <Text keyboard>{"版本筛选"}</Text>
+              {"显示其他版本"}
+            </>
+          }
+          type="success"
+          closable
+        />
+      ) : undefined}
       <ProList<IItem, IParams>
       <ProList<IItem, IParams>
         actionRef={ref}
         actionRef={ref}
         rowSelection={
         rowSelection={
@@ -162,11 +183,16 @@ const ChannelPickerTableWidget = ({
             const id = element.id.split("_")[1];
             const id = element.id.split("_")[1];
             sentList.push(id);
             sentList.push(id);
           }
           }
+          const currOwner = params.owner ? params.owner : defaultOwner;
+          if (params.owner) {
+            setOwnerChanged(true);
+          }
+          console.log("owner", currOwner);
           const res = await post<IProgressRequest, IApiResponseChannelList>(
           const res = await post<IProgressRequest, IApiResponseChannelList>(
             `/v2/channel-progress`,
             `/v2/channel-progress`,
             {
             {
               sentence: sentList,
               sentence: sentList,
-              owner: params.owner,
+              owner: currOwner,
             }
             }
           );
           );
           console.log("progress data", res.data.rows);
           console.log("progress data", res.data.rows);
@@ -361,15 +387,17 @@ const ChannelPickerTableWidget = ({
             title: "版本筛选",
             title: "版本筛选",
             valueType: "select",
             valueType: "select",
             valueEnum: {
             valueEnum: {
-              all: { text: "全部", status: "Default" },
+              all: { text: intl.formatMessage({ id: "buttons.channel.all" }) },
               my: {
               my: {
-                text: "我的",
+                text: intl.formatMessage({ id: "buttons.channel.my" }),
               },
               },
-              cooperator: {
-                text: "协作",
+              collaborator: {
+                text: intl.formatMessage({
+                  id: "buttons.channel.collaborator",
+                }),
               },
               },
               public: {
               public: {
-                text: "社区公开",
+                text: intl.formatMessage({ id: "buttons.channel.public" }),
               },
               },
             },
             },
           },
           },
@@ -380,7 +408,7 @@ const ChannelPickerTableWidget = ({
         open={copyOpen}
         open={copyOpen}
         onClose={() => setCopyOpen(false)}
         onClose={() => setCopyOpen(false)}
       />
       />
-    </>
+    </Space>
   );
   );
 };
 };
 
 

+ 35 - 21
dashboard/src/components/general/ThemeSelect.tsx

@@ -1,35 +1,49 @@
-import { Switch } from "antd";
+import { Button, Dropdown, MenuProps, Switch } from "antd";
 import { useEffect, useState } from "react";
 import { useEffect, useState } from "react";
+import { useIntl } from "react-intl";
+import { ThemeOutlinedIcon } from "../../assets/icon";
 import { refresh } from "../../reducers/theme";
 import { refresh } from "../../reducers/theme";
 import store from "../../store";
 import store from "../../store";
 
 
 const ThemeSelectWidget = () => {
 const ThemeSelectWidget = () => {
-  const [isDark, setIsDark] = useState<boolean>();
+  const intl = useIntl();
+  const [theme, setTheme] = useState<string>();
+
+  const items: MenuProps["items"] = [
+    {
+      key: "ant",
+      label: "默认",
+    },
+    {
+      key: "dark",
+      label: "夜间",
+    },
+  ];
+
+  const onClick: MenuProps["onClick"] = ({ key }) => {
+    store.dispatch(refresh(key));
+    localStorage.setItem("theme", key);
+  };
+
   useEffect(() => {
   useEffect(() => {
     const currTheme = localStorage.getItem("theme");
     const currTheme = localStorage.getItem("theme");
-    if (currTheme === "dark") {
-      setIsDark(true);
-    } else {
-      setIsDark(false);
+    if (currTheme) {
+      setTheme(currTheme);
     }
     }
   }, []);
   }, []);
 
 
   return (
   return (
-    <Switch
-      defaultChecked={isDark}
-      checkedChildren={"🌞"}
-      unCheckedChildren={"🌙"}
-      onChange={(checked: boolean) => {
-        console.log(`switch to ${checked}`);
-        if (checked) {
-          store.dispatch(refresh("dark"));
-          localStorage.setItem("theme", "dark");
-        } else {
-          store.dispatch(refresh("ant"));
-          localStorage.setItem("theme", "ant");
-        }
-      }}
-    />
+    <Dropdown menu={{ items, onClick }} placement="bottomRight">
+      <Button
+        ghost
+        style={{ border: "unset" }}
+        icon={<ThemeOutlinedIcon style={{ color: "white" }} />}
+      >
+        {intl.formatMessage({
+          id: `buttons.theme.${theme}`,
+        })}
+      </Button>
+    </Dropdown>
   );
   );
 };
 };
 
 

+ 6 - 0
dashboard/src/locales/zh-Hans/buttons.ts

@@ -61,6 +61,12 @@ const items = {
   "buttons.open": "打开",
   "buttons.open": "打开",
   "buttons.compact": "紧凑",
   "buttons.compact": "紧凑",
   "buttons.magic-dict": "神奇字典",
   "buttons.magic-dict": "神奇字典",
+  "buttons.theme.ant": "默认",
+  "buttons.theme.dark": "夜间",
+  "buttons.channel.all": "全部",
+  "buttons.channel.my": "我的",
+  "buttons.channel.collaborator": "协作",
+  "buttons.channel.public": "公开",
 };
 };
 
 
 export default items;
 export default items;

+ 2 - 1
dashboard/src/pages/library/article/show.tsx

@@ -37,6 +37,7 @@ import { get } from "../../../request";
 import store from "../../../store";
 import store from "../../../store";
 import { IRecent } from "../../../components/recent/RecentList";
 import { IRecent } from "../../../components/recent/RecentList";
 import { fullUrl } from "../../../utils";
 import { fullUrl } from "../../../utils";
+import ThemeSelect from "../../../components/general/ThemeSelect";
 
 
 /**
 /**
  * type:
  * type:
@@ -143,6 +144,7 @@ const Widget = () => {
               </Button>
               </Button>
             ) : undefined}
             ) : undefined}
             <Avatar placement="bottom" />
             <Avatar placement="bottom" />
+            <ThemeSelect />
             <Divider type="vertical" />
             <Divider type="vertical" />
             <ModeSwitch
             <ModeSwitch
               channel={searchParams.get("channel")}
               channel={searchParams.get("channel")}
@@ -171,7 +173,6 @@ const Widget = () => {
                 setSearchParams(output);
                 setSearchParams(output);
               }}
               }}
             />
             />
-            <Divider type="vertical" />
             <Tooltip title="文章目录" placement="bottomLeft">
             <Tooltip title="文章目录" placement="bottomLeft">
               <Button
               <Button
                 style={{ display: "block", color: "white" }}
                 style={{ display: "block", color: "white" }}

+ 3 - 3
dashboard/src/reducers/theme.ts

@@ -5,7 +5,7 @@ import type { RootState } from "../store";
 export type TTheme = "dark" | "ant" | undefined;
 export type TTheme = "dark" | "ant" | undefined;
 
 
 interface IState {
 interface IState {
-  theme?: TTheme;
+  theme?: string;
 }
 }
 
 
 const initialState: IState = { theme: "ant" };
 const initialState: IState = { theme: "ant" };
@@ -14,7 +14,7 @@ export const slice = createSlice({
   name: "theme",
   name: "theme",
   initialState,
   initialState,
   reducers: {
   reducers: {
-    refresh: (state, action: PayloadAction<TTheme>) => {
+    refresh: (state, action: PayloadAction<string>) => {
       state.theme = action.payload;
       state.theme = action.payload;
     },
     },
   },
   },
@@ -22,7 +22,7 @@ export const slice = createSlice({
 
 
 export const { refresh } = slice.actions;
 export const { refresh } = slice.actions;
 
 
-export const currTheme = (state: RootState): TTheme | undefined =>
+export const currTheme = (state: RootState): string | undefined =>
   state.theme.theme;
   state.theme.theme;
 
 
 export default slice.reducer;
 export default slice.reducer;