Skip to content

feat(webui): Add file listing UI for submitting compression jobs for local files.#1292

Merged
junhaoliao merged 78 commits into
y-scope:mainfrom
junhaoliao:local-submit
Dec 15, 2025
Merged

feat(webui): Add file listing UI for submitting compression jobs for local files.#1292
junhaoliao merged 78 commits into
y-scope:mainfrom
junhaoliao:local-submit

Conversation

@junhaoliao

@junhaoliao junhaoliao commented Sep 9, 2025

Copy link
Copy Markdown
Member

(Items that are crossed out are to be submitted in future improvement PRs.)

Description

This PR adds an interactive file system tree selector for the compression job submission page in the WebUI, replacing the previous text area input with a user-friendly tree-based file browser.

What Changed

Frontend (WebUI Client)

  • Replaced text input with interactive tree selector: Users can now browse and select files/directories through an expandable tree view instead of manually typing paths
  • Added Zustand-based state management: Implemented fsTreeStore for managing tree state, loading, and expansion
  • Created new API client: Added src/api/os/index.ts for file system operations
  • Lazy loading: Directories are loaded on-demand as users expand nodes, improving performance for large file systems
  • Search support: Users can type paths to quickly navigate to specific directories
  • Error handling: Proper user feedback for failed directory loads and path resolution errors

Backend (WebUI Server)

  • New /api/os/ls endpoint: Lists files and directories at a specified path with proper validation
  • Schema definitions: Added FileListingSchema and FileEntrySchema for type-safe responses
  • Settings integration: Added LogsInputRootDir configuration for server-side path resolution

Infrastructure

  • Docker Compose: Added volume mount configuration for CLP_LOGS_INPUT_DIR_HOST to enable file browsing in containerized environments
  • Settings propagation: Updated controller.py to properly configure client and server settings with logs input paths

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

Manual Testing

Sample logs were stored at /home/junhao/samples.

  • Verified tree loads root directory on component mount - clicking on the input box showed all children under root.
  • Tested directory expansion by clicking both expand icons and node titles
  • Validated search functionality by typing paths. e.g. /home/junhao/samp
    • Also, before the "sample" item was selected, tested directory expansion of other nodes (e.g. /var) by clicking both expand icons and node titles.
  • Confirmed proper error handling (404 error message) when accessing invalid paths
  • Tested path selection and form submission with various file/directory combinations.
  • Verified container environment path resolution by configuring logs_input.directory: "/home/junhao/samples" and restarting the package: in the popup, only files under "/home/junhao/samples are shown.
image image image

Summary by CodeRabbit

  • New Features

    • Interactive tree-based file browser for selecting compression paths with lazy loading and new expand/collapse icons.
    • Client API and utilities to list server files and map them into the tree.
    • Settings now include a persisted filesystem-backed logs input root propagated to client and server.
  • Bug Fixes / Improvements

    • Compression UI now accepts paths as an array and consistently builds server/container paths.
    • Replaced freeform paths textarea with the tree selector and clearer error feedback.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai

coderabbitai Bot commented Sep 9, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Adds a lazy-loading TreeSelect file browser for compression path selection, introduces a client API to list server directories, and propagates/clears filesystem-backed LogsInputRootDir between controller, client, and server; replaces a textarea paths input with an array-based paths input.

Changes

