Files
ACORE/templates/partials/documents-browser.html
T
lokses ed7dcaae3b Nextcloud connector: страница «Документы» подключена к хранилищу
Заменяет статичный макет documents.html реальным браузером Group Folders:
- access.py: accessible_sections (разделы по правам: Компания/Обучение/Обмен,
  отдел сотрудника, Кадровые дела для суперюзера) + safe_relpath (посегментная
  валидация подпути от path traversal); раздел резолвится только из whitelist
- views: documents_browse/download/upload с проверкой раздела и пути на каждом
  эндпоинте, запись — только в writable-разделы
- documents.html: вкладки разделов + ленивый HTMX-браузер с хлебными крошками,
  навигацией по папкам, скачиванием и загрузкой
- documents_view отдаёт доступные разделы; тесты разделов, путей и авторизации

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-28 15:02:30 +03:00

78 lines
4.0 KiB
HTML

{% load i18n %}
{% if message %}
<div style="margin-bottom:0.875rem; padding:0.625rem 0.875rem; border-radius:0.5rem; font-size:0.8125rem;
{% if message_type == 'success' %}color:#137333; background:rgba(19,115,51,0.1); border:1px solid rgba(19,115,51,0.25);
{% else %}color:#d63333; background:rgba(214,51,51,0.1); border:1px solid rgba(214,51,51,0.25);{% endif %}">
{{ message }}
</div>
{% endif %}
<!-- Хлебные крошки -->
<div style="display:flex; align-items:center; gap:0.375rem; flex-wrap:wrap; margin-bottom:1rem; font-size:0.8125rem;">
<a href="#" hx-get="/documents/browse/?section={{ section.key }}" hx-target="#documents-browser" hx-swap="innerHTML"
style="color:var(--color-primary); text-decoration:none; font-weight:500;">{{ section.label }}</a>
{% for c in crumbs %}
<span style="color:var(--color-muted-foreground);">/</span>
{% if forloop.last %}
<span style="color:var(--color-foreground);">{{ c.name }}</span>
{% else %}
<a href="#" hx-get="/documents/browse/?section={{ section.key }}&path={{ c.path|urlencode }}"
hx-target="#documents-browser" hx-swap="innerHTML"
style="color:var(--color-primary); text-decoration:none;">{{ c.name }}</a>
{% endif %}
{% endfor %}
</div>
{% if error == 'not_configured' %}
<div style="padding:0.875rem; font-size:0.8125rem; color:var(--color-muted-foreground);">
{% trans "Файловое хранилище пока не настроено." %}
</div>
{% elif error %}
<div style="padding:0.875rem; font-size:0.8125rem; color:#d63333;">
{% trans "Не удалось получить список документов." %}
</div>
{% else %}
{% if files %}
<div style="border:1px solid var(--color-border); border-radius:0.5rem; overflow:hidden; margin-bottom:1rem;">
<table style="width:100%; border-collapse:collapse; font-size:0.8125rem;">
<tbody>
{% for f in files %}
<tr style="border-bottom:1px solid var(--color-border);" class="tr-hover">
<td style="padding:0.5rem 0.75rem;">
{% if f.is_dir %}
<a href="#" hx-get="/documents/browse/?section={{ section.key }}&path={{ f.path|urlencode }}"
hx-target="#documents-browser" hx-swap="innerHTML"
style="color:var(--color-foreground); text-decoration:none; font-weight:500;">📁 {{ f.name }}</a>
{% else %}
<a href="/documents/download/?section={{ section.key }}&path={{ sub|urlencode }}&name={{ f.name|urlencode }}"
style="color:var(--color-primary); text-decoration:none;">📄 {{ f.name }}</a>
{% endif %}
</td>
<td style="padding:0.5rem 0.75rem; text-align:right; color:var(--color-muted-foreground); white-space:nowrap;">
{% if f.size is not None %}{{ f.size|filesizeformat }}{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<div style="padding:0.875rem; font-size:0.8125rem; color:var(--color-muted-foreground); margin-bottom:1rem;">
{% trans "В этой папке пока нет файлов." %}
</div>
{% endif %}
{% if section.writable %}
<form method="post" action="/documents/upload/"
hx-post="/documents/upload/" hx-target="#documents-browser" hx-swap="innerHTML"
hx-encoding="multipart/form-data" enctype="multipart/form-data"
style="display:flex; gap:0.5rem; align-items:center;">
{% csrf_token %}
<input type="hidden" name="section" value="{{ section.key }}">
<input type="hidden" name="path" value="{{ sub }}">
<input type="file" name="file" required style="font-size:0.8125rem; flex:1; min-width:0;">
<button type="submit" class="btn btn-primary" style="font-size:0.8125rem; white-space:nowrap;">{% trans "Загрузить" %}</button>
</form>
{% endif %}
{% endif %}