Skip to content

Commit e916f41

Browse files
committed
dynamic updates
1 parent c014c65 commit e916f41

File tree

2 files changed

+187
-3
lines changed

2 files changed

+187
-3
lines changed

WebInterface/src/css/wms-style.css

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,54 @@
2020
box-sizing: border-box;
2121
}
2222

23+
/* Dynamic Update Animations */
24+
@keyframes slideInFromTop {
25+
from {
26+
transform: translateY(-20px);
27+
opacity: 0;
28+
}
29+
to {
30+
transform: translateY(0);
31+
opacity: 1;
32+
}
33+
}
34+
35+
@keyframes highlightNew {
36+
0% {
37+
background-color: #e3f2fd;
38+
}
39+
100% {
40+
background-color: transparent;
41+
}
42+
}
43+
44+
@keyframes highlightUpdate {
45+
0% {
46+
background-color: #fff3cd;
47+
}
48+
100% {
49+
background-color: transparent;
50+
}
51+
}
52+
53+
.session-row {
54+
transition: all 0.3s ease-in-out;
55+
}
56+
57+
.session-row.new-session {
58+
animation: slideInFromTop 0.5s ease-out;
59+
}
60+
61+
.session-row.updated-session {
62+
animation: highlightUpdate 1s ease-out;
63+
}
64+
65+
.session-row:hover {
66+
background-color: #f8f9fa;
67+
transform: translateX(2px);
68+
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
69+
}
70+
2371
body {
2472
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
2573
background-color: var(--zebra-gray);

WebInterface/src/js/wms-app.js

Lines changed: 139 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)