Skip to content

Conversation

davemarco
Copy link
Contributor

@davemarco davemarco commented Apr 1, 2025

Description

The menu in the new webui is currently static, and does nothing.

This PR adds react-router library which makes the menu links clickable.

In old webui just relied on regular links, but using react router is supposedly more performant.

Note we are using data mode for react-router

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

Pages switch

Summary by CodeRabbit

  • New Features

    • Introduced two new pages: an Ingest Page and a Search Page, providing dedicated interfaces for content management and querying archives.
    • Upgraded the routing system to support dynamic page rendering and smooth, interactive navigation.
  • Style

    • Standardised styling across navigation elements to ensure a consistent user experience.

@davemarco davemarco requested a review from a team as a code owner April 1, 2025 22:58
Copy link
Contributor

coderabbitai bot commented Apr 1, 2025

Walkthrough

The changes introduce a new dependency (react-router), refactor the application's routing by replacing a layout-based approach with a router-based approach, and update related UI components. The AntdApp now uses RouterProvider with a newly created router. The MainLayout component has been modified to utilise Link and Outlet from react-router, with supporting CSS renamed to adhere to a new naming convention. Additionally, two new pages—IngestPage and SearchPage—were added, and the ESLint configuration was updated for TypeScript rules.

Changes

File(s) Change Summary
components/log-viewer-webui/.../package.json Added dependency "react-router": "^7.4.1"; fixed JSON formatting.
components/log-viewer-webui/.../AntdApp.tsx
components/log-viewer-webui/.../router.tsx
Refactored to use RouterProvider and created a new router with nested routes for Ingest and Search pages.
components/log-viewer-webui/.../components/Layout/MainLayout.tsx
components/log-viewer-webui/.../components/Layout/MainLayout.module.css
Updated MainLayout: switched from traditional CSS to CSS modules, renamed sidebar menu variable and CSS selectors, and integrated routing components (Link, Outlet).
components/log-viewer-webui/.../pages/IngestPage.tsx
components/log-viewer-webui/.../pages/SearchPage.tsx
Introduced new functional components for the Ingest and Search pages.
components/log-viewer-webui/.../eslint.config.mjs Added a new rule configuration for TypeScript files: disabled the base "dot-notation" and enabled "@typescript-eslint/dot-notation" with an "error" level.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant App as AntdApp
  participant Router as RouterProvider
  participant Layout as MainLayout
  participant Page as IngestPage/SearchPage

  User->>App: Navigates to a URL
  App->>Router: Forwards request to RouterProvider
  Router->>Layout: Renders MainLayout based on route configuration
  Layout->>Router: Uses Outlet to load child component
  Router-->>Layout: Renders IngestPage or SearchPage
  Layout->>User: Displays the routed content
Loading

Possibly related PRs

Suggested reviewers

  • junhaoliao

📜 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 4d40764 and 748b3c5.

📒 Files selected for processing (5)
  • components/log-viewer-webui/client/eslint.config.mjs (1 hunks)
  • components/log-viewer-webui/client/src/AntdApp.tsx (2 hunks)
  • components/log-viewer-webui/client/src/pages/IngestPage.tsx (1 hunks)
  • components/log-viewer-webui/client/src/pages/SearchPage.tsx (1 hunks)
  • components/log-viewer-webui/client/src/router.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • components/log-viewer-webui/client/src/AntdApp.tsx
  • components/log-viewer-webui/client/src/pages/IngestPage.tsx
  • components/log-viewer-webui/client/eslint.config.mjs
  • components/log-viewer-webui/client/src/pages/SearchPage.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>.

  • components/log-viewer-webui/client/src/router.tsx
🧠 Learnings (2)
📓 Common learnings
Learnt from: davemarco
PR: y-scope/clp#797
File: components/log-viewer-webui/client/src/components/Layout/MainLayout.tsx:2-5
Timestamp: 2025-04-08T22:32:05.367Z
Learning: React Router v7.4.1 uses a different package structure than previous versions. Components can be imported directly from "react-router" (e.g., `import { Link, Outlet } from "react-router";`) rather than from "react-router-dom" as was common in previous versions. Alternatively, DOM-specific components can also be imported using deep imports like `import { Link } from "react-router/dom";`.
components/log-viewer-webui/client/src/router.tsx (3)
Learnt from: davemarco
PR: y-scope/clp#797
File: components/log-viewer-webui/client/src/routes/routes.tsx:1-1
Timestamp: 2025-04-07T23:34:05.489Z
Learning: In React Router v7, `createBrowserRouter` and other router primitives should be imported from `react-router` package, not from `react-router-dom` as in previous versions. This represents a significant change in the library's structure where router primitives are now in the core package.
Learnt from: davemarco
PR: y-scope/clp#797
File: components/log-viewer-webui/client/src/components/Layout/MainLayout.tsx:2-5
Timestamp: 2025-04-08T22:32:05.366Z
Learning: In this codebase using React Router v7.4.1, components should be imported directly from "react-router" (e.g., `import { Link, Outlet } from "react-router";`) rather than from "react-router-dom" as was common in previous versions of React Router.
Learnt from: davemarco
PR: y-scope/clp#797
File: components/log-viewer-webui/client/src/components/Layout/MainLayout.tsx:2-5
Timestamp: 2025-04-08T22:32:05.367Z
Learning: React Router v7.4.1 uses a different package structure than previous versions. Components can be imported directly from "react-router" (e.g., `import { Link, Outlet } from "react-router";`) rather than from "react-router-dom" as was common in previous versions. Alternatively, DOM-specific components can also be imported using deep imports like `import { Link } from "react-router/dom";`.
⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: lint-check (ubuntu-latest)
  • GitHub Check: lint-check (macos-latest)
  • GitHub Check: lint-check (ubuntu-latest)
  • GitHub Check: lint-check (macos-latest)
