Add ticket sorting by status priority, updated, or created date

Default sort: status priority (käsittelyssä → uusi → odottaa → suljettu)
then by updated date within same status.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-10 11:37:31 +02:00
parent 64ff8eaa91
commit 92d52f34ad
2 changed files with 24 additions and 1 deletions

View File

@@ -263,7 +263,12 @@
<option value="odottaa">Odottaa vastausta</option> <option value="odottaa">Odottaa vastausta</option>
<option value="ratkaistu">Ratkaistu</option> <option value="ratkaistu">Ratkaistu</option>
</select> </select>
<input type="text" id="ticket-tag-filter" placeholder="#tagi" style="padding:9px 12px;border:2px solid #e0e0e0;border-radius:8px;font-size:0.88rem;max-width:140px;"> <select id="ticket-sort" style="padding:9px 12px;border:2px solid #e0e0e0;border-radius:8px;font-size:0.88rem;">
<option value="status">Tila → uusin</option>
<option value="updated">Päivitetty</option>
<option value="created">Luotu</option>
</select>
<input type="text" id="ticket-tag-filter" placeholder="#tagi" style="padding:9px 12px;border:2px solid #e0e0e0;border-radius:8px;font-size:0.88rem;max-width:120px;">
<label style="display:flex;align-items:center;gap:0.4rem;font-size:0.85rem;color:#777;cursor:pointer;white-space:nowrap;"> <label style="display:flex;align-items:center;gap:0.4rem;font-size:0.85rem;color:#777;cursor:pointer;white-space:nowrap;">
<input type="checkbox" id="ticket-show-closed"> Suljetut <input type="checkbox" id="ticket-show-closed"> Suljetut
</label> </label>

View File

@@ -1083,6 +1083,23 @@ function renderTickets() {
); );
} }
// Sorttaus: tila-prioriteetti + päivämäärä
const ticketSortField = document.getElementById('ticket-sort')?.value || 'status';
const statusPriority = { kasittelyssa: 0, uusi: 1, odottaa: 2, suljettu: 3 };
filtered.sort((a, b) => {
if (ticketSortField === 'status') {
const pa = statusPriority[a.status] ?? 9;
const pb = statusPriority[b.status] ?? 9;
if (pa !== pb) return pa - pb;
return (b.updated || '').localeCompare(a.updated || '');
} else if (ticketSortField === 'updated') {
return (b.updated || '').localeCompare(a.updated || '');
} else if (ticketSortField === 'created') {
return (b.created || '').localeCompare(a.created || '');
}
return 0;
});
const ttbody = document.getElementById('tickets-tbody'); const ttbody = document.getElementById('tickets-tbody');
const noTickets = document.getElementById('no-tickets'); const noTickets = document.getElementById('no-tickets');
if (filtered.length === 0) { if (filtered.length === 0) {
@@ -1137,6 +1154,7 @@ document.getElementById('ticket-search-input').addEventListener('input', () => r
document.getElementById('ticket-status-filter').addEventListener('change', () => renderTickets()); document.getElementById('ticket-status-filter').addEventListener('change', () => renderTickets());
document.getElementById('ticket-type-filter').addEventListener('change', () => renderTickets()); document.getElementById('ticket-type-filter').addEventListener('change', () => renderTickets());
document.getElementById('ticket-tag-filter').addEventListener('input', () => 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-closed').addEventListener('change', () => renderTickets());
document.getElementById('bulk-select-all').addEventListener('change', function() { document.getElementById('bulk-select-all').addEventListener('change', function() {
const checkboxes = document.querySelectorAll('.ticket-checkbox'); const checkboxes = document.querySelectorAll('.ticket-checkbox');