Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: session storage retrieval for url messes with the url history #6238

Merged
merged 25 commits into from
Dec 17, 2024

Conversation

AdityaHegde
Copy link
Collaborator

@AdityaHegde AdityaHegde commented Dec 9, 2024

  • Since we were redirecting url when visiting the home page. Any saved state would lead to a redirect loop when back button was pressed. Using history.replaceState instead to update the url to fix this.
  • Switching between dashboards using the breadcrumbs would pollute the other dashboard's state. Using exploreName from loader function to keep things consistent.
  • Disable TTD for dashboards without timeseries. Earlier the button was clickable but nothing would happen. Now there will not be a button at all.
  • Figure out the E2E failure
  • Load metrics view schema for bookmarks.

@AdityaHegde AdityaHegde force-pushed the fix/url-history-issues branch from 32a414f to 66d545a Compare December 9, 2024 15:07
@AdityaHegde AdityaHegde marked this pull request as ready for review December 10, 2024 10:33
@AdityaHegde AdityaHegde force-pushed the fix/url-history-issues branch from 0f5ee6b to 30b0075 Compare December 10, 2024 11:16
@AdityaHegde AdityaHegde added the blocker A release blocker issue that should be resolved before a new release label Dec 10, 2024
@ericpgreen2
Copy link
Contributor

I added a filter, pressed the browser's back button, the filter was removed from the URL, but the filter was not actually removed from the dashboard.

