Skip to content

feat: Add toggle for log message prettification (resolves #220). #223

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

Merged
merged 16 commits into from
Apr 11, 2025

Conversation

zzxthehappiest
Copy link
Contributor

@zzxthehappiest zzxthehappiest commented Apr 2, 2025

Description

This PR is to implement the first sub task as discussed in #220 . I implemented the following things per the discussion:

  • Use js-beautify to format the log messages (will switch to our own solution soon).
  • Provide the UI and URL interfaces for enabling this feature.
  • Compatible with loading new log file, setting log level filters and changing pages feature.

Checklist

  • The PR satisfies the contribution guidelines.
  • This is a breaking change and that has been indicated in the PR title, OR this isn't a
    breaking change.
  • Necessary docs have been updated, OR no docs need to be updated.

Validation performed

Since I can think of a lot of cases, here I only manually test for critical functionalities:

  1. Use a log file contains 10000 log messages from logger.info("some message {123} someFunc(123,123) {return 1;}") and a couple of messages of other log levels to test compatibility with log level filter. After loading file, click the prettify button, all log messages in the current page are formated.
  2. Click first page, last page, previous page etc., all log messages in each page are still formatted.
  3. Click the prettify button again, repeat the 1~2, all log messages in each page are not formatted.
  4. Select a log level filter, repeat 1~3, it also works as the same.
  5. Check before and after clicking the prettify button, if the URL appends the isPrettified= parameter.
  6. Directly change the URL by appending the isPrettified= parameter and toggle it in the URL, repeat 1~4, it also works as the same.
  7. After changing the URL and pressing enter key, the prettify button's icon changes to correct one.
  8. With the isPrettified set to true in the current URL, load a new log file, the log messages will be prettified. And if isPrettified is not set or is false, then the loaded new file will not be prettified.

Summary by CodeRabbit

  • Documentation

    • Updated the manual testing guide to include verification for the new formatting toggle.
  • New Features

    • Introduced a new toggle button in the status bar for enabling enhanced content and log formatting.
    • Added a keyboard shortcut (Alt+Shift+F) to quickly switch the formatting view.
    • Improved overall readability by applying consistent formatting across logs and interface elements.

@zzxthehappiest zzxthehappiest requested a review from a team as a code owner April 2, 2025 03:17
Copy link

coderabbitai bot commented Apr 2, 2025

Walkthrough

This pull request implements a new "prettify" toggle feature across the application. Documentation is updated with manual testing instructions, and dependencies for code formatting (js-beautify) are added. Multiple components now accept an isPrettified flag to control log message formatting. The change propagates this state via URL hash parameters, context providers, and worker requests. Additionally, UI components such as the editor, menu bar, and status bar have been updated to support the new toggle action.

Changes

File(s) Change Summary
docs/src/dev-guide/contributing-validation.md, package.json Updated documentation to include manual testing for toggling "Prettify" and added dependencies: @types/js-beautify and js-beautify.
src/components/Editor/index.tsx, src/utils/actions.ts In the editor: enforced ESLint rules, integrated isPrettified from URL context, added new TOGGLE_PRETTIFY action in handleEditorCustomAction, and added corresponding enum/action configuration.
src/contexts/StateContextProvider.tsx, src/contexts/UrlContextProvider.tsx, src/services/LogFileManager/index.ts, src/services/MainWorker.ts Updated context providers and services: adjusted ESLint max-lines rule, updated function signatures (e.g. loadPageByCursor, filterLogs) to accept isPrettified, introduced URL hash parameter handling for prettification, and modified worker calls to pass the new flag with conditional log formatting.
src/components/MenuBar/NavigationBar.tsx, src/components/MenuBar/ExportLogsButton.tsx, src/components/MenuBar/MenuBarIconButton.tsx Standardised tooltip properties: reformatted destructuring in NavigationBar, renamed parameters (e.g. event to ev), and replaced title with tooltipTitle in MenuBar button components.
src/components/StatusBar/StatusBarToggleButton.tsx, src/components/StatusBar/index.tsx Added a new status bar toggle component and integrated it into the StatusBar. The toggle button uses new icons and triggers a handler to update URL hash parameters based on the toggled isPrettified state.
src/typings/url.ts, src/typings/worker.ts, src/typings/states.ts Updated type definitions: added IS_PRETTIFIED to the URL hash enum and interface, appended isPrettified to relevant worker request types, and introduced PRETTIFY_BUTTON into the UI state grid to control the new UI element state.

Sequence Diagram(s)

sequenceDiagram
    participant U as User
    participant SB as StatusBarToggleButton
    participant S as StatusBar Component
    participant UC as UrlContextProvider
    participant SC as StateContextProvider
    participant MW as MainWorker
    participant LFM as LogFileManager

    U->>SB: Click toggle button
    SB->>S: Trigger handleStatusButtonClick event
    S->>UC: Update URL hash with isPrettified state
    UC-->>SC: Propagate new isPrettified value
    SC->>MW: Call loadPage(cursor, isPrettified)
    MW->>LFM: Process loadPage with isPrettified flag
Loading

Possibly related issues

Possibly related PRs

Suggested reviewers

  • junhaoliao
  • davemarco

Tip

⚡💬 Agentic Chat (Pro Plan, General Availability)
  • We're introducing multi-step agentic chat in review comments and issue comments, within and outside of PR's. This feature enhances review and issue discussions with the CodeRabbit agentic chat by enabling advanced interactions, including the ability to create pull requests directly from comments and add commits to existing pull requests.

📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c8b0e79 and 70f1cd4.

📒 Files selected for processing (4)
  • src/components/Editor/index.tsx (5 hunks)
  • src/contexts/StateContextProvider.tsx (10 hunks)
  • src/contexts/UrlContextProvider.tsx (2 hunks)
  • src/typings/url.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/contexts/UrlContextProvider.tsx
  • src/components/Editor/index.tsx
  • src/typings/url.ts
  • src/contexts/StateContextProvider.tsx

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (8)
src/components/MenuBar/NavigationBar.tsx (2)

1-18: Fix import formatting issues

The imports have multiple formatting issues flagged by the static analysis tools:

  • The MUI icons should use path imports and be named with "Icon" postfix
  • Multiple elements in a single import should be broken into multiple lines
  • Object curly spacing issues

Apply these changes to fix the formatting:

-import React, { useContext } from "react";
+import React from "react";
+import {useContext} from "react";

-import { ButtonGroup } from "@mui/joy";
+import {ButtonGroup} from "@mui/joy";

-import { AutoFixHighRounded, AutoFixOffRounded } from "@mui/icons-material";
+import AutoFixHighRoundedIcon from "@mui/icons-material/AutoFixHighRounded";
+import AutoFixOffRoundedIcon from "@mui/icons-material/AutoFixOffRounded";
 import NavigateBefore from "@mui/icons-material/NavigateBefore";
 import NavigateNext from "@mui/icons-material/NavigateNext";
 import SkipNext from "@mui/icons-material/SkipNext";
 import SkipPrevious from "@mui/icons-material/SkipPrevious";

-import { StateContext } from "../../contexts/StateContextProvider";
-import { UI_ELEMENT } from "../../typings/states";
-import { ACTION_NAME } from "../../utils/actions";
-import { ignorePointerIfFastLoading, isDisabled } from "../../utils/states";
+import {StateContext} from "../../contexts/StateContextProvider";
+import {UI_ELEMENT} from "../../typings/states";
+import {ACTION_NAME} from "../../utils/actions";
+import {
+    ignorePointerIfFastLoading,
+    isDisabled
+} from "../../utils/states";
 import MenuBarIconButton from "./MenuBarIconButton";
 import MenuBarToggleButton from "./MenuBarToggleButton";
 import PageNumInput from "./PageNumInput";
-import { UrlContext } from "../../contexts/UrlContextProvider";
+import {UrlContext} from "../../contexts/UrlContextProvider";
🧰 Tools
🪛 ESLint

[error] 1-1: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 1-1: There should be no space before '}'.

(@stylistic/object-curly-spacing)


[error] 3-3: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 3-3: There should be no space before '}'.

(@stylistic/object-curly-spacing)


[error] 5-5: '@mui/icons-material' import is restricted from being used. Please use path imports and name your imports with postfix "Icon" to avoid confusions.

(no-restricted-imports)


[error] 5-5: Imports must be broken into multiple lines if there are more than 1 elements.

(import-newlines/enforce)


[error] 5-5: Expected a line break after this opening brace.

(@stylistic/object-curly-newline)


[error] 5-5: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 5-5: There should be no space before '}'.

(@stylistic/object-curly-spacing)


[error] 5-5: Expected a line break before this closing brace.

(@stylistic/object-curly-newline)


[error] 11-11: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 11-11: There should be no space before '}'.

(@stylistic/object-curly-spacing)


[error] 12-12: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 12-12: There should be no space before '}'.

(@stylistic/object-curly-spacing)


[error] 13-13: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 13-13: There should be no space before '}'.

(@stylistic/object-curly-spacing)


[error] 14-14: Imports must be broken into multiple lines if there are more than 1 elements.

(import-newlines/enforce)


[error] 14-14: Expected a line break after this opening brace.

(@stylistic/object-curly-newline)


[error] 14-14: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 14-14: There should be no space before '}'.

(@stylistic/object-curly-spacing)


[error] 14-14: Expected a line break before this closing brace.

(@stylistic/object-curly-newline)


[error] 18-18: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 18-18: There should be no space before '}'.

(@stylistic/object-curly-spacing)


56-63: Fix formatting issues in MenuBarToggleButton props

The props have several formatting issues that should be fixed:

  • Ternary expressions should be multiline for better readability
  • Props should be sorted alphabetically
  • Callbacks should be listed after other props
  • The closing bracket placement needs adjustment

Apply these changes to fix the formatting:

 <MenuBarToggleButton
-    data-action-name={isPrettified ?? false ? ACTION_NAME.PRETTIFY_OFF : ACTION_NAME.PRETTIFY_ON}
-    title={isPrettified ?? false ? "Prettify Off" : "Prettify On"}
-    isActive={!(isPrettified ?? false)}
-    onIcon={<AutoFixHighRounded />}
-    offIcon={<AutoFixOffRounded />}
-    onClick={handleNavButtonClick}
+    data-action-name={isPrettified ?? false 
+        ? ACTION_NAME.PRETTIFY_OFF 
+        : ACTION_NAME.PRETTIFY_ON
+    }
+    isActive={!(isPrettified ?? false)}
+    offIcon={<AutoFixOffRoundedIcon />}
+    onIcon={<AutoFixHighRoundedIcon />}
+    title={isPrettified ?? false 
+        ? "Prettify Off" 
+        : "Prettify On"
+    }
+    onClick={handleNavButtonClick}
 />
🧰 Tools
🪛 ESLint

[error] 57-57: Expected newline between test and consequent of ternary expression.

(@stylistic/multiline-ternary)


[error] 57-57: Expected newline between consequent and alternate of ternary expression.

(@stylistic/multiline-ternary)


[error] 58-58: Expected newline between test and consequent of ternary expression.

(@stylistic/multiline-ternary)


[error] 58-58: Expected newline between consequent and alternate of ternary expression.

(@stylistic/multiline-ternary)


[error] 59-59: Props should be sorted alphabetically

(@stylistic/jsx-sort-props)


[error] 60-60: Callbacks must be listed after all other props

(@stylistic/jsx-sort-props)


[error] 60-60: A space is forbidden before closing bracket

(@stylistic/jsx-tag-spacing)


[error] 61-61: A space is forbidden before closing bracket

(@stylistic/jsx-tag-spacing)


[error] 62-62: Props should be sorted alphabetically

(@stylistic/jsx-sort-props)


[error] 63-63: The closing bracket must be placed after the last prop

(@stylistic/jsx-closing-bracket-location)

src/components/StatusBar/LogLevelSelect/index.tsx (2)

47-47: Fix import formatting to comply with project standards.

The import has spacing issues that are causing linting errors.

-import { UrlContext } from "../../../contexts/UrlContextProvider";
+import {UrlContext} from "../../../contexts/UrlContextProvider";
🧰 Tools
🪛 ESLint

[error] 47-47: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 47-47: There should be no space before '}'.

(@stylistic/object-curly-spacing)


157-160: Consider combining context hooks for consistency.

You've added a separate useContext call for the UrlContext. Consider combining related context hooks or maintaining a consistent pattern for retrieving context values.

-const {isPrettified} = useContext(UrlContext);
-const [selectedLogLevels, setSelectedLogLevels] = useState<LOG_LEVEL[]>([]);
-const {uiState, filterLogs} = useContext(StateContext);
+const [selectedLogLevels, setSelectedLogLevels] = useState<LOG_LEVEL[]>([]);
+const {isPrettified} = useContext(UrlContext);
+const {uiState, filterLogs} = useContext(StateContext);

or

-const {isPrettified} = useContext(UrlContext);
-const [selectedLogLevels, setSelectedLogLevels] = useState<LOG_LEVEL[]>([]);
-const {uiState, filterLogs} = useContext(StateContext);
+const [selectedLogLevels, setSelectedLogLevels] = useState<LOG_LEVEL[]>([]);
+const {
+    isPrettified,
+} = useContext(UrlContext);
+const {
+    uiState, 
+    filterLogs,
+} = useContext(StateContext);
src/components/MenuBar/MenuBarToggleButton.tsx (1)

1-50: Apply consistent false == expression pattern per coding guidelines.

According to the provided coding guidelines, the codebase should prefer false == <expression> rather than !<expression>.

Consider updating the conditional check in the component to follow this pattern:

-    {isActive ? onIcon : offIcon}
+    {false == isActive ? offIcon : onIcon}
🧰 Tools
🪛 ESLint

[error] 7-7: '@mui/icons-material' import is restricted from being used. Please use path imports and name your imports with postfix "Icon" to avoid confusions.

(no-restricted-imports)


[error] 7-7: Imports must be broken into multiple lines if there are more than 1 elements.

(import-newlines/enforce)


[error] 7-7: Expected 2 empty lines after import statement not followed by another import.

(import/newline-after-import)


[error] 7-7: Expected a line break after this opening brace.

(@stylistic/object-curly-newline)


[error] 7-7: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 7-7: There should be no space before '}'.

(@stylistic/object-curly-spacing)


[error] 7-7: Expected a line break before this closing brace.

(@stylistic/object-curly-newline)


[error] 28-28: Expected indentation of 4 spaces but found 33.

(@stylistic/indent)


[error] 29-29: Expected indentation of 4 spaces but found 33.

(@stylistic/indent)


[error] 30-30: Expected indentation of 4 spaces but found 33.

(@stylistic/indent)


[error] 31-31: Expected indentation of 4 spaces but found 33.

(@stylistic/indent)


[error] 31-31: A space is forbidden before closing bracket

(@stylistic/jsx-tag-spacing)


[error] 31-31: Unexpected comment inline with code.

(no-inline-comments)


[error] 31-31: Expected comment to be above code.

(@stylistic/line-comment-position)


[error] 32-32: Expected indentation of 4 spaces but found 33.

(@stylistic/indent)


[error] 32-32: A space is forbidden before closing bracket

(@stylistic/jsx-tag-spacing)


[error] 32-32: Unexpected comment inline with code.

(no-inline-comments)


[error] 32-32: Expected comment to be above code.

(@stylistic/line-comment-position)


[error] 33-33: Expected indentation of 4 spaces but found 33.

(@stylistic/indent)


[error] 34-34: Expected indentation of 0 spaces but found 29.

(@stylistic/indent)


[error] 34-36: Block must not be padded by blank lines.

(@stylistic/padded-blocks)


[error] 37-37: Prop title must be placed on a new line

(@stylistic/jsx-max-props-per-line)


[error] 40-40: Need to wrap this literal in a JSX expression.

(@stylistic/jsx-curly-brace-presence)


[error] 43-43: Expected newline between test and consequent of ternary expression.

(@stylistic/multiline-ternary)


[error] 43-43: Expected newline between consequent and alternate of ternary expression.

(@stylistic/multiline-ternary)

src/services/LogFileManager/index.ts (2)

39-39: Fix styling issues with the import statement.

The import statement for js_beautify has several style issues:

  • Expected 2 empty lines after the import (not followed by another import)
  • Identifier js_beautify is not in camelCase
-import js_beautify from "js-beautify";
+import jsBeautify from "js-beautify";

🧰 Tools
🪛 ESLint

[error] 39-39: Expected 2 empty lines after import statement not followed by another import.

(import/newline-after-import)


[error] 39-39: Identifier 'js_beautify' is not in camel case.

(camelcase)


289-290: Refactor the ternary expression for better readability.

The ternary expression has several style issues flagged by static analysis:

  • Expected newlines between test, consequent, and alternate
  • String concatenation should use template literals
-            const printedMsg = (isPrettified) ? js_beautify(msg) + "\n" : msg;
+            const printedMsg = (false === isPrettified) 
+                ? msg 
+                : `${jsBeautify(msg)}\n`;

Note: Changed the condition to follow the coding guideline of preferring false === <expression> rather than !<expression> and inverted the logic to make it more readable.

🧰 Tools
🪛 ESLint

[error] 289-289: Expected newline between test and consequent of ternary expression.

(@stylistic/multiline-ternary)


[error] 289-289: Expected newline between consequent and alternate of ternary expression.

(@stylistic/multiline-ternary)


[error] 289-289: Unexpected string concatenation.

(prefer-template)

src/contexts/StateContextProvider.tsx (1)

331-331: Conditional check style recommendation

According to the coding guidelines, false == <expression> is preferred over !<expression>.

Replace false === v.has(queryPageNum) with v.has(queryPageNum) == false to align with the project's coding guidelines.

-                        if (false === v.has(queryPageNum)) {
+                        if (v.has(queryPageNum) == false) {
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 24ed721 and b5c118e.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (13)
  • docs/src/dev-guide/contributing-validation.md (1 hunks)
  • package.json (2 hunks)
  • src/components/Editor/index.tsx (2 hunks)
  • src/components/MenuBar/MenuBarToggleButton.tsx (1 hunks)
  • src/components/MenuBar/NavigationBar.tsx (3 hunks)
  • src/components/StatusBar/LogLevelSelect/index.tsx (3 hunks)
  • src/contexts/StateContextProvider.tsx (10 hunks)
  • src/contexts/UrlContextProvider.tsx (2 hunks)
  • src/services/LogFileManager/index.ts (3 hunks)
  • src/services/MainWorker.ts (3 hunks)
  • src/typings/url.ts (1 hunks)
  • src/typings/worker.ts (1 hunks)
  • src/utils/actions.ts (3 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.{cpp,hpp,java,js,jsx,tpp,ts,tsx}`: - Prefer `false == ` rather than `!`.

**/*.{cpp,hpp,java,js,jsx,tpp,ts,tsx}: - Prefer false == <expression> rather than !<expression>.

  • src/components/Editor/index.tsx
  • src/typings/worker.ts
  • src/contexts/UrlContextProvider.tsx
  • src/components/StatusBar/LogLevelSelect/index.tsx
  • src/services/LogFileManager/index.ts
  • src/typings/url.ts
  • src/components/MenuBar/MenuBarToggleButton.tsx
  • src/utils/actions.ts
  • src/components/MenuBar/NavigationBar.tsx
  • src/services/MainWorker.ts
  • src/contexts/StateContextProvider.tsx
🧬 Code Definitions (5)
src/components/Editor/index.tsx (1)
src/utils/actions.ts (1)
  • ACTION_NAME (115-115)
src/contexts/UrlContextProvider.tsx (1)
src/typings/url.ts (1)
  • HASH_PARAM_NAMES (37-37)
src/components/StatusBar/LogLevelSelect/index.tsx (2)
src/contexts/UrlContextProvider.tsx (1)
  • UrlContext (280-280)
src/contexts/StateContextProvider.tsx (1)
  • StateContext (598-598)
src/components/MenuBar/NavigationBar.tsx (3)
src/contexts/StateContextProvider.tsx (1)
  • StateContext (598-598)
src/contexts/UrlContextProvider.tsx (1)
  • UrlContext (280-280)
src/utils/actions.ts (1)
  • ACTION_NAME (115-115)
src/contexts/StateContextProvider.tsx (6)
src/typings/states.ts (1)
  • UI_STATE (101-101)
src/typings/logs.ts (1)
  • LogLevelFilter (51-51)
src/utils/actions.ts (1)
  • ACTION_NAME (115-115)
src/typings/worker.ts (4)
  • EVENT_POSITION_ON_PAGE (189-189)
  • CursorType (196-196)
  • WORKER_REQ_CODE (190-190)
  • CURSOR_CODE (187-187)
src/contexts/UrlContextProvider.tsx (1)
  • UrlContext (280-280)
src/typings/url.ts (1)
  • HASH_PARAM_NAMES (37-37)
🪛 ESLint
src/components/Editor/index.tsx

[error] 1-1: Imports must be broken into multiple lines if there are more than 1 elements.

(import-newlines/enforce)


[error] 1-1: Expected a line break after this opening brace.

(@stylistic/object-curly-newline)


[error] 1-1: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 1-1: There should be no space before '}'.

(@stylistic/object-curly-spacing)


[error] 1-1: Expected a line break before this closing brace.

(@stylistic/object-curly-newline)


[error] 3-3: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 3-3: There should be no space before '}'.

(@stylistic/object-curly-spacing)


[error] 6-6: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 6-6: There should be no space before '}'.

(@stylistic/object-curly-spacing)


[error] 7-7: Imports must be broken into multiple lines if there are more than 1 elements.

(import-newlines/enforce)


[error] 7-7: Expected a line break after this opening brace.

(@stylistic/object-curly-newline)


[error] 7-7: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 7-7: There should be no space before '}'.

(@stylistic/object-curly-spacing)


[error] 7-7: Expected a line break before this closing brace.

(@stylistic/object-curly-newline)


[error] 8-8: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 8-8: There should be no space before '}'.

(@stylistic/object-curly-spacing)


[error] 9-9: Imports must be broken into multiple lines if there are more than 1 elements.

(import-newlines/enforce)


[error] 9-9: Expected a line break after this opening brace.

(@stylistic/object-curly-newline)


[error] 9-9: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 9-9: There should be no space before '}'.

(@stylistic/object-curly-spacing)


[error] 9-9: Expected a line break before this closing brace.

(@stylistic/object-curly-newline)


[error] 10-10: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 10-10: There should be no space before '}'.

(@stylistic/object-curly-spacing)


[error] 11-11: Imports must be broken into multiple lines if there are more than 1 elements.

(import-newlines/enforce)


[error] 11-11: Expected a line break after this opening brace.

(@stylistic/object-curly-newline)


[error] 11-11: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 11-11: There should be no space before '}'.

(@stylistic/object-curly-spacing)


[error] 11-11: Expected a line break before this closing brace.

(@stylistic/object-curly-newline)


[error] 12-12: Imports must be broken into multiple lines if there are more than 1 elements.

(import-newlines/enforce)


[error] 12-12: Expected a line break after this opening brace.

(@stylistic/object-curly-newline)


[error] 12-12: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 12-12: There should be no space before '}'.

(@stylistic/object-curly-spacing)


[error] 12-12: Expected a line break before this closing brace.

(@stylistic/object-curly-newline)


[error] 13-13: Imports must be broken into multiple lines if there are more than 1 elements.

(import-newlines/enforce)


[error] 13-13: Expected a line break after this opening brace.

(@stylistic/object-curly-newline)


[error] 13-13: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 13-13: There should be no space before '}'.

(@stylistic/object-curly-spacing)


[error] 13-13: Expected a line break before this closing brace.

(@stylistic/object-curly-newline)


[error] 15-15: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 15-15: There should be no space before '}'.

(@stylistic/object-curly-spacing)

src/components/StatusBar/LogLevelSelect/index.tsx

[error] 47-47: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 47-47: There should be no space before '}'.

(@stylistic/object-curly-spacing)

src/services/LogFileManager/index.ts

[error] 39-39: Expected 2 empty lines after import statement not followed by another import.

(import/newline-after-import)


[error] 39-39: Identifier 'js_beautify' is not in camel case.

(camelcase)


[error] 289-289: Expected newline between test and consequent of ternary expression.

(@stylistic/multiline-ternary)


[error] 289-289: Expected newline between consequent and alternate of ternary expression.

(@stylistic/multiline-ternary)


[error] 289-289: Unexpected string concatenation.

(prefer-template)

src/components/MenuBar/MenuBarToggleButton.tsx

[error] 7-7: '@mui/icons-material' import is restricted from being used. Please use path imports and name your imports with postfix "Icon" to avoid confusions.

(no-restricted-imports)


[error] 7-7: Imports must be broken into multiple lines if there are more than 1 elements.

(import-newlines/enforce)


[error] 7-7: Expected 2 empty lines after import statement not followed by another import.

(import/newline-after-import)


[error] 7-7: Expected a line break after this opening brace.

(@stylistic/object-curly-newline)


[error] 7-7: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 7-7: There should be no space before '}'.

(@stylistic/object-curly-spacing)


[error] 7-7: Expected a line break before this closing brace.

(@stylistic/object-curly-newline)


[error] 28-28: Expected indentation of 4 spaces but found 33.

(@stylistic/indent)


[error] 29-29: Expected indentation of 4 spaces but found 33.

(@stylistic/indent)


[error] 30-30: Expected indentation of 4 spaces but found 33.

(@stylistic/indent)


[error] 31-31: Expected indentation of 4 spaces but found 33.

(@stylistic/indent)


[error] 31-31: A space is forbidden before closing bracket

(@stylistic/jsx-tag-spacing)


[error] 31-31: Unexpected comment inline with code.

(no-inline-comments)


[error] 31-31: Expected comment to be above code.

(@stylistic/line-comment-position)


[error] 32-32: Expected indentation of 4 spaces but found 33.

(@stylistic/indent)


[error] 32-32: A space is forbidden before closing bracket

(@stylistic/jsx-tag-spacing)


[error] 32-32: Unexpected comment inline with code.

(no-inline-comments)


[error] 32-32: Expected comment to be above code.

(@stylistic/line-comment-position)


[error] 33-33: Expected indentation of 4 spaces but found 33.

(@stylistic/indent)


[error] 34-34: Expected indentation of 0 spaces but found 29.

(@stylistic/indent)


[error] 34-36: Block must not be padded by blank lines.

(@stylistic/padded-blocks)


[error] 37-37: Prop title must be placed on a new line

(@stylistic/jsx-max-props-per-line)


[error] 40-40: Need to wrap this literal in a JSX expression.

(@stylistic/jsx-curly-brace-presence)


[error] 43-43: Expected newline between test and consequent of ternary expression.

(@stylistic/multiline-ternary)


[error] 43-43: Expected newline between consequent and alternate of ternary expression.

(@stylistic/multiline-ternary)

src/components/MenuBar/NavigationBar.tsx

[error] 1-1: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 1-1: There should be no space before '}'.

(@stylistic/object-curly-spacing)


[error] 3-3: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 3-3: There should be no space before '}'.

(@stylistic/object-curly-spacing)


[error] 5-5: '@mui/icons-material' import is restricted from being used. Please use path imports and name your imports with postfix "Icon" to avoid confusions.

(no-restricted-imports)


[error] 5-5: Imports must be broken into multiple lines if there are more than 1 elements.

(import-newlines/enforce)


[error] 5-5: Expected a line break after this opening brace.

(@stylistic/object-curly-newline)


[error] 5-5: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 5-5: There should be no space before '}'.

(@stylistic/object-curly-spacing)


[error] 5-5: Expected a line break before this closing brace.

(@stylistic/object-curly-newline)


[error] 11-11: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 11-11: There should be no space before '}'.

(@stylistic/object-curly-spacing)


[error] 12-12: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 12-12: There should be no space before '}'.

(@stylistic/object-curly-spacing)


[error] 13-13: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 13-13: There should be no space before '}'.

(@stylistic/object-curly-spacing)


[error] 14-14: Imports must be broken into multiple lines if there are more than 1 elements.

(import-newlines/enforce)


[error] 14-14: Expected a line break after this opening brace.

(@stylistic/object-curly-newline)


[error] 14-14: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 14-14: There should be no space before '}'.

(@stylistic/object-curly-spacing)


[error] 14-14: Expected a line break before this closing brace.

(@stylistic/object-curly-newline)


[error] 18-18: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 18-18: There should be no space before '}'.

(@stylistic/object-curly-spacing)


[error] 57-57: Expected newline between test and consequent of ternary expression.

(@stylistic/multiline-ternary)


[error] 57-57: Expected newline between consequent and alternate of ternary expression.

(@stylistic/multiline-ternary)


[error] 58-58: Expected newline between test and consequent of ternary expression.

(@stylistic/multiline-ternary)


[error] 58-58: Expected newline between consequent and alternate of ternary expression.

(@stylistic/multiline-ternary)


[error] 59-59: Props should be sorted alphabetically

(@stylistic/jsx-sort-props)


[error] 60-60: Callbacks must be listed after all other props

(@stylistic/jsx-sort-props)


[error] 60-60: A space is forbidden before closing bracket

(@stylistic/jsx-tag-spacing)


[error] 61-61: A space is forbidden before closing bracket

(@stylistic/jsx-tag-spacing)


[error] 62-62: Props should be sorted alphabetically

(@stylistic/jsx-sort-props)


[error] 63-63: The closing bracket must be placed after the last prop

(@stylistic/jsx-closing-bracket-location)

src/contexts/StateContextProvider.tsx

[error] 2-2: Imports must be broken into multiple lines if there are more than 1 elements.

(import-newlines/enforce)


[error] 2-2: Expected a line break after this opening brace.

(@stylistic/object-curly-newline)


[error] 2-2: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 2-2: There should be no space before '}'.

(@stylistic/object-curly-spacing)


[error] 2-2: Expected a line break before this closing brace.

(@stylistic/object-curly-newline)


[error] 6-6: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 6-6: There should be no space before '}'.

(@stylistic/object-curly-spacing)


[error] 7-7: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 7-7: There should be no space before '}'.

(@stylistic/object-curly-spacing)


[error] 8-8: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 8-8: There should be no space before '}'.

(@stylistic/object-curly-spacing)


[error] 9-9: Imports must be broken into multiple lines if there are more than 1 elements.

(import-newlines/enforce)


[error] 9-9: Expected a line break after this opening brace.

(@stylistic/object-curly-newline)


[error] 9-9: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 9-9: There should be no space before '}'.

(@stylistic/object-curly-spacing)


[error] 9-9: Expected a line break before this closing brace.

(@stylistic/object-curly-newline)


[error] 10-10: Imports must be broken into multiple lines if there are more than 1 elements.

(import-newlines/enforce)


[error] 10-10: Expected a line break after this opening brace.

(@stylistic/object-curly-newline)


[error] 10-10: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 10-10: There should be no space before '}'.

(@stylistic/object-curly-spacing)


[error] 10-10: Expected a line break before this closing brace.

(@stylistic/object-curly-newline)


[error] 11-11: Imports must be broken into multiple lines if there are more than 1 elements.

(import-newlines/enforce)


[error] 11-11: Expected a line break after this opening brace.

(@stylistic/object-curly-newline)


[error] 11-11: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 11-11: There should be no space before '}'.

(@stylistic/object-curly-spacing)


[error] 11-11: Expected a line break before this closing brace.

(@stylistic/object-curly-newline)


[error] 12-12: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 12-12: There should be no space before '}'.

(@stylistic/object-curly-spacing)


[error] 13-13: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 13-13: There should be no space before '}'.

(@stylistic/object-curly-spacing)


[error] 14-14: Imports must be broken into multiple lines if there are more than 1 elements.

(import-newlines/enforce)


[error] 14-14: Expected a line break after this opening brace.

(@stylistic/object-curly-newline)


[error] 14-14: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 14-14: There should be no space before '}'.

(@stylistic/object-curly-spacing)


[error] 14-14: Expected a line break before this closing brace.

(@stylistic/object-curly-newline)


[error] 26-26: Imports must be broken into multiple lines if there are more than 1 elements.

(import-newlines/enforce)


[error] 26-26: Expected a line break after this opening brace.

(@stylistic/object-curly-newline)


[error] 26-26: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 26-26: There should be no space before '}'.

(@stylistic/object-curly-spacing)


[error] 26-26: Expected a line break before this closing brace.

(@stylistic/object-curly-newline)


[error] 27-27: Imports must be broken into multiple lines if there are more than 1 elements.

(import-newlines/enforce)


[error] 27-27: Expected a line break after this opening brace.

(@stylistic/object-curly-newline)


[error] 27-27: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 27-27: There should be no space before '}'.

(@stylistic/object-curly-spacing)


[error] 27-27: Expected a line break before this closing brace.

(@stylistic/object-curly-newline)


[error] 28-28: Imports must be broken into multiple lines if there are more than 1 elements.

(import-newlines/enforce)


[error] 28-28: Expected a line break after this opening brace.

(@stylistic/object-curly-newline)


[error] 28-28: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 28-28: There should be no space before '}'.

(@stylistic/object-curly-spacing)


[error] 28-28: Expected a line break before this closing brace.

(@stylistic/object-curly-newline)


[error] 29-29: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 29-29: There should be no space before '}'.

(@stylistic/object-curly-spacing)


[error] 30-30: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 30-30: There should be no space before '}'.

(@stylistic/object-curly-spacing)


[error] 450-450: Expected line before comment.

(@stylistic/lines-around-comment)


[error] 456-456: Expected line before comment.

(@stylistic/lines-around-comment)


[error] 462-462: There should be a linebreak after this element.

(@stylistic/array-element-newline)


[error] 464-464: 'isPrettified' is already declared in the upper scope on line 231 column 22.

(@typescript-eslint/no-shadow)

🪛 GitHub Check: lint-check
src/components/Editor/index.tsx

[failure] 7-7:
Imports must be broken into multiple lines if there are more than 1 elements


[failure] 6-6:
There should be no space before '}'


[failure] 6-6:
There should be no space after '{'


[failure] 3-3:
There should be no space before '}'


[failure] 3-3:
There should be no space after '{'


[failure] 1-1:
Expected a line break before this closing brace


[failure] 1-1:
There should be no space before '}'


[failure] 1-1:
There should be no space after '{'


[failure] 1-1:
Expected a line break after this opening brace


[failure] 1-1:
Imports must be broken into multiple lines if there are more than 1 elements

🪛 GitHub Actions: lint
src/components/Editor/index.tsx

[error] 1-1: Imports must be broken into multiple lines if there are more than 1 elements (import-newlines/enforce)

🔇 Additional comments (36)
docs/src/dev-guide/contributing-validation.md (1)

42-42: Added test case for new feature looks good!

The additional item in the manual testing section correctly documents the need to test the new "Prettify" toggle functionality in both the status bar and address bar.

package.json (2)

32-32: Appropriate type definitions added!

Adding @types/js-beautify type definitions is necessary for proper TypeScript support of the new prettifying feature.


58-58: Correct dependency placement!

The js-beautify library is appropriately placed in devDependencies, which aligns with the PR objective of implementing the prettifying toggle functionality.

src/components/MenuBar/NavigationBar.tsx (3)

31-31: Accessing context looks good!

You're correctly retrieving the isPrettified state from the UrlContext.


38-40: Good action handling!

The action handler now correctly includes checks for the new PRETTIFY_ON and PRETTIFY_OFF actions.


57-59: Ensure consistent defensive null handling

The code correctly uses the nullish coalescing operator ?? to handle potential null/undefined values in the isPrettified state. This is a good practice!

🧰 Tools
🪛 ESLint

[error] 57-57: Expected newline between test and consequent of ternary expression.

(@stylistic/multiline-ternary)


[error] 57-57: Expected newline between consequent and alternate of ternary expression.

(@stylistic/multiline-ternary)


[error] 58-58: Expected newline between test and consequent of ternary expression.

(@stylistic/multiline-ternary)


[error] 58-58: Expected newline between consequent and alternate of ternary expression.

(@stylistic/multiline-ternary)


[error] 59-59: Props should be sorted alphabetically

(@stylistic/jsx-sort-props)

src/typings/worker.ts (3)

105-105: Properly extending worker request interface

Adding the isPrettified property to the LOAD_FILE request type ensures the worker can apply prettification when loading files.


109-109: Properly extending LOAD_PAGE request type

Adding the isPrettified property to the LOAD_PAGE request type ensures the worker can apply prettification when navigating between pages.


114-114: Properly extending SET_FILTER request type

Adding the isPrettified property to the SET_FILTER request type ensures the worker can maintain the prettification state when filters are applied.

src/contexts/UrlContextProvider.tsx (2)

34-34: Added IS_PRETTIFIED parameter to URL_HASH_PARAMS_DEFAULT.

The addition of this parameter follows the established pattern for URL hash parameters in the application.


216-222: Good implementation of prettify toggle URL parameter handling.

The implementation correctly:

  1. Retrieves the parameter from hash params
  2. Converts string value "true" to boolean
  3. Sets a sensible default (false) when parameter is missing

This follows the established patterns for parameter handling in the application.

src/components/Editor/index.tsx (1)

131-132: Added prettify action handling.

The implementation correctly handles the new prettify toggle actions by adding appropriate cases to the switch statement. This follows the established pattern for similar actions in the codebase.

src/components/StatusBar/LogLevelSelect/index.tsx (2)

179-181: Proper integration of isPrettified parameter.

You've correctly passed the prettify state to the filter function with a fallback to false if the value is null. This ensures filtering maintains the prettify state.


182-186: Appropriate dependency array update.

Adding isPrettified to the dependency array ensures the callback will be recreated if the prettify state changes, which is necessary for proper reactivity.

src/components/MenuBar/MenuBarToggleButton.tsx (2)

9-14: Well-defined interface with appropriate properties.

The component interface is well-designed with appropriate props for customization of the toggle button.


16-26: Good documentation with JSDoc comments.

The JSDoc comments clearly document the component's purpose and parameters.

src/services/LogFileManager/index.ts (1)

247-252: Method signature update looks good.

The documentation and method signature have been properly updated to include the new isPrettified parameter.

src/typings/url.ts (2)

10-10: New enum value for prettify feature looks good.

The addition of IS_PRETTIFIED to the HASH_PARAM_NAMES enum is appropriate for the new feature.


18-19: Interface update handles the new feature well.

The UrlHashParams interface has been properly updated to include the new prettify parameter and improve type safety by using enum values as keys.

src/services/MainWorker.ts (3)

99-100: Parameter propagation to loadPage looks good.

The isPrettified parameter is now correctly passed to the loadPage method when loading a file.


109-110: Parameter propagation to loadPage looks good.

The isPrettified parameter is now correctly passed to the loadPage method when loading a page.


120-121: Parameter propagation to loadPage looks good.

The isPrettified parameter is now correctly passed to the loadPage method when setting a filter.

src/utils/actions.ts (3)

8-9: New action names for prettify feature look good.

The addition of PRETTIFY_ON and PRETTIFY_OFF to the ACTION_NAME enum is appropriate for the new feature.


39-48: Verify the identical key bindings for opposing actions.

Both PRETTIFY_ON and PRETTIFY_OFF actions use the same key binding (Ctrl/Cmd + P), which could potentially cause conflicts. Verify that the application logic correctly handles this by toggling between these actions based on the current state.

The approach of using the same keyboard shortcut for toggle actions is valid if the application determines which action to trigger based on the current prettify state. For example, when isPrettified is true, the PRETTIFY_OFF action would be triggered, and vice versa.


97-98: Type updates for navigation actions look good.

The NavigationActionsMap type has been properly updated to include the new prettify actions.

src/contexts/StateContextProvider.tsx (11)

55-55: Update function signature to align with changes

The interface for filterLogs has been updated to include the isPrettified parameter, which is necessary to support the new prettify feature. This change ensures that filtering operations can maintain the prettify state.


132-137: Handle prettify toggle in navigation actions

The implementation correctly handles the prettify toggle actions by returning to the top of the current page when prettifying is enabled or disabled. This ensures a consistent user experience when toggling the prettify feature.


169-179: Add prettify support to page loading

The loadPageByCursor function now accepts the isPrettified parameter and passes it to the worker. This modification is necessary to maintain the prettify state when navigating between pages.


231-231: Access prettify state from URL context

The code now correctly destructures the isPrettified property from the UrlContext, allowing the component to access and respond to changes in the prettify state from the URL.


406-406: Pass prettify state when loading files

The loadFile function now includes the isPrettified state in the worker request, ensuring that log files are loaded with the correct formatting based on the user's preference.


446-458: Update URL parameters for prettify toggle

The code correctly updates the URL hash parameters when the prettify state changes. The implementation avoids redundant page loading by returning early after updating the URL parameters, which is an optimization to prevent unnecessary re-renders.

🧰 Tools
🪛 ESLint

[error] 450-450: Expected line before comment.

(@stylistic/lines-around-comment)


[error] 456-456: Expected line before comment.

(@stylistic/lines-around-comment)


461-462: Include prettify state in page loading operations

The loadPageByAction function passes the isPrettified state to loadPageByCursor, ensuring that the prettify preference is maintained during navigation. The null coalescing operator provides a safe default value.

🧰 Tools
🪛 ESLint

[error] 413-462: Arrow function has too many statements (22). Maximum allowed is 20.

(max-statements)


[error] 462-462: There should be a linebreak after this element.

(@stylistic/array-element-newline)


472-472: Pass prettify state in filter requests

The worker request now includes the isPrettified parameter, ensuring that filtered log messages maintain the correct formatting state.


500-514: Add effect hook to handle prettify state changes

This new useEffect hook triggers a page reload whenever the isPrettified state changes, ensuring that the UI reflects the current prettifying setting. The implementation correctly creates a cursor to the top of the current page.


542-542: Include prettify state in event-based navigation

The code now passes the isPrettified state to loadPageByCursor when navigating to a specific event, ensuring that the prettify preference is maintained during this type of navigation.


194-194: Update conditional check style

According to the coding guidelines, false == <expression> is preferred over !<expression>.

The code already follows this guideline, using false === isWithinBounds(...) instead of !isWithinBounds(...).

Comment on lines 1 to 8
import {
IconButton,
IconButtonProps,
Tooltip,
TooltipTypeMap,
} from "@mui/joy";
import { Check, Close } from "@mui/icons-material";

Copy link

@coderabbitai coderabbitai bot Apr 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Import formatting and naming issues.

The imports have formatting issues and don't follow project naming conventions for icon imports.

According to the static analysis:

  1. Icon imports should have the "Icon" postfix
  2. Multiple imports should be broken into multiple lines
-import {
-    IconButton,
-    IconButtonProps,
-    Tooltip,
-    TooltipTypeMap,
-} from "@mui/joy";
-import { Check, Close } from "@mui/icons-material";
+import {
+    IconButton,
+    IconButtonProps,
+    Tooltip,
+    TooltipTypeMap,
+} from "@mui/joy";
+
+import CheckIcon from "@mui/icons-material/Check";
+import CloseIcon from "@mui/icons-material/Close";
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import {
IconButton,
IconButtonProps,
Tooltip,
TooltipTypeMap,
} from "@mui/joy";
import { Check, Close } from "@mui/icons-material";
import {
IconButton,
IconButtonProps,
Tooltip,
TooltipTypeMap,
} from "@mui/joy";
import CheckIcon from "@mui/icons-material/Check";
import CloseIcon from "@mui/icons-material/Close";
🧰 Tools
🪛 ESLint

[error] 7-7: '@mui/icons-material' import is restricted from being used. Please use path imports and name your imports with postfix "Icon" to avoid confusions.

(no-restricted-imports)


[error] 7-7: Imports must be broken into multiple lines if there are more than 1 elements.

(import-newlines/enforce)


[error] 7-7: Expected 2 empty lines after import statement not followed by another import.

(import/newline-after-import)


[error] 7-7: Expected a line break after this opening brace.

(@stylistic/object-curly-newline)


[error] 7-7: There should be no space after '{'.

(@stylistic/object-curly-spacing)


[error] 7-7: There should be no space before '}'.

(@stylistic/object-curly-spacing)


[error] 7-7: Expected a line break before this closing brace.

(@stylistic/object-curly-newline)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with the rabbit.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Henry8192 Great! Following the project's import naming conventions (using "Icon" suffix and properly formatting imports) will help maintain consistency across the codebase. These standards make the code more readable and easier to maintain for the entire team.


const filterLogs = useCallback((filter: LogLevelFilter) => {
const filterLogs = useCallback((filter: LogLevelFilter, isPrettified: boolean) => {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix parameter shadowing issue

The parameter isPrettified shadows the variable with the same name from the upper scope (line 231), which can lead to confusion and potential bugs.

Rename the parameter to avoid shadowing:

-const filterLogs = useCallback((filter: LogLevelFilter, isPrettified: boolean) => {
+const filterLogs = useCallback((filter: LogLevelFilter, isPrettifiedState: boolean) => {

And update its usage on line 472:

-    isPrettified: isPrettified
+    isPrettified: isPrettifiedState
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const filterLogs = useCallback((filter: LogLevelFilter, isPrettified: boolean) => {
const filterLogs = useCallback((filter: LogLevelFilter, isPrettifiedState: boolean) => {
// ... other code ...
return {
// ... possible other properties ...
isPrettified: isPrettifiedState
};
}, []);
🧰 Tools
🪛 ESLint

[error] 464-464: 'isPrettified' is already declared in the upper scope on line 231 column 22.

(@typescript-eslint/no-shadow)

@zzxthehappiest
Copy link
Contributor Author

When I test, after loading the test log file, since there are 10003 log messages in total, it will first open at the second page (I think it is because the logEventNum parameter is the index of the last one, which is 10003), then when I click previous page, it is the last row of this page (which is 10000). However, since I added the log messages of other log levels at the first row, to check if log filter work compatibly with the prettify, I had to scroll many many times to get to the first row.

I can think of a rough improvement (should I create an issue for this?) is to add a "jump to begin" and "jump to end" button which are similar to "first page" and "last page" but with smaller scope, so that we can jump to the first log message or the last log message in the current page easily. I think it should be easy because when I read the code it already provide the ability to do this.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
src/services/LogFileManager/index.ts (1)

2-2: Use camelCase for imported names

The imported js_beautify function doesn't follow the camelCase naming convention used throughout the codebase.

-import js_beautify from "js-beautify";
+import jsBeautify from "js-beautify";

You'll need to update all usages of this variable in the file as well.

🧰 Tools
🪛 ESLint

[error] 2-2: Identifier 'js_beautify' is not in camel case.

(camelcase)

🪛 GitHub Check: lint-check

[failure] 2-2:
Identifier 'js_beautify' is not in camel case

src/contexts/StateContextProvider.tsx (1)

435-435: Fix object key ordering

The object keys should be in alphabetical order according to the linting rules.

    workerPostReq(mainWorkerRef.current, WORKER_REQ_CODE.LOAD_FILE, {
        cursor: cursor,
        decoderOptions: getConfig(CONFIG_KEY.DECODER_OPTIONS),
        fileSrc: fileSrc,
-       pageSize: getConfig(CONFIG_KEY.PAGE_SIZE),
-       isPrettified: isPrettified ?? false,
+       isPrettified: isPrettified ?? false,
+       pageSize: getConfig(CONFIG_KEY.PAGE_SIZE),
    });
🧰 Tools
🪛 GitHub Check: lint-check

[failure] 435-435:
Expected object keys to be in natural ascending order. 'isPrettified' should be before 'pageSize'

🪛 GitHub Actions: lint

[warning] 435-435: Expected object keys to be in natural ascending order. 'isPrettified' should be before 'pageSize' (sort-keys)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b5c118e and dc66900.

📒 Files selected for processing (6)
  • src/components/Editor/index.tsx (1 hunks)
  • src/components/MenuBar/MenuBarToggleButton.tsx (1 hunks)
  • src/components/MenuBar/NavigationBar.tsx (3 hunks)
  • src/components/StatusBar/LogLevelSelect/index.tsx (1 hunks)
  • src/contexts/StateContextProvider.tsx (10 hunks)
  • src/services/LogFileManager/index.ts (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/components/StatusBar/LogLevelSelect/index.tsx
  • src/components/Editor/index.tsx
  • src/components/MenuBar/NavigationBar.tsx
  • src/components/MenuBar/MenuBarToggleButton.tsx
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.{cpp,hpp,java,js,jsx,tpp,ts,tsx}`: - Prefer `false == ` rather than `!`.

**/*.{cpp,hpp,java,js,jsx,tpp,ts,tsx}: - Prefer false == <expression> rather than !<expression>.

  • src/contexts/StateContextProvider.tsx
  • src/services/LogFileManager/index.ts
🧬 Code Definitions (2)
src/contexts/StateContextProvider.tsx (4)
src/utils/actions.ts (1)
  • ACTION_NAME (115-115)
src/typings/worker.ts (4)
  • EVENT_POSITION_ON_PAGE (189-189)
  • CursorType (196-196)
  • WORKER_REQ_CODE (190-190)
  • CURSOR_CODE (187-187)
src/contexts/UrlContextProvider.tsx (2)
  • UrlContext (280-280)
  • updateWindowUrlHashParams (276-276)
src/typings/url.ts (1)
  • HASH_PARAM_NAMES (37-37)
src/services/LogFileManager/index.ts (1)
src/typings/worker.ts (3)
  • CursorType (196-196)
  • WorkerResp (201-201)
  • WORKER_RESP_CODE (191-191)
🪛 GitHub Check: lint-check
src/contexts/StateContextProvider.tsx

[failure] 435-435:
Expected object keys to be in natural ascending order. 'isPrettified' should be before 'pageSize'

src/services/LogFileManager/index.ts

[failure] 2-2:
Identifier 'js_beautify' is not in camel case

🪛 GitHub Actions: lint
src/contexts/StateContextProvider.tsx

[warning] 435-435: Expected object keys to be in natural ascending order. 'isPrettified' should be before 'pageSize' (sort-keys)

🪛 ESLint
src/services/LogFileManager/index.ts

[error] 2-2: Identifier 'js_beautify' is not in camel case.

(camelcase)

🔇 Additional comments (13)
src/services/LogFileManager/index.ts (3)

248-249: JSDoc update looks good

The JSDoc has been properly updated to describe the new parameter.


253-253: Method signature change looks appropriate

Adding the isPrettified parameter to the loadPage method is a good way to implement the prettifying toggle feature.


290-294: Conditional formatting logic looks good

The implementation correctly applies formatting only when the isPrettified flag is true. The ternary operator provides a clean approach to conditional formatting.

src/contexts/StateContextProvider.tsx (10)

31-34: Import updates look good

The imports have been correctly updated to include the URL hash parameter names needed for the prettify feature.


161-166: Handling of prettify actions in page navigation looks good

The additional cases handle the prettify toggle actions appropriately, preserving the current page number and setting the position to the top of the page.


203-203: Parameter addition looks good

The isPrettified parameter has been correctly added to the loadPageByCursor function.


207-207: Parameter passing looks good

Passing the isPrettified parameter to the worker request ensures that the prettify state is properly communicated.


475-487: URL parameter update on prettify actions looks good

The code correctly updates the URL hash parameters when the prettify state changes without triggering a page reload.


530-544: Good implementation of page reload on prettify state change

Adding this effect ensures that when the prettify state changes, the current page is reloaded with the new prettify setting. The implementation correctly preserves the current page position.


502-502: Passing prettify state to filter logs looks good

The filterLogs function now correctly passes the prettify state when setting the log level filter.


572-572: Consistent use of prettify parameter in loadPageByCursor calls

This ensures that all page loads respect the current prettify state.


490-490: Good update to loadPageByCursor call

The loadPageByCursor function call has been updated to include the prettify state from the URL context.


464-464: Fix shadowing issue with isPrettified parameter

The parameter isPrettified shadows the variable with the same name from the upper scope (line 260), which can lead to confusion and potential bugs.

Rename the parameter to avoid shadowing:

-const filterLogs = useCallback((filter: LogLevelFilter) => {
+const filterLogs = useCallback((filter: LogLevelFilter, isPrettifiedState: boolean) => {

And update its usage on line 502:

-    isPrettified: isPrettified ?? false,
+    isPrettified: isPrettifiedState ?? false,

@zzxthehappiest
Copy link
Contributor Author

I fixed some linting issues but I have a few questions:

yscope-log-viewer/src/contexts/StateContextProvider.tsx:442:42  error    Arrow function has too many statements (22). Maximum allowed is 20                                   max-statements
yscope-log-viewer/src/contexts/StateContextProvider.tsx:601:1   error    File has too many lines (629). Maximum allowed is 600                                                max-lines

I don't know a good ways to fix these two issues, could you give me some advices?

Another question is about React's hook. Since I added a new argument in loadPageByCursor so I think I need to add isPrettified dependencies in all hooks that call loadPageByCursor so that I can pass the latest isPrettified argument. However for this hook in the StateContextProvider.tst:

    useEffect(() => {
        if (null === mainWorkerRef.current) {
            return;
        }

        if (URL_HASH_PARAMS_DEFAULT.logEventNum === logEventNum) {
            return;
        }

        const logEventNumsOnPage: number [] =
            Array.from(beginLineNumToLogEventNumRef.current.values());

        const clampedLogEventNum = clamp(logEventNum, 1, numEvents);

        if (updateUrlIfEventOnPage(clampedLogEventNum, logEventNumsOnPage)) {
            // No need to request a new page since the log event is on the current page.
            return;
        }

        const cursor: CursorType = {
            code: CURSOR_CODE.EVENT_NUM,
            args: {eventNum: logEventNum},
        };

        setUiState(UI_STATE.FAST_LOADING);
        loadPageByCursor(mainWorkerRef.current, cursor, isPrettified ?? false);
    }, [
        isPrettified,
        logEventNum,
        numEvents,
    ]);

There are some return statements can exit the function before loadPageByCursor, and the conditions determining return do not rely on isPrettified, which means if only isPrettified changes, the page will not be loaded again with or without prettifying. So my solution is to add another hook above this one:

useEffect(() => {
        if (null === mainWorkerRef.current) {
            return;
        }

        const cursor: CursorType = {
            code: CURSOR_CODE.PAGE_NUM,
            args: {pageNum: pageNumRef.current, eventPositionOnPage: EVENT_POSITION_ON_PAGE.TOP},
        };

        setUiState(UI_STATE.FAST_LOADING);
        loadPageByCursor(mainWorkerRef.current, cursor, isPrettified ?? false);
    }, [
        isPrettified,
    ]);

to ensure that the page will be loaded again after updating the isPrettified. But I think there might be performance issue when these two hooks are triggered at the same time, so that the loadPageByCursor will be called twice. I am not sure which one will be triggered first, so ideally I think we don't need the hook below. But I can't come up with a good way to bypass the those return when isPrettified is updated.

@zzxthehappiest
Copy link
Contributor Author

zzxthehappiest commented Apr 3, 2025

Sorry to bother UI team, could anyone take a look of this PR (and my questions in the last comment, which block the pipeline). I will try to fix them and potential reviewer comments by tomorrow morning to make the PR ready to merge, otherwise I maybe have less time over this long weekend in China (it will be Qingming Festival, and I need to go back home and spend time with my family).

@zzxthehappiest zzxthehappiest changed the title feat: Add prettifying toggle button feat: Add prettifying toggle button (resolves #220). Apr 7, 2025
@junhaoliao
Copy link
Member

Sorry to bother UI team, could anyone take a look of this PR (and my questions in the last comment, which block the pipeline). I will try to fix them and potential reviewer comments by tomorrow morning to make the PR ready to merge, otherwise I maybe have less time over this long weekend in China (it will be Qingming Festival, and I need to go back home and spend time with my family).

No problem! We discussed offline but I realize I didn't post a response here. Thanks again for helping and the attempt to lint the code. I'm taking a look at the code / lint issues now.

Copy link
Member

@junhaoliao junhaoliao left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks again for your contributions! The changes are mostly clean. I truly appreciate that

@@ -458,9 +472,24 @@ const StateContextProvider = ({children}: StateContextProviderProps) => {
return;
}

if (navAction.code === ACTION_NAME.PRETTIFY_ON) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is nice, but i'm not entirely sure if we need a NavAction for this. Can we refer to the handling of WORD_WRAP and see if the changes can be done similarly?

Don't hesitate to let me know if you think accessing the latest value of isPrettified is an issue. I can look further if that's the case

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here I just wanted to make it consistent with other button (because I put the prettify button left to the first page button in the Navigation bar). If we want to remove it here, I can come up with two ways:

  1. Import updateWindowUrlHashParams function to NavigationBar.tsx so that I candirectly update the URL so that the isPrettified can be updated in the UrlContext.
  2. I add it as a separated button like ExportLogsButton in MenuBar/index.tsx, and put it before the divider of the NavigationBar, and import updateWindowUrlHashParams in that new .tsx file and implement the same logic.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make it consistent with other button (because I put the prettify button left to the first page button in the Navigation bar)

ah, gotcha. can we add it as a status bar button (in the right bottom of the window)? That way it will match the semantics in VSCode better. Sorry for the previous oversight!

I can come up with two ways

yup, i think what you propose will work. Let's make helper functions, if appropriate, to avoid duplicating the logic in both. To get the latest value of isToggled in a non-reactive function, we can use getWindowUrlHashParams(). (might need to export getWindowUrlHashParams first

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I move and rename the MenuBarToggleButton to StatusBarToggleButton, and put the button in left to the "Log Level"
image

And I also simulate the code style of the NavigationBar so I implement a handleStatusButtonClick function in the StatusBar so that I can get the state variable from UrlContext. Let me know if this way is bad.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🔭 Outside diff range comments (2)
src/contexts/StateContextProvider.tsx (2)

81-89: ⚠️ Potential issue

Update the filterLogs interface to match its implementation.

The implementation of filterLogs (at line 488) now accepts a second parameter isPrettified, but the interface definition hasn't been updated to reflect this change.

-    filterLogs: (filter: LogLevelFilter) => void;
+    filterLogs: (filter: LogLevelFilter, isPrettified?: boolean) => void;

442-486: ⚠️ Potential issue

Refactor the function to address linting error.

The arrow function has too many statements (21) while the maximum allowed is 20, causing a linting error.

Consider extracting the logic for handling different navigation actions into separate functions:

-    const loadPageByAction = useCallback((navAction: NavigationAction) => {
+    const handleReloadAction = useCallback((navAction: NavigationAction) => {
+        if (null === fileSrcRef.current || null === logEventNumRef.current) {
+            throw new Error(`Unexpected fileSrc=${JSON.stringify(fileSrcRef.current)
+            }, logEventNum=${logEventNumRef.current} when reloading.`);
+        }
+        loadFile(fileSrcRef.current, {
+            code: CURSOR_CODE.EVENT_NUM,
+            args: {eventNum: logEventNumRef.current},
+        });
+    }, [loadFile]);
+
+    const loadPageByAction = useCallback((navAction: NavigationAction) => {
        if (null === mainWorkerRef.current) {
            console.error("Unexpected null mainWorkerRef.current");

            return;
        }

        if (navAction.code === ACTION_NAME.RELOAD) {
-            if (null === fileSrcRef.current || null === logEventNumRef.current) {
-                throw new Error(`Unexpected fileSrc=${JSON.stringify(fileSrcRef.current)
-                }, logEventNum=${logEventNumRef.current} when reloading.`);
-            }
-            loadFile(fileSrcRef.current, {
-                code: CURSOR_CODE.EVENT_NUM,
-                args: {eventNum: logEventNumRef.current},
-            });
+            handleReloadAction(navAction);

            return;
        }
🧰 Tools
🪛 GitHub Check: lint-check

[failure] 442-442:
Arrow function has too many statements (21). Maximum allowed is 20

🪛 ESLint

[error] 442-486: Arrow function has too many statements (21). Maximum allowed is 20.

(max-statements)

🪛 GitHub Actions: lint

[error] 442-442: ESLint: Arrow function has too many statements (21). Maximum allowed is 20 (max-statements)

♻️ Duplicate comments (1)
src/services/LogFileManager/index.ts (1)

2-2: ⚠️ Potential issue

Use proper import naming convention.

The import statement uses camel case for a function that starts with an uppercase letter, which triggers an ESLint error.

-import JsBeautify from "js-beautify";
+import jsBeautify from "js-beautify";
🧹 Nitpick comments (2)
src/contexts/StateContextProvider.tsx (2)

529-543: Consider using a consistent approach for state references.

The effect directly uses both isPrettified and logEventNumRef.current, which may cause inconsistencies.

For consistency, consider using the ref value throughout:

        const cursor: CursorType = {
            code: CURSOR_CODE.EVENT_NUM,
            args: {eventNum: logEventNumRef.current ?? 1},
        };

        setUiState(UI_STATE.FAST_LOADING);
-        loadPageByCursor(mainWorkerRef.current, cursor, isPrettified ?? false);
+        loadPageByCursor(mainWorkerRef.current, cursor, isPrettifiedRef.current);
    }, [
-        isPrettified,
+        // No dependencies needed if using refs consistently
    ]);

571-576: Consistent use of state references.

Similar to the previous comment, consider using isPrettifiedRef.current consistently rather than isPrettified ?? false.

        setUiState(UI_STATE.FAST_LOADING);
-        loadPageByCursor(mainWorkerRef.current, cursor, isPrettified ?? false);
+        loadPageByCursor(mainWorkerRef.current, cursor, isPrettifiedRef.current);
    }, [
-        isPrettified,
        logEventNum,
        numEvents,
    ]);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dc66900 and cef6abc.

📒 Files selected for processing (9)
  • src/components/Editor/index.tsx (1 hunks)
  • src/components/MenuBar/ExportLogsButton.tsx (1 hunks)
  • src/components/MenuBar/MenuBarIconButton.tsx (1 hunks)
  • src/components/MenuBar/MenuBarToggleButton.tsx (1 hunks)
  • src/components/MenuBar/NavigationBar.tsx (4 hunks)
  • src/contexts/StateContextProvider.tsx (11 hunks)
  • src/contexts/UrlContextProvider.tsx (2 hunks)
  • src/services/LogFileManager/index.ts (3 hunks)
  • src/utils/actions.ts (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/components/Editor/index.tsx
  • src/components/MenuBar/MenuBarToggleButton.tsx
  • src/utils/actions.ts
  • src/contexts/UrlContextProvider.tsx
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.{cpp,hpp,java,js,jsx,tpp,ts,tsx}`: - Prefer `false == ` rather than `!`.

**/*.{cpp,hpp,java,js,jsx,tpp,ts,tsx}: - Prefer false == <expression> rather than !<expression>.

  • src/components/MenuBar/ExportLogsButton.tsx
  • src/components/MenuBar/MenuBarIconButton.tsx
  • src/components/MenuBar/NavigationBar.tsx
  • src/contexts/StateContextProvider.tsx
  • src/services/LogFileManager/index.ts
🧬 Code Graph Analysis (3)
src/components/MenuBar/NavigationBar.tsx (3)
src/contexts/StateContextProvider.tsx (1)
  • StateContext (628-628)
src/contexts/UrlContextProvider.tsx (1)
  • UrlContext (277-277)
src/utils/actions.ts (1)
  • ACTION_NAME (108-108)
src/contexts/StateContextProvider.tsx (6)
src/utils/actions.ts (1)
  • ACTION_NAME (108-108)
src/typings/worker.ts (1)
  • CursorType (196-196)
src/contexts/UrlContextProvider.tsx (2)
  • UrlContext (277-277)
  • updateWindowUrlHashParams (273-273)
src/utils/config.ts (1)
  • getConfig (182-182)
src/typings/config.ts (1)
  • CONFIG_KEY (44-44)
src/typings/url.ts (1)
  • HASH_PARAM_NAMES (37-37)
src/services/LogFileManager/index.ts (1)
src/typings/worker.ts (3)
  • CursorType (196-196)
  • WorkerResp (201-201)
  • WORKER_RESP_CODE (191-191)
🪛 GitHub Actions: lint
src/contexts/StateContextProvider.tsx

[error] 442-442: ESLint: Arrow function has too many statements (21). Maximum allowed is 20 (max-statements)

🪛 GitHub Check: lint-check
src/services/LogFileManager/index.ts

[failure] 291-291:
A function with a name starting with an uppercase letter should only be used as a constructor

🪛 ESLint
src/services/LogFileManager/index.ts

[error] 291-291: A function with a name starting with an uppercase letter should only be used as a constructor.

(new-cap)

🔇 Additional comments (23)
src/components/MenuBar/ExportLogsButton.tsx (1)

34-34: Property name updated for consistency.

The title prop has been correctly updated to tooltipTitle to match the changes in the MenuBarIconButton component interface.

src/components/MenuBar/MenuBarIconButton.tsx (4)

11-11: New optional property added to interface.

The tooltipTitle optional string property replaces the previous title property, providing better semantics by clearly differentiating from HTML's native title attribute.


18-19: JSDoc updated to reflect parameter name change.

The documentation now correctly references the renamed parameter tooltipTitle instead of title, with added context about its purpose.


25-26: Function parameter renamed for clarity.

The parameter name has been changed from title to tooltipTitle to be more descriptive and consistent with the interface definition.


30-31: Tooltip component updated to use new property name.

The title prop in the Tooltip component now correctly references the renamed tooltipTitle parameter.

src/services/LogFileManager/index.ts (2)

248-249: Documentation updated for new parameter.

The JSDoc comment has been appropriately updated to document the new isPrettified parameter.


253-253: Method signature extended to support prettify feature.

The loadPage method now correctly accepts an isPrettified boolean parameter to determine whether log messages should be formatted.

src/components/MenuBar/NavigationBar.tsx (7)

5-6: Added MUI icons for toggle button states.

Appropriate icons have been imported to represent the on/off states of the prettify feature.


13-13: Added UrlContext import for accessing prettify state.

The UrlContext is now imported to access the isPrettified state, which is stored in the URL parameters.


21-21: Added import for new toggle button component.

The MenuBarToggleButton component has been imported to provide the prettify toggle functionality.


31-35: Context usage expanded to access prettify state.

The component now uses both StateContext and UrlContext to access the necessary state variables, with appropriate destructuring.


42-42: Action handling extended for toggle prettify functionality.

The conditional check now includes the TOGGLE_PRETTIFY action, allowing the navigation button click handler to process this new action.


59-67: New toggle button added for prettify functionality.

The MenuBarToggleButton component is properly configured with appropriate props:

  • Active state is inversely tied to isPrettified (active when not prettified)
  • Different icons for on/off states
  • Dynamic tooltip text based on current state
  • Proper action name for event handling

This implementation follows the design pattern of other navigation buttons while adding toggle functionality.


70-70: Updated tooltip property names for consistency.

All MenuBarIconButton components have been updated to use tooltipTitle instead of title, maintaining consistency with the component interface changes.

Also applies to: 77-77, 87-87, 94-94

src/contexts/StateContextProvider.tsx (9)

31-34: LGTM - Added required imports for URL parameters.

The addition of the imports for URL parameters is necessary for the new prettify feature.


161-165: LGTM - Proper handling of prettify toggle.

The implementation correctly handles the TOGGLE_PRETTIFY action by returning to the top of the current page.


197-203: LGTM - Well-documented parameter addition.

The addition of the isPrettified parameter is well documented and properly integrated into the function signature.


259-259: LGTM - Added URL context property.

The addition of isPrettified to the destructured properties from UrlContext is necessary for accessing the prettify state from the URL.


280-280: LGTM - Added state reference with proper initialization.

The isPrettifiedRef is correctly initialized with the URL value, defaulting to false if not provided.


434-440: LGTM - Updated worker request with prettify state.

The function now correctly passes the prettify state to the worker and includes it in the dependency array.


475-482: LGTM - Proper implementation of prettify toggle action.

The code correctly updates the isPrettifiedRef and the URL hash parameters when handling the toggle action.


496-497: LGTM - Added prettify state to filter request.

The prettify state is correctly included in the worker request for setting the filter.


500-503: LGTM - Added synchronization for prettify state.

The effect correctly synchronizes the isPrettifiedRef with the isPrettified value from the URL context.

Comment on lines 290 to 294
const printedMsg = (isPrettified) ?
`${JsBeautify(msg)}\n` :
msg;

messages.push(printedMsg);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Conditional formatting logic implemented.

The code now applies JS beautification to log messages when isPrettified is true. However, there's a linting issue with the function naming.

-            const printedMsg = (isPrettified) ?
-                `${JsBeautify(msg)}\n` :
+            const printedMsg = (isPrettified) ?
+                `${jsBeautify(msg)}\n` :

Also note that function currentLine += msg.split("\n").length - 1; on line 296 may produce incorrect results after beautification since it's still using the original message to count lines. Consider using the formatted message length instead:

-            currentLine += msg.split("\n").length - 1;
+            currentLine += printedMsg.split("\n").length - 1;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const printedMsg = (isPrettified) ?
`${JsBeautify(msg)}\n` :
msg;
messages.push(printedMsg);
const printedMsg = (isPrettified) ?
`${jsBeautify(msg)}\n` :
msg;
messages.push(printedMsg);
// ... (other code)
currentLine += printedMsg.split("\n").length - 1;
🧰 Tools
🪛 GitHub Check: lint-check

[failure] 291-291:
A function with a name starting with an uppercase letter should only be used as a constructor

🪛 ESLint

[error] 291-291: A function with a name starting with an uppercase letter should only be used as a constructor.

(new-cap)

Comment on lines 8 to 9
import Check from "@mui/icons-material/Check";
import Close from "@mui/icons-material/Close";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to follow the convention in mui official docs:

Suggested change
import Check from "@mui/icons-material/Check";
import Close from "@mui/icons-material/Close";
import CheckIcon from "@mui/icons-material/Check";
import CloseIcon from "@mui/icons-material/Close";

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed!

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (6)
src/components/StatusBar/StatusBarToggleButton.tsx (4)

12-18: Interface naming inconsistency.

The component is named StatusBarToggleButton but the interface is named MenuBarToggleButtonProps. This creates confusion about the component's purpose and location.

For better consistency, rename the interface:

-interface MenuBarToggleButtonProps extends IconButtonProps {
+interface StatusBarToggleButtonProps extends IconButtonProps {
    tooltipPlacement?: TooltipTypeMap["props"]["placement"];
    tooltipTitle?: string;
    isActive?: boolean;
    onIcon?: React.ReactNode;
    offIcon?: React.ReactNode;
}

Make sure to also update line 39 where the interface is used.


39-39: Update interface reference.

If you rename the interface as suggested earlier, update this reference too.

-}: MenuBarToggleButtonProps) => {
+}: StatusBarToggleButtonProps) => {

44-44: Remove space after spread operator.

There's an extra space after the spread operator which is not consistent with standard formatting.

-            {... tooltipPlacement && {placement: tooltipPlacement}}
+            {...tooltipPlacement && {placement: tooltipPlacement}}

45-55: Wrapping in a span adds unnecessary nesting.

Using a span solely as a tooltip container can be avoided as Material UI's Tooltip component already handles this internally.

Consider simplifying the structure:

        <Tooltip
            title={tooltipTitle}
            {...tooltipPlacement && {placement: tooltipPlacement}}
        >
-            <span>
                <IconButton
                    size={"sm"}
                    {...rest}
                >
                    {isActive ?
                        onIcon :
                        offIcon}
                </IconButton>
-            </span>
        </Tooltip>

This creates a simpler DOM structure while maintaining the same functionality.

src/components/StatusBar/index.tsx (2)

87-89: Simplify conditional tooltip text.

The current implementation uses a nullish coalescing operator followed by a ternary, which is unnecessarily complex.

-                tooltipTitle={isPrettified ?? false ?
-                    "Prettify Off" :
-                    "Prettify On"}
+                tooltipTitle={isPrettified ? "Prettify Off" : "Prettify On"}

This is cleaner and achieves the same result, as JavaScript already treats undefined as false in conditionals.


48-57: Prefer false === <expression> over !<expression>

According to the coding guidelines, we should prefer false === <expression> over !<expression>.

        switch (actionName) {
            case ACTION_NAME.TOGGLE_PRETTIFY:
                updateWindowUrlHashParams({
-                    [HASH_PARAM_NAMES.IS_PRETTIFIED]: !isPrettified,
+                    [HASH_PARAM_NAMES.IS_PRETTIFIED]: false === isPrettified,
                });
                break;
            default:
                console.error(`Unexpected action: ${actionName}`);
                break;
        }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cef6abc and 014e459.

📒 Files selected for processing (6)
  • src/components/MenuBar/MenuBarIconButton.tsx (1 hunks)
  • src/components/MenuBar/NavigationBar.tsx (3 hunks)
  • src/components/StatusBar/StatusBarToggleButton.tsx (1 hunks)
  • src/components/StatusBar/index.tsx (4 hunks)
  • src/contexts/StateContextProvider.tsx (9 hunks)
  • src/services/LogFileManager/index.ts (3 hunks)
✅ Files skipped from review due to trivial changes (1)
  • src/components/MenuBar/NavigationBar.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/components/MenuBar/MenuBarIconButton.tsx
  • src/services/LogFileManager/index.ts
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.{cpp,hpp,java,js,jsx,tpp,ts,tsx}`: - Prefer `false == ` rather than `!`.

**/*.{cpp,hpp,java,js,jsx,tpp,ts,tsx}: - Prefer false == <expression> rather than !<expression>.

  • src/components/StatusBar/StatusBarToggleButton.tsx
  • src/components/StatusBar/index.tsx
  • src/contexts/StateContextProvider.tsx
🧬 Code Graph Analysis (2)
src/components/StatusBar/index.tsx (3)
src/contexts/UrlContextProvider.tsx (2)
  • UrlContext (277-277)
  • updateWindowUrlHashParams (273-273)
src/utils/actions.ts (1)
  • ACTION_NAME (108-108)
src/typings/url.ts (1)
  • HASH_PARAM_NAMES (37-37)
src/contexts/StateContextProvider.tsx (5)
src/typings/states.ts (1)
  • UI_STATE (101-101)
src/typings/worker.ts (3)
  • CursorType (196-196)
  • WORKER_REQ_CODE (190-190)
  • CURSOR_CODE (187-187)
src/contexts/UrlContextProvider.tsx (1)
  • UrlContext (277-277)
src/utils/config.ts (1)
  • getConfig (182-182)
src/typings/config.ts (1)
  • CONFIG_KEY (44-44)
🪛 GitHub Check: lint-check
src/contexts/StateContextProvider.tsx

[failure] 555-555:
React Hook useEffect has a missing dependency: 'isPrettified'. Either include it or remove the dependency array

🪛 GitHub Actions: lint
src/contexts/StateContextProvider.tsx

[warning] 555-555: React Hook useEffect has a missing dependency: 'isPrettified'. Either include it or remove the dependency array.

🔇 Additional comments (6)
src/components/StatusBar/StatusBarToggleButton.tsx (1)

1-61: The component looks good overall.

The StatusBarToggleButton component is well-structured and includes proper documentation. It provides flexibility with customizable icons and tooltip placement, making it reusable.

src/components/StatusBar/index.tsx (1)

45-58: Well-structured event handler.

The handleStatusButtonClick function is well-structured, using a switch statement that can easily accommodate additional actions in the future.

src/contexts/StateContextProvider.tsx (4)

483-486: Good implementation of state synchronization.

The useEffect hook for synchronizing isPrettifiedRef with isPrettified is implemented correctly and ensures that the ref always has the latest value.


272-272: Ensure consistent initialization.

The isPrettifiedRef is initialized with isPrettified ?? false, which is good for handling the nullable state value.


425-427: Good implementation of isPrettified parameter.

The loadFile function correctly passes the isPrettified parameter, ensuring proper initialization of the file with the prettify state.


478-480: Using ref for stable callback definitions.

Using isPrettifiedRef.current in the filterLogs function is a good pattern to avoid re-creating the callback when the isPrettified state changes.

@@ -58,6 +80,16 @@ const StatusBar = () => {
</span>
</Tooltip>

<StatusBarToggleButton
data-action-name={ACTION_NAME.TOGGLE_PRETTIFY}
isActive={!isPrettified}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Inverted logic in isActive prop.

The isActive prop is set to !isPrettified, which is counterintuitive - users would expect the button to be active when prettification is enabled, not disabled.

-                isActive={!isPrettified}
+                isActive={isPrettified === true}

This makes the button state align with the actual feature state.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
isActive={!isPrettified}
isActive={isPrettified === true}

Comment on lines 83 to 91
<StatusBarToggleButton
data-action-name={ACTION_NAME.TOGGLE_PRETTIFY}
isActive={!isPrettified}
offIcon={<AutoFixOffRoundedIcon/>}
tooltipTitle={isPrettified ?? false ?
"Prettify Off" :
"Prettify On"}
onClick={handleStatusButtonClick}
onIcon={<AutoFixHighRoundedIcon/>}/>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider inverting tooltip text and icon logic.

Currently, the icons and tooltip text don't clearly match the state they represent. When prettification is ON, the tooltip says "Prettify Off", which is confusing.

Consider this more intuitive approach:

            <StatusBarToggleButton
                data-action-name={ACTION_NAME.TOGGLE_PRETTIFY}
-                isActive={!isPrettified}
-                offIcon={<AutoFixOffRoundedIcon/>}
-                tooltipTitle={isPrettified ?? false ?
-                    "Prettify Off" :
-                    "Prettify On"}
+                isActive={isPrettified === true}
+                onIcon={<AutoFixHighRoundedIcon/>}
+                offIcon={<AutoFixOffRoundedIcon/>}
+                tooltipTitle={isPrettified ? "Turn Prettify Off" : "Turn Prettify On"}
                onClick={handleStatusButtonClick}
-                onIcon={<AutoFixHighRoundedIcon/>}/>
+                />

This makes the tooltip indicate the action that will happen when clicked, rather than the current state.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<StatusBarToggleButton
data-action-name={ACTION_NAME.TOGGLE_PRETTIFY}
isActive={!isPrettified}
offIcon={<AutoFixOffRoundedIcon/>}
tooltipTitle={isPrettified ?? false ?
"Prettify Off" :
"Prettify On"}
onClick={handleStatusButtonClick}
onIcon={<AutoFixHighRoundedIcon/>}/>
<StatusBarToggleButton
data-action-name={ACTION_NAME.TOGGLE_PRETTIFY}
isActive={isPrettified === true}
onIcon={<AutoFixHighRoundedIcon/>}
offIcon={<AutoFixOffRoundedIcon/>}
tooltipTitle={isPrettified ? "Turn Prettify Off" : "Turn Prettify On"}
onClick={handleStatusButtonClick}
/>

Comment on lines 554 to 558
loadPageByCursor(mainWorkerRef.current, cursor, isPrettified ?? false);
}, [
numEvents,
logEventNum,
numEvents,
]);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Missing dependency in useEffect.

The useEffect hook is missing isPrettified in its dependency array, as flagged by the static analysis tool.

    }, [
        logEventNum,
        numEvents,
+       isPrettified,
    ]);

Without this, changes to isPrettified won't properly trigger this effect, potentially causing stale state issues.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
loadPageByCursor(mainWorkerRef.current, cursor, isPrettified ?? false);
}, [
numEvents,
logEventNum,
numEvents,
]);
loadPageByCursor(mainWorkerRef.current, cursor, isPrettified ?? false);
}, [
logEventNum,
numEvents,
isPrettified,
]);
🧰 Tools
🪛 GitHub Check: lint-check

[failure] 555-555:
React Hook useEffect has a missing dependency: 'isPrettified'. Either include it or remove the dependency array

🪛 GitHub Actions: lint

[warning] 555-555: React Hook useEffect has a missing dependency: 'isPrettified'. Either include it or remove the dependency array.

Copy link
Member

@junhaoliao junhaoliao left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for cleaning up the code, and sorry for the hassles the linter rules have brought to you.

here's my very last batch of comments, some of which can be directly applied (with the "Add suggestion to batch" button"s under the "Files changed" tab)

i believe this PR has been at a very good state and can be merged once all the suggestions are addressed

@@ -82,6 +88,7 @@ type NavigationActionsMap = {
[ACTION_NAME.SPECIFIC_PAGE]: {
pageNum: number;
};
[ACTION_NAME.TOGGLE_PRETTIFY]: null;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto: let's move it between COPY_LOG_EVENT and WORD_WRAP.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't find the COPY_LOG_EVENT and WORD_WRAP here, because I just realized that this is NavigationActionsMap, but now I have moved it to status bar, so I just deleted this line.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the changes we're to make in this file, we need to extend the line limit temporarily. Let's add this at the beginning:

/* eslint max-lines: ["error", 350] */

@coderabbitai please create an issue to track the effort of moving individual functions into a separate file. and also extracting helpers from the component because it has too many lines as well. Ideally, this should be done after #175 is merged, to avoid conflicts.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧩 Analysis chain

@junhaoliao I've created an issue to track the refactoring of the Editor component. The issue outlines the needed work to move helper functions into separate files and extract components to reduce the file size. As requested, it notes that this work should be done after PR #175 is merged to avoid conflicts.


🏁 Script executed:

#!/bin/bash
# Create a GitHub issue to track refactoring efforts for the Editor component

gh issue create \
  --title "refactor: Extract helper functions from Editor component into separate files" \
  --body "## Description

The Editor component in \`src/components/Editor/index.tsx\` has grown too large and is exceeding ESLint's line limit. This issue tracks the effort to:

1. Move individual utility functions (like \`getSelectedLogEventNum\`, \`handleCopyLogEventAction\`, \`handleWordWrapAction\`, etc.) into separate files
2. Extract helper components and hooks from the \`<Editor/>\` component
3. Reorganize the code to improve maintainability and readability

## Implementation Notes

- This refactoring should be done **after PR #175 is merged** to avoid conflicts
- Consider organizing the extracted functions by their purpose (editor actions, cursor handling, etc.)
- Ensure all existing functionality remains intact after refactoring

## Related PRs
- Identified in PR #223 (Add prettifying toggle button)

" \
  --assignee junhaoliao

Length of output: 996


@junhaoliao I've created GitHub issue #229 to track the refactoring of the Editor component. The issue includes the tasks to extract helper functions into separate files and reorganize the component to address the line limit concerns. As requested, I've noted that this work should be done after PR #175 is merged to avoid conflicts.


🧬 Code Graph Analysis Results

Relevant Code Snippets

1. Nullable

  • Filename: src/typings/common.ts
  • Line Range: 10-10
Nullable
  • Description: This type is likely used to indicate that a value can either be of a specified type or null, which is relevant for handling optional values in the Editor component.

2. StateContext

  • Filename: src/contexts/StateContextProvider.tsx
  • Line Range: 610-610
StateContext
  • Description: This context is used in the Editor component to access state values such as beginLineNumToLogEventNum, logData, and loadPageByAction, which are crucial for the editor's functionality.

3. CONFIG_KEY

  • Filename: src/typings/config.ts
  • Line Range: 44-44
CONFIG_KEY
  • Description: This constant is likely used to define keys for configuration settings, which are referenced in the Editor component for managing page size and other configurations.

4. THEME_NAME

  • Filename: src/typings/config.ts
  • Line Range: 46-46
THEME_NAME
  • Description: This constant is used to define theme names, which are applied in the Editor component to set the visual appearance based on the user's color scheme preference.

5. ACTION_NAME

  • Filename: src/utils/actions.ts
  • Line Range: 108-108
ACTION_NAME
  • Description: This enumeration likely defines various action names that can be triggered in the editor, such as toggling prettify or navigating pages.

6. EDITOR_ACTIONS

  • Filename: src/utils/actions.ts
  • Line Range: 109-109
EDITOR_ACTIONS
  • Description: This constant likely contains a set of actions specific to the editor, which are used in the MonacoInstance component for handling user interactions.

7. BeginLineNumToLogEventNumMap

  • Filename: src/typings/worker.ts
  • Line Range: 194-194
BeginLineNumToLogEventNumMap
  • Description: This type is used to map line numbers to log event numbers, which is essential for the functionality of the Editor component when selecting log events.

8. getConfig

  • Filename: src/utils/config.ts
  • Line Range: 182-182
getConfig
  • Description: This function retrieves configuration values, which are used in the Editor component to manage settings like page size.

9. setConfig

  • Filename: src/utils/config.ts
  • Line Range: 185-185
setConfig
  • Description: This function sets configuration values, which are used in the Editor component to update settings dynamically.

10. CONFIG_DEFAULT

  • Filename: src/utils/config.ts
  • Line Range: 180-180
CONFIG_DEFAULT
  • Description: This constant likely holds default configuration values, which are referenced in the Editor component when resetting settings.

11. UrlContext

  • Filename: src/contexts/UrlContextProvider.tsx
  • Line Range: 277-277
UrlContext
  • Description: This context is used in the Editor component to manage URL parameters related to log events, which are updated based on user interactions.

12. updateWindowUrlHashParams

  • Filename: src/contexts/UrlContextProvider.tsx
  • Line Range: 273-273
updateWindowUrlHashParams
  • Description: This function updates the URL hash parameters, which is used in the Editor component to reflect the current log event number in the URL.

13. getMapValueWithNearestLessThanOrEqualKey

  • Filename: src/utils/data.ts
  • Line Range: 192-192
getMapValueWithNearestLessThanOrEqualKey
  • Description: This function retrieves a value from a map based on a key, which is used in the Editor component to find log event numbers corresponding to line numbers.

14. getMapKeyByValue

  • Filename: src/utils/data.ts
  • Line Range: 191-191
getMapKeyByValue
  • Description: This function retrieves a key from a map based on a value, which is used in the Editor component to find line numbers corresponding to log event numbers.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also need to add this line:

/* eslint max-lines-per-function: ["error", 170] */

Otherwise it has:

136:16  error  Arrow function has too many lines (127). Maximum allowed is 120  max-lines-per-function

I see in current code const Editor = () => { is a very long arrow function, I don't know why this error was not detected in previous lint...

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (4)
src/components/StatusBar/index.tsx (1)

45-58: Adhere to codebase style guide for boolean comparison.

The toggle action follows the correct pattern for event handling, but there's a minor deviation from the coding guidelines.

According to the project's coding guidelines, you should prefer explicit comparison for boolean expressions.

-                    [HASH_PARAM_NAMES.IS_PRETTIFIED]: !isPrettified,
+                    [HASH_PARAM_NAMES.IS_PRETTIFIED]: false == isPrettified,
src/components/StatusBar/StatusBarToggleButton.tsx (3)

14-24: Remove redundant properties from StatusBarToggleButtonProps interface.

The interface includes both a structured icons object and individual onIcon/offIcon properties, but only the icons object is used in the component implementation. This creates confusion about which properties should be used.

interface StatusBarToggleButtonProps extends IconButtonProps {
    icons?: {
        active?: React.ReactNode;
        inactive?: React.ReactNode;
    };
    isActive: boolean;
-    onIcon?: React.ReactNode;
-    offIcon?: React.ReactNode;
    tooltipPlacement?: TooltipTypeMap["props"]["placement"];
    tooltipTitle?: string;
}

28-36: Update JSDoc to match implementation parameters.

The JSDoc references props.rest, but the component destructures it as just rest. For consistency and clarity, update the JSDoc.

 * @param props.icons Icons to use for the active and inactive states.
 * @param props.isActive
 * @param props.tooltipPlacement Tooltip position.
 * @param props.tooltipTitle Tooltip title, to discern with native HTML tooltip.
-* @param props.rest Other IconButton props.
+* @param rest Other IconButton props.

50-50: Improve readability of conditional tooltip placement.

The current spread operator with a condition works but is not as readable as it could be. Consider using a more explicit approach.

-            {... tooltipPlacement && {placement: tooltipPlacement}}
+            placement={tooltipPlacement}

This change works because the placement prop will be undefined when tooltipPlacement is not provided, which has the same effect as not setting the prop at all.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dc1563f and c8b0e79.

📒 Files selected for processing (7)
  • src/components/Editor/index.tsx (5 hunks)
  • src/components/MenuBar/NavigationBar.tsx (3 hunks)
  • src/components/StatusBar/StatusBarToggleButton.tsx (1 hunks)
  • src/components/StatusBar/index.tsx (4 hunks)
  • src/contexts/StateContextProvider.tsx (10 hunks)
  • src/typings/states.ts (5 hunks)
  • src/utils/actions.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/utils/actions.ts
  • src/components/Editor/index.tsx
  • src/components/MenuBar/NavigationBar.tsx
  • src/contexts/StateContextProvider.tsx
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.{cpp,hpp,java,js,jsx,tpp,ts,tsx}`: - Prefer `false == ` rather than `!`.

**/*.{cpp,hpp,java,js,jsx,tpp,ts,tsx}: - Prefer false == <expression> rather than !<expression>.

  • src/typings/states.ts
  • src/components/StatusBar/StatusBarToggleButton.tsx
  • src/components/StatusBar/index.tsx
🧬 Code Graph Analysis (1)
src/components/StatusBar/index.tsx (4)
src/contexts/UrlContextProvider.tsx (2)
  • UrlContext (277-277)
  • updateWindowUrlHashParams (273-273)
src/utils/actions.ts (1)
  • ACTION_NAME (107-107)
src/typings/url.ts (1)
  • HASH_PARAM_NAMES (37-37)
src/typings/states.ts (1)
  • UI_ELEMENT (105-105)
🔇 Additional comments (7)
src/typings/states.ts (2)

39-39: Addition of PRETTIFY_BUTTON looks good.

The UI_ELEMENT enum has been expanded with a new PRETTIFY_BUTTON entry. This follows the pattern of other UI elements in the codebase.


65-65: Appropriate UI state configuration for the prettify button.

The button is correctly disabled during the UNOPENED and FILE_LOADING states, and enabled during FAST_LOADING and READY states. This is consistent with the behavior of other UI elements that should only be available when a log file is loaded.

Also applies to: 76-76, 87-87, 98-98

src/components/StatusBar/index.tsx (4)

1-24: Imports are organized appropriately.

The new imports required for the prettify feature have been added correctly. The IconButton imports, action names, and context providers are all properly organized.


43-43: Correctly destructured isPrettified from UrlContext.

The isPrettified state is now extracted alongside logEventNum from the UrlContext, allowing it to be used in the component.


60-60: Good use of isDisabled utility.

Correctly utilizes the isDisabled utility to check if the prettify button should be disabled based on the current UI state. This ensures the button follows the same behavior as other UI elements.


87-98: Properly implemented toggle button with clear state indication.

The StatusBarToggleButton implementation looks good with appropriate props for action name, disabled state, icons, and tooltip. The button's state and tooltip text are correctly tied to the isPrettified state.

src/components/StatusBar/StatusBarToggleButton.tsx (1)

52-65: Well-structured toggle button with appropriate accessibility attributes.

The button implementation is solid with good use of aria-pressed for accessibility and correct handling of the icons based on the active state. The size and variant choices are appropriate for a status bar button.

junhaoliao
junhaoliao previously approved these changes Apr 10, 2025
Copy link
Member

@junhaoliao junhaoliao left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just some nit-picking comments. i'll approve again once you accept (you can directly "Add suggestion to batch" in the GitHub UI)

@junhaoliao
Copy link
Member

junhaoliao commented Apr 10, 2025

For the PR title, how about:

feat: Add toggle for log message prettification (resolves #220).

I tend not to mention "button" since we added many different types of toggles in this PR: a status bar button, a URL hash parameter, and a monaco editor action. pretty awesome!

@coderabbitai since we're marking #220 as resolved, please submit an issue for a request to improve the performance of the prettification function. related changes have been submitted to #225 .

Copy link

coderabbitai bot commented Apr 10, 2025

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

Let me gather more information about the prettification implementation and PR #225.

Let me check how the js-beautify library is imported and used in the code.

I'll create a new issue for improving the performance of the prettification function.

@junhaoliao I've created a new issue for improving the performance of the prettification function. The issue is now assigned to you and references the relevant PRs and original feature request. The issue focuses on evaluating the current js-beautify implementation and exploring more performant alternatives, especially for large log files.


🏁 Script executed:

#!/bin/bash
# Let's first look at the original issue #220 to understand the context
gh issue view 220

Length of output: 971


🏁 Script executed:

#!/bin/bash
# Check PR #225 to understand the related changes
gh pr view 225

# Look at the implementation of the prettification function in the current PR
git diff HEAD~1 -- src/services/LogFileManager/index.ts

Length of output: 2922


🏁 Script executed:

#!/bin/bash
# Find where the js-beautify is imported and used
rg -A 3 "js-beautify" --type ts --type tsx

Length of output: 70


🏁 Script executed:

#!/bin/bash
# Create a new issue for improving the performance of the prettification function
gh issue create \
  --title "Improve performance of log message prettification function" \
  --body "## Description

The current implementation of log message prettification uses the 'js-beautify' library, which works well for the initial implementation but may have performance concerns when working with large log files.

## Background
This feature was initially implemented in PR #223, which added toggle functionality for prettifying log messages. PR #225 has made some related changes to this functionality.

## Objective
Investigate and implement performance improvements for the log message prettification feature:

1. Evaluate the performance of the current js-beautify implementation with different log file sizes
2. Consider alternatives or optimizations that could improve performance
3. Implement custom solution that prioritizes performance with large log files
4. Add appropriate tests to verify performance characteristics

## Related
- Original feature implemented in PR #223
- Related changes in PR #225
- Original feature request in issue #220

@junhaoliao" \
  --assignee junhaoliao

Length of output: 1153


@junhaoliao I've created a new issue (#230) for improving the performance of the log message prettification function, as you requested. The issue outlines the current implementation using js-beautify and proposes investigating performance improvements and custom solutions.

I agree with your suggestion for the PR title. "feat: Add toggle for log message prettification (resolves #220)" better represents the comprehensive implementation that includes the status bar button, URL hash parameter, and monaco editor action - not just a button. It's a more accurate description of the work completed in this PR.

@zzxthehappiest zzxthehappiest changed the title feat: Add prettifying toggle button (resolves #220). feat: Add toggle for log message prettification (resolves #220). Apr 11, 2025
@junhaoliao junhaoliao merged commit eb3769a into y-scope:main Apr 11, 2025
3 checks passed
@@ -212,6 +213,11 @@ const getWindowUrlHashParams = () => {
parsed;
}

const isPrettified = hashParams.get(HASH_PARAM_NAMES.IS_PRETTIFIED);
if (null !== isPrettified) {
urlHashParams[HASH_PARAM_NAMES.IS_PRETTIFIED] = "true" === isPrettified;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

urlHashParams[HASH_PARAM_NAMES.IS_PRETTIFIED] = "true" === isPrettified;

What if user types "TRUE"?

setUiState(UI_STATE.FAST_LOADING);
loadPageByCursor(mainWorkerRef.current, cursor, isPrettified ?? false);
}, [
isPrettified,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if the url initially doesn't contain isPrettified property and later decides to add isPrettified=false? This should be a no-op, instead of triggering this function to load twice.


const cursor: CursorType = {
code: CURSOR_CODE.EVENT_NUM,
args: {eventNum: logEventNumRef.current ?? 1},
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest this:

let cursor: CursorType = {code: CURSOR_CODE.LAST_EVENT, args: null};
if (URL_HASH_PARAMS_DEFAULT.logEventNum !== logEventNumRef.current) {
    cursor = {
        code: CURSOR_CODE.EVENT_NUM,
        args: {eventNum: logEventNumRef.current},
    };
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is exactly what we did for filePath update.

@Henry8192
Copy link
Collaborator

@coderabbitai Create an issue about the overflowing StatusBarToggleButton, i.e. prettify button, that causes scroll bars to be appeared in certain zoom scales.

Copy link

coderabbitai bot commented Apr 21, 2025

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

@Henry8192 I've created a new issue about the StatusBarToggleButton overflow problem. The issue describes how the prettify button causes scroll bars to appear at certain zoom scales, and it's now assigned to you for tracking.


🏁 Script executed:

#!/bin/bash
# Create an issue about the overflowing StatusBarToggleButton
gh issue create \
  --title "UI: StatusBarToggleButton (prettify button) overflow causes scroll bars at certain zoom scales" \
  --body "## Description

The StatusBarToggleButton component (prettify button) in the status bar is causing UI overflow issues at certain zoom scales. This overflow results in unwanted scroll bars appearing in the interface.

## Steps to reproduce
1. Open the log viewer application
2. Change browser zoom to various scales (specific zoom percentages to be determined)
3. Observe that scroll bars appear when they shouldn't

## Expected behavior
The StatusBarToggleButton should properly fit within the status bar container at all common zoom levels without causing overflow or introducing scroll bars.

## Additional context
This issue was identified during testing of the prettification toggle feature. The component should be adjusted to either:
- Use responsive sizing
- Have proper overflow handling
- Include constraints to prevent expanding beyond its container

## Related components
- src/components/StatusBar/StatusBarToggleButton.tsx
- src/components/StatusBar/index.tsx" \
  --assignee Henry8192

Length of output: 1184


@Henry8192 I've successfully created issue #252 titled "UI: StatusBarToggleButton (prettify button) overflow causes scroll bars at certain zoom scales". The issue has been assigned to you and includes detailed information about the problem, steps to reproduce, expected behavior, and suggestions for potential fixes. You can access it here: #252

    /\ /\
   (°ᴥ°)  *hops excitedly*
  (\__/)

🎉 Success! 🎊


If you found this review helpful, would you consider giving us a shout-out on X?

Thank you for using CodeRabbit!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants