Skip to content

fix: tables should always go to the last page when out of bounds#1369

Open
AncientPatata wants to merge 1 commit into
mainfrom
ad/fix-clamp
Open

fix: tables should always go to the last page when out of bounds#1369
AncientPatata wants to merge 1 commit into
mainfrom
ad/fix-clamp

Conversation

@AncientPatata

@AncientPatata AncientPatata commented Jun 19, 2026

Copy link
Copy Markdown

Motivation

#1367 introduced the "jump to the last page when the current page is out of bounds" behavior, but its page-index math had an off-by-one. The last page was computed as Math.floor(total / pageSize), which returns the index one past the last page whenever total is an exact multiple of pageSize (e.g. total = 100, pageSize = 10 → index 10, but the last valid index is 9). That landed the user on another out-of-bounds page.

Description

Fix the clamping math so a table that is out of bounds reliably lands on the last page that actually holds data.
deletion-clamp-behavior

Testing

  • Updated the five *-data.service.spec.ts suites (applications, partitions, results, sessions, tasks) to assert the corrected last-page index (Math.ceil(total / pageSize) - 1).
  • Manually verified against a live ArmoniK deployment

Impact

Not Applicable.

Additional Information

Not Applicable.

Checklist

  • My code adheres to the coding and style guidelines of the project.
  • I have performed a self-review of my code.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have made corresponding changes to the documentation.
  • I have thoroughly tested my modifications and added tests when necessary.
  • Tests pass locally and in the CI.
  • I have assessed the performance impact of my modifications.

@CLAassistant

CLAassistant commented Jun 19, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@github-actions

github-actions Bot commented Jun 19, 2026

Copy link
Copy Markdown
Lines Statements Branches Functions
Coverage: 99%
99.61% (5732/5754) 98.93% (1113/1125) 99.04% (1456/1470)

JUnit

Tests Skipped Failures Errors Time
2173 0 💤 0 ❌ 0 🔥 1m 29s ⏱️
Files coverage (99%)
File% Stmts% Branch% Funcs% LinesUncovered Line #s
All files99.6198.9399.0499.62 
src/app/applications100100100100 
   index.component.html100100100100 
   index.component.ts100100100100 
src/app/applications/components100100100100 
   table.component.html100100100100 
   table.component.ts100100100100 
src/app/applications/services100100100100 
   applications-data.service.ts100100100100 
   applications-filters.service.ts100100100100 
   applications-grpc.service.ts100100100100 
   applications-index.service.ts100100100100 
src/app/components98.9189.8898.7798.82 
   auto-complete.component.html100100100100 
   auto-complete.component.ts100100100100 
   auto-refresh-button.component.html100100100100 
   auto-refresh-button.component.ts100100100100 
   auto-refresh-dialog.component.html100100100100 
   auto-refresh-dialog.component.ts100100100100 
   columns-button.component.html100100100100 
   columns-button.component.ts100100100100 
   count-tasks-by-status.component.html100100100100 
   count-tasks-by-status.component.ts100100100100 
   icon-picker-dialog.component.html100100100100 
   icon-picker-dialog.component.ts100100100100 
   inspect-list.component.html100100100100 
   inspect-list.component.ts100100100100 
   inspection-header.component.html100100100100 
   inspection-header.component.ts10066.6610010055
   inspection-toolbar.component.html100100100100 
   inspection-toolbar.component.ts100100100100 
   manage-custom-dialog.component.html100100100100 
   manage-custom-dialog.component.ts100100100100 
   page-header.component.html100100100100 
   page-header.component.ts100100100100 
   page-section-header.component.html100100100100 
   page-section-header.component.ts100100100100 
   refresh-button.component.html100100100100 
   refresh-button.component.ts100100100100 
   share-url.component.html100100100100 
   share-url.component.ts100100100100 
   show-action-area.component.html100100100100 
   show-action-area.component.ts100100100100 
   show-actions.component.html100100100100 
   show-actions.component.ts100100100100 
   show-card-content.component.html100100100100 
   show-card-content.component.ts100100100100 
   show-card.component.html100100100100 
   show-card.component.ts100100100100 
   show-page.component.html100100100100 
   show-page.component.ts100100100100 
   spinner.component.html100100100100 
   spinner.component.ts100100100100 
   status-chip.component.html100100100100 
   status-chip.component.ts500046.1520–30
   status-color-picker.component.html100100100100 
   status-color-picker.component.ts100100100100 
   status-color-picker.dialog.component.html100100100100 
   status-color-picker.dialog.component.ts100100100100 
   table-actions-toolbar.component.html100100100100 
   table-actions-toolbar.component.ts100100100100 
   table-container.component.html100100100100 
   table-container.component.ts100100100100 
   table-dashboard-actions-toolbar.component.html100100100100 
   table-dashboard-actions-toolbar.component.ts100100100100 
   table-index-actions-toolbar.component.html100100100100 
   table-index-actions-toolbar.component.ts100100100100 
   view-tasks-by-status.component.html100100100100 
   view-tasks-by-status.component.ts100100100100 
