@@ -5,6 +5,8 @@ class WMSApp {
55 this . currentView = 'sessions' ;
66 this . sessions = [ ] ;
77 this . currentSession = null ;
8+ this . lastUpdateTime = null ;
9+ this . existingSessionIds = new Set ( ) ;
810 this . init ( ) ;
911 }
1012
@@ -55,9 +57,16 @@ class WMSApp {
5557 const data = await response . json ( ) ;
5658
5759 if ( data . success ) {
58- this . sessions = data . sessions ;
59- this . renderSessions ( ) ;
60+ if ( silent && this . sessions . length > 0 ) {
61+ // Dynamic update mode - only add new sessions and update changed ones
62+ this . dynamicUpdateSessions ( data . sessions ) ;
63+ } else {
64+ // Full refresh mode - initial load or forced refresh
65+ this . sessions = data . sessions ;
66+ this . renderSessions ( ) ;
67+ }
6068 this . updateStats ( ) ;
69+ this . lastUpdateTime = new Date ( ) ;
6170 } else {
6271 throw new Error ( data . error || 'Failed to load sessions' ) ;
6372 }
@@ -69,6 +78,133 @@ class WMSApp {
6978 }
7079 }
7180
81+ dynamicUpdateSessions ( newSessions ) {
82+ const existingSessionMap = new Map ( ) ;
83+ this . sessions . forEach ( session => {
84+ existingSessionMap . set ( session . id , session ) ;
85+ } ) ;
86+
87+ const newSessionsToAdd = [ ] ;
88+ const sessionsToUpdate = [ ] ;
89+
90+ newSessions . forEach ( newSession => {
91+ const existingSession = existingSessionMap . get ( newSession . id ) ;
92+
93+ if ( ! existingSession ) {
94+ // This is a new session
95+ newSessionsToAdd . push ( newSession ) ;
96+ this . sessions . unshift ( newSession ) ; // Add to beginning of array
97+ } else {
98+ // Check if session data has changed
99+ if ( this . hasSessionChanged ( existingSession , newSession ) ) {
100+ sessionsToUpdate . push ( {
101+ old : existingSession ,
102+ new : newSession
103+ } ) ;
104+ // Update the session in our array
105+ const index = this . sessions . findIndex ( s => s . id === newSession . id ) ;
106+ if ( index !== - 1 ) {
107+ this . sessions [ index ] = newSession ;
108+ }
109+ }
110+ }
111+ } ) ;
112+
113+ // Apply dynamic updates to the DOM
114+ if ( newSessionsToAdd . length > 0 ) {
115+ this . addNewSessionsToDOM ( newSessionsToAdd ) ;
116+ }
117+
118+ if ( sessionsToUpdate . length > 0 ) {
119+ this . updateExistingSessionsInDOM ( sessionsToUpdate ) ;
120+ }
121+ }
122+
123+ hasSessionChanged ( oldSession , newSession ) {
124+ // Check if key properties have changed
125+ return oldSession . total_barcodes !== newSession . total_barcodes ||
126+ oldSession . processed_count !== newSession . processed_count ||
127+ oldSession . pending_count !== newSession . pending_count ||
128+ oldSession . last_scan !== newSession . last_scan ;
129+ }
130+
131+ addNewSessionsToDOM ( newSessions ) {
132+ const tableBody = document . querySelector ( '.table tbody' ) ;
133+ if ( ! tableBody ) return ;
134+
135+ newSessions . forEach ( session => {
136+ const sessionRow = this . createSessionRow ( session ) ;
137+
138+ // Add new session animation class
139+ sessionRow . classList . add ( 'new-session' ) ;
140+
141+ // Insert at the beginning (most recent first)
142+ tableBody . insertBefore ( sessionRow , tableBody . firstChild ) ;
143+
144+ // Add a subtle highlight effect after the slide-in animation
145+ setTimeout ( ( ) => {
146+ sessionRow . style . backgroundColor = '#e3f2fd' ;
147+ setTimeout ( ( ) => {
148+ sessionRow . style . backgroundColor = '' ;
149+ sessionRow . style . transition = 'background-color 1s ease-in-out' ;
150+ // Remove the animation class after effects are complete
151+ sessionRow . classList . remove ( 'new-session' ) ;
152+ } , 2000 ) ;
153+ } , 500 ) ;
154+ } ) ;
155+ }
156+
157+ updateExistingSessionsInDOM ( sessionsToUpdate ) {
158+ sessionsToUpdate . forEach ( ( { old : oldSession , new : newSession } ) => {
159+ const existingRow = document . querySelector ( `tr[data-session-id="${ newSession . id } "]` ) ;
160+ if ( existingRow ) {
161+ // Add update animation class
162+ existingRow . classList . add ( 'updated-session' ) ;
163+
164+ // Update the row content
165+ const newRow = this . createSessionRow ( newSession ) ;
166+ existingRow . innerHTML = newRow . innerHTML ;
167+
168+ // Ensure the data-session-id is preserved
169+ existingRow . setAttribute ( 'data-session-id' , newSession . id ) ;
170+
171+ // Remove animation class after animation completes
172+ setTimeout ( ( ) => {
173+ existingRow . classList . remove ( 'updated-session' ) ;
174+ } , 1000 ) ;
175+ }
176+ } ) ;
177+ }
178+
179+ createSessionRow ( session ) {
180+ const sessionTime = new Date ( session . session_timestamp ) . toLocaleString ( ) ;
181+ const duration = this . calculateSessionDuration ( session . first_scan , session . last_scan ) ;
182+ const processedPercent = session . total_barcodes > 0
183+ ? Math . round ( ( session . processed_count / session . total_barcodes ) * 100 )
184+ : 0 ;
185+
186+ const row = document . createElement ( 'tr' ) ;
187+ row . className = 'session-row' ;
188+ row . setAttribute ( 'data-session-id' , session . id ) ;
189+ row . onclick = ( ) => this . showSessionDetails ( session . id ) ;
190+
191+ row . innerHTML = `
192+ <td>${ sessionTime } </td>
193+ <td>${ session . device_info || 'Unknown Device' } </td>
194+ <td>${ session . total_barcodes } </td>
195+ <td>${ session . unique_symbologies } </td>
196+ <td>${ session . processed_count } /${ session . total_barcodes } </td>
197+ <td>
198+ <span class="status ${ processedPercent === 100 ? 'processed' : 'pending' } ">
199+ ${ processedPercent } % Complete
200+ </span>
201+ </td>
202+ <td>${ duration } </td>
203+ ` ;
204+
205+ return row ;
206+ }
207+
72208 async loadSessionDetails ( sessionId ) {
73209 try {
74210 this . showLoading ( 'Loading session details...' ) ;
@@ -233,7 +369,7 @@ class WMSApp {
233369 : 0 ;
234370
235371 html += `
236- <tr onclick="app.showSessionDetails(${ session . id } )" class="session-row">
372+ <tr onclick="app.showSessionDetails(${ session . id } )" class="session-row" data-session-id=" ${ session . id } " >
237373 <td>${ sessionTime } </td>
238374 <td>${ session . device_info || 'Unknown Device' } </td>
239375 <td>${ session . total_barcodes } </td>
0 commit comments