|
@@ -1,4 +1,5 @@
|
|
|
import { ReactiveCache } from '/imports/reactiveCache';
|
|
|
+import dragscroll from '@wekanteam/dragscroll';
|
|
|
const { calculateIndex } = Utils;
|
|
|
|
|
|
function currentListIsInThisSwimlane(swimlaneId) {
|
|
@@ -43,6 +44,20 @@ function currentCardIsInThisList(listId, swimlaneId) {
|
|
|
}
|
|
|
|
|
|
function initSortable(boardComponent, $listsDom) {
|
|
|
+ // Safety check: ensure we have valid DOM elements
|
|
|
+ if (!$listsDom || $listsDom.length === 0) {
|
|
|
+ console.error('initSortable: No valid DOM elements provided');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Check if sortable is already initialized
|
|
|
+ if ($listsDom.data('uiSortable') || $listsDom.data('sortable')) {
|
|
|
+ console.log('initSortable: Sortable already initialized, skipping');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ console.log('initSortable: Initializing sortable for', $listsDom.length, 'elements');
|
|
|
+
|
|
|
// We want to animate the card details window closing. We rely on CSS
|
|
|
// transition for the actual animation.
|
|
|
$listsDom._uihooks = {
|
|
@@ -62,20 +77,74 @@ function initSortable(boardComponent, $listsDom) {
|
|
|
},
|
|
|
};
|
|
|
|
|
|
- $listsDom.sortable({
|
|
|
- connectWith: '.js-swimlane, .js-lists',
|
|
|
- tolerance: 'pointer',
|
|
|
- helper: 'clone',
|
|
|
- items: '.js-list:not(.js-list-composer)',
|
|
|
- placeholder: 'js-list placeholder',
|
|
|
- distance: 7,
|
|
|
+ console.log('Initializing list sortable with', $listsDom.length, 'elements');
|
|
|
+ console.log('Connected elements:', $('.js-swimlane, .js-lists').length);
|
|
|
+ console.log('Available swimlanes:', $('.js-swimlane').map(function() { return $(this).attr('id'); }).get());
|
|
|
+
|
|
|
+ // Add click debugging for drag handles
|
|
|
+ $listsDom.on('mousedown', '.js-list-handle', function(e) {
|
|
|
+ console.log('List drag handle clicked!', e.target);
|
|
|
+ e.stopPropagation();
|
|
|
+ });
|
|
|
+
|
|
|
+ $listsDom.on('mousedown', '.js-list-header', function(e) {
|
|
|
+ console.log('List header clicked!', e.target);
|
|
|
+ });
|
|
|
+
|
|
|
+ // Add debugging for sortable events
|
|
|
+ $listsDom.on('sortstart', function(e, ui) {
|
|
|
+ console.log('Sortable start event fired!', ui.item);
|
|
|
+ });
|
|
|
+
|
|
|
+ $listsDom.on('sortbeforestop', function(e, ui) {
|
|
|
+ console.log('Sortable beforeStop event fired!', ui.item);
|
|
|
+ });
|
|
|
+
|
|
|
+ $listsDom.on('sortstop', function(e, ui) {
|
|
|
+ console.log('Sortable stop event fired!', ui.item);
|
|
|
+ });
|
|
|
+
|
|
|
+ try {
|
|
|
+ $listsDom.sortable({
|
|
|
+ connectWith: '.js-swimlane, .js-lists',
|
|
|
+ tolerance: 'pointer',
|
|
|
+ appendTo: '.board-canvas',
|
|
|
+ helper(evt, item) {
|
|
|
+ const helper = item.clone();
|
|
|
+ helper.css('z-index', 1000);
|
|
|
+ return helper;
|
|
|
+ },
|
|
|
+ items: '.js-list:not(.js-list-composer)',
|
|
|
+ placeholder: 'list placeholder',
|
|
|
+ distance: 3,
|
|
|
+ forcePlaceholderSize: true,
|
|
|
+ cursor: 'move',
|
|
|
start(evt, ui) {
|
|
|
+ console.log('List drag started');
|
|
|
+ ui.helper.css('z-index', 1000);
|
|
|
ui.placeholder.height(ui.helper.height());
|
|
|
ui.placeholder.width(ui.helper.width());
|
|
|
EscapeActions.executeUpTo('popup-close');
|
|
|
boardComponent.setIsDragging(true);
|
|
|
+
|
|
|
+ // Add visual feedback for list being dragged
|
|
|
+ ui.item.addClass('ui-sortable-helper');
|
|
|
+
|
|
|
+ // Disable dragscroll during list dragging to prevent interference
|
|
|
+ console.log('Disabling dragscroll for list dragging');
|
|
|
+ dragscroll.reset();
|
|
|
+
|
|
|
+ // Also disable dragscroll on all swimlanes during list dragging
|
|
|
+ $('.js-swimlane').each(function() {
|
|
|
+ $(this).removeClass('dragscroll');
|
|
|
+ });
|
|
|
+ },
|
|
|
+ beforeStop(evt, ui) {
|
|
|
+ // Clean up visual feedback
|
|
|
+ ui.item.removeClass('ui-sortable-helper');
|
|
|
},
|
|
|
stop(evt, ui) {
|
|
|
+ console.log('List drag stopped');
|
|
|
// To attribute the new index number, we need to get the DOM element
|
|
|
// of the previous and the following card -- if any.
|
|
|
const prevListDom = ui.item.prev('.js-list').get(0);
|
|
@@ -83,15 +152,39 @@ function initSortable(boardComponent, $listsDom) {
|
|
|
const sortIndex = calculateIndex(prevListDom, nextListDom, 1);
|
|
|
|
|
|
const listDomElement = ui.item.get(0);
|
|
|
- const list = Blaze.getData(listDomElement);
|
|
|
+ if (!listDomElement) {
|
|
|
+ console.error('List DOM element not found during drag stop');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ let list;
|
|
|
+ try {
|
|
|
+ list = Blaze.getData(listDomElement);
|
|
|
+ } catch (error) {
|
|
|
+ console.error('Error getting list data:', error);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!list) {
|
|
|
+ console.error('List data not found for element:', listDomElement);
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
// Detect if the list was dropped in a different swimlane
|
|
|
const targetSwimlaneDom = ui.item.closest('.js-swimlane');
|
|
|
let targetSwimlaneId = null;
|
|
|
|
|
|
+ console.log('Target swimlane DOM:', targetSwimlaneDom.length, targetSwimlaneDom.attr('id'));
|
|
|
+
|
|
|
if (targetSwimlaneDom.length > 0) {
|
|
|
// List was dropped in a swimlane
|
|
|
- targetSwimlaneId = targetSwimlaneDom.attr('id').replace('swimlane-', '');
|
|
|
+ try {
|
|
|
+ targetSwimlaneId = targetSwimlaneDom.attr('id').replace('swimlane-', '');
|
|
|
+ console.log('List dropped in swimlane:', targetSwimlaneId);
|
|
|
+ } catch (error) {
|
|
|
+ console.error('Error getting target swimlane ID:', error);
|
|
|
+ return;
|
|
|
+ }
|
|
|
} else {
|
|
|
// List was dropped in lists view (not swimlanes view)
|
|
|
// In this case, assign to the default swimlane
|
|
@@ -100,6 +193,7 @@ function initSortable(boardComponent, $listsDom) {
|
|
|
const defaultSwimlane = currentBoard.getDefaultSwimline();
|
|
|
if (defaultSwimlane) {
|
|
|
targetSwimlaneId = defaultSwimlane._id;
|
|
|
+ console.log('List dropped in lists view, using default swimlane:', targetSwimlaneId);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -123,6 +217,11 @@ function initSortable(boardComponent, $listsDom) {
|
|
|
|
|
|
// Check if the list was dropped in a different swimlane
|
|
|
const isDifferentSwimlane = targetSwimlaneId && targetSwimlaneId !== originalSwimlaneId;
|
|
|
+ console.log('Cross-swimlane check:', {
|
|
|
+ originalSwimlaneId,
|
|
|
+ targetSwimlaneId,
|
|
|
+ isDifferentSwimlane
|
|
|
+ });
|
|
|
|
|
|
// If the list was dropped in a different swimlane, update the swimlaneId
|
|
|
if (isDifferentSwimlane) {
|
|
@@ -152,34 +251,63 @@ function initSortable(boardComponent, $listsDom) {
|
|
|
$listsDom.sortable('cancel');
|
|
|
}
|
|
|
|
|
|
- Lists.update(list._id, {
|
|
|
- $set: updateData,
|
|
|
- });
|
|
|
+ try {
|
|
|
+ Lists.update(list._id, {
|
|
|
+ $set: updateData,
|
|
|
+ });
|
|
|
+ console.log('List updated successfully:', list._id, updateData);
|
|
|
+ } catch (error) {
|
|
|
+ console.error('Error updating list:', error);
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
boardComponent.setIsDragging(false);
|
|
|
+
|
|
|
+ // Re-enable dragscroll after list dragging is complete
|
|
|
+ console.log('Re-enabling dragscroll after list dragging');
|
|
|
+ dragscroll.reset();
|
|
|
+
|
|
|
+ // Re-enable dragscroll on all swimlanes
|
|
|
+ $('.js-swimlane').each(function() {
|
|
|
+ $(this).addClass('dragscroll');
|
|
|
+ });
|
|
|
},
|
|
|
});
|
|
|
+ } catch (error) {
|
|
|
+ console.error('Error initializing list sortable:', error);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ console.log('List sortable initialization completed successfully');
|
|
|
+ console.log('Sortable data after init:', $listsDom.data('uiSortable') || $listsDom.data('sortable'));
|
|
|
|
|
|
boardComponent.autorun(() => {
|
|
|
- if (Utils.isTouchScreenOrShowDesktopDragHandles()) {
|
|
|
- $listsDom.sortable({
|
|
|
- handle: '.js-list-handle',
|
|
|
- connectWith: '.js-swimlane, .js-lists',
|
|
|
- });
|
|
|
- } else {
|
|
|
- $listsDom.sortable({
|
|
|
- handle: '.js-list-header',
|
|
|
- connectWith: '.js-swimlane, .js-lists',
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
const $listDom = $listsDom;
|
|
|
+ console.log('Autorun running, checking sortable status...');
|
|
|
+ console.log('Has uiSortable:', $listDom.data('uiSortable'));
|
|
|
+ console.log('Has sortable:', $listDom.data('sortable'));
|
|
|
if ($listDom.data('uiSortable') || $listDom.data('sortable')) {
|
|
|
- $listsDom.sortable(
|
|
|
- 'option',
|
|
|
- 'disabled',
|
|
|
- !ReactiveCache.getCurrentUser()?.isBoardAdmin(),
|
|
|
- );
|
|
|
+ if (Utils.isTouchScreenOrShowDesktopDragHandles()) {
|
|
|
+ $listsDom.sortable('option', 'handle', '.js-list-handle');
|
|
|
+ console.log('List sortable: Using .js-list-handle as handle');
|
|
|
+ console.log('Found drag handles:', $listsDom.find('.js-list-handle').length);
|
|
|
+ } else {
|
|
|
+ $listsDom.sortable('option', 'handle', '.js-list-header');
|
|
|
+ console.log('List sortable: Using .js-list-header as handle');
|
|
|
+ console.log('Found list headers:', $listsDom.find('.js-list-header').length);
|
|
|
+ }
|
|
|
+
|
|
|
+ const currentUser = ReactiveCache.getCurrentUser();
|
|
|
+ const canModify = Utils.canModifyBoard();
|
|
|
+ const isDisabled = !canModify;
|
|
|
+ $listsDom.sortable('option', 'disabled', isDisabled);
|
|
|
+ console.log('List sortable disabled:', isDisabled);
|
|
|
+ console.log('Can modify board:', canModify);
|
|
|
+ console.log('Current user:', currentUser ? currentUser.username : 'null');
|
|
|
+ console.log('Is board member:', currentUser ? currentUser.isBoardMember() : 'null');
|
|
|
+ console.log('Is comment only:', currentUser ? currentUser.isCommentOnly() : 'null');
|
|
|
+ } else {
|
|
|
+ console.log('List sortable not initialized yet');
|
|
|
}
|
|
|
});
|
|
|
}
|
|
@@ -188,11 +316,15 @@ BlazeComponent.extendComponent({
|
|
|
onRendered() {
|
|
|
const boardComponent = this.parentComponent();
|
|
|
const $listsDom = this.$('.js-lists');
|
|
|
+
|
|
|
+ console.log('Swimlane onRendered - DOM elements found:', $listsDom.length);
|
|
|
+ console.log('Swimlane onRendered - DOM element:', $listsDom[0]);
|
|
|
|
|
|
if (!Utils.getCurrentCardId()) {
|
|
|
boardComponent.scrollLeft();
|
|
|
}
|
|
|
|
|
|
+ console.log('Calling initSortable...');
|
|
|
initSortable(boardComponent, $listsDom);
|
|
|
},
|
|
|
onCreated() {
|
|
@@ -538,11 +670,15 @@ BlazeComponent.extendComponent({
|
|
|
onRendered() {
|
|
|
const boardComponent = this.parentComponent();
|
|
|
const $listsDom = this.$('.js-lists');
|
|
|
+
|
|
|
+ console.log('ListsGroup onRendered - DOM elements found:', $listsDom.length);
|
|
|
+ console.log('ListsGroup onRendered - DOM element:', $listsDom[0]);
|
|
|
|
|
|
if (!Utils.getCurrentCardId()) {
|
|
|
boardComponent.scrollLeft();
|
|
|
}
|
|
|
|
|
|
+ console.log('ListsGroup calling initSortable...');
|
|
|
initSortable(boardComponent, $listsDom);
|
|
|
},
|
|
|
}).register('listsGroup');
|