bmc_hub/static/js/company-contacts.js
Christian 4871dd2d9e Add comprehensive test coverage for various modules
- Introduced tests for mail templates including ranking, rendering, and attachment handling.
- Added tests for time billing selection and approval processes, ensuring proper validation and state management.
- Implemented tests for case types in JavaScript, focusing on loading and editing functionality.
- Created tests for contact mail AI integration, ensuring proper parsing and error handling.
- Developed tests for dark theme CSS contrast and loading order.
- Added tests for invoice fee service, covering various scenarios including exemptions and invalid inputs.
- Implemented vendor resource tests, ensuring proper file handling and query validation.
2026-10-08 08:58:02 +02:00

50 lines
2.6 KiB
JavaScript

window.CompanyContacts = (() => {
const esc = value => String(value ?? "").replace(/[&<>"']/g, c => ({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"}[c]));
function rows(contacts, helpers) {
return contacts.map(contact => {
const displayName = helpers.name(contact);
const contactId = Number(contact.id) || null;
const mobileValue = helpers.mobile(contact);
const phoneValue = helpers.phone(contact);
const titleValue = String(contact.title || contact.role || '').trim();
const nameCell = contactId
? `<a class="contact-name-link" href="/contacts/${contactId}">${esc(displayName)}</a>`
: esc(displayName);
const email = contact.email ? `<a href="mailto:${esc(contact.email)}">${esc(contact.email)}</a>` : '—';
const phone = phoneValue
? `<div class="contact-phone-wrap"><span class="contact-number"><a href="tel:${esc(phoneValue)}">${esc(phoneValue)}</a></span>${helpers.actions(phoneValue, displayName, contactId)}</div>`
: '—';
const mobile = mobileValue
? `<div class="contact-mobile-wrap"><span class="contact-number"><a href="tel:${esc(mobileValue)}">${esc(mobileValue)}</a></span>${helpers.actions(mobileValue, displayName, contactId)}</div>`
: '—';
const title = titleValue ? esc(titleValue) : '—';
const primaryBadge = contact.is_primary ? '<span class="badge bg-primary primary-pill">Primær</span>' : '—';
return `
<tr>
<td class="contact-name">${nameCell}</td>
<td>${title}</td>
<td class="contact-email">${email}</td>
<td class="contact-number">${phone}</td>
<td>${mobile}</td>
<td>${primaryBadge}</td>${helpers.extra ? `<td>${helpers.extra(contact)}</td>` : ''}
</tr>
`;
}).join('');
}
function filter(contacts, query, onlyCallable, helpers) {
const term=String(query || '').trim().toLowerCase();
return contacts.filter(contact=>{
const phone=helpers.phone(contact), mobile=helpers.mobile(contact);
const text=[helpers.name(contact),contact.title,contact.role,contact.email,phone,mobile].join(' ').toLowerCase();
return (!term || text.includes(term)) && (!onlyCallable || Boolean(phone || mobile));
});
}
function table(body) {
return `<table class="table table-hover align-middle contacts-table"><thead><tr><th>Navn</th><th>Titel</th><th>Email</th><th>Telefon</th><th>Mobil</th><th>Primær</th></tr></thead><tbody>${body}</tbody></table>`;
}
return {rows, filter, table};
})();