src/app/components/dialogs/columns-modify-dialog100100100100 
   columns-modify-dialog.component.html100100100100 
   columns-modify-dialog.component.ts100100100100 
src/app/components/dialogs/columns-modify-dialog/components100100100100 
   columns-modify-area.component.html100100100100 
   columns-modify-area.component.ts100100100100 
src/app/components/dialogs/confirmation100100100100 
   confirmation.dialog.html100100100100 
   confirmation.dialog.ts100100100100 
src/app/components/filters100100100100 
   filters-chips.component.html100100100100 
   filters-chips.component.ts100100100100 
   filters-toolbar.component.html100100100100 
   filters-toolbar.component.ts100100100100 
src/app/components/filters/dialog98.0797.5694.9197.95 
   filters-dialog-and.component.html100100100100 
   filters-dialog-and.component.ts100100100100 
   filters-dialog-field.component.html100100100100 
   filters-dialog-field.component.ts97.2292.8590.997.0520
   filters-dialog-input.component.html100100100100 
   filters-dialog-input.component.ts98.2710094.1198.1433
   filters-dialog-operator.component.html100100100100 
   filters-dialog-operator.component.ts92.5991.6688.8891.6615, 27
   filters-dialog.component.html100100100100 
   filters-dialog.component.ts100100100100 
src/app/components/graph99.410097.4399.36 
   graph-legend.component.html100100100100 
   graph-legend.component.ts100100100100 
   graph.component.html100100100100 
   graph.component.ts99.3110097.1499.28123
src/app/components/inspection99.5410097.9199.52 
   byte-array.component.html100100100100 
   byte-array.component.ts100100100100 
   field-content.component.html100100100100 
   field-content.component.ts100100100100 
   inspection-card.component.html100100100100 
   inspection-card.component.ts100100100100 
   inspection-json.component.html100100100100 
   inspection-json.component.ts100100100100 
   inspection-list-grid.component.html100100100100 
   inspection-list-grid.component.ts100100100100 
   inspection-object.component.html100100100100 
   inspection-object.component.ts96.1510091.669670
   inspection.component.html100100100100 
   inspection.component.ts100100100100 
   json.component.html100100100100 
   json.component.ts100100100100 
   message.component.html100100100100 
   message.component.ts100100100100 
src/app/components/navigation100100100100 
   change-language-button.component.html100100100100 
   change-language-button.component.ts100100100100 
   navigation.component.html100100100100 
   navigation.component.ts100100100100 
src/app/components/navigation/add-sidebar-item-dialog100100100100 
   add-sidebar-item.dialog.component.html100100100100 
   add-sidebar-item.dialog.component.ts100100100100 
src/app/components/navigation/environment100100100100 
   environment.component.html100100100100 
   environment.component.ts100100100100 
src/app/components/navigation/environment/dialog100100100100 
   add-environment.dialog.html100100100100 
   add-environment.dialog.ts100100100100 
   conflicting-environment.dialog.html100100100100 
   conflicting-environment.dialog.ts100100100100 
src/app/components/navigation/external-services100100100100 
   external-services.component.html100100100100 
   external-services.component.ts100100100100 
   form-external-service.component.html100100100100 
   form-external-service.component.ts100100100100 
   manage-external-services-dialog.component.html100100100100 
   manage-external-services-dialog.component.ts100100100100 
src/app/components/navigation/scheme-switcher100100100100 
   scheme-switcher.component.html100100100100 
   scheme-switcher.component.ts100100100100 
src/app/components/navigation/settings-button100100100100 
   settings-button.component.html100100100100 
   settings-button.component.ts100100100100 
