@selfcommunity/react-ui 0.7.9-alpha.7 → 0.7.9-alpha.71
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/lib/cjs/components/AccountRecover/AccountRecover.js +6 -1
- package/lib/cjs/components/BottomNavigation/BottomNavigation.js +4 -3
- package/lib/cjs/components/CategoryHeader/Skeleton.js +3 -2
- package/lib/cjs/components/ChangeGroupPicture/ChangeGroupPicture.js +13 -10
- package/lib/cjs/components/Composer/Attributes/Attributes.js +3 -3
- package/lib/cjs/components/Composer/Composer.js +3 -3
- package/lib/cjs/components/Composer/Layer/AudienceLayer/AudienceLayer.d.ts +1 -1
- package/lib/cjs/components/Composer/Layer/AudienceLayer/AudienceLayer.js +9 -19
- package/lib/cjs/components/FeedObject/Contributors/Contributors.js +1 -1
- package/lib/cjs/components/FeedObject/FeedObject.d.ts +1 -0
- package/lib/cjs/components/FeedObject/FeedObject.js +27 -8
- package/lib/cjs/components/FeedObject/Poll/Poll.js +20 -20
- package/lib/cjs/components/FeedUpdatesWidget/FeedUpdatesWidget.js +1 -1
- package/lib/cjs/components/Group/Group.d.ts +8 -0
- package/lib/cjs/components/Group/Group.js +17 -5
- package/lib/cjs/components/GroupAutocomplete/GroupAutocomplete.js +1 -1
- package/lib/cjs/components/GroupForm/GroupForm.js +64 -13
- package/lib/cjs/components/GroupHeader/GroupHeader.d.ts +6 -5
- package/lib/cjs/components/GroupHeader/GroupHeader.js +53 -11
- package/lib/cjs/components/GroupInfoWidget/GroupInfoWidget.js +63 -9
- package/lib/cjs/components/GroupInviteButton/GroupInviteButton.js +31 -9
- package/lib/cjs/components/GroupInvitedWidget/GroupInvitedWidget.d.ts +74 -0
- package/lib/cjs/components/GroupInvitedWidget/GroupInvitedWidget.js +221 -0
- package/lib/cjs/components/GroupInvitedWidget/Skeleton.d.ts +22 -0
- package/lib/cjs/components/GroupInvitedWidget/Skeleton.js +38 -0
- package/lib/cjs/components/GroupInvitedWidget/constants.d.ts +1 -0
- package/lib/cjs/components/GroupInvitedWidget/constants.js +4 -0
- package/lib/cjs/components/GroupInvitedWidget/index.d.ts +4 -0
- package/lib/cjs/components/GroupInvitedWidget/index.js +8 -0
- package/lib/cjs/components/GroupMembersButton/GroupMembersButton.d.ts +5 -0
- package/lib/cjs/components/GroupMembersButton/GroupMembersButton.js +8 -3
- package/lib/cjs/components/GroupMembersWidget/GroupMembersWidget.js +25 -4
- package/lib/cjs/components/GroupRequestsWidget/GroupRequestsWidget.d.ts +11 -5
- package/lib/cjs/components/GroupRequestsWidget/GroupRequestsWidget.js +18 -7
- package/lib/cjs/components/GroupSettingsIconButton/GroupSettingsIconButton.d.ts +48 -0
- package/lib/cjs/components/GroupSettingsIconButton/GroupSettingsIconButton.js +151 -0
- package/lib/cjs/components/GroupSettingsIconButton/index.d.ts +3 -0
- package/lib/cjs/components/GroupSettingsIconButton/index.js +5 -0
- package/lib/cjs/components/GroupSubscribeButton/GroupSubscribeButton.d.ts +8 -3
- package/lib/cjs/components/GroupSubscribeButton/GroupSubscribeButton.js +30 -11
- package/lib/cjs/components/Groups/Groups.d.ts +15 -8
- package/lib/cjs/components/Groups/Groups.js +86 -32
- package/lib/cjs/components/Groups/Skeleton.d.ts +4 -0
- package/lib/cjs/components/Groups/Skeleton.js +2 -2
- package/lib/cjs/components/InlineComposerWidget/InlineComposerWidget.js +7 -0
- package/lib/cjs/components/NavigationMenuIconButton/NavigationMenuIconButton.js +1 -1
- package/lib/cjs/components/NavigationSettingsIconButton/NavigationSettingsIconButton.js +4 -4
- package/lib/cjs/components/NavigationToolbar/NavigationToolbar.js +6 -2
- package/lib/cjs/components/NavigationToolbarMobile/NavigationToolbarMobile.d.ts +5 -0
- package/lib/cjs/components/NavigationToolbarMobile/NavigationToolbarMobile.js +11 -4
- package/lib/cjs/components/Notification/Group/Group.d.ts +15 -0
- package/lib/cjs/components/Notification/Group/Group.js +78 -0
- package/lib/cjs/components/Notification/Group/index.d.ts +3 -0
- package/lib/cjs/components/Notification/Group/index.js +5 -0
- package/lib/cjs/components/Notification/Notification.js +31 -1
- package/lib/cjs/components/Notification/PrivateMessage/PrivateMessage.js +16 -5
- package/lib/cjs/components/PrivateMessageComponent/PrivateMessageComponent.d.ts +1 -1
- package/lib/cjs/components/PrivateMessageComponent/PrivateMessageComponent.js +12 -7
- package/lib/cjs/components/PrivateMessageSettingsIconButton/PrivateMessageSettingsIconButton.js +1 -1
- package/lib/cjs/components/PrivateMessageSnippetItem/PrivateMessageSnippetItem.js +11 -6
- package/lib/cjs/components/PrivateMessageSnippets/PrivateMessageSnippets.d.ts +3 -3
- package/lib/cjs/components/PrivateMessageSnippets/PrivateMessageSnippets.js +24 -6
- package/lib/cjs/components/PrivateMessageThread/PrivateMessageThread.d.ts +6 -1
- package/lib/cjs/components/PrivateMessageThread/PrivateMessageThread.js +45 -20
- package/lib/cjs/components/PrivateMessageThreadItem/PrivateMessageThreadItem.js +6 -0
- package/lib/cjs/components/SearchAutocomplete/SearchAutocomplete.js +22 -5
- package/lib/cjs/components/SnippetNotifications/SnippetNotifications.js +7 -0
- package/lib/cjs/components/ToastNotifications/ToastNotifications.js +7 -0
- package/lib/cjs/components/User/User.d.ts +6 -1
- package/lib/cjs/components/User/User.js +5 -4
- package/lib/cjs/components/UserSubscribedGroupsWidget/Skeleton.d.ts +21 -0
- package/lib/cjs/components/UserSubscribedGroupsWidget/Skeleton.js +46 -0
- package/lib/cjs/components/UserSubscribedGroupsWidget/UserSubscribedGroupsWidget.d.ts +68 -0
- package/lib/cjs/components/UserSubscribedGroupsWidget/UserSubscribedGroupsWidget.js +183 -0
- package/lib/cjs/components/UserSubscribedGroupsWidget/constants.d.ts +1 -0
- package/lib/cjs/components/UserSubscribedGroupsWidget/constants.js +4 -0
- package/lib/cjs/components/UserSubscribedGroupsWidget/index.d.ts +4 -0
- package/lib/cjs/components/UserSubscribedGroupsWidget/index.js +8 -0
- package/lib/cjs/components/VoteAudienceButton/VoteAudienceButton.js +1 -1
- package/lib/cjs/constants/PubSub.d.ts +28 -0
- package/lib/cjs/constants/PubSub.js +22 -0
- package/lib/cjs/index.d.ts +6 -2
- package/lib/cjs/index.js +15 -4
- package/lib/esm/components/AccountRecover/AccountRecover.js +6 -1
- package/lib/esm/components/BottomNavigation/BottomNavigation.js +5 -4
- package/lib/esm/components/CategoryHeader/Skeleton.js +3 -2
- package/lib/esm/components/ChangeGroupPicture/ChangeGroupPicture.js +13 -10
- package/lib/esm/components/Composer/Attributes/Attributes.js +3 -3
- package/lib/esm/components/Composer/Composer.js +3 -3
- package/lib/esm/components/Composer/Layer/AudienceLayer/AudienceLayer.d.ts +1 -1
- package/lib/esm/components/Composer/Layer/AudienceLayer/AudienceLayer.js +9 -19
- package/lib/esm/components/FeedObject/Contributors/Contributors.js +1 -1
- package/lib/esm/components/FeedObject/FeedObject.d.ts +1 -0
- package/lib/esm/components/FeedObject/FeedObject.js +28 -9
- package/lib/esm/components/FeedObject/Poll/Poll.js +20 -20
- package/lib/esm/components/FeedUpdatesWidget/FeedUpdatesWidget.js +1 -1
- package/lib/esm/components/Group/Group.d.ts +8 -0
- package/lib/esm/components/Group/Group.js +21 -9
- package/lib/esm/components/GroupAutocomplete/GroupAutocomplete.js +1 -1
- package/lib/esm/components/GroupForm/GroupForm.js +64 -13
- package/lib/esm/components/GroupHeader/GroupHeader.d.ts +6 -5
- package/lib/esm/components/GroupHeader/GroupHeader.js +55 -13
- package/lib/esm/components/GroupInfoWidget/GroupInfoWidget.js +63 -9
- package/lib/esm/components/GroupInviteButton/GroupInviteButton.js +31 -9
- package/lib/esm/components/GroupInvitedWidget/GroupInvitedWidget.d.ts +74 -0
- package/lib/esm/components/GroupInvitedWidget/GroupInvitedWidget.js +218 -0
- package/lib/esm/components/GroupInvitedWidget/Skeleton.d.ts +22 -0
- package/lib/esm/components/GroupInvitedWidget/Skeleton.js +34 -0
- package/lib/esm/components/GroupInvitedWidget/constants.d.ts +1 -0
- package/lib/esm/components/GroupInvitedWidget/constants.js +1 -0
- package/lib/esm/components/GroupInvitedWidget/index.d.ts +4 -0
- package/lib/esm/components/GroupInvitedWidget/index.js +4 -0
- package/lib/esm/components/GroupMembersButton/GroupMembersButton.d.ts +5 -0
- package/lib/esm/components/GroupMembersButton/GroupMembersButton.js +9 -4
- package/lib/esm/components/GroupMembersWidget/GroupMembersWidget.js +26 -5
- package/lib/esm/components/GroupRequestsWidget/GroupRequestsWidget.d.ts +11 -5
- package/lib/esm/components/GroupRequestsWidget/GroupRequestsWidget.js +18 -7
- package/lib/esm/components/GroupSettingsIconButton/GroupSettingsIconButton.d.ts +48 -0
- package/lib/esm/components/GroupSettingsIconButton/GroupSettingsIconButton.js +148 -0
- package/lib/esm/components/GroupSettingsIconButton/index.d.ts +3 -0
- package/lib/esm/components/GroupSettingsIconButton/index.js +2 -0
- package/lib/esm/components/GroupSubscribeButton/GroupSubscribeButton.d.ts +8 -3
- package/lib/esm/components/GroupSubscribeButton/GroupSubscribeButton.js +30 -11
- package/lib/esm/components/Groups/Groups.d.ts +15 -8
- package/lib/esm/components/Groups/Groups.js +91 -37
- package/lib/esm/components/Groups/Skeleton.d.ts +4 -0
- package/lib/esm/components/Groups/Skeleton.js +2 -2
- package/lib/esm/components/InlineComposerWidget/InlineComposerWidget.js +9 -2
- package/lib/esm/components/NavigationMenuIconButton/NavigationMenuIconButton.js +1 -1
- package/lib/esm/components/NavigationSettingsIconButton/NavigationSettingsIconButton.js +4 -4
- package/lib/esm/components/NavigationToolbar/NavigationToolbar.js +7 -3
- package/lib/esm/components/NavigationToolbarMobile/NavigationToolbarMobile.d.ts +5 -0
- package/lib/esm/components/NavigationToolbarMobile/NavigationToolbarMobile.js +13 -6
- package/lib/esm/components/Notification/Group/Group.d.ts +15 -0
- package/lib/esm/components/Notification/Group/Group.js +75 -0
- package/lib/esm/components/Notification/Group/index.d.ts +3 -0
- package/lib/esm/components/Notification/Group/index.js +2 -0
- package/lib/esm/components/Notification/Notification.js +31 -1
- package/lib/esm/components/Notification/PrivateMessage/PrivateMessage.js +16 -5
- package/lib/esm/components/PrivateMessageComponent/PrivateMessageComponent.d.ts +1 -1
- package/lib/esm/components/PrivateMessageComponent/PrivateMessageComponent.js +13 -8
- package/lib/esm/components/PrivateMessageSettingsIconButton/PrivateMessageSettingsIconButton.js +1 -1
- package/lib/esm/components/PrivateMessageSnippetItem/PrivateMessageSnippetItem.js +11 -6
- package/lib/esm/components/PrivateMessageSnippets/PrivateMessageSnippets.d.ts +3 -3
- package/lib/esm/components/PrivateMessageSnippets/PrivateMessageSnippets.js +26 -8
- package/lib/esm/components/PrivateMessageThread/PrivateMessageThread.d.ts +6 -1
- package/lib/esm/components/PrivateMessageThread/PrivateMessageThread.js +47 -22
- package/lib/esm/components/PrivateMessageThreadItem/PrivateMessageThreadItem.js +7 -1
- package/lib/esm/components/SearchAutocomplete/SearchAutocomplete.js +22 -5
- package/lib/esm/components/SnippetNotifications/SnippetNotifications.js +7 -0
- package/lib/esm/components/ToastNotifications/ToastNotifications.js +7 -0
- package/lib/esm/components/User/User.d.ts +6 -1
- package/lib/esm/components/User/User.js +5 -4
- package/lib/esm/components/UserSubscribedGroupsWidget/Skeleton.d.ts +21 -0
- package/lib/esm/components/UserSubscribedGroupsWidget/Skeleton.js +42 -0
- package/lib/esm/components/UserSubscribedGroupsWidget/UserSubscribedGroupsWidget.d.ts +68 -0
- package/lib/esm/components/UserSubscribedGroupsWidget/UserSubscribedGroupsWidget.js +180 -0
- package/lib/esm/components/UserSubscribedGroupsWidget/constants.d.ts +1 -0
- package/lib/esm/components/UserSubscribedGroupsWidget/constants.js +1 -0
- package/lib/esm/components/UserSubscribedGroupsWidget/index.d.ts +4 -0
- package/lib/esm/components/UserSubscribedGroupsWidget/index.js +4 -0
- package/lib/esm/components/VoteAudienceButton/VoteAudienceButton.js +1 -1
- package/lib/esm/constants/PubSub.d.ts +28 -0
- package/lib/esm/constants/PubSub.js +19 -0
- package/lib/esm/index.d.ts +6 -2
- package/lib/esm/index.js +8 -4
- package/lib/umd/react-ui.js +1 -1
- package/package.json +6 -6
|
@@ -9,6 +9,8 @@ import { FormattedMessage } from 'react-intl';
|
|
|
9
9
|
import classNames from 'classnames';
|
|
10
10
|
import { useThemeProps } from '@mui/system';
|
|
11
11
|
import { SCOPE_SC_UI } from '../../constants/Errors';
|
|
12
|
+
import { SCEventType, SCTopicType } from '../../constants/PubSub';
|
|
13
|
+
import PubSub from 'pubsub-js';
|
|
12
14
|
const PREFIX = 'SCGroupSubscribeButton';
|
|
13
15
|
const classes = {
|
|
14
16
|
root: `${PREFIX}-root`
|
|
@@ -47,7 +49,7 @@ export default function GroupSubscribeButton(inProps) {
|
|
|
47
49
|
props: inProps,
|
|
48
50
|
name: PREFIX
|
|
49
51
|
});
|
|
50
|
-
const { className, groupId, group,
|
|
52
|
+
const { className, groupId, group, user, onSubscribe } = props, rest = __rest(props, ["className", "groupId", "group", "user", "onSubscribe"]);
|
|
51
53
|
// STATE
|
|
52
54
|
const [status, setStatus] = useState(null);
|
|
53
55
|
// CONTEXT
|
|
@@ -61,7 +63,7 @@ export default function GroupSubscribeButton(inProps) {
|
|
|
61
63
|
group,
|
|
62
64
|
cacheStrategy: authUserId ? CacheStrategies.CACHE_FIRST : CacheStrategies.STALE_WHILE_REVALIDATE
|
|
63
65
|
});
|
|
64
|
-
const
|
|
66
|
+
const isGroupAdmin = useMemo(() => { var _a; return scUserContext.user && ((_a = scGroup === null || scGroup === void 0 ? void 0 : scGroup.managed_by) === null || _a === void 0 ? void 0 : _a.id) === scUserContext.user.id; }, [scUserContext.user, (_a = scGroup === null || scGroup === void 0 ? void 0 : scGroup.managed_by) === null || _a === void 0 ? void 0 : _a.id]);
|
|
65
67
|
useEffect(() => {
|
|
66
68
|
/**
|
|
67
69
|
* Call scGroupsManager.subscriptionStatus inside an effect
|
|
@@ -71,11 +73,25 @@ export default function GroupSubscribeButton(inProps) {
|
|
|
71
73
|
setStatus(scGroupsManager.subscriptionStatus(scGroup));
|
|
72
74
|
}
|
|
73
75
|
}, [authUserId, scGroupsManager.subscriptionStatus]);
|
|
74
|
-
|
|
76
|
+
/**
|
|
77
|
+
* Notify UI when a member is added to a group
|
|
78
|
+
* @param group
|
|
79
|
+
* @param user
|
|
80
|
+
*/
|
|
81
|
+
function notifyChanges(group, user) {
|
|
82
|
+
if (group && user) {
|
|
83
|
+
PubSub.publish(`${SCTopicType.GROUP}.${SCEventType.ADD_MEMBER}`, { group, user });
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
const subscribe = (user) => {
|
|
75
87
|
scGroupsManager
|
|
76
|
-
.subscribe(scGroup)
|
|
88
|
+
.subscribe(scGroup, user === null || user === void 0 ? void 0 : user.id)
|
|
77
89
|
.then(() => {
|
|
78
|
-
|
|
90
|
+
const _status = scGroup.privacy === SCGroupPrivacyType.PRIVATE && scGroup.subscription_status !== SCGroupSubscriptionStatusType.INVITED
|
|
91
|
+
? SCGroupSubscriptionStatusType.REQUESTED
|
|
92
|
+
: SCGroupSubscriptionStatusType.SUBSCRIBED;
|
|
93
|
+
notifyChanges(scGroup, user);
|
|
94
|
+
onSubscribe && onSubscribe(scGroup, _status);
|
|
79
95
|
})
|
|
80
96
|
.catch((e) => {
|
|
81
97
|
Logger.error(SCOPE_SC_UI, e);
|
|
@@ -85,7 +101,7 @@ export default function GroupSubscribeButton(inProps) {
|
|
|
85
101
|
scGroupsManager
|
|
86
102
|
.unsubscribe(scGroup)
|
|
87
103
|
.then(() => {
|
|
88
|
-
|
|
104
|
+
onSubscribe && onSubscribe(scGroup, null);
|
|
89
105
|
})
|
|
90
106
|
.catch((e) => {
|
|
91
107
|
Logger.error(SCOPE_SC_UI, e);
|
|
@@ -96,7 +112,7 @@ export default function GroupSubscribeButton(inProps) {
|
|
|
96
112
|
scContext.settings.handleAnonymousAction();
|
|
97
113
|
}
|
|
98
114
|
else {
|
|
99
|
-
SCGroupSubscriptionStatusType.SUBSCRIBED ? unsubscribe() : subscribe();
|
|
115
|
+
status === SCGroupSubscriptionStatusType.SUBSCRIBED && !(user === null || user === void 0 ? void 0 : user.id) ? unsubscribe() : (user === null || user === void 0 ? void 0 : user.id) ? subscribe(user) : subscribe();
|
|
100
116
|
}
|
|
101
117
|
};
|
|
102
118
|
/**
|
|
@@ -106,21 +122,24 @@ export default function GroupSubscribeButton(inProps) {
|
|
|
106
122
|
let _status;
|
|
107
123
|
switch (status) {
|
|
108
124
|
case SCGroupSubscriptionStatusType.REQUESTED:
|
|
109
|
-
_status = React.createElement(FormattedMessage, { defaultMessage: "ui.
|
|
125
|
+
_status = React.createElement(FormattedMessage, { defaultMessage: "ui.groupSubscribeButton.waitingApproval", id: "ui.groupSubscribeButton.waitingApproval" });
|
|
110
126
|
break;
|
|
111
127
|
case SCGroupSubscriptionStatusType.SUBSCRIBED:
|
|
112
128
|
_status = React.createElement(FormattedMessage, { defaultMessage: "ui.groupSubscribeButton.exit", id: "ui.groupSubscribeButton.exit" });
|
|
113
129
|
break;
|
|
130
|
+
case SCGroupSubscriptionStatusType.INVITED:
|
|
131
|
+
_status = React.createElement(FormattedMessage, { defaultMessage: "ui.groupSubscribeButton.accept", id: "ui.groupSubscribeButton.accept" });
|
|
132
|
+
break;
|
|
114
133
|
default:
|
|
115
134
|
scGroup.privacy === SCGroupPrivacyType.PUBLIC
|
|
116
135
|
? (_status = React.createElement(FormattedMessage, { defaultMessage: "ui.groupSubscribeButton.enter", id: "ui.groupSubscribeButton.enter" }))
|
|
117
|
-
: (_status = React.createElement(FormattedMessage, { defaultMessage: "ui.
|
|
136
|
+
: (_status = React.createElement(FormattedMessage, { defaultMessage: "ui.groupSubscribeButton.requestAccess", id: "ui.groupSubscribeButton.requestAccess" }));
|
|
118
137
|
break;
|
|
119
138
|
}
|
|
120
139
|
return _status;
|
|
121
140
|
};
|
|
122
|
-
if (!scGroup || (
|
|
141
|
+
if (!scGroup || (isGroupAdmin && (user === null || user === void 0 ? void 0 : user.id) === scUserContext.user.id) || (isGroupAdmin && !(user === null || user === void 0 ? void 0 : user.id))) {
|
|
123
142
|
return null;
|
|
124
143
|
}
|
|
125
|
-
return (React.createElement(Root, Object.assign({ size: "small", variant: "outlined", onClick: handleSubscribeAction, loading: scUserContext.user ? scGroupsManager.isLoading(scGroup) : null, className: classNames(classes.root, className) }, rest), getStatus()));
|
|
144
|
+
return (React.createElement(Root, Object.assign({ size: "small", variant: "outlined", onClick: handleSubscribeAction, loading: scUserContext.user ? scGroupsManager.isLoading(scGroup) : null, disabled: status === SCGroupSubscriptionStatusType.REQUESTED, className: classNames(classes.root, className) }, rest), isGroupAdmin ? React.createElement(FormattedMessage, { defaultMessage: "ui.groupSubscribeButton.accept", id: "ui.groupSubscribeButton.accept" }) : getStatus()));
|
|
126
145
|
}
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { SCGroupType } from '@selfcommunity/types';
|
|
2
|
-
import { EndpointType } from '@selfcommunity/api-services';
|
|
3
1
|
import { GroupProps } from '../Group';
|
|
4
2
|
export interface GroupsProps {
|
|
5
3
|
/**
|
|
@@ -8,20 +6,29 @@ export interface GroupsProps {
|
|
|
8
6
|
*/
|
|
9
7
|
className?: string;
|
|
10
8
|
/**
|
|
11
|
-
*
|
|
9
|
+
* Feed API Query Params
|
|
10
|
+
* @default [{'limit': 20, 'offset': 0}]
|
|
12
11
|
*/
|
|
13
|
-
|
|
12
|
+
endpointQueryParams?: Record<string, string | number>;
|
|
14
13
|
/**
|
|
15
14
|
* Props to spread to single group object
|
|
16
15
|
* @default {variant: 'outlined', ButtonBaseProps: {disableRipple: 'true'}}
|
|
17
16
|
*/
|
|
18
17
|
GroupComponentProps?: GroupProps;
|
|
18
|
+
/** If true, it means that the endpoint fetches all groups available
|
|
19
|
+
* @default true
|
|
20
|
+
*/
|
|
21
|
+
general?: boolean;
|
|
19
22
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
|
|
23
|
+
* Show/Hide filters
|
|
24
|
+
* @default false
|
|
25
|
+
*/
|
|
26
|
+
showFilters?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Filters component
|
|
29
|
+
* @param props
|
|
23
30
|
*/
|
|
24
|
-
|
|
31
|
+
filters?: JSX.Element;
|
|
25
32
|
/**
|
|
26
33
|
* Other props
|
|
27
34
|
*/
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { __rest } from "tslib";
|
|
2
2
|
import React, { useEffect, useMemo, useState } from 'react';
|
|
3
3
|
import { styled } from '@mui/material/styles';
|
|
4
|
-
import { Box, Grid, Typography } from '@mui/material';
|
|
5
|
-
import { http } from '@selfcommunity/api-services';
|
|
6
|
-
import { Logger } from '@selfcommunity/utils';
|
|
7
|
-
import { SCPreferences,
|
|
4
|
+
import { Box, Button, Grid, TextField, Typography, useMediaQuery, useTheme } from '@mui/material';
|
|
5
|
+
import { Endpoints, GroupService, http } from '@selfcommunity/api-services';
|
|
6
|
+
import { Logger, sortByAttr } from '@selfcommunity/utils';
|
|
7
|
+
import { SCPreferences, useSCPreferences, useSCUser } from '@selfcommunity/react-core';
|
|
8
8
|
import Skeleton from './Skeleton';
|
|
9
9
|
import { FormattedMessage } from 'react-intl';
|
|
10
10
|
import classNames from 'classnames';
|
|
@@ -12,9 +12,12 @@ import { SCOPE_SC_UI } from '../../constants/Errors';
|
|
|
12
12
|
import { useThemeProps } from '@mui/system';
|
|
13
13
|
import HiddenPlaceholder from '../../shared/HiddenPlaceholder';
|
|
14
14
|
import { PREFIX } from './constants';
|
|
15
|
-
import Group from '../Group';
|
|
15
|
+
import Group, { GroupSkeleton } from '../Group';
|
|
16
|
+
import { DEFAULT_PAGINATION_OFFSET } from '../../constants/Pagination';
|
|
17
|
+
import InfiniteScroll from '../../shared/InfiniteScroll';
|
|
16
18
|
const classes = {
|
|
17
19
|
root: `${PREFIX}-root`,
|
|
20
|
+
filters: `${PREFIX}-filter`,
|
|
18
21
|
groups: `${PREFIX}-groups`,
|
|
19
22
|
item: `${PREFIX}-item`,
|
|
20
23
|
noResults: `${PREFIX}-no-results`,
|
|
@@ -62,10 +65,14 @@ export default function Groups(inProps) {
|
|
|
62
65
|
props: inProps,
|
|
63
66
|
name: PREFIX
|
|
64
67
|
});
|
|
65
|
-
const {
|
|
68
|
+
const { endpointQueryParams = { limit: 20, offset: DEFAULT_PAGINATION_OFFSET }, className, GroupComponentProps = { variant: 'outlined', ButtonBaseProps: { disableRipple: true, component: Box } }, showFilters = false, filters, general = true } = props, rest = __rest(props, ["endpointQueryParams", "className", "GroupComponentProps", "showFilters", "filters", "general"]);
|
|
66
69
|
// STATE
|
|
67
70
|
const [groups, setGroups] = useState([]);
|
|
68
71
|
const [loading, setLoading] = useState(true);
|
|
72
|
+
const [next, setNext] = useState(null);
|
|
73
|
+
const [search, setSearch] = useState('');
|
|
74
|
+
const theme = useTheme();
|
|
75
|
+
const isMobile = useMediaQuery(theme.breakpoints.down('md'));
|
|
69
76
|
// CONTEXT
|
|
70
77
|
const scUserContext = useSCUser();
|
|
71
78
|
const scPreferencesContext = useSCPreferences();
|
|
@@ -74,19 +81,31 @@ export default function Groups(inProps) {
|
|
|
74
81
|
scPreferencesContext.preferences[SCPreferences.CONFIGURATIONS_CONTENT_AVAILABILITY].value, [scPreferencesContext.preferences]);
|
|
75
82
|
// CONST
|
|
76
83
|
const authUserId = scUserContext.user ? scUserContext.user.id : null;
|
|
77
|
-
//
|
|
78
|
-
const
|
|
84
|
+
// HANDLERS
|
|
85
|
+
const handleScrollUp = () => {
|
|
86
|
+
window.scrollTo({ left: 0, top: 0, behavior: 'smooth' });
|
|
87
|
+
};
|
|
79
88
|
/**
|
|
80
89
|
* Fetches groups list
|
|
81
90
|
*/
|
|
82
|
-
const fetchGroups = (
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
91
|
+
const fetchGroups = () => {
|
|
92
|
+
let groupService;
|
|
93
|
+
if (general) {
|
|
94
|
+
groupService = GroupService.searchGroups(Object.assign(Object.assign({}, endpointQueryParams), (search !== '' && { search: search })));
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
groupService = GroupService.getUserGroups(Object.assign(Object.assign({}, endpointQueryParams), (search !== '' && { search: search })));
|
|
98
|
+
}
|
|
99
|
+
groupService
|
|
100
|
+
.then((res) => {
|
|
101
|
+
setGroups(res.results);
|
|
102
|
+
setNext(res.next);
|
|
103
|
+
setLoading(false);
|
|
104
|
+
})
|
|
105
|
+
.catch((error) => {
|
|
106
|
+
Logger.error(SCOPE_SC_UI, error);
|
|
86
107
|
});
|
|
87
|
-
|
|
88
|
-
return data.next ? data.results.concat(yield fetchGroups(data.next)) : data.results;
|
|
89
|
-
});
|
|
108
|
+
};
|
|
90
109
|
/**
|
|
91
110
|
* On mount, fetches groups list
|
|
92
111
|
*/
|
|
@@ -94,32 +113,67 @@ export default function Groups(inProps) {
|
|
|
94
113
|
if (!contentAvailability && !authUserId) {
|
|
95
114
|
return;
|
|
96
115
|
}
|
|
97
|
-
else if (prefetchedGroups.length) {
|
|
98
|
-
setGroups(prefetchedGroups);
|
|
99
|
-
setLoading(false);
|
|
100
|
-
}
|
|
101
116
|
else {
|
|
102
|
-
fetchGroups()
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
})
|
|
109
|
-
.catch((error) => {
|
|
110
|
-
Logger.error(SCOPE_SC_UI, error);
|
|
111
|
-
});
|
|
117
|
+
fetchGroups();
|
|
118
|
+
}
|
|
119
|
+
}, [contentAvailability, authUserId, search]);
|
|
120
|
+
const handleNext = useMemo(() => () => {
|
|
121
|
+
if (!next) {
|
|
122
|
+
return;
|
|
112
123
|
}
|
|
113
|
-
|
|
124
|
+
return http
|
|
125
|
+
.request({
|
|
126
|
+
url: next,
|
|
127
|
+
method: general ? Endpoints.SearchGroups.method : Endpoints.GetUserGroups.method
|
|
128
|
+
})
|
|
129
|
+
.then((res) => {
|
|
130
|
+
setGroups([...groups, ...res.data.results]);
|
|
131
|
+
setNext(res.data.next);
|
|
132
|
+
})
|
|
133
|
+
.catch((error) => console.log(error))
|
|
134
|
+
.then(() => setLoading(false));
|
|
135
|
+
}, [next]);
|
|
136
|
+
/**
|
|
137
|
+
* Get groups filtered
|
|
138
|
+
*/
|
|
139
|
+
const getFilteredGroups = () => {
|
|
140
|
+
if (search) {
|
|
141
|
+
return groups.filter((g) => g.name.toLowerCase().includes(search.toLowerCase()));
|
|
142
|
+
}
|
|
143
|
+
return groups;
|
|
144
|
+
};
|
|
145
|
+
/**
|
|
146
|
+
* Handle change filter name
|
|
147
|
+
* @param event
|
|
148
|
+
*/
|
|
149
|
+
const handleOnChangeFilterName = (event) => {
|
|
150
|
+
setSearch(event.target.value);
|
|
151
|
+
};
|
|
152
|
+
/**
|
|
153
|
+
* Renders groups list
|
|
154
|
+
*/
|
|
155
|
+
const filteredGroups = sortByAttr(getFilteredGroups(), 'order');
|
|
156
|
+
const content = (React.createElement(React.Fragment, null,
|
|
157
|
+
showFilters && (React.createElement(Grid, { container: true, direction: "row", justifyContent: "center", alignItems: "center", className: classes.filters }, filters ? (filters) : (React.createElement(Grid, { item: true, xs: 12, md: 6 },
|
|
158
|
+
React.createElement(TextField, { fullWidth: true, value: search, label: React.createElement(FormattedMessage, { id: "ui.groups.filterByName", defaultMessage: "ui.groups.filterByName" }), variant: "outlined", onChange: handleOnChangeFilterName, disabled: loading }))))),
|
|
159
|
+
React.createElement(React.Fragment, null, !groups.length ? (React.createElement(Box, { className: classes.noResults },
|
|
160
|
+
React.createElement(Typography, { variant: "h4" },
|
|
161
|
+
React.createElement(FormattedMessage, { id: "ui.groups.noGroups.title", defaultMessage: "ui.groups.noGroups.title" })),
|
|
162
|
+
React.createElement(Typography, { variant: "body1" },
|
|
163
|
+
React.createElement(FormattedMessage, { id: "ui.groups.noGroups.subtitle", defaultMessage: "ui.groups.noGroups.subtitle" })))) : (React.createElement(InfiniteScroll, { dataLength: groups.length, next: handleNext, hasMoreNext: Boolean(next), loaderNext: isMobile ? React.createElement(GroupSkeleton, null) : React.createElement(Skeleton, { groupsNumber: 2 }), endMessage: React.createElement(Typography, { component: "div", className: classes.endMessage },
|
|
164
|
+
React.createElement(FormattedMessage, { id: "ui.groups.endMessage", defaultMessage: "ui.groups.endMessage", values: {
|
|
165
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
|
166
|
+
// @ts-ignore
|
|
167
|
+
button: (chunk) => (React.createElement(Button, { color: "secondary", variant: "text", onClick: handleScrollUp }, chunk))
|
|
168
|
+
} })) },
|
|
169
|
+
React.createElement(Grid, { container: true, spacing: { xs: 2 }, className: classes.groups }, filteredGroups.map((group) => (React.createElement(Grid, { item: true, xs: 12, sm: 8, md: 6, key: group.id, className: classes.item },
|
|
170
|
+
React.createElement(Group, Object.assign({ group: group, groupId: group.id, actionRedirect: true }, GroupComponentProps)))))))))));
|
|
114
171
|
// RENDER
|
|
115
172
|
if (!contentAvailability && !scUserContext.user) {
|
|
116
173
|
return React.createElement(HiddenPlaceholder, null);
|
|
117
174
|
}
|
|
118
|
-
|
|
119
|
-
React.createElement(
|
|
120
|
-
|
|
121
|
-
React.createElement(Typography, { variant: "body1" },
|
|
122
|
-
React.createElement(FormattedMessage, { id: "ui.groups.noGroups.subtitle", defaultMessage: "ui.groups.noGroups.subtitle" })))) : (React.createElement(React.Fragment, null, groups.map((group) => (React.createElement(Grid, { item: true, xs: 12, sm: 8, md: 6, key: group.id, className: classes.item },
|
|
123
|
-
React.createElement(Group, Object.assign({ group: group, groupId: group.id }, GroupComponentProps)))))))))));
|
|
175
|
+
if (loading) {
|
|
176
|
+
return React.createElement(Skeleton, null);
|
|
177
|
+
}
|
|
124
178
|
return (React.createElement(Root, Object.assign({ className: classNames(classes.root, className) }, rest), content));
|
|
125
179
|
}
|
|
@@ -9,6 +9,10 @@ export interface GroupsSkeletonProps {
|
|
|
9
9
|
* @default null
|
|
10
10
|
*/
|
|
11
11
|
GroupSkeletonProps?: any;
|
|
12
|
+
/**
|
|
13
|
+
* @default 20
|
|
14
|
+
*/
|
|
15
|
+
groupsNumber?: number;
|
|
12
16
|
}
|
|
13
17
|
/**
|
|
14
18
|
* > API documentation for the Community-JS Groups Skeleton component. Learn about the available props and the CSS API.
|
|
@@ -35,8 +35,8 @@ const Root = styled(Box, {
|
|
|
35
35
|
*
|
|
36
36
|
*/
|
|
37
37
|
export default function GroupsSkeleton(inProps) {
|
|
38
|
-
const { className, GroupSkeletonProps = {} } = inProps, rest = __rest(inProps, ["className", "GroupSkeletonProps"]);
|
|
38
|
+
const { className, GroupSkeletonProps = {}, groupsNumber = 20 } = inProps, rest = __rest(inProps, ["className", "GroupSkeletonProps", "groupsNumber"]);
|
|
39
39
|
return (React.createElement(Root, Object.assign({ className: classNames(classes.root, className) }, rest),
|
|
40
|
-
React.createElement(Grid, { container: true, spacing: { xs: 3 }, className: classes.groups }, [...Array(
|
|
40
|
+
React.createElement(Grid, { container: true, spacing: { xs: 3 }, className: classes.groups }, [...Array(groupsNumber)].map((category, index) => (React.createElement(Grid, { item: true, xs: 12, sm: 8, md: 6, key: index },
|
|
41
41
|
React.createElement(GroupSkeleton, Object.assign({ elevation: 0, variant: 'outlined' }, GroupSkeletonProps))))))));
|
|
42
42
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { __rest } from "tslib";
|
|
2
|
-
import React, { useCallback, useState } from 'react';
|
|
3
|
-
import { Link, SCRoutes, UserUtils, useSCContext, useSCRouting, useSCUser } from '@selfcommunity/react-core';
|
|
2
|
+
import React, { useCallback, useMemo, useState } from 'react';
|
|
3
|
+
import { Link, SCPreferences, SCRoutes, UserUtils, useSCContext, useSCPreferences, useSCRouting, useSCUser } from '@selfcommunity/react-core';
|
|
4
4
|
import { Avatar, Box, Button, CardContent } from '@mui/material';
|
|
5
5
|
import { styled } from '@mui/material/styles';
|
|
6
6
|
import { FormattedMessage } from 'react-intl';
|
|
@@ -10,6 +10,7 @@ import { useThemeProps } from '@mui/system';
|
|
|
10
10
|
import Composer from '../Composer';
|
|
11
11
|
import { File, Link as MediaLink } from '../../shared/Media';
|
|
12
12
|
import { PREFIX } from './constants';
|
|
13
|
+
import HiddenPlaceholder from '../../shared/HiddenPlaceholder';
|
|
13
14
|
const classes = {
|
|
14
15
|
root: `${PREFIX}-root`,
|
|
15
16
|
content: `${PREFIX}-content`,
|
|
@@ -58,6 +59,9 @@ export default function InlineComposerWidget(inProps) {
|
|
|
58
59
|
const scUserContext = useSCUser();
|
|
59
60
|
const scRoutingContext = useSCRouting();
|
|
60
61
|
const { enqueueSnackbar } = useSnackbar();
|
|
62
|
+
// PREFERENCES
|
|
63
|
+
const preferences = useSCPreferences();
|
|
64
|
+
const onlyStaffEnabled = useMemo(() => preferences.preferences[SCPreferences.CONFIGURATIONS_POST_ONLY_STAFF_ENABLED].value, [preferences.preferences]);
|
|
61
65
|
// State variables
|
|
62
66
|
const [open, setOpen] = useState(false);
|
|
63
67
|
// Handlers
|
|
@@ -92,6 +96,9 @@ export default function InlineComposerWidget(inProps) {
|
|
|
92
96
|
}
|
|
93
97
|
setOpen(false);
|
|
94
98
|
};
|
|
99
|
+
if (!UserUtils.isStaff(scUserContext.user) && onlyStaffEnabled) {
|
|
100
|
+
return React.createElement(HiddenPlaceholder, null);
|
|
101
|
+
}
|
|
95
102
|
return (React.createElement(React.Fragment, null,
|
|
96
103
|
React.createElement(Root, Object.assign({ className: classes.root }, rest),
|
|
97
104
|
React.createElement(CardContent, { className: classes.content },
|
|
@@ -60,7 +60,7 @@ export default function NavigationMenuIconButton(inProps) {
|
|
|
60
60
|
props: inProps,
|
|
61
61
|
name: PREFIX
|
|
62
62
|
});
|
|
63
|
-
const { className = null, DrawerProps = { anchor: 'left' },
|
|
63
|
+
const { className = null, DrawerProps = { anchor: 'left' }, drawerHeaderContent = React.createElement(DefaultHeaderContent, null), drawerContent = React.createElement(DefaultDrawerContent, null), ScrollContainerProps = {} } = props, rest = __rest(props, ["className", "DrawerProps", "drawerHeaderContent", "drawerContent", "ScrollContainerProps"]);
|
|
64
64
|
// STATE
|
|
65
65
|
const [anchorEl, setAnchorEl] = useState(null);
|
|
66
66
|
// CONTEXT
|
|
@@ -2,7 +2,6 @@ import { __rest } from "tslib";
|
|
|
2
2
|
import React, { useMemo, useState } from 'react';
|
|
3
3
|
import { styled } from '@mui/material/styles';
|
|
4
4
|
import { Divider, Icon, IconButton, List, ListItem, ListItemButton, Menu, MenuItem, SwipeableDrawer, useMediaQuery, useTheme } from '@mui/material';
|
|
5
|
-
import { SCFeatureName } from '@selfcommunity/types';
|
|
6
5
|
import { Link, SCPreferences, SCRoutes, UserUtils, useSCPreferences, useSCRouting, useSCUser } from '@selfcommunity/react-core';
|
|
7
6
|
import classNames from 'classnames';
|
|
8
7
|
import { useThemeProps } from '@mui/system';
|
|
@@ -34,7 +33,8 @@ const MenuRoot = styled(Menu, {
|
|
|
34
33
|
const PREFERENCES = [
|
|
35
34
|
SCPreferences.CONFIGURATIONS_FOLLOW_ENABLED,
|
|
36
35
|
SCPreferences.CONFIGURATIONS_POST_TYPE_ENABLED,
|
|
37
|
-
SCPreferences.CONFIGURATIONS_DISCUSSION_TYPE_ENABLED
|
|
36
|
+
SCPreferences.CONFIGURATIONS_DISCUSSION_TYPE_ENABLED,
|
|
37
|
+
SCPreferences.ADDONS_LOYALTY_POINTS_COLLECTION
|
|
38
38
|
];
|
|
39
39
|
/**
|
|
40
40
|
* > API documentation for the Community-JS Navigation Settings Icon Button component. Learn about the available props and the CSS API.
|
|
@@ -118,7 +118,7 @@ export default function NavigationSettingsIconButton(inProps) {
|
|
|
118
118
|
!preferences[SCPreferences.CONFIGURATIONS_FOLLOW_ENABLED] && (React.createElement(ListItem, { className: classes.item, key: "connections" },
|
|
119
119
|
React.createElement(ListItemButton, { component: Link, to: scRoutingContext.url(SCRoutes.USER_PROFILE_CONNECTIONS_ROUTE_NAME, scUserContext.user) },
|
|
120
120
|
React.createElement(FormattedMessage, { id: "ui.navigationSettingsIconButton.connections", defaultMessage: "ui.navigationSettingsIconButton.connections" })))),
|
|
121
|
-
|
|
121
|
+
preferences[SCPreferences.ADDONS_LOYALTY_POINTS_COLLECTION] && (React.createElement(ListItem, { className: classes.item, key: "loyaltyProgram" },
|
|
122
122
|
React.createElement(ListItemButton, { component: Link, to: scRoutingContext.url(SCRoutes.LOYALTY_ROUTE_NAME, {}) },
|
|
123
123
|
React.createElement(FormattedMessage, { id: "ui.navigationSettingsIconButton.loyalty", defaultMessage: "ui.navigationSettingsIconButton.loyalty" })))),
|
|
124
124
|
preferences[SCPreferences.CONFIGURATIONS_POST_TYPE_ENABLED] && (React.createElement(ListItem, { className: classes.item, key: "followedPosts" },
|
|
@@ -167,7 +167,7 @@ export default function NavigationSettingsIconButton(inProps) {
|
|
|
167
167
|
React.createElement(FormattedMessage, { id: "ui.navigationSettingsIconButton.followers", defaultMessage: "ui.navigationSettingsIconButton.followers" }))),
|
|
168
168
|
!preferences[SCPreferences.CONFIGURATIONS_FOLLOW_ENABLED] && (React.createElement(MenuItem, { className: classes.item, key: "connections", component: Link, to: scRoutingContext.url(SCRoutes.USER_PROFILE_CONNECTIONS_ROUTE_NAME, scUserContext.user) },
|
|
169
169
|
React.createElement(FormattedMessage, { id: "ui.navigationSettingsIconButton.connections", defaultMessage: "ui.navigationSettingsIconButton.connections" }))),
|
|
170
|
-
|
|
170
|
+
preferences[SCPreferences.ADDONS_LOYALTY_POINTS_COLLECTION] && (React.createElement(MenuItem, { className: classes.item, key: "loyaltyProgram", component: Link, to: scRoutingContext.url(SCRoutes.LOYALTY_ROUTE_NAME, {}) },
|
|
171
171
|
React.createElement(FormattedMessage, { id: "ui.navigationSettingsIconButton.loyalty", defaultMessage: "ui.navigationSettingsIconButton.loyalty" }))),
|
|
172
172
|
preferences[SCPreferences.CONFIGURATIONS_POST_TYPE_ENABLED] && (React.createElement(MenuItem, { className: classes.item, key: "followedPosts", component: Link, to: scRoutingContext.url(SCRoutes.USER_PROFILE_FOLLOWED_POSTS_ROUTE_NAME, scUserContext.user) },
|
|
173
173
|
React.createElement(FormattedMessage, { id: "ui.navigationSettingsIconButton.postsFollowed", defaultMessage: "ui.navigationSettingsIconButton.postsFollowed" }))),
|
|
@@ -11,7 +11,7 @@ import SearchAutocomplete from '../SearchAutocomplete';
|
|
|
11
11
|
import NavigationSettingsIconButton from '../NavigationSettingsIconButton';
|
|
12
12
|
import ComposerIconButton from '../ComposerIconButton';
|
|
13
13
|
import { SCFeatureName } from '@selfcommunity/types';
|
|
14
|
-
import { Link, SCPreferences, SCRoutes, useSCPreferences, useSCRouting, useSCUser } from '@selfcommunity/react-core';
|
|
14
|
+
import { Link, SCPreferences, SCRoutes, UserUtils, useSCPreferences, useSCRouting, useSCUser } from '@selfcommunity/react-core';
|
|
15
15
|
import NavigationMenuIconButton from '../NavigationMenuIconButton';
|
|
16
16
|
import { PREFIX } from './constants';
|
|
17
17
|
const classes = {
|
|
@@ -121,7 +121,9 @@ export default function NavigationToolbar(inProps) {
|
|
|
121
121
|
preferences[SCPreferences.CONFIGURATIONS_EXPLORE_STREAM_ENABLED] &&
|
|
122
122
|
(preferences[SCPreferences.CONFIGURATIONS_CONTENT_AVAILABILITY] || scUserContext.user) && (React.createElement(IconButton, { className: classNames(classes.explore, { [classes.active]: value.startsWith(scRoutingContext.url(SCRoutes.EXPLORE_ROUTE_NAME, {})) }), "aria-label": "Explore", to: scRoutingContext.url(SCRoutes.EXPLORE_ROUTE_NAME, {}), component: Link },
|
|
123
123
|
React.createElement(Icon, null, "explore"))),
|
|
124
|
-
groupsEnabled && scUserContext.user && (React.createElement(IconButton, { className: classNames(classes.groups, {
|
|
124
|
+
groupsEnabled && scUserContext.user && (React.createElement(IconButton, { className: classNames(classes.groups, {
|
|
125
|
+
[classes.active]: value.startsWith(scRoutingContext.url(SCRoutes.GROUPS_SUBSCRIBED_ROUTE_NAME, {}))
|
|
126
|
+
}), "aria-label": "Groups", to: scRoutingContext.url(SCRoutes.GROUPS_SUBSCRIBED_ROUTE_NAME, {}), component: Link },
|
|
125
127
|
React.createElement(Icon, null, "groups")))));
|
|
126
128
|
return (React.createElement(Root, Object.assign({ className: classNames(className, classes.root) }, rest),
|
|
127
129
|
React.createElement(NavigationMenuIconButtonComponent, null),
|
|
@@ -133,7 +135,9 @@ export default function NavigationToolbar(inProps) {
|
|
|
133
135
|
(preferences[SCPreferences.CONFIGURATIONS_CONTENT_AVAILABILITY] || scUserContext.user) && !disableSearch ? (React.createElement(SearchAutocomplete, Object.assign({ className: classes.search, blurOnSelect: true }, SearchAutocompleteProps))) : (React.createElement(Box, { className: classes.search })),
|
|
134
136
|
startActions,
|
|
135
137
|
scUserContext.user ? (React.createElement(React.Fragment, null,
|
|
136
|
-
!disableComposer
|
|
138
|
+
!disableComposer ||
|
|
139
|
+
!preferences[SCPreferences.CONFIGURATIONS_POST_ONLY_STAFF_ENABLED].value ||
|
|
140
|
+
(UserUtils.isStaff(scUserContext.user) && preferences[SCPreferences.CONFIGURATIONS_POST_ONLY_STAFF_ENABLED].value && (React.createElement(ComposerIconButton, Object.assign({ className: classes.composer }, ComposerIconButtonProps)))),
|
|
137
141
|
React.createElement(Tooltip, { title: scUserContext.user.username },
|
|
138
142
|
React.createElement(IconButton, { component: Link, to: scRoutingContext.url(SCRoutes.USER_PROFILE_ROUTE_NAME, scUserContext.user), "aria-label": "Profile", className: classes.profile },
|
|
139
143
|
React.createElement(Avatar, { alt: scUserContext.user.username, src: scUserContext.user.avatar }))),
|
|
@@ -8,6 +8,10 @@ export interface NavigationToolbarMobileProps extends ToolbarProps {
|
|
|
8
8
|
* Disable search action if possible
|
|
9
9
|
*/
|
|
10
10
|
disableSearch?: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Preserve the same as the desktop version
|
|
13
|
+
*/
|
|
14
|
+
preserveDesktopLogo?: boolean;
|
|
11
15
|
/**
|
|
12
16
|
* Props spread to SearchAutocomplete component
|
|
13
17
|
*/
|
|
@@ -55,6 +59,7 @@ export interface NavigationToolbarMobileProps extends ToolbarProps {
|
|
|
55
59
|
|logo|.SCNavigationToolbarMobile-logo|Styles applied to the logo element.|
|
|
56
60
|
|search|.SCNavigationToolbarMobile-search|Styles applied to the search button element|
|
|
57
61
|
|searchDialog|.SCNavigationToolbarMobile-search-dialog|Styles applied to the search dialog element|
|
|
62
|
+
|notifications|.SCNavigationToolbarMobile-notifications|Styles applied to the notifications button element|
|
|
58
63
|
|settings|.SCNavigationToolbarMobile-settings|Styles applied to the settings button element|
|
|
59
64
|
|settingsDialog|.SCNavigationToolbarMobile-settingsDialog|Styles applied to the settings dialog elements|
|
|
60
65
|
|login|.SCNavigationToolbarMobile-login|Styles applied to the login element.|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { __rest } from "tslib";
|
|
2
|
-
import { Button, IconButton, styled, Toolbar } from '@mui/material';
|
|
3
|
-
import React, { useCallback, useState } from 'react';
|
|
2
|
+
import { Badge, Button, IconButton, styled, Toolbar } from '@mui/material';
|
|
3
|
+
import React, { useCallback, useMemo, useState } from 'react';
|
|
4
4
|
import { Link, SCPreferences, SCRoutes, useSCPreferences, useSCRouting, useSCUser } from '@selfcommunity/react-core';
|
|
5
5
|
import Icon from '@mui/material/Icon';
|
|
6
6
|
import { useThemeProps } from '@mui/system';
|
|
@@ -11,11 +11,13 @@ import SearchDialog from '../SearchDialog';
|
|
|
11
11
|
import NavigationSettingsIconButton from '../NavigationSettingsIconButton';
|
|
12
12
|
import NavigationMenuIconButton from '../NavigationMenuIconButton';
|
|
13
13
|
import { PREFIX } from './constants';
|
|
14
|
+
import { SCFeatureName } from '@selfcommunity/types';
|
|
14
15
|
const classes = {
|
|
15
16
|
root: `${PREFIX}-root`,
|
|
16
17
|
logo: `${PREFIX}-logo`,
|
|
17
18
|
search: `${PREFIX}-search`,
|
|
18
19
|
searchDialog: `${PREFIX}-search-dialog`,
|
|
20
|
+
notifications: `${PREFIX}-notifications`,
|
|
19
21
|
settings: `${PREFIX}-settings`,
|
|
20
22
|
settingsDialog: `${PREFIX}-settings-dialog`,
|
|
21
23
|
login: `${PREFIX}-login`
|
|
@@ -50,6 +52,7 @@ const Root = styled(Toolbar, {
|
|
|
50
52
|
|logo|.SCNavigationToolbarMobile-logo|Styles applied to the logo element.|
|
|
51
53
|
|search|.SCNavigationToolbarMobile-search|Styles applied to the search button element|
|
|
52
54
|
|searchDialog|.SCNavigationToolbarMobile-search-dialog|Styles applied to the search dialog element|
|
|
55
|
+
|notifications|.SCNavigationToolbarMobile-notifications|Styles applied to the notifications button element|
|
|
53
56
|
|settings|.SCNavigationToolbarMobile-settings|Styles applied to the settings button element|
|
|
54
57
|
|settingsDialog|.SCNavigationToolbarMobile-settingsDialog|Styles applied to the settings dialog elements|
|
|
55
58
|
|login|.SCNavigationToolbarMobile-login|Styles applied to the login element.|
|
|
@@ -62,14 +65,16 @@ export default function NavigationToolbarMobile(inProps) {
|
|
|
62
65
|
props: inProps,
|
|
63
66
|
name: PREFIX
|
|
64
67
|
});
|
|
65
|
-
const { className = '', disableSearch = false, SearchAutocompleteProps = {}, children = null, startActions = null, endActions = null, NavigationMenuIconButtonComponent = NavigationMenuIconButton, NavigationSettingsIconButtonComponent = NavigationSettingsIconButton } = props, rest = __rest(props, ["className", "disableSearch", "SearchAutocompleteProps", "children", "startActions", "endActions", "NavigationMenuIconButtonComponent", "NavigationSettingsIconButtonComponent"]);
|
|
68
|
+
const { className = '', disableSearch = false, preserveDesktopLogo = false, SearchAutocompleteProps = {}, children = null, startActions = null, endActions = null, NavigationMenuIconButtonComponent = NavigationMenuIconButton, NavigationSettingsIconButtonComponent = NavigationSettingsIconButton } = props, rest = __rest(props, ["className", "disableSearch", "preserveDesktopLogo", "SearchAutocompleteProps", "children", "startActions", "endActions", "NavigationMenuIconButtonComponent", "NavigationSettingsIconButtonComponent"]);
|
|
66
69
|
// CONTEXT
|
|
67
70
|
const scUserContext = useSCUser();
|
|
68
71
|
const scRoutingContext = useSCRouting();
|
|
69
72
|
// PREFERENCES
|
|
70
|
-
const { preferences } = useSCPreferences();
|
|
73
|
+
const { preferences, features } = useSCPreferences();
|
|
71
74
|
// STATE
|
|
72
75
|
const [searchOpen, setSearchOpen] = useState(false);
|
|
76
|
+
// MEMO
|
|
77
|
+
const groupsEnabled = useMemo(() => features.includes(SCFeatureName.GROUPING), [features]);
|
|
73
78
|
// HANDLERS
|
|
74
79
|
const handleOpenSearch = useCallback(() => {
|
|
75
80
|
setSearchOpen(true);
|
|
@@ -83,8 +88,7 @@ export default function NavigationToolbarMobile(inProps) {
|
|
|
83
88
|
}
|
|
84
89
|
const _children = children || (React.createElement(React.Fragment, null,
|
|
85
90
|
React.createElement(NavigationMenuIconButtonComponent, null),
|
|
86
|
-
React.createElement(Link, { to: scRoutingContext.url(SCRoutes.HOME_ROUTE_NAME, {}), className: classes.logo },
|
|
87
|
-
React.createElement("img", { src: preferences[SCPreferences.LOGO_NAVBAR_LOGO_MOBILE].value, alt: "logo" }))));
|
|
91
|
+
React.createElement(Link, { to: scRoutingContext.url(SCRoutes.HOME_ROUTE_NAME, {}), className: classes.logo }, !preserveDesktopLogo ? (React.createElement("img", { src: preferences[SCPreferences.LOGO_NAVBAR_LOGO_MOBILE].value, alt: "logo" })) : (React.createElement("img", { src: preferences[SCPreferences.LOGO_NAVBAR_LOGO].value, alt: "logo" })))));
|
|
88
92
|
return (React.createElement(Root, Object.assign({ className: classNames(className, classes.root) }, rest),
|
|
89
93
|
_children,
|
|
90
94
|
startActions,
|
|
@@ -93,6 +97,9 @@ export default function NavigationToolbarMobile(inProps) {
|
|
|
93
97
|
React.createElement(Icon, null, "search")),
|
|
94
98
|
React.createElement(SearchDialog, { className: classes.searchDialog, fullScreen: true, open: searchOpen, SearchAutocompleteProps: Object.assign(Object.assign({}, SearchAutocompleteProps), { onClear: handleCloseSearch }) }))),
|
|
95
99
|
endActions,
|
|
100
|
+
scUserContext.user && groupsEnabled && (React.createElement(IconButton, { className: classes.notifications, component: Link, to: scRoutingContext.url(SCRoutes.USER_NOTIFICATIONS_ROUTE_NAME, {}) },
|
|
101
|
+
React.createElement(Badge, { badgeContent: scUserContext.user.unseen_notification_banners_counter + scUserContext.user.unseen_interactions_counter, color: "secondary" },
|
|
102
|
+
React.createElement(Icon, null, "notifications_active")))),
|
|
96
103
|
scUserContext.user ? (React.createElement(NavigationSettingsIconButtonComponent, { className: classes.settings })) : (React.createElement(Button, { className: classes.login, color: "inherit", component: Link, to: scRoutingContext.url(SCRoutes.SIGNIN_ROUTE_NAME, {}) },
|
|
97
104
|
React.createElement(FormattedMessage, { id: "ui.appBar.navigation.login", defaultMessage: "ui.appBar.navigation.login" })))));
|
|
98
105
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { SCNotificationGroupActivityType } from '@selfcommunity/types';
|
|
2
|
+
import { NotificationItemProps } from '../../../shared/NotificationItem';
|
|
3
|
+
export interface NotificationGroupProps extends Pick<NotificationItemProps, Exclude<keyof NotificationItemProps, 'image' | 'disableTypography' | 'primary' | 'primaryTypographyProps' | 'secondary' | 'secondaryTypographyProps' | 'actions' | 'footer' | 'isNew'>> {
|
|
4
|
+
/**
|
|
5
|
+
* Notification obj
|
|
6
|
+
* @default null
|
|
7
|
+
*/
|
|
8
|
+
notificationObject: SCNotificationGroupActivityType;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* This component render the content of the notification of type group
|
|
12
|
+
* @constructor
|
|
13
|
+
* @param props
|
|
14
|
+
*/
|
|
15
|
+
export default function GroupNotification(props: NotificationGroupProps): JSX.Element;
|