-
Notifications
You must be signed in to change notification settings - Fork 891
Premium Analytics: add Regions to the Top locations "View by" control #51267
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
Changes from 5 commits
962db00
04566ec
2c0155a
7776c28
2a45e4f
6366765
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| Significance: minor | ||
| Type: added | ||
|
|
||
| Locations: offer Regions in the widget's "View by" control. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -63,6 +63,17 @@ const MISSING_MAP_ERROR_MESSAGE = 'Requested map does not exist'; | |
| // load each country pays the failed draw (a brief error flash) at most once. | ||
| const runtimeUnsupportedProvinceMapCountries = new Set< string >(); | ||
|
|
||
| type GeoGranularity = NonNullable< LocationsAttributes[ 'geoGranularity' ] >; | ||
| // Tab ids owned by the Locations report; `ReportLink` takes a bare string, so | ||
| // naming them here is what catches a typo at build time. | ||
| type LocationsReportSection = 'countries' | 'regions' | 'cities'; | ||
|
|
||
| const REPORT_SECTIONS: Record< GeoGranularity, LocationsReportSection > = { | ||
| country: 'countries', | ||
| region: 'regions', | ||
| city: 'cities', | ||
| }; | ||
|
|
||
| function getGeoChartCountryId( countryCode: string ): string { | ||
| if ( countryCode.toUpperCase() === 'TW' ) { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hum why would we need this special handling here 🤔
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looked at it. I think this line does nothing now. It came in with #50251 the "Avoid unsupported Taiwan map" commit. The actual fix turned out to be cc @dognose24 for confirming.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Confirmed — that line came out of the TW "Requested map does not exist" fight, and you're right that the actual fix was
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Leaving the |
||
| return 'Taiwan'; | ||
|
|
@@ -91,9 +102,10 @@ function LocationsInner( { max, geoGranularity }: LocationsInnerProps ) { | |
| } = useWidgetDrillDown< DrillDownCountry >(); | ||
|
|
||
| // The "View by" control lives in the widget host header (the | ||
| // `relevance: 'high'` attribute). City mode disables country drill-down. | ||
| // `relevance: 'high'` attribute). Only Countries mode drills down, so leaving | ||
| // the other modes would strand a selected country the user can't clear. | ||
|
kangzj marked this conversation as resolved.
|
||
| useEffect( () => { | ||
| if ( geoGranularity === 'city' ) { | ||
| if ( geoGranularity !== 'country' ) { | ||
| clearSelectedCountry(); | ||
| } | ||
| }, [ clearSelectedCountry, geoGranularity ] ); | ||
|
|
@@ -134,11 +146,15 @@ function LocationsInner( { max, geoGranularity }: LocationsInnerProps ) { | |
| const useCountryFallbackMap = | ||
| renderGeoMode === 'region' && !! renderSelectedCountry && ! useProvinceMap; | ||
| const fallbackCountry = useCountryFallbackMap ? renderSelectedCountry : undefined; | ||
| const useCityCountryMap = renderGeoMode === 'city'; | ||
| const cityCountryRows = useMemo( () => { | ||
| // Cities, and Regions outside a country drill-down, span the whole world. | ||
| // Google GeoChart can't place either row type on the world map, so both are | ||
| // summed back up to their country. | ||
| const useCountrySummaryMap = | ||
| renderGeoMode === 'city' || ( renderGeoMode === 'region' && ! renderSelectedCountry ); | ||
| const countrySummaryRows = useMemo( () => { | ||
| const countryRows = new Map< string, { countryFull: string; value: number } >(); | ||
|
|
||
| if ( ! useCityCountryMap ) { | ||
| if ( ! useCountrySummaryMap ) { | ||
| return []; | ||
| } | ||
|
|
||
|
|
@@ -152,7 +168,7 @@ function LocationsInner( { max, geoGranularity }: LocationsInnerProps ) { | |
| } ); | ||
|
|
||
| return Array.from( countryRows.entries() ); | ||
| }, [ data, useCityCountryMap ] ); | ||
| }, [ data, useCountrySummaryMap ] ); | ||
| const handleGeoChartError = useCallback( | ||
| ( error: GeoChartError ) => { | ||
| const message = `${ error.message ?? '' } ${ error.detailedMessage ?? '' }`; | ||
|
|
@@ -201,9 +217,10 @@ function LocationsInner( { max, geoGranularity }: LocationsInnerProps ) { | |
| ); | ||
|
|
||
| const geoData = useMemo( (): GeoData => { | ||
| const useLocationHeader = renderGeoMode === 'region' && ! useCountryFallbackMap; | ||
| // Only the provinces map plots sub-country rows; every other map is | ||
| // country-scoped, whatever the leaderboard beside it lists. | ||
| const header: GoogleDataTableColumn[] = [ | ||
| useLocationHeader | ||
| useProvinceMap | ||
| ? __( 'Location', 'jetpack-premium-analytics-pkg' ) | ||
| : __( 'Country', 'jetpack-premium-analytics-pkg' ), | ||
| __( 'Views', 'jetpack-premium-analytics-pkg' ), | ||
|
|
@@ -227,10 +244,10 @@ function LocationsInner( { max, geoGranularity }: LocationsInnerProps ) { | |
| ]; | ||
| } | ||
|
|
||
| if ( useCityCountryMap ) { | ||
| if ( useCountrySummaryMap ) { | ||
| return [ | ||
| header, | ||
| ...cityCountryRows.map( | ||
| ...countrySummaryRows.map( | ||
| ( [ countryCode, location ] ): GoogleDataTableRow => [ | ||
| { | ||
| v: getGeoChartCountryId( countryCode ), | ||
|
|
@@ -244,14 +261,7 @@ function LocationsInner( { max, geoGranularity }: LocationsInnerProps ) { | |
|
|
||
| const rows: GoogleDataTableRow[] = data.map( location => [ location.label, location.value ] ); | ||
| return [ header, ...rows ]; | ||
| }, [ | ||
| cityCountryRows, | ||
| data, | ||
| fallbackCountry, | ||
| renderGeoMode, | ||
| useCityCountryMap, | ||
| useCountryFallbackMap, | ||
| ] ); | ||
| }, [ countrySummaryRows, data, fallbackCountry, useCountrySummaryMap, useProvinceMap ] ); | ||
|
|
||
| const leaderboardData = useMemo( () => { | ||
| const maxValue = getCombinedPeriodMax( | ||
|
|
@@ -382,17 +392,22 @@ function LocationsInner( { max, geoGranularity }: LocationsInnerProps ) { | |
| */ | ||
| export default function Locations( { attributes = {} }: LocationsWidgetProps ) { | ||
| const max = attributes?.max ?? 10; | ||
| const geoGranularity = attributes?.geoGranularity ?? 'country'; | ||
| // Attributes are persisted, so a stale layout can carry a granularity this | ||
| // widget no longer knows. Normalize once, before it becomes both the endpoint | ||
| // path segment and the report tab. | ||
| const storedGranularity = attributes?.geoGranularity ?? 'country'; | ||
| // `in` would also accept inherited keys such as `toString`, which would then | ||
| // reach the endpoint as a path segment. | ||
| const geoGranularity = Object.prototype.hasOwnProperty.call( REPORT_SECTIONS, storedGranularity ) | ||
| ? storedGranularity | ||
| : 'country'; | ||
|
kangzj marked this conversation as resolved.
Outdated
|
||
|
|
||
| return ( | ||
| <WidgetRoot attributes={ attributes }> | ||
| <div className={ styles.root }> | ||
| <LocationsInner max={ max } geoGranularity={ geoGranularity } /> | ||
| <WidgetFooter> | ||
| <ReportLink | ||
| report="locations" | ||
| section={ geoGranularity === 'city' ? 'cities' : 'countries' } | ||
| /> | ||
| <ReportLink report="locations" section={ REPORT_SECTIONS[ geoGranularity ] } /> | ||
| </WidgetFooter> | ||
| </div> | ||
| </WidgetRoot> | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| Significance: minor | ||
| Type: added | ||
|
|
||
| Top locations: add Regions to the "View by" control, listing the top regions worldwide. |
Uh oh!
There was an error while loading. Please reload this page.