bmc_hub/rewrite_bottom_bar.py

265 lines
8.8 KiB
Python
Raw Normal View History

with open("static/js/bottom-bar.js", "r") as f:
content = f.read()
# We replace everything from getCounts downwards.
# Let's find the start of getCounts
start_idx = content.find("function getCounts")
new_logic = """function getCounts(sections) {
const mail = sections.mail || {};
const cases = sections.cases || {};
const urgent = sections.urgent || {};
const timer = sections.timer || {};
const kuma = sections.kuma || {};
const eset = sections.eset || {};
return {
mail: Number(mail.unread || 0),
cases: Number(cases.open || 0),
urgent: Number(urgent.count || 0),
timer: Number(timer.active_count || 0),
kuma: Number(kuma.down || 0),
eset: Number(eset.incidents || 0)
};
}
function detailTextFor(key, sections) {
const counts = getCounts(sections);
const nameMap = {
mail: 'Ubesvarede mails',
cases: 'Åbne sager',
urgent: 'Hastesager',
timer: 'Aktive timere',
kuma: 'Kuma alerts',
eset: 'ESET incidents'
};
const val = counts[key] || 0;
return nameMap[key] + ': ' + val;
}
function listFor(key, sections) {
const mail = sections.mail || {};
const cases = sections.cases || {};
const urgent = sections.urgent || {};
const timer = sections.timer || {};
const kuma = sections.kuma || {};
const eset = sections.eset || {};
const messages = sections.messages || {};
const tasks = sections.tasks || {};
const boss = sections.boss || {};
if (key === 'overview') {
return [
'Velkommen til dit overblik',
'Her vises det vigtigste på tværs af systemet',
'Næste opgave kl. 14:00'
];
}
if (key === 'timer') {
if (timer.active_count > 0) {
return (timer.list || []).map(t => 'Timer aktiv: ' + t.description);
}
return ['Ingen aktive timere lige nu.'];
}
if (key === 'messages') {
if (messages.count > 0) {
return (messages.list || []).map(m => m.from + ': ' + m.text);
}
return ['Ingen nye beskeder.'];
}
if (key === 'tasks') {
if (tasks.count > 0) {
return (tasks.list || []).map(t => t.title + ' (Deadline: ' + t.deadline + ')');
}
return ['Ingen aktuelle opgaver.'];
}
if (key === 'boss') {
if (boss.stats) {
return [
'Ufordelte opgaver: ' + boss.stats.unassigned,
'Medarbejdere aktive: ' + boss.stats.active_employees
];
}
return ['Henter chef-overblik...'];
}
return ['Klik rundt i menuen for at se data for ' + key];
}
function updateBar(sections) {
const counts = getCounts(sections);
const keys = Object.keys(counts);
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
const chipText = document.querySelector('.bb-chip[data-bb-key="' + key + '"] .bb-chip-text');
const chip = document.querySelector('.bb-chip[data-bb-key="' + key + '"]');
if (chipText && chip) {
const val = counts[key];
const labels = {
mail: 'Mails',
cases: 'Sager',
urgent: 'Hastesager',
timer: 'Timere',
kuma: 'Kuma',
eset: 'ESET'
};
chipText.textContent = labels[key] + ': ' + val;
chip.classList.toggle('has-items', val > 0);
}
}
}
function renderTabPanel() {
const titleContainer = byId('bbTabTitle');
const innerContent = byId('bbTabInnerContent');
if (!titleContainer || !innerContent) {
return;
}
const titleText = titleContainer.querySelector('.bb-tab-title-text');
const titleByKey = {
overview: 'Overblik',
timer: 'Timere',
messages: 'Beskeder',
tasks: 'Opgaver',
boss: 'Chef Dashboard'
};
const iconByKey = {
overview: 'bi-bell',
timer: 'bi-stopwatch',
messages: 'bi-chat-dots',
tasks: 'bi-calendar-check',
boss: 'bi-person-workspace'
};
const activeTitle = titleByKey[activeKey] || 'Info';
if (titleText) {
titleText.textContent = activeTitle;
} else {
titleContainer.textContent = activeTitle;
}
const iconSpan = titleContainer.querySelector('.bi');
if (iconSpan) {
iconSpan.className = 'bi ' + (iconByKey[activeKey] || 'bi-info-circle') + ' me-2 text-accent';
}
// Render lists
const lines = listFor(activeKey, latestSections);
const ul = document.createElement('ul');
ul.className = 'bb-tab-list';
lines.forEach(function (line) {
const li = document.createElement('li');
li.innerHTML = String(line)
.replaceAll('&', '&amp;')
.replaceAll('<', '&lt;')
.replaceAll('>', '&gt;');
ul.appendChild(li);
});
innerContent.innerHTML = '';
innerContent.appendChild(ul);
}
function bindSideTabs() {
const buttons = document.querySelectorAll('.bb-tab-btn');
for (let i = 0; i < buttons.length; i++) {
buttons[i].addEventListener('click', function () {
for (let j = 0; j < buttons.length; j++) {
buttons[j].classList.remove('is-active');
buttons[j].setAttribute('aria-selected', 'false');
}
this.classList.add('is-active');
this.setAttribute('aria-selected', 'true');
activeKey = this.getAttribute('data-bb-tab');
renderTabPanel();
const detail = byId('bbCountDetail');
if (detail) {
detail.innerHTML = '<i class="bi bi-info-circle me-1 opacity-75"></i> Viser: ' + (activeKey.charAt(0).toUpperCase() + activeKey.slice(1));
}
});
}
}
function bindChipClicks() {
const chips = document.querySelectorAll('.bb-chip');
for (let i = 0; i < chips.length; i++) {
chips[i].addEventListener('click', function () {
const key = this.getAttribute('data-bb-key');
if (!key) return;
const detail = byId('bbCountDetail');
if (detail) {
detail.innerHTML = '<i class="bi bi-check-circle me-1 text-accent"></i> ' + detailTextFor(key, latestSections);
}
// If not expanded, expand it
const shell = byId('globalBottomBar');
if (shell && !shell.classList.contains('is-expanded')) {
setExpanded(true);
}
// Map top chip keys to side tabs if applicable, else 'overview'
let targetTab = 'overview';
if (key === 'timer') targetTab = 'timer';
const tabBtn = document.querySelector('.bb-tab-btn[data-bb-tab="' + targetTab + '"]');
if (tabBtn) tabBtn.click();
});
}
}
function bindSheetToggle() {
const toggle = byId('bbSheetToggle');
if (!toggle) return;
toggle.addEventListener('click', function () {
const shell = byId('globalBottomBar');
if (!shell) return;
const isExp = shell.classList.contains('is-expanded');
setExpanded(!isExp);
});
}
function tick() {
fetchBottomBarState().then(function (data) {
if (data && data.enabled) {
latestSections = data.sections || {};
updateBar(latestSections);
renderTabPanel();
setVisibility(true);
} else {
setVisibility(false);
}
}).catch(function (err) {
console.warn('Bottom bar poll failed', err);
}).finally(function () {
window.setTimeout(tick, 15000);
});
}
document.addEventListener('DOMContentLoaded', function () {
activeKey = 'overview'; // Default overview state
bindChipClicks();
bindSheetToggle();
bindSideTabs();
tick();
});
})();
"""
combined = content[:start_idx] + new_logic
with open("static/js/bottom-bar.js", "w") as f:
f.write(combined)