src/app/components/navigation/version-menu100100100100 
   repository-version.component.html100100100100 
   repository-version.component.ts100100100100 
   versions-menu.component.html100100100100 
   versions-menu.component.ts100100100100 
src/app/components/statuses100100100100 
   add-statuses-group-dialog.component.html100100100100 
   add-statuses-group-dialog.component.ts100100100100 
   edit-status-group-dialog.component.html100100100100 
   edit-status-group-dialog.component.ts100100100100 
   form-statuses-group.component.html100100100100 
   form-statuses-group.component.ts100100100100 
   manage-groups-dialog.component.html100100100100 
   manage-groups-dialog.component.ts100100100100 
src/app/components/table100100100100 
   table-actions.component.html100100100100 
   table-actions.component.ts100100100100 
   table-cell.component.html100100100100 
   table-cell.component.ts100100100100 
   table-column-header.component.html100100100100 
   table-column-header.component.ts100100100100 
   table-grpc-actions.component.html100100100100 
   table-grpc-actions.component.ts100100100100 
   table-inspect-message-dialog.component.html100100100100 
   table-inspect-message-dialog.component.ts100100100100 
   table-inspect-message.component.html100100100100 
   table-inspect-message.component.ts100100100100 
   table-inspect-object-dialog.component.html100100100100 
   table-inspect-object-dialog.component.ts100100100100 
   table-inspect-object.component.html100100100100 
   table-inspect-object.component.ts100100100100 
   table.component.html100100100100 
   table.component.ts100100100100 
src/app/components/table/cells100100100100 
   byte-array-cell.component.html100100100100 
   byte-array-cell.component.ts100100100100 
src/app/dashboard100100100100 
   index.component.html100100100100 
   index.component.ts100100100100 
src/app/dashboard/components100100100100 
   add-line-dialog.component.html100100100100 
   add-line-dialog.component.ts100100100100 
   edit-name-line-dialog.component.html100100100100 
   edit-name-line-dialog.component.ts100100100100 
   reorganize-lines-dialog.component.html100100100100 
   reorganize-lines-dialog.component.ts100100100100 
   split-lines-dialog.component.html100100100100 
   split-lines-dialog.component.ts100100100100 
   statuses-group-card.component.html100100100100 
   statuses-group-card.component.ts100100100100 
src/app/dashboard/components/lines99.2610095.8399.23 
   applications-line.component.html100100100100 
   applications-line.component.ts100100100100 
   partitions-line.component.html100100100100 
   partitions-line.component.ts100100100100 
   results-line.component.html100100100100 
   results-line.component.ts94.2810066.6693.9382–86
   sessions-line.component.html100100100100 
   sessions-line.component.ts100100100100 
   task-by-status-line.component.html100100100100 
   task-by-status-line.component.ts100100100100 
   tasks-line.component.html100100100100 
   tasks-line.component.ts100100100100 
src/app/dashboard/services100100100100 
   dashboard-index.service.ts100100100100 
   dashboard-storage.service.ts100100100100 
src/app/healthcheck100100100100 
   healthcheck.component.html100100100100 
   healthcheck.component.ts100100100100 
src/app/healthcheck/services100100100100 
   healthcheck-grpc.service.ts100100100100 
src/app/interceptors100100100100 
   grpc.interceptor.ts100100100100 
src/app/partitions100100100100 
   index.component.html100100100100 
   index.component.ts100100100100 
   show.component.html100100100100 
   show.component.ts100100100100 
src/app/partitions/components100100100100 
   table.component.html100100100100 
   table.component.ts100100100100 
src/app/partitions/services100100100100 
   partitions-data.service.ts100100100100 
   partitions-filters.service.ts100100100100 
   partitions-grpc.service.ts100100100100 
   partitions-index.service.ts100100100100 
   partitions-inspection.service.ts100100100100 
src/app/pipes100100100100 
   custom-column.pipe.ts100100100100 
   duration.pipe.ts100100100100 
   empty-cell.pipe.ts100100100100 
   pretty.pipe.ts100100100100 
src/app/profile100100100100 
   index.component.html100100100100 
   index.component.ts100100100100 
   types.ts100100100100 
src/app/profile/guards100100100100 
   user-connected.guard.ts100100100100 
