Paginointi asiakaspalveluun + Zammad-ryhmät näkyvyysasetuksiin
- Paginointi: 100 tikettiä/sivu, navigointipalkki sivujen välillä - Filtterit resetoivat sivunumeron 1:ksi - Select All valitsee vain nykyisen sivun tiketit - Zammad-synkronointi tallentaa source=zammad ja zammad_group - Postilaatikoiden näkyvyysasetuksissa Zammad-ryhmät (Zammad)-merkinnällä - Zammad-ryhmien piilotus filtteröi tiketit samalla tavalla kuin postilaatikot Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
110
script.js
110
script.js
@@ -1350,11 +1350,15 @@ let ticketTypeLabels = {
|
||||
muu: 'Muu',
|
||||
};
|
||||
|
||||
let ticketPage = 1;
|
||||
const TICKETS_PER_PAGE = 100;
|
||||
|
||||
async function loadTickets() {
|
||||
try {
|
||||
// Hae kaikkien yritysten tiketit jos useampi yritys
|
||||
const allParam = availableCompanies.length > 1 ? '&all=1' : '';
|
||||
tickets = await apiCall('tickets' + allParam);
|
||||
ticketPage = 1;
|
||||
renderTickets();
|
||||
} catch (e) { console.error(e); }
|
||||
}
|
||||
@@ -1367,9 +1371,15 @@ function renderTickets() {
|
||||
const showMine = document.getElementById('ticket-show-mine').checked;
|
||||
let filtered = tickets;
|
||||
|
||||
// Piilota piilotettujen postilaatikoiden tiketit
|
||||
// Piilota piilotettujen postilaatikoiden ja Zammad-ryhmien tiketit
|
||||
if (currentHiddenMailboxes.length > 0) {
|
||||
filtered = filtered.filter(t => !currentHiddenMailboxes.includes(String(t.mailbox_id)) && !currentHiddenMailboxes.includes(t.mailbox_id));
|
||||
filtered = filtered.filter(t => {
|
||||
// Piilota mailbox-perusteisesti
|
||||
if (t.mailbox_id && (currentHiddenMailboxes.includes(String(t.mailbox_id)) || currentHiddenMailboxes.includes(t.mailbox_id))) return false;
|
||||
// Piilota Zammad-ryhmä-perusteisesti
|
||||
if (t.source === 'zammad' && t.zammad_group && currentHiddenMailboxes.includes('zammad_group:' + t.zammad_group)) return false;
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
// Suljetut näkyvät vain kun täppä on päällä
|
||||
@@ -1431,6 +1441,14 @@ function renderTickets() {
|
||||
|
||||
const ttbody = document.getElementById('tickets-tbody');
|
||||
const noTickets = document.getElementById('no-tickets');
|
||||
|
||||
// Paginointi
|
||||
const totalFiltered = filtered.length;
|
||||
const totalPages = Math.max(1, Math.ceil(totalFiltered / TICKETS_PER_PAGE));
|
||||
if (ticketPage > totalPages) ticketPage = totalPages;
|
||||
const startIdx = (ticketPage - 1) * TICKETS_PER_PAGE;
|
||||
const pageTickets = filtered.slice(startIdx, startIdx + TICKETS_PER_PAGE);
|
||||
|
||||
if (filtered.length === 0) {
|
||||
ttbody.innerHTML = '';
|
||||
noTickets.style.display = 'block';
|
||||
@@ -1439,7 +1457,7 @@ function renderTickets() {
|
||||
noTickets.style.display = 'none';
|
||||
document.getElementById('tickets-table').style.display = 'table';
|
||||
const multiCompany = availableCompanies.length > 1;
|
||||
ttbody.innerHTML = filtered.map(t => {
|
||||
ttbody.innerHTML = pageTickets.map(t => {
|
||||
const lastType = t.last_message_type === 'reply_out' ? '→' : (t.last_message_type === 'note' ? '📝' : '←');
|
||||
const typeLabel = ticketTypeLabels[t.type] || 'Muu';
|
||||
const rowClass = t.priority === 'urgent' ? 'ticket-row-urgent' : (t.priority === 'tärkeä' ? 'ticket-row-important' : (t.status === 'kasittelyssa' ? 'ticket-row-active' : ''));
|
||||
@@ -1479,15 +1497,63 @@ function renderTickets() {
|
||||
if (counts.kasittelyssa) parts.push(`${counts.kasittelyssa} käsittelyssä`);
|
||||
if (counts.odottaa) parts.push(`${counts.odottaa} odottaa`);
|
||||
document.getElementById('ticket-status-summary').textContent = parts.join(' · ');
|
||||
|
||||
// Paginointipalkki
|
||||
renderTicketPagination(totalFiltered, totalPages);
|
||||
}
|
||||
|
||||
document.getElementById('ticket-search-input').addEventListener('input', () => renderTickets());
|
||||
document.getElementById('ticket-status-filter').addEventListener('change', () => renderTickets());
|
||||
document.getElementById('ticket-type-filter').addEventListener('change', () => renderTickets());
|
||||
document.getElementById('ticket-tag-filter').addEventListener('input', () => renderTickets());
|
||||
document.getElementById('ticket-sort').addEventListener('change', () => renderTickets());
|
||||
document.getElementById('ticket-show-closed').addEventListener('change', () => renderTickets());
|
||||
document.getElementById('ticket-show-mine').addEventListener('change', () => renderTickets());
|
||||
function renderTicketPagination(totalFiltered, totalPages) {
|
||||
let paginationEl = document.getElementById('ticket-pagination');
|
||||
if (!paginationEl) {
|
||||
paginationEl = document.createElement('div');
|
||||
paginationEl.id = 'ticket-pagination';
|
||||
paginationEl.style.cssText = 'display:flex;align-items:center;justify-content:center;gap:0.5rem;padding:0.75rem 0;flex-wrap:wrap;';
|
||||
const table = document.getElementById('tickets-table');
|
||||
table.parentNode.insertBefore(paginationEl, table.nextSibling);
|
||||
}
|
||||
if (totalPages <= 1) {
|
||||
paginationEl.innerHTML = totalFiltered > 0 ? `<span style="color:#888;font-size:0.85rem;">${totalFiltered} tikettiä</span>` : '';
|
||||
return;
|
||||
}
|
||||
let html = '';
|
||||
// Edellinen-nappi
|
||||
html += `<button class="btn-secondary" style="padding:0.3rem 0.6rem;font-size:0.85rem;" ${ticketPage <= 1 ? 'disabled' : ''} onclick="ticketPage=1;renderTickets()">⟪</button>`;
|
||||
html += `<button class="btn-secondary" style="padding:0.3rem 0.6rem;font-size:0.85rem;" ${ticketPage <= 1 ? 'disabled' : ''} onclick="ticketPage--;renderTickets()">← Edellinen</button>`;
|
||||
|
||||
// Sivunumerot
|
||||
const maxShow = 5;
|
||||
let startPage = Math.max(1, ticketPage - Math.floor(maxShow / 2));
|
||||
let endPage = Math.min(totalPages, startPage + maxShow - 1);
|
||||
if (endPage - startPage < maxShow - 1) startPage = Math.max(1, endPage - maxShow + 1);
|
||||
|
||||
if (startPage > 1) html += `<span style="color:#888;">...</span>`;
|
||||
for (let p = startPage; p <= endPage; p++) {
|
||||
if (p === ticketPage) {
|
||||
html += `<button style="padding:0.3rem 0.6rem;font-size:0.85rem;background:#0f3460;color:white;border:none;border-radius:6px;font-weight:600;">${p}</button>`;
|
||||
} else {
|
||||
html += `<button class="btn-secondary" style="padding:0.3rem 0.6rem;font-size:0.85rem;" onclick="ticketPage=${p};renderTickets()">${p}</button>`;
|
||||
}
|
||||
}
|
||||
if (endPage < totalPages) html += `<span style="color:#888;">...</span>`;
|
||||
|
||||
// Seuraava-nappi
|
||||
html += `<button class="btn-secondary" style="padding:0.3rem 0.6rem;font-size:0.85rem;" ${ticketPage >= totalPages ? 'disabled' : ''} onclick="ticketPage++;renderTickets()">Seuraava →</button>`;
|
||||
html += `<button class="btn-secondary" style="padding:0.3rem 0.6rem;font-size:0.85rem;" ${ticketPage >= totalPages ? 'disabled' : ''} onclick="ticketPage=${totalPages};renderTickets()">⟫</button>`;
|
||||
|
||||
// Näytetään sivuinfo
|
||||
const startNum = (ticketPage - 1) * TICKETS_PER_PAGE + 1;
|
||||
const endNum = Math.min(ticketPage * TICKETS_PER_PAGE, totalFiltered);
|
||||
html += `<span style="color:#888;font-size:0.85rem;margin-left:0.5rem;">${startNum}–${endNum} / ${totalFiltered}</span>`;
|
||||
|
||||
paginationEl.innerHTML = html;
|
||||
|
||||
document.getElementById('ticket-search-input').addEventListener('input', () => { ticketPage = 1; renderTickets(); });
|
||||
document.getElementById('ticket-status-filter').addEventListener('change', () => { ticketPage = 1; renderTickets(); });
|
||||
document.getElementById('ticket-type-filter').addEventListener('change', () => { ticketPage = 1; renderTickets(); });
|
||||
document.getElementById('ticket-tag-filter').addEventListener('input', () => { ticketPage = 1; renderTickets(); });
|
||||
document.getElementById('ticket-sort').addEventListener('change', () => { ticketPage = 1; renderTickets(); });
|
||||
document.getElementById('ticket-show-closed').addEventListener('change', () => { ticketPage = 1; renderTickets(); });
|
||||
document.getElementById('ticket-show-mine').addEventListener('change', () => { ticketPage = 1; renderTickets(); });
|
||||
document.getElementById('bulk-select-all').addEventListener('change', function() {
|
||||
const checkboxes = document.querySelectorAll('.ticket-checkbox');
|
||||
checkboxes.forEach(cb => {
|
||||
@@ -1496,6 +1562,11 @@ document.getElementById('bulk-select-all').addEventListener('change', function()
|
||||
else bulkSelectedIds.delete(cb.dataset.ticketId);
|
||||
});
|
||||
updateBulkToolbar();
|
||||
// Näytä montako valittu kaikista sivuilta
|
||||
const allCheckbox = document.getElementById('bulk-select-all');
|
||||
if (bulkSelectedIds.size > checkboxes.length) {
|
||||
allCheckbox.title = `${bulkSelectedIds.size} tikettiä valittu (myös muilta sivuilta)`;
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById('tickets-tbody').addEventListener('click', (e) => {
|
||||
@@ -2268,13 +2339,30 @@ async function initTicketSettings() {
|
||||
).join('');
|
||||
|
||||
// Postilaatikoiden näkyvyys — checkbox per postilaatikko
|
||||
visContainer.innerHTML = mailboxes.map(mb => {
|
||||
let visHtml = mailboxes.map(mb => {
|
||||
const isHidden = currentHiddenMailboxes.includes(String(mb.id)) || currentHiddenMailboxes.includes(mb.id);
|
||||
return `<label style="display:flex;align-items:center;gap:0.5rem;margin-bottom:0.5rem;font-size:0.9rem;cursor:pointer;">
|
||||
<input type="checkbox" class="mb-visibility-cb" data-mailbox-id="${mb.id}" ${!isHidden ? 'checked' : ''}>
|
||||
<span>${esc(mb.company_nimi)} — ${esc(mb.nimi)} <${esc(mb.smtp_from_email)}></span>
|
||||
</label>`;
|
||||
}).join('');
|
||||
|
||||
// Zammad-ryhmät näkyvyyteen (haetaan tiketeistä)
|
||||
try {
|
||||
const zammadGroups = [...new Set(tickets.filter(t => t.source === 'zammad' && t.zammad_group).map(t => t.zammad_group))].sort();
|
||||
if (zammadGroups.length > 0) {
|
||||
visHtml += '<div style="margin-top:0.75rem;padding-top:0.75rem;border-top:1px solid #eee;"><strong style="font-size:0.85rem;color:#666;">Zammad-ryhmät</strong></div>';
|
||||
zammadGroups.forEach(grp => {
|
||||
const key = 'zammad_group:' + grp;
|
||||
const isHidden = currentHiddenMailboxes.includes(key);
|
||||
visHtml += `<label style="display:flex;align-items:center;gap:0.5rem;margin-bottom:0.5rem;font-size:0.9rem;cursor:pointer;">
|
||||
<input type="checkbox" class="mb-visibility-cb" data-mailbox-id="${esc(key)}" ${!isHidden ? 'checked' : ''}>
|
||||
<span>${esc(grp)} <span style="color:#888;font-size:0.8rem;">(Zammad)</span></span>
|
||||
</label>`;
|
||||
});
|
||||
}
|
||||
} catch (e) {}
|
||||
visContainer.innerHTML = visHtml;
|
||||
} catch (e) {
|
||||
sigContainer.innerHTML = '<p style="color:red;font-size:0.85rem;">Virhe ladattaessa postilaatikoita.</p>';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user