bmc_hub/output/min-koe-forslag.html
Christian 1fb5b4a191 Add comprehensive tests for email and drift functionalities
- Introduced tests for drift operations UI and backend to ensure proper handling of ignore rules and UI elements.
- Added tests for email identity API to validate email linking and identity retrieval without updates.
- Implemented tests for email purchase link service to verify correct handling of purchase mail links and conflict scenarios.
- Created tests for email reply automation to ensure proper routing and processing of replies based on classification.
- Developed tests for email sender creation to validate suggestions and handling of existing contacts and companies.
- Added tests for email sender identity to ensure correct matching of contacts and domains.
- Implemented tests for work desk functionalities to validate task management, meeting registrations, and timer functionalities.
2026-11-03 01:16:12 +01:00

85 lines
11 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<div id="bmc-queue-proposals">
<style>
#bmc-queue-proposals{color-scheme:light dark;--q-bg:light-dark(#edf2f6,#14212c);--q-panel:light-dark(#fff,#1b2c3a);--q-ink:light-dark(#213b50,#e4edf4);--q-muted:light-dark(#536b7d,#b0c1ce);--q-line:light-dark(#d9e3ea,#3a4f60);--q-primary:light-dark(#225d88,#8bc6f1);--q-soft:light-dark(#e8f2fa,#263e52);--q-warn:light-dark(#9c4a17,#ffc494);--q-warn-bg:light-dark(#fff1e6,#463327);font:14px/1.45 system-ui,sans-serif;color:var(--q-ink)}
#bmc-queue-proposals *{box-sizing:border-box}
#bmc-queue-proposals .q-page{background:var(--q-bg);min-height:870px;padding-bottom:22px}
#bmc-queue-proposals .q-nav{display:flex;gap:22px;align-items:center;padding:16px 24px;background:var(--q-panel);border-bottom:1px solid var(--q-line);padding-right:105px}
#bmc-queue-proposals .q-brand{font-weight:700;letter-spacing:.5px}
#bmc-queue-proposals .q-muted{color:var(--q-muted)}
#bmc-queue-proposals .q-title{padding:25px 24px 18px;display:flex;justify-content:space-between;gap:16px;align-items:end;flex-wrap:wrap}
#bmc-queue-proposals h2{font-size:25px;letter-spacing:-.7px;line-height:1.2;margin:5px 0 7px;font-weight:650}
#bmc-queue-proposals h3{font-size:15px;margin:0 0 12px;font-weight:650}
#bmc-queue-proposals .q-main{display:grid;grid-template-columns:minmax(0,2fr) minmax(250px,1fr);gap:16px;padding:0 24px}
#bmc-queue-proposals .q-left{min-width:0}
#bmc-queue-proposals .q-surface{background:var(--q-panel);border:1px solid var(--q-line);border-radius:12px;padding:18px;margin-bottom:14px}
#bmc-queue-proposals .q-calendar{background:var(--q-panel);border:1px solid var(--q-line);border-radius:12px;overflow:hidden;align-self:start}
#bmc-queue-proposals .q-calendar-header{padding:16px 16px 0}
#bmc-queue-proposals .q-calendar-header h3{margin-bottom:3px}
#bmc-queue-proposals .q-table-wrap{overflow-x:auto}
#bmc-queue-proposals table{width:100%;border-collapse:collapse;font-size:12px;text-align:left}
#bmc-queue-proposals th{font-weight:500;color:var(--q-muted);padding:9px 7px;background:var(--q-bg);white-space:nowrap}
#bmc-queue-proposals td{padding:15px 7px;border-bottom:1px solid var(--q-line);vertical-align:top;font-variant-numeric:tabular-nums}
#bmc-queue-proposals tr:last-child td{border-bottom:0}
#bmc-queue-proposals td:first-child{min-width:155px}
#bmc-queue-proposals .q-task{padding:0;border:0;color:var(--q-ink);background:transparent;font:inherit;font-weight:650;text-align:left;text-decoration:underline;text-decoration-color:var(--q-line);text-underline-offset:4px;cursor:pointer}
#bmc-queue-proposals .q-caption{display:block;color:var(--q-muted);font-size:12px;margin-top:5px}
#bmc-queue-proposals .q-urgent{color:var(--q-warn)}
#bmc-queue-proposals .q-pill{display:inline-block;padding:3px 7px;border-radius:5px;background:var(--q-soft);color:var(--q-primary);font-size:12px}
#bmc-queue-proposals .q-summary{display:flex;gap:22px;flex-wrap:wrap;font-size:13px}
#bmc-queue-proposals .q-summary strong{display:block;font-size:20px;font-weight:650;margin-top:2px}
#bmc-queue-proposals .q-focus{border-left:4px solid var(--q-primary)}
#bmc-queue-proposals .q-eyebrow{color:var(--q-primary);font-size:12px;font-weight:650;letter-spacing:.5px;text-transform:uppercase}
#bmc-queue-proposals .q-focus h3{font-size:21px;margin:7px 0}
#bmc-queue-proposals .q-focus .q-facts{display:flex;gap:16px;flex-wrap:wrap;margin:15px 0 0;color:var(--q-muted);font-size:13px}
#bmc-queue-proposals .q-warning{padding:10px 12px;background:var(--q-warn-bg);color:var(--q-warn);border-radius:7px;font-size:13px;margin-bottom:16px}
#bmc-queue-proposals .q-group{display:flex;align-items:center;justify-content:space-between;padding:8px 0;gap:10px}
#bmc-queue-proposals .q-group h3{margin:0}
#bmc-queue-proposals .q-detail{border-top:1px solid var(--q-line);margin-top:16px;padding-top:13px;font-size:13px;min-height:65px}
#bmc-queue-proposals .q-picked td{background:var(--q-soft)}
#bmc-queue-proposals .q-bottom{display:flex;gap:22px;padding:16px 24px;margin-top:16px;border-top:1px solid var(--q-line);background:var(--q-panel);font-size:13px}
#bmc-queue-proposals .q-bottom strong{color:var(--q-primary)}
@media(max-width:720px){#bmc-queue-proposals .q-main{grid-template-columns:1fr;padding:0 12px}#bmc-queue-proposals .q-title{padding:18px 12px}#bmc-queue-proposals .q-nav{padding-left:12px;gap:12px;font-size:12px}#bmc-queue-proposals .q-nav .q-optional{display:none}#bmc-queue-proposals .q-page{min-height:1400px}#bmc-queue-proposals .q-surface{padding:12px}}
</style>
<div class="viz-carousel" aria-label="Tre forslag til Min kø" data-previous-label="Forrige forslag" data-next-label="Næste forslag">
<section data-variant="Fokus" aria-label="Fokus: én tydelig næste opgave"><div class="q-page" data-design="focus"></div></section>
<section data-variant="Arbejdsbord" aria-label="Arbejdsbord: samlet prioriteret tabel" hidden><div class="q-page" data-design="desk"></div></section>
<section data-variant="Dagsplan" aria-label="Dagsplan: faste aftaler og fleksible opgaver" hidden><div class="q-page" data-design="day"></div></section>
</div>
</div>
<script>
(() => {
const root=document.getElementById('bmc-queue-proposals');
const tasks=[
{id:241,title:'Genskab adgang til økonomisystem',customer:'Nordlys Kontor',reason:'Deadline overskredet · ingen tid reserveret',deadline:'I går',start:'I går',fixed:'—',estimate:'45 min',allocated:'0 min',urgent:true},
{id:228,title:'Klargør ny medarbejders pc',customer:'Fjord Service',reason:'Skal være klar inden kundemøde kl. 11',deadline:'I dag 11.00',start:'I dag',fixed:'09.00–10.00',estimate:'1 time',allocated:'1 time'},
{id:236,title:'Gennemgå netværk med kunden',customer:'Birk Teknik',reason:'Fast aftale kl. 11 · tidspunktet ligger fast',deadline:'I dag',start:'I dag',fixed:'11.00–12.00',estimate:'1 time',allocated:'1 time'},
{id:245,title:'Opdatér server og kontrollér backup',customer:'Nordlys Kontor',reason:'Deadline i dag · mangler 30 min i planen',deadline:'I dag 16.00',start:'I dag',fixed:'—',estimate:'1½ time',allocated:'1 time'},
{id:252,title:'Undersøg ustabil VPN-forbindelse',customer:'Fjord Service',reason:'Kan startes i dag · deadline i morgen',deadline:'I morgen',start:'I dag',fixed:'—',estimate:'1 time',allocated:'0 min'},
{id:254,title:'Følg op på printerfejl',customer:'Birk Teknik',reason:'Kan løses i et kort ledigt tidsrum',deadline:'Torsdag',start:'I dag',fixed:'—',estimate:'30 min',allocated:'0 min'}
];
const events=[{id:228,title:'Klargør pc',start:'09:00',end:'10:00',detail:'Fjord Service · fast aftale'}, {id:236,title:'Kundemøde',start:'11:00',end:'12:00',detail:'Birk Teknik · fast aftale'}, {id:245,title:'Server og backup',start:'13:00',end:'14:00',detail:'Nordlys Kontor · reserveret arbejdstid'}];
function rows(list,compact=false){return list.map(t=>`<tr data-task="${t.id}"><td><button type="button" class="q-task" data-id="${t.id}">${t.title}</button><span class="q-caption">#${t.id} · ${t.customer}</span>${!compact?`<span class="q-caption ${t.urgent?'q-urgent':''}">${t.reason}</span>`:''}</td><td class="${t.urgent?'q-urgent':''}">${t.deadline}</td><td>${t.start}</td><td>${t.fixed}</td><td>${t.estimate}<span class="q-caption">${t.allocated} planlagt</span></td></tr>`).join('')}
function table(list,compact=false){return `<div class="q-table-wrap"><table><thead><tr><th>Opgave</th><th>Deadline</th><th>Start</th><th>Fast tid</th><th>Estimat</th></tr></thead><tbody>${rows(list,compact)}</tbody></table></div>`}
const content={
focus:`<div class="q-surface q-focus"><div class="q-eyebrow">Tag denne først</div><h3>Genskab adgang til økonomisystem</h3><span class="q-caption">#241 · Nordlys Kontor</span><p class="q-urgent">Deadline var i går. Der er endnu ikke reserveret tid.</p><div class="q-facts"><span>Estimat: <strong>45 min</strong></span><span>Planlagt: <strong>0 min</strong></span><span>Næste faste aftale: <strong>09.00</strong></span></div></div><div class="q-surface"><h3>Derefter i dag</h3>${table(tasks.slice(1))}<div class="q-detail" aria-live="polite">Vælg en opgave for at se begrundelsen for prioriteringen.</div></div>`,
desk:`<div class="q-surface"><div class="q-summary"><span>Opgaver i dag<strong>6</strong></span><span>Estimeret arbejde<strong>5 t 45 min</strong></span><span>Reserveret i kalender<strong>3 timer</strong></span></div></div><div class="q-surface"><div class="q-group"><h3>Dagens opgaver · anbefalet rækkefølge</h3><span class="q-pill">1 overskredet</span></div>${table(tasks)}<div class="q-detail" aria-live="polite">Vælg en opgave for at se begrundelsen for prioriteringen.</div></div>`,
day:`<div class="q-warning">2 t 45 min af dagens estimerede arbejde mangler en plads i kalenderen.</div><div class="q-surface"><div class="q-group"><h3>Skal håndteres først</h3><span class="q-muted">1 opgave</span></div>${table(tasks.slice(0,1),true)}<div class="q-group"><h3>Faste aftaler</h3><span class="q-muted">Tidspunktet ligger fast</span></div>${table(tasks.slice(1,3),true)}<div class="q-group"><h3>Placér i dagens ledige tid</h3><span class="q-muted">Prioriteret</span></div>${table(tasks.slice(3),true)}<div class="q-detail" aria-live="polite">Vælg en opgave for at se, hvad der mangler i dagsplanen.</div></div>`
};
const names={focus:'En opgave ad gangen',desk:'Overblik over hele arbejdsdagen',day:'Få opgaverne til at passe ind i dagen'};
root.querySelectorAll('.q-page').forEach(page=>{
const design=page.dataset.design;
page.innerHTML=`<div class="q-nav"><span class="q-brand">BMC HUB</span><span class="q-muted q-optional">Sager</span><strong>Min kø</strong><span class="q-muted q-optional">Kalender</span></div><div class="q-title"><div><span class="q-eyebrow">Christian · Min arbejdsdag</span><h2>${names[design]}</h2><span class="q-muted">Tirsdag 20. oktober 2026</span></div><span class="q-muted">Designforslag · eksempeldata</span></div><div class="q-main"><div class="q-left">${content[design]}</div><aside class="q-calendar"><div class="q-calendar-header"><h3>Min kalender i dag</h3><span class="q-muted">07.00–17.00 · 3 aftaler</span></div><div class="q-calendar-host"></div></aside></div><div class="q-bottom"><span>← Tilbage</span><strong>Min kø</strong><span>Kalender</span></div>`;
const calendar=document.createElement('viz-calendar');
calendar.setAttribute('date','2026-10-20');calendar.setAttribute('start','07:00');calendar.setAttribute('end','17:00');calendar.setAttribute('lang','da-DK');calendar.setAttribute('interactive','');calendar.events=events;
page.querySelector('.q-calendar-host').append(calendar);
const select=id=>{
const task=tasks.find(t=>t.id===Number(id));if(!task)return;
page.querySelectorAll('tr[data-task]').forEach(row=>row.classList.toggle('q-picked',Number(row.dataset.task)===task.id));
page.querySelector('.q-detail').textContent=`#${task.id} · ${task.reason}. Estimat: ${task.estimate}. Allokeret: ${task.allocated}.`;
};
page.querySelectorAll('[data-id]').forEach(button=>button.addEventListener('click',()=>select(button.dataset.id)));
calendar.addEventListener('eventselect',event=>select(event.detail.event.id));
});
})();
</script>