Skip to content

Conversation

@scottdover
Copy link
Contributor

@scottdover scottdover commented Aug 29, 2025

Summary:
This updates the data viewer code to support sorting columns.

On the backend, this is supported by passing a new sortModel to our getRows function. ITC
connections support this by creating an order by statement, but REST connections are a bit more
complicated. With a non-empty sort model, the general process for REST is to:

  • Create a sorted view
  • Query that view and get results
  • Delete the view

This is consistent with how studio sorts data.

On the front-end, a ColumnMenu has been introduced to facilitate adding and removing sorting
criteria.

Last, these changes required exposing l10n messages to the ColumnMenu component. To do this, a
few changes were made to WebView:

  • WebView is now responsible for rendering it's content
  • WebView.render makes use of some new class methods to generate content:
    • body: returns the html that should show up in the <body> section of a webview
    • scripts (optional): An array of relative script sources to load for the webview
    • styles (optional): An array of relative style sources to load for the webview
    • l10nMessages (optional): A map of l10n translation messages to expose to React
      (NOTE: These messages can be read using the new localize helper)

The changes to WebView should make future webview panels work in a more consistent way.

Testing:

  • Test sorting a single column
  • Test sorting multiple columns (test sorting 3 or more columns and deleting a "middle" sort
    to make sure sort indexing is maintained)
  • Make sure sorting columns pops the grid back to the first row
  • Test sorting for REST and ITC-based connections
  • Make sure the column menu displays as expected
    • If the parent menu and child menu fit left to right, display them as such
    • If the parent menu fits in the view, but the child menu doesn't, the child menu
      should be displayed to the left
    • If neither the parent menu not the child menu fit, the parent menu should be adjusted
      to be near the right edge of the screen, and the child menu should be displayed to the left
  • Make sure column menu can be dismissed by clicking outside of the menu, or by pressing esc
  • Test opening properties view for a table, and opening properties view for a column within a table

@scottdover
Copy link
Contributor Author

Hey @scnwwu @smorrisj

I feel like the answer to this is obvious, but can we assume everyone with a REST connection has access to studio? And, is there a reason we shouldn't use a studio session for api calls/etc in the extension?

I'm looking into column sorting, and DataAccessApi.getRows doesn't provide a way to provide sorting information.

However, you can provide sorting data for one or more column in studio like this:

curl 'https://{studioUrl}/studio/sessions/{sessionId}/data/libraries/{library}/tables/{table}rows?start=0&limit=100&applyFormats=true&formatMissingValues=true' \
--data-raw '{
  "distinct": false,
  "filter": "",
  "sorts": [
    { "columnName": "COLUMN_TO_SORT", "sortOrder": "descending", "sortPriority": 0 }
  ]
}' \

This API call is what is used by the data viewer in studio.

Is there a reason we shouldn't use this?

@scnwwu
Copy link
Contributor

scnwwu commented Aug 30, 2025

Workbench goes through REST but no studio

@scnwwu
Copy link
Contributor

scnwwu commented Aug 30, 2025

Looks like getRowSet supports a sortBy, will it work?
https://developer.sas.com/rest-apis/compute/getRowSet

@smorrisj
Copy link
Contributor

Looks like getRowSet supports a sortBy, will it work? https://developer.sas.com/rest-apis/compute/getRowSet

Agreed. We should use the sorting features available via compute/platform microservices where possible IMO.

@scottdover scottdover force-pushed the feat/table-sort branch 9 times, most recently from 65f8813 to 5457e6a Compare October 20, 2025 17:38
@scottdover scottdover marked this pull request as ready for review October 20, 2025 18:18
@scottdover
Copy link
Contributor Author

scottdover commented Oct 20, 2025

Hey @kpatl1. I mentioned this in Teams, but wanted to get your thoughts on the changes to the WebView class when you get some time. My hope is that your changes in #1631 can get merged and I'll update things to work with the WebView changes (and maybe add a properties context menu item time permitting)

@scottdover scottdover changed the title chore(wip): implement table sorting chore: implement column sorting Oct 20, 2025
@scottdover scottdover added this to the 1.18.0 milestone Oct 20, 2025
@kpatl1
Copy link
Collaborator

kpatl1 commented Oct 20, 2025

I have also gone in and addressed comments in #1631 so hopefully that should be able to be merged soon

@scnwwu
Copy link
Contributor

