@@ -26,6 +26,12 @@ export default class extends Controller {
2626 'snapshotArrivalsChart' ,
2727 'snapshotOvernightsChart' ,
2828 'snapshotByCountryBody' ,
29+ 'showByState' ,
30+ 'byCountryTableHeader' ,
31+ 'byCountryColumnHeader' ,
32+ 'arrivalsChartHeader' ,
33+ 'overnightsChartHeader' ,
34+ 'noStateDataHint' ,
2935 ] ;
3036
3137 static values = {
@@ -40,6 +46,15 @@ export default class extends Controller {
4046 snapshotArrivalsLabel : String ,
4147 snapshotOvernightsLabel : String ,
4248 snapshotRoomLabel : String ,
49+ byCountryTableLabel : String ,
50+ byStateTableLabel : String ,
51+ countryLabel : String ,
52+ stateLabel : String ,
53+ arrivalsByCountryLabel : String ,
54+ overnightsByCountryLabel : String ,
55+ arrivalsByStateLabel : String ,
56+ overnightsByStateLabel : String ,
57+ noStateDataLabel : String ,
4358 } ;
4459
4560 connect ( ) {
@@ -320,17 +335,52 @@ export default class extends Controller {
320335 const data = await response . json ( ) ;
321336 this . currentSnapshotId = data . id || null ;
322337 const countryNames = data . countryNames || { } ;
338+ this . lastTourismData = ( data . metrics && data . metrics . tourism ) ? data . metrics . tourism : { } ;
339+ this . lastCountryNames = countryNames ;
323340
324341 this . updateSnapshotSummary ( data . metrics || { } ) ;
325342 this . updateSnapshotWarnings ( data . warnings || [ ] ) ;
326- this . updateSnapshotByCountryTable (
327- ( data . metrics && data . metrics . tourism ) ? data . metrics . tourism : { } ,
328- countryNames
329- ) ;
330- await this . drawSnapshotCharts (
331- ( data . metrics && data . metrics . tourism ) ? data . metrics . tourism : { } ,
332- countryNames
333- ) ;
343+ this . renderTourismView ( ) ;
344+ }
345+
346+ get isStateView ( ) {
347+ return this . hasShowByStateTarget && this . showByStateTarget . checked ;
348+ }
349+
350+ toggleByState ( ) {
351+ this . renderTourismView ( ) ;
352+ }
353+
354+ renderTourismView ( ) {
355+ const tourism = this . lastTourismData || { } ;
356+ const countryNames = this . lastCountryNames || { } ;
357+ this . updateHeaders ( ) ;
358+ this . updateSnapshotByCountryTable ( tourism , countryNames ) ;
359+ this . drawSnapshotCharts ( tourism , countryNames ) ;
360+ }
361+
362+ updateHeaders ( ) {
363+ const byState = this . isStateView ;
364+ if ( this . hasByCountryTableHeaderTarget ) {
365+ this . byCountryTableHeaderTarget . textContent = byState
366+ ? ( this . byStateTableLabelValue || 'By state' )
367+ : ( this . byCountryTableLabelValue || 'By country' ) ;
368+ }
369+ if ( this . hasByCountryColumnHeaderTarget ) {
370+ this . byCountryColumnHeaderTarget . textContent = byState
371+ ? ( this . stateLabelValue || 'State' )
372+ : ( this . countryLabelValue || 'Country' ) ;
373+ }
374+ if ( this . hasArrivalsChartHeaderTarget ) {
375+ this . arrivalsChartHeaderTarget . textContent = byState
376+ ? ( this . arrivalsByStateLabelValue || 'Arrivals by state' )
377+ : ( this . arrivalsByCountryLabelValue || 'Arrivals by country' ) ;
378+ }
379+ if ( this . hasOvernightsChartHeaderTarget ) {
380+ this . overnightsChartHeaderTarget . textContent = byState
381+ ? ( this . overnightsByStateLabelValue || 'Overnights by state' )
382+ : ( this . overnightsByCountryLabelValue || 'Overnights by country' ) ;
383+ }
334384 }
335385
336386 snapshotParams ( force = false ) {
@@ -413,39 +463,53 @@ export default class extends Controller {
413463
414464 updateSnapshotByCountryTable ( tourism , countryNames ) {
415465 if ( ! this . hasSnapshotByCountryBodyTarget ) return ;
416- const arrivals = tourism . arrivals_by_country || { } ;
417- const overnights = tourism . overnights_by_country || { } ;
418- const countries = Array . from ( new Set ( [
466+ const byState = this . isStateView ;
467+ const arrivals = byState ? ( tourism . arrivals_by_state || { } ) : ( tourism . arrivals_by_country || { } ) ;
468+ const overnights = byState ? ( tourism . overnights_by_state || { } ) : ( tourism . overnights_by_country || { } ) ;
469+ const keys = Array . from ( new Set ( [
419470 ...Object . keys ( arrivals ) ,
420471 ...Object . keys ( overnights ) ,
421472 ] ) ) . sort ( ) ;
422473
423474 this . snapshotByCountryBodyTarget . innerHTML = '' ;
424- countries . forEach ( ( country ) => {
425- const label = this . mapCountryLabel ( country , countryNames ) ;
475+ keys . forEach ( ( key ) => {
476+ const label = byState ? this . formatStateLabel ( key ) : this . mapCountryLabel ( key , countryNames ) ;
426477 const tr = document . createElement ( 'tr' ) ;
427- const tdCountry = document . createElement ( 'td' ) ;
478+ const tdKey = document . createElement ( 'td' ) ;
428479 const tdArrivals = document . createElement ( 'td' ) ;
429480 const tdOvernights = document . createElement ( 'td' ) ;
430- tdCountry . textContent = label ;
431- tdArrivals . textContent = ( arrivals [ country ] ?? 0 ) . toLocaleString ( ) ;
432- tdOvernights . textContent = ( overnights [ country ] ?? 0 ) . toLocaleString ( ) ;
433- tr . appendChild ( tdCountry ) ;
481+ tdKey . textContent = label ;
482+ tdArrivals . textContent = ( arrivals [ key ] ?? 0 ) . toLocaleString ( ) ;
483+ tdOvernights . textContent = ( overnights [ key ] ?? 0 ) . toLocaleString ( ) ;
484+ tr . appendChild ( tdKey ) ;
434485 tr . appendChild ( tdArrivals ) ;
435486 tr . appendChild ( tdOvernights ) ;
436487 this . snapshotByCountryBodyTarget . appendChild ( tr ) ;
437488 } ) ;
489+
490+ if ( this . hasNoStateDataHintTarget ) {
491+ this . noStateDataHintTarget . classList . toggle ( 'd-none' , ! byState || keys . length > 0 ) ;
492+ }
493+ }
494+
495+ formatStateLabel ( stateKey ) {
496+ const slashPos = stateKey . indexOf ( '/' ) ;
497+ if ( slashPos === - 1 ) return stateKey ;
498+ const countryCode = stateKey . substring ( 0 , slashPos ) ;
499+ const stateName = stateKey . substring ( slashPos + 1 ) ;
500+ return `${ stateName } (${ countryCode } )` ;
438501 }
439502
440503 async drawSnapshotCharts ( tourism , countryNames ) {
441504 if ( ! ( await this . waitForChart ( ) ) ) return ;
442- const arrivals = tourism . arrivals_by_country || { } ;
443- const overnights = tourism . overnights_by_country || { } ;
505+ const byState = this . isStateView ;
506+ const arrivals = byState ? ( tourism . arrivals_by_state || { } ) : ( tourism . arrivals_by_country || { } ) ;
507+ const overnights = byState ? ( tourism . overnights_by_state || { } ) : ( tourism . overnights_by_country || { } ) ;
444508 const codes = Array . from ( new Set ( [
445509 ...Object . keys ( arrivals ) ,
446510 ...Object . keys ( overnights ) ,
447511 ] ) ) . sort ( ) ;
448- const labels = codes ;
512+ const labels = codes . map ( ( code ) => byState ? this . formatStateLabel ( code ) : code ) ;
449513 const arrivalsData = codes . map ( ( code ) => arrivals [ code ] ?? 0 ) ;
450514 const overnightsData = codes . map ( ( code ) => overnights [ code ] ?? 0 ) ;
451515
0 commit comments