Corp/backend/employees/urls_front.py
Игорь Надеин d488b748ad feat(ui+calendar+auth+depts): большой апдейт календаря, форм авторизации и списка отделов
Календарь (rightbar) :

• Цвет события по умолчанию (#0d6efd) + удобная палитра (input[type=color] + быстрые свотчи).

• Детали события в модале (центрирование, перенос модала в <body> при необходимости), кнопки Редактировать/Удалить.

• Редактирование: заполнение формы из деталки, PATCH по API, возврат к календарю, безопасные обработчики (навешиваются один раз).

• Еженедельная лента теперь собирает события со всех доступных календарей (компания + отделы пользователя), дедупликация по id.

• В ленте недели: учитывается цвет события, показ источника (Компания / Отдел: N), location и краткое описание (≤20 символов).

• Устранены дубли отделов в селекторе календарей; нормализованы id; аккуратные ошибки/403; безопасная работа без токена.

Список отделов:

• Поиск по названию и руководителю (data-haystack); счётчик сотрудников обновляется только по видимым строкам.

• Кнопка «Создать отдел» в стиле списка (вся строка — кликабельна), видна только при наличии прав/статуса.

• Чёткое центрирование текста и иконки без кастомных стилей (Bootstrap-утилиты), стрелка фиксирована справа.

• Прокрутка только у списка (#deptList): шапка, поиск и кнопка остаются на месте; высота как в employees_list.html.

Auth / Регистрация / Логин / Верификация email / Сброс пароля:

• Шаблоны приведены к единой теме: уважаем переключатель тем из base.html, устранён «мигание» темы.

• RegistrationForm: валидация контактов (хотя бы один из Telegram/WhatsApp/WeChat), пароли совпадают.

• Поля телефона (регистрация/логин): inputmode='numeric', pattern для E.164, подсказки; на бэке по-прежнему нормализуется.

• Регистрация: превью аватара с заглушкой, radio для пола; убраны поля навыков/должности из формы (они не нужны здесь).

• API регистрации: принимаем avatar через Base64ImageField и сохраняем user.avatar при создании; остальная логика без изменений.

• Сообщение об ошибке «нужно хотя бы одно контактное поле» возвращается в ключе detail (совместимо с тестом).

• Логин/верификация/сброс: единые заголовки, floating labels, иконки, соответствие теме.

Техническое:

• Аккуратные утилиты JS: извлечение токена, формирование URL с диапазонами дат, нормализация событий, один раз навешиваемые обработчики.

• Безопасные fallbacks для отсутствующих узлов/данных; кросс-браузерные мелочи (overflow-scrolling, aria-атрибуты).

Примечания:

• Миграций БД нет. Изменены шаблоны, фронтовый JS и вью/сериализатор регистрации.

• Если пути файлов в проекте отличаются, коммит всё равно включает все изменённые файлы (git add -A).
2025-09-10 17:03:45 +03:00

75 lines
2.4 KiB
Python

# backend/employees/urls_front.py
from django.urls import path
from . import views_front
app_name = "employees"
urlpatterns = [
# --- Профиль и сотрудники ---
path("list/", views_front.employee_list, name="employees_list"),
path("me/", views_front.employee_profile, name="profile"),
path("me/edit/", views_front.employee_edit_me, name="employee_edit_me"),
path("<int:pk>/", views_front.employee_profile, name="employee_detail"),
path("<int:pk>/edit/", views_front.employee_edit, name="employee_edit"),
path("create/", views_front.employee_create, name="employee_create"),
# --- Отделы ---
path("departments/create/", views_front.department_create, name="department_create"),
path(
"departments/<int:pk>/roles/edit/",
views_front.edit_department_role,
name="edit_department_role",
),
path("departments/", views_front.department_list, name="department_list"),
path(
"departments/<int:pk>/", views_front.department_detail, name="department_detail"
),
path(
"departments/<int:pk>/edit/",
views_front.department_edit,
name="department_edit",
),
path(
"departments/<int:pk>/set-head/",
views_front.department_set_head,
name="department_set_head",
),
path(
"<int:emp_id>/departments/<int:dept_id>/set-role/",
views_front.set_member_role,
name="set_member_role",
),
path(
"departments/<int:pk>/add-member/",
views_front.department_add_member,
name="department_add_member",
),
path(
"departments/<int:pk>/remove-member/",
views_front.department_remove_member,
name="department_remove_member",
),
# --- Навыки ---
path("<int:pk>/skill/add/", views_front.skill_add, name="skill_add"),
path("<int:pk>/skill/remove/", views_front.skill_remove, name="skill_remove"),
# --- Должности ---
path(
"positions/create/", views_front.position_create_front, name="position_create"
),
path(
"positions/<int:pos_id>/update/",
views_front.position_update_front,
name="position_update",
),
path(
"<int:emp_id>/set-position/",
views_front.employee_set_position_front,
name="employee_set_position",
),
path(
"me/set-position/",
views_front.employee_set_position_me_front,
name="employee_set_position_me",
),
]