mirror of
https://github.com/wekan/wekan.git
synced 2026-03-12 00:22:34 +01:00
Added back feature: Toggle Drag Handles. Improved positions of Add List etc buttons.
Thanks to xet7 !
This commit is contained in:
parent
00793c39f8
commit
5cb712bee4
12 changed files with 85 additions and 86 deletions
|
|
@ -68,6 +68,7 @@ Meteor.startup(() => {
|
||||||
Tracker.autorun(() => {
|
Tracker.autorun(() => {
|
||||||
if (Meteor.userId()) {
|
if (Meteor.userId()) {
|
||||||
Meteor.subscribe('userGreyIcons');
|
Meteor.subscribe('userGreyIcons');
|
||||||
|
Meteor.subscribe('userDesktopDragHandles');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -124,7 +124,8 @@ template(name='checklistItemDetail')
|
||||||
role="checkbox" aria-checked="{{#if item.isFinished }}true{{else}}false{{/if}}" tabindex="0")
|
role="checkbox" aria-checked="{{#if item.isFinished }}true{{else}}false{{/if}}" tabindex="0")
|
||||||
if canModifyCard
|
if canModifyCard
|
||||||
span.check-box-unicode {{#if item.isFinished }}✅{{else}}⬜{{/if}}
|
span.check-box-unicode {{#if item.isFinished }}✅{{else}}⬜{{/if}}
|
||||||
span.checklistitem-handle(title="{{_ 'dragChecklistItem'}}") ↕️
|
if isTouchScreenOrShowDesktopDragHandles
|
||||||
|
span.checklistitem-handle(title="{{_ 'dragChecklistItem'}}") ↕️
|
||||||
.item-title.js-open-inlined-form.is-editable(class="{{#if item.isFinished }}is-checked{{/if}}")
|
.item-title.js-open-inlined-form.is-editable(class="{{#if item.isFinished }}is-checked{{/if}}")
|
||||||
+viewer
|
+viewer
|
||||||
= item.title
|
= item.title
|
||||||
|
|
|
||||||
|
|
@ -44,10 +44,12 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.minicard-details-menu-with-handle {
|
.minicard-details-menu-with-handle {
|
||||||
float: right;
|
position: absolute;
|
||||||
|
right: 0.7vw;
|
||||||
|
top: 0.7vh;
|
||||||
font-size: clamp(14px, 3vw, 18px);
|
font-size: clamp(14px, 3vw, 18px);
|
||||||
padding-right: 4vw;
|
padding: 0;
|
||||||
padding-left: 0.7vw;
|
z-index: 10;
|
||||||
}
|
}
|
||||||
.minicard-details-menu {
|
.minicard-details-menu {
|
||||||
float: right;
|
float: right;
|
||||||
|
|
@ -133,9 +135,10 @@
|
||||||
width: clamp(20px, 2.5vw, 28px);
|
width: clamp(20px, 2.5vw, 28px);
|
||||||
height: clamp(20px, 2.5vw, 28px);
|
height: clamp(20px, 2.5vw, 28px);
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0.7vw;
|
right: 3vw;
|
||||||
top: 0.7vh;
|
top: 0.7vh;
|
||||||
display: none;
|
display: none;
|
||||||
|
z-index: 10;
|
||||||
}
|
}
|
||||||
@media only screen {
|
@media only screen {
|
||||||
.minicard .handle {
|
.minicard .handle {
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,12 @@ 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="{{#if colorClass}}minicard-{{colorClass}}{{/if}}")
|
class="{{#if colorClass}}minicard-{{colorClass}}{{/if}}")
|
||||||
|
if canMoveCard
|
||||||
|
if isTouchScreenOrShowDesktopDragHandles
|
||||||
|
.handle
|
||||||
|
| ↕️
|
||||||
if canModifyCard
|
if canModifyCard
|
||||||
a.minicard-details-menu-with-handle.js-open-minicard-details-menu(title="{{_ 'cardDetailsActionsPopup-title'}}") ☰
|
a.minicard-details-menu-with-handle.js-open-minicard-details-menu(title="{{_ 'cardDetailsActionsPopup-title'}}") ☰
|
||||||
if canMoveCard
|
|
||||||
.handle
|
|
||||||
| ↕️
|
|
||||||
.dates
|
.dates
|
||||||
if getReceived
|
if getReceived
|
||||||
.date
|
.date
|
||||||
|
|
|
||||||
|
|
@ -179,56 +179,42 @@ body.list-resizing-active * {
|
||||||
margin-right: 120px !important;
|
margin-right: 120px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Position drag handle at top-right corner for ALL lists */
|
/* Position elements from right to left: hamburger, add card, drag handle */
|
||||||
.list-header .list-header-handle {
|
.list-header .js-open-list-menu {
|
||||||
/* Position at top-right corner, aligned with title text top */
|
|
||||||
position: absolute !important;
|
position: absolute !important;
|
||||||
top: 2.5vh !important;
|
top: 2.5vh !important;
|
||||||
right: 1.5vw !important;
|
right: 1.5vw !important;
|
||||||
/* Ensure it's above other elements */
|
|
||||||
z-index: 15 !important;
|
z-index: 15 !important;
|
||||||
/* Remove margin since it's absolutely positioned */
|
|
||||||
margin-right: 0 !important;
|
|
||||||
/* Ensure proper display */
|
|
||||||
display: inline-block !important;
|
display: inline-block !important;
|
||||||
/* Ensure it's clickable and shows proper cursor */
|
|
||||||
cursor: move !important;
|
|
||||||
pointer-events: auto !important;
|
|
||||||
/* Add some padding for better clickability */
|
|
||||||
padding: 4px !important;
|
padding: 4px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ensure buttons maintain original positioning */
|
.list-header .list-header-plus-top {
|
||||||
.js-swimlane .list[style*="--list-width"] .list-header .list-header-plus-top,
|
position: absolute !important;
|
||||||
.js-swimlane .list[style*="--list-width"] .list-header .js-collapse,
|
top: 2.5vh !important;
|
||||||
.js-swimlane .list[style*="--list-width"] .list-header .js-open-list-menu,
|
right: 3.25vw !important;
|
||||||
.dragscroll .list[style*="--list-width"] .list-header .list-header-plus-top,
|
z-index: 15 !important;
|
||||||
.dragscroll .list[style*="--list-width"] .list-header .js-collapse,
|
|
||||||
.dragscroll .list[style*="--list-width"] .list-header .js-open-list-menu,
|
|
||||||
[id^="swimlane-"] .list[style*="--list-width"] .list-header .list-header-plus-top,
|
|
||||||
[id^="swimlane-"] .list[style*="--list-width"] .list-header .js-collapse,
|
|
||||||
[id^="swimlane-"] .list[style*="--list-width"] .list-header .js-open-list-menu {
|
|
||||||
/* Use original positioning to maintain layout */
|
|
||||||
position: relative !important;
|
|
||||||
/* Maintain original spacing */
|
|
||||||
margin-right: 15px !important;
|
|
||||||
/* Ensure proper display */
|
|
||||||
display: inline-block !important;
|
display: inline-block !important;
|
||||||
|
padding: 4px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ensure watch icon and card count maintain original positioning */
|
.list-header .list-header-handle-desktop {
|
||||||
.js-swimlane .list[style*="--list-width"] .list-header .list-header-watch-icon,
|
position: absolute !important;
|
||||||
.dragscroll .list[style*="--list-width"] .list-header .list-header-watch-icon,
|
top: 2.5vh !important;
|
||||||
[id^="swimlane-"] .list[style*="--list-width"] .list-header .list-header-watch-icon,
|
right: 6.5vw !important;
|
||||||
.js-swimlane .list[style*="--list-width"] .list-header .cardCount,
|
z-index: 15 !important;
|
||||||
.dragscroll .list[style*="--list-width"] .list-header .cardCount,
|
|
||||||
[id^="swimlane-"] .list[style*="--list-width"] .list-header .cardCount {
|
|
||||||
/* Use original positioning to maintain layout */
|
|
||||||
position: relative !important;
|
|
||||||
/* Maintain original spacing */
|
|
||||||
margin-right: 15px !important;
|
|
||||||
/* Ensure proper display */
|
|
||||||
display: inline-block !important;
|
display: inline-block !important;
|
||||||
|
cursor: move !important;
|
||||||
|
pointer-events: auto !important;
|
||||||
|
padding: 4px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Anchor header action buttons within header during resize */
|
||||||
|
.list .list-header { position: relative; z-index: 5; }
|
||||||
|
.list .list-header .js-open-list-menu,
|
||||||
|
.list .list-header .list-header-plus-top,
|
||||||
|
.list .list-header .list-header-handle-desktop {
|
||||||
|
position: absolute !important;
|
||||||
}
|
}
|
||||||
[id^="swimlane-"] .list:first-child {
|
[id^="swimlane-"] .list:first-child {
|
||||||
min-width: 2.5vw;
|
min-width: 2.5vw;
|
||||||
|
|
|
||||||
|
|
@ -64,12 +64,9 @@ template(name="listHeader")
|
||||||
else
|
else
|
||||||
a.list-header-menu-icon.js-select-list ▶️
|
a.list-header-menu-icon.js-select-list ▶️
|
||||||
unless currentUser.isWorker
|
unless currentUser.isWorker
|
||||||
a.list-header-handle.handle.js-list-handle ↕️
|
if isTouchScreenOrShowDesktopDragHandles
|
||||||
else if currentUser.isBoardMember
|
|
||||||
if currentUser.isBoardMember
|
|
||||||
unless currentUser.isCommentOnly
|
|
||||||
unless currentUser.isWorker
|
|
||||||
a.list-header-handle.handle.js-list-handle ↕️
|
a.list-header-handle.handle.js-list-handle ↕️
|
||||||
|
else if currentUser.isBoardMember
|
||||||
if isWatching
|
if isWatching
|
||||||
i.list-header-watch-icon | 👁️
|
i.list-header-watch-icon | 👁️
|
||||||
unless collapsed
|
unless collapsed
|
||||||
|
|
@ -77,10 +74,11 @@ template(name="listHeader")
|
||||||
unless currentUser.isCommentOnly
|
unless currentUser.isCommentOnly
|
||||||
//if isBoardAdmin
|
//if isBoardAdmin
|
||||||
// a.fa.js-list-star.list-header-plus-top(class="fa-star{{#unless starred}}-o{{/unless}}")
|
// a.fa.js-list-star.list-header-plus-top(class="fa-star{{#unless starred}}-o{{/unless}}")
|
||||||
|
if isTouchScreenOrShowDesktopDragHandles
|
||||||
|
a.list-header-handle-desktop.handle.js-list-handle(title="{{_ 'drag-list'}}") ↕️
|
||||||
if canSeeAddCard
|
if canSeeAddCard
|
||||||
a.js-add-card.list-header-plus-top(title="{{_ 'add-card-to-top-of-list'}}") ➕
|
a.js-add-card.list-header-plus-top(title="{{_ 'add-card-to-top-of-list'}}") ➕
|
||||||
|
a.js-open-list-menu(title="{{_ 'listActionPopup-title'}}") ☰
|
||||||
a.js-open-list-menu(title="{{_ 'listActionPopup-title'}}") ☰
|
|
||||||
|
|
||||||
template(name="editListTitleForm")
|
template(name="editListTitleForm")
|
||||||
.list-composer
|
.list-composer
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,14 @@ template(name="header")
|
||||||
span.zoom-display {{zoomLevel}}%
|
span.zoom-display {{zoomLevel}}%
|
||||||
input.zoom-input.js-zoom-input(type="number" value=zoomLevel min="50" max="300" step="10" style="display: none;")
|
input.zoom-input.js-zoom-input(type="number" value=zoomLevel min="50" max="300" step="10" style="display: none;")
|
||||||
|
|
||||||
|
// Drag handles toggle - between zoom and mobile mode toggle
|
||||||
|
a.board-header-btn.js-toggle-desktop-drag-handles(title="{{_ 'show-desktop-drag-handles'}}")
|
||||||
|
| ↕️
|
||||||
|
if isShowDesktopDragHandles
|
||||||
|
| ✅
|
||||||
|
unless isShowDesktopDragHandles
|
||||||
|
| 🚫
|
||||||
|
|
||||||
if isMiniScreen
|
if isMiniScreen
|
||||||
ul.header-quick-access-list
|
ul.header-quick-access-list
|
||||||
if currentList
|
if currentList
|
||||||
|
|
@ -44,12 +52,6 @@ template(name="header")
|
||||||
a(href="{{pathFor 'board' id=_id slug=slug}}")
|
a(href="{{pathFor 'board' id=_id slug=slug}}")
|
||||||
+viewer
|
+viewer
|
||||||
= title
|
= title
|
||||||
//a.js-toggle-desktop-drag-handles(title="{{_ 'show-desktop-drag-handles'}}" alt="{{_ 'show-desktop-drag-handles'}}")
|
|
||||||
// i.fa.fa-arrows
|
|
||||||
// if isShowDesktopDragHandles
|
|
||||||
// i.fa.fa-check-square-o
|
|
||||||
// unless isShowDesktopDragHandles
|
|
||||||
// i.fa.fa-ban
|
|
||||||
#header-new-board-icon
|
#header-new-board-icon
|
||||||
else
|
else
|
||||||
ul.header-quick-access-list
|
ul.header-quick-access-list
|
||||||
|
|
@ -64,12 +66,7 @@ template(name="header")
|
||||||
= title
|
= title
|
||||||
else
|
else
|
||||||
li.current.empty {{_ 'quick-access-description'}}
|
li.current.empty {{_ 'quick-access-description'}}
|
||||||
//a.js-toggle-desktop-drag-handles(title="{{_ 'show-desktop-drag-handles'}}" alt="{{_ 'show-desktop-drag-handles'}}")
|
#header-new-board-icon
|
||||||
// i.fa.fa-arrows
|
|
||||||
// if isShowDesktopDragHandles
|
|
||||||
// i.fa.fa-check-square-o
|
|
||||||
// unless isShowDesktopDragHandles
|
|
||||||
// i.fa.fa-ban
|
|
||||||
// Next line is used only for spacing at header,
|
// Next line is used only for spacing at header,
|
||||||
// there is no visible clickable icon.
|
// there is no visible clickable icon.
|
||||||
#header-new-board-icon
|
#header-new-board-icon
|
||||||
|
|
|
||||||
|
|
@ -132,11 +132,10 @@ Template.header.events({
|
||||||
Session.set('currentCard', null);
|
Session.set('currentCard', null);
|
||||||
},
|
},
|
||||||
'click .js-toggle-desktop-drag-handles'() {
|
'click .js-toggle-desktop-drag-handles'() {
|
||||||
//currentUser = Meteor.user();
|
currentUser = Meteor.user();
|
||||||
//if (currentUser) {
|
if (currentUser) {
|
||||||
// Meteor.call('toggleDesktopDragHandles');
|
Meteor.call('toggleDesktopDragHandles');
|
||||||
//} else if (window.localStorage.getItem('showDesktopDragHandles')) {
|
} else if (window.localStorage.getItem('showDesktopDragHandles')) {
|
||||||
if (window.localStorage.getItem('showDesktopDragHandles')) {
|
|
||||||
window.localStorage.removeItem('showDesktopDragHandles');
|
window.localStorage.removeItem('showDesktopDragHandles');
|
||||||
location.reload();
|
location.reload();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -33,12 +33,13 @@ template(name="swimlaneFixedHeader")
|
||||||
| 🔽
|
| 🔽
|
||||||
a.js-open-add-swimlane-menu.swimlane-header-plus-icon(title="{{_ 'add-swimlane'}}")
|
a.js-open-add-swimlane-menu.swimlane-header-plus-icon(title="{{_ 'add-swimlane'}}")
|
||||||
| ➕
|
| ➕
|
||||||
unless isTouchScreen
|
if isTouchScreenOrShowDesktopDragHandles
|
||||||
a.swimlane-header-handle.handle.js-swimlane-header-handle
|
unless isTouchScreen
|
||||||
| ↕️
|
a.swimlane-header-handle.handle.js-swimlane-header-handle
|
||||||
if isTouchScreen
|
| ↕️
|
||||||
a.swimlane-header-miniscreen-handle.handle.js-swimlane-header-handle
|
if isTouchScreen
|
||||||
| ↕️
|
a.swimlane-header-miniscreen-handle.handle.js-swimlane-header-handle
|
||||||
|
| ↕️
|
||||||
a.js-open-swimlane-menu(title="{{_ 'swimlaneActionPopup-title'}}")
|
a.js-open-swimlane-menu(title="{{_ 'swimlaneActionPopup-title'}}")
|
||||||
| ☰
|
| ☰
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -182,12 +182,12 @@ template(name="changeLanguagePopup")
|
||||||
|
|
||||||
template(name="changeSettingsPopup")
|
template(name="changeSettingsPopup")
|
||||||
ul.pop-over-list
|
ul.pop-over-list
|
||||||
//li
|
li
|
||||||
// a.js-toggle-desktop-drag-handles
|
a.js-toggle-desktop-drag-handles
|
||||||
// i.fa.fa-arrows
|
| ↕️
|
||||||
// | {{_ 'show-desktop-drag-handles'}}
|
| {{_ 'show-desktop-drag-handles'}}
|
||||||
// if isShowDesktopDragHandles
|
if isShowDesktopDragHandles
|
||||||
// i.fa.fa-check
|
| ✅
|
||||||
unless currentUser.isWorker
|
unless currentUser.isWorker
|
||||||
li
|
li
|
||||||
label.bold.clear
|
label.bold.clear
|
||||||
|
|
|
||||||
|
|
@ -648,14 +648,18 @@ Utils = {
|
||||||
|
|
||||||
// returns if desktop drag handles are enabled
|
// returns if desktop drag handles are enabled
|
||||||
isShowDesktopDragHandles() {
|
isShowDesktopDragHandles() {
|
||||||
// Always show drag handles on all displays
|
const currentUser = Meteor.user();
|
||||||
return true;
|
if (currentUser) {
|
||||||
|
return currentUser.hasShowDesktopDragHandles();
|
||||||
|
} else {
|
||||||
|
// For non-logged-in users, check localStorage
|
||||||
|
return window.localStorage.getItem('showDesktopDragHandles') === 'true';
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// returns if mini screen or desktop drag handles
|
// returns if mini screen or desktop drag handles
|
||||||
isTouchScreenOrShowDesktopDragHandles() {
|
isTouchScreenOrShowDesktopDragHandles() {
|
||||||
// Always enable drag handles for all displays
|
return Utils.isTouchScreen() || Utils.isShowDesktopDragHandles();
|
||||||
return true;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
calculateIndexData(prevData, nextData, nItems = 1) {
|
calculateIndexData(prevData, nextData, nItems = 1) {
|
||||||
|
|
|
||||||
8
server/publications/userDesktopDragHandles.js
Normal file
8
server/publications/userDesktopDragHandles.js
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
Meteor.publish('userDesktopDragHandles', function() {
|
||||||
|
if (!this.userId) return this.ready();
|
||||||
|
return Meteor.users.find({ _id: this.userId }, {
|
||||||
|
fields: {
|
||||||
|
'profile.showDesktopDragHandles': 1
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
Loading…
Add table
Add a link
Reference in a new issue