Spaces:
No application file
No application file
fix
Browse files- app/static/js/app-device.js +105 -100
- app/static/js/app.js +18 -0
app/static/js/app-device.js
CHANGED
@@ -19,16 +19,74 @@ const programsLoading = document.getElementById('programsLoading');
|
|
19 |
const programsList = document.getElementById('programsList');
|
20 |
const noProgramsMessage = document.getElementById('noProgramsMessage');
|
21 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
22 |
// νμ΄μ§ λ‘λ μ μ΄κΈ°ν
|
23 |
document.addEventListener('DOMContentLoaded', () => {
|
24 |
console.log("μ₯μΉ κ΄λ¦¬ λͺ¨λ μ΄κΈ°ν");
|
25 |
|
26 |
-
//
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
|
|
|
|
|
|
|
|
32 |
|
33 |
// μ₯μΉ μν νμΈ λ²νΌ μ΄λ²€νΈ 리μ€λ
|
34 |
checkDeviceStatusButton.addEventListener('click', () => {
|
@@ -49,48 +107,6 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
49 |
});
|
50 |
});
|
51 |
|
52 |
-
/**
|
53 |
-
* ν μ ν ν¨μ (κΈ°μ‘΄ app.jsμ ν¨μ νμ₯)
|
54 |
-
* @param {string} tabName - νμ±νν ν μ΄λ¦ ('chat', 'docs', 'device')
|
55 |
-
*/
|
56 |
-
function switchTab(tabName) {
|
57 |
-
// app.jsμ μ΄λ―Έ μ μλ ν¨μλ₯Ό μ°Έμ‘°
|
58 |
-
if (typeof window.switchTab === 'function') {
|
59 |
-
// κΈ°μ‘΄ switchTab ν¨μ νΈμΆ
|
60 |
-
window.switchTab(tabName);
|
61 |
-
return;
|
62 |
-
}
|
63 |
-
|
64 |
-
// κΈ°μ‘΄ ν¨μκ° μλ κ²½μ°λ₯Ό λλΉν κΈ°λ³Έ ꡬν
|
65 |
-
const chatTab = document.getElementById('chatTab');
|
66 |
-
const docsTab = document.getElementById('docsTab');
|
67 |
-
const chatSection = document.getElementById('chatSection');
|
68 |
-
const docsSection = document.getElementById('docsSection');
|
69 |
-
|
70 |
-
if (tabName === 'chat') {
|
71 |
-
chatTab.classList.add('active');
|
72 |
-
docsTab.classList.remove('active');
|
73 |
-
deviceTab.classList.remove('active');
|
74 |
-
chatSection.classList.add('active');
|
75 |
-
docsSection.classList.remove('active');
|
76 |
-
deviceSection.classList.remove('active');
|
77 |
-
} else if (tabName === 'docs') {
|
78 |
-
chatTab.classList.remove('active');
|
79 |
-
docsTab.classList.add('active');
|
80 |
-
deviceTab.classList.remove('active');
|
81 |
-
chatSection.classList.remove('active');
|
82 |
-
docsSection.classList.add('active');
|
83 |
-
deviceSection.classList.remove('active');
|
84 |
-
} else if (tabName === 'device') {
|
85 |
-
chatTab.classList.remove('active');
|
86 |
-
docsTab.classList.remove('active');
|
87 |
-
deviceTab.classList.add('active');
|
88 |
-
chatSection.classList.remove('active');
|
89 |
-
docsSection.classList.remove('active');
|
90 |
-
deviceSection.classList.add('active');
|
91 |
-
}
|
92 |
-
}
|
93 |
-
|
94 |
/**
|
95 |
* μλ¬ μ²λ¦¬ ν¬νΌ ν¨μ
|
96 |
* @param {Error} error - λ°μν μ€λ₯
|
@@ -126,7 +142,7 @@ function escapeHtml(unsafe) {
|
|
126 |
}
|
127 |
|
128 |
/**
|
129 |
-
* μ₯μΉ κ΄λ¦¬ μλ² μν νμΈ ν¨μ
|
130 |
*/
|
131 |
async function checkDeviceStatus() {
|
132 |
console.log("μ₯μΉ μν νμΈ μ€...");
|
@@ -140,8 +156,8 @@ async function checkDeviceStatus() {
|
|
140 |
const controller = new AbortController();
|
141 |
const timeoutId = setTimeout(() => controller.abort(), 5000); // 5μ΄ νμμμ
|
142 |
|
143 |
-
// API μμ²
|
144 |
-
const response = await fetch('/api/
|
145 |
signal: controller.signal
|
146 |
});
|
147 |
|
@@ -159,10 +175,10 @@ async function checkDeviceStatus() {
|
|
159 |
deviceStatusLoading.classList.add('hidden');
|
160 |
deviceStatusResult.classList.remove('hidden');
|
161 |
|
162 |
-
if (data.
|
163 |
// μ¨λΌμΈ μνμΈ κ²½μ°
|
164 |
statusIcon.innerHTML = '<i class="fas fa-circle online"></i>';
|
165 |
-
statusText.textContent = `μλ² μν: ${data.
|
166 |
|
167 |
// μλμΌλ‘ μ₯μΉ λͺ©λ‘ λ‘λ
|
168 |
loadDevices();
|
@@ -199,8 +215,8 @@ async function loadDevices() {
|
|
199 |
const controller = new AbortController();
|
200 |
const timeoutId = setTimeout(() => controller.abort(), 5000); // 5μ΄ νμμμ
|
201 |
|
202 |
-
// API μμ²
|
203 |
-
const response = await fetch('/api/
|
204 |
signal: controller.signal
|
205 |
});
|
206 |
|
@@ -217,19 +233,15 @@ async function loadDevices() {
|
|
217 |
// UI μ
λ°μ΄νΈ
|
218 |
devicesLoading.classList.add('hidden');
|
219 |
|
220 |
-
if (data.
|
221 |
-
//
|
222 |
data.devices.forEach(device => {
|
223 |
-
const
|
224 |
-
deviceList.appendChild(
|
225 |
});
|
226 |
} else {
|
227 |
-
//
|
228 |
noDevicesMessage.classList.remove('hidden');
|
229 |
-
|
230 |
-
if (data.error) {
|
231 |
-
noDevicesMessage.querySelector('p').textContent = `μ€λ₯: ${data.error}`;
|
232 |
-
}
|
233 |
}
|
234 |
} catch (error) {
|
235 |
console.error("μ₯μΉ λͺ©λ‘ λ‘λ μ€λ₯:", error);
|
@@ -237,7 +249,7 @@ async function loadDevices() {
|
|
237 |
// UI μ
λ°μ΄νΈ
|
238 |
devicesLoading.classList.add('hidden');
|
239 |
noDevicesMessage.classList.remove('hidden');
|
240 |
-
noDevicesMessage.
|
241 |
}
|
242 |
}
|
243 |
|
@@ -334,8 +346,8 @@ async function loadPrograms() {
|
|
334 |
const controller = new AbortController();
|
335 |
const timeoutId = setTimeout(() => controller.abort(), 5000); // 5μ΄ νμμμ
|
336 |
|
337 |
-
// API μμ²
|
338 |
-
const response = await fetch('/api/
|
339 |
signal: controller.signal
|
340 |
});
|
341 |
|
@@ -352,20 +364,15 @@ async function loadPrograms() {
|
|
352 |
// UI μ
λ°μ΄νΈ
|
353 |
programsLoading.classList.add('hidden');
|
354 |
|
355 |
-
if (data.
|
356 |
-
//
|
357 |
data.programs.forEach(program => {
|
358 |
-
const
|
359 |
-
programsList.appendChild(
|
360 |
});
|
361 |
-
noProgramsMessage.classList.add('hidden');
|
362 |
} else {
|
363 |
-
//
|
364 |
noProgramsMessage.classList.remove('hidden');
|
365 |
-
|
366 |
-
if (data.error) {
|
367 |
-
noProgramsMessage.querySelector('p').textContent = `μ€λ₯: ${data.error}`;
|
368 |
-
}
|
369 |
}
|
370 |
} catch (error) {
|
371 |
console.error("νλ‘κ·Έλ¨ λͺ©λ‘ λ‘λ μ€λ₯:", error);
|
@@ -373,7 +380,7 @@ async function loadPrograms() {
|
|
373 |
// UI μ
λ°μ΄νΈ
|
374 |
programsLoading.classList.add('hidden');
|
375 |
noProgramsMessage.classList.remove('hidden');
|
376 |
-
noProgramsMessage.
|
377 |
}
|
378 |
}
|
379 |
|
@@ -421,52 +428,50 @@ function createProgramItem(program) {
|
|
421 |
|
422 |
/**
|
423 |
* νλ‘κ·Έλ¨ μ€ν ν¨μ
|
424 |
-
* @param {string} programId - νλ‘κ·Έλ¨ ID
|
425 |
-
* @param {string} programName - νλ‘κ·Έλ¨ μ΄λ¦
|
426 |
*/
|
427 |
async function executeProgram(programId, programName) {
|
428 |
-
|
|
|
|
|
429 |
|
430 |
// μ€ν νμΈ
|
431 |
if (!confirm(`'${programName}' νλ‘κ·Έλ¨μ μ€ννμκ² μ΅λκΉ?`)) {
|
|
|
432 |
return;
|
433 |
}
|
434 |
|
435 |
try {
|
436 |
-
//
|
437 |
-
|
438 |
-
const timeoutId = setTimeout(() => controller.abort(), 10000); // 10μ΄ νμμμ (μ€νμλ λ κΈ΄ μκ° λΆμ¬)
|
439 |
|
440 |
-
// API μμ²
|
441 |
-
const response = await fetch(`/api/
|
442 |
method: 'POST',
|
443 |
headers: {
|
444 |
'Content-Type': 'application/json'
|
445 |
},
|
446 |
-
body: JSON.stringify({})
|
447 |
-
signal: controller.signal
|
448 |
});
|
449 |
|
450 |
-
clearTimeout(timeoutId); // νμμμ ν΄μ
|
451 |
-
|
452 |
// μλ΅ μ²λ¦¬
|
453 |
if (!response.ok) {
|
454 |
-
|
455 |
-
throw new Error(errorData.error || `HTTP μ€λ₯: ${response.status}`);
|
456 |
}
|
457 |
|
458 |
const data = await response.json();
|
459 |
-
console.log(
|
460 |
|
461 |
-
//
|
462 |
if (data.success) {
|
463 |
-
showNotification(`'${programName}'
|
464 |
} else {
|
465 |
-
showNotification(`'${programName}' μ€ν
|
466 |
}
|
467 |
} catch (error) {
|
468 |
-
console.error(`νλ‘κ·Έλ¨ μ€ν μ€λ₯ (${
|
469 |
-
showNotification(`'${programName}' μ€ν
|
470 |
}
|
471 |
}
|
472 |
|
@@ -508,5 +513,5 @@ function showNotification(message, type = 'info') {
|
|
508 |
}, 5000); // 5μ΄ ν μ¬λΌμ§
|
509 |
}
|
510 |
|
511 |
-
//
|
512 |
-
window.
|
|
|
19 |
const programsList = document.getElementById('programsList');
|
20 |
const noProgramsMessage = document.getElementById('noProgramsMessage');
|
21 |
|
22 |
+
// μ₯μΉ μλ² URL μ€μ
|
23 |
+
// μ§μ μ κ·Ό μ€μ : λΉ λ¬Έμμ΄μ΄λ©΄ νμ¬ νΈμ€νΈμ 5050 ν¬νΈλ₯Ό μ¬μ©
|
24 |
+
let DEVICE_SERVER_URL = ''; // μλ²μμ μ λ¬λ URLμ΄ μμΌλ©΄ μ΄κΈ°ν μ μ€μ λ¨
|
25 |
+
|
26 |
+
/**
|
27 |
+
* μ₯μΉ μλ² API κ²½λ‘ μμ± ν¨μ
|
28 |
+
* @param {string} endpoint - API μλν¬μΈνΈ κ²½λ‘
|
29 |
+
* @returns {string} - μμ ν API URL
|
30 |
+
*/
|
31 |
+
function getDeviceApiUrl(endpoint) {
|
32 |
+
// μ§μ μ κ·Ό λͺ¨λμΈ κ²½μ° (λ³λ μλ²μ μ§μ μμ²)
|
33 |
+
if (DEVICE_SERVER_URL) {
|
34 |
+
return `${DEVICE_SERVER_URL}${endpoint}`;
|
35 |
+
}
|
36 |
+
|
37 |
+
// νλ‘μ λͺ¨λμΈ κ²½μ° (λ΄λΆ API κ²½λ‘ μ¬μ©)
|
38 |
+
return endpoint;
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* μ₯μΉ μλ² μ€μ μ΄κΈ°ν (νμ΄μ§ λ‘λ μ νΈμΆ)
|
43 |
+
*/
|
44 |
+
function initDeviceServerSettings() {
|
45 |
+
console.log("μ₯μΉ μλ² μ€μ μ΄κΈ°ν μμ");
|
46 |
+
// μλ² URL μ€μ (μΉ μλ²λ‘λΆν° μ€μ λΆλ¬μ€κΈ°)
|
47 |
+
fetch('/api/device/settings')
|
48 |
+
.then(response => {
|
49 |
+
if (!response.ok) {
|
50 |
+
throw new Error('μ€μ μ κ°μ Έμ¬ μ μμ΅λλ€');
|
51 |
+
}
|
52 |
+
return response.json();
|
53 |
+
})
|
54 |
+
.then(data => {
|
55 |
+
if (data.server_url) {
|
56 |
+
console.log(`μ₯μΉ μλ² URL μ€μ λ¨: ${data.server_url}`);
|
57 |
+
DEVICE_SERVER_URL = data.server_url;
|
58 |
+
} else {
|
59 |
+
// μ€μ μμ - μλ μμ± (νμ¬ νΈμ€νΈ + ν¬νΈ 5050)
|
60 |
+
const currentHost = window.location.hostname;
|
61 |
+
const protocol = window.location.protocol;
|
62 |
+
DEVICE_SERVER_URL = `${protocol}//${currentHost}:5050`;
|
63 |
+
console.log(`μ₯μΉ μλ² URL μλ μ€μ : ${DEVICE_SERVER_URL}`);
|
64 |
+
}
|
65 |
+
})
|
66 |
+
.catch(error => {
|
67 |
+
console.error('μ₯μΉ μλ² μ€μ μ΄κΈ°ν μ€λ₯:', error);
|
68 |
+
// κΈ°λ³Έκ°μΌλ‘ μ€μ (νμ¬ νΈμ€νΈ + ν¬νΈ 5050)
|
69 |
+
const currentHost = window.location.hostname;
|
70 |
+
const protocol = window.location.protocol;
|
71 |
+
DEVICE_SERVER_URL = `${protocol}//${currentHost}:5050`;
|
72 |
+
console.log(`μ₯μΉ μλ² URL κΈ°λ³Έκ° μ€μ : ${DEVICE_SERVER_URL}`);
|
73 |
+
});
|
74 |
+
}
|
75 |
+
|
76 |
// νμ΄μ§ λ‘λ μ μ΄κΈ°ν
|
77 |
document.addEventListener('DOMContentLoaded', () => {
|
78 |
console.log("μ₯μΉ κ΄λ¦¬ λͺ¨λ μ΄κΈ°ν");
|
79 |
|
80 |
+
// μ₯μΉ μλ² μ€μ μ΄κΈ°ν
|
81 |
+
initDeviceServerSettings();
|
82 |
+
|
83 |
+
// ν μ ν μ΄λ²€νΈ 리μ€λλ μ΄λ―Έ app.jsμμ λ±λ‘λμ΄ μμΌλ―λ‘ μ¬κΈ°μλ λ±λ‘νμ§ μμ
|
84 |
+
// λμ μ μ ν¨μκ° μ¬λ°λ₯΄κ² μ€μ λμ΄ μλμ§ νμΈ
|
85 |
+
if (typeof window.switchTab !== 'function') {
|
86 |
+
console.log("window.switchTab ν¨μκ° μ μλμ§ μμμ΅λλ€. λ΄λΆ ꡬνμ μ¬μ©ν©λλ€.");
|
87 |
+
} else {
|
88 |
+
console.log("window.switchTab ν¨μ μ¬μ© κ°λ₯ν©λλ€.");
|
89 |
+
}
|
90 |
|
91 |
// μ₯μΉ μν νμΈ λ²νΌ μ΄λ²€νΈ 리μ€λ
|
92 |
checkDeviceStatusButton.addEventListener('click', () => {
|
|
|
107 |
});
|
108 |
});
|
109 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
110 |
/**
|
111 |
* μλ¬ μ²λ¦¬ ν¬νΌ ν¨μ
|
112 |
* @param {Error} error - λ°μν μ€λ₯
|
|
|
142 |
}
|
143 |
|
144 |
/**
|
145 |
+
* μ₯μΉ κ΄λ¦¬ μλ² μν νμΈ ν¨μ - μ μ ν¨μλ‘ export
|
146 |
*/
|
147 |
async function checkDeviceStatus() {
|
148 |
console.log("μ₯μΉ μν νμΈ μ€...");
|
|
|
156 |
const controller = new AbortController();
|
157 |
const timeoutId = setTimeout(() => controller.abort(), 5000); // 5μ΄ νμμμ
|
158 |
|
159 |
+
// API μμ² - μμ λ URL κ΅¬μ± μ¬μ©
|
160 |
+
const response = await fetch(getDeviceApiUrl('/api/status'), {
|
161 |
signal: controller.signal
|
162 |
});
|
163 |
|
|
|
175 |
deviceStatusLoading.classList.add('hidden');
|
176 |
deviceStatusResult.classList.remove('hidden');
|
177 |
|
178 |
+
if (data.status === "online") {
|
179 |
// μ¨λΌμΈ μνμΈ κ²½μ°
|
180 |
statusIcon.innerHTML = '<i class="fas fa-circle online"></i>';
|
181 |
+
statusText.textContent = `μλ² μν: ${data.status || 'μ μ'}`;
|
182 |
|
183 |
// μλμΌλ‘ μ₯μΉ λͺ©λ‘ λ‘λ
|
184 |
loadDevices();
|
|
|
215 |
const controller = new AbortController();
|
216 |
const timeoutId = setTimeout(() => controller.abort(), 5000); // 5μ΄ νμμμ
|
217 |
|
218 |
+
// API μμ² - μμ λ URL κ΅¬μ± μ¬μ©
|
219 |
+
const response = await fetch(getDeviceApiUrl('/api/devices'), {
|
220 |
signal: controller.signal
|
221 |
});
|
222 |
|
|
|
233 |
// UI μ
λ°μ΄νΈ
|
234 |
devicesLoading.classList.add('hidden');
|
235 |
|
236 |
+
if (data.devices && data.devices.length > 0) {
|
237 |
+
// μ₯μΉ λͺ©λ‘ νμ
|
238 |
data.devices.forEach(device => {
|
239 |
+
const deviceElement = createDeviceItem(device);
|
240 |
+
deviceList.appendChild(deviceElement);
|
241 |
});
|
242 |
} else {
|
243 |
+
// μ₯μΉ μμ λ©μμ§ νμ
|
244 |
noDevicesMessage.classList.remove('hidden');
|
|
|
|
|
|
|
|
|
245 |
}
|
246 |
} catch (error) {
|
247 |
console.error("μ₯μΉ λͺ©λ‘ λ‘λ μ€λ₯:", error);
|
|
|
249 |
// UI μ
λ°μ΄νΈ
|
250 |
devicesLoading.classList.add('hidden');
|
251 |
noDevicesMessage.classList.remove('hidden');
|
252 |
+
noDevicesMessage.textContent = handleError(error);
|
253 |
}
|
254 |
}
|
255 |
|
|
|
346 |
const controller = new AbortController();
|
347 |
const timeoutId = setTimeout(() => controller.abort(), 5000); // 5μ΄ νμμμ
|
348 |
|
349 |
+
// API μμ² - μμ λ URL κ΅¬μ± μ¬μ©
|
350 |
+
const response = await fetch(getDeviceApiUrl('/api/programs'), {
|
351 |
signal: controller.signal
|
352 |
});
|
353 |
|
|
|
364 |
// UI μ
λ°μ΄νΈ
|
365 |
programsLoading.classList.add('hidden');
|
366 |
|
367 |
+
if (data.programs && data.programs.length > 0) {
|
368 |
+
// νλ‘κ·Έλ¨ λͺ©λ‘ νμ
|
369 |
data.programs.forEach(program => {
|
370 |
+
const programElement = createProgramItem(program);
|
371 |
+
programsList.appendChild(programElement);
|
372 |
});
|
|
|
373 |
} else {
|
374 |
+
// νλ‘κ·Έλ¨ μμ λ©μμ§ νμ
|
375 |
noProgramsMessage.classList.remove('hidden');
|
|
|
|
|
|
|
|
|
376 |
}
|
377 |
} catch (error) {
|
378 |
console.error("νλ‘κ·Έλ¨ λͺ©λ‘ λ‘λ μ€λ₯:", error);
|
|
|
380 |
// UI μ
λ°μ΄νΈ
|
381 |
programsLoading.classList.add('hidden');
|
382 |
noProgramsMessage.classList.remove('hidden');
|
383 |
+
noProgramsMessage.textContent = handleError(error);
|
384 |
}
|
385 |
}
|
386 |
|
|
|
428 |
|
429 |
/**
|
430 |
* νλ‘κ·Έλ¨ μ€ν ν¨μ
|
431 |
+
* @param {string} programId - μ€νν νλ‘κ·Έλ¨ ID
|
432 |
+
* @param {string} programName - νλ‘κ·Έλ¨ μ΄λ¦ (μλ¦Όμ©)
|
433 |
*/
|
434 |
async function executeProgram(programId, programName) {
|
435 |
+
if (!programId) return;
|
436 |
+
|
437 |
+
console.log(`νλ‘κ·Έλ¨ μ€ν μμ²: ${programId} (${programName})`);
|
438 |
|
439 |
// μ€ν νμΈ
|
440 |
if (!confirm(`'${programName}' νλ‘κ·Έλ¨μ μ€ννμκ² μ΅λκΉ?`)) {
|
441 |
+
console.log('νλ‘κ·Έλ¨ μ€ν μ·¨μλ¨');
|
442 |
return;
|
443 |
}
|
444 |
|
445 |
try {
|
446 |
+
// λ‘λ© μλ¦Ό νμ
|
447 |
+
showNotification(`'${programName}' μ€ν μ€...`, 'info');
|
|
|
448 |
|
449 |
+
// API μμ² - μμ λ URL κ΅¬μ± μ¬μ©
|
450 |
+
const response = await fetch(getDeviceApiUrl(`/api/programs/${programId}/execute`), {
|
451 |
method: 'POST',
|
452 |
headers: {
|
453 |
'Content-Type': 'application/json'
|
454 |
},
|
455 |
+
body: JSON.stringify({}) // νμ μ μΆκ° νλΌλ―Έν° μ λ¬
|
|
|
456 |
});
|
457 |
|
|
|
|
|
458 |
// μλ΅ μ²λ¦¬
|
459 |
if (!response.ok) {
|
460 |
+
throw new Error(`HTTP μ€λ₯: ${response.status}`);
|
|
|
461 |
}
|
462 |
|
463 |
const data = await response.json();
|
464 |
+
console.log(`νλ‘κ·Έλ¨ μ€ν μλ΅:`, data);
|
465 |
|
466 |
+
// κ²°κ³Ό μ²λ¦¬
|
467 |
if (data.success) {
|
468 |
+
showNotification(`'${programName}' μ€ν μ±κ³΅: ${data.message}`, 'success');
|
469 |
} else {
|
470 |
+
showNotification(`'${programName}' μ€ν μ€ν¨: ${data.message || 'μ μ μλ μ€λ₯'}`, 'error');
|
471 |
}
|
472 |
} catch (error) {
|
473 |
+
console.error(`νλ‘κ·Έλ¨ μ€ν μ€λ₯ (${programId}):`, error);
|
474 |
+
showNotification(`'${programName}' μ€ν μ€λ₯: ${handleError(error)}`, 'error');
|
475 |
}
|
476 |
}
|
477 |
|
|
|
513 |
}, 5000); // 5μ΄ ν μ¬λΌμ§
|
514 |
}
|
515 |
|
516 |
+
// checkDeviceStatus ν¨μλ₯Ό μ μμΌλ‘ λ
ΈμΆ
|
517 |
+
window.checkDeviceStatus = checkDeviceStatus;
|
app/static/js/app.js
CHANGED
@@ -174,14 +174,29 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
174 |
|
175 |
// ν μ ν μ΄λ²€νΈ 리μ€λ
|
176 |
chatTab.addEventListener('click', () => {
|
|
|
177 |
switchTab('chat');
|
178 |
});
|
179 |
|
180 |
docsTab.addEventListener('click', () => {
|
|
|
181 |
switchTab('docs');
|
182 |
loadDocuments();
|
183 |
});
|
184 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
185 |
// LLM μ ν μ΄λ²€νΈ 리μ€λ
|
186 |
llmSelect.addEventListener('change', (event) => {
|
187 |
changeLLM(event.target.value);
|
@@ -231,6 +246,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
231 |
* @param {string} tabName - νμ±νν ν μ΄λ¦ ('chat', 'docs', 'device')
|
232 |
*/
|
233 |
function switchTab(tabName) {
|
|
|
|
|
234 |
if (tabName === 'chat') {
|
235 |
chatTab.classList.add('active');
|
236 |
docsTab.classList.remove('active');
|
@@ -252,6 +269,7 @@ function switchTab(tabName) {
|
|
252 |
chatSection.classList.remove('active');
|
253 |
docsSection.classList.remove('active');
|
254 |
deviceSection.classList.add('active');
|
|
|
255 |
}
|
256 |
}
|
257 |
|
|
|
174 |
|
175 |
// ν μ ν μ΄λ²€νΈ 리μ€λ
|
176 |
chatTab.addEventListener('click', () => {
|
177 |
+
console.log("λν ν ν΄λ¦");
|
178 |
switchTab('chat');
|
179 |
});
|
180 |
|
181 |
docsTab.addEventListener('click', () => {
|
182 |
+
console.log("λ¬Έμκ΄λ¦¬ ν ν΄λ¦");
|
183 |
switchTab('docs');
|
184 |
loadDocuments();
|
185 |
});
|
186 |
|
187 |
+
// μ₯μΉκ΄λ¦¬ ν μ΄λ²€νΈ 리μ€λ μΆκ°
|
188 |
+
deviceTab.addEventListener('click', () => {
|
189 |
+
console.log("μ₯μΉκ΄λ¦¬ ν ν΄λ¦");
|
190 |
+
switchTab('device');
|
191 |
+
// μ₯μΉκ΄λ¦¬ νμΌλ‘ μ ν μ νμν μ΄κΈ°ν μμ
μ΄ μλ€λ©΄ μ¬κΈ°μ νΈμΆ
|
192 |
+
if (typeof checkDeviceStatus === 'function') {
|
193 |
+
console.log("μ₯μΉ μν νμΈ ν¨μ νΈμΆ");
|
194 |
+
checkDeviceStatus();
|
195 |
+
} else {
|
196 |
+
console.log("checkDeviceStatus ν¨μκ° μ μλμ§ μμμ΅λλ€");
|
197 |
+
}
|
198 |
+
});
|
199 |
+
|
200 |
// LLM μ ν μ΄λ²€νΈ 리μ€λ
|
201 |
llmSelect.addEventListener('change', (event) => {
|
202 |
changeLLM(event.target.value);
|
|
|
246 |
* @param {string} tabName - νμ±νν ν μ΄λ¦ ('chat', 'docs', 'device')
|
247 |
*/
|
248 |
function switchTab(tabName) {
|
249 |
+
console.log(`switchTab ν¨μ νΈμΆ: ${tabName}`);
|
250 |
+
|
251 |
if (tabName === 'chat') {
|
252 |
chatTab.classList.add('active');
|
253 |
docsTab.classList.remove('active');
|
|
|
269 |
chatSection.classList.remove('active');
|
270 |
docsSection.classList.remove('active');
|
271 |
deviceSection.classList.add('active');
|
272 |
+
console.log("μ₯μΉκ΄λ¦¬ νμΌλ‘ μ ν μλ£");
|
273 |
}
|
274 |
}
|
275 |
|