@selfcommunity/react-ui 0.7.9-alpha.4 → 0.7.9-alpha.41
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/ChangeGroupCover/ChangeGroupCover.js +24 -1
- package/lib/cjs/components/ChangeGroupPicture/ChangeGroupPicture.js +32 -11
- package/lib/cjs/components/Composer/Attributes/Attributes.js +3 -3
- package/lib/cjs/components/Composer/Composer.js +3 -5
- package/lib/cjs/components/Composer/Content/ContentPost/ContentPost.js +4 -3
- package/lib/cjs/components/Composer/Layer/AudienceLayer/AudienceLayer.d.ts +1 -2
- package/lib/cjs/components/Composer/Layer/AudienceLayer/AudienceLayer.js +18 -6
- package/lib/cjs/components/EditGroupButton/EditGroupButton.js +4 -0
- package/lib/cjs/components/FeedObject/FeedObject.d.ts +1 -0
- package/lib/cjs/components/FeedObject/FeedObject.js +23 -6
- package/lib/cjs/components/FeedUpdatesWidget/FeedUpdatesWidget.js +1 -1
- package/lib/cjs/components/Group/Group.js +9 -3
- package/lib/cjs/components/GroupForm/GroupForm.js +31 -9
- package/lib/cjs/components/GroupHeader/GroupHeader.d.ts +6 -5
- package/lib/cjs/components/GroupHeader/GroupHeader.js +52 -11
- package/lib/cjs/components/GroupHeader/Skeleton.d.ts +2 -4
- package/lib/cjs/components/GroupHeader/Skeleton.js +10 -10
- package/lib/cjs/components/GroupInfoWidget/GroupInfoWidget.js +40 -7
- package/lib/cjs/components/GroupInviteButton/GroupInviteButton.js +8 -7
- package/lib/cjs/components/GroupInvitedWidget/GroupInvitedWidget.d.ts +74 -0
- package/lib/cjs/components/GroupInvitedWidget/GroupInvitedWidget.js +197 -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 +7 -2
- package/lib/cjs/components/GroupMembersWidget/GroupMembersWidget.js +25 -4
- package/lib/cjs/components/GroupRequestsWidget/GroupRequestsWidget.d.ts +11 -5
- package/lib/cjs/components/GroupRequestsWidget/GroupRequestsWidget.js +18 -7
- package/lib/cjs/components/GroupSettingsIconButton/GroupSettingsIconButton.d.ts +48 -0
- package/lib/cjs/components/GroupSettingsIconButton/GroupSettingsIconButton.js +145 -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 +31 -10
- package/lib/cjs/components/Groups/Groups.d.ts +28 -13
- package/lib/cjs/components/Groups/Groups.js +71 -89
- package/lib/cjs/components/NavigationMenuIconButton/NavigationMenuIconButton.js +1 -1
- package/lib/cjs/components/NavigationToolbarMobile/NavigationToolbarMobile.d.ts +4 -0
- package/lib/cjs/components/NavigationToolbarMobile/NavigationToolbarMobile.js +2 -3
- package/lib/cjs/components/Notification/Group/Group.d.ts +15 -0
- package/lib/cjs/components/Notification/Group/Group.js +78 -0
- package/lib/cjs/components/Notification/Group/index.d.ts +3 -0
- package/lib/cjs/components/Notification/Group/index.js +5 -0
- package/lib/cjs/components/Notification/Notification.js +31 -1
- package/lib/cjs/components/Notification/PrivateMessage/PrivateMessage.js +16 -5
- package/lib/cjs/components/PrivateMessageComponent/PrivateMessageComponent.d.ts +1 -1
- package/lib/cjs/components/PrivateMessageComponent/PrivateMessageComponent.js +10 -7
- package/lib/cjs/components/PrivateMessageSnippetItem/PrivateMessageSnippetItem.js +11 -6
- package/lib/cjs/components/PrivateMessageSnippets/PrivateMessageSnippets.d.ts +3 -3
- package/lib/cjs/components/PrivateMessageSnippets/PrivateMessageSnippets.js +24 -6
- package/lib/cjs/components/PrivateMessageThread/PrivateMessageThread.d.ts +6 -1
- package/lib/cjs/components/PrivateMessageThread/PrivateMessageThread.js +45 -20
- package/lib/cjs/components/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 +5 -0
- package/lib/cjs/components/User/User.js +5 -4
- package/lib/cjs/constants/PubSub.d.ts +27 -0
- package/lib/cjs/constants/PubSub.js +21 -0
- package/lib/cjs/index.d.ts +5 -2
- package/lib/cjs/index.js +12 -4
- package/lib/esm/components/ChangeGroupCover/ChangeGroupCover.js +24 -1
- package/lib/esm/components/ChangeGroupPicture/ChangeGroupPicture.js +32 -11
- package/lib/esm/components/Composer/Attributes/Attributes.js +3 -3
- package/lib/esm/components/Composer/Composer.js +3 -5
- package/lib/esm/components/Composer/Content/ContentPost/ContentPost.js +4 -3
- package/lib/esm/components/Composer/Layer/AudienceLayer/AudienceLayer.d.ts +1 -2
- package/lib/esm/components/Composer/Layer/AudienceLayer/AudienceLayer.js +18 -6
- package/lib/esm/components/EditGroupButton/EditGroupButton.js +5 -1
- package/lib/esm/components/FeedObject/FeedObject.d.ts +1 -0
- package/lib/esm/components/FeedObject/FeedObject.js +24 -7
- package/lib/esm/components/FeedUpdatesWidget/FeedUpdatesWidget.js +1 -1
- package/lib/esm/components/Group/Group.js +11 -5
- package/lib/esm/components/GroupForm/GroupForm.js +31 -9
- package/lib/esm/components/GroupHeader/GroupHeader.d.ts +6 -5
- package/lib/esm/components/GroupHeader/GroupHeader.js +54 -13
- package/lib/esm/components/GroupHeader/Skeleton.d.ts +2 -4
- package/lib/esm/components/GroupHeader/Skeleton.js +10 -10
- package/lib/esm/components/GroupInfoWidget/GroupInfoWidget.js +40 -7
- package/lib/esm/components/GroupInviteButton/GroupInviteButton.js +8 -7
- package/lib/esm/components/GroupInvitedWidget/GroupInvitedWidget.d.ts +74 -0
- package/lib/esm/components/GroupInvitedWidget/GroupInvitedWidget.js +194 -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 +8 -3
- package/lib/esm/components/GroupMembersWidget/GroupMembersWidget.js +26 -5
- package/lib/esm/components/GroupRequestsWidget/GroupRequestsWidget.d.ts +11 -5
- package/lib/esm/components/GroupRequestsWidget/GroupRequestsWidget.js +18 -7
- package/lib/esm/components/GroupSettingsIconButton/GroupSettingsIconButton.d.ts +48 -0
- package/lib/esm/components/GroupSettingsIconButton/GroupSettingsIconButton.js +142 -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 +32 -11
- package/lib/esm/components/Groups/Groups.d.ts +28 -13
- package/lib/esm/components/Groups/Groups.js +76 -94
- package/lib/esm/components/NavigationMenuIconButton/NavigationMenuIconButton.js +1 -1
- package/lib/esm/components/NavigationToolbarMobile/NavigationToolbarMobile.d.ts +4 -0
- package/lib/esm/components/NavigationToolbarMobile/NavigationToolbarMobile.js +2 -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 +1 -1
- package/lib/esm/components/PrivateMessageComponent/PrivateMessageComponent.js +11 -8
- package/lib/esm/components/PrivateMessageSnippetItem/PrivateMessageSnippetItem.js +11 -6
- package/lib/esm/components/PrivateMessageSnippets/PrivateMessageSnippets.d.ts +3 -3
- package/lib/esm/components/PrivateMessageSnippets/PrivateMessageSnippets.js +26 -8
- package/lib/esm/components/PrivateMessageThread/PrivateMessageThread.d.ts +6 -1
- package/lib/esm/components/PrivateMessageThread/PrivateMessageThread.js +47 -22
- package/lib/esm/components/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 +5 -0
- package/lib/esm/components/User/User.js +5 -4
- package/lib/esm/constants/PubSub.d.ts +27 -0
- package/lib/esm/constants/PubSub.js +18 -0
- package/lib/esm/index.d.ts +5 -2
- package/lib/esm/index.js +7 -4
- package/lib/umd/react-ui.js +1 -1
- package/package.json +6 -6
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { __rest } from "tslib";
|
|
2
|
-
import React, { useMemo } from 'react';
|
|
2
|
+
import React, { useCallback, useEffect, useMemo, useRef } from 'react';
|
|
3
3
|
import { styled } from '@mui/material/styles';
|
|
4
4
|
import { Avatar, Box, Icon, Paper, Typography } from '@mui/material';
|
|
5
|
-
import { SCGroupPrivacyType } from '@selfcommunity/types';
|
|
5
|
+
import { SCGroupPrivacyType, SCGroupSubscriptionStatusType } from '@selfcommunity/types';
|
|
6
6
|
import { SCPreferences, useSCFetchGroup, useSCPreferences, useSCUser } from '@selfcommunity/react-core';
|
|
7
7
|
import GroupHeaderSkeleton from './Skeleton';
|
|
8
8
|
import classNames from 'classnames';
|
|
@@ -14,6 +14,10 @@ import Bullet from '../../shared/Bullet';
|
|
|
14
14
|
import ChangeGroupPicture from '../ChangeGroupPicture';
|
|
15
15
|
import GroupMembersButton from '../GroupMembersButton';
|
|
16
16
|
import EditGroupButton from '../EditGroupButton';
|
|
17
|
+
import GroupSubscribeButton from '../GroupSubscribeButton';
|
|
18
|
+
import GroupInviteButton from '../GroupInviteButton';
|
|
19
|
+
import { SCEventType, SCTopicType } from '../../constants/PubSub';
|
|
20
|
+
import PubSub from 'pubsub-js';
|
|
17
21
|
const classes = {
|
|
18
22
|
root: `${PREFIX}-root`,
|
|
19
23
|
cover: `${PREFIX}-cover`,
|
|
@@ -70,22 +74,24 @@ export default function GroupHeader(inProps) {
|
|
|
70
74
|
props: inProps,
|
|
71
75
|
name: PREFIX
|
|
72
76
|
});
|
|
73
|
-
const { id = null, className = null, group, groupId = null, ChangePictureProps = {}, ChangeCoverProps = {},
|
|
77
|
+
const { id = null, className = null, group, groupId = null, ChangePictureProps = {}, ChangeCoverProps = {}, GroupSubscribeButtonProps = {}, GroupMembersButtonProps = {} } = props, rest = __rest(props, ["id", "className", "group", "groupId", "ChangePictureProps", "ChangeCoverProps", "GroupSubscribeButtonProps", "GroupMembersButtonProps"]);
|
|
74
78
|
// PREFERENCES
|
|
75
79
|
const scPreferences = useSCPreferences();
|
|
76
80
|
// CONTEXT
|
|
77
81
|
const scUserContext = useSCUser();
|
|
78
82
|
// HOOKS
|
|
79
83
|
const { scGroup, setSCGroup } = useSCFetchGroup({ id: groupId, group });
|
|
84
|
+
// REFS
|
|
85
|
+
const updatesSubscription = useRef(null);
|
|
80
86
|
// CONST
|
|
81
|
-
const
|
|
87
|
+
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]);
|
|
82
88
|
/**
|
|
83
89
|
* Handles Change Avatar
|
|
84
90
|
* @param avatar
|
|
85
91
|
*/
|
|
86
92
|
function handleChangeAvatar(avatar) {
|
|
87
|
-
if (
|
|
88
|
-
setSCGroup(Object.assign({}, scGroup, {
|
|
93
|
+
if (isGroupAdmin) {
|
|
94
|
+
setSCGroup(Object.assign({}, scGroup, { image_big: avatar }));
|
|
89
95
|
}
|
|
90
96
|
}
|
|
91
97
|
/**
|
|
@@ -93,10 +99,43 @@ export default function GroupHeader(inProps) {
|
|
|
93
99
|
* @param cover
|
|
94
100
|
*/
|
|
95
101
|
function handleChangeCover(cover) {
|
|
96
|
-
if (
|
|
102
|
+
if (isGroupAdmin) {
|
|
97
103
|
setSCGroup(Object.assign({}, scGroup, { emotional_image: cover }));
|
|
98
104
|
}
|
|
99
105
|
}
|
|
106
|
+
/**
|
|
107
|
+
* Handles callback subscribe/unsubscribe group
|
|
108
|
+
*/
|
|
109
|
+
const handleSubscribe = (group, status) => {
|
|
110
|
+
setSCGroup(Object.assign(Object.assign({}, group), { subscribers_counter: group.subscribers_counter + (status ? 1 : -1) }));
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* Subscriber for pubsub callback
|
|
114
|
+
*/
|
|
115
|
+
const onChangeGroupMembersHandler = useCallback((msg, data) => {
|
|
116
|
+
if (data && data.group.id === scGroup.id) {
|
|
117
|
+
let _group = Object.assign({}, scGroup);
|
|
118
|
+
if (msg === `${SCTopicType.GROUP}.${SCEventType.ADD_MEMBER}`) {
|
|
119
|
+
_group.subscribers_counter = _group.subscribers_counter + 1;
|
|
120
|
+
}
|
|
121
|
+
else if (msg === `${SCTopicType.GROUP}.${SCEventType.REMOVE_MEMBER}`) {
|
|
122
|
+
_group.subscribers_counter = Math.max(_group.subscribers_counter - 1, 0);
|
|
123
|
+
}
|
|
124
|
+
console.log(_group);
|
|
125
|
+
setSCGroup(_group);
|
|
126
|
+
}
|
|
127
|
+
}, [scGroup, setSCGroup]);
|
|
128
|
+
/**
|
|
129
|
+
* On mount, subscribe to receive groups updates (only edit)
|
|
130
|
+
*/
|
|
131
|
+
useEffect(() => {
|
|
132
|
+
if (scGroup) {
|
|
133
|
+
updatesSubscription.current = PubSub.subscribe(`${SCTopicType.GROUP}.${SCEventType.MEMBERS}`, onChangeGroupMembersHandler);
|
|
134
|
+
}
|
|
135
|
+
return () => {
|
|
136
|
+
updatesSubscription.current && PubSub.unsubscribe(updatesSubscription.current);
|
|
137
|
+
};
|
|
138
|
+
}, [scGroup]);
|
|
100
139
|
// RENDER
|
|
101
140
|
if (!scGroup) {
|
|
102
141
|
return React.createElement(GroupHeaderSkeleton, null);
|
|
@@ -108,13 +147,13 @@ export default function GroupHeader(inProps) {
|
|
|
108
147
|
React.createElement(Paper, { style: _backgroundCover, classes: { root: classes.cover } },
|
|
109
148
|
React.createElement(Box, { className: classes.avatar },
|
|
110
149
|
React.createElement(Avatar, null,
|
|
111
|
-
React.createElement("img", { alt: "group", src: scGroup.
|
|
112
|
-
|
|
150
|
+
React.createElement("img", { alt: "group", src: scGroup.image_big ? scGroup.image_big : '' }))),
|
|
151
|
+
isGroupAdmin && (React.createElement(React.Fragment, null,
|
|
113
152
|
React.createElement(ChangeGroupPicture, Object.assign({ groupId: scGroup.id, onChange: handleChangeAvatar, className: classes.changePicture }, ChangePictureProps)),
|
|
114
153
|
React.createElement("div", { className: classes.changeCover },
|
|
115
154
|
React.createElement(ChangeGroupCover, Object.assign({ groupId: scGroup.id, onChange: handleChangeCover }, ChangeCoverProps)))))),
|
|
116
155
|
React.createElement(Box, { className: classes.info },
|
|
117
|
-
|
|
156
|
+
isGroupAdmin && React.createElement(EditGroupButton, { group: scGroup, groupId: scGroup.id, onEditSuccess: (data) => setSCGroup(data) }),
|
|
118
157
|
React.createElement(Typography, { variant: "h5", className: classes.name }, scGroup.name),
|
|
119
158
|
React.createElement(Box, { className: classes.visibility },
|
|
120
159
|
scGroup.privacy === SCGroupPrivacyType.PUBLIC ? (React.createElement(Typography, { className: classes.visibilityItem },
|
|
@@ -128,9 +167,11 @@ export default function GroupHeader(inProps) {
|
|
|
128
167
|
React.createElement(FormattedMessage, { id: "ui.groupHeader.visibility.visible", defaultMessage: "ui.groupHeader.visibility.visible" }))) : (React.createElement(Typography, { className: classes.visibilityItem },
|
|
129
168
|
React.createElement(Icon, null, "visibility_off"),
|
|
130
169
|
React.createElement(FormattedMessage, { id: "ui.groupHeader.visibility.hidden", defaultMessage: "ui.groupHeader.visibility.hidden" })))),
|
|
131
|
-
React.createElement(
|
|
170
|
+
React.createElement(React.Fragment, null, ((scGroup && scGroup.privacy === SCGroupPrivacyType.PUBLIC) ||
|
|
171
|
+
scGroup.subscription_status === SCGroupSubscriptionStatusType.SUBSCRIBED ||
|
|
172
|
+
isGroupAdmin) && (React.createElement(Box, { className: classes.members },
|
|
132
173
|
React.createElement(Typography, { className: classes.membersCounter, component: "div" },
|
|
133
174
|
React.createElement(FormattedMessage, { id: "ui.groupHeader.members", defaultMessage: "ui.groupHeader.members", values: { total: scGroup.subscribers_counter } })),
|
|
134
|
-
React.createElement(GroupMembersButton, Object.assign({ groupId: scGroup === null || scGroup === void 0 ? void 0 : scGroup.id, group: scGroup }, GroupMembersButtonProps))),
|
|
135
|
-
|
|
175
|
+
React.createElement(GroupMembersButton, Object.assign({ key: scGroup.subscribers_counter, groupId: scGroup === null || scGroup === void 0 ? void 0 : scGroup.id, group: scGroup, autoHide: !isGroupAdmin }, GroupMembersButtonProps))))),
|
|
176
|
+
isGroupAdmin ? (React.createElement(GroupInviteButton, { group: scGroup, groupId: scGroup.id })) : (React.createElement(GroupSubscribeButton, Object.assign({ group: scGroup, onSubscribe: handleSubscribe }, GroupSubscribeButtonProps))))));
|
|
136
177
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* > API documentation for the Community-JS Group
|
|
2
|
+
* > API documentation for the Community-JS Group Header Skeleton component. Learn about the available props and the CSS API.
|
|
3
3
|
|
|
4
4
|
#### Import
|
|
5
5
|
|
|
@@ -18,9 +18,7 @@
|
|
|
18
18
|
|root|.SCGroupHeader-skeleton-root|Styles applied to the root element.|
|
|
19
19
|
|avatar|.SCGroupHeader-avatar|Styles applied to the avatar element.|
|
|
20
20
|
|cover|.SCGroupHeader-cover|Styles applied to the cover element.|
|
|
21
|
-
|
|
|
22
|
-
|section|.SCGroupHeader-section|Styles applied to the info section.|
|
|
23
|
-
|username|.SCGroupHeader-username|Styles applied to the username element.|
|
|
21
|
+
|info|.SCGroupHeader-info|Styles applied to the info info.|
|
|
24
22
|
*
|
|
25
23
|
*/
|
|
26
24
|
declare function GroupHeaderSkeleton(): JSX.Element;
|
|
@@ -7,16 +7,14 @@ const classes = {
|
|
|
7
7
|
root: `${PREFIX}-skeleton-root`,
|
|
8
8
|
cover: `${PREFIX}-cover`,
|
|
9
9
|
avatar: `${PREFIX}-avatar`,
|
|
10
|
-
|
|
11
|
-
section: `${PREFIX}-section`,
|
|
12
|
-
username: `${PREFIX}-username`
|
|
10
|
+
info: `${PREFIX}-info`
|
|
13
11
|
};
|
|
14
12
|
const Root = styled(Box, {
|
|
15
13
|
name: PREFIX,
|
|
16
14
|
slot: 'SkeletonRoot'
|
|
17
15
|
})(() => ({}));
|
|
18
16
|
/**
|
|
19
|
-
* > API documentation for the Community-JS Group
|
|
17
|
+
* > API documentation for the Community-JS Group Header Skeleton component. Learn about the available props and the CSS API.
|
|
20
18
|
|
|
21
19
|
#### Import
|
|
22
20
|
|
|
@@ -35,9 +33,7 @@ const Root = styled(Box, {
|
|
|
35
33
|
|root|.SCGroupHeader-skeleton-root|Styles applied to the root element.|
|
|
36
34
|
|avatar|.SCGroupHeader-avatar|Styles applied to the avatar element.|
|
|
37
35
|
|cover|.SCGroupHeader-cover|Styles applied to the cover element.|
|
|
38
|
-
|
|
|
39
|
-
|section|.SCGroupHeader-section|Styles applied to the info section.|
|
|
40
|
-
|username|.SCGroupHeader-username|Styles applied to the username element.|
|
|
36
|
+
|info|.SCGroupHeader-info|Styles applied to the info info.|
|
|
41
37
|
*
|
|
42
38
|
*/
|
|
43
39
|
function GroupHeaderSkeleton() {
|
|
@@ -46,8 +42,12 @@ function GroupHeaderSkeleton() {
|
|
|
46
42
|
React.createElement(Skeleton, { className: classes.cover, animation: "wave", variant: "rectangular" }),
|
|
47
43
|
React.createElement(Box, { className: classes.avatar },
|
|
48
44
|
React.createElement(Skeleton, { animation: "wave", variant: "circular", width: theme.selfcommunity.group.avatar.sizeLarge, height: theme.selfcommunity.group.avatar.sizeLarge })),
|
|
49
|
-
React.createElement(Box, { className: classes.
|
|
50
|
-
React.createElement(Typography, { variant: "h5"
|
|
51
|
-
React.createElement(Skeleton, { animation: "wave", sx: { height: 30, width:
|
|
45
|
+
React.createElement(Box, { className: classes.info },
|
|
46
|
+
React.createElement(Typography, { variant: "h5" },
|
|
47
|
+
React.createElement(Skeleton, { animation: "wave", sx: { height: 30, width: 200 } })),
|
|
48
|
+
React.createElement(Typography, null,
|
|
49
|
+
React.createElement(Skeleton, { animation: "wave", sx: { height: 20, width: 150 } })),
|
|
50
|
+
React.createElement(Typography, null,
|
|
51
|
+
React.createElement(Skeleton, { animation: "wave", sx: { height: 20, width: 100 } })))));
|
|
52
52
|
}
|
|
53
53
|
export default GroupHeaderSkeleton;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { __rest } from "tslib";
|
|
2
|
-
import React from 'react';
|
|
2
|
+
import React, { useCallback, useEffect, useRef } from 'react';
|
|
3
3
|
import { styled } from '@mui/material/styles';
|
|
4
4
|
import { CardContent, Icon, Typography } from '@mui/material';
|
|
5
5
|
import classNames from 'classnames';
|
|
@@ -8,7 +8,10 @@ import { useThemeProps } from '@mui/system';
|
|
|
8
8
|
import { PREFIX } from './constants';
|
|
9
9
|
import { FormattedMessage, useIntl } from 'react-intl';
|
|
10
10
|
import { SCGroupPrivacyType } from '@selfcommunity/types';
|
|
11
|
+
import PubSub from 'pubsub-js';
|
|
11
12
|
import { useSCFetchGroup } from '@selfcommunity/react-core';
|
|
13
|
+
import GroupInfoWidgetSkeleton from './Skeleton';
|
|
14
|
+
import { SCEventType, SCTopicType } from '../../constants/PubSub';
|
|
12
15
|
const classes = {
|
|
13
16
|
root: `${PREFIX}-root`,
|
|
14
17
|
title: `${PREFIX}-title`,
|
|
@@ -17,6 +20,7 @@ const classes = {
|
|
|
17
20
|
privacyTitle: `${PREFIX}-privacy-title`,
|
|
18
21
|
visibility: `${PREFIX}-visibility`,
|
|
19
22
|
visibilityTitle: `${PREFIX}-visibility-title`,
|
|
23
|
+
admin: `${PREFIX}-admin`,
|
|
20
24
|
date: `${PREFIX}-date`
|
|
21
25
|
};
|
|
22
26
|
const Root = styled(Widget, {
|
|
@@ -59,9 +63,36 @@ export default function GroupInfoWidget(inProps) {
|
|
|
59
63
|
});
|
|
60
64
|
const { className, group, groupId, onHeightChange, onStateChange } = props, rest = __rest(props, ["className", "group", "groupId", "onHeightChange", "onStateChange"]);
|
|
61
65
|
// HOOKS
|
|
62
|
-
const { scGroup } = useSCFetchGroup({ id: groupId, group });
|
|
66
|
+
const { scGroup, setSCGroup } = useSCFetchGroup({ id: groupId, group });
|
|
63
67
|
// INTL
|
|
64
68
|
const intl = useIntl();
|
|
69
|
+
// REFS
|
|
70
|
+
const updatesSubscription = useRef(null);
|
|
71
|
+
/**
|
|
72
|
+
* Subscriber for pubsub callback
|
|
73
|
+
*/
|
|
74
|
+
const onChangeGroupHandler = useCallback((_msg, data) => {
|
|
75
|
+
if (data && scGroup.id === data.id) {
|
|
76
|
+
setSCGroup(data);
|
|
77
|
+
}
|
|
78
|
+
}, [scGroup, setSCGroup]);
|
|
79
|
+
/**
|
|
80
|
+
* On mount, subscribe to receive groups updates (only edit)
|
|
81
|
+
*/
|
|
82
|
+
useEffect(() => {
|
|
83
|
+
if (scGroup) {
|
|
84
|
+
updatesSubscription.current = PubSub.subscribe(`${SCTopicType.GROUP}.${SCEventType.EDIT}`, onChangeGroupHandler);
|
|
85
|
+
}
|
|
86
|
+
return () => {
|
|
87
|
+
updatesSubscription.current && PubSub.unsubscribe(updatesSubscription.current);
|
|
88
|
+
};
|
|
89
|
+
}, [scGroup]);
|
|
90
|
+
/**
|
|
91
|
+
* Loading group
|
|
92
|
+
*/
|
|
93
|
+
if (!scGroup) {
|
|
94
|
+
return React.createElement(GroupInfoWidgetSkeleton, null);
|
|
95
|
+
}
|
|
65
96
|
/**
|
|
66
97
|
* Renders root object
|
|
67
98
|
*/
|
|
@@ -73,14 +104,14 @@ export default function GroupInfoWidget(inProps) {
|
|
|
73
104
|
React.createElement(Typography, { component: "div", className: classes.privacy }, scGroup.privacy === SCGroupPrivacyType.PUBLIC ? (React.createElement(React.Fragment, null,
|
|
74
105
|
React.createElement(Typography, { className: classes.privacyTitle },
|
|
75
106
|
React.createElement(Icon, null, "public"),
|
|
76
|
-
React.createElement(FormattedMessage, { id: "ui.
|
|
107
|
+
React.createElement(FormattedMessage, { id: "ui.groupInfoWidget.privacy.public", defaultMessage: "ui.groupInfoWidget.privacy.public" })),
|
|
77
108
|
React.createElement(Typography, { variant: "body2" },
|
|
78
|
-
React.createElement(FormattedMessage, { id: "ui.
|
|
109
|
+
React.createElement(FormattedMessage, { id: "ui.groupInfoWidget.privacy.public.info", defaultMessage: "ui.groupInfoWidget.privacy.public.info", values: { b: (chunks) => React.createElement("strong", null, chunks) } })))) : (React.createElement(React.Fragment, null,
|
|
79
110
|
React.createElement(Typography, { className: classes.privacyTitle },
|
|
80
111
|
React.createElement(Icon, null, "private"),
|
|
81
|
-
React.createElement(FormattedMessage, { id: "ui.
|
|
112
|
+
React.createElement(FormattedMessage, { id: "ui.groupInfoWidget.privacy.private", defaultMessage: "ui.groupInfoWidget.privacy.private" })),
|
|
82
113
|
React.createElement(Typography, { variant: "body2" },
|
|
83
|
-
React.createElement(FormattedMessage, { id: "ui.
|
|
114
|
+
React.createElement(FormattedMessage, { id: "ui.groupInfoWidget.privacy.private.info", defaultMessage: "ui.groupInfoWidget.private.public.info", values: { b: (chunks) => React.createElement("strong", null, chunks) } }))))),
|
|
84
115
|
scGroup.privacy === SCGroupPrivacyType.PRIVATE && (React.createElement(Typography, { component: "div", className: classes.visibility }, scGroup.visible ? (React.createElement(React.Fragment, null,
|
|
85
116
|
React.createElement(Typography, { className: classes.visibilityTitle },
|
|
86
117
|
React.createElement(Icon, null, "visibility"),
|
|
@@ -93,5 +124,7 @@ export default function GroupInfoWidget(inProps) {
|
|
|
93
124
|
React.createElement(Typography, { variant: "body2" },
|
|
94
125
|
React.createElement(FormattedMessage, { id: "ui.groupForm.visibility.hidden.info", defaultMessage: "ui.groupForm.visibility.hidden.info", values: { b: (chunks) => React.createElement("strong", null, chunks) } })))))),
|
|
95
126
|
React.createElement(Typography, { variant: "body2", className: classes.date },
|
|
96
|
-
React.createElement(FormattedMessage, { id: "ui.groupInfoWidget.date", defaultMessage: "ui.groupInfoWidget.date", values: { date: intl.formatDate(scGroup.created_at, { day: 'numeric', year: 'numeric', month: 'long' }) } }))
|
|
127
|
+
React.createElement(FormattedMessage, { id: "ui.groupInfoWidget.date", defaultMessage: "ui.groupInfoWidget.date", values: { date: intl.formatDate(scGroup.created_at, { day: 'numeric', year: 'numeric', month: 'long' }) } })),
|
|
128
|
+
React.createElement(Typography, { variant: "body2", className: classes.admin },
|
|
129
|
+
React.createElement(FormattedMessage, { id: "ui.groupInfoWidget.admin", defaultMessage: "ui.groupInfoWidget.admin", values: { b: (chunks) => React.createElement("strong", null, chunks), admin: scGroup === null || scGroup === void 0 ? void 0 : scGroup.managed_by.username } })))));
|
|
97
130
|
}
|
|
@@ -89,11 +89,11 @@ export default function GroupInviteButton(inProps) {
|
|
|
89
89
|
const [loading, setLoading] = useState(false);
|
|
90
90
|
const [invited, setInvited] = useState([]);
|
|
91
91
|
function convertToInvitedUsersObject(data) {
|
|
92
|
-
const
|
|
92
|
+
const invite_users = {};
|
|
93
93
|
data.forEach((user, index) => {
|
|
94
|
-
|
|
94
|
+
invite_users[`invite_users[${index}]`] = user.id;
|
|
95
95
|
});
|
|
96
|
-
return
|
|
96
|
+
return invite_users;
|
|
97
97
|
}
|
|
98
98
|
/**
|
|
99
99
|
* Memoized users invited ids
|
|
@@ -108,7 +108,7 @@ export default function GroupInviteButton(inProps) {
|
|
|
108
108
|
}, [invited]);
|
|
109
109
|
// HOOKS
|
|
110
110
|
const { scGroup } = useSCFetchGroup({ id: groupId, group });
|
|
111
|
-
const
|
|
111
|
+
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]);
|
|
112
112
|
// INTL
|
|
113
113
|
const intl = useIntl();
|
|
114
114
|
function fetchResults() {
|
|
@@ -179,6 +179,7 @@ export default function GroupInviteButton(inProps) {
|
|
|
179
179
|
.then(() => {
|
|
180
180
|
setIsSending(false);
|
|
181
181
|
setOpen(false);
|
|
182
|
+
setInvited([]);
|
|
182
183
|
})
|
|
183
184
|
.catch((error) => {
|
|
184
185
|
setOpen(false);
|
|
@@ -223,9 +224,9 @@ export default function GroupInviteButton(inProps) {
|
|
|
223
224
|
setList((prev) => [...prev, option]);
|
|
224
225
|
};
|
|
225
226
|
/**
|
|
226
|
-
* If
|
|
227
|
+
* If in group edit mode and logged-in user is not also the group manager, the component is hidden.
|
|
227
228
|
// */
|
|
228
|
-
if (!
|
|
229
|
+
if (group && !isGroupAdmin) {
|
|
229
230
|
return null;
|
|
230
231
|
}
|
|
231
232
|
/**
|
|
@@ -239,7 +240,7 @@ export default function GroupInviteButton(inProps) {
|
|
|
239
240
|
React.createElement(Icon, { fontSize: "medium" }, "arrow_back")),
|
|
240
241
|
React.createElement(Typography, { className: classes.dialogTitle },
|
|
241
242
|
React.createElement(FormattedMessage, { id: "ui.groupInviteButton.dialog.title", defaultMessage: "ui.groupInviteButton.dialog.title" })),
|
|
242
|
-
React.createElement(LoadingButton, { size: "small", color: "secondary", variant: "contained", onClick: handleSendInvitations, loading: isSending },
|
|
243
|
+
React.createElement(LoadingButton, { size: "small", color: "secondary", variant: "contained", onClick: handleSendInvitations, loading: isSending, disabled: !invited.length },
|
|
243
244
|
React.createElement(FormattedMessage, { id: "ui.groupInviteButton.dialog.button.end", defaultMessage: "ui.groupInviteButton.dialog.button.end" }))) },
|
|
244
245
|
React.createElement(Box, { className: classes.dialogContent },
|
|
245
246
|
React.createElement(Autocomplete, { className: classes.autocomplete, loading: loading, size: "small", multiple: true, freeSolo: true, disableClearable: true, options: suggested, onChange: handleChange, onInputChange: handleInputChange, inputValue: value, value: invited, getOptionLabel: (option) => (option ? option.username : '...'), isOptionEqualToValue: (option, value) => (option ? value.id === option.id : false), renderTags: () => null, renderOption: (props, option) => (React.createElement(Box, Object.assign({ component: "li" }, props),
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { WidgetProps } from '../Widget';
|
|
2
|
+
import { SCGroupType } from '@selfcommunity/types';
|
|
3
|
+
import { CacheStrategies } from '@selfcommunity/utils';
|
|
4
|
+
import { BaseDialogProps } from '../../shared/BaseDialog';
|
|
5
|
+
import { VirtualScrollerItemProps } from '../../types/virtualScroller';
|
|
6
|
+
import { UserProps } from '../User';
|
|
7
|
+
export interface GroupInvitedWidgetProps extends VirtualScrollerItemProps, WidgetProps {
|
|
8
|
+
/**
|
|
9
|
+
* Group Object
|
|
10
|
+
* @default null
|
|
11
|
+
*/
|
|
12
|
+
group?: SCGroupType;
|
|
13
|
+
/**
|
|
14
|
+
* Id of the group
|
|
15
|
+
* @default null
|
|
16
|
+
*/
|
|
17
|
+
groupId?: number | string;
|
|
18
|
+
/**
|
|
19
|
+
* Limit the number of users to show
|
|
20
|
+
* @default false
|
|
21
|
+
*/
|
|
22
|
+
limit?: number;
|
|
23
|
+
/**
|
|
24
|
+
* Caching strategies
|
|
25
|
+
* @default CacheStrategies.CACHE_FIRST
|
|
26
|
+
*/
|
|
27
|
+
cacheStrategy?: CacheStrategies;
|
|
28
|
+
/**
|
|
29
|
+
* Props to spread to single user object
|
|
30
|
+
* @default empty object
|
|
31
|
+
*/
|
|
32
|
+
UserProps?: UserProps;
|
|
33
|
+
/**
|
|
34
|
+
* Props to spread to followers users dialog
|
|
35
|
+
* @default {}
|
|
36
|
+
*/
|
|
37
|
+
DialogProps?: BaseDialogProps;
|
|
38
|
+
/**
|
|
39
|
+
* Other props
|
|
40
|
+
*/
|
|
41
|
+
[p: string]: any;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* > API documentation for the Community-JS Group Invited Widget component. Learn about the available props and the CSS API.
|
|
45
|
+
*
|
|
46
|
+
*
|
|
47
|
+
* This component renders the list of the follows of the given group.
|
|
48
|
+
* Take a look at our <strong>demo</strong> component [here](/docs/sdk/community-js/react-ui/Components/GroupRequests)
|
|
49
|
+
|
|
50
|
+
#### Import
|
|
51
|
+
|
|
52
|
+
```jsx
|
|
53
|
+
import {GroupInvitedWidget} from '@selfcommunity/react-ui';
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
#### Component Name
|
|
57
|
+
|
|
58
|
+
The name `SCGroupInvitedWidget` can be used when providing style overrides in the theme.
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
#### CSS
|
|
62
|
+
|
|
63
|
+
|Rule Name|Global class|Description|
|
|
64
|
+
|---|---|---|
|
|
65
|
+
|root|.SCGroupInvitedWidget-root|Styles applied to the root element.|
|
|
66
|
+
|title|.SCGroupInvitedWidget-title|Styles applied to the title element.|
|
|
67
|
+
|noResults|.SCGroupInvitedWidget-no-results|Styles applied to no results section.|
|
|
68
|
+
|showMore|.SCGroupInvitedWidget-show-more|Styles applied to show more button element.|
|
|
69
|
+
|dialogRoot|.SCGroupInvitedWidget-dialog-root|Styles applied to the dialog root element.|
|
|
70
|
+
|endMessage|.SCGroupInvitedWidget-end-message|Styles applied to the end message element.|
|
|
71
|
+
|
|
72
|
+
* @param inProps
|
|
73
|
+
*/
|
|
74
|
+
export default function GroupInvitedWidget(inProps: GroupInvitedWidgetProps): JSX.Element;
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { __rest } from "tslib";
|
|
2
|
+
import React, { useEffect, useMemo, useReducer, useState } from 'react';
|
|
3
|
+
import { styled } from '@mui/material/styles';
|
|
4
|
+
import List from '@mui/material/List';
|
|
5
|
+
import { Button, CardContent, ListItem, Typography, useMediaQuery, useTheme } from '@mui/material';
|
|
6
|
+
import Widget from '../Widget';
|
|
7
|
+
import { http, Endpoints, GroupService } from '@selfcommunity/api-services';
|
|
8
|
+
import { CacheStrategies, isInteger, Logger } from '@selfcommunity/utils';
|
|
9
|
+
import { SCCache, SCPreferences, useSCFetchGroup, useSCPreferences, useSCUser } from '@selfcommunity/react-core';
|
|
10
|
+
import { actionWidgetTypes, dataWidgetReducer, stateWidgetInitializer } from '../../utils/widget';
|
|
11
|
+
import Skeleton from './Skeleton';
|
|
12
|
+
import { FormattedMessage } from 'react-intl';
|
|
13
|
+
import classNames from 'classnames';
|
|
14
|
+
import { SCOPE_SC_UI } from '../../constants/Errors';
|
|
15
|
+
import BaseDialog from '../../shared/BaseDialog';
|
|
16
|
+
import InfiniteScroll from '../../shared/InfiniteScroll';
|
|
17
|
+
import { useThemeProps } from '@mui/system';
|
|
18
|
+
import HiddenPlaceholder from '../../shared/HiddenPlaceholder';
|
|
19
|
+
import { PREFIX } from './constants';
|
|
20
|
+
import User, { UserSkeleton } from '../User';
|
|
21
|
+
const classes = {
|
|
22
|
+
root: `${PREFIX}-root`,
|
|
23
|
+
title: `${PREFIX}-title`,
|
|
24
|
+
noResults: `${PREFIX}-no-results`,
|
|
25
|
+
showMore: `${PREFIX}-show-more`,
|
|
26
|
+
dialogRoot: `${PREFIX}-dialog-root`,
|
|
27
|
+
endMessage: `${PREFIX}-end-message`
|
|
28
|
+
};
|
|
29
|
+
const Root = styled(Widget, {
|
|
30
|
+
name: PREFIX,
|
|
31
|
+
slot: 'Root'
|
|
32
|
+
})(() => ({}));
|
|
33
|
+
const DialogRoot = styled(BaseDialog, {
|
|
34
|
+
name: PREFIX,
|
|
35
|
+
slot: 'DialogRoot'
|
|
36
|
+
})(() => ({}));
|
|
37
|
+
/**
|
|
38
|
+
* > API documentation for the Community-JS Group Invited Widget component. Learn about the available props and the CSS API.
|
|
39
|
+
*
|
|
40
|
+
*
|
|
41
|
+
* This component renders the list of the follows of the given group.
|
|
42
|
+
* Take a look at our <strong>demo</strong> component [here](/docs/sdk/community-js/react-ui/Components/GroupRequests)
|
|
43
|
+
|
|
44
|
+
#### Import
|
|
45
|
+
|
|
46
|
+
```jsx
|
|
47
|
+
import {GroupInvitedWidget} from '@selfcommunity/react-ui';
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
#### Component Name
|
|
51
|
+
|
|
52
|
+
The name `SCGroupInvitedWidget` can be used when providing style overrides in the theme.
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
#### CSS
|
|
56
|
+
|
|
57
|
+
|Rule Name|Global class|Description|
|
|
58
|
+
|---|---|---|
|
|
59
|
+
|root|.SCGroupInvitedWidget-root|Styles applied to the root element.|
|
|
60
|
+
|title|.SCGroupInvitedWidget-title|Styles applied to the title element.|
|
|
61
|
+
|noResults|.SCGroupInvitedWidget-no-results|Styles applied to no results section.|
|
|
62
|
+
|showMore|.SCGroupInvitedWidget-show-more|Styles applied to show more button element.|
|
|
63
|
+
|dialogRoot|.SCGroupInvitedWidget-dialog-root|Styles applied to the dialog root element.|
|
|
64
|
+
|endMessage|.SCGroupInvitedWidget-end-message|Styles applied to the end message element.|
|
|
65
|
+
|
|
66
|
+
* @param inProps
|
|
67
|
+
*/
|
|
68
|
+
export default function GroupInvitedWidget(inProps) {
|
|
69
|
+
var _a;
|
|
70
|
+
// PROPS
|
|
71
|
+
const props = useThemeProps({
|
|
72
|
+
props: inProps,
|
|
73
|
+
name: PREFIX
|
|
74
|
+
});
|
|
75
|
+
const { groupId, group, limit = 5, className, cacheStrategy = CacheStrategies.NETWORK_ONLY, onHeightChange, onStateChange, UserProps = {}, DialogProps = {} } = props, rest = __rest(props, ["groupId", "group", "limit", "className", "cacheStrategy", "onHeightChange", "onStateChange", "UserProps", "DialogProps"]);
|
|
76
|
+
// STATE
|
|
77
|
+
const [state, dispatch] = useReducer(dataWidgetReducer, {
|
|
78
|
+
isLoadingNext: false,
|
|
79
|
+
next: null,
|
|
80
|
+
cacheKey: SCCache.getWidgetStateCacheKey(SCCache.GROUP_REQUESTS_TOOLS_STATE_CACHE_PREFIX_KEY, isInteger(groupId) ? groupId : group.id),
|
|
81
|
+
cacheStrategy,
|
|
82
|
+
visibleItems: limit
|
|
83
|
+
}, stateWidgetInitializer);
|
|
84
|
+
const [openDialog, setOpenDialog] = useState(false);
|
|
85
|
+
// CONTEXT
|
|
86
|
+
const scUserContext = useSCUser();
|
|
87
|
+
const scPreferencesContext = useSCPreferences();
|
|
88
|
+
const { scGroup } = useSCFetchGroup({ id: groupId, group });
|
|
89
|
+
// MEMO
|
|
90
|
+
const contentAvailability = useMemo(() => SCPreferences.CONFIGURATIONS_CONTENT_AVAILABILITY in scPreferencesContext.preferences &&
|
|
91
|
+
scPreferencesContext.preferences[SCPreferences.CONFIGURATIONS_CONTENT_AVAILABILITY].value, [scPreferencesContext.preferences]);
|
|
92
|
+
// HOOKS
|
|
93
|
+
const theme = useTheme();
|
|
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]);
|
|
96
|
+
/**
|
|
97
|
+
* Initialize component
|
|
98
|
+
* Fetch data only if the component is not initialized and it is not loading data
|
|
99
|
+
*/
|
|
100
|
+
const _initComponent = useMemo(() => () => {
|
|
101
|
+
if (!state.initialized && !state.isLoadingNext) {
|
|
102
|
+
dispatch({ type: actionWidgetTypes.LOADING_NEXT });
|
|
103
|
+
GroupService.getGroupInvitedUsers(scGroup.id, { limit })
|
|
104
|
+
.then((payload) => {
|
|
105
|
+
dispatch({ type: actionWidgetTypes.LOAD_NEXT_SUCCESS, payload: Object.assign(Object.assign({}, payload), { initialized: true }) });
|
|
106
|
+
})
|
|
107
|
+
.catch((error) => {
|
|
108
|
+
dispatch({ type: actionWidgetTypes.LOAD_NEXT_FAILURE, payload: { errorLoadNext: error } });
|
|
109
|
+
Logger.error(SCOPE_SC_UI, error);
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}, [state.isLoadingNext, state.initialized, scGroup, limit, dispatch]);
|
|
113
|
+
// EFFECTS
|
|
114
|
+
useEffect(() => {
|
|
115
|
+
var _a;
|
|
116
|
+
let _t;
|
|
117
|
+
if ((contentAvailability || (!contentAvailability && ((_a = scUserContext.user) === null || _a === void 0 ? void 0 : _a.id))) && scGroup && scUserContext.user !== undefined) {
|
|
118
|
+
_t = setTimeout(_initComponent);
|
|
119
|
+
return () => {
|
|
120
|
+
_t && clearTimeout(_t);
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
}, [scUserContext.user, contentAvailability, scGroup]);
|
|
124
|
+
useEffect(() => {
|
|
125
|
+
if (openDialog && state.next && state.results.length === limit && state.initialized) {
|
|
126
|
+
dispatch({ type: actionWidgetTypes.LOADING_NEXT });
|
|
127
|
+
GroupService.getGroupInvitedUsers(scGroup.id, { offset: limit, limit: 10 })
|
|
128
|
+
.then((payload) => {
|
|
129
|
+
dispatch({ type: actionWidgetTypes.LOAD_NEXT_SUCCESS, payload: payload });
|
|
130
|
+
})
|
|
131
|
+
.catch((error) => {
|
|
132
|
+
dispatch({ type: actionWidgetTypes.LOAD_NEXT_FAILURE, payload: { errorLoadNext: error } });
|
|
133
|
+
Logger.error(SCOPE_SC_UI, error);
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
}, [openDialog, state.next, state.results.length, state.initialized, limit]);
|
|
137
|
+
/**
|
|
138
|
+
* Virtual feed update
|
|
139
|
+
*/
|
|
140
|
+
useEffect(() => {
|
|
141
|
+
onHeightChange && onHeightChange();
|
|
142
|
+
}, [state.results]);
|
|
143
|
+
useEffect(() => {
|
|
144
|
+
if (!scGroup || (!contentAvailability && !scUserContext.user)) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
else if (cacheStrategy === CacheStrategies.NETWORK_ONLY) {
|
|
148
|
+
onStateChange && onStateChange({ cacheStrategy: CacheStrategies.CACHE_FIRST });
|
|
149
|
+
}
|
|
150
|
+
}, [scUserContext.user, scGroup, contentAvailability]);
|
|
151
|
+
useEffect(() => {
|
|
152
|
+
if (!scGroup || !scUserContext.user || !state.initialized) {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
}, []);
|
|
156
|
+
// HANDLERS
|
|
157
|
+
const handleNext = useMemo(() => () => {
|
|
158
|
+
dispatch({ type: actionWidgetTypes.LOADING_NEXT });
|
|
159
|
+
http
|
|
160
|
+
.request({
|
|
161
|
+
url: state.next,
|
|
162
|
+
method: Endpoints.GetGroupWaitingApprovalSubscribers.method
|
|
163
|
+
})
|
|
164
|
+
.then((res) => {
|
|
165
|
+
dispatch({ type: actionWidgetTypes.LOAD_NEXT_SUCCESS, payload: res.data });
|
|
166
|
+
});
|
|
167
|
+
}, [dispatch, state.next, state.isLoadingNext, state.initialized]);
|
|
168
|
+
const handleToggleDialogOpen = () => {
|
|
169
|
+
setOpenDialog((prev) => !prev);
|
|
170
|
+
};
|
|
171
|
+
// RENDER
|
|
172
|
+
if ((!state.count && state.initialized) || !contentAvailability || !scGroup || !state.count || !state.results.length || !isGroupAdmin) {
|
|
173
|
+
return React.createElement(HiddenPlaceholder, null);
|
|
174
|
+
}
|
|
175
|
+
if (!state.initialized) {
|
|
176
|
+
return React.createElement(Skeleton, null);
|
|
177
|
+
}
|
|
178
|
+
const content = (React.createElement(CardContent, null,
|
|
179
|
+
React.createElement(Typography, { className: classes.title, variant: "h5" },
|
|
180
|
+
React.createElement(FormattedMessage, { id: "ui.groupInvitedWidget.title", defaultMessage: "ui.groupInvitedWidget.title" })),
|
|
181
|
+
React.createElement(React.Fragment, null,
|
|
182
|
+
React.createElement(List, null, state.results.slice(0, state.visibleItems).map((user) => (React.createElement(ListItem, { key: user.id },
|
|
183
|
+
React.createElement(User, { elevation: 0, actions: React.createElement(Button, { disabled: true, variant: "outlined", size: "small" },
|
|
184
|
+
React.createElement(FormattedMessage, { id: "ui.groupInvitedWidget.status", defaultMessage: "ui.groupInvitedWidget.status" })), user: user, userId: user.id }))))),
|
|
185
|
+
state.count > state.visibleItems && (React.createElement(Button, { className: classes.showMore, onClick: handleToggleDialogOpen },
|
|
186
|
+
React.createElement(FormattedMessage, { id: "ui.groupInvitedWidget.button.showMore", defaultMessage: "ui.groupInvitedWidget.button.showMore" })))),
|
|
187
|
+
openDialog && (React.createElement(DialogRoot, Object.assign({ className: classes.dialogRoot, title: React.createElement(FormattedMessage, { defaultMessage: "ui.groupInvitedWidget.dialogTitle", id: "ui.groupInvitedWidget.dialogTitle", values: { total: scGroup.subscribers_counter } }), onClose: handleToggleDialogOpen, open: openDialog }, DialogProps),
|
|
188
|
+
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 },
|
|
189
|
+
React.createElement(FormattedMessage, { id: "ui.groupInvitedWidget.noMoreResults", defaultMessage: "ui.groupInvitedWidget.noMoreResults" })) },
|
|
190
|
+
React.createElement(List, null, state.results.map((user) => (React.createElement(ListItem, { key: user.id },
|
|
191
|
+
React.createElement(User, { elevation: 0, actions: React.createElement(Button, { disabled: true, variant: "outlined", size: "small" },
|
|
192
|
+
React.createElement(FormattedMessage, { id: "ui.groupInvitedWidget.status", defaultMessage: "ui.groupInvitedWidget.status" })), user: user, userId: user.id }))))))))));
|
|
193
|
+
return (React.createElement(Root, Object.assign({ className: classNames(classes.root, className) }, rest), content));
|
|
194
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { WidgetProps } from '../Widget';
|
|
2
|
+
/**
|
|
3
|
+
* > API documentation for the Community-JS Group Invited Widget Skeleton component. Learn about the available props and the CSS API.
|
|
4
|
+
|
|
5
|
+
#### Import
|
|
6
|
+
|
|
7
|
+
```jsx
|
|
8
|
+
import {GroupInvitedWidgetSkeleton} from '@selfcommunity/react-ui';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
#### Component Name
|
|
12
|
+
|
|
13
|
+
The name `SCGroupInvitedWidget-skeleton-root` can be used when providing style overrides in the theme.
|
|
14
|
+
|
|
15
|
+
#### CSS
|
|
16
|
+
|
|
17
|
+
|Rule Name|Global class|Description|
|
|
18
|
+
|---|---|---|
|
|
19
|
+
|root|.SCGroupInvitedWidget-skeleton-root|Styles applied to the root element.|
|
|
20
|
+
*
|
|
21
|
+
*/
|
|
22
|
+
export default function GroupInvitedWidgetSkeleton(props: WidgetProps): JSX.Element;
|