215 Commits

Author SHA1 Message Date
ce69498db2 merge: frontend/Igor2 into feature/procurement-module with Igor2 priority 2026-02-27 16:36:16 +03:00
cb46d869d6 Удалён режим 'до даты' для повторяемых событий, исправлен патч django-scheduler, фронт теперь только 'count' и 'forever' 2026-02-25 11:13:20 +03:00
01b35c3b83 fix: correct imports after frontend/Igor merge
- Fixed PHONE_FIELD import from _helpers module
- Fixed _normalize_phone import from employees.utils
2026-02-24 18:04:05 +03:00
28e2f1615f feat: реализован drag & drop для перемещения событий между календарями
- Создан модуль calendarEventDragDrop.js с классами DragDropState и CalendarUtils
- Реализовано перетаскивание событий между календарями через модальное окно
- Добавлена кнопка 'Переместить все' для массового перемещения
- Модальное окно отображает источник и цель перемещения
- Поддержка legacy-календарей (company/department/personal)
- Добавлены стили для подсветки drop-target (папки и календари)
- Backend: исправлена обработка null значений в serializer
- Backend: добавлен endpoint list_raw для получения немодерируемых событий
- Использованы стандартные Bootstrap стили для модалов
- Исправлено всплытие событий dragover/drop (stopPropagation)
- Эмодзи иконки для типов календарей (����)
- Toast уведомления об успехе/ошибках перемещения
2026-02-12 15:59:53 +03:00
db2be4b469 refactor: компактное отображение событий календаря через SCSS
Проблемы:
- События накладывались друг на друга
- Пилюли событий были раздуты
- CSS вместо SCSS
- Inline styles захламляли JS

Решение:

1. Новый SCSS модуль _calendar-events.scss
   - Компактные события: 10px шрифт, 2px padding, 18px min-height
   - Двухцветная схема через data-атрибуты
   - Управление стеком: max-height 72px (~4 события)
   - Hover, анимации, адаптивность
   - Кастомные scrollbar для popover

2. Упрощённый JavaScript
   - Только цвета через inline styles
   - Всё остальное через SCSS (padding, border, shadow)
   - Data-атрибуты: [data-has-calendar-color], [data-recurrence]
   - Убраны все inline hover-листенеры

3. Оптимизация FullCalendar
   - dayMaxEvents: true - автоматически '+N еще'
   - dayMaxEventRows: 4 - максимум 4 строки
   - eventMaxStack: 3 - до 3 в стеке
   - Ячейка дня: min-height 80px
   - События: max-height 72px контейнера

4. Компактный дизайн
   - Граница календаря: 3px (было 4px)
   - Padding: 2px 4px (было 6px 4px)
   - Font-size: 10px (было 11px)
   - Line-clamp: 2 строки (было 3)
   - Margin: 1px 2px (плотнее)

5. Производительность
   - will-change для GPU ускорения
   - Убраны лишние event listeners
   - CSS animations вместо JS
   - Transition только на hover

Результат:
✅ События компактные и не накладываются
✅ Читаемость сохранена (белый текст + тень)
✅ Двухцветная схема работает (граница + фон)
✅ +N еще при >4 событиях в день
✅ SCSS архитектура (не inline CSS)
✅ Быстрые hover эффекты через CSS
2026-02-11 12:57:07 +03:00
281f0b2bbc feat: современное отображение событий календаря с множественным выбором
Реализовано:

1. Множественный выбор календарей через чекбоксы
   - Заменил <select> на чекбоксы для выбора нескольких календарей
   - События создаются одновременно во всех выбранных календарях
   - При редактировании - обновляется только первый выбранный
   - Цветовые индикаторы для каждого календаря

2. Современный дизайн событий
   - Двухцветная схема: левая граница = цвет календаря, фон = цвет события
   - Полупрозрачный фон события (80%) для лучшей видимости
   - Тени и hover эффекты для объёма
   - Закругленные углы (4px)
   - Плавные анимации (transform + transition)

3. Улучшенное отображение накладывающихся событий
   - dayMaxEvents: автоматически показывать '+N еще'
   - dayMaxEventRows: 4 - максимум 4 строки на день
   - moreLinkClick: 'popover' - красивый popover для остальных
   - eventMaxStack: 3 - до 3 событий в стеке
   - eventOrder: сортировка по началу, длительности, алфавиту

4. Новый CSS файл calendar-improvements.css
   - Современные стили для FullCalendar
   - Улучшенный popover с градиентом
   - Стили для выходных дней (розоватый фон)
   - Hover эффекты на события
   - Анимация fadeInEvent при загрузке
   - Улучшенная читаемость текущего дня
   - Адаптивность для мобильных устройств
   - Кастомные scrollbar для списков

5. Передача цвета календаря в события
   - calendar_color добавляется в extendedProps
   - Используется __calendar из интеграции
   - Отдельная обработка eventColor и calendarColor

6. Визуальные улучшения
   - Текст события: font-weight 500, line-height 1.3
   - Отступы: paddingLeft 6px (с цветом календаря)
   - Тень текста для читаемости на любом фоне
   - Паттерн для ежегодных событий (диагональные полосы)
   - Индикатор текущего дня: синий круг с белым текстом

Результат:
✅ События визуально различимы по календарям (левая граница)
✅ Сохранён индивидуальный цвет события (основной фон)
✅ Множество событий в день отображается компактно (+N еще)
✅ Современный Material Design стиль
✅ Плавные анимации и hover эффекты
✅ Улучшенная читаемость и UX
2026-02-11 12:52:25 +03:00
417fda790d feat: полная интеграция селектора календарей в создание событий
Реализовано:
1. Селектор календаря в форме создания события
   - Заменил статический текст 'Календарь: Компания' на <select>
   - Показывает legacy календари (Компания, Личный, Отделы)
   - Показывает новые Calendar записи из БД
   - Разделитель между legacy и новыми календарями

2. Функция populateCalendarSelector()
   - Динамическое заполнение селектора при открытии формы
   - Использует window.calendarIntegration.calendars
   - Фильтрует legacy календари (startsWith('legacy-'))
   - Устанавливает значение по умолчанию по state.type

3. Обновлена логика создания/редактирования событий
   - Убран старый код с state.type (personal/dept/company)
   - Новая логика читает target_calendar из формы:
     * 'company' → без доп. параметров (общие события)
     * 'personal' → employee_id из meta[name='user-id']
     * 'dept-{id}' → department_id
     * numeric ID → calendar_id (новые календари)
   - Поддержка смешанных ID (string для legacy, int для новых)
   - Работает как для POST (создание), так и для PATCH (редактирование)

4. При редактировании события
   - Автоматическое определение календаря из data:
     * data.calendar_id → numeric ID
     * data.employee_id → 'personal'
     * data.department_id → 'dept-{id}'
     * иначе → 'company'
   - Селектор устанавливается в правильное положение

Результат:
✅ События можно создавать в любом календаре (legacy + новые)
✅ События можно редактировать и перемещать между календарями
✅ Сохранение calendar_id в БД для новых календарей
✅ Обратная совместимость с legacy системой (employee_id/department_id)
✅ UI с иконками � для новых календарей
2026-02-11 12:41:43 +03:00
024d3085ea feat: унифицированный список календарей (legacy + новые)
- calendarManager.js: добавлена функция createLegacyCalendars() для создания pseudo-calendar объектов
- loadCalendars() теперь объединяет legacy (Компания, Личный, Отделы) и новые календари в единый массив
- calendarWidgetIntegration.js: обновлена логика fetchEventsForVisibleCalendars для работы с legacy ID
  - legacy-company: все события без фильтров
  - legacy-personal: события текущего сотрудника (employee_id)
  - legacy-dept-{id}: события конкретного отдела (department_id)
- calendar_desktop.html: удален старый dropdown, оставлен только унифицированный список с чекбоксами
- Все календари теперь в одном списке с возможностью выбора через чекбоксы
- Цвета: Компания (красный), Личный (синий), Отделы (зеленый), новые календари (свои цвета)
2026-02-11 12:18:54 +03:00
299559ab4f fix(calendar): restore legacy calendar type dropdown selector
- Restored original dropdown for Company/Department/Personal selection
- Added new 'My Calendars' collapsible list as ADDITIONAL feature
- Legacy dropdown remains primary navigation
- New calendar list is collapsed by default, accessed via list-check icon
- Two systems work in parallel: legacy (dropdown) + new (multi-calendar)

