@plusscommunities/pluss-circles-web-groups 1.0.17 → 1.0.18
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.
- package/dist/index.cjs.js +347 -91
- package/dist/index.esm.js +347 -93
- package/dist/index.umd.js +349 -95
- package/package.json +5 -2
- package/src/apis/index.js +6 -0
- package/src/components/AnalyticsHub.js +214 -0
- package/src/index.js +2 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@plusscommunities/pluss-circles-web-groups",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.18",
|
|
4
4
|
"description": "Extension package to enable circles on Pluss Communities Platform",
|
|
5
5
|
"main": "dist/index.cjs.js",
|
|
6
6
|
"scripts": {
|
|
@@ -35,7 +35,10 @@
|
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"@babel/runtime": "^7.14.0",
|
|
38
|
-
"@plusscommunities/pluss-core-web": "1.4.
|
|
38
|
+
"@plusscommunities/pluss-core-web": "1.4.22",
|
|
39
|
+
"@fortawesome/fontawesome-svg-core": "^6.4.0",
|
|
40
|
+
"@fortawesome/free-solid-svg-icons": "^6.4.0",
|
|
41
|
+
"@fortawesome/react-fontawesome": "^0.2.0",
|
|
39
42
|
"lodash": "^4.17.4",
|
|
40
43
|
"moment": "^2.18.1",
|
|
41
44
|
"react": "^16.14.0",
|
package/src/apis/index.js
CHANGED
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import React, { useState, useEffect } from 'react';
|
|
2
|
+
import moment from 'moment';
|
|
3
|
+
import { faEye, faMessage, faPeopleArrows, faUserGroup, faUserTie, faUsers, faUsersRectangle } from '@fortawesome/free-solid-svg-icons';
|
|
4
|
+
import { connect } from 'react-redux';
|
|
5
|
+
import { analyticsActions } from '../apis';
|
|
6
|
+
import { values } from '../values.config';
|
|
7
|
+
import { PlussCore } from '../feature.config';
|
|
8
|
+
|
|
9
|
+
const { Analytics, Session, Components } = PlussCore;
|
|
10
|
+
|
|
11
|
+
const getInitialState = () => ({
|
|
12
|
+
isLoading: true,
|
|
13
|
+
messages: 0,
|
|
14
|
+
prevMessages: 0,
|
|
15
|
+
staffMessages: 0,
|
|
16
|
+
prevStaffMessages: 0,
|
|
17
|
+
residentMessages: 0,
|
|
18
|
+
prevResidentMessages: 0,
|
|
19
|
+
groupMessages: 0,
|
|
20
|
+
prevGroupMessages: 0,
|
|
21
|
+
privateMessages: 0,
|
|
22
|
+
prevPrivateMessages: 0,
|
|
23
|
+
activeGroups: 0,
|
|
24
|
+
prevActiveGroups: 0,
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
// AnalyticsHub Component
|
|
28
|
+
const AnalyticsHub = ({ startTime, endTime, auth, prevText, dayCount, strings }) => {
|
|
29
|
+
const [analyticsData, setAnalyticsData] = useState(getInitialState());
|
|
30
|
+
const [isExportOpen, setIsExportOpen] = useState(false);
|
|
31
|
+
|
|
32
|
+
const hasAccess = Session.validateAccess(auth.site, values.permissionNewsletter, auth);
|
|
33
|
+
if (!hasAccess) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const featureTitle = ((key) => {
|
|
38
|
+
if (!strings || !strings.sideNav || !strings.sideNav[key]) {
|
|
39
|
+
return values.textFeatureTitle;
|
|
40
|
+
}
|
|
41
|
+
return strings.sideNav[key];
|
|
42
|
+
})();
|
|
43
|
+
|
|
44
|
+
const exportColumns = [
|
|
45
|
+
{ label: 'Select All', key: '' },
|
|
46
|
+
{ label: 'Start Date', key: 'startDate' },
|
|
47
|
+
{ label: 'End Date', key: 'endDate' },
|
|
48
|
+
{ label: 'Messages', key: 'messages' },
|
|
49
|
+
{ label: 'Messages by Staff', key: 'staffMessages' },
|
|
50
|
+
{ label: 'Messages by Primary Users', key: 'residentMessages' },
|
|
51
|
+
{ label: 'Group Messages', key: 'groupMessages' },
|
|
52
|
+
{ label: 'Private Messages', key: 'privateMessages' },
|
|
53
|
+
{ label: 'Groups with Messages', key: 'activeGroups' },
|
|
54
|
+
];
|
|
55
|
+
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
getData();
|
|
58
|
+
}, [startTime, endTime]);
|
|
59
|
+
|
|
60
|
+
const getData = async () => {
|
|
61
|
+
setAnalyticsData(getInitialState());
|
|
62
|
+
// Load analytics data here using startTime and endTime
|
|
63
|
+
const timeDifference = endTime - startTime;
|
|
64
|
+
const [currentStatsResponse, prevStatsResponse] = await Promise.all([
|
|
65
|
+
analyticsActions.getAggregateEntityStats(auth.site, values.entityKey, startTime, endTime, true),
|
|
66
|
+
analyticsActions.getAggregateEntityStats(auth.site, values.entityKey, startTime - timeDifference, startTime, true),
|
|
67
|
+
]);
|
|
68
|
+
|
|
69
|
+
const data = {
|
|
70
|
+
messages: Analytics.countActivities(currentStatsResponse.data, 'Message', 'total'),
|
|
71
|
+
prevMessages: Analytics.countActivities(prevStatsResponse.data, 'Message', 'total'),
|
|
72
|
+
staffMessages: Analytics.countActivities(currentStatsResponse.data, 'StaffMessage', 'total'),
|
|
73
|
+
prevStaffMessages: Analytics.countActivities(prevStatsResponse.data, 'StaffMessage', 'total'),
|
|
74
|
+
residentMessages: Analytics.countActivities(currentStatsResponse.data, 'ResidentMessage', 'total'),
|
|
75
|
+
prevResidentMessages: Analytics.countActivities(prevStatsResponse.data, 'ResidentMessage', 'total'),
|
|
76
|
+
groupMessages: Analytics.countActivities(currentStatsResponse.data, 'GroupMessage', 'total'),
|
|
77
|
+
prevGroupMessages: Analytics.countActivities(prevStatsResponse.data, 'GroupMessage', 'total'),
|
|
78
|
+
privateMessages: Analytics.countActivities(currentStatsResponse.data, 'PrivateMessage', 'total'),
|
|
79
|
+
prevPrivateMessages: Analytics.countActivities(prevStatsResponse.data, 'PrivateMessage', 'total'),
|
|
80
|
+
activeGroups: Analytics.countActivities(currentStatsResponse.data, 'GroupMessage', 'unique'),
|
|
81
|
+
prevActiveGroups: Analytics.countActivities(prevStatsResponse.data, 'GroupMessage', 'unique'),
|
|
82
|
+
// uniquePageView: Analytics.countActivities(currentStatsResponse.data, 'UniquePageView', 'uniquearray'),
|
|
83
|
+
// prevUniquePageView: Analytics.countActivities(prevStatsResponse.data, 'UniquePageView', 'uniquearray'),
|
|
84
|
+
isLoading: false,
|
|
85
|
+
};
|
|
86
|
+
setAnalyticsData(data);
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const isReadyToOpenCSV = () => {
|
|
90
|
+
return !analyticsData.isLoading;
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const getExportSource = () => {
|
|
94
|
+
return [
|
|
95
|
+
{
|
|
96
|
+
startDate: moment(startTime + 1).format('D-MM-YYYY'),
|
|
97
|
+
endDate: moment(endTime).format('D-MM-YYYY'),
|
|
98
|
+
messages: analyticsData.messages,
|
|
99
|
+
staffMessages: analyticsData.staffMessages,
|
|
100
|
+
residentMessages: analyticsData.residentMessages,
|
|
101
|
+
groupMessages: analyticsData.groupMessages,
|
|
102
|
+
privateMessages: analyticsData.privateMessages,
|
|
103
|
+
activeGroups: analyticsData.activeGroups,
|
|
104
|
+
},
|
|
105
|
+
];
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
const csvPopup = () => {
|
|
109
|
+
if (!isExportOpen) {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
const source = getExportSource();
|
|
113
|
+
return (
|
|
114
|
+
<Components.ExportCsvPopup
|
|
115
|
+
onClose={() => {
|
|
116
|
+
setIsExportOpen(false);
|
|
117
|
+
}}
|
|
118
|
+
columns={exportColumns}
|
|
119
|
+
source={source}
|
|
120
|
+
filename={`${values.analyticsKey}analytics_${source[0].startDate}_${source[0].endDate}.csv`}
|
|
121
|
+
/>
|
|
122
|
+
);
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
return (
|
|
126
|
+
<div className="dashboardSection">
|
|
127
|
+
{csvPopup()}
|
|
128
|
+
<div>
|
|
129
|
+
<Components.Text type="h4" className="inlineBlock marginRight-40">
|
|
130
|
+
{featureTitle}
|
|
131
|
+
</Components.Text>
|
|
132
|
+
<Components.Button
|
|
133
|
+
inline
|
|
134
|
+
buttonType="primaryAction"
|
|
135
|
+
onClick={() => {
|
|
136
|
+
if (!isReadyToOpenCSV()) return;
|
|
137
|
+
setIsExportOpen(true);
|
|
138
|
+
}}
|
|
139
|
+
isActive={isReadyToOpenCSV()}
|
|
140
|
+
leftIcon="file-code-o"
|
|
141
|
+
>
|
|
142
|
+
Export CSV
|
|
143
|
+
</Components.Button>
|
|
144
|
+
</div>
|
|
145
|
+
<div className="analyticsSection dashboardSection_content">
|
|
146
|
+
<Components.StatBox
|
|
147
|
+
title="Groups with Messages"
|
|
148
|
+
icon={faUserGroup}
|
|
149
|
+
value={analyticsData.activeGroups}
|
|
150
|
+
previousValue={analyticsData.prevActiveGroups}
|
|
151
|
+
prevText={prevText}
|
|
152
|
+
viewGraphLink={`/chart?entity=${values.entityKey}&startTime=${startTime}&endTime=${endTime}&key=GroupMessage&countType=unique&dayCount=${dayCount}`}
|
|
153
|
+
isLoading={analyticsData.isLoading}
|
|
154
|
+
/>
|
|
155
|
+
<Components.StatBox
|
|
156
|
+
title="Messages"
|
|
157
|
+
icon={faMessage}
|
|
158
|
+
value={analyticsData.messages}
|
|
159
|
+
previousValue={analyticsData.prevMessages}
|
|
160
|
+
prevText={prevText}
|
|
161
|
+
viewGraphLink={`/chart?entity=${values.entityKey}&startTime=${startTime}&endTime=${endTime}&key=Message&countType=total&dayCount=${dayCount}`}
|
|
162
|
+
isLoading={analyticsData.isLoading}
|
|
163
|
+
/>
|
|
164
|
+
<Components.StatBox
|
|
165
|
+
title="Messages by Staff"
|
|
166
|
+
icon={faUserTie}
|
|
167
|
+
value={analyticsData.staffMessages}
|
|
168
|
+
previousValue={analyticsData.prevStaffMessages}
|
|
169
|
+
prevText={prevText}
|
|
170
|
+
viewGraphLink={`/chart?entity=${values.entityKey}&startTime=${startTime}&endTime=${endTime}&key=StaffMessage&countType=total&dayCount=${dayCount}`}
|
|
171
|
+
isLoading={analyticsData.isLoading}
|
|
172
|
+
/>
|
|
173
|
+
<Components.StatBox
|
|
174
|
+
title="Messages by Primary Users"
|
|
175
|
+
icon={faUsers}
|
|
176
|
+
value={analyticsData.residentMessages}
|
|
177
|
+
previousValue={analyticsData.prevResidentMessages}
|
|
178
|
+
prevText={prevText}
|
|
179
|
+
viewGraphLink={`/chart?entity=${values.entityKey}&startTime=${startTime}&endTime=${endTime}&key=ResidentMessage&countType=total&dayCount=${dayCount}`}
|
|
180
|
+
isLoading={analyticsData.isLoading}
|
|
181
|
+
/>
|
|
182
|
+
<Components.StatBox
|
|
183
|
+
title="Group Messages"
|
|
184
|
+
icon={faUsersRectangle}
|
|
185
|
+
value={analyticsData.groupMessages}
|
|
186
|
+
previousValue={analyticsData.prevGroupMessages}
|
|
187
|
+
prevText={prevText}
|
|
188
|
+
viewGraphLink={`/chart?entity=${values.entityKey}&startTime=${startTime}&endTime=${endTime}&key=GroupMessage&countType=total&dayCount=${dayCount}`}
|
|
189
|
+
isLoading={analyticsData.isLoading}
|
|
190
|
+
/>
|
|
191
|
+
<Components.StatBox
|
|
192
|
+
title="Private Messages"
|
|
193
|
+
icon={faPeopleArrows}
|
|
194
|
+
value={analyticsData.privateMessages}
|
|
195
|
+
previousValue={analyticsData.prevPrivateMessages}
|
|
196
|
+
prevText={prevText}
|
|
197
|
+
viewGraphLink={`/chart?entity=${values.entityKey}&startTime=${startTime}&endTime=${endTime}&key=PrivateMessage&countType=total&dayCount=${dayCount}`}
|
|
198
|
+
isLoading={analyticsData.isLoading}
|
|
199
|
+
/>
|
|
200
|
+
</div>
|
|
201
|
+
</div>
|
|
202
|
+
);
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
const mapStateToProps = (state) => {
|
|
206
|
+
const { auth } = state;
|
|
207
|
+
return {
|
|
208
|
+
auth,
|
|
209
|
+
strings: (state.strings && state.strings.config) || {},
|
|
210
|
+
};
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
const toExport = connect(mapStateToProps, {})(AnalyticsHub);
|
|
214
|
+
export { toExport as AnalyticsHub };
|
package/src/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import Circles from './screens/Circles';
|
|
2
2
|
import AddCircle from './screens/AddCircle';
|
|
3
3
|
import Circle from './screens/Circle';
|
|
4
|
+
import { AnalyticsHub } from './components/AnalyticsHub.js';
|
|
4
5
|
import CircleReducer from './reducers/CircleReducer';
|
|
5
6
|
import { values } from './values.config';
|
|
6
7
|
|
|
@@ -13,3 +14,4 @@ export { default as PreviewWidget } from './components/PreviewWidget';
|
|
|
13
14
|
export { default as PreviewFull } from './components/PreviewFull';
|
|
14
15
|
export { default as PreviewGrid } from './components/PreviewGrid';
|
|
15
16
|
export { default as FeaturePickerContent } from './components/FeaturePickerContent';
|
|
17
|
+
export const Analytics = [AnalyticsHub];
|