- Created migration 146 to seed case type tags with various categories and keywords. - Created migration 147 to seed brand and type tags, including a comprehensive list of brands and case types. - Added migration 148 to introduce a new column `is_next` in `sag_todo_steps` for persistent next-task selection. - Implemented a new script `run_migrations.py` to facilitate running SQL migrations against the PostgreSQL database with options for dry runs and error handling.
137 lines
8.1 KiB
HTML
137 lines
8.1 KiB
HTML
{% extends "shared/frontend/base.html" %}
|
|
|
|
{% block title %}Tekniker Dashboard V3 - Power Table{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="container-fluid py-4">
|
|
<div class="d-flex justify-content-between align-items-start flex-wrap gap-3 mb-4">
|
|
<div>
|
|
<h1 class="h3 mb-1">🛠️ Tekniker Dashboard V3</h1>
|
|
<p class="text-muted mb-0">Power table for {{ technician_name }} (bruger #{{ technician_user_id }})</p>
|
|
</div>
|
|
<div class="d-flex gap-2">
|
|
<a href="/ticket/dashboard/technician?technician_user_id={{ technician_user_id }}" class="btn btn-outline-secondary btn-sm">Tilbage til valg</a>
|
|
<a href="/ticket/dashboard/technician/v1?technician_user_id={{ technician_user_id }}" class="btn btn-outline-primary btn-sm">Se V1</a>
|
|
<a href="/ticket/dashboard/technician/v2?technician_user_id={{ technician_user_id }}" class="btn btn-outline-primary btn-sm">Se V2</a>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row g-4">
|
|
<div class="col-12">
|
|
<div class="card border-0 shadow-sm">
|
|
<div class="card-header bg-white border-0 d-flex justify-content-between align-items-center">
|
|
<h5 class="mb-0">Samlet teknikeroverblik</h5>
|
|
<div class="d-flex gap-2">
|
|
<span class="badge bg-info">Nye: {{ kpis.new_cases_count }}</span>
|
|
<span class="badge bg-secondary">Mine: {{ kpis.my_cases_count }}</span>
|
|
<span class="badge bg-danger">Haste: {{ kpis.urgent_overdue_count }}</span>
|
|
</div>
|
|
</div>
|
|
<div class="card-body p-0">
|
|
<div class="table-responsive">
|
|
<table class="table table-hover table-sm mb-0 align-middle">
|
|
<thead class="table-light">
|
|
<tr>
|
|
<th>SagsID</th>
|
|
<th>Virksom.</th>
|
|
<th>Kontakt</th>
|
|
<th>Beskr.</th>
|
|
<th>Type</th>
|
|
<th>Ansvarl.</th>
|
|
<th>Gruppe/Level</th>
|
|
<th>Opret.</th>
|
|
<th>Start arbejde</th>
|
|
<th>Start inden</th>
|
|
<th>Deadline</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for item in urgent_overdue %}
|
|
<tr>
|
|
<td>#{{ item.item_id }}</td>
|
|
<td>{{ item.customer_name or '-' }}</td>
|
|
<td>{{ item.kontakt_navn if item.kontakt_navn and item.kontakt_navn.strip() else '-' }}</td>
|
|
<td>{{ item.beskrivelse or item.title or '-' }}</td>
|
|
<td>{{ item.case_type or item.item_type or '-' }}</td>
|
|
<td>{{ item.ansvarlig_navn or '-' }}</td>
|
|
<td>{{ item.assigned_group_name or '-' }}</td>
|
|
<td>{{ item.created_at.strftime('%d/%m/%Y') if item.created_at else '-' }}</td>
|
|
<td>{{ item.start_date.strftime('%d/%m/%Y') if item.start_date else '-' }}</td>
|
|
<td>{{ item.deferred_until.strftime('%d/%m/%Y') if item.deferred_until else '-' }}</td>
|
|
<td>{{ item.due_at.strftime('%d/%m/%Y') if item.due_at else '-' }}</td>
|
|
</tr>
|
|
{% endfor %}
|
|
|
|
{% for item in today_tasks %}
|
|
<tr>
|
|
<td>#{{ item.item_id }}</td>
|
|
<td>{{ item.customer_name or '-' }}</td>
|
|
<td>{{ item.kontakt_navn if item.kontakt_navn and item.kontakt_navn.strip() else '-' }}</td>
|
|
<td>{{ item.beskrivelse or item.title or item.task_reason or '-' }}</td>
|
|
<td>{{ item.case_type or item.item_type or '-' }}</td>
|
|
<td>{{ item.ansvarlig_navn or '-' }}</td>
|
|
<td>{{ item.assigned_group_name or '-' }}</td>
|
|
<td>{{ item.created_at.strftime('%d/%m/%Y') if item.created_at else '-' }}</td>
|
|
<td>{{ item.start_date.strftime('%d/%m/%Y') if item.start_date else '-' }}</td>
|
|
<td>{{ item.deferred_until.strftime('%d/%m/%Y') if item.deferred_until else '-' }}</td>
|
|
<td>{{ item.due_at.strftime('%d/%m/%Y') if item.due_at else '-' }}</td>
|
|
</tr>
|
|
{% endfor %}
|
|
|
|
{% for item in my_cases %}
|
|
<tr>
|
|
<td>#{{ item.id }}</td>
|
|
<td>{{ item.customer_name or '-' }}</td>
|
|
<td>{{ item.kontakt_navn if item.kontakt_navn and item.kontakt_navn.strip() else '-' }}</td>
|
|
<td>{{ item.beskrivelse or item.titel or '-' }}</td>
|
|
<td>{{ item.case_type or '-' }}</td>
|
|
<td>{{ item.ansvarlig_navn or '-' }}</td>
|
|
<td>{{ item.assigned_group_name or '-' }}</td>
|
|
<td>{{ item.created_at.strftime('%d/%m/%Y') if item.created_at else '-' }}</td>
|
|
<td>{{ item.start_date.strftime('%d/%m/%Y') if item.start_date else '-' }}</td>
|
|
<td>{{ item.deferred_until.strftime('%d/%m/%Y') if item.deferred_until else '-' }}</td>
|
|
<td>{{ item.deadline.strftime('%d/%m/%Y') if item.deadline else '-' }}</td>
|
|
</tr>
|
|
{% endfor %}
|
|
|
|
{% if not urgent_overdue and not today_tasks and not my_cases %}
|
|
<tr>
|
|
<td colspan="11" class="text-center text-muted py-4">Ingen data at vise for denne tekniker.</td>
|
|
</tr>
|
|
{% endif %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-lg-6">
|
|
<div class="card border-0 shadow-sm">
|
|
<div class="card-header bg-white border-0"><h6 class="mb-0">Nye sager</h6></div>
|
|
<div class="card-body">
|
|
{% for item in new_cases[:6] %}
|
|
<div class="small mb-1">#{{ item.id }} · {{ item.titel }} <span class="text-muted">({{ item.customer_name }})</span></div>
|
|
{% else %}
|
|
<div class="text-muted small">Ingen nye sager.</div>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-lg-6">
|
|
<div class="card border-0 shadow-sm">
|
|
<div class="card-header bg-white border-0"><h6 class="mb-0">Mine opportunities</h6></div>
|
|
<div class="card-body">
|
|
{% for item in my_opportunities[:6] %}
|
|
<div class="small mb-1">#{{ item.id }} · {{ item.titel }} <span class="text-muted">({{ item.pipeline_stage or 'Uden stage' }}, {{ "%.0f"|format(item.pipeline_probability or 0) }}%)</span></div>
|
|
{% else %}
|
|
<div class="text-muted small">Ingen opportunities.</div>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|