- 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.
50 lines
2.6 KiB
JavaScript
50 lines
2.6 KiB
JavaScript
window.CompanyContacts = (() => {
|
|
const esc = value => String(value ?? "").replace(/[&<>"']/g, c => ({"&":"&","<":"<",">":">",'"':""","'":"'"}[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};
|
|
})();
|