Files
IT_Ticket_System/app/templates/admin/kb_list.html
T
2026-05-22 11:53:41 -04:00

136 lines
6.9 KiB
HTML

{% extends "base.html" %}
{% block title %}Manage Knowledge Base{% endblock %}
{% block page_title %}Knowledge Base Management{% endblock %}
{% block content %}
<!-- Filter bar -->
<form method="GET" action="{{ url_for('admin.kb_list') }}" class="card mb-3">
<div class="card-body py-2">
<div class="row g-2 align-items-center">
<div class="col-12 col-sm">
<div style="position:relative;">
<i class="bi bi-search" style="position:absolute;left:10px;top:50%;transform:translateY(-50%);color:var(--muted);font-size:13px;"></i>
<input type="text" name="q" value="{{ q }}" placeholder="Search title or tags…"
class="form-control form-control-sm" style="padding-left:30px;">
</div>
</div>
<div class="col-6 col-sm-auto">
<select name="category" class="form-select form-select-sm" style="min-width:140px;">
<option value="">All categories</option>
{% for cat in categories %}
<option value="{{ cat }}" {% if cat == sel_category %}selected{% endif %}>
{{ cat.replace('_',' ').title() }}
</option>
{% endfor %}
</select>
</div>
<div class="col-6 col-sm-auto">
<select name="author_id" class="form-select form-select-sm" style="min-width:140px;">
<option value="">All authors</option>
{% for author in authors %}
<option value="{{ author.id }}" {% if sel_author_id == author.id|string %}selected{% endif %}>
{{ author.full_name }}
</option>
{% endfor %}
</select>
</div>
<div class="col-6 col-sm-auto">
<select name="published" class="form-select form-select-sm" style="min-width:130px;">
<option value="" {% if sel_published == '' %}selected{% endif %}>All statuses</option>
<option value="yes" {% if sel_published == 'yes' %}selected{% endif %}>Published</option>
<option value="no" {% if sel_published == 'no' %}selected{% endif %}>Draft</option>
</select>
</div>
<div class="col-auto">
<button type="submit" class="btn btn-primary btn-sm">Filter</button>
{% if q or sel_category or sel_author_id or sel_published %}
<a href="{{ url_for('admin.kb_list') }}" class="btn btn-secondary btn-sm ms-1">Clear</a>
{% endif %}
</div>
</div>
</div>
</form>
<div class="card">
<div class="card-header d-flex align-items-center justify-content-between">
<span><i class="bi bi-journal-text me-2"></i>Articles
<span style="font-size:12px;color:var(--muted);">({{ articles|length }} result{{ 's' if articles|length != 1 }})</span>
</span>
<a href="{{ url_for('admin.kb_new') }}" class="btn btn-primary btn-sm">
<i class="bi bi-plus-lg me-1"></i>New Article
</a>
</div>
<div class="card-body p-0">
{% if articles %}
<table class="table mb-0">
<thead>
<tr><th>Title</th><th>Category</th><th>Author</th><th>Published</th><th>Views</th><th style="white-space:nowrap;">👍 / 👎</th><th>Updated</th><th>Actions</th></tr>
</thead>
<tbody>
{% for art in articles %}
<tr>
<td style="font-size:14px;">{{ art.title[:60] }}</td>
<td style="font-size:12px;color:var(--muted);">{{ art.category or '—' }}</td>
<td style="font-size:13px;">{{ art.author.full_name if art.author else '—' }}</td>
<td>
{% if art.is_published %}
<span style="color:var(--success);font-size:12px;"><i class="bi bi-check-circle-fill"></i> Yes</span>
{% else %}
<span style="color:var(--muted);font-size:12px;"><i class="bi bi-dash-circle"></i> Draft</span>
{% endif %}
</td>
<td style="font-size:12px;color:var(--muted);">{{ art.view_count }}</td>
<td style="font-size:12px;white-space:nowrap;">
{% set hc = art.feedback.filter_by(is_helpful=True).count() %}
{% set nc = art.feedback.filter_by(is_helpful=False).count() %}
<span style="color:var(--success);">👍 {{ hc }}</span>
<span style="color:var(--muted);margin:0 3px;">/</span>
<span style="color:var(--danger);">👎 {{ nc }}</span>
</td>
<td style="font-size:12px;color:var(--muted);">{{ art.updated_at.strftime('%b %d, %Y') }}</td>
<td>
<div class="d-flex gap-1 align-items-center">
<a href="{{ url_for('tickets.kb_article', article_id=art.id) }}" class="btn btn-secondary btn-sm" title="Preview"><i class="bi bi-eye"></i></a>
<a href="{{ url_for('admin.kb_edit', article_id=art.id) }}" class="btn btn-secondary btn-sm" title="Edit"><i class="bi bi-pencil"></i></a>
<!-- Publish / Unpublish quick toggle -->
<form method="POST" action="{{ url_for('admin.kb_toggle_publish', article_id=art.id) }}" style="margin:0;">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
{% if art.is_published %}
<button type="submit" class="btn btn-sm"
style="background:rgba(251,191,36,.1);border:1px solid rgba(251,191,36,.3);color:var(--warning);"
title="Unpublish (move to draft)">
<i class="bi bi-eye-slash"></i>
</button>
{% else %}
<button type="submit" class="btn btn-sm"
style="background:rgba(5,150,105,.1);border:1px solid rgba(5,150,105,.3);color:var(--success);"
title="Publish now">
<i class="bi bi-send-check"></i> Publish
</button>
{% endif %}
</form>
<form method="POST" action="{{ url_for('admin.kb_delete', article_id=art.id) }}" data-confirm="Delete this article? This cannot be undone." data-confirm-title="Delete Article" data-confirm-ok="Delete" style="margin:0;">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
<button type="submit" class="btn btn-sm" style="background:rgba(248,113,113,.1);border:1px solid rgba(248,113,113,.2);color:var(--danger);" title="Delete"><i class="bi bi-trash"></i></button>
</form>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<div class="p-5 text-center" style="color:var(--muted);">
<i class="bi bi-journal-x" style="font-size:40px;display:block;margin-bottom:12px;"></i>
{% if q or sel_category or sel_author_id or sel_published %}
No articles match your filters.
<a href="{{ url_for('admin.kb_list') }}" style="color:var(--accent3);display:block;margin-top:8px;">Clear filters</a>
{% else %}
No articles yet. <a href="{{ url_for('admin.kb_new') }}" style="color:var(--accent3);">Create your first article →</a>
{% endif %}
</div>
{% endif %}
</div>
</div>
{% endblock %}