### Custom Button System Implementation Created modern button system to replace Bootstrap buttons: - ✅ Created core/_buttons-custom.scss (550+ lines) - ✅ CSS Custom Properties for easy customization - ✅ 8 color variants (primary, secondary, success, danger, warning, info, light, dark) - ✅ Outline and Ghost variants - ✅ 4 sizes (sm, md, lg, xl) - ✅ Special variants (block, icon, circle, link) - ✅ Loading state with spinner animation - ✅ Button groups support - ✅ Modern animations (hover, active, focus) ### Template Migration Migrated 65 HTML templates using automated Python script: - Replaced .btn → .button - Replaced .btn-primary → .button--primary - Replaced .btn-outline-* → .button--outline button--* - Replaced size classes .btn-sm → .button--sm - Total changes: 354 → 347 button usages ### Results - app.css: 137 KB → 148 KB (+11 KB for custom buttons) - Templates changed: 65 files - Remaining .btn classes: 133 (mostly btn-close for modals) - New .button classes: 347 ### Backward Compatibility Kept @extend rules in _buttons-custom.scss for gradual migration. Can be removed after complete migration. Next step: Remove Bootstrap button imports from custom-bootstrap.scss
97 lines
4.3 KiB
HTML
97 lines
4.3 KiB
HTML
{% load static req_tags %}
|
|
|
|
<div id="sidebar"
|
|
class="offcanvas offcanvas-start offcanvas-lg"
|
|
tabindex="-1" aria-labelledby="sidebarLabel"
|
|
data-bs-backdrop="false" data-bs-scroll="true">
|
|
|
|
<div class="offcanvas-header border-bottom d-lg-none">
|
|
<h5 class="offcanvas-title" id="sidebarLabel">Меню</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Закрыть"></button>
|
|
</div>
|
|
|
|
<div class="offcanvas-body d-flex flex-column h-100 px-0">
|
|
<nav class="side-nav">
|
|
<a href="{% url 'feed:feed_list' %}"
|
|
class="nav-link {% if request.resolver_match.url_name == 'feed_list' %}active{% endif %}"
|
|
{% if request.resolver_match.url_name == 'feed_list' %}aria-current="page"{% endif %}>
|
|
<span class="side-icon"><i class="bi-megaphone"></i></span>
|
|
<span>Новости</span>
|
|
</a>
|
|
<a href="{% url 'employees:employees_list' %}"
|
|
class="nav-link {% if request.resolver_match.url_name == 'employees_list' %}active{% endif %}"
|
|
{% if request.resolver_match.url_name == 'employees_list' %}aria-current="page"{% endif %}>
|
|
<span class="side-icon"><i class="bi-people"></i></span>
|
|
<span>Сотрудники</span>
|
|
</a>
|
|
<a href="{% url 'employees:department_list' %}"
|
|
class="nav-link {% if request.resolver_match.url_name == 'department_list' %}active{% endif %}"
|
|
{% if request.resolver_match.url_name == 'department_list' %}aria-current="page"{% endif %}>
|
|
<span class="side-icon"><i class="bi-diagram-3"></i></span>
|
|
<span>Отделы</span>
|
|
</a>
|
|
<a href="{% url 'requests:request_list' %}"
|
|
class="nav-link {% if request.resolver_match.url_name == 'request_list' %}active{% endif %}"
|
|
{% if request.resolver_match.url_name == 'request_list' %}aria-current="page"{% endif %}>
|
|
<span class="side-icon"><i class="bi-clipboard-check"></i></span>
|
|
<span>Заявления</span>
|
|
</a>
|
|
|
|
{% with total=chat_unread_total|default:0 %}
|
|
<a href="{% url 'communications:chat_list' %}"
|
|
class="nav-link {% if request.resolver_match.app_name == 'communications' %}active{% endif %}"
|
|
{% if request.resolver_match.app_name == 'communications' %}aria-current="page"{% endif %}
|
|
aria-label="Чаты{% if total|add:0 > 0 %}, непрочитанных {{ total }}{% endif %}">
|
|
<span class="side-icon icon-wrap">
|
|
<i class="bi-chat-dots"></i>
|
|
{% if total|add:0 > 0 %}
|
|
<span class="badge badge--button" id="sidebarChatBadge" data-count="{{ total }}">{{ total }}</span>
|
|
{% else %}
|
|
<span class="badge badge--button" id="sidebarChatBadge" data-count="0" style="display: none;">0</span>
|
|
{% endif %}
|
|
</span>
|
|
<span>Чаты</span>
|
|
</a>
|
|
{% endwith %}
|
|
<a href="{% url 'documents:document_list' %}"
|
|
class="nav-link {% if request.resolver_match.url_name == 'document_list' %}active{% endif %}"
|
|
{% if request.resolver_match.url_name == 'document_list' %}aria-current="page"{% endif %}>
|
|
<span class="side-icon"><i class="bi-file-earmark-text"></i></span>
|
|
<span>Документы</span>
|
|
</a>
|
|
|
|
<a href="{% url 'finance:dashboard' %}"
|
|
class="nav-link {% if request.resolver_match.app_name == 'finance' %}active{% endif %}"
|
|
{% if request.resolver_match.app_name == 'finance' %}aria-current="page"{% endif %}>
|
|
<span class="side-icon"><i class="bi-cash-coin"></i></span>
|
|
<span>Финансы</span>
|
|
</a>
|
|
|
|
</nav>
|
|
|
|
<div class="mt-auto pt-3 small">
|
|
<button type="button" class="btn-theme js-theme-button" id="themeBtnSidebar"
|
|
aria-label="Сменить тему" title="Сменить тему">
|
|
<i class="bi bi-circle-half" aria-hidden="true"></i>
|
|
</button>
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<script type="module">
|
|
import { initChatBadge } from "{% static 'js/components/chatBadgeHandler.js' %}";
|
|
import { initThemeToggle } from "{% static 'js/components/themeToggleHandler.js' %}";
|
|
|
|
// Инициализация бейджа непрочитанных чатов
|
|
initChatBadge({ badgeId: 'sidebarChatBadge' });
|
|
|
|
// Инициализация переключателя темы
|
|
initThemeToggle();
|
|
</script>
|
|
|
|
|
|
|