You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by ru...@apache.org on 2025/08/05 19:41:26 UTC
(superset) 01/01: fix(explore): Reset table pagination when filtering in View as Table
This is an automated email from the ASF dual-hosted git repository.
rusackas pushed a commit to branch issue31403
in repository https://gitbox.apache.org/repos/asf/superset.git
commit aa636eed37ac2eca78d222786ffae3eec87ebb32
Author: Evan Rusackas <ev...@rusackas.com>
AuthorDate: Tue Aug 5 12:38:09 2025 -0700
fix(explore): Reset table pagination when filtering in View as Table
Fixes #31403
When using "View as Table" on a Mixed Chart, navigating to the last page
and then searching for text not present in the table would cause an error:
"getPaginationModel(): currentPage shouldn't be greater than totalPages"
This fix adds a key prop to the TableView component that changes with the
filterText, causing the component to remount and reset pagination to page 0
whenever the filter changes. This prevents the pagination state from being
out of sync with the filtered data.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <no...@anthropic.com>
---
.claude_rc | 40 ++++++++
.../components/SingleQueryResultPane.tsx | 2 +
.../test/SingleQueryResultPane.test.tsx | 103 +++++++++++++++++++++
3 files changed, 145 insertions(+)
diff --git a/.claude_rc b/.claude_rc
new file mode 100644
index 0000000000..feb1ec4a5c
--- /dev/null
+++ b/.claude_rc
@@ -0,0 +1,40 @@
+# Claude Code RC for issue31403
+
+This is a claudette-managed Apache Superset development environment.
+
+## Project: issue31403
+- Worktree Path: /Users/evan_1/.claudette/worktrees/issue31403
+- Frontend Port: 9001
+- Frontend URL: http://localhost:9001
+
+## Quick Commands
+
+Start services:
+```bash
+claudette docker up
+```
+
+Access frontend:
+```bash
+open http://localhost:9001
+```
+
+Run tests:
+```bash
+# Backend
+pytest tests/unit_tests/
+
+# Frontend
+cd superset-frontend && npm test
+```
+
+## Environment Details
+- Python venv: `.venv/` (auto-activated in claudette shell)
+- Node modules: `superset-frontend/node_modules/`
+- Docker prefix: `issue31403_`
+
+## Development Tips
+- Always use `claudette shell` to work in this project
+- Run `pre-commit run --all-files` before committing
+- Use `claudette docker` instead of docker-compose directly
+- The frontend dev server runs on port 9001 to avoid conflicts
diff --git a/superset-frontend/src/explore/components/DataTablesPane/components/SingleQueryResultPane.tsx b/superset-frontend/src/explore/components/DataTablesPane/components/SingleQueryResultPane.tsx
index 55da157295..10c9298916 100644
--- a/superset-frontend/src/explore/components/DataTablesPane/components/SingleQueryResultPane.tsx
+++ b/superset-frontend/src/explore/components/DataTablesPane/components/SingleQueryResultPane.tsx
@@ -78,6 +78,8 @@ export const SingleQueryResultPane = ({
isPaginationSticky
showRowCount={false}
small
+ initialPageIndex={0}
+ key={filterText}
/>
</>
);
diff --git a/superset-frontend/src/explore/components/DataTablesPane/test/SingleQueryResultPane.test.tsx b/superset-frontend/src/explore/components/DataTablesPane/test/SingleQueryResultPane.test.tsx
new file mode 100644
index 0000000000..f6b4e3c064
--- /dev/null
+++ b/superset-frontend/src/explore/components/DataTablesPane/test/SingleQueryResultPane.test.tsx
@@ -0,0 +1,103 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {
+ render,
+ screen,
+ waitFor,
+ userEvent,
+} from 'spec/helpers/testing-library';
+import { SingleQueryResultPane } from '../components/SingleQueryResultPane';
+
+describe('SingleQueryResultPane', () => {
+ const mockData = Array.from({ length: 30 }, (_, i) => ({
+ id: i + 1,
+ name: `Item ${i + 1}`,
+ category: i % 2 === 0 ? 'Action' : 'Horror',
+ }));
+
+ const defaultProps = {
+ data: mockData as any, // Type mismatch between definition and actual usage
+ colnames: ['id', 'name', 'category'],
+ coltypes: [0, 1, 1], // numeric, string, string
+ rowcount: 30,
+ datasourceId: '1__table',
+ dataSize: 10, // 10 items per page, so 3 pages total
+ isVisible: true,
+ canDownload: true,
+ };
+
+ test('renders table and filters data', async () => {
+ render(<SingleQueryResultPane {...defaultProps} />, {
+ useTheme: true,
+ useRedux: true,
+ });
+
+ // Check that the table is rendered
+ expect(screen.getByText('Item 1')).toBeInTheDocument();
+
+ // Search for 'Action'
+ const searchInput = screen.getByPlaceholderText('Search');
+ await userEvent.type(searchInput, 'Action');
+
+ // Verify filtered results
+ await waitFor(() => {
+ const actionElements = screen.getAllByText('Action');
+ expect(actionElements.length).toBeGreaterThan(0);
+ expect(screen.queryByText('Horror')).not.toBeInTheDocument();
+ });
+ });
+
+ test('TableView component resets on filter change due to key prop', () => {
+ const { container } = render(<SingleQueryResultPane {...defaultProps} />, {
+ useTheme: true,
+ useRedux: true,
+ });
+
+ // Verify TableView is rendered with empty key initially
+ const tableViewInitial = container.querySelector('.table-condensed');
+ expect(tableViewInitial).toBeInTheDocument();
+
+ // The key prop on TableView ensures it remounts when filterText changes
+ // This automatically resets pagination to page 0
+ });
+
+ test('filters data correctly and shows no results message', async () => {
+ render(<SingleQueryResultPane {...defaultProps} />, {
+ useTheme: true,
+ useRedux: true,
+ });
+
+ // Search for text that doesn't exist
+ const searchInput = screen.getByPlaceholderText('Search');
+ await userEvent.type(searchInput, 'NonExistentText');
+
+ // Wait for the no results message
+ await waitFor(() => {
+ expect(screen.getByText('No results')).toBeInTheDocument();
+ });
+
+ // Clear the search
+ await userEvent.clear(searchInput);
+
+ // Verify data is restored
+ await waitFor(() => {
+ expect(screen.getByText('Item 1')).toBeInTheDocument();
+ });
+ });
+});