3387418332
Каждому виджету можно задать ширину: «Полная» (на всю строку) или «½».
Виджеты выстраиваются в flex-сетку: два «½» встают в один ряд, «Полная»
занимает строку целиком. На узких экранах половинные переносятся в столбик.
- DashboardLayout.widget_widths (JSON {ключ: half|full}) + миграция 0022;
поле widgets не тронуто — обратная совместимость сохранена
- core/dashboard: layout_widths, ширина в build_dashboard_context/
customize_rows, save_layout(widths=...), normalize_width
- dashboard.html: flex-wrap сетка по ширине; customize: переключатель ½/полная
- tests: 6 (сохранение/чтение ширин, нормализация, дефолт, контекст, POST)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
67 lines
2.7 KiB
Python
67 lines
2.7 KiB
Python
from django.conf import settings
|
|
from django.db import models
|
|
from django.utils.translation import gettext_lazy as _
|
|
|
|
|
|
class DashboardLayout(models.Model):
|
|
"""Персональная раскладка дашборда сотрудника.
|
|
|
|
widgets — упорядоченный список ключей включённых виджетов (см.
|
|
core.dashboard.DASHBOARD_WIDGETS). Отсутствие записи = дашборд по
|
|
умолчанию для типа локации сотрудника.
|
|
"""
|
|
|
|
employee = models.OneToOneField(
|
|
settings.AUTH_USER_MODEL, on_delete=models.CASCADE,
|
|
related_name='dashboard_layout', verbose_name=_('Сотрудник'),
|
|
)
|
|
widgets = models.JSONField(_('Виджеты (порядок)'), default=list, blank=True)
|
|
# {ключ виджета: 'half' | 'full'} — ширина виджета в сетке дашборда.
|
|
widget_widths = models.JSONField(_('Ширины виджетов'), default=dict, blank=True)
|
|
updated_at = models.DateTimeField(auto_now=True)
|
|
|
|
class Meta:
|
|
verbose_name = _('Раскладка дашборда')
|
|
verbose_name_plural = _('Раскладки дашборда')
|
|
|
|
def __str__(self):
|
|
return f'{self.employee}: {len(self.widgets or [])} виджетов'
|
|
|
|
|
|
class DashboardDefaults(models.Model):
|
|
"""Синглтон: наборы виджетов дашборда по умолчанию для типа локации.
|
|
|
|
Применяются к сотруднику, который ещё не настраивал свой дашборд.
|
|
Каждое поле — упорядоченный список ключей виджетов.
|
|
"""
|
|
|
|
office = models.JSONField(_('Офис'), default=list, blank=True)
|
|
pharmacy = models.JSONField(_('Аптека'), default=list, blank=True)
|
|
warehouse = models.JSONField(_('Склад'), default=list, blank=True)
|
|
|
|
class Meta:
|
|
verbose_name = _('Дашборд по умолчанию')
|
|
verbose_name_plural = _('Дашборд по умолчанию')
|
|
|
|
def __str__(self):
|
|
return str(_('Дашборд по умолчанию'))
|
|
|
|
def save(self, *args, **kwargs):
|
|
self.pk = 1
|
|
super().save(*args, **kwargs)
|
|
|
|
def delete(self, *args, **kwargs):
|
|
pass # синглтон нельзя удалить
|
|
|
|
@classmethod
|
|
def load(cls):
|
|
obj, _created = cls.objects.get_or_create(pk=1)
|
|
return obj
|
|
|
|
def keys_for(self, location_type: str) -> list:
|
|
return {
|
|
'office': self.office,
|
|
'pharmacy': self.pharmacy,
|
|
'warehouse': self.warehouse,
|
|
}.get(location_type) or []
|