mirror of
https://github.com/wekan/wekan.git
synced 2025-12-16 15:30:13 +01:00
Drag handles. In progress.
This commit is contained in:
parent
21fa26a1be
commit
5bc355f9a5
9 changed files with 133 additions and 73 deletions
|
|
@ -89,7 +89,7 @@ BlazeComponent.extendComponent({
|
||||||
helper.append(list.clone());
|
helper.append(list.clone());
|
||||||
return helper;
|
return helper;
|
||||||
},
|
},
|
||||||
handle: '.js-swimlane-header-handle',
|
handle: '.js-swimlane-header',
|
||||||
items: '.swimlane:not(.placeholder)',
|
items: '.swimlane:not(.placeholder)',
|
||||||
placeholder: 'swimlane placeholder',
|
placeholder: 'swimlane placeholder',
|
||||||
distance: 7,
|
distance: 7,
|
||||||
|
|
|
||||||
|
|
@ -165,8 +165,7 @@ BlazeComponent.extendComponent({
|
||||||
$checklistsDom.sortable({
|
$checklistsDom.sortable({
|
||||||
tolerance: 'pointer',
|
tolerance: 'pointer',
|
||||||
helper: 'clone',
|
helper: 'clone',
|
||||||
//handle: '.checklist-title',
|
handle: '.checklist-title',
|
||||||
handle: '.checklist-item-handle',
|
|
||||||
items: '.js-checklist',
|
items: '.js-checklist',
|
||||||
placeholder: 'checklist placeholder',
|
placeholder: 'checklist placeholder',
|
||||||
distance: 7,
|
distance: 7,
|
||||||
|
|
|
||||||
|
|
@ -31,11 +31,19 @@ template(name="checklistDetail")
|
||||||
h2.title.js-open-inlined-form.is-editable
|
h2.title.js-open-inlined-form.is-editable
|
||||||
+viewer
|
+viewer
|
||||||
= checklist.title
|
= checklist.title
|
||||||
|
if isMiniScreen
|
||||||
|
a.checklist-handle.handle.fa.fa-arrows.js-checklist-handle
|
||||||
|
unless isMiniScreen
|
||||||
|
if showDesktopDragHandles
|
||||||
a.checklist-handle.handle.fa.fa-arrows.js-checklist-handle
|
a.checklist-handle.handle.fa.fa-arrows.js-checklist-handle
|
||||||
else
|
else
|
||||||
h2.title
|
h2.title
|
||||||
+viewer
|
+viewer
|
||||||
= checklist.title
|
= checklist.title
|
||||||
|
if isMiniScreen
|
||||||
|
a.checklist-handle.handle.fa.fa-arrows.js-checklist-handle
|
||||||
|
unless isMiniScreen
|
||||||
|
if showDesktopDragHandles
|
||||||
a.checklist-handle.handle.fa.fa-arrows.js-checklist-handle
|
a.checklist-handle.handle.fa.fa-arrows.js-checklist-handle
|
||||||
+checklistItems(checklist = checklist)
|
+checklistItems(checklist = checklist)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,11 @@ function initSorting(items) {
|
||||||
items.sortable({
|
items.sortable({
|
||||||
tolerance: 'pointer',
|
tolerance: 'pointer',
|
||||||
helper: 'clone',
|
helper: 'clone',
|
||||||
items: '.js-checklist-item-handle:not(.placeholder)',
|
items: '.js-checklist-item:not(.placeholder)',
|
||||||
connectWith: '.js-checklist-items',
|
connectWith: '.js-checklist-items',
|
||||||
appendTo: '.board-canvas',
|
appendTo: '.board-canvas',
|
||||||
distance: 7,
|
distance: 7,
|
||||||
placeholder: 'checklist-item-handle placeholder',
|
placeholder: 'checklist-item placeholder',
|
||||||
scroll: false,
|
scroll: false,
|
||||||
start(evt, ui) {
|
start(evt, ui) {
|
||||||
ui.placeholder.height(ui.helper.height());
|
ui.placeholder.height(ui.helper.height());
|
||||||
|
|
@ -17,11 +17,11 @@ function initSorting(items) {
|
||||||
stop(evt, ui) {
|
stop(evt, ui) {
|
||||||
const parent = ui.item.parents('.js-checklist-items');
|
const parent = ui.item.parents('.js-checklist-items');
|
||||||
const checklistId = Blaze.getData(parent.get(0)).checklist._id;
|
const checklistId = Blaze.getData(parent.get(0)).checklist._id;
|
||||||
let prevItem = ui.item.prev('.js-checklist-item-handle').get(0);
|
let prevItem = ui.item.prev('.js-checklist-item').get(0);
|
||||||
if (prevItem) {
|
if (prevItem) {
|
||||||
prevItem = Blaze.getData(prevItem).item;
|
prevItem = Blaze.getData(prevItem).item;
|
||||||
}
|
}
|
||||||
let nextItem = ui.item.next('.js-checklist-item-handle').get(0);
|
let nextItem = ui.item.next('.js-checklist-item').get(0);
|
||||||
if (nextItem) {
|
if (nextItem) {
|
||||||
nextItem = Blaze.getData(nextItem).item;
|
nextItem = Blaze.getData(nextItem).item;
|
||||||
}
|
}
|
||||||
|
|
@ -38,7 +38,8 @@ function initSorting(items) {
|
||||||
});
|
});
|
||||||
|
|
||||||
// ugly touch event hotfix
|
// ugly touch event hotfix
|
||||||
enableClickOnTouch('.js-checklist-item-handle:not(.placeholder)');
|
enableClickOnTouch('.js-checklist-item:not(.placeholder)');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BlazeComponent.extendComponent({
|
BlazeComponent.extendComponent({
|
||||||
|
|
@ -60,6 +61,30 @@ BlazeComponent.extendComponent({
|
||||||
if ($itemsDom.data('sortable')) {
|
if ($itemsDom.data('sortable')) {
|
||||||
$(self.itemsDom).sortable('option', 'disabled', !userIsMember());
|
$(self.itemsDom).sortable('option', 'disabled', !userIsMember());
|
||||||
}
|
}
|
||||||
|
if(Utils.isMiniScreen()) {
|
||||||
|
this.$('.js-checklists').sortable({
|
||||||
|
handle: '.checklist-handle',
|
||||||
|
});
|
||||||
|
this.$('.js-checklist-item').sortable({
|
||||||
|
handle: '.checklist-item-handle',
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if (Meteor.user().hasShowDesktopDragHandles()) {
|
||||||
|
this.$('.js-checklists').sortable({
|
||||||
|
handle: '.checklist-handle',
|
||||||
|
});
|
||||||
|
this.$('.js-checklist-item').sortable({
|
||||||
|
handle: '.checklist-item-handle',
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.$('.js-checklists').sortable({
|
||||||
|
handle: '.checklist-title',
|
||||||
|
});
|
||||||
|
this.$('.js-checklist-item').sortable({
|
||||||
|
handle: '.checklist-item',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -72,6 +97,12 @@ BlazeComponent.extendComponent({
|
||||||
},
|
},
|
||||||
}).register('checklistDetail');
|
}).register('checklistDetail');
|
||||||
|
|
||||||
|
Template.checklistDetail.helpers({
|
||||||
|
showDesktopDragHandles() {
|
||||||
|
return Meteor.user().hasShowDesktopDragHandles();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
BlazeComponent.extendComponent({
|
BlazeComponent.extendComponent({
|
||||||
addChecklist(event) {
|
addChecklist(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
|
||||||
|
|
@ -37,10 +37,10 @@ textarea.js-add-checklist-item, textarea.js-edit-checklist-item
|
||||||
|
|
||||||
.checklist-handle
|
.checklist-handle
|
||||||
position: absolute
|
position: absolute
|
||||||
padding: 7px
|
float: right
|
||||||
top: 50%
|
padding-bottom: 30px
|
||||||
transform: translateY(-50%)
|
transform: translateY(-50%)
|
||||||
left: 100px
|
left: 400px
|
||||||
font-size: 18px
|
font-size: 18px
|
||||||
|
|
||||||
.js-delete-checklist
|
.js-delete-checklist
|
||||||
|
|
@ -141,10 +141,10 @@ textarea.js-add-checklist-item, textarea.js-edit-checklist-item
|
||||||
max-width: 420px
|
max-width: 420px
|
||||||
.checklist-item-handle
|
.checklist-item-handle
|
||||||
position: absolute
|
position: absolute
|
||||||
padding: 7px
|
float: right
|
||||||
top: 50%
|
padding-bottom: 30px
|
||||||
transform: translateY(-50%)
|
transform: translateY(-50%)
|
||||||
left: 200px
|
left: 400px
|
||||||
font-size: 18px
|
font-size: 18px
|
||||||
|
|
||||||
.js-delete-checklist-item
|
.js-delete-checklist-item
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,13 @@ template(name="minicard")
|
||||||
class="{{#if isLinkedCard}}linked-card{{/if}}"
|
class="{{#if isLinkedCard}}linked-card{{/if}}"
|
||||||
class="{{#if isLinkedBoard}}linked-board{{/if}}"
|
class="{{#if isLinkedBoard}}linked-board{{/if}}"
|
||||||
class="minicard-{{colorClass}}")
|
class="minicard-{{colorClass}}")
|
||||||
if isMiniScreen
|
|
||||||
.handle
|
|
||||||
.fa.fa-arrows
|
|
||||||
unless isMiniScreen
|
unless isMiniScreen
|
||||||
if showDesktopDragHandles
|
if showDesktopDragHandles
|
||||||
.handle
|
.handle
|
||||||
.fa.fa-arrows
|
.fa.fa-arrows
|
||||||
|
if isMiniScreen
|
||||||
|
.handle
|
||||||
|
.fa.fa-arrows
|
||||||
if cover
|
if cover
|
||||||
.minicard-cover(style="background-image: url('{{cover.url}}');")
|
.minicard-cover(style="background-image: url('{{cover.url}}');")
|
||||||
if labels
|
if labels
|
||||||
|
|
|
||||||
|
|
@ -105,12 +105,25 @@
|
||||||
right: 5px;
|
right: 5px;
|
||||||
top: 5px;
|
top: 5px;
|
||||||
display:none;
|
display:none;
|
||||||
@media only screen {
|
@media only screen and (min-width: 1200px) {
|
||||||
display:block;
|
display:block;
|
||||||
}
|
}
|
||||||
.fa-arrows
|
.fa-arrows
|
||||||
font-size:20px;
|
font-size:20px;
|
||||||
color: #ccc;
|
color: #ccc;
|
||||||
|
//.handle-minicard-desktop
|
||||||
|
// width: 20px;
|
||||||
|
// height: 20px;
|
||||||
|
// position: absolute;
|
||||||
|
// right: 5px;
|
||||||
|
// top: 5px;
|
||||||
|
// display:none;
|
||||||
|
// @media only screen and (min-width: 1200px) {
|
||||||
|
// display:block;
|
||||||
|
// }
|
||||||
|
// .fa-arrows
|
||||||
|
// font-size:20px;
|
||||||
|
// color: #ccc;
|
||||||
.minicard-title
|
.minicard-title
|
||||||
p:last-child
|
p:last-child
|
||||||
margin-bottom: 0
|
margin-bottom: 0
|
||||||
|
|
|
||||||
|
|
@ -31,24 +31,6 @@ BlazeComponent.extendComponent({
|
||||||
const itemsSelector = '.js-minicard:not(.placeholder, .js-card-composer)';
|
const itemsSelector = '.js-minicard:not(.placeholder, .js-card-composer)';
|
||||||
const $cards = this.$('.js-minicards');
|
const $cards = this.$('.js-minicards');
|
||||||
|
|
||||||
if (Utils.isMiniScreen) {
|
|
||||||
$('.js-minicards').sortable({
|
|
||||||
handle: '.handle',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Utils.isMiniScreen && showDesktopDragHandles) {
|
|
||||||
$('.js-minicards').sortable({
|
|
||||||
handle: '.handle',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Utils.isMiniScreen && !showDesktopDragHandles) {
|
|
||||||
$('.js-minicards').sortable({
|
|
||||||
handle: 'list-header',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
$cards.sortable({
|
$cards.sortable({
|
||||||
connectWith: '.js-minicards:not(.js-list-full)',
|
connectWith: '.js-minicards:not(.js-list-full)',
|
||||||
tolerance: 'pointer',
|
tolerance: 'pointer',
|
||||||
|
|
@ -138,6 +120,21 @@ BlazeComponent.extendComponent({
|
||||||
// Disable drag-dropping if the current user is not a board member or is comment only
|
// Disable drag-dropping if the current user is not a board member or is comment only
|
||||||
this.autorun(() => {
|
this.autorun(() => {
|
||||||
$cards.sortable('option', 'disabled', !userIsMember());
|
$cards.sortable('option', 'disabled', !userIsMember());
|
||||||
|
if (Utils.isMiniScreen()) {
|
||||||
|
this.$('.js-minicards').sortable({
|
||||||
|
handle: '.handle',
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if (Meteor.user().hasShowDesktopDragHandles()) {
|
||||||
|
this.$('.js-minicards').sortable({
|
||||||
|
handle: '.handle',
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.$('.js-minicards').sortable({
|
||||||
|
handle: '.minicard-title',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// We want to re-run this function any time a card is added.
|
// We want to re-run this function any time a card is added.
|
||||||
|
|
@ -180,3 +177,9 @@ Template.miniList.events({
|
||||||
Session.set('currentList', listId);
|
Session.set('currentList', listId);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Template.miniList.helpers({
|
||||||
|
showDesktopDragHandles() {
|
||||||
|
return Meteor.user().hasShowDesktopDragHandles();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,7 @@ function initSortable(boardComponent, $listsDom) {
|
||||||
$listsDom.sortable({
|
$listsDom.sortable({
|
||||||
tolerance: 'pointer',
|
tolerance: 'pointer',
|
||||||
helper: 'clone',
|
helper: 'clone',
|
||||||
|
handle: '.js-list-header',
|
||||||
items: '.js-list:not(.js-list-composer)',
|
items: '.js-list:not(.js-list-composer)',
|
||||||
placeholder: 'list placeholder',
|
placeholder: 'list placeholder',
|
||||||
distance: 7,
|
distance: 7,
|
||||||
|
|
@ -101,16 +102,7 @@ function initSortable(boardComponent, $listsDom) {
|
||||||
boardComponent.autorun(() => {
|
boardComponent.autorun(() => {
|
||||||
const $listDom = $listsDom;
|
const $listDom = $listsDom;
|
||||||
|
|
||||||
if (Utils.isMiniScreen) {
|
|
||||||
$listsDom.sortable({
|
|
||||||
handle: '.js-list-handle',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (!Utils.isMiniScreen && showDesktopDragHandles) {
|
|
||||||
$listsDom.sortable({
|
|
||||||
handle: '.js-list-header',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if ($listDom.data('sortable')) {
|
if ($listDom.data('sortable')) {
|
||||||
$listsDom.sortable(
|
$listsDom.sortable(
|
||||||
'option',
|
'option',
|
||||||
|
|
@ -118,6 +110,33 @@ function initSortable(boardComponent, $listsDom) {
|
||||||
MultiSelection.isActive() || !userIsMember(),
|
MultiSelection.isActive() || !userIsMember(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (Utils.isMiniScreen()) {
|
||||||
|
this.$('.js-lists').sortable({
|
||||||
|
handle: '.list-header-menu-handle',
|
||||||
|
});
|
||||||
|
this.$('.js-swimlanes').sortable({
|
||||||
|
handle: '.swimlane-header-menu-miniscreen-handle',
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if (Meteor.user().hasShowDesktopDragHandles()) {
|
||||||
|
this.$('.js-lists').sortable({
|
||||||
|
handle: '.list-header-menu-handle',
|
||||||
|
});
|
||||||
|
this.$('.js-swimlanes').sortable({
|
||||||
|
handle: '.swimlane-header-menu-handle',
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.$('.js-lists').sortable({
|
||||||
|
handle: '.list-header',
|
||||||
|
});
|
||||||
|
this.$('.js-swimlanes').sortable({
|
||||||
|
handle: '.swimlane-header',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -161,32 +180,13 @@ BlazeComponent.extendComponent({
|
||||||
// define a list of elements in which we disable the dragging because
|
// define a list of elements in which we disable the dragging because
|
||||||
// the user will legitimately expect to be able to select some text with
|
// the user will legitimately expect to be able to select some text with
|
||||||
// his mouse.
|
// his mouse.
|
||||||
|
const noDragInside = [
|
||||||
if (Utils.isMiniScreen) {
|
|
||||||
noDragInside = [
|
|
||||||
'a',
|
'a',
|
||||||
'input',
|
'input',
|
||||||
'textarea',
|
'textarea',
|
||||||
'p',
|
'p',
|
||||||
'.js-list-handle',
|
'.js-list-header',
|
||||||
'.js-swimlane-header-handle',
|
|
||||||
];
|
];
|
||||||
}
|
|
||||||
|
|
||||||
if (!Utils.isMiniScreen && !showDesktopDragHandles) {
|
|
||||||
noDragInside = ['a', 'input', 'textarea', 'p', '.js-list-header'];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Utils.isMiniScreen && showDesktopDragHandles) {
|
|
||||||
noDragInside = [
|
|
||||||
'a',
|
|
||||||
'input',
|
|
||||||
'textarea',
|
|
||||||
'p',
|
|
||||||
'.js-list-handle',
|
|
||||||
'.js-swimlane-header-handle',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
$(evt.target).closest(noDragInside.join(',')).length === 0 &&
|
$(evt.target).closest(noDragInside.join(',')).length === 0 &&
|
||||||
|
|
@ -308,3 +308,9 @@ BlazeComponent.extendComponent({
|
||||||
initSortable(boardComponent, $listsDom);
|
initSortable(boardComponent, $listsDom);
|
||||||
},
|
},
|
||||||
}).register('listsGroup');
|
}).register('listsGroup');
|
||||||
|
|
||||||
|
Template.listsGroup.helpers({
|
||||||
|
showDesktopDragHandles() {
|
||||||
|
return Meteor.user().hasShowDesktopDragHandles();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue