Add closed tickets checkbox, customer linking for tickets
- Closed tickets completely hidden from default view, separate "Suljetut" checkbox to toggle them with search capability - Removed "Osoitettu" column, added "Asiakas" column to ticket list - Customer dropdown in ticket detail view to link ticket to a customer - ticket_customer API endpoint for linking tickets to customers - ticket_type changelog label added Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
40
script.js
40
script.js
@@ -845,6 +845,8 @@ const actionLabels = {
|
||||
ticket_assign: 'Osoitti tiketin',
|
||||
ticket_note: 'Lisäsi muistiinpanon',
|
||||
ticket_delete: 'Poisti tiketin',
|
||||
ticket_customer: 'Linkitti tiketin asiakkaaseen',
|
||||
ticket_type: 'Muutti tiketin tyyppiä',
|
||||
};
|
||||
|
||||
async function loadChangelog() {
|
||||
@@ -976,13 +978,17 @@ function renderTickets() {
|
||||
const query = document.getElementById('ticket-search-input').value.toLowerCase().trim();
|
||||
const statusFilter = document.getElementById('ticket-status-filter').value;
|
||||
const typeFilter = document.getElementById('ticket-type-filter').value;
|
||||
const showClosed = document.getElementById('ticket-show-closed').checked;
|
||||
let filtered = tickets;
|
||||
|
||||
// Default: hide closed tickets unless explicitly selected or "kaikki"
|
||||
if (!statusFilter || statusFilter === '') {
|
||||
// Suljetut näkyvät vain kun täppä on päällä
|
||||
if (showClosed) {
|
||||
filtered = filtered.filter(t => t.status === 'suljettu');
|
||||
} else {
|
||||
filtered = filtered.filter(t => t.status !== 'suljettu');
|
||||
} else if (statusFilter !== 'kaikki') {
|
||||
filtered = filtered.filter(t => t.status === statusFilter);
|
||||
if (statusFilter) {
|
||||
filtered = filtered.filter(t => t.status === statusFilter);
|
||||
}
|
||||
}
|
||||
|
||||
if (typeFilter) {
|
||||
@@ -1015,8 +1021,8 @@ function renderTickets() {
|
||||
<td><span class="ticket-type ticket-type-${t.type || 'muu'}">${typeLabel}</span></td>
|
||||
<td><strong>${esc(t.subject)}</strong></td>
|
||||
<td>${esc(t.from_name || t.from_email)}</td>
|
||||
<td>${t.customer_name ? esc(t.customer_name) : '<span style="color:#ccc;">-</span>'}</td>
|
||||
<td style="text-align:center;">${lastType} ${t.message_count}</td>
|
||||
<td>${esc(t.assigned_to || '-')}</td>
|
||||
<td class="nowrap">${esc((t.updated || '').substring(0, 16))}</td>
|
||||
</tr>`;
|
||||
}).join('');
|
||||
@@ -1038,6 +1044,7 @@ function renderTickets() {
|
||||
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-show-closed').addEventListener('change', () => renderTickets());
|
||||
|
||||
document.getElementById('tickets-tbody').addEventListener('click', (e) => {
|
||||
const row = e.target.closest('tr');
|
||||
@@ -1075,6 +1082,9 @@ async function showTicketDetail(id) {
|
||||
<select id="ticket-assign-select" style="padding:6px 10px;border:2px solid #e0e0e0;border-radius:8px;font-size:0.85rem;">
|
||||
<option value="">Ei osoitettu</option>
|
||||
</select>
|
||||
<select id="ticket-customer-select" style="padding:6px 10px;border:2px solid #e0e0e0;border-radius:8px;font-size:0.85rem;">
|
||||
<option value="">Ei asiakkuutta</option>
|
||||
</select>
|
||||
<button class="btn-danger" id="btn-ticket-delete" style="padding:6px 12px;font-size:0.82rem;">Poista</button>
|
||||
</div>
|
||||
</div>`;
|
||||
@@ -1113,6 +1123,26 @@ async function showTicketDetail(id) {
|
||||
} catch (e) { alert(e.message); }
|
||||
});
|
||||
|
||||
// Customer link — load customers dropdown
|
||||
try {
|
||||
const custSelect = document.getElementById('ticket-customer-select');
|
||||
customers.forEach(c => {
|
||||
const opt = document.createElement('option');
|
||||
opt.value = c.id;
|
||||
opt.textContent = c.yritys;
|
||||
if (c.id === ticket.customer_id) opt.selected = true;
|
||||
custSelect.appendChild(opt);
|
||||
});
|
||||
} catch (e) {}
|
||||
|
||||
document.getElementById('ticket-customer-select').addEventListener('change', async function() {
|
||||
const selOpt = this.options[this.selectedIndex];
|
||||
const custName = this.value ? selOpt.textContent : '';
|
||||
try {
|
||||
await apiCall('ticket_customer', 'POST', { id: currentTicketId, customer_id: this.value, customer_name: custName });
|
||||
} catch (e) { alert(e.message); }
|
||||
});
|
||||
|
||||
// Delete handler
|
||||
document.getElementById('btn-ticket-delete').addEventListener('click', async () => {
|
||||
if (!confirm('Poistetaanko tiketti "' + ticket.subject + '"?')) return;
|
||||
|
||||
Reference in New Issue
Block a user