24331df462
Виджеты теперь могут требовать доступ к разделу портала (required_section). Недоступный виджет не отдаётся и не предлагается в настройке — даже если остался в сохранённой раскладке или в наборе по умолчанию; save_layout отбрасывает недоступные ключи (защита от подмены). Виджет «Метрики» (общекорпоративная сводка) требует доступа к разделу «Отчёты». Плитки в «Быстром доступе» скрываются по can_section (Документы, Задачи, Календарь, Сотрудники) — как email и справочники ранее; остаются только разделы, доступные пользователю. - core/dashboard.py: required_section, widget_allowed, accessible_keys; фильтрация в resolve/customize/save - quick_access.html: плитки под can_section - tests: 6 тестов доступности (скрытие/показ, отбрасывание, ре-фильтр) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
92 lines
8.3 KiB
HTML
92 lines
8.3 KiB
HTML
{% load common_tags %}
|
|
{% load i18n %}
|
|
<div class="dashboard-widget" data-widget="quick_access" style="background: var(--color-card); border-radius: 0.75rem; border: 1px solid var(--color-border); box-shadow: 0 1px 2px rgb(0 0 0 / 0.05);">
|
|
<div style="padding: 1.25rem 1.5rem; border-bottom: 1px solid var(--color-border);">
|
|
<h3 style="font-weight: 600; color: var(--color-card-foreground); font-size: 0.9375rem;">{% trans "Быстрый доступ" %}</h3>
|
|
<p style="font-size: 0.8125rem; color: var(--color-muted-foreground); margin-top: 0.125rem;">{% trans "Полезные ссылки и инструменты" %}</p>
|
|
</div>
|
|
<div style="padding: 1.25rem; display: grid; grid-template-columns: repeat(auto-fill, minmax(6rem, 1fr)); gap: 0.5rem;">
|
|
|
|
{% if request.user|can_section:'email' %}
|
|
<a href="/email/" hx-get="/email/" hx-target="#main-content" hx-push-url="/email/" hx-indicator="#loader" class="li-hover" style="display: flex; flex-direction: column; align-items: center; gap: 0.5rem; padding: 0.875rem 0.25rem; border-radius: 0.5rem; text-decoration: none; cursor: pointer; transition: background 150ms;">
|
|
<div style="width: 2.5rem; height: 2.5rem; border-radius: 0.625rem; background: hsl(205 80% 55% / 0.12); color: hsl(205 80% 45%); display: flex; align-items: center; justify-content: center;">
|
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
<rect width="20" height="16" x="2" y="4" rx="2"/><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"/>
|
|
</svg>
|
|
</div>
|
|
<span style="font-size: 0.6875rem; color: var(--color-foreground); text-align: center; line-height: 1.3;">{% trans "Электронная почта" %}</span>
|
|
</a>
|
|
{% endif %}
|
|
|
|
{% if request.user|can_section:'documents' %}
|
|
<a href="/documents/" hx-get="/documents/" hx-target="#main-content" hx-push-url="/documents/" hx-indicator="#loader" class="li-hover" style="display: flex; flex-direction: column; align-items: center; gap: 0.5rem; padding: 0.875rem 0.25rem; border-radius: 0.5rem; text-decoration: none; cursor: pointer; transition: background 150ms;">
|
|
<div style="width: 2.5rem; height: 2.5rem; border-radius: 0.625rem; background: hsl(270 60% 55% / 0.12); color: hsl(270 60% 45%); display: flex; align-items: center; justify-content: center;">
|
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"/>
|
|
<path d="M14 2v4a2 2 0 0 0 2 2h4"/>
|
|
</svg>
|
|
</div>
|
|
<span style="font-size: 0.6875rem; color: var(--color-foreground); text-align: center; line-height: 1.3;">{% trans "Документы" %}</span>
|
|
</a>
|
|
{% endif %}
|
|
|
|
{% if request.user|can_section:'tasks' %}
|
|
<a href="/tasks/" hx-get="/tasks/" hx-target="#main-content" hx-push-url="/tasks/" hx-indicator="#loader" class="li-hover" style="display: flex; flex-direction: column; align-items: center; gap: 0.5rem; padding: 0.875rem 0.25rem; border-radius: 0.5rem; text-decoration: none; cursor: pointer; transition: background 150ms;">
|
|
<div style="width: 2.5rem; height: 2.5rem; border-radius: 0.625rem; background: hsl(152 55% 45% / 0.12); color: hsl(152 55% 35%); display: flex; align-items: center; justify-content: center;">
|
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
<rect width="8" height="4" x="8" y="2" rx="1"/><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"/>
|
|
<path d="m9 14 2 2 4-4"/>
|
|
</svg>
|
|
</div>
|
|
<span style="font-size: 0.6875rem; color: var(--color-foreground); text-align: center; line-height: 1.3;">{% trans "Задачи" %}</span>
|
|
</a>
|
|
{% endif %}
|
|
|
|
{% if request.user|can_section:'calendar' %}
|
|
<a href="/calendar/" hx-get="/calendar/" hx-target="#main-content" hx-push-url="/calendar/" hx-indicator="#loader" class="li-hover" style="display: flex; flex-direction: column; align-items: center; gap: 0.5rem; padding: 0.875rem 0.25rem; border-radius: 0.5rem; text-decoration: none; cursor: pointer; transition: background 150ms;">
|
|
<div style="width: 2.5rem; height: 2.5rem; border-radius: 0.625rem; background: hsl(38 92% 50% / 0.12); color: hsl(38 80% 35%); display: flex; align-items: center; justify-content: center;">
|
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
<rect width="18" height="18" x="3" y="4" rx="2"/><path d="M16 2v4M8 2v4M3 10h18"/>
|
|
</svg>
|
|
</div>
|
|
<span style="font-size: 0.6875rem; color: var(--color-foreground); text-align: center; line-height: 1.3;">{% trans "Календарь" %}</span>
|
|
</a>
|
|
{% endif %}
|
|
|
|
{% if request.user|can_section:'databases' %}
|
|
<a href="/databases/" hx-get="/databases/" hx-target="#main-content" hx-push-url="/databases/" hx-indicator="#loader" class="li-hover" style="display: flex; flex-direction: column; align-items: center; gap: 0.5rem; padding: 0.875rem 0.25rem; border-radius: 0.5rem; text-decoration: none; cursor: pointer; transition: background 150ms;">
|
|
<div style="width: 2.5rem; height: 2.5rem; border-radius: 0.625rem; background: hsl(205 80% 55% / 0.12); color: hsl(205 80% 45%); display: flex; align-items: center; justify-content: center;">
|
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
<path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"/><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"/>
|
|
</svg>
|
|
</div>
|
|
<span style="font-size: 0.6875rem; color: var(--color-foreground); text-align: center; line-height: 1.3;">{% trans "Системные справочники" %}</span>
|
|
</a>
|
|
{% endif %}
|
|
|
|
{% if request.user|can_section:'hr_portal' %}
|
|
<a href="/hr-portal/" hx-get="/hr-portal/" hx-target="#main-content" hx-push-url="/hr-portal/" hx-indicator="#loader" class="li-hover" style="display: flex; flex-direction: column; align-items: center; gap: 0.5rem; padding: 0.875rem 0.25rem; border-radius: 0.5rem; text-decoration: none; cursor: pointer; transition: background 150ms;">
|
|
<div style="width: 2.5rem; height: 2.5rem; border-radius: 0.625rem; background: hsl(174 55% 42% / 0.12); color: hsl(174 55% 35%); display: flex; align-items: center; justify-content: center;">
|
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/>
|
|
<circle cx="9" cy="7" r="4"/>
|
|
<path d="M22 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/>
|
|
</svg>
|
|
</div>
|
|
<span style="font-size: 0.6875rem; color: var(--color-foreground); text-align: center; line-height: 1.3;">{% trans "Сотрудники" %}</span>
|
|
</a>
|
|
{% endif %}
|
|
|
|
<a href="/it-support/" hx-get="/it-support/" hx-target="#main-content" hx-push-url="/it-support/" hx-indicator="#loader" class="li-hover" style="display: flex; flex-direction: column; align-items: center; gap: 0.5rem; padding: 0.875rem 0.25rem; border-radius: 0.5rem; text-decoration: none; cursor: pointer; transition: background 150ms;">
|
|
<div style="width: 2.5rem; height: 2.5rem; border-radius: 0.625rem; background: hsl(152 55% 45% / 0.12); color: hsl(152 55% 35%); display: flex; align-items: center; justify-content: center;">
|
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
<path d="M3 18v-6a9 9 0 0 1 18 0v6"/>
|
|
<path d="M21 19a2 2 0 0 1-2 2h-1a2 2 0 0 1-2-2v-3a2 2 0 0 1 2-2h3zM3 19a2 2 0 0 0 2 2h1a2 2 0 0 0 2-2v-3a2 2 0 0 0-2-2H3z"/>
|
|
</svg>
|
|
</div>
|
|
<span style="font-size: 0.6875rem; color: var(--color-foreground); text-align: center; line-height: 1.3;">{% trans "Поддержка IT" %}</span>
|
|
</a>
|
|
|
|
</div>
|
|
</div>
|