summaryrefslogtreecommitdiffstats
path: root/client/components/notifications
diff options
context:
space:
mode:
authorLauri Ojansivu <x@xet7.org>2020-04-02 01:09:35 +0300
committerLauri Ojansivu <x@xet7.org>2020-04-02 01:09:35 +0300
commite34f240c35b6eaec3e3ac2830129ddf914de5feb (patch)
tree9185e821c0e24cd1c9ae55da416d30b974035c31 /client/components/notifications
parent56667112d7fd146a9847794207e9a2224b1115d7 (diff)
parent8ea86ae0b9e4351b935fde45c77f37d09778739d (diff)
downloadwekan-e34f240c35b6eaec3e3ac2830129ddf914de5feb.tar.gz
wekan-e34f240c35b6eaec3e3ac2830129ddf914de5feb.tar.bz2
wekan-e34f240c35b6eaec3e3ac2830129ddf914de5feb.zip
Merge branch 'jtbairdsr-master'
Diffstat (limited to 'client/components/notifications')
-rw-r--r--client/components/notifications/notification.jade10
-rw-r--r--client/components/notifications/notification.js28
-rw-r--r--client/components/notifications/notification.styl57
-rw-r--r--client/components/notifications/notificationIcon.jade53
-rw-r--r--client/components/notifications/notifications.jade5
-rw-r--r--client/components/notifications/notifications.js32
-rw-r--r--client/components/notifications/notifications.styl17
-rw-r--r--client/components/notifications/notificationsDrawer.jade16
-rw-r--r--client/components/notifications/notificationsDrawer.js38
-rw-r--r--client/components/notifications/notificationsDrawer.styl57
10 files changed, 313 insertions, 0 deletions
diff --git a/client/components/notifications/notification.jade b/client/components/notifications/notification.jade
new file mode 100644
index 00000000..c98bbdba
--- /dev/null
+++ b/client/components/notifications/notification.jade
@@ -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
diff --git a/client/components/notifications/notification.js b/client/components/notifications/notification.js
new file mode 100644
index 00000000..89277520
--- /dev/null
+++ b/client/components/notifications/notification.js
@@ -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;
+ },
+});
diff --git a/client/components/notifications/notification.styl b/client/components/notifications/notification.styl
new file mode 100644
index 00000000..0cf0cfd5
--- /dev/null
+++ b/client/components/notifications/notification.styl
@@ -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
diff --git a/client/components/notifications/notificationIcon.jade b/client/components/notifications/notificationIcon.jade
new file mode 100644
index 00000000..04377606
--- /dev/null
+++ b/client/components/notifications/notificationIcon.jade
@@ -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")
diff --git a/client/components/notifications/notifications.jade b/client/components/notifications/notifications.jade
new file mode 100644
index 00000000..bf8acbbf
--- /dev/null
+++ b/client/components/notifications/notifications.jade
@@ -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)
diff --git a/client/components/notifications/notifications.js b/client/components/notifications/notifications.js
new file mode 100644
index 00000000..c0aa6cb5
--- /dev/null
+++ b/client/components/notifications/notifications.js
@@ -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'),
+ );
+}
diff --git a/client/components/notifications/notifications.styl b/client/components/notifications/notifications.styl
new file mode 100644
index 00000000..710cd3f9
--- /dev/null
+++ b/client/components/notifications/notifications.styl
@@ -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;
+
diff --git a/client/components/notifications/notificationsDrawer.jade b/client/components/notifications/notificationsDrawer.jade
new file mode 100644
index 00000000..01117009
--- /dev/null
+++ b/client/components/notifications/notificationsDrawer.jade
@@ -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'}}
diff --git a/client/components/notifications/notificationsDrawer.js b/client/components/notifications/notificationsDrawer.js
new file mode 100644
index 00000000..98d4750d
--- /dev/null
+++ b/client/components/notifications/notificationsDrawer.js
@@ -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'));
+ },
+});
diff --git a/client/components/notifications/notificationsDrawer.styl b/client/components/notifications/notificationsDrawer.styl
new file mode 100644
index 00000000..a26b5e4a
--- /dev/null
+++ b/client/components/notifications/notificationsDrawer.styl
@@ -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