@@ -22,17 +22,7 @@ import "./global.css";
2222import { log } from "./Utils" ;
2323import { toast , ToastContainer } from "react-toastify" ;
2424import "react-toastify/dist/ReactToastify.css" ;
25-
26- /**
27- * returns the default value for the button from the url
28- */
29- function getToggleDefault ( urlKey , defaultVal ) {
30- const urlVal = getQueryStringValue ( urlKey ) ;
31- if ( urlVal === "true" ) {
32- defaultVal = true ;
33- }
34- return defaultVal ;
35- }
25+ import { ALL_TOGGLES , getVisibleToggles } from "./MapToggles" ;
3626
3727class App extends React . Component {
3828 constructor ( props ) {
@@ -41,7 +31,7 @@ class App extends React.Component {
4131 const nowDate = new Date ( ) ;
4232 let urlMinTime = getQueryStringValue ( "minTime" ) ;
4333 let urlMaxTime = getQueryStringValue ( "maxTime" ) ;
44- this . initialMinTime = urlMinTime ? parseInt ( urlMinTime ) : 0 ; // default max time to 1 year in the future
34+ this . initialMinTime = urlMinTime ? parseInt ( urlMinTime ) : 0 ;
4535 this . initialMaxTime = urlMaxTime ? parseInt ( urlMaxTime ) : nowDate . setFullYear ( nowDate . getFullYear ( ) + 1 ) ;
4636 this . focusOnRowFunction = null ;
4737 this . state = {
@@ -50,162 +40,25 @@ class App extends React.Component {
5040 playSpeed : 1000 ,
5141 featuredObject : { msg : "Click a table row to select object" } ,
5242 extraColumns : [ ] ,
53- toggleOptions : {
54- showGPSBubbles : getToggleDefault ( "showGPSBubbles" , false ) ,
55- showHeading : getToggleDefault ( "showHeading" , false ) ,
56- showSpeed : getToggleDefault ( "showSpeed" , false ) ,
57- showTraffic : getToggleDefault ( "showTraffic" , false ) ,
58- showTripStatus : getToggleDefault ( "showTripStatus" , false ) ,
59- showDwellLocations : getToggleDefault ( "showDwellLocations" , false ) ,
60- showNavStatus : getToggleDefault ( "showNavStatus" , false ) ,
61- showETADeltas : getToggleDefault ( "showETADeltas" , false ) ,
62- showHighVelocityJumps : getToggleDefault ( "showHighVelocityJumps" , false ) ,
63- showMissingUpdates : getToggleDefault ( "showMissingUpdates" , false ) ,
64- showTasksAsCreated : getToggleDefault ( "showTasksAsCreated" , false ) ,
65- showPlannedPaths : getToggleDefault ( "showPlannedPaths" , false ) ,
66- showLiveJS : getToggleDefault ( "showLiveJS" , false ) ,
67- showClientServerTimeDeltas : getToggleDefault ( "showClientServerTimeDeltas" , false ) ,
68- } ,
43+ toggleOptions : Object . fromEntries ( ALL_TOGGLES . map ( ( t ) => [ t . id , false ] ) ) ,
6944 uploadedDatasets : [ null , null , null , null , null ] ,
7045 activeDatasetIndex : null ,
7146 activeMenuIndex : null ,
7247 initialMapBounds : null ,
7348 selectedRowIndexPerDataset : [ - 1 , - 1 , - 1 , - 1 , - 1 ] ,
7449 currentLogData : this . props . logData ,
7550 } ;
76- // Realtime updates are too heavy. There must be a better/ react way
7751 this . onSliderChangeDebounced = _ . debounce ( ( timeRange ) => this . onSliderChange ( timeRange ) , 25 ) ;
78-
79- // TODO: refactor so that visualizations are registered
80- // rather than enumerated here?
81- this . toggles = _ . filter (
82- [
83- {
84- id : "showGPSBubbles" ,
85- name : "GPS Accuracy" ,
86- docLink : "https://github.com/googlemaps/fleet-debugger/blob/main/docs/GPSAccuracy.md" ,
87- columns : [ "lastlocation.rawlocationaccuracy" , "lastlocation.locationsensor" ] ,
88- solutionTypes : [ "ODRD" , "LMFS" ] ,
89- } ,
90- {
91- id : "showHeading" ,
92- name : "Heading" ,
93- docLink : "https://github.com/googlemaps/fleet-debugger/blob/main/docs/Heading.md" ,
94- columns : [ "lastlocation.heading" , "lastlocation.headingaccuracy" ] ,
95- solutionTypes : [ "ODRD" , "LMFS" ] ,
96- } ,
97- {
98- id : "showSpeed" ,
99- name : "Speed" ,
100- docLink : "https://github.com/googlemaps/fleet-debugger/blob/main/docs/Speed.md" ,
101- columns : [ ] ,
102- solutionTypes : [ "ODRD" , "LMFS" ] ,
103- } ,
104- {
105- id : "showTripStatus" ,
106- name : "Trip Status" ,
107- docLink : "https://github.com/googlemaps/fleet-debugger/blob/main/docs/TripStatus.md" ,
108- columns : [ ] ,
109- solutionTypes : [ "ODRD" ] ,
110- } ,
111- {
112- id : "showNavStatus" ,
113- name : "Navigation Status" ,
114- docLink : "https://github.com/googlemaps/fleet-debugger/blob/main/docs/NavStatus.md" ,
115- columns : [ ] ,
116- solutionTypes : [ "ODRD" , "LMFS" ] ,
117- } ,
118- {
119- id : "showTasksAsCreated" ,
120- name : "Tasks" ,
121- docLink : "https://github.com/googlemaps/fleet-debugger/blob/main/docs/Tasks.md" ,
122- columns : [ ] ,
123- solutionTypes : [ "LMFS" ] ,
124- } ,
125- {
126- id : "showPlannedPaths" ,
127- name : "Planned Paths" ,
128- docLink : "https://github.com/googlemaps/fleet-debugger/blob/main/docs/PlannedPaths.md" ,
129- columns : [ ] ,
130- solutionTypes : [ "LMFS" ] ,
131- } ,
132- {
133- id : "showDwellLocations" ,
134- name : "Dwell Locations" ,
135- docLink : "https://github.com/googlemaps/fleet-debugger/blob/main/docs/DwellTimes.md" ,
136- columns : [ ] ,
137- solutionTypes : [ "ODRD" , "LMFS" ] ,
138- } ,
139- {
140- id : "showHighVelocityJumps" ,
141- name : "Jumps (unrealistic velocity)" ,
142- docLink : "https://github.com/googlemaps/fleet-debugger/blob/main/docs/VelocityJumps.md" ,
143- columns : [ ] ,
144- solutionTypes : [ "ODRD" , "LMFS" ] ,
145- } ,
146- {
147- id : "showMissingUpdates" ,
148- name : "Jumps (Temporal)" ,
149- docLink : "https://github.com/googlemaps/fleet-debugger/blob/main/docs/MissingUpdates.md" ,
150- columns : [ "temporal_gap" ] ,
151- solutionTypes : [ "ODRD" , "LMFS" ] ,
152- } ,
153- {
154- id : "showClientServerTimeDeltas" ,
155- name : "Client/Server Time Deltas" ,
156- docLink : "https://github.com/googlemaps/fleet-debugger/blob/main/README.md" ,
157- columns : [ ] ,
158- solutionTypes : [ "ODRD" , "LMFS" ] ,
159- } ,
160- {
161- id : "showETADeltas" ,
162- name : "ETA Deltas" ,
163- docLink : "https://github.com/googlemaps/fleet-debugger/blob/main/docs/EtaDeltas.md" ,
164- columns : [ "request.vehicle.etatofirstwaypoint" ] ,
165- solutionTypes : [ "ODRD" ] ,
166- } ,
167- {
168- id : "showTraffic" ,
169- name : "Live Traffic" ,
170- docLink : "https://github.com/googlemaps/fleet-debugger/blob/main/README.md" ,
171- columns : [ ] ,
172- solutionTypes : [ "ODRD" , "LMFS" ] ,
173- } ,
174- {
175- id : "showLiveJS" ,
176- name : "Live Journey Sharing" ,
177- docLink : "https://github.com/googlemaps/fleet-debugger/blob/main/README.md" ,
178- columns : [ ] ,
179- solutionTypes : [ "ODRD" , "LMFS" ] ,
180- } ,
181- ] ,
182- ( toggle ) => {
183- return toggle . solutionTypes . indexOf ( this . state . currentLogData . solutionType ) !== - 1 ;
184- }
185- ) ;
18652 this . setFeaturedObject = this . setFeaturedObject . bind ( this ) ;
18753 this . setTimeRange = this . setTimeRange . bind ( this ) ;
18854 }
18955
190- /*
191- * Update react state from data in the url. This could/should be
192- * cleaned up. The pure react state is actually set properly in the
193- * constructor ... all this does is update the map and associated
194- * data (once it's loaded). Given this split it's definitely possible
195- * that this just overwrites settings a quickfingered user already
196- * changed.
197- */
19856 updateMapAndAssociatedData = ( ) => {
19957 this . setTimeRange ( this . state . timeRange . minTime , this . state . timeRange . maxTime ) ;
200- _ . map ( this . toggles , ( toggle ) => {
201- const urlVal = getQueryStringValue ( toggle . id ) ;
202- if ( urlVal === "true" ) {
203- this . updateToggleState ( true , toggle . id , toggle . columns ) ;
204- }
205- } ) ;
20658 } ;
20759
20860 componentDidMount ( ) {
61+ log ( `Initial device pixel ratio: ${ window . devicePixelRatio } ` ) ;
20962 this . initializeData ( ) . then ( ( ) => {
21063 this . updateMapAndAssociatedData ( ) ;
21164 } ) ;
@@ -221,34 +74,27 @@ class App extends React.Component {
22174
22275 updateToggleState ( newValue , toggleName , jsonPaths ) {
22376 this . setState ( ( prevState ) => {
224- prevState . toggleOptions [ toggleName ] = newValue ;
225- setQueryStringValue ( toggleName , newValue ) ;
226- const extraColumns = _ . clone ( prevState . extraColumns ) ;
227- _ . forEach ( jsonPaths , ( path ) => {
228- if ( newValue ) {
229- extraColumns . push ( path ) ;
230- } else {
231- _ . pull ( extraColumns , path ) ;
232- }
233- } ) ;
234- prevState . extraColumns = _ . uniq ( extraColumns ) ;
235- return prevState ;
77+ const newToggleOptions = {
78+ ...prevState . toggleOptions ,
79+ [ toggleName ] : newValue ,
80+ } ;
81+
82+ const newExtraColumns = newValue
83+ ? _ . union ( prevState . extraColumns , jsonPaths )
84+ : _ . difference ( prevState . extraColumns , jsonPaths ) ;
85+
86+ return {
87+ toggleOptions : newToggleOptions ,
88+ extraColumns : newExtraColumns ,
89+ } ;
23690 } ) ;
23791 }
23892
239- /*
240- * Updates react state associated with the slider and calls into
241- * the non-react map code to do the same.
242- */
24393 onSliderChange ( timeRange ) {
24494 this . setTimeRange ( timeRange . minTime , timeRange . maxTime ) ;
24595 }
24696
247- /*
248- * Callback to updated selected log row
249- */
25097 onSelectionChange ( selectedRow , rowIndex ) {
251- // Save both the selected row and its index for the current dataset
25298 if ( this . state . activeDatasetIndex !== null && rowIndex !== undefined ) {
25399 this . setState ( ( prevState ) => {
254100 const newSelectedIndexes = [ ...prevState . selectedRowIndexPerDataset ] ;
@@ -264,9 +110,6 @@ class App extends React.Component {
264110 }
265111 }
266112
267- /*
268- * Set the featured object
269- */
270113 setFeaturedObject ( featuredObject ) {
271114 this . setState ( { featuredObject : featuredObject } ) ;
272115 }
@@ -281,9 +124,6 @@ class App extends React.Component {
281124 }
282125 } ;
283126
284- /*
285- * exposes editing of the timeRange state
286- */
287127 setTimeRange ( minTime , maxTime , callback ) {
288128 setQueryStringValue ( "minTime" , minTime ) ;
289129 setQueryStringValue ( "maxTime" , maxTime ) ;
@@ -818,29 +658,22 @@ class App extends React.Component {
818658 log ( `Switched to dataset ${ index } ` ) ;
819659 log ( `New time range: ${ tripLogs . minDate } - ${ tripLogs . maxDate } ` ) ;
820660
821- // After dataset is loaded, try to restore the previously selected row index
822661 const savedRowIndex = this . state . selectedRowIndexPerDataset [ index ] ;
823662 log ( `Attempting to restore row at index ${ savedRowIndex } for dataset ${ index } ` ) ;
824663
825- // Wait for map and components to fully initialize
826664 setTimeout ( ( ) => {
827665 if ( savedRowIndex >= 0 ) {
828- // Get current log data with the new time range
829666 const minDate = new Date ( this . state . timeRange . minTime ) ;
830667 const maxDate = new Date ( this . state . timeRange . maxTime ) ;
831668 const logs = tripLogs . getLogs_ ( minDate , maxDate ) . value ( ) ;
832669
833- // Check if the saved index is valid for the current dataset
834670 if ( savedRowIndex < logs . length ) {
835671 log ( `Restoring row at index ${ savedRowIndex } ` ) ;
836672 const rowToSelect = logs [ savedRowIndex ] ;
837673
838- // First update the featured object
839674 this . setState ( { featuredObject : rowToSelect } , ( ) => {
840- // Then focus on the row in the table
841675 this . focusOnSelectedRow ( ) ;
842676
843- // And finally center the map on the location (simulating a long press)
844677 const lat = _ . get ( rowToSelect , "lastlocation.rawlocation.latitude" ) ;
845678 const lng = _ . get ( rowToSelect , "lastlocation.rawlocation.longitude" ) ;
846679
@@ -856,13 +689,11 @@ class App extends React.Component {
856689 this . selectFirstRow ( ) ;
857690 }
858691 } else {
859- // If no saved selection or invalid index, select first row
860692 log ( `No previously saved row index for dataset ${ index } , selecting first row` ) ;
861693 this . selectFirstRow ( ) ;
862694 }
863- } , 300 ) ; // Increased delay to ensure map is fully initialized
695+ } , 300 ) ;
864696
865- // Update map and associated data
866697 this . updateMapAndAssociatedData ( ) ;
867698 }
868699 ) ;
@@ -875,15 +706,15 @@ class App extends React.Component {
875706 } ;
876707
877708 toggleClickHandler ( id ) {
878- const toggle = _ . find ( this . toggles , { id } ) ;
709+ const toggle = _ . find ( ALL_TOGGLES , { id } ) ;
879710 const newValue = ! this . state . toggleOptions [ id ] ;
880711 this . updateToggleState ( newValue , id , toggle . columns ) ;
881712 }
882713
883714 render ( ) {
884- const selectedEventTime = this . state . featuredObject ?. timestamp
885- ? new Date ( this . state . featuredObject . timestamp ) . getTime ( )
886- : null ;
715+ const { featuredObject , timeRange , currentLogData , toggleOptions , extraColumns } = this . state ;
716+ const selectedEventTime = featuredObject ?. timestamp ? new Date ( featuredObject . timestamp ) . getTime ( ) : null ;
717+ const visibleToggles = getVisibleToggles ( currentLogData . solutionType ) ;
887718
888719 return (
889720 < div className = "app-container" >
@@ -893,12 +724,12 @@ class App extends React.Component {
893724 < div className = "map-container" >
894725 < Map
895726 key = { `map-${ this . state . activeDatasetIndex } ` }
896- logData = { this . state . currentLogData }
897- rangeStart = { this . state . timeRange . minTime }
898- rangeEnd = { this . state . timeRange . maxTime }
899- selectedRow = { this . state . featuredObject }
900- toggles = { this . toggles }
901- toggleOptions = { this . state . toggleOptions }
727+ logData = { currentLogData }
728+ rangeStart = { timeRange . minTime }
729+ rangeEnd = { timeRange . maxTime }
730+ selectedRow = { featuredObject }
731+ toggles = { visibleToggles }
732+ toggleOptions = { toggleOptions }
902733 setFeaturedObject = { this . setFeaturedObject }
903734 setTimeRange = { this . setTimeRange }
904735 setCenterOnLocation = { this . setCenterOnLocation }
@@ -907,18 +738,18 @@ class App extends React.Component {
907738 />
908739 </ div >
909740 < TimeSlider
910- logData = { this . state . currentLogData }
911- curMin = { this . state . timeRange . minTime }
912- curMax = { this . state . timeRange . maxTime }
741+ logData = { currentLogData }
742+ curMin = { timeRange . minTime }
743+ curMax = { timeRange . maxTime }
913744 onSliderChange = { this . onSliderChangeDebounced }
914745 selectedEventTime = { selectedEventTime }
915746 onRowSelect = { ( row , rowIndex ) => this . onSelectionChange ( row , rowIndex ) }
916747 centerOnLocation = { this . centerOnLocation }
917748 focusSelectedRow = { this . focusOnSelectedRow }
918749 />
919750 < ToggleBar
920- toggles = { this . toggles }
921- toggleState = { this . state . toggleOptions }
751+ toggles = { visibleToggles }
752+ toggleState = { toggleOptions }
922753 clickHandler = { ( id ) => this . toggleClickHandler ( id ) }
923754 />
924755 < div className = "nav-controls" >
@@ -959,21 +790,18 @@ class App extends React.Component {
959790 </ div >
960791 < div style = { { flex : 1 , overflow : "auto" } } >
961792 < LogTable
962- logData = { this . state . currentLogData }
793+ logData = { currentLogData }
963794 style = { { width : "100%" } }
964- timeRange = { this . state . timeRange }
965- extraColumns = { this . state . extraColumns }
795+ timeRange = { timeRange }
796+ extraColumns = { extraColumns }
966797 onSelectionChange = { ( rowData , rowIndex ) => this . onSelectionChange ( rowData , rowIndex ) }
967798 setFocusOnRowFunction = { this . setFocusOnRowFunction }
968799 centerOnLocation = { this . centerOnLocation }
969800 />
970801 </ div >
971802 </ div >
972803 < div className = "dataframe-section" >
973- < Dataframe
974- featuredObject = { this . state . featuredObject }
975- onClick = { ( select ) => this . onDataframePropClick ( select ) }
976- />
804+ < Dataframe featuredObject = { featuredObject } onClick = { ( select ) => this . onDataframePropClick ( select ) } />
977805 </ div >
978806 </ div >
979807 ) ;
0 commit comments