@selfcommunity/react-ui 0.7.9-alpha.6 → 0.7.9-alpha.61

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.
Files changed (160) hide show
  1. package/lib/cjs/components/BottomNavigation/BottomNavigation.js +2 -2
  2. package/lib/cjs/components/CategoryHeader/Skeleton.js +3 -2
  3. package/lib/cjs/components/ChangeGroupCover/ChangeGroupCover.js +24 -1
  4. package/lib/cjs/components/ChangeGroupPicture/ChangeGroupPicture.js +32 -11
  5. package/lib/cjs/components/Composer/Attributes/Attributes.js +3 -3
  6. package/lib/cjs/components/Composer/Composer.js +3 -3
  7. package/lib/cjs/components/Composer/Layer/AudienceLayer/AudienceLayer.d.ts +1 -1
  8. package/lib/cjs/components/Composer/Layer/AudienceLayer/AudienceLayer.js +9 -19
  9. package/lib/cjs/components/FeedObject/Contributors/Contributors.js +1 -1
  10. package/lib/cjs/components/FeedObject/FeedObject.d.ts +1 -0
  11. package/lib/cjs/components/FeedObject/FeedObject.js +23 -6
  12. package/lib/cjs/components/FeedUpdatesWidget/FeedUpdatesWidget.js +1 -1
  13. package/lib/cjs/components/Group/Group.d.ts +8 -0
  14. package/lib/cjs/components/Group/Group.js +40 -5
  15. package/lib/cjs/components/GroupAutocomplete/GroupAutocomplete.js +1 -1
  16. package/lib/cjs/components/GroupForm/GroupForm.js +33 -10
  17. package/lib/cjs/components/GroupHeader/GroupHeader.d.ts +6 -5
  18. package/lib/cjs/components/GroupHeader/GroupHeader.js +53 -11
  19. package/lib/cjs/components/GroupInfoWidget/GroupInfoWidget.js +40 -7
  20. package/lib/cjs/components/GroupInviteButton/GroupInviteButton.js +33 -11
  21. package/lib/cjs/components/GroupInvitedWidget/GroupInvitedWidget.d.ts +74 -0
  22. package/lib/cjs/components/GroupInvitedWidget/GroupInvitedWidget.js +221 -0
  23. package/lib/cjs/components/GroupInvitedWidget/Skeleton.d.ts +22 -0
  24. package/lib/cjs/components/GroupInvitedWidget/Skeleton.js +38 -0
  25. package/lib/cjs/components/GroupInvitedWidget/constants.d.ts +1 -0
  26. package/lib/cjs/components/GroupInvitedWidget/constants.js +4 -0
  27. package/lib/cjs/components/GroupInvitedWidget/index.d.ts +4 -0
  28. package/lib/cjs/components/GroupInvitedWidget/index.js +8 -0
  29. package/lib/cjs/components/GroupMembersButton/GroupMembersButton.d.ts +5 -0
  30. package/lib/cjs/components/GroupMembersButton/GroupMembersButton.js +8 -3
  31. package/lib/cjs/components/GroupMembersWidget/GroupMembersWidget.js +25 -4
  32. package/lib/cjs/components/GroupRequestsWidget/GroupRequestsWidget.d.ts +11 -5
  33. package/lib/cjs/components/GroupRequestsWidget/GroupRequestsWidget.js +18 -7
  34. package/lib/cjs/components/GroupSettingsIconButton/GroupSettingsIconButton.d.ts +48 -0
  35. package/lib/cjs/components/GroupSettingsIconButton/GroupSettingsIconButton.js +145 -0
  36. package/lib/cjs/components/GroupSettingsIconButton/index.d.ts +3 -0
  37. package/lib/cjs/components/GroupSettingsIconButton/index.js +5 -0
  38. package/lib/cjs/components/GroupSubscribeButton/GroupSubscribeButton.d.ts +8 -3
  39. package/lib/cjs/components/GroupSubscribeButton/GroupSubscribeButton.js +30 -11
  40. package/lib/cjs/components/Groups/Groups.d.ts +19 -16
  41. package/lib/cjs/components/Groups/Groups.js +85 -86
  42. package/lib/cjs/components/Groups/Skeleton.d.ts +4 -0
  43. package/lib/cjs/components/Groups/Skeleton.js +2 -2
  44. package/lib/cjs/components/NavigationMenuIconButton/NavigationMenuIconButton.js +1 -1
  45. package/lib/cjs/components/NavigationToolbar/NavigationToolbar.js +1 -1
  46. package/lib/cjs/components/NavigationToolbarMobile/NavigationToolbarMobile.d.ts +5 -0
  47. package/lib/cjs/components/NavigationToolbarMobile/NavigationToolbarMobile.js +11 -4
  48. package/lib/cjs/components/Notification/Group/Group.d.ts +15 -0
  49. package/lib/cjs/components/Notification/Group/Group.js +78 -0
  50. package/lib/cjs/components/Notification/Group/index.d.ts +3 -0
  51. package/lib/cjs/components/Notification/Group/index.js +5 -0
  52. package/lib/cjs/components/Notification/Notification.js +31 -1
  53. package/lib/cjs/components/Notification/PrivateMessage/PrivateMessage.js +16 -5
  54. package/lib/cjs/components/PrivateMessageComponent/PrivateMessageComponent.d.ts +1 -1
  55. package/lib/cjs/components/PrivateMessageComponent/PrivateMessageComponent.js +12 -7
  56. package/lib/cjs/components/PrivateMessageSnippetItem/PrivateMessageSnippetItem.js +11 -6
  57. package/lib/cjs/components/PrivateMessageSnippets/PrivateMessageSnippets.d.ts +3 -3
  58. package/lib/cjs/components/PrivateMessageSnippets/PrivateMessageSnippets.js +24 -6
  59. package/lib/cjs/components/PrivateMessageThread/PrivateMessageThread.d.ts +6 -1
  60. package/lib/cjs/components/PrivateMessageThread/PrivateMessageThread.js +45 -20
  61. package/lib/cjs/components/PrivateMessageThreadItem/PrivateMessageThreadItem.js +6 -0
  62. package/lib/cjs/components/SearchAutocomplete/SearchAutocomplete.js +22 -5
  63. package/lib/cjs/components/SnippetNotifications/SnippetNotifications.js +7 -0
  64. package/lib/cjs/components/ToastNotifications/ToastNotifications.js +7 -0
  65. package/lib/cjs/components/User/User.d.ts +6 -1
  66. package/lib/cjs/components/User/User.js +5 -4
  67. package/lib/cjs/components/UserSubscribedGroupsWidget/Skeleton.d.ts +21 -0
  68. package/lib/cjs/components/UserSubscribedGroupsWidget/Skeleton.js +46 -0
  69. package/lib/cjs/components/UserSubscribedGroupsWidget/UserSubscribedGroupsWidget.d.ts +68 -0
  70. package/lib/cjs/components/UserSubscribedGroupsWidget/UserSubscribedGroupsWidget.js +183 -0
  71. package/lib/cjs/components/UserSubscribedGroupsWidget/constants.d.ts +1 -0
  72. package/lib/cjs/components/UserSubscribedGroupsWidget/constants.js +4 -0
  73. package/lib/cjs/components/UserSubscribedGroupsWidget/index.d.ts +4 -0
  74. package/lib/cjs/components/UserSubscribedGroupsWidget/index.js +8 -0
  75. package/lib/cjs/components/VoteAudienceButton/VoteAudienceButton.js +1 -1
  76. package/lib/cjs/constants/PubSub.d.ts +28 -0
  77. package/lib/cjs/constants/PubSub.js +22 -0
  78. package/lib/cjs/index.d.ts +6 -2
  79. package/lib/cjs/index.js +15 -4
  80. package/lib/esm/components/BottomNavigation/BottomNavigation.js +2 -2
  81. package/lib/esm/components/CategoryHeader/Skeleton.js +3 -2
  82. package/lib/esm/components/ChangeGroupCover/ChangeGroupCover.js +24 -1
  83. package/lib/esm/components/ChangeGroupPicture/ChangeGroupPicture.js +32 -11
  84. package/lib/esm/components/Composer/Attributes/Attributes.js +3 -3
  85. package/lib/esm/components/Composer/Composer.js +3 -3
  86. package/lib/esm/components/Composer/Layer/AudienceLayer/AudienceLayer.d.ts +1 -1
  87. package/lib/esm/components/Composer/Layer/AudienceLayer/AudienceLayer.js +9 -19
  88. package/lib/esm/components/FeedObject/Contributors/Contributors.js +1 -1
  89. package/lib/esm/components/FeedObject/FeedObject.d.ts +1 -0
  90. package/lib/esm/components/FeedObject/FeedObject.js +24 -7
  91. package/lib/esm/components/FeedUpdatesWidget/FeedUpdatesWidget.js +1 -1
  92. package/lib/esm/components/Group/Group.d.ts +8 -0
  93. package/lib/esm/components/Group/Group.js +44 -9
  94. package/lib/esm/components/GroupAutocomplete/GroupAutocomplete.js +1 -1
  95. package/lib/esm/components/GroupForm/GroupForm.js +33 -10
  96. package/lib/esm/components/GroupHeader/GroupHeader.d.ts +6 -5
  97. package/lib/esm/components/GroupHeader/GroupHeader.js +55 -13
  98. package/lib/esm/components/GroupInfoWidget/GroupInfoWidget.js +40 -7
  99. package/lib/esm/components/GroupInviteButton/GroupInviteButton.js +33 -11
  100. package/lib/esm/components/GroupInvitedWidget/GroupInvitedWidget.d.ts +74 -0
  101. package/lib/esm/components/GroupInvitedWidget/GroupInvitedWidget.js +218 -0
  102. package/lib/esm/components/GroupInvitedWidget/Skeleton.d.ts +22 -0
  103. package/lib/esm/components/GroupInvitedWidget/Skeleton.js +34 -0
  104. package/lib/esm/components/GroupInvitedWidget/constants.d.ts +1 -0
  105. package/lib/esm/components/GroupInvitedWidget/constants.js +1 -0
  106. package/lib/esm/components/GroupInvitedWidget/index.d.ts +4 -0
  107. package/lib/esm/components/GroupInvitedWidget/index.js +4 -0
  108. package/lib/esm/components/GroupMembersButton/GroupMembersButton.d.ts +5 -0
  109. package/lib/esm/components/GroupMembersButton/GroupMembersButton.js +9 -4
  110. package/lib/esm/components/GroupMembersWidget/GroupMembersWidget.js +26 -5
  111. package/lib/esm/components/GroupRequestsWidget/GroupRequestsWidget.d.ts +11 -5
  112. package/lib/esm/components/GroupRequestsWidget/GroupRequestsWidget.js +18 -7
  113. package/lib/esm/components/GroupSettingsIconButton/GroupSettingsIconButton.d.ts +48 -0
  114. package/lib/esm/components/GroupSettingsIconButton/GroupSettingsIconButton.js +142 -0
  115. package/lib/esm/components/GroupSettingsIconButton/index.d.ts +3 -0
  116. package/lib/esm/components/GroupSettingsIconButton/index.js +2 -0
  117. package/lib/esm/components/GroupSubscribeButton/GroupSubscribeButton.d.ts +8 -3
  118. package/lib/esm/components/GroupSubscribeButton/GroupSubscribeButton.js +30 -11
  119. package/lib/esm/components/Groups/Groups.d.ts +19 -16
  120. package/lib/esm/components/Groups/Groups.js +90 -91
  121. package/lib/esm/components/Groups/Skeleton.d.ts +4 -0
  122. package/lib/esm/components/Groups/Skeleton.js +2 -2
  123. package/lib/esm/components/NavigationMenuIconButton/NavigationMenuIconButton.js +1 -1
  124. package/lib/esm/components/NavigationToolbar/NavigationToolbar.js +1 -1
  125. package/lib/esm/components/NavigationToolbarMobile/NavigationToolbarMobile.d.ts +5 -0
  126. package/lib/esm/components/NavigationToolbarMobile/NavigationToolbarMobile.js +13 -6
  127. package/lib/esm/components/Notification/Group/Group.d.ts +15 -0
  128. package/lib/esm/components/Notification/Group/Group.js +75 -0
  129. package/lib/esm/components/Notification/Group/index.d.ts +3 -0
  130. package/lib/esm/components/Notification/Group/index.js +2 -0
  131. package/lib/esm/components/Notification/Notification.js +31 -1
  132. package/lib/esm/components/Notification/PrivateMessage/PrivateMessage.js +16 -5
  133. package/lib/esm/components/PrivateMessageComponent/PrivateMessageComponent.d.ts +1 -1
  134. package/lib/esm/components/PrivateMessageComponent/PrivateMessageComponent.js +13 -8
  135. package/lib/esm/components/PrivateMessageSnippetItem/PrivateMessageSnippetItem.js +11 -6
  136. package/lib/esm/components/PrivateMessageSnippets/PrivateMessageSnippets.d.ts +3 -3
  137. package/lib/esm/components/PrivateMessageSnippets/PrivateMessageSnippets.js +26 -8
  138. package/lib/esm/components/PrivateMessageThread/PrivateMessageThread.d.ts +6 -1
  139. package/lib/esm/components/PrivateMessageThread/PrivateMessageThread.js +47 -22
  140. package/lib/esm/components/PrivateMessageThreadItem/PrivateMessageThreadItem.js +7 -1
  141. package/lib/esm/components/SearchAutocomplete/SearchAutocomplete.js +22 -5
  142. package/lib/esm/components/SnippetNotifications/SnippetNotifications.js +7 -0
  143. package/lib/esm/components/ToastNotifications/ToastNotifications.js +7 -0
  144. package/lib/esm/components/User/User.d.ts +6 -1
  145. package/lib/esm/components/User/User.js +5 -4
  146. package/lib/esm/components/UserSubscribedGroupsWidget/Skeleton.d.ts +21 -0
  147. package/lib/esm/components/UserSubscribedGroupsWidget/Skeleton.js +42 -0
  148. package/lib/esm/components/UserSubscribedGroupsWidget/UserSubscribedGroupsWidget.d.ts +68 -0
  149. package/lib/esm/components/UserSubscribedGroupsWidget/UserSubscribedGroupsWidget.js +180 -0
  150. package/lib/esm/components/UserSubscribedGroupsWidget/constants.d.ts +1 -0
  151. package/lib/esm/components/UserSubscribedGroupsWidget/constants.js +1 -0
  152. package/lib/esm/components/UserSubscribedGroupsWidget/index.d.ts +4 -0
  153. package/lib/esm/components/UserSubscribedGroupsWidget/index.js +4 -0
  154. package/lib/esm/components/VoteAudienceButton/VoteAudienceButton.js +1 -1
  155. package/lib/esm/constants/PubSub.d.ts +28 -0
  156. package/lib/esm/constants/PubSub.js +19 -0
  157. package/lib/esm/index.d.ts +6 -2
  158. package/lib/esm/index.js +8 -4
  159. package/lib/umd/react-ui.js +1 -1
  160. package/package.json +6 -6
@@ -1,11 +1,10 @@
1
1
  import { __rest } from "tslib";
2
- import React, { useEffect, useMemo, useReducer } from 'react';
2
+ import React, { useEffect, useMemo, useState } from 'react';
3
3
  import { styled } from '@mui/material/styles';
4
- import { Box, Button, Grid, Typography } from '@mui/material';
5
- import { http } from '@selfcommunity/api-services';
6
- import { CacheStrategies, Logger } from '@selfcommunity/utils';
7
- import { SCCache, SCPreferences, useSCPreferences, useSCUser } from '@selfcommunity/react-core';
8
- import { actionWidgetTypes, dataWidgetReducer, stateWidgetInitializer } from '../../utils/widget';
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';
9
8
  import Skeleton from './Skeleton';
10
9
  import { FormattedMessage } from 'react-intl';
11
10
  import classNames from 'classnames';
@@ -13,9 +12,12 @@ import { SCOPE_SC_UI } from '../../constants/Errors';
13
12
  import { useThemeProps } from '@mui/system';
14
13
  import HiddenPlaceholder from '../../shared/HiddenPlaceholder';
15
14
  import { PREFIX } from './constants';
16
- import Group from '../Group';
15
+ import Group, { GroupSkeleton } from '../Group';
16
+ import { DEFAULT_PAGINATION_OFFSET } from '../../constants/Pagination';
17
+ import InfiniteScroll from '../../shared/InfiniteScroll';
17
18
  const classes = {
18
19
  root: `${PREFIX}-root`,
20
+ filters: `${PREFIX}-filter`,
19
21
  groups: `${PREFIX}-groups`,
20
22
  item: `${PREFIX}-item`,
21
23
  noResults: `${PREFIX}-no-results`,
@@ -63,116 +65,113 @@ export default function Groups(inProps) {
63
65
  props: inProps,
64
66
  name: PREFIX
65
67
  });
66
- const { endpoint, autoHide = false, limit = 6, className, cacheStrategy = CacheStrategies.NETWORK_ONLY, onHeightChange, onStateChange, GroupProps = { variant: 'outlined', ButtonBaseProps: { disableRipple: true, component: Box } } } = props, rest = __rest(props, ["endpoint", "autoHide", "limit", "className", "cacheStrategy", "onHeightChange", "onStateChange", "GroupProps"]);
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"]);
67
69
  // STATE
68
- const [state, dispatch] = useReducer(dataWidgetReducer, {
69
- isLoadingNext: false,
70
- next: null,
71
- cacheKey: SCCache.getWidgetStateCacheKey(SCCache.GROUPS_LIST_TOOLS_STATE_CACHE_PREFIX_KEY),
72
- cacheStrategy,
73
- visibleItems: limit
74
- }, stateWidgetInitializer);
70
+ const [groups, setGroups] = useState([]);
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'));
75
76
  // CONTEXT
76
77
  const scUserContext = useSCUser();
77
78
  const scPreferencesContext = useSCPreferences();
78
79
  // MEMO
79
80
  const contentAvailability = useMemo(() => SCPreferences.CONFIGURATIONS_CONTENT_AVAILABILITY in scPreferencesContext.preferences &&
80
81
  scPreferencesContext.preferences[SCPreferences.CONFIGURATIONS_CONTENT_AVAILABILITY].value, [scPreferencesContext.preferences]);
81
- // HOOKS
82
- // const theme = useTheme<SCThemeType>();
83
- // const isMobile = useMediaQuery(theme.breakpoints.down('md'));
82
+ // CONST
83
+ const authUserId = scUserContext.user ? scUserContext.user.id : null;
84
+ // HANDLERS
85
+ const handleScrollUp = () => {
86
+ window.scrollTo({ left: 0, top: 0, behavior: 'smooth' });
87
+ };
84
88
  /**
85
- * Initialize component
86
- * Fetch data only if the component is not initialized, and it is not loading data
89
+ * Fetches groups list
87
90
  */
88
- const _initComponent = useMemo(() => () => {
89
- if (!state.initialized && !state.isLoadingNext) {
90
- dispatch({ type: actionWidgetTypes.LOADING_NEXT });
91
- http
92
- .request({
93
- url: endpoint.url({ limit }),
94
- method: endpoint.method
95
- })
96
- .then((payload) => {
97
- dispatch({ type: actionWidgetTypes.LOAD_NEXT_SUCCESS, payload: Object.assign(Object.assign({}, payload.data), { initialized: true }) });
98
- })
99
- .catch((error) => {
100
- dispatch({ type: actionWidgetTypes.LOAD_NEXT_FAILURE, payload: { errorLoadNext: error } });
101
- Logger.error(SCOPE_SC_UI, error);
102
- });
103
- }
104
- }, [state.isLoadingNext, state.initialized, endpoint, limit, dispatch]);
105
- // EFFECTS
106
- useEffect(() => {
107
- var _a;
108
- let _t;
109
- if ((contentAvailability || (!contentAvailability && ((_a = scUserContext.user) === null || _a === void 0 ? void 0 : _a.id))) && scUserContext.user !== undefined) {
110
- _t = setTimeout(_initComponent);
111
- return () => {
112
- _t && clearTimeout(_t);
113
- };
91
+ const fetchGroups = () => {
92
+ let groupService;
93
+ if (general) {
94
+ groupService = GroupService.searchGroups(Object.assign(Object.assign({}, endpointQueryParams), (search !== '' && { search: search })));
114
95
  }
115
- }, [scUserContext.user, contentAvailability]);
116
- useEffect(() => {
117
- if (state.next && state.results.length === limit && state.initialized) {
118
- dispatch({ type: actionWidgetTypes.LOADING_NEXT });
119
- http
120
- .request({
121
- url: endpoint.url({ offset: limit, limit: 10 }),
122
- method: endpoint.method
123
- })
124
- .then((payload) => {
125
- dispatch({ type: actionWidgetTypes.LOAD_NEXT_SUCCESS, payload: payload.data });
126
- })
127
- .catch((error) => {
128
- dispatch({ type: actionWidgetTypes.LOAD_NEXT_FAILURE, payload: { errorLoadNext: error } });
129
- Logger.error(SCOPE_SC_UI, error);
130
- });
96
+ else {
97
+ groupService = GroupService.getUserGroups(Object.assign(Object.assign({}, endpointQueryParams), (search !== '' && { search: search })));
131
98
  }
132
- }, [state.next, state.results.length, state.initialized, limit]);
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);
107
+ });
108
+ };
133
109
  /**
134
- * Virtual feed update
110
+ * On mount, fetches groups list
135
111
  */
136
112
  useEffect(() => {
137
- onHeightChange && onHeightChange();
138
- }, [state.results]);
139
- useEffect(() => {
140
- if (!endpoint || (!contentAvailability && !scUserContext.user)) {
113
+ if (!contentAvailability && !authUserId) {
141
114
  return;
142
115
  }
143
- else if (cacheStrategy === CacheStrategies.NETWORK_ONLY) {
144
- onStateChange && onStateChange({ cacheStrategy: CacheStrategies.CACHE_FIRST });
116
+ else {
117
+ fetchGroups();
145
118
  }
146
- }, [scUserContext.user, endpoint, contentAvailability]);
147
- useEffect(() => {
148
- if (!endpoint || !scUserContext.user || !state.initialized) {
119
+ }, [contentAvailability, authUserId, search]);
120
+ const handleNext = useMemo(() => () => {
121
+ if (!next) {
149
122
  return;
150
123
  }
151
- }, []);
152
- // HANDLERS
153
- const handleNext = useMemo(() => () => {
154
- dispatch({ type: actionWidgetTypes.LOADING_NEXT });
155
- http
124
+ return http
156
125
  .request({
157
- url: state.next,
158
- method: endpoint.method
126
+ url: next,
127
+ method: general ? Endpoints.SearchGroups.method : Endpoints.GetUserGroups.method
159
128
  })
160
129
  .then((res) => {
161
- dispatch({ type: actionWidgetTypes.LOAD_NEXT_SUCCESS, payload: res.data });
162
- });
163
- }, [dispatch, state.next, state.isLoadingNext, state.initialized, endpoint.method]);
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
+ button: (chunk) => (React.createElement(Button, { color: "secondary", variant: "text", onClick: handleScrollUp }, chunk))
166
+ } })) },
167
+ 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 },
168
+ React.createElement(Group, Object.assign({ group: group, groupId: group.id, actionRedirect: true }, GroupComponentProps)))))))))));
164
169
  // RENDER
165
- if ((autoHide && !state.count && state.initialized) || (!contentAvailability && !scUserContext.user) || !endpoint) {
170
+ if (!contentAvailability && !scUserContext.user) {
166
171
  return React.createElement(HiddenPlaceholder, null);
167
172
  }
168
- if (!state.initialized) {
173
+ if (loading) {
169
174
  return React.createElement(Skeleton, null);
170
175
  }
171
- const content = (React.createElement(React.Fragment, null, !state.count ? (React.createElement(Typography, { className: classes.noResults, variant: "body2" },
172
- React.createElement(FormattedMessage, { id: "ui.groupRequestsWidget.subtitle.noResults", defaultMessage: "" }))) : (React.createElement(React.Fragment, null,
173
- React.createElement(Grid, { container: true, spacing: { xs: 3 }, className: classes.groups }, state.results.slice(0, state.visibleItems).map((group) => (React.createElement(Grid, { item: true, xs: 12, sm: 8, md: 6, key: group.id, className: classes.item },
174
- React.createElement(Group, Object.assign({ group: group, groupId: group.id }, GroupProps)))))),
175
- state.count > state.visibleItems && (React.createElement(Button, { className: classes.showMore, onClick: handleNext },
176
- React.createElement(FormattedMessage, { id: "ui.groupRequestsWidget.button.showMore", defaultMessage: "ui.groupRequestsWidget.button.showMore" })))))));
177
176
  return (React.createElement(Root, Object.assign({ className: classNames(classes.root, className) }, rest), content));
178
177
  }
@@ -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(15)].map((category, index) => (React.createElement(Grid, { item: true, xs: 12, sm: 8, md: 6, key: index },
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
  }
@@ -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' }, drawerContent = React.createElement(DefaultDrawerContent, null), drawerHeaderContent = React.createElement(DefaultHeaderContent, null), ScrollContainerProps = {} } = props, rest = __rest(props, ["className", "DrawerProps", "drawerContent", "drawerHeaderContent", "ScrollContainerProps"]);
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
@@ -121,7 +121,7 @@ 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, { [classes.active]: value.startsWith(scRoutingContext.url(SCRoutes.GROUPS_ROUTE_NAME, {})) }), "aria-label": "Groups", to: scRoutingContext.url(SCRoutes.GROUPS_ROUTE_NAME, {}), component: Link },
124
+ groupsEnabled && scUserContext.user && (React.createElement(IconButton, { className: classNames(classes.groups, { [classes.active]: value.startsWith(scRoutingContext.url(SCRoutes.GROUPS_SUBSCRIBED_ROUTE_NAME, {})) }), "aria-label": "Groups", to: scRoutingContext.url(SCRoutes.GROUPS_SUBSCRIBED_ROUTE_NAME, {}), component: Link },
125
125
  React.createElement(Icon, null, "groups")))));
126
126
  return (React.createElement(Root, Object.assign({ className: classNames(className, classes.root) }, rest),
127
127
  React.createElement(NavigationMenuIconButtonComponent, null),
@@ -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;
@@ -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.groupSubscribeButton.accept", defaultMessage: "ui.groupSubscribeButton.accept" })))))) }, 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.groupSubscribeButton.accept", defaultMessage: "ui.groupSubscribeButton.accept" })))) }, rest)),
74
+ openAlert && React.createElement(UserDeletedSnackBar, { open: openAlert, handleClose: () => setOpenAlert(false) })));
75
+ }
@@ -0,0 +1,3 @@
1
+ import GroupNotification, { NotificationGroupProps } from './Group';
2
+ export default GroupNotification;
3
+ export { NotificationGroupProps };
@@ -0,0 +1,2 @@
1
+ import GroupNotification from './Group';
2
+ export default GroupNotification;
@@ -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 comment
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: scRoutingContext.url(SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, notificationObject.message.sender), className: classes.message },
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: scRoutingContext.url(SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, notificationObject.message.sender), className: classes.messageLabel }, intl.formatMessage(messages.receivePrivateMessage, {
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: 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)));
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: 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 },
116
- React.createElement(Link, { to: scRoutingContext.url(SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, notificationObject.message.sender), className: classes.message },
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
  }
@@ -8,7 +8,7 @@ export interface PrivateMessageComponentProps {
8
8
  * Handler on message click
9
9
  * @default null
10
10
  */
11
- onItemClick?: (id: any) => void;
11
+ onItemClick?: (id: any, type: any) => void;
12
12
  /**
13
13
  * Handler on single message open
14
14
  * @default null