@selfcommunity/react-ui 0.7.9-alpha.8 → 0.7.9-alpha.81
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/components/AccountRecover/AccountRecover.js +6 -1
- package/lib/cjs/components/BottomNavigation/BottomNavigation.js +4 -3
- package/lib/cjs/components/CategoryHeader/Skeleton.js +3 -2
- package/lib/cjs/components/ChangeGroupCover/ChangeGroupCover.js +6 -6
- package/lib/cjs/components/ChangeGroupPicture/ChangeGroupPicture.js +19 -16
- package/lib/cjs/components/Composer/Attributes/Attributes.js +3 -3
- package/lib/cjs/components/Composer/Composer.js +3 -3
- package/lib/cjs/components/Composer/Layer/AudienceLayer/AudienceLayer.d.ts +1 -1
- package/lib/cjs/components/Composer/Layer/AudienceLayer/AudienceLayer.js +9 -19
- package/lib/cjs/components/Editor/Editor.js +2 -0
- package/lib/cjs/components/Editor/nodes/ImageNode.js +6 -0
- package/lib/cjs/components/Editor/plugins/ImagePlugin.js +4 -0
- package/lib/cjs/components/Editor/plugins/ToolbarPlugin.js +17 -3
- package/lib/cjs/components/FeedObject/Actions/Share/Share.js +18 -16
- package/lib/cjs/components/FeedObject/Contributors/Contributors.js +1 -1
- package/lib/cjs/components/FeedObject/FeedObject.d.ts +1 -0
- package/lib/cjs/components/FeedObject/FeedObject.js +27 -8
- package/lib/cjs/components/FeedObject/Poll/Poll.js +20 -20
- package/lib/cjs/components/FeedUpdatesWidget/FeedUpdatesWidget.js +1 -1
- package/lib/cjs/components/Footer/Footer.js +1 -1
- package/lib/cjs/components/Group/Group.d.ts +9 -1
- package/lib/cjs/components/Group/Group.js +18 -6
- package/lib/cjs/components/GroupAutocomplete/GroupAutocomplete.d.ts +0 -1
- package/lib/cjs/components/GroupAutocomplete/GroupAutocomplete.js +1 -2
- package/lib/cjs/components/GroupForm/GroupForm.js +64 -13
- package/lib/cjs/components/GroupHeader/GroupHeader.d.ts +6 -6
- package/lib/cjs/components/GroupHeader/GroupHeader.js +53 -12
- package/lib/cjs/components/GroupInfoWidget/GroupInfoWidget.js +63 -9
- package/lib/cjs/components/GroupInviteButton/GroupInviteButton.js +31 -9
- package/lib/cjs/components/GroupInvitedWidget/GroupInvitedWidget.d.ts +73 -0
- package/lib/cjs/components/GroupInvitedWidget/GroupInvitedWidget.js +220 -0
- package/lib/cjs/components/GroupInvitedWidget/Skeleton.d.ts +22 -0
- package/lib/cjs/components/GroupInvitedWidget/Skeleton.js +38 -0
- package/lib/cjs/components/GroupInvitedWidget/constants.d.ts +1 -0
- package/lib/cjs/components/GroupInvitedWidget/constants.js +4 -0
- package/lib/cjs/components/GroupInvitedWidget/index.d.ts +4 -0
- package/lib/cjs/components/GroupInvitedWidget/index.js +8 -0
- package/lib/cjs/components/GroupMembersButton/GroupMembersButton.d.ts +5 -0
- package/lib/cjs/components/GroupMembersButton/GroupMembersButton.js +8 -3
- package/lib/cjs/components/GroupMembersWidget/GroupMembersWidget.js +25 -4
- package/lib/cjs/components/GroupRequestsWidget/GroupRequestsWidget.d.ts +12 -7
- package/lib/cjs/components/GroupRequestsWidget/GroupRequestsWidget.js +19 -9
- package/lib/cjs/components/GroupSettingsIconButton/GroupSettingsIconButton.d.ts +48 -0
- package/lib/cjs/components/GroupSettingsIconButton/GroupSettingsIconButton.js +151 -0
- package/lib/cjs/components/GroupSettingsIconButton/index.d.ts +3 -0
- package/lib/cjs/components/GroupSettingsIconButton/index.js +5 -0
- package/lib/cjs/components/GroupSubscribeButton/GroupSubscribeButton.d.ts +8 -3
- package/lib/cjs/components/GroupSubscribeButton/GroupSubscribeButton.js +30 -11
- package/lib/cjs/components/Groups/Groups.d.ts +15 -8
- package/lib/cjs/components/Groups/Groups.js +86 -32
- package/lib/cjs/components/Groups/Skeleton.d.ts +4 -0
- package/lib/cjs/components/Groups/Skeleton.js +2 -2
- package/lib/cjs/components/InlineComposerWidget/InlineComposerWidget.js +7 -0
- package/lib/cjs/components/NavigationSettingsIconButton/NavigationSettingsIconButton.js +4 -4
- package/lib/cjs/components/NavigationToolbar/NavigationToolbar.js +9 -2
- package/lib/cjs/components/NavigationToolbarMobile/NavigationToolbarMobile.d.ts +1 -0
- package/lib/cjs/components/NavigationToolbarMobile/NavigationToolbarMobile.js +9 -1
- package/lib/cjs/components/Notification/Group/Group.d.ts +15 -0
- package/lib/cjs/components/Notification/Group/Group.js +78 -0
- package/lib/cjs/components/Notification/Group/index.d.ts +3 -0
- package/lib/cjs/components/Notification/Group/index.js +5 -0
- package/lib/cjs/components/Notification/Notification.js +31 -1
- package/lib/cjs/components/Notification/PrivateMessage/PrivateMessage.js +16 -5
- package/lib/cjs/components/PrivateMessageComponent/PrivateMessageComponent.d.ts +7 -1
- package/lib/cjs/components/PrivateMessageComponent/PrivateMessageComponent.js +16 -8
- package/lib/cjs/components/PrivateMessageSettingsIconButton/PrivateMessageSettingsIconButton.js +1 -1
- package/lib/cjs/components/PrivateMessageSnippetItem/PrivateMessageSnippetItem.js +11 -6
- package/lib/cjs/components/PrivateMessageSnippets/PrivateMessageSnippets.d.ts +9 -4
- package/lib/cjs/components/PrivateMessageSnippets/PrivateMessageSnippets.js +24 -6
- package/lib/cjs/components/PrivateMessageThread/PrivateMessageThread.d.ts +6 -1
- package/lib/cjs/components/PrivateMessageThread/PrivateMessageThread.js +46 -20
- package/lib/cjs/components/PrivateMessageThreadItem/PrivateMessageThreadItem.js +6 -0
- package/lib/cjs/components/SearchAutocomplete/SearchAutocomplete.js +22 -5
- package/lib/cjs/components/SnippetNotifications/SnippetNotifications.js +7 -0
- package/lib/cjs/components/ToastNotifications/ToastNotifications.js +7 -0
- package/lib/cjs/components/User/User.d.ts +6 -1
- package/lib/cjs/components/User/User.js +5 -4
- package/lib/cjs/components/UserSubscribedGroupsWidget/Skeleton.d.ts +21 -0
- package/lib/cjs/components/UserSubscribedGroupsWidget/Skeleton.js +46 -0
- package/lib/cjs/components/UserSubscribedGroupsWidget/UserSubscribedGroupsWidget.d.ts +68 -0
- package/lib/cjs/components/UserSubscribedGroupsWidget/UserSubscribedGroupsWidget.js +183 -0
- package/lib/cjs/components/UserSubscribedGroupsWidget/constants.d.ts +1 -0
- package/lib/cjs/components/UserSubscribedGroupsWidget/constants.js +4 -0
- package/lib/cjs/components/UserSubscribedGroupsWidget/index.d.ts +4 -0
- package/lib/cjs/components/UserSubscribedGroupsWidget/index.js +8 -0
- package/lib/cjs/components/VoteAudienceButton/VoteAudienceButton.js +1 -1
- package/lib/cjs/constants/PubSub.d.ts +28 -0
- package/lib/cjs/constants/PubSub.js +22 -0
- package/lib/cjs/index.d.ts +6 -3
- package/lib/cjs/index.js +13 -4
- package/lib/cjs/types/index.d.ts +2 -1
- package/lib/esm/components/AccountRecover/AccountRecover.js +6 -1
- package/lib/esm/components/BottomNavigation/BottomNavigation.js +5 -4
- package/lib/esm/components/CategoryHeader/Skeleton.js +3 -2
- package/lib/esm/components/ChangeGroupCover/ChangeGroupCover.js +6 -6
- package/lib/esm/components/ChangeGroupPicture/ChangeGroupPicture.js +19 -16
- package/lib/esm/components/Composer/Attributes/Attributes.js +3 -3
- package/lib/esm/components/Composer/Composer.js +3 -3
- package/lib/esm/components/Composer/Layer/AudienceLayer/AudienceLayer.d.ts +1 -1
- package/lib/esm/components/Composer/Layer/AudienceLayer/AudienceLayer.js +9 -19
- package/lib/esm/components/Editor/Editor.js +2 -0
- package/lib/esm/components/Editor/nodes/ImageNode.js +6 -0
- package/lib/esm/components/Editor/plugins/ImagePlugin.js +4 -0
- package/lib/esm/components/Editor/plugins/ToolbarPlugin.js +19 -5
- package/lib/esm/components/FeedObject/Actions/Share/Share.js +19 -17
- package/lib/esm/components/FeedObject/Contributors/Contributors.js +1 -1
- package/lib/esm/components/FeedObject/FeedObject.d.ts +1 -0
- package/lib/esm/components/FeedObject/FeedObject.js +28 -9
- package/lib/esm/components/FeedObject/Poll/Poll.js +20 -20
- package/lib/esm/components/FeedUpdatesWidget/FeedUpdatesWidget.js +1 -1
- package/lib/esm/components/Footer/Footer.js +2 -2
- package/lib/esm/components/Group/Group.d.ts +9 -1
- package/lib/esm/components/Group/Group.js +22 -10
- package/lib/esm/components/GroupAutocomplete/GroupAutocomplete.d.ts +0 -1
- package/lib/esm/components/GroupAutocomplete/GroupAutocomplete.js +1 -2
- package/lib/esm/components/GroupForm/GroupForm.js +64 -13
- package/lib/esm/components/GroupHeader/GroupHeader.d.ts +6 -6
- package/lib/esm/components/GroupHeader/GroupHeader.js +55 -14
- package/lib/esm/components/GroupInfoWidget/GroupInfoWidget.js +63 -9
- package/lib/esm/components/GroupInviteButton/GroupInviteButton.js +31 -9
- package/lib/esm/components/GroupInvitedWidget/GroupInvitedWidget.d.ts +73 -0
- package/lib/esm/components/GroupInvitedWidget/GroupInvitedWidget.js +217 -0
- package/lib/esm/components/GroupInvitedWidget/Skeleton.d.ts +22 -0
- package/lib/esm/components/GroupInvitedWidget/Skeleton.js +34 -0
- package/lib/esm/components/GroupInvitedWidget/constants.d.ts +1 -0
- package/lib/esm/components/GroupInvitedWidget/constants.js +1 -0
- package/lib/esm/components/GroupInvitedWidget/index.d.ts +4 -0
- package/lib/esm/components/GroupInvitedWidget/index.js +4 -0
- package/lib/esm/components/GroupMembersButton/GroupMembersButton.d.ts +5 -0
- package/lib/esm/components/GroupMembersButton/GroupMembersButton.js +9 -4
- package/lib/esm/components/GroupMembersWidget/GroupMembersWidget.js +26 -5
- package/lib/esm/components/GroupRequestsWidget/GroupRequestsWidget.d.ts +12 -7
- package/lib/esm/components/GroupRequestsWidget/GroupRequestsWidget.js +19 -9
- package/lib/esm/components/GroupSettingsIconButton/GroupSettingsIconButton.d.ts +48 -0
- package/lib/esm/components/GroupSettingsIconButton/GroupSettingsIconButton.js +148 -0
- package/lib/esm/components/GroupSettingsIconButton/index.d.ts +3 -0
- package/lib/esm/components/GroupSettingsIconButton/index.js +2 -0
- package/lib/esm/components/GroupSubscribeButton/GroupSubscribeButton.d.ts +8 -3
- package/lib/esm/components/GroupSubscribeButton/GroupSubscribeButton.js +30 -11
- package/lib/esm/components/Groups/Groups.d.ts +15 -8
- package/lib/esm/components/Groups/Groups.js +91 -37
- package/lib/esm/components/Groups/Skeleton.d.ts +4 -0
- package/lib/esm/components/Groups/Skeleton.js +2 -2
- package/lib/esm/components/InlineComposerWidget/InlineComposerWidget.js +9 -2
- package/lib/esm/components/NavigationSettingsIconButton/NavigationSettingsIconButton.js +4 -4
- package/lib/esm/components/NavigationToolbar/NavigationToolbar.js +10 -3
- package/lib/esm/components/NavigationToolbarMobile/NavigationToolbarMobile.d.ts +1 -0
- package/lib/esm/components/NavigationToolbarMobile/NavigationToolbarMobile.js +11 -3
- package/lib/esm/components/Notification/Group/Group.d.ts +15 -0
- package/lib/esm/components/Notification/Group/Group.js +75 -0
- package/lib/esm/components/Notification/Group/index.d.ts +3 -0
- package/lib/esm/components/Notification/Group/index.js +2 -0
- package/lib/esm/components/Notification/Notification.js +31 -1
- package/lib/esm/components/Notification/PrivateMessage/PrivateMessage.js +16 -5
- package/lib/esm/components/PrivateMessageComponent/PrivateMessageComponent.d.ts +7 -1
- package/lib/esm/components/PrivateMessageComponent/PrivateMessageComponent.js +17 -9
- package/lib/esm/components/PrivateMessageSettingsIconButton/PrivateMessageSettingsIconButton.js +1 -1
- package/lib/esm/components/PrivateMessageSnippetItem/PrivateMessageSnippetItem.js +11 -6
- package/lib/esm/components/PrivateMessageSnippets/PrivateMessageSnippets.d.ts +9 -4
- package/lib/esm/components/PrivateMessageSnippets/PrivateMessageSnippets.js +26 -8
- package/lib/esm/components/PrivateMessageThread/PrivateMessageThread.d.ts +6 -1
- package/lib/esm/components/PrivateMessageThread/PrivateMessageThread.js +48 -22
- package/lib/esm/components/PrivateMessageThreadItem/PrivateMessageThreadItem.js +7 -1
- package/lib/esm/components/SearchAutocomplete/SearchAutocomplete.js +22 -5
- package/lib/esm/components/SnippetNotifications/SnippetNotifications.js +7 -0
- package/lib/esm/components/ToastNotifications/ToastNotifications.js +7 -0
- package/lib/esm/components/User/User.d.ts +6 -1
- package/lib/esm/components/User/User.js +5 -4
- package/lib/esm/components/UserSubscribedGroupsWidget/Skeleton.d.ts +21 -0
- package/lib/esm/components/UserSubscribedGroupsWidget/Skeleton.js +42 -0
- package/lib/esm/components/UserSubscribedGroupsWidget/UserSubscribedGroupsWidget.d.ts +68 -0
- package/lib/esm/components/UserSubscribedGroupsWidget/UserSubscribedGroupsWidget.js +180 -0
- package/lib/esm/components/UserSubscribedGroupsWidget/constants.d.ts +1 -0
- package/lib/esm/components/UserSubscribedGroupsWidget/constants.js +1 -0
- package/lib/esm/components/UserSubscribedGroupsWidget/index.d.ts +4 -0
- package/lib/esm/components/UserSubscribedGroupsWidget/index.js +4 -0
- package/lib/esm/components/VoteAudienceButton/VoteAudienceButton.js +1 -1
- package/lib/esm/constants/PubSub.d.ts +28 -0
- package/lib/esm/constants/PubSub.js +19 -0
- package/lib/esm/index.d.ts +6 -3
- package/lib/esm/index.js +6 -3
- package/lib/esm/types/index.d.ts +2 -1
- package/lib/umd/311.js +2 -0
- package/lib/umd/react-ui.js +1 -1
- package/package.json +9 -9
- package/lib/umd/871.js +0 -2
- /package/lib/umd/{871.js.LICENSE.txt → 311.js.LICENSE.txt} +0 -0
|
@@ -18,6 +18,7 @@ import { useThemeProps } from '@mui/system';
|
|
|
18
18
|
import HiddenPlaceholder from '../../shared/HiddenPlaceholder';
|
|
19
19
|
import { PREFIX } from './constants';
|
|
20
20
|
import User, { UserSkeleton } from '../User';
|
|
21
|
+
import GroupSubscribeButton from '../GroupSubscribeButton';
|
|
21
22
|
const classes = {
|
|
22
23
|
root: `${PREFIX}-root`,
|
|
23
24
|
title: `${PREFIX}-title`,
|
|
@@ -38,8 +39,7 @@ const DialogRoot = styled(BaseDialog, {
|
|
|
38
39
|
* > API documentation for the Community-JS Group Requests Widget component. Learn about the available props and the CSS API.
|
|
39
40
|
*
|
|
40
41
|
*
|
|
41
|
-
* This component
|
|
42
|
-
* Take a look at our <strong>demo</strong> component [here](/docs/sdk/community-js/react-ui/Components/GroupRequests)
|
|
42
|
+
* This component displays the list of users who have requested access to the specified group.
|
|
43
43
|
|
|
44
44
|
#### Import
|
|
45
45
|
|
|
@@ -66,12 +66,13 @@ const DialogRoot = styled(BaseDialog, {
|
|
|
66
66
|
* @param inProps
|
|
67
67
|
*/
|
|
68
68
|
export default function GroupRequestsWidget(inProps) {
|
|
69
|
+
var _a;
|
|
69
70
|
// PROPS
|
|
70
71
|
const props = useThemeProps({
|
|
71
72
|
props: inProps,
|
|
72
73
|
name: PREFIX
|
|
73
74
|
});
|
|
74
|
-
const { groupId, group,
|
|
75
|
+
const { groupId, group, limit = 5, className, cacheStrategy = CacheStrategies.NETWORK_ONLY, onHeightChange, onStateChange, UserProps = {}, DialogProps = {}, GroupSubscribeButtonProps = {}, onSubscribeActon } = props, rest = __rest(props, ["groupId", "group", "limit", "className", "cacheStrategy", "onHeightChange", "onStateChange", "UserProps", "DialogProps", "GroupSubscribeButtonProps", "onSubscribeActon"]);
|
|
75
76
|
// STATE
|
|
76
77
|
const [state, dispatch] = useReducer(dataWidgetReducer, {
|
|
77
78
|
isLoadingNext: false,
|
|
@@ -91,6 +92,7 @@ export default function GroupRequestsWidget(inProps) {
|
|
|
91
92
|
// HOOKS
|
|
92
93
|
const theme = useTheme();
|
|
93
94
|
const isMobile = useMediaQuery(theme.breakpoints.down('md'));
|
|
95
|
+
const isGroupAdmin = useMemo(() => { var _a; return scUserContext.user && ((_a = scGroup === null || scGroup === void 0 ? void 0 : scGroup.managed_by) === null || _a === void 0 ? void 0 : _a.id) === scUserContext.user.id; }, [scUserContext.user, (_a = scGroup === null || scGroup === void 0 ? void 0 : scGroup.managed_by) === null || _a === void 0 ? void 0 : _a.id]);
|
|
94
96
|
/**
|
|
95
97
|
* Initialize component
|
|
96
98
|
* Fetch data only if the component is not initialized and it is not loading data
|
|
@@ -166,8 +168,17 @@ export default function GroupRequestsWidget(inProps) {
|
|
|
166
168
|
const handleToggleDialogOpen = () => {
|
|
167
169
|
setOpenDialog((prev) => !prev);
|
|
168
170
|
};
|
|
171
|
+
const handleSubscribeAction = useMemo(() => (user) => {
|
|
172
|
+
const newRequests = [...state.results];
|
|
173
|
+
const _updated = newRequests.filter((u) => u.id !== user.id);
|
|
174
|
+
dispatch({
|
|
175
|
+
type: actionWidgetTypes.SET_RESULTS,
|
|
176
|
+
payload: { results: newRequests.length > 1 ? _updated : [] }
|
|
177
|
+
});
|
|
178
|
+
onSubscribeActon && onSubscribeActon(user);
|
|
179
|
+
}, [dispatch, state.count, state.results, onSubscribeActon]);
|
|
169
180
|
// RENDER
|
|
170
|
-
if ((
|
|
181
|
+
if ((!state.count && state.initialized) || !contentAvailability || !scGroup || !state.count || !state.results.length || !isGroupAdmin) {
|
|
171
182
|
return React.createElement(HiddenPlaceholder, null);
|
|
172
183
|
}
|
|
173
184
|
if (!state.initialized) {
|
|
@@ -176,16 +187,15 @@ export default function GroupRequestsWidget(inProps) {
|
|
|
176
187
|
const content = (React.createElement(CardContent, null,
|
|
177
188
|
React.createElement(Typography, { className: classes.title, variant: "h5" },
|
|
178
189
|
React.createElement(FormattedMessage, { id: "ui.groupRequestsWidget.title", defaultMessage: "ui.groupRequestsWidget.title" })),
|
|
179
|
-
|
|
180
|
-
React.createElement(FormattedMessage, { id: "ui.groupRequestsWidget.subtitle.noResults", defaultMessage: "" }))) : (React.createElement(React.Fragment, null,
|
|
190
|
+
React.createElement(React.Fragment, null,
|
|
181
191
|
React.createElement(List, null, state.results.slice(0, state.visibleItems).map((user) => (React.createElement(ListItem, { key: user.id },
|
|
182
|
-
React.createElement(User, { elevation: 0, actions: React.createElement(
|
|
192
|
+
React.createElement(User, { elevation: 0, actions: React.createElement(GroupSubscribeButton, Object.assign({ group: scGroup, groupId: scGroup === null || scGroup === void 0 ? void 0 : scGroup.id, user: user, onSubscribe: () => handleSubscribeAction(user) }, GroupSubscribeButtonProps)), user: user, userId: user.id }))))),
|
|
183
193
|
state.count > state.visibleItems && (React.createElement(Button, { className: classes.showMore, onClick: handleToggleDialogOpen },
|
|
184
|
-
React.createElement(FormattedMessage, { id: "ui.groupRequestsWidget.button.showMore", defaultMessage: "ui.groupRequestsWidget.button.showMore" }))))
|
|
194
|
+
React.createElement(FormattedMessage, { id: "ui.groupRequestsWidget.button.showMore", defaultMessage: "ui.groupRequestsWidget.button.showMore" })))),
|
|
185
195
|
openDialog && (React.createElement(DialogRoot, Object.assign({ className: classes.dialogRoot, title: React.createElement(FormattedMessage, { defaultMessage: "ui.groupRequestsWidget.dialogTitle", id: "ui.groupRequestsWidget.dialogTitle", values: { total: scGroup.subscribers_counter } }), onClose: handleToggleDialogOpen, open: openDialog }, DialogProps),
|
|
186
196
|
React.createElement(InfiniteScroll, { dataLength: state.results.length, next: handleNext, hasMoreNext: Boolean(state.next), loaderNext: React.createElement(UserSkeleton, Object.assign({ elevation: 0 }, UserProps)), height: isMobile ? '100%' : 400, endMessage: React.createElement(Typography, { className: classes.endMessage },
|
|
187
197
|
React.createElement(FormattedMessage, { id: "ui.groupRequestsWidget.noMoreResults", defaultMessage: "ui.groupRequestsWidget.noMoreResults" })) },
|
|
188
198
|
React.createElement(List, null, state.results.map((user) => (React.createElement(ListItem, { key: user.id },
|
|
189
|
-
React.createElement(User, { elevation: 0, actions: React.createElement(
|
|
199
|
+
React.createElement(User, { elevation: 0, actions: React.createElement(GroupSubscribeButton, Object.assign({ group: scGroup, groupId: scGroup === null || scGroup === void 0 ? void 0 : scGroup.id, user: user, onSubscribe: () => handleSubscribeAction(user) }, GroupSubscribeButtonProps)), user: user, userId: user.id }))))))))));
|
|
190
200
|
return (React.createElement(Root, Object.assign({ className: classNames(classes.root, className) }, rest), content));
|
|
191
201
|
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { IconButtonProps } from '@mui/material';
|
|
2
|
+
import { SCGroupType, SCUserType } from '@selfcommunity/types';
|
|
3
|
+
export interface GroupSettingsIconButtonProps extends IconButtonProps {
|
|
4
|
+
/**
|
|
5
|
+
* Overrides or extends the styles applied to the component.
|
|
6
|
+
* @default null
|
|
7
|
+
*/
|
|
8
|
+
className?: string;
|
|
9
|
+
/**
|
|
10
|
+
* Handles callback on delete success
|
|
11
|
+
*/
|
|
12
|
+
onRemoveSuccess?: () => void;
|
|
13
|
+
/**
|
|
14
|
+
* The user
|
|
15
|
+
*/
|
|
16
|
+
user: SCUserType;
|
|
17
|
+
/**
|
|
18
|
+
* The group obj
|
|
19
|
+
*/
|
|
20
|
+
group: SCGroupType;
|
|
21
|
+
/**
|
|
22
|
+
* Any other properties
|
|
23
|
+
*/
|
|
24
|
+
[p: string]: any;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* > API documentation for the Community-JS PrivateMessageSettingsIconButton component. Learn about the available props and the CSS API.
|
|
28
|
+
|
|
29
|
+
#### Import
|
|
30
|
+
|
|
31
|
+
```jsx
|
|
32
|
+
import {PrivateMessageSettingsIconButton} from '@selfcommunity/react-ui';
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
#### Component Name
|
|
36
|
+
|
|
37
|
+
The name `SCGroupSettingsIconButton` can be used when providing style overrides in the theme.
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
#### CSS
|
|
41
|
+
|
|
42
|
+
|Rule Name|Global class|Description|
|
|
43
|
+
|---|---|---|
|
|
44
|
+
|root|.SCGroupSettingsIconButton-root|Styles applied to the root element.|
|
|
45
|
+
|
|
46
|
+
* @param inProps
|
|
47
|
+
*/
|
|
48
|
+
export default function GroupSettingsIconButton(inProps: GroupSettingsIconButtonProps): JSX.Element;
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { __rest } from "tslib";
|
|
2
|
+
import React, { useState } from 'react';
|
|
3
|
+
import { styled } from '@mui/material/styles';
|
|
4
|
+
import { SwipeableDrawer, MenuItem, IconButton, Menu, useTheme, useMediaQuery, List, ListItem } from '@mui/material';
|
|
5
|
+
import { FormattedMessage } from 'react-intl';
|
|
6
|
+
import Icon from '@mui/material/Icon';
|
|
7
|
+
import classNames from 'classnames';
|
|
8
|
+
import { useThemeProps } from '@mui/system';
|
|
9
|
+
import { Link, SCRoutes, useSCRouting, useSCUser } from '@selfcommunity/react-core';
|
|
10
|
+
import ConfirmDialog from '../../shared/ConfirmDialog/ConfirmDialog';
|
|
11
|
+
import { GroupService } from '@selfcommunity/api-services';
|
|
12
|
+
import { SCEventType, SCTopicType } from '../../constants/PubSub';
|
|
13
|
+
import PubSub from 'pubsub-js';
|
|
14
|
+
const PREFIX = 'SCGroupSettingsIconButton';
|
|
15
|
+
const classes = {
|
|
16
|
+
root: `${PREFIX}-root`,
|
|
17
|
+
drawerRoot: `${PREFIX}-drawer-root`,
|
|
18
|
+
menuRoot: `${PREFIX}-menu-root`,
|
|
19
|
+
paper: `${PREFIX}-paper`,
|
|
20
|
+
item: `${PREFIX}-item`
|
|
21
|
+
};
|
|
22
|
+
const Root = styled(IconButton, {
|
|
23
|
+
name: PREFIX,
|
|
24
|
+
slot: 'Root'
|
|
25
|
+
})(() => ({}));
|
|
26
|
+
const SwipeableDrawerRoot = styled(SwipeableDrawer, {
|
|
27
|
+
name: PREFIX,
|
|
28
|
+
slot: 'DrawerRoot'
|
|
29
|
+
})(() => ({}));
|
|
30
|
+
const MenuRoot = styled(Menu, {
|
|
31
|
+
name: PREFIX,
|
|
32
|
+
slot: 'MenuRoot'
|
|
33
|
+
})(() => ({}));
|
|
34
|
+
/**
|
|
35
|
+
* > API documentation for the Community-JS PrivateMessageSettingsIconButton component. Learn about the available props and the CSS API.
|
|
36
|
+
|
|
37
|
+
#### Import
|
|
38
|
+
|
|
39
|
+
```jsx
|
|
40
|
+
import {PrivateMessageSettingsIconButton} from '@selfcommunity/react-ui';
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
#### Component Name
|
|
44
|
+
|
|
45
|
+
The name `SCGroupSettingsIconButton` can be used when providing style overrides in the theme.
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
#### CSS
|
|
49
|
+
|
|
50
|
+
|Rule Name|Global class|Description|
|
|
51
|
+
|---|---|---|
|
|
52
|
+
|root|.SCGroupSettingsIconButton-root|Styles applied to the root element.|
|
|
53
|
+
|
|
54
|
+
* @param inProps
|
|
55
|
+
*/
|
|
56
|
+
export default function GroupSettingsIconButton(inProps) {
|
|
57
|
+
// PROPS
|
|
58
|
+
const props = useThemeProps({
|
|
59
|
+
props: inProps,
|
|
60
|
+
name: PREFIX
|
|
61
|
+
});
|
|
62
|
+
const { className = null, group, user, onRemoveSuccess } = props, rest = __rest(props, ["className", "group", "user", "onRemoveSuccess"]);
|
|
63
|
+
// STATE
|
|
64
|
+
const [anchorEl, setAnchorEl] = useState(null);
|
|
65
|
+
const [openConfirmDialog, setOpenConfirmDialog] = useState(false);
|
|
66
|
+
// HOOKS
|
|
67
|
+
const theme = useTheme();
|
|
68
|
+
const isMobile = useMediaQuery(theme.breakpoints.down('md'));
|
|
69
|
+
const scRoutingContext = useSCRouting();
|
|
70
|
+
// CONTEXT
|
|
71
|
+
const scUserContext = useSCUser();
|
|
72
|
+
// HANDLERS
|
|
73
|
+
const handleOpen = (event) => {
|
|
74
|
+
setAnchorEl(event.currentTarget);
|
|
75
|
+
};
|
|
76
|
+
const handleClose = () => {
|
|
77
|
+
setAnchorEl(null);
|
|
78
|
+
};
|
|
79
|
+
const handleOpenDialog = () => {
|
|
80
|
+
setOpenConfirmDialog(true);
|
|
81
|
+
setAnchorEl(null);
|
|
82
|
+
};
|
|
83
|
+
const handleCloseDialog = () => {
|
|
84
|
+
setOpenConfirmDialog(false);
|
|
85
|
+
setAnchorEl(null);
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* Notify UI when a user is removed from a group
|
|
89
|
+
* @param group
|
|
90
|
+
* @param user
|
|
91
|
+
*/
|
|
92
|
+
function notifyChanges(group, user) {
|
|
93
|
+
if (group && user) {
|
|
94
|
+
PubSub.publish(`${SCTopicType.GROUP}.${SCEventType.REMOVE_MEMBER}`, { group, user });
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Handles thread deletion
|
|
99
|
+
*/
|
|
100
|
+
function handleRemoveUser() {
|
|
101
|
+
GroupService.removeUserFromGroup(group.id, user.id)
|
|
102
|
+
.then(() => {
|
|
103
|
+
notifyChanges(group, user);
|
|
104
|
+
onRemoveSuccess && onRemoveSuccess();
|
|
105
|
+
handleCloseDialog();
|
|
106
|
+
})
|
|
107
|
+
.catch((error) => {
|
|
108
|
+
setOpenConfirmDialog(false);
|
|
109
|
+
console.log(error);
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
if (scUserContext.user.id === user.id) {
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
*
|
|
117
|
+
*/
|
|
118
|
+
const renderList = () => {
|
|
119
|
+
if (isMobile) {
|
|
120
|
+
return [
|
|
121
|
+
React.createElement(ListItem, { className: classes.item, key: "message", component: Link, to: scRoutingContext.url(SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, user) },
|
|
122
|
+
React.createElement(FormattedMessage, { id: "ui.groupSettingsIconButton.item.message", defaultMessage: "ui.groupSettingsIconButton.item.message" })),
|
|
123
|
+
React.createElement(ListItem, { className: classes.item, key: "delete", onClick: handleOpenDialog },
|
|
124
|
+
React.createElement(FormattedMessage, { id: "ui.groupSettingsIconButton.item.remove", defaultMessage: "ui.groupSettingsIconButton.item.remove" }))
|
|
125
|
+
];
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
return [
|
|
129
|
+
React.createElement(MenuItem, { className: classes.item, component: Link, to: scRoutingContext.url(SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, user), key: "message" },
|
|
130
|
+
React.createElement(FormattedMessage, { id: "ui.groupSettingsIconButton.item.message", defaultMessage: "ui.groupSettingsIconButton.item.message" })),
|
|
131
|
+
React.createElement(MenuItem, { className: classes.item, onClick: handleOpenDialog, key: "delete" },
|
|
132
|
+
React.createElement(FormattedMessage, { id: "ui.groupSettingsIconButton.item.remove", defaultMessage: "ui.groupSettingsIconButton.item.remove" }))
|
|
133
|
+
];
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
return (React.createElement(React.Fragment, null,
|
|
137
|
+
React.createElement(Root, Object.assign({ className: classNames(classes.root, className) }, rest, { onClick: handleOpen }),
|
|
138
|
+
React.createElement(Icon, null, "more_vert")),
|
|
139
|
+
isMobile ? (React.createElement(SwipeableDrawerRoot, { className: classes.drawerRoot, anchor: "bottom", open: Boolean(anchorEl), onClose: handleClose, onOpen: handleOpen, PaperProps: { className: classes.paper }, disableSwipeToOpen: true },
|
|
140
|
+
React.createElement(List, null, renderList()))) : (React.createElement(MenuRoot, { className: classes.menuRoot, anchorEl: anchorEl, open: Boolean(anchorEl), onClose: handleClose, PaperProps: { className: classes.paper } }, renderList())),
|
|
141
|
+
openConfirmDialog && (React.createElement(ConfirmDialog, { open: openConfirmDialog, title: React.createElement(FormattedMessage, { id: "ui.groupSettingsIconButton.dialog.msg", defaultMessage: "ui.groupSettingsIconButton.dialog.msg", values: {
|
|
142
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
|
143
|
+
// @ts-ignore
|
|
144
|
+
b: (...chunks) => React.createElement("strong", null, chunks),
|
|
145
|
+
user: user.username,
|
|
146
|
+
group: group.name
|
|
147
|
+
} }), btnConfirm: React.createElement(FormattedMessage, { id: "ui.groupSettingsIconButton.dialog.confirm", defaultMessage: "ui.groupSettingsIconButton.dialog.confirm" }), onConfirm: handleRemoveUser, onClose: handleCloseDialog }))));
|
|
148
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SCGroupType } from '@selfcommunity/types';
|
|
1
|
+
import { SCGroupType, SCUserType } from '@selfcommunity/types';
|
|
2
2
|
export interface GroupSubscribeButtonProps {
|
|
3
3
|
/**
|
|
4
4
|
* Overrides or extends the styles applied to the component.
|
|
@@ -16,11 +16,16 @@ export interface GroupSubscribeButtonProps {
|
|
|
16
16
|
*/
|
|
17
17
|
groupId?: number;
|
|
18
18
|
/**
|
|
19
|
-
*
|
|
19
|
+
* The user to be accepted into the group
|
|
20
|
+
* @default null
|
|
21
|
+
*/
|
|
22
|
+
user?: SCUserType;
|
|
23
|
+
/**
|
|
24
|
+
* onSubscribe callback
|
|
20
25
|
* @param user
|
|
21
26
|
* @param joined
|
|
22
27
|
*/
|
|
23
|
-
|
|
28
|
+
onSubscribe?: (group: SCGroupType, status: string | null) => any;
|
|
24
29
|
/**
|
|
25
30
|
* Others properties
|
|
26
31
|
*/
|
|
@@ -9,6 +9,8 @@ import { FormattedMessage } from 'react-intl';
|
|
|
9
9
|
import classNames from 'classnames';
|
|
10
10
|
import { useThemeProps } from '@mui/system';
|
|
11
11
|
import { SCOPE_SC_UI } from '../../constants/Errors';
|
|
12
|
+
import { SCEventType, SCTopicType } from '../../constants/PubSub';
|
|
13
|
+
import PubSub from 'pubsub-js';
|
|
12
14
|
const PREFIX = 'SCGroupSubscribeButton';
|
|
13
15
|
const classes = {
|
|
14
16
|
root: `${PREFIX}-root`
|
|
@@ -47,7 +49,7 @@ export default function GroupSubscribeButton(inProps) {
|
|
|
47
49
|
props: inProps,
|
|
48
50
|
name: PREFIX
|
|
49
51
|
});
|
|
50
|
-
const { className, groupId, group,
|
|
52
|
+
const { className, groupId, group, user, onSubscribe } = props, rest = __rest(props, ["className", "groupId", "group", "user", "onSubscribe"]);
|
|
51
53
|
// STATE
|
|
52
54
|
const [status, setStatus] = useState(null);
|
|
53
55
|
// CONTEXT
|
|
@@ -61,7 +63,7 @@ export default function GroupSubscribeButton(inProps) {
|
|
|
61
63
|
group,
|
|
62
64
|
cacheStrategy: authUserId ? CacheStrategies.CACHE_FIRST : CacheStrategies.STALE_WHILE_REVALIDATE
|
|
63
65
|
});
|
|
64
|
-
const
|
|
66
|
+
const isGroupAdmin = useMemo(() => { var _a; return scUserContext.user && ((_a = scGroup === null || scGroup === void 0 ? void 0 : scGroup.managed_by) === null || _a === void 0 ? void 0 : _a.id) === scUserContext.user.id; }, [scUserContext.user, (_a = scGroup === null || scGroup === void 0 ? void 0 : scGroup.managed_by) === null || _a === void 0 ? void 0 : _a.id]);
|
|
65
67
|
useEffect(() => {
|
|
66
68
|
/**
|
|
67
69
|
* Call scGroupsManager.subscriptionStatus inside an effect
|
|
@@ -71,11 +73,25 @@ export default function GroupSubscribeButton(inProps) {
|
|
|
71
73
|
setStatus(scGroupsManager.subscriptionStatus(scGroup));
|
|
72
74
|
}
|
|
73
75
|
}, [authUserId, scGroupsManager.subscriptionStatus]);
|
|
74
|
-
|
|
76
|
+
/**
|
|
77
|
+
* Notify UI when a member is added to a group
|
|
78
|
+
* @param group
|
|
79
|
+
* @param user
|
|
80
|
+
*/
|
|
81
|
+
function notifyChanges(group, user) {
|
|
82
|
+
if (group && user) {
|
|
83
|
+
PubSub.publish(`${SCTopicType.GROUP}.${SCEventType.ADD_MEMBER}`, { group, user });
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
const subscribe = (user) => {
|
|
75
87
|
scGroupsManager
|
|
76
|
-
.subscribe(scGroup)
|
|
88
|
+
.subscribe(scGroup, user === null || user === void 0 ? void 0 : user.id)
|
|
77
89
|
.then(() => {
|
|
78
|
-
|
|
90
|
+
const _status = scGroup.privacy === SCGroupPrivacyType.PRIVATE && scGroup.subscription_status !== SCGroupSubscriptionStatusType.INVITED
|
|
91
|
+
? SCGroupSubscriptionStatusType.REQUESTED
|
|
92
|
+
: SCGroupSubscriptionStatusType.SUBSCRIBED;
|
|
93
|
+
notifyChanges(scGroup, user);
|
|
94
|
+
onSubscribe && onSubscribe(scGroup, _status);
|
|
79
95
|
})
|
|
80
96
|
.catch((e) => {
|
|
81
97
|
Logger.error(SCOPE_SC_UI, e);
|
|
@@ -85,7 +101,7 @@ export default function GroupSubscribeButton(inProps) {
|
|
|
85
101
|
scGroupsManager
|
|
86
102
|
.unsubscribe(scGroup)
|
|
87
103
|
.then(() => {
|
|
88
|
-
|
|
104
|
+
onSubscribe && onSubscribe(scGroup, null);
|
|
89
105
|
})
|
|
90
106
|
.catch((e) => {
|
|
91
107
|
Logger.error(SCOPE_SC_UI, e);
|
|
@@ -96,7 +112,7 @@ export default function GroupSubscribeButton(inProps) {
|
|
|
96
112
|
scContext.settings.handleAnonymousAction();
|
|
97
113
|
}
|
|
98
114
|
else {
|
|
99
|
-
SCGroupSubscriptionStatusType.SUBSCRIBED ? unsubscribe() : subscribe();
|
|
115
|
+
status === SCGroupSubscriptionStatusType.SUBSCRIBED && !(user === null || user === void 0 ? void 0 : user.id) ? unsubscribe() : (user === null || user === void 0 ? void 0 : user.id) ? subscribe(user) : subscribe();
|
|
100
116
|
}
|
|
101
117
|
};
|
|
102
118
|
/**
|
|
@@ -106,21 +122,24 @@ export default function GroupSubscribeButton(inProps) {
|
|
|
106
122
|
let _status;
|
|
107
123
|
switch (status) {
|
|
108
124
|
case SCGroupSubscriptionStatusType.REQUESTED:
|
|
109
|
-
_status = React.createElement(FormattedMessage, { defaultMessage: "ui.
|
|
125
|
+
_status = React.createElement(FormattedMessage, { defaultMessage: "ui.groupSubscribeButton.waitingApproval", id: "ui.groupSubscribeButton.waitingApproval" });
|
|
110
126
|
break;
|
|
111
127
|
case SCGroupSubscriptionStatusType.SUBSCRIBED:
|
|
112
128
|
_status = React.createElement(FormattedMessage, { defaultMessage: "ui.groupSubscribeButton.exit", id: "ui.groupSubscribeButton.exit" });
|
|
113
129
|
break;
|
|
130
|
+
case SCGroupSubscriptionStatusType.INVITED:
|
|
131
|
+
_status = React.createElement(FormattedMessage, { defaultMessage: "ui.groupSubscribeButton.accept", id: "ui.groupSubscribeButton.accept" });
|
|
132
|
+
break;
|
|
114
133
|
default:
|
|
115
134
|
scGroup.privacy === SCGroupPrivacyType.PUBLIC
|
|
116
135
|
? (_status = React.createElement(FormattedMessage, { defaultMessage: "ui.groupSubscribeButton.enter", id: "ui.groupSubscribeButton.enter" }))
|
|
117
|
-
: (_status = React.createElement(FormattedMessage, { defaultMessage: "ui.
|
|
136
|
+
: (_status = React.createElement(FormattedMessage, { defaultMessage: "ui.groupSubscribeButton.requestAccess", id: "ui.groupSubscribeButton.requestAccess" }));
|
|
118
137
|
break;
|
|
119
138
|
}
|
|
120
139
|
return _status;
|
|
121
140
|
};
|
|
122
|
-
if (!scGroup || (
|
|
141
|
+
if (!scGroup || (isGroupAdmin && (user === null || user === void 0 ? void 0 : user.id) === scUserContext.user.id) || (isGroupAdmin && !(user === null || user === void 0 ? void 0 : user.id))) {
|
|
123
142
|
return null;
|
|
124
143
|
}
|
|
125
|
-
return (React.createElement(Root, Object.assign({ size: "small", variant: "outlined", onClick: handleSubscribeAction, loading: scUserContext.user ? scGroupsManager.isLoading(scGroup) : null, className: classNames(classes.root, className) }, rest), getStatus()));
|
|
144
|
+
return (React.createElement(Root, Object.assign({ size: "small", variant: "outlined", onClick: handleSubscribeAction, loading: scUserContext.user ? scGroupsManager.isLoading(scGroup) : null, disabled: status === SCGroupSubscriptionStatusType.REQUESTED, className: classNames(classes.root, className) }, rest), isGroupAdmin ? React.createElement(FormattedMessage, { defaultMessage: "ui.groupSubscribeButton.accept", id: "ui.groupSubscribeButton.accept" }) : getStatus()));
|
|
126
145
|
}
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { SCGroupType } from '@selfcommunity/types';
|
|
2
|
-
import { EndpointType } from '@selfcommunity/api-services';
|
|
3
1
|
import { GroupProps } from '../Group';
|
|
4
2
|
export interface GroupsProps {
|
|
5
3
|
/**
|
|
@@ -8,20 +6,29 @@ export interface GroupsProps {
|
|
|
8
6
|
*/
|
|
9
7
|
className?: string;
|
|
10
8
|
/**
|
|
11
|
-
*
|
|
9
|
+
* Feed API Query Params
|
|
10
|
+
* @default [{'limit': 20, 'offset': 0}]
|
|
12
11
|
*/
|
|
13
|
-
|
|
12
|
+
endpointQueryParams?: Record<string, string | number>;
|
|
14
13
|
/**
|
|
15
14
|
* Props to spread to single group object
|
|
16
15
|
* @default {variant: 'outlined', ButtonBaseProps: {disableRipple: 'true'}}
|
|
17
16
|
*/
|
|
18
17
|
GroupComponentProps?: GroupProps;
|
|
18
|
+
/** If true, it means that the endpoint fetches all groups available
|
|
19
|
+
* @default true
|
|
20
|
+
*/
|
|
21
|
+
general?: boolean;
|
|
19
22
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
|
|
23
|
+
* Show/Hide filters
|
|
24
|
+
* @default false
|
|
25
|
+
*/
|
|
26
|
+
showFilters?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Filters component
|
|
29
|
+
* @param props
|
|
23
30
|
*/
|
|
24
|
-
|
|
31
|
+
filters?: JSX.Element;
|
|
25
32
|
/**
|
|
26
33
|
* Other props
|
|
27
34
|
*/
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { __rest } from "tslib";
|
|
2
2
|
import React, { useEffect, useMemo, useState } from 'react';
|
|
3
3
|
import { styled } from '@mui/material/styles';
|
|
4
|
-
import { Box, Grid, Typography } from '@mui/material';
|
|
5
|
-
import { http } from '@selfcommunity/api-services';
|
|
6
|
-
import { Logger } from '@selfcommunity/utils';
|
|
7
|
-
import { SCPreferences,
|
|
4
|
+
import { Box, Button, Grid, TextField, Typography, useMediaQuery, useTheme } from '@mui/material';
|
|
5
|
+
import { Endpoints, GroupService, http } from '@selfcommunity/api-services';
|
|
6
|
+
import { Logger, sortByAttr } from '@selfcommunity/utils';
|
|
7
|
+
import { SCPreferences, useSCPreferences, useSCUser } from '@selfcommunity/react-core';
|
|
8
8
|
import Skeleton from './Skeleton';
|
|
9
9
|
import { FormattedMessage } from 'react-intl';
|
|
10
10
|
import classNames from 'classnames';
|
|
@@ -12,9 +12,12 @@ import { SCOPE_SC_UI } from '../../constants/Errors';
|
|
|
12
12
|
import { useThemeProps } from '@mui/system';
|
|
13
13
|
import HiddenPlaceholder from '../../shared/HiddenPlaceholder';
|
|
14
14
|
import { PREFIX } from './constants';
|
|
15
|
-
import Group from '../Group';
|
|
15
|
+
import Group, { GroupSkeleton } from '../Group';
|
|
16
|
+
import { DEFAULT_PAGINATION_OFFSET } from '../../constants/Pagination';
|
|
17
|
+
import InfiniteScroll from '../../shared/InfiniteScroll';
|
|
16
18
|
const classes = {
|
|
17
19
|
root: `${PREFIX}-root`,
|
|
20
|
+
filters: `${PREFIX}-filter`,
|
|
18
21
|
groups: `${PREFIX}-groups`,
|
|
19
22
|
item: `${PREFIX}-item`,
|
|
20
23
|
noResults: `${PREFIX}-no-results`,
|
|
@@ -62,10 +65,14 @@ export default function Groups(inProps) {
|
|
|
62
65
|
props: inProps,
|
|
63
66
|
name: PREFIX
|
|
64
67
|
});
|
|
65
|
-
const {
|
|
68
|
+
const { endpointQueryParams = { limit: 20, offset: DEFAULT_PAGINATION_OFFSET }, className, GroupComponentProps = { variant: 'outlined', ButtonBaseProps: { disableRipple: true, component: Box } }, showFilters = false, filters, general = true } = props, rest = __rest(props, ["endpointQueryParams", "className", "GroupComponentProps", "showFilters", "filters", "general"]);
|
|
66
69
|
// STATE
|
|
67
70
|
const [groups, setGroups] = useState([]);
|
|
68
71
|
const [loading, setLoading] = useState(true);
|
|
72
|
+
const [next, setNext] = useState(null);
|
|
73
|
+
const [search, setSearch] = useState('');
|
|
74
|
+
const theme = useTheme();
|
|
75
|
+
const isMobile = useMediaQuery(theme.breakpoints.down('md'));
|
|
69
76
|
// CONTEXT
|
|
70
77
|
const scUserContext = useSCUser();
|
|
71
78
|
const scPreferencesContext = useSCPreferences();
|
|
@@ -74,19 +81,31 @@ export default function Groups(inProps) {
|
|
|
74
81
|
scPreferencesContext.preferences[SCPreferences.CONFIGURATIONS_CONTENT_AVAILABILITY].value, [scPreferencesContext.preferences]);
|
|
75
82
|
// CONST
|
|
76
83
|
const authUserId = scUserContext.user ? scUserContext.user.id : null;
|
|
77
|
-
//
|
|
78
|
-
const
|
|
84
|
+
// HANDLERS
|
|
85
|
+
const handleScrollUp = () => {
|
|
86
|
+
window.scrollTo({ left: 0, top: 0, behavior: 'smooth' });
|
|
87
|
+
};
|
|
79
88
|
/**
|
|
80
89
|
* Fetches groups list
|
|
81
90
|
*/
|
|
82
|
-
const fetchGroups = (
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
91
|
+
const fetchGroups = () => {
|
|
92
|
+
let groupService;
|
|
93
|
+
if (general) {
|
|
94
|
+
groupService = GroupService.searchGroups(Object.assign(Object.assign({}, endpointQueryParams), (search !== '' && { search: search })));
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
groupService = GroupService.getUserGroups(Object.assign(Object.assign({}, endpointQueryParams), (search !== '' && { search: search })));
|
|
98
|
+
}
|
|
99
|
+
groupService
|
|
100
|
+
.then((res) => {
|
|
101
|
+
setGroups(res.results);
|
|
102
|
+
setNext(res.next);
|
|
103
|
+
setLoading(false);
|
|
104
|
+
})
|
|
105
|
+
.catch((error) => {
|
|
106
|
+
Logger.error(SCOPE_SC_UI, error);
|
|
86
107
|
});
|
|
87
|
-
|
|
88
|
-
return data.next ? data.results.concat(yield fetchGroups(data.next)) : data.results;
|
|
89
|
-
});
|
|
108
|
+
};
|
|
90
109
|
/**
|
|
91
110
|
* On mount, fetches groups list
|
|
92
111
|
*/
|
|
@@ -94,32 +113,67 @@ export default function Groups(inProps) {
|
|
|
94
113
|
if (!contentAvailability && !authUserId) {
|
|
95
114
|
return;
|
|
96
115
|
}
|
|
97
|
-
else if (prefetchedGroups.length) {
|
|
98
|
-
setGroups(prefetchedGroups);
|
|
99
|
-
setLoading(false);
|
|
100
|
-
}
|
|
101
116
|
else {
|
|
102
|
-
fetchGroups()
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
})
|
|
109
|
-
.catch((error) => {
|
|
110
|
-
Logger.error(SCOPE_SC_UI, error);
|
|
111
|
-
});
|
|
117
|
+
fetchGroups();
|
|
118
|
+
}
|
|
119
|
+
}, [contentAvailability, authUserId, search]);
|
|
120
|
+
const handleNext = useMemo(() => () => {
|
|
121
|
+
if (!next) {
|
|
122
|
+
return;
|
|
112
123
|
}
|
|
113
|
-
|
|
124
|
+
return http
|
|
125
|
+
.request({
|
|
126
|
+
url: next,
|
|
127
|
+
method: general ? Endpoints.SearchGroups.method : Endpoints.GetUserGroups.method
|
|
128
|
+
})
|
|
129
|
+
.then((res) => {
|
|
130
|
+
setGroups([...groups, ...res.data.results]);
|
|
131
|
+
setNext(res.data.next);
|
|
132
|
+
})
|
|
133
|
+
.catch((error) => console.log(error))
|
|
134
|
+
.then(() => setLoading(false));
|
|
135
|
+
}, [next]);
|
|
136
|
+
/**
|
|
137
|
+
* Get groups filtered
|
|
138
|
+
*/
|
|
139
|
+
const getFilteredGroups = () => {
|
|
140
|
+
if (search) {
|
|
141
|
+
return groups.filter((g) => g.name.toLowerCase().includes(search.toLowerCase()));
|
|
142
|
+
}
|
|
143
|
+
return groups;
|
|
144
|
+
};
|
|
145
|
+
/**
|
|
146
|
+
* Handle change filter name
|
|
147
|
+
* @param event
|
|
148
|
+
*/
|
|
149
|
+
const handleOnChangeFilterName = (event) => {
|
|
150
|
+
setSearch(event.target.value);
|
|
151
|
+
};
|
|
152
|
+
/**
|
|
153
|
+
* Renders groups list
|
|
154
|
+
*/
|
|
155
|
+
const filteredGroups = sortByAttr(getFilteredGroups(), 'order');
|
|
156
|
+
const content = (React.createElement(React.Fragment, null,
|
|
157
|
+
showFilters && (React.createElement(Grid, { container: true, direction: "row", justifyContent: "center", alignItems: "center", className: classes.filters }, filters ? (filters) : (React.createElement(Grid, { item: true, xs: 12, md: 6 },
|
|
158
|
+
React.createElement(TextField, { fullWidth: true, value: search, label: React.createElement(FormattedMessage, { id: "ui.groups.filterByName", defaultMessage: "ui.groups.filterByName" }), variant: "outlined", onChange: handleOnChangeFilterName, disabled: loading }))))),
|
|
159
|
+
React.createElement(React.Fragment, null, !groups.length ? (React.createElement(Box, { className: classes.noResults },
|
|
160
|
+
React.createElement(Typography, { variant: "h4" },
|
|
161
|
+
React.createElement(FormattedMessage, { id: "ui.groups.noGroups.title", defaultMessage: "ui.groups.noGroups.title" })),
|
|
162
|
+
React.createElement(Typography, { variant: "body1" },
|
|
163
|
+
React.createElement(FormattedMessage, { id: "ui.groups.noGroups.subtitle", defaultMessage: "ui.groups.noGroups.subtitle" })))) : (React.createElement(InfiniteScroll, { dataLength: groups.length, next: handleNext, hasMoreNext: Boolean(next), loaderNext: isMobile ? React.createElement(GroupSkeleton, null) : React.createElement(Skeleton, { groupsNumber: 2 }), endMessage: React.createElement(Typography, { component: "div", className: classes.endMessage },
|
|
164
|
+
React.createElement(FormattedMessage, { id: "ui.groups.endMessage", defaultMessage: "ui.groups.endMessage", values: {
|
|
165
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
|
166
|
+
// @ts-ignore
|
|
167
|
+
button: (chunk) => (React.createElement(Button, { color: "secondary", variant: "text", onClick: handleScrollUp }, chunk))
|
|
168
|
+
} })) },
|
|
169
|
+
React.createElement(Grid, { container: true, spacing: { xs: 2 }, className: classes.groups }, filteredGroups.map((group) => (React.createElement(Grid, { item: true, xs: 12, sm: 8, md: 6, key: group.id, className: classes.item },
|
|
170
|
+
React.createElement(Group, Object.assign({ group: group, groupId: group.id, actionRedirect: true }, GroupComponentProps)))))))))));
|
|
114
171
|
// RENDER
|
|
115
172
|
if (!contentAvailability && !scUserContext.user) {
|
|
116
173
|
return React.createElement(HiddenPlaceholder, null);
|
|
117
174
|
}
|
|
118
|
-
|
|
119
|
-
React.createElement(
|
|
120
|
-
|
|
121
|
-
React.createElement(Typography, { variant: "body1" },
|
|
122
|
-
React.createElement(FormattedMessage, { id: "ui.groups.noGroups.subtitle", defaultMessage: "ui.groups.noGroups.subtitle" })))) : (React.createElement(React.Fragment, null, groups.map((group) => (React.createElement(Grid, { item: true, xs: 12, sm: 8, md: 6, key: group.id, className: classes.item },
|
|
123
|
-
React.createElement(Group, Object.assign({ group: group, groupId: group.id }, GroupComponentProps)))))))))));
|
|
175
|
+
if (loading) {
|
|
176
|
+
return React.createElement(Skeleton, null);
|
|
177
|
+
}
|
|
124
178
|
return (React.createElement(Root, Object.assign({ className: classNames(classes.root, className) }, rest), content));
|
|
125
179
|
}
|
|
@@ -9,6 +9,10 @@ export interface GroupsSkeletonProps {
|
|
|
9
9
|
* @default null
|
|
10
10
|
*/
|
|
11
11
|
GroupSkeletonProps?: any;
|
|
12
|
+
/**
|
|
13
|
+
* @default 20
|
|
14
|
+
*/
|
|
15
|
+
groupsNumber?: number;
|
|
12
16
|
}
|
|
13
17
|
/**
|
|
14
18
|
* > API documentation for the Community-JS Groups Skeleton component. Learn about the available props and the CSS API.
|