Skip to content

feat(api-web): add "All" pagination option and per-table search filter#3493

Open
kdhulipala-wq wants to merge 2 commits into
NVIDIA:mainfrom
kdhulipala-wq:kcd-paginate-all
Open

feat(api-web): add "All" pagination option and per-table search filter#3493
kdhulipala-wq wants to merge 2 commits into
NVIDIA:mainfrom
kdhulipala-wq:kcd-paginate-all

Conversation

@kdhulipala-wq

Copy link
Copy Markdown
Contributor

This PR restores easy searching of long list pages in the NICo web-UI, which the paginated views had made harder (browser Ctrl-F only sees the current page).

  • "All" pagination option: adds an All choice (limit=0) alongside 25 / 50 / 100 in the shared pagination footer, so that an entire list renders on one page.
    • Works out of the box for the in-memory paginated pages (Managed Hosts, Machine Interfaces, Explored Endpoints, Machines, Expected Machines, NVLink, Machine Validation, DPU Versions).
    • Updates the three DB page-count paginated handlers (Compute Allocations, Instance Types, Network Security Groups), which previously reset limit=0 to a default — to honor "All" via a new PageContext::all() helper.
  • Per-table search bar: table_filter.js auto-attaches a live filter box above every list table (table.sortable.overview) with 5+ rows. This is case-insensitive, multi-term AND matching, a "Showing X of Y" count, "No matching rows" state, and Esc to clear. Benefits every list screen, including DPU Network Status.

Change appears as the folloing:
pagination

Signed-off-by: Krishna Dhulipala <kdhulipala@nvidia.com>
@kdhulipala-wq kdhulipala-wq requested a review from a team as a code owner July 14, 2026 17:31
@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Summary by CodeRabbit

  • New Features

    • Added an “All” page-size option for compute allocations, instance types, and network security groups.
    • Added client-side filtering to larger sortable tables, including match counts and Escape-to-clear support.
    • Added filtering controls styling and supporting static assets.
  • Bug Fixes

    • Corrected pagination behavior for empty results and pages beyond the available data.
    • Improved handling of boundary pages and zero-item limits.

Walkthrough

Admin pagination now supports an explicit “All” page across three resource views. The admin interface also serves and loads a client-side table filter with matching-count feedback, keyboard clearing, and associated styling.

Changes

Admin web behavior

Layer / File(s) Summary
All-items pagination contract
crates/api-web/src/pagination.rs
PageContext::all represents a single-page limit=0 view with its total item count.
All-items pagination handlers
crates/api-web/src/compute_allocation.rs, crates/api-web/src/instance_type.rs, crates/api-web/src/network_security_group.rs
The three handlers return all IDs on one page when limit=0, handle empty ID lists, and return empty results for boundary-exact out-of-range pages.
All-items pagination UI
crates/api-web/templates/pages_footer.html
The pagination footer renders an active or linked “All” page-size option.
Client-side table filtering
crates/api-web/templates/static/table_filter.js, crates/api-web/templates/static/carbide.css
Sortable overview tables receive filtered search controls, match counts, Escape-to-clear behavior, and related styling.
Table-filter asset delivery
crates/api-web/src/lib.rs, crates/api-web/templates/base.html
The filter script is embedded, served as a JavaScript static asset, and loaded by the base template.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Browser
  participant static_data
  participant table_filter.js
  participant OverviewTable
  Browser->>static_data: request /admin/static/table_filter.js
  static_data-->>Browser: return embedded JavaScript
  Browser->>table_filter.js: dispatch DOMContentLoaded
  table_filter.js->>OverviewTable: attach filter to sortable overview table
  Browser->>table_filter.js: enter terms or press Escape
  table_filter.js->>OverviewTable: hide rows and update match count
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly reflects the main change set: an All pagination option and per-table search filtering in api-web.
Description check ✅ Passed The description is directly related to the implemented pagination and table-filter changes and matches the PR objectives.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@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

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/api-web/src/compute_allocation.rs`:
- Around line 171-190: Update the pagination offset guards to use >= instead of
>, so an offset equal to the total ID count returns an empty result without
issuing an empty-ID lookup. Apply this in the pagination logic of
crates/api-web/src/compute_allocation.rs (lines 171-190),
crates/api-web/src/instance_type.rs (lines 227-250), and
crates/api-web/src/network_security_group.rs (lines 178-201), preserving the
existing behavior for genuinely in-range pages.

In `@crates/api-web/templates/static/table_filter.js`:
- Around line 56-58: Update the result-count span created in the table filter
code to expose dynamic filter result changes as an appropriate ARIA live region,
while preserving its existing class and text-update behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: e3e9cb67-faa3-43a6-99d1-f385b0322b51

📥 Commits

Reviewing files that changed from the base of the PR and between 8b5fd50 and 2460d17.

📒 Files selected for processing (10)
  • crates/api-web/src/compute_allocation.rs
  • crates/api-web/src/instance_type.rs
  • crates/api-web/src/lib.rs
  • crates/api-web/src/network_security_group.rs
  • crates/api-web/src/pagination.rs
  • crates/api-web/templates/base.html
  • crates/api-web/templates/pages_footer.html
  • crates/api-web/templates/static/carbide.css
  • crates/api-web/templates/static/table_filter.js
  • pxe/ipxe/upstream

Comment on lines +171 to +190
// `limit == 0` means "show all" on a single page.
let (pages, ids_for_page): (usize, Vec<_>) = if limit == 0 {
(1, all_ids)
} else {
let pages = all_ids.len().div_ceil(limit);
let current_record_cnt_seen = current_page.saturating_mul(limit);

if current_record_cnt_seen > all_ids.len() {
return Ok((pages, vec![]));
}
if current_record_cnt_seen > all_ids.len() {
return Ok((pages, vec![]));
}

let ids_for_page = all_ids
.into_iter()
.skip(current_record_cnt_seen)
.take(limit)
.collect();
(
pages,
all_ids
.into_iter()
.skip(current_record_cnt_seen)
.take(limit)
.collect(),
)
};

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.

🚀 Performance & Scalability | 🟡 Minor | ⚡ Quick win

Avoid empty-ID RPCs for the first out-of-range page. When the record count is an exact multiple of limit, current_page == pages makes the offset equal to the ID count. The > check falls through and sends an unnecessary lookup with no IDs; use >=.

  • crates/api-web/src/compute_allocation.rs#L171-L190: change the offset guard to >=.
  • crates/api-web/src/instance_type.rs#L227-L250: change the offset guard to >=.
  • crates/api-web/src/network_security_group.rs#L178-L201: change the offset guard to >=.
📍 Affects 3 files
  • crates/api-web/src/compute_allocation.rs#L171-L190 (this comment)
  • crates/api-web/src/instance_type.rs#L227-L250
  • crates/api-web/src/network_security_group.rs#L178-L201
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/api-web/src/compute_allocation.rs` around lines 171 - 190, Update the
pagination offset guards to use >= instead of >, so an offset equal to the total
ID count returns an empty result without issuing an empty-ID lookup. Apply this
in the pagination logic of crates/api-web/src/compute_allocation.rs (lines
171-190), crates/api-web/src/instance_type.rs (lines 227-250), and
crates/api-web/src/network_security_group.rs (lines 178-201), preserving the
existing behavior for genuinely in-range pages.

