diff --git a/app/routes/tickets.py b/app/routes/tickets.py index d20e1c3..a09d510 100644 --- a/app/routes/tickets.py +++ b/app/routes/tickets.py @@ -134,7 +134,7 @@ def dashboard(): return render_template('tickets/dashboard_employee.html', my_tickets=my_tickets, open_count=open_count, active_count=active_count, resolved_count=resolved_count, - articles=articles, + articles=articles, now=datetime.utcnow(), ) @@ -538,6 +538,12 @@ def update_ticket(ticket_id): if new_status == TicketStatus.RESOLVED: send_satisfaction_survey(ticket) + if request.headers.get('X-Requested-With') == 'XMLHttpRequest': + from flask import jsonify + return jsonify({'ok': True, 'changes': changes, + 'status': ticket.status, 'priority': ticket.priority, + 'assigned_to_id': ticket.assigned_to_id}) + flash('Ticket updated successfully.', 'success') return redirect(url_for('tickets.ticket_detail', ticket_id=ticket.id)) diff --git a/app/templates/admin/activity_logs.html b/app/templates/admin/activity_logs.html index 9bd7acc..417a38d 100644 --- a/app/templates/admin/activity_logs.html +++ b/app/templates/admin/activity_logs.html @@ -93,6 +93,7 @@
+
@@ -143,6 +144,7 @@ {% endfor %}
+
{% if logs.pages > 1 %}
diff --git a/app/templates/admin/index.html b/app/templates/admin/index.html index 6b1fbe0..d4d7fe2 100644 --- a/app/templates/admin/index.html +++ b/app/templates/admin/index.html @@ -174,6 +174,7 @@
IT Staff Performance
{% if staff_stats %} +
@@ -212,6 +213,7 @@ {% endfor %}
+
{% else %}
No IT staff found.
{% endif %} diff --git a/app/templates/admin/kb_list.html b/app/templates/admin/kb_list.html index cfbb2bb..e4072d6 100644 --- a/app/templates/admin/kb_list.html +++ b/app/templates/admin/kb_list.html @@ -63,6 +63,7 @@
{% if articles %} +
@@ -120,6 +121,7 @@ {% endfor %}
TitleCategoryAuthorPublishedViews👍 / 👎UpdatedActions
+
{% else %}
diff --git a/app/templates/admin/ticket_templates.html b/app/templates/admin/ticket_templates.html index 23e2c17..c08ad88 100644 --- a/app/templates/admin/ticket_templates.html +++ b/app/templates/admin/ticket_templates.html @@ -19,6 +19,7 @@
{% if templates %} +
@@ -68,6 +69,7 @@ {% endfor %}
+
{% else %}
diff --git a/app/templates/admin/tickets.html b/app/templates/admin/tickets.html index 3b7f33b..07c3acb 100644 --- a/app/templates/admin/tickets.html +++ b/app/templates/admin/tickets.html @@ -62,6 +62,7 @@
{% if tickets.items %} +
@@ -115,6 +116,7 @@ {% endfor %}
+
{% if tickets.pages > 1 %}
diff --git a/app/templates/admin/users.html b/app/templates/admin/users.html index 3f73f53..67b148d 100644 --- a/app/templates/admin/users.html +++ b/app/templates/admin/users.html @@ -11,6 +11,7 @@
+
@@ -73,6 +74,7 @@ {% endfor %}
+
{% endblock %} \ No newline at end of file diff --git a/app/templates/base.html b/app/templates/base.html index 27c0f98..1bebb63 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -2,6 +2,9 @@ + @@ -52,6 +55,36 @@ --shadow-lg: 0 10px 25px rgba(0, 0, 0, .1), 0 4px 10px rgba(0, 0, 0, .06); } + html[data-bs-theme="dark"] { + --bg: #0d1117; + --surface: #161b22; + --surface2: #1c2333; + --border: #30363d; + --border2: #3d444d; + --text: #e6edf3; + --text2: #adbac7; + --muted: #8b949e; + --muted2: #545d68; + --success: #3fb950; + --success-bg: #0b2a12; + --warning: #d29922; + --warning-bg: #1c1100; + --danger: #f85149; + --danger-bg: #210b0a; + --info: #388bfd; + --info-bg: #031d40; + --sidebar-bg: #0d1117; + --sidebar-text: #8b949e; + --sidebar-active: #e6edf3; + --shadow-sm: 0 1px 3px rgba(0,0,0,.35), 0 1px 2px rgba(0,0,0,.25); + --shadow: 0 4px 6px rgba(0,0,0,.3), 0 2px 4px rgba(0,0,0,.2); + --shadow-lg: 0 10px 25px rgba(0,0,0,.5), 0 4px 10px rgba(0,0,0,.3); + } + + html[data-bs-theme="dark"] #topbar { + background: rgba(22, 27, 34, .95); + } + * { box-sizing: border-box; margin: 0; @@ -1181,6 +1214,10 @@ {{ unread_notifications if unread_notifications > 0 }} + + {{ current_user.full_name.split()[0] }} @@ -1513,7 +1550,7 @@ function showToast(title, msg) { const t = document.createElement('div'); - t.style.cssText = 'position:fixed;bottom:90px;right:28px;background:var(--surface);border:1px solid var(--border);border-left:3px solid var(--accent3);border-radius:8px;padding:12px 16px;z-index:300;max-width:300px;box-shadow:0 4px 16px rgba(0,0,0,.4);animation:slideIn .25s ease;'; + t.style.cssText = 'position:fixed;top:72px;right:16px;background:var(--surface);border:1px solid var(--border);border-left:3px solid var(--accent3);border-radius:8px;padding:12px 16px;z-index:1090;max-width:320px;box-shadow:0 4px 16px rgba(0,0,0,.18);animation:slideIn .25s ease;'; t.innerHTML = `
${_esc(title)}
${_esc(msg)}
`; document.body.appendChild(t); setTimeout(() => t.remove(), 5000); @@ -1591,7 +1628,71 @@ opacity: 1; } } + + #nprogress-bar { + position: fixed; + top: 0; + left: 0; + height: 3px; + width: 0%; + background: var(--accent); + z-index: 9999; + transition: width .2s ease, opacity .4s ease; + border-radius: 0 2px 2px 0; + } + + {% block scripts %}{% endblock %} diff --git a/app/templates/tickets/dashboard_employee.html b/app/templates/tickets/dashboard_employee.html index 502a84a..c9036dc 100644 --- a/app/templates/tickets/dashboard_employee.html +++ b/app/templates/tickets/dashboard_employee.html @@ -52,28 +52,64 @@
{% if my_tickets %} +
- + {% for t in my_tickets %} + {% set is_done = t.status in ('resolved', 'closed') %} + {% set is_overdue = t.due_date and not is_done and t.due_date < now %} + {% set stage = 0 %} + {% if t.status == 'in_progress' %}{% set stage = 1 %}{% endif %} + {% if t.status == 'pending' %}{% set stage = 2 %}{% endif %} + {% if is_done %}{% set stage = 3 %}{% endif %} - - - + + + - + {% endfor %}
Ticket # TitleStatusProgress Priority Date
{{ t.ticket_number }}{{ t.title[:45] }}{% if t.title|length > 45 %}…{% endif %}{{ t.status.replace('_',' ').upper() }} + {{ t.ticket_number }} + +
+ {{ t.title[:40] }}{% if t.title|length > 40 %}…{% endif %} +
+
+ {% if is_overdue %} + + Overdue + + {% endif %} + {% if t.priority == 'critical' %} + Critical + {% elif t.priority == 'high' %} + High + {% endif %} +
+
+
+ {{ t.status.replace('_',' ').title() }} +
+
+ {% for i in range(4) %} +
+ {% endfor %} +
+
{{ t.priority.upper() }}{{ t.created_at | localtime("%b %d") }}{{ t.created_at | localtime("%b %d") }}
+
{% else %}
diff --git a/app/templates/tickets/dashboard_it.html b/app/templates/tickets/dashboard_it.html index 2f5d54b..31dcd60 100644 --- a/app/templates/tickets/dashboard_it.html +++ b/app/templates/tickets/dashboard_it.html @@ -38,6 +38,7 @@
{% if my_tickets %} +
@@ -51,6 +52,7 @@ {% endfor %}
Ticket #TitlePriorityStatus
+
{% else %}
No tickets assigned to you.
{% endif %} @@ -66,6 +68,7 @@ All tickets →
+
@@ -86,6 +89,7 @@ {% endfor %}
Ticket #UserPriorityStatusAssignee
+
diff --git a/app/templates/tickets/detail.html b/app/templates/tickets/detail.html index c064671..5017401 100644 --- a/app/templates/tickets/detail.html +++ b/app/templates/tickets/detail.html @@ -579,7 +579,7 @@ function buildCommentEl(c) {
Update Ticket
-
+
@@ -623,10 +623,55 @@ function buildCommentEl(c) {
- +
+ + +
+
{% endif %} @@ -728,6 +773,24 @@ function buildCommentEl(c) {
{% endif %} + + {% if not current_user.is_it_staff and linked_tickets %} +
+
Linked Tickets
+
+ {% for lnk, other in linked_tickets %} +
+ {{ other.ticket_number }} + {{ lnk.link_type.replace('_',' ') }} +
{{ other.title }}
+
+ {% endfor %} +
+
+ {% endif %} +
Ticket Details
diff --git a/app/templates/tickets/list.html b/app/templates/tickets/list.html index 3d7c2bb..a192c6b 100644 --- a/app/templates/tickets/list.html +++ b/app/templates/tickets/list.html @@ -59,6 +59,7 @@
{% if tickets.items %} +
@@ -103,6 +104,7 @@ {% endfor %}
+
{% if tickets.pages > 1 %}