diff --git a/templates/index.html b/templates/index.html
index a1d7b09..f65512c 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -601,11 +601,11 @@ const els = {
lvlInfo: document.getElementById('lvlInfo'),
lvlWarn: document.getElementById('lvlWarn'),
lvlErr: document.getElementById('lvlErr'),
- layoutBadge: document.getElementById('layoutBadge'),
- aggregate: document.getElementById('aggregate'),
+ layoutBadge: document.getElementById('layoutBadge') || { textContent: '' },
+ aggregate: document.getElementById('aggregate') || { checked: false },
themeSwitch: document.getElementById('themeSwitch'),
copyFab: document.getElementById('copyFab'),
- groupBtn: document.getElementById('groupBtn'),
+ groupBtn: document.getElementById('groupBtn') || { onclick: null },
// New modern elements
containerList: document.getElementById('containerList'),
@@ -792,51 +792,78 @@ function buildTabs(){
function setLayout(cls){
state.layout = cls;
- els.layoutBadge.textContent = 'view: ' + (cls==='tabs'?'tabs':cls);
+ if (els.layoutBadge) {
+ els.layoutBadge.textContent = 'view: ' + (cls==='tabs'?'tabs':cls);
+ }
els.grid.className = cls==='tabs' ? 'grid-1' : (cls==='grid2'?'grid-2':cls==='grid3'?'grid-3':'grid-4');
}
async function fetchProjects(){
- const url = new URL(location.origin + '/api/projects');
- const res = await fetch(url);
- if (!res.ok){ console.error('Failed to fetch projects'); return; }
- const projects = await res.json();
-
- // Обновляем селектор проектов
- const select = els.projectSelect;
- select.innerHTML = '';
- projects.forEach(project => {
- const option = document.createElement('option');
- option.value = project;
- option.textContent = project;
- select.appendChild(option);
- });
-
- // Устанавливаем сохраненный проект
- if (localStorage.lb_project && projects.includes(localStorage.lb_project)) {
- select.value = localStorage.lb_project;
+ try {
+ console.log('Fetching projects...');
+ const url = new URL(location.origin + '/api/projects');
+ const res = await fetch(url);
+ if (!res.ok){
+ console.error('Failed to fetch projects:', res.status, res.statusText);
+ return;
+ }
+ const projects = await res.json();
+ console.log('Projects loaded:', projects);
+
+ // Обновляем селектор проектов
+ const select = els.projectSelect;
+ if (select) {
+ select.innerHTML = '';
+ projects.forEach(project => {
+ const option = document.createElement('option');
+ option.value = project;
+ option.textContent = project;
+ select.appendChild(option);
+ });
+
+ // Устанавливаем сохраненный проект
+ if (localStorage.lb_project && projects.includes(localStorage.lb_project)) {
+ select.value = localStorage.lb_project;
+ }
+ }
+ } catch (error) {
+ console.error('Error fetching projects:', error);
}
}
async function fetchServices(){
- const url = new URL(location.origin + '/api/services');
- const selectedProject = els.projectSelect.value;
-
- if (selectedProject && selectedProject !== 'all') {
- url.searchParams.set('projects', selectedProject);
- localStorage.lb_project = selectedProject;
- } else {
- localStorage.removeItem('lb_project');
+ try {
+ console.log('Fetching services...');
+ const url = new URL(location.origin + '/api/services');
+ const selectedProject = els.projectSelect ? els.projectSelect.value : 'all';
+
+ if (selectedProject && selectedProject !== 'all') {
+ url.searchParams.set('projects', selectedProject);
+ localStorage.lb_project = selectedProject;
+ } else {
+ localStorage.removeItem('lb_project');
+ }
+
+ const res = await fetch(url);
+ if (!res.ok){
+ console.error('Auth failed (HTTP):', res.status, res.statusText);
+ alert('Auth failed (HTTP)');
+ return;
+ }
+ const data = await res.json();
+ console.log('Services loaded:', data);
+ state.services = data;
+ const pj = selectedProject === 'all' ? 'all' : selectedProject;
+
+ if (els.projectBadge) {
+ els.projectBadge.innerHTML = 'project: '+escapeHtml(pj)+'';
+ }
+
+ buildTabs();
+ if (!state.current && state.services.length) switchToSingle(state.services[0]);
+ } catch (error) {
+ console.error('Error fetching services:', error);
}
-
- const res = await fetch(url);
- if (!res.ok){ alert('Auth failed (HTTP)'); return; }
- const data = await res.json();
- state.services = data;
- const pj = selectedProject === 'all' ? 'all' : selectedProject;
- els.projectBadge.innerHTML = 'project: '+escapeHtml(pj)+'';
- buildTabs();
- if (!state.current && state.services.length) switchToSingle(state.services[0]);
}
function wsUrl(containerId, service, project){
@@ -966,8 +993,12 @@ function switchToSingle(svc){
for (const p of [...els.grid.children]) if (p!==panel) p.remove();
// Modern interface updates
- els.logTitle.textContent = `${svc.name} (${svc.service || svc.name})`;
- els.logContent.textContent = 'Connecting...';
+ if (els.logTitle) {
+ els.logTitle.textContent = `${svc.name} (${svc.service || svc.name})`;
+ }
+ if (els.logContent) {
+ els.logContent.textContent = 'Connecting...';
+ }
// Update active state in container list
document.querySelectorAll('.container-item').forEach(item => {
@@ -1090,14 +1121,16 @@ function openFanGroup(services){
updateIdFiltersBar();
}
-els.groupBtn.onclick = ()=>{
- const list = state.services.map(s=> `${s.service}`).filter((v,i,a)=> a.indexOf(v)===i).join(', ');
- const ans = prompt('Введите имена сервисов через запятую:\n'+list);
- if (ans){
- const services = ans.split(',').map(x=>x.trim()).filter(Boolean);
- if (services.length) openFanGroup(services);
- }
-};
+if (els.groupBtn && els.groupBtn.onclick !== null) {
+ els.groupBtn.onclick = ()=>{
+ const list = state.services.map(s=> `${s.service}`).filter((v,i,a)=> a.indexOf(v)===i).join(', ');
+ const ans = prompt('Введите имена сервисов через запятую:\n'+list);
+ if (ans){
+ const services = ans.split(',').map(x=>x.trim()).filter(Boolean);
+ if (services.length) openFanGroup(services);
+ }
+ };
+}
// Controls
els.clearBtn.onclick = ()=> Object.values(state.open).forEach(o=> o.logEl.textContent='');
@@ -1156,6 +1189,16 @@ window.addEventListener('keydown', (e)=>{
// Инициализация
(async function init() {
+ console.log('Initializing LogBoard+...');
+ console.log('Elements found:', {
+ projectSelect: !!els.projectSelect,
+ containerList: !!els.containerList,
+ logTitle: !!els.logTitle,
+ logContent: !!els.logContent,
+ mobileToggle: !!els.mobileToggle,
+ themeSwitch: !!els.themeSwitch
+ });
+
await fetchProjects();
await fetchServices();
})();