mirror of
https://github.com/wekan/wekan.git
synced 2026-03-03 20:30:15 +01:00
Collapse Swimlane, List, Opened Card. Opened Card window X and Y position can be moved freely from drag handle. Fix some dragging not possible. Fix iPhone Safari.
Thanks to xet7 ! Fixes #6040, fixes #6027, fixes #6021, fixes #6002
This commit is contained in:
parent
95d1625a9f
commit
58f4884ad6
37 changed files with 1415 additions and 112 deletions
|
|
@ -231,6 +231,30 @@
|
|||
font-size: 1em !important; /* Keep original icon size */
|
||||
}
|
||||
|
||||
/* Mobile iPhone: scale card details text and icons to 2x */
|
||||
body.mobile-mode.iphone-device .card-details {
|
||||
font-size: 2em !important;
|
||||
}
|
||||
body.mobile-mode.iphone-device .card-details .fa,
|
||||
body.mobile-mode.iphone-device .card-details .icon,
|
||||
body.mobile-mode.iphone-device .card-details i,
|
||||
body.mobile-mode.iphone-device .card-details .emoji-icon,
|
||||
body.mobile-mode.iphone-device .card-details a,
|
||||
body.mobile-mode.iphone-device .card-details p,
|
||||
body.mobile-mode.iphone-device .card-details span,
|
||||
body.mobile-mode.iphone-device .card-details div,
|
||||
body.mobile-mode.iphone-device .card-details button,
|
||||
body.mobile-mode.iphone-device .card-details input,
|
||||
body.mobile-mode.iphone-device .card-details select,
|
||||
body.mobile-mode.iphone-device .card-details textarea {
|
||||
font-size: inherit !important;
|
||||
}
|
||||
/* Section titles slightly larger than content but not as big as card title */
|
||||
body.mobile-mode.iphone-device .card-details .card-details-item-title {
|
||||
font-size: 1.1em !important;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* Ensure scrollbars are positioned correctly */
|
||||
#content[style*="overflow-x: auto"]::-webkit-scrollbar:vertical {
|
||||
width: 12px;
|
||||
|
|
@ -263,6 +287,35 @@
|
|||
animation: fadeIn 0.2s;
|
||||
z-index: 16;
|
||||
}
|
||||
|
||||
/* Fix for mobile Safari: ensure overlay stays behind card details */
|
||||
@media screen and (max-width: 800px) {
|
||||
.board-wrapper .board-canvas .board-overlay {
|
||||
z-index: 17 !important;
|
||||
}
|
||||
|
||||
/* In desktop mode on small screens, still keep overlay behind card */
|
||||
body.desktop-mode .board-wrapper .board-canvas .board-overlay {
|
||||
z-index: 17 !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* In mobile mode, lower the overlay z-index to stay behind card details */
|
||||
body.mobile-mode .board-wrapper .board-canvas .board-overlay {
|
||||
z-index: 17 !important;
|
||||
}
|
||||
|
||||
/* iPhone in desktop mode: remove overlay to avoid blocking card */
|
||||
body.desktop-mode.iphone-device .board-wrapper .board-canvas .board-overlay {
|
||||
display: none !important;
|
||||
pointer-events: none !important;
|
||||
}
|
||||
|
||||
/* Desktop mode: hide overlay to allow multiple cards and board interaction */
|
||||
body.desktop-mode .board-wrapper .board-canvas .board-overlay {
|
||||
display: none !important;
|
||||
pointer-events: none !important;
|
||||
}
|
||||
.board-wrapper .board-canvas.is-dragging-active .open-minicard-composer,
|
||||
.board-wrapper .board-canvas.is-dragging-active .minicard-wrapper.is-checked {
|
||||
display: none;
|
||||
|
|
|
|||
|
|
@ -58,6 +58,10 @@ template(name="boardBody")
|
|||
+swimlane(this)
|
||||
else
|
||||
+listsGroup(currentBoard)
|
||||
//- Render multiple open cards in desktop mode
|
||||
unless isMiniScreen
|
||||
each openCards
|
||||
+cardDetails(this cardIndex=@index)
|
||||
+sidebar
|
||||
|
||||
template(name="calendarView")
|
||||
|
|
|
|||
|
|
@ -516,6 +516,16 @@ BlazeComponent.extendComponent({
|
|||
return isMiniScreen && currentCardId;
|
||||
},
|
||||
|
||||
openCards() {
|
||||
// In desktop mode, return array of all open cards
|
||||
const isMobile = Utils.getMobileMode();
|
||||
if (!isMobile) {
|
||||
const openCardIds = Session.get('openCards') || [];
|
||||
return openCardIds.map(id => ReactiveCache.getCard(id)).filter(card => card);
|
||||
}
|
||||
return [];
|
||||
},
|
||||
|
||||
goHome() {
|
||||
FlowRouter.go('home');
|
||||
},
|
||||
|
|
@ -1642,6 +1652,15 @@ BlazeComponent.extendComponent({
|
|||
|
||||
// Open card the same way as clicking a minicard - set currentCard session
|
||||
// This shows the full card details overlay, not a popup
|
||||
// In desktop mode, add to openCards array to support multiple cards
|
||||
const isMobile = Utils.getMobileMode();
|
||||
if (!isMobile) {
|
||||
const openCards = Session.get('openCards') || [];
|
||||
if (!openCards.includes(cardId)) {
|
||||
openCards.push(cardId);
|
||||
Session.set('openCards', openCards);
|
||||
}
|
||||
}
|
||||
Session.set('currentCard', cardId);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -583,9 +583,9 @@
|
|||
}
|
||||
|
||||
.board-list .board-list-item .multi-selection-checkbox.is-checked {
|
||||
background: #2196F3;
|
||||
border-color: #2196F3;
|
||||
box-shadow: 0 2px 8px rgba(33, 150, 243, 0.6);
|
||||
background: #3cb500;
|
||||
border-color: #3cb500;
|
||||
box-shadow: 0 2px 8px rgba(60, 181, 0, 0.6);
|
||||
width: 24px !important;
|
||||
height: 24px !important;
|
||||
top: auto !important;
|
||||
|
|
@ -601,10 +601,22 @@
|
|||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* Grey checkboxes when grey icons setting is enabled */
|
||||
body.grey-icons-enabled .board-list .board-list-item .multi-selection-checkbox.is-checked {
|
||||
background: #7a7a7a;
|
||||
border-color: #7a7a7a;
|
||||
box-shadow: 0 2px 8px rgba(122, 122, 122, 0.6);
|
||||
}
|
||||
|
||||
body.grey-icons-enabled .board-list.is-multiselection-active .js-board.is-checked {
|
||||
outline: 4px solid #7a7a7a;
|
||||
box-shadow: 0 4px 12px rgba(122, 122, 122, 0.4);
|
||||
}
|
||||
|
||||
.board-list.is-multiselection-active .js-board.is-checked {
|
||||
outline: 4px solid #2196F3;
|
||||
outline: 4px solid #3cb500;
|
||||
outline-offset: -4px;
|
||||
box-shadow: 0 4px 12px rgba(33, 150, 243, 0.4);
|
||||
box-shadow: 0 4px 12px rgba(60, 181, 0, 0.4);
|
||||
}
|
||||
|
||||
/* Visual hint when multiselection is active */
|
||||
|
|
@ -645,7 +657,11 @@
|
|||
}
|
||||
.board-backgrounds-list .board-background-select .background-box i.fa-check {
|
||||
font-size: 25px;
|
||||
color: #fff;
|
||||
color: #3cb500;
|
||||
}
|
||||
/* Grey check icons when grey icons setting is enabled */
|
||||
body.grey-icons-enabled .board-backgrounds-list .board-background-select .background-box i.fa-check {
|
||||
color: #7a7a7a;
|
||||
}
|
||||
|
||||
/* Prevent Grey Icons from affecting checkmarks in background color list */
|
||||
|
|
|
|||
|
|
@ -55,10 +55,9 @@ template(name="cardCustomField-number")
|
|||
template(name="cardCustomField-checkbox")
|
||||
.js-checklist-item.checklist-item(class="{{#if data.value }}is-checked{{/if}}")
|
||||
if canModifyCard
|
||||
.check-box-container
|
||||
.check-box.materialCheckBox(class="{{#if data.value }}is-checked{{/if}}")
|
||||
span.check-box-unicode {{#if data.value }}✅{{else}}⬜{{/if}}
|
||||
else
|
||||
.materialCheckBox(class="{{#if data.value }}is-checked{{/if}}")
|
||||
span.check-box-unicode {{#if data.value }}✅{{else}}⬜{{/if}}
|
||||
|
||||
template(name="cardCustomField-currency")
|
||||
if canModifyCard
|
||||
|
|
|
|||
|
|
@ -112,6 +112,7 @@ CardCustomField.register('cardCustomField');
|
|||
events() {
|
||||
return [
|
||||
{
|
||||
'click .js-checklist-item .check-box-unicode': this.toggleItem,
|
||||
'click .js-checklist-item .check-box-container': this.toggleItem,
|
||||
},
|
||||
];
|
||||
|
|
|
|||
|
|
@ -118,6 +118,65 @@
|
|||
transition: flex-basis 0.1s;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* Desktop mode: position card below board header */
|
||||
body.desktop-mode .card-details:not(.card-details-popup) {
|
||||
position: fixed;
|
||||
width: auto;
|
||||
max-width: 800px;
|
||||
flex-basis: auto;
|
||||
border-radius: 8px;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
/* Default position for first card or when dragged */
|
||||
body.desktop-mode .card-details:not(.card-details-popup):not([style*="left"]):not([style*="top"]) {
|
||||
top: 50px;
|
||||
left: 20px;
|
||||
right: 20px;
|
||||
bottom: 20px;
|
||||
}
|
||||
|
||||
/* Stagger positions for multiple cards using nth-of-type */
|
||||
body.desktop-mode .card-details:not(.card-details-popup):nth-of-type(1) {
|
||||
top: 50px;
|
||||
left: 20px;
|
||||
}
|
||||
body.desktop-mode .card-details:not(.card-details-popup):nth-of-type(2) {
|
||||
top: 80px;
|
||||
left: 50px;
|
||||
}
|
||||
body.desktop-mode .card-details:not(.card-details-popup):nth-of-type(3) {
|
||||
top: 110px;
|
||||
left: 80px;
|
||||
}
|
||||
body.desktop-mode .card-details:not(.card-details-popup):nth-of-type(4) {
|
||||
top: 140px;
|
||||
left: 110px;
|
||||
}
|
||||
body.desktop-mode .card-details:not(.card-details-popup):nth-of-type(5) {
|
||||
top: 170px;
|
||||
left: 140px;
|
||||
}
|
||||
|
||||
/* For expanded cards, set dimensions */
|
||||
body.desktop-mode .card-details:not(.card-details-popup):not(.card-details-collapsed) {
|
||||
right: 20px;
|
||||
bottom: 20px;
|
||||
}
|
||||
|
||||
/* Collapsed card state - hide content and set height to title row only */
|
||||
.card-details.card-details-collapsed .card-details-canvas > *:not(.card-details-header) {
|
||||
display: none;
|
||||
}
|
||||
.card-details.card-details-collapsed {
|
||||
height: auto !important;
|
||||
bottom: auto !important;
|
||||
overflow: visible;
|
||||
}
|
||||
body.desktop-mode .card-details.card-details-collapsed {
|
||||
bottom: auto !important;
|
||||
}
|
||||
.card-details .mCustomScrollBox {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
|
@ -139,6 +198,49 @@
|
|||
display: inline-block;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
/* Collapse toggle triangle */
|
||||
.card-details .card-details-header .card-collapse-toggle {
|
||||
float: left;
|
||||
font-size: 20px;
|
||||
padding: 7px 10px;
|
||||
margin-left: -10px;
|
||||
margin-right: 5px;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
/* Bring to front / Send to back buttons */
|
||||
.card-details .card-details-header .card-bring-to-front,
|
||||
.card-details .card-details-header .card-send-to-back {
|
||||
float: right;
|
||||
font-size: 18px;
|
||||
padding: 7px 8px;
|
||||
margin-right: 5px;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.card-details .card-details-header .card-bring-to-front:hover,
|
||||
.card-details .card-details-header .card-send-to-back:hover {
|
||||
color: #000;
|
||||
background: rgba(0,0,0,0.05);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
/* Drag handle */
|
||||
.card-details .card-details-header .card-drag-handle {
|
||||
font-size: 20px;
|
||||
padding: 8px 10px;
|
||||
margin-right: 10px;
|
||||
cursor: move;
|
||||
user-select: none;
|
||||
display: inline-block;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.card-details .card-details-header .close-card-details,
|
||||
.card-details .card-details-header .maximize-card-details,
|
||||
.card-details .card-details-header .minimize-card-details,
|
||||
|
|
@ -156,11 +258,16 @@
|
|||
font-size: 24px;
|
||||
padding: 5px 10px 5px 10px;
|
||||
margin-right: -8px;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
.card-details .card-details-header .close-card-details-mobile-web {
|
||||
.card-details .card-details-header .close-card-details-mobile-web,
|
||||
.card-details .card-details-header .card-mobile-desktop-toggle {
|
||||
font-size: 24px;
|
||||
padding: 5px;
|
||||
margin-right: 40px;
|
||||
margin-right: 5px;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
.card-details .card-details-header .card-copy-button {
|
||||
font-size: 17px;
|
||||
|
|
@ -181,6 +288,36 @@
|
|||
padding: 10px;
|
||||
margin-right: 30px;
|
||||
}
|
||||
.card-details .card-details-header .card-mobile-desktop-toggle,
|
||||
.card-details .card-details-header .card-zoom-in,
|
||||
.card-details .card-details-header .card-zoom-out {
|
||||
font-size: 24px;
|
||||
padding: 5px 10px 5px 10px;
|
||||
margin-right: 5px;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
float: right;
|
||||
}
|
||||
|
||||
/* Unify all card text to match title size */
|
||||
.card-details {
|
||||
font-size: 1em;
|
||||
}
|
||||
.card-details p,
|
||||
.card-details span,
|
||||
.card-details div,
|
||||
.card-details a,
|
||||
.card-details label,
|
||||
.card-details input,
|
||||
.card-details textarea,
|
||||
.card-details select,
|
||||
.card-details button,
|
||||
.card-details .card-details-item-title,
|
||||
.card-details .card-label,
|
||||
.card-details .viewer {
|
||||
font-size: inherit;
|
||||
line-height: 1.4;
|
||||
}
|
||||
.card-details .card-details-header .card-details-watch {
|
||||
font-size: 17px;
|
||||
padding-left: 7px;
|
||||
|
|
@ -284,6 +421,19 @@
|
|||
position: fixed;
|
||||
resize: both;
|
||||
}
|
||||
|
||||
/* Override for mobile mode even on larger screens */
|
||||
body.mobile-mode .card-details {
|
||||
width: 100vw !important;
|
||||
top: 0 !important;
|
||||
left: 0 !important;
|
||||
right: 0 !important;
|
||||
bottom: 0 !important;
|
||||
height: 100vh !important;
|
||||
max-height: 100vh !important;
|
||||
resize: none !important;
|
||||
}
|
||||
|
||||
.card-details-maximized {
|
||||
padding: 0;
|
||||
flex-shrink: 0;
|
||||
|
|
@ -335,19 +485,53 @@ input[type="submit"].attachment-add-link-submit {
|
|||
}
|
||||
@media screen and (max-width: 800px) {
|
||||
.card-details {
|
||||
width: calc(100% - 1px);
|
||||
padding: 0px 20px 0px 20px;
|
||||
margin: 0px;
|
||||
width: 100% !important;
|
||||
padding: 0px 0px 0px 0px !important;
|
||||
margin: 0px !important;
|
||||
transition: none;
|
||||
overflow-y: revert;
|
||||
overflow-x: revert;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
/* iOS Safari specific fixes */
|
||||
-webkit-overflow-scrolling: touch;
|
||||
position: fixed !important;
|
||||
top: 0 !important;
|
||||
left: 0 !important;
|
||||
right: 0 !important;
|
||||
bottom: 0 !important;
|
||||
z-index: 100 !important;
|
||||
height: 100vh !important;
|
||||
max-height: 100vh !important;
|
||||
border-radius: 0 !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
/* Ensure card details are above everything on mobile */
|
||||
body.mobile-mode .card-details {
|
||||
z-index: 100 !important;
|
||||
width: 100vw !important;
|
||||
left: 0 !important;
|
||||
right: 0 !important;
|
||||
}
|
||||
.card-details .card-details-canvas {
|
||||
width: 100%;
|
||||
padding-left: 0px;
|
||||
padding: 0 15px;
|
||||
}
|
||||
.card-details .card-details-header .close-card-details {
|
||||
margin-right: 0px;
|
||||
display: block !important;
|
||||
}
|
||||
.card-details .card-details-header .close-card-details-mobile-web {
|
||||
display: block !important;
|
||||
margin-right: 5px !important;
|
||||
}
|
||||
.card-details .card-details-header .card-mobile-desktop-toggle {
|
||||
display: block !important;
|
||||
margin-right: 5px !important;
|
||||
}
|
||||
.card-details .card-details-header .card-mobile-desktop-toggle {
|
||||
display: block !important;
|
||||
margin-right: 5px !important;
|
||||
}
|
||||
.card-details .card-details-header .card-details-menu {
|
||||
margin-right: 40px;
|
||||
|
|
@ -373,6 +557,62 @@ input[type="submit"].attachment-add-link-submit {
|
|||
.pop-over > .content-wrapper > .popup-container-depth-0 .card-details-header {
|
||||
margin: 0;
|
||||
}
|
||||
/* iPhone mobile: enlarge header buttons and increase spacing */
|
||||
body.mobile-mode.iphone-device .card-details .card-details-header {
|
||||
padding-right: 16px;
|
||||
}
|
||||
body.mobile-mode.iphone-device .card-details .card-details-header .close-card-details,
|
||||
body.mobile-mode.iphone-device .card-details .card-details-header .maximize-card-details,
|
||||
body.mobile-mode.iphone-device .card-details .card-details-header .minimize-card-details,
|
||||
body.mobile-mode.iphone-device .card-details .card-details-header .card-details-menu-mobile-web,
|
||||
body.mobile-mode.iphone-device .card-details .card-details-header .card-copy-mobile-button,
|
||||
body.mobile-mode.iphone-device .card-details .card-details-header .card-mobile-desktop-toggle,
|
||||
body.mobile-mode.iphone-device .card-details .card-details-header .card-zoom-in,
|
||||
body.mobile-mode.iphone-device .card-details .card-details-header .card-zoom-out {
|
||||
font-size: 2em !important; /* 2x bigger */
|
||||
padding: 0.3em !important;
|
||||
margin-right: 0.75em !important; /* 2x space compared to default */
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
/* Avoid clipping of the close button on the right edge */
|
||||
body.mobile-mode.iphone-device .card-details .card-details-header .close-card-details {
|
||||
margin-right: 0.75em !important;
|
||||
}
|
||||
/* Enlarge the header title too */
|
||||
body.mobile-mode.iphone-device .card-details .card-details-header .card-details-title {
|
||||
font-size: 1.2em !important;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
/* Mobile mode styles - apply when body has mobile-mode class regardless of screen size */
|
||||
body.mobile-mode .card-details {
|
||||
width: 100vw !important;
|
||||
padding: 0px !important;
|
||||
margin: 0px !important;
|
||||
position: fixed !important;
|
||||
top: 0 !important;
|
||||
left: 0 !important;
|
||||
right: 0 !important;
|
||||
bottom: 0 !important;
|
||||
z-index: 100 !important;
|
||||
height: 100vh !important;
|
||||
max-height: 100vh !important;
|
||||
border-radius: 0 !important;
|
||||
box-shadow: none !important;
|
||||
overflow-y: auto !important;
|
||||
overflow-x: hidden !important;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
body.mobile-mode .card-details .card-details-canvas {
|
||||
width: 100% !important;
|
||||
padding: 0 15px !important;
|
||||
}
|
||||
|
||||
body.mobile-mode .card-details .card-details-header .close-card-details,
|
||||
body.mobile-mode .card-details .card-details-header .close-card-details-mobile-web {
|
||||
display: block !important;
|
||||
}
|
||||
.card-details-white {
|
||||
background: #fff !important;
|
||||
|
|
|
|||
|
|
@ -5,16 +5,25 @@ template(name="cardDetails")
|
|||
|
||||
+attachmentViewer
|
||||
|
||||
section.card-details.js-card-details.nodragscroll(class='{{#if cardMaximized}}card-details-maximized{{/if}}' class='{{#if isPopup}}card-details-popup{{/if}}' class='{{#unless isVerticalScrollbars}}no-scrollbars{{/unless}}'): .card-details-canvas
|
||||
section.card-details.js-card-details.nodragscroll(class='{{#if cardMaximized}}card-details-maximized{{/if}}' class='{{#if isPopup}}card-details-popup{{/if}}' class='{{#unless isVerticalScrollbars}}no-scrollbars{{/unless}}' class='{{#if cardCollapsed}}card-details-collapsed{{/if}}'): .card-details-canvas
|
||||
.card-details-header(class='{{#if colorClass}}card-details-{{colorClass}}{{/if}}')
|
||||
+inlinedForm(classNames="js-card-details-title")
|
||||
+editCardTitleForm
|
||||
else
|
||||
unless isMiniScreen
|
||||
unless isPopup
|
||||
span.card-collapse-toggle.js-card-collapse-toggle(title="{{_ 'collapse-card'}}")
|
||||
if cardCollapsed
|
||||
| ▶
|
||||
else
|
||||
| 🔽
|
||||
a.close-card-details.js-close-card-details(title="{{_ 'close-card'}}")
|
||||
| ❌
|
||||
if canModifyCard
|
||||
a.card-bring-to-front.js-card-bring-to-front(title="Bring to front")
|
||||
| ⏫
|
||||
a.card-send-to-back.js-card-send-to-back(title="Send to back")
|
||||
| ⏬
|
||||
if cardMaximized
|
||||
a.minimize-card-details.js-minimize-card-details(title="{{_ 'minimize-card'}}")
|
||||
| 🔽
|
||||
|
|
@ -30,12 +39,28 @@ template(name="cardDetails")
|
|||
href="{{ originRelativeUrl }}"
|
||||
)
|
||||
span.emoji-icon 🔗
|
||||
span.card-drag-handle.js-card-drag-handle(title="Drag card")
|
||||
| ↕️
|
||||
span.copied-tooltip {{_ 'copied'}}
|
||||
else
|
||||
unless isPopup
|
||||
a.close-card-details.js-close-card-details(title="{{_ 'close-card'}}")
|
||||
| ❌
|
||||
a.close-card-details.js-close-card-details(title="{{_ 'close-card'}}")
|
||||
| ❌
|
||||
a.card-zoom-out.js-card-zoom-out(title="{{_ 'zoom-out'}}")
|
||||
| 🔍➖
|
||||
a.card-zoom-in.js-card-zoom-in(title="{{_ 'zoom-in'}}")
|
||||
| 🔍➕
|
||||
a.card-mobile-desktop-toggle.js-card-mobile-desktop-toggle(title="{{_ 'mobile-desktop-toggle'}}")
|
||||
if mobileMode
|
||||
| 🖥️
|
||||
else
|
||||
| 📱
|
||||
if canModifyCard
|
||||
if cardMaximized
|
||||
a.minimize-card-details.js-minimize-card-details(title="{{_ 'minimize-card'}}")
|
||||
| 🔽
|
||||
else
|
||||
a.maximize-card-details.js-maximize-card-details(title="{{_ 'maximize-card'}}")
|
||||
| 🔼
|
||||
a.card-details-menu-mobile-web.js-open-card-details-menu(title="{{_ 'cardDetailsActionsPopup-title'}}")
|
||||
| ☰
|
||||
a.card-copy-mobile-button.js-copy-link(
|
||||
|
|
|
|||
|
|
@ -63,7 +63,11 @@ BlazeComponent.extendComponent({
|
|||
const boardBody = this.parentComponent().parentComponent();
|
||||
//in Miniview parent is Board, not BoardBody.
|
||||
if (boardBody !== null) {
|
||||
boardBody.showOverlay.set(true);
|
||||
// Only show overlay in mobile mode, not in desktop mode
|
||||
const isMobile = Utils.getMobileMode();
|
||||
if (isMobile) {
|
||||
boardBody.showOverlay.set(true);
|
||||
}
|
||||
boardBody.mouseHasEnterCardDetails = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -93,6 +97,18 @@ BlazeComponent.extendComponent({
|
|||
return !Utils.getPopupCardId() && ReactiveCache.getCurrentUser().hasCardMaximized();
|
||||
},
|
||||
|
||||
cardCollapsed() {
|
||||
const user = ReactiveCache.getCurrentUser();
|
||||
if (user && user.profile) {
|
||||
return !!user.profile.cardCollapsed;
|
||||
}
|
||||
if (Users.getPublicCardCollapsed) {
|
||||
const stored = Users.getPublicCardCollapsed();
|
||||
if (typeof stored === 'boolean') return stored;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
presentParentTask() {
|
||||
let result = this.currentBoard.presentParentTask;
|
||||
if (result === null || result === undefined) {
|
||||
|
|
@ -296,13 +312,88 @@ BlazeComponent.extendComponent({
|
|||
return [
|
||||
{
|
||||
...events,
|
||||
'click .js-card-collapse-toggle'() {
|
||||
const user = ReactiveCache.getCurrentUser();
|
||||
const currentState = user && user.profile ? !!user.profile.cardCollapsed : !!Users.getPublicCardCollapsed();
|
||||
if (user) {
|
||||
Meteor.call('setCardCollapsed', !currentState);
|
||||
} else if (Users.setPublicCardCollapsed) {
|
||||
Users.setPublicCardCollapsed(!currentState);
|
||||
}
|
||||
},
|
||||
'click .js-card-bring-to-front'(event) {
|
||||
event.preventDefault();
|
||||
const $card = $(event.target).closest('.card-details');
|
||||
// Find the highest z-index among all cards
|
||||
let maxZ = 100;
|
||||
$('.card-details').each(function() {
|
||||
const z = parseInt($(this).css('z-index')) || 100;
|
||||
if (z > maxZ) maxZ = z;
|
||||
});
|
||||
// Set this card's z-index to be higher
|
||||
$card.css('z-index', maxZ + 1);
|
||||
},
|
||||
'click .js-card-send-to-back'(event) {
|
||||
event.preventDefault();
|
||||
const $card = $(event.target).closest('.card-details');
|
||||
// Find the lowest z-index among all cards
|
||||
let minZ = 100;
|
||||
$('.card-details').each(function() {
|
||||
const z = parseInt($(this).css('z-index')) || 100;
|
||||
if (z < minZ) minZ = z;
|
||||
});
|
||||
// Set this card's z-index to be lower
|
||||
$card.css('z-index', minZ - 1);
|
||||
},
|
||||
'mousedown .js-card-drag-handle'(event) {
|
||||
event.preventDefault();
|
||||
const $card = $(event.target).closest('.card-details');
|
||||
const startX = event.clientX;
|
||||
const startY = event.clientY;
|
||||
const startLeft = $card.offset().left;
|
||||
const startTop = $card.offset().top;
|
||||
|
||||
const onMouseMove = (e) => {
|
||||
const deltaX = e.clientX - startX;
|
||||
const deltaY = e.clientY - startY;
|
||||
$card.css({
|
||||
left: startLeft + deltaX + 'px',
|
||||
top: startTop + deltaY + 'px'
|
||||
});
|
||||
};
|
||||
|
||||
const onMouseUp = () => {
|
||||
$(document).off('mousemove', onMouseMove);
|
||||
$(document).off('mouseup', onMouseUp);
|
||||
};
|
||||
|
||||
$(document).on('mousemove', onMouseMove);
|
||||
$(document).on('mouseup', onMouseUp);
|
||||
},
|
||||
'click .js-close-card-details'() {
|
||||
// Get board ID from either the card data or current board in session
|
||||
const card = this.currentData() || this.data();
|
||||
const boardId = (card && card.boardId) || Utils.getCurrentBoard()._id;
|
||||
const cardId = card && card._id;
|
||||
|
||||
if (boardId) {
|
||||
// Clear the current card session to close the card
|
||||
// In desktop mode, remove from openCards array
|
||||
const isMobile = Utils.getMobileMode();
|
||||
if (!isMobile && cardId) {
|
||||
const openCards = Session.get('openCards') || [];
|
||||
const filtered = openCards.filter(id => id !== cardId);
|
||||
Session.set('openCards', filtered);
|
||||
|
||||
// If this was the current card, clear it
|
||||
if (Session.get('currentCard') === cardId) {
|
||||
Session.set('currentCard', null);
|
||||
}
|
||||
|
||||
// Don't navigate away in desktop mode - just close the card
|
||||
return;
|
||||
}
|
||||
|
||||
// Mobile mode: Clear the current card session to close the card
|
||||
Session.set('currentCard', null);
|
||||
|
||||
// Navigate back to board without card
|
||||
|
|
@ -327,6 +418,34 @@ BlazeComponent.extendComponent({
|
|||
Meteor.call('changeDateFormat', dateFormat);
|
||||
},
|
||||
'click .js-open-card-details-menu': Popup.open('cardDetailsActions'),
|
||||
// Mobile: switch to desktop popup view (maximize)
|
||||
'click .js-mobile-switch-to-desktop'(event) {
|
||||
event.preventDefault();
|
||||
// Switch global mode to desktop so the card appears as desktop popup
|
||||
Utils.setMobileMode(false);
|
||||
},
|
||||
'click .js-card-zoom-in'(event) {
|
||||
event.preventDefault();
|
||||
const current = Utils.getCardZoom();
|
||||
const newZoom = Math.min(3.0, current + 0.1);
|
||||
Utils.setCardZoom(newZoom);
|
||||
},
|
||||
'click .js-card-zoom-out'(event) {
|
||||
event.preventDefault();
|
||||
const current = Utils.getCardZoom();
|
||||
const newZoom = Math.max(0.5, current - 0.1);
|
||||
Utils.setCardZoom(newZoom);
|
||||
},
|
||||
'click .js-card-mobile-desktop-toggle'(event) {
|
||||
event.preventDefault();
|
||||
const currentMode = Utils.getMobileMode();
|
||||
Utils.setMobileMode(!currentMode);
|
||||
},
|
||||
'click .js-card-mobile-desktop-toggle'(event) {
|
||||
event.preventDefault();
|
||||
const currentMode = Utils.getMobileMode();
|
||||
Utils.setMobileMode(!currentMode);
|
||||
},
|
||||
'submit .js-card-description'(event) {
|
||||
event.preventDefault();
|
||||
const description = this.currentComponent().getValue();
|
||||
|
|
|
|||
|
|
@ -37,14 +37,23 @@ textarea.js-edit-checklist-item {
|
|||
.checklist-progress-bar-container .checklist-progress-bar {
|
||||
width: 80%;
|
||||
height: 10px;
|
||||
background-color: #d6ebff !important;
|
||||
border-radius: 16px;
|
||||
}
|
||||
.checklist-progress-bar-container .checklist-progress-bar .checklist-progress {
|
||||
color: #fff !important;
|
||||
background-color: #2196f3 !important;
|
||||
background-color: #3cb500 !important;
|
||||
padding: 0.01em 16px;
|
||||
border-radius: 16px;
|
||||
height: 100%;
|
||||
}
|
||||
/* Grey progress bar when grey icons setting is enabled */
|
||||
body.grey-icons-enabled .checklist-progress-bar-container .checklist-progress-bar {
|
||||
background-color: #d9d9d9;
|
||||
}
|
||||
body.grey-icons-enabled .checklist-progress-bar-container .checklist-progress-bar .checklist-progress {
|
||||
background-color: #7a7a7a !important;
|
||||
}
|
||||
.checklist-title {
|
||||
padding: 10px;
|
||||
}
|
||||
|
|
@ -105,6 +114,25 @@ textarea.js-edit-checklist-item {
|
|||
height: auto;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* iPhone mobile: larger checklist titles and more spacing between items */
|
||||
body.mobile-mode.iphone-device .checklist-title .title {
|
||||
font-size: 1.3em !important;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
body.mobile-mode.iphone-device .checklist-item {
|
||||
margin-top: 12px !important;
|
||||
margin-bottom: 8px !important;
|
||||
padding: 8px 4px !important;
|
||||
min-height: 44px; /* iOS recommended touch target size */
|
||||
}
|
||||
|
||||
body.mobile-mode.iphone-device .checklist-item span.checklistitem-handle {
|
||||
font-size: 1.5em !important;
|
||||
padding-right: 15px !important;
|
||||
width: 1.5em !important;
|
||||
}
|
||||
.checklist-item.is-checked.invisible {
|
||||
opacity: 0;
|
||||
height: 0;
|
||||
|
|
@ -134,6 +162,27 @@ textarea.js-edit-checklist-item {
|
|||
border-bottom: 2px solid #3cb500;
|
||||
border-right: 2px solid #3cb500;
|
||||
}
|
||||
/* Unicode checkbox icons styling */
|
||||
.checklist-item .check-box-unicode,
|
||||
.cardCustomField-checkbox .check-box-unicode {
|
||||
font-size: 1.3em;
|
||||
margin-right: 8px;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
line-height: 1;
|
||||
}
|
||||
/* Grey checkmarks when grey icons setting is enabled */
|
||||
body.grey-icons-enabled .checklist-item .check-box.is-checked {
|
||||
border-bottom: 2px solid #7a7a7a;
|
||||
border-right: 2px solid #7a7a7a;
|
||||
}
|
||||
body.grey-icons-enabled .checklist-item .check-box-unicode,
|
||||
body.grey-icons-enabled .cardCustomField-checkbox .check-box-unicode {
|
||||
filter: grayscale(100%);
|
||||
-webkit-filter: grayscale(100%);
|
||||
opacity: 0.85;
|
||||
}
|
||||
.checklist-item .item-title {
|
||||
flex: 1;
|
||||
}
|
||||
|
|
@ -155,6 +204,7 @@ textarea.js-edit-checklist-item {
|
|||
width: 1.2em;
|
||||
text-align: center;
|
||||
color: #999;
|
||||
cursor: pointer;
|
||||
}
|
||||
.js-delete-checklist-item,
|
||||
.js-convert-checklist-item-to-card {
|
||||
|
|
|
|||
|
|
@ -125,14 +125,13 @@ template(name='checklistItemDetail')
|
|||
.js-checklist-item.checklist-item(class="{{#if item.isFinished }}is-checked{{#if checklist.hideCheckedChecklistItems}} invisible{{/if}}{{/if}}{{#if checklist.hideAllChecklistItems}} is-checked invisible{{/if}}"
|
||||
role="checkbox" aria-checked="{{#if item.isFinished }}true{{else}}false{{/if}}" tabindex="0")
|
||||
if canModifyCard
|
||||
.check-box-container
|
||||
.check-box.materialCheckBox(class="{{#if item.isFinished }}is-checked{{/if}}")
|
||||
span.check-box-unicode {{#if item.isFinished }}✅{{else}}⬜{{/if}}
|
||||
span.checklistitem-handle(title="{{_ 'dragChecklistItem'}}") ↕️
|
||||
.item-title.js-open-inlined-form.is-editable(class="{{#if item.isFinished }}is-checked{{/if}}")
|
||||
+viewer
|
||||
= item.title
|
||||
else
|
||||
.materialCheckBox(class="{{#if item.isFinished }}is-checked{{/if}}")
|
||||
span.check-box-unicode {{#if item.isFinished }}✅{{else}}⬜{{/if}}
|
||||
.item-title(class="{{#if item.isFinished }}is-checked{{/if}}")
|
||||
+viewer
|
||||
= item.title
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ BlazeComponent.extendComponent({
|
|||
$(self.itemsDom).sortable('option', 'disabled', !userIsMember());
|
||||
if (Utils.isTouchScreenOrShowDesktopDragHandles()) {
|
||||
$(self.itemsDom).sortable({
|
||||
handle: 'span.fa.checklistitem-handle',
|
||||
handle: 'span.checklistitem-handle',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -360,6 +360,7 @@ BlazeComponent.extendComponent({
|
|||
events() {
|
||||
return [
|
||||
{
|
||||
'click .js-checklist-item .check-box-unicode': this.toggleItem,
|
||||
'click .js-checklist-item .check-box-container': this.toggleItem,
|
||||
},
|
||||
];
|
||||
|
|
|
|||
|
|
@ -87,6 +87,15 @@ textarea.js-edit-subtask-item {
|
|||
top: 0;
|
||||
bottom: -600px;
|
||||
right: 0;
|
||||
z-index: 15;
|
||||
}
|
||||
|
||||
/* Fix for mobile Safari: ensure this doesn't block card interaction */
|
||||
@media screen and (max-width: 800px) {
|
||||
#card-details-overlay {
|
||||
z-index: 15;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
.subtasks {
|
||||
background: #f7f7f7;
|
||||
|
|
@ -127,6 +136,25 @@ textarea.js-edit-subtask-item {
|
|||
border-bottom: 2px solid #3cb500;
|
||||
border-right: 2px solid #3cb500;
|
||||
}
|
||||
/* Unicode checkbox icons styling */
|
||||
.subtasks-item .check-box-unicode {
|
||||
font-size: 1.3em;
|
||||
margin-right: 8px;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
line-height: 1;
|
||||
}
|
||||
/* Grey checkmarks when grey icons setting is enabled */
|
||||
body.grey-icons-enabled .subtasks-item .check-box.is-checked {
|
||||
border-bottom: 2px solid #7a7a7a;
|
||||
border-right: 2px solid #7a7a7a;
|
||||
}
|
||||
body.grey-icons-enabled .subtasks-item .check-box-unicode {
|
||||
filter: grayscale(100%);
|
||||
-webkit-filter: grayscale(100%);
|
||||
opacity: 0.85;
|
||||
}
|
||||
.subtasks-item .item-title {
|
||||
flex: 1;
|
||||
padding-left: 10px;
|
||||
|
|
|
|||
|
|
@ -74,12 +74,12 @@ template(name="subtasksItems")
|
|||
template(name='subtaskItemDetail')
|
||||
.js-subtasks-item.subtasks-item
|
||||
if canModifyCard
|
||||
.check-box.materialCheckBox(class="{{#if item.isFinished }}is-checked{{/if}}")
|
||||
span.check-box-unicode {{#if item.isFinished }}✅{{else}}⬜{{/if}}
|
||||
.item-title.js-open-inlined-form.is-editable(class="{{#if item.isFinished }}is-checked{{/if}}")
|
||||
+viewer
|
||||
= item.title
|
||||
else
|
||||
.materialCheckBox(class="{{#if item.isFinished }}is-checked{{/if}}")
|
||||
span.check-box-unicode {{#if item.isFinished }}✅{{else}}⬜{{/if}}
|
||||
.item-title(class="{{#if item.isFinished }}is-checked{{/if}}")
|
||||
+viewer
|
||||
= item.title
|
||||
|
|
|
|||
|
|
@ -104,7 +104,19 @@ BlazeComponent.extendComponent({
|
|||
}).register('subtasks');
|
||||
|
||||
BlazeComponent.extendComponent({
|
||||
// ...
|
||||
toggleItem() {
|
||||
const item = this.currentData().item;
|
||||
if (item && item._id) {
|
||||
item.toggleItem();
|
||||
}
|
||||
},
|
||||
events() {
|
||||
return [
|
||||
{
|
||||
'click .js-subtasks-item .check-box-unicode': this.toggleItem,
|
||||
},
|
||||
];
|
||||
},
|
||||
}).register('subtaskItemDetail');
|
||||
|
||||
BlazeComponent.extendComponent({
|
||||
|
|
|
|||
|
|
@ -315,11 +315,18 @@ textarea::-moz-placeholder {
|
|||
margin-right: 6px;
|
||||
border-top: 2px solid transparent;
|
||||
border-left: 2px solid transparent;
|
||||
border-bottom: 2px solid #3cb500;
|
||||
border-right: 2px solid #3cb500;
|
||||
transform: rotate(40deg);
|
||||
-webkit-backface-visibility: hidden;
|
||||
backface-visibility: hidden;
|
||||
transform-origin: 100% 100%;
|
||||
}
|
||||
/* Grey checkmarks when grey icons setting is enabled */
|
||||
body.grey-icons-enabled .materialCheckBox.is-checked {
|
||||
border-bottom: 2px solid #7a7a7a;
|
||||
border-right: 2px solid #7a7a7a;
|
||||
}
|
||||
.button-link {
|
||||
background: #fff;
|
||||
background: linear-gradient(#fff, #f5f5f5);
|
||||
|
|
|
|||
|
|
@ -282,7 +282,7 @@ body.list-resizing-active * {
|
|||
margin: 0 auto;
|
||||
}
|
||||
.list.list-collapsed .list-header .js-collapse {
|
||||
margin: 0 auto 20px auto;
|
||||
margin: 0 auto 0 auto;
|
||||
z-index: 10;
|
||||
padding: 8px 12px;
|
||||
font-size: 12px;
|
||||
|
|
@ -290,6 +290,12 @@ body.list-resizing-active * {
|
|||
display: block;
|
||||
width: fit-content;
|
||||
}
|
||||
.list.list-collapsed .list-header .list-header-handle {
|
||||
position: absolute !important;
|
||||
top: 30px !important;
|
||||
right: 1.5vw !important;
|
||||
z-index: 15 !important;
|
||||
}
|
||||
.list.list-collapsed .list-header .list-rotated {
|
||||
width: auto !important;
|
||||
height: auto !important;
|
||||
|
|
@ -297,7 +303,6 @@ body.list-resizing-active * {
|
|||
position: relative !important;
|
||||
overflow: visible !important;
|
||||
}
|
||||
|
||||
.list.list-collapsed .list-header .list-rotated h2.list-header-name {
|
||||
text-align: left;
|
||||
overflow: visible;
|
||||
|
|
@ -308,15 +313,15 @@ body.list-resizing-active * {
|
|||
color: #333;
|
||||
background-color: rgba(255, 255, 255, 0.95);
|
||||
border: 1px solid #ddd;
|
||||
padding: 8px 4px;
|
||||
padding: 0;
|
||||
border-radius: 4px;
|
||||
margin: 0 auto;
|
||||
width: 25vh;
|
||||
height: 60vh;
|
||||
margin: 0;
|
||||
width: 100vh;
|
||||
height: 30px;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
left: 40px;
|
||||
top: 50%;
|
||||
transform: translate(calc(-50% + 50px), -50%) rotate(0deg);
|
||||
transform: translateY(calc(-50% + 20px)) rotate(0deg);
|
||||
z-index: 10;
|
||||
visibility: visible !important;
|
||||
opacity: 1 !important;
|
||||
|
|
@ -415,22 +420,42 @@ body.list-resizing-active * {
|
|||
color: #a6a6a6;
|
||||
margin-right: 15px;
|
||||
}
|
||||
/* List header collapse button styling */
|
||||
.list-header .list-header-collapse-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: flex-start;
|
||||
gap: 10px;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.list-header .js-collapse {
|
||||
color: #a6a6a6;
|
||||
margin-right: 15px;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
padding: 5px 8px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
background-color: #f5f5f5;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
background-color: transparent;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
font-size: 18px;
|
||||
line-height: 1;
|
||||
min-width: 30px;
|
||||
text-align: center;
|
||||
flex-shrink: 0;
|
||||
text-decoration: none;
|
||||
margin: 0;
|
||||
}
|
||||
.list-header .js-collapse:hover {
|
||||
background-color: #e0e0e0;
|
||||
background-color: transparent;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.list-header .list-header-collapse-container > div {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
.list.list-collapsed .list-header .js-collapse {
|
||||
display: inline-block !important;
|
||||
visibility: visible !important;
|
||||
|
|
@ -459,17 +484,18 @@ body.list-resizing-active * {
|
|||
position: relative !important;
|
||||
}
|
||||
.list.list-collapsed .list-header .list-rotated h2.list-header-name {
|
||||
width: 15vh;
|
||||
width: 100vh;
|
||||
font-size: 12px;
|
||||
height: 30px;
|
||||
line-height: 1.2;
|
||||
padding: 8px 4px;
|
||||
margin: 0 auto;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
overflow: visible;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
left: 40px;
|
||||
top: 50%;
|
||||
transform: translate(calc(-50% + 50px), -50%) rotate(0deg);
|
||||
text-align: left;
|
||||
transform: translateY(calc(-50% + 120px)) rotate(0deg);
|
||||
text-align: center;
|
||||
visibility: visible !important;
|
||||
opacity: 1 !important;
|
||||
display: block !important;
|
||||
|
|
@ -499,17 +525,18 @@ body.list-resizing-active * {
|
|||
position: relative !important;
|
||||
}
|
||||
.list.list-collapsed .list-header .list-rotated h2.list-header-name {
|
||||
width: 15vh;
|
||||
width: 100vh;
|
||||
font-size: 12px;
|
||||
height: 30px;
|
||||
line-height: 1.2;
|
||||
padding: 8px 4px;
|
||||
margin: 0 auto;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
overflow: visible;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
left: 40px;
|
||||
top: 50%;
|
||||
transform: translate(calc(-50% + 50px), -50%) rotate(0deg);
|
||||
text-align: left;
|
||||
transform: translateY(calc(-50% + 120px)) rotate(0deg);
|
||||
text-align: center;
|
||||
visibility: visible !important;
|
||||
opacity: 1 !important;
|
||||
display: block !important;
|
||||
|
|
@ -539,16 +566,17 @@ body.list-resizing-active * {
|
|||
position: relative !important;
|
||||
}
|
||||
.list.list-collapsed .list-header .list-rotated h2.list-header-name {
|
||||
width: 15vh;
|
||||
width: 100vh;
|
||||
font-size: 12px;
|
||||
height: 30px;
|
||||
line-height: 1.2;
|
||||
padding: 8px 4px;
|
||||
margin: 0 auto;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
overflow: visible;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
left: 40px;
|
||||
top: 50%;
|
||||
transform: translate(calc(-50% + 50px), -50%) rotate(0deg);
|
||||
transform: translateY(calc(-50% + 40px)) rotate(0deg);
|
||||
text-align: left;
|
||||
visibility: visible !important;
|
||||
opacity: 1 !important;
|
||||
|
|
@ -1053,6 +1081,23 @@ body.list-resizing-active * {
|
|||
grid-row: 1/3 !important;
|
||||
grid-column: 1 !important;
|
||||
}
|
||||
|
||||
/* Allow long list titles to expand on desktop (non-mobile, non-collapsed) */
|
||||
.list:not(.mobile-view):not(.list-collapsed) .list-header {
|
||||
overflow: visible !important;
|
||||
}
|
||||
|
||||
.list:not(.mobile-view):not(.list-collapsed) .list-header .list-header-name {
|
||||
/* Permit wrapping and full visibility */
|
||||
white-space: normal !important;
|
||||
overflow: visible !important;
|
||||
text-overflow: clip !important;
|
||||
display: inline-block !important;
|
||||
/* Reserve space for right-side controls (menu, handle, count) */
|
||||
max-width: calc(100% - 120px) !important;
|
||||
/* Break long words to avoid overflow */
|
||||
word-break: break-word !important;
|
||||
}
|
||||
.link-board-wrapper {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ template(name='list')
|
|||
style="{{#unless collapsed}}min-width:{{listWidth}}px;max-width:{{listConstraint}}px;{{/unless}}"
|
||||
class="{{#if collapsed}}list-collapsed{{/if}} {{#if autoWidth}}list-auto-width{{/if}} {{#if isMiniScreen}}mobile-view{{/if}}")
|
||||
+listHeader
|
||||
+listBody
|
||||
.list-resize-handle.js-list-resize-handle.nodragscroll
|
||||
unless collapsed
|
||||
+listBody
|
||||
.list-resize-handle.js-list-resize-handle.nodragscroll
|
||||
|
||||
template(name='miniList')
|
||||
a.mini-list.js-select-list.js-list(id="js-list-{{_id}}" class="{{#if isMiniScreen}}mobile-view{{/if}}")
|
||||
|
|
|
|||
|
|
@ -279,7 +279,8 @@ BlazeComponent.extendComponent({
|
|||
|
||||
// Only enable resize for non-collapsed, non-auto-width lists
|
||||
const isAutoWidth = this.autoWidth();
|
||||
if (list.collapsed || isAutoWidth) {
|
||||
const isCollapsed = Utils.getListCollapseState(list);
|
||||
if (isCollapsed || isAutoWidth) {
|
||||
$resizeHandle.hide();
|
||||
return;
|
||||
}
|
||||
|
|
@ -433,9 +434,10 @@ BlazeComponent.extendComponent({
|
|||
});
|
||||
|
||||
|
||||
// Reactively update resize handle visibility when auto-width changes
|
||||
// Reactively update resize handle visibility when auto-width or collapse changes
|
||||
component.autorun(() => {
|
||||
if (component.autoWidth()) {
|
||||
const collapsed = Utils.getListCollapseState(list);
|
||||
if (component.autoWidth() || collapsed) {
|
||||
$resizeHandle.hide();
|
||||
} else {
|
||||
$resizeHandle.show();
|
||||
|
|
@ -452,6 +454,12 @@ BlazeComponent.extendComponent({
|
|||
},
|
||||
}).register('list');
|
||||
|
||||
Template.list.helpers({
|
||||
collapsed() {
|
||||
return Utils.getListCollapseState(this);
|
||||
},
|
||||
});
|
||||
|
||||
Template.miniList.events({
|
||||
'click .js-select-list'() {
|
||||
const listId = this._id;
|
||||
|
|
|
|||
|
|
@ -30,20 +30,22 @@ template(name="listHeader")
|
|||
|
|
||||
span.list-sum-badge(title="{{_ 'sum-of-number-fields'}}") ∑ {{numberFieldsSum}}
|
||||
else
|
||||
if collapsed
|
||||
a.js-collapse(title="{{_ 'uncollapse'}}")
|
||||
| ⬅️
|
||||
| ➡️
|
||||
div(class="{{#if collapsed}}list-rotated{{/if}}")
|
||||
h2.list-header-name(
|
||||
title="{{ moment modifiedAt 'LLL' }}"
|
||||
class="{{#if currentUser.isBoardMember}}{{#unless currentUser.isCommentOnly}}{{#unless currentUser.isWorker}}js-open-inlined-form is-editable{{/unless}}{{/unless}}{{/if}}")
|
||||
+viewer
|
||||
= title
|
||||
if wipLimit.enabled
|
||||
| (
|
||||
span(class="{{#if exceededWipLimit}}highlight{{/if}}") {{cards.length}}
|
||||
|/#{wipLimit.value})
|
||||
div.list-header-collapse-container
|
||||
a.list-collapse-indicator.js-collapse(title="{{_ 'collapse'}}")
|
||||
if collapsed
|
||||
| ▶
|
||||
else
|
||||
| 🔽
|
||||
div(class="{{#if collapsed}}list-rotated{{/if}}")
|
||||
h2.list-header-name(
|
||||
title="{{ moment modifiedAt 'LLL' }}"
|
||||
class="{{#if currentUser.isBoardMember}}{{#unless currentUser.isCommentOnly}}{{#unless currentUser.isWorker}}js-open-inlined-form is-editable{{/unless}}{{/unless}}{{/if}}")
|
||||
+viewer
|
||||
= title
|
||||
if wipLimit.enabled
|
||||
| (
|
||||
span(class="{{#if exceededWipLimit}}highlight{{/if}}") {{cards.length}}
|
||||
|/#{wipLimit.value})
|
||||
unless collapsed
|
||||
if showCardsCountForList cards.length
|
||||
span.cardCount {{cardsCount}} {{cardsCountForListIsOne cards.length}}
|
||||
|
|
@ -64,6 +66,10 @@ template(name="listHeader")
|
|||
unless currentUser.isWorker
|
||||
a.list-header-handle.handle.js-list-handle ↕️
|
||||
else if currentUser.isBoardMember
|
||||
if currentUser.isBoardMember
|
||||
unless currentUser.isCommentOnly
|
||||
unless currentUser.isWorker
|
||||
a.list-header-handle.handle.js-list-handle ↕️
|
||||
if isWatching
|
||||
i.list-header-watch-icon | 👁️
|
||||
unless collapsed
|
||||
|
|
@ -73,14 +79,8 @@ template(name="listHeader")
|
|||
// a.fa.js-list-star.list-header-plus-top(class="fa-star{{#unless starred}}-o{{/unless}}")
|
||||
if canSeeAddCard
|
||||
a.js-add-card.list-header-plus-top(title="{{_ 'add-card-to-top-of-list'}}") ➕
|
||||
a.js-collapse(title="{{_ 'collapse'}}")
|
||||
| ⬅️
|
||||
| ➡️
|
||||
|
||||
a.js-open-list-menu(title="{{_ 'listActionPopup-title'}}") ☰
|
||||
if currentUser.isBoardMember
|
||||
unless currentUser.isCommentOnly
|
||||
unless currentUser.isWorker
|
||||
a.list-header-handle.handle.js-list-handle ↕️
|
||||
|
||||
template(name="editListTitleForm")
|
||||
.list-composer
|
||||
|
|
|
|||
|
|
@ -34,13 +34,14 @@ BlazeComponent.extendComponent({
|
|||
},
|
||||
collapsed(check = undefined) {
|
||||
const list = Template.currentData();
|
||||
const status = list.isCollapsed();
|
||||
const status = Utils.getListCollapseState(list);
|
||||
if (check === undefined) {
|
||||
// just check
|
||||
return status;
|
||||
} else {
|
||||
list.collapse(!status);
|
||||
return !status;
|
||||
const next = typeof check === 'boolean' ? check : !status;
|
||||
Utils.setListCollapseState(list, next);
|
||||
return next;
|
||||
}
|
||||
},
|
||||
editTitle(event) {
|
||||
|
|
|
|||
|
|
@ -339,15 +339,20 @@
|
|||
width: 100%;
|
||||
min-width: 3vw;
|
||||
font-size: clamp(12px, 2vw, 14px);
|
||||
box-sizing: border-box;
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
/* Make zoom input wider on all mobile screens */
|
||||
@media screen and (max-width: 800px),
|
||||
screen and (max-device-width: 932px) and (-webkit-min-device-pixel-ratio: 3) {
|
||||
#header-quick-access .zoom-controls .zoom-input {
|
||||
min-width: 50px !important; /* Wider on mobile */
|
||||
width: 50px !important; /* Fixed width to show all numbers */
|
||||
font-size: 14px !important; /* Slightly larger text */
|
||||
min-width: 80px !important; /* Wider on mobile to show 3 digits */
|
||||
width: 80px !important; /* Fixed width to show 100 fully */
|
||||
font-size: 16px !important; /* Slightly larger text */
|
||||
flex: 0 0 80px !important; /* Prevent shrinking in flex */
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -850,8 +855,9 @@
|
|||
#header-quick-access .zoom-controls .zoom-input {
|
||||
font-size: 16px !important; /* Larger input text */
|
||||
padding: 0.5vh 0.8vw !important;
|
||||
min-width: 6vw !important; /* Much wider for mobile */
|
||||
width: 60px !important; /* Fixed width to show all numbers */
|
||||
min-width: 80px !important; /* Wider to fit 100 */
|
||||
width: 80px !important; /* Fixed width to show 100 fully */
|
||||
flex: 0 0 80px !important; /* Prevent shrinking in flex */
|
||||
}
|
||||
|
||||
/* Make mobile mode toggle larger */
|
||||
|
|
|
|||
|
|
@ -81,6 +81,27 @@ body {
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
/* iOS Safari fixes */
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
/* Mobile mode specific fixes for iOS Safari */
|
||||
body.mobile-mode {
|
||||
overflow-x: hidden;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
/* Prevent iOS Safari bounce scroll */
|
||||
overscroll-behavior: none;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
/* Ensure content area is scrollable in mobile mode */
|
||||
body.mobile-mode #content {
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
height: calc(100vh - 48px);
|
||||
}
|
||||
#content {
|
||||
position: relative;
|
||||
|
|
@ -899,6 +920,40 @@ a:not(.disabled).is-active i.fa {
|
|||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
/* iOS Safari Mobile Mode Fixes */
|
||||
@media screen and (max-width: 800px) {
|
||||
/* Prevent scrolling issues on iOS Safari when card popup is open */
|
||||
body.mobile-mode {
|
||||
overflow: hidden;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
/* Fix z-index stacking for mobile Safari */
|
||||
body.mobile-mode .board-wrapper {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
body.mobile-mode .board-wrapper .board-canvas .board-overlay {
|
||||
z-index: 17 !important;
|
||||
}
|
||||
|
||||
body.mobile-mode .card-details {
|
||||
z-index: 100 !important;
|
||||
}
|
||||
|
||||
body.mobile-mode .pop-over {
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
/* Ensure smooth scrolling on iOS */
|
||||
body.mobile-mode .card-details,
|
||||
body.mobile-mode .pop-over .content-wrapper {
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
}
|
||||
@-moz-keyframes lds-roller {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
|
|
|
|||
|
|
@ -2,8 +2,10 @@ template(name="main")
|
|||
html(lang="{{TAPi18n.getLanguage}}")
|
||||
head
|
||||
title
|
||||
meta(name="viewport" content="width=device-width, initial-scale=1, maximum-scale=5, user-scalable=yes")
|
||||
meta(name="viewport" content="width=device-width, initial-scale=1, maximum-scale=5, user-scalable=yes, viewport-fit=cover")
|
||||
meta(http-equiv="X-UA-Compatible" content="IE=edge")
|
||||
meta(name="apple-mobile-web-app-capable" content="yes")
|
||||
meta(name="apple-mobile-web-app-status-bar-style" content="black-translucent")
|
||||
//- XXX We should use pathFor in the following `href` to support the case
|
||||
where the application is deployed with a path prefix, but it seems to be
|
||||
difficult to do that cleanly with Blaze -- at least without adding extra
|
||||
|
|
|
|||
|
|
@ -538,6 +538,7 @@
|
|||
position: absolute;
|
||||
top: 6px;
|
||||
right: 12px;
|
||||
color: #3cb500;
|
||||
}
|
||||
.pop-over-list .pop-over-list.checkable li.active a {
|
||||
padding-right: 28px;
|
||||
|
|
@ -545,6 +546,10 @@
|
|||
.pop-over-list .pop-over-list.checkable li.active a .fa-check {
|
||||
display: block;
|
||||
}
|
||||
/* Grey check icons when grey icons setting is enabled */
|
||||
body.grey-icons-enabled .pop-over-list .pop-over-list.checkable .fa-check {
|
||||
color: #7a7a7a;
|
||||
}
|
||||
.pop-over.miniprofile .header {
|
||||
border-bottom-color: transparent;
|
||||
height: 30px;
|
||||
|
|
@ -590,6 +595,10 @@
|
|||
overflow: hidden;
|
||||
margin-top: 0px;
|
||||
border: 0px solid #dbdbdb;
|
||||
/* Ensure popups appear above card details on mobile */
|
||||
z-index: 999999 !important;
|
||||
/* iOS Safari scrolling fix */
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
.pop-over .header {
|
||||
color: #fff;
|
||||
|
|
@ -674,3 +683,23 @@
|
|||
transform: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* Force full-screen popups in mobile mode regardless of screen width */
|
||||
body.mobile-mode .pop-over {
|
||||
position: fixed !important;
|
||||
top: 0 !important;
|
||||
left: 0 !important;
|
||||
right: 0 !important;
|
||||
bottom: 0 !important;
|
||||
width: 100vw !important;
|
||||
height: 100vh !important;
|
||||
max-width: 100vw !important;
|
||||
max-height: 100vh !important;
|
||||
}
|
||||
body.mobile-mode .pop-over .content-wrapper {
|
||||
width: 100% !important;
|
||||
height: calc(100vh - 48px) !important;
|
||||
max-height: calc(100vh - 48px) !important;
|
||||
overflow-y: auto !important;
|
||||
overflow-x: hidden !important;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -137,8 +137,13 @@
|
|||
padding: 0.5rem 0.5rem;
|
||||
}
|
||||
.setting-content .content-body .main-body ul li a .is-checked {
|
||||
border-bottom: 2px solid #2980b9;
|
||||
border-right: 2px solid #2980b9;
|
||||
border-bottom: 2px solid #3cb500;
|
||||
border-right: 2px solid #3cb500;
|
||||
}
|
||||
/* Grey checkmarks when grey icons setting is enabled */
|
||||
body.grey-icons-enabled .setting-content .content-body .main-body ul li a .is-checked {
|
||||
border-bottom: 2px solid #7a7a7a;
|
||||
border-right: 2px solid #7a7a7a;
|
||||
}
|
||||
.setting-content .content-body .main-body ul li a span {
|
||||
padding: 0 0.5rem;
|
||||
|
|
|
|||
|
|
@ -68,6 +68,14 @@
|
|||
transform-origin: 100% 100% !important;
|
||||
}
|
||||
|
||||
/* Grey checkmarks when grey icons setting is enabled */
|
||||
body.grey-icons-enabled .sidebar .materialCheckBox.is-checked,
|
||||
body.grey-icons-enabled .boardCardSettingsPopup .materialCheckBox.is-checked,
|
||||
body.grey-icons-enabled .boardSubtaskSettingsPopup .materialCheckBox.is-checked {
|
||||
border-bottom: 2px solid #7a7a7a !important;
|
||||
border-right: 2px solid #7a7a7a !important;
|
||||
}
|
||||
|
||||
/* Card Settings 3-column grid layout */
|
||||
.card-settings-grid {
|
||||
display: grid;
|
||||
|
|
@ -130,6 +138,11 @@
|
|||
}
|
||||
.sidebar .sidebar-content ul.sidebar-list li > a .fa.fa-check {
|
||||
margin: 0 4px;
|
||||
color: #3cb500;
|
||||
}
|
||||
/* Grey check icons when grey icons setting is enabled */
|
||||
body.grey-icons-enabled .sidebar .sidebar-content ul.sidebar-list li > a .fa.fa-check {
|
||||
color: #7a7a7a;
|
||||
}
|
||||
.sidebar .sidebar-content ul.sidebar-list li .minicard {
|
||||
padding: 6px 8px 4px;
|
||||
|
|
|
|||
|
|
@ -26,6 +26,11 @@ template(name="swimlaneFixedHeader")
|
|||
if currentUser
|
||||
unless currentUser.isCommentOnly
|
||||
unless currentUser.isWorker
|
||||
a.swimlane-collapse-indicator.js-collapse-swimlane.swimlane-header-collapse(title="{{_ 'collapse'}}")
|
||||
if collapseSwimlane
|
||||
| ▶
|
||||
else
|
||||
| 🔽
|
||||
a.js-open-add-swimlane-menu.swimlane-header-plus-icon(title="{{_ 'add-swimlane'}}")
|
||||
| ➕
|
||||
unless isTouchScreen
|
||||
|
|
|
|||
|
|
@ -20,13 +20,14 @@ BlazeComponent.extendComponent({
|
|||
},
|
||||
collapsed(check = undefined) {
|
||||
const swimlane = Template.currentData();
|
||||
const status = swimlane.isCollapsed();
|
||||
const status = Utils.getSwimlaneCollapseState(swimlane);
|
||||
if (check === undefined) {
|
||||
// just check
|
||||
return status;
|
||||
} else {
|
||||
swimlane.collapse(!status);
|
||||
return !status;
|
||||
const next = typeof check === 'boolean' ? check : !status;
|
||||
Utils.setSwimlaneCollapseState(swimlane, next);
|
||||
return next;
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -49,6 +50,10 @@ Template.swimlaneFixedHeader.helpers({
|
|||
isBoardAdmin() {
|
||||
return ReactiveCache.getCurrentUser().isBoardAdmin();
|
||||
},
|
||||
collapseSwimlane() {
|
||||
const swimlane = Template.currentData();
|
||||
return Utils.getSwimlaneCollapseState(swimlane);
|
||||
},
|
||||
isTitleDefault(title) {
|
||||
// https://github.com/wekan/wekan/issues/4763
|
||||
// https://github.com/wekan/wekan/issues/4742
|
||||
|
|
|
|||
|
|
@ -130,6 +130,29 @@
|
|||
pointer-events: auto;
|
||||
}
|
||||
|
||||
/* Swimlane collapse button styling - matches list collapse button */
|
||||
.swimlane .swimlane-header-wrap .swimlane-header-menu .swimlane-collapse-indicator {
|
||||
color: #a6a6a6;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
padding: 5px 8px;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
background-color: transparent;
|
||||
cursor: pointer;
|
||||
font-size: 18px;
|
||||
line-height: 1;
|
||||
min-width: 30px;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
margin: 0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.swimlane .swimlane-header-wrap .swimlane-header-menu .swimlane-collapse-indicator:hover {
|
||||
background-color: transparent;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
#js-swimlane-height-edit .swimlane-height-error {
|
||||
display: none;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -283,6 +283,9 @@ BlazeComponent.extendComponent({
|
|||
|
||||
// Wait for DOM to be ready
|
||||
setTimeout(() => {
|
||||
const handleSelector = Utils.isTouchScreenOrShowDesktopDragHandles()
|
||||
? '.js-list-handle'
|
||||
: '.js-list-header';
|
||||
const $lists = this.$('.js-list');
|
||||
|
||||
const $parent = $lists.parent();
|
||||
|
|
@ -306,7 +309,7 @@ BlazeComponent.extendComponent({
|
|||
items: '.js-list:not(.js-list-composer)',
|
||||
placeholder: 'list placeholder',
|
||||
distance: 7,
|
||||
handle: '.js-list-handle',
|
||||
handle: handleSelector,
|
||||
disabled: !Utils.canModifyBoard(),
|
||||
start(evt, ui) {
|
||||
ui.helper.css('z-index', 1000);
|
||||
|
|
@ -319,6 +322,15 @@ BlazeComponent.extendComponent({
|
|||
boardComponent.setIsDragging(false);
|
||||
}
|
||||
});
|
||||
// Reactively update handle when user toggles desktop drag handles
|
||||
this.autorun(() => {
|
||||
const newHandle = Utils.isTouchScreenOrShowDesktopDragHandles()
|
||||
? '.js-list-handle'
|
||||
: '.js-list-header';
|
||||
if ($parent.data('uiSortable') || $parent.data('sortable')) {
|
||||
try { $parent.sortable('option', 'handle', newHandle); } catch (e) {}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
}
|
||||
}, 100);
|
||||
|
|
@ -684,6 +696,10 @@ Template.swimlane.helpers({
|
|||
lists() {
|
||||
// Return per-swimlane lists for this swimlane
|
||||
return this.myLists();
|
||||
},
|
||||
|
||||
collapseSwimlane() {
|
||||
return Utils.getSwimlaneCollapseState(this);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -691,6 +707,9 @@ Template.swimlane.helpers({
|
|||
setTimeout(() => {
|
||||
const $swimlaneElements = $('.swimlane');
|
||||
const $listsGroupElements = $('.list-group');
|
||||
const computeHandle = () => (
|
||||
Utils.isTouchScreenOrShowDesktopDragHandles() ? '.js-list-handle' : '.js-list-header'
|
||||
);
|
||||
|
||||
// Initialize sortable on ALL swimlane elements (even empty ones)
|
||||
$swimlaneElements.each(function(index) {
|
||||
|
|
@ -707,7 +726,7 @@ setTimeout(() => {
|
|||
items: '.js-list:not(.js-list-composer)',
|
||||
placeholder: 'list placeholder',
|
||||
distance: 7,
|
||||
handle: '.js-list-handle',
|
||||
handle: computeHandle(),
|
||||
disabled: !Utils.canModifyBoard(),
|
||||
start(evt, ui) {
|
||||
ui.helper.css('z-index', 1000);
|
||||
|
|
@ -831,6 +850,13 @@ setTimeout(() => {
|
|||
});
|
||||
}
|
||||
});
|
||||
// Reactively adjust handle when setting changes
|
||||
Tracker.autorun(() => {
|
||||
const newHandle = computeHandle();
|
||||
if ($swimlane.data('uiSortable') || $swimlane.data('sortable')) {
|
||||
try { $swimlane.sortable('option', 'handle', newHandle); } catch (e) {}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -849,7 +875,7 @@ setTimeout(() => {
|
|||
items: '.js-list:not(.js-list-composer)',
|
||||
placeholder: 'list placeholder',
|
||||
distance: 7,
|
||||
handle: '.js-list-handle',
|
||||
handle: computeHandle(),
|
||||
disabled: !Utils.canModifyBoard(),
|
||||
start(evt, ui) {
|
||||
ui.helper.css('z-index', 1000);
|
||||
|
|
@ -973,6 +999,13 @@ setTimeout(() => {
|
|||
});
|
||||
}
|
||||
});
|
||||
// Reactively adjust handle when setting changes
|
||||
Tracker.autorun(() => {
|
||||
const newHandle = computeHandle();
|
||||
if ($listsGroup.data('uiSortable') || $listsGroup.data('sortable')) {
|
||||
try { $listsGroup.sortable('option', 'handle', newHandle); } catch (e) {}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}, 1000);
|
||||
|
|
@ -1018,6 +1051,9 @@ BlazeComponent.extendComponent({
|
|||
|
||||
// Wait for DOM to be ready
|
||||
setTimeout(() => {
|
||||
const handleSelector = Utils.isTouchScreenOrShowDesktopDragHandles()
|
||||
? '.js-list-handle'
|
||||
: '.js-list-header';
|
||||
const $lists = this.$('.js-list');
|
||||
|
||||
const $parent = $lists.parent();
|
||||
|
|
@ -1041,7 +1077,7 @@ BlazeComponent.extendComponent({
|
|||
items: '.js-list:not(.js-list-composer)',
|
||||
placeholder: 'list placeholder',
|
||||
distance: 7,
|
||||
handle: '.js-list-handle',
|
||||
handle: handleSelector,
|
||||
disabled: !Utils.canModifyBoard(),
|
||||
start(evt, ui) {
|
||||
ui.helper.css('z-index', 1000);
|
||||
|
|
@ -1054,6 +1090,15 @@ BlazeComponent.extendComponent({
|
|||
boardComponent.setIsDragging(false);
|
||||
}
|
||||
});
|
||||
// Reactively update handle when user toggles desktop drag handles
|
||||
this.autorun(() => {
|
||||
const newHandle = Utils.isTouchScreenOrShowDesktopDragHandles()
|
||||
? '.js-list-handle'
|
||||
: '.js-list-header';
|
||||
if ($parent.data('uiSortable') || $parent.data('sortable')) {
|
||||
try { $parent.sortable('option', 'handle', newHandle); } catch (e) {}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
}
|
||||
}, 100);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue