blob: fd5c04db9240285e538058b52d1cf5b6f01e171d [file] [log] [blame]
talig8e9c0652017-12-20 14:30:43 +02001/*!
2 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
13 * or implied. See the License for the specific language governing
14 * permissions and limitations under the License.
15 */
16
17import React from 'react';
18import PropTypes from 'prop-types';
19import ReactDOM from 'react-dom';
20import classnames from 'classnames';
21import i18n from 'nfvo-utils/i18n/i18n.js';
22import {notificationType} from './UserNotificationsConstants.js';
23import ShowMore from 'react-show-more';
24
25const Notification = ({notification, users, onActionClicked, getNotificationTypeDesc}) => {
26 const {eventType, read, eventAttributes, dateTime} = notification;
27 const {itemName, userId, description, versionName, permission, granted} = eventAttributes;
28 const {fullName: userName} = users.find(user => user.userId === userId);
29 return (
30 <div className={classnames('notification', {'unread': !read})}>
31 <div className='notification-data'>
32 <div className='item-name'>
33 {itemName}
34 {versionName && <span>&nbsp;&nbsp;&nbsp;v{versionName}</span>}
35 {!read && <div className='unread-circle-icon'></div> }
36 </div>
37 <div className='flex-items'>
38 <div className='type'>{getNotificationTypeDesc(eventType, permission, granted)}</div>
39 <div className='separator'/>
40 <div className='user-name'>{`${i18n('By')} ${userName}`}</div>
41 </div>
42 {(description || versionName) && <div className='description'>
43 {description && <ShowMore anchorClass='more-less' lines={2} more={i18n('More')} less={i18n('Less')}>
44 {description}
45 </ShowMore>}
46 {eventType === notificationType.ITEM_CHANGED.SUBMIT &&
47 <div>
48 <div>{i18n('Version {versionName} was submitted.', {versionName: versionName})}</div>
49 </div>
50 }
51 </div>
52 }
53 <div className='date'>{dateTime}</div>
54 </div>
55 <div className='notification-action'>
56 <div className={classnames('action-button', {'hidden': read})} onClick={() => onActionClicked(notification)}>
svishnev091edfd2018-03-19 12:15:19 +020057 {eventType === notificationType.PERMISSION_CHANGED
58 || eventType === notificationType.ITEM_DELETED
59 || eventType === notificationType.ITEM_ARCHIVED
60 || eventType === notificationType.ITEM_RESTORED ? i18n('OK') : i18n('Sync')}
talig8e9c0652017-12-20 14:30:43 +020061 </div>
62 </div>
63 </div>
64 );
65};
66
67function getNotificationTypeDesc(eventType, permission, granted) {
68 switch (eventType) {
69 case notificationType.PERMISSION_CHANGED:
svishnev091edfd2018-03-19 12:15:19 +020070 const grantedStr = granted ? i18n('Granted') : i18n('Taken');
71 return `${i18n('Permission')} ${grantedStr}: ${permission}`;
talig8e9c0652017-12-20 14:30:43 +020072 case notificationType.ITEM_CHANGED.COMMIT:
73 return i18n('Your Copy Is Out Of Sync');
74 case notificationType.ITEM_CHANGED.SUBMIT:
75 return i18n('Version Submitted');
svishnev091edfd2018-03-19 12:15:19 +020076 case notificationType.ITEM_DELETED:
77 return i18n('Item was deleted');
78 case notificationType.ITEM_ARCHIVED:
79 return i18n('Item was archived');
80 case notificationType.ITEM_RESTORED:
81 return i18n('Item was restored from archive');
talig8e9c0652017-12-20 14:30:43 +020082 }
83}
84
85class UserNotifications extends React.Component {
86
87 static propTypes = {
88 currentScreen: PropTypes.object,
89 notificationsList: PropTypes.array,
90 usersList: PropTypes.array,
91 lastScanned: PropTypes.string,
92 endOfPage:PropTypes.string,
93 onLoadPrevNotifications: PropTypes.func,
94 onSync: PropTypes.func,
95 updateNotification: PropTypes.func,
96 onLoadItemsLists: PropTypes.func
97 };
98
99 render() {
100 const {notificationsList = [], usersList, lastScanned, endOfPage} = this.props;
101
102 return (
103 <div className='user-notifications'>
104 <div className='notifications-title'>{i18n('Notifications')}</div>
105 <div className='notifications-list' ref='notificationList' onScroll={() => this.loadPrevNotifications(lastScanned, endOfPage)}>
106 {
107 notificationsList.map(notification => (
108 <Notification key={notification.eventId} notification={notification} users={usersList}
109 onActionClicked={notification => this.onActionClicked(notification)}
110 getNotificationTypeDesc={getNotificationTypeDesc}/>))
111 }
112 </div>
113 </div>
114 );
115 }
116
117 onActionClicked(notification) {
118 const {onSync, updateNotification, currentScreen, onLoadItemsLists} = this.props;
svishnev091edfd2018-03-19 12:15:19 +0200119 const {eventType, eventAttributes: {itemId, itemName, versionId, versionName}} = notification;
120 if(eventType !== notificationType.PERMISSION_CHANGED &&
121 eventType !== notificationType.ITEM_DELETED &&
122 eventType !== notificationType.ITEM_ARCHIVED &&
123 eventType !== notificationType.ITEM_RESTORED) {
talig8e9c0652017-12-20 14:30:43 +0200124 onSync({itemId, itemName, versionId, versionName, currentScreen});
125 }
126 else {
127 onLoadItemsLists();
128 }
129 updateNotification(notification);
130 }
131
132 loadPrevNotifications(lastScanned, endOfPage) {
133 if(endOfPage && lastScanned) {
134 let element = ReactDOM.findDOMNode(this.refs['notificationList']);
135 const {onLoadPrevNotifications} = this.props;
136
137 if (element && element.clientHeight + element.scrollTop === element.scrollHeight) {
138 onLoadPrevNotifications(lastScanned, endOfPage);
139 }
140 }
141 }
142}
143
miriamed411d152018-01-02 15:35:55 +0200144export default UserNotifications;