added comment section on card details to avoid loading the card comment activities from the server

- and added to show only the activities a card

- to display the card comments a connection to the server was needed to get the activities of the card comments, now, it's not necessary
- also performance relevant. until now there were a lot of activities loaded, now only of the current card
This commit is contained in:
Martin Filser 2023-03-17 21:26:40 +01:00
parent 0196f46094
commit 8a446de3e9
21 changed files with 329 additions and 266 deletions

View file

@ -49,43 +49,6 @@
margin-top: 5px; margin-top: 5px;
padding: 5px; padding: 5px;
} }
.activities .activity .activity-desc .reactions {
display: flex;
margin-top: 5px;
gap: 5px;
}
.activities .activity .activity-desc .reactions .open-comment-reaction-popup {
display: flex;
align-items: center;
text-decoration: none;
height: 24px;
}
.activities .activity .activity-desc .reactions .open-comment-reaction-popup i.fa.fa-smile-o {
font-size: 17px;
font-weight: 500;
margin-left: 2px;
}
.activities .activity .activity-desc .reactions .open-comment-reaction-popup i.fa.fa-plus {
font-size: 8px;
margin-top: -7px;
margin-left: 1px;
}
.activities .activity .activity-desc .reactions .reaction {
cursor: pointer;
border: 1px solid #808080;
border-radius: 15px;
display: flex;
padding: 2px 5px;
}
.activities .activity .activity-desc .reactions .reaction.selected {
background-color: #b0c4de;
}
.activities .activity .activity-desc .reactions .reaction:hover {
background-color: #b0c4de;
}
.activities .activity .activity-desc .reactions .reaction .reaction-count {
font-size: 12px;
}
.activities .activity .activity-desc .activity-checklist { .activities .activity .activity-desc .activity-checklist {
display: block; display: block;
border-radius: 3px; border-radius: 3px;

View file

@ -1,4 +1,5 @@
template(name="activities") template(name="activities")
if showActivities
.activities.js-sidebar-activities .activities.js-sidebar-activities
//- We should use Template.dynamic here but there is a bug with //- We should use Template.dynamic here but there is a bug with
//- blaze-components: https://github.com/peerlibrary/meteor-blaze-components/issues/30 //- blaze-components: https://github.com/peerlibrary/meteor-blaze-components/issues/30
@ -15,31 +16,6 @@ template(name="cardActivities")
each activityData in activities each activityData in activities
+activity(activity=activityData card=card mode=mode) +activity(activity=activityData card=card mode=mode)
template(name="editOrDeleteComment")
a.js-open-inlined-form {{_ "edit"}}
= ' - '
a.js-delete-comment {{_ "delete"}}
template(name="deleteCommentPopup")
p {{_ "comment-delete"}}
button.js-confirm.negate.full(type="submit") {{_ 'delete'}}
template(name="commentReactions")
.reactions
each reaction in reactions
span.reaction(class="{{#if isSelected reaction.userIds}}selected{{/if}}" data-codepoint="#{reaction.reactionCodepoint}" title="{{userNames reaction.userIds}}")
span.reaction-codepoint !{reaction.reactionCodepoint}
span.reaction-count #{reaction.userIds.length}
if (currentUser.isBoardMember)
a.open-comment-reaction-popup(title="{{_ 'addReactionPopup-title'}}")
i.fa.fa-smile-o
i.fa.fa-plus
template(name="addReactionPopup")
.reactions-popup
each codepoint in codepoints
span.add-comment-reaction(data-codepoint="#{codepoint}") !{codepoint}
template(name="activity") template(name="activity")
.activity(data-id=activity._id) .activity(data-id=activity._id)
+userAvatar(userId=activity.user._id) +userAvatar(userId=activity.user._id)
@ -129,33 +105,12 @@ template(name="activity")
| {{{_ 'activity-checklist-item-removed' (sanitize activity.checklist.title) cardLink}}}. | {{{_ 'activity-checklist-item-removed' (sanitize activity.checklist.title) cardLink}}}.
//- comment activity ---------------------------------------------------- //- comment activity ----------------------------------------------------
if($eq mode 'card')
//- if we are in card mode we display the comment in a way that it
//- can be edited by the owner
if($eq activity.activityType 'addComment')
+inlinedForm(classNames='js-edit-comment')
+editor(autofocus=true)
= activity.comment.text
.edit-controls
button.primary(type="submit") {{_ 'edit'}}
.fa.fa-times-thin.js-close-inlined-form
else
.activity-comment
+viewer
= activity.comment.text
+commentReactions(reactions=activity.comment.reactions commentId=activity.comment._id)
if($eq currentUser._id activity.comment.userId)
+editOrDeleteComment
else if currentUser.isBoardAdmin
+editOrDeleteComment
if($eq activity.activityType 'deleteComment') if($eq activity.activityType 'deleteComment')
| {{{_ 'activity-deleteComment' activity.commentId}}}. | {{{_ 'activity-deleteComment' activity.commentId}}}.
if($eq activity.activityType 'editComment') if($eq activity.activityType 'editComment')
| {{{_ 'activity-editComment' activity.commentId}}}. | {{{_ 'activity-editComment' activity.commentId}}}.
else
//- if we are not in card mode we only display a summary of the comment
if($eq activity.activityType 'addComment') if($eq activity.activityType 'addComment')
| {{{_ 'activity-on' cardLink}}} | {{{_ 'activity-on' cardLink}}}
a.activity-comment(href="{{ activity.card.originRelativeUrl }}") a.activity-comment(href="{{ activity.card.originRelativeUrl }}")

View file

@ -17,8 +17,10 @@ BlazeComponent.extendComponent({
if (mode) { if (mode) {
const capitalizedMode = Utils.capitalize(mode); const capitalizedMode = Utils.capitalize(mode);
let searchId; let searchId;
const showActivities = this.showActivities();
if (mode === 'linkedcard' || mode === 'linkedboard') { if (mode === 'linkedcard' || mode === 'linkedboard') {
searchId = Utils.getCurrentCard().linkedId; const currentCard = Utils.getCurrentCard();
searchId = currentCard.linkedId;
mode = mode.replace('linked', ''); mode = mode.replace('linked', '');
} else if (mode === 'card') { } else if (mode === 'card') {
searchId = Utils.getCurrentCardId(); searchId = Utils.getCurrentCardId();
@ -26,11 +28,9 @@ BlazeComponent.extendComponent({
searchId = Session.get(`current${capitalizedMode}`); searchId = Session.get(`current${capitalizedMode}`);
} }
const limit = this.page.get() * activitiesPerPage; const limit = this.page.get() * activitiesPerPage;
const user = ReactiveCache.getCurrentUser();
const hideSystem = user ? user.hasHiddenSystemMessages() : false;
if (searchId === null) return; if (searchId === null) return;
this.subscribe('activities', mode, searchId, limit, hideSystem, () => { this.subscribe('activities', mode, searchId, limit, showActivities, () => {
this.loadNextPageLocked = false; this.loadNextPageLocked = false;
// TODO the guard can be removed as soon as the TODO above is resolved // TODO the guard can be removed as soon as the TODO above is resolved
@ -56,14 +56,26 @@ BlazeComponent.extendComponent({
this.loadNextPageLocked = true; this.loadNextPageLocked = true;
} }
}, },
}).register('activities'); showActivities() {
let ret = false;
Template.activities.helpers({ let mode = this.data()?.mode;
activities() { if (mode) {
const ret = this.card.activities(); if (mode === 'linkedcard' || mode === 'linkedboard') {
const currentCard = Utils.getCurrentCard();
ret = currentCard.showActivities ?? false;
} else if (mode === 'card') {
ret = this.data()?.card?.showActivities ?? false;
} else {
ret = Utils.getCurrentBoard().showActivities ?? false;
}
}
return ret; return ret;
}, },
}); activities() {
const ret = this.data().card.activities();
return ret;
},
}).register('activities');
BlazeComponent.extendComponent({ BlazeComponent.extendComponent({
checkItem() { checkItem() {
@ -249,32 +261,6 @@ BlazeComponent.extendComponent({
return customField.name; return customField.name;
}, },
events() {
return [
{
// XXX We should use Popup.afterConfirmation here
'click .js-delete-comment': Popup.afterConfirm('deleteComment', () => {
const commentId = this.data().activity.commentId;
CardComments.remove(commentId);
Popup.back();
}),
'submit .js-edit-comment'(evt) {
evt.preventDefault();
const commentText = this.currentComponent()
.getValue()
.trim();
const commentId = Template.parentData().activity.commentId;
if (commentText) {
CardComments.update(commentId, {
$set: {
text: commentText,
},
});
}
},
},
];
},
}).register('activity'); }).register('activity');
Template.activity.helpers({ Template.activity.helpers({

View file

@ -63,3 +63,78 @@
display: block; display: block;
margin: auto; margin: auto;
} }
.comments {
clear: both;
}
.comments .comment {
margin: 0.5px 0;
padding: 6px 0;
display: flex;
}
.comments .comment .member {
width: 32px;
height: 32px;
}
.comments .comment .comment-member {
font-weight: 700;
}
.comments .comment .comment-desc {
word-wrap: break-word;
overflow: hidden;
flex: 1;
align-self: center;
margin: 0;
margin-left: 3px;
overflow: hidden;
word-break: break-word;
}
.comments .comment .comment-desc .comment-text {
display: block;
border-radius: 3px;
background: #fff;
text-decoration: none;
box-shadow: 0 1px 2px rgba(0,0,0,0.2);
margin-top: 5px;
padding: 5px;
}
.comments .comment .comment-desc .reactions {
display: flex;
margin-top: 5px;
gap: 5px;
}
.comments .comment .comment-desc .reactions .open-comment-reaction-popup {
display: flex;
align-items: center;
text-decoration: none;
height: 24px;
}
.comments .comment .comment-desc .reactions .open-comment-reaction-popup i.fa.fa-smile-o {
font-size: 17px;
font-weight: 500;
margin-left: 2px;
}
.comments .comment .comment-desc .reactions .open-comment-reaction-popup i.fa.fa-plus {
font-size: 8px;
margin-top: -7px;
margin-left: 1px;
}
.comments .comment .comment-desc .reactions .reaction {
cursor: pointer;
border: 1px solid #808080;
border-radius: 15px;
display: flex;
padding: 2px 5px;
}
.comments .comment .comment-desc .reactions .reaction.selected {
background-color: #b0c4de;
}
.comments .comment .comment-desc .reactions .reaction:hover {
background-color: #b0c4de;
}
.comments .comment .comment-desc .reactions .reaction .reaction-count {
font-size: 12px;
}
.comments .comment .comment-desc .comment-meta {
font-size: 0.8em;
color: #999;
}

View file

@ -7,3 +7,59 @@ template(name="commentForm")
| {{getUnsavedValue 'cardComment' currentCard._id}} | {{getUnsavedValue 'cardComment' currentCard._id}}
.add-controls .add-controls
button.primary.confirm.clear.js-add-comment(type="submit") {{_ 'comment'}} button.primary.confirm.clear.js-add-comment(type="submit") {{_ 'comment'}}
template(name="comments")
.comments
each commentData in getComments
+comment(commentData)
template(name="comment")
.comment
+userAvatar(userId=userId)
p.comment-desc
span.comment-member
+memberName(user=user)
+inlinedForm(classNames='js-edit-comment')
+editor(autofocus=true)
= text
.edit-controls
button.primary(type="submit") {{_ 'edit'}}
.fa.fa-times-thin.js-close-inlined-form
else
.comment-text
+viewer
= text
+commentReactions(reactions=reactions commentId=_id)
span(title=createdAt).comment-meta {{ moment createdAt }}
if($eq currentUser._id userId)
+editOrDeleteComment
else if currentUser.isBoardAdmin
+editOrDeleteComment
template(name="editOrDeleteComment")
= ' - '
a.js-open-inlined-form {{_ "edit"}}
= ' - '
a.js-delete-comment {{_ "delete"}}
template(name="deleteCommentPopup")
p {{_ "comment-delete"}}
button.js-confirm.negate.full(type="submit") {{_ 'delete'}}
template(name="commentReactions")
.reactions
each reaction in reactions
span.reaction(class="{{#if isSelected reaction.userIds}}selected{{/if}}" data-codepoint="#{reaction.reactionCodepoint}" title="{{userNames reaction.userIds}}")
span.reaction-codepoint !{reaction.reactionCodepoint}
span.reaction-count #{reaction.userIds.length}
if (currentUser.isBoardMember)
a.open-comment-reaction-popup(title="{{_ 'addReactionPopup-title'}}")
i.fa.fa-smile-o
i.fa.fa-plus
template(name="addReactionPopup")
.reactions-popup
each codepoint in codepoints
span.add-comment-reaction(data-codepoint="#{codepoint}") !{codepoint}

View file

@ -55,6 +55,41 @@ BlazeComponent.extendComponent({
}, },
}).register('commentForm'); }).register('commentForm');
BlazeComponent.extendComponent({
getComments() {
const ret = this.data().comments();
return ret;
},
}).register("comments");
BlazeComponent.extendComponent({
events() {
return [
{
'click .js-delete-comment': Popup.afterConfirm('deleteComment', () => {
const commentId = this.data()._id;
CardComments.remove(commentId);
Popup.back();
}),
'submit .js-edit-comment'(evt) {
evt.preventDefault();
const commentText = this.currentComponent()
.getValue()
.trim();
const commentId = this.data()._id;
if (commentText) {
CardComments.update(commentId, {
$set: {
text: commentText,
},
});
}
},
},
];
},
}).register("comment");
// XXX This should be a static method of the `commentForm` component // XXX This should be a static method of the `commentForm` component
function resetCommentInput(input) { function resetCommentInput(input) {
input.val(''); // without manually trigger, input event won't be fired input.val(''); // without manually trigger, input event won't be fired

View file

@ -569,25 +569,34 @@ template(name="cardDetails")
+attachmentGallery +attachmentGallery
hr hr
unless currentUser.isNoComments
.comment-title
h3.card-details-item-title
i.fa.fa-comment-o
| {{_ 'comments'}}
if currentBoard.allowsComments
if currentUser.isBoardMember
unless currentUser.isNoComments
+commentForm
+comments
hr
.card-details-right .card-details-right
unless currentUser.isNoComments unless currentUser.isNoComments
.activity-title .activity-title
h3.card-details-item-title h3.card-details-item-title
i.fa.fa-history i.fa.fa-history
| {{ _ 'activity'}} | {{ _ 'activities'}}
if currentUser.isBoardMember if currentUser.isBoardMember
.material-toggle-switch(title="{{_ 'hide-system-messages'}}") .material-toggle-switch(title="{{_ 'show-activities'}}")
//span.toggle-switch-title if showActivities
if hiddenSystemMessages input.toggle-switch(type="checkbox" id="toggleShowActivitiesCard" checked="checked")
input.toggle-switch(type="checkbox" id="toggleButton" checked="checked")
else else
input.toggle-switch(type="checkbox" id="toggleButton") input.toggle-switch(type="checkbox" id="toggleShowActivitiesCard")
label.toggle-label(for="toggleButton") label.toggle-label(for="toggleShowActivitiesCard")
if currentBoard.allowsComments
if currentUser.isBoardMember
unless currentUser.isNoComments
+commentForm
unless currentUser.isNoComments unless currentUser.isNoComments
if isLoaded.get if isLoaded.get
if isLinkedCard if isLinkedCard

View file

@ -63,10 +63,6 @@ BlazeComponent.extendComponent({
return card.findWatcher(Meteor.userId()); return card.findWatcher(Meteor.userId());
}, },
hiddenSystemMessages() {
return ReactiveCache.getCurrentUser().hasHiddenSystemMessages();
},
customFieldsGrid() { customFieldsGrid() {
return ReactiveCache.getCurrentUser().hasCustomFieldsGrid(); return ReactiveCache.getCurrentUser().hasCustomFieldsGrid();
}, },
@ -377,8 +373,8 @@ BlazeComponent.extendComponent({
Session.set('cardDetailsIsDragging', false); Session.set('cardDetailsIsDragging', false);
Session.set('cardDetailsIsMouseDown', false); Session.set('cardDetailsIsMouseDown', false);
}, },
'click #toggleButton'() { 'click #toggleShowActivitiesCard'() {
Meteor.call('toggleSystemMessages'); this.data().toggleShowActivities();
}, },
'click #toggleCustomFieldsGridButton'() { 'click #toggleCustomFieldsGridButton'() {
Meteor.call('toggleCustomFieldsGrid'); Meteor.call('toggleCustomFieldsGrid');

View file

@ -144,8 +144,6 @@ template(name='tableVisibilityModeSettings')
template(name='accountSettings') template(name='accountSettings')
ul#account-setting.setting-detail ul#account-setting.setting-detail
li
button.js-all-hide-system-messages.primary {{_ 'hide-system-messages-of-all-users'}}
li.accounts-form li.accounts-form
.title {{_ 'accounts-allowEmailChange'}} .title {{_ 'accounts-allowEmailChange'}}
.form-group.flex .form-group.flex
@ -185,6 +183,8 @@ template(name='announcementSettings')
template(name='layoutSettings') template(name='layoutSettings')
ul#layout-setting.setting-detail ul#layout-setting.setting-detail
li
button.js-all-boards-hide-activities.primary {{_ 'hide-activities-of-all-boards'}}
li.layout-form li.layout-form
.title {{_ 'oidc-button-text'}} .title {{_ 'oidc-button-text'}}
.form-group .form-group

View file

@ -336,12 +336,12 @@ BlazeComponent.extendComponent({
allowUserDelete() { allowUserDelete() {
return AccountSettings.findOne('accounts-allowUserDelete').booleanValue; return AccountSettings.findOne('accounts-allowUserDelete').booleanValue;
}, },
allHideSystemMessages() { allBoardsHideActivities() {
Meteor.call('setAllUsersHideSystemMessages', (err, ret) => { Meteor.call('setAllBoardsHideActivities', (err, ret) => {
if (!err && ret) { if (!err && ret) {
if (ret === true) { if (ret === true) {
const message = `${TAPi18n.__( const message = `${TAPi18n.__(
'now-system-messages-of-all-users-are-hidden', 'now-activities-of-all-boards-are-hidden',
)}`; )}`;
alert(message); alert(message);
} }
@ -359,7 +359,7 @@ BlazeComponent.extendComponent({
'click button.js-accounts-save': this.saveAccountsChange, 'click button.js-accounts-save': this.saveAccountsChange,
}, },
{ {
'click button.js-all-hide-system-messages': this.allHideSystemMessages, 'click button.js-all-boards-hide-activities': this.allBoardsHideActivities,
}, },
]; ];
}, },
@ -376,12 +376,12 @@ BlazeComponent.extendComponent({
allowPrivateOnly() { allowPrivateOnly() {
return TableVisibilityModeSettings.findOne('tableVisibilityMode-allowPrivateOnly').booleanValue; return TableVisibilityModeSettings.findOne('tableVisibilityMode-allowPrivateOnly').booleanValue;
}, },
allHideSystemMessages() { allBoardsHideActivities() {
Meteor.call('setAllUsersHideSystemMessages', (err, ret) => { Meteor.call('setAllBoardsHideActivities', (err, ret) => {
if (!err && ret) { if (!err && ret) {
if (ret === true) { if (ret === true) {
const message = `${TAPi18n.__( const message = `${TAPi18n.__(
'now-system-messages-of-all-users-are-hidden', 'now-activities-of-all-boards-are-hidden',
)}`; )}`;
alert(message); alert(message);
} }
@ -399,7 +399,7 @@ BlazeComponent.extendComponent({
'click button.js-tableVisibilityMode-save': this.saveTableVisibilityChange, 'click button.js-tableVisibilityMode-save': this.saveTableVisibilityChange,
}, },
{ {
'click button.js-all-hide-system-messages': this.allHideSystemMessages, 'click button.js-all-boards-hide-activities': this.allBoardsHideActivities,
}, },
]; ];
}, },

View file

@ -28,9 +28,16 @@ template(name='homeSidebar')
.materialCheckBox(class="{{#if hiddenMinicardLabelText}}is-checked{{/if}}") .materialCheckBox(class="{{#if hiddenMinicardLabelText}}is-checked{{/if}}")
hr hr
unless currentUser.isNoComments unless currentUser.isNoComments
h3 h3.activity-title
i.fa.fa-comments-o i.fa.fa-comments-o
| {{_ 'activities'}} | {{_ 'activities'}}
.material-toggle-switch(title="{{_ 'show-activities'}}")
if showActivities
input.toggle-switch(type="checkbox" id="toggleShowActivitiesBoard" checked="checked")
else
input.toggle-switch(type="checkbox" id="toggleShowActivitiesBoard")
label.toggle-label(for="toggleShowActivitiesBoard")
+activities(mode="board") +activities(mode="board")
template(name="membersWidget") template(name="membersWidget")

View file

@ -136,7 +136,7 @@ BlazeComponent.extendComponent({
Blaze.registerHelper('Sidebar', () => Sidebar); Blaze.registerHelper('Sidebar', () => Sidebar);
Template.homeSidebar.helpers({ BlazeComponent.extendComponent({
hiddenMinicardLabelText() { hiddenMinicardLabelText() {
currentUser = ReactiveCache.getCurrentUser(); currentUser = ReactiveCache.getCurrentUser();
if (currentUser) { if (currentUser) {
@ -147,7 +147,20 @@ Template.homeSidebar.helpers({
return false; return false;
} }
}, },
}); showActivities() {
let ret = Utils.getCurrentBoard().showActivities ?? false;
return ret;
},
events() {
return [
{
'click #toggleShowActivitiesBoard'() {
Utils.getCurrentBoard().toggleShowActivities();
},
},
];
},
}).register('homeSidebar');
Template.boardInfoOnMyBoardsPopup.helpers({ Template.boardInfoOnMyBoardsPopup.helpers({
hideCardCounterList() { hideCardCounterList() {

View file

@ -153,12 +153,6 @@ template(name="changeLanguagePopup")
template(name="changeSettingsPopup") template(name="changeSettingsPopup")
ul.pop-over-list ul.pop-over-list
//li
// a.js-toggle-system-messages
// i.fa.fa-comments-o
// | {{_ 'hide-system-messages'}}
// if hiddenSystemMessages
// i.fa.fa-check
//li //li
// a.js-toggle-desktop-drag-handles // a.js-toggle-desktop-drag-handles
// i.fa.fa-arrows // i.fa.fa-arrows

View file

@ -283,16 +283,6 @@ Template.changeLanguagePopup.events({
}); });
Template.changeSettingsPopup.helpers({ Template.changeSettingsPopup.helpers({
hiddenSystemMessages() {
const currentUser = ReactiveCache.getCurrentUser();
if (currentUser) {
return (currentUser.profile || {}).hasHiddenSystemMessages;
} else if (window.localStorage.getItem('hasHiddenSystemMessages')) {
return true;
} else {
return false;
}
},
rescueCardDescription() { rescueCardDescription() {
const currentUser = ReactiveCache.getCurrentUser(); const currentUser = ReactiveCache.getCurrentUser();
if (currentUser) { if (currentUser) {
@ -352,16 +342,6 @@ Template.changeSettingsPopup.events({
window.localStorage.setItem('showDesktopDragHandles', 'true'); window.localStorage.setItem('showDesktopDragHandles', 'true');
} }
}, },
'click .js-toggle-system-messages'() {
currentUser = Meteor.user();
if (currentUser) {
Meteor.call('toggleSystemMessages');
} else if (window.localStorage.getItem('hasHiddenSystemMessages')) {
window.localStorage.removeItem('hasHiddenSystemMessages');
} else {
window.localStorage.setItem('hasHiddenSystemMessages', 'true');
}
},
'click .js-rescue-card-description'() { 'click .js-rescue-card-description'() {
Meteor.call('toggleRescueCardDescription') Meteor.call('toggleRescueCardDescription')
}, },

View file

@ -294,6 +294,7 @@
"color-white": "Weiß", "color-white": "Weiß",
"color-yellow": "gelb", "color-yellow": "gelb",
"unset-color": "Nicht festgelegt", "unset-color": "Nicht festgelegt",
"comments": "Kommentare",
"comment": "Kommentar speichern", "comment": "Kommentar speichern",
"comment-placeholder": "Kommentar schreiben", "comment-placeholder": "Kommentar schreiben",
"comment-only": "Nur Kommentare", "comment-only": "Nur Kommentare",
@ -443,7 +444,7 @@
"advanced-filter-description": "Der erweiterte Filter erlaubt die Eingabe von Zeichenfolgen, die folgende Operatoren enthalten: == != <= >= && || ( ). Ein Leerzeichen wird als Trennzeichen zwischen den Operatoren verwendet. Sie können nach allen benutzerdefinierten Feldern filtern, indem Sie deren Namen und Werte eingeben. Zum Beispiel: Feld1 == Wert1. Hinweis: Wenn Felder oder Werte Leerzeichen enthalten, müssen Sie sie in einfache Anführungszeichen setzen. Zum Beispiel: 'Feld 1' == 'Wert 1'. Um einzelne Steuerzeichen (' \\\\/) zu überspringen, können Sie \\\\ verwenden. Zum Beispiel: Feld1 == Ich bin\\\\'s. Sie können außerdem mehrere Bedingungen kombinieren. Zum Beispiel: F1 == W1 || F1 == W2. Normalerweise werden alle Operatoren von links nach rechts interpretiert. Sie können die Reihenfolge ändern, indem Sie Klammern setzen. Zum Beispiel: F1 == W1 && ( F2 == W2 || F2 == W3 ). Sie können Textfelder auch mithilfe regulärer Ausdrücke durchsuchen: F1 == /Tes.*/i", "advanced-filter-description": "Der erweiterte Filter erlaubt die Eingabe von Zeichenfolgen, die folgende Operatoren enthalten: == != <= >= && || ( ). Ein Leerzeichen wird als Trennzeichen zwischen den Operatoren verwendet. Sie können nach allen benutzerdefinierten Feldern filtern, indem Sie deren Namen und Werte eingeben. Zum Beispiel: Feld1 == Wert1. Hinweis: Wenn Felder oder Werte Leerzeichen enthalten, müssen Sie sie in einfache Anführungszeichen setzen. Zum Beispiel: 'Feld 1' == 'Wert 1'. Um einzelne Steuerzeichen (' \\\\/) zu überspringen, können Sie \\\\ verwenden. Zum Beispiel: Feld1 == Ich bin\\\\'s. Sie können außerdem mehrere Bedingungen kombinieren. Zum Beispiel: F1 == W1 || F1 == W2. Normalerweise werden alle Operatoren von links nach rechts interpretiert. Sie können die Reihenfolge ändern, indem Sie Klammern setzen. Zum Beispiel: F1 == W1 && ( F2 == W2 || F2 == W3 ). Sie können Textfelder auch mithilfe regulärer Ausdrücke durchsuchen: F1 == /Tes.*/i",
"fullname": "Vollständiger Name", "fullname": "Vollständiger Name",
"header-logo-title": "Zurück zur Board Seite.", "header-logo-title": "Zurück zur Board Seite.",
"hide-system-messages": "Systemmeldungen ausblenden", "show-activities": "Aktivitäten anzeigen",
"headerBarCreateBoardPopup-title": "Board erstellen", "headerBarCreateBoardPopup-title": "Board erstellen",
"home": "Home", "home": "Home",
"import": "Importieren", "import": "Importieren",
@ -1109,8 +1110,8 @@
"created-at-newest-first": "Erstelldatum (neueste zuerst)", "created-at-newest-first": "Erstelldatum (neueste zuerst)",
"created-at-oldest-first": "Erstelldatum (älteste zuerst)", "created-at-oldest-first": "Erstelldatum (älteste zuerst)",
"links-heading": "Links", "links-heading": "Links",
"hide-system-messages-of-all-users": "Alle System-Nachrichten aller Nutzer verbergen", "hide-activities-of-all-boards": "Alle Board Aktivitäten anzeigen abschalten",
"now-system-messages-of-all-users-are-hidden": "Alle System-Nachrichten aller Nutzer sind nun verborgen", "now-activities-of-all-boards-are-hidden": "Alle Aktivitäten von allen Boards sind nun verborgen",
"move-swimlane": "Swimlane verschieben", "move-swimlane": "Swimlane verschieben",
"moveSwimlanePopup-title": "Swimlane verschieben", "moveSwimlanePopup-title": "Swimlane verschieben",
"custom-field-stringtemplate": "String-Vorlage", "custom-field-stringtemplate": "String-Vorlage",

View file

@ -295,6 +295,7 @@
"color-white": "white", "color-white": "white",
"color-yellow": "yellow", "color-yellow": "yellow",
"unset-color": "Unset", "unset-color": "Unset",
"comments": "Comments",
"comment": "Comment", "comment": "Comment",
"comment-placeholder": "Write Comment", "comment-placeholder": "Write Comment",
"comment-only": "Comment only", "comment-only": "Comment only",
@ -444,7 +445,7 @@
"advanced-filter-description": "Advanced Filter allows to write a string containing following operators: == != <= >= && || ( ) A space is used as a separator between the Operators. You can filter for all Custom Fields by typing their names and values. For Example: Field1 == Value1. Note: If fields or values contains spaces, you need to encapsulate them into single quotes. For Example: 'Field 1' == 'Value 1'. For single control characters (' \\/) to be skipped, you can use \\. For example: Field1 == I\\'m. Also you can combine multiple conditions. For Example: F1 == V1 || F1 == V2. Normally all operators are interpreted from left to right. You can change the order by placing brackets. For Example: F1 == V1 && ( F2 == V2 || F2 == V3 ). Also you can search text fields using regex: F1 == /Tes.*/i", "advanced-filter-description": "Advanced Filter allows to write a string containing following operators: == != <= >= && || ( ) A space is used as a separator between the Operators. You can filter for all Custom Fields by typing their names and values. For Example: Field1 == Value1. Note: If fields or values contains spaces, you need to encapsulate them into single quotes. For Example: 'Field 1' == 'Value 1'. For single control characters (' \\/) to be skipped, you can use \\. For example: Field1 == I\\'m. Also you can combine multiple conditions. For Example: F1 == V1 || F1 == V2. Normally all operators are interpreted from left to right. You can change the order by placing brackets. For Example: F1 == V1 && ( F2 == V2 || F2 == V3 ). Also you can search text fields using regex: F1 == /Tes.*/i",
"fullname": "Full Name", "fullname": "Full Name",
"header-logo-title": "Go back to your boards page.", "header-logo-title": "Go back to your boards page.",
"hide-system-messages": "Hide system messages", "show-activities": "Show Activities",
"headerBarCreateBoardPopup-title": "Create Board", "headerBarCreateBoardPopup-title": "Create Board",
"home": "Home", "home": "Home",
"import": "Import", "import": "Import",
@ -1110,8 +1111,8 @@
"created-at-newest-first": "Created At (Newest First)", "created-at-newest-first": "Created At (Newest First)",
"created-at-oldest-first": "Created At (Oldest First)", "created-at-oldest-first": "Created At (Oldest First)",
"links-heading": "Links", "links-heading": "Links",
"hide-system-messages-of-all-users": "Hide system messages of all users", "hide-activities-of-all-boards": "Don't show the board activities on all boards",
"now-system-messages-of-all-users-are-hidden": "Now system messages of all users are hidden", "now-activities-of-all-boards-are-hidden": "Now all activities of all boards are hidden",
"move-swimlane": "Move Swimlane", "move-swimlane": "Move Swimlane",
"moveSwimlanePopup-title": "Move Swimlane", "moveSwimlanePopup-title": "Move Swimlane",
"custom-field-stringtemplate": "String Template", "custom-field-stringtemplate": "String Template",

View file

@ -634,6 +634,10 @@ Boards.attachSchema(
decimal: true, decimal: true,
defaultValue: -1, defaultValue: -1,
}, },
showActivities: {
type: Boolean,
defaultValue: false,
},
}), }),
); );
@ -1544,6 +1548,10 @@ Boards.mutations({
move(sortIndex) { move(sortIndex) {
return { $set: { sort: sortIndex } }; return { $set: { sort: sortIndex } };
}, },
toggleShowActivities() {
return { $set: { showActivities: !this.showActivities } };
},
}); });
function boardRemover(userId, doc) { function boardRemover(userId, doc) {
@ -1751,6 +1759,26 @@ if (Meteor.isServer) {
}), }),
).sort(); ).sort();
}, },
setAllBoardsHideActivities() {
if (ReactiveCache.getCurrentUser()?.isAdmin) {
Boards.update(
{
showActivities: true
},
{
$set: {
showActivities: false,
},
},
{
multi: true,
},
);
return true;
} else {
return false;
}
},
}); });
Meteor.methods({ Meteor.methods({

View file

@ -473,6 +473,10 @@ Cards.attachSchema(
optional: true, optional: true,
defaultValue: 0, defaultValue: 0,
}, },
showActivities: {
type: Boolean,
defaultValue: false,
},
}), }),
); );
@ -2167,6 +2171,14 @@ Cards.mutations({
} }
}, },
toggleShowActivities() {
return {
$set: {
showActivities: !this.showActivities,
}
};
},
setCustomField(customFieldId, value) { setCustomField(customFieldId, value) {
// todo // todo
const index = this.customFieldIndex(customFieldId); const index = this.customFieldIndex(customFieldId);

View file

@ -193,13 +193,6 @@ Users.attachSchema(
type: Boolean, type: Boolean,
optional: true, optional: true,
}, },
'profile.hiddenSystemMessages': {
/**
* does the user want to hide system messages?
*/
type: Boolean,
optional: true,
},
'profile.hiddenMinicardLabelText': { 'profile.hiddenMinicardLabelText': {
/** /**
* does the user want to hide minicard label texts? * does the user want to hide minicard label texts?
@ -865,11 +858,6 @@ Users.helpers({
return profile.hideCheckedItems || false; return profile.hideCheckedItems || false;
}, },
hasHiddenSystemMessages() {
const profile = this.profile || {};
return profile.hiddenSystemMessages || false;
},
hasCustomFieldsGrid() { hasCustomFieldsGrid() {
const profile = this.profile || {}; const profile = this.profile || {};
return profile.customFieldsGrid || false; return profile.customFieldsGrid || false;
@ -1069,14 +1057,6 @@ Users.mutations({
}; };
}, },
toggleSystem(value = false) {
return {
$set: {
'profile.hiddenSystemMessages': !value,
},
};
},
toggleFieldsGrid(value = false) { toggleFieldsGrid(value = false) {
return { return {
$set: { $set: {
@ -1216,10 +1196,6 @@ Meteor.methods({
const user = ReactiveCache.getCurrentUser(); const user = ReactiveCache.getCurrentUser();
user.toggleHideCheckedItems(); user.toggleHideCheckedItems();
}, },
toggleSystemMessages() {
const user = ReactiveCache.getCurrentUser();
user.toggleSystem(user.hasHiddenSystemMessages());
},
toggleCustomFieldsGrid() { toggleCustomFieldsGrid() {
const user = ReactiveCache.getCurrentUser(); const user = ReactiveCache.getCurrentUser();
user.toggleFieldsGrid(user.hasCustomFieldsGrid()); user.toggleFieldsGrid(user.hasCustomFieldsGrid());
@ -1262,43 +1238,6 @@ Meteor.methods({
if (Meteor.isServer) { if (Meteor.isServer) {
Meteor.methods({ Meteor.methods({
setAllUsersHideSystemMessages() {
if (ReactiveCache.getCurrentUser()?.isAdmin) {
// If setting is missing, add it
Users.update(
{
'profile.hiddenSystemMessages': {
$exists: false,
},
},
{
$set: {
'profile.hiddenSystemMessages': true,
},
},
{
multi: true,
},
);
// If setting is false, set it to true
Users.update(
{
'profile.hiddenSystemMessages': false,
},
{
$set: {
'profile.hiddenSystemMessages': true,
},
},
{
multi: true,
},
);
return true;
} else {
return false;
}
},
setCreateUser( setCreateUser(
fullname, fullname,
username, username,

View file

@ -1457,3 +1457,19 @@ Migrations.add('remove-unused-planning-poker', () => {
noValidateMulti, noValidateMulti,
); );
}); });
Migrations.add('remove-user-profile-hiddenSystemMessages', () => {
Users.update(
{
"profile.hiddenSystemMessages": {
$exists: true,
},
},
{
$unset: {
"profile.hiddenSystemMessages": 1,
},
},
noValidateMulti,
);
});

View file

@ -5,7 +5,7 @@ import { ReactiveCache } from '/imports/reactiveCache';
// 2. The card activity tab // 2. The card activity tab
// We use this publication to paginate for these two publications. // We use this publication to paginate for these two publications.
Meteor.publish('activities', (kind, id, limit, hideSystem) => { Meteor.publish('activities', (kind, id, limit, showActivities) => {
check( check(
kind, kind,
Match.Where(x => { Match.Where(x => {
@ -14,7 +14,7 @@ Meteor.publish('activities', (kind, id, limit, hideSystem) => {
); );
check(id, String); check(id, String);
check(limit, Number); check(limit, Number);
check(hideSystem, Boolean); check(showActivities, Boolean);
// Get linkedBoard // Get linkedBoard
let linkedElmtId = [id]; let linkedElmtId = [id];
@ -27,12 +27,9 @@ Meteor.publish('activities', (kind, id, limit, hideSystem) => {
}); });
} }
//const selector = hideSystem const selector = showActivities
// ? { $and: [{ activityType: 'addComment' }, { [`${kind}Id`]: id }] } ? { [`${kind}Id`]: { $in: linkedElmtId } }
// : { [`${kind}Id`]: id }; : { $and: [{ activityType: 'addComment' }, { [`${kind}Id`]: { $in: linkedElmtId } }] };
const selector = hideSystem
? { $and: [{ activityType: 'addComment' }, { [`${kind}Id`]: { $in: linkedElmtId } }] }
: { [`${kind}Id`]: { $in: linkedElmtId } };
const ret = ReactiveCache.getActivities(selector, const ret = ReactiveCache.getActivities(selector,
{ {
limit, limit,