Merge branch 'master' of https://github.com/mark-i-m/wekan into mark-i-m-master

This commit is contained in:
Lauri Ojansivu 2023-07-30 01:41:45 +03:00
commit a2f479f4bd
13 changed files with 232 additions and 19 deletions

View file

@ -7,8 +7,8 @@
border-left: 1px solid #ccc;
padding: 0;
float: left;
min-width: 270px;
max-width: 270px;
min-width: 100px; /* TODO(mark-i-m): hardcoded? */
/*max-width: 270px;*/
/* Reverted incomplete change list width: */
/* https://github.com/wekan/wekan/issues/4558 */
/* Orinal width: 270px. Changes not saved yet: */
@ -179,6 +179,9 @@
#js-wip-limit-edit div {
float: left;
}
#js-list-width-edit .list-width-error {
display: none;
}
@media screen and (max-width: 800px) {
.mini-list {
flex: 0 0 60px;

View file

@ -1,5 +1,6 @@
template(name='list')
.list.js-list(id="js-list-{{_id}}")
.list.js-list(id="js-list-{{_id}}"
style="width:{{listWidth}}px;")
+listHeader
+listBody

View file

@ -194,6 +194,12 @@ BlazeComponent.extendComponent({
});
});
},
listWidth() {
const user = Meteor.user();
const list = Template.currentData();
return user.getListWidth(list.boardId, list._id);
},
}).register('list');
Template.miniList.events({

View file

@ -62,6 +62,11 @@ template(name="listActionPopup")
i.fa.fa-arrow-down
| {{_ 'add-card-to-bottom-of-list'}}
hr
ul.pop-over-list
li
a.js-set-list-width
i.fa.fa-arrows-h
| {{_ 'set-list-width'}}
ul.pop-over-list
li
a.js-toggle-watch-list
@ -156,6 +161,19 @@ template(name="wipLimitErrorPopup")
p {{_ 'wipLimitErrorPopup-dialog-pt2'}}
button.full.js-back-view(type="submit") {{_ 'cancel'}}
template(name="setListWidthPopup")
#js-list-width-edit
label {{_ 'set-list-width-value'}}
p
input.list-width-value(type="number" value="{{ listWidthValue }}" min="100")
input.list-width-apply(type="submit" value="{{_ 'apply'}}")
input.list-width-error
template(name="listWidthErrorPopup")
.list-width-invalid
p {{_ 'list-width-error-message'}}
button.full.js-back-view(type="submit") {{_ 'cancel'}}
template(name="setListColorPopup")
form.edit-label
.palette-colors: each colors

View file

@ -153,6 +153,7 @@ Template.listActionPopup.events({
});
Popup.back();
},
'click .js-set-list-width': Popup.open('setListWidth'),
'click .js-set-color-list': Popup.open('setListColor'),
'click .js-select-cards'() {
const cardIds = this.allCards().map(card => card._id);
@ -320,3 +321,41 @@ BlazeComponent.extendComponent({
];
},
}).register('setListColorPopup');
BlazeComponent.extendComponent({
applyListWidth() {
const list = Template.currentData();
const board = list.boardId;
const width = parseInt(
Template.instance()
.$('.list-width-value')
.val(),
10,
);
// FIXME(mark-i-m): where do we put constants?
if (width < 100 || !width) {
Template.instance()
.$('.list-width-error')
.click();
} else {
Meteor.call('applyListWidth', board, list._id, width);
Popup.back();
}
},
listWidthValue() {
const list = Template.currentData();
const board = list.boardId;
return Meteor.user().getListWidth(board, list._id);
},
events() {
return [
{
'click .list-width-apply': this.applyListWidth,
'click .list-width-error': Popup.open('listWidthError'),
},
];
},
}).register('setListWidthPopup');

View file

@ -44,6 +44,9 @@ template(name="swimlaneActionPopup")
li: a.js-set-swimlane-color
i.fa.fa-paint-brush
| {{_ 'select-color'}}
li: a.js-set-swimlane-height
i.fa.fa-arrows-v
| {{_ 'set-swimlane-height'}}
unless this.isTemplateContainer
hr
ul.pop-over-list
@ -82,6 +85,19 @@ template(name="setSwimlaneColorPopup")
button.primary.confirm.js-submit {{_ 'save'}}
button.js-remove-color.negate.wide.right {{_ 'unset-color'}}
template(name="setSwimlaneHeightPopup")
#js-swimlane-height-edit
label {{_ 'set-swimlane-height-value'}}
p
input.swimlane-height-value(type="number" value="{{ swimlaneHeightValue }}" min="100")
input.swimlane-height-apply(type="submit" value="{{_ 'apply'}}")
input.swimlane-height-error
template(name="swimlaneHeightErrorPopup")
.swimlane-height-invalid
p {{_ 'swimlane-height-error-message'}}
button.full.js-back-view(type="submit") {{_ 'cancel'}}
template(name="swimlaneDeletePopup")
p {{_ "swimlane-delete-pop"}}
button.js-confirm.negate.full(type="submit") {{_ 'delete'}}

View file

