refactor(frontend): compose DataTable storageKey via usePageStorageKeys

Hard-coding the full `table_4_/settings/prompts:agents` / `:tools` keys in
the page duplicated the route prefix that `usePageStorageKeys` already
computes — if the prefix ever bumps (e.g. `table_4_` → `table_5_` on a
storage migration), every call site silently goes stale. Read the route
base from the hook instead and only own the per-table suffix in the page.
Updated the `storageKey` JSDoc on DataTable to document this composition
pattern.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Sergey Kozyrenko
2026-05-16 20:28:15 +07:00
co-authored by Claude Opus 4.7
parent de695ec1c5
commit ca32c199e8
2 changed files with 17 additions and 2 deletions
+10
View File
@@ -111,6 +111,16 @@ interface DataTableProps<TData, TValue = unknown> {
* one DataTable. Pages that mount multiple DataTables on the same route
* (e.g. `/settings/prompts`) must pass distinct keys per instance, or
* their persisted state will alias and overwrite each other.
*
* Recommended composition for multi-table routes — take the route base
* through `usePageStorageKeys` and append a per-table suffix instead of
* hard-coding the `table_4_<path>` prefix:
*
* ```tsx
* const { table: base } = usePageStorageKeys();
* <DataTable storageKey={`${base}:agents`} … />
* <DataTable storageKey={`${base}:tools`} … />
* ```
*/
storageKey?: string;
}
@@ -35,6 +35,7 @@ import {
} from '@/components/ui/dropdown-menu';
import { StatusCard } from '@/components/ui/status-card';
import { useDeletePromptMutation, useSettingsPromptsQuery } from '@/graphql/types';
import { usePageStorageKeys } from '@/hooks/use-page-storage-keys';
// Types for table data
type AgentPromptTableData = {
displayName: string; // Formatted display name
@@ -69,6 +70,10 @@ const SettingsPrompts = () => {
const { data, error, loading: isLoading } = useSettingsPromptsQuery();
const [deletePrompt, { loading: isDeleteLoading }] = useDeletePromptMutation();
const navigate = useNavigate();
// Shared base key for the route; each DataTable appends its own suffix so
// sorting / column visibility / search-column narrowing live in distinct
// slots even though the page mounts two tables.
const { table: tableStorageBase } = usePageStorageKeys();
// Reset dialog states
const [resetDialogOpen, setResetDialogOpen] = useState(false);
@@ -860,7 +865,7 @@ const SettingsPrompts = () => {
initialPageSize={1000}
renderRowContextMenu={renderAgentRowContextMenu}
renderSubComponent={renderAgentSubComponent}
storageKey="table_4_/settings/prompts:agents"
storageKey={`${tableStorageBase}:agents`}
/>
</div>
)}
@@ -881,7 +886,7 @@ const SettingsPrompts = () => {
initialPageSize={1000}
renderRowContextMenu={renderToolRowContextMenu}
renderSubComponent={renderToolSubComponent}
storageKey="table_4_/settings/prompts:tools"
storageKey={`${tableStorageBase}:tools`}
/>
</div>
)}