blob: c70c57338f21b36c3d5cdb78d4e50a3abf5aa290 [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';
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +020022import { notificationType } from './UserNotificationsConstants.js';
Einav Weiss Keidarf2c47232018-05-30 18:12:02 +030023import ShowMore from 'react-show-more-text';
talig8e9c0652017-12-20 14:30:43 +020024
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +020025const Notification = ({
26 notification,
27 users,
28 onActionClicked,
29 getNotificationTypeDesc
30}) => {
31 const { eventType, read, eventAttributes, dateTime } = notification;
32 const {
33 itemName,
34 userId,
35 description,
36 versionName,
37 permission,
38 granted
39 } = eventAttributes;
40 const { fullName: userName } = users.find(user => user.userId === userId);
41 return (
42 <div className={classnames('notification', { unread: !read })}>
43 <div className="notification-data">
44 <div className="item-name">
45 {itemName}
46 {versionName && (
47 <span>&nbsp;&nbsp;&nbsp;v{versionName}</span>
48 )}
49 {!read && <div className="unread-circle-icon" />}
50 </div>
51 <div className="flex-items">
52 <div className="type">
53 {getNotificationTypeDesc(
54 eventType,
55 permission,
56 granted
57 )}
58 </div>
59 <div className="separator" />
60 <div className="user-name">{`${i18n(
61 'By'
62 )} ${userName}`}</div>
63 </div>
64 {(description || versionName) && (
65 <div className="description">
66 {description && (
67 <ShowMore
68 anchorClass="more-less"
69 lines={2}
70 more={i18n('More')}
71 less={i18n('Less')}>
72 {description}
73 </ShowMore>
74 )}
75 {eventType === notificationType.ITEM_CHANGED.SUBMIT && (
76 <div>
77 <div>
78 {i18n(
79 'Version {versionName} was submitted.',
80 { versionName: versionName }
81 )}
82 </div>
83 </div>
84 )}
85 </div>
86 )}
87 <div className="date">{dateTime}</div>
88 </div>
89 <div className="notification-action">
90 <div
91 className={classnames('action-button', { hidden: read })}
92 onClick={() => onActionClicked(notification)}>
93 {eventType === notificationType.PERMISSION_CHANGED ||
94 eventType === notificationType.ITEM_DELETED ||
95 eventType === notificationType.ITEM_ARCHIVED ||
96 eventType === notificationType.ITEM_RESTORED
97 ? i18n('OK')
98 : i18n('Sync')}
99 </div>
100 </div>
101 </div>
102 );
talig8e9c0652017-12-20 14:30:43 +0200103};
104
105function getNotificationTypeDesc(eventType, permission, granted) {
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200106 switch (eventType) {
107 case notificationType.PERMISSION_CHANGED:
108 const grantedStr = granted ? i18n('Granted') : i18n('Taken');
109 return `${i18n('Permission')} ${grantedStr}: ${permission}`;
110 case notificationType.ITEM_CHANGED.COMMIT:
111 return i18n('Your Copy Is Out Of Sync');
112 case notificationType.ITEM_CHANGED.SUBMIT:
113 return i18n('Version Submitted');
114 case notificationType.ITEM_DELETED:
115 return i18n('Item was deleted');
116 case notificationType.ITEM_ARCHIVED:
117 return i18n('Item was archived');
118 case notificationType.ITEM_RESTORED:
119 return i18n('Item was restored from archive');
120 }
talig8e9c0652017-12-20 14:30:43 +0200121}
122
123class UserNotifications extends React.Component {
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200124 static propTypes = {
125 currentScreen: PropTypes.object,
126 notificationsList: PropTypes.array,
127 usersList: PropTypes.array,
128 lastScanned: PropTypes.string,
129 endOfPage: PropTypes.string,
130 onLoadPrevNotifications: PropTypes.func,
131 onSync: PropTypes.func,
132 updateNotification: PropTypes.func,
133 onLoadItemsLists: PropTypes.func
134 };
talig8e9c0652017-12-20 14:30:43 +0200135
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200136 render() {
137 const {
138 notificationsList = [],
139 usersList,
140 lastScanned,
141 endOfPage
142 } = this.props;
talig8e9c0652017-12-20 14:30:43 +0200143
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200144 return (
145 <div className="user-notifications">
146 <div className="notifications-title">
147 {i18n('Notifications')}
148 </div>
149 <div
150 className="notifications-list"
151 ref="notificationList"
152 onScroll={() =>
153 this.loadPrevNotifications(lastScanned, endOfPage)
154 }>
155 {notificationsList.map(notification => (
156 <Notification
157 key={notification.eventId}
158 notification={notification}
159 users={usersList}
160 onActionClicked={notification =>
161 this.onActionClicked(notification)
162 }
163 getNotificationTypeDesc={getNotificationTypeDesc}
164 />
165 ))}
166 </div>
167 </div>
168 );
169 }
talig8e9c0652017-12-20 14:30:43 +0200170
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200171 onActionClicked(notification) {
172 const {
173 onSync,
174 updateNotification,
175 currentScreen,
176 onLoadItemsLists
177 } = this.props;
178 const {
179 eventType,
180 eventAttributes: { itemId, itemName, versionId, versionName }
181 } = notification;
182 if (
183 eventType !== notificationType.PERMISSION_CHANGED &&
184 eventType !== notificationType.ITEM_DELETED &&
185 eventType !== notificationType.ITEM_ARCHIVED &&
186 eventType !== notificationType.ITEM_RESTORED
187 ) {
188 onSync({ itemId, itemName, versionId, versionName, currentScreen });
189 } else {
190 onLoadItemsLists();
191 }
192 updateNotification(notification);
193 }
talig8e9c0652017-12-20 14:30:43 +0200194
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200195 loadPrevNotifications(lastScanned, endOfPage) {
196 if (endOfPage && lastScanned) {
197 let element = ReactDOM.findDOMNode(this.refs['notificationList']);
198 const { onLoadPrevNotifications } = this.props;
talig8e9c0652017-12-20 14:30:43 +0200199
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200200 if (
201 element &&
202 element.clientHeight + element.scrollTop ===
203 element.scrollHeight
204 ) {
205 onLoadPrevNotifications(lastScanned, endOfPage);
206 }
207 }
208 }
talig8e9c0652017-12-20 14:30:43 +0200209}
210
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200211export default UserNotifications;