Corp/backend/templates/search/results.html
Игорь Надеин dd56953e89 Исправлена разметка и стили страницы профиля
- Заменен лишний div.container на стандартный container для единообразия
- Заменен класс .card на .ios-card в секции активности для устранения конфликтов стилей
- Добавлен card-list.css в base.html для корректного отображения карточек новостей
- Добавлены CSS правила для правильного поведения .row и колонок в grid-layout
- Исправлена проблема с выходом календаря за границы страницы
- Убраны видимые скроллбары у modal-body и modal-content для чистого UI
2025-11-29 13:52:21 +03:00

299 lines
15 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{% extends "base.html" %}
{% load static django_bootstrap5 %}
{% block title %}Поиск{% endblock %}
{% block extra_css %}
<link rel="stylesheet" href="{% static 'css/components/page-header.css' %}">
<link rel="stylesheet" href="{% static 'css/components/ios-search.css' %}">
{% endblock %}
{% block content %}
<div class="container">
<div class="row gx-0">
<div class="col-12">
<!-- Шапка страницы -->
{% include "includes/components/page_header.html" with icon="bi-search" title="Поиск" count=total count_label="Найдено:" search_id="globalSearch" search_placeholder="Фильтр по заголовкам" no_create=True has_filters=True filters_target="searchFilters" filters_template="search/_filters.html" %}
{% if total > 0 %}
{# ===== ПУБЛИКАЦИИ ===== #}
{% if counts.post %}
<div class="card mb-3 section" data-sec="post">
<div class="card-header">
<div class="card-icon" style="width:44px;height:44px;"><i class="bi-journal-text"></i></div>
<div class="card-meta flex-grow-1"><h6 class="mb-0 text-secondary">Публикации</h6></div>
</div>
<div class="list-results">
{% for item in results %}
{% if item.model_name == 'post' %}
{% with post=item.object %}
<div class="result-row d-flex align-items-start gap-2 py-2 px-2" data-type="post" data-haystack="{{ post.title|default_if_none:'' }}">
<div class="card-icon" style="width:44px;height:44px;"><i class="bi-journal-text"></i></div>
<div class="flex-grow-1 position-relative">
<a href="{% url 'feed:post_detail' post.pk %}" class="card-title text-decoration-none stretched-link">{{ post.title }}</a>
<div class="card-subtitle mt-1 text-secondary">{{ post.created_at|date:"d.m.Y H:i" }}</div>
{% if post.body %}<div class="small mt-1 text-body">{{ post.body|truncatewords:35 }}</div>{% endif %}
</div>
</div>
{% endwith %}
{% endif %}
{% endfor %}
</div>
</div>
{% endif %}
{# ===== СОТРУДНИКИ ===== #}
{% if counts.employee %}
<div class="card mb-3 section" data-sec="employee">
<div class="card-header">
<div class="card-icon" style="width:44px;height:44px;"><i class="bi-person-badge"></i></div>
<div class="card-meta flex-grow-1"><h6 class="mb-0 text-secondary">Сотрудники</h6></div>
</div>
<div class="list-results">
{% for item in results %}
{% if item.model_name == 'employee' %}
{% with emp=item.object %}
<div class="result-row d-flex align-items-start gap-2 py-2 px-2" data-type="employee" data-haystack="{{ emp.last_name }} {{ emp.first_name }} {{ emp.patronymic|default_if_none:'' }}">
<div class="card-icon" style="width:44px;height:44px;">
{% if emp.avatar %}<img src="{{ emp.avatar.url }}" alt="">{% else %}<i class="bi-person"></i>{% endif %}
</div>
<div class="flex-grow-1 position-relative">
<a href="{% url 'employees:employee_detail' emp.pk %}" class="card-title text-decoration-none stretched-link">
{{ emp.last_name }} {{ emp.first_name }}{% if emp.patronymic %} {{ emp.patronymic }}{% endif %}
</a>
<div class="card-subtitle mt-1 text-secondary">
{% if emp.position %}{{ emp.position.name }} · {% endif %}
{{ emp.email }}{% if emp.phone_number %} · {{ emp.phone_number }}{% endif %}
</div>
</div>
</div>
{% endwith %}
{% endif %}
{% endfor %}
</div>
</div>
{% endif %}
{# ===== ОТДЕЛЫ ===== #}
{% if counts.department %}
<div class="card mb-3 section" data-sec="department">
<div class="card-header">
<div class="card-icon" style="width:44px;height:44px;"><i class="bi-diagram-3"></i></div>
<div class="card-meta flex-grow-1"><h6 class="mb-0 text-secondary">Отделы</h6></div>
</div>
<div class="list-results">
{% for item in results %}
{% if item.model_name == 'department' %}
{% with dept=item.object %}
<div class="result-row d-flex align-items-start gap-2 py-2 px-2" data-type="department" data-haystack="{{ dept.name|default_if_none:'' }}">
<div class="card-icon" style="width:44px;height:44px;"><i class="bi-diagram-3"></i></div>
<div class="flex-grow-1 position-relative">
<a href="{% url 'employees:department_detail' dept.pk %}" class="card-title text-decoration-none stretched-link">{{ dept.name }}</a>
<div class="card-subtitle mt-1 text-secondary">
{% if dept.head %}Руководитель: {{ dept.head.last_name }} {{ dept.head.first_name }}{% if dept.head.patronymic %} {{ dept.head.patronymic }}{% endif %}{% endif %}
</div>
{% if dept.description %}<div class="small mt-1 text-body">{{ dept.description|truncatewords:35 }}</div>{% endif %}
</div>
</div>
{% endwith %}
{% endif %}
{% endfor %}
</div>
</div>
{% endif %}
{# ===== ЗАЯВЛЕНИЯ ===== #}
{% if counts.request %}
<div class="card mb-3 section" data-sec="request">
<div class="card-header">
<div class="card-icon" style="width:44px;height:44px;"><i class="bi-file-earmark-text"></i></div>
<div class="card-meta flex-grow-1"><h6 class="mb-0 text-secondary">Заявления</h6></div>
</div>
<div class="list-results">
{% for item in results %}
{% if item.model_name == 'request' %}
{% with req=item.object %}
<div class="result-row d-flex align-items-start gap-2 py-2 px-2" data-type="request" data-haystack="{% firstof req.title req.get_type_display '' %}">
<div class="card-icon" style="width:44px;height:44px;"><i class="bi-file-earmark-text"></i></div>
<div class="flex-grow-1 position-relative">
<div class="card-title">
{% firstof req.title req.get_type_display "Заявление" %}
</div>
<div class="card-subtitle mt-1 text-secondary">
Автор: {{ req.employee }}{% if req.department %} · Отдел: {{ req.department }}{% endif %} · {{ req.created_at|date:"d.m.Y H:i" }}
</div>
{% if req.comment %}<div class="small mt-1 text-body">{{ req.comment|truncatewords:35 }}</div>{% endif %}
</div>
<div class="ms-2 mt-1">
{% if req.status == 'pending' %}<span class="badge bg-secondary-subtle text-secondary-emphasis border border-secondary-subtle">На рассмотрении</span>
{% elif req.status == 'approved' %}<span class="badge bg-success-subtle text-success-emphasis border border-success-subtle">Одобрено</span>
{% elif req.status == 'rejected' %}<span class="badge bg-danger-subtle text-danger-emphasis border border-danger-subtle">Отклонено</span>
{% elif req.status == 'cancelled' %}<span class="badge bg-dark-subtle text-dark-emphasis border border-dark-subtle">Отменено</span>
{% elif req.status == 'draft' %}<span class="badge bg-light text-body border">Черновик</span>
{% endif %}
</div>
</div>
{% endwith %}
{% endif %}
{% endfor %}
</div>
</div>
{% endif %}
{# ===== ЧАТЫ ===== #}
{% if counts.chat %}
<div class="card mb-3 section" data-sec="chat">
<div class="card-header">
<div class="card-icon" style="width:44px;height:44px;"><i class="bi-chat-dots"></i></div>
<div class="card-meta flex-grow-1"><h6 class="mb-0 text-secondary">Чаты</h6></div>
</div>
<div class="list-results">
{% for item in results %}
{% if item.model_name == 'chat' %}
{% with chat=item.object %}
{% firstof chat.name chat.department.name chat.pk as chat_label %}
<div class="result-row d-flex align-items-start gap-2 py-2 px-2" data-type="chat" data-haystack="{{ chat_label }}">
<div class="card-icon" style="width:44px;height:44px;"><i class="bi-chat-dots"></i></div>
<div class="flex-grow-1 position-relative">
<a href="{% url 'communications:chat_detail' chat.pk %}" class="card-title text-decoration-none stretched-link">
{% if chat.type == 'global' %}
Глобальный чат
{% elif chat.type == 'department' and chat.department %}
Чат отдела: {{ chat.department.name }}
{% elif chat.type == 'private' %}
{% for u in chat.participants.all %}{% if u != request.user %}{% if not forloop.first %}, {% endif %}{{ u.get_full_name|default:u.username }}{% endif %}{% endfor %}
{% else %}
{{ chat_label }}
{% endif %}
</a>
</div>
</div>
{% endwith %}
{% endif %}
{% endfor %}
</div>
</div>
{% endif %}
{# ===== СООБЩЕНИЯ ===== #}
{% if counts.message %}
<div class="card mb-3 section" data-sec="message">
<div class="card-header">
<div class="card-icon" style="width:44px;height:44px;"><i class="bi-chat-left-text"></i></div>
<div class="card-meta flex-grow-1"><h6 class="mb-0 text-secondary">Сообщения</h6></div>
</div>
<div class="list-results">
{% for item in results %}
{% if item.model_name == 'message' %}
{% with msg=item.object %}
{% firstof msg.chat.name msg.chat.department.name msg.chat.pk as msg_chat_label %}
<div class="result-row d-flex align-items-start gap-2 py-2 px-2" data-type="message" data-haystack="{{ msg.content|default_if_none:'' }}">
<div class="card-icon" style="width:44px;height:44px;"><i class="bi-chat-left-text"></i></div>
<div class="flex-grow-1 position-relative">
<a href="{% url 'communications:chat_detail' msg.chat.pk %}" class="card-title text-decoration-none stretched-link">
{% if msg.author %}{{ msg.author.get_full_name|default:msg.author.username }}: {% endif %}
{{ msg.content|default:"(вложение)"|truncatechars:120 }}
</a>
<div class="card-subtitle mt-1 text-secondary">
{{ msg.created_at|date:"d.m.Y H:i" }} · Чат: {{ msg_chat_label }}
</div>
</div>
</div>
{% endwith %}
{% endif %}
{% endfor %}
</div>
</div>
{% endif %}
{# ===== СОБЫТИЯ ===== #}
{% if counts.event %}
<div class="card mb-3 section" data-sec="event">
<div class="card-header">
<div class="card-icon" style="width:44px;height:44px;"><i class="bi-calendar-event"></i></div>
<div class="card-meta flex-grow-1"><h6 class="mb-0 text-secondary">События</h6></div>
</div>
<div class="list-results">
{% for item in results %}
{% if item.model_name == 'event' %}
{% with ev=item.object %}
{% firstof ev.title ev.name "Событие" as ev_title %}
<div class="result-row d-flex align-items-start gap-2 py-2 px-2" data-type="event" data-haystack="{{ ev_title }}">
<div class="card-icon" style="width:44px;height:44px;"><i class="bi-calendar-event"></i></div>
<div class="flex-grow-1 position-relative">
<div class="card-title">{{ ev_title }}</div>
<div class="card-subtitle mt-1 text-secondary">
{% if ev.start %}Начало: {{ ev.start|date:"d.m.Y H:i" }}
{% elif ev.starts_at %}Начало: {{ ev.starts_at|date:"d.m.Y H:i" }}{% endif %}
{% if ev.location %} · {{ ev.location }}{% endif %}
{% if ev.department %} · {% firstof ev.department.name ev.department " " %}{% endif %}
</div>
</div>
</div>
{% endwith %}
{% endif %}
{% endfor %}
</div>
</div>
{% endif %}
{% else %}
<div class="alert alert-info shadow-sm mt-3">Ничего не найдено.</div>
{% endif %}
</div>
</div>
</div>
<script type="module">
import { initSearchFilter } from "{% static 'js/components/searchFilterHandler.js' %}";
// Инициализация поиска по заголовкам
initSearchFilter({
inputId: 'globalSearch',
clearSelector: '.ios-search-clear',
sectionSelector: '.section',
rowSelector: '.result-row'
});
// Фильтрация по типу через селект
const typeFilter = document.getElementById('searchTypeFilter');
const applyBtn = document.getElementById('applySearchFilter');
const resetBtn = document.getElementById('resetSearchFilter');
const sections = document.querySelectorAll('.section');
function applyTypeFilter() {
const selectedType = typeFilter.value;
sections.forEach(section => {
const sectionType = section.dataset.sec;
if (selectedType === 'all' || sectionType === selectedType) {
section.style.display = '';
} else {
section.style.display = 'none';
}
});
}
function resetFilter() {
typeFilter.value = 'all';
applyTypeFilter();
}
if (applyBtn) {
applyBtn.addEventListener('click', applyTypeFilter);
}
if (resetBtn) {
resetBtn.addEventListener('click', resetFilter);
}
// Применение при изменении селекта
if (typeFilter) {
typeFilter.addEventListener('change', applyTypeFilter);
}
</script>
{% endblock %}