@plusscommunities/pluss-feeds-web 1.0.7 → 1.0.9-beta.0

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.
Binary file
Binary file
package/src/index.js DELETED
@@ -1,27 +0,0 @@
1
- import FeedHub from './screens/FeedHub';
2
- import Feed from './screens/Feed';
3
- import AddFeed from './screens/AddFeed';
4
- // import { AnalyticsHub } from './components/AnalyticsHub.js';
5
- import FeedReducer from './reducers/FeedReducer';
6
- import { values } from './values.config';
7
-
8
- export const Reducers = (() => {
9
- const reducers = {};
10
- reducers[values.reducerKey] = FeedReducer;
11
- return reducers;
12
- })();
13
- export const Screens = (() => {
14
- const screens = {};
15
- screens[values.screenFeedHub] = FeedHub;
16
- screens[values.screenFeed] = Feed;
17
- screens[values.screenAddFeed] = AddFeed;
18
- return screens;
19
- })();
20
- export { default as Config } from './feature.config';
21
- // export { default as ActivityText } from './components/ActivityText';
22
- export { default as ViewWidget } from './components/ViewWidget';
23
- export { default as ViewFull } from './components/ViewFull';
24
- export { default as PreviewWidget } from './components/PreviewWidget';
25
- export { default as PreviewFull } from './components/PreviewFull';
26
- export { default as PreviewGrid } from './components/PreviewGrid';
27
- // export const Analytics = [AnalyticsHub];
@@ -1,71 +0,0 @@
1
- import _ from 'lodash';
2
-
3
- import {
4
- FEEDS_LOADING,
5
- FEEDS_LOADED,
6
- FEEDS_REMOVED,
7
- FEEDS_SUBMISSIONS_LOADED,
8
- FEEDS_SUBMISSIONS_REMOVED,
9
- FEED_TYPES_LOADED,
10
- } from '../actions/types';
11
-
12
- const INITIAL_STATE = {
13
- feeds: [],
14
- submissions: [],
15
- feedTypes: [],
16
- loading: false,
17
- };
18
-
19
- export default (state = INITIAL_STATE, action) => {
20
- switch (action.type) {
21
- case FEEDS_LOADING:
22
- return { ...state, loading: true };
23
- case FEEDS_LOADED:
24
- const feeds = _.unionWith(action.payload, state.feeds, (v1, v2) => {
25
- return v1 != null && v2 != null && v1.id === v2.id;
26
- });
27
- return {
28
- ...state,
29
- feeds: feeds.map((feedItem) => ({ ...feedItem })),
30
- loading: false,
31
- };
32
- case FEEDS_REMOVED:
33
- const fIndex = _.findIndex(state.feeds, (feed) => {
34
- return feed != null && feed.id === action.payload;
35
- });
36
- if (fIndex > -1) {
37
- const newFeeds = [...state.feeds];
38
- newFeeds.splice(fIndex, 1);
39
- return { ...state, feeds: newFeeds };
40
- }
41
- return state;
42
- case FEEDS_SUBMISSIONS_LOADED:
43
- var submissions = _.unionWith(action.payload, state.submissions, (v1, v2) => {
44
- return v1 != null && v2 != null && v1.id === v2.id;
45
- });
46
- return {
47
- ...state,
48
- submissions: _.filter(submissions, (feed) => !feed.deleted),
49
- };
50
- case FEEDS_SUBMISSIONS_REMOVED:
51
- const sIndex = _.findIndex(state.submissions, (submission) => {
52
- return submission != null && submission.id === action.payload;
53
- });
54
- if (sIndex > -1) {
55
- const newSubmissions = [...state.submissions];
56
- newSubmissions.splice(sIndex, 1);
57
- return { ...state, submissions: newSubmissions };
58
- }
59
- return state;
60
- case FEED_TYPES_LOADED:
61
- const feedTypes = _.unionWith(action.payload, state.feedTypes, (v1, v2) => {
62
- return v1 != null && v2 != null && v1.id === v2.id;
63
- });
64
- return {
65
- ...state,
66
- feedTypes: feedTypes,
67
- };
68
- default:
69
- return state;
70
- }
71
- };
@@ -1,489 +0,0 @@
1
- import _ from "lodash";
2
- import React, { Component } from "react";
3
- import { withRouter } from "react-router";
4
- import { connect } from "react-redux";
5
- import { feedsLoaded, feedsUpdate } from "../actions";
6
- import { PlussCore } from "../feature.config";
7
- import { feedActions, userActions } from "../apis";
8
- import { values } from "../values.config";
9
-
10
- const { Components, Helper, Session } = PlussCore;
11
-
12
- class AddFeed extends Component {
13
- constructor(props) {
14
- super(props);
15
- this.imageInput = null;
16
- const queryParams = new URLSearchParams(props.location.search);
17
- this.state = {
18
- feedId: Helper.safeReadParams(props, "feedId")
19
- ? props.match.params.feedId
20
- : null,
21
- feed: null,
22
- updating: false,
23
- types: [],
24
- users: [],
25
- photos: [],
26
- userSearch: "",
27
- userFilterOpen: false,
28
- selectedUser: null,
29
- id: null,
30
- userId: queryParams.get("userId") || "",
31
- userName: "",
32
- title: "",
33
- text: "",
34
- type: "",
35
- showWarnings: false,
36
- success: false,
37
- };
38
- }
39
-
40
- UNSAFE_componentWillMount() {
41
- Session.checkLoggedIn(this, this.props.auth);
42
- }
43
-
44
- componentDidMount() {
45
- this.getFeedTypes();
46
- this.getUsers();
47
- if (this.state.feedId) this.getFeed();
48
- }
49
-
50
- getFeed = async () => {
51
- try {
52
- const res = await feedActions.getFeed(this.state.feedId);
53
- // console.log('getFeed:', res.data);
54
- this.setState({
55
- ...res.data,
56
- selectedUser: res.data.user,
57
- userId: res.data.user.id,
58
- userName: res.data.user.displayName,
59
- });
60
- this.checkSetImages(res.data.photos);
61
- } catch (error) {
62
- console.error("getFeed", error);
63
- }
64
- };
65
-
66
- checkSetImages(photos) {
67
- if (this.imageInput) {
68
- if (!_.isEmpty(photos)) {
69
- this.imageInput.setValue(photos);
70
- }
71
- } else {
72
- setTimeout(() => {
73
- this.checkSetImages(photos);
74
- }, 100);
75
- }
76
- }
77
-
78
- getFeedTypes = async () => {
79
- try {
80
- const res = await feedActions.getFeedTypes(this.props.auth.site);
81
- this.setState({ types: res.data }, this.setDefaultFeedType);
82
- // if (res.data != null) this.props.feedTypesLoaded(res.data);
83
- } catch (error) {
84
- console.error("getFeedTypes", error);
85
- }
86
- };
87
-
88
- setDefaultFeedType = () => {
89
- const { types, feedId } = this.state;
90
- if (types.length !== 0 && feedId == null) {
91
- this.setState({ type: types[0].label });
92
- }
93
- };
94
-
95
- getUsers = async () => {
96
- try {
97
- const res = await userActions.fetchUsers(this.props.auth.site);
98
- if (res.userFetchFail) return;
99
- if (res.data != null && !_.isEmpty(res.data.results.Items)) {
100
- const items = res.data.results.Items;
101
- this.setState(
102
- {
103
- users: _.sortBy(items, (u) => {
104
- return (u.displayName || "").toLowerCase();
105
- }),
106
- },
107
- this.setDefaultUser,
108
- );
109
- }
110
- } catch (error) {
111
- console.error("getUsers", error);
112
- }
113
- };
114
-
115
- getUserId = (user) => user.userId || user.Id || user.id;
116
-
117
- setDefaultUser = () => {
118
- const { users, userId } = this.state;
119
- // console.log('setDefaultUser', { userId });
120
- if (userId) {
121
- const user = users.find((u) => this.getUserId(u) === userId);
122
- if (user) this.onSelectUser(user);
123
- } else {
124
- this.onUnselectUser();
125
- }
126
- };
127
-
128
- onSelectType = (key) => {
129
- this.setState({ type: key });
130
- };
131
-
132
- onHandleChange = (event) => {
133
- var stateChange = {};
134
- stateChange[event.target.getAttribute("id")] = event.target.value;
135
- this.setState(stateChange);
136
- };
137
-
138
- onOpenUserSelector = () => {
139
- this.setState({ userFilterOpen: true });
140
- };
141
-
142
- onCloseUserSelector = () => {
143
- this.setState({ userFilterOpen: false });
144
- };
145
-
146
- onSelectUser = (user) => {
147
- // console.log('onSelectUser', user);
148
- this.setState({
149
- selectedUser: user,
150
- userId: this.getUserId(user),
151
- userName: user.displayName,
152
- userFilterOpen: false,
153
- });
154
- };
155
-
156
- onUnselectUser = () => {
157
- this.setState({ selectedUser: null, userId: "", userName: "" });
158
- };
159
-
160
- onSave = async () => {
161
- try {
162
- this.setState({ showWarnings: false });
163
- if (!this.validateForm()) {
164
- this.setState({ showWarnings: true });
165
- return;
166
- }
167
- if (this.state.updating) return;
168
- this.setState({ updating: true });
169
- const feed = {
170
- id: this.state.id,
171
- userId: this.state.userId,
172
- type: this.state.type,
173
- title: this.state.title,
174
- text: this.state.text,
175
- photos: this.state.photos,
176
- site: this.props.auth.site,
177
- };
178
-
179
- if (this.state.id !== null) {
180
- await feedActions.editFeed(feed);
181
- this.setState({ success: true, updating: false });
182
- this.props.feedsLoaded([feed]);
183
- } else {
184
- await feedActions.createFeed(feed);
185
- this.setState({ success: true, updating: false });
186
- this.props.feedsUpdate(this.props.auth.site);
187
- }
188
- } catch (error) {
189
- this.setState({ updating: false });
190
- alert("Something went wrong with the request. Please try again.");
191
- }
192
- };
193
-
194
- renderSuccess() {
195
- if (!this.state.success) return null;
196
-
197
- const title =
198
- this.props.strings[`${values.featureKey}_textTitleFeeds`] ||
199
- values.textTitleFeeds;
200
- return (
201
- <Components.SuccessPopup
202
- text={`Feed has been ${this.state.id != null ? "edited" : "added"}`}
203
- buttons={[
204
- {
205
- type: "outlined",
206
- onClick: () => window.history.back(),
207
- text: `Back to ${title}`,
208
- },
209
- ]}
210
- />
211
- );
212
- }
213
-
214
- validateForm() {
215
- const { userId, userName, type, title } = this.state;
216
- // console.log('validateForm', { userId, userName, type, title });
217
-
218
- if (_.isEmpty(userId)) return false;
219
- if (_.isEmpty(userName)) return false;
220
- if (_.isEmpty(type)) return false;
221
- if (_.isEmpty(title)) return false;
222
- return true;
223
- }
224
-
225
- renderSubmit() {
226
- if (this.state.updating) {
227
- return (
228
- <Components.Button buttonType="secondary">Saving...</Components.Button>
229
- );
230
- }
231
-
232
- return (
233
- <div>
234
- <Components.Button
235
- inline
236
- buttonType="tertiary"
237
- onClick={() => this.props.history.push(values.routeHub)}
238
- isActive
239
- style={{ marginRight: 16 }}
240
- >
241
- Cancel
242
- </Components.Button>
243
- <Components.Button
244
- inline
245
- buttonType="primary"
246
- onClick={this.onSave}
247
- isActive={this.validateForm()}
248
- >
249
- Save
250
- </Components.Button>
251
- </div>
252
- );
253
- }
254
-
255
- renderSelectUser() {
256
- const { showWarnings, selectedUser } = this.state;
257
- const isValid = !_.isNil(selectedUser);
258
- const showError = showWarnings && !isValid;
259
-
260
- return (
261
- <div
262
- className={`genericInputContainer ${isValid ? "genericInput-valid" : ""} ${showError ? "genericInput-error" : ""}`.trim()}
263
- >
264
- <div
265
- style={{
266
- display: "flex",
267
- flexDirection: "row",
268
- alignItems: "center",
269
- marginBottom: 0,
270
- justifyContent: "space-between",
271
- }}
272
- >
273
- <div className="fieldLabel">Select User</div>
274
- {showError ? (
275
- <div className="fieldLabel fieldLabel-warning">Required</div>
276
- ) : null}
277
- </div>
278
- <div
279
- style={{
280
- display: "flex",
281
- flexDirection: "row",
282
- alignItems: "center",
283
- }}
284
- >
285
- <div className="inputRequired " />
286
- {selectedUser ? (
287
- <Components.Tag
288
- className="marginRight-10"
289
- rightIcon="close"
290
- rightClick={this.onUnselectUser}
291
- >
292
- <Components.UserListing
293
- size={15}
294
- user={selectedUser}
295
- textClass="tag_text"
296
- />
297
- </Components.Tag>
298
- ) : (
299
- <Components.Tag
300
- onClick={this.onOpenUserSelector}
301
- text="Select User"
302
- />
303
- )}
304
- </div>
305
- </div>
306
- );
307
- }
308
-
309
- renderTypeOptions() {
310
- const { showWarnings, types, type } = this.state;
311
- const isValid = !!type;
312
- const showError = showWarnings && !isValid;
313
-
314
- return (
315
- <div
316
- className={`genericInputContainer ${isValid ? "genericInput-valid" : ""} ${showError ? "genericInput-error" : ""}`.trim()}
317
- >
318
- <div
319
- style={{
320
- display: "flex",
321
- flexDirection: "row",
322
- alignItems: "center",
323
- marginBottom: 0,
324
- justifyContent: "space-between",
325
- }}
326
- >
327
- <Components.Text type="formLabel">Select Type</Components.Text>
328
- {showError ? (
329
- <div className="fieldLabel fieldLabel-warning">Required</div>
330
- ) : null}
331
- </div>
332
- <div className="marginTop-4">
333
- {types.map((ev) => {
334
- if (ev === null) return null;
335
- return (
336
- <Components.Tag
337
- key={ev.id}
338
- text={ev.label}
339
- style={{
340
- backgroundColor: ev.colour,
341
- borderRadius: 8,
342
- marginRight: 10,
343
- opacity: ev.label === type ? 1 : 0.5,
344
- }}
345
- onClick={() => this.onSelectType(ev.label)}
346
- />
347
- );
348
- })}
349
- </div>
350
- </div>
351
- );
352
- }
353
-
354
- renderMain() {
355
- return (
356
- <div style={{ marginBottom: 15 }}>
357
- <div className="padding-60 paddingVertical-40 bottomDivideBorder">
358
- <Components.Text type="formTitleLarge" className="marginBottom-24">
359
- {this.state.feedId == null ? "New" : "Edit"} Post
360
- </Components.Text>
361
- {/* Resident Information */}
362
- {this.renderSelectUser()}
363
- {this.renderTypeOptions()}
364
- <Components.GenericInput
365
- id="title"
366
- label="Title"
367
- type="textarea"
368
- placeholder="Title"
369
- value={this.state.title}
370
- onChange={(e) => this.onHandleChange(e)}
371
- inputStyle={{
372
- height: 80,
373
- }}
374
- isRequired
375
- isValid={() => {
376
- return !_.isEmpty(this.state.title);
377
- }}
378
- showError={() => {
379
- return this.state.showWarnings && _.isEmpty(this.state.title);
380
- }}
381
- alwaysShowLabel
382
- />
383
- <Components.GenericInput
384
- id="text"
385
- label="Text"
386
- type="textarea"
387
- placeholder="Text"
388
- value={this.state.text}
389
- onChange={(e) => this.onHandleChange(e)}
390
- inputStyle={{
391
- height: 80,
392
- }}
393
- alwaysShowLabel
394
- />
395
- <div className="marginBottom-16">
396
- <Components.Text type="formLabel" className="marginBottom-4">
397
- Images
398
- </Components.Text>
399
- <Components.ImageInput
400
- ref={(ref) => (this.imageInput = ref)}
401
- multiple
402
- refreshCallback={(photos) => this.setState({ photos })}
403
- />
404
- </div>
405
- </div>
406
- </div>
407
- );
408
- }
409
-
410
- renderUserFilterPopup() {
411
- const { userFilterOpen, userSearch, users } = this.state;
412
- if (!userFilterOpen) return null;
413
- return (
414
- <Components.Popup
415
- title="Select Requestor"
416
- maxWidth={600}
417
- minWidth={400}
418
- maxHeight={600}
419
- minHeight={600}
420
- hasPadding
421
- onClose={this.onCloseUserSelector}
422
- buttons={[
423
- {
424
- type: "tertiary",
425
- onClick: this.onCloseUserSelector,
426
- isActive: true,
427
- text: "Cancel",
428
- },
429
- ]}
430
- >
431
- <Components.GenericInput
432
- id="userSearch"
433
- type="text"
434
- label="Search User"
435
- placeholder="Search name"
436
- value={userSearch}
437
- onChange={(e) => this.onHandleChange(e)}
438
- alwaysShowLabel
439
- />
440
- {_.sortBy(users, (u) => u.displayName.toUpperCase())
441
- .filter((u) => {
442
- if (_.isEmpty(userSearch)) return true;
443
- return (
444
- u.displayName.toUpperCase().indexOf(userSearch.toUpperCase()) > -1
445
- );
446
- })
447
- .map((user) => {
448
- return (
449
- <Components.UserListing
450
- key={this.getUserId(user)}
451
- user={user}
452
- onClick={() => this.onSelectUser(user)}
453
- />
454
- );
455
- })}
456
- </Components.Popup>
457
- );
458
- }
459
-
460
- render() {
461
- const { success } = this.state;
462
-
463
- return (
464
- <Components.OverlayPage>
465
- <Components.OverlayPageContents noBottomButtons={success}>
466
- <Components.OverlayPageSection className="pageSectionWrapper--newPopup">
467
- <div>
468
- {this.renderSuccess()}
469
- {!success && this.renderMain()}
470
- </div>
471
- {this.renderUserFilterPopup()}
472
- </Components.OverlayPageSection>
473
- </Components.OverlayPageContents>
474
- <Components.OverlayPageBottomButtons>
475
- {this.renderSubmit()}
476
- </Components.OverlayPageBottomButtons>
477
- </Components.OverlayPage>
478
- );
479
- }
480
- }
481
-
482
- const mapStateToProps = (state) => {
483
- const { auth } = state;
484
- return { auth, strings: (state.strings && state.strings.config) || {} };
485
- };
486
-
487
- export default connect(mapStateToProps, { feedsUpdate, feedsLoaded })(
488
- withRouter(AddFeed),
489
- );