@plusscommunities/pluss-circles-web-groups 1.5.7-beta.0 → 1.5.7-beta.2
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 +209 -53
- package/dist/index.esm.js +209 -53
- package/dist/index.umd.js +209 -53
- package/package.json +1 -1
- package/src/apis/circleActions.js +10 -0
- package/src/screens/Circle.js +9 -0
- package/src/screens/Circles.js +92 -3
- package/src/screens/Circles.module.css +96 -0
package/src/screens/Circles.js
CHANGED
|
@@ -9,6 +9,7 @@ import { circleActions } from "../apis";
|
|
|
9
9
|
import { Table } from "react-bootstrap";
|
|
10
10
|
import FontAwesome from "react-fontawesome";
|
|
11
11
|
import { values } from "../values.config";
|
|
12
|
+
import badgeStyles from "./Circles.module.css";
|
|
12
13
|
|
|
13
14
|
const { Components, Session, Helper } = PlussCore;
|
|
14
15
|
|
|
@@ -18,11 +19,17 @@ class Circles extends Component {
|
|
|
18
19
|
this.state = {
|
|
19
20
|
userSearch: "",
|
|
20
21
|
sortBy: "newest",
|
|
22
|
+
showUnreadOnly: false,
|
|
23
|
+
pollingInterval: null,
|
|
21
24
|
};
|
|
22
25
|
}
|
|
23
26
|
|
|
24
27
|
componentDidMount() {
|
|
25
28
|
this.getData();
|
|
29
|
+
// Poll for updates every 10 seconds
|
|
30
|
+
this.pollingInterval = setInterval(() => {
|
|
31
|
+
this.getData();
|
|
32
|
+
}, 10000);
|
|
26
33
|
}
|
|
27
34
|
|
|
28
35
|
getData = () => {
|
|
@@ -40,6 +47,31 @@ class Circles extends Component {
|
|
|
40
47
|
});
|
|
41
48
|
};
|
|
42
49
|
|
|
50
|
+
componentWillUnmount() {
|
|
51
|
+
if (this.pollingInterval) {
|
|
52
|
+
clearInterval(this.pollingInterval);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
isCircleUnread(circle) {
|
|
57
|
+
const userId = this.props.user.Id;
|
|
58
|
+
if (!circle.Unread || !circle.Unread[userId]) {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
return circle.Unread[userId] > 0;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
getUnreadCount(circle) {
|
|
65
|
+
const userId = this.props.user.Id;
|
|
66
|
+
if (!circle.Unread || !circle.Unread[userId]) {
|
|
67
|
+
return 0;
|
|
68
|
+
}
|
|
69
|
+
return circle.Unread[userId];
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
selectUnreadFilter = (showUnreadOnly) => {
|
|
73
|
+
this.setState({ showUnreadOnly });
|
|
74
|
+
};
|
|
43
75
|
getCircles() {
|
|
44
76
|
let result = this.props.circles;
|
|
45
77
|
if (this.state.selectedTypeFilter) {
|
|
@@ -62,6 +94,11 @@ class Circles extends Component {
|
|
|
62
94
|
});
|
|
63
95
|
if (this.state.sortBy === "newest") {
|
|
64
96
|
result.reverse();
|
|
97
|
+
if (this.state.showUnreadOnly) {
|
|
98
|
+
result = _.filter(result, (circle) => {
|
|
99
|
+
return this.isCircleUnread(circle);
|
|
100
|
+
});
|
|
101
|
+
}
|
|
65
102
|
}
|
|
66
103
|
return result;
|
|
67
104
|
}
|
|
@@ -223,12 +260,23 @@ class Circles extends Component {
|
|
|
223
260
|
};
|
|
224
261
|
|
|
225
262
|
renderRow(circle) {
|
|
263
|
+
const unreadCount = this.getUnreadCount(circle);
|
|
264
|
+
const badge = unreadCount > 0 ? (
|
|
265
|
+
<Components.Tag
|
|
266
|
+
className={badgeStyles.badgeTag}
|
|
267
|
+
text={`${unreadCount} new`}
|
|
268
|
+
/>
|
|
269
|
+
) : null;
|
|
270
|
+
|
|
226
271
|
return (
|
|
227
272
|
<tr key={circle.Id}>
|
|
228
273
|
<td className="table-TitleColumn">
|
|
229
|
-
<
|
|
230
|
-
{
|
|
231
|
-
|
|
274
|
+
<div className="flex flex-center" style={{ gap: "8px" }}>
|
|
275
|
+
<Link to={`/${values.featureKey}/${values.entityKey}/${circle.Id}`}>
|
|
276
|
+
{this.getTitle(circle)}
|
|
277
|
+
</Link>
|
|
278
|
+
{badge}
|
|
279
|
+
</div>
|
|
232
280
|
</td>
|
|
233
281
|
<td>{moment(circle.Changed).local().format("D MMM YYYY")}</td>
|
|
234
282
|
<td>
|
|
@@ -281,6 +329,35 @@ class Circles extends Component {
|
|
|
281
329
|
);
|
|
282
330
|
}
|
|
283
331
|
|
|
332
|
+
renderUnreadFilterInfo() {
|
|
333
|
+
const { showUnreadOnly } = this.state;
|
|
334
|
+
|
|
335
|
+
if (!showUnreadOnly) {
|
|
336
|
+
return null;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
return (
|
|
340
|
+
<div className={badgeStyles.unreadFilterBanner}>
|
|
341
|
+
<div className={badgeStyles.unreadFilterContent}>
|
|
342
|
+
<FontAwesome
|
|
343
|
+
name="info-circle"
|
|
344
|
+
className={badgeStyles.unreadFilterIcon}
|
|
345
|
+
/>
|
|
346
|
+
<span className={badgeStyles.unreadFilterText}>
|
|
347
|
+
Showing only items with new messages.{" "}
|
|
348
|
+
<button
|
|
349
|
+
className={badgeStyles.unreadFilterButton}
|
|
350
|
+
onClick={() => this.selectUnreadFilter(false)}
|
|
351
|
+
aria-label="Turn off unread filter"
|
|
352
|
+
>
|
|
353
|
+
Turn off filter
|
|
354
|
+
</button>
|
|
355
|
+
</span>
|
|
356
|
+
</div>
|
|
357
|
+
</div>
|
|
358
|
+
);
|
|
359
|
+
}
|
|
360
|
+
|
|
284
361
|
renderFilters() {
|
|
285
362
|
let userFilter = (
|
|
286
363
|
<Components.Tag
|
|
@@ -289,6 +366,16 @@ class Circles extends Component {
|
|
|
289
366
|
text="User"
|
|
290
367
|
/>
|
|
291
368
|
);
|
|
369
|
+
|
|
370
|
+
let unreadFilter = (
|
|
371
|
+
<Components.Tag
|
|
372
|
+
className="marginRight-10"
|
|
373
|
+
onClick={() => this.selectUnreadFilter(!this.state.showUnreadOnly)}
|
|
374
|
+
leftIcon={this.state.showUnreadOnly ? "check" : null}
|
|
375
|
+
text="Unread Only"
|
|
376
|
+
/>
|
|
377
|
+
);
|
|
378
|
+
|
|
292
379
|
let typeFilter = (
|
|
293
380
|
<Components.Tag
|
|
294
381
|
className="marginRight-10"
|
|
@@ -331,6 +418,7 @@ class Circles extends Component {
|
|
|
331
418
|
</Components.Text>
|
|
332
419
|
{userFilter}
|
|
333
420
|
{typeFilter}
|
|
421
|
+
{unreadFilter}
|
|
334
422
|
<Components.Text type="h5" className="marginRight-20 marginLeft-20">
|
|
335
423
|
Sort by:
|
|
336
424
|
</Components.Text>
|
|
@@ -433,6 +521,7 @@ class Circles extends Component {
|
|
|
433
521
|
{values.textFeatureTitle}
|
|
434
522
|
</Components.Text>
|
|
435
523
|
{this.renderFilters()}
|
|
524
|
+
{this.renderUnreadFilterInfo()}
|
|
436
525
|
|
|
437
526
|
<Table
|
|
438
527
|
className="plussTable"
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/* Badge styling for unread count */
|
|
2
|
+
:root {
|
|
3
|
+
--badge-bg-color: #597db4; /* COLOUR_BRANDING_OFF */
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.badgeTag {
|
|
7
|
+
font-size: 11px;
|
|
8
|
+
font-weight: 400;
|
|
9
|
+
padding: 3px 10px;
|
|
10
|
+
background-color: var(--badge-bg-color) !important;
|
|
11
|
+
color: #fff !important;
|
|
12
|
+
border-radius: 999px !important;
|
|
13
|
+
border: none !important;
|
|
14
|
+
display: inline-flex;
|
|
15
|
+
align-items: center;
|
|
16
|
+
justify-content: center;
|
|
17
|
+
line-height: 1;
|
|
18
|
+
letter-spacing: 0.02em;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/* Unread filter info banner */
|
|
22
|
+
.unreadFilterBanner {
|
|
23
|
+
background-color: #f0f4f8;
|
|
24
|
+
border-left: 3px solid var(--badge-bg-color);
|
|
25
|
+
border-radius: 4px;
|
|
26
|
+
padding: 12px 16px;
|
|
27
|
+
margin-top: 16px;
|
|
28
|
+
margin-bottom: 16px;
|
|
29
|
+
display: flex;
|
|
30
|
+
align-items: center;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.unreadFilterContent {
|
|
34
|
+
display: flex;
|
|
35
|
+
align-items: center;
|
|
36
|
+
gap: 10px;
|
|
37
|
+
width: 100%;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.unreadFilterIcon {
|
|
41
|
+
font-size: 16px;
|
|
42
|
+
color: var(--badge-bg-color);
|
|
43
|
+
flex-shrink: 0;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.unreadFilterText {
|
|
47
|
+
font-size: 14px;
|
|
48
|
+
line-height: 1.5;
|
|
49
|
+
color: #333333;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.unreadFilterButton {
|
|
53
|
+
background: none;
|
|
54
|
+
border: none;
|
|
55
|
+
color: var(--badge-bg-color);
|
|
56
|
+
font-size: 14px;
|
|
57
|
+
font-weight: 500;
|
|
58
|
+
text-decoration: underline;
|
|
59
|
+
cursor: pointer;
|
|
60
|
+
padding: 4px 8px;
|
|
61
|
+
margin-left: 4px;
|
|
62
|
+
min-height: 32px;
|
|
63
|
+
min-width: 32px;
|
|
64
|
+
transition: all 0.2s ease;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.unreadFilterButton:hover {
|
|
68
|
+
background-color: rgba(89, 125, 180, 0.1);
|
|
69
|
+
text-decoration: none;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.unreadFilterButton:focus {
|
|
73
|
+
outline: 2px solid var(--badge-bg-color);
|
|
74
|
+
outline-offset: 2px;
|
|
75
|
+
border-radius: 2px;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/* Mobile responsiveness */
|
|
79
|
+
@media (max-width: 768px) {
|
|
80
|
+
.unreadFilterBanner {
|
|
81
|
+
flex-direction: column;
|
|
82
|
+
align-items: flex-start;
|
|
83
|
+
padding: 12px;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.unreadFilterContent {
|
|
87
|
+
flex-direction: column;
|
|
88
|
+
align-items: flex-start;
|
|
89
|
+
gap: 8px;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.unreadFilterText {
|
|
93
|
+
font-size: 13px;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|