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

Visual improvements to automatic realtime updates #2532

Merged
merged 16 commits into from
Dec 21, 2022

Conversation

RobertJoonas
Copy link
Contributor

Changes

  1. Use the react-flip-move library to make updates to ListReports look nicer.
  2. Unify the color of 'No data yet' in darkmode.

Screencasts to showcase 1 and 2: before -> after (the "Before" screencast already includes the auto-updating work done in #2445)

  1. Lose the flicker in the graph when updated in the realtime mode. A console log demonstrates the moment when new data is fetched. Screencasts: before -> after (before = master)

  2. Fix a bug where graph data was requested twice upon changing the interval. Screencasts: before -> after (before = master)

  3. Some refactoring commits to visitor-graph.js

Tests

  • Writing unit tests for the React dashboard is currently out of scope

Changelog

Documentation

  • This change does not need a documentation update

Dark mode

  • The UI has been tested both in dark and light mode

Fetching new data is handled by the `fetchGraphData` callback in `updateInterval`
The 'maybeRollbackInterval' function was also used to fetch data. This commit replaces
all those function calls with 'fetchGraphData' which better describes the actual behavior.
We should only worry about rolling back the interval if 'query.period' has changed.

This commit also stops the graph from flickering when it is updated in realtime.
@RobertJoonas RobertJoonas changed the base branch from master to realtime-dashboard-improvements December 19, 2022 21:38
@@ -330,16 +329,9 @@ export default class VisitorGraph extends React.Component {
return validIntervals.includes(interval)
}

maybeRollbackInterval() {
Copy link
Contributor

@vinibrsl vinibrsl Dec 20, 2022

Choose a reason for hiding this comment

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

This function checked for invalid states at the very first paint of the component. For example if Plausible ever changes an interval name or removes an interval for a period, users' localStorage would still keep the old invalid value. We need to check that and reset the interval in this case. Could you please also add a comment to the function to make clear this edge case?

Additionally we could delete the localStorage entry whenever an invalid interval value is found. Currently we only reset the state, but not the stored value.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for pointing that out, @vinibrsl! I totally missed thinking about this. It was indeed hard to understand that this was the reason maybeRollbackInterval was called instead of fetchGraphData. Applied your suggested changes in b9c9da3 and also left a comment.

Copy link
Contributor

@ukutaht ukutaht Dec 20, 2022

Choose a reason for hiding this comment

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

I'm still not a fan of the way we have to sync the interval from localStorage to the component state along with worrying about whether it's invalid or not.

This got me thinking that maybe the interval doesn't need to be stored in the component state at all. So I made a little PoC that you can see here: https://github.com/plausible/analytics/compare/flipmove...interval-without-state?expand=1

The main difference is that the interval is gone from the component state. It's always fetched from localStorage when sending a request to the backend. And updating the interval value just means updating localStorage. As far as I can tell this works fine, and doesn't allow invalid intervals to cause an error state. What do you think @RobertJoonas @vinibrsl ?

This makes things a little bit easier to follow for me - no need to reset or sync between localStorage and state. Reading and writing the interval key is more direct and does not care about the component's lifecycle (componentDidMount, componentDidUpdate)

Copy link
Contributor

@vinibrsl vinibrsl Dec 20, 2022

Choose a reason for hiding this comment

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

Good call, @ukutaht! I agree that reading and writing to a single source is better than managing two different sources (localStorage and component state).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I like that idea, and I agree that we wouldn't need to keep the interval state in the component itself. As long as we have default interval values, there shouldn't be any concerns with this. @ukutaht, @vinibrsl, is it OK to open that PoC PR that Uku linked, test it and merge into this branch?

Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like a good plan. I approved this PR in case you want to do that in a separate PR.

@ukutaht
Copy link
Contributor

ukutaht commented Dec 20, 2022

I pulled down the code and I saw that reports using ListReport don't show a spinner when changing period from the date picker. Is that a regression?

@RobertJoonas
Copy link
Contributor Author

@ukutaht

I pulled down the code and I saw that reports using ListReport don't show a spinner when changing period from the date picker. Is that a regression?

You're right. The spinner doesn't show anymore. Should I fix it with a new commit in this PR?

@RobertJoonas RobertJoonas merged commit 497d35a into realtime-dashboard-improvements Dec 21, 2022
@RobertJoonas RobertJoonas deleted the flipmove branch December 21, 2022 13:17
RobertJoonas added a commit that referenced this pull request Jan 2, 2023
* add a new realtime-update-timer module

* hook to the new 'tick' event in ListReport for auto-updates

This commit fixes the bug where all reports using the `ListReport` component did not
auto-update in realtime mode. Those reports are:

- Pages (Top / Entry / Exit)
- Locations (Countries / Regions / Cities)
- Devices (Screen Sizes / Browsers + versions / OS-s + versions)

* fetch data for ListReports only when scrolled into view

* refactor fetching data in ListReport

* refer to one source of truth for utm tags

* make the 'All' tab in Sources auto-update

* make all UTM tabs in Sources auto-update

* fetch UTM data only when scrolled into view

* auto-update Referrers with the new timer

* auto-update google search terms

* auto-update Conversions

* make countries map auto-update

* auto-update visitor-graph and top stats with new timer

* use new tick event for current visitors (in Historical)

* remove the old timer class

* update changelog

* Visual improvements to automatic realtime updates (#2532)

* minor consistency fix for text color in dark mode

* use FlipMove in goal conversions report

* use FlipMove in ListReports

* set main graph and top stats loading state correctly

* refactor isIntervalValid function

* enforce intervals are valid when set and stored

* remove duplicate data fetching on interval change

Fetching new data is handled by the `fetchGraphData` callback in `updateInterval`

* refactor updateMetric function

* make it clearer why 'metric' can be a faulty value

* extract 'query' and 'site' variables from 'this.props'

* reset interval state only when period is changed

The 'maybeRollbackInterval' function was also used to fetch data. This commit replaces
all those function calls with 'fetchGraphData' which better describes the actual behavior.
We should only worry about rolling back the interval if 'query.period' has changed.

This commit also stops the graph from flickering when it is updated in realtime.

* update names of two variables

* remove unnecessary negation

* make collapsed graph state more explicit

* consider stored invalid intervals when graph mounts

* fix not showing loading spinner regression

* remove interval state from VisitorGraph (#2540)

* Realtime prop breakdown (#2535)

* disable load more in realtime mode

* extract doFetch function

* separate fetchPropBreakdown and fetchNextPage functions

* subscribe for auto-updates in realtime

* improve readability with function name changes
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants