some fixes
This commit is contained in:
parent
725c62a179
commit
9b8d10bbfa
|
|
@ -391,8 +391,8 @@ class DealsController extends BaseController
|
||||||
$organizationId = $this->requireActiveOrg();
|
$organizationId = $this->requireActiveOrg();
|
||||||
$userId = $this->getCurrentUserId();
|
$userId = $this->getCurrentUserId();
|
||||||
|
|
||||||
$dealId = $this->request->getPost('deal_id');
|
$dealId = $this->request->getPost('id');
|
||||||
$newStageId = $this->request->getPost('stage_id');
|
$newStageId = $this->request->getPost('column_id');
|
||||||
|
|
||||||
$deal = $this->dealService->getDealWithJoins($dealId, $organizationId);
|
$deal = $this->dealService->getDealWithJoins($dealId, $organizationId);
|
||||||
if (!$deal) {
|
if (!$deal) {
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,10 @@
|
||||||
style="cursor: grab;">
|
style="cursor: grab;">
|
||||||
<div class="card-body py-2 px-3">
|
<div class="card-body py-2 px-3">
|
||||||
<div class="d-flex justify-content-between align-items-start mb-2">
|
<div class="d-flex justify-content-between align-items-start mb-2">
|
||||||
<a href="{{ site_url('/crm/deals/' ~ item.id) }}" class="text-decoration-none">
|
<a href="{{ site_url('/crm/deals/' ~ item.id) }}" class="text-decoration-none flex-grow-1">
|
||||||
<strong class="text-dark">{{ item.title }}</strong>
|
<strong class="text-dark">{{ item.title }}</strong>
|
||||||
</a>
|
</a>
|
||||||
<span class="badge bg-light text-dark">
|
<span class="badge bg-light text-dark ms-2">
|
||||||
₽{{ item.amount|number_format(0, ',', ' ') }}
|
₽{{ item.amount|number_format(0, ',', ' ') }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -35,11 +35,19 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if item.expected_close_date %}
|
{% if item.expected_close_date %}
|
||||||
<small class="{{ item.expected_close_date < date('today') ? 'text-danger' : 'text-muted' }}">
|
<small class="{{ item.expected_close_date < date('today') ? 'text-danger fw-bold' : 'text-muted' }}">
|
||||||
<i class="fa-regular fa-calendar me-1"></i>
|
<i class="fa-regular fa-calendar me-1"></i>
|
||||||
{{ item.expected_close_date|date('d.m') }}
|
{{ item.expected_close_date|date('d.m') }}
|
||||||
|
{% if item.expected_close_date < date('today') %}
|
||||||
|
<i class="fa-solid fa-circle-exclamation ms-1" style="font-size: 0.6rem;" title="Просрочено"></i>
|
||||||
|
{% endif %}
|
||||||
</small>
|
</small>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
{# Кнопка просмотра #}
|
||||||
|
<a href="{{ site_url('/crm/deals/' ~ item.id) }}" class="btn btn-sm btn-outline-primary ms-2" title="Просмотр">
|
||||||
|
<i class="fa-solid fa-eye"></i>
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -399,7 +399,7 @@ class TasksController extends BaseController
|
||||||
$organizationId = $this->requireActiveOrg();
|
$organizationId = $this->requireActiveOrg();
|
||||||
$userId = $this->getCurrentUserId();
|
$userId = $this->getCurrentUserId();
|
||||||
|
|
||||||
$taskId = $this->request->getPost('task_id');
|
$taskId = $this->request->getPost('id');
|
||||||
$newColumnId = $this->request->getPost('column_id');
|
$newColumnId = $this->request->getPost('column_id');
|
||||||
|
|
||||||
$result = $this->taskService->changeColumn($taskId, $newColumnId, $userId);
|
$result = $this->taskService->changeColumn($taskId, $newColumnId, $userId);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
{#
|
||||||
|
task_card.twig - Карточка задачи для Канбан-компонента
|
||||||
|
|
||||||
|
Параметры:
|
||||||
|
- item: Объект задачи
|
||||||
|
- column: Объект колонки (для доступа к color и т.д.)
|
||||||
|
#}
|
||||||
|
<div class="card mb-2 kanban-card {{ item.completed_at ? 'opacity-75' : '' }}"
|
||||||
|
draggable="true"
|
||||||
|
data-item-id="{{ item.id }}"
|
||||||
|
style="cursor: grab;">
|
||||||
|
<div class="card-body py-2 px-3">
|
||||||
|
{# Заголовок #}
|
||||||
|
<div class="d-flex justify-content-between align-items-start mb-2">
|
||||||
|
<a href="{{ base_url('/tasks/' ~ item.id) }}" class="text-decoration-none flex-grow-1">
|
||||||
|
<strong class="text-dark">{{ item.title }}</strong>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
{# Индикатор приоритета #}
|
||||||
|
{% if item.priority == 'urgent' %}
|
||||||
|
<span class="badge bg-danger ms-2" style="font-size: 0.6rem;">Срочно</span>
|
||||||
|
{% elseif item.priority == 'high' %}
|
||||||
|
<span class="badge bg-warning text-dark ms-2" style="font-size: 0.6rem;">Высокий</span>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{# Описание #}
|
||||||
|
{% if item.description is defined and item.description %}
|
||||||
|
<small class="text-muted d-block mb-2">
|
||||||
|
{{ item.description|length > 50 ? item.description|slice(0, 50) ~ '...' : item.description }}
|
||||||
|
</small>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{# Нижняя панель #}
|
||||||
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
|
{# Дата и статус просроченности #}
|
||||||
|
{% if item.due_date is defined and item.due_date %}
|
||||||
|
{% set isOverdue = item.due_date < date('now') and not item.completed_at %}
|
||||||
|
<small class="{{ isOverdue ? 'text-danger fw-bold' : (item.completed_at ? 'text-success' : 'text-muted') }}">
|
||||||
|
<i class="fa-regular fa-calendar me-1"></i>
|
||||||
|
{{ item.due_date|date('d.m') }}
|
||||||
|
{% if item.completed_at %}
|
||||||
|
<i class="fa-solid fa-check ms-1" style="font-size: 0.7rem;"></i>
|
||||||
|
{% elseif isOverdue %}
|
||||||
|
<i class="fa-solid fa-circle-exclamation ms-1" style="font-size: 0.6rem;" title="Просрочено"></i>
|
||||||
|
{% endif %}
|
||||||
|
</small>
|
||||||
|
{% else %}
|
||||||
|
<small></small>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{# Кнопка просмотра #}
|
||||||
|
<a href="{{ base_url('/tasks/' ~ item.id) }}" class="btn btn-sm btn-outline-primary" title="Просмотр">
|
||||||
|
<i class="fa-solid fa-eye"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
{#
|
||||||
|
task_event.twig - Событие задачи для Календарь-компонента
|
||||||
|
|
||||||
|
Параметры:
|
||||||
|
- event: Объект задачи
|
||||||
|
- onEventClick: JavaScript функция при клике (опционально)
|
||||||
|
#}
|
||||||
|
{% set isOverdue = event.due_date is defined and event.due_date < date('now') and not event.completed_at %}
|
||||||
|
<a href="{{ event.url|default('/tasks/' ~ event.id) }}"
|
||||||
|
class="calendar-event {{ isOverdue ? 'border-danger text-danger' : '' }}"
|
||||||
|
style="border-left-color: {{ event.color|default(event.column_color|default('#6B7280')) }};"
|
||||||
|
{% if onEventClick %}onclick="{{ onEventClick }}({{ event.id }}); return false;"{% endif %}>
|
||||||
|
{% if event.priority in ['urgent', 'high'] %}
|
||||||
|
<i class="fa-solid fa-flag me-1" style="color: {{ event.priority == 'urgent' ? '#dc3545' : '#ffc107' }};"></i>
|
||||||
|
{% endif %}
|
||||||
|
{{ event.title }}
|
||||||
|
</a>
|
||||||
|
|
@ -51,120 +51,18 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card border-0 shadow-sm">
|
{# Календарь - универсальный компонент #}
|
||||||
<div class="card-header bg-white d-flex justify-content-between align-items-center">
|
{{ include('@components/calendar/calendar.twig', {
|
||||||
<div class="btn-group">
|
eventsByDate: eventsByDate,
|
||||||
<a href="{{ base_url('/tasks/calendar?month=' ~ prevMonth) }}" class="btn btn-outline-secondary btn-sm">
|
currentMonth: currentMonth,
|
||||||
<i class="fa-solid fa-chevron-left"></i>
|
monthName: monthName,
|
||||||
</a>
|
daysInMonth: daysInMonth,
|
||||||
<a href="{{ base_url('/tasks/calendar?month=' ~ nextMonth) }}" class="btn btn-outline-secondary btn-sm">
|
firstDayOfWeek: firstDayOfWeek,
|
||||||
<i class="fa-solid fa-chevron-right"></i>
|
prevMonth: base_url('/tasks/calendar?month=' ~ prevMonth),
|
||||||
</a>
|
nextMonth: base_url('/tasks/calendar?month=' ~ nextMonth),
|
||||||
</div>
|
today: today,
|
||||||
<h5 class="mb-0">{{ monthName }}</h5>
|
showNavigation: true,
|
||||||
<a href="{{ base_url('/tasks/calendar') }}" class="btn btn-outline-secondary btn-sm">
|
showLegend: false,
|
||||||
Сегодня
|
eventComponent: '@Tasks/components/task_event.twig'
|
||||||
</a>
|
}) }}
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="calendar-container">
|
|
||||||
{# Дни недели #}
|
|
||||||
<div class="calendar-weekdays mb-2">
|
|
||||||
{% for day in ['Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб', 'Вс'] %}
|
|
||||||
<div class="calendar-weekday text-center text-muted fw-bold" style="flex: 1;">{{ day }}</div>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{# Календарная сетка #}
|
|
||||||
<div class="calendar-grid">
|
|
||||||
{% set firstDay = firstDayOfWeek %}
|
|
||||||
{% set daysInMonth = daysInMonth %}
|
|
||||||
|
|
||||||
{# Пустые ячейки до первого дня #}
|
|
||||||
{% for i in 0..(firstDay - 1) %}
|
|
||||||
<div class="calendar-day p-2 border bg-light"></div>
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
{# Дни месяца #}
|
|
||||||
{% for day in 1..daysInMonth %}
|
|
||||||
{% set dateStr = currentMonth ~ '-' ~ (day < 10 ? '0' ~ day : day) %}
|
|
||||||
{% set isToday = dateStr == today %}
|
|
||||||
{% set isPast = dateStr < today %}
|
|
||||||
{% set dayEvents = eventsByDate[dateStr]|default([]) %}
|
|
||||||
|
|
||||||
<div class="calendar-day p-2 border {% if isToday %}bg-primary bg-opacity-10{% endif %}">
|
|
||||||
<div class="d-flex justify-content-between align-items-start mb-1">
|
|
||||||
<span class="calendar-day-number fw-bold {% if isToday %}text-primary{% endif %}">{{ day }}</span>
|
|
||||||
{% if dayEvents|length > 0 %}
|
|
||||||
<span class="badge bg-primary" style="font-size: 0.6rem;">{{ dayEvents|length }}</span>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="calendar-events">
|
|
||||||
{% for event in dayEvents|slice(0, 3) %}
|
|
||||||
<a href="{{ base_url(event.url) }}"
|
|
||||||
class="calendar-event d-block text-decoration-none mb-1 px-1 py-1 rounded small"
|
|
||||||
style="font-size: 0.75rem; background-color: {{ event.column_color }}20; border-left: 3px solid {{ event.column_color }}; color: #333;"
|
|
||||||
title="{{ event.title }}">
|
|
||||||
<i class="fa-solid fa-circle me-1" style="font-size: 0.5rem; color: {{ event.column_color }};"></i>
|
|
||||||
{{ event.title|length > 15 ? event.title|slice(0, 15) ~ '...' : event.title }}
|
|
||||||
{% if event.priority == 'urgent' or event.priority == 'high' %}
|
|
||||||
<i class="fa-solid fa-flag text-danger ms-1" style="font-size: 0.5rem;"></i>
|
|
||||||
{% endif %}
|
|
||||||
</a>
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
{% if dayEvents|length > 3 %}
|
|
||||||
<div class="text-muted small text-center">
|
|
||||||
+{{ dayEvents|length - 3 }} ещё
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
{# Пустые ячейки после последнего дня #}
|
|
||||||
{% set remaining = 7 - ((firstDay + daysInMonth) % 7) %}
|
|
||||||
{% if remaining < 7 %}
|
|
||||||
{% for i in 1..remaining %}
|
|
||||||
<div class="calendar-day p-2 border bg-light"></div>
|
|
||||||
{% endfor %}
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.calendar-grid {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(7, 1fr);
|
|
||||||
gap: 1px;
|
|
||||||
background-color: #dee2e6;
|
|
||||||
border: 1px solid #dee2e6;
|
|
||||||
}
|
|
||||||
|
|
||||||
.calendar-day {
|
|
||||||
min-height: 100px;
|
|
||||||
background-color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.calendar-day.bg-light {
|
|
||||||
background-color: #f8f9fa;
|
|
||||||
}
|
|
||||||
|
|
||||||
.calendar-event:hover {
|
|
||||||
background-color: {{ event.column_color }}40 !important;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block scripts %}
|
|
||||||
<script>
|
|
||||||
// Навигация по месяцам при клике на заголовок
|
|
||||||
document.querySelector('h5.mb-0').style.cursor = 'pointer';
|
|
||||||
document.querySelector('h5.mb-0').addEventListener('click', function() {
|
|
||||||
window.location.href = '{{ base_url('/tasks/calendar') }}';
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
||||||
|
|
@ -63,10 +63,33 @@
|
||||||
<div class="card border-0 shadow-sm">
|
<div class="card border-0 shadow-sm">
|
||||||
<div class="card-body p-0">
|
<div class="card-body p-0">
|
||||||
{{ tableHtml|raw }}
|
{{ tableHtml|raw }}
|
||||||
|
{# CSRF токен для AJAX запросов #}
|
||||||
|
{{ csrf_field()|raw }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block scripts %}
|
{% block scripts %}
|
||||||
<script src="{{ base_url('assets/js/modules/DataTable.js') }}"></script>
|
<script src="{{ base_url('assets/js/modules/DataTable.js') }}"></script>
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
document.querySelectorAll('.data-table').forEach(function(container) {
|
||||||
|
const id = container.id;
|
||||||
|
const url = container.dataset.url;
|
||||||
|
const perPage = parseInt(container.dataset.perPage) || 10;
|
||||||
|
|
||||||
|
if (window.dataTables && window.dataTables[id]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const table = new DataTable(id, {
|
||||||
|
url: url,
|
||||||
|
perPage: perPage
|
||||||
|
});
|
||||||
|
|
||||||
|
window.dataTables = window.dataTables || {};
|
||||||
|
window.dataTables[id] = table;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
||||||
|
|
@ -64,136 +64,13 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{# Канбан доска #}
|
{{ csrf_field()|raw }}
|
||||||
<div class="kanban-container" style="overflow-x: auto; padding-bottom: 1rem;">
|
{# Канбан доска - универсальный компонент #}
|
||||||
<div class="d-flex gap-3" style="min-width: max-content;">
|
{{ include('@components/kanban/kanban.twig', {
|
||||||
{% for column in kanbanColumns %}
|
columns: kanbanColumns,
|
||||||
<div class="kanban-column" style="width: 320px; min-width: 320px;">
|
cardComponent: '@Tasks/components/task_card.twig',
|
||||||
<div class="card border-0 shadow-sm">
|
moveUrl: base_url('/tasks/move-column'),
|
||||||
<div class="card-header d-flex justify-content-between align-items-center" style="background-color: {{ column.color }}; color: white;">
|
addUrl: base_url('/tasks/new'),
|
||||||
<h6 class="mb-0 fw-bold">{{ column.name }}</h6>
|
addLabel: 'Добавить задачу'
|
||||||
<span class="badge bg-light text-dark">{{ column.items|length }}</span>
|
}) }}
|
||||||
</div>
|
|
||||||
<div class="card-body p-2 kanban-items" data-column-id="{{ column.id }}"
|
|
||||||
style="min-height: 400px; max-height: 600px; overflow-y: auto;">
|
|
||||||
|
|
||||||
{% for item in column.items %}
|
|
||||||
<div class="card mb-2 kanban-item" data-task-id="{{ item.id }}" style="cursor: grab;">
|
|
||||||
<div class="card-body p-3">
|
|
||||||
<div class="d-flex justify-content-between align-items-start mb-2">
|
|
||||||
<h6 class="card-title mb-0">{{ item.title }}</h6>
|
|
||||||
{% if item.priority == 'urgent' %}
|
|
||||||
<span class="badge bg-danger" style="font-size: 0.6rem;">Срочно</span>
|
|
||||||
{% elseif item.priority == 'high' %}
|
|
||||||
<span class="badge bg-warning text-dark" style="font-size: 0.6rem;">Высокий</span>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% if item.description %}
|
|
||||||
<p class="card-text text-muted small mb-2">
|
|
||||||
{{ item.description|length > 50 ? item.description|slice(0, 50) ~ '...' : item.description }}
|
|
||||||
</p>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<div class="d-flex justify-content-between align-items-center">
|
|
||||||
{% if item.due_date %}
|
|
||||||
<small class="text-muted">
|
|
||||||
<i class="fa-regular fa-calendar me-1"></i>
|
|
||||||
{{ item.due_date|date('d.m') }}
|
|
||||||
{% if item.due_date < date('Y-m-d') %}
|
|
||||||
<span class="text-danger">!</span>
|
|
||||||
{% endif %}
|
|
||||||
</small>
|
|
||||||
{% endif %}
|
|
||||||
<a href="{{ base_url('/tasks/' ~ item.id) }}" class="btn btn-sm btn-outline-primary">
|
|
||||||
<i class="fa-solid fa-arrow-right"></i>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
{# Кнопка добавления #}
|
|
||||||
<a href="{{ base_url('/tasks/new?board=' ~ board.id ~ '&column=' ~ column.id) }}" class="btn btn-outline-secondary btn-sm w-100 mt-2">
|
|
||||||
<i class="fa-solid fa-plus me-1"></i>Добавить задачу
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<form id="move-task-form" action="{{ base_url('/tasks/move-column') }}" method="post" style="display: none;">
|
|
||||||
{{ csrf_field|raw }}
|
|
||||||
<input type="hidden" name="task_id" id="move-task-id">
|
|
||||||
<input type="hidden" name="column_id" id="move-column-id">
|
|
||||||
</form>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block scripts %}
|
|
||||||
<script>
|
|
||||||
// Drag and drop для Канбана
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
|
||||||
const columns = document.querySelectorAll('.kanban-items');
|
|
||||||
let draggedItem = null;
|
|
||||||
|
|
||||||
columns.forEach(column => {
|
|
||||||
column.addEventListener('dragover', function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
this.style.backgroundColor = '#f8f9fa';
|
|
||||||
});
|
|
||||||
|
|
||||||
column.addEventListener('dragleave', function() {
|
|
||||||
this.style.backgroundColor = '';
|
|
||||||
});
|
|
||||||
|
|
||||||
column.addEventListener('drop', function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
this.style.backgroundColor = '';
|
|
||||||
|
|
||||||
if (draggedItem && draggedItem.dataset.taskId) {
|
|
||||||
const taskId = draggedItem.dataset.taskId;
|
|
||||||
const newColumnId = this.dataset.columnId;
|
|
||||||
|
|
||||||
// Отправляем запрос на перемещение
|
|
||||||
document.getElementById('move-task-id').value = taskId;
|
|
||||||
document.getElementById('move-column-id').value = newColumnId;
|
|
||||||
|
|
||||||
fetch('{{ base_url('/tasks/move-column') }}', {
|
|
||||||
method: 'POST',
|
|
||||||
body: new FormData(document.getElementById('move-task-form'))
|
|
||||||
})
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(data => {
|
|
||||||
if (data.success) {
|
|
||||||
// Перезагружаем страницу для обновления
|
|
||||||
location.reload();
|
|
||||||
} else {
|
|
||||||
alert('Ошибка при перемещении задачи');
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.error('Error:', error);
|
|
||||||
alert('Ошибка при перемещении задачи');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
draggedItem = null;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
document.querySelectorAll('.kanban-item').forEach(item => {
|
|
||||||
item.addEventListener('dragstart', function() {
|
|
||||||
draggedItem = this;
|
|
||||||
this.style.opacity = '0.5';
|
|
||||||
});
|
|
||||||
|
|
||||||
item.addEventListener('dragend', function() {
|
|
||||||
this.style.opacity = '1';
|
|
||||||
draggedItem = null;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
||||||
|
|
@ -131,7 +131,7 @@ function handleDrop(e) {
|
||||||
|
|
||||||
if (itemId && newColumnId) {
|
if (itemId && newColumnId) {
|
||||||
if (moveUrl) {
|
if (moveUrl) {
|
||||||
console.log('Moving deal:', itemId, 'to stage:', newColumnId);
|
console.log('Moving item:', itemId, 'to column:', newColumnId);
|
||||||
|
|
||||||
// Находим перетаскиваемую карточку
|
// Находим перетаскиваемую карточку
|
||||||
const draggedCard = document.querySelector(`.kanban-card[data-item-id="${itemId}"]`);
|
const draggedCard = document.querySelector(`.kanban-card[data-item-id="${itemId}"]`);
|
||||||
|
|
@ -145,7 +145,7 @@ function handleDrop(e) {
|
||||||
'Content-Type': 'application/x-www-form-urlencoded',
|
'Content-Type': 'application/x-www-form-urlencoded',
|
||||||
'X-Requested-With': 'XMLHttpRequest'
|
'X-Requested-With': 'XMLHttpRequest'
|
||||||
},
|
},
|
||||||
body: 'deal_id=' + itemId + '&stage_id=' + newColumnId
|
body: 'id=' + itemId + '&column_id=' + newColumnId
|
||||||
})
|
})
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue