Architecting a Centralized Column Visibility Manager for Dynamic Perspective Tables

I am managing 20+ Perspective Table components across multiple views. Many of these tables are dynamic—their columns change based on query parameters or user selection. I need a scalable, centralized system that allows users to toggle column visibility via a popup, remembers their preferences for the session, and handles dynamic column generation without hardcoding.

Description: I currently use a custom Python module to dynamically generate table columns. I want to extend this system to include a "Column Manager" popup that works for any table in the project.

My Proposed Architecture:

  1. Centralized Storage: A Session Custom Property dictionary session.custom.ColumnPreferences that stores visibility states keyed by a unique tableId (e.g., {"TableA": {"Station": True, "Timestamp": False}}).
  2. Universal Popup: A single View containing a Table component. This table will display the column names and a boolean checkbox. It will be passed a tableId and the current columnNames list as parameters.
  3. The Logic:
  • A helper function applyColumnVisibility(generatedCols, tableId, prefs) that intercepts the column configuration before it is applied to the component.
  • It should default any "newly discovered" dynamic columns to Visible: True if they aren't yet in the user's preference dictionary.

Goal: I want to ensure this is the most performant way to handle this in Perspective. Specifically:

  • Should I be using onEditCellCommit on the popup table to write directly back to the Session prop?
  • Is there a better way to "discover" available columns for the popup than passing them from the parent table's current data?

I'm looking for feedback on this "Hub-and-Spoke" model or any tips on how others have handled persistent column states across large-scale projects.

The centralized storage method more or less lines up with what I have recommended to others in the past for holding similar user specific information, like personalization and such. You could expand it to hold additional data other than just column visibility. (Sorting preferences or similar). Just make sure the top level property is set to private.

One pitfall I could see is if a single table is used for different queries, you could run into a case where column A needs to be hidden for query A, but should be shown for query B. That means you might need to include additional identifier information in your config data to indicate if the column visibility is for the table in general or a specific query on that table.

Writing directly to the session props could leave you with orphaned key/value pairs if you change what columns are available for the table after saving a config, but that's a pretty negligible cost unless you have thousands of orphaned items. You could also run a cleanup operation on the storage table if you really needed/wanted to clean out stale keys.

Are you able to modify your existing function that generates your columns to take an optional userConfig argument and pass the config for the table through that?

Then when you are doing whatever logic to loop through and create the columns, you can check immediately to see if the column should be hidden or not. This would save you from looping over the list of columns again after their generation.

I would still keep the helper for any post generation changes. On submission of new config, pass the existing generated columns, new config, and table Id, and adjust the columns based on the new config.