@ -37,6 +37,7 @@ Template.swimlaneFixedHeader.helpers({
Template.swimlaneActionPopup.events({
'click .js-set-swimlane-color': Popup.open('setSwimlaneColor'),
'click .js-set-swimlane-height': Popup.open('setSwimlaneHeight'),
'click .js-close-swimlane'(event) {
event.preventDefault();
this.archive();
@ -129,3 +130,45 @@ BlazeComponent.extendComponent({
];
},
}).register('setSwimlaneColorPopup');
BlazeComponent.extendComponent({
onCreated() {
this.currentSwimlane = this.currentData();
},
applySwimlaneHeight() {
const swimlane = this.currentData();
const board = swimlane.boardId;
const height = parseInt(
Template.instance()
.$('.swimlane-height-value')
.val(),
10,
);
// FIXME(mark-i-m): where do we put constants?
if (height < 100 || !height) {
Template.instance()
.$('.swimlane-height-error')
.click();
} else {
Meteor.call('applySwimlaneHeight', board, swimlane._id, height);
Popup.back();
}
},
swimlaneHeightValue() {
const swimlane = this.currentData();
const board = swimlane.boardId;
return Meteor.user().getSwimlaneHeight(board, swimlane._id);
},
events() {
return [
{
'click .swimlane-height-apply': this.applySwimlaneHeight,
'click .swimlane-height-error': Popup.open('swimlaneHeightError'),
},
];
},
}).register('setSwimlaneHeightPopup');

View file

@ -116,6 +116,9 @@
left: 87vw;
font-size: 24px;
}
#js-swimlane-height-edit .swimlane-height-error {
display: none;
}
.list-group {
height: 100%;
}

View file

@ -2,7 +2,8 @@ template(name="swimlane")
.swimlane
+swimlaneHeader
unless collapseSwimlane
.swimlane.js-lists.js-swimlane(id="swimlane-{{_id}}")
.swimlane.js-lists.js-swimlane(id="swimlane-{{_id}}"
style="height:{{swimlaneHeight}}px;")
if isMiniScreen
if currentListIsInThisSwimlane _id
+list(currentList)

View file

@ -223,6 +223,12 @@ BlazeComponent.extendComponent({
},
];
},
swimlaneHeight() {
const user = Meteor.user();
const swimlane = Template.currentData();
return user.getSwimlaneHeight(swimlane.boardId, swimlane._id);
},
}).register('swimlane');
BlazeComponent.extendComponent({

View file

@ -85,6 +85,14 @@
"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 List Width",
"set-list-width-value": "List Width (pixels)",
"list-width-error-message": "List width must be a positive integer >=100. TODO(mark-i-m): hard-coded constants",
"setSwimlaneHeightPopup-title": "Set Swimlane Height",
"set-swimlane-height": "Set Swimlane Height",
"set-swimlane-height-value": "Swimlane Height (pixels)",
"swimlane-height-error-message": "Swimlane height must be a positive integer >=100. TODO(mark-i-m): hard-coded constants",
"add-swimlane": "Add Swimlane",
"add-subtask": "Add Subtask",
"add-checklist": "Add Checklist",

View file

@ -80,21 +80,6 @@ Lists.attachSchema(
// XXX We should probably provide a default
optional: true,
},
width: {
/**
* list width, default 270px
*/
type: String,
defaultValue: '270px',
optional: true,
},
height: {
/**
* list height
*/
type: String,
optional: true,
},
updatedAt: {
/**
* last update of the list

View file

@ -422,6 +422,24 @@ Users.attachSchema(
type: String,
defaultValue: '',
},
'profile.listWidths': {
/**
* User-specified width of each list (or nothing if default).
* profile[boardId][listId] = width;
*/
type: Object,
defaultValue: {},
blackbox: true,
},
'profile.swimlaneHeights': {
/**
* User-specified heights of each swimlane (or nothing if default).
* profile[boardId][swimlaneId] = height;
*/
type: Object,
defaultValue: {},
blackbox: true,
},
services: {
/**
* services field of the user
@ -758,6 +776,32 @@ Users.helpers({
return this._getListSortBy()[1];
},
getListWidths() {
const { listWidths = {} } = this.profile || {};
return listWidths;
},
getListWidth(boardId, listId) {
const listWidths = this.getListWidths();
if (listWidths[boardId] && listWidths[boardId][listId]) {
return listWidths[boardId][listId];
} else {
return 270; //TODO(mark-i-m): default?
}
},
getSwimlaneHeights() {
const { swimlaneHeights = {} } = this.profile || {};
return swimlaneHeights;
},
getSwimlaneHeight(boardId, listId) {
const swimlaneHeights = this.getSwimlaneHeights();
if (swimlaneHeights[boardId] && swimlaneHeights[boardId][listId]) {
return swimlaneHeights[boardId][listId];
} else {
return 270; //TODO(mark-i-m): default?
}
},
/** returns all confirmed move and copy dialog field values
* <li> the board, swimlane and list id is stored for each board
*/
@ -1135,6 +1179,32 @@ Users.mutations({
},
};
},
setListWidth(boardId, listId, width) {
let currentWidths = this.getListWidths();
if (!currentWidths[boardId]) {
currentWidths[boardId] = {};
}
currentWidths[boardId][listId] = width;
return {
$set: {
'profile.listWidths': currentWidths,
},
};
},
setSwimlaneHeight(boardId, swimlaneId, height) {
let currentHeights = this.getSwimlaneHeights();
if (!currentHeights[boardId]) {
currentHeights[boardId] = {};
}
currentHeights[boardId][swimlaneId] = height;
return {
$set: {
'profile.swimlaneHeights': currentHeights,
},
};
},
});
Meteor.methods({
@ -1178,6 +1248,20 @@ Meteor.methods({
check(startDay, Number);
ReactiveCache.getCurrentUser().setStartDayOfWeek(startDay);
},
applyListWidth(boardId, listId, width) {
check(boardId, String);
check(listId, String);
check(width, Number);
const user = Meteor.user();
user.setListWidth(boardId, listId, width);
},
applySwimlaneHeight(boardId, swimlaneId, height) {
check(boardId, String);
check(swimlaneId, String);
check(height, Number);
const user = Meteor.user();
user.setSwimlaneHeight(boardId, swimlaneId, height);
},
});
if (Meteor.isServer) {