@selfcommunity/react-ui 0.8.0-alpha.3 → 0.8.0-alpha.31
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/BottomNavigation/BottomNavigation.js +11 -2
- package/lib/cjs/components/Composer/Composer.js +10 -2
- package/lib/cjs/components/Composer/Layer/AudienceLayer/AudienceLayer.js +12 -3
- package/lib/cjs/components/CreateEventButton/CreateEventButton.js +5 -1
- package/lib/cjs/components/CreateEventWidget/CreateEventWidget.js +5 -1
- package/lib/cjs/components/EventForm/EventForm.d.ts +1 -1
- package/lib/cjs/components/EventForm/EventForm.js +72 -54
- package/lib/cjs/components/EventForm/constants.d.ts +4 -0
- package/lib/cjs/components/EventForm/constants.js +5 -1
- package/lib/cjs/components/EventForm/types.d.ts +1 -2
- package/lib/cjs/components/EventForm/utils.d.ts +4 -0
- package/lib/cjs/components/EventForm/utils.js +28 -0
- package/lib/cjs/components/EventInfoWidget/EventInfoWidget.js +24 -1
- package/lib/cjs/components/Events/Events.js +17 -7
- package/lib/cjs/components/Events/LocationEventsFilter.d.ts +14 -0
- package/lib/cjs/components/Events/LocationEventsFilter.js +45 -0
- package/lib/cjs/components/Events/PastEventsFilter.js +1 -2
- package/lib/cjs/components/Feed/Feed.js +12 -3
- package/lib/cjs/components/GroupActionsMenu/index.d.ts +57 -0
- package/lib/cjs/components/GroupActionsMenu/index.js +157 -0
- package/lib/cjs/components/GroupHeader/GroupHeader.d.ts +6 -0
- package/lib/cjs/components/GroupHeader/GroupHeader.js +8 -4
- package/lib/cjs/components/Groups/Groups.js +26 -0
- package/lib/cjs/components/MyEventsWidget/MyEventsWidget.js +6 -2
- package/lib/cjs/components/NavigationMenuIconButton/NavigationMenuDrawer.d.ts +35 -0
- package/lib/cjs/components/NavigationMenuIconButton/NavigationMenuDrawer.js +68 -0
- package/lib/cjs/components/NavigationMenuIconButton/NavigationMenuIconButton.d.ts +9 -20
- package/lib/cjs/components/NavigationMenuIconButton/NavigationMenuIconButton.js +8 -27
- package/lib/cjs/components/NavigationMenuIconButton/index.d.ts +2 -1
- package/lib/cjs/components/NavigationMenuIconButton/index.js +3 -1
- package/lib/cjs/components/NavigationToolbar/NavigationToolbar.d.ts +5 -0
- package/lib/cjs/components/NavigationToolbar/NavigationToolbar.js +14 -5
- package/lib/cjs/components/NavigationToolbarMobile/NavigationToolbarMobile.js +11 -2
- package/lib/cjs/components/Notification/Event/Event.js +4 -0
- package/lib/cjs/components/OnBoardingWidget/OnBoardingWidget.d.ts +10 -1
- package/lib/cjs/components/OnBoardingWidget/OnBoardingWidget.js +69 -26
- package/lib/cjs/components/OnBoardingWidget/Steps/Appearance/Appearance.js +8 -4
- package/lib/cjs/components/OnBoardingWidget/Steps/Invite/Invite.js +56 -12
- package/lib/cjs/components/PlatformWidget/constants.d.ts +0 -4
- package/lib/cjs/components/PlatformWidget/constants.js +1 -5
- package/lib/cjs/components/UserSubscribedGroupsWidget/UserSubscribedGroupsWidget.js +7 -2
- package/lib/cjs/constants/GroupActionsMenu.d.ts +5 -0
- package/lib/cjs/constants/GroupActionsMenu.js +8 -0
- package/lib/cjs/constants/PubSub.d.ts +16 -1
- package/lib/cjs/constants/PubSub.js +11 -1
- package/lib/cjs/index.d.ts +4 -2
- package/lib/cjs/index.js +12 -5
- package/lib/cjs/shared/ContributionActionsMenu/index.js +6 -6
- package/lib/cjs/shared/InfiniteScroll/index.js +3 -3
- package/lib/cjs/shared/Media/Link/DisplayComponent.js +21 -5
- package/lib/cjs/utils/formatRelativeTime.js +2 -2
- package/lib/esm/components/BottomNavigation/BottomNavigation.js +11 -2
- package/lib/esm/components/Composer/Composer.js +10 -2
- package/lib/esm/components/Composer/Layer/AudienceLayer/AudienceLayer.js +13 -4
- package/lib/esm/components/CreateEventButton/CreateEventButton.js +5 -1
- package/lib/esm/components/CreateEventWidget/CreateEventWidget.js +5 -1
- package/lib/esm/components/EventForm/EventForm.d.ts +1 -1
- package/lib/esm/components/EventForm/EventForm.js +74 -56
- package/lib/esm/components/EventForm/constants.d.ts +4 -0
- package/lib/esm/components/EventForm/constants.js +4 -0
- package/lib/esm/components/EventForm/types.d.ts +1 -2
- package/lib/esm/components/EventForm/utils.d.ts +4 -0
- package/lib/esm/components/EventForm/utils.js +21 -0
- package/lib/esm/components/EventInfoWidget/EventInfoWidget.js +25 -2
- package/lib/esm/components/Events/Events.js +18 -8
- package/lib/esm/components/Events/LocationEventsFilter.d.ts +14 -0
- package/lib/esm/components/Events/LocationEventsFilter.js +41 -0
- package/lib/esm/components/Events/PastEventsFilter.js +1 -2
- package/lib/esm/components/Feed/Feed.js +14 -5
- package/lib/esm/components/GroupActionsMenu/index.d.ts +57 -0
- package/lib/esm/components/GroupActionsMenu/index.js +154 -0
- package/lib/esm/components/GroupHeader/GroupHeader.d.ts +6 -0
- package/lib/esm/components/GroupHeader/GroupHeader.js +9 -5
- package/lib/esm/components/Groups/Groups.js +27 -1
- package/lib/esm/components/MyEventsWidget/MyEventsWidget.js +7 -3
- package/lib/esm/components/NavigationMenuIconButton/NavigationMenuDrawer.d.ts +35 -0
- package/lib/esm/components/NavigationMenuIconButton/NavigationMenuDrawer.js +65 -0
- package/lib/esm/components/NavigationMenuIconButton/NavigationMenuIconButton.d.ts +9 -20
- package/lib/esm/components/NavigationMenuIconButton/NavigationMenuIconButton.js +11 -30
- package/lib/esm/components/NavigationMenuIconButton/index.d.ts +2 -1
- package/lib/esm/components/NavigationMenuIconButton/index.js +2 -1
- package/lib/esm/components/NavigationToolbar/NavigationToolbar.d.ts +5 -0
- package/lib/esm/components/NavigationToolbar/NavigationToolbar.js +14 -5
- package/lib/esm/components/NavigationToolbarMobile/NavigationToolbarMobile.js +11 -2
- package/lib/esm/components/Notification/Event/Event.js +4 -0
- package/lib/esm/components/OnBoardingWidget/OnBoardingWidget.d.ts +10 -1
- package/lib/esm/components/OnBoardingWidget/OnBoardingWidget.js +71 -28
- package/lib/esm/components/OnBoardingWidget/Steps/Appearance/Appearance.js +9 -5
- package/lib/esm/components/OnBoardingWidget/Steps/Invite/Invite.js +59 -14
- package/lib/esm/components/PlatformWidget/constants.d.ts +0 -4
- package/lib/esm/components/PlatformWidget/constants.js +0 -4
- package/lib/esm/components/UserSubscribedGroupsWidget/UserSubscribedGroupsWidget.js +8 -3
- package/lib/esm/constants/GroupActionsMenu.d.ts +5 -0
- package/lib/esm/constants/GroupActionsMenu.js +5 -0
- package/lib/esm/constants/PubSub.d.ts +16 -1
- package/lib/esm/constants/PubSub.js +10 -0
- package/lib/esm/index.d.ts +4 -2
- package/lib/esm/index.js +5 -3
- package/lib/esm/shared/ContributionActionsMenu/index.js +6 -6
- package/lib/esm/shared/InfiniteScroll/index.js +3 -3
- package/lib/esm/shared/Media/Link/DisplayComponent.js +21 -5
- package/lib/esm/utils/formatRelativeTime.js +2 -2
- package/lib/umd/148.js +2 -0
- package/lib/umd/react-ui.js +1 -1
- package/package.json +7 -7
- package/lib/umd/99.js +0 -2
- /package/lib/umd/{99.js.LICENSE.txt → 148.js.LICENSE.txt} +0 -0
|
@@ -3,8 +3,8 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
|
|
|
3
3
|
import React, { forwardRef, useContext, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
|
|
4
4
|
import { Link, SCCache, SCPreferences, SCPreferencesContext, SCUserContext, useIsComponentMountedRef, usePreviousValue, useSCFetchFeed } from '@selfcommunity/react-core';
|
|
5
5
|
import { styled, useTheme } from '@mui/material/styles';
|
|
6
|
-
import { Box, CardContent, Grid, Hidden, useMediaQuery } from '@mui/material';
|
|
7
|
-
import { FormattedMessage } from 'react-intl';
|
|
6
|
+
import { Box, Button, CardContent, Grid, Hidden, Typography, useMediaQuery } from '@mui/material';
|
|
7
|
+
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
|
8
8
|
import { GenericSkeleton } from '../Skeleton';
|
|
9
9
|
import CustomAdv from '../CustomAdv';
|
|
10
10
|
import { SCCustomAdvPosition } from '@selfcommunity/types';
|
|
@@ -23,11 +23,18 @@ import FeedSkeleton from './Skeleton';
|
|
|
23
23
|
import { useDeepCompareEffectNoCheck } from 'use-deep-compare-effect';
|
|
24
24
|
import StickyBoxComp from '../../shared/StickyBox';
|
|
25
25
|
import { PREFIX } from './constants';
|
|
26
|
+
const messages = defineMessages({
|
|
27
|
+
refresh: {
|
|
28
|
+
id: 'ui.feed.refreshRelease',
|
|
29
|
+
defaultMessage: 'ui.feed.refreshRelease'
|
|
30
|
+
}
|
|
31
|
+
});
|
|
26
32
|
const classes = {
|
|
27
33
|
root: `${PREFIX}-root`,
|
|
28
34
|
left: `${PREFIX}-left`,
|
|
29
35
|
leftItems: `${PREFIX}-left-items`,
|
|
30
36
|
start: `${PREFIX}-start`,
|
|
37
|
+
headerItem: `${PREFIX}-header-item`,
|
|
31
38
|
end: `${PREFIX}-end`,
|
|
32
39
|
endMessage: `${PREFIX}-end-message`,
|
|
33
40
|
right: `${PREFIX}-right`,
|
|
@@ -75,7 +82,9 @@ const Feed = (inProps, ref) => {
|
|
|
75
82
|
props: inProps,
|
|
76
83
|
name: PREFIX
|
|
77
84
|
});
|
|
78
|
-
|
|
85
|
+
// HOOKS
|
|
86
|
+
const intl = useIntl();
|
|
87
|
+
const { id = 'feed', className, endpoint, endpointQueryParams = { limit: DEFAULT_PAGINATION_LIMIT, offset: DEFAULT_PAGINATION_OFFSET }, endMessage = _jsx(FormattedMessage, { id: "ui.feed.noOtherFeedObject", defaultMessage: "ui.feed.noOtherFeedObject" }), refreshMessage = _jsx(Typography, { dangerouslySetInnerHTML: { __html: `${intl.formatMessage(messages.refresh)}` } }), HeaderComponent, FooterComponent = Footer, FooterComponentProps = {}, widgets = [], ItemComponent, itemPropsGenerator, itemIdGenerator, ItemProps = {}, ItemSkeleton, ItemSkeletonProps = {}, onNextData, onPreviousData, FeedSidebarProps = {}, CustomAdvProps = {}, enabledCustomAdvPositions = [SCCustomAdvPosition.POSITION_FEED_SIDEBAR, SCCustomAdvPosition.POSITION_FEED], requireAuthentication = false, cacheStrategy = CacheStrategies.NETWORK_ONLY, prefetchedData, scrollableTargetId, VirtualizedScrollerProps = {}, disablePaginationLinks = false, hidePaginationLinks = true, paginationLinksPageQueryParam = DEFAULT_PAGINATION_QUERY_PARAM_NAME, PaginationLinkProps = {}, hideAdvs = false, emptyFeedPlaceholder } = props;
|
|
79
88
|
// CONTEXT
|
|
80
89
|
const scPreferences = useContext(SCPreferencesContext);
|
|
81
90
|
const scUserContext = useContext(SCUserContext);
|
|
@@ -282,7 +291,7 @@ const Feed = (inProps, ref) => {
|
|
|
282
291
|
const renderHeaderComponent = () => {
|
|
283
292
|
return (_jsx(Box, Object.assign({ className: classes.start }, { children: !feedDataObject.previous && (_jsxs(_Fragment, { children: [virtualScrollerMountState.current && HeaderComponent, headData.map((item) => {
|
|
284
293
|
const _itemId = `item_${itemIdGenerator(item)}`;
|
|
285
|
-
return (_jsx(ItemComponent, Object.assign({ id: _itemId }, itemPropsGenerator(scUserContext.user, item), ItemProps, { sx: { width: '100%' } }), _itemId));
|
|
294
|
+
return (_jsx(ItemComponent, Object.assign({ className: classes.headerItem, id: _itemId }, itemPropsGenerator(scUserContext.user, item), ItemProps, { sx: { width: '100%' } }), _itemId));
|
|
286
295
|
})] })) })));
|
|
287
296
|
};
|
|
288
297
|
/**
|
|
@@ -408,6 +417,6 @@ const Feed = (inProps, ref) => {
|
|
|
408
417
|
if (feedDataObject.isLoadingNext && !feedDataLeft.length) {
|
|
409
418
|
return (_jsx(FeedSkeleton, { children: [...Array(3)].map((v, i) => (_jsx(ItemSkeleton, Object.assign({}, ItemSkeletonProps), i))) }));
|
|
410
419
|
}
|
|
411
|
-
return (_jsxs(Root, Object.assign({ container: true, spacing: 2, id: id, className: classNames(classes.root, className) }, { children: [advEnabled && !hideAdvs && enabledCustomAdvPositions.includes(SCCustomAdvPosition.POSITION_BELOW_TOPBAR) ? (_jsx(Grid, Object.assign({ item: true, xs: 12 }, { children: _jsx(CustomAdv, Object.assign({ position: SCCustomAdvPosition.POSITION_BELOW_TOPBAR }, CustomAdvProps)) }))) : null, _jsx(Grid, Object.assign({ item: true, xs: 12, md: 7 }, { children: _jsxs(InfiniteScroll, Object.assign({ ref: containerRef, className: classes.left, dataLength: feedDataLeft.length, next: getNextPage, previous: getPreviousPage, hasMoreNext: Boolean(feedDataObject.next), hasMorePrevious: Boolean(feedDataObject.previous), header: PreviousPageLink, footer: NextPageLink, loaderNext: _jsx(ItemSkeleton, Object.assign({}, ItemSkeletonProps)), loaderPrevious: _jsx(ItemSkeleton, Object.assign({}, ItemSkeletonProps)), scrollThreshold: '90%', endMessage: _jsxs(Box, Object.assign({ className: classes.end }, { children: [_jsx(Widget, Object.assign({ className: classes.endMessage }, { children: _jsx(CardContent, { children: endMessage }) })), FooterComponent ? _jsx(FooterComponent, Object.assign({}, FooterComponentProps)) : null] })), refreshFunction: refresh, pullDownToRefresh: true, pullDownToRefreshThreshold: 1000, pullDownToRefreshContent: null, releaseToRefreshContent: _jsx(
|
|
420
|
+
return (_jsxs(Root, Object.assign({ container: true, spacing: 2, id: id, className: classNames(classes.root, className) }, { children: [advEnabled && !hideAdvs && enabledCustomAdvPositions.includes(SCCustomAdvPosition.POSITION_BELOW_TOPBAR) ? (_jsx(Grid, Object.assign({ item: true, xs: 12 }, { children: _jsx(CustomAdv, Object.assign({ position: SCCustomAdvPosition.POSITION_BELOW_TOPBAR }, CustomAdvProps)) }))) : null, _jsx(Grid, Object.assign({ item: true, xs: 12, md: 7 }, { children: _jsxs(InfiniteScroll, Object.assign({ ref: containerRef, className: classes.left, dataLength: feedDataLeft.length, next: getNextPage, previous: getPreviousPage, hasMoreNext: Boolean(feedDataObject.next), hasMorePrevious: Boolean(feedDataObject.previous), header: PreviousPageLink, footer: NextPageLink, loaderNext: _jsx(ItemSkeleton, Object.assign({}, ItemSkeletonProps)), loaderPrevious: _jsx(ItemSkeleton, Object.assign({}, ItemSkeletonProps)), scrollThreshold: '90%', endMessage: _jsxs(Box, Object.assign({ className: classes.end }, { children: [_jsx(Widget, Object.assign({ className: classes.endMessage }, { children: _jsx(CardContent, { children: endMessage }) })), FooterComponent ? _jsx(FooterComponent, Object.assign({}, FooterComponentProps)) : null] })), refreshFunction: refresh, pullDownToRefresh: true, pullDownToRefreshThreshold: 1000, pullDownToRefreshContent: null, releaseToRefreshContent: _jsx(Button, Object.assign({ color: "secondary", variant: "contained", className: classes.refresh }, { children: refreshMessage })), style: { overflow: 'visible' } }, (scrollableTargetId && { scrollableTarget: scrollableTargetId }), { children: [renderHeaderComponent(), feedDataObject.count === 0 && emptyFeedPlaceholder && emptyFeedPlaceholder, _jsx(VirtualizedScroller, Object.assign({ className: classes.leftItems, items: feedDataLeft, itemComponent: InnerItem, onMount: onScrollerMount, onScrollerStateChange: onScrollerStateChange, getItemId: getScrollItemId, preserveScrollPosition: true, preserveScrollPositionOnPrependItems: true, cacheScrollStateKey: SCCache.getVirtualizedScrollStateCacheKey(id), cacheScrollerPositionKey: SCCache.getFeedSPCacheKey(id), cacheStrategy: cacheStrategy }, (scrollableTargetId && { getScrollableContainer: () => document.getElementById(scrollableTargetId) }), VirtualizedScrollerProps))] })) })), feedDataRight.length > 0 && !hideAdvs && (_jsx(Hidden, Object.assign({ smDown: true }, { children: _jsx(Grid, Object.assign({ item: true, xs: 12, md: 5 }, { children: _jsx(StickyBoxComp, Object.assign({ className: classes.right }, FeedSidebarProps, { children: _jsx(React.Suspense, Object.assign({ fallback: _jsx(GenericSkeleton, {}) }, { children: feedDataRight.map((d, i) => (_jsx(d.component, Object.assign({}, d.componentProps), i))) })) })) })) })))] })));
|
|
412
421
|
};
|
|
413
422
|
export default forwardRef(Feed);
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { IconButtonProps } from '@mui/material';
|
|
2
|
+
import { SCGroupType } from '@selfcommunity/types';
|
|
3
|
+
export interface GroupActionsMenuProps extends IconButtonProps {
|
|
4
|
+
/**
|
|
5
|
+
* Overrides or extends the styles applied to the component.
|
|
6
|
+
* @default null
|
|
7
|
+
*/
|
|
8
|
+
className?: string;
|
|
9
|
+
/**
|
|
10
|
+
* The group
|
|
11
|
+
*/
|
|
12
|
+
group: SCGroupType;
|
|
13
|
+
/**
|
|
14
|
+
* The group id
|
|
15
|
+
*/
|
|
16
|
+
groupId?: number;
|
|
17
|
+
/**
|
|
18
|
+
* Handles callback on delete confirm
|
|
19
|
+
*/
|
|
20
|
+
onDeleteConfirm?: () => void;
|
|
21
|
+
/**
|
|
22
|
+
* Handles on edit success
|
|
23
|
+
*/
|
|
24
|
+
onEditSuccess?: (data: SCGroupType) => any;
|
|
25
|
+
/**
|
|
26
|
+
* Any other properties
|
|
27
|
+
*/
|
|
28
|
+
[p: string]: any;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* > API documentation for the Community-JS GroupActionsMenu component. Learn about the available props and the CSS API.
|
|
32
|
+
|
|
33
|
+
#### Import
|
|
34
|
+
|
|
35
|
+
```jsx
|
|
36
|
+
import {GroupActionsMenu} from '@selfcommunity/react-ui';
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
#### Component Name
|
|
40
|
+
|
|
41
|
+
The name `SCGroupActionsMenu` can be used when providing style overrides in the theme.
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
#### CSS
|
|
45
|
+
|
|
46
|
+
|Rule Name|Global class|Description|
|
|
47
|
+
|---|---|---|
|
|
48
|
+
|root|.SCGroupActionsMenu-root|Styles applied to the root element.|
|
|
49
|
+
|drawerRoot|.SCGroupActionsMenu-drawer-root|Styles applied to the drawer root element.|
|
|
50
|
+
|menuRoot|.SCGroupActionsMenu-menu-root|Styles applied to the menu root element.|
|
|
51
|
+
|paper|.SCGroupActionsMenu-paper|Styles applied to the paper element.|
|
|
52
|
+
|item|.SCGroupActionsMenu-item|Styles applied to the item element.|
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
* @param inProps
|
|
56
|
+
*/
|
|
57
|
+
export default function GroupActionsMenu(inProps: GroupActionsMenuProps): JSX.Element;
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { __rest } from "tslib";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { useMemo, useState } from 'react';
|
|
4
|
+
import { styled } from '@mui/material/styles';
|
|
5
|
+
import { Divider, IconButton, List, ListItemIcon, Menu, MenuItem, SwipeableDrawer, useMediaQuery, useTheme } from '@mui/material';
|
|
6
|
+
import { FormattedMessage } from 'react-intl';
|
|
7
|
+
import Icon from '@mui/material/Icon';
|
|
8
|
+
import classNames from 'classnames';
|
|
9
|
+
import { useThemeProps } from '@mui/system';
|
|
10
|
+
import { SCRoutes, useSCFetchGroup, useSCRouting, useSCUser } from '@selfcommunity/react-core';
|
|
11
|
+
import ConfirmDialog from '../../shared/ConfirmDialog/ConfirmDialog';
|
|
12
|
+
import { GroupService } from '@selfcommunity/api-services';
|
|
13
|
+
import { copyTextToClipboard } from '@selfcommunity/utils';
|
|
14
|
+
import { enqueueSnackbar } from 'notistack';
|
|
15
|
+
import PubSub from 'pubsub-js';
|
|
16
|
+
import { SCGroupEventType, SCTopicType } from '../../constants/PubSub';
|
|
17
|
+
import GroupForm from '../../components/GroupForm';
|
|
18
|
+
import { DELETE_GROUP, GET_GROUP_LINK } from '../../constants/GroupActionsMenu';
|
|
19
|
+
const PREFIX = 'SCGroupActionsMenu';
|
|
20
|
+
const classes = {
|
|
21
|
+
root: `${PREFIX}-root`,
|
|
22
|
+
drawerRoot: `${PREFIX}-drawer-root`,
|
|
23
|
+
menuRoot: `${PREFIX}-menu-root`,
|
|
24
|
+
paper: `${PREFIX}-paper`,
|
|
25
|
+
item: `${PREFIX}-item`
|
|
26
|
+
};
|
|
27
|
+
const Root = styled(IconButton, {
|
|
28
|
+
name: PREFIX,
|
|
29
|
+
slot: 'Root'
|
|
30
|
+
})(() => ({}));
|
|
31
|
+
const SwipeableDrawerRoot = styled(SwipeableDrawer, {
|
|
32
|
+
name: PREFIX,
|
|
33
|
+
slot: 'DrawerRoot'
|
|
34
|
+
})(() => ({}));
|
|
35
|
+
const MenuRoot = styled(Menu, {
|
|
36
|
+
name: PREFIX,
|
|
37
|
+
slot: 'MenuRoot'
|
|
38
|
+
})(() => ({}));
|
|
39
|
+
/**
|
|
40
|
+
* > API documentation for the Community-JS GroupActionsMenu component. Learn about the available props and the CSS API.
|
|
41
|
+
|
|
42
|
+
#### Import
|
|
43
|
+
|
|
44
|
+
```jsx
|
|
45
|
+
import {GroupActionsMenu} from '@selfcommunity/react-ui';
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
#### Component Name
|
|
49
|
+
|
|
50
|
+
The name `SCGroupActionsMenu` can be used when providing style overrides in the theme.
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
#### CSS
|
|
54
|
+
|
|
55
|
+
|Rule Name|Global class|Description|
|
|
56
|
+
|---|---|---|
|
|
57
|
+
|root|.SCGroupActionsMenu-root|Styles applied to the root element.|
|
|
58
|
+
|drawerRoot|.SCGroupActionsMenu-drawer-root|Styles applied to the drawer root element.|
|
|
59
|
+
|menuRoot|.SCGroupActionsMenu-menu-root|Styles applied to the menu root element.|
|
|
60
|
+
|paper|.SCGroupActionsMenu-paper|Styles applied to the paper element.|
|
|
61
|
+
|item|.SCGroupActionsMenu-item|Styles applied to the item element.|
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
* @param inProps
|
|
65
|
+
*/
|
|
66
|
+
export default function GroupActionsMenu(inProps) {
|
|
67
|
+
var _a;
|
|
68
|
+
// PROPS
|
|
69
|
+
const props = useThemeProps({
|
|
70
|
+
props: inProps,
|
|
71
|
+
name: PREFIX
|
|
72
|
+
});
|
|
73
|
+
const { className, group, groupId, onDeleteConfirm, onEditSuccess } = props, rest = __rest(props, ["className", "group", "groupId", "onDeleteConfirm", "onEditSuccess"]);
|
|
74
|
+
// STATE
|
|
75
|
+
const [anchorEl, setAnchorEl] = useState(null);
|
|
76
|
+
const [openConfirmDialog, setOpenConfirmDialog] = useState(false);
|
|
77
|
+
const [openEdit, setOpenEdit] = useState(false);
|
|
78
|
+
// HOOKS
|
|
79
|
+
const theme = useTheme();
|
|
80
|
+
const isMobile = useMediaQuery(theme.breakpoints.down('md'));
|
|
81
|
+
const scRoutingContext = useSCRouting();
|
|
82
|
+
const scUserContext = useSCUser();
|
|
83
|
+
const { scGroup, setSCGroup } = useSCFetchGroup({ id: groupId, group });
|
|
84
|
+
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]);
|
|
85
|
+
// HANDLERS
|
|
86
|
+
const handleOpen = (group) => {
|
|
87
|
+
setAnchorEl(group.currentTarget);
|
|
88
|
+
};
|
|
89
|
+
const handleClose = () => {
|
|
90
|
+
setAnchorEl(null);
|
|
91
|
+
};
|
|
92
|
+
const handleEditClick = () => {
|
|
93
|
+
setOpenEdit((o) => !o);
|
|
94
|
+
};
|
|
95
|
+
const handleCloseDialog = () => {
|
|
96
|
+
setOpenConfirmDialog(false);
|
|
97
|
+
setAnchorEl(null);
|
|
98
|
+
};
|
|
99
|
+
const handleEditSuccess = (data) => {
|
|
100
|
+
setSCGroup(data);
|
|
101
|
+
onEditSuccess && onEditSuccess(data);
|
|
102
|
+
};
|
|
103
|
+
/**
|
|
104
|
+
* Handles thread deletion
|
|
105
|
+
*/
|
|
106
|
+
function handleDeleteThread() {
|
|
107
|
+
GroupService.deleteGroup(scGroup.id)
|
|
108
|
+
.then(() => {
|
|
109
|
+
onDeleteConfirm();
|
|
110
|
+
handleCloseDialog();
|
|
111
|
+
PubSub.publish(`${SCTopicType.GROUP}.${SCGroupEventType.DELETE}`, scGroup.id);
|
|
112
|
+
})
|
|
113
|
+
.catch((error) => {
|
|
114
|
+
setOpenConfirmDialog(false);
|
|
115
|
+
console.log(error);
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Handles actions
|
|
120
|
+
*/
|
|
121
|
+
function handleAction(action) {
|
|
122
|
+
if (action === GET_GROUP_LINK) {
|
|
123
|
+
copyTextToClipboard(`${location.protocol}//${location.host}${scRoutingContext.url(SCRoutes.GROUP_ROUTE_NAME, scGroup)}`).then(() => {
|
|
124
|
+
enqueueSnackbar(_jsx(FormattedMessage, { id: "ui.common.permanentLinkCopied", defaultMessage: "ui.common.permanentLinkCopied" }), {
|
|
125
|
+
variant: 'success',
|
|
126
|
+
autoHideDuration: 3000
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
handleClose();
|
|
130
|
+
}
|
|
131
|
+
else if (action === DELETE_GROUP) {
|
|
132
|
+
setOpenConfirmDialog(true);
|
|
133
|
+
handleClose();
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
*
|
|
138
|
+
*/
|
|
139
|
+
const renderList = () => {
|
|
140
|
+
return [
|
|
141
|
+
_jsxs(MenuItem, Object.assign({ className: classes.item, onClick: () => handleAction(GET_GROUP_LINK) }, { children: [_jsx(ListItemIcon, { children: _jsx(Icon, { children: "link" }) }), _jsx(FormattedMessage, { id: "ui.groupActionsMenu.item.link", defaultMessage: "ui.groupActionsMenu.item.link" })] }), "link"),
|
|
142
|
+
isGroupAdmin &&
|
|
143
|
+
scGroup.active && [
|
|
144
|
+
_jsx(Divider, {}, "divider"),
|
|
145
|
+
isMobile && (_jsxs(MenuItem, Object.assign({ className: classes.item, onClick: handleEditClick }, { children: [_jsx(ListItemIcon, { children: _jsx(Icon, { children: "edit" }) }), _jsx(FormattedMessage, { id: "ui.groupActionsMenu.item.edit", defaultMessage: "ui.groupActionsMenu.item.edit" })] }), "edit")),
|
|
146
|
+
_jsxs(MenuItem, Object.assign({ className: classes.item, onClick: () => handleAction(DELETE_GROUP) }, { children: [_jsx(ListItemIcon, { children: _jsx(Icon, { children: "delete" }) }), _jsx(FormattedMessage, { id: "ui.groupActionsMenu.item.delete", defaultMessage: "ui.groupActionsMenu.item.delete" })] }), "delete")
|
|
147
|
+
]
|
|
148
|
+
];
|
|
149
|
+
};
|
|
150
|
+
if (!scGroup) {
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
return (_jsxs(_Fragment, { children: [_jsx(Root, Object.assign({ className: classNames(classes.root, className) }, rest, { onClick: handleOpen }, { children: _jsx(Icon, { children: "more_vert" }) })), isMobile ? (_jsx(SwipeableDrawerRoot, Object.assign({ className: classes.drawerRoot, anchor: "bottom", open: Boolean(anchorEl), onClose: handleClose, onOpen: handleOpen, PaperProps: { className: classes.paper }, disableSwipeToOpen: true }, { children: _jsx(List, { children: renderList() }) }))) : (_jsx(MenuRoot, Object.assign({ className: classes.menuRoot, anchorEl: anchorEl, open: Boolean(anchorEl), onClose: handleClose, PaperProps: { className: classes.paper } }, { children: renderList() }))), openConfirmDialog && (_jsx(ConfirmDialog, { open: openConfirmDialog, title: _jsx(FormattedMessage, { id: "ui.groupActionsMenu.dialog.msg", defaultMessage: "ui.groupActionsMenu.dialog.msg" }), btnConfirm: _jsx(FormattedMessage, { id: "ui.groupActionsMenu.dialog.confirm", defaultMessage: "ui.groupActionsMenu.dialog.confirm" }), onConfirm: handleDeleteThread, onClose: handleCloseDialog })), openEdit && _jsx(GroupForm, { onClose: handleEditClick, group: scGroup, onSuccess: handleEditSuccess })] }));
|
|
154
|
+
}
|
|
@@ -3,6 +3,7 @@ import { ChangeGroupCoverProps } from '../ChangeGroupCover';
|
|
|
3
3
|
import { ChangeGroupPictureProps } from '../ChangeGroupPicture';
|
|
4
4
|
import { GroupMembersButtonProps } from '../GroupMembersButton';
|
|
5
5
|
import { GroupSubscribeButtonProps } from '../GroupSubscribeButton';
|
|
6
|
+
import { GroupActionsMenuProps } from '../GroupActionsMenu';
|
|
6
7
|
export interface GroupHeaderProps {
|
|
7
8
|
/**
|
|
8
9
|
* Id of group object
|
|
@@ -44,6 +45,11 @@ export interface GroupHeaderProps {
|
|
|
44
45
|
* @default {}
|
|
45
46
|
*/
|
|
46
47
|
GroupMembersButtonProps?: GroupMembersButtonProps;
|
|
48
|
+
/**
|
|
49
|
+
* Props to spread event actions menu
|
|
50
|
+
* @default {}
|
|
51
|
+
*/
|
|
52
|
+
GroupActionsProps?: Omit<GroupActionsMenuProps, 'group'>;
|
|
47
53
|
/**
|
|
48
54
|
* Any other properties
|
|
49
55
|
*/
|
|
@@ -2,7 +2,7 @@ import { __rest } from "tslib";
|
|
|
2
2
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useCallback, useEffect, useMemo, useRef } from 'react';
|
|
4
4
|
import { styled } from '@mui/material/styles';
|
|
5
|
-
import { Avatar, Box, Icon, Paper, Typography } from '@mui/material';
|
|
5
|
+
import { Avatar, Box, Icon, Paper, Typography, useMediaQuery, useTheme } from '@mui/material';
|
|
6
6
|
import { SCGroupPrivacyType, SCGroupSubscriptionStatusType } from '@selfcommunity/types';
|
|
7
7
|
import { SCPreferences, useSCFetchGroup, useSCPreferences, useSCUser } from '@selfcommunity/react-core';
|
|
8
8
|
import GroupHeaderSkeleton from './Skeleton';
|
|
@@ -19,6 +19,7 @@ import GroupSubscribeButton from '../GroupSubscribeButton';
|
|
|
19
19
|
import GroupInviteButton from '../GroupInviteButton';
|
|
20
20
|
import { SCGroupEventType, SCTopicType } from '../../constants/PubSub';
|
|
21
21
|
import PubSub from 'pubsub-js';
|
|
22
|
+
import GroupActionsMenu from '../GroupActionsMenu';
|
|
22
23
|
const classes = {
|
|
23
24
|
root: `${PREFIX}-root`,
|
|
24
25
|
cover: `${PREFIX}-cover`,
|
|
@@ -30,7 +31,8 @@ const classes = {
|
|
|
30
31
|
visibility: `${PREFIX}-visibility`,
|
|
31
32
|
visibilityItem: `${PREFIX}-visibility-item`,
|
|
32
33
|
members: `${PREFIX}-members`,
|
|
33
|
-
membersCounter: `${PREFIX}-members-counter
|
|
34
|
+
membersCounter: `${PREFIX}-members-counter`,
|
|
35
|
+
multiActions: `${PREFIX}-multi-actions`
|
|
34
36
|
};
|
|
35
37
|
const Root = styled(Box, {
|
|
36
38
|
name: PREFIX,
|
|
@@ -74,7 +76,7 @@ export default function GroupHeader(inProps) {
|
|
|
74
76
|
props: inProps,
|
|
75
77
|
name: PREFIX
|
|
76
78
|
});
|
|
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"]);
|
|
79
|
+
const { id = null, className = null, group, groupId = null, ChangePictureProps = {}, ChangeCoverProps = {}, GroupSubscribeButtonProps = {}, GroupMembersButtonProps = {}, GroupActionsProps } = props, rest = __rest(props, ["id", "className", "group", "groupId", "ChangePictureProps", "ChangeCoverProps", "GroupSubscribeButtonProps", "GroupMembersButtonProps", "GroupActionsProps"]);
|
|
78
80
|
// PREFERENCES
|
|
79
81
|
const scPreferences = useSCPreferences();
|
|
80
82
|
const visibilityEnabled = useMemo(() => scPreferences.preferences[SCPreferences.CONFIGURATIONS_GROUPS_VISIBILITY_ENABLED].value, [scPreferences.preferences]);
|
|
@@ -83,6 +85,8 @@ export default function GroupHeader(inProps) {
|
|
|
83
85
|
const scUserContext = useSCUser();
|
|
84
86
|
// HOOKS
|
|
85
87
|
const { scGroup, setSCGroup } = useSCFetchGroup({ id: groupId, group });
|
|
88
|
+
const theme = useTheme();
|
|
89
|
+
const isMobile = useMediaQuery(theme.breakpoints.down('md'));
|
|
86
90
|
// REFS
|
|
87
91
|
const updatesSubscription = useRef(null);
|
|
88
92
|
// CONST
|
|
@@ -145,7 +149,7 @@ export default function GroupHeader(inProps) {
|
|
|
145
149
|
const _backgroundCover = Object.assign({}, (scGroup.emotional_image
|
|
146
150
|
? { background: `url('${scGroup.emotional_image}') center / cover` }
|
|
147
151
|
: { background: `url('${scPreferences.preferences[SCPreferences.IMAGES_USER_DEFAULT_COVER].value}') center / cover` }));
|
|
148
|
-
return (_jsxs(Root, Object.assign({ id: id, className: classNames(classes.root, className) }, rest, { children: [_jsxs(Paper, Object.assign({ style: _backgroundCover, classes: { root: classes.cover } }, { children: [_jsx(Box, Object.assign({ className: classes.avatar }, { children: _jsx(Avatar, { children: _jsx("img", { alt: "group", src: scGroup.image_big ? scGroup.image_big : '' }) }) })), isGroupAdmin && (_jsxs(_Fragment, { children: [_jsx(ChangeGroupPicture, Object.assign({ groupId: scGroup.id, onChange: handleChangeAvatar, className: classes.changePicture }, ChangePictureProps)), _jsx("div", Object.assign({ className: classes.changeCover }, { children: _jsx(ChangeGroupCover, Object.assign({ groupId: scGroup.id, onChange: handleChangeCover }, ChangeCoverProps)) }))] }))] })), _jsxs(Box, Object.assign({ className: classes.info }, { children: [isGroupAdmin && _jsx(EditGroupButton, { group: scGroup, groupId: scGroup.id, onEditSuccess: (data) => setSCGroup(data) }), _jsx(Typography, Object.assign({ variant: "h5", className: classes.name }, { children: scGroup.name })), privateEnabled && (_jsxs(Box, Object.assign({ className: classes.visibility }, { children: [privateEnabled && (_jsx(_Fragment, { children: scGroup.privacy === SCGroupPrivacyType.PUBLIC ? (_jsxs(Typography, Object.assign({ className: classes.visibilityItem }, { children: [_jsx(Icon, { children: "public" }), _jsx(FormattedMessage, { id: "ui.groupHeader.visibility.public", defaultMessage: "ui.groupHeader.visibility.public" })] }))) : (_jsxs(Typography, Object.assign({ className: classes.visibilityItem }, { children: [_jsx(Icon, { children: "private" }), _jsx(FormattedMessage, { id: "ui.groupHeader.visibility.private", defaultMessage: "ui.groupHeader.visibility.private" })] }))) })), visibilityEnabled && (_jsxs(_Fragment, { children: [privateEnabled && _jsx(Bullet, {}), scGroup.visible ? (_jsxs(Typography, Object.assign({ className: classes.visibilityItem }, { children: [_jsx(Icon, { children: "visibility" }), _jsx(FormattedMessage, { id: "ui.groupHeader.visibility.visible", defaultMessage: "ui.groupHeader.visibility.visible" })] }))) : (_jsxs(Typography, Object.assign({ className: classes.visibilityItem }, { children: [_jsx(Icon, { children: "visibility_off" }), _jsx(FormattedMessage, { id: "ui.groupHeader.visibility.hidden", defaultMessage: "ui.groupHeader.visibility.hidden" })] })))] }))] }))), _jsx(_Fragment, { children: ((scGroup && scGroup.privacy === SCGroupPrivacyType.PUBLIC) ||
|
|
152
|
+
return (_jsxs(Root, Object.assign({ id: id, className: classNames(classes.root, className) }, rest, { children: [_jsxs(Paper, Object.assign({ style: _backgroundCover, classes: { root: classes.cover } }, { children: [_jsx(Box, Object.assign({ className: classes.avatar }, { children: _jsx(Avatar, { children: _jsx("img", { alt: "group", src: scGroup.image_big ? scGroup.image_big : '' }) }) })), isGroupAdmin && (_jsxs(_Fragment, { children: [_jsx(ChangeGroupPicture, Object.assign({ groupId: scGroup.id, onChange: handleChangeAvatar, className: classes.changePicture }, ChangePictureProps)), _jsx("div", Object.assign({ className: classes.changeCover }, { children: _jsx(ChangeGroupCover, Object.assign({ groupId: scGroup.id, onChange: handleChangeCover }, ChangeCoverProps)) }))] }))] })), _jsxs(Box, Object.assign({ className: classes.info }, { children: [isGroupAdmin && !isMobile && (_jsxs(Box, Object.assign({ className: classes.multiActions }, { children: [_jsx(EditGroupButton, { group: scGroup, groupId: scGroup.id, onEditSuccess: (data) => setSCGroup(data) }), _jsx(GroupActionsMenu, Object.assign({ group: scGroup, onEditSuccess: (data) => setSCGroup(data) }, GroupActionsProps))] }))), _jsx(Typography, Object.assign({ variant: "h5", className: classes.name }, { children: scGroup.name })), privateEnabled && (_jsxs(Box, Object.assign({ className: classes.visibility }, { children: [privateEnabled && (_jsx(_Fragment, { children: scGroup.privacy === SCGroupPrivacyType.PUBLIC ? (_jsxs(Typography, Object.assign({ className: classes.visibilityItem }, { children: [_jsx(Icon, { children: "public" }), _jsx(FormattedMessage, { id: "ui.groupHeader.visibility.public", defaultMessage: "ui.groupHeader.visibility.public" })] }))) : (_jsxs(Typography, Object.assign({ className: classes.visibilityItem }, { children: [_jsx(Icon, { children: "private" }), _jsx(FormattedMessage, { id: "ui.groupHeader.visibility.private", defaultMessage: "ui.groupHeader.visibility.private" })] }))) })), visibilityEnabled && (_jsxs(_Fragment, { children: [privateEnabled && _jsx(Bullet, {}), scGroup.visible ? (_jsxs(Typography, Object.assign({ className: classes.visibilityItem }, { children: [_jsx(Icon, { children: "visibility" }), _jsx(FormattedMessage, { id: "ui.groupHeader.visibility.visible", defaultMessage: "ui.groupHeader.visibility.visible" })] }))) : (_jsxs(Typography, Object.assign({ className: classes.visibilityItem }, { children: [_jsx(Icon, { children: "visibility_off" }), _jsx(FormattedMessage, { id: "ui.groupHeader.visibility.hidden", defaultMessage: "ui.groupHeader.visibility.hidden" })] })))] }))] }))), _jsx(_Fragment, { children: ((scGroup && scGroup.privacy === SCGroupPrivacyType.PUBLIC) ||
|
|
149
153
|
scGroup.subscription_status === SCGroupSubscriptionStatusType.SUBSCRIBED ||
|
|
150
|
-
isGroupAdmin) && (_jsxs(Box, Object.assign({ className: classes.members }, { children: [_jsx(Typography, Object.assign({ className: classes.membersCounter, component: "div" }, { children: _jsx(FormattedMessage, { id: "ui.groupHeader.members", defaultMessage: "ui.groupHeader.members", values: { total: scGroup.subscribers_counter } }) })), _jsx(GroupMembersButton, Object.assign({ groupId: scGroup === null || scGroup === void 0 ? void 0 : scGroup.id, group: scGroup, autoHide: !isGroupAdmin }, GroupMembersButtonProps), scGroup.subscribers_counter)] }))) }), isGroupAdmin ? (_jsx(GroupInviteButton, { group: scGroup, groupId: scGroup.id })) : (_jsx(GroupSubscribeButton, Object.assign({ group: scGroup, onSubscribe: handleSubscribe }, GroupSubscribeButtonProps)))] }))] })));
|
|
154
|
+
isGroupAdmin) && (_jsxs(Box, Object.assign({ className: classes.members }, { children: [_jsx(Typography, Object.assign({ className: classes.membersCounter, component: "div" }, { children: _jsx(FormattedMessage, { id: "ui.groupHeader.members", defaultMessage: "ui.groupHeader.members", values: { total: scGroup.subscribers_counter } }) })), _jsx(GroupMembersButton, Object.assign({ groupId: scGroup === null || scGroup === void 0 ? void 0 : scGroup.id, group: scGroup, autoHide: !isGroupAdmin }, GroupMembersButtonProps), scGroup.subscribers_counter)] }))) }), isGroupAdmin ? (_jsxs(Box, { children: [_jsx(GroupInviteButton, { group: scGroup, groupId: scGroup.id }), isMobile && _jsx(GroupActionsMenu, Object.assign({ group: scGroup, onEditSuccess: (data) => setSCGroup(data) }, GroupActionsProps))] })) : (_jsx(GroupSubscribeButton, Object.assign({ group: scGroup, onSubscribe: handleSubscribe }, GroupSubscribeButtonProps)))] }))] })));
|
|
151
155
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { __rest } from "tslib";
|
|
2
2
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useEffect, useMemo, useState } from 'react';
|
|
3
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
4
4
|
import { styled } from '@mui/material/styles';
|
|
5
5
|
import { Box, Button, Grid, TextField, Typography, useMediaQuery, useTheme } from '@mui/material';
|
|
6
6
|
import { Endpoints, GroupService, http } from '@selfcommunity/api-services';
|
|
@@ -16,6 +16,8 @@ import { PREFIX } from './constants';
|
|
|
16
16
|
import Group, { GroupSkeleton } from '../Group';
|
|
17
17
|
import { DEFAULT_PAGINATION_OFFSET } from '../../constants/Pagination';
|
|
18
18
|
import InfiniteScroll from '../../shared/InfiniteScroll';
|
|
19
|
+
import PubSub from 'pubsub-js';
|
|
20
|
+
import { SCGroupEventType, SCTopicType } from '../../constants/PubSub';
|
|
19
21
|
const classes = {
|
|
20
22
|
root: `${PREFIX}-root`,
|
|
21
23
|
filters: `${PREFIX}-filter`,
|
|
@@ -83,6 +85,8 @@ export default function Groups(inProps) {
|
|
|
83
85
|
scPreferencesContext.preferences[SCPreferences.CONFIGURATIONS_CONTENT_AVAILABILITY].value, [scPreferencesContext.preferences]);
|
|
84
86
|
// CONST
|
|
85
87
|
const authUserId = scUserContext.user ? scUserContext.user.id : null;
|
|
88
|
+
// REFS
|
|
89
|
+
const updatesSubscription = useRef(null);
|
|
86
90
|
// HANDLERS
|
|
87
91
|
const handleScrollUp = () => {
|
|
88
92
|
window.scrollTo({ left: 0, top: 0, behavior: 'smooth' });
|
|
@@ -119,6 +123,28 @@ export default function Groups(inProps) {
|
|
|
119
123
|
fetchGroups();
|
|
120
124
|
}
|
|
121
125
|
}, [contentAvailability, authUserId, search]);
|
|
126
|
+
/**
|
|
127
|
+
* Subscriber for pubsub callback
|
|
128
|
+
*/
|
|
129
|
+
const onDeleteGroupHandler = useCallback((_msg, deleted) => {
|
|
130
|
+
setGroups((prev) => {
|
|
131
|
+
if (prev.some((e) => e.id === deleted)) {
|
|
132
|
+
return prev.filter((e) => e.id !== deleted);
|
|
133
|
+
}
|
|
134
|
+
return prev;
|
|
135
|
+
});
|
|
136
|
+
}, [groups]);
|
|
137
|
+
/**
|
|
138
|
+
* On mount, subscribe to receive event updates (only delete)
|
|
139
|
+
*/
|
|
140
|
+
useEffect(() => {
|
|
141
|
+
if (groups) {
|
|
142
|
+
updatesSubscription.current = PubSub.subscribe(`${SCTopicType.GROUP}.${SCGroupEventType.DELETE}`, onDeleteGroupHandler);
|
|
143
|
+
}
|
|
144
|
+
return () => {
|
|
145
|
+
updatesSubscription.current && PubSub.unsubscribe(updatesSubscription.current);
|
|
146
|
+
};
|
|
147
|
+
}, [groups]);
|
|
122
148
|
const handleNext = useMemo(() => () => {
|
|
123
149
|
if (!next) {
|
|
124
150
|
return;
|
|
@@ -4,7 +4,7 @@ import { Button, CardActions, Icon, IconButton, Typography } from '@mui/material
|
|
|
4
4
|
import { styled } from '@mui/material/styles';
|
|
5
5
|
import { Box, useThemeProps } from '@mui/system';
|
|
6
6
|
import { Endpoints, EventService, http } from '@selfcommunity/api-services';
|
|
7
|
-
import { SCCache, SCRoutes, useSCPreferences, useSCRouting, useSCUser } from '@selfcommunity/react-core';
|
|
7
|
+
import { SCCache, SCPreferences, SCRoutes, useSCPreferences, useSCRouting, useSCUser } from '@selfcommunity/react-core';
|
|
8
8
|
import { SCEventSubscriptionStatusType, SCFeatureName } from '@selfcommunity/types';
|
|
9
9
|
import { Logger } from '@selfcommunity/utils';
|
|
10
10
|
import { useCallback, useEffect, useMemo, useReducer, useRef, useState } from 'react';
|
|
@@ -64,8 +64,12 @@ export default function MyEventsWidget(inProps) {
|
|
|
64
64
|
// CONTEXT
|
|
65
65
|
const scUserContext = useSCUser();
|
|
66
66
|
const scRoutingContext = useSCRouting();
|
|
67
|
-
const { features } = useSCPreferences();
|
|
68
|
-
const eventsEnabled = useMemo(() =>
|
|
67
|
+
const { preferences, features } = useSCPreferences();
|
|
68
|
+
const eventsEnabled = useMemo(() => preferences &&
|
|
69
|
+
features &&
|
|
70
|
+
features.includes(SCFeatureName.TAGGING) &&
|
|
71
|
+
SCPreferences.CONFIGURATIONS_EVENTS_ENABLED in preferences &&
|
|
72
|
+
preferences[SCPreferences.CONFIGURATIONS_EVENTS_ENABLED].value, [preferences, features]);
|
|
69
73
|
// REFS
|
|
70
74
|
const updatesSubscription = useRef(null);
|
|
71
75
|
/**
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { DrawerProps } from '@mui/material';
|
|
3
|
+
export interface NavigationMenuDrawerProps extends DrawerProps {
|
|
4
|
+
/**
|
|
5
|
+
* Custom Drawer header content
|
|
6
|
+
* @default null
|
|
7
|
+
*/
|
|
8
|
+
drawerHeaderContent?: React.ReactNode;
|
|
9
|
+
/**
|
|
10
|
+
* Hide drawer header
|
|
11
|
+
* @default true
|
|
12
|
+
*/
|
|
13
|
+
showDrawerHeader?: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Custom Drawer content
|
|
16
|
+
* @default null
|
|
17
|
+
*/
|
|
18
|
+
drawerContent?: React.ReactNode;
|
|
19
|
+
/**
|
|
20
|
+
* Props to spread to ScrollContainer component
|
|
21
|
+
* This lib use 'react-custom-scrollbars' component to perform scrollbars
|
|
22
|
+
* For more info: https://github.com/malte-wessel/react-custom-scrollbars/blob/master/docs/API.md
|
|
23
|
+
* @default {}
|
|
24
|
+
*/
|
|
25
|
+
ScrollContainerProps?: Record<string, any>;
|
|
26
|
+
/**
|
|
27
|
+
* Override onClose
|
|
28
|
+
*/
|
|
29
|
+
handleOnClose?: () => void;
|
|
30
|
+
/**
|
|
31
|
+
* Any other properties
|
|
32
|
+
*/
|
|
33
|
+
[p: string]: any;
|
|
34
|
+
}
|
|
35
|
+
export default function NavigationMenuDrawer(inProps: NavigationMenuDrawerProps): JSX.Element;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { __rest } from "tslib";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
4
|
+
import { styled } from '@mui/material/styles';
|
|
5
|
+
import { Box, Divider, Drawer, Icon, IconButton, List } from '@mui/material';
|
|
6
|
+
import classNames from 'classnames';
|
|
7
|
+
import { useThemeProps } from '@mui/system';
|
|
8
|
+
import ScrollContainer from '../../shared/ScrollContainer';
|
|
9
|
+
import DefaultDrawerContent from './DefaultDrawerContent';
|
|
10
|
+
import DefaultHeaderContent from './DefaultHeaderContent';
|
|
11
|
+
import PubSub from 'pubsub-js';
|
|
12
|
+
import { SCLayoutEventType, SCTopicType } from '../../constants/PubSub';
|
|
13
|
+
const PREFIX = 'SCNavigationMenuDrawer';
|
|
14
|
+
const classes = {
|
|
15
|
+
root: `${PREFIX}-root`,
|
|
16
|
+
logo: `${PREFIX}-logo`,
|
|
17
|
+
drawerRoot: `${PREFIX}-drawer-root`,
|
|
18
|
+
drawerHeader: `${PREFIX}-drawer-header`,
|
|
19
|
+
drawerHeaderAction: `${PREFIX}-drawer-header-action`,
|
|
20
|
+
drawerContent: `${PREFIX}-drawer-content`
|
|
21
|
+
};
|
|
22
|
+
const Root = styled(Drawer, {
|
|
23
|
+
name: PREFIX,
|
|
24
|
+
slot: 'Root',
|
|
25
|
+
overridesResolver: (props, styles) => styles.root
|
|
26
|
+
})(({ theme }) => ({}));
|
|
27
|
+
export default function NavigationMenuDrawer(inProps) {
|
|
28
|
+
// PROPS
|
|
29
|
+
const props = useThemeProps({
|
|
30
|
+
props: inProps,
|
|
31
|
+
name: PREFIX
|
|
32
|
+
});
|
|
33
|
+
const { className = null, open, drawerHeaderContent = _jsx(DefaultHeaderContent, {}), drawerContent = _jsx(DefaultDrawerContent, {}), ScrollContainerProps = {}, handleOnClose, showDrawerHeader = true } = props, rest = __rest(props, ["className", "open", "drawerHeaderContent", "drawerContent", "ScrollContainerProps", "handleOnClose", "showDrawerHeader"]);
|
|
34
|
+
// REFS
|
|
35
|
+
const refreshSubscription = useRef(null);
|
|
36
|
+
const [isDrawerOpen, setIsDrawerOpen] = useState(open);
|
|
37
|
+
// HANDLERS
|
|
38
|
+
const onClose = useCallback(() => {
|
|
39
|
+
if (handleOnClose) {
|
|
40
|
+
handleOnClose();
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
setIsDrawerOpen(false);
|
|
44
|
+
}
|
|
45
|
+
}, [open]);
|
|
46
|
+
// Subscriber for pubsub callback
|
|
47
|
+
const subscriber = useCallback((msg, data) => {
|
|
48
|
+
if (msg === `${SCTopicType.LAYOUT}.${SCLayoutEventType.TOGGLE_DRAWER}`) {
|
|
49
|
+
setIsDrawerOpen(!isDrawerOpen);
|
|
50
|
+
}
|
|
51
|
+
else if (msg === `${SCTopicType.LAYOUT}.${SCLayoutEventType.SET_DRAWER}`) {
|
|
52
|
+
setIsDrawerOpen(data.open);
|
|
53
|
+
}
|
|
54
|
+
}, [isDrawerOpen]);
|
|
55
|
+
/**
|
|
56
|
+
* When a ws notification arrives, update data
|
|
57
|
+
*/
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
refreshSubscription.current = PubSub.subscribe(`${SCTopicType.LAYOUT}.${SCLayoutEventType.DRAWER}`, subscriber);
|
|
60
|
+
return () => {
|
|
61
|
+
PubSub.unsubscribe(refreshSubscription.current);
|
|
62
|
+
};
|
|
63
|
+
}, [subscriber]);
|
|
64
|
+
return (_jsxs(Root, Object.assign({ anchor: "left", className: classNames(classes.root, className), open: isDrawerOpen, onClose: onClose }, rest, { children: [showDrawerHeader && (_jsxs(_Fragment, { children: [_jsxs(Box, Object.assign({ className: classes.drawerHeader }, { children: [drawerHeaderContent, _jsx(IconButton, Object.assign({ className: classes.drawerHeaderAction, onClick: onClose }, { children: _jsx(Icon, { children: "close" }) }))] })), _jsx(Divider, {})] })), _jsx(ScrollContainer, Object.assign({}, ScrollContainerProps, { children: _jsx(List, Object.assign({ className: classes.drawerContent, onClick: onClose }, { children: drawerContent })) }))] })));
|
|
65
|
+
}
|
|
@@ -1,28 +1,21 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
1
|
+
import { IconButtonProps } from '@mui/material';
|
|
2
|
+
import { NavigationMenuDrawerProps } from './NavigationMenuDrawer';
|
|
3
3
|
export interface NavigationMenuIconButtonProps extends IconButtonProps {
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
* @default
|
|
5
|
+
* Prop to show/hide the default drawer component
|
|
6
|
+
* @default true
|
|
7
7
|
*/
|
|
8
|
-
|
|
8
|
+
showDrawer?: boolean;
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
10
|
+
* Callback triggered on menu click
|
|
11
11
|
* @default null
|
|
12
12
|
*/
|
|
13
|
-
|
|
13
|
+
onMenuIconClick?: () => void;
|
|
14
14
|
/**
|
|
15
|
-
*
|
|
16
|
-
* @default null
|
|
17
|
-
*/
|
|
18
|
-
drawerContent?: React.ReactNode;
|
|
19
|
-
/**
|
|
20
|
-
* Props to spread to ScrollContainer component
|
|
21
|
-
* This lib use 'react-custom-scrollbars' component to perform scrollbars
|
|
22
|
-
* For more info: https://github.com/malte-wessel/react-custom-scrollbars/blob/master/docs/API.md
|
|
15
|
+
* Props to spread to default drawer root
|
|
23
16
|
* @default {}
|
|
24
17
|
*/
|
|
25
|
-
|
|
18
|
+
DrawerProps?: NavigationMenuDrawerProps;
|
|
26
19
|
}
|
|
27
20
|
/**
|
|
28
21
|
* > API documentation for the Community-JS Navigation Menu Icon Button component. Learn about the available props and the CSS API.
|
|
@@ -43,10 +36,6 @@ export interface NavigationMenuIconButtonProps extends IconButtonProps {
|
|
|
43
36
|
|Rule Name|Global class|Description|
|
|
44
37
|
|---|---|---|
|
|
45
38
|
|root|.SCNavigationMenuIconButton-root|Styles applied to the root element.|
|
|
46
|
-
|drawerRoot|.SCNavigationMenuIconButton-drawer-root|Styles applied to the drawer root element.|
|
|
47
|
-
|drawerHeader|.SCNavigationMenuIconButton-drawer-header|Styles applied to the drawer header.|
|
|
48
|
-
|drawerHeaderAction|.SCNavigationMenuIconButton-drawer-header-action|Styles applied to the drawer header action element.|
|
|
49
|
-
|drawerContent|.SCNavigationMenuIconButton-drawer-content|Styles applied to the drawer content.|
|
|
50
39
|
|
|
51
40
|
* @param inProps
|
|
52
41
|
*/
|