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
pull/5566/head
Martin Filser 2 years ago
parent 0196f46094
commit 8a446de3e9
  1. 37
      client/components/activities/activities.css
  2. 83
      client/components/activities/activities.jade
  3. 56
      client/components/activities/activities.js
  4. 75
      client/components/activities/comments.css
  5. 56
      client/components/activities/comments.jade
  6. 35
      client/components/activities/comments.js
  7. 31
      client/components/cards/cardDetails.jade
  8. 8
      client/components/cards/cardDetails.js
  9. 4
      client/components/settings/settingBody.jade
  10. 16
      client/components/settings/settingBody.js
  11. 9
      client/components/sidebar/sidebar.jade
  12. 17
      client/components/sidebar/sidebar.js
  13. 6
      client/components/users/userHeader.jade
  14. 20
      client/components/users/userHeader.js
  15. 7
      imports/i18n/data/de.i18n.json
  16. 7
      imports/i18n/data/en.i18n.json
  17. 28
      models/boards.js
  18. 12
      models/cards.js
  19. 61
      models/users.js
  20. 16
      server/migrations.js
  21. 13
      server/publications/activities.js

@ -49,43 +49,6 @@
margin-top: 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 {
display: block;
border-radius: 3px;

@ -1,11 +1,12 @@
template(name="activities")
.activities.js-sidebar-activities
//- We should use Template.dynamic here but there is a bug with
//- blaze-components: https://github.com/peerlibrary/meteor-blaze-components/issues/30
if $eq mode "board"
+boardActivities
else
+cardActivities
if showActivities
.activities.js-sidebar-activities
//- We should use Template.dynamic here but there is a bug with
//- blaze-components: https://github.com/peerlibrary/meteor-blaze-components/issues/30
if $eq mode "board"
+boardActivities
else
+cardActivities
template(name="boardActivities")
each activityData in currentBoard.activities
@ -15,31 +16,6 @@ template(name="cardActivities")
each activityData in activities
+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")
.activity(data-id=activity._id)
+userAvatar(userId=activity.user._id)
@ -129,38 +105,17 @@ template(name="activity")
| {{{_ 'activity-checklist-item-removed' (sanitize activity.checklist.title) cardLink}}}.
//- 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')
| {{{_ 'activity-deleteComment' activity.commentId}}}.
if($eq activity.activityType 'editComment')
| {{{_ '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')
| {{{_ 'activity-on' cardLink}}}
a.activity-comment(href="{{ activity.card.originRelativeUrl }}")
+viewer
= activity.comment.text
if($eq activity.activityType 'deleteComment')
| {{{_ 'activity-deleteComment' activity.commentId}}}.
if($eq activity.activityType 'editComment')
| {{{_ 'activity-editComment' activity.commentId}}}.
if($eq activity.activityType 'addComment')
| {{{_ 'activity-on' cardLink}}}
a.activity-comment(href="{{ activity.card.originRelativeUrl }}")
+viewer
= activity.comment.text
//- date activity ------------------------------------------------
if($eq activity.activityType 'a-receivedAt')

@ -17,8 +17,10 @@ BlazeComponent.extendComponent({
if (mode) {
const capitalizedMode = Utils.capitalize(mode);
let searchId;
const showActivities = this.showActivities();
if (mode === 'linkedcard' || mode === 'linkedboard') {
searchId = Utils.getCurrentCard().linkedId;
const currentCard = Utils.getCurrentCard();
searchId = currentCard.linkedId;
mode = mode.replace('linked', '');
} else if (mode === 'card') {
searchId = Utils.getCurrentCardId();
@ -26,11 +28,9 @@ BlazeComponent.extendComponent({
searchId = Session.get(`current${capitalizedMode}`);
}
const limit = this.page.get() * activitiesPerPage;
const user = ReactiveCache.getCurrentUser();
const hideSystem = user ? user.hasHiddenSystemMessages() : false;
if (searchId === null) return;
this.subscribe('activities', mode, searchId, limit, hideSystem, () => {
this.subscribe('activities', mode, searchId, limit, showActivities, () => {
this.loadNextPageLocked = false;
// TODO the guard can be removed as soon as the TODO above is resolved
@ -56,14 +56,26 @@ BlazeComponent.extendComponent({
this.loadNextPageLocked = true;
}
},
}).register('activities');
Template.activities.helpers({
showActivities() {
let ret = false;
let mode = this.data()?.mode;
if (mode) {
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;
},
activities() {
const ret = this.card.activities();
const ret = this.data().card.activities();
return ret;
},
});
}).register('activities');
BlazeComponent.extendComponent({
checkItem() {
@ -249,32 +261,6 @@ BlazeComponent.extendComponent({
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');
Template.activity.helpers({

@ -63,3 +63,78 @@
display: block;
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;
}

@ -7,3 +7,59 @@ template(name="commentForm")
| {{getUnsavedValue 'cardComment' currentCard._id}}
.add-controls
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}

@ -55,6 +55,41 @@ BlazeComponent.extendComponent({
},
}).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
function resetCommentInput(input) {
input.val(''); // without manually trigger, input event won't be fired

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

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

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

@ -336,12 +336,12 @@ BlazeComponent.extendComponent({
allowUserDelete() {
return AccountSettings.findOne('accounts-allowUserDelete').booleanValue;
},
allHideSystemMessages() {
Meteor.call('setAllUsersHideSystemMessages', (err, ret) => {
allBoardsHideActivities() {
Meteor.call('setAllBoardsHideActivities', (err, ret) => {
if (!err && ret) {
if (ret === true) {
const message = `${TAPi18n.__(
'now-system-messages-of-all-users-are-hidden',
'now-activities-of-all-boards-are-hidden',
)}`;
alert(message);
}
@ -359,7 +359,7 @@ BlazeComponent.extendComponent({
'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() {
return TableVisibilityModeSettings.findOne('tableVisibilityMode-allowPrivateOnly').booleanValue;
},
allHideSystemMessages() {
Meteor.call('setAllUsersHideSystemMessages', (err, ret) => {
allBoardsHideActivities() {
Meteor.call('setAllBoardsHideActivities', (err, ret) => {
if (!err && ret) {
if (ret === true) {
const message = `${TAPi18n.__(
'now-system-messages-of-all-users-are-hidden',
'now-activities-of-all-boards-are-hidden',
)}`;
alert(message);
}
@ -399,7 +399,7 @@ BlazeComponent.extendComponent({
'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,
},
];
},

@ -28,9 +28,16 @@ template(name='homeSidebar')
.materialCheckBox(class="{{#if hiddenMinicardLabelText}}is-checked{{/if}}")
hr
unless currentUser.isNoComments
h3
h3.activity-title
i.fa.fa-comments-o
| {{_ '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")
template(name="membersWidget")

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

@ -153,12 +153,6 @@ template(name="changeLanguagePopup")
template(name="changeSettingsPopup")
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
// a.js-toggle-desktop-drag-handles
// i.fa.fa-arrows

@ -283,16 +283,6 @@ Template.changeLanguagePopup.events({
});
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() {
const currentUser = ReactiveCache.getCurrentUser();
if (currentUser) {
@ -352,16 +342,6 @@ Template.changeSettingsPopup.events({
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'() {
Meteor.call('toggleRescueCardDescription')
},

@ -294,6 +294,7 @@
"color-white": "Weiß",
"color-yellow": "gelb",
"unset-color": "Nicht festgelegt",
"comments": "Kommentare",
"comment": "Kommentar speichern",
"comment-placeholder": "Kommentar schreiben",
"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",
"fullname": "Vollständiger Name",
"header-logo-title": "Zurück zur Board Seite.",
"hide-system-messages": "Systemmeldungen ausblenden",
"show-activities": "Aktivitäten anzeigen",
"headerBarCreateBoardPopup-title": "Board erstellen",
"home": "Home",
"import": "Importieren",
@ -1109,8 +1110,8 @@
"created-at-newest-first": "Erstelldatum (neueste zuerst)",
"created-at-oldest-first": "Erstelldatum (älteste zuerst)",
"links-heading": "Links",
"hide-system-messages-of-all-users": "Alle System-Nachrichten aller Nutzer verbergen",
"now-system-messages-of-all-users-are-hidden": "Alle System-Nachrichten aller Nutzer sind nun verborgen",
"hide-activities-of-all-boards": "Alle Board Aktivitäten anzeigen abschalten",
"now-activities-of-all-boards-are-hidden": "Alle Aktivitäten von allen Boards sind nun verborgen",
"move-swimlane": "Swimlane verschieben",
"moveSwimlanePopup-title": "Swimlane verschieben",
"custom-field-stringtemplate": "String-Vorlage",

@ -295,6 +295,7 @@
"color-white": "white",
"color-yellow": "yellow",
"unset-color": "Unset",
"comments": "Comments",
"comment": "Comment",
"comment-placeholder": "Write Comment",
"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",
"fullname": "Full Name",
"header-logo-title": "Go back to your boards page.",
"hide-system-messages": "Hide system messages",
"show-activities": "Show Activities",
"headerBarCreateBoardPopup-title": "Create Board",
"home": "Home",
"import": "Import",
@ -1110,8 +1111,8 @@
"created-at-newest-first": "Created At (Newest First)",
"created-at-oldest-first": "Created At (Oldest First)",
"links-heading": "Links",
"hide-system-messages-of-all-users": "Hide system messages of all users",
"now-system-messages-of-all-users-are-hidden": "Now system messages of all users are hidden",
"hide-activities-of-all-boards": "Don't show the board activities on all boards",
"now-activities-of-all-boards-are-hidden": "Now all activities of all boards are hidden",
"move-swimlane": "Move Swimlane",
"moveSwimlanePopup-title": "Move Swimlane",
"custom-field-stringtemplate": "String Template",

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

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

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

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

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

Loading…
Cancel
Save