bmc_hub/static/js/internal-message.js
2026-09-08 01:55:47 +02:00

69 lines
5.7 KiB
JavaScript
Raw Permalink 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.

(() => {
'use strict';
const $ = id => document.getElementById(id);
let kind = 'message', contact = null, searchTimer, searchVersion = 0, sending = false;
async function api(url, options = {}) {
const response = await fetch(`/api/v1/${url}`, {credentials:'include',...options});
const data = await response.json().catch(()=>({}));
if (!response.ok) throw new Error(typeof data.detail === 'string' ? data.detail : 'Handlingen mislykkedes. Prøv igen.');
return data;
}
function showError(message) { $('im-error').textContent=message; $('im-error').classList.remove('d-none'); }
function setKind(value) {
kind=value;
$('im-phone-fields').classList.toggle('d-none',kind!=='phone');
document.querySelectorAll('[data-internal-kind]').forEach(b=>{const active=b.dataset.internalKind===kind;b.classList.toggle('btn-primary',active);b.classList.toggle('btn-outline-primary',!active);b.setAttribute('aria-pressed',String(active));});
$('im-text').placeholder=kind==='phone'?'Fx: Har ringet om tilbuddet og vil gerne ringes op i eftermiddag.':'Hvad skal din kollega vide?';
}
function selectContact(value) {
contact=value; ++searchVersion; clearTimeout(searchTimer);
$('im-contact').replaceChildren(); $('im-contact-search').value=''; $('im-contact-results').classList.add('d-none');
if (!contact) return;
$('im-contact-panel').open = true;
const chip=document.createElement('button');chip.type='button';chip.className='btn btn-sm btn-outline-primary';chip.textContent=`${contact.name} ×`;chip.setAttribute('aria-label',`Fjern ${contact.name}`);chip.onclick=()=>selectContact(null);$('im-contact').append(chip);
if (!$('im-caller').value) $('im-caller').value=contact.name;
if (!$('im-phone').value) $('im-phone').value=contact.phone || '';
}
window.openInternalMessage = async (context={}) => {
if (sending) return;
$('im-error').classList.add('d-none');
if (!$('im-text').value.trim() && context.kind) setKind(context.kind);
if (!$('im-text').value.trim() && context.contact) selectContact(context.contact);
bootstrap.Modal.getOrCreateInstance($('internalMessageModal')).show();
try {
const [payload, me]=await Promise.all([api('users?is_active=true'),api('auth/me')]);
const selected=!$('im-text').value.trim() && context.recipient ? String(context.recipient) : $('im-recipient').value;
const users=Array.isArray(payload)?payload:(payload.data || []);
$('im-recipient').replaceChildren(new Option('Vælg medarbejder…',''));
users.filter(u=>Number(u.id || u.user_id)!==Number(me.id || me.user_id)).forEach(u=>$('im-recipient').add(new Option(u.full_name || u.username || u.email, u.id || u.user_id)));
$('im-recipient').value=selected;
} catch(error) { showError(error.message); }
};
document.querySelectorAll('[data-internal-kind]').forEach(b=>b.onclick=()=>setKind(b.dataset.internalKind));
$('internalMessageModal').addEventListener('hidden.bs.modal',()=>{++searchVersion;clearTimeout(searchTimer);$('im-contact-results').classList.add('d-none');});
$('im-contact-search').addEventListener('input',()=>{
clearTimeout(searchTimer);const version=++searchVersion,query=$('im-contact-search').value.trim();
$('im-contact-results').classList.add('d-none');
if(query.length<2)return;
searchTimer=setTimeout(async()=>{try{
const rows=await api(`search/contacts?q=${encodeURIComponent(query)}`);
if(version!==searchVersion || document.activeElement!==$('im-contact-search'))return;
$('im-contact-results').replaceChildren();
if(!Array.isArray(rows) || !rows.length){$('im-contact-results').textContent='Ingen kontakter fundet. Du kan sende uden kontaktperson.';}
else rows.slice(0,10).forEach(r=>{const name=[r.first_name,r.last_name].filter(Boolean).join(' ') || r.name || `Kontakt #${r.id}`,phone=r.mobile || r.phone || '';const b=document.createElement('button');b.type='button';b.className='list-group-item list-group-item-action';b.textContent=`${name}${phone?' · '+phone:''}`;b.onclick=()=>selectContact({id:r.id,name,phone});$('im-contact-results').append(b);});
$('im-contact-results').classList.remove('d-none');
}catch(error){if(version===searchVersion)showError(error.message);}},300);
});
$('internalMessageForm').addEventListener('submit',async e=>{
e.preventDefault();if(sending)return;
if(!$('im-recipient').value || !$('im-text').value.trim()){showError('Vælg en modtager og skriv en besked.');return;}
sending=true;$('im-send').disabled=true;$('im-send').textContent='Sender…';$('im-error').classList.add('d-none');
try {
await api('bottom-bar/messages',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({message:$('im-text').value.trim(),recipient_user_id:Number($('im-recipient').value),requires_manual_ack:$('im-ack').checked,message_kind:kind,contact_id:contact?.id || null,caller_name:kind==='phone'?$('im-caller').value.trim():'',callback_phone:kind==='phone'?$('im-phone').value.trim():''})});
$('internalMessageForm').reset();selectContact(null);$('im-contact-panel').open=false;setKind('message');bootstrap.Modal.getOrCreateInstance($('internalMessageModal')).hide();
window.dispatchEvent(new CustomEvent('hub:internal-message-sent'));
if(window.showNotification)window.showNotification('Besked sendt til din kollega','success');
}catch(error){showError(error.message);}finally{sending=false;$('im-send').disabled=false;$('im-send').innerHTML='<i class="bi bi-send me-2"></i>Send besked';}
});
})();