Merge branch 'feature/optional-auto-width' of https://github.com/NadavTasher/wekan

This commit is contained in:
Lauri Ojansivu 2024-12-08 00:33:58 +02:00
commit 133dd55f4c
9 changed files with 116 additions and 11 deletions

View file

@ -23,6 +23,10 @@ template(name="boardHeaderBar")
span
= currentBoard.stars
a.board-header-btn.js-auto-width-board(
title="{{#if isAutoWidth}}{{_ 'click-to-disable-auto-width'}}{{else}}{{_ 'click-to-enable-auto-width'}}{{/if}}")
i.fa(class="fa-solid fa-{{#if isAutoWidth}}compress{{else}}expand{{/if}}")
a.board-header-btn(
class="{{#if currentUser.isBoardAdmin}}js-change-visibility{{else}}is-disabled{{/if}}"
title="{{_ currentBoard.permission}}")
@ -66,6 +70,10 @@ template(name="boardHeaderBar")
span
= currentBoard.stars
a.board-header-btn.js-auto-width-board(
title="{{#if isAutoWidth}}{{_ 'click-to-disable-auto-width'}}{{else}}{{_ 'click-to-enable-auto-width'}}{{/if}}")
i.fa(class="fa-solid fa-{{#if isAutoWidth}}compress{{else}}expand{{/if}}")
a.board-header-btn(
class="{{#if currentUser.isBoardAdmin}}js-change-visibility{{else}}is-disabled{{/if}}"
title="{{_ currentBoard.permission}}")

View file