scnwwu commented Oct 21, 2025

suggest to change the PR title to be feat: ...


return {
rows: data.items,
count: data.count,
Copy link
Contributor

Choose a reason for hiding this comment

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

When I tried it, there seems a problem. When get from a view, the count is undefined, thus the scrollbar doesn't show enough space.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ohh, good catch. I noticed there was some weirdness around loading larger tables while sorting, but thought it was mainly due to the fact that sorting took marginally longer than just displaying the table. Will take a look.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was resolved in 2a16789. This doesn't quite fix the issue with count being undefined...there wasn't a straightforward way to find that as it isn't returned by a view or by the createView statement.

However, this does resolve the issue enough (imo) as it stops us from indefinitely trying to load more data by inferring the total count.

Copy link
Contributor

Choose a reason for hiding this comment

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

So the user experience will be inconsistent. When I open a table (no sorting initially), I can see the scrollbar as if all rows are there. I can drag the scrollbar to a position and see empty cells and I know the content is being loaded. And later the content filled in.
Now when I add a sort, the scrollbar will change to like there're only 100 rows. When I scroll to the bottom, it's not obvious if it's really at end or loading.
It would be great if we can provide the count to ag grid. When the table opened initially, no sorting applied, we should already get the count. Can we cache the count?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I'd rather it not be inconsistent, either. I did consider caching things. That would fix the issue temporarily. However, once we incorporate filtering, I think we're going to run into the same issue and will have to manage this cache differently. Fwiw, it looks like scrollbars also get a little inconsistent in studio when we're applying both a sort and filter.

I'm inclined to not address this one until a user complains, unless @snlwih thinks it is worth exploring further before releasing?

@scottdover scottdover changed the title chore: implement column sorting feat: implement column sorting Oct 21, 2025
@scottdover
Copy link
Contributor Author

scottdover commented Oct 22, 2025

Hey @scnwwu @smorrisj @danila-grobov . I'm wondering if any of you have guidance on how to proceed with the formatting issues? The actual sorting isn't the issue, but if I execute SELECT * FROM SASHELP.AIR I get improperly formatted results.

I thought I could correct the issue by applying formats in the query like...

SELECT
   AIR,
   DATE FORMAT=MONYY.
FROM SASHELP.AIR

However, that returns improperly formatted results as well.

Fwiw, I originally planned to use RecordSet.Sort to sort our results. However, that gave me the following error:

Current provider does not support the necessary interfaces for sorting or filtering

@scnwwu
Copy link
Contributor

scnwwu commented Oct 23, 2025

It looks like the "SAS Formats" only works well with adCmdTableDirect (what main branch is doing).
I guess an easy way is to do similar like Viya.

$this.dataConnection.Execute("create view work.test as select * from sashelp.air order by air asc")
$objRecordSet = New-Object -comobject ADODB.Recordset
$objRecordSet.ActiveConnection = $this.dataConnection # This is needed to set the properties for sas formats.
$objRecordSet.Properties.Item("SAS Formats").Value = "_ALL_"
$objRecordSet.Open(
      "work.test",
      [System.Reflection.Missing]::Value, # Use the active connection
      2,  # adOpenDynamic
      1,  # adLockReadOnly
      512 # adCmdTableDirect
)
$this.dataConnection.Execute("drop view work.test")

@dahils dahils added the testing-complete Complete the pull requests testing label Nov 17, 2025
@dahils dahils self-requested a review November 17, 2025 15:49
Scott Dover added 24 commits November 17, 2025 11:25
Signed-off-by: Scott Dover <[email protected]>
Signed-off-by: Scott Dover <[email protected]>
Signed-off-by: Scott Dover <[email protected]>
Signed-off-by: Scott Dover <[email protected]>
Signed-off-by: Scott Dover <[email protected]>
Signed-off-by: Scott Dover <[email protected]>
- move useDataViewer
- improve keyboard accessibility
- improve localize

Signed-off-by: Scott Dover <[email protected]>
Signed-off-by: Scott Dover <[email protected]>
Signed-off-by: Scott Dover <[email protected]>
Signed-off-by: Scott Dover <[email protected]>
@scottdover scottdover merged commit 9b3945f into main Nov 17, 2025
2 checks passed
@scottdover scottdover deleted the feat/table-sort branch November 17, 2025 18:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

testing-complete Complete the pull requests testing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants