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

Stats: Trying to add The Last updated time to the StatsModule component #11035

Merged
merged 8 commits into from
Feb 10, 2017

Conversation

youknowriad
Copy link
Contributor

@youknowriad youknowriad commented Jan 30, 2017

closes #10911

Since the stats data are now persisted in the local cache, when first hitting the stats page, we show some outdated stats while the query is fetching. So in this PR, I'm adding a blinking effect to the header of the stats module component while the query is fetching.

Also, I added a "time" icon with a title showing the elapsed time since the last stats request.
All this is experimental and needs a design review.

screen shot 2017-01-30 at 14 11 07

Testing instructions

  • Open a stats page: stats/day/$site
  • Notice the "time" icon on the header of the stats panels
  • Also, notice the blinking effect on the header while the query is refreshing

@youknowriad youknowriad added Stats Everything related to our analytics product at /stats/ [Status] Needs Design Review Add this when you'd like to get a review / feedback from the Design team on your PR [Status] Needs Review The PR is ready for review. This also triggers e2e canary tests and wp-desktop tests automatically. labels Jan 30, 2017
@youknowriad youknowriad self-assigned this Jan 30, 2017
@matticbot
Copy link
Contributor

matticbot commented Jan 30, 2017

@folletto
Copy link
Contributor

Also, I added a "time" icon with a title showing the elapsed time since the last stats request.

What's the reason for this? What user goal does it satisfy?

a blinking effect to the header of the stats module component while the query is fetching.

I think it's a good approach. We might review this later, but for now I'd 👍

Here's a visual reference gif:

cap-

@youknowriad
Copy link
Contributor Author

What's the reason for this? What user goal does it satisfy?

The reason for this is to let the user know how old is his data on long requests (websites with a lot of traffic for example), but I agree it's not that important since in most cases the request is quick enough.

@folletto
Copy link
Contributor

The reason for this is to let the user know how old is his data on long requests (websites with a lot of traffic for example), but I agree it's not that important since in most cases the request is quick enough.

Ok. I'd leave this out for now. Adds visual clutter and I can't trace it back to a sensible need for it.
We can come back to it later. :)

@timmyc
Copy link
Contributor

timmyc commented Jan 30, 2017

Here is the related user feedback pKdGS-181-p2 ( not sure if the tampermonkey script works anymore )

So here are the user goals:

I also miss the clock time at the head of the stats that indicated the last time that they were checked. Any chance of the timing indicator being reinstated?

Do the graphs on the new page update in real time? If not, giving the time that the data has been accessed, rather than just the date would also be useful

I'm still using the old stats page, https://wordpress.com/my-stats/, because it
has a timestamp. All the new views no longer show this and that's a big problem
for me.

I like the time stamp at the top of the old stats page among other things. The hole page is just a lot cleaner than the new format.

Old Stats Feature
my_stats_ _wordpress_com

This card in old stats served as a navigation piece ( which users also miss being able to toggle with one click between sites ), but also the timestamp shown represents the time that the stats report was generated. The same navigation piece with the timestamp was shown on all stats pages, including summary pages.

The data situation in calypso is a bit different as each stats module is updated independently - and even in some cases, multiple API calls are used to generate stats on some Insights blocks.

The user goal here is to give them visibility to how current the data the data on-page is. I also failed to search prior to making the new issue, and here is further feedback on the original duplicate issue: #2533

Aside: If other stats pages aren’t going to live update, we really need some way to show when it was “generated” and have a refresh link, especially for the desktop app where there is no “refresh”.

That user goal also adds the need for an easy way to refresh within the desktop app. I believe that feedback was from Matt, but I'd have to dig through the p2 archives to verify.

Alternate Idea
In-lieu of the visual clutter of the clock icon on each module, could we possibly add a single timestamp somewhere on the page? We could use the most recent time that a stats API request was made.

@folletto
Copy link
Contributor

Ok, understood. Thanks for the awesome recap and background. Very useful.

I think a lean solution to that is this one:

screen shot 2017-01-31 at 12 24 08

Note: the second line won't show up in the sticky header, just on the page. Unless we want that, so we might redesign the header a bit.

Where btw we could also change the two arrows icon (which is click-to-refresh) to a pulsating dot of some kind if/when we're able to do auto-refresh of the whole page (like, a refresh every minute?).

What do you think?

@youknowriad
Copy link
Contributor Author

Hey, tks @folletto This looks really good, but I have some technical concerns.

Basically, each one of the panels has its own query, so if we were to show a global date like this "outside of the panels", we'll have to make choices.

I suggest that we rely on the status of the last "statsVisits" query which corresponds to the bar chart query (the chart above) and we add a refresh mechanism to all stats queries.

@timmyc you could have an opinion about this too

@timmyc
Copy link
Contributor

timmyc commented Jan 31, 2017

I suggest that we rely on the status of the last "statsVisits" query which corresponds to the bar chart

Sounds reasonable to me, and would simplify the logic substantially. I think adding the timestamp to the stats "period" pages is a great first step - but we might want to eventually add a similar feature to summary and insight pages too.

@youknowriad
Copy link
Contributor Author

I updated the PR in cddfe9a to reflect the proposal above, but I have several remarks

  • Implementing the click to refresh is very complex because the component showing the date is not responsible of triggering the request (there's a different request in each component). It's feasible by adding a redux state value containing the date when we required a refresh and making the QueryComponents fetch this date and compare it to the last one (or something similar), but IMO if we could avoid adding this complexity, I would prefer. @timmyc @folletto thoughts?

  • I used to topPosts query instead of the chart query because the chart query is complex to compute and. This has no visible effect on the behaviour.

  • I'm wondering if I should make the heartbeat to 1min as the default value on QuerySiteStats this would benefit all stats page calling this component

  • The request date is not persisted on the Redux cache, this means when we refresh the page, the date won't be visible. We could persist this information on the state but there are some technical concerns here. If we were to persist this, we should limit the content of this state subtree (maybe keep only the 20 last requests per site or something like that) to avoid going the cache indefinitely.

  • Also, if we consider persisting the date, we should probably display the date + time.

@folletto
Copy link
Contributor

folletto commented Feb 1, 2017

Implementing the click to refresh

Yep! That was just a design proposal in case we could do it. If we can't, just add the date, knowing that at any point we already know how to do also the manual update.

we add a refresh mechanism to all stats queries

Since we are adding also a refresh mechanism – which is automatic right? – we can just show a pulsating dot on the side, like this: http://codepen.io/folletto/pen/KaQjLV

cap-

Also, if we consider persisting the date, we should probably display the date + time.

What do you mean here?

@youknowriad
Copy link
Contributor Author

which is automatic right?

The refresh mechanism is automatic on the pages showing the refresh date for now, we could generalize to all the stats pages.

we can just show a pulsating dot on the side

Should we show this pulsating dot next to the last update date? I'm not sure where do you want to add this, should it be always visible? And if we already have something similar elsewhere, that could be helpful for consistency.

Also, if we consider persisting the date, we should probably display the date + time.

When you refresh the page, the last query date is not shown on the page because it's not persisted unlike the query results. If we were to change this and cache the date as well, we would probably need to show the full date (Day + Time) to avoid confusion with old dates.

A user could visit the stats page today at 12 and come back tomorrow at the same time (or a week later). I was suggesting to show the date in a format like MMM D, YYYY @ h:mm

@folletto
Copy link
Contributor

folletto commented Feb 1, 2017

Should we show this pulsating dot next to the last update date? I'm not sure where do you want to add this, should it be always visible? And if we already have something similar elsewhere, that could be helpful for consistency.

  1. In place of the refresh icon in the mock above
  2. Always visible, maybe with a tooltip that when hovered says "Auto-refreshing every X minutes"
  3. We already have it. The pulsating dot shows in multiple places already: masterbar when a new section loads, theme modal when a theme is activated. This would be a "small" variation of that same pulsating dot.

A user could visit the stats page today at 12 and come back tomorrow at the same time (or a week later). I was suggesting to show the date in a format like MMM D, YYYY @ h:mm

You mean then on the side of "Last update"? I would avoid that as it gets far too long, and it force the user to read it all. We should use natural language processing:

  • "Last updated: one minute ago"
  • "Last updated: 2 hours ago"
  • "Last updated: yesterday at 20:30"
  • "Last updated: 12 Jan at 12:22"
  • "Last updated: 12 Dec at 18:49"

Ideally using the locale settings of the user.

We should have already something like this as I think it's used elsewhere in Calypso... however, if for any reason we can't use it, we could have just a simple threshold that avoids locale:

  • "h:mm" if it's today
  • "Yesterday" if it's yesterday
  • "X days old" anything else

@youknowriad
Copy link
Contributor Author

I added the pulsing dot and persisted the query date in 7d6821f

kapture 2017-02-02 at 11 32 58

@folletto
Copy link
Contributor

folletto commented Feb 2, 2017

Looking good!

  1. I'm not sure why, but there's a wider gap between the title and the "Last update:" line. Can we reduce it like the mock?
  2. Should we read that from the site "Date / Time format" settings?

@timmyc
Copy link
Contributor

timmyc commented Feb 2, 2017

Should we read that from the site "Date / Time format" settings?

I believe we use moment.js localized date format here.

Oh - I see the timestamp itself:

args: { time: isToday ? date.format( 'HH:mm' ) : date.fromNow() }

If we always used date.fromNow that is localized.

Copy link
Contributor

@timmyc timmyc left a comment

Choose a reason for hiding this comment

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

Few minor questions, and overall looking really great.

@folletto had asked:

Always visible, maybe with a tooltip that when hovered says "Auto-refreshing every X minutes"

I'm not seeing a tooltip currently, do we want to have a tooltip?

Will users want to stop auto-refresh?

As I mentioned in the comments, perhaps in a follow-up PR I think we should consider not doing the heartbeat/refresh on periods that don't include today. Stats data from past periods shouldn't change so repeatedly requesting the same data over and over is kind of a waste of bandwidth.

Additionally, 1 minute seems a bit too eager to me. I think we should bump the refresh up to something like 3 minutes.

Here are a couple of gifs with refreshes in action. The first is for a page that doesn't have much data. Things get a bit jumpy looking to me when the loading placeholders get turned on/off:

heartbeat

Perhaps we can tweak the loading state toggle in <StatsModule /> to handle this a bit better.

On a stats page with data however, I really like the experience. The subtle pulsing of the header is nice:

heartbeat-data

@@ -142,7 +142,7 @@ class StatsGeochart extends Component {
return (
<div>
<div ref="chart" className={ classes } />
{ siteId && <QuerySiteStats statType={ statType } siteId={ siteId } query={ query } /> }
{ siteId && <QuerySiteStats statType={ statType } siteId={ siteId } query={ query } heartbeat={ 60000 } /> }
Copy link
Contributor

Choose a reason for hiding this comment

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

As I mentioned during the hangout, maybe we can bump this up to 2 or 3 minutes. Eventually we might consider disabling the heartbeat on stat periods that are not "active", as-in the data will not change if the period does not include today.

{ queryDate && this.renderQueryDate() }
</span>
}
{ showQueryDate && <div className="stats-date-picker__pulsing-dot" /> }
Copy link
Contributor

Choose a reason for hiding this comment

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

extra tab or spaces here?

@@ -75,8 +89,19 @@ class StatsDatePicker extends Component {
return formattedDate;
}

renderQueryDate() {
const { queryDate, moment, translate } = this.props;
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need to handle a case where queryDate is null? Seems unlikely to happen but curious if we should still add an early return here if so.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is handled but on the calling side, I guess it's better here 👍

@youknowriad
Copy link
Contributor Author

Several things in the last commit c140ddf :

  • Less space between the title and the "Last update" line
  • Auto-refresh enabled by default on all StatsQueries including today
  • The pulsing dot is hidden if Auto-refresh is disabled
  • The loading state for the statsModule component can only be triggered on the first display of the component (not while refreshing)

@youknowriad
Copy link
Contributor Author

@timmyc I preferred to avoid to use only date.fromNow() because this will always show the same thing:

Last update: 1 second ago (or similar and this is not updated until the next redux subscribe)

That's why I kept the HH:mm for closer periods. How can we localize this?

@folletto
Copy link
Contributor

folletto commented Feb 3, 2017

Several things in the last commit

Great suggestions above, and ace work!
I think visually it's solid, and the tooltip I think it gives a proper answer to the question "what's this dot about?" :D

How can we localize this?

Three things:

  1. I think that the combination of time and the pulsating dot explanation "every 3 minutes" works. I felt initially too that "2 minutes ago" was better, but then I thought that didn't make much sense with an auto-update, plus: if the page gets frozen for any reason, then seeing the time frozen is acutually better (even if I'm not sure if this is a case that will ever happen at all!)
  2. For today's time, if we can, we should just localize 12 / 24h time formats.
  3. For previous days, we should probably change the text from "Last update: time" to "24h stats" or something similar. The idea is saying "this data is final".

@youknowriad
Copy link
Contributor Author

In 291e5f0 I've used a localized time format

For previous days, we should probably change the text from "Last update: time" to "24h stats"

This does not work well on other periods weeks, years and months I would rather keep the last update time or maybe drop this line entirely.

const today = moment();
const date = moment( queryDate );
const isToday = today.isSame( date, 'day' );
return translate( 'Last update: %(time)s', {
Copy link

Choose a reason for hiding this comment

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

Hi! I've found a possible matching string that has already been translated 79 times:
translate( 'Last updated: %s' ) ES Score: 7.32

Help me improve these suggestions: react with 👎 if the suggestion doesn't make any sense, or with 👍 if it's a particularly good one (even if not implemented).

@folletto
Copy link
Contributor

folletto commented Feb 6, 2017

This does not work well on other periods weeks, years and months I would rather keep the last update time or maybe drop this line entirely.

Yes I agree, "or something similar"!
I just mentioned we need a different string. Let's find one that works. :)

I just think the time doesn't cut it, as it seems saying "this day was calculated only until $time", which isn't correct as the data is now completed for the full time period.

I think that having some text, if we can find the right one, would be ace. Otherwise we can remove it, but I'd like to try to avoid the "jump" in the visual, as well as having a clear message about "this data is done".

Ideas:

  • "All day", "All month", ...
  • "Full data"
  • "Complete time period"
  • no text

To be honest none of these feels great to me. Ideas welcome. :)

@michelleweber
Copy link

Howdy, y'all! Davide asked me to take a look re: the language here -- a few thoughts from an editor:

I don’t actually think you need text there, because the fact that the date listed will be in the past says pretty clearly that these stats are done being calculated. However, if you feel like you want something there, I’d probably go with something slightly more narrative/full sentence like "These are your complete stats for this day/week/month/year." Using a full sentence here (1) makes things extra clear and (2) the full sentence w/punctuation itself communicates “nothing is changing here, this is done."

If listing a specific time is important, then I’d go with something like “Final calculation for this day/week/month/year completed at timestamp" -- but my choice would be the sentence above rather than the specific time listing.

@folletto
Copy link
Contributor

folletto commented Feb 6, 2017

I tried to mock it up for reference:

screen shot 2017-02-06 at 20 06 20

I think it works well, but I also agree it would make sense without. @youknowriad I'll let you choose since maybe code-wise one is easier than the other (i.e. considering also the sticky bar in the other PR). :)

@timmyc
Copy link
Contributor

timmyc commented Feb 6, 2017

I think when the time period has passed, we just shouldn't render any sentence at all. I believe the date itself implies that the data is for a certain period.

@youknowriad
Copy link
Contributor Author

Thanks everyone for your reflexions on this. I think the majority wins here, let's drop this sentence.

@youknowriad
Copy link
Contributor Author

I updated the PR with last remarks and rebased (the sticky behaviour), Let me know if there's any other concern :)

@folletto
Copy link
Contributor

folletto commented Feb 7, 2017

Current state for reference (sticky behaviour):

screen shot 2017-02-07 at 12 55 31

screen shot 2017-02-07 at 12 55 42

The height of the sticky bar should be constant at so I'd drop the indicator when the page scrolls, like this:

screen shot 2017-02-07 at 12 57 41

This should do the trick:

.is-sticky .stats-date-picker__refresh-status {
  display: none;
}

With that, I think the design is 👍

@@ -37,6 +38,23 @@ export function rangeOfPeriod( period, date ) {
}

/**
* Returns true if is auto refreshing astats is allowed
Copy link
Contributor

Choose a reason for hiding this comment

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

small typo here "Returns true if is auto refreshing of stats is allowed:

@timmyc
Copy link
Contributor

timmyc commented Feb 7, 2017

Testing out really well for me - love this addition!

@timmyc timmyc added [Status] Ready to Merge and removed [Status] Needs Design Review Add this when you'd like to get a review / feedback from the Design team on your PR [Status] Needs Review The PR is ready for review. This also triggers e2e canary tests and wp-desktop tests automatically. labels Feb 7, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Stats Everything related to our analytics product at /stats/
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Stats: Add Last Updated Time Stats
6 participants