mirror of
https://github.com/wekan/wekan.git
synced 2025-12-16 23:40:13 +01:00
At Public Board, drag resize list width and swimlane height. For logged in users, fix adding labels.
Thanks to xet7 ! Fixes #5922
This commit is contained in:
parent
55bec31a3f
commit
3514335247
13 changed files with 279 additions and 103 deletions
|
|
@ -34,7 +34,8 @@ This release fixes the following bugs:
|
||||||
- [Fix unable to see My Due Cards](https://github.com/wekan/wekan/commit/66b444e2b0c9b2ed5f98cd1ff0cd9222b2d0c624).
|
- [Fix unable to see My Due Cards](https://github.com/wekan/wekan/commit/66b444e2b0c9b2ed5f98cd1ff0cd9222b2d0c624).
|
||||||
Thanks to xet7.
|
Thanks to xet7.
|
||||||
- Fix drag drop lists.
|
- Fix drag drop lists.
|
||||||
[Part 1](https://github.com/wekan/wekan/commit/324f3f7794aace800022a24deb5fd5fb36ebd384).
|
[Part 1](https://github.com/wekan/wekan/commit/324f3f7794aace800022a24deb5fd5fb36ebd384),
|
||||||
|
[Part 2](https://github.com/wekan/wekan/commit/ff516ec696ef499f11b04b30053eeb9d3f96d8d1).
|
||||||
Thanks to xet7.
|
Thanks to xet7.
|
||||||
- [Removed extra pipe characters](https://github.com/wekan/wekan/commit/caa6e615ff3c3681bf2b470a625eb39c6009b825).
|
- [Removed extra pipe characters](https://github.com/wekan/wekan/commit/caa6e615ff3c3681bf2b470a625eb39c6009b825).
|
||||||
Thanks to xet7.
|
Thanks to xet7.
|
||||||
|
|
|
||||||
|
|
@ -168,7 +168,12 @@ CardCustomField.register('cardCustomField');
|
||||||
}
|
}
|
||||||
|
|
||||||
showWeekOfYear() {
|
showWeekOfYear() {
|
||||||
return ReactiveCache.getCurrentUser().isShowWeekOfYear();
|
const user = ReactiveCache.getCurrentUser();
|
||||||
|
if (!user) {
|
||||||
|
// For non-logged-in users, week of year is not shown
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return user.isShowWeekOfYear();
|
||||||
}
|
}
|
||||||
|
|
||||||
showDate() {
|
showDate() {
|
||||||
|
|
|
||||||
|
|
@ -131,7 +131,12 @@ const CardDate = BlazeComponent.extendComponent({
|
||||||
},
|
},
|
||||||
|
|
||||||
showWeekOfYear() {
|
showWeekOfYear() {
|
||||||
return ReactiveCache.getCurrentUser().isShowWeekOfYear();
|
const user = ReactiveCache.getCurrentUser();
|
||||||
|
if (!user) {
|
||||||
|
// For non-logged-in users, week of year is not shown
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return user.isShowWeekOfYear();
|
||||||
},
|
},
|
||||||
|
|
||||||
showDate() {
|
showDate() {
|
||||||
|
|
@ -301,7 +306,12 @@ class CardCustomFieldDate extends CardDate {
|
||||||
}
|
}
|
||||||
|
|
||||||
showWeekOfYear() {
|
showWeekOfYear() {
|
||||||
return ReactiveCache.getCurrentUser().isShowWeekOfYear();
|
const user = ReactiveCache.getCurrentUser();
|
||||||
|
if (!user) {
|
||||||
|
// For non-logged-in users, week of year is not shown
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return user.isShowWeekOfYear();
|
||||||
}
|
}
|
||||||
|
|
||||||
showDate() {
|
showDate() {
|
||||||
|
|
|
||||||
|
|
@ -125,8 +125,19 @@ Template.createLabelPopup.events({
|
||||||
.$('#labelName')
|
.$('#labelName')
|
||||||
.val()
|
.val()
|
||||||
.trim();
|
.trim();
|
||||||
const color = Blaze.getData(templateInstance.find('.fa-check')).color;
|
|
||||||
board.addLabel(name, color);
|
// Find the selected color by looking for the palette color that contains the checkmark
|
||||||
|
let selectedColor = null;
|
||||||
|
templateInstance.$('.js-palette-color').each(function() {
|
||||||
|
if ($(this).text().includes('✅')) {
|
||||||
|
selectedColor = Blaze.getData(this).color;
|
||||||
|
return false; // break out of loop
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (selectedColor) {
|
||||||
|
board.addLabel(name, selectedColor);
|
||||||
|
}
|
||||||
Popup.back();
|
Popup.back();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
@ -144,8 +155,19 @@ Template.editLabelPopup.events({
|
||||||
.$('#labelName')
|
.$('#labelName')
|
||||||
.val()
|
.val()
|
||||||
.trim();
|
.trim();
|
||||||
const color = Blaze.getData(templateInstance.find('.fa-check')).color;
|
|
||||||
board.editLabel(this._id, name, color);
|
// Find the selected color by looking for the palette color that contains the checkmark
|
||||||
|
let selectedColor = null;
|
||||||
|
templateInstance.$('.js-palette-color').each(function() {
|
||||||
|
if ($(this).text().includes('✅')) {
|
||||||
|
selectedColor = Blaze.getData(this).color;
|
||||||
|
return false; // break out of loop
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (selectedColor) {
|
||||||
|
board.editLabel(this._id, name, selectedColor);
|
||||||
|
}
|
||||||
Popup.back();
|
Popup.back();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -197,20 +197,60 @@ BlazeComponent.extendComponent({
|
||||||
listWidth() {
|
listWidth() {
|
||||||
const user = ReactiveCache.getCurrentUser();
|
const user = ReactiveCache.getCurrentUser();
|
||||||
const list = Template.currentData();
|
const list = Template.currentData();
|
||||||
if (!user || !list) return 270; // Return default width if user or list is not available
|
if (!list) return 270; // Return default width if list is not available
|
||||||
|
|
||||||
|
if (user) {
|
||||||
|
// For logged-in users, get from user profile
|
||||||
return user.getListWidthFromStorage(list.boardId, list._id);
|
return user.getListWidthFromStorage(list.boardId, list._id);
|
||||||
|
} else {
|
||||||
|
// For non-logged-in users, get from localStorage
|
||||||
|
try {
|
||||||
|
const stored = localStorage.getItem('wekan-list-widths');
|
||||||
|
if (stored) {
|
||||||
|
const widths = JSON.parse(stored);
|
||||||
|
if (widths[list.boardId] && widths[list.boardId][list._id]) {
|
||||||
|
return widths[list.boardId][list._id];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('Error reading list width from localStorage:', e);
|
||||||
|
}
|
||||||
|
return 270; // Return default width if not found
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
listConstraint() {
|
listConstraint() {
|
||||||
const user = ReactiveCache.getCurrentUser();
|
const user = ReactiveCache.getCurrentUser();
|
||||||
const list = Template.currentData();
|
const list = Template.currentData();
|
||||||
if (!user || !list) return 550; // Return default constraint if user or list is not available
|
if (!list) return 550; // Return default constraint if list is not available
|
||||||
|
|
||||||
|
if (user) {
|
||||||
|
// For logged-in users, get from user profile
|
||||||
return user.getListConstraintFromStorage(list.boardId, list._id);
|
return user.getListConstraintFromStorage(list.boardId, list._id);
|
||||||
|
} else {
|
||||||
|
// For non-logged-in users, get from localStorage
|
||||||
|
try {
|
||||||
|
const stored = localStorage.getItem('wekan-list-constraints');
|
||||||
|
if (stored) {
|
||||||
|
const constraints = JSON.parse(stored);
|
||||||
|
if (constraints[list.boardId] && constraints[list.boardId][list._id]) {
|
||||||
|
return constraints[list.boardId][list._id];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('Error reading list constraint from localStorage:', e);
|
||||||
|
}
|
||||||
|
return 550; // Return default constraint if not found
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
autoWidth() {
|
autoWidth() {
|
||||||
const user = ReactiveCache.getCurrentUser();
|
const user = ReactiveCache.getCurrentUser();
|
||||||
const list = Template.currentData();
|
const list = Template.currentData();
|
||||||
|
if (!user) {
|
||||||
|
// For non-logged-in users, auto-width is disabled
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return user.isAutoWidth(list.boardId);
|
return user.isAutoWidth(list.boardId);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -329,6 +369,10 @@ BlazeComponent.extendComponent({
|
||||||
// Use the new storage method that handles both logged-in and non-logged-in users
|
// Use the new storage method that handles both logged-in and non-logged-in users
|
||||||
if (process.env.DEBUG === 'true') {
|
if (process.env.DEBUG === 'true') {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const currentUser = ReactiveCache.getCurrentUser();
|
||||||
|
if (currentUser) {
|
||||||
|
// For logged-in users, use server method
|
||||||
Meteor.call('applyListWidthToStorage', boardId, listId, finalWidth, listConstraint, (error, result) => {
|
Meteor.call('applyListWidthToStorage', boardId, listId, finalWidth, listConstraint, (error, result) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
console.error('Error saving list width:', error);
|
console.error('Error saving list width:', error);
|
||||||
|
|
@ -337,6 +381,37 @@ BlazeComponent.extendComponent({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
// For non-logged-in users, save to localStorage directly
|
||||||
|
try {
|
||||||
|
// Save list width
|
||||||
|
const storedWidths = localStorage.getItem('wekan-list-widths');
|
||||||
|
let widths = storedWidths ? JSON.parse(storedWidths) : {};
|
||||||
|
|
||||||
|
if (!widths[boardId]) {
|
||||||
|
widths[boardId] = {};
|
||||||
|
}
|
||||||
|
widths[boardId][listId] = finalWidth;
|
||||||
|
|
||||||
|
localStorage.setItem('wekan-list-widths', JSON.stringify(widths));
|
||||||
|
|
||||||
|
// Save list constraint
|
||||||
|
const storedConstraints = localStorage.getItem('wekan-list-constraints');
|
||||||
|
let constraints = storedConstraints ? JSON.parse(storedConstraints) : {};
|
||||||
|
|
||||||
|
if (!constraints[boardId]) {
|
||||||
|
constraints[boardId] = {};
|
||||||
|
}
|
||||||
|
constraints[boardId][listId] = listConstraint;
|
||||||
|
|
||||||
|
localStorage.setItem('wekan-list-constraints', JSON.stringify(constraints));
|
||||||
|
|
||||||
|
if (process.env.DEBUG === 'true') {
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('Error saving list width/constraint to localStorage:', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -220,6 +220,7 @@
|
||||||
margin: 0;
|
margin: 0;
|
||||||
margin-top: 1px;
|
margin-top: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#header-quick-access #header-user-bar .header-user-bar-name,
|
#header-quick-access #header-user-bar .header-user-bar-name,
|
||||||
#header-quick-access #header-help {
|
#header-quick-access #header-help {
|
||||||
margin: 4px 8px 0 0;
|
margin: 4px 8px 0 0;
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,6 @@ template(name="sidebar")
|
||||||
+Template.dynamic(template=getViewTemplate)
|
+Template.dynamic(template=getViewTemplate)
|
||||||
|
|
||||||
template(name='homeSidebar')
|
template(name='homeSidebar')
|
||||||
hr
|
|
||||||
+membersWidget
|
+membersWidget
|
||||||
hr
|
hr
|
||||||
+labelsWidget
|
+labelsWidget
|
||||||
|
|
@ -38,6 +37,7 @@ template(name='homeSidebar')
|
||||||
span {{_ 'hide-minicard-label-text'}}
|
span {{_ 'hide-minicard-label-text'}}
|
||||||
b
|
b
|
||||||
.materialCheckBox(class="{{#if hiddenMinicardLabelText}}is-checked{{/if}}")
|
.materialCheckBox(class="{{#if hiddenMinicardLabelText}}is-checked{{/if}}")
|
||||||
|
if currentUser
|
||||||
ul#cards.vertical-scrollbars-toggle
|
ul#cards.vertical-scrollbars-toggle
|
||||||
a.flex.js-vertical-scrollbars-toggle(title="{{_ 'enable-vertical-scrollbars'}}")
|
a.flex.js-vertical-scrollbars-toggle(title="{{_ 'enable-vertical-scrollbars'}}")
|
||||||
span {{_ 'enable-vertical-scrollbars'}}
|
span {{_ 'enable-vertical-scrollbars'}}
|
||||||
|
|
|
||||||
|
|
@ -203,6 +203,8 @@ BlazeComponent.extendComponent({
|
||||||
},
|
},
|
||||||
}).register('homeSidebar');
|
}).register('homeSidebar');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Template.boardInfoOnMyBoardsPopup.helpers({
|
Template.boardInfoOnMyBoardsPopup.helpers({
|
||||||
hideCardCounterList() {
|
hideCardCounterList() {
|
||||||
return Utils.isMiniScreen() && Session.get('currentBoard');
|
return Utils.isMiniScreen() && Session.get('currentBoard');
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ template(name="swimlaneFixedHeader")
|
||||||
+viewer
|
+viewer
|
||||||
| {{isTitleDefault title}}
|
| {{isTitleDefault title}}
|
||||||
.swimlane-header-menu
|
.swimlane-header-menu
|
||||||
|
if currentUser
|
||||||
unless currentUser.isCommentOnly
|
unless currentUser.isCommentOnly
|
||||||
a.js-open-add-swimlane-menu.swimlane-header-plus-icon(title="{{_ 'add-swimlane'}}")
|
a.js-open-add-swimlane-menu.swimlane-header-plus-icon(title="{{_ 'add-swimlane'}}")
|
||||||
| ➕
|
| ➕
|
||||||
|
|
@ -53,6 +54,7 @@ template(name="editSwimlaneTitleForm")
|
||||||
| ❌
|
| ❌
|
||||||
|
|
||||||
template(name="swimlaneActionPopup")
|
template(name="swimlaneActionPopup")
|
||||||
|
if currentUser
|
||||||
unless currentUser.isCommentOnly
|
unless currentUser.isCommentOnly
|
||||||
ul.pop-over-list
|
ul.pop-over-list
|
||||||
if currentUser.isBoardAdmin
|
if currentUser.isBoardAdmin
|
||||||
|
|
@ -80,6 +82,7 @@ template(name="swimlaneActionPopup")
|
||||||
| {{_ 'move-swimlane'}}
|
| {{_ 'move-swimlane'}}
|
||||||
|
|
||||||
template(name="swimlaneAddPopup")
|
template(name="swimlaneAddPopup")
|
||||||
|
if currentUser
|
||||||
unless currentUser.isCommentOnly
|
unless currentUser.isCommentOnly
|
||||||
form
|
form
|
||||||
input.swimlane-name-input.full-line(type="text" placeholder="{{_ 'add-swimlane'}}"
|
input.swimlane-name-input.full-line(type="text" placeholder="{{_ 'add-swimlane'}}"
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,7 @@ template(name="addListForm")
|
||||||
| ➕
|
| ➕
|
||||||
|
|
||||||
template(name="moveSwimlanePopup")
|
template(name="moveSwimlanePopup")
|
||||||
|
if currentUser
|
||||||
unless currentUser.isWorker
|
unless currentUser.isWorker
|
||||||
label {{_ 'boards'}}:
|
label {{_ 'boards'}}:
|
||||||
select.js-select-boards(autofocus)
|
select.js-select-boards(autofocus)
|
||||||
|
|
@ -82,6 +83,7 @@ template(name="moveSwimlanePopup")
|
||||||
button.primary.confirm.js-done {{_ 'done'}}
|
button.primary.confirm.js-done {{_ 'done'}}
|
||||||
|
|
||||||
template(name="copySwimlanePopup")
|
template(name="copySwimlanePopup")
|
||||||
|
if currentUser
|
||||||
unless currentUser.isWorker
|
unless currentUser.isWorker
|
||||||
label {{_ 'boards'}}:
|
label {{_ 'boards'}}:
|
||||||
select.js-select-boards(autofocus)
|
select.js-select-boards(autofocus)
|
||||||
|
|
|
||||||
|
|
@ -423,7 +423,31 @@ BlazeComponent.extendComponent({
|
||||||
swimlaneHeight() {
|
swimlaneHeight() {
|
||||||
const user = ReactiveCache.getCurrentUser();
|
const user = ReactiveCache.getCurrentUser();
|
||||||
const swimlane = Template.currentData();
|
const swimlane = Template.currentData();
|
||||||
const height = user.getSwimlaneHeightFromStorage(swimlane.boardId, swimlane._id);
|
|
||||||
|
let height;
|
||||||
|
if (user) {
|
||||||
|
// For logged-in users, get from user profile
|
||||||
|
height = user.getSwimlaneHeightFromStorage(swimlane.boardId, swimlane._id);
|
||||||
|
} else {
|
||||||
|
// For non-logged-in users, get from localStorage
|
||||||
|
try {
|
||||||
|
const stored = localStorage.getItem('wekan-swimlane-heights');
|
||||||
|
if (stored) {
|
||||||
|
const heights = JSON.parse(stored);
|
||||||
|
if (heights[swimlane.boardId] && heights[swimlane.boardId][swimlane._id]) {
|
||||||
|
height = heights[swimlane.boardId][swimlane._id];
|
||||||
|
} else {
|
||||||
|
height = -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
height = -1;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('Error reading swimlane height from localStorage:', e);
|
||||||
|
height = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return height == -1 ? "auto" : (height + 5 + "px");
|
return height == -1 ? "auto" : (height + 5 + "px");
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -537,7 +561,9 @@ BlazeComponent.extendComponent({
|
||||||
if (process.env.DEBUG === 'true') {
|
if (process.env.DEBUG === 'true') {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use the new storage method that handles both logged-in and non-logged-in users
|
const currentUser = ReactiveCache.getCurrentUser();
|
||||||
|
if (currentUser) {
|
||||||
|
// For logged-in users, use server method
|
||||||
Meteor.call('applySwimlaneHeightToStorage', boardId, swimlaneId, finalHeight, (error, result) => {
|
Meteor.call('applySwimlaneHeightToStorage', boardId, swimlaneId, finalHeight, (error, result) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
console.error('Error saving swimlane height:', error);
|
console.error('Error saving swimlane height:', error);
|
||||||
|
|
@ -546,6 +572,25 @@ BlazeComponent.extendComponent({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
// For non-logged-in users, save to localStorage directly
|
||||||
|
try {
|
||||||
|
const stored = localStorage.getItem('wekan-swimlane-heights');
|
||||||
|
let heights = stored ? JSON.parse(stored) : {};
|
||||||
|
|
||||||
|
if (!heights[boardId]) {
|
||||||
|
heights[boardId] = {};
|
||||||
|
}
|
||||||
|
heights[boardId][swimlaneId] = finalHeight;
|
||||||
|
|
||||||
|
localStorage.setItem('wekan-swimlane-heights', JSON.stringify(heights));
|
||||||
|
|
||||||
|
if (process.env.DEBUG === 'true') {
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('Error saving swimlane height to localStorage:', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,10 @@ window.Popup = new (class {
|
||||||
// our internal dependency, and since we just changed the top element of
|
// our internal dependency, and since we just changed the top element of
|
||||||
// our internal stack, the popup will be updated with the new data.
|
// our internal stack, the popup will be updated with the new data.
|
||||||
if (!self.isOpen()) {
|
if (!self.isOpen()) {
|
||||||
|
if (!Template[popupName]) {
|
||||||
|
console.error('Template not found:', popupName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
self.current = Blaze.renderWithData(
|
self.current = Blaze.renderWithData(
|
||||||
self.template,
|
self.template,
|
||||||
() => {
|
() => {
|
||||||
|
|
|
||||||
|
|
@ -1619,7 +1619,10 @@ Meteor.methods({
|
||||||
check(swimlaneId, String);
|
check(swimlaneId, String);
|
||||||
check(height, Number);
|
check(height, Number);
|
||||||
const user = ReactiveCache.getCurrentUser();
|
const user = ReactiveCache.getCurrentUser();
|
||||||
|
if (user) {
|
||||||
user.setSwimlaneHeightToStorage(boardId, swimlaneId, height);
|
user.setSwimlaneHeightToStorage(boardId, swimlaneId, height);
|
||||||
|
}
|
||||||
|
// For non-logged-in users, the client-side code will handle localStorage
|
||||||
},
|
},
|
||||||
|
|
||||||
applyListWidthToStorage(boardId, listId, width, constraint) {
|
applyListWidthToStorage(boardId, listId, width, constraint) {
|
||||||
|
|
@ -1628,8 +1631,11 @@ Meteor.methods({
|
||||||
check(width, Number);
|
check(width, Number);
|
||||||
check(constraint, Number);
|
check(constraint, Number);
|
||||||
const user = ReactiveCache.getCurrentUser();
|
const user = ReactiveCache.getCurrentUser();
|
||||||
|
if (user) {
|
||||||
user.setListWidthToStorage(boardId, listId, width);
|
user.setListWidthToStorage(boardId, listId, width);
|
||||||
user.setListConstraintToStorage(boardId, listId, constraint);
|
user.setListConstraintToStorage(boardId, listId, constraint);
|
||||||
|
}
|
||||||
|
// For non-logged-in users, the client-side code will handle localStorage
|
||||||
},
|
},
|
||||||
setZoomLevel(level) {
|
setZoomLevel(level) {
|
||||||
check(level, Number);
|
check(level, Number);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue