@selfcommunity/react-ui 0.7.9-alpha.39 → 0.7.9-alpha.40
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/Group/Group.js +5 -0
- package/lib/cjs/components/GroupForm/GroupForm.js +8 -5
- package/lib/cjs/components/GroupInfoWidget/GroupInfoWidget.js +4 -1
- package/lib/cjs/components/GroupInviteButton/GroupInviteButton.js +3 -3
- package/lib/cjs/components/GroupMembersWidget/GroupMembersWidget.js +8 -4
- package/lib/cjs/components/Groups/Groups.d.ts +15 -0
- package/lib/cjs/components/Groups/Groups.js +35 -7
- package/lib/esm/components/Group/Group.js +7 -2
- package/lib/esm/components/GroupForm/GroupForm.js +8 -5
- package/lib/esm/components/GroupInfoWidget/GroupInfoWidget.js +4 -1
- package/lib/esm/components/GroupInviteButton/GroupInviteButton.js +3 -3
- package/lib/esm/components/GroupMembersWidget/GroupMembersWidget.js +9 -5
- package/lib/esm/components/Groups/Groups.d.ts +15 -0
- package/lib/esm/components/Groups/Groups.js +37 -9
- package/lib/umd/react-ui.js +1 -1
- package/package.json +4 -4
|
@@ -59,6 +59,7 @@ const Root = (0, styles_1.styled)(BaseItemButton_1.default, {
|
|
|
59
59
|
* @param inProps
|
|
60
60
|
*/
|
|
61
61
|
function Group(inProps) {
|
|
62
|
+
var _a;
|
|
62
63
|
// PROPS
|
|
63
64
|
const props = (0, system_1.useThemeProps)({
|
|
64
65
|
props: inProps,
|
|
@@ -69,6 +70,9 @@ function Group(inProps) {
|
|
|
69
70
|
const { scGroup } = (0, react_core_1.useSCFetchGroup)({ id: groupId, group });
|
|
70
71
|
// CONTEXT
|
|
71
72
|
const scRoutingContext = (0, react_core_1.useSCRouting)();
|
|
73
|
+
const scUserContext = (0, react_core_1.useSCUser)();
|
|
74
|
+
// CONST
|
|
75
|
+
const isGroupAdmin = (0, react_1.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]);
|
|
72
76
|
const [openAlert, setOpenAlert] = (0, react_1.useState)(false);
|
|
73
77
|
// INTL
|
|
74
78
|
const intl = (0, react_intl_1.useIntl)();
|
|
@@ -79,6 +83,7 @@ function Group(inProps) {
|
|
|
79
83
|
function renderAuthenticatedActions() {
|
|
80
84
|
return (react_1.default.createElement(material_1.Stack, { className: classes.actions, direction: "row", alignItems: "center", justifyContent: "center", spacing: 2 },
|
|
81
85
|
react_1.default.createElement(material_1.Icon, null, (group === null || group === void 0 ? void 0 : group.privacy) === types_1.SCGroupPrivacyType.PRIVATE ? 'private' : 'public'),
|
|
86
|
+
isGroupAdmin && react_1.default.createElement(material_1.Icon, null, "face"),
|
|
82
87
|
react_1.default.createElement(GroupSubscribeButton_1.default, Object.assign({ group: group, groupId: groupId }, groupSubscribeButtonProps))));
|
|
83
88
|
}
|
|
84
89
|
/**
|
|
@@ -173,8 +173,10 @@ function GroupForm(inProps) {
|
|
|
173
173
|
if (field.emotionalImageOriginalFile) {
|
|
174
174
|
formData.append('emotional_image_original', field.emotionalImageOriginalFile);
|
|
175
175
|
}
|
|
176
|
-
|
|
177
|
-
|
|
176
|
+
if (!group) {
|
|
177
|
+
for (const key in field.invitedUsers) {
|
|
178
|
+
formData.append(key, field.invitedUsers[key]);
|
|
179
|
+
}
|
|
178
180
|
}
|
|
179
181
|
let groupService;
|
|
180
182
|
if (group) {
|
|
@@ -251,8 +253,9 @@ function GroupForm(inProps) {
|
|
|
251
253
|
react_1.default.createElement(material_1.Icon, null, "visibility"),
|
|
252
254
|
react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.groupForm.visibility.visible", defaultMessage: "ui.groupForm.visibility.visible" }))),
|
|
253
255
|
react_1.default.createElement(material_1.Typography, { variant: "body2", className: classes.visibilitySectionInfo }, !field.isVisible ? (react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.groupForm.visibility.hidden.info", defaultMessage: "ui.groupForm.visibility.hidden.info", values: { b: (chunks) => react_1.default.createElement("strong", null, chunks) } })) : (react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.groupForm.visibility.visible.info", defaultMessage: "ui.groupForm.visibility.visible.info", values: { b: (chunks) => react_1.default.createElement("strong", null, chunks) } }))))))),
|
|
254
|
-
react_1.default.createElement(
|
|
255
|
-
|
|
256
|
-
react_1.default.createElement(
|
|
256
|
+
!group && (react_1.default.createElement(react_1.default.Fragment, null,
|
|
257
|
+
react_1.default.createElement(material_1.Divider, null),
|
|
258
|
+
react_1.default.createElement(material_1.Box, { className: classes.inviteSection },
|
|
259
|
+
react_1.default.createElement(GroupInviteButton_1.default, { handleInvitations: handleInviteSection })))))));
|
|
257
260
|
}
|
|
258
261
|
exports.default = GroupForm;
|
|
@@ -22,6 +22,7 @@ const classes = {
|
|
|
22
22
|
privacyTitle: `${constants_1.PREFIX}-privacy-title`,
|
|
23
23
|
visibility: `${constants_1.PREFIX}-visibility`,
|
|
24
24
|
visibilityTitle: `${constants_1.PREFIX}-visibility-title`,
|
|
25
|
+
admin: `${constants_1.PREFIX}-admin`,
|
|
25
26
|
date: `${constants_1.PREFIX}-date`
|
|
26
27
|
};
|
|
27
28
|
const Root = (0, styles_1.styled)(Widget_1.default, {
|
|
@@ -125,6 +126,8 @@ function GroupInfoWidget(inProps) {
|
|
|
125
126
|
react_1.default.createElement(material_1.Typography, { variant: "body2" },
|
|
126
127
|
react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.groupForm.visibility.hidden.info", defaultMessage: "ui.groupForm.visibility.hidden.info", values: { b: (chunks) => react_1.default.createElement("strong", null, chunks) } })))))),
|
|
127
128
|
react_1.default.createElement(material_1.Typography, { variant: "body2", className: classes.date },
|
|
128
|
-
react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.groupInfoWidget.date", defaultMessage: "ui.groupInfoWidget.date", values: { date: intl.formatDate(scGroup.created_at, { day: 'numeric', year: 'numeric', month: 'long' }) } }))
|
|
129
|
+
react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.groupInfoWidget.date", defaultMessage: "ui.groupInfoWidget.date", values: { date: intl.formatDate(scGroup.created_at, { day: 'numeric', year: 'numeric', month: 'long' }) } })),
|
|
130
|
+
react_1.default.createElement(material_1.Typography, { variant: "body2", className: classes.admin },
|
|
131
|
+
react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.groupInfoWidget.admin", defaultMessage: "ui.groupInfoWidget.admin", values: { b: (chunks) => react_1.default.createElement("strong", null, chunks), admin: scGroup === null || scGroup === void 0 ? void 0 : scGroup.managed_by.username } })))));
|
|
129
132
|
}
|
|
130
133
|
exports.default = GroupInfoWidget;
|
|
@@ -91,11 +91,11 @@ function GroupInviteButton(inProps) {
|
|
|
91
91
|
const [loading, setLoading] = (0, react_1.useState)(false);
|
|
92
92
|
const [invited, setInvited] = (0, react_1.useState)([]);
|
|
93
93
|
function convertToInvitedUsersObject(data) {
|
|
94
|
-
const
|
|
94
|
+
const invite_users = {};
|
|
95
95
|
data.forEach((user, index) => {
|
|
96
|
-
|
|
96
|
+
invite_users[`invite_users[${index}]`] = user.id;
|
|
97
97
|
});
|
|
98
|
-
return
|
|
98
|
+
return invite_users;
|
|
99
99
|
}
|
|
100
100
|
/**
|
|
101
101
|
* Memoized users invited ids
|
|
@@ -22,10 +22,12 @@ const constants_1 = require("./constants");
|
|
|
22
22
|
const User_1 = tslib_1.__importStar(require("../User"));
|
|
23
23
|
const GroupInviteButton_1 = tslib_1.__importDefault(require("../GroupInviteButton"));
|
|
24
24
|
const GroupSettingsIconButton_1 = tslib_1.__importDefault(require("../GroupSettingsIconButton"));
|
|
25
|
+
const Icon_1 = tslib_1.__importDefault(require("@mui/material/Icon"));
|
|
25
26
|
const classes = {
|
|
26
27
|
root: `${constants_1.PREFIX}-root`,
|
|
27
28
|
title: `${constants_1.PREFIX}-title`,
|
|
28
29
|
actions: `${constants_1.PREFIX}-actions`,
|
|
30
|
+
badge: `${constants_1.PREFIX}-badge`,
|
|
29
31
|
noResults: `${constants_1.PREFIX}-no-results`,
|
|
30
32
|
showMore: `${constants_1.PREFIX}-show-more`,
|
|
31
33
|
dialogRoot: `${constants_1.PREFIX}-dialog-root`,
|
|
@@ -197,10 +199,11 @@ function GroupMembersWidget(inProps) {
|
|
|
197
199
|
!state.count ? (react_1.default.createElement(material_1.Typography, { className: classes.noResults, variant: "body2" },
|
|
198
200
|
react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.groupMembersWidget.subtitle.noResults", defaultMessage: "" }))) : (react_1.default.createElement(react_1.default.Fragment, null,
|
|
199
201
|
react_1.default.createElement(List_1.default, null, state.results.slice(0, state.visibleItems).map((user) => {
|
|
200
|
-
var _a;
|
|
202
|
+
var _a, _b;
|
|
201
203
|
return (react_1.default.createElement(material_1.ListItem, { key: user.id },
|
|
202
204
|
react_1.default.createElement(User_1.default, { elevation: 0, actions: isGroupAdmin ? (react_1.default.createElement(GroupSettingsIconButton_1.default, { group: scGroup, user: user, onRemoveSuccess: () => handleRefresh(user.id) })) : ((_a = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _a === void 0 ? void 0 : _a.id) !== user.id ? (react_1.default.createElement(material_1.Button, { size: "small", variant: "outlined", component: react_core_1.Link, to: scRoutingContext.url(react_core_1.SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, user) },
|
|
203
|
-
react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.groupSettingsIconButton.item.message", defaultMessage: "ui.groupSettingsIconButton.item.message" }))) : null,
|
|
205
|
+
react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.groupSettingsIconButton.item.message", defaultMessage: "ui.groupSettingsIconButton.item.message" }))) : null, badgeContent: ((_b = scGroup === null || scGroup === void 0 ? void 0 : scGroup.managed_by) === null || _b === void 0 ? void 0 : _b.id) === user.id ? (react_1.default.createElement(material_1.Avatar, { className: classes.badge },
|
|
206
|
+
react_1.default.createElement(Icon_1.default, null, "face"))) : null, user: user, userId: user.id })));
|
|
204
207
|
})),
|
|
205
208
|
state.count > state.visibleItems && (react_1.default.createElement(material_1.Button, { className: classes.showMore, onClick: handleToggleDialogOpen },
|
|
206
209
|
react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.groupMembersWidget.button.showMore", defaultMessage: "ui.groupMembersWidget.button.showMore" }))))),
|
|
@@ -208,10 +211,11 @@ function GroupMembersWidget(inProps) {
|
|
|
208
211
|
react_1.default.createElement(InfiniteScroll_1.default, { dataLength: state.results.length, next: handleNext, hasMoreNext: Boolean(state.next), loaderNext: react_1.default.createElement(User_1.UserSkeleton, Object.assign({ elevation: 0 }, UserProps)), height: isMobile ? '100%' : 400, endMessage: react_1.default.createElement(material_1.Typography, { className: classes.endMessage },
|
|
209
212
|
react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.groupMembersWidget.noMoreResults", defaultMessage: "ui.groupMembersWidget.noMoreResults" })) },
|
|
210
213
|
react_1.default.createElement(List_1.default, null, state.results.map((user) => {
|
|
211
|
-
var _a;
|
|
214
|
+
var _a, _b;
|
|
212
215
|
return (react_1.default.createElement(material_1.ListItem, { key: user.id },
|
|
213
216
|
react_1.default.createElement(User_1.default, { elevation: 0, actions: isGroupAdmin ? (react_1.default.createElement(GroupSettingsIconButton_1.default, { group: scGroup, user: user, onRemoveSuccess: () => handleRefresh(user.id) })) : ((_a = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _a === void 0 ? void 0 : _a.id) !== user.id ? (react_1.default.createElement(material_1.Button, { size: "small", variant: "outlined", component: react_core_1.Link, to: scRoutingContext.url(react_core_1.SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, user) },
|
|
214
|
-
react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.groupSettingsIconButton.item.message", defaultMessage: "ui.groupSettingsIconButton.item.message" }))) : null,
|
|
217
|
+
react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.groupSettingsIconButton.item.message", defaultMessage: "ui.groupSettingsIconButton.item.message" }))) : null, badgeContent: ((_b = scGroup === null || scGroup === void 0 ? void 0 : scGroup.managed_by) === null || _b === void 0 ? void 0 : _b.id) === user.id ? (react_1.default.createElement(material_1.Avatar, { className: classes.badge },
|
|
218
|
+
react_1.default.createElement(Icon_1.default, null, "face"))) : null, user: user, userId: user.id })));
|
|
215
219
|
})))))),
|
|
216
220
|
react_1.default.createElement(material_1.CardActions, { className: classes.actions },
|
|
217
221
|
react_1.default.createElement(GroupInviteButton_1.default, { groupId: scGroup === null || scGroup === void 0 ? void 0 : scGroup.id, group: scGroup }))));
|
|
@@ -26,6 +26,21 @@ export interface GroupsProps {
|
|
|
26
26
|
* @default null
|
|
27
27
|
*/
|
|
28
28
|
general?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Show/Hide filters
|
|
31
|
+
* @default false
|
|
32
|
+
*/
|
|
33
|
+
showFilters?: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Override filter func
|
|
36
|
+
* @default null
|
|
37
|
+
*/
|
|
38
|
+
handleFilterGroups?: (groups: SCGroupType[]) => SCGroupType[];
|
|
39
|
+
/**
|
|
40
|
+
* Filters component
|
|
41
|
+
* @param props
|
|
42
|
+
*/
|
|
43
|
+
filters?: JSX.Element;
|
|
29
44
|
/**
|
|
30
45
|
* Other props
|
|
31
46
|
*/
|
|
@@ -17,6 +17,7 @@ const constants_1 = require("./constants");
|
|
|
17
17
|
const Group_1 = tslib_1.__importDefault(require("../Group"));
|
|
18
18
|
const classes = {
|
|
19
19
|
root: `${constants_1.PREFIX}-root`,
|
|
20
|
+
filters: `${constants_1.PREFIX}-filter`,
|
|
20
21
|
groups: `${constants_1.PREFIX}-groups`,
|
|
21
22
|
item: `${constants_1.PREFIX}-item`,
|
|
22
23
|
noResults: `${constants_1.PREFIX}-no-results`,
|
|
@@ -64,10 +65,11 @@ function Groups(inProps) {
|
|
|
64
65
|
props: inProps,
|
|
65
66
|
name: constants_1.PREFIX
|
|
66
67
|
});
|
|
67
|
-
const { endpoint, className, GroupComponentProps = { variant: 'outlined', ButtonBaseProps: { disableRipple: true, component: material_1.Box } }, prefetchedGroups = [], general } = props, rest = tslib_1.__rest(props, ["endpoint", "className", "GroupComponentProps", "prefetchedGroups", "general"]);
|
|
68
|
+
const { endpoint, className, GroupComponentProps = { variant: 'outlined', ButtonBaseProps: { disableRipple: true, component: material_1.Box } }, prefetchedGroups = [], showFilters = false, filters, handleFilterGroups, general } = props, rest = tslib_1.__rest(props, ["endpoint", "className", "GroupComponentProps", "prefetchedGroups", "showFilters", "filters", "handleFilterGroups", "general"]);
|
|
68
69
|
// STATE
|
|
69
70
|
const [groups, setGroups] = (0, react_1.useState)([]);
|
|
70
71
|
const [loading, setLoading] = (0, react_1.useState)(true);
|
|
72
|
+
const [filterName, setFilterName] = (0, react_1.useState)('');
|
|
71
73
|
// CONTEXT
|
|
72
74
|
const scUserContext = (0, react_core_1.useSCUser)();
|
|
73
75
|
const scPreferencesContext = (0, react_core_1.useSCPreferences)();
|
|
@@ -120,16 +122,42 @@ function Groups(inProps) {
|
|
|
120
122
|
setGroups(_updated);
|
|
121
123
|
}
|
|
122
124
|
};
|
|
125
|
+
/**
|
|
126
|
+
* Get groups filtered
|
|
127
|
+
*/
|
|
128
|
+
const getFilteredGroups = () => {
|
|
129
|
+
if (handleFilterGroups) {
|
|
130
|
+
return handleFilterGroups(groups);
|
|
131
|
+
}
|
|
132
|
+
if (filterName) {
|
|
133
|
+
return groups.filter((g) => g.name.toLowerCase().includes(filterName.toLowerCase()));
|
|
134
|
+
}
|
|
135
|
+
return groups;
|
|
136
|
+
};
|
|
137
|
+
/**
|
|
138
|
+
* Handle change filter name
|
|
139
|
+
* @param event
|
|
140
|
+
*/
|
|
141
|
+
const handleOnChangeFilterName = (event) => {
|
|
142
|
+
setFilterName(event.target.value);
|
|
143
|
+
};
|
|
144
|
+
/**
|
|
145
|
+
* Renders groups list
|
|
146
|
+
*/
|
|
147
|
+
const filteredGroups = (0, utils_1.sortByAttr)(getFilteredGroups(), 'order');
|
|
148
|
+
const content = (react_1.default.createElement(react_1.default.Fragment, null,
|
|
149
|
+
showFilters && (react_1.default.createElement(material_1.Grid, { container: true, direction: "row", justifyContent: "center", alignItems: "center", className: classes.filters }, filters ? (filters) : (react_1.default.createElement(material_1.Grid, { item: true, xs: 12, md: 6 },
|
|
150
|
+
react_1.default.createElement(material_1.TextField, { fullWidth: true, value: filterName, label: react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.groups.filterByName", defaultMessage: "ui.groups.filterByName" }), variant: "outlined", onChange: handleOnChangeFilterName, disabled: loading }))))),
|
|
151
|
+
loading ? (react_1.default.createElement(Skeleton_1.default, null)) : (react_1.default.createElement(react_1.default.Fragment, null, !groups.length ? (react_1.default.createElement(material_1.Box, { className: classes.noResults },
|
|
152
|
+
react_1.default.createElement(material_1.Typography, { variant: "h4" },
|
|
153
|
+
react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.groups.noGroups.title", defaultMessage: "ui.groups.noGroups.title" })),
|
|
154
|
+
react_1.default.createElement(material_1.Typography, { variant: "body1" },
|
|
155
|
+
react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.groups.noGroups.subtitle", defaultMessage: "ui.groups.noGroups.subtitle" })))) : (react_1.default.createElement(material_1.Grid, { container: true, spacing: { xs: 3 }, className: classes.groups }, filteredGroups.map((group) => (react_1.default.createElement(material_1.Grid, { item: true, xs: 12, sm: 8, md: 6, key: group.id, className: classes.item },
|
|
156
|
+
react_1.default.createElement(Group_1.default, Object.assign({ group: group, groupId: group.id, groupSubscribeButtonProps: { onSubscribe: handleSubscribe } }, GroupComponentProps)))))))))));
|
|
123
157
|
// RENDER
|
|
124
158
|
if (!contentAvailability && !scUserContext.user) {
|
|
125
159
|
return react_1.default.createElement(HiddenPlaceholder_1.default, null);
|
|
126
160
|
}
|
|
127
|
-
const content = (react_1.default.createElement(react_1.default.Fragment, null, loading ? (react_1.default.createElement(Skeleton_1.default, null)) : (react_1.default.createElement(react_1.default.Fragment, null, !groups.length ? (react_1.default.createElement(material_1.Box, { className: classes.noResults },
|
|
128
|
-
react_1.default.createElement(material_1.Typography, { variant: "h4" },
|
|
129
|
-
react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.groups.noGroups.title", defaultMessage: "ui.groups.noGroups.title" })),
|
|
130
|
-
react_1.default.createElement(material_1.Typography, { variant: "body1" },
|
|
131
|
-
react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.groups.noGroups.subtitle", defaultMessage: "ui.groups.noGroups.subtitle" })))) : (react_1.default.createElement(material_1.Grid, { container: true, spacing: { xs: 3 }, className: classes.groups }, groups.map((group) => (react_1.default.createElement(material_1.Grid, { item: true, xs: 12, sm: 8, md: 6, key: group.id, className: classes.item },
|
|
132
|
-
react_1.default.createElement(Group_1.default, Object.assign({ group: group, groupId: group.id, groupSubscribeButtonProps: { onSubscribe: handleSubscribe } }, GroupComponentProps)))))))))));
|
|
133
161
|
return (react_1.default.createElement(Root, Object.assign({ className: (0, classnames_1.default)(classes.root, className) }, rest), content));
|
|
134
162
|
}
|
|
135
163
|
exports.default = Groups;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { __rest } from "tslib";
|
|
2
|
-
import React, { useState } from 'react';
|
|
2
|
+
import React, { useMemo, useState } from 'react';
|
|
3
3
|
import { styled } from '@mui/material/styles';
|
|
4
4
|
import { Avatar, Icon, Stack } from '@mui/material';
|
|
5
5
|
import { SCGroupPrivacyType } from '@selfcommunity/types';
|
|
6
|
-
import { Link, SCRoutes, useSCFetchGroup, useSCRouting } from '@selfcommunity/react-core';
|
|
6
|
+
import { Link, SCRoutes, useSCFetchGroup, useSCRouting, useSCUser } from '@selfcommunity/react-core';
|
|
7
7
|
import { defineMessages, useIntl } from 'react-intl';
|
|
8
8
|
import classNames from 'classnames';
|
|
9
9
|
import { useThemeProps } from '@mui/system';
|
|
@@ -57,6 +57,7 @@ const Root = styled(BaseItemButton, {
|
|
|
57
57
|
* @param inProps
|
|
58
58
|
*/
|
|
59
59
|
export default function Group(inProps) {
|
|
60
|
+
var _a;
|
|
60
61
|
// PROPS
|
|
61
62
|
const props = useThemeProps({
|
|
62
63
|
props: inProps,
|
|
@@ -67,6 +68,9 @@ export default function Group(inProps) {
|
|
|
67
68
|
const { scGroup } = useSCFetchGroup({ id: groupId, group });
|
|
68
69
|
// CONTEXT
|
|
69
70
|
const scRoutingContext = useSCRouting();
|
|
71
|
+
const scUserContext = useSCUser();
|
|
72
|
+
// CONST
|
|
73
|
+
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]);
|
|
70
74
|
const [openAlert, setOpenAlert] = useState(false);
|
|
71
75
|
// INTL
|
|
72
76
|
const intl = useIntl();
|
|
@@ -77,6 +81,7 @@ export default function Group(inProps) {
|
|
|
77
81
|
function renderAuthenticatedActions() {
|
|
78
82
|
return (React.createElement(Stack, { className: classes.actions, direction: "row", alignItems: "center", justifyContent: "center", spacing: 2 },
|
|
79
83
|
React.createElement(Icon, null, (group === null || group === void 0 ? void 0 : group.privacy) === SCGroupPrivacyType.PRIVATE ? 'private' : 'public'),
|
|
84
|
+
isGroupAdmin && React.createElement(Icon, null, "face"),
|
|
80
85
|
React.createElement(GroupSubscribeButton, Object.assign({ group: group, groupId: groupId }, groupSubscribeButtonProps))));
|
|
81
86
|
}
|
|
82
87
|
/**
|
|
@@ -171,8 +171,10 @@ export default function GroupForm(inProps) {
|
|
|
171
171
|
if (field.emotionalImageOriginalFile) {
|
|
172
172
|
formData.append('emotional_image_original', field.emotionalImageOriginalFile);
|
|
173
173
|
}
|
|
174
|
-
|
|
175
|
-
|
|
174
|
+
if (!group) {
|
|
175
|
+
for (const key in field.invitedUsers) {
|
|
176
|
+
formData.append(key, field.invitedUsers[key]);
|
|
177
|
+
}
|
|
176
178
|
}
|
|
177
179
|
let groupService;
|
|
178
180
|
if (group) {
|
|
@@ -249,7 +251,8 @@ export default function GroupForm(inProps) {
|
|
|
249
251
|
React.createElement(Icon, null, "visibility"),
|
|
250
252
|
React.createElement(FormattedMessage, { id: "ui.groupForm.visibility.visible", defaultMessage: "ui.groupForm.visibility.visible" }))),
|
|
251
253
|
React.createElement(Typography, { variant: "body2", className: classes.visibilitySectionInfo }, !field.isVisible ? (React.createElement(FormattedMessage, { id: "ui.groupForm.visibility.hidden.info", defaultMessage: "ui.groupForm.visibility.hidden.info", values: { b: (chunks) => React.createElement("strong", null, chunks) } })) : (React.createElement(FormattedMessage, { id: "ui.groupForm.visibility.visible.info", defaultMessage: "ui.groupForm.visibility.visible.info", values: { b: (chunks) => React.createElement("strong", null, chunks) } }))))))),
|
|
252
|
-
React.createElement(
|
|
253
|
-
|
|
254
|
-
React.createElement(
|
|
254
|
+
!group && (React.createElement(React.Fragment, null,
|
|
255
|
+
React.createElement(Divider, null),
|
|
256
|
+
React.createElement(Box, { className: classes.inviteSection },
|
|
257
|
+
React.createElement(GroupInviteButton, { handleInvitations: handleInviteSection })))))));
|
|
255
258
|
}
|
|
@@ -20,6 +20,7 @@ const classes = {
|
|
|
20
20
|
privacyTitle: `${PREFIX}-privacy-title`,
|
|
21
21
|
visibility: `${PREFIX}-visibility`,
|
|
22
22
|
visibilityTitle: `${PREFIX}-visibility-title`,
|
|
23
|
+
admin: `${PREFIX}-admin`,
|
|
23
24
|
date: `${PREFIX}-date`
|
|
24
25
|
};
|
|
25
26
|
const Root = styled(Widget, {
|
|
@@ -123,5 +124,7 @@ export default function GroupInfoWidget(inProps) {
|
|
|
123
124
|
React.createElement(Typography, { variant: "body2" },
|
|
124
125
|
React.createElement(FormattedMessage, { id: "ui.groupForm.visibility.hidden.info", defaultMessage: "ui.groupForm.visibility.hidden.info", values: { b: (chunks) => React.createElement("strong", null, chunks) } })))))),
|
|
125
126
|
React.createElement(Typography, { variant: "body2", className: classes.date },
|
|
126
|
-
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 } })))));
|
|
127
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
|
|
@@ -2,7 +2,7 @@ import { __rest } from "tslib";
|
|
|
2
2
|
import React, { useEffect, useMemo, useReducer, useState } from 'react';
|
|
3
3
|
import { styled } from '@mui/material/styles';
|
|
4
4
|
import List from '@mui/material/List';
|
|
5
|
-
import { Button, CardActions, CardContent, ListItem, Typography, useMediaQuery, useTheme } from '@mui/material';
|
|
5
|
+
import { Avatar, Button, CardActions, CardContent, ListItem, Typography, useMediaQuery, useTheme } from '@mui/material';
|
|
6
6
|
import Widget from '../Widget';
|
|
7
7
|
import { http, Endpoints, GroupService } from '@selfcommunity/api-services';
|
|
8
8
|
import { CacheStrategies, isInteger, Logger } from '@selfcommunity/utils';
|
|
@@ -20,10 +20,12 @@ import { PREFIX } from './constants';
|
|
|
20
20
|
import User, { UserSkeleton } from '../User';
|
|
21
21
|
import GroupInviteButton from '../GroupInviteButton';
|
|
22
22
|
import GroupSettingsIconButton from '../GroupSettingsIconButton';
|
|
23
|
+
import Icon from '@mui/material/Icon';
|
|
23
24
|
const classes = {
|
|
24
25
|
root: `${PREFIX}-root`,
|
|
25
26
|
title: `${PREFIX}-title`,
|
|
26
27
|
actions: `${PREFIX}-actions`,
|
|
28
|
+
badge: `${PREFIX}-badge`,
|
|
27
29
|
noResults: `${PREFIX}-no-results`,
|
|
28
30
|
showMore: `${PREFIX}-show-more`,
|
|
29
31
|
dialogRoot: `${PREFIX}-dialog-root`,
|
|
@@ -195,10 +197,11 @@ export default function GroupMembersWidget(inProps) {
|
|
|
195
197
|
!state.count ? (React.createElement(Typography, { className: classes.noResults, variant: "body2" },
|
|
196
198
|
React.createElement(FormattedMessage, { id: "ui.groupMembersWidget.subtitle.noResults", defaultMessage: "" }))) : (React.createElement(React.Fragment, null,
|
|
197
199
|
React.createElement(List, null, state.results.slice(0, state.visibleItems).map((user) => {
|
|
198
|
-
var _a;
|
|
200
|
+
var _a, _b;
|
|
199
201
|
return (React.createElement(ListItem, { key: user.id },
|
|
200
202
|
React.createElement(User, { elevation: 0, actions: isGroupAdmin ? (React.createElement(GroupSettingsIconButton, { group: scGroup, user: user, onRemoveSuccess: () => handleRefresh(user.id) })) : ((_a = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _a === void 0 ? void 0 : _a.id) !== user.id ? (React.createElement(Button, { size: "small", variant: "outlined", component: Link, to: scRoutingContext.url(SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, user) },
|
|
201
|
-
React.createElement(FormattedMessage, { id: "ui.groupSettingsIconButton.item.message", defaultMessage: "ui.groupSettingsIconButton.item.message" }))) : null,
|
|
203
|
+
React.createElement(FormattedMessage, { id: "ui.groupSettingsIconButton.item.message", defaultMessage: "ui.groupSettingsIconButton.item.message" }))) : null, badgeContent: ((_b = scGroup === null || scGroup === void 0 ? void 0 : scGroup.managed_by) === null || _b === void 0 ? void 0 : _b.id) === user.id ? (React.createElement(Avatar, { className: classes.badge },
|
|
204
|
+
React.createElement(Icon, null, "face"))) : null, user: user, userId: user.id })));
|
|
202
205
|
})),
|
|
203
206
|
state.count > state.visibleItems && (React.createElement(Button, { className: classes.showMore, onClick: handleToggleDialogOpen },
|
|
204
207
|
React.createElement(FormattedMessage, { id: "ui.groupMembersWidget.button.showMore", defaultMessage: "ui.groupMembersWidget.button.showMore" }))))),
|
|
@@ -206,10 +209,11 @@ export default function GroupMembersWidget(inProps) {
|
|
|
206
209
|
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 },
|
|
207
210
|
React.createElement(FormattedMessage, { id: "ui.groupMembersWidget.noMoreResults", defaultMessage: "ui.groupMembersWidget.noMoreResults" })) },
|
|
208
211
|
React.createElement(List, null, state.results.map((user) => {
|
|
209
|
-
var _a;
|
|
212
|
+
var _a, _b;
|
|
210
213
|
return (React.createElement(ListItem, { key: user.id },
|
|
211
214
|
React.createElement(User, { elevation: 0, actions: isGroupAdmin ? (React.createElement(GroupSettingsIconButton, { group: scGroup, user: user, onRemoveSuccess: () => handleRefresh(user.id) })) : ((_a = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _a === void 0 ? void 0 : _a.id) !== user.id ? (React.createElement(Button, { size: "small", variant: "outlined", component: Link, to: scRoutingContext.url(SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, user) },
|
|
212
|
-
React.createElement(FormattedMessage, { id: "ui.groupSettingsIconButton.item.message", defaultMessage: "ui.groupSettingsIconButton.item.message" }))) : null,
|
|
215
|
+
React.createElement(FormattedMessage, { id: "ui.groupSettingsIconButton.item.message", defaultMessage: "ui.groupSettingsIconButton.item.message" }))) : null, badgeContent: ((_b = scGroup === null || scGroup === void 0 ? void 0 : scGroup.managed_by) === null || _b === void 0 ? void 0 : _b.id) === user.id ? (React.createElement(Avatar, { className: classes.badge },
|
|
216
|
+
React.createElement(Icon, null, "face"))) : null, user: user, userId: user.id })));
|
|
213
217
|
})))))),
|
|
214
218
|
React.createElement(CardActions, { className: classes.actions },
|
|
215
219
|
React.createElement(GroupInviteButton, { groupId: scGroup === null || scGroup === void 0 ? void 0 : scGroup.id, group: scGroup }))));
|
|
@@ -26,6 +26,21 @@ export interface GroupsProps {
|
|
|
26
26
|
* @default null
|
|
27
27
|
*/
|
|
28
28
|
general?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Show/Hide filters
|
|
31
|
+
* @default false
|
|
32
|
+
*/
|
|
33
|
+
showFilters?: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Override filter func
|
|
36
|
+
* @default null
|
|
37
|
+
*/
|
|
38
|
+
handleFilterGroups?: (groups: SCGroupType[]) => SCGroupType[];
|
|
39
|
+
/**
|
|
40
|
+
* Filters component
|
|
41
|
+
* @param props
|
|
42
|
+
*/
|
|
43
|
+
filters?: JSX.Element;
|
|
29
44
|
/**
|
|
30
45
|
* Other props
|
|
31
46
|
*/
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { __awaiter, __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';
|
|
4
|
+
import { Box, Grid, TextField, Typography } from '@mui/material';
|
|
5
5
|
import { http } from '@selfcommunity/api-services';
|
|
6
|
-
import { Logger } from '@selfcommunity/utils';
|
|
6
|
+
import { Logger, sortByAttr } from '@selfcommunity/utils';
|
|
7
7
|
import { SCPreferences, useIsComponentMountedRef, useSCPreferences, useSCUser } from '@selfcommunity/react-core';
|
|
8
8
|
import Skeleton from './Skeleton';
|
|
9
9
|
import { FormattedMessage } from 'react-intl';
|
|
@@ -15,6 +15,7 @@ import { PREFIX } from './constants';
|
|
|
15
15
|
import Group from '../Group';
|
|
16
16
|
const classes = {
|
|
17
17
|
root: `${PREFIX}-root`,
|
|
18
|
+
filters: `${PREFIX}-filter`,
|
|
18
19
|
groups: `${PREFIX}-groups`,
|
|
19
20
|
item: `${PREFIX}-item`,
|
|
20
21
|
noResults: `${PREFIX}-no-results`,
|
|
@@ -62,10 +63,11 @@ export default function Groups(inProps) {
|
|
|
62
63
|
props: inProps,
|
|
63
64
|
name: PREFIX
|
|
64
65
|
});
|
|
65
|
-
const { endpoint, className, GroupComponentProps = { variant: 'outlined', ButtonBaseProps: { disableRipple: true, component: Box } }, prefetchedGroups = [], general } = props, rest = __rest(props, ["endpoint", "className", "GroupComponentProps", "prefetchedGroups", "general"]);
|
|
66
|
+
const { endpoint, className, GroupComponentProps = { variant: 'outlined', ButtonBaseProps: { disableRipple: true, component: Box } }, prefetchedGroups = [], showFilters = false, filters, handleFilterGroups, general } = props, rest = __rest(props, ["endpoint", "className", "GroupComponentProps", "prefetchedGroups", "showFilters", "filters", "handleFilterGroups", "general"]);
|
|
66
67
|
// STATE
|
|
67
68
|
const [groups, setGroups] = useState([]);
|
|
68
69
|
const [loading, setLoading] = useState(true);
|
|
70
|
+
const [filterName, setFilterName] = useState('');
|
|
69
71
|
// CONTEXT
|
|
70
72
|
const scUserContext = useSCUser();
|
|
71
73
|
const scPreferencesContext = useSCPreferences();
|
|
@@ -118,15 +120,41 @@ export default function Groups(inProps) {
|
|
|
118
120
|
setGroups(_updated);
|
|
119
121
|
}
|
|
120
122
|
};
|
|
123
|
+
/**
|
|
124
|
+
* Get groups filtered
|
|
125
|
+
*/
|
|
126
|
+
const getFilteredGroups = () => {
|
|
127
|
+
if (handleFilterGroups) {
|
|
128
|
+
return handleFilterGroups(groups);
|
|
129
|
+
}
|
|
130
|
+
if (filterName) {
|
|
131
|
+
return groups.filter((g) => g.name.toLowerCase().includes(filterName.toLowerCase()));
|
|
132
|
+
}
|
|
133
|
+
return groups;
|
|
134
|
+
};
|
|
135
|
+
/**
|
|
136
|
+
* Handle change filter name
|
|
137
|
+
* @param event
|
|
138
|
+
*/
|
|
139
|
+
const handleOnChangeFilterName = (event) => {
|
|
140
|
+
setFilterName(event.target.value);
|
|
141
|
+
};
|
|
142
|
+
/**
|
|
143
|
+
* Renders groups list
|
|
144
|
+
*/
|
|
145
|
+
const filteredGroups = sortByAttr(getFilteredGroups(), 'order');
|
|
146
|
+
const content = (React.createElement(React.Fragment, null,
|
|
147
|
+
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 },
|
|
148
|
+
React.createElement(TextField, { fullWidth: true, value: filterName, label: React.createElement(FormattedMessage, { id: "ui.groups.filterByName", defaultMessage: "ui.groups.filterByName" }), variant: "outlined", onChange: handleOnChangeFilterName, disabled: loading }))))),
|
|
149
|
+
loading ? (React.createElement(Skeleton, null)) : (React.createElement(React.Fragment, null, !groups.length ? (React.createElement(Box, { className: classes.noResults },
|
|
150
|
+
React.createElement(Typography, { variant: "h4" },
|
|
151
|
+
React.createElement(FormattedMessage, { id: "ui.groups.noGroups.title", defaultMessage: "ui.groups.noGroups.title" })),
|
|
152
|
+
React.createElement(Typography, { variant: "body1" },
|
|
153
|
+
React.createElement(FormattedMessage, { id: "ui.groups.noGroups.subtitle", defaultMessage: "ui.groups.noGroups.subtitle" })))) : (React.createElement(Grid, { container: true, spacing: { xs: 3 }, className: classes.groups }, filteredGroups.map((group) => (React.createElement(Grid, { item: true, xs: 12, sm: 8, md: 6, key: group.id, className: classes.item },
|
|
154
|
+
React.createElement(Group, Object.assign({ group: group, groupId: group.id, groupSubscribeButtonProps: { onSubscribe: handleSubscribe } }, GroupComponentProps)))))))))));
|
|
121
155
|
// RENDER
|
|
122
156
|
if (!contentAvailability && !scUserContext.user) {
|
|
123
157
|
return React.createElement(HiddenPlaceholder, null);
|
|
124
158
|
}
|
|
125
|
-
const content = (React.createElement(React.Fragment, null, loading ? (React.createElement(Skeleton, null)) : (React.createElement(React.Fragment, null, !groups.length ? (React.createElement(Box, { className: classes.noResults },
|
|
126
|
-
React.createElement(Typography, { variant: "h4" },
|
|
127
|
-
React.createElement(FormattedMessage, { id: "ui.groups.noGroups.title", defaultMessage: "ui.groups.noGroups.title" })),
|
|
128
|
-
React.createElement(Typography, { variant: "body1" },
|
|
129
|
-
React.createElement(FormattedMessage, { id: "ui.groups.noGroups.subtitle", defaultMessage: "ui.groups.noGroups.subtitle" })))) : (React.createElement(Grid, { container: true, spacing: { xs: 3 }, className: classes.groups }, groups.map((group) => (React.createElement(Grid, { item: true, xs: 12, sm: 8, md: 6, key: group.id, className: classes.item },
|
|
130
|
-
React.createElement(Group, Object.assign({ group: group, groupId: group.id, groupSubscribeButtonProps: { onSubscribe: handleSubscribe } }, GroupComponentProps)))))))))));
|
|
131
159
|
return (React.createElement(Root, Object.assign({ className: classNames(classes.root, className) }, rest), content));
|
|
132
160
|
}
|