@ -38,6 +38,12 @@ BlazeComponent.extendComponent({
return user && user.hasStarred(boardId);
},
isAutoWidth() {
const boardId = Utils.getCurrentBoardId();
const user = ReactiveCache.getCurrentUser();
return user && user.isAutoWidth(boardId);
},
// Only show the star counter if the number of star is greater than 2
showStarCounter() {
const currentBoard = Utils.getCurrentBoard();
@ -71,6 +77,9 @@ BlazeComponent.extendComponent({
'click .js-star-board'() {
ReactiveCache.getCurrentUser().toggleBoardStar(Session.get('currentBoard'));
},
'click .js-auto-width-board'() {
ReactiveCache.getCurrentUser().toggleAutoWidth(Utils.getCurrentBoardId());
},
'click .js-open-board-menu': Popup.open('boardMenu'),
'click .js-change-visibility': Popup.open('boardChangeVisibility'),
'click .js-watch-board': Popup.open('boardChangeWatch'),

View file

@ -7,11 +7,13 @@
border-left: 1px solid #ccc;
padding: 0;
float: left;
flex: 1;
}
[id^="swimlane-"] .list:first-child {
min-width: 20px;
}
.list.list-auto-width {
flex: 1;
}
.list:first-child {
border-left: none;
flex: none;

View file

@ -1,7 +1,7 @@
template(name='list')
.list.js-list(id="js-list-{{_id}}"
style="{{#unless collapsed}}min-width:{{listWidth}}px;{{/unless}}"
class="{{#if collapsed}}list-collapsed{{/if}}")
style="{{#unless collapsed}}min-width:{{listWidth}}px;max-width:{{listConstraint}}px;{{/unless}}"
class="{{#if collapsed}}list-collapsed{{/if}} {{#if autoWidth}}list-auto-width{{/if}}")
+listHeader
+listBody

View file

@ -200,6 +200,18 @@ BlazeComponent.extendComponent({
const list = Template.currentData();
return user.getListWidth(list.boardId, list._id);
},
listConstraint() {
const user = ReactiveCache.getCurrentUser();
const list = Template.currentData();
return user.getListConstraint(list.boardId, list._id);
},
autoWidth() {
const user = ReactiveCache.getCurrentUser();
const list = Template.currentData();
return user.isAutoWidth(list.boardId);
},
}).register('list');
Template.miniList.events({

View file

@ -191,6 +191,7 @@ template(name="setListWidthPopup")
label {{_ 'set-list-width-value'}}
p
input.list-width-value(type="number" value="{{ listWidthValue }}" min="100")
input.list-constraint-value(type="number" value="{{ listConstraintValue }}" min="100")
input.list-width-apply(type="submit" value="{{_ 'apply'}}")
input.list-width-error

View file

@ -347,14 +347,20 @@ BlazeComponent.extendComponent({
.val(),
10,
);
const constraint = parseInt(
Template.instance()
.$('.list-constraint-value')
.val(),
10,
);
// FIXME(mark-i-m): where do we put constants?
if (width < 100 || !width) {
if (width < 100 || !width || constraint < 100 || !constraint) {
Template.instance()
.$('.list-width-error')
.click();
} else {
Meteor.call('applyListWidth', board, list._id, width);
Meteor.call('applyListWidth', board, list._id, width, constraint);
Popup.back();
}
},
@ -365,6 +371,12 @@ BlazeComponent.extendComponent({
return ReactiveCache.getCurrentUser().getListWidth(board, list._id);
},
listConstraintValue() {
const list = Template.currentData();
const board = list.boardId;
return ReactiveCache.getCurrentUser().getListConstraint(board, list._id);
},
events() {
return [
{

View file

@ -86,10 +86,10 @@
"add-card": "Add Card",
"add-card-to-top-of-list": "Add Card to Top of List",
"add-card-to-bottom-of-list": "Add Card to Bottom of List",
"setListWidthPopup-title": "Set List Width",
"set-list-width": "Set Min Width",
"set-list-width-value": "Min Width (pixels)",
"list-width-error-message": "List width must be a positive integer",
"setListWidthPopup-title": "Set Widths",
"set-list-width": "Set Widths",
"set-list-width-value": "Set Min & Max Widths (pixels)",
"list-width-error-message": "List widths must be integers greater than 100",
"setSwimlaneHeightPopup-title": "Set Swimlane Height",
"set-swimlane-height": "Set Swimlane Height",
"set-swimlane-height-value": "Swimlane Height (pixels)",
@ -264,6 +264,8 @@
"checklists": "Checklists",
"click-to-star": "Click to star this board.",
"click-to-unstar": "Click to unstar this board.",
"click-to-enable-auto-width": "Click to enable auto list width.",
"click-to-disable-auto-width": "Click to disable auto list width.",
"clipboard": "Clipboard or drag & drop",
"close": "Close",
"close-board": "Close Board",

View file

@ -417,6 +417,24 @@ Users.attachSchema(
defaultValue: {},
blackbox: true,
},
'profile.listConstraints': {
/**
* User-specified constraint of each list (or nothing if default).
* profile[boardId][listId] = constraint;
*/
type: Object,
defaultValue: {},
blackbox: true,
},
'profile.autoWidthBoards': {
/**
* User-specified flag for enabling auto-width for boards (false is the default).
* profile[boardId][listId] = constraint;
*/
type: Object,
defaultValue: {},
blackbox: true,
},
'profile.swimlaneHeights': {
/**
* User-specified heights of each swimlane (or nothing if default).
@ -716,6 +734,11 @@ Users.helpers({
return _.contains(starredBoards, boardId);
},
isAutoWidth(boardId) {
const { autoWidthBoards = {} } = this.profile || {};
return autoWidthBoards[boardId] === true;
},
invitedBoards() {
const { invitedBoards = [] } = this.profile || {};
return Boards.userBoards(
@ -757,7 +780,7 @@ Users.helpers({
},
getListWidths() {
const { listWidths = {} } = this.profile || {};
const { listWidths = {}, } = this.profile || {};
return listWidths;
},
getListWidth(boardId, listId) {
@ -768,6 +791,18 @@ Users.helpers({
return 270; //TODO(mark-i-m): default?
}
},
getListConstraints() {
const { listConstraints = {} } = this.profile || {};
return listConstraints;
},
getListConstraint(boardId, listId) {
const listConstraints = this.getListConstraints();
if (listConstraints[boardId] && listConstraints[boardId][listId]) {
return listConstraints[boardId][listId];
} else {
return 350;
}
},
getSwimlaneHeights() {
const { swimlaneHeights = {} } = this.profile || {};
@ -974,6 +1009,15 @@ Users.mutations({
},
};
},
toggleAutoWidth(boardId) {
const { autoWidthBoards = {} } = this.profile || {};
autoWidthBoards[boardId] = !autoWidthBoards[boardId];
return {
$set: {
'profile.autoWidthBoards': autoWidthBoards,
},
};
},
addInvite(boardId) {
return {
@ -1148,6 +1192,19 @@ Users.mutations({
};
},
setListConstraint(boardId, listId, constraint) {
let currentConstraints = this.getListConstraints();
if (!currentConstraints[boardId]) {
currentConstraints[boardId] = {};
}
currentConstraints[boardId][listId] = constraint;
return {
$set: {
'profile.listConstraints': currentConstraints,
},
};
},
setSwimlaneHeight(boardId, swimlaneId, height) {
let currentHeights = this.getSwimlaneHeights();
if (!currentHeights[boardId]) {
@ -1199,12 +1256,14 @@ Meteor.methods({
check(startDay, Number);
ReactiveCache.getCurrentUser().setStartDayOfWeek(startDay);
},
applyListWidth(boardId, listId, width) {
applyListWidth(boardId, listId, width, constraint) {
check(boardId, String);
check(listId, String);
check(width, Number);
check(constraint, Number);
const user = ReactiveCache.getCurrentUser();
user.setListWidth(boardId, listId, width);
user.setListConstraint(boardId, listId, constraint);
},
applySwimlaneHeight(boardId, swimlaneId, height) {
check(boardId, String);