Set drag handle on touch screen not miniscreen

This commit is contained in:
Repmovs 2022-08-12 17:21:45 +00:00
parent 61d2fd0308
commit d7bb0b4cc0
16 changed files with 214 additions and 223 deletions

View file

@ -193,7 +193,7 @@ BlazeComponent.extendComponent({
});
this.autorun(() => {
if (Utils.isMiniScreenOrShowDesktopDragHandles()) {
if (Utils.isTouchScreenOrShowDesktopDragHandles()) {
$swimlanesDom.sortable({
handle: '.js-swimlane-header-handle',
});
@ -228,10 +228,10 @@ BlazeComponent.extendComponent({
}
},
notDisplayThisBoard(){
notDisplayThisBoard() {
let allowPrivateVisibilityOnly = TableVisibilityModeSettings.findOne('tableVisibilityMode-allowPrivateOnly');
let currentBoard = Boards.findOne(Session.get('currentBoard'));
if(allowPrivateVisibilityOnly !== undefined && allowPrivateVisibilityOnly.booleanValue && currentBoard.permission == 'public'){
if (allowPrivateVisibilityOnly !== undefined && allowPrivateVisibilityOnly.booleanValue && currentBoard.permission == 'public') {
return true;
}
@ -319,7 +319,7 @@ BlazeComponent.extendComponent({
BlazeComponent.extendComponent({
onRendered() {
this.autorun(function() {
this.autorun(function () {
$('#calendar-view').fullCalendar('refetchEvents');
});
},
@ -351,7 +351,7 @@ BlazeComponent.extendComponent({
events(start, end, timezone, callback) {
const currentBoard = Boards.findOne(Session.get('currentBoard'));
const events = [];
const pushEvent = function(card, title, start, end, extraCls) {
const pushEvent = function (card, title, start, end, extraCls) {
start = start || card.startAt;
end = end || card.endAt;
title = title || card.title;
@ -375,12 +375,12 @@ BlazeComponent.extendComponent({
};
currentBoard
.cardsInInterval(start.toDate(), end.toDate())
.forEach(function(card) {
.forEach(function (card) {
pushEvent(card);
});
currentBoard
.cardsDueInBetween(start.toDate(), end.toDate())
.forEach(function(card) {
.forEach(function (card) {
pushEvent(
card,
`${card.title} ${TAPi18n.__('card-due')}`,
@ -388,7 +388,7 @@ BlazeComponent.extendComponent({
new Date(card.dueAt.getTime() + 36e5),
);
});
events.sort(function(first, second) {
events.sort(function (first, second) {
return first.id > second.id ? 1 : -1;
});
callback(events);

View file

@ -62,7 +62,7 @@ template(name="boardList")
i.fa.js-has-spenttime-cards(
class="fa-circle{{#if hasOvertimeCards}} has-overtime-card-active{{else}} no-overtime-card-active{{/if}}"
title="{{#if hasOvertimeCards}}{{_ 'has-overtime-cards'}}{{else}}{{_ 'has-spenttime-cards'}}{{/if}}")
if isMiniScreenOrShowDesktopDragHandles
if isTouchScreenOrShowDesktopDragHandles
i.fa.board-handle(
class="fa-arrows"
title="{{_ 'Drag board'}}")
@ -114,7 +114,7 @@ template(name="boardList")
i.fa.js-has-spenttime-cards(
class="fa-circle{{#if hasOvertimeCards}} has-overtime-card-active{{else}} no-overtime-card-active{{/if}}"
title="{{#if hasOvertimeCards}}{{_ 'has-overtime-cards'}}{{else}}{{_ 'has-spenttime-cards'}}{{/if}}")
if isMiniScreenOrShowDesktopDragHandles
if isTouchScreenOrShowDesktopDragHandles
i.fa.board-handle(
class="fa-arrows"
title="{{_ 'Drag board'}}")

View file

@ -30,7 +30,7 @@ BlazeComponent.extendComponent({
Meteor.subscribe('tableVisibilityModeSettings');
let currUser = Meteor.user();
let userLanguage;
if(currUser && currUser.profile){
if (currUser && currUser.profile) {
userLanguage = currUser.profile.language
}
if (userLanguage) {
@ -79,54 +79,54 @@ BlazeComponent.extendComponent({
// Disable drag-dropping if the current user is not a board member or is comment only
this.autorun(() => {
if (Utils.isMiniScreenOrShowDesktopDragHandles()) {
if (Utils.isTouchScreenOrShowDesktopDragHandles()) {
$boards.sortable({
handle: '.board-handle',
});
}
});
},
userHasTeams(){
if(Meteor.user() != null && Meteor.user().teams && Meteor.user().teams.length > 0)
userHasTeams() {
if (Meteor.user() != null && Meteor.user().teams && Meteor.user().teams.length > 0)
return true;
else
return false;
},
teamsDatas() {
if(Meteor.user().teams)
if (Meteor.user().teams)
return Meteor.user().teams.sort((a, b) => a.teamDisplayName.localeCompare(b.teamDisplayName));
else
return [];
},
userHasOrgs(){
if(Meteor.user() != null && Meteor.user().orgs && Meteor.user().orgs.length > 0)
userHasOrgs() {
if (Meteor.user() != null && Meteor.user().orgs && Meteor.user().orgs.length > 0)
return true;
else
return false;
},
/*
userHasTemplates(){
if(Meteor.user() != null && Meteor.user().orgs && Meteor.user().orgs.length > 0)
return true;
else
return false;
},
*/
/*
userHasTemplates(){
if(Meteor.user() != null && Meteor.user().orgs && Meteor.user().orgs.length > 0)
return true;
else
return false;
},
*/
orgsDatas() {
if(Meteor.user().orgs)
if (Meteor.user().orgs)
return Meteor.user().orgs.sort((a, b) => a.orgDisplayName.localeCompare(b.orgDisplayName));
else
return [];
},
userHasOrgsOrTeams(){
userHasOrgsOrTeams() {
let boolUserHasOrgs;
if(Meteor.user() != null && Meteor.user().orgs && Meteor.user().orgs.length > 0)
if (Meteor.user() != null && Meteor.user().orgs && Meteor.user().orgs.length > 0)
boolUserHasOrgs = true;
else
boolUserHasOrgs = false;
let boolUserHasTeams;
if(Meteor.user() != null && Meteor.user().teams && Meteor.user().teams.length > 0)
if (Meteor.user() != null && Meteor.user().teams && Meteor.user().teams.length > 0)
boolUserHasTeams = true;
else
boolUserHasTeams = false;
@ -139,18 +139,18 @@ BlazeComponent.extendComponent({
// { type: { $in: ['board','template-container'] } },
$and: [
{ archived: false },
{ type: { $in: ['board','template-container'] } },
{ $or:[] }
{ type: { $in: ['board', 'template-container'] } },
{ $or: [] }
]
};
let allowPrivateVisibilityOnly = TableVisibilityModeSettings.findOne('tableVisibilityMode-allowPrivateOnly');
if (FlowRouter.getRouteName() === 'home'){
query.$and[2].$or.push({'members.userId': Meteor.userId()});
if (FlowRouter.getRouteName() === 'home') {
query.$and[2].$or.push({ 'members.userId': Meteor.userId() });
if(allowPrivateVisibilityOnly !== undefined && allowPrivateVisibilityOnly.booleanValue){
query.$and.push({'permission': 'private'});
if (allowPrivateVisibilityOnly !== undefined && allowPrivateVisibilityOnly.booleanValue) {
query.$and.push({ 'permission': 'private' });
}
const currUser = Users.findOne(Meteor.userId());
@ -162,27 +162,27 @@ BlazeComponent.extendComponent({
// });
let orgIdsUserBelongs = currUser !== undefined && currUser.teams !== 'undefined' ? currUser.orgIdsUserBelongs() : '';
if(orgIdsUserBelongs && orgIdsUserBelongs != ''){
if (orgIdsUserBelongs && orgIdsUserBelongs != '') {
let orgsIds = orgIdsUserBelongs.split(',');
// for(let i = 0; i < orgsIds.length; i++){
// query.$and[2].$or.push({'orgs.orgId': orgsIds[i]});
// }
//query.$and[2].$or.push({'orgs': {$elemMatch : {orgId: orgsIds[0]}}});
query.$and[2].$or.push({'orgs.orgId': {$in : orgsIds}});
query.$and[2].$or.push({ 'orgs.orgId': { $in: orgsIds } });
}
let teamIdsUserBelongs = currUser !== undefined && currUser.teams !== 'undefined' ? currUser.teamIdsUserBelongs() : '';
if(teamIdsUserBelongs && teamIdsUserBelongs != ''){
if (teamIdsUserBelongs && teamIdsUserBelongs != '') {
let teamsIds = teamIdsUserBelongs.split(',');
// for(let i = 0; i < teamsIds.length; i++){
// query.$or[2].$or.push({'teams.teamId': teamsIds[i]});
// }
//query.$and[2].$or.push({'teams': { $elemMatch : {teamId: teamsIds[0]}}});
query.$and[2].$or.push({'teams.teamId': {$in : teamsIds}});
query.$and[2].$or.push({ 'teams.teamId': { $in: teamsIds } });
}
}
else if(allowPrivateVisibilityOnly !== undefined && !allowPrivateVisibilityOnly.booleanValue){
else if (allowPrivateVisibilityOnly !== undefined && !allowPrivateVisibilityOnly.booleanValue) {
query = {
archived: false,
//type: { $in: ['board','template-container'] },
@ -197,9 +197,9 @@ BlazeComponent.extendComponent({
},
boardLists(boardId) {
let boardLists = [];
const lists = Lists.find({'boardId' : boardId, 'archived': false})
const lists = Lists.find({ 'boardId': boardId, 'archived': false })
lists.forEach(list => {
let cardCount = Cards.find({'boardId':boardId, 'listId':list._id}).count()
let cardCount = Cards.find({ 'boardId': boardId, 'listId': list._id }).count()
boardLists.push(`${list.title}: ${cardCount}`);
});
return boardLists
@ -207,7 +207,7 @@ BlazeComponent.extendComponent({
boardMembers(boardId) {
let boardMembers = [];
const lists = Boards.findOne({'_id' : boardId})
const lists = Boards.findOne({ '_id': boardId })
let members = lists.members
members.forEach(member => {
boardMembers.push(member.userId);
@ -291,10 +291,10 @@ BlazeComponent.extendComponent({
}
});
},
'click #resetBtn'(event){
'click #resetBtn'(event) {
let allBoards = document.getElementsByClassName("js-board");
let currBoard;
for(let i=0; i < allBoards.length; i++){
for (let i = 0; i < allBoards.length; i++) {
currBoard = allBoards[i];
currBoard.style.display = "block";
}
@ -302,57 +302,55 @@ BlazeComponent.extendComponent({
'click #filterBtn'(event) {
event.preventDefault();
let selectedTeams = document.querySelectorAll('#jsAllBoardTeams option:checked');
let selectedTeamsValues = Array.from(selectedTeams).map(function(elt){return elt.value});
let selectedTeamsValues = Array.from(selectedTeams).map(function (elt) { return elt.value });
let index = selectedTeamsValues.indexOf("-1");
if (index > -1) {
selectedTeamsValues.splice(index, 1);
}
let selectedOrgs = document.querySelectorAll('#jsAllBoardOrgs option:checked');
let selectedOrgsValues = Array.from(selectedOrgs).map(function(elt){return elt.value});
let selectedOrgsValues = Array.from(selectedOrgs).map(function (elt) { return elt.value });
index = selectedOrgsValues.indexOf("-1");
if (index > -1) {
selectedOrgsValues.splice(index, 1);
}
if(selectedTeamsValues.length > 0 || selectedOrgsValues.length > 0){
if (selectedTeamsValues.length > 0 || selectedOrgsValues.length > 0) {
const query = {
$and: [
{ archived: false },
{ type: 'board' },
{ $or:[] }
{ $or: [] }
]
};
if(selectedTeamsValues.length > 0)
{
query.$and[2].$or.push({'teams.teamId': {$in : selectedTeamsValues}});
if (selectedTeamsValues.length > 0) {
query.$and[2].$or.push({ 'teams.teamId': { $in: selectedTeamsValues } });
}
if(selectedOrgsValues.length > 0)
{
query.$and[2].$or.push({'orgs.orgId': {$in : selectedOrgsValues}});
if (selectedOrgsValues.length > 0) {
query.$and[2].$or.push({ 'orgs.orgId': { $in: selectedOrgsValues } });
}
let filteredBoards = Boards.find(query, {}).fetch();
let allBoards = document.getElementsByClassName("js-board");
let currBoard;
if(filteredBoards.length > 0){
if (filteredBoards.length > 0) {
let currBoardId;
let found;
for(let i=0; i < allBoards.length; i++){
for (let i = 0; i < allBoards.length; i++) {
currBoard = allBoards[i];
currBoardId = currBoard.classList[0];
found = filteredBoards.find(function(board){
found = filteredBoards.find(function (board) {
return board._id == currBoardId;
});
if(found !== undefined)
if (found !== undefined)
currBoard.style.display = "block";
else
currBoard.style.display = "none";
}
}
else{
for(let i=0; i < allBoards.length; i++){
else {
for (let i = 0; i < allBoards.length; i++) {
currBoard = allBoards[i];
currBoard.style.display = "none";
}

View file

@ -87,27 +87,27 @@ BlazeComponent.extendComponent({
const cardPanelWidth = 600;
const parentComponent = this.parentComponent();
/*
// Incomplete fix about bug where opening card scrolls to wrong place
// https://github.com/wekan/wekan/issues/4572#issuecomment-1184149395
// TODO sometimes parentComponent is not available, maybe because it's not
// yet created?!
if (!parentComponent) return;
const bodyBoardComponent = parentComponent.parentComponent();
*/
/*
// Incomplete fix about bug where opening card scrolls to wrong place
// https://github.com/wekan/wekan/issues/4572#issuecomment-1184149395
// TODO sometimes parentComponent is not available, maybe because it's not
// yet created?!
if (!parentComponent) return;
const bodyBoardComponent = parentComponent.parentComponent();
*/
//On Mobile View Parent is Board, Not Board Body. I cant see how this funciton should work then.
if (bodyBoardComponent === null) return;
const $cardView = this.$(this.firstNode());
const $cardContainer = bodyBoardComponent.$('.js-swimlanes');
/*
// Incomplete fix about bug where opening card scrolls to wrong place
// https://github.com/wekan/wekan/issues/4572#issuecomment-1184149395
// TODO sometimes cardContainer is not available, maybe because it's not yet
// created?!
if (!$cardContainer) return;
*/
/*
// Incomplete fix about bug where opening card scrolls to wrong place
// https://github.com/wekan/wekan/issues/4572#issuecomment-1184149395
// TODO sometimes cardContainer is not available, maybe because it's not yet
// created?!
if (!$cardContainer) return;
*/
const cardContainerScroll = $cardContainer.scrollLeft();
const cardContainerWidth = $cardContainer.width();
@ -306,7 +306,7 @@ BlazeComponent.extendComponent({
$checklistsDom.data('sortable')
) {
$checklistsDom.sortable('option', 'disabled', disabled);
if (Utils.isMiniScreenOrShowDesktopDragHandles()) {
if (Utils.isTouchScreenOrShowDesktopDragHandles()) {
$checklistsDom.sortable({ handle: '.checklist-handle' });
}
}
@ -793,8 +793,8 @@ const filterMembers = (filterTerm) => {
user: Users.findOne(member.userId)
}))
.filter(({ user }) =>
(user.profile.fullname !== undefined && user.profile.fullname.toLowerCase().indexOf(filterTerm.toLowerCase()) !== -1)
|| user.profile.fullname === undefined && user.profile.username !== undefined && user.profile.username.toLowerCase().indexOf(filterTerm.toLowerCase()) !== -1)
(user.profile.fullname !== undefined && user.profile.fullname.toLowerCase().indexOf(filterTerm.toLowerCase()) !== -1)
|| user.profile.fullname === undefined && user.profile.username !== undefined && user.profile.username.toLowerCase().indexOf(filterTerm.toLowerCase()) !== -1)
.map(({ member }) => member);
}
return members;
@ -866,9 +866,9 @@ BlazeComponent.extendComponent({
*/
setMoveAndCopyDialogOption(boardId) {
this.moveAndCopyDialogOption = {
'boardId' : "",
'swimlaneId' : "",
'listId' : "",
'boardId': "",
'swimlaneId': "",
'listId': "",
}
let currentOptions = Meteor.user().getMoveAndCopyDialogOptions();
@ -945,9 +945,9 @@ BlazeComponent.extendComponent({
const swimlaneId = swimlaneSelect.options[swimlaneSelect.selectedIndex].value;
const options = {
'boardId' : boardId,
'swimlaneId' : swimlaneId,
'listId' : listId,
'boardId': boardId,
'swimlaneId': swimlaneId,
'listId': listId,
}
Meteor.user().setMoveAndCopyDialogOption(this.currentBoardId, options);
},
@ -1728,16 +1728,14 @@ EscapeActions.register(
() => {
// if card description diverges from database due to editing
// ask user whether changes should be applied
if(currentUser.profile.rescueCardDescription== true)
{
if (currentUser.profile.rescueCardDescription == true) {
currentDescription = document.getElementsByClassName("editor js-new-description-input").item(0)
if (currentDescription?.value && !(currentDescription.value === Utils.getCurrentCard().getDescription()))
{
if (currentDescription?.value && !(currentDescription.value === Utils.getCurrentCard().getDescription())) {
if (confirm(TAPi18n.__('rescue-card-description-dialogue'))) {
Utils.getCurrentCard().setDescription(document.getElementsByClassName("editor js-new-description-input").item(0).value);
// Save it!
console.log(document.getElementsByClassName("editor js-new-description-input").item(0).value);
console.log("current description",Utils.getCurrentCard().getDescription());
console.log("current description", Utils.getCurrentCard().getDescription());
} else {
// Do nothing!
console.log('Description changes were not saved to the database.');
@ -1824,17 +1822,17 @@ Template.cardAssigneePopup.helpers({
return user && user.isBoardAdmin() ? 'admin' : 'normal';
},
/*
presenceStatusClassName() {
const user = Users.findOne(this.userId);
const userPresence = presences.findOne({ userId: this.userId });
if (user && user.isInvitedTo(Session.get('currentBoard'))) return 'pending';
else if (!userPresence) return 'disconnected';
else if (Session.equals('currentBoard', userPresence.state.currentBoardId))
return 'active';
else return 'idle';
},
*/
/*
presenceStatusClassName() {
const user = Users.findOne(this.userId);
const userPresence = presences.findOne({ userId: this.userId });
if (user && user.isInvitedTo(Session.get('currentBoard'))) return 'pending';
else if (!userPresence) return 'disconnected';
else if (Session.equals('currentBoard', userPresence.state.currentBoardId))
return 'active';
else return 'idle';
},
*/
isCardAssignee() {
const card = Template.parentData();
const cardAssignees = card.getAssignees();

View file

@ -35,7 +35,7 @@ template(name="checklistDetail")
if canModifyCard
h2.title.js-open-inlined-form.is-editable
if isMiniScreenOrShowDesktopDragHandles
if isTouchScreenOrShowDesktopDragHandles
span.fa.checklist-handle(class="fa-arrows" title="{{_ 'dragChecklist'}}")
+viewer
= checklist.title
@ -104,7 +104,7 @@ template(name='checklistItemDetail')
if canModifyCard
.check-box-container
.check-box.materialCheckBox(class="{{#if item.isFinished }}is-checked{{/if}}")
if isMiniScreenOrShowDesktopDragHandles
if isTouchScreenOrShowDesktopDragHandles
span.fa.checklistitem-handle(class="fa-arrows" title="{{_ 'dragChecklistItem'}}")
.item-title.js-open-inlined-form.is-editable(class="{{#if item.isFinished }}is-checked{{/if}}")
+viewer

View file

@ -48,7 +48,7 @@ BlazeComponent.extendComponent({
const self = this;
self.itemsDom = this.$('.js-checklist-items');
initSorting(self.itemsDom);
self.itemsDom.mousedown(function(evt) {
self.itemsDom.mousedown(function (evt) {
evt.stopPropagation();
});
@ -61,7 +61,7 @@ BlazeComponent.extendComponent({
const $itemsDom = $(self.itemsDom);
if ($itemsDom.data('uiSortable') || $itemsDom.data('sortable')) {
$(self.itemsDom).sortable('option', 'disabled', !userIsMember());
if (Utils.isMiniScreenOrShowDesktopDragHandles()) {
if (Utils.isTouchScreenOrShowDesktopDragHandles()) {
$(self.itemsDom).sortable({
handle: 'span.fa.checklistitem-handle',
});
@ -306,15 +306,15 @@ BlazeComponent.extendComponent({
events() {
return [
{
'click .js-delete-checklist' : Popup.afterConfirm('checklistDelete', function () {
'click .js-delete-checklist': Popup.afterConfirm('checklistDelete', function () {
Popup.back(2);
const checklist = this.checklist;
if (checklist && checklist._id) {
Checklists.remove(checklist._id);
}
}),
'click .js-move-checklist' : Popup.open('moveChecklist'),
'click .js-copy-checklist' : Popup.open('copyChecklist'),
'click .js-move-checklist': Popup.open('moveChecklist'),
'click .js-copy-checklist': Popup.open('copyChecklist'),
}
]
}
@ -407,9 +407,9 @@ class DialogWithBoardSwimlaneListAndCard extends BlazeComponent {
*/
setChecklistDialogOption(boardId) {
this.checklistDialogOption = {
'boardId' : "",
'swimlaneId' : "",
'listId' : "",
'boardId': "",
'swimlaneId': "",
'listId': "",
'cardId': "",
}
@ -417,20 +417,19 @@ class DialogWithBoardSwimlaneListAndCard extends BlazeComponent {
if (currentOptions && boardId && currentOptions[boardId]) {
this.checklistDialogOption = currentOptions[boardId];
if (this.checklistDialogOption.boardId &&
this.checklistDialogOption.swimlaneId &&
this.checklistDialogOption.listId
)
{
this.checklistDialogOption.swimlaneId &&
this.checklistDialogOption.listId
) {
this.selectedBoardId.set(this.checklistDialogOption.boardId)
this.selectedSwimlaneId.set(this.checklistDialogOption.swimlaneId);
this.selectedListId.set(this.checklistDialogOption.listId);
}
}
this.getBoardData(this.selectedBoardId.get());
if (!this.selectedSwimlaneId.get() || !Swimlanes.findOne({_id: this.selectedSwimlaneId.get(), boardId: this.selectedBoardId.get()})) {
if (!this.selectedSwimlaneId.get() || !Swimlanes.findOne({ _id: this.selectedSwimlaneId.get(), boardId: this.selectedBoardId.get() })) {
this.setFirstSwimlaneId();
}
if (!this.selectedListId.get() || !Lists.findOne({_id: this.selectedListId.get(), boardId: this.selectedBoardId.get()})) {
if (!this.selectedListId.get() || !Lists.findOne({ _id: this.selectedListId.get(), boardId: this.selectedBoardId.get() })) {
this.setFirstListId();
}
}
@ -440,7 +439,7 @@ class DialogWithBoardSwimlaneListAndCard extends BlazeComponent {
const board = Boards.findOne(this.selectedBoardId.get());
const swimlaneId = board.swimlanes().fetch()[0]._id;
this.selectedSwimlaneId.set(swimlaneId);
} catch (e) {}
} catch (e) { }
}
/** sets the first list id */
setFirstListId() {
@ -448,7 +447,7 @@ class DialogWithBoardSwimlaneListAndCard extends BlazeComponent {
const board = Boards.findOne(this.selectedBoardId.get());
const listId = board.lists().fetch()[0]._id;
this.selectedListId.set(listId);
} catch (e) {}
} catch (e) { }
}
/** returns if the board id was the last confirmed one
@ -561,9 +560,9 @@ class DialogWithBoardSwimlaneListAndCard extends BlazeComponent {
const cardId = cardSelect.options[cardSelect.selectedIndex].value;
const options = {
'boardId' : boardId,
'swimlaneId' : swimlaneId,
'listId' : listId,
'boardId': boardId,
'swimlaneId': swimlaneId,
'listId': listId,
'cardId': cardId,
}
this.setDone(cardId, options);

View file

@ -29,7 +29,7 @@ template(name="cardLabelsPopup")
each board.labels
li.js-card-label-item
a.card-label-edit-button.fa.fa-pencil.js-edit-label
if isMiniScreenOrShowDesktopDragHandles
if isTouchScreenOrShowDesktopDragHandles
span.fa.label-handle(class="fa-arrows" title="{{_ 'dragLabel'}}")
span.card-label.card-label-selectable.js-select-label.card-label-wrapper(class="card-label-{{color}}"
class="{{# if isLabelSelected ../_id }}active{{/if}}")

View file

@ -50,8 +50,7 @@ BlazeComponent.extendComponent({
appendTo: '.edit-labels-pop-over',
helper(element, currentItem) {
let ret = currentItem.clone();
if (currentItem.closest('.popup-container-depth-0').size() == 0)
{ // only set css transform at every sub-popup, not at the main popup
if (currentItem.closest('.popup-container-depth-0').size() == 0) { // only set css transform at every sub-popup, not at the main popup
const content = currentItem.closest('.content')[0]
const offsetLeft = content.offsetLeft;
const offsetTop = $('.pop-over > .header').height() * -1;
@ -76,7 +75,7 @@ BlazeComponent.extendComponent({
// Disable drag-dropping if the current user is not a board member or is comment only
this.autorun(() => {
if (Utils.isMiniScreenOrShowDesktopDragHandles()) {
if (Utils.isTouchScreenOrShowDesktopDragHandles()) {
$labels.sortable({
handle: '.label-handle',
});
@ -130,7 +129,7 @@ Template.createLabelPopup.events({
});
Template.editLabelPopup.events({
'click .js-delete-label': Popup.afterConfirm('deleteLabel', function() {
'click .js-delete-label': Popup.afterConfirm('deleteLabel', function () {
const board = Boards.findOne(Session.get('currentBoard'));
board.removeLabel(this._id);
Popup.back(2);

View file

@ -3,7 +3,7 @@ template(name="minicard")
class="{{#if isLinkedCard}}linked-card{{/if}}"
class="{{#if isLinkedBoard}}linked-board{{/if}}"
class="{{#if colorClass}}minicard-{{colorClass}}{{/if}}")
if isMiniScreenOrShowDesktopDragHandles
if isTouchScreenOrShowDesktopDragHandles
.handle
.fa.fa-arrows
if cover

View file

@ -96,7 +96,7 @@ BlazeComponent.extendComponent({
$cards.sortable('cancel');
if (MultiSelection.isActive()) {
Cards.find(MultiSelection.getMongoSelector(), {sort: ['sort']}).forEach((card, i) => {
Cards.find(MultiSelection.getMongoSelector(), { sort: ['sort'] }).forEach((card, i) => {
const newSwimlaneId = targetSwimlaneId
? targetSwimlaneId
: card.swimlaneId || defaultSwimlaneId;
@ -119,35 +119,31 @@ BlazeComponent.extendComponent({
},
sort(event, ui) {
const $boardCanvas = $('.board-canvas');
const boardCanvas = $boardCanvas[0];
const boardCanvas = $boardCanvas[0];
if (event.pageX < 10)
{ // scroll to the left
if (event.pageX < 10) { // scroll to the left
boardCanvas.scrollLeft -= 15;
ui.helper[0].offsetLeft -= 15;
}
if (
event.pageX > boardCanvas.offsetWidth - 10 &&
boardCanvas.scrollLeft < $boardCanvas.data('scrollLeftMax') // don't scroll more than possible
)
{ // scroll to the right
) { // scroll to the right
boardCanvas.scrollLeft += 15;
}
if (
event.pageY > boardCanvas.offsetHeight - 10 &&
event.pageY + boardCanvas.scrollTop < $boardCanvas.data('scrollTopMax') // don't scroll more than possible
)
{ // scroll to the bottom
) { // scroll to the bottom
boardCanvas.scrollTop += 15;
}
if (event.pageY < 10)
{ // scroll to the top
if (event.pageY < 10) { // scroll to the top
boardCanvas.scrollTop -= 15;
}
},
activate(event, ui) {
const $boardCanvas = $('.board-canvas');
const boardCanvas = $boardCanvas[0];
const boardCanvas = $boardCanvas[0];
// scrollTopMax and scrollLeftMax only available at Firefox (https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollTopMax)
// https://www.it-swarm.com.de/de/javascript/so-erhalten-sie-den-maximalen-dokument-scrolltop-wert/1069126844/
$boardCanvas.data('scrollTopMax', boardCanvas.scrollHeight - boardCanvas.clientTop);
@ -157,7 +153,7 @@ BlazeComponent.extendComponent({
});
this.autorun(() => {
if (Utils.isMiniScreenOrShowDesktopDragHandles()) {
if (Utils.isTouchScreenOrShowDesktopDragHandles()) {
$cards.sortable({
handle: '.handle',
});

View file

@ -44,7 +44,7 @@ template(name="listHeader")
a.js-add-card.fa.fa-plus.list-header-plus-top(title="{{_ 'add-card-to-top-of-list'}}")
a.fa.fa-navicon.js-open-list-menu(title="{{_ 'listActionPopup-title'}}")
if currentUser.isBoardAdmin
if isShowDesktopDragHandles
if isTouchScreenOrShowDesktopDragHandles
a.list-header-handle.handle.fa.fa-arrows.js-list-handle
template(name="editListTitleForm")

View file

@ -25,10 +25,10 @@ template(name="swimlaneFixedHeader")
if currentUser.isBoardAdmin
a.fa.fa-plus.js-open-add-swimlane-menu.swimlane-header-plus-icon(title="{{_ 'add-swimlane'}}")
a.fa.fa-navicon.js-open-swimlane-menu(title="{{_ 'swimlaneActionPopup-title'}}")
unless isMiniScreen
unless isTouchScreen
if isShowDesktopDragHandles
a.swimlane-header-handle.handle.fa.fa-arrows.js-swimlane-header-handle
if isMiniScreen
if isTouchScreen
a.swimlane-header-miniscreen-handle.handle.fa.fa-arrows.js-swimlane-header-handle
template(name="editSwimlaneTitleForm")

View file

@ -85,14 +85,14 @@ function initSortable(boardComponent, $listsDom) {
const listDomElement = ui.item.get(0);
const list = Blaze.getData(listDomElement);
/*
Reverted incomplete change list width,
removed from below Lists.update:
https://github.com/wekan/wekan/issues/4558
$set: {
width: list._id.width(),
height: list._id.height(),
*/
/*
Reverted incomplete change list width,
removed from below Lists.update:
https://github.com/wekan/wekan/issues/4558
$set: {
width: list._id.width(),
height: list._id.height(),
*/
Lists.update(list._id, {
$set: {
@ -114,7 +114,7 @@ function initSortable(boardComponent, $listsDom) {
//}
boardComponent.autorun(() => {
if (Utils.isMiniScreenOrShowDesktopDragHandles()) {
if (Utils.isTouchScreenOrShowDesktopDragHandles()) {
$listsDom.sortable({
handle: '.js-list-handle',
});
@ -200,7 +200,7 @@ BlazeComponent.extendComponent({
// his mouse.
const noDragInside = ['a', 'input', 'textarea', 'p'].concat(
Utils.isMiniScreenOrShowDesktopDragHandles()
Utils.isTouchScreenOrShowDesktopDragHandles()
? ['.js-list-handle', '.js-swimlane-header-handle']
: ['.js-list-header'],
);

View file

@ -27,12 +27,14 @@ Blaze.registerHelper('concat', (...args) => args.slice(0, -1).join(''));
Blaze.registerHelper('isMiniScreen', () => Utils.isMiniScreen());
Blaze.registerHelper('isTouchScreen', () => Utils.isTouchScreen());
Blaze.registerHelper('isShowDesktopDragHandles', () =>
Utils.isShowDesktopDragHandles(),
);
Blaze.registerHelper('isMiniScreenOrShowDesktopDragHandles', () =>
Utils.isMiniScreenOrShowDesktopDragHandles(),
Blaze.registerHelper('isTouchScreenOrShowDesktopDragHandles', () =>
Utils.isTouchScreenOrShowDesktopDragHandles(),
);
Blaze.registerHelper('moment', (...args) => {

View file

@ -5,20 +5,20 @@ import { Random } from 'meteor/random';
import '../utils';
describe('Utils', function() {
beforeEach(function() {
sinon.stub(Utils, 'reload').callsFake(() => {});
describe('Utils', function () {
beforeEach(function () {
sinon.stub(Utils, 'reload').callsFake(() => { });
});
afterEach(function() {
afterEach(function () {
window.localStorage.removeItem(boardView);
sinon.restore();
});
const boardView = 'boardView';
describe(Utils.setBoardView.name, function() {
it('sets the board view if the user exists', function(done) {
describe(Utils.setBoardView.name, function () {
it('sets the board view if the user exists', function (done) {
const viewId = Random.id();
const user = {
setBoardView: (view) => {
@ -32,14 +32,14 @@ describe('Utils', function() {
expect(window.localStorage.getItem(boardView)).to.equal(viewId);
});
it('sets a specific view if no user exists but a view is defined', function() {
it('sets a specific view if no user exists but a view is defined', function () {
const views = [
'board-view-swimlanes',
'board-view-lists',
'board-view-cal'
];
sinon.stub(Meteor, 'user').callsFake(() => {});
sinon.stub(Meteor, 'user').callsFake(() => { });
views.forEach(viewName => {
Utils.setBoardView(viewName);
@ -47,15 +47,15 @@ describe('Utils', function() {
});
});
it('sets a default view if no user and no view are given', function() {
sinon.stub(Meteor, 'user').callsFake(() => {});
it('sets a default view if no user and no view are given', function () {
sinon.stub(Meteor, 'user').callsFake(() => { });
Utils.setBoardView();
expect(window.localStorage.getItem(boardView)).to.equal('board-view-swimlanes');
});
});
describe(Utils.unsetBoardView.name, function() {
it('removes the boardview from localStoage', function() {
describe(Utils.unsetBoardView.name, function () {
it('removes the boardview from localStoage', function () {
window.localStorage.setItem(boardView, Random.id());
window.localStorage.setItem('collapseSwimlane', Random.id());
@ -66,8 +66,8 @@ describe('Utils', function() {
});
});
describe(Utils.boardView.name, function() {
it('returns the user\'s board view if a user exists', function() {
describe(Utils.boardView.name, function () {
it('returns the user\'s board view if a user exists', function () {
const viewId = Random.id();
const user = {};
sinon.stub(Meteor, 'user').callsFake(() => user);
@ -78,108 +78,108 @@ describe('Utils', function() {
expect(Utils.boardView()).to.equal(boardView);
});
it('returns the current defined view', function() {
it('returns the current defined view', function () {
const views = [
'board-view-swimlanes',
'board-view-lists',
'board-view-cal'
];
sinon.stub(Meteor, 'user').callsFake(() => {});
sinon.stub(Meteor, 'user').callsFake(() => { });
views.forEach(viewName => {
window.localStorage.setItem(boardView, viewName);
expect(Utils.boardView()).to.equal(viewName);
});
});
it('returns a default if nothing is set', function() {
sinon.stub(Meteor, 'user').callsFake(() => {});
it('returns a default if nothing is set', function () {
sinon.stub(Meteor, 'user').callsFake(() => { });
expect(Utils.boardView()).to.equal('board-view-swimlanes');
expect(window.localStorage.getItem(boardView)).to.equal('board-view-swimlanes');
});
});
describe(Utils.myCardsSort.name, function() {
describe(Utils.myCardsSort.name, function () {
it('has no tests yet');
});
describe(Utils.myCardsSortToggle.name, function() {
describe(Utils.myCardsSortToggle.name, function () {
it('has no tests yet');
});
describe(Utils.setMyCardsSort.name, function() {
describe(Utils.setMyCardsSort.name, function () {
it('has no tests yet');
});
describe(Utils.archivedBoardIds.name, function() {
describe(Utils.archivedBoardIds.name, function () {
it('has no tests yet');
});
describe(Utils.dueCardsView.name, function() {
describe(Utils.dueCardsView.name, function () {
it('has no tests yet');
});
describe(Utils.setDueCardsView.name, function() {
describe(Utils.setDueCardsView.name, function () {
it('has no tests yet');
});
describe(Utils.goBoardId.name, function() {
describe(Utils.goBoardId.name, function () {
it('has no tests yet');
});
describe(Utils.goCardId.name, function() {
describe(Utils.goCardId.name, function () {
it('has no tests yet');
});
describe(Utils.processUploadedAttachment.name, function() {
describe(Utils.processUploadedAttachment.name, function () {
it('has no tests yet');
});
describe(Utils.shrinkImage.name, function() {
describe(Utils.shrinkImage.name, function () {
it('has no tests yet');
});
describe(Utils.capitalize.name, function() {
describe(Utils.capitalize.name, function () {
it('has no tests yet');
});
describe(Utils.isMiniScreen.name, function() {
describe(Utils.isMiniScreen.name, function () {
it('has no tests yet');
});
describe(Utils.isShowDesktopDragHandles.name, function() {
describe(Utils.isShowDesktopDragHandles.name, function () {
it('has no tests yet');
});
describe(Utils.isMiniScreenOrShowDesktopDragHandles.name, function() {
describe(Utils.isTouchScreenOrShowDesktopDragHandles.name, function () {
it('has no tests yet');
});
describe(Utils.calculateIndexData.name, function() {
describe(Utils.calculateIndexData.name, function () {
it('has no tests yet');
});
describe(Utils.calculateIndex.name, function() {
describe(Utils.calculateIndex.name, function () {
it('has no tests yet');
});
describe(Utils.manageCustomUI.name, function() {
describe(Utils.manageCustomUI.name, function () {
it('has no tests yet');
});
describe(Utils.setCustomUI.name, function() {
describe(Utils.setCustomUI.name, function () {
it('has no tests yet');
});
describe(Utils.setMatomo.name, function() {
describe(Utils.setMatomo.name, function () {
it('has no tests yet');
});
describe(Utils.manageMatomo.name, function() {
describe(Utils.manageMatomo.name, function () {
it('has no tests yet');
});
describe(Utils.getTriggerActionDesc.name, function() {
describe(Utils.getTriggerActionDesc.name, function () {
it('has no tests yet');
});
});

View file

@ -40,7 +40,7 @@ Utils = {
const ret = Cards.findOne(cardId);
return ret;
},
reload () {
reload() {
// we move all window.location.reload calls into this function
// so we can disable it when running tests.
// This is because we are not allowed to override location.reload but
@ -201,14 +201,14 @@ Utils = {
image = document.createElement('img');
const maxSize = options.maxSize || 1024;
const ratio = options.ratio || 1.0;
const next = function(result) {
const next = function (result) {
image = null;
canvas = null;
if (typeof callback === 'function') {
callback(result);
}
};
image.onload = function() {
image.onload = function () {
let width = this.width,
height = this.height;
let changed = false;
@ -237,7 +237,7 @@ Utils = {
next(changed);
}
};
image.onerror = function() {
image.onerror = function () {
next(false);
};
image.src = dataurl;
@ -256,35 +256,34 @@ Utils = {
// OLD WINDOW WIDTH DETECTION:
this.windowResizeDep.depend();
return $(window).width() <= 800;
},
isTouchScreen() {
// NEW TOUCH DEVICE DETECTION:
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Browser_detection_using_the_user_agent
/*
var hasTouchScreen = false;
if ("maxTouchPoints" in navigator) {
hasTouchScreen = navigator.maxTouchPoints > 0;
hasTouchScreen = navigator.maxTouchPoints > 0;
} else if ("msMaxTouchPoints" in navigator) {
hasTouchScreen = navigator.msMaxTouchPoints > 0;
hasTouchScreen = navigator.msMaxTouchPoints > 0;
} else {
var mQ = window.matchMedia && matchMedia("(pointer:coarse)");
if (mQ && mQ.media === "(pointer:coarse)") {
hasTouchScreen = !!mQ.matches;
} else if ('orientation' in window) {
hasTouchScreen = true; // deprecated, but good fallback
} else {
// Only as a last resort, fall back to user agent sniffing
var UA = navigator.userAgent;
hasTouchScreen = (
/\b(BlackBerry|webOS|iPhone|IEMobile)\b/i.test(UA) ||
/\b(Android|Windows Phone|iPad|iPod)\b/i.test(UA)
);
}
var mQ = window.matchMedia && matchMedia("(pointer:coarse)");
if (mQ && mQ.media === "(pointer:coarse)") {
hasTouchScreen = !!mQ.matches;
} else if ('orientation' in window) {
hasTouchScreen = true; // deprecated, but good fallback
} else {
// Only as a last resort, fall back to user agent sniffing
var UA = navigator.userAgent;
hasTouchScreen = (
/\b(BlackBerry|webOS|iPhone|IEMobile)\b/i.test(UA) ||
/\b(Android|Windows Phone|iPad|iPod)\b/i.test(UA)
);
}
}
*/
//if (hasTouchScreen)
// document.getElementById("exampleButton").style.padding="1em";
//return false;
return hasTouchScreen;
},
// returns if desktop drag handles are enabled
@ -300,8 +299,8 @@ Utils = {
},
// returns if mini screen or desktop drag handles
isMiniScreenOrShowDesktopDragHandles() {
return this.isMiniScreen() || this.isShowDesktopDragHandles();
isTouchScreenOrShowDesktopDragHandles() {
return this.isTouchScreen() || this.isShowDesktopDragHandles();
},
calculateIndexData(prevData, nextData, nItems = 1) {
@ -396,7 +395,7 @@ Utils = {
window._paq.push(['trackPageView']);
window._paq.push(['enableLinkTracking']);
(function() {
(function () {
window._paq.push(['setTrackerUrl', `${data.address}piwik.php`]);
window._paq.push(['setSiteId', data.siteId]);
@ -500,8 +499,8 @@ Utils = {
copyTextToClipboard(text) {
let ret;
if (navigator.clipboard) {
ret = navigator.clipboard.writeText(text).then(function() {
}, function(err) {
ret = navigator.clipboard.writeText(text).then(function () {
}, function (err) {
console.error('Async: Could not copy text: ', err);
});
} else {