Tickets
src/features/ticket_management/ · (UI-екран) — спільна внутрішня тікет-система з дошкою, створенням, деталями, вкладеннями, журналом і коментарями.
Суть
Tickets дає користувачам усіх основних ролей єдиний канал для задач, bug reports, support-запитів і покращень. Backend визначає доступні category, projects, assignee roles, status transitions, TU та schedule permissions; frontend не задає однакові права для всіх ролей.
Use cases
- Користувач створює тікет, вибирає category, project, primary/secondary assignees, за потреби TU і schedule та додає вкладення.
- Reporter або assignee знаходить тікет через board search/date filter і відкриває details.
- Учасник змінює дозволені backend поля, переглядає logs, додає comments і reactions та перевіряє read state.
- Користувач переглядає нові тікети через bell indicator на картці й unread counter у role menu.
Доступ і маршрути
Feature підключена для восьми route prefixes:
| Роль | Prefix |
|---|---|
| Director | /ceo |
| Top manager | /top_manager |
| Team lead | /teamlead |
| Operator | /operator |
| Client manager | /client_manager |
| HR manager | /hr |
| Recruiter | /recruiter |
| Technical department | /technical_department |
Для кожного prefix використовуються однакові route templates:
/<role>/tickets— redirect на board;/<role>/tickets/board— дошка;/<role>/tickets/new— створення;/<role>/tickets/details?ticketId=<id>— деталі.
Role routing підключений у відповідних Index файлах src/components/director/, top_manager/, team_lead/, operator/, client_manager/, hr_manager/, recruiter/ і technical_department/. src/features/ticket_management/Index.tsx формує спільний header/outlet shell.
Tickets board
Board має п’ять колонок:
waiting— TO DO;in_progress— IN PROGRESS;pending_review— PENDING REVIEW;done— DONE;rejected— REJECTED.
Лічильник у header колонки показує кількість тікетів, уже завантажених у frontend-список, а не гарантований backend total. Для DONE і REJECTED він збільшується після кожного успішного Load older tickets.
Пошук і date filter
- Text search запускається натисканням Enter або search icon.
- Escape або clear action скидає search.
- Date range передається як UTC start першого вибраного дня та UTC end останнього.
- Новий search/date query замінює поточний board result.
Пагінація та сортування
Активні колонки завантажуються початковим board request. Закриті DONE і REJECTED мають незалежну пагінацію по 20 і кнопку Load older tickets. Нові сторінки додаються у серверному порядку; окремого frontend deduplication за id немає.
Активні тікети сортуються:
- pinned перед unpinned;
Urgent,High,Normal,Low;createdAtвід старіших до новіших.
Закриті тікети сортуються за датою status/update від новіших до старіших.
Картка тікета
Картка показує title, project/category, schedule/date state, priority, optional TU, reporter, primary assignee та кількість додаткових assignees. isNews додає bell indicator.
Pin доступний лише для незакритого тікета. Оновлення optimistic: card змінюється одразу, а при помилці backend попередній стан повертається і показується notification.
Створення тікета
Спочатку frontend отримує доступні categories. Після вибору category окремо завантажуються create permissions:
- чи потрібен TU і чи вимагає його selector серверного search;
- чи доступний schedule;
- які projects дозволені;
- які assignee roles дозволені.
Зміна category очищає permissions, project, TU, assignees і schedule. Зміна project очищає TU та assignees. Якщо backend дозволив лише один project, він вибирається автоматично й selector стає disabled.
Для створення обов’язкові:
- непорожній title;
- непорожній description;
- category;
- project;
- щонайменше один assignee, позначений primary;
- TU, якщо backend повернув
isRequired.
Default priority — Low.
Assignees
Assignee modal завантажує користувачів лише дозволених backend ролей. Пошук працює за name або nickname. Done недоступний без primary assignee. Користувачі, які вже входять до ticket і позначені як non-deletable, не можуть бути прибрані через toggle.
У details змінювати те, хто з вибраних assignees є primary, може лише reporter.
TU
TU selector працює у двох режимах:
- preload — список завантажується при відкритті;
requiredSearch— запит виконується лише після непорожнього query та Enter.
Після отримання списку доступний локальний пошук за name або TU ID.
Schedule
Schedule підтримує Full day, start і due date/time. Якщо задані обидві межі, start не може бути пізніше due. На create screen start без due date не приймається. Право використовувати schedule визначає backend.
Окремої симетричної frontend-перевірки для due date без start у поточному create flow немає; чи приймає таке значення backend, із frontend-коду невідомо.
Return із формою, де є незбережені зміни, відкриває confirmation.
Ticket details
Details і update permissions завантажуються паралельно. Якщо query parameter ticketId відсутній, frontend показує notification і не відкриває ticket.
На details screen:
- title, description, category, project, TU та priority — read-only;
- status, assignees і schedule — editable лише за backend permissions;
- status selector disabled, якщо доступних transitions немає;
- перехід у
Rejectedвідкриває reason modal; - schedule показується, якщо він уже існує або backend дозволяє його змінити;
Updateпотребує фактичної зміни, primary assignee та валідного schedule range.
Description відображається як звичайний текст. Поточна реалізація не гарантує автоматичне перетворення URL на links.
Logs початково згорнуті. Show logs відкриває перші 20 записів, Load more додає наступні порції по 20.
Return із незбереженими details changes відкриває confirmation.
Comments і read state
Comment можна відправити з непорожнім text або хоча б одним attachment. Запис comment створюється першим, після чого attachments завантажуються послідовно. Помилка upload не відкочує вже створений comment.
Comments показують автора, час, reactions і read marker. Hover на read state відкриває список користувачів, які переглянули comment.
Вкладення
Вкладення ticket і comments використовують Shared media renderer для preview, fullscreen, playback та file open/download.
Локальні файли можна додати через file picker, drag-and-drop або вставлення image з clipboard. До відправлення окремий draft-файл можна видалити.
- Максимальний розмір одного файла —
20 MB. - Файли понад ліміт пропускаються, а прийнятні залишаються у draft.
- Окремого frontend-ліміту загальної кількості або переліку MIME types не визначено.
Під час create основний ticket зберігається до послідовного upload вкладень. Аналогічно comment зберігається до послідовного upload comment attachments. Тому file upload може завершитися частково: уже створений ticket/comment не відкочується, а користувач отримує notification про невдалі файли.
Loading, empty та error states
| Сценарій | Поведінка |
|---|---|
| Початковий board request, search або date filter | Global loader. |
Load older tickets | Локальний spinner у відповідній closed column. |
| Порожня board column | Колонка залишається порожньою; окремого No tickets немає. |
| Відкриття details | Global loader до завершення details і permissions requests. |
| Create/update/comment/file mutations | Global loader або mutation loading відповідного action. |
| Помилка | Global notification із backend message або frontend fallback; окремої inline error-картки немає. |
Відсутній ticketId | Notification і порожній details state. |
API та realtime
Feature використовує POST endpoint constants із src/utils/tickets.ts:
TICKETS_GET_ALL—/ticket/getTickets;TICKETS_SEARCH—/ticket/searchTickets;TICKETS_FIND_BY_DATE_RANGE—/ticket/findTicketsByDateRange;TICKETS_GET_CATEGORIES_FOR_CREATE—/ticket/getCategories;TICKETS_GET_CREATE_ALLOWS—/ticket/getAllowsCreateTicket;TICKETS_GET_TUS—/ticket/getTUs;TICKETS_GET_ASSIGNEE—/ticket/getAssignee;TICKETS_GET_CREATE_TICKET—/ticket/createTicket;TICKETS_UPLOAD_FILES—/ticket/uploadFilesTicket;TICKETS_GET_DETAILS—/ticket/openTicket;TICKETS_GET_UPDATE_ALLOWS—/ticket/getAllowsUpdateTicket;TICKETS_UPDATE_TICKET—/ticket/updateTicket;TICKETS_SET_PIN—/ticket/setPin;TICKETS_CREATE_COMMENT—/ticket/addComment;TICKETS_UPLOAD_COMMENT_FILES—/ticket/uploadFilesTicketComment;TICKETS_GET_CLOSED_TICKETS—/ticket/getClosedTickets;TICKETS_GET_NEWS_QUANTITY—/ticket/getNewsQuantityTickets.
TICKETS_GET_NEWS_QUANTITY використовується role burger menus для unread counter; повторний виклик у межах однієї хвилини пропускається.
Socket events або listeners у src/features/ticket_management/ відсутні.
Зв’язки
- Спільна поведінка вкладень: media-renderer.
- Реєстр Swagger UI: swagger.
- Frontend endpoint constants:
src/utils/tickets.ts. - Feature routes:
src/features/ticket_management/Index.tsx. - TODO: додати перевірені operation deeplink-и для board, create, details, comments, files і unread counter.