@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.
Files changed (187) hide show
  1. package/lib/cjs/components/AccountRecover/AccountRecover.js +6 -1
  2. package/lib/cjs/components/BottomNavigation/BottomNavigation.js +4 -3
  3. package/lib/cjs/components/CategoryHeader/Skeleton.js +3 -2
  4. package/lib/cjs/components/ChangeGroupCover/ChangeGroupCover.js +6 -6
  5. package/lib/cjs/components/ChangeGroupPicture/ChangeGroupPicture.js +19 -16
  6. package/lib/cjs/components/Composer/Attributes/Attributes.js +3 -3
  7. package/lib/cjs/components/Composer/Composer.js +3 -3
  8. package/lib/cjs/components/Composer/Layer/AudienceLayer/AudienceLayer.d.ts +1 -1
  9. package/lib/cjs/components/Composer/Layer/AudienceLayer/AudienceLayer.js +9 -19
  10. package/lib/cjs/components/Editor/Editor.js +2 -0
  11. package/lib/cjs/components/Editor/nodes/ImageNode.js +6 -0
  12. package/lib/cjs/components/Editor/plugins/ImagePlugin.js +4 -0
  13. package/lib/cjs/components/Editor/plugins/ToolbarPlugin.js +17 -3
  14. package/lib/cjs/components/FeedObject/Actions/Share/Share.js +18 -16
  15. package/lib/cjs/components/FeedObject/Contributors/Contributors.js +1 -1
  16. package/lib/cjs/components/FeedObject/FeedObject.d.ts +1 -0
  17. package/lib/cjs/components/FeedObject/FeedObject.js +27 -8
  18. package/lib/cjs/components/FeedObject/Poll/Poll.js +20 -20
  19. package/lib/cjs/components/FeedUpdatesWidget/FeedUpdatesWidget.js +1 -1
  20. package/lib/cjs/components/Footer/Footer.js +1 -1
  21. package/lib/cjs/components/Group/Group.d.ts +9 -1
  22. package/lib/cjs/components/Group/Group.js +18 -6
  23. package/lib/cjs/components/GroupAutocomplete/GroupAutocomplete.d.ts +0 -1
  24. package/lib/cjs/components/GroupAutocomplete/GroupAutocomplete.js +1 -2
  25. package/lib/cjs/components/GroupForm/GroupForm.js +64 -13
  26. package/lib/cjs/components/GroupHeader/GroupHeader.d.ts +6 -6
  27. package/lib/cjs/components/GroupHeader/GroupHeader.js +53 -12
  28. package/lib/cjs/components/GroupInfoWidget/GroupInfoWidget.js +63 -9
  29. package/lib/cjs/components/GroupInviteButton/GroupInviteButton.js +31 -9
  30. package/lib/cjs/components/GroupInvitedWidget/GroupInvitedWidget.d.ts +73 -0
  31. package/lib/cjs/components/GroupInvitedWidget/GroupInvitedWidget.js +220 -0
  32. package/lib/cjs/components/GroupInvitedWidget/Skeleton.d.ts +22 -0
  33. package/lib/cjs/components/GroupInvitedWidget/Skeleton.js +38 -0
  34. package/lib/cjs/components/GroupInvitedWidget/constants.d.ts +1 -0
  35. package/lib/cjs/components/GroupInvitedWidget/constants.js +4 -0
  36. package/lib/cjs/components/GroupInvitedWidget/index.d.ts +4 -0
  37. package/lib/cjs/components/GroupInvitedWidget/index.js +8 -0
  38. package/lib/cjs/components/GroupMembersButton/GroupMembersButton.d.ts +5 -0
  39. package/lib/cjs/components/GroupMembersButton/GroupMembersButton.js +8 -3
  40. package/lib/cjs/components/GroupMembersWidget/GroupMembersWidget.js +25 -4
  41. package/lib/cjs/components/GroupRequestsWidget/GroupRequestsWidget.d.ts +12 -7
  42. package/lib/cjs/components/GroupRequestsWidget/GroupRequestsWidget.js +19 -9
  43. package/lib/cjs/components/GroupSettingsIconButton/GroupSettingsIconButton.d.ts +48 -0
  44. package/lib/cjs/components/GroupSettingsIconButton/GroupSettingsIconButton.js +151 -0
  45. package/lib/cjs/components/GroupSettingsIconButton/index.d.ts +3 -0
  46. package/lib/cjs/components/GroupSettingsIconButton/index.js +5 -0
  47. package/lib/cjs/components/GroupSubscribeButton/GroupSubscribeButton.d.ts +8 -3
  48. package/lib/cjs/components/GroupSubscribeButton/GroupSubscribeButton.js +30 -11
  49. package/lib/cjs/components/Groups/Groups.d.ts +15 -8
  50. package/lib/cjs/components/Groups/Groups.js +86 -32
  51. package/lib/cjs/components/Groups/Skeleton.d.ts +4 -0
  52. package/lib/cjs/components/Groups/Skeleton.js +2 -2
  53. package/lib/cjs/components/InlineComposerWidget/InlineComposerWidget.js +7 -0
  54. package/lib/cjs/components/NavigationSettingsIconButton/NavigationSettingsIconButton.js +4 -4
  55. package/lib/cjs/components/NavigationToolbar/NavigationToolbar.js +9 -2
  56. package/lib/cjs/components/NavigationToolbarMobile/NavigationToolbarMobile.d.ts +1 -0
  57. package/lib/cjs/components/NavigationToolbarMobile/NavigationToolbarMobile.js +9 -1
  58. package/lib/cjs/components/Notification/Group/Group.d.ts +15 -0
  59. package/lib/cjs/components/Notification/Group/Group.js +78 -0
  60. package/lib/cjs/components/Notification/Group/index.d.ts +3 -0
  61. package/lib/cjs/components/Notification/Group/index.js +5 -0
  62. package/lib/cjs/components/Notification/Notification.js +31 -1
  63. package/lib/cjs/components/Notification/PrivateMessage/PrivateMessage.js +16 -5
  64. package/lib/cjs/components/PrivateMessageComponent/PrivateMessageComponent.d.ts +7 -1
  65. package/lib/cjs/components/PrivateMessageComponent/PrivateMessageComponent.js +16 -8
  66. package/lib/cjs/components/PrivateMessageSettingsIconButton/PrivateMessageSettingsIconButton.js +1 -1
  67. package/lib/cjs/components/PrivateMessageSnippetItem/PrivateMessageSnippetItem.js +11 -6
  68. package/lib/cjs/components/PrivateMessageSnippets/PrivateMessageSnippets.d.ts +9 -4
  69. package/lib/cjs/components/PrivateMessageSnippets/PrivateMessageSnippets.js +24 -6
  70. package/lib/cjs/components/PrivateMessageThread/PrivateMessageThread.d.ts +6 -1
  71. package/lib/cjs/components/PrivateMessageThread/PrivateMessageThread.js +46 -20
  72. package/lib/cjs/components/PrivateMessageThreadItem/PrivateMessageThreadItem.js +6 -0
  73. package/lib/cjs/components/SearchAutocomplete/SearchAutocomplete.js +22 -5
  74. package/lib/cjs/components/SnippetNotifications/SnippetNotifications.js +7 -0
  75. package/lib/cjs/components/ToastNotifications/ToastNotifications.js +7 -0
  76. package/lib/cjs/components/User/User.d.ts +6 -1
  77. package/lib/cjs/components/User/User.js +5 -4
  78. package/lib/cjs/components/UserSubscribedGroupsWidget/Skeleton.d.ts +21 -0
  79. package/lib/cjs/components/UserSubscribedGroupsWidget/Skeleton.js +46 -0
  80. package/lib/cjs/components/UserSubscribedGroupsWidget/UserSubscribedGroupsWidget.d.ts +68 -0
  81. package/lib/cjs/components/UserSubscribedGroupsWidget/UserSubscribedGroupsWidget.js +183 -0
  82. package/lib/cjs/components/UserSubscribedGroupsWidget/constants.d.ts +1 -0
  83. package/lib/cjs/components/UserSubscribedGroupsWidget/constants.js +4 -0
  84. package/lib/cjs/components/UserSubscribedGroupsWidget/index.d.ts +4 -0
  85. package/lib/cjs/components/UserSubscribedGroupsWidget/index.js +8 -0
  86. package/lib/cjs/components/VoteAudienceButton/VoteAudienceButton.js +1 -1
  87. package/lib/cjs/constants/PubSub.d.ts +28 -0
  88. package/lib/cjs/constants/PubSub.js +22 -0
  89. package/lib/cjs/index.d.ts +6 -3
  90. package/lib/cjs/index.js +13 -4
  91. package/lib/cjs/types/index.d.ts +2 -1
  92. package/lib/esm/components/AccountRecover/AccountRecover.js +6 -1
  93. package/lib/esm/components/BottomNavigation/BottomNavigation.js +5 -4
  94. package/lib/esm/components/CategoryHeader/Skeleton.js +3 -2
  95. package/lib/esm/components/ChangeGroupCover/ChangeGroupCover.js +6 -6
  96. package/lib/esm/components/ChangeGroupPicture/ChangeGroupPicture.js +19 -16
  97. package/lib/esm/components/Composer/Attributes/Attributes.js +3 -3
  98. package/lib/esm/components/Composer/Composer.js +3 -3
  99. package/lib/esm/components/Composer/Layer/AudienceLayer/AudienceLayer.d.ts +1 -1
  100. package/lib/esm/components/Composer/Layer/AudienceLayer/AudienceLayer.js +9 -19
  101. package/lib/esm/components/Editor/Editor.js +2 -0
  102. package/lib/esm/components/Editor/nodes/ImageNode.js +6 -0
  103. package/lib/esm/components/Editor/plugins/ImagePlugin.js +4 -0
  104. package/lib/esm/components/Editor/plugins/ToolbarPlugin.js +19 -5
  105. package/lib/esm/components/FeedObject/Actions/Share/Share.js +19 -17
  106. package/lib/esm/components/FeedObject/Contributors/Contributors.js +1 -1
  107. package/lib/esm/components/FeedObject/FeedObject.d.ts +1 -0
  108. package/lib/esm/components/FeedObject/FeedObject.js +28 -9
  109. package/lib/esm/components/FeedObject/Poll/Poll.js +20 -20
  110. package/lib/esm/components/FeedUpdatesWidget/FeedUpdatesWidget.js +1 -1
  111. package/lib/esm/components/Footer/Footer.js +2 -2
  112. package/lib/esm/components/Group/Group.d.ts +9 -1
  113. package/lib/esm/components/Group/Group.js +22 -10
  114. package/lib/esm/components/GroupAutocomplete/GroupAutocomplete.d.ts +0 -1
  115. package/lib/esm/components/GroupAutocomplete/GroupAutocomplete.js +1 -2
  116. package/lib/esm/components/GroupForm/GroupForm.js +64 -13
  117. package/lib/esm/components/GroupHeader/GroupHeader.d.ts +6 -6
  118. package/lib/esm/components/GroupHeader/GroupHeader.js +55 -14
  119. package/lib/esm/components/GroupInfoWidget/GroupInfoWidget.js +63 -9
  120. package/lib/esm/components/GroupInviteButton/GroupInviteButton.js +31 -9
  121. package/lib/esm/components/GroupInvitedWidget/GroupInvitedWidget.d.ts +73 -0
  122. package/lib/esm/components/GroupInvitedWidget/GroupInvitedWidget.js +217 -0
  123. package/lib/esm/components/GroupInvitedWidget/Skeleton.d.ts +22 -0
  124. package/lib/esm/components/GroupInvitedWidget/Skeleton.js +34 -0
  125. package/lib/esm/components/GroupInvitedWidget/constants.d.ts +1 -0
  126. package/lib/esm/components/GroupInvitedWidget/constants.js +1 -0
  127. package/lib/esm/components/GroupInvitedWidget/index.d.ts +4 -0
  128. package/lib/esm/components/GroupInvitedWidget/index.js +4 -0
  129. package/lib/esm/components/GroupMembersButton/GroupMembersButton.d.ts +5 -0
  130. package/lib/esm/components/GroupMembersButton/GroupMembersButton.js +9 -4
  131. package/lib/esm/components/GroupMembersWidget/GroupMembersWidget.js +26 -5
  132. package/lib/esm/components/GroupRequestsWidget/GroupRequestsWidget.d.ts +12 -7
  133. package/lib/esm/components/GroupRequestsWidget/GroupRequestsWidget.js +19 -9
  134. package/lib/esm/components/GroupSettingsIconButton/GroupSettingsIconButton.d.ts +48 -0
  135. package/lib/esm/components/GroupSettingsIconButton/GroupSettingsIconButton.js +148 -0
  136. package/lib/esm/components/GroupSettingsIconButton/index.d.ts +3 -0
  137. package/lib/esm/components/GroupSettingsIconButton/index.js +2 -0
  138. package/lib/esm/components/GroupSubscribeButton/GroupSubscribeButton.d.ts +8 -3
  139. package/lib/esm/components/GroupSubscribeButton/GroupSubscribeButton.js +30 -11
  140. package/lib/esm/components/Groups/Groups.d.ts +15 -8
  141. package/lib/esm/components/Groups/Groups.js +91 -37
  142. package/lib/esm/components/Groups/Skeleton.d.ts +4 -0
  143. package/lib/esm/components/Groups/Skeleton.js +2 -2
  144. package/lib/esm/components/InlineComposerWidget/InlineComposerWidget.js +9 -2
  145. package/lib/esm/components/NavigationSettingsIconButton/NavigationSettingsIconButton.js +4 -4
  146. package/lib/esm/components/NavigationToolbar/NavigationToolbar.js +10 -3
  147. package/lib/esm/components/NavigationToolbarMobile/NavigationToolbarMobile.d.ts +1 -0
  148. package/lib/esm/components/NavigationToolbarMobile/NavigationToolbarMobile.js +11 -3
  149. package/lib/esm/components/Notification/Group/Group.d.ts +15 -0
  150. package/lib/esm/components/Notification/Group/Group.js +75 -0
  151. package/lib/esm/components/Notification/Group/index.d.ts +3 -0
  152. package/lib/esm/components/Notification/Group/index.js +2 -0
  153. package/lib/esm/components/Notification/Notification.js +31 -1
  154. package/lib/esm/components/Notification/PrivateMessage/PrivateMessage.js +16 -5
  155. package/lib/esm/components/PrivateMessageComponent/PrivateMessageComponent.d.ts +7 -1
  156. package/lib/esm/components/PrivateMessageComponent/PrivateMessageComponent.js +17 -9
  157. package/lib/esm/components/PrivateMessageSettingsIconButton/PrivateMessageSettingsIconButton.js +1 -1
  158. package/lib/esm/components/PrivateMessageSnippetItem/PrivateMessageSnippetItem.js +11 -6
  159. package/lib/esm/components/PrivateMessageSnippets/PrivateMessageSnippets.d.ts +9 -4
  160. package/lib/esm/components/PrivateMessageSnippets/PrivateMessageSnippets.js +26 -8
  161. package/lib/esm/components/PrivateMessageThread/PrivateMessageThread.d.ts +6 -1
  162. package/lib/esm/components/PrivateMessageThread/PrivateMessageThread.js +48 -22
  163. package/lib/esm/components/PrivateMessageThreadItem/PrivateMessageThreadItem.js +7 -1
  164. package/lib/esm/components/SearchAutocomplete/SearchAutocomplete.js +22 -5
  165. package/lib/esm/components/SnippetNotifications/SnippetNotifications.js +7 -0
  166. package/lib/esm/components/ToastNotifications/ToastNotifications.js +7 -0
  167. package/lib/esm/components/User/User.d.ts +6 -1
  168. package/lib/esm/components/User/User.js +5 -4
  169. package/lib/esm/components/UserSubscribedGroupsWidget/Skeleton.d.ts +21 -0
  170. package/lib/esm/components/UserSubscribedGroupsWidget/Skeleton.js +42 -0
  171. package/lib/esm/components/UserSubscribedGroupsWidget/UserSubscribedGroupsWidget.d.ts +68 -0
  172. package/lib/esm/components/UserSubscribedGroupsWidget/UserSubscribedGroupsWidget.js +180 -0
  173. package/lib/esm/components/UserSubscribedGroupsWidget/constants.d.ts +1 -0
  174. package/lib/esm/components/UserSubscribedGroupsWidget/constants.js +1 -0
  175. package/lib/esm/components/UserSubscribedGroupsWidget/index.d.ts +4 -0
  176. package/lib/esm/components/UserSubscribedGroupsWidget/index.js +4 -0
  177. package/lib/esm/components/VoteAudienceButton/VoteAudienceButton.js +1 -1
  178. package/lib/esm/constants/PubSub.d.ts +28 -0
  179. package/lib/esm/constants/PubSub.js +19 -0
  180. package/lib/esm/index.d.ts +6 -3
  181. package/lib/esm/index.js +6 -3
  182. package/lib/esm/types/index.d.ts +2 -1
  183. package/lib/umd/311.js +2 -0
  184. package/lib/umd/react-ui.js +1 -1
  185. package/package.json +9 -9
  186. package/lib/umd/871.js +0 -2
  187. /package/lib/umd/{871.js.LICENSE.txt → 311.js.LICENSE.txt} +0 -0
