diff --git a/api.php b/api.php
index 1e66173..85996e7 100644
--- a/api.php
+++ b/api.php
@@ -1689,6 +1689,35 @@ switch ($action) {
saveTickets($tickets);
break;
+ case 'ticket_customer':
+ requireAuth();
+ if ($method !== 'POST') break;
+ $input = json_decode(file_get_contents('php://input'), true);
+ $id = $input['id'] ?? '';
+ $customerId = $input['customer_id'] ?? '';
+ $customerName = $input['customer_name'] ?? '';
+ $tickets = loadTickets();
+ $found = false;
+ foreach ($tickets as &$t) {
+ if ($t['id'] === $id) {
+ $t['customer_id'] = $customerId;
+ $t['customer_name'] = $customerName;
+ $t['updated'] = date('Y-m-d H:i:s');
+ $found = true;
+ addLog('ticket_customer', $t['id'], $t['subject'], "Asiakkuus: {$customerName}");
+ echo json_encode($t);
+ break;
+ }
+ }
+ unset($t);
+ if (!$found) {
+ http_response_code(404);
+ echo json_encode(['error' => 'Tikettiä ei löydy']);
+ break;
+ }
+ saveTickets($tickets);
+ break;
+
case 'ticket_assign':
requireAuth();
if ($method !== 'POST') break;
diff --git a/index.html b/index.html
index bbb4aaa..4160ab8 100644
--- a/index.html
+++ b/index.html
@@ -255,14 +255,15 @@
+
@@ -273,8 +274,8 @@
Tyyppi |
Aihe |
Lähettäjä |
+ Asiakas |
Viestejä |
- Osoitettu |
Päivitetty |
diff --git a/script.js b/script.js
index e746ee1..68bc6e8 100644
--- a/script.js
+++ b/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() {
${typeLabel} |
${esc(t.subject)} |
${esc(t.from_name || t.from_email)} |
+ ${t.customer_name ? esc(t.customer_name) : '-'} |
${lastType} ${t.message_count} |
- ${esc(t.assigned_to || '-')} |
${esc((t.updated || '').substring(0, 16))} |
`;
}).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) {
+
`;
@@ -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;