Reverted New UI Design of WeKan v8.29 and added more fixes and performance improvements.

Thanks to xet7 !
This commit is contained in:
Lauri Ojansivu 2026-02-08 00:48:39 +02:00
parent d152d8fc1b
commit 1b8b8d2eef
196 changed files with 17659 additions and 10028 deletions

View file

@ -13,7 +13,7 @@
position: absolute;
right: 0px;
top: 0px;
font-size: 25px;
padding: 10px;
}
.sidebar-xmark:hover {
@ -27,21 +27,7 @@
padding: 10px 10px 0px 10px;
}
.sidebar .sidebar-content {
padding: 0 1ch;
>ul {
display: flex;
}
.fa:not(.fa-plus) {
padding-right: 0.5ch;
align-self: center;
}
*:has(>.fa-plus) {
/* as long as container as a min height,
we can accomodate it while staying symetric */
aspect-ratio: 1/1;
height: var(--label-height);
min-width: 0;
}
padding: 0 12px;
}
.sidebar .sidebar-content .hide-btn {
display: none;
@ -52,13 +38,15 @@
margin-bottom: 10px;
font-weight: bold;
}
.sidebar .sidebar-content h3 i.fa {
margin-right: 3px;
}
.sidebar .sidebar-content hr {
margin: 13px 0;
}
.sidebar .sidebar-content ul.sidebar-list {
display: flex;
flex-direction: column;
gap: 0.1lh;
}
/* Use checklist-style green checkboxes for all sidebar checkboxes */
@ -72,7 +60,7 @@
margin-right: 6px !important;
border-top: 2px solid transparent !important;
border-left: 2px solid transparent !important;
border-bottom: 0.2ch solid #3cb500 !important;
border-bottom: 2px solid #3cb500 !important;
border-right: 2px solid #3cb500 !important;
transform: rotate(40deg) !important;
-webkit-backface-visibility: hidden !important;
@ -117,17 +105,16 @@ body.grey-icons-enabled .boardSubtaskSettingsPopup .materialCheckBox.is-checked
.card-settings-column h4 {
margin: 0;
font-size: 12px;
font-weight: bold;
text-align: center;
}
.sidebar .sidebar-content ul.sidebar-list li > a {
display: flex;
height: 30px;
margin: 0;
padding: 4px;
border-radius: 3px;
max-height: 2lh;
overflow: hidden;
align-items: center;
}
.sidebar .sidebar-content ul.sidebar-list li > a:hover,
@ -145,6 +132,10 @@ body.grey-icons-enabled .boardSubtaskSettingsPopup .materialCheckBox.is-checked
padding: 8px;
border-radius: 3px;
}
.sidebar .sidebar-content ul.sidebar-list li > a .sidebar-list-item-description {
flex: 1;
overflow: ellipsis;
}
.sidebar .sidebar-content ul.sidebar-list li > a .fa.fa-check {
margin: 0 4px;
color: #3cb500;
@ -153,6 +144,9 @@ body.grey-icons-enabled .boardSubtaskSettingsPopup .materialCheckBox.is-checked
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;
}
.sidebar .sidebar-content ul.sidebar-list li .minicard .minicard-edit-button {
float: right;
padding: 4px;
@ -189,28 +183,13 @@ body.grey-icons-enabled .sidebar .sidebar-content ul.sidebar-list li > a .fa.fa-
}
.board-sidebar {
display: none;
width: fit-content;
height: fit-content;
max-width: min(50ch, 50vw);
max-height: 100vh;
overflow: auto;
z-index: 10;
width: 30vw;
z-index: 100;
transition: top 0.1s, right 0.1s, width 0.1s;
}
body.mobile-mode .board-sidebar {
max-width: 100vw;
}
.board-sidebar.is-open {
display: block;
}
.board-widget-content {
display: flex;
flex-wrap: wrap;
gap: 0.2lh;
min-height: 1.5lh;
align-items: stretch;
}
.board-widget h4 {
margin: 5px 0;
}
@ -233,7 +212,7 @@ body.mobile-mode .board-sidebar {
}
.sidebar-tongue i.fa {
padding: 3px 9px;
font-size: 24px;
transition: transform 0.5s;
}
.sidebar-accessibility {
@ -304,7 +283,7 @@ body.mobile-mode .board-sidebar {
}
.board-sidebar .sidebar-content .hide-btn i.fa {
padding: 8px 16px;
font-size: 24px;
font-weight: bold;
}
.sidebar-tongue {

View file

@ -1,9 +1,12 @@
template(name="sidebar")
.board-sidebar.sidebar(class="{{#if isOpen}}is-open{{/if}} {{#unless isVerticalScrollbars}}no-scrollbars{{/unless}}")
//a.sidebar-tongue.js-toggle-sidebar(
// class="{{#if isTongueHidden}}is-hidden{{/if}}",
// title="{{showTongueTitle}}")
// i.fa.fa-navicon
//
class="{{#if isTongueHidden}}is-hidden{{/if}}",
//
title="{{showTongueTitle}}")
//
i.fa.fa-navicon
.sidebar-actions
.sidebar-shortcuts
a.sidebar-btn.js-shortcuts(title="{{_ 'keyboard-shortcuts' }}")
@ -19,7 +22,8 @@ template(name="sidebar")
a.sidebar-xmark.js-close-sidebar ✕
.sidebar-content.js-board-sidebar-content
//a.hide-btn.js-hide-sidebar
// i.fa.fa-navicon
//
i.fa.fa-navicon
unless isDefaultView
h2
a.fa.fa-arrow-left.js-back-home
@ -48,9 +52,8 @@ template(name='homeSidebar')
hr
if currentUser.isBoardAdmin
h3.activity-title
span
i.fa.fa-comment-o
span {{_ 'activities'}}
i.fa.fa-comment-o
| {{_ 'activities'}}
a.flex.js-toggle-show-activities(title="{{_ 'show-activities'}}")
i.fa(class="{{#if showActivities}}fa-check{{else}}fa-square-o{{/if}}")
@ -61,7 +64,7 @@ template(name="membersWidget")
unless currentUser.isCommentOnly
unless currentUser.isWorker
h3
a.js-open-board-menu(title="{{_ 'boardMenuPopup-title'}}")
a.board-header-btn.js-open-board-menu(title="{{_ 'boardMenuPopup-title'}}")
i.fa.fa-cog
| {{_ 'boardMenuPopup-title'}}
hr
@ -162,7 +165,7 @@ template(name="boardChangeBackgroundImagePopup")
form
label
| {{_ 'board-background-image-url'}}
input.js-board-background-image-url(type="text" value="{{backgroundImageURL}}" )
input.js-board-background-image-url(type="text" value="{{backgroundImageURL}}" autofocus)
div.buttonsContainer
input.primary.wide(type="submit" value="{{_ 'save'}}")
br
@ -308,7 +311,7 @@ template(name="boardCardSettingsPopup")
.card-settings-column
span
i.fa.fa-user
i.fa.fa-plus
|
| {{_ 'requested-by'}}
.card-settings-row
.card-settings-column
@ -461,17 +464,27 @@ template(name="boardCardSettingsPopup")
i.fa.fa-picture-o
| {{_ 'cover-attachment-on-minicard'}}
//div.check-div
// a.flex.js-field-has-comments(class="{{#if allowsComments}}is-checked{{/if}}")
// .materialCheckBox(class="{{#if allowsComments}}is-checked{{/if}}")
// span
// i.fa.fa-comment-o
// | {{_ 'comment'}}
//
a.flex.js-field-has-comments(class="{{#if allowsComments}}is-checked{{/if}}")
//
.materialCheckBox(class="{{#if allowsComments}}is-checked{{/if}}")
//
span
//
i.fa.fa-comment-o
//
| {{_ 'comment'}}
//div.check-div
// a.flex.js-field-has-activities(class="{{#if allowsActivities}}is-checked{{/if}}")
// .materialCheckBox(class="{{#if allowsActivities}}is-checked{{/if}}")
// span
// i.fa.fa-history
// | {{_ 'activities'}}
//
a.flex.js-field-has-activities(class="{{#if allowsActivities}}is-checked{{/if}}")
//
.materialCheckBox(class="{{#if allowsActivities}}is-checked{{/if}}")
//
span
//
i.fa.fa-history
//
| {{_ 'activities'}}
template(name="boardSubtaskSettingsPopup")
form.board-subtask-settings
@ -598,12 +611,18 @@ template(name="boardMenuPopup")
| {{_ 'board-change-background-image'}}
//Bug Board icons random dance https://github.com/wekan/wekan/issues/4214
//if currentUser.isBoardAdmin
// unless currentSetting.hideBoardMemberList
// unless currentSetting.hideCardCounterList
// li
// a.js-board-info-on-my-boards(title="{{_ 'board-info-on-my-boards'}}")
// i.fa.fa-id-card-o
// | {{_ 'board-info-on-my-boards'}}
//
unless currentSetting.hideBoardMemberList
//
unless currentSetting.hideCardCounterList
//
li
//
a.js-board-info-on-my-boards(title="{{_ 'board-info-on-my-boards'}}")
//
i.fa.fa-id-card-o
//
| {{_ 'board-info-on-my-boards'}}
hr
ul.pop-over-list
if withApi
@ -629,17 +648,16 @@ template(name="boardMenuPopup")
hr
ul.pop-over-list
// li
// a.js-delete-duplicate-lists
// | 🗑️
// | {{_ 'delete-duplicate-lists'}}
//
a.js-delete-duplicate-lists
//
| 🗑️
//
| {{_ 'delete-duplicate-lists'}}
li
a.js-archive-board
i.fa.fa-archive
| {{_ 'archive-board'}}
//- this popup is the only one to not open
//- with correct size; related to issue linked above ?
//- artificially add a bit a space
div.invisible-line
template(name="exportBoard")
ul.pop-over-list

View file

@ -41,15 +41,16 @@ BlazeComponent.extendComponent({
},
open() {
// setting a ReactiveVar is idempotent;
// do not try to get(), because it will
// react to changes...
this._isOpen.set(true);
EscapeActions.executeUpTo('detailsPane');
if (!this._isOpen.get()) {
this._isOpen.set(true);
EscapeActions.executeUpTo('detailsPane');
}
},
hide() {
this._isOpen.set(false);
if (this._isOpen.get()) {
this._isOpen.set(false);
}
},
toggle() {
@ -153,7 +154,7 @@ BlazeComponent.extendComponent({
ReactiveCache.getCurrentUser().toggleVerticalScrollbars();
},
'click .js-show-week-of-year-toggle'() {
Meteor.call('toggleShowWeekOfYear');
ReactiveCache.getCurrentUser().toggleShowWeekOfYear();
},
'click .sidebar-accessibility'() {
FlowRouter.go('accessibility');
@ -946,7 +947,7 @@ BlazeComponent.extendComponent({
{
'click .js-field-has-subtasks'(evt) {
evt.preventDefault();
const newValue = !this.allowsSubtasks();
const newValue = !this.currentBoard.allowsSubtasks;
Boards.update(this.currentBoard._id, { $set: { allowsSubtasks: newValue } });
$('.js-field-deposit-board').prop(
'disabled',
@ -985,6 +986,171 @@ BlazeComponent.extendComponent({
this.currentBoard = Utils.getCurrentBoard();
},
allowsReceivedDate() {
const boardId = Session.get('currentBoard');
const currentBoard = ReactiveCache.getBoard(boardId);
return currentBoard ? currentBoard.allowsReceivedDate : false;
},
allowsStartDate() {
const boardId = Session.get('currentBoard');
const currentBoard = ReactiveCache.getBoard(boardId);
return currentBoard ? currentBoard.allowsStartDate : false;
},
allowsDueDate() {
const boardId = Session.get('currentBoard');
const currentBoard = ReactiveCache.getBoard(boardId);
return currentBoard ? currentBoard.allowsDueDate : false;
},
allowsEndDate() {
const boardId = Session.get('currentBoard');
const currentBoard = ReactiveCache.getBoard(boardId);
return currentBoard ? currentBoard.allowsEndDate : false;
},
allowsSubtasks() {
const boardId = Session.get('currentBoard');
const currentBoard = ReactiveCache.getBoard(boardId);
return currentBoard ? currentBoard.allowsSubtasks : false;
},
allowsCreator() {
const boardId = Session.get('currentBoard');
const currentBoard = ReactiveCache.getBoard(boardId);
return currentBoard ? (currentBoard.allowsCreator ?? false) : false;
},
allowsCreatorOnMinicard() {
const boardId = Session.get('currentBoard');
const currentBoard = ReactiveCache.getBoard(boardId);
return currentBoard ? (currentBoard.allowsCreatorOnMinicard ?? false) : false;
},
allowsMembers() {
const boardId = Session.get('currentBoard');
const currentBoard = ReactiveCache.getBoard(boardId);
return currentBoard ? currentBoard.allowsMembers : false;
},
allowsAssignee() {
const boardId = Session.get('currentBoard');
const currentBoard = ReactiveCache.getBoard(boardId);
return currentBoard ? currentBoard.allowsAssignee : false;
},
allowsAssignedBy() {
const boardId = Session.get('currentBoard');
const currentBoard = ReactiveCache.getBoard(boardId);
return currentBoard ? currentBoard.allowsAssignedBy : false;
},
allowsRequestedBy() {
const boardId = Session.get('currentBoard');
const currentBoard = ReactiveCache.getBoard(boardId);
return currentBoard ? currentBoard.allowsRequestedBy : false;
},
allowsCardSortingByNumber() {
const boardId = Session.get('currentBoard');
const currentBoard = ReactiveCache.getBoard(boardId);
return currentBoard ? currentBoard.allowsCardSortingByNumber : false;
},
allowsShowLists() {
const boardId = Session.get('currentBoard');
const currentBoard = ReactiveCache.getBoard(boardId);
return currentBoard ? currentBoard.allowsShowLists : false;
},
allowsLabels() {
const boardId = Session.get('currentBoard');
const currentBoard = ReactiveCache.getBoard(boardId);
return currentBoard ? currentBoard.allowsLabels : false;
},
allowsShowListsOnMinicard() {
const boardId = Session.get('currentBoard');
const currentBoard = ReactiveCache.getBoard(boardId);
return currentBoard ? currentBoard.allowsShowListsOnMinicard : false;
},
allowsChecklists() {
const boardId = Session.get('currentBoard');
const currentBoard = ReactiveCache.getBoard(boardId);
return currentBoard ? currentBoard.allowsChecklists : false;
},
allowsAttachments() {
const boardId = Session.get('currentBoard');
const currentBoard = ReactiveCache.getBoard(boardId);
return currentBoard ? currentBoard.allowsAttachments : false;
},
allowsComments() {
const boardId = Session.get('currentBoard');
const currentBoard = ReactiveCache.getBoard(boardId);
return currentBoard ? currentBoard.allowsComments : false;
},
allowsCardNumber() {
const boardId = Session.get('currentBoard');
const currentBoard = ReactiveCache.getBoard(boardId);
return currentBoard ? currentBoard.allowsCardNumber : false;
},
allowsDescriptionTitle() {
const boardId = Session.get('currentBoard');
const currentBoard = ReactiveCache.getBoard(boardId);
return currentBoard ? currentBoard.allowsDescriptionTitle : false;
},
allowsDescriptionText() {
const boardId = Session.get('currentBoard');
const currentBoard = ReactiveCache.getBoard(boardId);
return currentBoard ? currentBoard.allowsDescriptionText : false;
},
isBoardSelected() {
const boardId = Session.get('currentBoard');
const currentBoard = ReactiveCache.getBoard(boardId);
return currentBoard ? currentBoard.dateSettingsDefaultBoardID : false;
},
isNullBoardSelected() {
const boardId = Session.get('currentBoard');
const currentBoard = ReactiveCache.getBoard(boardId);
return currentBoard ? (
currentBoard.dateSettingsDefaultBoardId === null ||
currentBoard.dateSettingsDefaultBoardId === undefined
) : true;
},
allowsDescriptionTextOnMinicard() {
const boardId = Session.get('currentBoard');
const currentBoard = ReactiveCache.getBoard(boardId);
return currentBoard ? currentBoard.allowsDescriptionTextOnMinicard : false;
},
allowsCoverAttachmentOnMinicard() {
const boardId = Session.get('currentBoard');
const currentBoard = ReactiveCache.getBoard(boardId);
return currentBoard ? currentBoard.allowsCoverAttachmentOnMinicard : false;
},
allowsBadgeAttachmentOnMinicard() {
const boardId = Session.get('currentBoard');
const currentBoard = ReactiveCache.getBoard(boardId);
return currentBoard ? currentBoard.allowsBadgeAttachmentOnMinicard : false;
},
allowsCardSortingByNumberOnMinicard() {
const boardId = Session.get('currentBoard');
const currentBoard = ReactiveCache.getBoard(boardId);
return currentBoard ? currentBoard.allowsCardSortingByNumberOnMinicard : false;
},
boards() {
const ret = ReactiveCache.getBoards(
{
@ -1025,228 +1191,261 @@ BlazeComponent.extendComponent({
{
'click .js-field-has-receiveddate'(evt) {
evt.preventDefault();
const newValue = !Utils.allowsReceivedDate();
this.currentBoard.setAllowsReceivedDate(newValue);
const newValue = !this.currentBoard.allowsReceivedDate;
Boards.update(this.currentBoard._id, { $set: { allowsReceivedDate: newValue } });
},
'click .js-field-has-startdate'(evt) {
evt.preventDefault();
const newValue = !Utils.allowsStartDate();
this.currentBoard.setAllowsStartDate(newValue);
const newValue = !this.currentBoard.allowsStartDate;
Boards.update(this.currentBoard._id, { $set: { allowsStartDate: newValue } });
},
'click .js-field-has-enddate'(evt) {
evt.preventDefault();
const newValue = !Utils.allowsEndDate();
this.currentBoard.setAllowsEndDate(newValue);
const newValue = !this.currentBoard.allowsEndDate;
Boards.update(this.currentBoard._id, { $set: { allowsEndDate: newValue } });
},
'click .js-field-has-duedate'(evt) {
evt.preventDefault();
const newValue = !Utils.allowsDueDate();
this.currentBoard.setAllowsDueDate(newValue);
const newValue = !this.currentBoard.allowsDueDate;
Boards.update(this.currentBoard._id, { $set: { allowsDueDate: newValue } });
},
'click .js-field-has-subtasks'(evt) {
evt.preventDefault();
const newValue = !Utils.allowsSubtasks();
this.currentBoard.setAllowsSubtasks(newValue);
const newValue = !this.currentBoard.allowsSubtasks;
Boards.update(this.currentBoard._id, { $set: { allowsSubtasks: newValue } });
},
'click .js-field-has-creator'(evt) {
evt.preventDefault();
const newValue = !Utils.allowsCreator();
this.currentBoard.setAllowsCreator(newValue);
const newValue = !this.currentBoard.allowsCreator;
Boards.update(this.currentBoard._id, { $set: { allowsCreator: newValue } });
},
'click .js-field-has-creator-on-minicard'(evt) {
evt.preventDefault();
const newValue = !Utils.allowsCreatorOnMinicard();
this.currentBoard.setAllowsCreatorOnMinicard(newValue);
const newValue = !this.currentBoard.allowsCreatorOnMinicard;
Boards.update(this.currentBoard._id, { $set: { allowsCreatorOnMinicard: newValue } });
},
'click .js-field-has-members'(evt) {
evt.preventDefault();
const newValue = !Utils.allowsMembers();
this.currentBoard.setAllowsMembers(newValue);
const newValue = !this.currentBoard.allowsMembers;
Boards.update(this.currentBoard._id, { $set: { allowsMembers: newValue } });
},
'click .js-field-has-assignee'(evt) {
evt.preventDefault();
const newValue = !Utils.allowsAssignee();
this.currentBoard.setAllowsAssignee(newValue);
const newValue = !this.currentBoard.allowsAssignee;
Boards.update(this.currentBoard._id, { $set: { allowsAssignee: newValue } });
},
'click .js-field-has-assigned-by'(evt) {
evt.preventDefault();
const newValue = !Utils.allowsAssignedBy();
this.currentBoard.setAllowsAssignedBy(newValue);
const newValue = !this.currentBoard.allowsAssignedBy;
Boards.update(this.currentBoard._id, { $set: { allowsAssignedBy: newValue } });
},
'click .js-field-has-requested-by'(evt) {
evt.preventDefault();
const newValue = !Utils.allowsRequestedBy();
this.currentBoard.setAllowsRequestedBy(newValue);
const newValue = !this.currentBoard.allowsRequestedBy;
Boards.update(this.currentBoard._id, { $set: { allowsRequestedBy: newValue } });
},
'click .js-field-has-card-sorting-by-number'(evt) {
evt.preventDefault();
const newValue = !Utils.allowsCardSortingByNumber();
this.currentBoard.setAllowsCardSortingByNumber(newValue);
const newValue = !this.currentBoard.allowsCardSortingByNumber;
Boards.update(this.currentBoard._id, { $set: { allowsCardSortingByNumber: newValue } });
},
'click .js-field-has-card-show-lists'(evt) {
evt.preventDefault();
const newValue = !Utils.allowsShowLists();
this.currentBoard.setAllowsShowLists(newValue);
const newValue = !this.currentBoard.allowsShowLists;
Boards.update(this.currentBoard._id, { $set: { allowsShowLists: newValue } });
},
'click .js-field-has-labels'(evt) {
evt.preventDefault();
const newValue = !Utils.allowsLabels();
this.currentBoard.setAllowsLabels(newValue);
const newValue = !this.currentBoard.allowsLabels;
Boards.update(this.currentBoard._id, { $set: { allowsLabels: newValue } });
},
'click .js-field-has-card-show-lists-on-minicard'(evt) {
evt.preventDefault();
const newValue = !Utils.allowsShowListsOnMinicard();
this.currentBoard.setAllowsShowListsOnMinicard(newValue);
this.currentBoard.allowsShowListsOnMinicard = !this.currentBoard
.allowsShowListsOnMinicard;
this.currentBoard.setAllowsShowListsOnMinicard(
this.currentBoard.allowsShowListsOnMinicard,
);
$(`.js-field-has-card-show-lists-on-minicard ${MCB}`).toggleClass(
CKCLS,
Utils.allowsShowListsOnMinicard(),
this.currentBoard.allowsShowListsOnMinicard,
);
$('.js-field-has-card-show-lists-on-minicard').toggleClass(
CKCLS,
Utils.allowsShowListsOnMinicard(),
this.currentBoard.allowsShowListsOnMinicard,
);
},
'click .js-field-has-description-title'(evt) {
evt.preventDefault();
const newValue = !Utils.allowsDescriptionTitle();
this.currentBoard.setAllowsDescriptionTitle(newValue);
this.currentBoard.allowsDescriptionTitle = !this.currentBoard
.allowsDescriptionTitle;
this.currentBoard.setAllowsDescriptionTitle(
this.currentBoard.allowsDescriptionTitle,
);
$(`.js-field-has-description-title ${MCB}`).toggleClass(
CKCLS,
Utils.allowsDescriptionTitle(),
this.currentBoard.allowsDescriptionTitle,
);
$('.js-field-has-description-title').toggleClass(
CKCLS,
Utils.allowsDescriptionTitle(),
this.currentBoard.allowsDescriptionTitle,
);
},
'click .js-field-has-card-number'(evt) {
evt.preventDefault();
const newValue = !Utils.allowsCardNumber();
this.currentBoard.setAllowsCardNumber(newValue);
this.currentBoard.allowsCardNumber = !this.currentBoard
.allowsCardNumber;
this.currentBoard.setAllowsCardNumber(
this.currentBoard.allowsCardNumber,
);
$(`.js-field-has-card-number ${MCB}`).toggleClass(
CKCLS,
Utils.allowsCardNumber(),
this.currentBoard.allowsCardNumber,
);
$('.js-field-has-card-number').toggleClass(
CKCLS,
Utils.allowsCardNumber(),
this.currentBoard.allowsCardNumber,
);
},
'click .js-field-has-description-text-on-minicard'(evt) {
evt.preventDefault();
const newValue = !Utils.allowsDescriptionTextOnMinicard();
this.currentBoard.setAllowsDescriptionTextOnMinicard(newValue);
this.currentBoard.allowsDescriptionTextOnMinicard = !this.currentBoard
.allowsDescriptionTextOnMinicard;
this.currentBoard.setallowsDescriptionTextOnMinicard(
this.currentBoard.allowsDescriptionTextOnMinicard,
);
$(`.js-field-has-description-text-on-minicard ${MCB}`).toggleClass(
CKCLS,
Utils.allowsDescriptionTextOnMinicard(),
this.currentBoard.allowsDescriptionTextOnMinicard,
);
$('.js-field-has-description-text-on-minicard').toggleClass(
CKCLS,
Utils.allowsDescriptionTextOnMinicard(),
this.currentBoard.allowsDescriptionTextOnMinicard,
);
},
'click .js-field-has-description-text'(evt) {
evt.preventDefault();
const newValue = !Utils.allowsDescriptionText();
this.currentBoard.setAllowsDescriptionText(newValue);
this.currentBoard.allowsDescriptionText = !this.currentBoard
.allowsDescriptionText;
this.currentBoard.setAllowsDescriptionText(
this.currentBoard.allowsDescriptionText,
);
$(`.js-field-has-description-text ${MCB}`).toggleClass(
CKCLS,
Utils.allowsDescriptionText(),
this.currentBoard.allowsDescriptionText,
);
$('.js-field-has-description-text').toggleClass(
CKCLS,
Utils.allowsDescriptionText(),
this.currentBoard.allowsDescriptionText,
);
},
'click .js-field-has-checklists'(evt) {
evt.preventDefault();
const newValue = !Utils.allowsChecklists();
this.currentBoard.setAllowsChecklists(newValue);
this.currentBoard.allowsChecklists = !this.currentBoard
.allowsChecklists;
this.currentBoard.setAllowsChecklists(
this.currentBoard.allowsChecklists,
);
$(`.js-field-has-checklists ${MCB}`).toggleClass(
CKCLS,
Utils.allowsChecklists(),
this.currentBoard.allowsChecklists,
);
$('.js-field-has-checklists').toggleClass(
CKCLS,
Utils.allowsChecklists(),
this.currentBoard.allowsChecklists,
);
},
'click .js-field-has-attachments'(evt) {
evt.preventDefault();
const newValue = !Utils.allowsAttachments();
this.currentBoard.setAllowsAttachments(newValue);
this.currentBoard.allowsAttachments = !this.currentBoard
.allowsAttachments;
this.currentBoard.setAllowsAttachments(
this.currentBoard.allowsAttachments,
);
$(`.js-field-has-attachments ${MCB}`).toggleClass(
CKCLS,
Utils.allowsAttachments(),
this.currentBoard.allowsAttachments,
);
$('.js-field-has-attachments').toggleClass(
CKCLS,
Utils.allowsAttachments(),
this.currentBoard.allowsAttachments,
);
},
'click .js-field-has-comments'(evt) {
evt.preventDefault();
const newValue = !Utils.allowsComments();
this.currentBoard.setAllowsComments(newValue);
this.currentBoard.allowsComments = !this.currentBoard.allowsComments;
this.currentBoard.setAllowsComments(this.currentBoard.allowsComments);
$(`.js-field-has-comments ${MCB}`).toggleClass(
CKCLS,
Utils.allowsComments(),
this.currentBoard.allowsComments,
);
$('.js-field-has-comments').toggleClass(
CKCLS,
Utils.allowsComments(),
this.currentBoard.allowsComments,
);
},
'click .js-field-has-activities'(evt) {
evt.preventDefault();
const newValue = !Utils.allowsActivities();
this.currentBoard.setAllowsActivities(newValue);
this.currentBoard.allowsActivities = !this.currentBoard
.allowsActivities;
this.currentBoard.setAllowsActivities(
this.currentBoard.allowsActivities,
);
$(`.js-field-has-activities ${MCB}`).toggleClass(
CKCLS,
Utils.allowsActivities(),
this.currentBoard.allowsActivities,
);
$('.js-field-has-activities').toggleClass(
CKCLS,
Utils.allowsActivities(),
this.currentBoard.allowsActivities,
);
},
'click .js-field-has-cover-attachment-on-minicard'(evt) {
evt.preventDefault();
const newValue = !Utils.allowsCoverAttachmentOnMinicard();
this.currentBoard.setAllowsCoverAttachmentOnMinicard(newValue);
this.currentBoard.allowsCoverAttachmentOnMinicard = !this.currentBoard
.allowsCoverAttachmentOnMinicard;
this.currentBoard.setallowsCoverAttachmentOnMinicard(
this.currentBoard.allowsCoverAttachmentOnMinicard,
);
$(`.js-field-has-cover-attachment-on-minicard ${MCB}`).toggleClass(
CKCLS,
Utils.allowsCoverAttachmentOnMinicard(),
this.currentBoard.allowsCoverAttachmentOnMinicard,
);
$('.js-field-has-cover-attachment-on-minicard').toggleClass(
CKCLS,
Utils.allowsCoverAttachmentOnMinicard(),
this.currentBoard.allowsCoverAttachmentOnMinicard,
);
},
'click .js-field-has-badge-attachment-on-minicard'(evt) {
evt.preventDefault();
const newValue = !Utils.allowsBadgeAttachmentOnMinicard();
this.currentBoard.setAllowsBadgeAttachmentOnMinicard(newValue);
this.currentBoard.allowsBadgeAttachmentOnMinicard = !this.currentBoard
.allowsBadgeAttachmentOnMinicard;
this.currentBoard.setallowsBadgeAttachmentOnMinicard(
this.currentBoard.allowsBadgeAttachmentOnMinicard,
);
$(`.js-field-has-badge-attachment-on-minicard ${MCB}`).toggleClass(
CKCLS,
Utils.allowsBadgeAttachmentOnMinicard(),
this.currentBoard.allowsBadgeAttachmentOnMinicard,
);
$('.js-field-has-badge-attachment-on-minicard').toggleClass(
CKCLS,
Utils.allowsBadgeAttachmentOnMinicard(),
this.currentBoard.allowsBadgeAttachmentOnMinicard,
);
},
'click .js-field-has-card-sorting-by-number-on-minicard'(evt) {
evt.preventDefault();
const newValue = !Utils.allowsCardSortingByNumberOnMinicard();
this.currentBoard.setAllowsCardSortingByNumberOnMinicard(newValue);
this.currentBoard.allowsCardSortingByNumberOnMinicard = !this.currentBoard
.allowsCardSortingByNumberOnMinicard;
this.currentBoard.setallowsCardSortingByNumberOnMinicard(
this.currentBoard.allowsCardSortingByNumberOnMinicard,
);
$(`.js-field-has-card-sorting-by-number-on-minicard ${MCB}`).toggleClass(
CKCLS,
Utils.allowsCardSortingByNumberOnMinicard(),
this.currentBoard.allowsCardSortingByNumberOnMinicard,
);
$('.js-field-has-card-sorting-by-number-on-minicard').toggleClass(
CKCLS,
Utils.allowsCardSortingByNumberOnMinicard(),
this.currentBoard.allowsCardSortingByNumberOnMinicard,
);
},
},
@ -1862,3 +2061,4 @@ Template.changePermissionsPopup.helpers({
);
},
});

View file

@ -20,8 +20,7 @@ template(name="archivesSidebar")
p.quiet
if this.archivedAt
| {{_ 'archived-at' }}
|
| {{ moment this.archivedAt 'LLL' }}
| | {{ moment this.archivedAt 'LLL' }}
br
a.js-restore-card {{_ 'restore'}}
if currentUser.isBoardAdmin
@ -52,8 +51,7 @@ template(name="archivesSidebar")
p.quiet
if this.archivedAt
| {{_ 'archived-at' }}
|
| {{ moment this.archivedAt 'LLL' }}
| | {{ moment this.archivedAt 'LLL' }}
br
a.js-restore-list {{_ 'restore'}}
if currentUser.isBoardAdmin
@ -82,8 +80,7 @@ template(name="archivesSidebar")
p.quiet
if this.archivedAt
| {{_ 'archived-at' }}
|
| {{ moment this.archivedAt 'LLL' }}
| | {{ moment this.archivedAt 'LLL' }}
br
a.js-restore-swimlane {{_ 'restore'}}
if currentUser.isBoardAdmin

View file

@ -117,6 +117,70 @@ async function mutateSelectedCards(mutationNameOrCallback, ...args) {
}
}
function getSelectedCardsSorted() {
return ReactiveCache.getCards(MultiSelection.getMongoSelector(), { sort: ['sort'] });
}
function getListsForBoardSwimlane(boardId, swimlaneId) {
if (!boardId) return [];
const board = ReactiveCache.getBoard(boardId);
if (!board) return [];
const selector = {
boardId,
archived: false,
};
if (swimlaneId) {
const defaultSwimlane = board.getDefaultSwimline && board.getDefaultSwimline();
if (defaultSwimlane && defaultSwimlane._id === swimlaneId) {
selector.swimlaneId = { $in: [swimlaneId, null, ''] };
} else {
selector.swimlaneId = swimlaneId;
}
}
return ReactiveCache.getLists(selector, { sort: { sort: 1 } });
}
function getMaxSortForList(listId, swimlaneId) {
if (!listId || !swimlaneId) return null;
const card = ReactiveCache.getCard(
{ listId, swimlaneId, archived: false },
{ sort: { sort: -1 } },
true,
);
return card ? card.sort : null;
}
function buildInsertionSortIndexes(cardsCount, targetCard, position, listId, swimlaneId) {
const indexes = [];
if (cardsCount <= 0) return indexes;
if (targetCard) {
const step = 0.5;
if (position === 'above') {
const start = targetCard.sort - step * cardsCount;
for (let i = 0; i < cardsCount; i += 1) {
indexes.push(start + step * i);
}
} else {
const start = targetCard.sort + step;
for (let i = 0; i < cardsCount; i += 1) {
indexes.push(start + step * i);
}
}
return indexes;
}
const maxSort = getMaxSortForList(listId, swimlaneId);
const start = maxSort === null ? 0 : maxSort + 1;
for (let i = 0; i < cardsCount; i += 1) {
indexes.push(start + i);
}
return indexes;
}
BlazeComponent.extendComponent({
mapSelection(kind, _id) {
return ReactiveCache.getCards(MultiSelection.getMongoSelector(), {sort: ['sort']}).map(card => {
@ -242,9 +306,12 @@ Template.moveSelectionPopup.onCreated(function() {
this.setFirstListId = function() {
try {
const board = ReactiveCache.getBoard(this.selectedBoardId.get());
const listId = board.lists()[0]._id;
const boardId = this.selectedBoardId.get();
const swimlaneId = this.selectedSwimlaneId.get();
const lists = getListsForBoardSwimlane(boardId, swimlaneId);
const listId = lists[0] ? lists[0]._id : '';
this.selectedListId.set(listId);
this.selectedCardId.set('');
} catch (e) {}
};
@ -271,8 +338,11 @@ Template.moveSelectionPopup.helpers({
return board ? board.swimlanes() : [];
},
lists() {
const board = ReactiveCache.getBoard(Template.instance().selectedBoardId.get());
return board ? board.lists() : [];
const instance = Template.instance();
return getListsForBoardSwimlane(
instance.selectedBoardId.get(),
instance.selectedSwimlaneId.get(),
);
},
cards() {
const instance = Template.instance();
@ -316,10 +386,14 @@ Template.moveSelectionPopup.events({
Template.instance().getBoardData(boardId);
},
'change .js-select-swimlanes'(event) {
Template.instance().selectedSwimlaneId.set($(event.currentTarget).val());
const instance = Template.instance();
instance.selectedSwimlaneId.set($(event.currentTarget).val());
instance.setFirstListId();
},
'change .js-select-lists'(event) {
Template.instance().selectedListId.set($(event.currentTarget).val());
const instance = Template.instance();
instance.selectedListId.set($(event.currentTarget).val());
instance.selectedCardId.set('');
},
'change .js-select-cards'(event) {
Template.instance().selectedCardId.set($(event.currentTarget).val());
@ -327,7 +401,7 @@ Template.moveSelectionPopup.events({
'change input[name="position"]'(event) {
Template.instance().position.set($(event.currentTarget).val());
},
'click .js-done'() {
async 'click .js-done'() {
const instance = Template.instance();
const boardId = instance.selectedBoardId.get();
const swimlaneId = instance.selectedSwimlaneId.get();
@ -335,27 +409,19 @@ Template.moveSelectionPopup.events({
const cardId = instance.selectedCardId.get();
const position = instance.position.get();
// Calculate sortIndex
let sortIndex = 0;
if (cardId) {
const targetCard = ReactiveCache.getCard(cardId);
if (targetCard) {
if (position === 'above') {
sortIndex = targetCard.sort - 0.5;
} else {
sortIndex = targetCard.sort + 0.5;
}
}
} else {
// If no card selected, move to end
const board = ReactiveCache.getBoard(boardId);
const cards = board.cards({ swimlaneId, listId }).sort((a, b) => a.sort - b.sort);
if (cards.length > 0) {
sortIndex = cards[cards.length - 1].sort + 1;
}
}
const selectedCards = getSelectedCardsSorted();
const targetCard = cardId ? ReactiveCache.getCard(cardId) : null;
const sortIndexes = buildInsertionSortIndexes(
selectedCards.length,
targetCard,
position,
listId,
swimlaneId,
);
mutateSelectedCards('move', boardId, swimlaneId, listId, sortIndex);
for (let i = 0; i < selectedCards.length; i += 1) {
await selectedCards[i].move(boardId, swimlaneId, listId, sortIndexes[i]);
}
EscapeActions.executeUpTo('multiselection');
},
});
@ -392,9 +458,12 @@ Template.copySelectionPopup.onCreated(function() {
this.setFirstListId = function() {
try {
const board = ReactiveCache.getBoard(this.selectedBoardId.get());
const listId = board.lists()[0]._id;
const boardId = this.selectedBoardId.get();
const swimlaneId = this.selectedSwimlaneId.get();
const lists = getListsForBoardSwimlane(boardId, swimlaneId);
const listId = lists[0] ? lists[0]._id : '';
this.selectedListId.set(listId);
this.selectedCardId.set('');
} catch (e) {}
};
@ -421,8 +490,11 @@ Template.copySelectionPopup.helpers({
return board ? board.swimlanes() : [];
},
lists() {
const board = ReactiveCache.getBoard(Template.instance().selectedBoardId.get());
return board ? board.lists() : [];
const instance = Template.instance();
return getListsForBoardSwimlane(
instance.selectedBoardId.get(),
instance.selectedSwimlaneId.get(),
);
},
cards() {
const instance = Template.instance();
@ -466,10 +538,14 @@ Template.copySelectionPopup.events({
Template.instance().getBoardData(boardId);
},
'change .js-select-swimlanes'(event) {
Template.instance().selectedSwimlaneId.set($(event.currentTarget).val());
const instance = Template.instance();
instance.selectedSwimlaneId.set($(event.currentTarget).val());
instance.setFirstListId();
},
'change .js-select-lists'(event) {
Template.instance().selectedListId.set($(event.currentTarget).val());
const instance = Template.instance();
instance.selectedListId.set($(event.currentTarget).val());
instance.selectedCardId.set('');
},
'change .js-select-cards'(event) {
Template.instance().selectedCardId.set($(event.currentTarget).val());
@ -477,7 +553,7 @@ Template.copySelectionPopup.events({
'change input[name="position"]'(event) {
Template.instance().position.set($(event.currentTarget).val());
},
'click .js-done'() {
async 'click .js-done'() {
const instance = Template.instance();
const boardId = instance.selectedBoardId.get();
const swimlaneId = instance.selectedSwimlaneId.get();
@ -485,7 +561,18 @@ Template.copySelectionPopup.events({
const cardId = instance.selectedCardId.get();
const position = instance.position.get();
mutateSelectedCards(async (card) => {
const selectedCards = getSelectedCardsSorted();
const targetCard = cardId ? ReactiveCache.getCard(cardId) : null;
const sortIndexes = buildInsertionSortIndexes(
selectedCards.length,
targetCard,
position,
listId,
swimlaneId,
);
for (let i = 0; i < selectedCards.length; i += 1) {
const card = selectedCards[i];
const newCardId = await Meteor.callAsync(
'copyCard',
card._id,
@ -495,32 +582,13 @@ Template.copySelectionPopup.events({
true,
{ title: card.title },
);
if (!newCardId) return;
if (!newCardId) continue;
const newCard = ReactiveCache.getCard(newCardId);
if (!newCard) return;
if (!newCard) continue;
let sortIndex = 0;
if (cardId) {
const targetCard = ReactiveCache.getCard(cardId);
if (targetCard) {
if (position === 'above') {
sortIndex = targetCard.sort - 0.5;
} else {
sortIndex = targetCard.sort + 0.5;
}
}
} else {
// To end
const board = ReactiveCache.getBoard(boardId);
const cards = board.cards({ swimlaneId, listId }).sort((a, b) => a.sort - b.sort);
if (cards.length > 0) {
sortIndex = cards[cards.length - 1].sort + 1;
}
}
await newCard.move(boardId, swimlaneId, listId, sortIndex);
});
await newCard.move(boardId, swimlaneId, listId, sortIndexes[i]);
}
EscapeActions.executeUpTo('multiselection');
},
});

View file

@ -0,0 +1,3 @@
input {
max-width: 100%;
}

View file

@ -14,8 +14,11 @@ BlazeComponent.extendComponent({
},
clickOnMiniCard(evt) {
evt.preventDefault();
Session.set('popupCardId', this.currentData()._id);
if (Utils.isMiniScreen()) {
evt.preventDefault();
Session.set('popupCardId', this.currentData()._id);
this.cardDetailsPopup(evt);
}
},
cardDetailsPopup(event) {