@@ -14,9 +14,12 @@ const Errors_1 = require("../../constants/Errors");
14
14
  const system_1 = require("@mui/system");
15
15
  const HiddenPlaceholder_1 = tslib_1.__importDefault(require("../../shared/HiddenPlaceholder"));
16
16
  const constants_1 = require("./constants");
17
- const Group_1 = tslib_1.__importDefault(require("../Group"));
17
+ const Group_1 = tslib_1.__importStar(require("../Group"));
18
+ const Pagination_1 = require("../../constants/Pagination");
19
+ const InfiniteScroll_1 = tslib_1.__importDefault(require("../../shared/InfiniteScroll"));
18
20
  const classes = {
19
21
  root: `${constants_1.PREFIX}-root`,
22
+ filters: `${constants_1.PREFIX}-filter`,
20
23
  groups: `${constants_1.PREFIX}-groups`,
21
24
  item: `${constants_1.PREFIX}-item`,
22
25
  noResults: `${constants_1.PREFIX}-no-results`,
@@ -64,10 +67,14 @@ function Groups(inProps) {
64
67
  props: inProps,
65
68
  name: constants_1.PREFIX
66
69
  });
67
- const { endpoint, className, GroupComponentProps = { variant: 'outlined', ButtonBaseProps: { disableRipple: true, component: material_1.Box } }, prefetchedGroups = [] } = props, rest = tslib_1.__rest(props, ["endpoint", "className", "GroupComponentProps", "prefetchedGroups"]);
70
+ const { endpointQueryParams = { limit: 20, offset: Pagination_1.DEFAULT_PAGINATION_OFFSET }, className, GroupComponentProps = { variant: 'outlined', ButtonBaseProps: { disableRipple: true, component: material_1.Box } }, showFilters = false, filters, general = true } = props, rest = tslib_1.__rest(props, ["endpointQueryParams", "className", "GroupComponentProps", "showFilters", "filters", "general"]);
68
71
  // STATE
69
72
  const [groups, setGroups] = (0, react_1.useState)([]);
70
73
  const [loading, setLoading] = (0, react_1.useState)(true);
74
+ const [next, setNext] = (0, react_1.useState)(null);
75
+ const [search, setSearch] = (0, react_1.useState)('');
76
+ const theme = (0, material_1.useTheme)();
77
+ const isMobile = (0, material_1.useMediaQuery)(theme.breakpoints.down('md'));
71
78
  // CONTEXT
72
79
  const scUserContext = (0, react_core_1.useSCUser)();
73
80
  const scPreferencesContext = (0, react_core_1.useSCPreferences)();
@@ -76,19 +83,31 @@ function Groups(inProps) {
76
83
  scPreferencesContext.preferences[react_core_1.SCPreferences.CONFIGURATIONS_CONTENT_AVAILABILITY].value, [scPreferencesContext.preferences]);
77
84
  // CONST
78
85
  const authUserId = scUserContext.user ? scUserContext.user.id : null;
79
- // REFS
80
- const isMountedRef = (0, react_core_1.useIsComponentMountedRef)();
86
+ // HANDLERS
87
+ const handleScrollUp = () => {
88
+ window.scrollTo({ left: 0, top: 0, behavior: 'smooth' });
89
+ };
81
90
  /**
82
91
  * Fetches groups list
83
92
  */
84
- const fetchGroups = (next = endpoint.url({})) => tslib_1.__awaiter(this, void 0, void 0, function* () {
85
- const response = yield api_services_1.http.request({
86
- url: next,
87
- method: endpoint.method
93
+ const fetchGroups = () => {
94
+ let groupService;
95
+ if (general) {
96
+ groupService = api_services_1.GroupService.searchGroups(Object.assign(Object.assign({}, endpointQueryParams), (search !== '' && { search: search })));
97
+ }
98
+ else {
99
+ groupService = api_services_1.GroupService.getUserGroups(Object.assign(Object.assign({}, endpointQueryParams), (search !== '' && { search: search })));
100
+ }
101
+ groupService
102
+ .then((res) => {
103
+ setGroups(res.results);
104
+ setNext(res.next);
105
+ setLoading(false);
106
+ })
107
+ .catch((error) => {
108
+ utils_1.Logger.error(Errors_1.SCOPE_SC_UI, error);
88
109
  });
89
- const data = response.data;
90
- return data.next ? data.results.concat(yield fetchGroups(data.next)) : data.results;
91
- });
110
+ };
92
111
  /**
93
112
  * On mount, fetches groups list
94
113
  */
@@ -96,33 +115,68 @@ function Groups(inProps) {
96
115
  if (!contentAvailability && !authUserId) {
97
116
  return;
98
117
  }
99
- else if (prefetchedGroups.length) {
100
- setGroups(prefetchedGroups);
101
- setLoading(false);
102
- }
103
118
  else {
104
- fetchGroups()
105
- .then((data) => {
106
- if (isMountedRef.current) {
107
- setGroups(data);
108
- setLoading(false);
109
- }
110
- })
111
- .catch((error) => {
112
- utils_1.Logger.error(Errors_1.SCOPE_SC_UI, error);
113
- });
119
+ fetchGroups();
120
+ }
121
+ }, [contentAvailability, authUserId, search]);
122
+ const handleNext = (0, react_1.useMemo)(() => () => {
123
+ if (!next) {
124
+ return;
114
125
  }
115
- }, [contentAvailability, authUserId, prefetchedGroups.length]);
126
+ return api_services_1.http
127
+ .request({
128
+ url: next,
129
+ method: general ? api_services_1.Endpoints.SearchGroups.method : api_services_1.Endpoints.GetUserGroups.method
130
+ })
131
+ .then((res) => {
132
+ setGroups([...groups, ...res.data.results]);
133
+ setNext(res.data.next);
134
+ })
135
+ .catch((error) => console.log(error))
136
+ .then(() => setLoading(false));
137
+ }, [next]);
138
+ /**
139
+ * Get groups filtered
140
+ */
141
+ const getFilteredGroups = () => {
142
+ if (search) {
143
+ return groups.filter((g) => g.name.toLowerCase().includes(search.toLowerCase()));
144
+ }
145
+ return groups;
146
+ };
147
+ /**
148
+ * Handle change filter name
149
+ * @param event
150
+ */
151
+ const handleOnChangeFilterName = (event) => {
152
+ setSearch(event.target.value);
153
+ };
154
+ /**
155
+ * Renders groups list
156
+ */
157
+ const filteredGroups = (0, utils_1.sortByAttr)(getFilteredGroups(), 'order');
158
+ const content = (react_1.default.createElement(react_1.default.Fragment, null,
159
+ showFilters && (react_1.default.createElement(material_1.Grid, { container: true, direction: "row", justifyContent: "center", alignItems: "center", className: classes.filters }, filters ? (filters) : (react_1.default.createElement(material_1.Grid, { item: true, xs: 12, md: 6 },
160
+ react_1.default.createElement(material_1.TextField, { fullWidth: true, value: search, label: react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.groups.filterByName", defaultMessage: "ui.groups.filterByName" }), variant: "outlined", onChange: handleOnChangeFilterName, disabled: loading }))))),
161
+ react_1.default.createElement(react_1.default.Fragment, null, !groups.length ? (react_1.default.createElement(material_1.Box, { className: classes.noResults },
162
+ react_1.default.createElement(material_1.Typography, { variant: "h4" },
163
+ react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.groups.noGroups.title", defaultMessage: "ui.groups.noGroups.title" })),
164
+ react_1.default.createElement(material_1.Typography, { variant: "body1" },
165
+ react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.groups.noGroups.subtitle", defaultMessage: "ui.groups.noGroups.subtitle" })))) : (react_1.default.createElement(InfiniteScroll_1.default, { dataLength: groups.length, next: handleNext, hasMoreNext: Boolean(next), loaderNext: isMobile ? react_1.default.createElement(Group_1.GroupSkeleton, null) : react_1.default.createElement(Skeleton_1.default, { groupsNumber: 2 }), endMessage: react_1.default.createElement(material_1.Typography, { component: "div", className: classes.endMessage },
166
+ react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.groups.endMessage", defaultMessage: "ui.groups.endMessage", values: {
167
+ // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
168
+ // @ts-ignore
169
+ button: (chunk) => (react_1.default.createElement(material_1.Button, { color: "secondary", variant: "text", onClick: handleScrollUp }, chunk))
170
+ } })) },
171
+ react_1.default.createElement(material_1.Grid, { container: true, spacing: { xs: 2 }, className: classes.groups }, filteredGroups.map((group) => (react_1.default.createElement(material_1.Grid, { item: true, xs: 12, sm: 8, md: 6, key: group.id, className: classes.item },
172
+ react_1.default.createElement(Group_1.default, Object.assign({ group: group, groupId: group.id, actionRedirect: true }, GroupComponentProps)))))))))));
116
173
  // RENDER
117
174
  if (!contentAvailability && !scUserContext.user) {
118
175
  return react_1.default.createElement(HiddenPlaceholder_1.default, null);
119
176
  }
120
- const content = (react_1.default.createElement(react_1.default.Fragment, null, loading ? (react_1.default.createElement(Skeleton_1.default, null)) : (react_1.default.createElement(material_1.Grid, { container: true, spacing: { xs: 3 }, className: classes.groups }, !groups.length ? (react_1.default.createElement(material_1.Box, { className: classes.noResults },
121
- react_1.default.createElement(material_1.Typography, { variant: "h4" },
122
- react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.groups.noGroups.title", defaultMessage: "ui.groups.noGroups.title" })),
123
- react_1.default.createElement(material_1.Typography, { variant: "body1" },
124
- react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.groups.noGroups.subtitle", defaultMessage: "ui.groups.noGroups.subtitle" })))) : (react_1.default.createElement(react_1.default.Fragment, null, groups.map((group) => (react_1.default.createElement(material_1.Grid, { item: true, xs: 12, sm: 8, md: 6, key: group.id, className: classes.item },
125
- react_1.default.createElement(Group_1.default, Object.assign({ group: group, groupId: group.id }, GroupComponentProps)))))))))));
177
+ if (loading) {
178
+ return react_1.default.createElement(Skeleton_1.default, null);
179
+ }
126
180
  return (react_1.default.createElement(Root, Object.assign({ className: (0, classnames_1.default)(classes.root, className) }, rest), content));
127
181
  }
128
182
  exports.default = Groups;
@@ -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.
@@ -37,9 +37,9 @@ const Root = (0, styles_1.styled)(material_1.Box, {
37
37
  *
38
38
  */
39
39
  function GroupsSkeleton(inProps) {
40
- const { className, GroupSkeletonProps = {} } = inProps, rest = tslib_1.__rest(inProps, ["className", "GroupSkeletonProps"]);
40
+ const { className, GroupSkeletonProps = {}, groupsNumber = 20 } = inProps, rest = tslib_1.__rest(inProps, ["className", "GroupSkeletonProps", "groupsNumber"]);
41
41
  return (react_1.default.createElement(Root, Object.assign({ className: (0, classnames_1.default)(classes.root, className) }, rest),
42
- react_1.default.createElement(material_1.Grid, { container: true, spacing: { xs: 3 }, className: classes.groups }, [...Array(15)].map((category, index) => (react_1.default.createElement(material_1.Grid, { item: true, xs: 12, sm: 8, md: 6, key: index },
42
+ react_1.default.createElement(material_1.Grid, { container: true, spacing: { xs: 3 }, className: classes.groups }, [...Array(groupsNumber)].map((category, index) => (react_1.default.createElement(material_1.Grid, { item: true, xs: 12, sm: 8, md: 6, key: index },
43
43
  react_1.default.createElement(Group_1.GroupSkeleton, Object.assign({ elevation: 0, variant: 'outlined' }, GroupSkeletonProps))))))));
44
44
  }
45
45
  exports.default = GroupsSkeleton;
@@ -12,6 +12,7 @@ const system_1 = require("@mui/system");
12
12
  const Composer_1 = tslib_1.__importDefault(require("../Composer"));
13
13
  const Media_1 = require("../../shared/Media");
14
14
  const constants_1 = require("./constants");
15
+ const HiddenPlaceholder_1 = tslib_1.__importDefault(require("../../shared/HiddenPlaceholder"));
15
16
  const classes = {
16
17
  root: `${constants_1.PREFIX}-root`,
17
18
  content: `${constants_1.PREFIX}-content`,
@@ -60,6 +61,9 @@ function InlineComposerWidget(inProps) {
60
61
  const scUserContext = (0, react_core_1.useSCUser)();
61
62
  const scRoutingContext = (0, react_core_1.useSCRouting)();
62
63
  const { enqueueSnackbar } = (0, notistack_1.useSnackbar)();
64
+ // PREFERENCES
65
+ const preferences = (0, react_core_1.useSCPreferences)();
66
+ const onlyStaffEnabled = (0, react_1.useMemo)(() => preferences.preferences[react_core_1.SCPreferences.CONFIGURATIONS_POST_ONLY_STAFF_ENABLED].value, [preferences.preferences]);
63
67
  // State variables
64
68
  const [open, setOpen] = (0, react_1.useState)(false);
65
69
  // Handlers
@@ -94,6 +98,9 @@ function InlineComposerWidget(inProps) {
94
98
  }
95
99
  setOpen(false);
96
100
  };
101
+ if (!react_core_1.UserUtils.isStaff(scUserContext.user) && onlyStaffEnabled) {
102
+ return react_1.default.createElement(HiddenPlaceholder_1.default, null);
103
+ }
97
104
  return (react_1.default.createElement(react_1.default.Fragment, null,
98
105
  react_1.default.createElement(Root, Object.assign({ className: classes.root }, rest),
99
106
  react_1.default.createElement(material_1.CardContent, { className: classes.content },
@@ -4,7 +4,6 @@ const tslib_1 = require("tslib");
4
4
  const react_1 = tslib_1.__importStar(require("react"));
5
5
  const styles_1 = require("@mui/material/styles");
6
6
  const material_1 = require("@mui/material");
7
- const types_1 = require("@selfcommunity/types");
8
7
  const react_core_1 = require("@selfcommunity/react-core");
9
8
  const classnames_1 = tslib_1.__importDefault(require("classnames"));
10
9
  const system_1 = require("@mui/system");
@@ -36,7 +35,8 @@ const MenuRoot = (0, styles_1.styled)(material_1.Menu, {
36
35
  const PREFERENCES = [
37
36
  react_core_1.SCPreferences.CONFIGURATIONS_FOLLOW_ENABLED,
38
37
  react_core_1.SCPreferences.CONFIGURATIONS_POST_TYPE_ENABLED,
39
- react_core_1.SCPreferences.CONFIGURATIONS_DISCUSSION_TYPE_ENABLED
38
+ react_core_1.SCPreferences.CONFIGURATIONS_DISCUSSION_TYPE_ENABLED,
39
+ react_core_1.SCPreferences.ADDONS_LOYALTY_POINTS_COLLECTION
40
40
  ];
41
41
  /**
42
42
  * > API documentation for the Community-JS Navigation Settings Icon Button component. Learn about the available props and the CSS API.
@@ -120,7 +120,7 @@ function NavigationSettingsIconButton(inProps) {
120
120
  !preferences[react_core_1.SCPreferences.CONFIGURATIONS_FOLLOW_ENABLED] && (react_1.default.createElement(material_1.ListItem, { className: classes.item, key: "connections" },
121
121
  react_1.default.createElement(material_1.ListItemButton, { component: react_core_1.Link, to: scRoutingContext.url(react_core_1.SCRoutes.USER_PROFILE_CONNECTIONS_ROUTE_NAME, scUserContext.user) },
122
122
  react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.navigationSettingsIconButton.connections", defaultMessage: "ui.navigationSettingsIconButton.connections" })))),
123
- scPreferences.features.includes(types_1.SCFeatureName.LOYALTY) && (react_1.default.createElement(material_1.ListItem, { className: classes.item, key: "loyaltyProgram" },
123
+ preferences[react_core_1.SCPreferences.ADDONS_LOYALTY_POINTS_COLLECTION] && (react_1.default.createElement(material_1.ListItem, { className: classes.item, key: "loyaltyProgram" },
124
124
  react_1.default.createElement(material_1.ListItemButton, { component: react_core_1.Link, to: scRoutingContext.url(react_core_1.SCRoutes.LOYALTY_ROUTE_NAME, {}) },
125
125
  react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.navigationSettingsIconButton.loyalty", defaultMessage: "ui.navigationSettingsIconButton.loyalty" })))),
126
126
  preferences[react_core_1.SCPreferences.CONFIGURATIONS_POST_TYPE_ENABLED] && (react_1.default.createElement(material_1.ListItem, { className: classes.item, key: "followedPosts" },
@@ -169,7 +169,7 @@ function NavigationSettingsIconButton(inProps) {
169
169
  react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.navigationSettingsIconButton.followers", defaultMessage: "ui.navigationSettingsIconButton.followers" }))),
170
170
  !preferences[react_core_1.SCPreferences.CONFIGURATIONS_FOLLOW_ENABLED] && (react_1.default.createElement(material_1.MenuItem, { className: classes.item, key: "connections", component: react_core_1.Link, to: scRoutingContext.url(react_core_1.SCRoutes.USER_PROFILE_CONNECTIONS_ROUTE_NAME, scUserContext.user) },
171
171
  react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.navigationSettingsIconButton.connections", defaultMessage: "ui.navigationSettingsIconButton.connections" }))),
172
- scPreferences.features.includes(types_1.SCFeatureName.LOYALTY) && (react_1.default.createElement(material_1.MenuItem, { className: classes.item, key: "loyaltyProgram", component: react_core_1.Link, to: scRoutingContext.url(react_core_1.SCRoutes.LOYALTY_ROUTE_NAME, {}) },
172
+ preferences[react_core_1.SCPreferences.ADDONS_LOYALTY_POINTS_COLLECTION] && (react_1.default.createElement(material_1.MenuItem, { className: classes.item, key: "loyaltyProgram", component: react_core_1.Link, to: scRoutingContext.url(react_core_1.SCRoutes.LOYALTY_ROUTE_NAME, {}) },
173
173
  react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.navigationSettingsIconButton.loyalty", defaultMessage: "ui.navigationSettingsIconButton.loyalty" }))),
174
174
  preferences[react_core_1.SCPreferences.CONFIGURATIONS_POST_TYPE_ENABLED] && (react_1.default.createElement(material_1.MenuItem, { className: classes.item, key: "followedPosts", component: react_core_1.Link, to: scRoutingContext.url(react_core_1.SCRoutes.USER_PROFILE_FOLLOWED_POSTS_ROUTE_NAME, scUserContext.user) },
175
175
  react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.navigationSettingsIconButton.postsFollowed", defaultMessage: "ui.navigationSettingsIconButton.postsFollowed" }))),
@@ -102,6 +102,11 @@ function NavigationToolbar(inProps) {
102
102
  }, [scPreferences.preferences]);
103
103
  const privateMessagingEnabled = (0, react_1.useMemo)(() => scPreferences.features.includes(types_1.SCFeatureName.PRIVATE_MESSAGING), [scPreferences.features]);
104
104
  const groupsEnabled = (0, react_1.useMemo)(() => scPreferences.features.includes(types_1.SCFeatureName.GROUPING), [scPreferences.features]);
105
+ const showComposer = (0, react_1.useMemo)(() => {
106
+ return (scPreferences.preferences[react_core_1.SCPreferences.CONFIGURATIONS_POST_ONLY_STAFF_ENABLED].value &&
107
+ !disableComposer &&
108
+ (!scPreferences.preferences[react_core_1.SCPreferences.CONFIGURATIONS_POST_ONLY_STAFF_ENABLED].value || react_core_1.UserUtils.isStaff(scUserContext.user)));
109
+ }, [scPreferences, disableComposer, scUserContext.user]);
105
110
  // STATE
106
111
  const [anchorNotification, setAnchorNotification] = react_1.default.useState(null);
107
112
  // HANDLERS
@@ -123,7 +128,9 @@ function NavigationToolbar(inProps) {
123
128
  preferences[react_core_1.SCPreferences.CONFIGURATIONS_EXPLORE_STREAM_ENABLED] &&
124
129
  (preferences[react_core_1.SCPreferences.CONFIGURATIONS_CONTENT_AVAILABILITY] || scUserContext.user) && (react_1.default.createElement(material_1.IconButton, { className: (0, classnames_1.default)(classes.explore, { [classes.active]: value.startsWith(scRoutingContext.url(react_core_1.SCRoutes.EXPLORE_ROUTE_NAME, {})) }), "aria-label": "Explore", to: scRoutingContext.url(react_core_1.SCRoutes.EXPLORE_ROUTE_NAME, {}), component: react_core_1.Link },
125
130
  react_1.default.createElement(Icon_1.default, null, "explore"))),
126
- groupsEnabled && scUserContext.user && (react_1.default.createElement(material_1.IconButton, { className: (0, classnames_1.default)(classes.groups, { [classes.active]: value.startsWith(scRoutingContext.url(react_core_1.SCRoutes.GROUPS_ROUTE_NAME, {})) }), "aria-label": "Groups", to: scRoutingContext.url(react_core_1.SCRoutes.GROUPS_ROUTE_NAME, {}), component: react_core_1.Link },
131
+ groupsEnabled && scUserContext.user && (react_1.default.createElement(material_1.IconButton, { className: (0, classnames_1.default)(classes.groups, {
132
+ [classes.active]: value.startsWith(scRoutingContext.url(react_core_1.SCRoutes.GROUPS_SUBSCRIBED_ROUTE_NAME, {}))
133
+ }), "aria-label": "Groups", to: scRoutingContext.url(react_core_1.SCRoutes.GROUPS_SUBSCRIBED_ROUTE_NAME, {}), component: react_core_1.Link },
127
134
  react_1.default.createElement(Icon_1.default, null, "groups")))));
128
135
  return (react_1.default.createElement(Root, Object.assign({ className: (0, classnames_1.default)(className, classes.root) }, rest),
129
136
  react_1.default.createElement(NavigationMenuIconButtonComponent, null),
@@ -135,7 +142,7 @@ function NavigationToolbar(inProps) {
135
142
  (preferences[react_core_1.SCPreferences.CONFIGURATIONS_CONTENT_AVAILABILITY] || scUserContext.user) && !disableSearch ? (react_1.default.createElement(SearchAutocomplete_1.default, Object.assign({ className: classes.search, blurOnSelect: true }, SearchAutocompleteProps))) : (react_1.default.createElement(material_1.Box, { className: classes.search })),
136
143
  startActions,
137
144
  scUserContext.user ? (react_1.default.createElement(react_1.default.Fragment, null,
138
- !disableComposer && react_1.default.createElement(ComposerIconButton_1.default, Object.assign({ className: classes.composer }, ComposerIconButtonProps)),
145
+ showComposer && react_1.default.createElement(ComposerIconButton_1.default, Object.assign({ className: classes.composer }, ComposerIconButtonProps)),
139
146
  react_1.default.createElement(material_1.Tooltip, { title: scUserContext.user.username },
140
147
  react_1.default.createElement(material_1.IconButton, { component: react_core_1.Link, to: scRoutingContext.url(react_core_1.SCRoutes.USER_PROFILE_ROUTE_NAME, scUserContext.user), "aria-label": "Profile", className: classes.profile },
141
148
  react_1.default.createElement(material_1.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.|
@@ -13,11 +13,13 @@ const SearchDialog_1 = tslib_1.__importDefault(require("../SearchDialog"));
13
13
  const NavigationSettingsIconButton_1 = tslib_1.__importDefault(require("../NavigationSettingsIconButton"));
14
14
  const NavigationMenuIconButton_1 = tslib_1.__importDefault(require("../NavigationMenuIconButton"));
15
15
  const constants_1 = require("./constants");
16
+ const types_1 = require("@selfcommunity/types");
16
17
  const classes = {
17
18
  root: `${constants_1.PREFIX}-root`,
18
19
  logo: `${constants_1.PREFIX}-logo`,
19
20
  search: `${constants_1.PREFIX}-search`,
20
21
  searchDialog: `${constants_1.PREFIX}-search-dialog`,
22
+ notifications: `${constants_1.PREFIX}-notifications`,
21
23
  settings: `${constants_1.PREFIX}-settings`,
22
24
  settingsDialog: `${constants_1.PREFIX}-settings-dialog`,
23
25
  login: `${constants_1.PREFIX}-login`
@@ -52,6 +54,7 @@ const Root = (0, material_1.styled)(material_1.Toolbar, {
52
54
  |logo|.SCNavigationToolbarMobile-logo|Styles applied to the logo element.|
53
55
  |search|.SCNavigationToolbarMobile-search|Styles applied to the search button element|
54
56
  |searchDialog|.SCNavigationToolbarMobile-search-dialog|Styles applied to the search dialog element|
57
+ |notifications|.SCNavigationToolbarMobile-notifications|Styles applied to the notifications button element|
55
58
  |settings|.SCNavigationToolbarMobile-settings|Styles applied to the settings button element|
56
59
  |settingsDialog|.SCNavigationToolbarMobile-settingsDialog|Styles applied to the settings dialog elements|
57
60
  |login|.SCNavigationToolbarMobile-login|Styles applied to the login element.|
@@ -69,9 +72,11 @@ function NavigationToolbarMobile(inProps) {
69
72
  const scUserContext = (0, react_core_1.useSCUser)();
70
73
  const scRoutingContext = (0, react_core_1.useSCRouting)();
71
74
  // PREFERENCES
72
- const { preferences } = (0, react_core_1.useSCPreferences)();
75
+ const { preferences, features } = (0, react_core_1.useSCPreferences)();
73
76
  // STATE
74
77
  const [searchOpen, setSearchOpen] = (0, react_1.useState)(false);
78
+ // MEMO
79
+ const groupsEnabled = (0, react_1.useMemo)(() => features.includes(types_1.SCFeatureName.GROUPING), [features]);
75
80
  // HANDLERS
76
81
  const handleOpenSearch = (0, react_1.useCallback)(() => {
77
82
  setSearchOpen(true);
@@ -94,6 +99,9 @@ function NavigationToolbarMobile(inProps) {
94
99
  react_1.default.createElement(Icon_1.default, null, "search")),
95
100
  react_1.default.createElement(SearchDialog_1.default, { className: classes.searchDialog, fullScreen: true, open: searchOpen, SearchAutocompleteProps: Object.assign(Object.assign({}, SearchAutocompleteProps), { onClear: handleCloseSearch }) }))),
96
101
  endActions,
102
+ scUserContext.user && groupsEnabled && (react_1.default.createElement(material_1.IconButton, { className: classes.notifications, component: react_core_1.Link, to: scRoutingContext.url(react_core_1.SCRoutes.USER_NOTIFICATIONS_ROUTE_NAME, {}) },
103
+ react_1.default.createElement(material_1.Badge, { badgeContent: scUserContext.user.unseen_notification_banners_counter + scUserContext.user.unseen_interactions_counter, color: "secondary" },
104
+ react_1.default.createElement(Icon_1.default, null, "notifications_active")))),
97
105
  scUserContext.user ? (react_1.default.createElement(NavigationSettingsIconButtonComponent, { className: classes.settings })) : (react_1.default.createElement(material_1.Button, { className: classes.login, color: "inherit", component: react_core_1.Link, to: scRoutingContext.url(react_core_1.SCRoutes.SIGNIN_ROUTE_NAME, {}) },
98
106
  react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.appBar.navigation.login", defaultMessage: "ui.appBar.navigation.login" })))));
99
107
  }
@@ -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,78 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const react_1 = tslib_1.__importStar(require("react"));
5
+ const styles_1 = require("@mui/material/styles");
6
+ const material_1 = require("@mui/material");
7
+ const react_core_1 = require("@selfcommunity/react-core");
8
+ const types_1 = require("@selfcommunity/types");
9
+ const react_intl_1 = require("react-intl");
10
+ const DateTimeAgo_1 = tslib_1.__importDefault(require("../../../shared/DateTimeAgo"));
11
+ const classnames_1 = tslib_1.__importDefault(require("classnames"));
12
+ const types_2 = require("../../../types");
13
+ const NotificationItem_1 = tslib_1.__importDefault(require("../../../shared/NotificationItem"));
14
+ const lab_1 = require("@mui/lab");
15
+ const UserDeletedSnackBar_1 = tslib_1.__importDefault(require("../../../shared/UserDeletedSnackBar"));
16
+ const UserAvatar_1 = tslib_1.__importDefault(require("../../../shared/UserAvatar"));
17
+ const constants_1 = require("../constants");
18
+ const classes = {
19
+ root: `${constants_1.PREFIX}-group-root`,
20
+ avatar: `${constants_1.PREFIX}-avatar`,
21
+ actions: `${constants_1.PREFIX}-actions`,
22
+ acceptButton: `${constants_1.PREFIX}-reply-button`,
23
+ activeAt: `${constants_1.PREFIX}-active-at`,
24
+ username: `${constants_1.PREFIX}-username`
25
+ };
26
+ const Root = (0, styles_1.styled)(NotificationItem_1.default, {
27
+ name: constants_1.PREFIX,
28
+ slot: 'GroupRoot'
29
+ })(() => ({}));
30
+ /**
31
+ * This component render the content of the notification of type group
32
+ * @constructor
33
+ * @param props
34
+ */
35
+ function GroupNotification(props) {
36
+ // PROPS
37
+ const { notificationObject, id = `n_${props.notificationObject['sid']}`, className, template = types_2.SCNotificationObjectTemplateType.DETAIL } = props, rest = tslib_1.__rest(props, ["notificationObject", "id", "className", "template"]);
38
+ // CONTEXT
39
+ const scRoutingContext = (0, react_core_1.useSCRouting)();
40
+ const scUserContext = (0, react_1.useContext)(react_core_1.SCUserContext);
41
+ const manager = scUserContext.managers.groups;
42
+ // STATE
43
+ const [status, setStatus] = (0, react_1.useState)(null);
44
+ const [openAlert, setOpenAlert] = (0, react_1.useState)(false);
45
+ // CONST
46
+ const isSnippetTemplate = template === types_2.SCNotificationObjectTemplateType.SNIPPET;
47
+ const isToastTemplate = template === types_2.SCNotificationObjectTemplateType.TOAST;
48
+ (0, react_1.useEffect)(() => {
49
+ setStatus(manager.subscriptionStatus(notificationObject.group));
50
+ }, [manager.subscriptionStatus, notificationObject.group]);
51
+ // RENDER
52
+ if (isSnippetTemplate || isToastTemplate) {
53
+ return (react_1.default.createElement(Root, Object.assign({ id: id, className: (0, classnames_1.default)(classes.root, className, `${constants_1.PREFIX}-${template}`), template: template, isNew: notificationObject.is_new, disableTypography: true, image: react_1.default.createElement(react_core_1.Link, Object.assign({}, (!notificationObject.user.deleted && {
54
+ to: scRoutingContext.url(react_core_1.SCRoutes.USER_PROFILE_ROUTE_NAME, notificationObject.user)
55
+ }), { onClick: notificationObject.user.deleted ? () => setOpenAlert(true) : null }),
56
+ react_1.default.createElement(UserAvatar_1.default, { hide: !notificationObject.user.community_badge, smaller: true },
57
+ react_1.default.createElement(material_1.Avatar, { alt: notificationObject.user.username, variant: "circular", src: notificationObject.user.avatar, classes: { root: classes.avatar } }))), primary: react_1.default.createElement(material_1.Box, null,
58
+ react_1.default.createElement(react_core_1.Link, Object.assign({}, (!notificationObject.user.deleted && {
59
+ to: scRoutingContext.url(react_core_1.SCRoutes.USER_PROFILE_ROUTE_NAME, notificationObject.user)
60
+ }), { onClick: notificationObject.user.deleted ? () => setOpenAlert(true) : null, className: classes.username }), notificationObject.user.username),
61
+ ' ',
62
+ react_1.default.createElement(react_intl_1.FormattedMessage, { id: `ui.notification.${notificationObject.type}`, defaultMessage: `ui.notification.${notificationObject.type}`, values: {
63
+ group: notificationObject.group.name,
64
+ link: (...chunks) => react_1.default.createElement(react_core_1.Link, { to: scRoutingContext.url(react_core_1.SCRoutes.GROUP_ROUTE_NAME, notificationObject.group) }, chunks)
65
+ } })), footer: isToastTemplate && (react_1.default.createElement(material_1.Stack, { direction: "row", justifyContent: "space-between", alignItems: "center", spacing: 2 },
66
+ react_1.default.createElement(DateTimeAgo_1.default, { date: notificationObject.active_at }),
67
+ status && status !== types_1.SCGroupSubscriptionStatusType.SUBSCRIBED && (react_1.default.createElement(material_1.Typography, { color: "primary" },
68
+ react_1.default.createElement(react_core_1.Link, { to: scRoutingContext.url(react_core_1.SCRoutes.GROUP_ROUTE_NAME, notificationObject.group) },
69
+ react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.notification.group.button.see", defaultMessage: "ui.notification.group.button.see" })))))) }, rest)));
70
+ }
71
+ return (react_1.default.createElement(react_1.default.Fragment, null,
72
+ react_1.default.createElement(Root, Object.assign({ id: id, className: (0, classnames_1.default)(classes.root, className, `${constants_1.PREFIX}-${template}`), template: template, isNew: notificationObject.is_new, disableTypography: true, actions: react_1.default.createElement(material_1.Stack, { direction: "row", justifyContent: "space-between", alignItems: "center", spacing: 2 },
73
+ react_1.default.createElement(DateTimeAgo_1.default, { date: notificationObject.active_at, className: classes.activeAt }),
74
+ status && status !== types_1.SCGroupSubscriptionStatusType.SUBSCRIBED && (react_1.default.createElement(lab_1.LoadingButton, { color: 'primary', variant: "outlined", size: "small", classes: { root: classes.acceptButton }, component: react_core_1.Link, loading: scUserContext.user ? status === null || manager.isLoading(notificationObject.group) : null, to: scRoutingContext.url(react_core_1.SCRoutes.GROUP_ROUTE_NAME, notificationObject.group) },
75
+ react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.notification.group.button.see", defaultMessage: "ui.notification.group.button.see" })))) }, rest)),
76
+ openAlert && react_1.default.createElement(UserDeletedSnackBar_1.default, { open: openAlert, handleClose: () => setOpenAlert(false) })));
77
+ }
78
+ exports.default = GroupNotification;
@@ -0,0 +1,3 @@
1
+ import GroupNotification, { NotificationGroupProps } from './Group';
2
+ export default GroupNotification;
3
+ export { NotificationGroupProps };
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const Group_1 = tslib_1.__importDefault(require("./Group"));
5
+ exports.default = Group_1.default;
@@ -35,6 +35,7 @@ const types_1 = require("@selfcommunity/types");
35
35
  const UserDeletedSnackBar_1 = tslib_1.__importDefault(require("../../shared/UserDeletedSnackBar"));
36
36
  const UserAvatar_1 = tslib_1.__importDefault(require("../../shared/UserAvatar"));
37
37
  const constants_1 = require("./constants");
38
+ const Group_1 = tslib_1.__importDefault(require("./Group"));
38
39
  const messages = (0, react_intl_1.defineMessages)({
39
40
  receivePrivateMessage: {
40
41
  id: 'ui.notification.receivePrivateMessage',
@@ -151,7 +152,7 @@ function UserNotification(inProps) {
151
152
  }
152
153
  /**
153
154
  * Handles vote
154
- * @param comment
155
+ * @param index
155
156
  */
156
157
  const handleVote = (index) => {
157
158
  return (contribution) => {
@@ -196,6 +197,29 @@ function UserNotification(inProps) {
196
197
  b: (...chunks) => react_1.default.createElement("strong", null, chunks)
197
198
  })) }));
198
199
  }
200
+ /**
201
+ * Group notifications header
202
+ */
203
+ if (notificationObject.aggregated &&
204
+ (notificationObject.aggregated[0].type === types_1.SCNotificationTypologyType.USER_INVITED_TO_JOIN_GROUP ||
205
+ notificationObject.aggregated[0].type === types_1.SCNotificationTypologyType.USER_ACCEPTED_TO_JOIN_GROUP ||
206
+ notificationObject.aggregated[0].type === types_1.SCNotificationTypologyType.USER_ADDED_TO_GROUP ||
207
+ notificationObject.aggregated[0].type === types_1.SCNotificationTypologyType.USER_REQUESTED_TO_JOIN_GROUP)) {
208
+ let groupNotification = notificationObject.aggregated[0];
209
+ return (react_1.default.createElement(material_1.CardHeader, { className: classes.header, avatar: react_1.default.createElement(react_core_1.Link, Object.assign({}, (!groupNotification.user.deleted && {
210
+ to: scRoutingContext.url(react_core_1.SCRoutes.USER_PROFILE_ROUTE_NAME, groupNotification.user)
211
+ }), { onClick: groupNotification.user.deleted ? () => setOpenAlert(true) : null }),
212
+ react_1.default.createElement(UserAvatar_1.default, { hide: !groupNotification.user.community_badge, smaller: true },
213
+ react_1.default.createElement(material_1.Avatar, { className: classes.avatar, alt: groupNotification.user.username, variant: "circular", src: groupNotification.user.avatar }))), titleTypographyProps: { className: classes.title, variant: 'subtitle1' }, title: react_1.default.createElement(react_1.default.Fragment, null,
214
+ react_1.default.createElement(react_core_1.Link, Object.assign({}, (!groupNotification.user.deleted && {
215
+ to: scRoutingContext.url(react_core_1.SCRoutes.USER_PROFILE_ROUTE_NAME, groupNotification.user)
216
+ }), { onClick: groupNotification.user.deleted ? () => setOpenAlert(true) : null, className: classes.username }), groupNotification.user.username),
217
+ ' ',
218
+ react_1.default.createElement(react_intl_1.FormattedMessage, { id: `ui.notification.${notificationObject.aggregated[0].type}`, defaultMessage: `ui.notification.${notificationObject.aggregated[0].type}`, values: {
219
+ group: groupNotification.group.name,
220
+ link: (...chunks) => react_1.default.createElement(react_core_1.Link, { to: scRoutingContext.url(react_core_1.SCRoutes.GROUP_ROUTE_NAME, groupNotification.group) }, chunks)
221
+ } })) }));
222
+ }
199
223
  /**
200
224
  * Comment, NestedComment, Follow Contribution header
201
225
  */
@@ -278,6 +302,12 @@ function UserNotification(inProps) {
278
302
  else if (n.type === types_1.SCNotificationTypologyType.CONTRIBUTION) {
279
303
  return react_1.default.createElement(Contribution_1.default, { notificationObject: n, key: i, onVote: handleVote(i) });
280
304
  }
305
+ else if (n.type === types_1.SCNotificationTypologyType.USER_ADDED_TO_GROUP ||
306
+ n.type === types_1.SCNotificationTypologyType.USER_INVITED_TO_JOIN_GROUP ||
307
+ n.type === types_1.SCNotificationTypologyType.USER_ACCEPTED_TO_JOIN_GROUP ||
308
+ n.type === types_1.SCNotificationTypologyType.USER_REQUESTED_TO_JOIN_GROUP) {
309
+ return react_1.default.createElement(Group_1.default, { notificationObject: n, key: i });
310
+ }
281
311
  return null;
282
312
  }
283
313
  /**
@@ -41,6 +41,7 @@ const Root = (0, styles_1.styled)(NotificationItem_1.default, {
41
41
  * @param props
42
42
  */
43
43
  function PrivateMessageNotification(props) {
44
+ var _a, _b, _c, _d, _e;
44
45
  // PROPS
45
46
  const { notificationObject, id = `n_${props.notificationObject['sid']}`, className, template = types_1.SCNotificationObjectTemplateType.DETAIL } = props, rest = tslib_1.__rest(props, ["notificationObject", "id", "className", "template"]);
46
47
  // CONTEXT
@@ -91,7 +92,9 @@ function PrivateMessageNotification(props) {
91
92
  react_1.default.createElement(react_intl_1.FormattedMessage, { id: 'ui.userToastNotifications.privateMessage.sentMessage', defaultMessage: 'ui.userToastNotifications.privateMessage.sentMessage' }),
92
93
  ":",
93
94
  react_1.default.createElement(material_1.Box, { className: classes.messageWrap },
94
- react_1.default.createElement(react_core_1.Link, { to: scRoutingContext.url(react_core_1.SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, notificationObject.message.sender), className: classes.message },
95
+ react_1.default.createElement(react_core_1.Link, { to: ((_a = notificationObject.message) === null || _a === void 0 ? void 0 : _a.group)
96
+ ? scRoutingContext.url(react_core_1.SCRoutes.GROUP_MESSAGES_ROUTE_NAME, notificationObject.message.group)
97
+ : scRoutingContext.url(react_core_1.SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, notificationObject.message.sender), className: classes.message },
95
98
  react_1.default.createElement(material_1.Typography, { variant: "body2", dangerouslySetInnerHTML: { __html: notificationObject.message.message } }))))),
96
99
  isSnippetTemplate && (react_1.default.createElement(material_1.Box, null,
97
100
  react_1.default.createElement(material_1.Typography, { component: "div", color: "inherit" },
@@ -99,13 +102,17 @@ function PrivateMessageNotification(props) {
99
102
  to: scRoutingContext.url(react_core_1.SCRoutes.USER_PROFILE_ROUTE_NAME, notificationObject.message.sender)
100
103
  }), { onClick: notificationObject.message.sender.deleted ? () => setOpenAlert(true) : null, className: classes.username }), notificationObject.message.sender.username),
101
104
  ' ',
102
- react_1.default.createElement(react_core_1.Link, { to: scRoutingContext.url(react_core_1.SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, notificationObject.message.sender), className: classes.messageLabel }, intl.formatMessage(messages.receivePrivateMessage, {
105
+ react_1.default.createElement(react_core_1.Link, { to: ((_b = notificationObject.message) === null || _b === void 0 ? void 0 : _b.group)
106
+ ? scRoutingContext.url(react_core_1.SCRoutes.GROUP_MESSAGES_ROUTE_NAME, notificationObject.message.group)
107
+ : scRoutingContext.url(react_core_1.SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, notificationObject.message.sender), className: classes.messageLabel }, intl.formatMessage(messages.receivePrivateMessage, {
103
108
  total: 1,
104
109
  b: (...chunks) => react_1.default.createElement("strong", null, chunks)
105
110
  })))))), footer: isToastTemplate && (react_1.default.createElement(material_1.Stack, { direction: "row", justifyContent: "space-between", alignItems: "center", spacing: 2 },
106
111
  react_1.default.createElement(DateTimeAgo_1.default, { date: notificationObject.active_at }),
107
112
  react_1.default.createElement(material_1.Typography, { color: "primary" },
108
- react_1.default.createElement(react_core_1.Link, { to: scRoutingContext.url(react_core_1.SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, notificationObject.message.sender) }, scUserContext.user && follower ? (react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.userToastNotifications.replyMessage", defaultMessage: 'ui.userToastNotifications.replyMessage' })) : (react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.userToastNotifications.viewMessage", defaultMessage: 'ui.userToastNotifications.viewMessage' })))))) }, rest)));
113
+ react_1.default.createElement(react_core_1.Link, { to: ((_c = notificationObject.message) === null || _c === void 0 ? void 0 : _c.group)
114
+ ? scRoutingContext.url(react_core_1.SCRoutes.GROUP_MESSAGES_ROUTE_NAME, notificationObject.message.group)
115
+ : scRoutingContext.url(react_core_1.SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, notificationObject.message.sender) }, scUserContext.user && follower ? (react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.userToastNotifications.replyMessage", defaultMessage: 'ui.userToastNotifications.replyMessage' })) : (react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.userToastNotifications.viewMessage", defaultMessage: 'ui.userToastNotifications.viewMessage' })))))) }, rest)));
109
116
  }
110
117
  return (react_1.default.createElement(react_1.default.Fragment, null,
111
118
  react_1.default.createElement(Root, Object.assign({ id: id, className: (0, classnames_1.default)(classes.root, className, `${constants_1.PREFIX}-${template}`), template: template, isNew: notificationObject.is_new, disableTypography: true, actions: react_1.default.createElement(material_1.Stack, { direction: "row", justifyContent: "space-between", alignItems: "center", spacing: 2 },
@@ -114,8 +121,12 @@ function PrivateMessageNotification(props) {
114
121
  ? null
115
122
  : scUserContext.user
116
123
  ? follower === null || manager.isLoading(notificationObject.message.sender)
117
- : null, to: scRoutingContext.url(react_core_1.SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, notificationObject.message.sender) }, scUserContext.user && follower ? (react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.notification.privateMessage.btnReplyLabel", defaultMessage: "ui.notification.privateMessage.btnReplyLabel" })) : (react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.notification.privateMessage.btnViewLabel", defaultMessage: "ui.notification.privateMessage.btnViewLabel" })))), primary: react_1.default.createElement(material_1.Box, { className: classes.messageWrap },
118
- react_1.default.createElement(react_core_1.Link, { to: scRoutingContext.url(react_core_1.SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, notificationObject.message.sender), className: classes.message },
124
+ : null, to: ((_d = notificationObject.message) === null || _d === void 0 ? void 0 : _d.group)
125
+ ? scRoutingContext.url(react_core_1.SCRoutes.GROUP_MESSAGES_ROUTE_NAME, notificationObject.message.group)
126
+ : scRoutingContext.url(react_core_1.SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, notificationObject.message.sender) }, scUserContext.user && follower ? (react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.notification.privateMessage.btnReplyLabel", defaultMessage: "ui.notification.privateMessage.btnReplyLabel" })) : (react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.notification.privateMessage.btnViewLabel", defaultMessage: "ui.notification.privateMessage.btnViewLabel" })))), primary: react_1.default.createElement(material_1.Box, { className: classes.messageWrap },
127
+ react_1.default.createElement(react_core_1.Link, { to: ((_e = notificationObject.message) === null || _e === void 0 ? void 0 : _e.group)
128
+ ? scRoutingContext.url(react_core_1.SCRoutes.GROUP_MESSAGES_ROUTE_NAME, notificationObject.message.group)
129
+ : scRoutingContext.url(react_core_1.SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, notificationObject.message.sender), className: classes.message },
119
130
  react_1.default.createElement(material_1.Typography, { variant: "body2", dangerouslySetInnerHTML: { __html: notificationObject.message.message } }))) }, rest)),
120
131
  openAlert && react_1.default.createElement(UserDeletedSnackBar_1.default, { open: openAlert, handleClose: () => setOpenAlert(false) })));
121
132
  }
@@ -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