- Шаблоны используют obj.attachment_url напрямую из API - Удален templatetag absolute_url (больше не нужен) - Упрощена проверка наличия вложения - Создан requestListHandler.js для AJAX загрузки с infinite scroll - Обновлен requestList.js для поддержки AJAX режима - Подход аналогичен приложению документов
166 lines
7.6 KiB
HTML
166 lines
7.6 KiB
HTML
{% extends 'base.html' %}
|
||
{% load static django_bootstrap5 %}
|
||
|
||
{% block title %}Заявление{% endblock %}
|
||
|
||
{% block content %}
|
||
<div class="container">
|
||
<div class="row gx-0">
|
||
<div class="col-12">
|
||
|
||
{# — Шапка — #}
|
||
<div class="section-header">
|
||
<i class="bi-file-earmark-text fs-2 text-primary"></i>
|
||
<h2 class="title mb-0">Детали заявления</h2>
|
||
<div class="ms-auto d-flex gap-2">
|
||
<a href="{% url 'requests:request_list' %}" class="btn btn-ghost">
|
||
<i class="bi-arrow-left"></i> К списку
|
||
</a>
|
||
</div>
|
||
</div>
|
||
|
||
{# — Карточка заявки — #}
|
||
<article class="card mb-3">
|
||
<header class="card-header">
|
||
<div class="card-icon" style="width:48px;height:48px;">
|
||
{% if request_obj.employee.avatar %}
|
||
<img src="{{ request_obj.employee.avatar }}" alt="">
|
||
{% else %}<i class="bi-person"></i>{% endif %}
|
||
</div>
|
||
|
||
<div class="card-meta flex-grow-1">
|
||
<div class="d-flex align-items-center gap-2 flex-wrap">
|
||
<span class="card-title">
|
||
{{ request_obj.employee.get_full_name|default:request_obj.employee.username }}
|
||
</span>
|
||
|
||
{# статус — бейдж #}
|
||
{% if request_obj.status == 'pending' %}
|
||
<span class="badge bg-secondary-subtle text-secondary-emphasis border border-secondary-subtle">На рассмотрении</span>
|
||
{% elif request_obj.status == 'approved' %}
|
||
<span class="badge bg-success-subtle text-success-emphasis border border-success-subtle">Одобрено</span>
|
||
{% elif request_obj.status == 'rejected' %}
|
||
<span class="badge bg-danger-subtle text-danger-emphasis border border-danger-subtle">Отклонено</span>
|
||
{% elif request_obj.status == 'cancelled' %}
|
||
<span class="badge bg-dark-subtle text-dark-emphasis border border-dark-subtle">Отменено</span>
|
||
{% elif request_obj.status == 'draft' %}
|
||
<span class="badge bg-light text-body border">Черновик</span>
|
||
{% else %}
|
||
<span class="badge bg-light text-body border">Неизвестно</span>
|
||
{% endif %}
|
||
|
||
{# тип заявки #}
|
||
<span class="badge bg-primary-subtle text-primary-emphasis border border-primary-subtle">
|
||
{{ request_obj.get_type_display }}
|
||
</span>
|
||
</div>
|
||
|
||
<div class="card-subtitle mt-1">
|
||
<time datetime="{{ request_obj.created_at|date:'c' }}">{{ request_obj.created_at|date:"d.m.Y H:i" }}</time>
|
||
{% if request_obj.date_from or request_obj.date_to %}
|
||
· Период: {{ request_obj.date_from|date:'d.m.Y' }}{% if request_obj.date_to %} — {{ request_obj.date_to|date:'d.m.Y' }}{% endif %}
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
|
||
{# Отозвать — только если можно (ожидание и не финальное) #}
|
||
{% if request_obj.status == 'pending' and not request_obj.is_final %}
|
||
<a href="{% url 'requests_app:request_cancel' request_obj.pk %}"
|
||
class="btn btn-ghost ms-auto">
|
||
<i class="bi-x-circle"></i> Отозвать
|
||
</a>
|
||
{% endif %}
|
||
</header>
|
||
|
||
<div class="card-body pt-0">
|
||
<div class="mb-2">
|
||
<span class="text-secondary small">Комментарий:</span>
|
||
<div>{{ request_obj.comment|default:"—" }}</div>
|
||
</div>
|
||
|
||
{% if request_obj.attachment_url %}
|
||
<a class="btn btn-ghost d-inline-flex align-items-center gap-1"
|
||
href="{{ request_obj.attachment_url }}" target="_blank" rel="noopener">
|
||
<i class="bi-paperclip"></i><span>Вложение</span>
|
||
</a>
|
||
{% endif %}
|
||
</div>
|
||
</article>
|
||
<!--
|
||
{# — Комментарии — #}
|
||
<article class="card" id="comments">
|
||
<header class="card-header">
|
||
<div class="card-icon" style="width:44px;height:44px;">
|
||
<i class="bi-chat-dots"></i>
|
||
</div>
|
||
<div class="card-meta">
|
||
<div class="card-title">Комментарии</div>
|
||
<div class="card-subtitle">Всего: {{ request_obj.comments.count }}</div>
|
||
</div>
|
||
</header>
|
||
|
||
<div class="card-body pt-0">
|
||
{% if request_obj.comments.all %}
|
||
<div class="d-flex flex-column gap-2 mb-3">
|
||
{% for c in request_obj.comments.all %}
|
||
<div class="bg-body-tertiary border rounded p-2">
|
||
<div class="small d-flex justify-content-between align-items-start">
|
||
<div>
|
||
<span class="fw-semibold">{{ c.author.get_full_name|default:c.author.username }}</span>
|
||
<span class="text-secondary">·</span>
|
||
<time class="text-muted">{{ c.created_at|date:"d.m.Y H:i" }}</time>
|
||
</div>
|
||
|
||
{# удалить — только автору комментария (права дополнительно проверяются во вьюхе) #}
|
||
{% if c.author_id == request.user.id %}
|
||
<form method="post" action="{% url 'requests_app:request_comment_delete' request_obj.pk c.pk %}">
|
||
{% csrf_token %}
|
||
<button class="btn btn-sm btn-ghost text-danger" type="submit" title="Удалить">
|
||
<i class="bi-trash"></i>
|
||
</button>
|
||
</form>
|
||
{% endif %}
|
||
</div>
|
||
<div class="small mt-1">{{ c.text|linebreaksbr }}</div>
|
||
</div>
|
||
{% endfor %}
|
||
</div>
|
||
{% else %}
|
||
<div class="text-secondary small mb-3">Комментариев пока нет.</div>
|
||
{% endif %}
|
||
|
||
{# Добавить комментарий — #}
|
||
<form class="mt-2 request-comment-form" method="post" action="{% url 'requests_app:request_comment_add' request_obj.pk %}">
|
||
{% csrf_token %}
|
||
<div class="message-field message-field--compact">
|
||
<!-- Кнопка выбора эмодзи -->
|
||
<div class="dropdown message-emoji">
|
||
<button type="button" class="btn btn-ghost btn-emoji message-icon-btn"
|
||
data-bs-toggle="dropdown"
|
||
aria-expanded="false"
|
||
title="Вставить смайлик">
|
||
<i class="bi-emoji-smile"></i>
|
||
</button>
|
||
<div class="dropdown-menu dropdown-menu-start message-emoji-menu">
|
||
<emoji-picker data-emoji-picker class="chat-emoji-picker"></emoji-picker>
|
||
</div>
|
||
</div>
|
||
<textarea name="text" class="form-control message-input" rows="1" placeholder="Оставить комментарий…" maxlength="1000"></textarea>
|
||
<button class="btn btn-primary message-send" type="submit" title="Отправить"><i class="bi-send"></i></button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</article> -->
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
{% endblock %}
|
||
|
||
{% block extra_js %}
|
||
{{ block.super }}
|
||
<script src="{% static 'js/components/requestComments.js' %}"></script>
|
||
<!-- Emoji Picker Library -->
|
||
<script type="module" src="https://cdn.jsdelivr.net/npm/emoji-picker-element@^1/index.js"></script>
|
||
{% endblock %}
|