This fixes the broken calendar type selection functionality.
2026-02-11 11:45:07 +03:00
f8a8b3b2f2 fix(calendar): improve integration initialization and fallback to legacy mode
- Fixed calendar_scripts.html to wait for DOM ready before initialization
- Added retry logic if widget not found on first attempt
- Changed integration fallback: show ALL events when no calendars configured
- Changed behavior: if no calendars selected, show all events (legacy mode)
- This ensures backward compatibility with existing events

User feedback: Integration wasn't initializing on page load, button '+' didn't work.
Solution: Auto-init with retry + always show events (no empty state).
2026-02-11 11:26:25 +03:00
6a99acf7e4 fix(calendar): resolve infinite loading on manage calendar button
- Removed duplicate modal opening via data-bs-toggle attribute
- Changed to programmatic opening via openForCreate() only
- Added calendar:edit event listener for edit functionality
- Updated button selector from data-bs-target to data-action

Issue: Button had both Bootstrap modal trigger and JS event listener,
causing double initialization and infinite loading state.

Solution: Use only programmatic modal opening through calendarManageModal API.
2026-02-11 10:59:10 +03:00
d9395def63 feat(calendar): integrate calendar manager with widget (Phase 3 - Part 2)
- Created calendarWidgetIntegration.js as integration layer
- Modified calendarWidget.js to use new calendar filtering system
- Added fallback to legacy mode for backward compatibility
- Updated calendar_scripts.html to initialize integration
- Implemented fetchEventsForVisibleCalendars with calendar_id filtering
- Added event deduplication and color override from calendars
- Exposed window.calendarIntegration for global access
- Added comprehensive logging for debugging

Technical decisions:
- Non-invasive integration via optional chaining
- Callback-based synchronization (onCalendarToggle, onCalendarsChange)
- Parallel event loading with Promise.all()
- Automatic legacy mode when no calendars configured
2026-02-11 10:10:30 +03:00
826298ff08 feat(calendar): add frontend components for calendar management (Phase 3 - Part 1)
Added API Integration:
- calendarsApi.js: Complete API wrapper for /api/v1/calendar/calendars/
  * CRUD operations (create, read, update, delete)
  * Subscribe/unsubscribe endpoints
  * My subscriptions endpoint
  * Cache invalidation support

Added UI Components:
- calendarManager.js: Calendar list management component
  * Displays available calendars with color indicators
  * Toggle calendar visibility (checkboxes)
  * Subscribe/unsubscribe buttons
  * Edit calendar button (for owners)
  * Real-time calendar filtering

- calendarManageModal.js: Calendar creation/editing modal
  * Create personal/public/department calendars
  * Edit calendar properties (title, description, color)
  * Delete calendar (owner only)
  * Department selection for department calendars
  * Auto-subscription settings

Added Styles:
- calendar-manager.scss: BEM-based styling
  * Calendar list with glassmorphism design
  * Color indicators and icons
  * Hover states and animations
  * Responsive design for mobile
  * Empty state styling

Updated Templates:
- calendar_desktop.html: Added calendar list UI
  * Replaced dropdown with collapsible calendar list
  * Added manage calendar button
  * Updated create event button icon

- calendar_modal_manage.html: New modal template
  * Form fields for calendar properties
  * Radio buttons for calendar types
  * Department selector
  * Auto-subscription checkboxes
  * Delete button for owners

- rightbar_calendar.html: Included new modal

Updated Imports:
- main.scss: Added calendar-manager component import

Status: Phase 3 Part 1 complete (UI components ready)
Next: Part 2 - Integration with calendarWidget.js for event filtering
2026-02-11 09:42:18 +03:00
4dae6400d5 fix: исправлен URL создания чата на корректный REST endpoint /api/v1/communications/chats/ вместо /create/ (ошибка 405) 2026-02-09 12:19:45 +03:00
3e4137daa4 feat(ldap): добавлено кэширование LDAP логина с возможностью обновления
- Добавлено поле Employee.username для кэширования LDAP логина
- API endpoint обновлен: поддержка кэша и force_refresh параметра
- Новый дизайн: убран blur, добавлена иконка обновления
- Автоматическая загрузка при инициализации (из кэша или LDAP)
- Визуальная индикация источника данных (cached/fresh)
- Доступно всем пользователям без ограничений
2026-02-06 15:33:48 +03:00
17c4e506cf refactor(employees): упрощена логика прав для LDAP endpoint
- Использована встроенная система пермишенов DRF вместо ручной проверки
- Добавлен ldap_info в required_perms_by_action с правом view_ldap_info
- Добавлен ldap_info в get_permissions() для применения IsSelfOrStaff
- Удалена избыточная ручная проверка прав внутри метода ldap_info()
- Проверка прав теперь выполняется автоматически через get_object()
- Пользователь может видеть свой LDAP логин (IsSelfOrStaff)
- Админы и пользователи с view_ldap_info могут видеть любые логины
2026-02-06 14:28:21 +03:00
c6cd2ba20d feat(employees): добавлен функционал отображения LDAP логина в профиле
- Добавлено поле с LDAP логином (sAMAccountName) в профиле сотрудника
- Реализован blur-эффект с раскрытием по клику для безопасности
- Создан API endpoint /api/v1/employees/{id}/ldap-info/ для получения LDAP данных
- Добавлен новый пермишен employees.view_ldap_info
- Стили: SCSS компонент _ldap-login.scss с анимациями и состояниями
- JavaScript: класс LdapLoginField с AJAX запросами и обработкой ошибок
- Доступ только для staff или пользователей с правом view_ldap_info
- Данные запрашиваются из Active Directory on-demand (не хранятся в БД)
2026-02-06 14:24:31 +03:00
da7bf54c6c feat: Реализация полной функциональности опросов в чатах
- Исправлен PollSerializer для создания опросов с опциями
- Добавлено поле read_only_fields для корректной валидации
- Реализована отправка WebSocket уведомлений при создании опроса
- Исправлен импорт serialize_message из communications.serialization
- Добавлен обработчик poll_update в UserConsumer для WebSocket событий
- Исправлен эндпоинт /results/ для возврата user_voted_option_ids
- Добавлено поле voters в PollOptionSerializer для списка проголосовавших
- Реализована инициализация poll виджетов после рендера сообщений
- Добавлено игнорирование poll_update в notification-manager
- Исправлены стили для request list badges (height, word-break, flex)
- Восстановлены стили team-wheel (.wheel-focus, .scroll-arc) из git истории
- Реализовано отображение forwarded message info в messageRendererV2
- Множественные улучшения UI и UX для опросов

Fixes: создание опросов, голосование, отображение результатов, список проголосовавших
2026-01-22 01:33:42 +03:00
8363cbd541 feat: Complete CSS to SCSS migration (100%)
- Migrated all 28 CSS components to SCSS architecture
- Deleted 29 source CSS files (kept only compiled app.css & bootstrap-custom.css)
- Created 30 SCSS component modules in scss/components/
- Cleaned 24 templates from duplicate CSS links
- Updated main.scss with new imports (layout-spacing, spacing-utils, rightbar-calendar)
- Filled empty _navbar.scss with content
- Refactored css/ folder: removed obsolete files, updated README.md
- Created comprehensive documentation (migration complete, quick reference, reports)

Migration Statistics:
- Components migrated: 28 (~4,768 lines SCSS)
- CSS files deleted: 29
- Templates cleaned: 24
- app.css size: 95 KB (compiled from SCSS)
- bootstrap-custom.css: 301 KB
- Total: 396 KB

Phase 6 Complete: 100% SCSS architecture achieved ✅
2026-01-15 13:48:11 +03:00
53ec1a7b87 feat: implement Telegram-style image dimension pre-loading to fix auto-scroll
- Backend: added width/height fields to MessageAttachment model with Pillow auto-extraction
- Migration: 0021_add_image_dimensions + populate_image_dimensions management command
- API: serialize width/height in messageAttachmentSerializer and consumers.py
- Frontend: switched from CSS aspect-ratio to explicit pixel calculation (Telegram approach)
  * messageRendererV2.js: calculate exact dimensions (maxWidth=500px, proportional height)
  * Fixes scroll jump issue: images now reserve exact space before loading
  * Debug logging added to validate dimension rendering
- Testing: 18/18 images populated successfully with dimensions

This prevents scroll position shifts when images load after initial positioning,
implementing the same approach as Telegram Web.

Related: scroll positioning, image preloading, chat UX
2026-01-14 17:32:06 +03:00
f00f7c0be5 fix(ui): исправлен рендеринг аватаров - устранена деформация и выравнивание
Проблема:
- Аватары деформировались из-за object-fit на контейнере
- Аватары выравнивались по верху сообщения вместо низа
- Неконсистентная HTML структура: <img class="mini-ava"> vs <div class="mini-ava"><i></i></div>

Решение:

SCSS (_common.scss):
- object-fit: cover перемещен с контейнера на вложенный img
- Добавлен display: block для img элементов

SCSS (_chat-detail.scss):
- Добавлен align-items: flex-end к .d-flex.msg для выравнивания по низу
- .mini-ava рефакторинг: display: flex (было grid), border-radius: 50% (было 9999px)
- Добавлен background и border для контейнера
- Добавлен font-size: 20px для fallback иконки
- object-fit остается только на img тегах

JavaScript (messageRendererV2.js):
- Всегда создавать <div class="mini-ava"> как контейнер
- Вложенный <img> или <i class="bi bi-person-circle"> внутри
- Устранена несогласованность разметки

Рефакторинг архитектуры SCSS (бонус):
- Создан Design System: abstracts/_variables.scss (200+ токенов)
- Создано abstracts/_mixins.scss (40+ миксинов)
- Реорганизована файловая структура: layout/, components/, components/chat/
- Централизованы стили аватаров в _common.scss
- Устранены дубликаты (avatar определялся в 3 файлах)
- Применены design tokens к navbar, page-header
- Создана документация: SCSS_NAMING_CONVENTIONS.md
- Удалено 9 дублирующихся CSS файлов

Компиляция: 280KB, 0 ошибок, production ready
2026-01-14 11:18:35 +03:00
b92fd8849e test: Template changes - add badge element to button 2026-01-13 16:14:33 +03:00
d96d6633f0 chore: Add documentation and supporting files for bidirectional loading
Added:
- Autoscroll audit and reports
- Date divider analysis and Telegram comparison
- Bidirectional loading tests and results
- Date group manager and utilities
- Test scripts and HTML test pages
- CSS for chat date groups
- IntersectionObserver utilities
2026-01-13 15:02:20 +03:00
2a012c297f refactor: удалены test/example файлы и deprecated templates
- Deleted chatHistoryLoader.js (@deprecated)
- Deleted chatControllerUsage.js (example)
- Deleted chatTests.js (manual test, 1732 lines)
- Deleted test_message_editing.html
- Deleted test_message_renderer.html
- Deleted chat_detail_scripts.html (неиспользуемый template)
2026-01-13 10:18:12 +03:00
697f8c6d37 refactor: удален legacy код, chatDetailV2 переименован в chatDetail
УДАЛЕНО (57KB, 1306 строк):
✅ scrollManager.legacy.js (23KB) - заменен на ScrollManagerV2
✅ messageLoader.legacy.js (16KB) - заменен на MessageLoaderV2
✅ messageRenderer.legacy.js (18KB) - заменен на MessageRendererV2
✅ chatDetail.js (старая версия) - имел deprecated обертки
✅ chatDetailTest.js - тестовый файл

ПЕРЕИМЕНОВАНО:
✅ chatDetailV2.js → chatDetail.js (стал основным)

ПРЕИМУЩЕСТВА:
- Прямой импорт ChatControllerV2
- Нет deprecated оберток
- Поддержка lastReadTimestamp fallback
- Правильная загрузка вокруг lastRead
- Минус 57KB мертвого кода
2026-01-13 10:14:11 +03:00
a9a6c9ffee refactor: переключились на chatDetailV2.js (чистая архитектура)
- Прямой импорт ChatControllerV2 без промежуточных слоев
- Убраны deprecated обертки (window.messageRenderer, window.chatHistoryLoader)
- Меньше кода: 231 vs 264 строки
- Более явная архитектура
- Для тестирования работы в production
2026-01-13 10:03:54 +03:00
f29bfc283d fix: исправлены импорты в messageEditing и chat/index 2026-01-13 09:18:25 +03:00
aba011731f feat: implement Telegram-style badges system
- Created comprehensive badges-telegram-style.css (240 lines) based on Telegram Web K
- Updated all badge markup in templates (navbar, sidebar, chat_list, chat_detail, chat_title)
- Replaced Bootstrap badge classes with .badge-telegram classes
- Implemented Telegram specifications: 20px height, 10px radius, 11px font, 600 weight
- Added smooth animations: pulse (on update), animate-in (on mount), animate-out (on unmount)
- Updated JavaScript: replaced .d-none with style.display for badge visibility
- Updated 5 JS files: bottom-navbar, notification-manager, chatBadgeHandler, chatBadgeManager, chatListRealtime
- Added pulse animation on badge value increase
- Improved shadows and transitions with cubic-bezier easing
- Added badges-telegram-style.css to base.html for global availability
- Created documentation: TELEGRAM_BADGES_GUIDE.md, TELEGRAM_BADGES_UPDATE.md

Technical details:
- Research: Analyzed 50+ files from Telegram Web K GitHub repository
- Perfect circles: border-radius: 10px (not 50%)
- Spring animation: cubic-bezier(0.175, 0.885, 0.32, 1.275)
- Auto-hide: :empty and [data-count='0'] selectors
- Responsive design + dark theme support
2026-01-12 17:37:41 +03:00
d5be62b34c refactor: восстановлены старые стили пузырей сообщений, аватаров и разделителей (pre-redesign)
- Восстановлен мягкий цвет пузырей: color-mix(92%) вместо жесткого var(--bs-primary)
- Аватары: border-radius 9999px + grid layout для идеальных кругов
- Разделители: правильный spacing, font-weight 700, pointer-events, color-mix прозрачность
- Добавлены оптимизации скролла: rootMargin 300px, limit 50 сообщений (Telegram-стиль)
- Добавлены новые модули: messageLoader, scrollManager, chatUtils
- Рефакторинг логики загрузки сообщений для предотвращения дубликатов
- Создана документация по архитектуре и тестированию
2026-01-12 17:21:41 +03:00
07cd6acaff fix(messenger): исправление прыжков при загрузке и дублирования скриптов
ПРОБЛЕМЫ:
1. Видимые прыжки прокрутки при загрузке чата
2. Принудительный скролл при получении чужих сообщений
3. Дублирование загрузки chat-detail-enhanced.js

РЕШЕНИЯ:
1. Используем requestAnimationFrame для гарантии обновления DOM перед прокруткой
   - Скрываем контейнер → рендерим → ждем RAF → скроллим → показываем
   - Прокрутка происходит ДО показа контейнера = нет видимых прыжков

2. Убираем агрессивный автоскролл в handleNewMessage:
   - Скроллим только если это наше сообщение ИЛИ мы уже внизу
   - Предотвращаем прерывание чтения старых сообщений

3. Убираем дублирование chat-detail-enhanced.js в шаблоне:
   - Было: загружается ДО chatDetail.js
   - Стало: загружается ПОСЛЕ для правильного порядка инициализации

4. Улучшен порядок загрузки скриптов в chat_detail.html:
   - emoji-picker (третья сторона)
   - chatDetail.js (core инициализация)
   - chat-detail-enhanced.js (UI расширения)

РЕЗУЛЬТАТЫ:
✅ Нет видимых прыжков - чат открывается сразу в конце
✅ Не прерывается чтение старых сообщений при приходе новых
✅ Правильный порядок инициализации компонентов
✅ Убрано дублирование загрузки скриптов
2026-01-12 11:03:41 +03:00
85ce134bac feat(chat): рефакторинг мобильной навигации и шапки чата
- Реализован современный нижний navbar для мобильных (5 кнопок)
- Скрытие нижнего navbar на странице чата
- Новая шапка чата с аватарами и бейджами типа чата
- Переработана HTML структура чата (убраны лишние Bootstrap контейнеры)
- Добавлены стили для аватаров и бейджей типов чатов
- Условное отображение: аватар OR иконка категории
2026-01-12 10:14:16 +03:00
0ec6a46831 Добавлена нижняя навигационная панель для мобильных устройств
- Добавлена bottom navbar с 5 кнопками (Главная, Уведомления, Поиск, Календарь, Ещё)
- Панель отображается только на мобильных устройствах (до 768px)
- Использованы системные CSS переменные и стили
- Удалена кнопка гамбургера из верхней панели (дублирование функционала)
- Добавлена синхронизация бейджей уведомлений
- Поддержка светлой и темной темы
- Backdrop-filter для полупрозрачности в iOS-стиле
2026-01-12 08:32:16 +03:00
7838a55ef4 feat: Replace CDN with local vendor libraries + complete Web Push setup
- Замена всех CDN зависимостей на локальные файлы:
  * Bootstrap 5.3.3 (CSS + JS)
  * Bootstrap Icons 1.11.3 (CSS + шрифты woff/woff2)
  * FullCalendar 6.1.8 (JS + локали)
  * Cropper.js 1.6.1
  * emoji-picker-element 1.21.3

- Web Push Notifications:
  * VAPID ключи настроены в settings.py
  * Service Worker (sw.js) в корне backend/
  * API endpoints: /api/v1/notifications/push/
  * Auto-request permission при загрузке страницы
  * Simplified subscribe logic (Phase 1 refactor)
  * resetEverything() для восстановления после ошибок

- Документация:
  * backend/docs/guides/WEB_PUSH_QUICK_TEST.md
  * backend/docs/guides/FIX_NO_PUSH_SUBSCRIPTIONS.md
  * backend/docs/troubleshooting/WEB_PUSH_OFFLINE_ISSUE.md

- Обновлено 10 шаблонов для использования local vendor
- Устранены проблемы с CORS и integrity checks
- Все иконки Bootstrap Icons теперь отображаются корректно
2026-01-06 09:22:16 +03:00
4a139180f7 feat: Auto-unsubscribe push on logout, force resubscribe on login
- Добавлена автоматическая отписка от Web Push при выходе
- При входе принудительно переподписываем пользователя
- Очищаем старую подписку из localStorage перед новой
- Это исправляет AbortError из-за старых подписок с другими VAPID ключами
2026-01-06 08:11:24 +03:00
788a245cc9 feat: implement Web Push notifications for offline browser notifications
- Add WebPushSubscription model for storing push subscriptions
- Generate VAPID keys for Web Push authentication
- Add API endpoints for push subscribe/unsubscribe
- Create Service Worker (sw.js) for handling push events
- Create JavaScript module for managing push subscriptions
- Integrate send_web_push_notification into NotificationService
- Add Service Worker registration to base.html
- Update requirements.txt with pywebpush package
2026-01-05 14:10:42 +03:00
8c546e59fb - 2026-01-05 10:59:07 +03:00
d5b5437c60 fix: password reset emails now use HTML template for Gmail compatibility 2026-01-05 10:47:56 +03:00
026bc46816 feat(department-roles): complete LDAP architecture redesign with RoleAssignment model
BREAKING CHANGES:
- Removed OU=Roles from LDAP structure, role groups now created directly in department OU
- Role groups use ROLE_<Name> naming convention (similar to DEP_, POS_)

New features:
- RoleAssignment model: allows assigning roles to ANY employee, not just department members
- New API endpoints: /assign/, /revoke/, /assignments/ on DepartmentRoleViewSet
- Permission system updated: has_dept_perm() checks RoleAssignment first
- Employee profile shows external roles with 'внешняя роль' badge
- Employee list filter includes role-only employees with department_relation field
- Role assignment modal now searches all employees via AJAX

LDAP changes:
- _ensure_role_group(): creates ROLE_<Name> group in department OU
- assign_role(), revoke_role(): manage RoleAssignment + LDAP sync
- rename_role_group(), delete_role_group(): full lifecycle support
- Removed all references to OU=Roles

Migrations:
- 0035: Create RoleAssignment model
- 0036: Data migration from EmployeeDepartment.role

Tests:
- 7 new tests for role assignment (all passing)

Docs:
- 9 detailed reports on architecture, models, API, LDAP, tests
2025-12-30 10:35:34 +03:00
36f756988b fix(requests): улучшены названия фильтров дат и исправлена логика фильтрации 2025-12-29 15:42:00 +03:00
8ebe241174 feat(requests): добавлены фильтры по сотруднику и периоду дат 2025-12-29 15:32:27 +03:00
0b959f33e0 refactor(requests): заменён фильтр 'Область' на nav-pills как в документах 2025-12-29 15:25:18 +03:00
f6a1315d76 feat(requests): текст темы в списке заявлений теперь ссылка на страницу деталей 2025-12-29 14:47:13 +03:00
0890d02efc refactor: переделать страницу деталей заявления с нуля со стилями из списка
- Полная переделка шаблона request_detail.html с единообразными стилями
- Новая структура: основная карточка (8 колонок) + боковая панель комментариев (4 колонки)
- Единообразные иконки типов заявлений (calendar-check, capsule, umbrella-fill и т.д.)
- Единообразные бейджи статуса и типа как в списке
- Информационные блоки для автора, описания, получателей, одобрившего
- Форма комментариев с правильным стилем message-field--compact
- Emoji picker с поддержкой dropdown-menu поверх контента
- AJAX обработка отправки и удаления комментариев
- Новый CSS файл request-detail.css с адаптивностью
- Добавлена функция _add_type_display() в views.py для отображения типа

Улучшения:
- Единство дизайна со страницей списка заявлений
- Правильное позиционирование emoji picker (fixed positioning)
- Sticky боковая панель с комментариями
- Форма комментария как в ленте (message-field--compact)
- Кнопки одобрения/отклонения с правильными иконками
2025-12-29 14:27:47 +03:00
dd219d4752 Исправлена view request_detail
- Добавлены comments в контекст
- Добавлен prefetch recipients и cc_users в DETAIL_REQUEST_QS
- Теперь все данные передаются правильно
2025-12-29 12:31:37 +03:00
be21b9ca4a Полностью переработана страница деталей заявления
Исправлено:
- Добавлена правильная структура card-header с аватаром 48x48px
- Добавлены все необходимые детали: получатели, копия, согласующий
- Исправлены стили для badge и card-body
- Добавлена корректная форма комментария с emoji picker и auto-expand
- Подключены правильные JavaScript компоненты
- Исправлен формат дат (d.m.Y H:i)
- Добавлена передача can_process в контексте view

Добавлено:
- Иконки для каждого раздела (получатели, копия, согласующий)
- Ссылки на карточки сотрудников
- Правильные Badge с subtle цветами
- Форма комментария с message-field компонентом
2025-12-29 12:25:42 +03:00
1349ebce35 fix(requests): временно отключена кнопка 'Отозвать'
URL request_cancel не подключен в urls_front.py
Закомментирована кнопка до добавления функционала
2025-12-29 12:00:52 +03:00
532098499b fix(requests): исправлен namespace для URL request_cancel
Изменено: requests:request_cancel → requests_app:request_cancel
Исправлена ошибка NoReverseMatch при открытии страницы заявления
2025-12-29 11:59:03 +03:00
087cff7901 fix: исключен approver из получателей уведомлений о решении
- Approver (тот кто принял решение) не получает уведомление о своем действии
- Исключены employee.id и approver_id из recipients при approve/reject
- Упрощен signal create_request_notifications (убран лишний запрос в БД)
- Теперь передается актуальный request_obj с установленным approver_id
2025-12-29 11:02:39 +03:00
3941b5c963 fix: уточнен селектор формы решения в request_process.html 2025-12-29 10:15:45 +03:00
849545b11c feat: AJAX обработка формы решения на странице заявления без перезагрузки 2025-12-29 10:01:32 +03:00