Compare commits

...
35 Commits
Author SHA1 Message Date
Lauri Ojansivu f438d04c42 v3.90 2020-04-06 16:25:12 +03:00
Lauri Ojansivu d798f6e3ef Update dependencies. 2020-04-06 15:46:59 +03:00
Lauri Ojansivu c96ca4e875 Update translations. 2020-04-06 15:37:09 +03:00
Lauri Ojansivu 8a71fe39c5 Update ChangeLog. 2020-04-06 15:35:19 +03:00
Lauri Ojansivu e4ec5c38b7 Merge branch 'doggy8088-patch-1' 2020-04-06 15:27:53 +03:00
Will 保哥 b849d4c2ba Update layouts.js 2020-04-06 18:16:17 +08:00
Lauri Ojansivu db9c895da8 v3.89 2020-04-05 01:20:09 +03:00
Lauri Ojansivu a938c386cf Update translations. 2020-04-05 01:06:49 +03:00
Lauri Ojansivu 06c2ff0904 Update ChangeLog. 2020-04-04 01:43:09 +03:00
Lauri Ojansivu 76e832c3a6 Merge branch 'daniel-eder-feature/subtask-use-parent-swimlane' 2020-04-04 01:36:43 +03:00
Lauri Ojansivu b7fd79aef0 Merge branch 'feature/subtask-use-parent-swimlane' of https://github.com/daniel-eder/wekan into daniel-eder-feature/subtask-use-parent-swimlane 2020-04-04 01:26:49 +03:00
Lauri Ojansivu 28a9ab7131 Update translations. 2020-04-04 01:19:47 +03:00
Lauri Ojansivu 8e0b1cc056 Merge branch 'slvrpdr-master' 2020-04-04 01:04:17 +03:00
Lauri Ojansivu b424b34cab Merge branch 'master' of https://github.com/slvrpdr/wekan into slvrpdr-master 2020-04-04 00:42:14 +03:00
Lauri Ojansivu 45a83da7be Update translations. 2020-04-04 00:37:23 +03:00
Pedro Sousa 6e86292b99 Search also a Card's Custom Fields 2020-04-03 16:23:48 +01:00
Daniel Eder 89fe030fa3 subtasks now use swimlane with title matching parent lane title
As discussed in #1953 this is required to handle two-board scenarios correctly.
2020-04-02 07:49:26 +02:00
Lauri Ojansivu 1e0b53eb9b v3.88 2020-04-02 02:34:02 +03:00
Lauri Ojansivu a5f2ae497a Update translations. 2020-04-02 02:05:25 +03:00
Lauri Ojansivu 6441ebec83 Update ChangeLog. 2020-04-02 01:34:27 +03:00
Lauri Ojansivu 7c609d402a Update translations. 2020-04-02 01:29:22 +03:00
Lauri Ojansivu e34f240c35 Merge branch 'jtbairdsr-master' 2020-04-02 01:09:35 +03:00
Jonathan Baird 8ea86ae0b9 fix error from notifications subscriptions 2020-04-01 15:04:12 -06:00
Jonathan Baird f4d0791c6c add correct i18n for notifications menu 2020-04-01 14:50:31 -06:00
Jonathan Baird fcb1def355 Merge upstream/master
* commit '56667112d7fd146a9847794207e9a2224b1115d7':
  Update ChangeLog.
  Minicard labels on the top and title on bottom.
  Update translations.
  Update translations.
  Add translations for Notification drawer like Trello.
  Add translations for Board Settings / Allow Rename Board/Swimlane/Card.
  Update ChangeLog.
  Fix start-wekan.sh MongoDB port to 27017.
  v3.87
  Update translations.
  Update ChangeLog.
  Improvements on card details visualization.
  Update ChangeLog.
  Move "Rules" from "Board View" to "Board Settings".
  Update ChangeLog.
  Fix richer editor submit did not clear edit area.
  Update ChangeLog.
  Fix Browser always reload the whole page when I change one of the card color. Fixed by making label colors and text again editable. Regression from [Wekan v3.86 2)](https://github.com/wekan/wekan/commit/b9099a8b7ea6f63c79bdcbb871cb993b2cb7e325).
2020-04-01 14:47:53 -06:00
Lauri Ojansivu 56667112d7 Update ChangeLog. 2020-04-01 19:42:26 +03:00
Lauri Ojansivu d0003a334f Minicard labels on the top and title on bottom.
Thanks to helioguardabaxo and xet7 !

Closes #2980
2020-04-01 19:39:02 +03:00
Lauri Ojansivu 35427063ff Update translations. 2020-04-01 17:11:02 +03:00
Lauri Ojansivu f5182e6328 Update translations. 2020-04-01 17:04:01 +03:00
Lauri Ojansivu 0c911694c8 Add translations for Notification drawer like Trello. 2020-04-01 16:51:54 +03:00
Lauri Ojansivu 2eed1ca0eb Add translations for Board Settings / Allow Rename Board/Swimlane/Card.
Thanks to xet7 !
2020-04-01 16:48:14 +03:00
Lauri Ojansivu 99e5293ef5 Update ChangeLog. 2020-04-01 00:37:26 +03:00
Lauri Ojansivu c60a092fc0 Fix start-wekan.sh MongoDB port to 27017.
Thanks to Keelan and xet7 !

Related #2979
2020-04-01 00:34:21 +03:00
Jonathan Baird 9819c9f801 add a notification drawer like trello 2020-03-27 11:35:03 -06:00
Daniel Eder c41c1e5293 subtasks now use parent task swimlane by default 2020-03-26 10:57:05 +01:00
86 changed files with 36967 additions and 36133 deletions

No files matched your search

+6 -6
View File
@@ -11,7 +11,7 @@ allow-deny@1.1.0
arillo:flow-router-helpers@0.5.2
audit-argument-checks@1.0.7
autoupdate@1.6.0
babel-compiler@7.5.2
babel-compiler@7.5.3
babel-runtime@1.5.0
base64@1.0.12
binary-heap@1.0.11
@@ -20,7 +20,7 @@ blaze-tools@1.0.10
boilerplate-generator@1.7.0
browser-policy-common@1.0.11
browser-policy-framing@1.1.0
caching-compiler@1.2.1
caching-compiler@1.2.2
caching-html-compiler@1.1.3
callback-hook@1.3.0
cfs:access-point@0.1.49
@@ -55,9 +55,9 @@ ddp-rate-limiter@1.0.7
ddp-server@2.3.1
deps@1.0.12
diff-sequence@1.1.1
dynamic-import@0.5.1
dynamic-import@0.5.2
easylogic:summernote@0.8.8
ecmascript@0.14.2
ecmascript@0.14.3
ecmascript-runtime@0.7.0
ecmascript-runtime-client@0.10.0
ecmascript-runtime-server@0.9.0
@@ -110,7 +110,7 @@ modern-browsers@0.1.5
modules@0.15.0
modules-runtime@0.12.0
momentjs:moment@2.24.0
mongo@1.9.0
mongo@1.9.1
mongo-decimal@0.1.1
mongo-dev-server@1.1.0
mongo-id@1.0.7
@@ -186,7 +186,7 @@ useraccounts:core@1.14.2
useraccounts:flow-routing@1.14.2
useraccounts:unstyled@1.14.2
verron:autosize@3.0.8
webapp@1.9.0
webapp@1.9.1
webapp-hashing@1.0.9
wekan-accounts-cas@0.1.0
wekan-accounts-oidc@1.0.10
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "wekan",
"version": "v3.87.0",
"version": "v3.90.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "wekan",
"version": "v3.87.0",
"version": "v3.90.0",
"description": "Open-Source kanban",
"private": true,
"scripts": {
+43
View File
@@ -1,3 +1,46 @@
# v3.90 2020-04-06 Wekan release
This release makes the following updates:
- [Update dependencies](https://github.com/wekan/wekan/commit/d798f6e3ef09595ce4f1d1fbc053eec70fc91fb9).
and updates the following translations:
- [Update layouts.js for zh-TW language name](https://github.com/wekan/wekan/pull/2988).
Thanks to doggy8088.
Thanks to above GitHub users for their contributions and translators for their translations.
# v3.89 2020-04-05 Wekan release
This release adds the following new features:
- [Create subtasks in parenttask swimlane](https://github.com/wekan/wekan/issues/1953).
Thanks to TOSCom-DanielEder.
- [When searching cards in a board, also search from Custom Fields](https://github.com/wekan/wekan/pull/2985).
Thanks to slvrpdr.
Thanks to above GitHub users for their contributions and translators for their translations.
# v3.88 2020-04-02 Wekan release
This release adds the following new features:
- [Notification drawer](https://github.com/wekan/wekan/pull/2975) [like Trello](https://github.com/wekan/wekan/issues/2471).
Thanks to jtbairdsr and xet7.
and makes the following UI changes:
- [Minicard labels on the top and title on bottom](https://github.com/wekan/wekan/issues/2980).
Thanks to helioguardabaxo and xet7.
and fixes the following bugs:
- [Fix start-wekan.sh MongoDB port to 27017](https://github.com/wekan/wekan/commit/c60a092fc0ed9fe15c417bcb443b1e3e3aaedf7e).
Thanks to Keelan and xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v3.87 2020-04-01 Wekan release
This release makes the following UI changes:
+1 -1
View File
@@ -1,5 +1,5 @@
appId: wekan-public/apps/77b94f60-dec9-0136-304e-16ff53095928
appVersion: "v3.87.0"
appVersion: "v3.90.0"
files:
userUploads:
- README.md
+167 -200
View File
@@ -8,234 +8,201 @@ template(name="activities")
+cardActivities
template(name="boardActivities")
each currentBoard.activities
.activity
+userAvatar(userId=user._id)
p.activity-desc
+memberName(user=user)
if($eq activityType 'deleteAttachment')
| {{{_ 'activity-delete-attach' cardLink}}}.
if($eq activityType 'addAttachment')
| {{{_ 'activity-attached' attachmentLink cardLink}}}.
if($eq activityType 'addBoardMember')
| {{{_ 'activity-added' memberLink boardLabel}}}.
if($eq activityType 'addComment')
| {{{_ 'activity-on' cardLink}}}
a.activity-comment(href="{{ card.absoluteUrl }}")
+viewer
= comment.text
if($eq activityType 'addChecklist')
| {{{_ 'activity-checklist-added' cardLink}}}.
.activity-checklist(href="{{ card.absoluteUrl }}")
+viewer
= checklist.title
if($eq activityType 'removeChecklist')
| {{{_ 'activity-checklist-removed' cardLink}}}.
if($eq activityType 'checkedItem')
| {{{_ 'activity-checked-item' checkItem checklist.title cardLink}}}.
if($eq activityType 'uncheckedItem')
| {{{_ 'activity-unchecked-item' checkItem checklist.title cardLink}}}.
if($eq activityType 'checklistCompleted')
| {{{_ 'activity-checklist-completed' checklist.title cardLink}}}.
if($eq activityType 'checklistUncompleted')
| {{{_ 'activity-checklist-uncompleted' checklist.title cardLink}}}.
if($eq activityType 'addChecklistItem')
| {{{_ 'activity-checklist-item-added' checklist.title cardLink}}}.
.activity-checklist(href="{{ card.absoluteUrl }}")
+viewer
= checklistItem.title
if($eq activityType 'removedChecklistItem')
| {{{_ 'activity-checklist-item-removed' checklist.title cardLink}}}.
if($eq activityType 'archivedCard')
| {{{_ 'activity-archived' cardLink}}}.
if($eq activityType 'archivedList')
| {{_ 'activity-archived' list.title}}.
if($eq activityType 'archivedSwimlane')
| {{_ 'activity-archived' swimlane.title}}.
if($eq activityType 'createBoard')
| {{_ 'activity-created' boardLabel}}.
if($eq activityType 'createCard')
| {{{_ 'activity-added' cardLink boardLabel}}}.
if($eq activityType 'createCustomField')
| {{_ 'activity-customfield-created' customField}}.
if($eq activityType 'createList')
| {{_ 'activity-added' list.title boardLabel}}.
if($eq activityType 'createSwimlane')
| {{_ 'activity-added' swimlane.title boardLabel}}.
if($eq activityType 'removeList')
| {{_ 'activity-removed' title boardLabel}}.
if($eq activityType 'importBoard')
| {{{_ 'activity-imported-board' boardLabel sourceLink}}}.
if($eq activityType 'importCard')
| {{{_ 'activity-imported' cardLink boardLabel sourceLink}}}.
if($eq activityType 'importList')
| {{{_ 'activity-imported' listLabel boardLabel sourceLink}}}.
if($eq activityType 'joinMember')
if($eq user._id member._id)
| {{{_ 'activity-joined' cardLink}}}.
else
| {{{_ 'activity-added' memberLink cardLink}}}.
if($eq activityType 'moveCardBoard')
| {{{_ 'activity-moved' cardLink oldBoardName boardName}}}.
if($eq activityType 'moveCard')
| {{{_ 'activity-moved' cardLink oldList.title list.title}}}.
if($eq activityType 'removeBoardMember')
| {{{_ 'activity-excluded' memberLink boardLabel}}}.
if($eq activityType 'restoredCard')
| {{{_ 'activity-sent' cardLink boardLabel}}}.
if($eq activityType 'addedLabel')
| {{{_ 'activity-added-label' lastLabel cardLink}}}.
if($eq activityType 'removedLabel')
| {{{_ 'activity-removed-label' lastLabel cardLink}}}.
if($eq activityType 'setCustomField')
| {{{_ 'activity-set-customfield' lastCustomField lastCustomFieldValue cardLink}}}.
if($eq activityType 'unsetCustomField')
| {{{_ 'activity-unset-customfield' lastCustomField cardLink}}}.
if($eq activityType 'unjoinMember')
if($eq user._id member._id)
| {{{_ 'activity-unjoined' cardLink}}}.
else
| {{{_ 'activity-removed' memberLink cardLink}}}.
span(title=createdAt).activity-meta {{ moment createdAt }}
each activityData in currentBoard.activities
+activity(activity=activityData card=card mode=mode)
template(name="cardActivities")
each currentCard.activities
.activity
+userAvatar(userId=user._id)
p.activity-desc
+memberName(user=user)
if($eq activityType 'createCard')
| {{_ 'activity-added' cardLabel listName}}.
if($eq activityType 'importCard')
| {{{_ 'activity-imported' cardLabel list.title sourceLink}}}.
if($eq activityType 'joinMember')
if($eq user._id member._id)
| {{_ 'activity-joined' cardLabel}}.
else
| {{{_ 'activity-added' memberLink cardLabel}}}.
if($eq activityType 'unjoinMember')
if($eq user._id member._id)
| {{_ 'activity-unjoined' cardLabel}}.
else
| {{{_ 'activity-removed' cardLabel memberLink}}}.
if($eq activityType 'archivedCard')
| {{_ 'activity-archived' cardLabel}}.
each activityData in currentCard.activities
+activity(activity=activityData card=card mode=mode)
if($eq activityType 'addedLabel')
| {{{_ 'activity-added-label-card' lastLabel }}}.
template(name="activity")
.activity
+userAvatar(userId=activity.user._id)
p.activity-desc
+memberName(user=activity.user)
if($eq activityType 'removedLabel')
| {{{_ 'activity-removed-label-card' lastLabel }}}.
//- attachment activity -------------------------------------------------
if($eq activity.activityType 'deleteAttachment')
| {{{_ 'activity-delete-attach' cardLink}}}.
if($eq activityType 'removeChecklist')
| {{{_ 'activity-checklist-removed' cardLabel}}}.
if($eq activity.activityType 'addAttachment')
| {{{_ 'activity-attached' attachmentLink cardLink}}}.
if($neq mode 'board')
if activity.attachment.isImage
img.attachment-image-preview(src=activity.attachment.url)
if($eq activityType 'checkedItem')
| {{{_ 'activity-checked-item-card' checkItem checklist.title }}}.
//- board activity ------------------------------------------------------
if($eq mode 'board')
if($eq activity.activityType 'createBoard')
| {{_ 'activity-created' boardLabel}}.
if($eq activityType 'uncheckedItem')
| {{{_ 'activity-unchecked-item-card' checkItem checklist.title }}}.
if($eq activity.activityType 'importBoard')
| {{{_ 'activity-imported-board' boardLabel sourceLink}}}.
if($eq activityType 'checklistCompleted')
| {{{_ 'activity-checklist-completed-card' checklist.title }}}.
if($eq activity.activityType 'addBoardMember')
| {{{_ 'activity-added' memberLink boardLabel}}}.
if($eq activityType 'checklistUncompleted')
| {{{_ 'activity-checklist-uncompleted-card' checklist.title }}}.
if($eq activity.activityType 'removeBoardMember')
| {{{_ 'activity-excluded' memberLink boardLabel}}}.
if($eq activityType 'restoredCard')
| {{_ 'activity-sent' cardLabel boardLabel}}.
if($eq activityType 'moveCard')
| {{_ 'activity-moved' cardLabel oldList.title list.title}}.
//- card activity -------------------------------------------------------
if($eq activity.activityType 'createCard')
if($eq mode 'card')
| {{{_ 'activity-added' cardLabel activity.listName}}}.
else
| {{{_ 'activity-added' cardLabel boardLabel}}}.
if($eq activityType 'moveCardBoard')
| {{{_ 'activity-moved' cardLink oldBoardName boardName}}}.
if($eq activity.activityType 'importCard')
| {{{_ 'activity-imported' cardLink boardLabel sourceLink}}}.
if($eq activityType 'addAttachment')
| {{{_ 'activity-attached' attachmentLink cardLabel}}}.
if attachment.isImage
img.attachment-image-preview(src=attachment.url)
if($eq activityType 'deleteAttachment')
| {{{_ 'activity-delete-attach' cardLabel}}}.
if($eq activityType 'removedChecklist')
| {{{_ 'activity-checklist-removed' cardLabel}}}.
if($eq activityType 'addChecklist')
| {{{_ 'activity-checklist-added' cardLabel}}}.
if($eq activity.activityType 'moveCard')
| {{{_ 'activity-moved' cardLabel activity.oldList.title activity.list.title}}}.
if($eq activity.activityType 'moveCardBoard')
| {{{_ 'activity-moved' cardLink activity.oldBoardName activity.boardName}}}.
if($eq activity.activityType 'archivedCard')
| {{{_ 'activity-archived' cardLink}}}.
if($eq activity.activityType 'restoredCard')
| {{{_ 'activity-sent' cardLink boardLabel}}}.
//- checklist activity --------------------------------------------------
if($eq activity.activityType 'addChecklist')
| {{{_ 'activity-checklist-added' cardLink}}}.
if($eq mode 'card')
.activity-checklist
+viewer
= checklist.title
if($eq activityType 'addChecklistItem')
| {{{_ 'activity-checklist-item-added' checklist.title cardLink}}}.
.activity-checklist(href="{{ card.absoluteUrl }}")
= activity.checklist.title
else
a.activity-checklist(href="{{ activity.card.absoluteUrl }}")
+viewer
= checklistItem.title
= activity.checklist.title
if(currentData.timeKey)
| {{{_ activityType }}}
= ' '
i(title=currentData.timeValue).activity-meta {{ moment currentData.timeValue 'LLL' }}
if (currentData.timeOldValue)
= ' '
| {{{_ "previous_as" }}}
= ' '
i(title=currentData.timeOldValue).activity-meta {{ moment currentData.timeOldValue 'LLL' }}
= ' @'
else if(currentData.timeValue)
| {{{_ activityType currentData.timeValue}}}
if($eq activity.activityType 'removedChecklist')
| {{{_ 'activity-checklist-removed' cardLink}}}.
if($eq activity.activityType 'completeChecklist')
| {{{_ 'activity-checklist-completed' activity.checklist.title cardLink}}}.
if($eq activityType 'deleteComment')
| {{{_ 'activity-deleteComment' currentData.commentId}}}.
if($eq activityType 'editComment')
| {{{_ 'activity-editComment' currentData.commentId}}}.
if($eq activityType 'addComment')
if($eq activity.activityType 'uncompleteChecklist')
| {{{_ 'activity-checklist-uncompleted' activity.checklist.title cardLink}}}.
if($eq activity.activityType 'checkedItem')
| {{{_ 'activity-checked-item' checkItem activity.checklist.title cardLink}}}.
if($eq activity.activityType 'uncheckedItem')
| {{{_ 'activity-unchecked-item' checkItem activity.checklist.title cardLink}}}.
if($eq activity.activityType 'addChecklistItem')
| {{{_ 'activity-checklist-item-added' activity.checklist.title cardLink}}}.
.activity-checklist(href="{{ activity.card.absoluteUrl }}")
+viewer
= activity.checklistItem.title
if($eq activity.activityType 'removedChecklistItem')
| {{{_ 'activity-checklist-item-removed' 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)
= comment.text
= activity.comment.text
.edit-controls
button.primary(type="submit") {{_ 'edit'}}
else
.activity-comment
+viewer
= comment.text
span(title=createdAt).activity-meta {{ moment createdAt }}
if ($eq currentUser._id comment.userId)
= activity.comment.text
span(title=activity.createdAt).activity-meta {{ moment activity.createdAt }}
if ($eq currentUser._id activity.comment.userId)
= ' - '
a.js-open-inlined-form {{_ "edit"}}
= ' - '
a.js-delete-comment {{_ "delete"}}
if($eq activity.activityType 'deleteComment')
| {{{_ 'activity-deleteComment' currentData.commentId}}}.
if($eq activity.activityType 'editComment')
| {{{_ 'activity-editComment' currentData.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.absoluteUrl }}")
+viewer
= activity.comment.text
//- customField activity ------------------------------------------------
if($eq mode 'board')
if($eq activity.activityType 'createCustomField')
| {{_ 'activity-customfield-created' customField}}.
if($eq activity.activityType 'setCustomField')
| {{{_ 'activity-set-customfield' lastCustomField lastCustomFieldValue cardLink}}}.
if($eq activity.activityType 'unsetCustomField')
| {{{_ 'activity-unset-customfield' lastCustomField cardLink}}}.
//- label activity ------------------------------------------------------
if($eq activity.activityType 'addedLabel')
| {{{_ 'activity-added-label' lastLabel cardLink}}}.
if($eq activity.activityType 'removedLabel')
| {{{_ 'activity-removed-label' lastLabel cardLink}}}.
//- list activity -------------------------------------------------------
if($neq mode 'card')
if($eq activity.activityType 'createList')
| {{{_ 'activity-added' listLabel boardLabel}}}.
if($eq activity.activityType 'importList')
| {{{_ 'activity-imported' listLabel boardLabel sourceLink}}}.
if($eq activity.activityType 'removeList')
| {{{_ 'activity-removed' activity.title boardLabel}}}.
if($eq activity.activityType 'archivedList')
| {{_ 'activity-archived' listLabel}}.
//- member activity ----------------------------------------------------
if($eq activity.activityType 'joinMember')
if($eq user._id activity.member._id)
| {{{_ 'activity-joined' cardLink}}}.
else
span(title=createdAt).activity-meta {{ moment createdAt }}
| {{{_ 'activity-added' memberLink cardLink}}}.
if($eq activity.activityType 'unjoinMember')
if($eq user._id activity.member._id)
| {{{_ 'activity-unjoined' cardLink}}}.
else
| {{{_ 'activity-removed' memberLink cardLink}}}.
//- swimlane activity --------------------------------------------------
if($neq mode 'card')
if($eq activity.activityType 'createSwimlane')
| {{{_ 'activity-added' activity.swimlane.title boardLabel}}}.
if($eq activity.activityType 'archivedSwimlane')
| {{_ 'activity-archived' activity.swimlane.title}}.
//- I don't understand this part ----------------------------------------
if(currentData.timeKey)
| {{{_ activity.activityType }}}
= ' '
i(title=currentData.timeValue).activity-meta {{ moment currentData.timeValue 'LLL' }}
if (currentData.timeOldValue)
= ' '
| {{{_ "previous_as" }}}
= ' '
i(title=currentData.timeOldValue).activity-meta {{ moment currentData.timeOldValue 'LLL' }}
= ' @'
else if(currentData.timeValue)
| {{{_ activity.activityType currentData.timeValue}}}
span(title=activity.createdAt).activity-meta {{ moment activity.createdAt }}
+72 -39
View File
@@ -41,7 +41,9 @@ BlazeComponent.extendComponent({
});
});
},
}).register('activities');
BlazeComponent.extendComponent({
loadNextPage() {
if (this.loadNextPageLocked === false) {
this.page.set(this.page.get() + 1);
@@ -50,41 +52,37 @@ BlazeComponent.extendComponent({
},
checkItem() {
const checkItemId = this.currentData().checklistItemId;
const checkItemId = this.currentData().activity.checklistItemId;
const checkItem = ChecklistItems.findOne({ _id: checkItemId });
return checkItem.title;
return checkItem && checkItem.title;
},
boardLabel() {
const data = this.currentData();
if (data.mode !== 'board') {
return createBoardLink(data.activity.board(), data.activity.listName);
}
return TAPi18n.__('this-board');
},
cardLabel() {
const data = this.currentData();
if (data.mode !== 'card') {
return createCardLink(this.currentData().activity.card());
}
return TAPi18n.__('this-card');
},
cardLink() {
const card = this.currentData().card();
return (
card &&
Blaze.toHTML(
HTML.A(
{
href: card.absoluteUrl(),
class: 'action-card',
},
card.title,
),
)
);
return createCardLink(this.currentData().activity.card());
},
lastLabel() {
const lastLabelId = this.currentData().labelId;
const lastLabelId = this.currentData().activity.labelId;
if (!lastLabelId) return null;
const lastLabel = Boards.findOne(Session.get('currentBoard')).getLabelById(
lastLabelId,
);
const lastLabel = Boards.findOne(
this.currentData().activity.boardId,
).getLabelById(lastLabelId);
if (lastLabel && (lastLabel.name === undefined || lastLabel.name === '')) {
return lastLabel.color;
} else {
@@ -94,7 +92,7 @@ BlazeComponent.extendComponent({
lastCustomField() {
const lastCustomField = CustomFields.findOne(
this.currentData().customFieldId,
this.currentData().activity.customFieldId,
);
if (!lastCustomField) return null;
return lastCustomField.name;
@@ -102,10 +100,10 @@ BlazeComponent.extendComponent({
lastCustomFieldValue() {
const lastCustomField = CustomFields.findOne(
this.currentData().customFieldId,
this.currentData().activity.customFieldId,
);
if (!lastCustomField) return null;
const value = this.currentData().value;
const value = this.currentData().activity.value;
if (
lastCustomField.settings.dropdownItems &&
lastCustomField.settings.dropdownItems.length > 0
@@ -122,11 +120,13 @@ BlazeComponent.extendComponent({
},
listLabel() {
return this.currentData().list().title;
const activity = this.currentData().activity;
const list = activity.list();
return (list && list.title) || activity.title;
},
sourceLink() {
const source = this.currentData().source;
const source = this.currentData().activity.source;
if (source) {
if (source.url) {
return Blaze.toHTML(
@@ -146,30 +146,31 @@ BlazeComponent.extendComponent({
memberLink() {
return Blaze.toHTMLWithData(Template.memberName, {
user: this.currentData().member(),
user: this.currentData().activity.member(),
});
},
attachmentLink() {
const attachment = this.currentData().attachment();
const attachment = this.currentData().activity.attachment();
// trying to display url before file is stored generates js errors
return (
attachment &&
attachment.url({ download: true }) &&
Blaze.toHTML(
HTML.A(
{
href: attachment.url({ download: true }),
target: '_blank',
},
attachment.name(),
),
)
(attachment &&
attachment.url({ download: true }) &&
Blaze.toHTML(
HTML.A(
{
href: attachment.url({ download: true }),
target: '_blank',
},
attachment.name(),
),
)) ||
this.currentData().activity.attachmentName
);
},
customField() {
const customField = this.currentData().customField();
const customField = this.currentData().activity.customField();
if (!customField) return null;
return customField.name;
},
@@ -199,4 +200,36 @@ BlazeComponent.extendComponent({
},
];
},
}).register('activities');
}).register('activity');
function createCardLink(card) {
return (
card &&
Blaze.toHTML(
HTML.A(
{
href: card.absoluteUrl(),
class: 'action-card',
},
card.title,
),
)
);
}
function createBoardLink(board, list) {
let text = board.title;
if (list) text += `: ${list}`;
return (
board &&
Blaze.toHTML(
HTML.A(
{
href: board.absoluteUrl(),
class: 'action-board',
},
text,
),
)
);
}
+1 -1
View File
@@ -79,7 +79,7 @@
border-radius: top 2px
.minicard-labels
float: right
float: none
display: flex
flex-wrap: wrap
+7 -1
View File
@@ -20,7 +20,13 @@ BlazeComponent.extendComponent({
const crtBoard = Boards.findOne(card.boardId);
const targetBoard = crtBoard.getDefaultSubtasksBoard();
const listId = targetBoard.getDefaultSubtasksListId();
const swimlaneId = targetBoard.getDefaultSwimline()._id;
//Get the full swimlane data for the parent task.
const parentSwimlane = Swimlanes.findOne({boardId: crtBoard._id, _id: card.swimlaneId});
//find the swimlane of the same name in the target board.
const targetSwimlane = Swimlanes.findOne({boardId: targetBoard._id, title: parentSwimlane.title});
//If no swimlane with a matching title exists in the target board, fall back to the default swimlane.
const swimlaneId = targetSwimlane === undefined ? targetBoard.getDefaultSwimline()._id : targetSwimlane._id;
if (title) {
const _id = Cards.insert({
+2
View File
@@ -35,6 +35,8 @@ template(name="header")
a#header-new-board-icon.js-create-board
i.fa.fa-plus(title="Create a new board")
+notifications
+headerUserBar
#header(class=currentBoard.colorClass)
+1 -1
View File
@@ -99,7 +99,7 @@
height: 28px
font-size: 12px
display: flex
z-index: 17
z-index: 21
#header-user-bar,
#header-new-board-icon,
+2
View File
@@ -73,6 +73,8 @@ Template.userFormsLayout.helpers({
name = 'Igbo';
} else if (lang.name === 'oc') {
name = 'Occitan';
} else if (lang.name === 'zh-TW') {
name = '繁體中文(台灣)';
}
return { tag, name };
}).sort(function(a, b) {
@@ -0,0 +1,10 @@
template(name='notification')
li.notification(class="{{#if read}}read{{/if}}")
.read-status
.materialCheckBox(class="{{#if read}}is-checked{{/if}}")
+notificationIcon(activityData)
.details
+activity(activity=activityData mode='none')
if read
.remove
a.fa.fa-trash
@@ -0,0 +1,28 @@
Template.notification.events({
'click .read-status .materialCheckBox'() {
const update = {};
update[`profile.notifications.${this.index}.read`] = this.read
? null
: Date.now();
Users.update(Meteor.userId(), { $set: update });
},
'click .remove a'() {
Meteor.user().removeNotification(this.activityData._id);
},
});
Template.notification.helpers({
mode: 'board',
isOfActivityType(activityId, type) {
const activity = Activities.findOne(activityId);
return activity && activity.activityType === type;
},
activityType(activityId) {
const activity = Activities.findOne(activityId);
return activity ? activity.activityType : '';
},
activityUser(activityId) {
const activity = Activities.findOne(activityId);
return activity && activity.userId;
},
});
@@ -0,0 +1,57 @@
#notifications-drawer
&.show-read .notification.read
display: flex
.notification
display: flex
float: none
padding: 12px 8px 8px
color: black
border-bottom: 1px solid #dbdbdb
&.read
display: none
.read-status
width: 30px
input
width: 24px
height: 24px
.activity-type
margin: 16px 0 0
width: 17px
height: 17px
font-size: 17px
display: block
color: #bbb
.details
width: calc(100% - 30px)
.activity
display: flex
.activity-desc
width: 100%;
.activity-comment
display: block
width: 100%
border-radius: 3px
background: #fff
text-decoration: none
box-shadow: 0 1px 2px rgba(0,0,0,0.2)
margin-top: 5px
padding: 5px
.activity-meta
display: block
font-size: 0.8em
color: #999
font-style: italic
.remove
a:hover
color #eb4646 !important
@@ -0,0 +1,53 @@
template(name='notificationIcon')
if($in activityType 'deleteAttachment' 'addAttachment')
i.fa.fa-paperclip.activity-type(title="attachment")
else if($in activityType 'createBoard' 'importBoard')
i.fa.fa-chalkboard.activity-type(title="board")
else if($in activityType 'createCard' 'importCard' 'moveCard')
+cardNotificationIcon
else if($in activityType 'moveCardBoard' 'archivedCard' 'restoredCard')
+cardNotificationIcon
//- $in can only handle up to 3 cases so we have to break this case over 2 cases... use a simple template to keep it
//- DRY and consistant
else if($in activityType 'addChecklist' 'removedChecklist' 'completeChecklist')
+checklistNotificationIcon
else if($in activityType 'uncompleteChecklist')
+checklistNotificationIcon
//- $in can only handle up to 3 cases so we have to break this case over 2 cases... use a simple template to keep it
//- DRY and consistant
else if($in activityType 'checkedItem' 'uncheckedItem' 'addChecklistItem' 'removedChecklistItem')
i.fa.fa-check-square.activity-type(title="checklist item")
else if($in activityType 'addComment')
i.fa.fa-comment-o.activity-type(title="comment")
else if($in activityType 'createCustomField' 'setCustomField' 'unsetCustomField')
i.fa.fa-code.activity-type(title="custom field")
else if($in activityType 'addedLabel' 'removedLabel')
i.fa.fa-tag.activity-type(title="label")
else if($in activityType 'createList' 'removeList' 'archivedList')
+listNotificationIcon
else if($in activityType 'importList')
+listNotificationIcon
//- $in can only handle up to 3 cases so we have to break this case over 2 cases... use a simple template to keep it
//- DRY and consistant
//- elswhere in the app we use fa-trello to indicate lists...
//- i personally like fa-columns a bit better
else if($in activityType 'unjoinMember' 'addBoardMember' 'joinMember' 'removeBoardMember')
i.fa.fa-user.activity-type(title="member")
else if($in activityType 'createSwimlane' 'archivedSwimlane')
i.fa.fa-th-large.activity-type(title="swimlane")
else
i.fa.fa-bug.activity-type(title="can't find icon for #{activityType}")
template(name='cardNotificationIcon')
i.fa.fa-clone.activity-type(title="card")
template(name='checklistNotificationIcon')
i.fa.fa-list.activity-type(title="checklist")
template(name='listNotificationIcon')
i.fa.fa-columns.activity-type(title="list")
@@ -0,0 +1,5 @@
template(name='notifications')
#notifications.board-header-btns.right
a.notifications-drawer-toggle.fa.fa-bell(class="{{#if $gt unreadNotifications 0}}alert{{/if}}")
if $.Session.get 'showNotificationsDrawer'
+notificationsDrawer(unreadNotifications=unreadNotifications)
@@ -0,0 +1,32 @@
// this hides the notifications drawer if anyone clicks off of the panel
Template.body.events({
click(event) {
if (
!$(event.target).is('#notifications *') &&
Session.get('showNotificationsDrawer')
) {
toggleNotificationsDrawer();
}
},
});
Template.notifications.helpers({
unreadNotifications() {
const notifications = Users.findOne(Meteor.userId()).notifications();
const unreadNotifications = _.filter(notifications, v => !v.read);
return unreadNotifications.length;
},
});
Template.notifications.events({
'click .notifications-drawer-toggle'() {
toggleNotificationsDrawer();
},
});
export function toggleNotificationsDrawer() {
Session.set(
'showNotificationsDrawer',
!Session.get('showNotificationsDrawer'),
);
}
@@ -0,0 +1,17 @@
#notifications
position: relative
.notifications-drawer-toggle
display: block
line-height: 28px
color: #f2f2f2
margin: 0 10px
width: 28px
height: 28px
text-align: center
border: 0
padding: 0
&.alert
background-color: #eb4646;
@@ -0,0 +1,16 @@
template(name='notificationsDrawer')
section#notifications-drawer(class="{{#if $.Session.get 'showReadNotifications'}}show-read{{/if}}")
.header
if $.Session.get 'showReadNotifications'
a.toggle-read {{_ 'filter-by-unread'}}
else
a.toggle-read {{_ 'view-all'}}
h5 {{_ 'notifications'}}
if($gt unreadNotifications 0)
|(#{unreadNotifications})
a.fa.fa-times-thin.close
ul.notifications
each transformedProfile.notifications
+notification(activityData=activity index=dbIndex read=read)
if($gt unreadNotifications 0)
a.all-read {{_ 'mark-all-as-read'}}
@@ -0,0 +1,38 @@
import { toggleNotificationsDrawer } from './notifications.js';
Template.notificationsDrawer.onCreated(function() {
Meteor.subscribe('notificationActivities');
Meteor.subscribe('notificationCards');
Meteor.subscribe('notificationUsers');
Meteor.subscribe('notificationsAttachments');
Meteor.subscribe('notificationChecklistItems');
Meteor.subscribe('notificationChecklists');
Meteor.subscribe('notificationComments');
Meteor.subscribe('notificationLists');
Meteor.subscribe('notificationSwimlanes');
});
Template.notificationsDrawer.helpers({
transformedProfile() {
return Users.findOne(Meteor.userId());
},
});
Template.notificationsDrawer.events({
'click .all-read'() {
const notifications = Meteor.user().profile.notifications;
for (const index in notifications) {
if (notifications.hasOwnProperty(index) && !notifications[index].read) {
const update = {};
update[`profile.notifications.${index}.read`] = Date.now();
Users.update(Meteor.userId(), { $set: update });
}
}
},
'click .close'() {
toggleNotificationsDrawer();
},
'click .toggle-read'() {
Session.set('showReadNotifications', !Session.get('showReadNotifications'));
},
});
@@ -0,0 +1,57 @@
belize = #2980b9
section#notifications-drawer
position: fixed
top: 28px
right: 0
width: 400px
background-color: #fafafa
box-shadow: 0 1px 2px rgba(0,0,0,0.15)
border-radius: 2px
max-height: calc(100vh - 28px - 36px)
color: black
padding-top 36px;
overflow: scroll
a:hover
color: belize !important
.header
position: fixed
top 28px
right 0
width calc(400px - 32px)
padding: 8px 16px
background: #ededed
border-bottom: 1px solid #dbdbdb
z-index 2
.toggle-read
position absolute
left 16px
top calc(50% - 8px)
color belize
h5
text-align: center
margin: 0
.close
position: absolute
top: calc(50% - 12px)
right: 12px
font-size: 24px
height: 24px
line-height: 24px
opacity 1
.all-read
color belize
background-color: #fafafa
margin 8px 16px 12px
display inline-block
ul.notifications
display: block
padding: 0px 16px
margin: 0
+768 -762
View File
File diff suppressed because it is too large. Load diff
+768 -762
View File
File diff suppressed because it is too large. Load diff
+768 -762
View File
File diff suppressed because it is too large. Load diff
+768 -762
View File
File diff suppressed because it is too large. Load diff
+768 -762
View File
File diff suppressed because it is too large. Load diff
+768 -762
View File
File diff suppressed because it is too large. Load diff
+9 -3
View File
@@ -64,7 +64,7 @@
"activity-unchecked-item": "hat %s in Checkliste %s von %s abgewählt",
"activity-checklist-added": "hat eine Checkliste zu %s hinzugefügt",
"activity-checklist-removed": "entfernte eine Checkliste von %s",
"activity-checklist-completed": "hat Checkliste __checklist__ der Karte __card__ auf der Liste __list__ in Swimlane __swimlane__ in Board __board__ vervollständigt",
"activity-checklist-completed": "Abgeschlossene Checkliste",
"activity-checklist-uncompleted": "unvervollständigte die Checkliste %s von %s",
"activity-checklist-item-added": "hat ein Checklistenelement zu '%s' in %s hinzugefügt",
"activity-checklist-item-removed": "hat ein Checklistenelement von '%s' in %s entfernt",
@@ -440,7 +440,7 @@
"save": "Speichern",
"search": "Suchen",
"rules": "Regeln",
"search-cards": "Suche nach Karten-/Listentiteln und Beschreibungen auf diesem Board",
"search-cards": "Suche nach Karten-/Listentiteln, Beschreibungen und personalisierten Feldern auf diesem Brett ",
"search-example": "Suchbegriff",
"select-color": "Farbe auswählen",
"set-wip-limit-value": "Setzen Sie ein Limit für die maximale Anzahl von Aufgaben in dieser Liste",
@@ -759,5 +759,11 @@
"show-on-card": "Zeige auf Karte",
"new": "Neu",
"editUserPopup-title": "Benutzer ändern",
"newUserPopup-title": "Neuer Benutzer"
"newUserPopup-title": "Neuer Benutzer",
"notifications": "Benachrichtigungen",
"view-all": "Alle anzeigen",
"filter-by-unread": "Nach Ungelesenen filtern",
"mark-all-as-read": "Als ungelesen markieren",
"allow-rename": "Umbenennen erlauben",
"allowRenamePopup-title": "Umbenennen erlauben"
}
+768 -762
View File
File diff suppressed because it is too large. Load diff
+768 -762
View File
File diff suppressed because it is too large. Load diff
+9 -3
View File
@@ -64,7 +64,7 @@
"activity-unchecked-item": "unchecked %s in checklist %s of %s",
"activity-checklist-added": "added checklist to %s",
"activity-checklist-removed": "removed a checklist from %s",
"activity-checklist-completed": "completed checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"activity-checklist-completed": "completed checklist %s of %s",
"activity-checklist-uncompleted": "uncompleted the checklist %s of %s",
"activity-checklist-item-added": "added checklist item to '%s' in %s",
"activity-checklist-item-removed": "removed a checklist item from '%s' in %s",
@@ -440,7 +440,7 @@
"save": "Save",
"search": "Search",
"rules": "Rules",
"search-cards": "Search from card/list titles and descriptions on this board",
"search-cards": "Search from card/list titles, descriptions and custom fields on this board",
"search-example": "Text to search for?",
"select-color": "Select Color",
"set-wip-limit-value": "Set a limit for the maximum number of tasks in this list",
@@ -762,5 +762,11 @@
"show-on-card": "Show on Card",
"new": "New",
"editUserPopup-title": "Edit User",
"newUserPopup-title": "New User"
"newUserPopup-title": "New User",
"notifications": "Notifications",
"view-all": "View All",
"filter-by-unread": "Filter by Unread",
"mark-all-as-read": "Mark all as read",
"allow-rename": "Allow Rename",
"allowRenamePopup-title": "Allow Rename"
}
+768 -762
View File
File diff suppressed because it is too large. Load diff
+768 -762
View File
File diff suppressed because it is too large. Load diff
+9 -3
View File
@@ -64,7 +64,7 @@
"activity-unchecked-item": "desmarcado %s en lista %s de %s",
"activity-checklist-added": "ha añadido una lista de verificación a %s",
"activity-checklist-removed": "eliminada una lista de verificación desde %s",
"activity-checklist-completed": "completada la lista de verificación __checklist__ de la tarjeta __card__ de la lista __list__ del carril __swimlane__ del tablero __board__",
"activity-checklist-completed": "lista de verificación completada %s de %s",
"activity-checklist-uncompleted": "no completado la lista %s de %s",
"activity-checklist-item-added": "ha añadido el elemento de la lista de verificación a '%s' en %s",
"activity-checklist-item-removed": "eliminado un elemento de la lista de verificación desde '%s' en %s",
@@ -440,7 +440,7 @@
"save": "Añadir",
"search": "Buscar",
"rules": "Reglas",
"search-cards": "Buscar entre los títulos y las descripciones de las tarjetas en este tablero.",
"search-cards": "Buscar entre los títulos, las descripciones de las tarjetas/listas y los campos personalizados en este tablero. ",
"search-example": "¿Texto a buscar?",
"select-color": "Seleccionar el color",
"set-wip-limit-value": "Cambiar el límite para el número máximo de tareas en esta lista.",
@@ -759,5 +759,11 @@
"show-on-card": "Mostrar en la tarjeta",
"new": "Nuevo",
"editUserPopup-title": "Editar el usuario",
"newUserPopup-title": "Nuevo usuario"
"newUserPopup-title": "Nuevo usuario",
"notifications": "Notificaciones",
"view-all": "Ver todo",
"filter-by-unread": "Filtrar por no leído",
"mark-all-as-read": "Marcar todo como leido",
"allow-rename": "Permitir renombrar",
"allowRenamePopup-title": "Permitir renombrar"
}
+768 -762
View File
File diff suppressed because it is too large. Load diff
+768 -762
View File
File diff suppressed because it is too large. Load diff
+768 -762
View File
File diff suppressed because it is too large. Load diff
+768 -762
View File
File diff suppressed because it is too large. Load diff
+768 -762
View File
File diff suppressed because it is too large. Load diff
+768 -762
View File
File diff suppressed because it is too large. Load diff
+768 -762
View File
File diff suppressed because it is too large. Load diff
+768 -762
View File
File diff suppressed because it is too large. Load diff
+768 -762
View File
File diff suppressed because it is too large. Load diff
+768 -762
View File
File diff suppressed because it is too large. Load diff
+768 -762
View File
File diff suppressed because it is too large. Load diff
+22 -16
View File
@@ -1,5 +1,5 @@
{
"accept": "Accetta",
"accept": "Accept",
"act-activity-notify": "Notifica attività",
"act-addAttachment": "aggiunto allegato __attachment__ alla scheda __card__ della lista __list__ della corsia __swimlane__  nella bacheca __board__",
"act-deleteAttachment": "eliminato allegato __attachment__ dalla scheda __card__ della lista __list__ della corsia __swimlane__  nella bacheca __board__",
@@ -64,7 +64,7 @@
"activity-unchecked-item": "disattivato %s nella checklist %s di %s",
"activity-checklist-added": "aggiunta checklist a %s",
"activity-checklist-removed": "È stata rimossa una checklist da%s",
"activity-checklist-completed": "checklist __checklist__ completata nella scheda __card__ della lista __list__ della corsia __swimlane__  nella bacheca __board__",
"activity-checklist-completed": "%s di %s checklists completate",
"activity-checklist-uncompleted": "La checklist non è stata completata",
"activity-checklist-item-added": "Aggiunto l'elemento checklist a '%s' in %s",
"activity-checklist-item-removed": "è stato rimosso un elemento della checklist da '%s' in %s",
@@ -440,7 +440,7 @@
"save": "Salva",
"search": "Cerca",
"rules": "Regole",
"search-cards": "Ricerca per titolo e descrizione scheda/lista su questa bacheca",
"search-cards": "Ricerca per titolo, descrizione scheda/lista e campi personalizzati su questa bacheca",
"search-example": "Testo da ricercare?",
"select-color": "Seleziona Colore",
"set-wip-limit-value": "Seleziona un limite per il massimo numero di attività in questa lista",
@@ -733,21 +733,21 @@
"loading": "Loading, please wait.",
"previous_as": "l'ultima volta è stata",
"act-a-dueAt": "Scadenza modificata in __timeValue__\nData precedente: __timeOldValue__",
"act-a-endAt": "modified ending time to __timeValue__ from (__timeOldValue__)",
"act-a-startAt": "modified starting time to __timeValue__ from (__timeOldValue__)",
"act-a-receivedAt": "modified received time to __timeValue__ from (__timeOldValue__)",
"a-dueAt": "modified due time to be",
"a-endAt": "modified ending time to be",
"a-startAt": "modified starting time to be",
"a-receivedAt": "modified received time to be",
"act-a-endAt": "orario finale modificato in __timeValue__ (precedentemente: __timeOldValue__)",
"act-a-startAt": "orario iniziale modificato in __timeValue__ (precedentemente: __timeOldValue__)",
"act-a-receivedAt": "orario di ricezione modificato in __timeValue__ (precedentemente: __timeOldValue__)",
"a-dueAt": "scadenza modificata in",
"a-endAt": "orario finale modificato in",
"a-startAt": "orario iniziale modificato in",
"a-receivedAt": "orario di ricezione modificato in",
"almostdue": "la data di scadenza attuale %s si sta avvicinando",
"pastdue": "la data di scadenza attuale %s è scaduta",
"duenow": "la data di scadenza attuale %s è oggi",
"act-newDue": "__list__/__card__ has 1st due reminder [__board__]",
"act-withDue": "__list__/__card__ due reminders [__board__]",
"act-almostdue": "was reminding the current due (__timeValue__) of __card__ is approaching",
"act-pastdue": "was reminding the current due (__timeValue__) of __card__ is past",
"act-duenow": "was reminding the current due (__timeValue__) of __card__ is now",
"act-newDue": "__list__/__card__ ha un 1° sollecito [__board__]",
"act-withDue": "sollecito relativo a __list__/__card__ [__board__]",
"act-almostdue": "sollecito inviato: la scadenza (__timeValue__) di __card__ è vicina",
"act-pastdue": "sollecito inviato: la scadenza (__timeValue__) di __card__ è già passata",
"act-duenow": "sollecito inviato: la scadenza (__timeValue__) di __card__ è adesso",
"act-atUserComment": "Sei stato menzionato in [__board__] __list__/__card__",
"delete-user-confirm-popup": "Sei sicuro di voler cancellare questo profilo? Non sarà possibile ripristinarlo.",
"accounts-allowUserDelete": "Permetti agli utenti di cancellare il loro profilo",
@@ -759,5 +759,11 @@
"show-on-card": "Mostra sulla scheda",
"new": "Nuovo",
"editUserPopup-title": "Modifica utente",
"newUserPopup-title": "Nuovo utente"
"newUserPopup-title": "Nuovo utente",
"notifications": "Notifiche",
"view-all": "Mostra Tutto",
"filter-by-unread": "Filtra per non letto",
"mark-all-as-read": "Segna come letto",
"allow-rename": "Consenti Rinomina",
"allowRenamePopup-title": "Consenti Rinomina"
}
+768 -762
View File
File diff suppressed because it is too large. Load diff
+768 -762
View File
File diff suppressed because it is too large. Load diff
+768 -762
View File
File diff suppressed because it is too large. Load diff
+768 -762
View File
File diff suppressed because it is too large. Load diff
+768 -762
View File
File diff suppressed because it is too large. Load diff
+768 -762
View File
File diff suppressed because it is too large. Load diff
+768 -762
View File
File diff suppressed because it is too large. Load diff
+768 -762
View File
File diff suppressed because it is too large. Load diff
+9 -3
View File
@@ -64,7 +64,7 @@
"activity-unchecked-item": "%s uitgevinkt in checklist %s van %s",
"activity-checklist-added": "checklist toegevoegd aan %s",
"activity-checklist-removed": "checklist verwijderd van %s",
"activity-checklist-completed": "heeft checklist __checklist__ afgewerkt op kaart __card__ van lijst __list__ in swimlane __swimlane__ op bord __board__",
"activity-checklist-completed": "checklist %s afgewerkt van %s",
"activity-checklist-uncompleted": "checklist %s onafgewerkt van %s",
"activity-checklist-item-added": "checklist item toegevoegd aan '%s' in '%s'",
"activity-checklist-item-removed": "checklist item verwijderd van '%s' in %s",
@@ -440,7 +440,7 @@
"save": "Opslaan",
"search": "Zoek",
"rules": "Regels",
"search-cards": "Zoek op kaarten/lijsten en omschrijvingen op dit bord",
"search-cards": "Zoek in kaart/lijst, titels, beschrijvingen en maatwerkvelden op dit bord",
"search-example": "Tekst om naar te zoeken?",
"select-color": "Selecteer kleur",
"set-wip-limit-value": "Zet een limiet voor het maximaal aantal taken in deze lijst",
@@ -759,5 +759,11 @@
"show-on-card": "Toon op kaart",
"new": "Nieuw",
"editUserPopup-title": "Wijzig gebruiker",
"newUserPopup-title": "Nieuwe gebruiker"
"newUserPopup-title": "Nieuwe gebruiker",
"notifications": "Meldingen",
"view-all": "Bekijk alles",
"filter-by-unread": "Filter op Ongelezen",
"mark-all-as-read": "Markeer alles als gelezen",
"allow-rename": "Sta Hernoemen toe",
"allowRenamePopup-title": "Sta Hernoemen toe"
}
+768 -762
View File
File diff suppressed because it is too large. Load diff
+768 -762
View File
File diff suppressed because it is too large. Load diff
+768 -762
View File
File diff suppressed because it is too large. Load diff
+768 -762
View File
File diff suppressed because it is too large. Load diff
+768 -762
View File
File diff suppressed because it is too large. Load diff
+768 -762
View File
File diff suppressed because it is too large. Load diff
+768 -762
View File
File diff suppressed because it is too large. Load diff
+768 -762
View File
File diff suppressed because it is too large. Load diff
+768 -762
View File
File diff suppressed because it is too large. Load diff
+768 -762
View File
File diff suppressed because it is too large. Load diff
+768 -762
View File
File diff suppressed because it is too large. Load diff
+768 -762
View File
File diff suppressed because it is too large. Load diff
+768 -762
View File
File diff suppressed because it is too large. Load diff
+768 -762
View File
File diff suppressed because it is too large. Load diff
+768 -762
View File
File diff suppressed because it is too large. Load diff
+768 -762
View File
File diff suppressed because it is too large. Load diff
+768 -762
View File
File diff suppressed because it is too large. Load diff
+768 -762
View File
File diff suppressed because it is too large. Load diff
+6 -6
View File
@@ -219,6 +219,9 @@ if (Meteor.isServer) {
type: 'card',
activityType: 'addAttachment',
attachmentId: doc._id,
// this preserves the name so that notifications can be meaningful after
// this file is removed
attachmentName: doc.original.name,
boardId: doc.boardId,
cardId: doc.cardId,
listId: doc.listId,
@@ -246,18 +249,15 @@ if (Meteor.isServer) {
type: 'card',
activityType: 'deleteAttachment',
attachmentId: doc._id,
// this preserves the name so that notifications can be meaningful after
// this file is removed
attachmentName: doc.original.name,
boardId: doc.boardId,
cardId: doc.cardId,
listId: doc.listId,
swimlaneId: doc.swimlaneId,
});
});
Attachments.files.after.remove((userId, doc) => {
Activities.remove({
attachmentId: doc._id,
});
});
}
export default Attachments;
+5 -1
View File
@@ -806,7 +806,11 @@ Boards.helpers({
if (term) {
const regex = new RegExp(term, 'i');
query.$or = [{ title: regex }, { description: regex }];
query.$or = [
{ title: regex },
{ description: regex },
{ customFields: { $elemMatch: { value: regex } } },
];
}
return Cards.find(query, projection);
+6
View File
@@ -369,6 +369,9 @@ if (Meteor.isServer) {
activityType: 'createList',
boardId: doc.boardId,
listId: doc._id,
// this preserves the name so that the activity can be useful after the
// list is deleted
title: doc.title,
});
});
@@ -397,6 +400,9 @@ if (Meteor.isServer) {
activityType: 'archivedList',
listId: doc._id,
boardId: doc.boardId,
// this preserves the name so that the activity can be useful after the
// list is deleted
title: doc.title,
});
}
});
+30 -3
View File
@@ -165,7 +165,20 @@ Users.attachSchema(
/**
* enabled notifications for the user
*/
type: [String],
type: [Object],
optional: true,
},
'profile.notifications.$.activity': {
/**
* The id of the activity this notification references
*/
type: String,
},
'profile.notifications.$.read': {
/**
* the date on which this notification was read
*/
type: Date,
optional: true,
},
'profile.showCardsCountAt': {
@@ -429,6 +442,20 @@ Users.helpers({
return _.contains(notifications, activityId);
},
notifications() {
const { notifications = [] } = this.profile || {};
for (const index in notifications) {
if (!notifications.hasOwnProperty(index)) continue;
const notification = notifications[index];
// this preserves their db sort order for editing
notification.dbIndex = index;
notification.activity = Activities.findOne(notification.activity);
}
// this sorts them newest to oldest to match Trello's behavior
notifications.reverse();
return notifications;
},
hasShowDesktopDragHandles() {
const profile = this.profile || {};
return profile.showDesktopDragHandles || false;
@@ -573,7 +600,7 @@ Users.mutations({
addNotification(activityId) {
return {
$addToSet: {
'profile.notifications': activityId,
'profile.notifications': { activity: activityId },
},
};
},
@@ -581,7 +608,7 @@ Users.mutations({
removeNotification(activityId) {
return {
$pull: {
'profile.notifications': activityId,
'profile.notifications': { activity: activityId },
},
};
},
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "wekan",
"version": "v3.87.0",
"version": "v3.90.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "wekan",
"version": "v3.87.0",
"version": "v3.90.0",
"description": "Open-Source kanban",
"private": true,
"scripts": {
+29 -15
View File
@@ -1524,7 +1524,7 @@ var n=this.pipeline.run(e.tokenizer(t)),r=new e.Vector,i=[],o=this._fields.reduc
<ul class="toc-list-h1">
<li>
<a href="#wekan-rest-api" class="toc-h1 toc-link" data-title="Wekan REST API v3.87">Wekan REST API v3.87</a>
<a href="#wekan-rest-api" class="toc-h1 toc-link" data-title="Wekan REST API v3.90">Wekan REST API v3.90</a>
</li>
@@ -2017,7 +2017,7 @@ var n=this.pipeline.run(e.tokenizer(t)),r=new e.Vector,i=[],o=this._fields.reduc
<div class="page-wrapper">
<div class="dark-box"></div>
<div class="content">
<h1 id="wekan-rest-api">Wekan REST API v3.87</h1>
<h1 id="wekan-rest-api">Wekan REST API v3.90</h1>
<blockquote>
<p>Scroll down for code samples, example requests and responses. Select a language for code samples from the tabs above or the mobile navigation menu.</p>
</blockquote>
@@ -11665,9 +11665,9 @@ System.out.println(response.toString());
<span class="hljs-string">"string"</span>
],
<span class="hljs-attr">"language"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"notifications"</span>: [
<span class="hljs-string">"string"</span>
],
<span class="hljs-attr">"notifications"</span>: [],
<span class="hljs-attr">"activity"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"read"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"showCardsCountAt"</span>: <span class="hljs-number">0</span>,
<span class="hljs-attr">"starredBoards"</span>: [
<span class="hljs-string">"string"</span>
@@ -12320,9 +12320,9 @@ System.out.println(response.toString());
<span class="hljs-string">"string"</span>
],
<span class="hljs-attr">"language"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"notifications"</span>: [
<span class="hljs-string">"string"</span>
],
<span class="hljs-attr">"notifications"</span>: [],
<span class="hljs-attr">"activity"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"read"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"showCardsCountAt"</span>: <span class="hljs-number">0</span>,
<span class="hljs-attr">"starredBoards"</span>: [
<span class="hljs-string">"string"</span>
@@ -15625,9 +15625,9 @@ UserSecurity
<span class="hljs-string">"string"</span>
],
<span class="hljs-attr">"language"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"notifications"</span>: [
<span class="hljs-string">"string"</span>
],
<span class="hljs-attr">"notifications"</span>: [],
<span class="hljs-attr">"activity"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"read"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"showCardsCountAt"</span>: <span class="hljs-number">0</span>,
<span class="hljs-attr">"starredBoards"</span>: [
<span class="hljs-string">"string"</span>
@@ -15793,9 +15793,9 @@ UserSecurity
<span class="hljs-string">"string"</span>
],
<span class="hljs-attr">"language"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"notifications"</span>: [
<span class="hljs-string">"string"</span>
],
<span class="hljs-attr">"notifications"</span>: [],
<span class="hljs-attr">"activity"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"read"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"showCardsCountAt"</span>: <span class="hljs-number">0</span>,
<span class="hljs-attr">"starredBoards"</span>: [
<span class="hljs-string">"string"</span>
@@ -15887,12 +15887,26 @@ UserSecurity
</tr>
<tr>
<td>notifications</td>
<td>[string]</td>
<td>[<a href="#schemausersprofilenotifications">UsersProfileNotifications</a>]</td>
<td>false</td>
<td>none</td>
<td>enabled notifications for the user</td>
</tr>
<tr>
<td>activity</td>
<td>string</td>
<td>true</td>
<td>none</td>
<td>The id of the activity this notification references</td>
</tr>
<tr>
<td>read</td>
<td>string</td>
<td>false</td>
<td>none</td>
<td>the date on which this notification was read</td>
</tr>
<tr>
<td>showCardsCountAt</td>
<td>number</td>
<td>false</td>
+11 -3
View File
@@ -1,7 +1,7 @@
swagger: '2.0'
info:
title: Wekan REST API
version: v3.87
version: v3.90
description: |
The REST API allows you to control and extend Wekan with ease.
@@ -3025,8 +3025,15 @@ definitions:
enabled notifications for the user
type: array
items:
type: string
x-nullable: true
$ref: "#/definitions/UsersProfileNotifications"
activity:
description: |
The id of the activity this notification references
type: string
read:
description: |
the date on which this notification was read
type: string
showCardsCountAt:
description: |
showCardCountAt field of the user
@@ -3078,6 +3085,7 @@ definitions:
Reference to the board templates swimlane Id
type: string
required:
- activity
- templatesBoardId
- cardTemplatesSwimlaneId
- listTemplatesSwimlaneId
+2 -2
View File
@@ -22,10 +22,10 @@ const pkgdef :Spk.PackageDefinition = (
appTitle = (defaultText = "Wekan"),
# The name of the app as it is displayed to the user.
appVersion = 387,
appVersion = 390,
# Increment this for every release.
appMarketingVersion = (defaultText = "3.87.0~2020-04-01"),
appMarketingVersion = (defaultText = "3.90.0~2020-04-06"),
# Human-readable presentation of the app version.
minUpgradableAppVersion = 0,
+3 -7
View File
@@ -1,9 +1,5 @@
Meteor.startup(() => {
// XXX: add activity id to profile.notifications,
// it can be displayed and rendered on web or mobile UI
// will uncomment the following code once UI implemented
//
// Notifications.subscribe('profile', (user, title, description, params) => {
// user.addNotification(params.activityId);
// });
Notifications.subscribe('profile', (user, title, description, params) => {
user.addNotification(params.activityId);
});
});
+101
View File
@@ -0,0 +1,101 @@
// We use these when displaying notifications in the notificationsDrawer
// gets all activities associated with the current user
Meteor.publish('notificationActivities', () => {
return activities();
});
// gets all attachments associated with activities associated with the current user
Meteor.publish('notificationAttachments', function() {
return Attachments.find({
_id: {
$in: activities()
.map(v => v.attachmentId)
.filter(v => !!v),
},
});
});
// gets all cards associated with activities associated with the current user
Meteor.publish('notificationCards', function() {
return Cards.find({
_id: {
$in: activities()
.map(v => v.cardId)
.filter(v => !!v),
},
});
});
// gets all checklistItems associated with activities associated with the current user
Meteor.publish('notificationChecklistItems', function() {
return ChecklistItems.find({
_id: {
$in: activities()
.map(v => v.checklistItemId)
.filter(v => !!v),
},
});
});
// gets all checklists associated with activities associated with the current user
Meteor.publish('notificationChecklists', function() {
return Checklists.find({
_id: {
$in: activities()
.map(v => v.checklistId)
.filter(v => !!v),
},
});
});
// gets all comments associated with activities associated with the current user
Meteor.publish('notificationComments', function() {
return CardComments.find({
_id: {
$in: activities()
.map(v => v.commentId)
.filter(v => !!v),
},
});
});
// gets all lists associated with activities associated with the current user
Meteor.publish('notificationLists', function() {
return Lists.find({
_id: {
$in: activities()
.map(v => v.listId)
.filter(v => !!v),
},
});
});
// gets all swimlanes associated with activities associated with the current user
Meteor.publish('notificationSwimlanes', function() {
return Swimlanes.find({
_id: {
$in: activities()
.map(v => v.swimlaneId)
.filter(v => !!v),
},
});
});
// gets all users associated with activities associated with the current user
Meteor.publish('notificationUsers', function() {
return Users.find({
_id: {
$in: activities()
.map(v => v.userId)
.filter(v => !!v),
},
});
});
function activities() {
const notifications = Meteor.user().profile.notifications || [];
return Activities.find({
_id: { $in: notifications.map(v => v.activity) },
});
}
+1 -1
View File
@@ -7,7 +7,7 @@
# Debug OIDC OAuth2 etc.
#export DEBUG=true
#---------------------------------------------
export MONGO_URL='mongodb://127.0.0.1:27018/wekan'
export MONGO_URL='mongodb://127.0.0.1:27017/wekan'
#---------------------------------------------
# Production: https://example.com/wekan
# Local: http://localhost:2000