GoogleCloudPlatform / GoogleCloudPlatform/gcc-creative-studio

Admin table pagination: previous-page button is permanently disabled, stranding the user on page 2

Open
#278 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
144
Forks
385
Avg merge
1d 46m
Merged PRs (30d)
5

Description

## Expected Behavior

On `/admin/media-gallery`, after advancing to page 2 of the results, the paginator should show the range for page 2 (`26 – 50 of 723`) and its previous-page arrow should be enabled so the user can go back.

## Actual Behavior

After advancing to page 2, the paginator resets to page 1: the range label reads `1 – 25 of 723` and the previous-page arrow stays greyed out, so there is no way back. The rows displayed are page 2's data, so the label and the table disagree. Clicking next again re-requests the same offset, so the user cannot move forward either. Effectively the table is limited to its first two pages, and only in one direction.

Browser-independent (reproduced in Chrome and Firefox); this is the in-page `mat-paginator` control, not browser history.

Affects two components:

- `frontend/src/app/admin/media-gallery-management/media-gallery-management.component.html` (route `/admin/media-gallery`)
- `frontend/src/app/admin/tags-management/tags-management.component.html`

### Cause

In both components the `` and the `` share one wrapper gated on the loading flag, e.g. `media-gallery-management.component.html:108`:

```html


```

`fetchPage()` sets `isLoading = true` before awaiting the request (`media-gallery-management.component.ts:135`), so every page change destroys the paginator and constructs a new one when the response lands. Neither template binds `[pageIndex]`, so the replacement always initialises to page 0, and `MatPaginator` disables its own previous-page button whenever `pageIndex === 0`:

```ts
_previousButtonsDisabled() { return this.disabled || !this.hasPreviousPage(); }
```

Both components already track the right value in `currentPageIndex` and assign it on success; it is simply never bound to the view.

`users-management` and `source-assets-management` have the identical loading wrapper and are unaffected, because both already bind `[pageIndex]="currentPageIndex"`. Those two are the pattern the fix follows.

`tags-management` additionally resets `currentPageIndex` to 0 on a page-size change and then calls `loadTags(event.pageIndex)`. Material recomputes that index to keep the first visible row on screen, so it is not 0, and `loadTags` reassigns `currentPageIndex` from it, undoing the reset.

## Steps to Reproduce the Problem

1. Sign in as an admin and go to `/admin/media-gallery`, with enough media in the workspace to fill more than two pages.
2. Click the paginator's next-page arrow.
3. Observe that the rows update to page 2, but the range label still reads `1 – 25 of ...` and the previous-page arrow is disabled. Clicking next again reloads the same page.

Same steps reproduce on `/admin/tags` (needs more than one page of tags).

## Specifications

- Version: `upstream/main` at `1f19478` ("Merge pull request #273 from GoogleCloudPlatform/cherry-pick-temp")
- Platform: Angular 18.2.1, Angular Material 18.2.1, Chrome 152 and Firefox; reproduced headless in Karma against an unmodified checkout of `main`

I have a fix plus regression specs for both components, and will open a PR referencing this issue. For what it's worth, the specs fail on unmodified `main` (5 failures across the two components) and pass with the one-line bindings added, so the behaviour is pinned in both directions.

While confirming the scope I noticed something adjacent that I have deliberately left out of the fix, in case it is useful: `media-templates-management.component.ts` assigns `this.dataSource.paginator = this.paginator` in `ngAfterViewInit`, but `isLoading` is initialised to `true`, so the paginator is not in the DOM at that point, `this.paginator` is `undefined`, and it is never reassigned once the table appears. If that is right, that table's client-side paging and sorting are inert rather than merely wrong on page 2. I have not confirmed it against a running app.

Contributor guide

Open the contributing guide

Research direction

Start with the loading wrappers in frontend/src/app/admin/media-gallery-management/media-gallery-management.component.html and frontend/src/app/admin/tags-management/tags-management.component.html, then compare their paginator usage with users-management and source-assets-management. Check the existing regression specs for both components and verify that page 2 displays 26–50, enables the previous arrow, and allows subsequent navigation in both directions.

Written by the indexing model from the issue text.

Assessment

Tech stack
angular, typescript
Domain
frontend
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.