@@ -86,6 +77,7 @@ export function useExploreValidSpec(
export async function fetchExploreSpec(
Copy link
Contributor

@ericpgreen2 ericpgreen2 Dec 10, 2024

Choose a reason for hiding this comment

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

This is confusing as the function does not actually return an explore spec (or validSpec). A better name might be fetchExploreResourceAndState, but then it's clear that this function is doing more than one thing. While a better name would be an improvement, consider if this function should really be split in two.

Comment on lines 18 to 22
export let defaultExplorePreset: V1ExplorePreset;
export let initExploreState: Partial<MetricsExplorerEntity>;
export let initUrlSearch: string;
export let partialExploreState: Partial<MetricsExplorerEntity>;
export let urlSearchForPartial: string;
Copy link
Contributor

Choose a reason for hiding this comment

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

This confuses me that we're passing state from a subset of sources (defaultExplorePreset, initUrlSearch) and passing initExploreState (which should be a synthesis of the all state sources). We should either:

  1. Pass all state sources (e.g. including localStorageExploreState) and not pass initExploreState (which would be computed downstream).
  2. Pass no individual state sources (e.g. defaultExplorePreset, initUrlSearch) and instead pass initExploreState (which would be computed somewhere upstream).

Given this component seems to be in charge of state synthesis, we should do option 1.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Passing down all states to DashboardURLStateSync and handling the merging logic there.

Copy link
Contributor

Choose a reason for hiding this comment

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

General reminder that this should be a conversion to ExploreState not to ExplorePreset

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes. This PR is not an exhaustive refactor. Lets do that in a separate PR.

web-common/src/features/explores/selectors.ts Outdated Show resolved Hide resolved
web-common/src/features/explores/selectors.ts Outdated Show resolved Hide resolved
web-common/src/features/explores/selectors.ts Outdated Show resolved Hide resolved
@briangregoryholmes
Copy link
Contributor

Related issue here: #6248

@AdityaHegde AdityaHegde self-assigned this Dec 11, 2024
@AdityaHegde AdityaHegde force-pushed the fix/url-history-issues branch from 676a774 to 3fc4354 Compare December 12, 2024 07:16
Comment on lines 27 to +28
export let defaultExplorePreset: V1ExplorePreset;
export let partialExploreState: Partial<MetricsExplorerEntity>;
export let exploreStateFromYAMLConfig: Partial<MetricsExplorerEntity>;
Copy link
Contributor

Choose a reason for hiding this comment

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

These props are covering two different state sources: the Rill-opinionated default state (A) and the developer-specified default state (B).

defaultExplorePreset combines A + B.
exploreStateFromYAMLConfig is just B.

We should have 1 prop for A and 1 prop for B.

"A" should always be of the type ExploreState. I think "B" should be converted from ExplorePreset to ExploreState as soon as we get it back from the GetResource API.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Lets take that refactor in a future PR. ExploreState should inherit from ExplorePreset to avoid mapping of individual fields.

export let defaultExplorePreset: V1ExplorePreset;
export let partialExploreState: Partial<MetricsExplorerEntity>;
export let exploreStateFromYAMLConfig: Partial<MetricsExplorerEntity>;
export let initExploreState: Partial<MetricsExplorerEntity> | undefined =
Copy link
Contributor

Choose a reason for hiding this comment

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

"initExploreState" doesn't specify which source of state it is.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Hmmm this is supposed to be bookmark state on cloud explore, token's state for public URLs and undefined for rill-dev. Not sure what a good name would be to capture this. Adding them explicitly like bookmarkExploreState etc doesnt make sense since it is irrelevant on rill-dev.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think optional props would be most clear:

export let bookmarkExploreState: Partial<ExploreState> | undefined = undefined;
export let tokenExploreState: Partial<ExploreState> | undefined = undefined;

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I have renamed the variables until the call to DashboardURLStateSync. We should avoid having cloud/dev specific login in common code.

@AdityaHegde AdityaHegde force-pushed the fix/url-history-issues branch from 61fc74a to 9cafbd1 Compare December 13, 2024 10:08
@AdityaHegde AdityaHegde force-pushed the fix/url-history-issues branch from b25ea0c to 14d76a9 Compare December 13, 2024 12:56
@AdityaHegde AdityaHegde force-pushed the fix/url-history-issues branch from a8fbef9 to 273a675 Compare December 16, 2024 17:14
Copy link
Contributor

@ericpgreen2 ericpgreen2 left a comment

Choose a reason for hiding this comment

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

UXQA:

  1. Navigate from the project page to a dashboard, add a filter, click the back button, the filter is not removed. Click the back button again, and you're navigated directly to the project page. Jam.
  2. When I highlight a time range, clicking "back" does not remove it: Jam
  3. When I move a highlighted time range to the end of the time series, it gets stuck. I'm unable to move it, and clicking esc does not remove it. Jam
  4. Go from a small timerange & grain (e.g. Last 14 Days, Daily) to a large one (e.g. All Time, which flips to Monthly by default). The dashboard reflects the new time grain (Monthly), but the URL does not (Daily).
  5. In the GitHub Analytics example, there are some commit values that can't be filtered on: Jam. (Maybe this fix belongs in a separate PR.)

I found the above issues from playing with this branch for 5-10 minutes. I will stop there, so, after fixing, please do a thorough round of QA yourself.

Comment on lines 7 to 11
// TODO: Remove this in favour of just `getBasePreset`
export function getDefaultExploreState(
name: string,
metricsView: V1MetricsViewSpec,
explore: V1ExploreSpec,
fullTimeRange: V1MetricsViewTimeRangeResponse | undefined,
defaultExplorePreset = getDefaultExplorePreset(explore, fullTimeRange),
initState: Partial<MetricsExplorerEntity>,
): MetricsExplorerEntity {
Copy link
Contributor

Choose a reason for hiding this comment

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

For now, can you update this comment and describe the difference between the "default" explore state and the "init" explore state? (Though we should disentangle the defaults in a follow-up PR)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Update the variable names. getFullInitExploreState for the function and partialInitState for the argument.

web-common/src/features/explores/selectors.ts Outdated Show resolved Hide resolved
@@ -74,6 +74,7 @@ export class FileArtifact {
readonly fileName: string;
readonly disableAutoSave: boolean;
readonly autoSave: Writable<boolean>;
lastSeenResource: V1Resource;
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this needed? This seems redundant to resourceName

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We need to get all explores that are referring to a metrics view exploreResource?.explore?.state?.validSpec?.metricsView so just the name is not enough.

Comment on lines 50 to 63
// Reset local persisted explore state derived from this metrics view
fileArtifacts
.getResourcesForKind(ResourceKind.Explore)
.forEach((exploreResource) => {
const exploreName = exploreResource?.meta?.name?.name;
if (
!exploreName ||
!exploreResource?.explore?.state?.validSpec?.metricsView ||
exploreResource?.explore?.state?.validSpec?.metricsView !==
metricsViewName
)
return;
clearExploreSessionStore(exploreName, undefined);
});
Copy link
Contributor

Choose a reason for hiding this comment

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

Rather than clearing the session store here, what if we cleared the session store whenever a user navigates away from the dashboard? Similarly, in Cloud, I'm thinking we should clear the session store whenever the user navigates away from the dashboard (say, to the project homepage).

The session store is primarily meant to facilitate navigation between a dashboard's different views. It's not intended to be a "last viewed state" feature when leaving & returning to a dashboard.

Copy link
Contributor

@ericpgreen2 ericpgreen2 left a comment

Choose a reason for hiding this comment

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

I'll approve and merge, so we can get this progress into the main branch and take the follow-ups in smaller PRs. Let's please try to work via more focused, smaller-in-scope PRs. Most of the bullet points in the PR's description could've merited its own dedicated PR.

? FromURLParamViewMap[viewFromUrl]
: (defaultExplorePreset.view ??
V1ExploreWebView.EXPLORE_WEB_VIEW_UNSPECIFIED);
const explorePresetFromSessionStorage = getExplorePresetForWebView(
Copy link
Contributor

Choose a reason for hiding this comment

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

We should be getting ExploreState from session storage, not ExplorePreset

* 2. If only view param is set then load the params from session storage.
* 3. If view=ttd and `measure` is the only other param set load from session storage.
*/
export function getExploreStateFromSessionStorage(
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd expect to see a call to session storage in this function. Perhaps getExplorePresetForWebView (where I see the call to session storage actually happens) is an unnecessary additional layer.

@ericpgreen2 ericpgreen2 merged commit e5ffc5d into main Dec 17, 2024
7 checks passed
@ericpgreen2 ericpgreen2 deleted the fix/url-history-issues branch December 17, 2024 21:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
blocker A release blocker issue that should be resolved before a new release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants