@plusscommunities/pluss-circles-web 1.0.3 → 1.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,345 @@
1
+ import React, { Component } from 'react';
2
+ import { connect } from 'react-redux';
3
+ import _ from 'lodash';
4
+ import moment from 'moment';
5
+ import { Link } from 'react-router-dom';
6
+ import { PlussCore } from '../feature.config';
7
+ import { circlesLoaded } from '../actions';
8
+ import { circleActions } from '../apis';
9
+ import { Table } from 'react-bootstrap';
10
+ import FontAwesome from 'react-fontawesome';
11
+
12
+ const { Components, Session, Helper } = PlussCore;
13
+
14
+ class Circles extends Component {
15
+ constructor(props) {
16
+ super(props);
17
+ this.state = {
18
+ userSearch: '',
19
+ };
20
+ }
21
+
22
+ componentDidMount() {
23
+ this.getData();
24
+ }
25
+
26
+ getData = () => {
27
+ const { auth } = this.props;
28
+ this.setState({ loadingAll: true }, async () => {
29
+ try {
30
+ const res = await circleActions.getAll(auth.site);
31
+ console.log('getData', res.data);
32
+ this.props.circlesLoaded(res.data);
33
+ this.setState({ loadingAll: false });
34
+ } catch (error) {
35
+ console.error('getData', error);
36
+ this.setState({ loadingAll: false });
37
+ }
38
+ });
39
+ };
40
+
41
+ getCircles() {
42
+ let result = this.props.circles;
43
+ if (this.state.selectedTypeFilter) {
44
+ result = _.filter(result, (circle) => {
45
+ return this.state.selectedTypeFilter === 'circle' ? !circle.IsPrivate : circle.IsPrivate;
46
+ });
47
+ }
48
+ if (this.state.selectedUserFilter) {
49
+ result = _.filter(result, (circle) => {
50
+ return _.some(circle.Audience, (user) => {
51
+ return user.userId === this.state.selectedUserFilter.userId;
52
+ });
53
+ });
54
+ }
55
+ return result;
56
+ }
57
+
58
+ getUsers() {
59
+ let users = [];
60
+ this.props.circles.forEach((circle) => {
61
+ circle.Audience.forEach((user) => {
62
+ users.push(user);
63
+ });
64
+ });
65
+ users = _.sortBy(
66
+ _.uniqBy(users, (user) => {
67
+ return user.userId;
68
+ }),
69
+ 'displayName',
70
+ );
71
+ return _.filter(users, (u) => {
72
+ if (!_.isEmpty(this.state.userSearch)) {
73
+ return (u.displayName || '').toLowerCase().indexOf(this.state.userSearch.toLowerCase()) > -1;
74
+ }
75
+ return true;
76
+ });
77
+ }
78
+
79
+ validateCircleAdmin(circle) {
80
+ if (Session.validateAccess(this.props.auth.site, 'circles', this.props.auth)) {
81
+ return true;
82
+ }
83
+ return _.some(circle.Audience, (user) => {
84
+ return user.userId === this.props.user.Id && user.isAdmin;
85
+ });
86
+ }
87
+
88
+ canAddNew = () => {
89
+ const { auth } = this.props;
90
+ return Session.validateAccess(auth.site, 'circles', auth);
91
+ };
92
+
93
+ onAddNew = () => {
94
+ const { auth } = this.props;
95
+ if (Session.validateAccess(auth.site, 'circles', auth)) {
96
+ this.props.history.push(`/circles/add`);
97
+ }
98
+ };
99
+
100
+ openUserFilter = () => {
101
+ this.setState({
102
+ userFilterOpen: true,
103
+ });
104
+ };
105
+
106
+ closeUserFilter = () => {
107
+ this.setState({
108
+ userFilterOpen: false,
109
+ });
110
+ };
111
+
112
+ selectUserFilter = (user) => {
113
+ this.setState({
114
+ selectedUserFilter: user,
115
+ userFilterOpen: false,
116
+ });
117
+ };
118
+
119
+ removeUserFilter = (event) => {
120
+ event.stopPropagation();
121
+ this.setState({
122
+ selectedUserFilter: null,
123
+ });
124
+ };
125
+
126
+ openTypeFilter = () => {
127
+ this.setState({
128
+ typeFilterOpen: true,
129
+ });
130
+ };
131
+
132
+ closeTypeFilter = () => {
133
+ this.setState({
134
+ typeFilterOpen: false,
135
+ });
136
+ };
137
+
138
+ selectTypeFilter = (type) => {
139
+ this.setState({
140
+ selectedTypeFilter: type,
141
+ typeFilterOpen: false,
142
+ });
143
+ };
144
+
145
+ removeTypeFilter = (event) => {
146
+ event.stopPropagation();
147
+ this.setState({
148
+ selectedTypeFilter: null,
149
+ });
150
+ };
151
+
152
+ onHandleChange = (event) => {
153
+ var stateChange = {};
154
+ stateChange[event.target.getAttribute('id')] = event.target.value;
155
+ this.setState(stateChange);
156
+ };
157
+
158
+ getTypeFilterText = (type) => {
159
+ if (type === 'private') {
160
+ return 'Private Message';
161
+ }
162
+ return 'Circle';
163
+ };
164
+
165
+ getTitle = (circle) => {
166
+ if (circle.IsPrivate) {
167
+ return `PM: ${circle.Audience.map((user) => {
168
+ return user.displayName;
169
+ }).join(', ')}`;
170
+ }
171
+ return circle.Title;
172
+ };
173
+
174
+ renderRow(circle) {
175
+ return (
176
+ <tr key={circle.Id}>
177
+ <td className="table-TitleColumn">
178
+ <Link to={`/circles/circle/${circle.Id}`}>{this.getTitle(circle)}</Link>
179
+ </td>
180
+ <td>{moment(circle.Changed).local().format('D MMM YYYY')}</td>
181
+ <td>
182
+ {circle.Audience.map((user) => {
183
+ return (
184
+ <Components.ProfilePic
185
+ size={30}
186
+ image={user.profilePic}
187
+ hoverText={user.displayName}
188
+ containerClass="circleTableProfilePic"
189
+ />
190
+ );
191
+ })}
192
+ </td>
193
+ <td>
194
+ {this.validateCircleAdmin(circle) && !circle.IsPrivate && (
195
+ <Link to={`/circles/edit/${circle.Id}`}>
196
+ <FontAwesome
197
+ style={{
198
+ fontSize: 20,
199
+ padding: 5,
200
+ marginLeft: 12,
201
+ cursor: 'pointer',
202
+ }}
203
+ name="pencil"
204
+ />
205
+ </Link>
206
+ )}
207
+ </td>
208
+ </tr>
209
+ );
210
+ }
211
+
212
+ renderFilters() {
213
+ let userFilter = <Components.Tag className="marginRight-10" onClick={this.openUserFilter} text="User" />;
214
+ let typeFilter = <Components.Tag className="marginRight-10" onClick={this.openTypeFilter} text="Type" />;
215
+
216
+ if (this.state.selectedUserFilter) {
217
+ userFilter = (
218
+ <Components.Tag className="marginRight-10" onClick={this.openUserFilter} rightIcon="close" rightClick={this.removeUserFilter}>
219
+ <Components.UserListing size={15} user={this.state.selectedUserFilter} textClass="tag_text" />
220
+ </Components.Tag>
221
+ );
222
+ }
223
+ if (this.state.selectedTypeFilter) {
224
+ typeFilter = (
225
+ <Components.Tag
226
+ className="marginRight-10"
227
+ onClick={this.openTypeFilter}
228
+ rightIcon="close"
229
+ rightClick={this.removeTypeFilter}
230
+ text={this.getTypeFilterText(this.state.selectedTypeFilter)}
231
+ />
232
+ );
233
+ }
234
+ return (
235
+ <div className="flex flex-center marginTop-20">
236
+ <Components.Text type="h5" className="marginRight-20">
237
+ Filter by
238
+ </Components.Text>
239
+ {userFilter}
240
+ {typeFilter}
241
+ </div>
242
+ );
243
+ }
244
+
245
+ renderUserFilterPopup() {
246
+ if (!this.state.userFilterOpen) {
247
+ return null;
248
+ }
249
+ return (
250
+ <Components.Popup title="Select User" maxWidth={600} minWidth={400} minHeight={400} hasPadding onClose={this.closeUserFilter}>
251
+ <Components.GenericInput
252
+ id="userSearch"
253
+ type="text"
254
+ label="Search"
255
+ placeholder="Enter name"
256
+ value={this.state.userSearch}
257
+ onChange={(e) => this.onHandleChange(e)}
258
+ alwaysShowLabel
259
+ />
260
+ {this.getUsers().map((user) => {
261
+ return (
262
+ <Components.UserListing
263
+ key={user.userId}
264
+ user={user}
265
+ onClick={() => {
266
+ this.selectUserFilter(user);
267
+ }}
268
+ />
269
+ );
270
+ })}
271
+ </Components.Popup>
272
+ );
273
+ }
274
+
275
+ renderTypeFilterPopup() {
276
+ if (!this.state.typeFilterOpen) {
277
+ return null;
278
+ }
279
+ return (
280
+ <Components.Popup title="Select Type" maxWidth={600} minWidth={400} hasPadding onClose={this.closeTypeFilter}>
281
+ <Components.Tag
282
+ onClick={() => {
283
+ this.selectTypeFilter('circle');
284
+ }}
285
+ text="Circle"
286
+ className="marginRight-10"
287
+ />
288
+ <Components.Tag
289
+ onClick={() => {
290
+ this.selectTypeFilter('private');
291
+ }}
292
+ text="Private Message"
293
+ />
294
+ </Components.Popup>
295
+ );
296
+ }
297
+
298
+ render() {
299
+ return (
300
+ <div>
301
+ {this.renderTypeFilterPopup()}
302
+ {this.renderUserFilterPopup()}
303
+ <Components.Header>{this.canAddNew() && <Components.AddButton onClick={this.onAddNew} text="NEW CIRCLE" />}</Components.Header>
304
+ <div className="pageContainer paddingVertical-20 paddingHorizontal-40">
305
+ <Components.Text type="h1" className="">
306
+ Circles
307
+ </Components.Text>
308
+ {this.renderFilters()}
309
+
310
+ <Table className="plussTable" striped bordered condensed hover style={{ minWidth: '100%' }}>
311
+ <thead>
312
+ <tr>
313
+ <th>Title</th>
314
+ <th>Last updated</th>
315
+ <th>Members</th>
316
+ <th style={{ width: 50 }} />
317
+ </tr>
318
+ </thead>
319
+ <tbody>
320
+ {this.getCircles().map((circle) => {
321
+ return this.renderRow(circle);
322
+ })}
323
+ </tbody>
324
+ </Table>
325
+ <div className="hub_tidioPadding"></div>
326
+ </div>
327
+ </div>
328
+ );
329
+ }
330
+ }
331
+
332
+ const styles = {};
333
+
334
+ const mapStateToProps = (state) => {
335
+ const { circles } = state.circles;
336
+ const { auth } = state;
337
+
338
+ return {
339
+ circles,
340
+ auth,
341
+ user: Helper.getUserFromState(state),
342
+ };
343
+ };
344
+
345
+ export default connect(mapStateToProps, { circlesLoaded })(Circles);