Cohort / File(s) Summary
Backend controller & server settings
components/clp-package-utils/clp_package_utils/controller.py, components/webui/server/settings.json, components/webui/server/src/routes/api/compress/index.ts
Import CONTAINER_INPUT_LOGS_ROOT_DIR in controller; controller now sets/clears LogsInputRootDir for FS-backed LogsInput and writes updated client/server settings JSONs after applying updates; server settings adds LogsInputRootDir; compress route uses settings.LogsInputRootDir when building input paths.
Client public settings & runtime types
components/webui/client/public/settings.json, components/webui/client/src/settings.ts
Adds public LogsInputRootDir key ("/") and extends Settings type with `LogsInputRootDir: string
Filesystem API & schema types
components/webui/client/src/api/os/index.ts, components/webui/common/src/schemas/os.ts
Adds client API listFiles(path: string): Promise<FileListing> hitting /api/os/ls; exposes FileEntry type alongside FileListing in shared schemas.
Tree-select path picker (new UI)
components/webui/client/src/pages/IngestPage/Compress/PathsSelectFormItem/index.tsx, components/webui/client/src/pages/IngestPage/Compress/PathsSelectFormItem/SwitcherIcon.tsx, components/webui/client/src/pages/IngestPage/Compress/PathsSelectFormItem/typings.ts, components/webui/client/src/pages/IngestPage/Compress/PathsSelectFormItem/utils.ts
Adds PathsSelectFormItem with lazy-loading multi-select TreeSelect, SwitcherIcon, ROOT_PATH/ROOT_NODE constants, list-height helper, path normalization, and server-prefix helpers (addServerPrefix/removeServerPrefix) plus toTreeNode mapper and load deduplication.
Compress page integration
components/webui/client/src/pages/IngestPage/Compress/index.tsx
Replaces textarea-based paths input with PathsSelectFormItem; changes FormValues.paths from string to string[] and sends the array directly in the compress payload.
Removed/trimmed exports & components
components/webui/client/src/pages/IngestPage/Compress/PathsInputFormItem.tsx, components/webui/client/src/pages/IngestPage/Compress/validation.ts, components/webui/common/src/schemas/compression.ts
Removes old textarea PathsInputFormItem component, removes validateAbsolutePaths export from validation, and stops exporting AbsolutePathSchema (schema still present).

Sequence Diagram

sequenceDiagram
    participant User as User (Browser)
    participant UI as PathsSelectFormItem (TreeSelect)
    participant Utils as Path Utils (addServerPrefix / toTreeNode)
    participant API as Client API (/api/os/ls)
    participant Server as Backend FS service

    User->>UI: Expand tree node (e.g., "/")
    activate UI

    UI->>UI: Check loadedPathsRef (dedupe)
    alt already loading/loaded
        UI-->>User: Use existing children
    else first load
        UI->>UI: mark path as loading
        UI->>Utils: addServerPrefix(path)
        Utils->>API: GET /api/os/ls?path=<encoded>
        activate API

        API->>Server: Request directory listing
        Server-->>API: FileEntry[] response
        API-->>Utils: FileListing
        deactivate API

        Utils->>Utils: toTreeNode(FileEntry[]) -> TreeNode[]
        Utils->>UI: return nodes
        UI->>UI: merge nodes into treeData, unmark loading
        UI-->>User: Render expanded children
    end

    alt error during load
        UI->>UI: unmark loading
        UI-->>User: message.error(...)
    end
    deactivate UI
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~40 minutes

  • Areas needing extra attention:
    • components/webui/client/src/pages/IngestPage/Compress/PathsSelectFormItem/utils.ts — correctness of addServerPrefix / removeServerPrefix and error handling when LogsInputRootDir is unset.
    • components/webui/client/src/pages/IngestPage/Compress/PathsSelectFormItem/index.tsx — load deduplication (loadedPathsRef), concurrency, and merging of treeData.
    • components/webui/server/src/routes/api/compress/index.ts and components/clp-package-utils/clp_package_utils/controller.py — consistency in path construction and persistence/propagation of LogsInputRootDir between controller, client, and server.

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: replacing a textarea with a file listing UI (tree selector) for submitting compression jobs for local files.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f5e487b and 1934d79.

📒 Files selected for processing (3)
  • components/clp-package-utils/clp_package_utils/controller.py (2 hunks)
  • components/webui/client/public/settings.json (1 hunks)
  • components/webui/client/src/settings.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{cpp,hpp,java,js,jsx,tpp,ts,tsx}

⚙️ CodeRabbit configuration file

  • Prefer false == <expression> rather than !<expression>.

Files:

  • components/webui/client/src/settings.ts
🧠 Learnings (4)
📚 Learning: 2025-11-29T08:03:34.272Z
Learnt from: junhaoliao
Repo: y-scope/clp PR: 1688
File: components/webui/server/src/routes/api/os/index.ts:46-46
Timestamp: 2025-11-29T08:03:34.272Z
Learning: In the WebUI server (components/webui/server), the file listing API relies on container isolation for security rather than explicit path validation like ALLOWED_BASE_PATH. The service runs in a Docker container with controlled volume mappings, which provides the security boundary.

Applied to files:

  • components/webui/client/public/settings.json
📚 Learning: 2025-06-16T13:05:27.349Z
Learnt from: davemarco
Repo: y-scope/clp PR: 1015
File: components/log-viewer-webui/server/src/routes/static.ts:65-70
Timestamp: 2025-06-16T13:05:27.349Z
Learning: In components/log-viewer-webui/server/src/routes/static.ts, when decorateReply is set to true in fastifyStatic configuration, the reply.sendFile() method automatically uses the root directory configured in the static plugin registration, eliminating the need to pass the root directory as a second parameter.

Applied to files:

  • components/webui/client/public/settings.json
📚 Learning: 2025-10-17T19:59:25.596Z
Learnt from: junhaoliao
Repo: y-scope/clp PR: 1178
File: components/clp-package-utils/clp_package_utils/controller.py:315-315
Timestamp: 2025-10-17T19:59:25.596Z
Learning: In components/clp-package-utils/clp_package_utils/controller.py, worker log directories (compression_worker, query_worker, reducer) created via `mkdir()` do not need `_chown_paths_if_root()` calls because directories are created with the same owner as the script caller. This differs from infrastructure service directories (database, queue, Redis, results cache) which do require explicit ownership changes.

Applied to files:

  • components/clp-package-utils/clp_package_utils/controller.py
📚 Learning: 2025-10-07T07:54:32.427Z
Learnt from: junhaoliao
Repo: y-scope/clp PR: 1178
File: components/clp-py-utils/clp_py_utils/clp_config.py:47-47
Timestamp: 2025-10-07T07:54:32.427Z
Learning: In components/clp-py-utils/clp_py_utils/clp_config.py, the CONTAINER_AWS_CONFIG_DIRECTORY constant is intentionally set to pathlib.Path("/") / ".aws" (i.e., `/.aws`) rather than a user-specific home directory. This hardcoded path is part of the container orchestration design.

Applied to files:

  • components/clp-package-utils/clp_package_utils/controller.py
🧬 Code graph analysis (1)
components/clp-package-utils/clp_package_utils/controller.py (3)
components/webui/server/src/routes/api/compress/typings.ts (1)
  • CONTAINER_INPUT_LOGS_ROOT_DIR (7-7)
components/clp-py-utils/clp_py_utils/clp_config.py (1)
  • StorageType (161-163)
components/clp-py-utils/clp_py_utils/core.py (1)
  • resolve_host_path_in_container (82-103)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: package-image
  • GitHub Check: lint-check (macos-15)
  • GitHub Check: lint-check (ubuntu-24.04)
  • GitHub Check: build (macos-15)
  • GitHub Check: build (ubuntu-24.04)
🔇 Additional comments (5)
components/webui/client/src/settings.ts (1)

8-8: LGTM!

The type expansion correctly reflects the new LogsInputRootDir configuration field. The nullable type (string | null) properly aligns with the controller logic that sets this to None when logs input type is not filesystem-backed.

components/webui/client/public/settings.json (1)

5-5: Configuration value is correct for standalone development.

The default value "/" intentionally differs from the server's default ("/mnt/logs") to support debugging when the WebUI dev server runs standalone without the full package, as noted in your earlier comment.

components/clp-package-utils/clp_package_utils/controller.py (3)

31-31: LGTM!

The import of CONTAINER_INPUT_LOGS_ROOT_DIR is correctly sourced from the configuration module for use in the LogsInputRootDir propagation logic below.


745-750: LogsInputRootDir propagation logic is correct.

The conditional logic properly handles both cases as requested in previous feedback:

  • When logs input type is FS, it propagates CONTAINER_INPUT_LOGS_ROOT_DIR to both client and server settings for filesystem-backed path resolution.
  • When logs input type is not FS, it clears the value by setting it to None, ensuring the configuration accurately reflects the input type.

752-759: Client settings update and write sequence is correct.

The restored write operation for client settings properly applies the LogsInputRootDir updates computed above. The sequence (resolve path → read/update → write) ensures all configuration changes, including the new LogsInputRootDir field, are persisted correctly.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@junhaoliao junhaoliao changed the title feat(webui): Add compression job submission with input file listing. feat(webui): Add compression job submission for local files only, with input file listing. Sep 9, 2025
junhaoliao and others added 27 commits September 9, 2025 02:30
Resolved conflicts by accepting origin/main changes:
- Refactored compression job submission to use common schemas
- Updated webui components to use new architecture
- Moved compression schema from server to common package
- Updated server settings to include archive output configuration
- Simplified SearchControls implementation
- Updated start_clp.py to use DockerComposeController

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Replace http-status-codes with constants from http2
- Update import to use @webui/common/schemas/common
- Fix lint errors in os/index.ts

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
…bmission

- Restore the TreeSelect-based file browser that was lost during merge
- Extract file tree logic into useFileTree custom hook for better organization
- Fix all lint and TypeScript compilation errors
- Update compression API call to use new schema format with jobId response

The file lister provides an interactive tree view for selecting files/directories
to compress, replacing the simple text input from origin/main.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@junhaoliao junhaoliao requested a review from davemarco December 11, 2025 01:39
server_settings_json_updates["PrestoPort"] = None

if StorageType.FS == self._clp_config.logs_input.type:
client_settings_json_updates["LogsInputDir"] = str(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I just realized i dont think we need LogsInputDir at all? At first i was confused, but maybe this is correct, and it just for docker mounting? we should probably test with a non-root mount with full package. If that is correct we should remove here and in settings.json

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Right, i was originally treating the user configured path as root but ended up not doing so, so this path is no longer needed. thanks for catching it

/**
* Height of the dropdown list in pixels.
*/
const LIST_HEIGHT_PX = 512;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
const LIST_HEIGHT_PX = 512;
const LIST_HEIGHT_PX = 450;

@junhaoliao junhaoliao Dec 11, 2025

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

i removed it and now change the height dynamically. see bff4e55

/**
* Tree node for Ant Design TreeSelect in simple mode (treeDataSimpleMode).
*/
interface TreeNode extends Omit<GetProp<TreeSelectProps, "treeData">[number], "label"> {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I prefer the custom type since we are using it for rootNode. Like we are adding more fields that just id

…pages/IngestPage/Compress/PathsSelectFormItem/SwitcherIcon.tsx

Co-authored-by: davemarco <83603688+davemarco@users.noreply.github.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 459afc5 and 7f4eb64.

📒 Files selected for processing (1)
  • components/webui/client/src/pages/IngestPage/Compress/PathsSelectFormItem/SwitcherIcon.tsx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{cpp,hpp,java,js,jsx,tpp,ts,tsx}

⚙️ CodeRabbit configuration file

  • Prefer false == <expression> rather than !<expression>.

Files:

  • components/webui/client/src/pages/IngestPage/Compress/PathsSelectFormItem/SwitcherIcon.tsx
🧠 Learnings (1)
📓 Common learnings
Learnt from: Bill-hbrhbr
Repo: y-scope/clp PR: 1122
File: components/core/src/clp/clp/CMakeLists.txt:175-195
Timestamp: 2025-07-23T09:54:45.185Z
Learning: In the CLP project, when reviewing CMakeLists.txt changes that introduce new compression library dependencies (BZip2, LibLZMA, LZ4, ZLIB), the team prefers to address conditional linking improvements in separate PRs rather than expanding the scope of focused migration PRs like the LibArchive task-based installation migration.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: package-image
🔇 Additional comments (4)
components/webui/client/src/pages/IngestPage/Compress/PathsSelectFormItem/SwitcherIcon.tsx (4)

1-7: LGTM!

The imports are clean and all are used appropriately in the component.


10-12: LGTM!

The type derivation is well-structured and ensures type safety by extracting prop types directly from Ant Design's TreeSelectProps.


27-27: LGTM!

The default export is appropriate for this component.


22-24: Consider adding an explicit return type annotation.

While TypeScript can infer the return type, explicitly annotating it improves code clarity and catches potential type errors earlier.

Apply this diff:

-const SwitcherIcon = ({expanded}: SwitcherIconProps) => (expanded ?
+const SwitcherIcon = ({expanded}: SwitcherIconProps): React.ReactElement => (expanded ?
     <MinusOutlined style={{color: "grey"}}/> :
     <PlusOutlined style={{color: "grey"}}/>);
⛔ Skipped due to learnings
Learnt from: junhaoliao
Repo: y-scope/clp PR: 937
File: components/log-viewer-webui/client/src/AntdApp.tsx:16-24
Timestamp: 2025-05-29T20:33:40.653Z
Learning: In components/log-viewer-webui React codebase: Return type annotations (like `: JSX.Element`) are unnecessary and not preferred for React components in JSX/TSX files.

Comment on lines +15 to +21
/**
* Icon component for tree node expand/collapse state.
*
* @param props
* @param props.expanded Whether the node is expanded (passed by Ant Design).
* @return
*/

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Complete the @return JSDoc tag.

The @return tag on line 20 is missing its description. Add a brief description of what the component returns.

Apply this diff:

  * @param props
  * @param props.expanded Whether the node is expanded (passed by Ant Design).
- * @return
+ * @return A grey plus or minus icon based on the expanded 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
/**
* Icon component for tree node expand/collapse state.
*
* @param props
* @param props.expanded Whether the node is expanded (passed by Ant Design).
* @return
*/
/**
* Icon component for tree node expand/collapse state.
*
* @param props
* @param props.expanded Whether the node is expanded (passed by Ant Design).
* @return A grey plus or minus icon based on the expanded state.
*/
🤖 Prompt for AI Agents
In
components/webui/client/src/pages/IngestPage/Compress/PathsSelectFormItem/SwitcherIcon.tsx
around lines 15 to 21, the JSDoc @return tag is missing its description; update
the JSDoc so the @return line briefly describes what the component returns
(e.g., "JSX.Element — the icon element representing expanded/collapsed state"),
keeping the wording concise and accurate to indicate a React element is
returned.

…electFormItem; remove hardcoded LIST_HEIGHT_PX.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (1)
components/webui/client/src/pages/IngestPage/Compress/PathsSelectFormItem/utils.ts (1)

60-71: Address the prefix matching false positive risk.

The removeServerPrefix function at line 66 uses startsWith() without verifying path-segment boundaries, allowing false matches (e.g., /mnt/logs-archive incorrectly matching /mnt/logs). The suggested fix is valid: normalize paths and check for exact prefix match or prefix with trailing slash before stripping.

 const removeServerPrefix = (serverPath: string): string => {
     const logsInputRootDir = settings.LogsInputRootDir;
     if (null === logsInputRootDir) {
         throw new Error("LogsInputRootDir is not configured.");
     }
+    const prefix = logsInputRootDir.endsWith("/") ?
+        logsInputRootDir.slice(0, -1) :
+        logsInputRootDir;
+    const normalized = serverPath.replace(/\/{2,}/g, "/");
 
-    const stripped = serverPath.startsWith(logsInputRootDir) ?
-        serverPath.slice(logsInputRootDir.length) :
-        serverPath;
+    const shouldStrip = normalized === prefix || normalized.startsWith(`${prefix}/`);
+    const stripped = shouldStrip ?
+        normalized.slice(prefix.length) :
+        normalized;
 
     return joinPath(ROOT_PATH, stripped);
 };
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7f4eb64 and bff4e55.

📒 Files selected for processing (3)
  • components/webui/client/src/pages/IngestPage/Compress/PathsSelectFormItem/index.tsx (1 hunks)
  • components/webui/client/src/pages/IngestPage/Compress/PathsSelectFormItem/typings.ts (1 hunks)
  • components/webui/client/src/pages/IngestPage/Compress/PathsSelectFormItem/utils.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{cpp,hpp,java,js,jsx,tpp,ts,tsx}

⚙️ CodeRabbit configuration file

  • Prefer false == <expression> rather than !<expression>.

Files:

  • components/webui/client/src/pages/IngestPage/Compress/PathsSelectFormItem/typings.ts
  • components/webui/client/src/pages/IngestPage/Compress/PathsSelectFormItem/index.tsx
  • components/webui/client/src/pages/IngestPage/Compress/PathsSelectFormItem/utils.ts
🧠 Learnings (1)
📓 Common learnings
Learnt from: Bill-hbrhbr
Repo: y-scope/clp PR: 1122
File: components/core/src/clp/clp/CMakeLists.txt:175-195
Timestamp: 2025-07-23T09:54:45.185Z
Learning: In the CLP project, when reviewing CMakeLists.txt changes that introduce new compression library dependencies (BZip2, LibLZMA, LZ4, ZLIB), the team prefers to address conditional linking improvements in separate PRs rather than expanding the scope of focused migration PRs like the LibArchive task-based installation migration.
🧬 Code graph analysis (2)
components/webui/client/src/pages/IngestPage/Compress/PathsSelectFormItem/typings.ts (1)
components/webui/client/src/pages/IngestPage/Compress/PathsSelectFormItem/utils.ts (2)
  • ROOT_PATH (113-113)
  • TreeNode (109-109)
components/webui/client/src/pages/IngestPage/Compress/PathsSelectFormItem/utils.ts (3)
components/webui/client/src/settings.ts (1)
  • settings (39-39)
components/webui/client/src/pages/IngestPage/Compress/PathsSelectFormItem/typings.ts (1)
  • ROOT_PATH (20-20)
components/webui/common/src/schemas/os.ts (1)
  • FileEntry (39-39)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: package-image
  • GitHub Check: lint-check (ubuntu-24.04)
  • GitHub Check: build (ubuntu-24.04)
  • GitHub Check: lint-check (macos-15)
  • GitHub Check: build (macos-15)
🔇 Additional comments (5)
components/webui/client/src/pages/IngestPage/Compress/PathsSelectFormItem/typings.ts (1)

1-21: LGTM! Clean constants definition.

The ROOT_PATH and ROOT_NODE constants are well-defined with appropriate use of Object.freeze for immutability. The structure aligns with the TreeNode type requirements.

components/webui/client/src/pages/IngestPage/Compress/PathsSelectFormItem/index.tsx (2)

57-69: LGTM! Correct use of comparison style.

The implementation correctly follows the coding guideline by using false === existingIds.has(n.id) (line 60) and 0 < newNodes.length (line 62) rather than negation operators. The deduplication logic is sound.


85-97: Good error handling with user feedback.

The error handling properly logs errors, removes failed paths from the dedupe set, and provides user-friendly error messages via message.error.

components/webui/client/src/pages/IngestPage/Compress/PathsSelectFormItem/utils.ts (2)

14-16: LGTM! Custom TreeNode type is appropriate.

The custom TreeNode interface extending Ant Design's type with an explicit id field is well-justified given the usage in ROOT_NODE and the tree structure requirements.


101-101: LGTM! Correct comparison style.

The code correctly follows the coding guideline by using false === fileEntry.isExpandable instead of !fileEntry.isExpandable.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bff4e55 and f5e487b.

📒 Files selected for processing (4)
  • components/webui/client/src/pages/IngestPage/Compress/PathsSelectFormItem/SwitcherIcon.tsx (1 hunks)
  • components/webui/client/src/pages/IngestPage/Compress/PathsSelectFormItem/index.tsx (1 hunks)
  • components/webui/client/src/pages/IngestPage/Compress/PathsSelectFormItem/typings.ts (1 hunks)
  • components/webui/client/src/pages/IngestPage/Compress/PathsSelectFormItem/utils.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{cpp,hpp,java,js,jsx,tpp,ts,tsx}

⚙️ CodeRabbit configuration file

  • Prefer false == <expression> rather than !<expression>.

Files:

  • components/webui/client/src/pages/IngestPage/Compress/PathsSelectFormItem/SwitcherIcon.tsx
  • components/webui/client/src/pages/IngestPage/Compress/PathsSelectFormItem/index.tsx
  • components/webui/client/src/pages/IngestPage/Compress/PathsSelectFormItem/typings.ts
  • components/webui/client/src/pages/IngestPage/Compress/PathsSelectFormItem/utils.ts
🧠 Learnings (3)
📓 Common learnings
Learnt from: Bill-hbrhbr
Repo: y-scope/clp PR: 1122
File: components/core/src/clp/clp/CMakeLists.txt:175-195
Timestamp: 2025-07-23T09:54:45.185Z
Learning: In the CLP project, when reviewing CMakeLists.txt changes that introduce new compression library dependencies (BZip2, LibLZMA, LZ4, ZLIB), the team prefers to address conditional linking improvements in separate PRs rather than expanding the scope of focused migration PRs like the LibArchive task-based installation migration.
📚 Learning: 2025-05-29T20:33:40.653Z
Learnt from: junhaoliao
Repo: y-scope/clp PR: 937
File: components/log-viewer-webui/client/src/AntdApp.tsx:16-24
Timestamp: 2025-05-29T20:33:40.653Z
Learning: In components/log-viewer-webui React codebase: Return type annotations (like `: JSX.Element`) are unnecessary and not preferred for React components in JSX/TSX files.

Applied to files:

  • components/webui/client/src/pages/IngestPage/Compress/PathsSelectFormItem/SwitcherIcon.tsx
📚 Learning: 2025-11-29T08:03:34.272Z
Learnt from: junhaoliao
Repo: y-scope/clp PR: 1688
File: components/webui/server/src/routes/api/os/index.ts:46-46
Timestamp: 2025-11-29T08:03:34.272Z
Learning: In the WebUI server (components/webui/server), the file listing API relies on container isolation for security rather than explicit path validation like ALLOWED_BASE_PATH. The service runs in a Docker container with controlled volume mappings, which provides the security boundary.

Applied to files:

  • components/webui/client/src/pages/IngestPage/Compress/PathsSelectFormItem/utils.ts
🧬 Code graph analysis (2)
components/webui/client/src/pages/IngestPage/Compress/PathsSelectFormItem/index.tsx (4)
components/webui/client/src/pages/IngestPage/Compress/PathsSelectFormItem/typings.ts (2)
  • TreeNode (25-25)
  • ROOT_NODE (27-27)
components/webui/client/src/pages/IngestPage/Compress/PathsSelectFormItem/utils.ts (3)
  • getListHeight (103-103)
  • addServerPrefix (102-102)
  • toTreeNode (105-105)
components/webui/common/src/schemas/os.ts (1)
  • FileEntry (39-39)
components/webui/client/src/api/os/index.ts (1)
  • listFiles (19-19)
components/webui/client/src/pages/IngestPage/Compress/PathsSelectFormItem/utils.ts (3)
components/webui/client/src/settings.ts (1)
  • settings (39-39)
components/webui/client/src/pages/IngestPage/Compress/PathsSelectFormItem/typings.ts (2)
  • ROOT_PATH (28-28)
  • TreeNode (25-25)
components/webui/common/src/schemas/os.ts (1)
  • FileEntry (39-39)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: package-image
  • GitHub Check: build (ubuntu-24.04)
  • GitHub Check: build (macos-15)
  • GitHub Check: lint-check (macos-15)
  • GitHub Check: lint-check (ubuntu-24.04)
🔇 Additional comments (9)
components/webui/client/src/pages/IngestPage/Compress/PathsSelectFormItem/typings.ts (1)

1-29: LGTM! Well-structured type definitions.

The TreeNode interface is properly defined for Ant Design TreeSelect, and using Object.freeze for ROOT_NODE ensures immutability. The structure is clean and appropriate for the file browser implementation.

components/webui/client/src/pages/IngestPage/Compress/PathsSelectFormItem/SwitcherIcon.tsx (1)

1-27: LGTM! Clean icon component implementation.

The type extraction from TreeSelectProps is elegant, and the component correctly renders the appropriate icon based on the expanded state. The implementation is straightforward and type-safe.

components/webui/client/src/pages/IngestPage/Compress/PathsSelectFormItem/index.tsx (4)

40-54: LGTM! Proper state initialization and effect cleanup.

The resize listener is correctly registered and cleaned up, and the initial state values are appropriate for lazy loading the tree data.


56-85: LGTM! Solid deduplication and error handling.

The ref-based deduplication strategy avoids unnecessary re-renders while preventing duplicate loads. The error handling correctly removes failed paths from the loaded set, allowing retry. Good adherence to the coding guideline with false === existingIds.has(n.id) on line 62.


87-103: LGTM! Type-safe callbacks with good error handling.

The type guard on line 88 correctly follows the coding guideline with "string" !== typeof value. Error messages are user-friendly and provide appropriate feedback for loading failures.


105-129: LGTM! Properly configured TreeSelect for lazy loading.

The TreeSelect configuration is appropriate for multi-select with lazy loading. The combination of treeCheckable, showCheckedStrategy={TreeSelect.SHOW_PARENT}, and loadData provides a good user experience for path selection.

components/webui/client/src/pages/IngestPage/Compress/PathsSelectFormItem/utils.ts (3)

10-43: LGTM! Clean utility implementations.

getListHeight provides a responsive dropdown size clamped to reasonable bounds, and joinPath correctly normalizes POSIX paths by filtering empty segments and collapsing consecutive slashes.


65-79: LGTM! Proper validation and path construction.

addServerPrefix correctly validates that LogsInputRootDir is configured before constructing the full server path. The error message is clear and actionable.


81-98: LGTM! Correct tree node conversion with guideline adherence.

Line 93 correctly follows the coding guideline with false === fileEntry.isExpandable. The function properly maps API responses to TreeSelect nodes.

The parentPath parameter usage (for pId) versus fileEntry.parentPath (for path construction) is intentional and consistent with how it's called in index.tsx line 80, though renaming to parentId could improve clarity as noted in previous feedback.

@junhaoliao junhaoliao requested a review from davemarco December 11, 2025 22:31

/**
* Form item with TreeSelect for selecting file paths for compression.
* Supports lazy loading and search with auto-expand.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
* Supports lazy loading and search with auto-expand.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

we got rid of search

@davemarco davemarco left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Okay i am ready to approve this, just want to test the small new height thing when bakers are back up

@davemarco

Copy link
Copy Markdown
Contributor

okay i retested height. I approve

@junhaoliao junhaoliao merged commit 1351bd6 into y-scope:main Dec 15, 2025
19 checks passed
@junhaoliao junhaoliao deleted the local-submit branch December 15, 2025 20:44
davidlion pushed a commit to davidlion/clp that referenced this pull request Jan 17, 2026
…local files. (y-scope#1292)

Co-authored-by: davemarco <83603688+davemarco@users.noreply.github.com>
junhaoliao added a commit to junhaoliao/clp that referenced this pull request May 17, 2026
…local files. (y-scope#1292)

Co-authored-by: davemarco <83603688+davemarco@users.noreply.github.com>
junhaoliao added a commit to junhaoliao/clp that referenced this pull request May 17, 2026
…local files. (y-scope#1292)

Co-authored-by: davemarco <83603688+davemarco@users.noreply.github.com>
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