🔇 Additional comments (4)
components/log-viewer-webui/client/src/router.tsx (4)

1-1: Good import practice for React Router v7.

The use of "react-router" for importing createBrowserRouter follows the best practice for React Router v7, which has a different package structure than previous versions.


3-5: Appropriate component imports.

All the necessary components are properly imported for the router configuration.


8-17: Well-structured router configuration.

The router configuration is clean and follows React Router v7 conventions with a main layout route that contains nested child routes. The use of the Component prop (with capital C) is the correct syntax for React Router v7.


20-20: Clean export syntax.

Exporting the router as default is appropriate for this use case.

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 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.

@davemarco davemarco marked this pull request as draft April 1, 2025 22:58
@davemarco davemarco requested a review from junhaoliao April 1, 2025 22:59
@davemarco davemarco changed the title feat(webuI): Add support for page switching using react-router. feat(webui): Add support for page switching using react-router. Apr 1, 2025
Copy link
Contributor

@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 (11)
components/log-viewer-webui/client/README.md (1)

3-14: Fix the heading hierarchy in the README

The heading structure jumps from level 1 (# Log Viewer WebUI Client) to level 3 (### Start a Dev Server). Heading levels should only increment by one level at a time.

# Log Viewer WebUI Client

-### Start a Dev Server
+## Start a Dev Server
Run:
```bash
npm run start

-### Start a Dev Server for the New WebUI (Under Development)
+## Start a Dev Server for the New WebUI (Under Development)
Run:

npm run antd

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 markdownlint-cli2 (0.17.2)</summary>

3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3

(MD001, heading-increment)

</details>

</details>

</blockquote></details>
<details>
<summary>components/log-viewer-webui/client/src/ui/IngestView.tsx (2)</summary><blockquote>

`1-2`: **Fix import spacing according to lint rules**

There should be 2 empty lines after the import statement when it's not followed by another import.

```diff
import React from "react";

+
+
const IngestView = () => {
🧰 Tools
🪛 GitHub Actions: clp-lint

[error] 1-1: Expected 2 empty lines after import statement not followed by another import import/newline-after-import


3-10: Add JSDoc comment to component function

The linter requires JSDoc comments for functions. Add documentation to describe what this component does.

+/**
+ * Renders the Ingest View page.
+ *
+ * @returns {JSX.Element} The Ingest View component
+ */
const IngestView = () => {
    return (
        <div>
            <h1>Ingest View</h1>
            <p>This is the Ingest view.</p>
        </div>
    );
};
🧰 Tools
🪛 GitHub Actions: clp-lint

[warning] 3-3: Missing JSDoc comment jsdoc/require-jsdoc

components/log-viewer-webui/client/src/ui/SearchView.tsx (2)

1-2: Fix import spacing according to lint rules

There should be 2 empty lines after the import statement when it's not followed by another import.

import React from "react";

+
+
const SearchView = () => {
🧰 Tools
🪛 GitHub Actions: clp-lint

[error] 1-1: Expected 2 empty lines after import statement not followed by another import import/newline-after-import


3-10: Add JSDoc comment to component function

The linter requires JSDoc comments for functions. Add documentation to describe what this component does.

+/**
+ * Renders the Search View page.
+ *
+ * @returns {JSX.Element} The Search View component
+ */
const SearchView = () => {
    return (
        <div>
            <h1>Search View</h1>
            <p>This is the Search view.</p>
        </div>
    );
};
🧰 Tools
🪛 GitHub Actions: clp-lint

[warning] 3-3: Missing JSDoc comment jsdoc/require-jsdoc

components/log-viewer-webui/client/src/AntdApp.tsx (3)

4-5: Fix import spacing according to lint rules

There should be 2 empty lines after import statement when it's not followed by another import.

import React from "react";
import {RouterProvider} from "react-router";


import router from "./routes/routes";

+
+
/**
🧰 Tools
🪛 GitHub Actions: clp-lint

[error] 4-4: Expected 2 empty lines after import statement not followed by another import import/newline-after-import


6-10: Complete the JSDoc comment with return information

The JSDoc comment is missing the return type information. Complete the documentation to describe what the component returns.

/**
 * Renders Web UI app.
 *
- * @return
+ * @returns {JSX.Element} The AntApp component with router configuration
 */

12-12: Fix JSX tag spacing

Remove the space before the closing bracket according to the style rule.

-    return <RouterProvider router={router} />;
+    return <RouterProvider router={router}/>;
🧰 Tools
🪛 GitHub Actions: clp-lint

[error] 12-12: A space is forbidden before closing bracket @stylistic/jsx-tag-spacing

components/log-viewer-webui/client/src/routes/routes.tsx (2)

1-5: Sort imports and fix import spacing

Sort imports according to the linter rules and add required empty lines after imports.

-import {createBrowserRouter} from "react-router";
+import {createBrowserRouter} from "react-router-dom";
+
+import IngestView from "../ui/IngestView";
+import MainLayout from "../ui/MainLayout";
+import SearchView from "../ui/SearchView";

-import MainLayout from "../ui/MainLayout";
-import IngestView from "../ui/IngestView";
-import SearchView from "../ui/SearchView";

+
+
🧰 Tools
🪛 GitHub Actions: clp-lint

[warning] 1-1: Run autofix to sort these imports! simple-import-sort/imports


[error] 5-5: Expected 2 empty lines after import statement not followed by another import import/newline-after-import


7-16: Consider adding a default route

Currently, there's no default route specified when users navigate to the root path "/". Consider adding a redirect to one of the existing views or adding an index route.

const router = createBrowserRouter([
    {
        path: "/",
        Component: MainLayout,
        children: [
+           {index: true, element: <Navigate to="search" replace />},
            {path: "ingest", Component: IngestView},
            {path: "search", Component: SearchView},
        ],
    },
]);

Don't forget to import Navigate:

import {Navigate} from "react-router-dom";
components/log-viewer-webui/client/src/ui/MainLayout.tsx (1)

34-57: Ensure proper path for logo source and verify routing works correctly.

While the layout component looks structurally sound, please verify that:

  1. The logo path /clp-logo.png correctly resolves in your app's public directory
  2. The routing configuration properly uses this layout component with its outlet

Additionally, consider using boolean attributes without redundant values:

            <Sider
                collapsed={collapsed}
-               collapsible={true}
+               collapsible
                theme={"light"}
                width={"150"}
                onCollapse={(value) => {
                    setCollapsed(value);
                }}
            >
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between c7d2072 and 712af39.

⛔ Files ignored due to path filters (2)
  • components/log-viewer-webui/client/package-lock.json is excluded by !**/package-lock.json
  • components/log-viewer-webui/client/public/clp-logo.png is excluded by !**/*.png
📒 Files selected for processing (9)
  • components/log-viewer-webui/client/README.md (1 hunks)
  • components/log-viewer-webui/client/package.json (2 hunks)
  • components/log-viewer-webui/client/src/AntdApp.tsx (1 hunks)
  • components/log-viewer-webui/client/src/main.tsx (2 hunks)
  • components/log-viewer-webui/client/src/routes/routes.tsx (1 hunks)
  • components/log-viewer-webui/client/src/ui/IngestView.tsx (1 hunks)
  • components/log-viewer-webui/client/src/ui/MainLayout.css (1 hunks)
  • components/log-viewer-webui/client/src/ui/MainLayout.tsx (1 hunks)
  • components/log-viewer-webui/client/src/ui/SearchView.tsx (1 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>.

  • components/log-viewer-webui/client/src/ui/MainLayout.tsx
  • components/log-viewer-webui/client/src/routes/routes.tsx
  • components/log-viewer-webui/client/src/ui/SearchView.tsx
  • components/log-viewer-webui/client/src/AntdApp.tsx
  • components/log-viewer-webui/client/src/main.tsx
  • components/log-viewer-webui/client/src/ui/IngestView.tsx
🪛 GitHub Actions: clp-lint
components/log-viewer-webui/client/src/ui/MainLayout.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: Expected a line break before this closing brace @stylistic/object-curly-newline


[error] 14-14: Expected 2 empty lines after import statement not followed by another import import/newline-after-import


[error] 21-21: Need to wrap this literal in a JSX expression @stylistic/jsx-curly-brace-presence


[error] 22-22: Need to wrap this literal in a JSX expression @stylistic/jsx-curly-brace-presence

components/log-viewer-webui/client/src/routes/routes.tsx

[warning] 1-1: Run autofix to sort these imports! simple-import-sort/imports


[error] 5-5: Expected 2 empty lines after import statement not followed by another import import/newline-after-import

components/log-viewer-webui/client/src/ui/SearchView.tsx

[error] 1-1: Expected 2 empty lines after import statement not followed by another import import/newline-after-import


[warning] 3-3: Missing JSDoc comment jsdoc/require-jsdoc

components/log-viewer-webui/client/src/AntdApp.tsx

[error] 4-4: Expected 2 empty lines after import statement not followed by another import import/newline-after-import


[error] 12-12: A space is forbidden before closing bracket @stylistic/jsx-tag-spacing

components/log-viewer-webui/client/src/ui/IngestView.tsx

[error] 1-1: Expected 2 empty lines after import statement not followed by another import import/newline-after-import


[warning] 3-3: Missing JSDoc comment jsdoc/require-jsdoc

🪛 markdownlint-cli2 (0.17.2)
components/log-viewer-webui/client/README.md

3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3

(MD001, heading-increment)

🔇 Additional comments (6)
components/log-viewer-webui/client/src/ui/MainLayout.css (1)

1-16: LGTM! Clean CSS structure that follows best practices.

The CSS styles are well-organized, with clear class names that follow a logical structure. The layout styles ensure the application takes full viewport height, and the logo styling maintains proper proportions while centered in its container.

components/log-viewer-webui/client/src/main.tsx (3)

15-21: LGTM! Clean conditional app rendering implementation.

The conditional rendering approach properly follows the project's style guide with the literal on the left side of the comparison ("true" === VITE_USE_ANTD_APP). Good practice to include the TODO comment with eslint disable explanation for later cleanup.


25-25: Component usage is consistent with React 19.

Good usage of the self-closing tag syntax for the AppComponent, which is consistent with React 19 best practices.


4-4:

❓ Verification inconclusive

Please ensure the AntdApp component is implemented properly.

I notice we're importing AntdApp but don't see this component in the files for review. Make sure this component:

  1. Is properly implemented with RouterProvider from react-router-dom
  2. Is using the proper routing configuration

🏁 Script executed:

#!/bin/bash
# Check if AntdApp.tsx exists and how it's structured
if [ -f "components/log-viewer-webui/client/src/AntdApp.tsx" ]; then
  echo "AntdApp.tsx exists, showing its content:"
  cat "components/log-viewer-webui/client/src/AntdApp.tsx"
else
  echo "AntdApp.tsx file not found!"
fi

# Check if routes.tsx exists (likely imported by AntdApp)
if [ -f "components/log-viewer-webui/client/src/routes.tsx" ]; then
  echo -e "\nroutes.tsx exists, showing its content:"
  cat "components/log-viewer-webui/client/src/routes.tsx"
else
  echo -e "\nroutes.tsx file not found!"
fi

Length of output: 597


AntdApp Component Verification Notice

  • The file AntdApp.tsx is present in the codebase and correctly wraps the application with the <RouterProvider> using the imported router.
  • There is a slight inconsistency: the component imports RouterProvider from "react-router" instead of "react-router-dom" as suggested in the review comment. If the intention is to use the higher-level abstractions from react-router-dom, please update the import accordingly.
  • Ensure that the routing configuration is correctly set up. The router is imported from the relative path "./routes/routes", so please verify that the actual file (likely named routes.tsx, routes.ts, or perhaps an index file in a routes folder) is in the correct location and contains the intended routing definitions.

Please review these points to confirm that the implementation meets the expectations.

components/log-viewer-webui/client/package.json (2)

10-11: LGTM! Well-structured script for conditional app rendering.

The new "antd" script appropriately sets the environment variable needed for the conditional rendering in main.tsx.


21-25:

✅ Verification successful

Add missing react-router-dom dependency.

The MainLayout component uses Link and Outlet components which come from the react-router-dom package, not react-router. You need to add this dependency.

    "antd": "^5.24.5",
    "axios": "^1.7.9",
    "react": "^19.0.0",
    "react-dom": "^19.0.0",
-   "react-router": "^7.4.1"
+   "react-router": "^7.4.1",
+   "react-router-dom": "^7.4.1"

🌐 Web query:

What is the latest version of react-router and react-router-dom? Is version 7.4.1 valid?

💡 Result:

React Router's latest version as of March 2025 is 7.4.1, which is valid and includes several key updates:

Latest Package Versions

  • react-router@7.4.1 ([NPM][8])
  • react-router-dom@7.4.1 (now deprecated, but maintained as a re-export of react-router[8])

Key Changes in v7.x

  1. Simplified Packages

    • react-router-dom merged into react-router[2][9]
    • Install everything via npm install react-router@latest[2]
  2. New Requirements
    Requires:

    • Node.js ≥20
    • React ≥18
    • React-DOM ≥18[2]
  3. Future-First Architecture

    • Relative path handling for nested routes[2]
    • Transition-based state management via React.useTransition[2]
    • Enhanced fetcher lifecycle persistence[2]

Compatibility Notes

  • Migration from v6:
    Non-breaking if all future flags are enabled (like v7_relativeSplatPath)[2]
  • Deprecated Features:
    • Separate react-router-dom package (use react-router imports)[2][8]
    • json/defer utilities (use native Response.json())[2]

Security fixes in 7.4.1 address URL manipulation risks via improved header sanitization[10].

For new projects, the official docs recommend using react-router directly with the new framework-style routing features[14][16].

Citations:


Action: Add the missing react-router-dom dependency

The MainLayout component is importing Link and Outlet from react-router-dom. Although version 7.4.1 is valid for both packages—and even though the react-router-dom package is now maintained as a re-export—the dependency is still required to avoid breaking these imports. Please update your dependencies as follows:

  • File: components/log-viewer-webui/client/package.json (Lines 21–25)

  • Change:

        "antd": "^5.24.5",
        "axios": "^1.7.9",
        "react": "^19.0.0",
        "react-dom": "^19.0.0",
    -   "react-router": "^7.4.1"
    +   "react-router": "^7.4.1",
    +   "react-router-dom": "^7.4.1"

This update ensures that the components relying on react-router-dom are available while remaining consistent with the latest valid versions.

@davemarco davemarco marked this pull request as ready for review April 4, 2025 15:39
@davemarco
Copy link
Contributor Author

@junhaoliao - this is now ready for review

Copy link
Contributor

@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

♻️ Duplicate comments (1)
components/log-viewer-webui/client/src/ui/MainLayout.tsx (1)

2-5: ⚠️ Potential issue

Incorrect import source for React Router components.

You're importing Link and Outlet from "react-router" when they should be imported from "react-router-dom". This could lead to runtime errors.

 import {
     Link,
     Outlet,
-} from "react-router";
+} from "react-router-dom";
🧹 Nitpick comments (2)
components/log-viewer-webui/client/src/ui/SearchView.tsx (1)

4-8: Complete the JSDoc @return tag

The JSDoc comment is missing information for the @return tag. Completing this will improve documentation quality and help other developers understand what the component returns.

/**
 * Provides a search interface that allows users to query archives and visualize search results.
 *
- * @return
+ * @return {JSX.Element} A React component that displays the search interface
 */
components/log-viewer-webui/client/src/ui/MainLayout.tsx (1)

38-38: Consider using dot notation for CSS modules.

While the bracket notation for CSS modules works, dot notation is often preferred for better readability when property names don't contain special characters or hyphens. If you're going to stick with hyphenated class names, this is fine, but consider renaming your CSS classes to use camelCase for consistency with JavaScript naming conventions.

-<Layout className={styles["main-layout"]}>
+<Layout className={styles.mainLayout}>

-<div className={styles["sider-logo-container"]}>
+<div className={styles.siderLogoContainer}>

-className={styles["sider-logo"]}
+className={styles.siderLogo}

This would require updating your CSS module class names as well:

/* In MainLayout.module.css */
.mainLayout { /* styles */ }
.siderLogoContainer { /* styles */ }
.siderLogo { /* styles */ }

Also applies to: 48-48, 51-51

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 712af39 and c36902c.

⛔ Files ignored due to path filters (1)
  • components/log-viewer-webui/client/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (6)
  • components/log-viewer-webui/client/package.json (1 hunks)
  • components/log-viewer-webui/client/src/AntdApp.tsx (2 hunks)
  • components/log-viewer-webui/client/src/routes.tsx (1 hunks)
  • components/log-viewer-webui/client/src/ui/IngestView.tsx (1 hunks)
  • components/log-viewer-webui/client/src/ui/MainLayout.tsx (4 hunks)
  • components/log-viewer-webui/client/src/ui/SearchView.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • components/log-viewer-webui/client/package.json
🧰 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>.

  • components/log-viewer-webui/client/src/ui/IngestView.tsx
  • components/log-viewer-webui/client/src/routes.tsx
  • components/log-viewer-webui/client/src/ui/SearchView.tsx
  • components/log-viewer-webui/client/src/ui/MainLayout.tsx
  • components/log-viewer-webui/client/src/AntdApp.tsx
🧠 Learnings (1)
components/log-viewer-webui/client/src/routes.tsx (1)
Learnt from: davemarco
PR: y-scope/clp#797
File: components/log-viewer-webui/client/src/routes/routes.tsx:1-1
Timestamp: 2025-04-04T15:15:59.432Z
Learning: In React Router v7, `createBrowserRouter` and other router primitives should be imported from `react-router` package, not from `react-router-dom` as in previous versions. This represents a significant change in the library's structure where router primitives are now in the core package.
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: lint-check (macos-latest)
  • GitHub Check: lint-check (macos-latest)
🔇 Additional comments (7)
components/log-viewer-webui/client/src/ui/SearchView.tsx (1)

9-16: Implementation looks good

The component provides a simple placeholder for the Search view that works well with the routing system being implemented. As development progresses, this component can be expanded with actual search functionality.

components/log-viewer-webui/client/src/ui/IngestView.tsx (1)

9-16: Implementation looks good

The component provides a clean placeholder for the Ingest view that works well with the routing system being implemented. This can be expanded with actual ingest functionality as development progresses.

components/log-viewer-webui/client/src/AntdApp.tsx (1)

2-13: Routing implementation looks good

The application now properly uses RouterProvider to implement dynamic page switching, which meets the PR objectives. This change effectively transforms the static menu into an interactive navigation system.

components/log-viewer-webui/client/src/routes.tsx (1)

1-19: Routing configuration is well-structured

The router setup correctly implements nested routes with MainLayout as the parent container, which will maintain consistent navigation elements while switching between views. This is a good pattern for single-page applications.

The import from "react-router" (rather than "react-router-dom") follows the correct pattern for React Router v7.

components/log-viewer-webui/client/src/ui/MainLayout.tsx (3)

17-17: Missing empty lines after import statement.

According to the linting rules, you need two empty lines after import statements that aren't followed by another import.

 import styles from "./MainLayout.module.css";
 

 const {Sider} = Layout;

25-26: JSX string literals need to be wrapped in curly braces.

According to the linting rules, JSX string literals like "Ingest" and "Search" should be wrapped in curly braces.

-    {label: <Link to={"/ingest"}>Ingest</Link>, key: "/ingest", icon: <UploadOutlined/>},
-    {label: <Link to={"/search"}>Search</Link>, key: "/search", icon: <SearchOutlined/>},
+    {label: <Link to={"/ingest"}>{"Ingest"}</Link>, key: "/ingest", icon: <UploadOutlined/>},
+    {label: <Link to={"/search"}>{"Search"}</Link>, key: "/search", icon: <SearchOutlined/>},

58-60: LGTM! Good implementation of nested routing.

The Outlet component is properly wrapped in a Layout component, which will enable proper rendering of nested routes. This is a key part of implementing react-router functionality.

@@ -31,7 +35,7 @@ const MainLayout = () => {
const [collapsed, setCollapsed] = useState(false);

return (
<Layout className={"main-layout"}>
<Layout className={styles["main-layout"]}>
Copy link
Member

Choose a reason for hiding this comment

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

Let's use camelCasing for class names in CSS modules, following the recommendation at https://github.com/css-modules/css-modules/blob/master/docs/naming.md

Then we can use the dot-notation here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

directly accesing them dosen't work with typescript. the linter complains

CSS modules dosent have native typescript support

I tried this plugin but i can't really seem to get it working - https://github.com/mrmckeb/typescript-plugin-css-modules

Let me know if I should just go back to regular css.

Copy link
Member

Choose a reason for hiding this comment

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

Let me quickly check the linter on my end.

Copy link
Member

Choose a reason for hiding this comment

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

https://github.com/mrmckeb/typescript-plugin-css-modules

this plugin is only a Language Service Plugin, which means it only have effects in IDEs (than tsc -b).


How about this:

  1. We always name the classes in camelCase in CSS modules.
  2. If we want to use dot-notation access, we shall disable noPropertyAccessFromIndexSignature in tsconfig.app.json.
  3. Alternatively, we can update eslint.config.mjs to add below block:
{files: ["**/*.ts","**/*.tsx",],rules: {"dot-notation": "off","@typescript-eslint/dot-notation": "error",},},

I will also be adding the above to eslint-config-yscope so the config lib users do not have to config those explicitly.

Let me know what you think.

Copy link
Contributor Author

@davemarco davemarco Apr 8, 2025

Choose a reason for hiding this comment

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

It's neat that you found a fix for this. Turning this off noPropertyAccessFromIndexSignature is okay but not prefered.I still have slight preference to go with regular css. I will add kirk as arbiter @kirkrodrigues

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@kirkrodrigues - no longer needed. I resolved with junhao

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@junhaoliao - i got some error adding "@typescript-eslint/dot-notation": "error",, but it worked just fine with only "dot-notation": "off". If this is an issue let me know.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Might have to do with secondary dependency and make u have to change in eslint yscope
Screenshot 2025-04-08 at 6 25 21 PM

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For now i just added "dot-notation": "off"

Copy link
Member

Choose a reason for hiding this comment

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

Note this creates some problems with antd not supporting underfined className type. So we have to do like this in somecases [key] | "" for antd

I created an issue to track this: react-component/select#1143

If time permits, i'll submit a fix to them. Let me know if there're other components giving you issues.

import SearchView from "./ui/SearchView";


const router = createBrowserRouter([
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
const router = createBrowserRouter([
const ROUTER = createBrowserRouter([

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 took this syntax from their docs. Unless u have strong opinions i would leave it to match

Copy link
Member

Choose a reason for hiding this comment

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

we've been using SNAKE_CASE for global constants but i do get variables are mostly const since EM6. I prefer keeping SNAKE_CASES, but let's quickly check with @kirkrodrigues before we commit.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Router may also make sense if it is a component

Copy link
Member

Choose a reason for hiding this comment

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

I discussed this offline with @kirkrodrigues and here're some consolidated thoughts (a copy of section https://www.notion.so/yscope/WIP-Coding-Guidelines-9a308b847a5343958ba3cb97a850be66?pvs=4#1cf04e4d9e6b80c7ac4fe69b846f5791)

Naming convention for constants in JavaScript / TypeScript

JavaScript doesn't enforce deep immutability for const objects or arrays, so we apply a semantic naming convention to indicate intent:

  • SCREAMING_SNAKE_CASE

    Use this for truly immutable values. This includes:

    • Primitive constant values
      e.g., const SECONDS_IN_MINUTE = 60;
    • Deeply frozen objects
      e.g., const CONFIG = Object.freeze({...});
    • Any value that is intended to remain constant throughout its lifetime.
  • camelCase

    Use this for variables declared with const whose contents may still change (e.g., properties of objects or elements of arrays). This keeps the code readable and avoids excessive SCREAMING_SNAKE_CASE.

Additional Notes

  • React useState variables should not use SCREAMING_SNAKE_CASE, even though the bindings are immutable. Their values can change via re-renders, so they are not considered truly constant.

  • Constant functions should follow normal function naming rules, based on their role:

    • Use PascalCase for JSX functional components (e.g., const MyComponent = () => { ... }), as required by React.
    • Use camelCase for all other functions (e.g., const formatDate = () => { ... }).

    Even though function bindings with const are immutable, the function itself is a callable entity, not a constant value, so we do not use SCREAMING_SNAKE_CASE.

Copy link
Member

Choose a reason for hiding this comment

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

That said, let's make this object deeply frozen since the routes are not expected to be modified elsewhere. We will then rename the object and the filename to ROUTES as well.

Copy link
Contributor Author

@davemarco davemarco Apr 8, 2025

Choose a reason for hiding this comment

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

I think this router has state and manages stuff like breadcrumbs. See their comment.
Screenshot 2025-04-08 at 6 07 18 PM

I dont think its just a config. Anyways for now as router... i left it. Let me know if u disagree

Copy link
Member

Choose a reason for hiding this comment

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

sure. i just thought of another reason that we don't want to make it deeply frozen: if we are to support any plugins like an optional page. this is fine to leave then

Co-authored-by: Junhao Liao <junhao.liao@yscope.com>
Copy link
Contributor Author

@davemarco davemarco left a comment

Choose a reason for hiding this comment

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

responded to ur questions

import SearchView from "./ui/SearchView";


const router = createBrowserRouter([
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 took this syntax from their docs. Unless u have strong opinions i would leave it to match

@@ -31,7 +35,7 @@ const MainLayout = () => {
const [collapsed, setCollapsed] = useState(false);

return (
<Layout className={"main-layout"}>
<Layout className={styles["main-layout"]}>
Copy link
Contributor Author

Choose a reason for hiding this comment

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

directly accesing them dosen't work with typescript. the linter complains

CSS modules dosent have native typescript support

I tried this plugin but i can't really seem to get it working - https://github.com/mrmckeb/typescript-plugin-css-modules

Let me know if I should just go back to regular css.

@@ -10,16 +14,16 @@ import {
MenuProps,
} from "antd";

import "./MainLayout.css";
import styles from "./MainLayout.module.css";


const {Sider} = Layout;

type MenuItem = Required<MenuProps>["items"][number];

const items: MenuItem[] = [
Copy link
Member

Choose a reason for hiding this comment

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

How about SIDEBAR_MENU_ITEMS?

Copy link
Member

Choose a reason for hiding this comment

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

Let's make this deeply frozen with Object.freeze().

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Screenshot 2025-04-08 at 6 04 11 PM
There is some issue with freezing the antd types. I left for now

import SearchView from "./ui/SearchView";


const router = createBrowserRouter([
Copy link
Member

Choose a reason for hiding this comment

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

we've been using SNAKE_CASE for global constants but i do get variables are mostly const since EM6. I prefer keeping SNAKE_CASES, but let's quickly check with @kirkrodrigues before we commit.

@@ -31,7 +35,7 @@ const MainLayout = () => {
const [collapsed, setCollapsed] = useState(false);

return (
<Layout className={"main-layout"}>
<Layout className={styles["main-layout"]}>
Copy link
Member

Choose a reason for hiding this comment

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

Let me quickly check the linter on my end.

@junhaoliao
Copy link
Member

@davemarco
Please also merge main into this branch. I added a fix on a build issue due to TS check errors this morning

import SearchView from "./ui/SearchView";


const router = createBrowserRouter([
Copy link
Member

Choose a reason for hiding this comment

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

I discussed this offline with @kirkrodrigues and here're some consolidated thoughts (a copy of section https://www.notion.so/yscope/WIP-Coding-Guidelines-9a308b847a5343958ba3cb97a850be66?pvs=4#1cf04e4d9e6b80c7ac4fe69b846f5791)

Naming convention for constants in JavaScript / TypeScript

JavaScript doesn't enforce deep immutability for const objects or arrays, so we apply a semantic naming convention to indicate intent:

  • SCREAMING_SNAKE_CASE

    Use this for truly immutable values. This includes:

    • Primitive constant values
      e.g., const SECONDS_IN_MINUTE = 60;
    • Deeply frozen objects
      e.g., const CONFIG = Object.freeze({...});
    • Any value that is intended to remain constant throughout its lifetime.
  • camelCase

    Use this for variables declared with const whose contents may still change (e.g., properties of objects or elements of arrays). This keeps the code readable and avoids excessive SCREAMING_SNAKE_CASE.

Additional Notes

  • React useState variables should not use SCREAMING_SNAKE_CASE, even though the bindings are immutable. Their values can change via re-renders, so they are not considered truly constant.

  • Constant functions should follow normal function naming rules, based on their role:

    • Use PascalCase for JSX functional components (e.g., const MyComponent = () => { ... }), as required by React.
    • Use camelCase for all other functions (e.g., const formatDate = () => { ... }).

    Even though function bindings with const are immutable, the function itself is a callable entity, not a constant value, so we do not use SCREAMING_SNAKE_CASE.

import SearchView from "./ui/SearchView";


const router = createBrowserRouter([
Copy link
Member

Choose a reason for hiding this comment

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

That said, let's make this object deeply frozen since the routes are not expected to be modified elsewhere. We will then rename the object and the filename to ROUTES as well.

@@ -10,16 +14,16 @@ import {
MenuProps,
} from "antd";

import "./MainLayout.css";
import styles from "./MainLayout.module.css";


const {Sider} = Layout;

type MenuItem = Required<MenuProps>["items"][number];

const items: MenuItem[] = [
Copy link
Member

Choose a reason for hiding this comment

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

Let's make this deeply frozen with Object.freeze().

Copy link
Contributor

@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

🧹 Nitpick comments (2)
components/log-viewer-webui/client/src/pages/SearchPage.tsx (1)

1-5: JSDoc return type is missing

The JSDoc comment for the SearchView component has an empty @return tag. You should specify what the component returns for better documentation.

/**
 * Provides a search interface that allows users to query archives and visualize search results.
 *
- * @return
+ * @return {JSX.Element} The rendered Search view
 */
components/log-viewer-webui/client/src/pages/IngestPage.tsx (1)

1-5: JSDoc comment doesn't match implementation

The JSDoc comment states "Presents compression statistics" but the component doesn't actually show any statistics. The comment should be updated to match the actual implementation.

/**
- * Presents compression statistics.
+ * Provides an interface for the ingest functionality.
 *
 * @return
 */

Additionally, the @return tag is empty and should specify the return type.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 6acc4f9 and f8f176c.

⛔ Files ignored due to path filters (1)
  • components/log-viewer-webui/client/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (7)
  • components/log-viewer-webui/client/package.json (1 hunks)
  • components/log-viewer-webui/client/src/AntdApp.tsx (2 hunks)
  • components/log-viewer-webui/client/src/components/Layout/MainLayout.module.css (1 hunks)
  • components/log-viewer-webui/client/src/components/Layout/MainLayout.tsx (4 hunks)
  • components/log-viewer-webui/client/src/pages/IngestPage.tsx (1 hunks)
  • components/log-viewer-webui/client/src/pages/SearchPage.tsx (1 hunks)
  • components/log-viewer-webui/client/src/routes.tsx (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • components/log-viewer-webui/client/src/components/Layout/MainLayout.module.css
🚧 Files skipped from review as they are similar to previous changes (2)
  • components/log-viewer-webui/client/src/routes.tsx
  • components/log-viewer-webui/client/package.json
🧰 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>.

  • components/log-viewer-webui/client/src/pages/SearchPage.tsx
  • components/log-viewer-webui/client/src/AntdApp.tsx
  • components/log-viewer-webui/client/src/pages/IngestPage.tsx
  • components/log-viewer-webui/client/src/components/Layout/MainLayout.tsx
🧬 Code Graph Analysis (2)
components/log-viewer-webui/client/src/pages/SearchPage.tsx (1)
components/webui/imports/ui/SearchView/SearchView.jsx (1)
  • SearchView (42-347)
components/log-viewer-webui/client/src/pages/IngestPage.tsx (1)
components/webui/imports/ui/IngestView/IngestView.jsx (1)
  • IngestView (20-49)
⏰ Context from checks skipped due to timeout of 90000ms (7)
  • GitHub Check: lint-check (ubuntu-latest)
  • GitHub Check: lint-check (ubuntu-latest)
  • GitHub Check: build-macos (macos-15, true)
  • GitHub Check: build-macos (macos-14, true)
  • GitHub Check: build-macos (macos-15, false)
  • GitHub Check: build-macos (macos-13, true)
  • GitHub Check: build-macos (macos-14, false)
🔇 Additional comments (8)
components/log-viewer-webui/client/src/pages/SearchPage.tsx (1)

6-13: Placeholder component needs implementation

The current implementation is just a placeholder and doesn't include the functionality present in the legacy component (from the relevant code snippets). This component needs to be expanded to include actual search functionality such as query input, result visualization, and timeline features.

The current component is a minimal placeholder while the legacy component in components/webui/imports/ui/SearchView/SearchView.jsx has extensive search functionality including:

  • Query handling
  • Search job management
  • Results display
  • Timeline visualization

Will this functionality be implemented in a future PR, or should it be part of this one?

components/log-viewer-webui/client/src/AntdApp.tsx (1)

1-3: Implementation of react-router looks good

The integration of react-router is properly implemented with RouterProvider. This aligns with the PR objective of adding support for page switching.

Also applies to: 12-12

components/log-viewer-webui/client/src/pages/IngestPage.tsx (1)

6-13: Placeholder component needs implementation

Similar to the SearchView, this is just a placeholder and doesn't include the functionality present in the legacy component. The legacy IngestView component from the code snippets includes statistics display and ingestion jobs.

Is the plan to enhance this component in a future PR, or should the full functionality be implemented as part of this PR?

components/log-viewer-webui/client/src/components/Layout/MainLayout.tsx (5)

17-17: Good use of CSS modules

Moving to CSS modules with the .module.css naming convention is a good practice for style encapsulation.


24-26: Good use of constants naming and navigation structure

Renaming to SIDEBAR_MENU_ITEMS follows the convention for constants. The Link components are correctly implemented for navigation.


38-38: CSS module class names are properly applied

The class names are correctly updated to use the CSS module syntax with styles.className.

Also applies to: 48-48, 51-51


55-55: Menu items correctly updated

The menu items reference has been updated to use the renamed constant.


58-60: Proper implementation of nested routes with Outlet

The addition of the Outlet component within the Layout is the correct way to implement nested routes in react-router. This allows child routes to render within the parent layout.

Copy link
Contributor Author

@davemarco davemarco left a comment

Choose a reason for hiding this comment

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

Finished last round of comments

@davemarco davemarco requested a review from junhaoliao April 8, 2025 22:32
Copy link
Contributor

@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 (1)
components/log-viewer-webui/client/eslint.config.mjs (1)

31-31: ESLint rule change appears to support the routing implementation

The addition of "dot-notation": "off" disables the ESLint rule that enforces dot notation for property access. This change likely supports the new react-router implementation, as routing code often uses bracket notation for dynamic property access, especially when working with route parameters or dynamic routes.

While this change is acceptable, consider documenting the rationale behind disabling this rule with a comment in the code to help future maintainers understand why this exception was made.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between f8f176c and 4d40764.

📒 Files selected for processing (2)
  • components/log-viewer-webui/client/eslint.config.mjs (1 hunks)
  • components/log-viewer-webui/client/src/components/Layout/MainLayout.tsx (4 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>.

  • components/log-viewer-webui/client/src/components/Layout/MainLayout.tsx
🧠 Learnings (1)
components/log-viewer-webui/client/src/components/Layout/MainLayout.tsx (2)
Learnt from: davemarco
PR: y-scope/clp#797
File: components/log-viewer-webui/client/src/components/Layout/MainLayout.tsx:2-5
Timestamp: 2025-04-08T22:32:05.367Z
Learning: React Router v7.4.1 uses a different package structure than previous versions. Components can be imported directly from "react-router" (e.g., `import { Link, Outlet } from "react-router";`) rather than from "react-router-dom" as was common in previous versions. Alternatively, DOM-specific components can also be imported using deep imports like `import { Link } from "react-router/dom";`.
Learnt from: davemarco
PR: y-scope/clp#797
File: components/log-viewer-webui/client/src/components/Layout/MainLayout.tsx:2-5
Timestamp: 2025-04-08T22:32:05.366Z
Learning: In this codebase using React Router v7.4.1, components should be imported directly from "react-router" (e.g., `import { Link, Outlet } from "react-router";`) rather than from "react-router-dom" as was common in previous versions of React Router.
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: lint-check (ubuntu-latest)
  • GitHub Check: lint-check (ubuntu-latest)
🔇 Additional comments (5)
components/log-viewer-webui/client/src/components/Layout/MainLayout.tsx (5)

2-5: Import from "react-router" is correct

This import statement correctly uses the React Router v7.4.1 package structure, where components like Link and Outlet can be imported directly from "react-router" rather than "react-router-dom" as in previous versions.


17-17: Good use of CSS modules

Switching to CSS modules provides better encapsulation of styles and prevents class name collisions. This is a good practice for component-scoped styling.


24-27: Good implementation of clickable menu items

The constant naming convention to uppercase (SIDEBAR_MENU_ITEMS) follows best practices for constants. The use of Link components for menu labels successfully implements the clickable menu items requirement for page switching.


38-38: Consistent use of CSS modules syntax

The class names have been correctly updated to use CSS modules syntax. The bracket notation (styles["className"]) is valid, though dot notation (styles.className) is also commonly used when class names don't contain special characters.

Also applies to: 48-48, 51-51, 55-55


58-60: Proper implementation of nested routing

Adding the Outlet component within the Layout is essential for the proper functioning of nested routes. This allows child routes to be rendered in the specified location, enabling the page switching functionality that is the core objective of this PR.

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.

good with a few nits

import SearchView from "./ui/SearchView";


const router = createBrowserRouter([
Copy link
Member

Choose a reason for hiding this comment

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

sure. i just thought of another reason that we don't want to make it deeply frozen: if we are to support any plugins like an optional page. this is fine to leave then

Copy link
Member

Choose a reason for hiding this comment

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

  1. don't forget updating the page component names inside the files.
  2. since this routes.tsx default exports router, let's name this file router.tsx to match the default export name then.

@@ -28,6 +28,7 @@ const EslintConfig = [
...ReactConfigArray,
{
rules: {
"dot-notation": "off",
Copy link
Member

Choose a reason for hiding this comment

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

Let's turn it off for TS only. like instead, we want to add this object to the end of the EslintConfig array:

{

    'files: [

        "**/*.ts",

        "**/*.tsx",

    ],

    rules: {

        "dot-notation": "off",

        "@typescript-eslint/dot-notation": "error",

    },
},

@junhaoliao junhaoliao requested a review from hoophalab April 8, 2025 23:34
@junhaoliao junhaoliao changed the title feat(webui): Add support for page switching using react-router. feat(new-webui): Add support for page switching using react-router. Apr 8, 2025
@junhaoliao
Copy link
Member

i edited the PR title directly to change the scope "webui" -> "new-webui"

@davemarco davemarco requested a review from junhaoliao April 9, 2025 00:30
Copy link
Contributor Author

@davemarco davemarco left a comment

Choose a reason for hiding this comment

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

Fixed latest comments

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.

2 participants