src/app/results100100100100 
   index.component.html100100100100 
   index.component.ts100100100100 
   show.component.html100100100100 
   show.component.ts100100100100 
src/app/results/components100100100100 
   table.component.html100100100100 
   table.component.ts100100100100 
src/app/results/services99.3110010099.26 
   results-data.service.ts100100100100 
   results-filters.service.ts100100100100 
   results-grpc-actions.service.ts98.310010098.2166
   results-grpc.service.ts100100100100 
   results-index.service.ts100100100100 
   results-inspection.service.ts100100100100 
   results-statuses.service.ts100100100100 
src/app/services99.4910098.3299.43 
   auto-refresh.service.ts100100100100 
   byte-array.service.ts100100100100 
   cache.service.ts100100100100 
   default-config.service.ts94.2310086.3694369, 429–433
   environment.service.ts100100100100 
   filters-cache.service.ts100100100100 
   filters.service.ts100100100100 
   graph-data.service.ts100100100100 
   grpc-build-request.service.ts100100100100 
   grpc-events.service.ts100100100100 
   grpc-sort-field.service.ts100100100100 
   icons.service.ts100100100100 
   navigation.service.ts100100100100 
   notification.service.ts100100100100 
   query-params.service.ts100100100100 
   share-url.service.ts100100100100 
   storage.service.ts100100100100 
   table-storage.service.ts100100100100 
   table-url.service.ts100100100100 
   table.service.ts100100100100 
   tasks-by-status.service.ts100100100100 
   theme.service.ts100100100100 
   user-grpc.service.ts100100100100 
   user.service.ts100100100100 
   utils.service.ts100100100100 
   versions-grpc.service.ts100100100100 
   versions.service.ts100100100100 
src/app/sessions100100100100 
   graph.component.html100100100100 
   graph.component.ts100100100100 
   index.component.html100100100100 
   index.component.ts100100100100 
   show.component.html100100100100 
   show.component.ts100100100100 
src/app/sessions/components100100100100 
   table.component.html100100100100 
   table.component.ts100100100100 
src/app/sessions/services100100100100 
   sessions-data.service.ts100100100100 
   sessions-filters.service.ts100100100100 
   sessions-grpc-actions.service.ts100100100100 
   sessions-grpc.service.ts100100100100 
   sessions-index.service.ts100100100100 
   sessions-inspection.service.ts100100100100 
   sessions-statuses.service.ts100100100100 
src/app/settings100100100100 
   index.component.html100100100100 
   index.component.ts100100100100 
src/app/settings/component100100100100 
   clear-all-dialog.component.html100100100100 
   clear-all-dialog.component.ts100100100100 
   theme-selector.component.html100100100100 
   theme-selector.component.ts100100100100 
src/app/shared100100100100 
   animations.ts100100100100 
src/app/tasks100100100100 
   index.component.html100100100100 
   index.component.ts100100100100 
   show.component.html100100100100 
   show.component.ts100100100100 
src/app/tasks/components100100100100 
   manage-view-in-logs-dialog.component.html100100100100 
   manage-view-in-logs-dialog.component.ts100100100100 
   table.component.html100100100100 
   table.component.ts100100100100 
src/app/tasks/services100100100100 
   tasks-data.service.ts100100100100 
   tasks-filters.service.ts100100100100 
   tasks-grpc-actions.service.ts100100100100 
   tasks-grpc.service.ts100100100100 
   tasks-index.service.ts100100100100 
   tasks-inspection.service.ts100100100100 
   tasks-statuses.service.ts100100100100 
src/app/types100100100100 
   navigation.ts100100100100 
   status.ts100100100100 
   themes.ts100100100100 
src/app/types/components99.3210098.03100 
   dashboard-line-table.ts99.1310097.29100 
   index.ts99.0510097.22100 
   show.ts100100100100 
   table.ts100100100100 
src/app/types/services99.297.3610099.17 
   data-filter.service.ts100100100100 
   grpc-actions.service.ts100100100100 
   grpcService.ts100100100100 
   inspectionService.ts100100100100 
   table-data.service.ts98.1494.1110098.07124
test100100100100 
   d3.js100100100100 
   force-graph.js100100100100 

@lemaitre-aneo lemaitre-aneo 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.

What if there is actually no data?
Also, I think the logic should be abstracted, factorized, and tested.

@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants