From 91f408aca246ece16e6f890f1a7fa3f7dbd6f8f0 Mon Sep 17 00:00:00 2001 From: kalugin66 Date: Thu, 5 Mar 2026 23:21:57 +0500 Subject: [PATCH] =?UTF-8?q?=D0=B4=D0=B5=D0=B9=D1=81=D1=82=D0=B2=D0=B8?= =?UTF-8?q?=D1=8F=20=D0=BF=D0=BE=D0=B4=D0=BF=D0=B8=D1=81=D0=B0=D1=82=D1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/nav-task-actions.js | 14 +++- public/signature.js | 163 ++----------------------------------- 2 files changed, 18 insertions(+), 159 deletions(-) diff --git a/public/nav-task-actions.js b/public/nav-task-actions.js index aabb6a8..d6e8b92 100644 --- a/public/nav-task-actions.js +++ b/public/nav-task-actions.js @@ -88,7 +88,16 @@ if (currentUser && !isDeleted && !isClosed) { log('nav-task-actions openManageAssigneesModal not'); } } - +// Подписание (только для документов, если текущий пользователь - исполнитель) +if (!isDeleted && !isClosed && task.task_type === 'document' && currentUser && task.assignments?.some(a => parseInt(a.user_id) === currentUser.id)) { + if (typeof window.signTask === 'function') { + actions.push({ + label: '✍️ Подписать', + handler: () => window.signTask(taskId, currentUser.id), + admin: true // primary_task + }); + } +} // ${currentUser && currentUser.role === 'tasks' && canEdit || currentUser.role === 'admin' // Администраторы и роль tasks if (currentUser && (currentUser.role === 'admin' || (currentUser.role === 'tasks' && canEdit))) { @@ -122,6 +131,7 @@ if (currentUser && (currentUser.role === 'admin' || (currentUser.role === 'tasks } } } + // Доработка и изменение срока для необычных задач (исполнитель) if (!isDeleted && !isClosed && task.task_type !== 'regular' && task.assignments && task.assignments.some(a => parseInt(a.user_id) === currentUser?.id)) { if (typeof openReworkModal === 'function') { actions.push({ label: '🔄 Доработка', handler: () => openReworkModal(taskId),primary_task: true}); @@ -131,7 +141,7 @@ if (typeof openChangeDeadlineModal === 'function') { actions.push({ label: '📅 log('nav-task-actions openChangeDeadlineModal yes'); } else {log('nav-task-actions openChangeDeadlineModal not');} } - + if (currentUser && currentUser.login === 'minicrm') { // Закрытие (только minicrm) //if (window.currentUser && window.currentUser.login === 'minicrm') { diff --git a/public/signature.js b/public/signature.js index d07b296..5ec7ce2 100644 --- a/public/signature.js +++ b/public/signature.js @@ -1,4 +1,4 @@ -// signature.js - Универсальный скрипт для подписания задач +// signature.js - Универсальный скрипт для подписания задач (только логика, без встройки в интерфейс) (function() { 'use strict'; @@ -9,7 +9,7 @@ usersEndpoint: '/api/users', replaceEndpoint: '/api/tasks/${taskId}/replace-assignee', replaceAllEndpoint: '/api/tasks/${taskId}/replace-all-assignees', - taskTypeDocument: 'document' // Тип задачи "Документ" + taskTypeDocument: 'document' }; // Текущий пользователь @@ -24,9 +24,6 @@ const data = await response.json(); if (data.user) { currentUser = data.user; - ////console.log('✅ Signature: текущий пользователь', currentUser); - - // Проверяем, является ли пользователь подписантом await checkIfUserIsSigner(); } return currentUser; @@ -39,19 +36,13 @@ // Проверка, является ли текущий пользователь подписантом async function checkIfUserIsSigner() { if (!currentUser) return false; - try { - // Получаем всех подписантов const signers = await getSigners(); - - // Проверяем, есть ли текущий пользователь в списке подписантов isCurrentUserSigner = signers.some(signer => signer.id === currentUser.id || signer.login === currentUser.login || signer.name === currentUser.name ); - - ////console.log('✅ Signature: пользователь является подписантом?', isCurrentUserSigner); return isCurrentUserSigner; } catch (error) { console.error('❌ Signature: ошибка проверки подписанта', error); @@ -64,7 +55,6 @@ try { const response = await fetch(CONFIG.apiEndpoint); if (!response.ok) return await getSignersFallback(); - const data = await response.json(); const signers = data.filter(user => user.is_active && ( @@ -73,7 +63,6 @@ user.ldap_group?.toLowerCase().includes(CONFIG.signerGroup.toLowerCase()) ) ); - return signers.map(s => ({ id: s.user_id, name: s.user_name || s.login || 'Неизвестно', @@ -99,9 +88,7 @@ // Основная функция подписания window.signTask = async function(taskId, userId) { - // Если userId не передан, используем текущего пользователя const targetUserId = userId || currentUser?.id; - if (!targetUserId) { alert('❌ Не удалось определить текущего пользователя'); return false; @@ -109,7 +96,6 @@ try { const signers = await getSigners(); - if (!signers.length) { alert('❌ Секретари не найдены в системе'); return false; @@ -119,11 +105,9 @@ const msg = signers.length === 1 ? `✍️ Назначить подписанта?\n\n${names}` : `✍️ Назначить подписантов?\n\n${names}`; - if (!confirm(msg)) return false; let response; - if (signers.length > 1) { const url = CONFIG.replaceAllEndpoint.replace('${taskId}', taskId); response = await fetch(url, { @@ -145,16 +129,14 @@ if (response.ok) { alert(`✅ Задача ${signers.length > 1 ? 'назначена подписантам' : 'переназначена подписанту'}`); - // Пробуем перезагрузить задачи разными способами + // Пробуем перезагрузить задачи if (window.TasksType && typeof window.TasksType.loadTasks === 'function') { window.TasksType.loadTasks(); } else if (window.loadTasks && typeof window.loadTasks === 'function') { window.loadTasks(); } else { - // Если нет функций загрузки, просто обновляем страницу setTimeout(() => window.location.reload(), 1500); } - return true; } else { const err = await response.json(); @@ -168,7 +150,7 @@ } }; - // Обновление статуса задачи + // Обновление статуса задачи (может пригодиться) window.updateTaskStatus = async function(taskId, userId, status) { try { const response = await fetch(`/api/tasks/${taskId}/status`, { @@ -176,7 +158,6 @@ headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ userId, status }) }); - if (response.ok) { if (window.TasksType && typeof window.TasksType.loadTasks === 'function') { window.TasksType.loadTasks(); @@ -196,142 +177,10 @@ } }; - // Получение типа задачи из элемента карточки - function getTaskTypeFromCard(card) { - // Ищем элемент с типом задачи - const typeElement = card.querySelector('.task-type-badge, .task-type'); - if (typeElement) { - const classList = typeElement.className; - if (classList.includes('document') || classList.includes('Документ')) { - return 'document'; - } - } - - // Пробуем найти по тексту - const cardText = card.textContent || ''; - if (cardText.includes('Документ') || cardText.includes('document')) { - return 'document'; - } - - return null; - } - - // Функция для добавления кнопок в существующие карточки задач - window.addSignatureButtons = function() { - // Показываем кнопку только если пользователь является подписантом - if (!currentUser || isCurrentUserSigner) return; - - document.querySelectorAll('[data-task-id]').forEach(card => { - // Проверяем, есть ли уже кнопка - if (card.querySelector('.signature-btn')) return; - - // Проверяем тип задачи - только для документов - const taskType = getTaskTypeFromCard(card); - if (taskType !== CONFIG.taskTypeDocument) return; - - const taskId = card.dataset.taskId; - - // Ищем контейнер action-buttons - const actionsContainer = card.querySelector('.action-buttons'); - - if (actionsContainer) { - const btn = document.createElement('button'); - btn.className = 'signature-btn action-btn sign-btn'; - btn.innerHTML = '✍️ Подписать'; - btn.onclick = (e) => { - e.stopPropagation(); - window.signTask(taskId, currentUser.id); - }; - btn.title = 'Передать подписанту'; - actionsContainer.appendChild(btn); - } - }); - }; - - // Наблюдатель за изменениями DOM для динамической добавления кнопок - function observeDOM() { - const observer = new MutationObserver((mutations) => { - mutations.forEach((mutation) => { - if (mutation.addedNodes.length) { - window.addSignatureButtons(); - } - }); - }); - - observer.observe(document.body, { - childList: true, - subtree: true - }); - } - - // Функция для получения отображаемого имени типа задачи - function getTaskTypeDisplayName(type) { - const typeMap = { - 'document': 'Документ', - 'task': 'Задача', - 'bug': 'Ошибка', - 'request': 'Заявка' - }; - return typeMap[type] || type; - } - - // Инициализация при загрузке страницы + // Инициализация: получаем данные текущего пользователя (без добавления кнопок) async function init() { - //console.log('🔄 Signature module initializing...'); - - // Получаем текущего пользователя и проверяем, является ли он подписантом await getCurrentUser(); - - // Добавляем кнопки на существующие карточки только если пользователь подписант - setTimeout(() => { - if (isCurrentUserSigner) { - window.addSignatureButtons(); - } - }, 1000); - - // Запускаем наблюдение за DOM - observeDOM(); - - // Перехватываем функцию рендеринга TasksType если она существует - if (window.TasksType && window.TasksType.renderExpandedContent) { - const originalRender = window.TasksType.renderExpandedContent; - window.TasksType.renderExpandedContent = function(task) { - let html = originalRender ? originalRender(task) : ''; - - // Добавляем кнопку подписания в развернутое содержимое только для документов и если пользователь подписант - if (currentUser && isCurrentUserSigner && task.task_type === CONFIG.taskTypeDocument) { - - // Создаем контейнер action-buttons если его нет - if (!html.includes('action-buttons')) { - const signButton = ` -
- -
- `; - - // Вставляем кнопки после заголовка - html = html.replace('
', - '
' + signButton); - } else { - // Добавляем кнопку в существующий контейнер - const signButton = ` - - `; - - html = html.replace('
', - signButton + '
'); - } - } - - return html; - }; - } - - ////console.log('✅ Signature module loaded. User is signer:', isCurrentUserSigner); + console.log('✅ Signature module loaded (UI integration removed)'); } // Запускаем инициализацию после загрузки DOM