From b127bbf78775f97346dbfe90c2d467140e06ab26 Mon Sep 17 00:00:00 2001 From: Henry <50559854+Henry8192@users.noreply.github.com> Date: Sun, 15 Sep 2024 18:47:08 -0400 Subject: [PATCH 01/25] Export Logs draft --- .../src/components/MenuBar/index.tsx | 10 ++- .../src/contexts/StateContextProvider.tsx | 72 +++++++++++++++---- new-log-viewer/src/services/LogFileManager.ts | 25 +++++++ new-log-viewer/src/services/MainWorker.ts | 14 ++++ new-log-viewer/src/typings/worker.ts | 8 +++ new-log-viewer/src/utils/config.ts | 2 + 6 files changed, 116 insertions(+), 15 deletions(-) diff --git a/new-log-viewer/src/components/MenuBar/index.tsx b/new-log-viewer/src/components/MenuBar/index.tsx index e9955286..ab0154be 100644 --- a/new-log-viewer/src/components/MenuBar/index.tsx +++ b/new-log-viewer/src/components/MenuBar/index.tsx @@ -11,6 +11,7 @@ import { } from "@mui/joy"; import Description from "@mui/icons-material/Description"; +import Download from "@mui/icons-material/Download"; import FileOpenIcon from "@mui/icons-material/FileOpen"; import Settings from "@mui/icons-material/Settings"; @@ -30,7 +31,7 @@ import "./index.css"; * @return */ const MenuBar = () => { - const {fileName, loadFile} = useContext(StateContext); + const {fileName, exportLogs, loadFile} = useContext(StateContext); const [isSettingsModalOpen, setIsSettingsModalOpen] = useState(false); @@ -48,6 +49,10 @@ const MenuBar = () => { setIsSettingsModalOpen(true); }; + const handleExportLogsButtonClick = () => { + exportLogs(); + }; + return ( <> @@ -76,6 +81,9 @@ const MenuBar = () => { > + + + void, - loadPage: (newPageNum: number) => void, logData: string, numEvents: number, numPages: number, - pageNum: Nullable + pageNum: Nullable, + + exportLogs: () => void, + loadFile: (fileSrc: FileSrcType, cursor: CursorType) => void, + loadPage: (newPageNum: number) => void, } const StateContext = createContext({} as StateContextType); @@ -52,12 +57,14 @@ const StateContext = createContext({} as StateContextType); const STATE_DEFAULT: Readonly = Object.freeze({ beginLineNumToLogEventNum: new Map(), fileName: "", - loadFile: () => null, - loadPage: () => null, logData: "Loading...", numEvents: 0, numPages: 0, pageNum: 0, + + exportLogs: () => null, + loadFile: () => null, + loadPage: () => null, }); interface StateContextProviderProps { @@ -138,17 +145,44 @@ const StateContextProvider = ({children}: StateContextProviderProps) => { const logEventNumRef = useRef(logEventNum); const numPagesRef = useRef(STATE_DEFAULT.numPages); const pageNumRef = useRef>(STATE_DEFAULT.pageNum); + const receivedNumChunksRef = useRef(0); const mainWorkerRef = useRef(null); const handleMainWorkerResp = useCallback((ev: MessageEvent) => { const {code, args} = ev.data; + + // Create a file blob and push the data inside + const blob = new Blob(); + const url = URL.createObjectURL(blob); + const numChunks = Math.ceil(numEvents / EXPORT_LOGS_CHUNK_SIZE); + console.log(`[MainWorker -> Renderer] code=${code}`); switch (code) { + case WORKER_RESP_CODE.CHUNK_DATA: + receivedNumChunksRef.current += 1; + console.log(receivedNumChunksRef.current, args.logs); + + // If all chunks are received, trigger the download of the file + if (numChunks === receivedNumChunksRef.current) { + const link = document.createElement("a"); + link.href = url; + link.download = `${fileName}-exported-${new Date().toISOString() + .replace(/[:.]/g, "-")}.log`; + link.click(); + URL.revokeObjectURL(url); + } + break; case WORKER_RESP_CODE.LOG_FILE_INFO: setFileName(args.fileName); setNumEvents(args.numEvents); break; + case WORKER_RESP_CODE.NOTIFICATION: + // eslint-disable-next-line no-warning-comments + // TODO: notifications should be shown in the UI when the NotificationProvider + // is added + console.error(args.logLevel, args.message); + break; case WORKER_RESP_CODE.PAGE_DATA: { setLogData(args.logs); beginLineNumToLogEventNumRef.current = args.beginLineNumToLogEventNum; @@ -156,18 +190,26 @@ const StateContextProvider = ({children}: StateContextProviderProps) => { updateLogEventNumInUrl(lastLogEventNum, logEventNumRef.current); break; } - case WORKER_RESP_CODE.NOTIFICATION: - // eslint-disable-next-line no-warning-comments - // TODO: notifications should be shown in the UI when the NotificationProvider - // is added - console.error(args.logLevel, args.message); - break; default: console.error(`Unexpected ev.data: ${JSON.stringify(ev.data)}`); break; } }, []); + const exportLogs = useCallback(() => { + if (null === mainWorkerRef.current) { + console.error("Unexpected null mainWorkerRef.current"); + + return; + } + receivedNumChunksRef.current = 0; + workerPostReq( + mainWorkerRef.current, + WORKER_REQ_CODE.EXPORT_LOG, + {decoderOptions: getConfig(CONFIG_KEY.DECODER_OPTIONS)} + ); + }, []); + const loadFile = useCallback((fileSrc: FileSrcType, cursor: CursorType) => { if ("string" !== typeof fileSrc) { updateWindowUrlSearchParams({[SEARCH_PARAM_NAMES.FILE_PATH]: null}); @@ -275,12 +317,14 @@ const StateContextProvider = ({children}: StateContextProviderProps) => { value={{ beginLineNumToLogEventNum: beginLineNumToLogEventNumRef.current, fileName: fileName, - loadFile: loadFile, - loadPage: loadPage, logData: logData, numEvents: numEvents, numPages: numPagesRef.current, pageNum: pageNumRef.current, + + exportLogs: exportLogs, + loadFile: loadFile, + loadPage: loadPage, }} > {children} diff --git a/new-log-viewer/src/services/LogFileManager.ts b/new-log-viewer/src/services/LogFileManager.ts index ea73d7fa..176973c8 100644 --- a/new-log-viewer/src/services/LogFileManager.ts +++ b/new-log-viewer/src/services/LogFileManager.ts @@ -10,6 +10,7 @@ import { CursorType, FileSrcType, } from "../typings/worker"; +import {EXPORT_LOGS_CHUNK_SIZE} from "../utils/config"; import {getUint8ArrayFrom} from "../utils/http"; import {getChunkNum} from "../utils/math"; import {formatSizeInBytes} from "../utils/units"; @@ -152,6 +153,30 @@ class LogFileManager { this.#decoder.setDecoderOptions(options); } + loadChunk (eventIdx: number): { + logs: string, + } { + const results = this.#decoder.decode( + eventIdx, + Math.min(eventIdx + EXPORT_LOGS_CHUNK_SIZE, this.#numEvents) + ); + + if (null === results) { + throw new Error("Error occurred during decoding chunk. " + + `eventIdx=${eventIdx});`); + } + + const messages: string[] = []; + results.forEach((r) => { + const [msg] = r; + messages.push(msg); + }); + + return { + logs: messages.join(""), + }; + } + /** * Loads a page of log events based on the provided cursor. * diff --git a/new-log-viewer/src/services/MainWorker.ts b/new-log-viewer/src/services/MainWorker.ts index 87a1bd89..3f8bc351 100644 --- a/new-log-viewer/src/services/MainWorker.ts +++ b/new-log-viewer/src/services/MainWorker.ts @@ -9,6 +9,7 @@ import { WORKER_RESP_CODE, WorkerResp, } from "../typings/worker"; +import {EXPORT_LOGS_CHUNK_SIZE} from "../utils/config"; import LogFileManager from "./LogFileManager"; @@ -17,6 +18,7 @@ dayjs.extend(dayjsUtc); dayjs.extend(dayjsTimezone); /* eslint-enable import/no-named-as-default-member */ + /** * Manager for the currently opened log file. */ @@ -41,6 +43,18 @@ onmessage = async (ev: MessageEvent) => { try { switch (code) { + case WORKER_REQ_CODE.EXPORT_LOG: { + if (null === LOG_FILE_MANAGER) { + throw new Error("Log file manager hasn't been initialized"); + } + + let decodedEventIdx = 0; + while (LOG_FILE_MANAGER.numEvents > decodedEventIdx) { + postResp(WORKER_RESP_CODE.CHUNK_DATA, LOG_FILE_MANAGER.loadChunk(decodedEventIdx)); + decodedEventIdx += EXPORT_LOGS_CHUNK_SIZE; + } + break; + } case WORKER_REQ_CODE.LOAD_FILE: { LOG_FILE_MANAGER = await LogFileManager.create( args.fileSrc, diff --git a/new-log-viewer/src/typings/worker.ts b/new-log-viewer/src/typings/worker.ts index 0c88beb6..82b186c0 100644 --- a/new-log-viewer/src/typings/worker.ts +++ b/new-log-viewer/src/typings/worker.ts @@ -38,17 +38,22 @@ type BeginLineNumToLogEventNumMap = Map; * Enum of the protocol code for communications between the renderer and MainWorker. */ enum WORKER_REQ_CODE { + EXPORT_LOG = "exportLog", LOAD_FILE = "loadFile", LOAD_PAGE = "loadPage", } enum WORKER_RESP_CODE { + CHUNK_DATA = "chunkData", LOG_FILE_INFO = "fileInfo", PAGE_DATA = "pageData", NOTIFICATION = "notification", } type WorkerReqMap = { + [WORKER_REQ_CODE.EXPORT_LOG]: { + decoderOptions: DecoderOptionsType + } [WORKER_REQ_CODE.LOAD_FILE]: { fileSrc: FileSrcType, pageSize: number, @@ -62,6 +67,9 @@ type WorkerReqMap = { }; type WorkerRespMap = { + [WORKER_RESP_CODE.CHUNK_DATA]: { + logs: string + }, [WORKER_RESP_CODE.LOG_FILE_INFO]: { fileName: string, numEvents: number, diff --git a/new-log-viewer/src/utils/config.ts b/new-log-viewer/src/utils/config.ts index 0661702d..65f6d44b 100644 --- a/new-log-viewer/src/utils/config.ts +++ b/new-log-viewer/src/utils/config.ts @@ -10,6 +10,7 @@ import {DecoderOptionsType} from "../typings/decoders"; const MAX_PAGE_SIZE = 1_000_000; +const EXPORT_LOGS_CHUNK_SIZE = 10_000; /** * The default configuration values. @@ -148,6 +149,7 @@ const getConfig = (key: T): ConfigMap[T] => { export { CONFIG_DEFAULT, + EXPORT_LOGS_CHUNK_SIZE, getConfig, setConfig, testConfig, From b9ab9dd49779e2cf9516b32c17b4125e98350a44 Mon Sep 17 00:00:00 2001 From: Henry8192 <50559854+Henry8192@users.noreply.github.com> Date: Mon, 16 Sep 2024 12:43:34 -0400 Subject: [PATCH 02/25] Apply suggestions from code review Co-authored-by: Junhao Liao --- new-log-viewer/src/contexts/StateContextProvider.tsx | 1 - new-log-viewer/src/services/LogFileManager.ts | 6 +----- new-log-viewer/src/services/MainWorker.ts | 1 - 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/new-log-viewer/src/contexts/StateContextProvider.tsx b/new-log-viewer/src/contexts/StateContextProvider.tsx index 89a29b66..832f7e90 100644 --- a/new-log-viewer/src/contexts/StateContextProvider.tsx +++ b/new-log-viewer/src/contexts/StateContextProvider.tsx @@ -161,7 +161,6 @@ const StateContextProvider = ({children}: StateContextProviderProps) => { switch (code) { case WORKER_RESP_CODE.CHUNK_DATA: receivedNumChunksRef.current += 1; - console.log(receivedNumChunksRef.current, args.logs); // If all chunks are received, trigger the download of the file if (numChunks === receivedNumChunksRef.current) { diff --git a/new-log-viewer/src/services/LogFileManager.ts b/new-log-viewer/src/services/LogFileManager.ts index 176973c8..90d73e69 100644 --- a/new-log-viewer/src/services/LogFileManager.ts +++ b/new-log-viewer/src/services/LogFileManager.ts @@ -166,11 +166,7 @@ class LogFileManager { `eventIdx=${eventIdx});`); } - const messages: string[] = []; - results.forEach((r) => { - const [msg] = r; - messages.push(msg); - }); + const messages = results.map(([msg]) => msg); return { logs: messages.join(""), diff --git a/new-log-viewer/src/services/MainWorker.ts b/new-log-viewer/src/services/MainWorker.ts index 3f8bc351..51f1b1fd 100644 --- a/new-log-viewer/src/services/MainWorker.ts +++ b/new-log-viewer/src/services/MainWorker.ts @@ -18,7 +18,6 @@ dayjs.extend(dayjsUtc); dayjs.extend(dayjsTimezone); /* eslint-enable import/no-named-as-default-member */ - /** * Manager for the currently opened log file. */ From da3f0be38245d2b0748e1aedd5e2f3164457613e Mon Sep 17 00:00:00 2001 From: Henry8192 <50559854+Henry8192@users.noreply.github.com> Date: Mon, 16 Sep 2024 15:54:41 -0400 Subject: [PATCH 03/25] Move blob & numChunks to LogExportManager; Move downloadDecompressedLogs to utils folder --- .../src/contexts/StateContextProvider.tsx | 26 ++++++------ .../src/services/LogExportManager.ts | 42 +++++++++++++++++++ new-log-viewer/src/services/MainWorker.ts | 3 ++ .../src/utils/downloadDecompressedLogs.ts | 23 ++++++++++ 4 files changed, 81 insertions(+), 13 deletions(-) create mode 100644 new-log-viewer/src/services/LogExportManager.ts create mode 100644 new-log-viewer/src/utils/downloadDecompressedLogs.ts diff --git a/new-log-viewer/src/contexts/StateContextProvider.tsx b/new-log-viewer/src/contexts/StateContextProvider.tsx index 832f7e90..d7a8c61e 100644 --- a/new-log-viewer/src/contexts/StateContextProvider.tsx +++ b/new-log-viewer/src/contexts/StateContextProvider.tsx @@ -7,6 +7,7 @@ import React, { useState, } from "react"; +import LogExportManager from "../services/LogExportManager"; import {Nullable} from "../typings/common"; import {CONFIG_KEY} from "../typings/config"; import {SEARCH_PARAM_NAMES} from "../typings/url"; @@ -146,30 +147,24 @@ const StateContextProvider = ({children}: StateContextProviderProps) => { const numPagesRef = useRef(STATE_DEFAULT.numPages); const pageNumRef = useRef>(STATE_DEFAULT.pageNum); const receivedNumChunksRef = useRef(0); + const logExportManagerRef = useRef(new LogExportManager()); const mainWorkerRef = useRef(null); + logExportManagerRef.current.setNumChunks(Math.ceil(numEvents / EXPORT_LOGS_CHUNK_SIZE)); + console.error("beforeDownload", logExportManagerRef.current.getNumChunks()); + const handleMainWorkerResp = useCallback((ev: MessageEvent) => { const {code, args} = ev.data; - // Create a file blob and push the data inside - const blob = new Blob(); - const url = URL.createObjectURL(blob); - const numChunks = Math.ceil(numEvents / EXPORT_LOGS_CHUNK_SIZE); - console.log(`[MainWorker -> Renderer] code=${code}`); switch (code) { case WORKER_RESP_CODE.CHUNK_DATA: receivedNumChunksRef.current += 1; + logExportManagerRef.current.appendChunkData(args.logs); - // If all chunks are received, trigger the download of the file - if (numChunks === receivedNumChunksRef.current) { - const link = document.createElement("a"); - link.href = url; - link.download = `${fileName}-exported-${new Date().toISOString() - .replace(/[:.]/g, "-")}.log`; - link.click(); - URL.revokeObjectURL(url); + if (logExportManagerRef.current.getNumChunks() === receivedNumChunksRef.current) { + logExportManagerRef.current.download(fileName); } break; case WORKER_RESP_CODE.LOG_FILE_INFO: @@ -202,6 +197,11 @@ const StateContextProvider = ({children}: StateContextProviderProps) => { return; } receivedNumChunksRef.current = 0; + + // FIXME: uncomment the line below to observe the error + // logExportManagerRef.current.reset(Math.ceil(numEvents / EXPORT_LOGS_CHUNK_SIZE)); + console.error("numEvents", numEvents); + console.error(logExportManagerRef.current.getNumChunks()); workerPostReq( mainWorkerRef.current, WORKER_REQ_CODE.EXPORT_LOG, diff --git a/new-log-viewer/src/services/LogExportManager.ts b/new-log-viewer/src/services/LogExportManager.ts new file mode 100644 index 00000000..876e1ee3 --- /dev/null +++ b/new-log-viewer/src/services/LogExportManager.ts @@ -0,0 +1,42 @@ +import downloadDecompressedLogs from "../utils/downloadDecompressedLogs"; + + +class LogExportManager { + private blob: Blob; + + private numChunks: number; + + constructor (numChunks?: number) { + this.blob = new Blob(); + this.numChunks = numChunks ?? 0; + } + + getBlob (): Blob { + return this.blob; + } + + appendChunkData (chunkData: string) { + this.blob = new Blob([this.blob, + chunkData], {type: "text/plain"}); + } + + getNumChunks (): number { + return this.numChunks; + } + + setNumChunks (numChunks: number) { + this.numChunks = numChunks; + } + + download (fileName: string) { + // FIXME: eslint complains about this format + downloadDecompressedLogs({blob: this.blob, fileName}); + } + + reset (numChunks?: number) { + this.blob = new Blob(); + this.numChunks = numChunks ?? 0; + } +} + +export default LogExportManager; diff --git a/new-log-viewer/src/services/MainWorker.ts b/new-log-viewer/src/services/MainWorker.ts index 51f1b1fd..9b863b53 100644 --- a/new-log-viewer/src/services/MainWorker.ts +++ b/new-log-viewer/src/services/MainWorker.ts @@ -46,6 +46,9 @@ onmessage = async (ev: MessageEvent) => { if (null === LOG_FILE_MANAGER) { throw new Error("Log file manager hasn't been initialized"); } + if ("undefined" !== typeof args.decoderOptions) { + LOG_FILE_MANAGER.setDecoderOptions(args.decoderOptions); + } let decodedEventIdx = 0; while (LOG_FILE_MANAGER.numEvents > decodedEventIdx) { diff --git a/new-log-viewer/src/utils/downloadDecompressedLogs.ts b/new-log-viewer/src/utils/downloadDecompressedLogs.ts new file mode 100644 index 00000000..4b17267c --- /dev/null +++ b/new-log-viewer/src/utils/downloadDecompressedLogs.ts @@ -0,0 +1,23 @@ +interface downloadDecompressedLogsProps { + blob: Blob, + fileName: string, +} + +/** + * + * @param blob.blob + * @param blob + * @param fileName + * @param blob.fileName + */ +const downloadDecompressedLogs = ({blob, fileName}: downloadDecompressedLogsProps) => { + const url = URL.createObjectURL(blob); + const link = document.createElement("a"); + link.href = url; + link.download = `${fileName}-exported-${new Date().toISOString() + .replace(/[:.]/g, "-")}.log`; + link.click(); + URL.revokeObjectURL(url); +}; + +export default downloadDecompressedLogs; From 5abb6407b29ef8e298808cda82bc62d2f56c8a78 Mon Sep 17 00:00:00 2001 From: Henry <50559854+Henry8192@users.noreply.github.com> Date: Tue, 17 Sep 2024 01:10:44 -0400 Subject: [PATCH 04/25] Download logs can only be downloaded once; Need to check corner case of appendChunkData --- .../src/contexts/StateContextProvider.tsx | 24 +++++----- .../src/services/LogExportManager.ts | 44 ++++++++----------- .../src/utils/downloadDecompressedLogs.ts | 23 ---------- new-log-viewer/src/utils/file.ts | 20 ++++++++- 4 files changed, 47 insertions(+), 64 deletions(-) delete mode 100644 new-log-viewer/src/utils/downloadDecompressedLogs.ts diff --git a/new-log-viewer/src/contexts/StateContextProvider.tsx b/new-log-viewer/src/contexts/StateContextProvider.tsx index d7a8c61e..18b4f7e4 100644 --- a/new-log-viewer/src/contexts/StateContextProvider.tsx +++ b/new-log-viewer/src/contexts/StateContextProvider.tsx @@ -146,13 +146,17 @@ const StateContextProvider = ({children}: StateContextProviderProps) => { const logEventNumRef = useRef(logEventNum); const numPagesRef = useRef(STATE_DEFAULT.numPages); const pageNumRef = useRef>(STATE_DEFAULT.pageNum); - const receivedNumChunksRef = useRef(0); - const logExportManagerRef = useRef(new LogExportManager()); + const logExportManagerRef = useRef(null); const mainWorkerRef = useRef(null); - logExportManagerRef.current.setNumChunks(Math.ceil(numEvents / EXPORT_LOGS_CHUNK_SIZE)); - console.error("beforeDownload", logExportManagerRef.current.getNumChunks()); + useEffect(() => { + logExportManagerRef.current = new LogExportManager( + Math.ceil(numEvents / EXPORT_LOGS_CHUNK_SIZE), + fileName + ); + }, [fileName, + numEvents]); const handleMainWorkerResp = useCallback((ev: MessageEvent) => { const {code, args} = ev.data; @@ -160,11 +164,8 @@ const StateContextProvider = ({children}: StateContextProviderProps) => { console.log(`[MainWorker -> Renderer] code=${code}`); switch (code) { case WORKER_RESP_CODE.CHUNK_DATA: - receivedNumChunksRef.current += 1; - logExportManagerRef.current.appendChunkData(args.logs); - - if (logExportManagerRef.current.getNumChunks() === receivedNumChunksRef.current) { - logExportManagerRef.current.download(fileName); + if (null !== logExportManagerRef.current) { + logExportManagerRef.current.appendChunkData(args.logs); } break; case WORKER_RESP_CODE.LOG_FILE_INFO: @@ -196,12 +197,7 @@ const StateContextProvider = ({children}: StateContextProviderProps) => { return; } - receivedNumChunksRef.current = 0; - // FIXME: uncomment the line below to observe the error - // logExportManagerRef.current.reset(Math.ceil(numEvents / EXPORT_LOGS_CHUNK_SIZE)); - console.error("numEvents", numEvents); - console.error(logExportManagerRef.current.getNumChunks()); workerPostReq( mainWorkerRef.current, WORKER_REQ_CODE.EXPORT_LOG, diff --git a/new-log-viewer/src/services/LogExportManager.ts b/new-log-viewer/src/services/LogExportManager.ts index 876e1ee3..b09e473e 100644 --- a/new-log-viewer/src/services/LogExportManager.ts +++ b/new-log-viewer/src/services/LogExportManager.ts @@ -1,41 +1,33 @@ -import downloadDecompressedLogs from "../utils/downloadDecompressedLogs"; +import {downloadBlob} from "../utils/file"; class LogExportManager { - private blob: Blob; + readonly #chunks: string[]; - private numChunks: number; + readonly #numChunks: number; - constructor (numChunks?: number) { - this.blob = new Blob(); - this.numChunks = numChunks ?? 0; - } + readonly #fileName: string; - getBlob (): Blob { - return this.blob; + constructor (numChunks: number, fileName: string) { + this.#chunks = []; + this.#numChunks = numChunks; + this.#fileName = fileName; } appendChunkData (chunkData: string) { - this.blob = new Blob([this.blob, - chunkData], {type: "text/plain"}); - } - - getNumChunks (): number { - return this.numChunks; + // TODO: check corner case: what if chunkData is empty? + this.#chunks.push(chunkData); + if (this.#chunks.length === this.#numChunks) { + this.download(); + } } - setNumChunks (numChunks: number) { - this.numChunks = numChunks; - } - - download (fileName: string) { - // FIXME: eslint complains about this format - downloadDecompressedLogs({blob: this.blob, fileName}); - } + download () { + const blob = new Blob(this.#chunks, {type: "text/plain"}); + const fileNameTimeStamped = `${this.#fileName}-exported-${new Date().toISOString() + .replace(/[:.]/g, "-")}.log`; - reset (numChunks?: number) { - this.blob = new Blob(); - this.numChunks = numChunks ?? 0; + downloadBlob(blob, fileNameTimeStamped); } } diff --git a/new-log-viewer/src/utils/downloadDecompressedLogs.ts b/new-log-viewer/src/utils/downloadDecompressedLogs.ts deleted file mode 100644 index 4b17267c..00000000 --- a/new-log-viewer/src/utils/downloadDecompressedLogs.ts +++ /dev/null @@ -1,23 +0,0 @@ -interface downloadDecompressedLogsProps { - blob: Blob, - fileName: string, -} - -/** - * - * @param blob.blob - * @param blob - * @param fileName - * @param blob.fileName - */ -const downloadDecompressedLogs = ({blob, fileName}: downloadDecompressedLogsProps) => { - const url = URL.createObjectURL(blob); - const link = document.createElement("a"); - link.href = url; - link.download = `${fileName}-exported-${new Date().toISOString() - .replace(/[:.]/g, "-")}.log`; - link.click(); - URL.revokeObjectURL(url); -}; - -export default downloadDecompressedLogs; diff --git a/new-log-viewer/src/utils/file.ts b/new-log-viewer/src/utils/file.ts index 36980915..710b3699 100644 --- a/new-log-viewer/src/utils/file.ts +++ b/new-log-viewer/src/utils/file.ts @@ -22,4 +22,22 @@ const openFile = (onOpen: OnFileOpenCallback) => { input.click(); }; -export {openFile}; +/** + * + * @param blob.blob + * @param blob + * @param fileName + * @param blob.fileName + */ +const downloadBlob = (blob: Blob, fileName: string) => { + const url = URL.createObjectURL(blob); + const link = document.createElement("a"); + link.href = url; + link.download = fileName; + link.click(); + URL.revokeObjectURL(url); +}; + +export { + downloadBlob, openFile, +}; From 4b5c2768c1c0e36f6e03c1a8731255a5b4476ec8 Mon Sep 17 00:00:00 2001 From: Henry <50559854+Henry8192@users.noreply.github.com> Date: Tue, 17 Sep 2024 01:38:15 -0400 Subject: [PATCH 05/25] logs can be downloaded multiple times --- new-log-viewer/src/contexts/StateContextProvider.tsx | 7 +++++++ new-log-viewer/src/services/LogExportManager.ts | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/new-log-viewer/src/contexts/StateContextProvider.tsx b/new-log-viewer/src/contexts/StateContextProvider.tsx index 18b4f7e4..dad470a4 100644 --- a/new-log-viewer/src/contexts/StateContextProvider.tsx +++ b/new-log-viewer/src/contexts/StateContextProvider.tsx @@ -197,7 +197,14 @@ const StateContextProvider = ({children}: StateContextProviderProps) => { return; } + if (null === logExportManagerRef.current) { + console.error("logExportManager not initialized"); + return; + } + if (logExportManagerRef.current.getChunkLength()) { + logExportManagerRef.current.download(); + } workerPostReq( mainWorkerRef.current, WORKER_REQ_CODE.EXPORT_LOG, diff --git a/new-log-viewer/src/services/LogExportManager.ts b/new-log-viewer/src/services/LogExportManager.ts index b09e473e..856e26c8 100644 --- a/new-log-viewer/src/services/LogExportManager.ts +++ b/new-log-viewer/src/services/LogExportManager.ts @@ -14,6 +14,10 @@ class LogExportManager { this.#fileName = fileName; } + getChunkLength () { + return this.#chunks.length; + } + appendChunkData (chunkData: string) { // TODO: check corner case: what if chunkData is empty? this.#chunks.push(chunkData); From 20d98a635d94085614e65b331597d4ca1f48f667 Mon Sep 17 00:00:00 2001 From: Henry <50559854+Henry8192@users.noreply.github.com> Date: Tue, 17 Sep 2024 01:45:12 -0400 Subject: [PATCH 06/25] plausible fix for empty logs --- new-log-viewer/src/services/LogExportManager.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/new-log-viewer/src/services/LogExportManager.ts b/new-log-viewer/src/services/LogExportManager.ts index 856e26c8..1b341f8a 100644 --- a/new-log-viewer/src/services/LogExportManager.ts +++ b/new-log-viewer/src/services/LogExportManager.ts @@ -19,7 +19,11 @@ class LogExportManager { } appendChunkData (chunkData: string) { - // TODO: check corner case: what if chunkData is empty? + if (0 === this.#numChunks) { + this.download(); + + return; + } this.#chunks.push(chunkData); if (this.#chunks.length === this.#numChunks) { this.download(); From f6023cfdc2a3e41faefacdf88dc726f3c5e2818a Mon Sep 17 00:00:00 2001 From: Henry8192 <50559854+Henry8192@users.noreply.github.com> Date: Tue, 17 Sep 2024 12:13:39 -0400 Subject: [PATCH 07/25] address comments in code review --- .../src/components/MenuBar/index.tsx | 12 ++--- .../src/contexts/StateContextProvider.tsx | 23 ++++----- .../src/services/LogExportManager.ts | 51 +++++++++++++++---- new-log-viewer/src/services/MainWorker.ts | 8 ++- new-log-viewer/src/utils/file.ts | 7 ++- 5 files changed, 65 insertions(+), 36 deletions(-) diff --git a/new-log-viewer/src/components/MenuBar/index.tsx b/new-log-viewer/src/components/MenuBar/index.tsx index ab0154be..f3cd059d 100644 --- a/new-log-viewer/src/components/MenuBar/index.tsx +++ b/new-log-viewer/src/components/MenuBar/index.tsx @@ -10,10 +10,10 @@ import { Typography, } from "@mui/joy"; -import Description from "@mui/icons-material/Description"; -import Download from "@mui/icons-material/Download"; +import DescriptionIcon from "@mui/icons-material/Description"; +import DownloadIcon from "@mui/icons-material/Download"; import FileOpenIcon from "@mui/icons-material/FileOpen"; -import Settings from "@mui/icons-material/Settings"; +import SettingsIcon from "@mui/icons-material/Settings"; import {StateContext} from "../../contexts/StateContextProvider"; import {CURSOR_CODE} from "../../typings/worker"; @@ -63,7 +63,7 @@ const MenuBar = () => { flexGrow={1} gap={0.5} > - + {fileName} @@ -79,10 +79,10 @@ const MenuBar = () => { - + - + { const mainWorkerRef = useRef(null); - useEffect(() => { - logExportManagerRef.current = new LogExportManager( - Math.ceil(numEvents / EXPORT_LOGS_CHUNK_SIZE), - fileName - ); - }, [fileName, - numEvents]); - const handleMainWorkerResp = useCallback((ev: MessageEvent) => { const {code, args} = ev.data; @@ -197,20 +190,22 @@ const StateContextProvider = ({children}: StateContextProviderProps) => { return; } - if (null === logExportManagerRef.current) { - console.error("logExportManager not initialized"); + if (STATE_DEFAULT.numEvents === numEvents && STATE_DEFAULT.fileName === fileName) { + console.error("numEvents and fileName not initialized yet"); return; } - if (logExportManagerRef.current.getChunkLength()) { - logExportManagerRef.current.download(); - } + logExportManagerRef.current = new LogExportManager( + Math.ceil(numEvents / EXPORT_LOGS_CHUNK_SIZE), + fileName + ); workerPostReq( mainWorkerRef.current, WORKER_REQ_CODE.EXPORT_LOG, {decoderOptions: getConfig(CONFIG_KEY.DECODER_OPTIONS)} ); - }, []); + }, [numEvents, + fileName]); const loadFile = useCallback((fileSrc: FileSrcType, cursor: CursorType) => { if ("string" !== typeof fileSrc) { diff --git a/new-log-viewer/src/services/LogExportManager.ts b/new-log-viewer/src/services/LogExportManager.ts index 1b341f8a..a6efc6e3 100644 --- a/new-log-viewer/src/services/LogExportManager.ts +++ b/new-log-viewer/src/services/LogExportManager.ts @@ -1,36 +1,67 @@ import {downloadBlob} from "../utils/file"; +/** + * Manager for exporting logs to a file. + */ class LogExportManager { - readonly #chunks: string[]; + /** + * Array to store chunks of log data. + * + * @type {string[]} + * @private + */ + readonly #chunks: string[] = []; + /** + * Total number of chunks to export. + * + * @type {number} + * @private + */ readonly #numChunks: number; + /** + * Name of the file to export to. + * + * @type {string} + * @private + */ readonly #fileName: string; constructor (numChunks: number, fileName: string) { - this.#chunks = []; this.#numChunks = numChunks; this.#fileName = fileName; } - getChunkLength () { - return this.#chunks.length; - } - + /** + * Append a chunk of log string. + * If the number of chunks reaches the specified limit, trigger a download. + * + * @param chunkData The chunk of log string to append. + * @return The current download progress. + */ appendChunkData (chunkData: string) { if (0 === this.#numChunks) { - this.download(); + this.#download(); - return; + return 1; } this.#chunks.push(chunkData); if (this.#chunks.length === this.#numChunks) { - this.download(); + this.#download(); + this.#chunks.length = 0; } + + return this.#chunks.length / this.#numChunks; } - download () { + /** + * Trigger a download of the accumulated log data chunks. + * + * @private + */ + #download () { const blob = new Blob(this.#chunks, {type: "text/plain"}); const fileNameTimeStamped = `${this.#fileName}-exported-${new Date().toISOString() .replace(/[:.]/g, "-")}.log`; diff --git a/new-log-viewer/src/services/MainWorker.ts b/new-log-viewer/src/services/MainWorker.ts index 9b863b53..fd67d0e9 100644 --- a/new-log-viewer/src/services/MainWorker.ts +++ b/new-log-viewer/src/services/MainWorker.ts @@ -36,6 +36,7 @@ const postResp = ( postMessage({code, args}); }; +// eslint-disable-next-line max-lines-per-function,max-statements onmessage = async (ev: MessageEvent) => { const {code, args} = ev.data; console.log(`[Renderer -> MainWorker] code=${code}: args=${JSON.stringify(args)}`); @@ -51,8 +52,11 @@ onmessage = async (ev: MessageEvent) => { } let decodedEventIdx = 0; - while (LOG_FILE_MANAGER.numEvents > decodedEventIdx) { - postResp(WORKER_RESP_CODE.CHUNK_DATA, LOG_FILE_MANAGER.loadChunk(decodedEventIdx)); + while (decodedEventIdx < LOG_FILE_MANAGER.numEvents) { + postResp( + WORKER_RESP_CODE.CHUNK_DATA, + LOG_FILE_MANAGER.loadChunk(decodedEventIdx) + ); decodedEventIdx += EXPORT_LOGS_CHUNK_SIZE; } break; diff --git a/new-log-viewer/src/utils/file.ts b/new-log-viewer/src/utils/file.ts index 710b3699..9f4cc7df 100644 --- a/new-log-viewer/src/utils/file.ts +++ b/new-log-viewer/src/utils/file.ts @@ -23,11 +23,10 @@ const openFile = (onOpen: OnFileOpenCallback) => { }; /** + * Triggers a download of the provided Blob object with the specified file name. * - * @param blob.blob - * @param blob - * @param fileName - * @param blob.fileName + * @param blob The Blob object to download. + * @param fileName The name of the file to be downloaded. */ const downloadBlob = (blob: Blob, fileName: string) => { const url = URL.createObjectURL(blob); From 7bf9432ed0c6f67d6c272a8c0c30e75d7765d910 Mon Sep 17 00:00:00 2001 From: Henry8192 <50559854+Henry8192@users.noreply.github.com> Date: Tue, 17 Sep 2024 16:45:33 -0400 Subject: [PATCH 08/25] Apply suggestions from code review Co-authored-by: Junhao Liao --- .../src/services/LogExportManager.ts | 19 ++++--------------- new-log-viewer/src/utils/file.ts | 3 ++- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/new-log-viewer/src/services/LogExportManager.ts b/new-log-viewer/src/services/LogExportManager.ts index a6efc6e3..c6cdc498 100644 --- a/new-log-viewer/src/services/LogExportManager.ts +++ b/new-log-viewer/src/services/LogExportManager.ts @@ -6,26 +6,17 @@ import {downloadBlob} from "../utils/file"; */ class LogExportManager { /** - * Array to store chunks of log data. - * - * @type {string[]} - * @private + * Internal buffer which stores decoded chunks of log data. */ readonly #chunks: string[] = []; /** * Total number of chunks to export. - * - * @type {number} - * @private */ readonly #numChunks: number; /** * Name of the file to export to. - * - * @type {string} - * @private */ readonly #fileName: string; @@ -35,13 +26,13 @@ class LogExportManager { } /** - * Append a chunk of log string. + * Append the provided chunk of logs into an internal buffer. * If the number of chunks reaches the specified limit, trigger a download. * * @param chunkData The chunk of log string to append. - * @return The current download progress. + * @return The current download progress as a decimal between 0 (initialization) and 1 (download complete). */ - appendChunkData (chunkData: string) { + appendChunkData (chunkData: string): number { if (0 === this.#numChunks) { this.#download(); @@ -58,8 +49,6 @@ class LogExportManager { /** * Trigger a download of the accumulated log data chunks. - * - * @private */ #download () { const blob = new Blob(this.#chunks, {type: "text/plain"}); diff --git a/new-log-viewer/src/utils/file.ts b/new-log-viewer/src/utils/file.ts index 9f4cc7df..a8ccf7ca 100644 --- a/new-log-viewer/src/utils/file.ts +++ b/new-log-viewer/src/utils/file.ts @@ -38,5 +38,6 @@ const downloadBlob = (blob: Blob, fileName: string) => { }; export { - downloadBlob, openFile, + downloadBlob, + openFile, }; From 73bc71f759abdc6046543da0d91591ad0aafec74 Mon Sep 17 00:00:00 2001 From: Henry <50559854+Henry8192@users.noreply.github.com> Date: Tue, 17 Sep 2024 16:58:32 -0400 Subject: [PATCH 09/25] address changes from code review --- .../src/contexts/StateContextProvider.tsx | 7 +++-- .../src/services/LogExportManager.ts | 9 +++--- new-log-viewer/src/utils/file.ts | 30 +++++++++---------- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/new-log-viewer/src/contexts/StateContextProvider.tsx b/new-log-viewer/src/contexts/StateContextProvider.tsx index 34305cd8..0fcb23ac 100644 --- a/new-log-viewer/src/contexts/StateContextProvider.tsx +++ b/new-log-viewer/src/contexts/StateContextProvider.tsx @@ -153,7 +153,6 @@ const StateContextProvider = ({children}: StateContextProviderProps) => { const handleMainWorkerResp = useCallback((ev: MessageEvent) => { const {code, args} = ev.data; - console.log(`[MainWorker -> Renderer] code=${code}`); switch (code) { case WORKER_RESP_CODE.CHUNK_DATA: @@ -204,8 +203,10 @@ const StateContextProvider = ({children}: StateContextProviderProps) => { WORKER_REQ_CODE.EXPORT_LOG, {decoderOptions: getConfig(CONFIG_KEY.DECODER_OPTIONS)} ); - }, [numEvents, - fileName]); + }, [ + numEvents, + fileName, + ]); const loadFile = useCallback((fileSrc: FileSrcType, cursor: CursorType) => { if ("string" !== typeof fileSrc) { diff --git a/new-log-viewer/src/services/LogExportManager.ts b/new-log-viewer/src/services/LogExportManager.ts index c6cdc498..93a0b44b 100644 --- a/new-log-viewer/src/services/LogExportManager.ts +++ b/new-log-viewer/src/services/LogExportManager.ts @@ -18,11 +18,11 @@ class LogExportManager { /** * Name of the file to export to. */ - readonly #fileName: string; + readonly #exportedFileName: string; constructor (numChunks: number, fileName: string) { this.#numChunks = numChunks; - this.#fileName = fileName; + this.#exportedFileName = fileName; } /** @@ -30,7 +30,8 @@ class LogExportManager { * If the number of chunks reaches the specified limit, trigger a download. * * @param chunkData The chunk of log string to append. - * @return The current download progress as a decimal between 0 (initialization) and 1 (download complete). + * @return The current download progress as a decimal between + * 0 (initialization) and 1 (download complete). */ appendChunkData (chunkData: string): number { if (0 === this.#numChunks) { @@ -52,7 +53,7 @@ class LogExportManager { */ #download () { const blob = new Blob(this.#chunks, {type: "text/plain"}); - const fileNameTimeStamped = `${this.#fileName}-exported-${new Date().toISOString() + const fileNameTimeStamped = `${this.#exportedFileName}-exported-${new Date().toISOString() .replace(/[:.]/g, "-")}.log`; downloadBlob(blob, fileNameTimeStamped); diff --git a/new-log-viewer/src/utils/file.ts b/new-log-viewer/src/utils/file.ts index a8ccf7ca..5e223bac 100644 --- a/new-log-viewer/src/utils/file.ts +++ b/new-log-viewer/src/utils/file.ts @@ -1,6 +1,21 @@ import type {OnFileOpenCallback} from "../typings/file"; +/** + * Triggers a download of the provided Blob object with the specified file name. + * + * @param blob The Blob object to download. + * @param fileName The name of the file to be downloaded. + */ +const downloadBlob = (blob: Blob, fileName: string) => { + const url = URL.createObjectURL(blob); + const link = document.createElement("a"); + link.href = url; + link.download = fileName; + link.click(); + URL.revokeObjectURL(url); +}; + /** * Opens a file and invokes the provided callback on the file. * @@ -22,21 +37,6 @@ const openFile = (onOpen: OnFileOpenCallback) => { input.click(); }; -/** - * Triggers a download of the provided Blob object with the specified file name. - * - * @param blob The Blob object to download. - * @param fileName The name of the file to be downloaded. - */ -const downloadBlob = (blob: Blob, fileName: string) => { - const url = URL.createObjectURL(blob); - const link = document.createElement("a"); - link.href = url; - link.download = fileName; - link.click(); - URL.revokeObjectURL(url); -}; - export { downloadBlob, openFile, From 406b76ce255b40c0af4fabd028ca98fa66ee18b5 Mon Sep 17 00:00:00 2001 From: Henry <50559854+Henry8192@users.noreply.github.com> Date: Tue, 17 Sep 2024 22:14:31 -0400 Subject: [PATCH 10/25] Introduce 8px padding to .menu-bar for better spacing. Add .menu-bar-filename class to CSS. --- .../components/MenuBar/ExportLogsButton.tsx | 58 +++++++++++++++++++ .../src/components/MenuBar/index.tsx | 11 +--- .../src/contexts/StateContextProvider.tsx | 8 ++- .../src/services/LogExportManager.ts | 19 ++++-- 4 files changed, 81 insertions(+), 15 deletions(-) create mode 100644 new-log-viewer/src/components/MenuBar/ExportLogsButton.tsx diff --git a/new-log-viewer/src/components/MenuBar/ExportLogsButton.tsx b/new-log-viewer/src/components/MenuBar/ExportLogsButton.tsx new file mode 100644 index 00000000..161e1e6a --- /dev/null +++ b/new-log-viewer/src/components/MenuBar/ExportLogsButton.tsx @@ -0,0 +1,58 @@ +import {useContext} from "react"; + +import { + CircularProgress, + Typography, +} from "@mui/joy"; + +import DownloadIcon from "@mui/icons-material/Download"; + +import {StateContext} from "../../contexts/StateContextProvider"; +import { + EXPORT_LOG_PROGRESS_COMPLETE, + EXPORT_LOG_PROGRESS_INITIALIZATION, +} from "../../services/LogExportManager"; +import SmallIconButton from "./SmallIconButton"; + + +/** + * Represents a button for triggering log exports and displays the progress. + * + * @return + */ +export const ExportLogsButton = () => { + const {exportLogs, exportProgress} = useContext(StateContext); + const handleExportLogsButtonClick = () => { + exportLogs(); + }; + + + return ( + + {null === exportProgress || EXPORT_LOG_PROGRESS_INITIALIZATION === exportProgress ? + : + + {EXPORT_LOG_PROGRESS_COMPLETE === exportProgress ? + : + + {Math.ceil(exportProgress * 100)} + } + } + + ); +}; + +export default ExportLogsButton; diff --git a/new-log-viewer/src/components/MenuBar/index.tsx b/new-log-viewer/src/components/MenuBar/index.tsx index f3cd059d..1e345069 100644 --- a/new-log-viewer/src/components/MenuBar/index.tsx +++ b/new-log-viewer/src/components/MenuBar/index.tsx @@ -11,7 +11,6 @@ import { } from "@mui/joy"; import DescriptionIcon from "@mui/icons-material/Description"; -import DownloadIcon from "@mui/icons-material/Download"; import FileOpenIcon from "@mui/icons-material/FileOpen"; import SettingsIcon from "@mui/icons-material/Settings"; @@ -19,6 +18,7 @@ import {StateContext} from "../../contexts/StateContextProvider"; import {CURSOR_CODE} from "../../typings/worker"; import {openFile} from "../../utils/file"; import SettingsModal from "../modals/SettingsModal"; +import ExportLogsButton from "./ExportLogsButton"; import NavigationBar from "./NavigationBar"; import SmallIconButton from "./SmallIconButton"; @@ -31,7 +31,7 @@ import "./index.css"; * @return */ const MenuBar = () => { - const {fileName, exportLogs, loadFile} = useContext(StateContext); + const {fileName, loadFile} = useContext(StateContext); const [isSettingsModalOpen, setIsSettingsModalOpen] = useState(false); @@ -49,9 +49,6 @@ const MenuBar = () => { setIsSettingsModalOpen(true); }; - const handleExportLogsButtonClick = () => { - exportLogs(); - }; return ( <> @@ -81,9 +78,7 @@ const MenuBar = () => { > - - - + , logData: string, numEvents: number, numPages: number, @@ -58,6 +59,7 @@ const StateContext = createContext({} as StateContextType); */ const STATE_DEFAULT: Readonly = Object.freeze({ beginLineNumToLogEventNum: new Map(), + exportProgress: null, fileName: "", logData: "Loading...", numEvents: 0, @@ -140,6 +142,8 @@ const StateContextProvider = ({children}: StateContextProviderProps) => { const {filePath, logEventNum} = useContext(UrlContext); const [fileName, setFileName] = useState(STATE_DEFAULT.fileName); + const [exportProgress, setExportProgress] = + useState>(STATE_DEFAULT.exportProgress); const [logData, setLogData] = useState(STATE_DEFAULT.logData); const [numEvents, setNumEvents] = useState(STATE_DEFAULT.numEvents); const beginLineNumToLogEventNumRef = @@ -157,7 +161,8 @@ const StateContextProvider = ({children}: StateContextProviderProps) => { switch (code) { case WORKER_RESP_CODE.CHUNK_DATA: if (null !== logExportManagerRef.current) { - logExportManagerRef.current.appendChunkData(args.logs); + const progress = logExportManagerRef.current.appendChunkData(args.logs); + setExportProgress(progress); } break; case WORKER_RESP_CODE.LOG_FILE_INFO: @@ -314,6 +319,7 @@ const StateContextProvider = ({children}: StateContextProviderProps) => { Date: Tue, 17 Sep 2024 23:02:35 -0400 Subject: [PATCH 11/25] change exportedFileName format; address two exports in ExportLogsButton.tsx --- new-log-viewer/src/components/MenuBar/ExportLogsButton.tsx | 3 +-- new-log-viewer/src/services/LogExportManager.ts | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/new-log-viewer/src/components/MenuBar/ExportLogsButton.tsx b/new-log-viewer/src/components/MenuBar/ExportLogsButton.tsx index 161e1e6a..f433563e 100644 --- a/new-log-viewer/src/components/MenuBar/ExportLogsButton.tsx +++ b/new-log-viewer/src/components/MenuBar/ExportLogsButton.tsx @@ -20,13 +20,12 @@ import SmallIconButton from "./SmallIconButton"; * * @return */ -export const ExportLogsButton = () => { +const ExportLogsButton = () => { const {exportLogs, exportProgress} = useContext(StateContext); const handleExportLogsButtonClick = () => { exportLogs(); }; - return ( Date: Wed, 18 Sep 2024 11:12:39 -0400 Subject: [PATCH 12/25] Apply suggestions from code review Co-authored-by: Junhao Liao Co-authored-by: kirkrodrigues <2454684+kirkrodrigues@users.noreply.github.com> --- .../src/components/MenuBar/ExportLogsButton.tsx | 2 +- new-log-viewer/src/components/MenuBar/index.tsx | 1 - new-log-viewer/src/contexts/StateContextProvider.tsx | 1 + new-log-viewer/src/services/LogExportManager.ts | 9 ++++----- new-log-viewer/src/services/LogFileManager.ts | 3 +-- 5 files changed, 7 insertions(+), 9 deletions(-) diff --git a/new-log-viewer/src/components/MenuBar/ExportLogsButton.tsx b/new-log-viewer/src/components/MenuBar/ExportLogsButton.tsx index f433563e..ed79509f 100644 --- a/new-log-viewer/src/components/MenuBar/ExportLogsButton.tsx +++ b/new-log-viewer/src/components/MenuBar/ExportLogsButton.tsx @@ -28,7 +28,7 @@ const ExportLogsButton = () => { return ( {null === exportProgress || EXPORT_LOG_PROGRESS_INITIALIZATION === exportProgress ? diff --git a/new-log-viewer/src/components/MenuBar/index.tsx b/new-log-viewer/src/components/MenuBar/index.tsx index 1e345069..e2a21487 100644 --- a/new-log-viewer/src/components/MenuBar/index.tsx +++ b/new-log-viewer/src/components/MenuBar/index.tsx @@ -49,7 +49,6 @@ const MenuBar = () => { setIsSettingsModalOpen(true); }; - return ( <> diff --git a/new-log-viewer/src/contexts/StateContextProvider.tsx b/new-log-viewer/src/contexts/StateContextProvider.tsx index aa71e706..fb1db68f 100644 --- a/new-log-viewer/src/contexts/StateContextProvider.tsx +++ b/new-log-viewer/src/contexts/StateContextProvider.tsx @@ -199,6 +199,7 @@ const StateContextProvider = ({children}: StateContextProviderProps) => { return; } + logExportManagerRef.current = new LogExportManager( Math.ceil(numEvents / EXPORT_LOGS_CHUNK_SIZE), fileName diff --git a/new-log-viewer/src/services/LogExportManager.ts b/new-log-viewer/src/services/LogExportManager.ts index 746c08bb..50c35d93 100644 --- a/new-log-viewer/src/services/LogExportManager.ts +++ b/new-log-viewer/src/services/LogExportManager.ts @@ -5,7 +5,7 @@ const EXPORT_LOG_PROGRESS_INITIALIZATION = 0; const EXPORT_LOG_PROGRESS_COMPLETE = 1; /** - * Manager for exporting logs to a file. + * Manager for exporting logs as a file. */ class LogExportManager { /** @@ -33,9 +33,8 @@ class LogExportManager { * Append the provided chunk of logs into an internal buffer. * If the number of chunks reaches the specified limit, trigger a download. * - * @param chunkData The chunk of log string to append. - * @return The current download progress as a decimal between - * 0 (initialization) and 1 (download complete). + * @param chunkData + * @return The current download progress as a float between 0 and 1. */ appendChunkData (chunkData: string): number { if (0 === this.#numChunks) { @@ -55,7 +54,7 @@ class LogExportManager { } /** - * Trigger a download of the accumulated log data chunks. + * Triggers a download of the accumulated chunks. */ #download () { const blob = new Blob(this.#chunks, {type: "text/plain"}); diff --git a/new-log-viewer/src/services/LogFileManager.ts b/new-log-viewer/src/services/LogFileManager.ts index 90d73e69..8bfa3412 100644 --- a/new-log-viewer/src/services/LogFileManager.ts +++ b/new-log-viewer/src/services/LogFileManager.ts @@ -162,8 +162,7 @@ class LogFileManager { ); if (null === results) { - throw new Error("Error occurred during decoding chunk. " + - `eventIdx=${eventIdx});`); + throw new Error(`Failed to decode chunk containing logEventIdx=${eventIdx}`); } const messages = results.map(([msg]) => msg); From 8bcf11506a5b06007c1e679a9b9d76ba70787e9b Mon Sep 17 00:00:00 2001 From: Henry <50559854+Henry8192@users.noreply.github.com> Date: Wed, 18 Sep 2024 14:07:17 -0400 Subject: [PATCH 13/25] fix issues in review --- .../components/MenuBar/ExportLogsButton.tsx | 17 ++++++------- .../src/contexts/StateContextProvider.tsx | 2 +- .../src/services/LogExportManager.ts | 24 +++++++++---------- new-log-viewer/src/services/LogFileManager.ts | 15 ++++++++---- new-log-viewer/src/services/MainWorker.ts | 2 ++ 5 files changed, 33 insertions(+), 27 deletions(-) diff --git a/new-log-viewer/src/components/MenuBar/ExportLogsButton.tsx b/new-log-viewer/src/components/MenuBar/ExportLogsButton.tsx index ed79509f..f3a2d1d7 100644 --- a/new-log-viewer/src/components/MenuBar/ExportLogsButton.tsx +++ b/new-log-viewer/src/components/MenuBar/ExportLogsButton.tsx @@ -9,8 +9,8 @@ import DownloadIcon from "@mui/icons-material/Download"; import {StateContext} from "../../contexts/StateContextProvider"; import { - EXPORT_LOG_PROGRESS_COMPLETE, - EXPORT_LOG_PROGRESS_INITIALIZATION, + EXPORT_LOG_PROGRESS_VALUE_MAX, + EXPORT_LOG_PROGRESS_VALUE_MIN, } from "../../services/LogExportManager"; import SmallIconButton from "./SmallIconButton"; @@ -22,27 +22,24 @@ import SmallIconButton from "./SmallIconButton"; */ const ExportLogsButton = () => { const {exportLogs, exportProgress} = useContext(StateContext); - const handleExportLogsButtonClick = () => { - exportLogs(); - }; return ( - {null === exportProgress || EXPORT_LOG_PROGRESS_INITIALIZATION === exportProgress ? + {null === exportProgress || EXPORT_LOG_PROGRESS_VALUE_MIN === exportProgress ? : - {EXPORT_LOG_PROGRESS_COMPLETE === exportProgress ? + {EXPORT_LOG_PROGRESS_VALUE_MAX === exportProgress ? : diff --git a/new-log-viewer/src/contexts/StateContextProvider.tsx b/new-log-viewer/src/contexts/StateContextProvider.tsx index fb1db68f..2caf54ed 100644 --- a/new-log-viewer/src/contexts/StateContextProvider.tsx +++ b/new-log-viewer/src/contexts/StateContextProvider.tsx @@ -161,7 +161,7 @@ const StateContextProvider = ({children}: StateContextProviderProps) => { switch (code) { case WORKER_RESP_CODE.CHUNK_DATA: if (null !== logExportManagerRef.current) { - const progress = logExportManagerRef.current.appendChunkData(args.logs); + const progress = logExportManagerRef.current.appendChunk(args.logs); setExportProgress(progress); } break; diff --git a/new-log-viewer/src/services/LogExportManager.ts b/new-log-viewer/src/services/LogExportManager.ts index 50c35d93..7f8df625 100644 --- a/new-log-viewer/src/services/LogExportManager.ts +++ b/new-log-viewer/src/services/LogExportManager.ts @@ -1,8 +1,8 @@ import {downloadBlob} from "../utils/file"; -const EXPORT_LOG_PROGRESS_INITIALIZATION = 0; -const EXPORT_LOG_PROGRESS_COMPLETE = 1; +const EXPORT_LOG_PROGRESS_VALUE_MIN = 0; +const EXPORT_LOG_PROGRESS_VALUE_MAX = 1; /** * Manager for exporting logs as a file. @@ -25,29 +25,29 @@ class LogExportManager { constructor (numChunks: number, fileName: string) { this.#numChunks = numChunks; - this.#exportedFileName = `exported-${fileName}-${new Date().toISOString() + this.#exportedFileName = `${fileName}-exported-${new Date().toISOString() .replace(/[:.]/g, "-")}.log`; } /** - * Append the provided chunk of logs into an internal buffer. - * If the number of chunks reaches the specified limit, trigger a download. + * Appends the provided chunk of logs into an internal buffer. If the number of chunks reaches + * the specified limit, trigger a download. * - * @param chunkData + * @param chunk * @return The current download progress as a float between 0 and 1. */ - appendChunkData (chunkData: string): number { + appendChunk (chunk: string): number { if (0 === this.#numChunks) { this.#download(); - return EXPORT_LOG_PROGRESS_COMPLETE; + return EXPORT_LOG_PROGRESS_VALUE_MAX; } - this.#chunks.push(chunkData); + this.#chunks.push(chunk); if (this.#chunks.length === this.#numChunks) { this.#download(); this.#chunks.length = 0; - return EXPORT_LOG_PROGRESS_COMPLETE; + return EXPORT_LOG_PROGRESS_VALUE_MAX; } return this.#chunks.length / this.#numChunks; @@ -64,6 +64,6 @@ class LogExportManager { export default LogExportManager; export { - EXPORT_LOG_PROGRESS_COMPLETE, - EXPORT_LOG_PROGRESS_INITIALIZATION, + EXPORT_LOG_PROGRESS_VALUE_MAX, + EXPORT_LOG_PROGRESS_VALUE_MIN, }; diff --git a/new-log-viewer/src/services/LogFileManager.ts b/new-log-viewer/src/services/LogFileManager.ts index 8bfa3412..e27bc051 100644 --- a/new-log-viewer/src/services/LogFileManager.ts +++ b/new-log-viewer/src/services/LogFileManager.ts @@ -153,16 +153,23 @@ class LogFileManager { this.#decoder.setDecoderOptions(options); } - loadChunk (eventIdx: number): { + /** + * Loads a chunk of log events based on the provided event index. + * + * @param logEventIdx The index of the first event to load. + * @return An object containing the logs as a string. + * @throws {Error} if any error occurs during decode. + */ + loadChunk (logEventIdx: number): { logs: string, } { const results = this.#decoder.decode( - eventIdx, - Math.min(eventIdx + EXPORT_LOGS_CHUNK_SIZE, this.#numEvents) + logEventIdx, + Math.min(logEventIdx + EXPORT_LOGS_CHUNK_SIZE, this.#numEvents) ); if (null === results) { - throw new Error(`Failed to decode chunk containing logEventIdx=${eventIdx}`); + throw new Error(`Failed to decode chunk containing logEventIdx=${logEventIdx}`); } const messages = results.map(([msg]) => msg); diff --git a/new-log-viewer/src/services/MainWorker.ts b/new-log-viewer/src/services/MainWorker.ts index fd67d0e9..281f0378 100644 --- a/new-log-viewer/src/services/MainWorker.ts +++ b/new-log-viewer/src/services/MainWorker.ts @@ -36,6 +36,8 @@ const postResp = ( postMessage({code, args}); }; +// eslint-disable-next-line no-warning-comments +// TODO: break this function up into smaller functions // eslint-disable-next-line max-lines-per-function,max-statements onmessage = async (ev: MessageEvent) => { const {code, args} = ev.data; From e2cc493d663472efad961c387499398d10f16c2b Mon Sep 17 00:00:00 2001 From: Henry <50559854+Henry8192@users.noreply.github.com> Date: Wed, 18 Sep 2024 16:02:25 -0400 Subject: [PATCH 14/25] fix lint warnings; address the remaining issues in code review --- new-log-viewer/src/components/MenuBar/ExportLogsButton.tsx | 7 +++++-- new-log-viewer/src/components/MenuBar/PageNumInput.tsx | 3 ++- new-log-viewer/src/services/LogExportManager.ts | 4 ++-- new-log-viewer/src/utils/config.ts | 3 +++ 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/new-log-viewer/src/components/MenuBar/ExportLogsButton.tsx b/new-log-viewer/src/components/MenuBar/ExportLogsButton.tsx index f3a2d1d7..2f702c04 100644 --- a/new-log-viewer/src/components/MenuBar/ExportLogsButton.tsx +++ b/new-log-viewer/src/components/MenuBar/ExportLogsButton.tsx @@ -21,11 +21,14 @@ import SmallIconButton from "./SmallIconButton"; * @return */ const ExportLogsButton = () => { - const {exportLogs, exportProgress} = useContext(StateContext); + const {exportLogs, exportProgress, fileName} = useContext(StateContext); return ( {null === exportProgress || EXPORT_LOG_PROGRESS_VALUE_MIN === exportProgress ? diff --git a/new-log-viewer/src/components/MenuBar/PageNumInput.tsx b/new-log-viewer/src/components/MenuBar/PageNumInput.tsx index e8ad1489..52b9c718 100644 --- a/new-log-viewer/src/components/MenuBar/PageNumInput.tsx +++ b/new-log-viewer/src/components/MenuBar/PageNumInput.tsx @@ -55,7 +55,8 @@ const PageNumInput = () => { return; } inputRef.current.style.width = "0"; - inputRef.current.style.width = `${inputRef.current.scrollWidth + PAGE_NUM_INPUT_FIT_EXTRA_WIDTH}px`; + inputRef.current.style.width = `${inputRef.current.scrollWidth + + PAGE_NUM_INPUT_FIT_EXTRA_WIDTH}px`; }; const handleInputChange = () => { diff --git a/new-log-viewer/src/services/LogExportManager.ts b/new-log-viewer/src/services/LogExportManager.ts index 7f8df625..6b308df2 100644 --- a/new-log-viewer/src/services/LogExportManager.ts +++ b/new-log-viewer/src/services/LogExportManager.ts @@ -25,8 +25,8 @@ class LogExportManager { constructor (numChunks: number, fileName: string) { this.#numChunks = numChunks; - this.#exportedFileName = `${fileName}-exported-${new Date().toISOString() - .replace(/[:.]/g, "-")}.log`; + this.#exportedFileName = `exported-${new Date().toISOString() + .replace(/[:.]/g, "-")}-${fileName}.log`; } /** diff --git a/new-log-viewer/src/utils/config.ts b/new-log-viewer/src/utils/config.ts index 65f6d44b..524d62d1 100644 --- a/new-log-viewer/src/utils/config.ts +++ b/new-log-viewer/src/utils/config.ts @@ -32,6 +32,7 @@ const CONFIG_DEFAULT: ConfigMap = Object.freeze({ * @param props.key * @param props.value * @return `null` if the value is valid, or an error message otherwise. + * @throws {Error} If the key is CONFIG_KEY.THEME. */ const testConfig = ({key, value}: ConfigUpdate): Nullable => { let result = null; @@ -62,6 +63,7 @@ const testConfig = ({key, value}: ConfigUpdate): Nullable => { * @param props.key * @param props.value * @return `null` if the update succeeds, or an error message otherwise. + * @throws {Error} If the key is CONFIG_KEY.THEME. */ const setConfig = ({key, value}: ConfigUpdate): Nullable => { const error = testConfig({key, value} as ConfigUpdate); @@ -102,6 +104,7 @@ const setConfig = ({key, value}: ConfigUpdate): Nullable => { * * @param key * @return The value. + * @throws {Error} If the key is CONFIG_KEY.THEME. */ const getConfig = (key: T): ConfigMap[T] => { let value = null; From 69ca0b77ba7a8d0715a789ae6f0c4d99b20c7a90 Mon Sep 17 00:00:00 2001 From: Kirk Rodrigues <2454684+kirkrodrigues@users.noreply.github.com> Date: Wed, 18 Sep 2024 23:34:18 -0400 Subject: [PATCH 15/25] Minor comment fixes. --- new-log-viewer/src/services/LogExportManager.ts | 2 +- new-log-viewer/src/services/MainWorker.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/new-log-viewer/src/services/LogExportManager.ts b/new-log-viewer/src/services/LogExportManager.ts index 6b308df2..82a2afc2 100644 --- a/new-log-viewer/src/services/LogExportManager.ts +++ b/new-log-viewer/src/services/LogExportManager.ts @@ -31,7 +31,7 @@ class LogExportManager { /** * Appends the provided chunk of logs into an internal buffer. If the number of chunks reaches - * the specified limit, trigger a download. + * the specified limit, triggers a download. * * @param chunk * @return The current download progress as a float between 0 and 1. diff --git a/new-log-viewer/src/services/MainWorker.ts b/new-log-viewer/src/services/MainWorker.ts index 281f0378..a04d134c 100644 --- a/new-log-viewer/src/services/MainWorker.ts +++ b/new-log-viewer/src/services/MainWorker.ts @@ -37,7 +37,7 @@ const postResp = ( }; // eslint-disable-next-line no-warning-comments -// TODO: break this function up into smaller functions +// TODO: Break this function up into smaller functions. // eslint-disable-next-line max-lines-per-function,max-statements onmessage = async (ev: MessageEvent) => { const {code, args} = ev.data; From 0744f99c99b4fd5122323c28f6e988770517acb4 Mon Sep 17 00:00:00 2001 From: Kirk Rodrigues <2454684+kirkrodrigues@users.noreply.github.com> Date: Wed, 18 Sep 2024 23:35:25 -0400 Subject: [PATCH 16/25] loadChunk: Refactor docstring and error. --- new-log-viewer/src/services/LogFileManager.ts | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/new-log-viewer/src/services/LogFileManager.ts b/new-log-viewer/src/services/LogFileManager.ts index e27bc051..e32813a9 100644 --- a/new-log-viewer/src/services/LogFileManager.ts +++ b/new-log-viewer/src/services/LogFileManager.ts @@ -154,22 +154,26 @@ class LogFileManager { } /** - * Loads a chunk of log events based on the provided event index. + * Loads log events in the range [`logEventIdx`, `logEventIdx + EXPORT_LOGS_CHUNK_SIZE`) or all + * remaining log events if `EXPORT_LOGS_CHUNK_SIZE` log events aren't available. * - * @param logEventIdx The index of the first event to load. - * @return An object containing the logs as a string. - * @throws {Error} if any error occurs during decode. + * @param logEventIdx + * @return An object containing the log events as a string. + * @throws {Error} if any error occurs when decoding the log events. */ loadChunk (logEventIdx: number): { logs: string, } { + const logEventEndIdx = Math.min(logEventIdx + EXPORT_LOGS_CHUNK_SIZE, this.#numEvents); const results = this.#decoder.decode( logEventIdx, - Math.min(logEventIdx + EXPORT_LOGS_CHUNK_SIZE, this.#numEvents) + logEventEndIdx ); if (null === results) { - throw new Error(`Failed to decode chunk containing logEventIdx=${logEventIdx}`); + throw new Error( + `Failed to decode log events in range [${logEventIdx}, ${logEventEndIdx})` + ); } const messages = results.map(([msg]) => msg); From bc4d46310f3fc8cfaa42fdb06953ed6b6841262d Mon Sep 17 00:00:00 2001 From: Kirk Rodrigues <2454684+kirkrodrigues@users.noreply.github.com> Date: Wed, 18 Sep 2024 23:36:31 -0400 Subject: [PATCH 17/25] StateContextProvider: Group states and refs; Reorder exportProgress state. --- new-log-viewer/src/contexts/StateContextProvider.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/new-log-viewer/src/contexts/StateContextProvider.tsx b/new-log-viewer/src/contexts/StateContextProvider.tsx index 2caf54ed..28322a67 100644 --- a/new-log-viewer/src/contexts/StateContextProvider.tsx +++ b/new-log-viewer/src/contexts/StateContextProvider.tsx @@ -141,18 +141,20 @@ const workerPostReq = ( const StateContextProvider = ({children}: StateContextProviderProps) => { const {filePath, logEventNum} = useContext(UrlContext); + // States const [fileName, setFileName] = useState(STATE_DEFAULT.fileName); - const [exportProgress, setExportProgress] = - useState>(STATE_DEFAULT.exportProgress); const [logData, setLogData] = useState(STATE_DEFAULT.logData); const [numEvents, setNumEvents] = useState(STATE_DEFAULT.numEvents); const beginLineNumToLogEventNumRef = useRef(STATE_DEFAULT.beginLineNumToLogEventNum); + const [exportProgress, setExportProgress] = + useState>(STATE_DEFAULT.exportProgress); + + // Refs const logEventNumRef = useRef(logEventNum); const numPagesRef = useRef(STATE_DEFAULT.numPages); const pageNumRef = useRef>(STATE_DEFAULT.pageNum); const logExportManagerRef = useRef(null); - const mainWorkerRef = useRef(null); const handleMainWorkerResp = useCallback((ev: MessageEvent) => { From 6b51ef9963d83f7965cce2f3cf335f19c0d14b64 Mon Sep 17 00:00:00 2001 From: Kirk Rodrigues <2454684+kirkrodrigues@users.noreply.github.com> Date: Wed, 18 Sep 2024 23:37:06 -0400 Subject: [PATCH 18/25] Clear export progress when a new file is loaded. --- new-log-viewer/src/contexts/StateContextProvider.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/new-log-viewer/src/contexts/StateContextProvider.tsx b/new-log-viewer/src/contexts/StateContextProvider.tsx index 28322a67..335f0af6 100644 --- a/new-log-viewer/src/contexts/StateContextProvider.tsx +++ b/new-log-viewer/src/contexts/StateContextProvider.tsx @@ -170,6 +170,7 @@ const StateContextProvider = ({children}: StateContextProviderProps) => { case WORKER_RESP_CODE.LOG_FILE_INFO: setFileName(args.fileName); setNumEvents(args.numEvents); + setExportProgress(STATE_DEFAULT.exportProgress); break; case WORKER_RESP_CODE.NOTIFICATION: // eslint-disable-next-line no-warning-comments From 5e5d24dad3c157df0da7390f6d63e8a86eec83f5 Mon Sep 17 00:00:00 2001 From: Kirk Rodrigues <2454684+kirkrodrigues@users.noreply.github.com> Date: Thu, 19 Sep 2024 13:04:57 -0400 Subject: [PATCH 19/25] loadChunk: Apply renaming suggestions from review. --- new-log-viewer/src/services/LogFileManager.ts | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/new-log-viewer/src/services/LogFileManager.ts b/new-log-viewer/src/services/LogFileManager.ts index e32813a9..2ceded83 100644 --- a/new-log-viewer/src/services/LogFileManager.ts +++ b/new-log-viewer/src/services/LogFileManager.ts @@ -154,25 +154,26 @@ class LogFileManager { } /** - * Loads log events in the range [`logEventIdx`, `logEventIdx + EXPORT_LOGS_CHUNK_SIZE`) or all - * remaining log events if `EXPORT_LOGS_CHUNK_SIZE` log events aren't available. + * Loads log events in the range + * [`beginLogEventIdx`, `beginLogEventIdx + EXPORT_LOGS_CHUNK_SIZE`), or all remaining log + * events if `EXPORT_LOGS_CHUNK_SIZE` log events aren't available. * - * @param logEventIdx + * @param beginLogEventIdx * @return An object containing the log events as a string. * @throws {Error} if any error occurs when decoding the log events. */ - loadChunk (logEventIdx: number): { + loadChunk (beginLogEventIdx: number): { logs: string, } { - const logEventEndIdx = Math.min(logEventIdx + EXPORT_LOGS_CHUNK_SIZE, this.#numEvents); + const endLogEventIdx = Math.min(beginLogEventIdx + EXPORT_LOGS_CHUNK_SIZE, this.#numEvents); const results = this.#decoder.decode( - logEventIdx, - logEventEndIdx + beginLogEventIdx, + endLogEventIdx ); if (null === results) { throw new Error( - `Failed to decode log events in range [${logEventIdx}, ${logEventEndIdx})` + `Failed to decode log events in range [${beginLogEventIdx}, ${endLogEventIdx})` ); } From 73bd8faae9ad9a9b2d317c32ef54b16671329c76 Mon Sep 17 00:00:00 2001 From: Henry <50559854+Henry8192@users.noreply.github.com> Date: Thu, 19 Sep 2024 13:10:05 -0400 Subject: [PATCH 20/25] Address suggestions from code review --- new-log-viewer/src/components/MenuBar/ExportLogsButton.tsx | 3 +++ new-log-viewer/src/contexts/StateContextProvider.tsx | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/new-log-viewer/src/components/MenuBar/ExportLogsButton.tsx b/new-log-viewer/src/components/MenuBar/ExportLogsButton.tsx index 2f702c04..07327779 100644 --- a/new-log-viewer/src/components/MenuBar/ExportLogsButton.tsx +++ b/new-log-viewer/src/components/MenuBar/ExportLogsButton.tsx @@ -26,6 +26,9 @@ const ExportLogsButton = () => { return ( { return; } + setExportProgress(EXPORT_LOG_PROGRESS_VALUE_MIN); logExportManagerRef.current = new LogExportManager( Math.ceil(numEvents / EXPORT_LOGS_CHUNK_SIZE), fileName From c34ed9b9d322e2969b858e96c700a71353318a0f Mon Sep 17 00:00:00 2001 From: Henry <50559854+Henry8192@users.noreply.github.com> Date: Thu, 19 Sep 2024 13:23:35 -0400 Subject: [PATCH 21/25] suppress todo warnings --- new-log-viewer/src/components/MenuBar/ExportLogsButton.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/new-log-viewer/src/components/MenuBar/ExportLogsButton.tsx b/new-log-viewer/src/components/MenuBar/ExportLogsButton.tsx index 07327779..65f2cfd1 100644 --- a/new-log-viewer/src/components/MenuBar/ExportLogsButton.tsx +++ b/new-log-viewer/src/components/MenuBar/ExportLogsButton.tsx @@ -27,6 +27,7 @@ const ExportLogsButton = () => { Date: Thu, 19 Sep 2024 15:31:15 -0400 Subject: [PATCH 22/25] Use EXPORT_LOGS_PROGRESS_VALUE_MIN instead of STATE_DEFAULT.exportProgress. --- new-log-viewer/src/contexts/StateContextProvider.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/new-log-viewer/src/contexts/StateContextProvider.tsx b/new-log-viewer/src/contexts/StateContextProvider.tsx index b2a2893b..1b0d0727 100644 --- a/new-log-viewer/src/contexts/StateContextProvider.tsx +++ b/new-log-viewer/src/contexts/StateContextProvider.tsx @@ -170,7 +170,7 @@ const StateContextProvider = ({children}: StateContextProviderProps) => { case WORKER_RESP_CODE.LOG_FILE_INFO: setFileName(args.fileName); setNumEvents(args.numEvents); - setExportProgress(STATE_DEFAULT.exportProgress); + setExportProgress(EXPORT_LOG_PROGRESS_VALUE_MIN); break; case WORKER_RESP_CODE.NOTIFICATION: // eslint-disable-next-line no-warning-comments From 623b9ed21a1a06b26045c4f14e00e54e3e87b24d Mon Sep 17 00:00:00 2001 From: Kirk Rodrigues <2454684+kirkrodrigues@users.noreply.github.com> Date: Thu, 19 Sep 2024 15:37:51 -0400 Subject: [PATCH 23/25] Edit TODO about empty fileName check. --- new-log-viewer/src/components/MenuBar/ExportLogsButton.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/new-log-viewer/src/components/MenuBar/ExportLogsButton.tsx b/new-log-viewer/src/components/MenuBar/ExportLogsButton.tsx index 65f2cfd1..5d998e8d 100644 --- a/new-log-viewer/src/components/MenuBar/ExportLogsButton.tsx +++ b/new-log-viewer/src/components/MenuBar/ExportLogsButton.tsx @@ -26,10 +26,9 @@ const ExportLogsButton = () => { return ( Date: Fri, 20 Sep 2024 15:55:50 -0400 Subject: [PATCH 24/25] Revert "Use EXPORT_LOGS_PROGRESS_VALUE_MIN instead of STATE_DEFAULT.exportProgress." This reverts commit 1e99e07337bd04550d2966151b1d49e2613ff3d4. --- new-log-viewer/src/contexts/StateContextProvider.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/new-log-viewer/src/contexts/StateContextProvider.tsx b/new-log-viewer/src/contexts/StateContextProvider.tsx index 1b0d0727..b2a2893b 100644 --- a/new-log-viewer/src/contexts/StateContextProvider.tsx +++ b/new-log-viewer/src/contexts/StateContextProvider.tsx @@ -170,7 +170,7 @@ const StateContextProvider = ({children}: StateContextProviderProps) => { case WORKER_RESP_CODE.LOG_FILE_INFO: setFileName(args.fileName); setNumEvents(args.numEvents); - setExportProgress(EXPORT_LOG_PROGRESS_VALUE_MIN); + setExportProgress(STATE_DEFAULT.exportProgress); break; case WORKER_RESP_CODE.NOTIFICATION: // eslint-disable-next-line no-warning-comments From f1699d628c9ababe659e47d90c38054b92a16108 Mon Sep 17 00:00:00 2001 From: Kirk Rodrigues <2454684+kirkrodrigues@users.noreply.github.com> Date: Fri, 20 Sep 2024 16:03:28 -0400 Subject: [PATCH 25/25] Reset export progress before loading file. --- new-log-viewer/src/contexts/StateContextProvider.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/new-log-viewer/src/contexts/StateContextProvider.tsx b/new-log-viewer/src/contexts/StateContextProvider.tsx index b2a2893b..c6e07803 100644 --- a/new-log-viewer/src/contexts/StateContextProvider.tsx +++ b/new-log-viewer/src/contexts/StateContextProvider.tsx @@ -170,7 +170,6 @@ const StateContextProvider = ({children}: StateContextProviderProps) => { case WORKER_RESP_CODE.LOG_FILE_INFO: setFileName(args.fileName); setNumEvents(args.numEvents); - setExportProgress(STATE_DEFAULT.exportProgress); break; case WORKER_RESP_CODE.NOTIFICATION: // eslint-disable-next-line no-warning-comments @@ -235,6 +234,8 @@ const StateContextProvider = ({children}: StateContextProviderProps) => { cursor: cursor, decoderOptions: getConfig(CONFIG_KEY.DECODER_OPTIONS), }); + + setExportProgress(STATE_DEFAULT.exportProgress); }, [ handleMainWorkerResp, ]);