- 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.
85 lines
11 KiB
HTML
85 lines
11 KiB
HTML
<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>
|