Skip to content

Conversation

@shuoweil
Copy link
Contributor

@shuoweil shuoweil commented Nov 11, 2025

This PR introduces column sorting functionality to the interactive table widget.

  1. Updated Python backend and JS/CSS frontend to allow sorting by columns.
    Three-State Sorting UI:

    • The sort indicator dot () is now hidden by default and only appears when the user hovers the mouse over a column header
    • Implemented a sorting cycle: unsorted () → ascending () → descending () → unsorted ().
    • Visual indicators (●, ▲, ▼) are displayed in column headers to reflect the current sort state.
    • Sorting controls are now only enabled for columns with orderable data types.
  2. Tests
    2.1) Updated paginated_pandas_df fixture for better sorting test coverage
    2.2) Added new system tests to verify ascending, descending, and multi-column sorting.

  3. Docs has been updated to document the new features. The main description now mentions column sorting and adjustable widths, and a new section has been added to explain how to use the column resizing feature. The sorting section was also updated to mention that the indicators are only visible on hover.

Fixes #<459835971> 🦕

@shuoweil shuoweil requested a review from tswast November 11, 2025 19:19
@shuoweil shuoweil self-assigned this Nov 11, 2025
@shuoweil shuoweil requested review from a team as code owners November 11, 2025 19:19
@review-notebook-app
Copy link

Check out this pull request on  ReviewNB

See visual diffs & provide feedback on Jupyter Notebooks.


Powered by ReviewNB

@product-auto-label product-auto-label bot added size: l Pull request size is large. api: bigquery Issues related to the googleapis/python-bigquery-dataframes API. labels Nov 11, 2025
Comment on lines 229 to 232
except KeyError:
logging.warning(
f"Attempted to sort by unknown column: {self.sort_column}"
)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why are we catching this exception and dropping it? If we get to this state something bad has happened and the user should know about it.

Copy link
Contributor Author

@shuoweil shuoweil Nov 12, 2025

Choose a reason for hiding this comment

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

Here is my plan:
When a KeyError is caught, the current implementation does the following:

  1. Notifies the user: It sets self._error_message to a user-friendly message like "Column '...' not found.". The frontend will then display this error.
  2. Reverts to unsorted: It resets self.sort_column = "".
  3. Displays the unsorted table: The function then continues, but since sort_column is now empty, it fetches and displays the data in its original, unsorted order.

const headers = tableContainer.querySelectorAll("th");
headers.forEach((header) => {
const columnName = header.textContent.trim();
if (columnName) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Not all data types are sortable. See the orderable property in our dtypes.

orderable: bool = False

We should not add the handler or arrow to columns that we can't sort.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here is the plan:

  1. Display a dot (●) indicator for all sortable columns by default
  2. Allow users to cycle through three states: unsorted (●) → ascending (▲) → descending (▼) → unsorted (●)
  3. Only show sorting UI for columns with orderable data types

@shuoweil shuoweil requested a review from tswast November 12, 2025 22:55
@shuoweil shuoweil marked this pull request as draft November 14, 2025 19:27
@shuoweil shuoweil requested a review from tswast November 14, 2025 20:29
@shuoweil shuoweil marked this pull request as ready for review November 14, 2025 20:29
@shuoweil
Copy link
Contributor Author

@tswast Upon checking, the failed e2e tests
FAILED tests/system/large/functions/test_remote_function.py::test_remote_function_max_instances[set-None]
FAILED tests/system/large/functions/test_remote_function.py::test_remote_function_max_instances[no-set]
are not due to my change.

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

Labels

api: bigquery Issues related to the googleapis/python-bigquery-dataframes API. size: l Pull request size is large.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants