@selfcommunity/react-ui 0.7.9-alpha.8 → 0.7.9-alpha.81
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/ChangeGroupCover/ChangeGroupCover.js +6 -6
- package/lib/cjs/components/ChangeGroupPicture/ChangeGroupPicture.js +19 -16
- 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/Editor/Editor.js +2 -0
- package/lib/cjs/components/Editor/nodes/ImageNode.js +6 -0
- package/lib/cjs/components/Editor/plugins/ImagePlugin.js +4 -0
- package/lib/cjs/components/Editor/plugins/ToolbarPlugin.js +17 -3
- package/lib/cjs/components/FeedObject/Actions/Share/Share.js +18 -16
- 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/Footer/Footer.js +1 -1
- package/lib/cjs/components/Group/Group.d.ts +9 -1
- package/lib/cjs/components/Group/Group.js +18 -6
- package/lib/cjs/components/GroupAutocomplete/GroupAutocomplete.d.ts +0 -1
- package/lib/cjs/components/GroupAutocomplete/GroupAutocomplete.js +1 -2
- package/lib/cjs/components/GroupForm/GroupForm.js +64 -13
- package/lib/cjs/components/GroupHeader/GroupHeader.d.ts +6 -6
- package/lib/cjs/components/GroupHeader/GroupHeader.js +53 -12
- 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 +73 -0
- package/lib/cjs/components/GroupInvitedWidget/GroupInvitedWidget.js +220 -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 +12 -7
- package/lib/cjs/components/GroupRequestsWidget/GroupRequestsWidget.js +19 -9
- 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/NavigationSettingsIconButton/NavigationSettingsIconButton.js +4 -4
- package/lib/cjs/components/NavigationToolbar/NavigationToolbar.js +9 -2
- package/lib/cjs/components/NavigationToolbarMobile/NavigationToolbarMobile.d.ts +1 -0
- package/lib/cjs/components/NavigationToolbarMobile/NavigationToolbarMobile.js +9 -1
- 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 +7 -1
- package/lib/cjs/components/PrivateMessageComponent/PrivateMessageComponent.js +16 -8
- 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 +9 -4
- 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 +46 -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 -3
- package/lib/cjs/index.js +13 -4
- package/lib/cjs/types/index.d.ts +2 -1
- 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/ChangeGroupCover/ChangeGroupCover.js +6 -6
- package/lib/esm/components/ChangeGroupPicture/ChangeGroupPicture.js +19 -16
- 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/Editor/Editor.js +2 -0
- package/lib/esm/components/Editor/nodes/ImageNode.js +6 -0
- package/lib/esm/components/Editor/plugins/ImagePlugin.js +4 -0
- package/lib/esm/components/Editor/plugins/ToolbarPlugin.js +19 -5
- package/lib/esm/components/FeedObject/Actions/Share/Share.js +19 -17
- 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/Footer/Footer.js +2 -2
- package/lib/esm/components/Group/Group.d.ts +9 -1
- package/lib/esm/components/Group/Group.js +22 -10
- package/lib/esm/components/GroupAutocomplete/GroupAutocomplete.d.ts +0 -1
- package/lib/esm/components/GroupAutocomplete/GroupAutocomplete.js +1 -2
- package/lib/esm/components/GroupForm/GroupForm.js +64 -13
- package/lib/esm/components/GroupHeader/GroupHeader.d.ts +6 -6
- package/lib/esm/components/GroupHeader/GroupHeader.js +55 -14
- 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 +73 -0
- package/lib/esm/components/GroupInvitedWidget/GroupInvitedWidget.js +217 -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 +12 -7
- package/lib/esm/components/GroupRequestsWidget/GroupRequestsWidget.js +19 -9
- 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/NavigationSettingsIconButton/NavigationSettingsIconButton.js +4 -4
- package/lib/esm/components/NavigationToolbar/NavigationToolbar.js +10 -3
- package/lib/esm/components/NavigationToolbarMobile/NavigationToolbarMobile.d.ts +1 -0
- package/lib/esm/components/NavigationToolbarMobile/NavigationToolbarMobile.js +11 -3
- 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 +7 -1
- package/lib/esm/components/PrivateMessageComponent/PrivateMessageComponent.js +17 -9
- 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 +9 -4
- 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 +48 -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 -3
- package/lib/esm/index.js +6 -3
- package/lib/esm/types/index.d.ts +2 -1
- package/lib/umd/311.js +2 -0
- package/lib/umd/react-ui.js +1 -1
- package/package.json +9 -9
- package/lib/umd/871.js +0 -2
- /package/lib/umd/{871.js.LICENSE.txt → 311.js.LICENSE.txt} +0 -0
|
@@ -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 },
|
|
@@ -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 = {
|
|
@@ -100,6 +100,11 @@ export default function NavigationToolbar(inProps) {
|
|
|
100
100
|
}, [scPreferences.preferences]);
|
|
101
101
|
const privateMessagingEnabled = useMemo(() => scPreferences.features.includes(SCFeatureName.PRIVATE_MESSAGING), [scPreferences.features]);
|
|
102
102
|
const groupsEnabled = useMemo(() => scPreferences.features.includes(SCFeatureName.GROUPING), [scPreferences.features]);
|
|
103
|
+
const showComposer = useMemo(() => {
|
|
104
|
+
return (scPreferences.preferences[SCPreferences.CONFIGURATIONS_POST_ONLY_STAFF_ENABLED].value &&
|
|
105
|
+
!disableComposer &&
|
|
106
|
+
(!scPreferences.preferences[SCPreferences.CONFIGURATIONS_POST_ONLY_STAFF_ENABLED].value || UserUtils.isStaff(scUserContext.user)));
|
|
107
|
+
}, [scPreferences, disableComposer, scUserContext.user]);
|
|
103
108
|
// STATE
|
|
104
109
|
const [anchorNotification, setAnchorNotification] = React.useState(null);
|
|
105
110
|
// HANDLERS
|
|
@@ -121,7 +126,9 @@ export default function NavigationToolbar(inProps) {
|
|
|
121
126
|
preferences[SCPreferences.CONFIGURATIONS_EXPLORE_STREAM_ENABLED] &&
|
|
122
127
|
(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
128
|
React.createElement(Icon, null, "explore"))),
|
|
124
|
-
groupsEnabled && scUserContext.user && (React.createElement(IconButton, { className: classNames(classes.groups, {
|
|
129
|
+
groupsEnabled && scUserContext.user && (React.createElement(IconButton, { className: classNames(classes.groups, {
|
|
130
|
+
[classes.active]: value.startsWith(scRoutingContext.url(SCRoutes.GROUPS_SUBSCRIBED_ROUTE_NAME, {}))
|
|
131
|
+
}), "aria-label": "Groups", to: scRoutingContext.url(SCRoutes.GROUPS_SUBSCRIBED_ROUTE_NAME, {}), component: Link },
|
|
125
132
|
React.createElement(Icon, null, "groups")))));
|
|
126
133
|
return (React.createElement(Root, Object.assign({ className: classNames(className, classes.root) }, rest),
|
|
127
134
|
React.createElement(NavigationMenuIconButtonComponent, null),
|
|
@@ -133,7 +140,7 @@ export default function NavigationToolbar(inProps) {
|
|
|
133
140
|
(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
141
|
startActions,
|
|
135
142
|
scUserContext.user ? (React.createElement(React.Fragment, null,
|
|
136
|
-
|
|
143
|
+
showComposer && React.createElement(ComposerIconButton, Object.assign({ className: classes.composer }, ComposerIconButtonProps)),
|
|
137
144
|
React.createElement(Tooltip, { title: scUserContext.user.username },
|
|
138
145
|
React.createElement(IconButton, { component: Link, to: scRoutingContext.url(SCRoutes.USER_PROFILE_ROUTE_NAME, scUserContext.user), "aria-label": "Profile", className: classes.profile },
|
|
139
146
|
React.createElement(Avatar, { alt: scUserContext.user.username, src: scUserContext.user.avatar }))),
|
|
@@ -59,6 +59,7 @@ export interface NavigationToolbarMobileProps extends ToolbarProps {
|
|
|
59
59
|
|logo|.SCNavigationToolbarMobile-logo|Styles applied to the logo element.|
|
|
60
60
|
|search|.SCNavigationToolbarMobile-search|Styles applied to the search button element|
|
|
61
61
|
|searchDialog|.SCNavigationToolbarMobile-search-dialog|Styles applied to the search dialog element|
|
|
62
|
+
|notifications|.SCNavigationToolbarMobile-notifications|Styles applied to the notifications button element|
|
|
62
63
|
|settings|.SCNavigationToolbarMobile-settings|Styles applied to the settings button element|
|
|
63
64
|
|settingsDialog|.SCNavigationToolbarMobile-settingsDialog|Styles applied to the settings dialog elements|
|
|
64
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.|
|
|
@@ -67,9 +70,11 @@ export default function NavigationToolbarMobile(inProps) {
|
|
|
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);
|
|
@@ -92,6 +97,9 @@ export default function NavigationToolbarMobile(inProps) {
|
|
|
92
97
|
React.createElement(Icon, null, "search")),
|
|
93
98
|
React.createElement(SearchDialog, { className: classes.searchDialog, fullScreen: true, open: searchOpen, SearchAutocompleteProps: Object.assign(Object.assign({}, SearchAutocompleteProps), { onClear: handleCloseSearch }) }))),
|
|
94
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")))),
|
|
95
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, {}) },
|
|
96
104
|
React.createElement(FormattedMessage, { id: "ui.appBar.navigation.login", defaultMessage: "ui.appBar.navigation.login" })))));
|
|
97
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;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { __rest } from "tslib";
|
|
2
|
+
import React, { useContext, useEffect, useState } from 'react';
|
|
3
|
+
import { styled } from '@mui/material/styles';
|
|
4
|
+
import { Avatar, Box, Stack, Typography } from '@mui/material';
|
|
5
|
+
import { Link, SCRoutes, SCUserContext, useSCRouting } from '@selfcommunity/react-core';
|
|
6
|
+
import { SCGroupSubscriptionStatusType } from '@selfcommunity/types';
|
|
7
|
+
import { FormattedMessage } from 'react-intl';
|
|
8
|
+
import DateTimeAgo from '../../../shared/DateTimeAgo';
|
|
9
|
+
import classNames from 'classnames';
|
|
10
|
+
import { SCNotificationObjectTemplateType } from '../../../types';
|
|
11
|
+
import NotificationItem from '../../../shared/NotificationItem';
|
|
12
|
+
import { LoadingButton } from '@mui/lab';
|
|
13
|
+
import UserDeletedSnackBar from '../../../shared/UserDeletedSnackBar';
|
|
14
|
+
import UserAvatar from '../../../shared/UserAvatar';
|
|
15
|
+
import { PREFIX } from '../constants';
|
|
16
|
+
const classes = {
|
|
17
|
+
root: `${PREFIX}-group-root`,
|
|
18
|
+
avatar: `${PREFIX}-avatar`,
|
|
19
|
+
actions: `${PREFIX}-actions`,
|
|
20
|
+
acceptButton: `${PREFIX}-reply-button`,
|
|
21
|
+
activeAt: `${PREFIX}-active-at`,
|
|
22
|
+
username: `${PREFIX}-username`
|
|
23
|
+
};
|
|
24
|
+
const Root = styled(NotificationItem, {
|
|
25
|
+
name: PREFIX,
|
|
26
|
+
slot: 'GroupRoot'
|
|
27
|
+
})(() => ({}));
|
|
28
|
+
/**
|
|
29
|
+
* This component render the content of the notification of type group
|
|
30
|
+
* @constructor
|
|
31
|
+
* @param props
|
|
32
|
+
*/
|
|
33
|
+
export default function GroupNotification(props) {
|
|
34
|
+
// PROPS
|
|
35
|
+
const { notificationObject, id = `n_${props.notificationObject['sid']}`, className, template = SCNotificationObjectTemplateType.DETAIL } = props, rest = __rest(props, ["notificationObject", "id", "className", "template"]);
|
|
36
|
+
// CONTEXT
|
|
37
|
+
const scRoutingContext = useSCRouting();
|
|
38
|
+
const scUserContext = useContext(SCUserContext);
|
|
39
|
+
const manager = scUserContext.managers.groups;
|
|
40
|
+
// STATE
|
|
41
|
+
const [status, setStatus] = useState(null);
|
|
42
|
+
const [openAlert, setOpenAlert] = useState(false);
|
|
43
|
+
// CONST
|
|
44
|
+
const isSnippetTemplate = template === SCNotificationObjectTemplateType.SNIPPET;
|
|
45
|
+
const isToastTemplate = template === SCNotificationObjectTemplateType.TOAST;
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
setStatus(manager.subscriptionStatus(notificationObject.group));
|
|
48
|
+
}, [manager.subscriptionStatus, notificationObject.group]);
|
|
49
|
+
// RENDER
|
|
50
|
+
if (isSnippetTemplate || isToastTemplate) {
|
|
51
|
+
return (React.createElement(Root, Object.assign({ id: id, className: classNames(classes.root, className, `${PREFIX}-${template}`), template: template, isNew: notificationObject.is_new, disableTypography: true, image: React.createElement(Link, Object.assign({}, (!notificationObject.user.deleted && {
|
|
52
|
+
to: scRoutingContext.url(SCRoutes.USER_PROFILE_ROUTE_NAME, notificationObject.user)
|
|
53
|
+
}), { onClick: notificationObject.user.deleted ? () => setOpenAlert(true) : null }),
|
|
54
|
+
React.createElement(UserAvatar, { hide: !notificationObject.user.community_badge, smaller: true },
|
|
55
|
+
React.createElement(Avatar, { alt: notificationObject.user.username, variant: "circular", src: notificationObject.user.avatar, classes: { root: classes.avatar } }))), primary: React.createElement(Box, null,
|
|
56
|
+
React.createElement(Link, Object.assign({}, (!notificationObject.user.deleted && {
|
|
57
|
+
to: scRoutingContext.url(SCRoutes.USER_PROFILE_ROUTE_NAME, notificationObject.user)
|
|
58
|
+
}), { onClick: notificationObject.user.deleted ? () => setOpenAlert(true) : null, className: classes.username }), notificationObject.user.username),
|
|
59
|
+
' ',
|
|
60
|
+
React.createElement(FormattedMessage, { id: `ui.notification.${notificationObject.type}`, defaultMessage: `ui.notification.${notificationObject.type}`, values: {
|
|
61
|
+
group: notificationObject.group.name,
|
|
62
|
+
link: (...chunks) => React.createElement(Link, { to: scRoutingContext.url(SCRoutes.GROUP_ROUTE_NAME, notificationObject.group) }, chunks)
|
|
63
|
+
} })), footer: isToastTemplate && (React.createElement(Stack, { direction: "row", justifyContent: "space-between", alignItems: "center", spacing: 2 },
|
|
64
|
+
React.createElement(DateTimeAgo, { date: notificationObject.active_at }),
|
|
65
|
+
status && status !== SCGroupSubscriptionStatusType.SUBSCRIBED && (React.createElement(Typography, { color: "primary" },
|
|
66
|
+
React.createElement(Link, { to: scRoutingContext.url(SCRoutes.GROUP_ROUTE_NAME, notificationObject.group) },
|
|
67
|
+
React.createElement(FormattedMessage, { id: "ui.notification.group.button.see", defaultMessage: "ui.notification.group.button.see" })))))) }, rest)));
|
|
68
|
+
}
|
|
69
|
+
return (React.createElement(React.Fragment, null,
|
|
70
|
+
React.createElement(Root, Object.assign({ id: id, className: classNames(classes.root, className, `${PREFIX}-${template}`), template: template, isNew: notificationObject.is_new, disableTypography: true, actions: React.createElement(Stack, { direction: "row", justifyContent: "space-between", alignItems: "center", spacing: 2 },
|
|
71
|
+
React.createElement(DateTimeAgo, { date: notificationObject.active_at, className: classes.activeAt }),
|
|
72
|
+
status && status !== SCGroupSubscriptionStatusType.SUBSCRIBED && (React.createElement(LoadingButton, { color: 'primary', variant: "outlined", size: "small", classes: { root: classes.acceptButton }, component: Link, loading: scUserContext.user ? status === null || manager.isLoading(notificationObject.group) : null, to: scRoutingContext.url(SCRoutes.GROUP_ROUTE_NAME, notificationObject.group) },
|
|
73
|
+
React.createElement(FormattedMessage, { id: "ui.notification.group.button.see", defaultMessage: "ui.notification.group.button.see" })))) }, rest)),
|
|
74
|
+
openAlert && React.createElement(UserDeletedSnackBar, { open: openAlert, handleClose: () => setOpenAlert(false) })));
|
|
75
|
+
}
|
|
@@ -33,6 +33,7 @@ import { SCNotificationTypologyType } from '@selfcommunity/types';
|
|
|
33
33
|
import UserDeletedSnackBar from '../../shared/UserDeletedSnackBar';
|
|
34
34
|
import UserAvatar from '../../shared/UserAvatar';
|
|
35
35
|
import { PREFIX } from './constants';
|
|
36
|
+
import GroupNotification from './Group';
|
|
36
37
|
const messages = defineMessages({
|
|
37
38
|
receivePrivateMessage: {
|
|
38
39
|
id: 'ui.notification.receivePrivateMessage',
|
|
@@ -149,7 +150,7 @@ export default function UserNotification(inProps) {
|
|
|
149
150
|
}
|
|
150
151
|
/**
|
|
151
152
|
* Handles vote
|
|
152
|
-
* @param
|
|
153
|
+
* @param index
|
|
153
154
|
*/
|
|
154
155
|
const handleVote = (index) => {
|
|
155
156
|
return (contribution) => {
|
|
@@ -194,6 +195,29 @@ export default function UserNotification(inProps) {
|
|
|
194
195
|
b: (...chunks) => React.createElement("strong", null, chunks)
|
|
195
196
|
})) }));
|
|
196
197
|
}
|
|
198
|
+
/**
|
|
199
|
+
* Group notifications header
|
|
200
|
+
*/
|
|
201
|
+
if (notificationObject.aggregated &&
|
|
202
|
+
(notificationObject.aggregated[0].type === SCNotificationTypologyType.USER_INVITED_TO_JOIN_GROUP ||
|
|
203
|
+
notificationObject.aggregated[0].type === SCNotificationTypologyType.USER_ACCEPTED_TO_JOIN_GROUP ||
|
|
204
|
+
notificationObject.aggregated[0].type === SCNotificationTypologyType.USER_ADDED_TO_GROUP ||
|
|
205
|
+
notificationObject.aggregated[0].type === SCNotificationTypologyType.USER_REQUESTED_TO_JOIN_GROUP)) {
|
|
206
|
+
let groupNotification = notificationObject.aggregated[0];
|
|
207
|
+
return (React.createElement(CardHeader, { className: classes.header, avatar: React.createElement(Link, Object.assign({}, (!groupNotification.user.deleted && {
|
|
208
|
+
to: scRoutingContext.url(SCRoutes.USER_PROFILE_ROUTE_NAME, groupNotification.user)
|
|
209
|
+
}), { onClick: groupNotification.user.deleted ? () => setOpenAlert(true) : null }),
|
|
210
|
+
React.createElement(UserAvatar, { hide: !groupNotification.user.community_badge, smaller: true },
|
|
211
|
+
React.createElement(Avatar, { className: classes.avatar, alt: groupNotification.user.username, variant: "circular", src: groupNotification.user.avatar }))), titleTypographyProps: { className: classes.title, variant: 'subtitle1' }, title: React.createElement(React.Fragment, null,
|
|
212
|
+
React.createElement(Link, Object.assign({}, (!groupNotification.user.deleted && {
|
|
213
|
+
to: scRoutingContext.url(SCRoutes.USER_PROFILE_ROUTE_NAME, groupNotification.user)
|
|
214
|
+
}), { onClick: groupNotification.user.deleted ? () => setOpenAlert(true) : null, className: classes.username }), groupNotification.user.username),
|
|
215
|
+
' ',
|
|
216
|
+
React.createElement(FormattedMessage, { id: `ui.notification.${notificationObject.aggregated[0].type}`, defaultMessage: `ui.notification.${notificationObject.aggregated[0].type}`, values: {
|
|
217
|
+
group: groupNotification.group.name,
|
|
218
|
+
link: (...chunks) => React.createElement(Link, { to: scRoutingContext.url(SCRoutes.GROUP_ROUTE_NAME, groupNotification.group) }, chunks)
|
|
219
|
+
} })) }));
|
|
220
|
+
}
|
|
197
221
|
/**
|
|
198
222
|
* Comment, NestedComment, Follow Contribution header
|
|
199
223
|
*/
|
|
@@ -276,6 +300,12 @@ export default function UserNotification(inProps) {
|
|
|
276
300
|
else if (n.type === SCNotificationTypologyType.CONTRIBUTION) {
|
|
277
301
|
return React.createElement(ContributionNotification, { notificationObject: n, key: i, onVote: handleVote(i) });
|
|
278
302
|
}
|
|
303
|
+
else if (n.type === SCNotificationTypologyType.USER_ADDED_TO_GROUP ||
|
|
304
|
+
n.type === SCNotificationTypologyType.USER_INVITED_TO_JOIN_GROUP ||
|
|
305
|
+
n.type === SCNotificationTypologyType.USER_ACCEPTED_TO_JOIN_GROUP ||
|
|
306
|
+
n.type === SCNotificationTypologyType.USER_REQUESTED_TO_JOIN_GROUP) {
|
|
307
|
+
return React.createElement(GroupNotification, { notificationObject: n, key: i });
|
|
308
|
+
}
|
|
279
309
|
return null;
|
|
280
310
|
}
|
|
281
311
|
/**
|
|
@@ -39,6 +39,7 @@ const Root = styled(NotificationItem, {
|
|
|
39
39
|
* @param props
|
|
40
40
|
*/
|
|
41
41
|
export default function PrivateMessageNotification(props) {
|
|
42
|
+
var _a, _b, _c, _d, _e;
|
|
42
43
|
// PROPS
|
|
43
44
|
const { notificationObject, id = `n_${props.notificationObject['sid']}`, className, template = SCNotificationObjectTemplateType.DETAIL } = props, rest = __rest(props, ["notificationObject", "id", "className", "template"]);
|
|
44
45
|
// CONTEXT
|
|
@@ -89,7 +90,9 @@ export default function PrivateMessageNotification(props) {
|
|
|
89
90
|
React.createElement(FormattedMessage, { id: 'ui.userToastNotifications.privateMessage.sentMessage', defaultMessage: 'ui.userToastNotifications.privateMessage.sentMessage' }),
|
|
90
91
|
":",
|
|
91
92
|
React.createElement(Box, { className: classes.messageWrap },
|
|
92
|
-
React.createElement(Link, { to:
|
|
93
|
+
React.createElement(Link, { to: ((_a = notificationObject.message) === null || _a === void 0 ? void 0 : _a.group)
|
|
94
|
+
? scRoutingContext.url(SCRoutes.GROUP_MESSAGES_ROUTE_NAME, notificationObject.message.group)
|
|
95
|
+
: scRoutingContext.url(SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, notificationObject.message.sender), className: classes.message },
|
|
93
96
|
React.createElement(Typography, { variant: "body2", dangerouslySetInnerHTML: { __html: notificationObject.message.message } }))))),
|
|
94
97
|
isSnippetTemplate && (React.createElement(Box, null,
|
|
95
98
|
React.createElement(Typography, { component: "div", color: "inherit" },
|
|
@@ -97,13 +100,17 @@ export default function PrivateMessageNotification(props) {
|
|
|
97
100
|
to: scRoutingContext.url(SCRoutes.USER_PROFILE_ROUTE_NAME, notificationObject.message.sender)
|
|
98
101
|
}), { onClick: notificationObject.message.sender.deleted ? () => setOpenAlert(true) : null, className: classes.username }), notificationObject.message.sender.username),
|
|
99
102
|
' ',
|
|
100
|
-
React.createElement(Link, { to:
|
|
103
|
+
React.createElement(Link, { to: ((_b = notificationObject.message) === null || _b === void 0 ? void 0 : _b.group)
|
|
104
|
+
? scRoutingContext.url(SCRoutes.GROUP_MESSAGES_ROUTE_NAME, notificationObject.message.group)
|
|
105
|
+
: scRoutingContext.url(SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, notificationObject.message.sender), className: classes.messageLabel }, intl.formatMessage(messages.receivePrivateMessage, {
|
|
101
106
|
total: 1,
|
|
102
107
|
b: (...chunks) => React.createElement("strong", null, chunks)
|
|
103
108
|
})))))), footer: isToastTemplate && (React.createElement(Stack, { direction: "row", justifyContent: "space-between", alignItems: "center", spacing: 2 },
|
|
104
109
|
React.createElement(DateTimeAgo, { date: notificationObject.active_at }),
|
|
105
110
|
React.createElement(Typography, { color: "primary" },
|
|
106
|
-
React.createElement(Link, { to:
|
|
111
|
+
React.createElement(Link, { to: ((_c = notificationObject.message) === null || _c === void 0 ? void 0 : _c.group)
|
|
112
|
+
? scRoutingContext.url(SCRoutes.GROUP_MESSAGES_ROUTE_NAME, notificationObject.message.group)
|
|
113
|
+
: scRoutingContext.url(SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, notificationObject.message.sender) }, scUserContext.user && follower ? (React.createElement(FormattedMessage, { id: "ui.userToastNotifications.replyMessage", defaultMessage: 'ui.userToastNotifications.replyMessage' })) : (React.createElement(FormattedMessage, { id: "ui.userToastNotifications.viewMessage", defaultMessage: 'ui.userToastNotifications.viewMessage' })))))) }, rest)));
|
|
107
114
|
}
|
|
108
115
|
return (React.createElement(React.Fragment, null,
|
|
109
116
|
React.createElement(Root, Object.assign({ id: id, className: classNames(classes.root, className, `${PREFIX}-${template}`), template: template, isNew: notificationObject.is_new, disableTypography: true, actions: React.createElement(Stack, { direction: "row", justifyContent: "space-between", alignItems: "center", spacing: 2 },
|
|
@@ -112,8 +119,12 @@ export default function PrivateMessageNotification(props) {
|
|
|
112
119
|
? null
|
|
113
120
|
: scUserContext.user
|
|
114
121
|
? follower === null || manager.isLoading(notificationObject.message.sender)
|
|
115
|
-
: null, to:
|
|
116
|
-
|
|
122
|
+
: null, to: ((_d = notificationObject.message) === null || _d === void 0 ? void 0 : _d.group)
|
|
123
|
+
? scRoutingContext.url(SCRoutes.GROUP_MESSAGES_ROUTE_NAME, notificationObject.message.group)
|
|
124
|
+
: scRoutingContext.url(SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, notificationObject.message.sender) }, scUserContext.user && follower ? (React.createElement(FormattedMessage, { id: "ui.notification.privateMessage.btnReplyLabel", defaultMessage: "ui.notification.privateMessage.btnReplyLabel" })) : (React.createElement(FormattedMessage, { id: "ui.notification.privateMessage.btnViewLabel", defaultMessage: "ui.notification.privateMessage.btnViewLabel" })))), primary: React.createElement(Box, { className: classes.messageWrap },
|
|
125
|
+
React.createElement(Link, { to: ((_e = notificationObject.message) === null || _e === void 0 ? void 0 : _e.group)
|
|
126
|
+
? scRoutingContext.url(SCRoutes.GROUP_MESSAGES_ROUTE_NAME, notificationObject.message.group)
|
|
127
|
+
: scRoutingContext.url(SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, notificationObject.message.sender), className: classes.message },
|
|
117
128
|
React.createElement(Typography, { variant: "body2", dangerouslySetInnerHTML: { __html: notificationObject.message.message } }))) }, rest)),
|
|
118
129
|
openAlert && React.createElement(UserDeletedSnackBar, { open: openAlert, handleClose: () => setOpenAlert(false) })));
|
|
119
130
|
}
|
|
@@ -1,14 +1,20 @@
|
|
|
1
|
+
import { SCPrivateMessageType } from '@selfcommunity/types';
|
|
1
2
|
export interface PrivateMessageComponentProps {
|
|
2
3
|
/**
|
|
3
4
|
* Thread receiver id
|
|
4
5
|
* @default null
|
|
5
6
|
*/
|
|
6
7
|
id?: number | string;
|
|
8
|
+
/**
|
|
9
|
+
* Thread type
|
|
10
|
+
* @default null
|
|
11
|
+
*/
|
|
12
|
+
type?: SCPrivateMessageType;
|
|
7
13
|
/**
|
|
8
14
|
* Handler on message click
|
|
9
15
|
* @default null
|
|
10
16
|
*/
|
|
11
|
-
onItemClick?: (id: any) => void;
|
|
17
|
+
onItemClick?: (id: any, type: any) => void;
|
|
12
18
|
/**
|
|
13
19
|
* Handler on single message open
|
|
14
20
|
* @default null
|
|
@@ -5,7 +5,7 @@ import { Grid, useMediaQuery, useTheme } from '@mui/material';
|
|
|
5
5
|
import { useSCPreferences, useSCUser } from '@selfcommunity/react-core';
|
|
6
6
|
import classNames from 'classnames';
|
|
7
7
|
import { useThemeProps } from '@mui/system';
|
|
8
|
-
import { SCFeatureName, SCPrivateMessageStatusType } from '@selfcommunity/types';
|
|
8
|
+
import { SCFeatureName, SCPrivateMessageStatusType, SCPrivateMessageType } from '@selfcommunity/types';
|
|
9
9
|
import PrivateMessageThread from '../PrivateMessageThread';
|
|
10
10
|
import PrivateMessageSnippets from '../PrivateMessageSnippets';
|
|
11
11
|
import { PREFIX } from './constants';
|
|
@@ -55,7 +55,7 @@ export default function PrivateMessageComponent(inProps) {
|
|
|
55
55
|
props: inProps,
|
|
56
56
|
name: PREFIX
|
|
57
57
|
});
|
|
58
|
-
const { id = null, className = null, onItemClick = null, onThreadBack = null, onSingleMessageOpen = null } = props, rest = __rest(props, ["id", "className", "onItemClick", "onThreadBack", "onSingleMessageOpen"]);
|
|
58
|
+
const { id = null, type = null, className = null, onItemClick = null, onThreadBack = null, onSingleMessageOpen = null } = props, rest = __rest(props, ["id", "type", "className", "onItemClick", "onThreadBack", "onSingleMessageOpen"]);
|
|
59
59
|
// CONTEXT
|
|
60
60
|
const scUserContext = useSCUser();
|
|
61
61
|
const scPreferences = useSCPreferences();
|
|
@@ -65,6 +65,7 @@ export default function PrivateMessageComponent(inProps) {
|
|
|
65
65
|
const isMobile = useMediaQuery(theme.breakpoints.down('md'));
|
|
66
66
|
const [layout, setLayout] = useState('default');
|
|
67
67
|
const [obj, setObj] = useState(id !== null && id !== void 0 ? id : null);
|
|
68
|
+
const [_type, _setType] = useState(type);
|
|
68
69
|
const isNew = obj && obj === SCPrivateMessageStatusType.NEW;
|
|
69
70
|
const [openNewMessage, setOpenNewMessage] = useState(isNew !== null && isNew !== void 0 ? isNew : false);
|
|
70
71
|
const mobileSnippetsView = (layout === 'default' && !obj) || (layout === 'mobile' && !obj);
|
|
@@ -82,14 +83,19 @@ export default function PrivateMessageComponent(inProps) {
|
|
|
82
83
|
useEffect(() => {
|
|
83
84
|
setObj(id !== null && id !== void 0 ? id : null);
|
|
84
85
|
}, [id]);
|
|
86
|
+
useEffect(() => {
|
|
87
|
+
_setType(type !== null && type !== void 0 ? type : null);
|
|
88
|
+
}, [type]);
|
|
85
89
|
// HANDLERS
|
|
86
90
|
/**
|
|
87
91
|
* Handles thread opening on click
|
|
88
92
|
* @param item
|
|
93
|
+
* @param type
|
|
89
94
|
*/
|
|
90
|
-
const handleThreadOpening = (item) => {
|
|
91
|
-
onItemClick && onItemClick(messageReceiver(item, authUserId));
|
|
92
|
-
|
|
95
|
+
const handleThreadOpening = (item, type) => {
|
|
96
|
+
onItemClick && onItemClick(item.group ? item.group.id : messageReceiver(item, authUserId), type);
|
|
97
|
+
_setType(type);
|
|
98
|
+
setObj(item.group ? item : messageReceiver(item, authUserId));
|
|
93
99
|
setOpenNewMessage(false);
|
|
94
100
|
};
|
|
95
101
|
/**
|
|
@@ -105,7 +111,8 @@ export default function PrivateMessageComponent(inProps) {
|
|
|
105
111
|
const handleOpenNewMessage = () => {
|
|
106
112
|
setOpenNewMessage(!openNewMessage);
|
|
107
113
|
setObj(SCPrivateMessageStatusType.NEW);
|
|
108
|
-
|
|
114
|
+
_setType(SCPrivateMessageType.NEW);
|
|
115
|
+
onItemClick && onItemClick(SCPrivateMessageStatusType.NEW, SCPrivateMessageType.NEW);
|
|
109
116
|
};
|
|
110
117
|
/**
|
|
111
118
|
* Handles new messages open from user profile page or notifications section
|
|
@@ -121,13 +128,14 @@ export default function PrivateMessageComponent(inProps) {
|
|
|
121
128
|
id && setLayout('mobile');
|
|
122
129
|
setOpenNewMessage(false);
|
|
123
130
|
setObj(null);
|
|
131
|
+
_setType(null);
|
|
124
132
|
onThreadBack && onThreadBack();
|
|
125
133
|
};
|
|
126
134
|
/**
|
|
127
135
|
* Handles state update when a new message is sent
|
|
128
136
|
*/
|
|
129
137
|
const handleOnNewMessageSent = (msg, isOne) => {
|
|
130
|
-
onItemClick && onItemClick(isOne ? messageReceiver(msg, authUserId) : '');
|
|
138
|
+
onItemClick && onItemClick(isOne ? messageReceiver(msg, authUserId) : '', msg.group ? SCPrivateMessageType.GROUP : SCPrivateMessageType.USER);
|
|
131
139
|
setObj(isOne ? messageReceiver(msg, authUserId) : null);
|
|
132
140
|
setOpenNewMessage(false);
|
|
133
141
|
};
|
|
@@ -147,14 +155,14 @@ export default function PrivateMessageComponent(inProps) {
|
|
|
147
155
|
onSnippetClick: handleThreadOpening,
|
|
148
156
|
onNewMessageClick: handleOpenNewMessage,
|
|
149
157
|
onDeleteConfirm: handleDeleteThread
|
|
150
|
-
},
|
|
158
|
+
}, threadObj: obj, clearSearch: clear, elevation: 0, type: _type })));
|
|
151
159
|
}
|
|
152
160
|
/**
|
|
153
161
|
* Renders thread section
|
|
154
162
|
*/
|
|
155
163
|
function renderThread() {
|
|
156
164
|
return (React.createElement(Grid, { item: true, xs: 12, md: 7, className: classNames(classes.threadBox, { [classes.hide]: isMobile && mobileSnippetsView }) },
|
|
157
|
-
React.createElement(PrivateMessageThread, {
|
|
165
|
+
React.createElement(PrivateMessageThread, { threadObj: obj, type: _type, openNewMessage: openNewMessage, onNewMessageClose: handleMessageBack, onNewMessageSent: handleOnNewMessageSent, onSingleMessageOpen: handleSingleMessage, elevation: 0 })));
|
|
158
166
|
}
|
|
159
167
|
/**
|
|
160
168
|
* Renders the component (if not hidden by autoHide prop)
|
package/lib/esm/components/PrivateMessageSettingsIconButton/PrivateMessageSettingsIconButton.js
CHANGED
|
@@ -114,7 +114,7 @@ export default function PrivateMessageSettingsIconButton(inProps) {
|
|
|
114
114
|
}
|
|
115
115
|
else {
|
|
116
116
|
return [
|
|
117
|
-
user && (React.createElement(MenuItem, { className: classes.item, component: Link, to: scRoutingContext.url(SCRoutes.USER_PROFILE_ROUTE_NAME, user), key: "profile" },
|
|
117
|
+
user && (React.createElement(MenuItem, { className: classes.item, component: Link, to: scRoutingContext.url(SCRoutes.USER_PROFILE_ROUTE_NAME, user), key: "profile", onClick: handleCloseDialog },
|
|
118
118
|
React.createElement(ListItemIcon, null,
|
|
119
119
|
React.createElement(Icon, { fontSize: "small" }, "people_alt")),
|
|
120
120
|
React.createElement(FormattedMessage, { id: "ui.privateMessageSettingsIconButton.item.profile", defaultMessage: "ui.privateMessageSettingsIconButton.item.profile" }))),
|
|
@@ -72,10 +72,12 @@ export default function PrivateMessageSnippetItem(inProps) {
|
|
|
72
72
|
// STATE
|
|
73
73
|
const hasBadge = () => {
|
|
74
74
|
var _a;
|
|
75
|
-
if (
|
|
76
|
-
|
|
75
|
+
if (message.receiver) {
|
|
76
|
+
if ((message === null || message === void 0 ? void 0 : message.receiver.id) !== ((_a = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _a === void 0 ? void 0 : _a.id)) {
|
|
77
|
+
return message === null || message === void 0 ? void 0 : message.receiver.community_badge;
|
|
78
|
+
}
|
|
79
|
+
return message === null || message === void 0 ? void 0 : message.sender.community_badge;
|
|
77
80
|
}
|
|
78
|
-
return message === null || message === void 0 ? void 0 : message.sender.community_badge;
|
|
79
81
|
};
|
|
80
82
|
if (!message) {
|
|
81
83
|
return React.createElement(PrivateMessageSnippetItemSkeleton, { elevation: 0 });
|
|
@@ -86,10 +88,13 @@ export default function PrivateMessageSnippetItem(inProps) {
|
|
|
86
88
|
return (React.createElement(Root, Object.assign({ className: classNames(classes.root, className) }, rest, { secondaryAction: secondaryAction, disablePadding: true }),
|
|
87
89
|
React.createElement(ListItemButton, { onClick: onItemClick, classes: { root: classNames({ [classes.unread]: message.thread_status === SCPrivateMessageStatusType.NEW }) } },
|
|
88
90
|
React.createElement(ListItemAvatar, null,
|
|
89
|
-
React.createElement(UserAvatar, { hide: !hasBadge() },
|
|
90
|
-
React.createElement(Avatar, { alt: ((_a = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _a === void 0 ? void 0 : _a.username) === message.receiver.username ? message.sender.username : message.receiver.username, src: ((_b = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _b === void 0 ? void 0 : _b.username) === message.receiver.username ? message.sender.avatar : message.receiver.avatar }))),
|
|
91
|
+
React.createElement(UserAvatar, { hide: !hasBadge() }, message.group ? (React.createElement(Avatar, { alt: message.group.name, src: message.group.image_big })) : (React.createElement(Avatar, { alt: ((_a = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _a === void 0 ? void 0 : _a.username) === message.receiver.username ? message.sender.username : message.receiver.username, src: ((_b = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _b === void 0 ? void 0 : _b.username) === message.receiver.username ? message.sender.avatar : message.receiver.avatar })))),
|
|
91
92
|
React.createElement(ListItemText, { primary: React.createElement(React.Fragment, null,
|
|
92
|
-
React.createElement(Typography, { component: "span", className: classes.username },
|
|
93
|
+
React.createElement(Typography, { component: "span", className: classes.username }, message.group
|
|
94
|
+
? message.group.name
|
|
95
|
+
: ((_c = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _c === void 0 ? void 0 : _c.username) === message.receiver.username
|
|
96
|
+
? message.sender.username
|
|
97
|
+
: message.receiver.username),
|
|
93
98
|
hasBadge() && preferences && (React.createElement(Chip, { component: "span", className: classes.badgeLabel, size: "small", label: preferences[SCPreferences.STAFF_STAFF_BADGE_LABEL] })),
|
|
94
99
|
React.createElement(Typography, { color: "secondary", className: classes.time, component: "span" }, `${intl.formatDate(message.last_message_at, {
|
|
95
100
|
day: '2-digit',
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CardProps } from '@mui/material';
|
|
2
|
-
import { SCPrivateMessageSnippetType } from '@selfcommunity/types';
|
|
2
|
+
import { SCPrivateMessageSnippetType, SCPrivateMessageType } from '@selfcommunity/types';
|
|
3
3
|
export interface PrivateMessageSnippetsProps extends CardProps {
|
|
4
4
|
/**
|
|
5
5
|
* Snippets list
|
|
@@ -20,7 +20,7 @@ export interface PrivateMessageSnippetsProps extends CardProps {
|
|
|
20
20
|
*
|
|
21
21
|
*/
|
|
22
22
|
snippetActions?: {
|
|
23
|
-
onSnippetClick?: (msg: any) => void;
|
|
23
|
+
onSnippetClick?: (msg: any, type: any) => void;
|
|
24
24
|
onNewMessageClick?: () => void;
|
|
25
25
|
onDeleteConfirm?: (msg: any) => void;
|
|
26
26
|
};
|
|
@@ -29,10 +29,15 @@ export interface PrivateMessageSnippetsProps extends CardProps {
|
|
|
29
29
|
*/
|
|
30
30
|
[p: string]: any;
|
|
31
31
|
/**
|
|
32
|
-
* thread user object
|
|
32
|
+
* thread user/ group object
|
|
33
33
|
* @default null
|
|
34
34
|
*/
|
|
35
|
-
|
|
35
|
+
threadObj?: any;
|
|
36
|
+
/**
|
|
37
|
+
* Thread type
|
|
38
|
+
* @default SCPrivateMessageType.USER
|
|
39
|
+
*/
|
|
40
|
+
type?: SCPrivateMessageType;
|
|
36
41
|
}
|
|
37
42
|
/**
|
|
38
43
|
* > API documentation for the Community-JS PrivateMessageSnippets component. Learn about the available props and the CSS API.
|