Comment thread crates/api-web/templates/static/table_filter.js
@github-actions

github-actions Bot commented Jul 14, 2026

Copy link
Copy Markdown

🔍 Container Scan Summary

Service Total Critical High Medium Low Other
boot-artifacts-aarch64 3 0 0 3 0 0
boot-artifacts-x86_64 3 0 0 3 0 0
forge-admin-cli-x86_64 259 13 30 78 7 131
machine-validation-runner 807 40 234 288 36 209
machine_validation 807 40 234 288 36 209
machine_validation-aarch64 807 40 234 288 36 209
nvmetal-carbide 807 40 234 288 36 209
TOTAL 3493 173 966 1236 151 967

Per-CVE detail lives in the per-service grype-* artifacts (JSON + SARIF). Severity counts only — no CVE IDs published here.

Signed-off-by: Krishna Dhulipala <kdhulipala@nvidia.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.

🧹 Nitpick comments (1)
crates/api-web/src/instance_type.rs (1)

227-252: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add table-driven regression coverage for the pagination boundaries.

Please cover limit == 0, an exact multiple where current_page == pages, and pages beyond the end. These cases define the new observable contract and should remain protected by grouped Rust scenarios or equivalent table-driven checks.

As per coding guidelines, Rust tests should use table-driven coverage with scenarios!, value_scenarios!, check_cases, or check_values.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/api-web/src/instance_type.rs` around lines 227 - 252, Add grouped
table-driven Rust regression tests using the project’s established scenarios!,
value_scenarios!, check_cases, or check_values helpers for the pagination logic
around limit == 0, an exact multiple with current_page == pages, and pages
beyond the end. Assert both the reported page count and returned IDs, including
empty results for out-of-range pages, while keeping the cases together as
boundary coverage.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@crates/api-web/src/instance_type.rs`:
- Around line 227-252: Add grouped table-driven Rust regression tests using the
project’s established scenarios!, value_scenarios!, check_cases, or check_values
helpers for the pagination logic around limit == 0, an exact multiple with
current_page == pages, and pages beyond the end. Assert both the reported page
count and returned IDs, including empty results for out-of-range pages, while
keeping the cases together as boundary coverage.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 69286c87-0a5f-4363-891b-1e2c1eb322ca

📥 Commits

Reviewing files that changed from the base of the PR and between 2460d17 and bd97d38.

📒 Files selected for processing (4)
  • crates/api-web/src/compute_allocation.rs
  • crates/api-web/src/instance_type.rs
  • crates/api-web/src/network_security_group.rs
  • crates/api-web/templates/static/table_filter.js
🚧 Files skipped from review as they are similar to previous changes (3)
  • crates/api-web/src/compute_allocation.rs
  • crates/api-web/templates/static/table_filter.js
  • crates/api-web/src/network_security_group.rs

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.

1 participant