Collapse Lists to be per user, not per board. In Progress.

Related #5388

Thanks to xet7 !
This commit is contained in:
Lauri Ojansivu 2024-05-01 23:58:57 +03:00
parent e73a44d15b
commit 902f86d363
7 changed files with 74 additions and 44 deletions

View file

@ -6,15 +6,15 @@ template(name="listHeader")
+editListTitleForm
else
unless isMiniScreen
if collapsed
a.js-collapse(title="{{_ 'uncollapse'}}")
if listCollapsed
a.js-collapse-list(title="{{_ 'uncollapse'}}")
i.fa.fa-arrow-left.list-header-uncollapse-left
i.fa.fa-arrow-right.list-header-uncollapse-right
if isMiniScreen
if currentList
a.list-header-left-icon.fa.fa-angle-left.js-unselect-list
unless isMiniScreen
if collapsed
if listCollapsed
if showCardsCountForList cards.length
br
span.cardCount {{cardsCount}}
@ -29,7 +29,7 @@ template(name="listHeader")
span(class="{{#if exceededWipLimit}}highlight{{/if}}") {{cards.length}}
|/#{wipLimit.value})
unless isMiniScreen
div(class="{{#if collapsed}}list-rotated{{/if}}")
div(class="{{#if listCollapsed}}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}}")
@ -39,7 +39,7 @@ template(name="listHeader")
| (
span(class="{{#if exceededWipLimit}}highlight{{/if}}") {{cards.length}}
|/#{wipLimit.value})
unless collapsed
unless listCollapsed
if showCardsCountForList cards.length
span.cardCount {{cardsCount}} {{cardsCountForListIsOne cards.length}}
if isMiniScreen
@ -57,14 +57,14 @@ template(name="listHeader")
else if currentUser.isBoardMember
if isWatching
i.list-header-watch-icon.fa.fa-eye
unless collapsed
unless listCollapsed
div.list-header-menu
unless currentUser.isCommentOnly
//if isBoardAdmin
// a.fa.js-list-star.list-header-plus-top(class="fa-star{{#unless starred}}-o{{/unless}}")
if canSeeAddCard
a.js-add-card.fa.fa-plus.list-header-plus-top(title="{{_ 'add-card-to-top-of-list'}}")
a.js-collapse(title="{{_ 'collapse'}}")
a.js-collapse-list(title="{{_ 'collapse'}}")
i.fa.fa-arrow-right.list-header-collapse-right
i.fa.fa-arrow-left.list-header-collapse-left
a.fa.fa-navicon.js-open-list-menu(title="{{_ 'listActionPopup-title'}}")

View file

@ -31,14 +31,14 @@ BlazeComponent.extendComponent({
return !status;
}
},
collapsed(check = undefined) {
const list = Template.currentData();
const status = list.isCollapsed();
listCollapsed(check = undefined) {
const user = Meteor.user();
const status = user.hasCollapsedList(this._id);
if (check === undefined) {
// just check
return status;
} else {
list.collapse(!status);
user.toggleCollapseList(this._id);
return !status;
}
},
@ -115,9 +115,9 @@ BlazeComponent.extendComponent({
event.preventDefault();
this.starred(!this.starred());
},
'click .js-collapse'(event) {
'click .js-collapse-list'(event) {
event.preventDefault();
this.collapsed(!this.collapsed());
this.listCollapsed(!this.listCollapsed());
},
'click .js-open-list-menu': Popup.open('listAction'),
'click .js-add-card.list-header-plus-top'(event) {

View file

@ -156,13 +156,6 @@ Lists.attachSchema(
type: String,
defaultValue: 'list',
},
collapsed: {
/**
* is the list collapsed
*/
type: Boolean,
defaultValue: false,
},
}),
);
@ -293,10 +286,6 @@ Lists.helpers({
return this.starred === true;
},
isCollapsed() {
return this.collapsed === true;
},
absoluteUrl() {
const card = ReactiveCache.getCard({ listId: this._id });
return card && card.absoluteUrl();
@ -317,9 +306,6 @@ Lists.mutations({
star(enable = true) {
return { $set: { starred: !!enable } };
},
collapse(enable = true) {
return { $set: { collapsed: !!enable } };
},
archive() {
if (this.isTemplateList()) {

View file

@ -107,13 +107,6 @@ Swimlanes.attachSchema(
type: String,
defaultValue: 'swimlane',
},
collapsed: {
/**
* is the swimlane collapsed
*/
type: Boolean,
defaultValue: false,
},
}),
);
@ -239,10 +232,6 @@ Swimlanes.helpers({
return ret;
},
isCollapsed() {
return this.collapsed === true;
},
board() {
return ReactiveCache.getBoard(this.boardId);
},
@ -285,10 +274,6 @@ Swimlanes.mutations({
return { $set: { title } };
},
collapse(enable = true) {
return { $set: { collapsed: !!enable } };
},
archive() {
if (this.isTemplateSwimlane()) {
this.myLists().forEach(list => {

View file

@ -440,6 +440,20 @@ Users.attachSchema(
defaultValue: {},
blackbox: true,
},
'profile.listCollapsed': {
/**
* User-specific list of collapsed list IDs
*/
type: [String],
optional: true,
},
'profile.swimlaneCollapsed': {
/**
* User-specific list of collapsed swimlane IDs
*/
type: [String],
optional: true,
},
services: {
/**
* services field of the user
@ -736,6 +750,36 @@ Users.helpers({
return _.contains(starredBoards, boardId);
},
collapsedLists() {
const { collapsedLists = [] } = this.profile || {};
return Lists.userLists(
this._id,
false,
{ _id: { $in: collapsedLists } },
{ sort: { sort: 1 } },
);
},
hasCollapsedList(listId) {
const { collapsedLists = [] } = this.profile || {};
return _.contains(collapsedLists, listId);
},
collapsedSwimlanes() {
const { collapsedSwimlanes = [] } = this.profile || {};
return Swimlanes.userSwimlanes(
this._id,
false,
{ _id: { $in: collapsedSwimlanes } },
{ sort: { sort: 1 } },
);
},
hasCollapsedSwimlane(swimlaneId) {
const { collapsedSwimlanes = [] } = this.profile || {};
return _.contains(collapsedSwimlanes, swimlaneId);
},
invitedBoards() {
const { invitedBoards = [] } = this.profile || {};
return Boards.userBoards(
@ -1004,6 +1048,22 @@ Users.mutations({
},
};
},
toggleCollapseList(listId) {
const queryKind = this.hasCollapsedList(listId) ? '$pull' : '$addToSet';
return {
[queryKind]: {
'profile.listCollapsed': listId,
},
};
},
toggleCollapseSwimlane(swimlaneId) {
const queryKind = this.hasCollapsedSwimlane(swimlaneId) ? '$pull' : '$addToSet';
return {
[queryKind]: {
'profile.swimlaneCollapsed': swimlaneId,
},
};
},
addInvite(boardId) {
return {

View file

@ -61,7 +61,6 @@ Meteor.publishRelations('boards', function() {
title: 1,
boardId: 1,
archived: 1,
collapsed: 1,
sort: 1
}
},

View file

@ -785,7 +785,7 @@ function findCards(sessionId, query) {
),
ReactiveCache.getSwimlanes(
{ _id: { $in: swimlanes } },
{ fields: { ...fields, color: 1, collapsed: 1 } },
{ fields: { ...fields, color: 1 } },
true,
),
ReactiveCache.getLists({ _id: { $in: lists } }, { fields }, true),