Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(web): add logs pause button #1811

Merged
merged 5 commits into from
Jan 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions web/public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -753,5 +754,4 @@
"Title": "Laf is ready to update!",
"Description": "Click to update"
}
}

}
5 changes: 3 additions & 2 deletions web/public/locales/zh-CN/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -718,7 +718,8 @@
"Logs": {
"PodLogs": "应用实例日志",
"Export": "导出",
"logs": "日志"
"logs": "日志",
"ScrollToBottom": "滚动到底部"
},
"KeyCannotBeEmpty": "Key 不能为空",
"ValueCannotBeEmpty": "Value 不能为空",
Expand Down Expand Up @@ -753,4 +754,4 @@
"Title": "Laf 新版本已经准备好了!",
"Description": "点击立即更新"
}
}
}
5 changes: 3 additions & 2 deletions web/public/locales/zh/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -718,7 +718,8 @@
"Logs": {
"PodLogs": "应用实例日志",
"Export": "导出",
"logs": "日志"
"logs": "日志",
"ScrollToBottom": "滚动到底部"
},
"KeyCannotBeEmpty": "Key 不能为空",
"ValueCannotBeEmpty": "Value 不能为空",
Expand Down Expand Up @@ -753,4 +754,4 @@
"Title": "Laf 新版本已经准备好了!",
"Description": "点击立即更新"
}
}
}
2 changes: 1 addition & 1 deletion web/src/chakraThemeDark.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ const Button = defineStyleConfig({
text: {
color: "primary.500",
_hover: {
bg: "primary.100",
bg: "primary.900",
},
},

Expand Down
31 changes: 31 additions & 0 deletions web/src/components/CommonIcon/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
<svg
viewBox="0 0 1024 1024"
xmlns="http://www.w3.org/2000/svg"
width={props.size}
height={props.size}
>
<path d="M486.4 537.6C492.8 544 505.6 544 512 544s19.2 0 25.6-6.4l224-224c12.8-12.8 12.8-32 0-44.8s-32-12.8-44.8 0L512 467.2 313.6 262.4C300.8 256 275.2 256 262.4 262.4S256 300.8 262.4 313.6L486.4 537.6z"
fill={props.color}
></path>
<path d="M710.4 486.4 512 691.2 313.6 486.4c-12.8-12.8-32-12.8-44.8 0S256 524.8 262.4 537.6l224 224C492.8 768 505.6 768 512 768s19.2 0 25.6-6.4l224-224c12.8-12.8 12.8-32 0-44.8S723.2 480 710.4 486.4z"
fill={props.color}
></path>

</svg>
);
};
82 changes: 70 additions & 12 deletions web/src/pages/app/mods/StatusBar/LogsModal/index.tsx
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -12,6 +12,7 @@ import {
ModalOverlay,
Select,
Spinner,
useColorMode,
useDisclosure,
} from "@chakra-ui/react";
import { LogViewer, LogViewerSearch } from "@patternfly/react-log-viewer";
Expand All @@ -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;
Expand All @@ -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"],
Expand Down Expand Up @@ -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;
Expand All @@ -109,7 +142,7 @@ export default function LogsModal(props: { children: React.ReactElement }) {
return () => {
controller?.abort();
};
}, [podName, isOpen, fetchLogs]);
}, [podName, containerName, isOpen, refresh]);

return (
<>
Expand Down Expand Up @@ -167,11 +200,12 @@ export default function LogsModal(props: { children: React.ReactElement }) {
)}
<span>
<Button
variant={"outline"}
variant={"text"}
leftIcon={<RefreshIcon boxSize={5} />}
px={2}
onClick={() => {
setIsLoading(true);
setLogs("");
fetchLogs();
setRefresh((pre) => !pre);
setIsPaused(false);
}}
>
{t("Refresh")}
Expand All @@ -187,14 +221,25 @@ export default function LogsModal(props: { children: React.ReactElement }) {
) : (
<div
id="log-viewer-container"
className="text-sm flex flex-col overflow-y-auto px-2 font-mono"
style={{ height: "98%", fontSize: settingStore.commonSettings.fontSize - 1 }}
className="text-sm flex flex-col px-2 font-mono h-full"
style={{ fontSize: settingStore.commonSettings.fontSize - 1 }}
onWheel={(e) => {
newfish-cmyk marked this conversation as resolved.
Show resolved Hide resolved
if (e.deltaY < 0 && !isPaused) {
setIsPaused(true);
setPausedRowNumber(rowNumber);
}
}}
>
<LogViewer
data={logs.replace(/^\s*\n/, "")}
data={renderLogs}
hasLineNumbers={false}
scrollToRow={100000}
height={"100%"}
scrollToRow={isPaused ? pausedRowNumber : rowNumber + 1}
height={"98%"}
onScroll={(e) => {
if (e.scrollOffsetToBottom <= 0) {
setIsPaused(false);
}
}}
toolbar={
<div className="absolute right-24 top-4">
<LogViewerSearch
Expand All @@ -205,6 +250,19 @@ export default function LogsModal(props: { children: React.ReactElement }) {
</div>
}
/>
<div className="w-[95%] absolute bottom-1">
{isPaused && (
<HStack
onClick={() => { setIsPaused(false) }}
className={clsx("w-full flex justify-center items-center cursor-pointer",
darkMode ? "bg-[#212630]" : "bg-white"
)}
>
<DownIcon color={'#33BAB1'} size={24} />
<span className="text-primary-500 font-medium text-lg">{t("Logs.ScrollToBottom")}</span>
</HStack>
)}
</div>
</div>
)}
</ModalBody>
Expand Down