Skip to content

Commit 0e143fb

Browse files
author
Dylan Huang
committed
query params are applied when provided
1 parent 6a8e73e commit 0e143fb

2 files changed

Lines changed: 101 additions & 1 deletion

File tree

vite-app/src/GlobalState.tsx

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ import type {
1111
import flattenJson from "./util/flatten-json";
1212
import type { FlatJson } from "./util/flatten-json";
1313
import { createFilterFunction } from "./util/filter-utils";
14-
import { QueryParamsWatcher } from "./util/query-params";
14+
import {
15+
QueryParamsWatcher,
16+
queryParamsToPartialConfig,
17+
} from "./util/query-params";
1518

1619
// Default pivot configuration
1720
const DEFAULT_PIVOT_CONFIG: PivotConfig = {
@@ -75,6 +78,9 @@ export class GlobalState {
7578
this.appliedFilterConfig = this.filterConfig.slice();
7679
makeAutoObservable(this);
7780
this.queryParamsWatcher = new QueryParamsWatcher(this);
81+
82+
// Apply query params from URL if they exist
83+
this.applyQueryParamsFromUrl();
7884
}
7985

8086
// Computed getters for individual configs
@@ -243,6 +249,49 @@ export class GlobalState {
243249
this.isConnected = connected;
244250
}
245251

252+
// Apply query params to global configuration
253+
applyQueryParams(queryParams: Record<string, string>) {
254+
debugger;
255+
const partialConfig = queryParamsToPartialConfig(queryParams);
256+
257+
// Apply each section of the partial config
258+
if (partialConfig.pivotConfig) {
259+
this.updatePivotConfig(partialConfig.pivotConfig);
260+
}
261+
262+
if (partialConfig.filterConfig) {
263+
this.updateFilterConfig(partialConfig.filterConfig);
264+
}
265+
266+
if (partialConfig.paginationConfig) {
267+
this.updatePaginationConfig(partialConfig.paginationConfig);
268+
}
269+
270+
if (partialConfig.sortConfig) {
271+
this.updateSortConfig(partialConfig.sortConfig);
272+
}
273+
}
274+
275+
// Extract query params from URL and apply them to global configuration
276+
private applyQueryParamsFromUrl() {
277+
if (typeof window === "undefined") {
278+
return; // Skip on server-side rendering
279+
}
280+
281+
const urlParams = new URLSearchParams(window.location.search);
282+
const queryParams: Record<string, string> = {};
283+
284+
// Convert URLSearchParams to Record<string, string>
285+
for (const [key, value] of urlParams.entries()) {
286+
queryParams[key] = value;
287+
}
288+
289+
// Only apply if there are query params
290+
if (Object.keys(queryParams).length > 0) {
291+
this.applyQueryParams(queryParams);
292+
}
293+
}
294+
246295
upsertRows(dataset: EvaluationRow[]) {
247296
runInAction(() => {
248297
this.isLoading = true;

vite-app/src/util/query-params.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,57 @@ function calculateDifferentValues(
161161
return differences;
162162
}
163163

164+
/**
165+
* Converts serialized query params back into a partial GlobalConfig
166+
* This is the inverse operation of nonDefaultValues()
167+
*
168+
* @param queryParams - Record where keys are JSON paths and values are JSON-serialized values
169+
* @returns Partial<GlobalConfig> that can be applied to update GlobalConfig
170+
*/
171+
export function queryParamsToPartialConfig(
172+
queryParams: Record<string, string>
173+
): Partial<GlobalConfig> {
174+
const result: any = {};
175+
176+
for (const [path, serializedValue] of Object.entries(queryParams)) {
177+
try {
178+
const value = JSON.parse(serializedValue);
179+
setNestedValue(result, path, value);
180+
} catch (error) {
181+
console.warn(
182+
`Failed to parse query param value for path "${path}":`,
183+
error
184+
);
185+
}
186+
}
187+
188+
return result;
189+
}
190+
191+
/**
192+
* Helper function to set a nested value in an object using dot notation path
193+
* @param obj - The object to modify
194+
* @param path - Dot notation path (e.g., "pivotConfig.selectedRowFields")
195+
* @param value - The value to set
196+
*/
197+
function setNestedValue(obj: any, path: string, value: any): void {
198+
const keys = path.split(".");
199+
let current = obj;
200+
201+
// Navigate to the parent of the target key
202+
for (let i = 0; i < keys.length - 1; i++) {
203+
const key = keys[i];
204+
if (!(key in current)) {
205+
current[key] = {};
206+
}
207+
current = current[key];
208+
}
209+
210+
// Set the final value
211+
const finalKey = keys[keys.length - 1];
212+
current[finalKey] = value;
213+
}
214+
164215
/**
165216
* Custom hook that integrates QueryParamsWatcher with React Router's useSearchParams
166217
* This hook should be used in components that need to sync global state with URL query params

0 commit comments

Comments
 (0)