diff --git a/web/public/locales/en/translation.json b/web/public/locales/en/translation.json index a5d9d0c620..f8d9383c09 100644 --- a/web/public/locales/en/translation.json +++ b/web/public/locales/en/translation.json @@ -718,7 +718,8 @@ "Logs": { "PodLogs": "App Instance Logs", "Export": "Export", - "logs": "Logs" + "logs": "Logs", + "ScrollToBottom": "Scroll to bottom" }, "KeyCannotBeEmpty": "Key can't be empty", "ValueCannotBeEmpty": "Value can't be empty", @@ -753,5 +754,4 @@ "Title": "Laf is ready to update!", "Description": "Click to update" } -} - +} \ No newline at end of file diff --git a/web/public/locales/zh-CN/translation.json b/web/public/locales/zh-CN/translation.json index 46cad40036..db66004443 100644 --- a/web/public/locales/zh-CN/translation.json +++ b/web/public/locales/zh-CN/translation.json @@ -718,7 +718,8 @@ "Logs": { "PodLogs": "应用实例日志", "Export": "导出", - "logs": "日志" + "logs": "日志", + "ScrollToBottom": "滚动到底部" }, "KeyCannotBeEmpty": "Key 不能为空", "ValueCannotBeEmpty": "Value 不能为空", @@ -753,4 +754,4 @@ "Title": "Laf 新版本已经准备好了!", "Description": "点击立即更新" } -} +} \ No newline at end of file diff --git a/web/public/locales/zh/translation.json b/web/public/locales/zh/translation.json index 7c0a992cc1..4e0e32294d 100644 --- a/web/public/locales/zh/translation.json +++ b/web/public/locales/zh/translation.json @@ -718,7 +718,8 @@ "Logs": { "PodLogs": "应用实例日志", "Export": "导出", - "logs": "日志" + "logs": "日志", + "ScrollToBottom": "滚动到底部" }, "KeyCannotBeEmpty": "Key 不能为空", "ValueCannotBeEmpty": "Value 不能为空", @@ -753,4 +754,4 @@ "Title": "Laf 新版本已经准备好了!", "Description": "点击立即更新" } -} +} \ No newline at end of file diff --git a/web/src/chakraThemeDark.ts b/web/src/chakraThemeDark.ts index 52f2969db5..e87843a883 100644 --- a/web/src/chakraThemeDark.ts +++ b/web/src/chakraThemeDark.ts @@ -127,7 +127,7 @@ const Button = defineStyleConfig({ text: { color: "primary.500", _hover: { - bg: "primary.100", + bg: "primary.900", }, }, diff --git a/web/src/components/CommonIcon/index.tsx b/web/src/components/CommonIcon/index.tsx index 471ee84a28..afec1eecc2 100644 --- a/web/src/components/CommonIcon/index.tsx +++ b/web/src/components/CommonIcon/index.tsx @@ -741,3 +741,34 @@ export const CommonSettingIcon = createIcon({ viewBox: "0 0 16 16", d: "M1.5 4.54688C1.5 4.38526 1.5642 4.23026 1.67848 4.11598C1.79276 4.0017 1.94776 3.9375 2.10938 3.9375H13.8906C14.0522 3.9375 14.2072 4.0017 14.3215 4.11598C14.4358 4.23026 14.5 4.38526 14.5 4.54688C14.5 4.70849 14.4358 4.86349 14.3215 4.97777C14.2072 5.09205 14.0522 5.15625 13.8906 5.15625H2.10938C1.94776 5.15625 1.79276 5.09205 1.67848 4.97777C1.5642 4.86349 1.5 4.70849 1.5 4.54688ZM1.5 8C1.5 7.83838 1.5642 7.68339 1.67848 7.56911C1.79276 7.45483 1.94776 7.39062 2.10938 7.39062H13.8906C14.0522 7.39062 14.2072 7.45483 14.3215 7.56911C14.4358 7.68339 14.5 7.83838 14.5 8C14.5 8.16162 14.4358 8.31661 14.3215 8.43089C14.2072 8.54517 14.0522 8.60938 13.8906 8.60938H2.10938C1.94776 8.60938 1.79276 8.54517 1.67848 8.43089C1.5642 8.31661 1.5 8.16162 1.5 8ZM2.10938 10.8438C1.94776 10.8438 1.79276 10.908 1.67848 11.0222C1.5642 11.1365 1.5 11.2915 1.5 11.4531C1.5 11.6147 1.5642 11.7697 1.67848 11.884C1.79276 11.9983 1.94776 12.0625 2.10938 12.0625H9.82812C9.98974 12.0625 10.1447 11.9983 10.259 11.884C10.3733 11.7697 10.4375 11.6147 10.4375 11.4531C10.4375 11.2915 10.3733 11.1365 10.259 11.0222C10.1447 10.908 9.98974 10.8438 9.82812 10.8438H2.10938Z", }); + +export const PauseIcon = createIcon({ + displayName: "PauseIcon", + viewBox: "0 0 1024 1024", + d: "M304 176h80v672h-80zM712 176h-64c-4.4 0-8 3.6-8 8v656c0 4.4 3.6 8 8 8h64c4.4 0 8-3.6 8-8V184c0-4.4-3.6-8-8-8z", +}); + +export const ContinueIcon = createIcon({ + displayName: "ContinueIcon", + viewBox: "0 0 1024 1024", + d: "M104 0v1024l816-512z" +}); + +export const DownIcon = (props: any) => { + return ( + + + + + + ); +}; \ No newline at end of file diff --git a/web/src/pages/app/mods/StatusBar/LogsModal/index.tsx b/web/src/pages/app/mods/StatusBar/LogsModal/index.tsx index 9dc3d52e18..af1a14318f 100644 --- a/web/src/pages/app/mods/StatusBar/LogsModal/index.tsx +++ b/web/src/pages/app/mods/StatusBar/LogsModal/index.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect, useState } from "react"; +import React, { useCallback, useEffect, useRef, useState } from "react"; import { useTranslation } from "react-i18next"; import { Button, @@ -12,6 +12,7 @@ import { ModalOverlay, Select, Spinner, + useColorMode, useDisclosure, } from "@chakra-ui/react"; import { LogViewer, LogViewerSearch } from "@patternfly/react-log-viewer"; @@ -25,6 +26,9 @@ import "./index.scss"; import { PodControllerGetContainerNameList, PodControllerGetPodNameList } from "@/apis/v1/apps"; import useCustomSettingStore from "@/pages/customSetting"; import useGlobalStore from "@/pages/globalStore"; +import { DownIcon, RefreshIcon } from "@/components/CommonIcon"; +import clsx from "clsx"; +import { debounce } from "lodash"; export default function LogsModal(props: { children: React.ReactElement }) { const { children } = props; @@ -38,6 +42,34 @@ export default function LogsModal(props: { children: React.ReactElement }) { const [podName, setPodName] = useState(""); const [containerName, setContainerName] = useState(""); const [isLoading, setIsLoading] = useState(true); + const [rowNumber, setRowNumber] = useState(0); + const [isPaused, setIsPaused] = useState(false); + const [pausedRowNumber, setPausedRowNumber] = useState(0); + + const [renderLogs, setRenderLogs] = useState(""); + const [refresh, setRefresh] = useState(true); + + const darkMode = useColorMode().colorMode === "dark"; + + useEffect(() => { + const resizeHandler = debounce(() => { + if (!isPaused) { + setRefresh((pre) => !pre); + } + }, 200) + + window.addEventListener("resize", resizeHandler); + + return () => { + window.removeEventListener("resize", resizeHandler); + }; + }, [isPaused]) + + useEffect(() => { + if (!isPaused) { + setRenderLogs(logs.trim()); + } + }, [isPaused, logs]); const { data: podData } = useQuery( ["GetPodQuery"], @@ -90,10 +122,11 @@ export default function LogsModal(props: { children: React.ReactElement }) { ) .join("\n"); + setRowNumber((pre) => pre + logs.length); setLogs((pre) => pre + logStr + "\n"); }, }).catch((e) => { - if (e.includes("BodyStreamBuffer was aborte")) { + if (e.includes("BodyStreamBuffer was aborted")) { return; } throw e; @@ -109,7 +142,7 @@ export default function LogsModal(props: { children: React.ReactElement }) { return () => { controller?.abort(); }; - }, [podName, isOpen, fetchLogs]); + }, [podName, containerName, isOpen, refresh]); return ( <> @@ -167,11 +200,12 @@ export default function LogsModal(props: { children: React.ReactElement }) { )}