@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.
Files changed (107) hide show
  1. package/lib/cjs/components/BottomNavigation/BottomNavigation.js +11 -2
  2. package/lib/cjs/components/Composer/Composer.js +10 -2
  3. package/lib/cjs/components/Composer/Layer/AudienceLayer/AudienceLayer.js +12 -3
  4. package/lib/cjs/components/CreateEventButton/CreateEventButton.js +5 -1
  5. package/lib/cjs/components/CreateEventWidget/CreateEventWidget.js +5 -1
  6. package/lib/cjs/components/EventForm/EventForm.d.ts +1 -1
  7. package/lib/cjs/components/EventForm/EventForm.js +72 -54
  8. package/lib/cjs/components/EventForm/constants.d.ts +4 -0
  9. package/lib/cjs/components/EventForm/constants.js +5 -1
  10. package/lib/cjs/components/EventForm/types.d.ts +1 -2
  11. package/lib/cjs/components/EventForm/utils.d.ts +4 -0
  12. package/lib/cjs/components/EventForm/utils.js +28 -0
  13. package/lib/cjs/components/EventInfoWidget/EventInfoWidget.js +24 -1
  14. package/lib/cjs/components/Events/Events.js +17 -7
  15. package/lib/cjs/components/Events/LocationEventsFilter.d.ts +14 -0
  16. package/lib/cjs/components/Events/LocationEventsFilter.js +45 -0
  17. package/lib/cjs/components/Events/PastEventsFilter.js +1 -2
  18. package/lib/cjs/components/Feed/Feed.js +12 -3
  19. package/lib/cjs/components/GroupActionsMenu/index.d.ts +57 -0
  20. package/lib/cjs/components/GroupActionsMenu/index.js +157 -0
  21. package/lib/cjs/components/GroupHeader/GroupHeader.d.ts +6 -0
  22. package/lib/cjs/components/GroupHeader/GroupHeader.js +8 -4
  23. package/lib/cjs/components/Groups/Groups.js +26 -0
  24. package/lib/cjs/components/MyEventsWidget/MyEventsWidget.js +6 -2
  25. package/lib/cjs/components/NavigationMenuIconButton/NavigationMenuDrawer.d.ts +35 -0
  26. package/lib/cjs/components/NavigationMenuIconButton/NavigationMenuDrawer.js +68 -0
  27. package/lib/cjs/components/NavigationMenuIconButton/NavigationMenuIconButton.d.ts +9 -20
  28. package/lib/cjs/components/NavigationMenuIconButton/NavigationMenuIconButton.js +8 -27
  29. package/lib/cjs/components/NavigationMenuIconButton/index.d.ts +2 -1
  30. package/lib/cjs/components/NavigationMenuIconButton/index.js +3 -1
  31. package/lib/cjs/components/NavigationToolbar/NavigationToolbar.d.ts +5 -0
  32. package/lib/cjs/components/NavigationToolbar/NavigationToolbar.js +14 -5
  33. package/lib/cjs/components/NavigationToolbarMobile/NavigationToolbarMobile.js +11 -2
  34. package/lib/cjs/components/Notification/Event/Event.js +4 -0
  35. package/lib/cjs/components/OnBoardingWidget/OnBoardingWidget.d.ts +10 -1
  36. package/lib/cjs/components/OnBoardingWidget/OnBoardingWidget.js +69 -26
  37. package/lib/cjs/components/OnBoardingWidget/Steps/Appearance/Appearance.js +8 -4
  38. package/lib/cjs/components/OnBoardingWidget/Steps/Invite/Invite.js +56 -12
  39. package/lib/cjs/components/PlatformWidget/constants.d.ts +0 -4
  40. package/lib/cjs/components/PlatformWidget/constants.js +1 -5
  41. package/lib/cjs/components/UserSubscribedGroupsWidget/UserSubscribedGroupsWidget.js +7 -2
  42. package/lib/cjs/constants/GroupActionsMenu.d.ts +5 -0
  43. package/lib/cjs/constants/GroupActionsMenu.js +8 -0
  44. package/lib/cjs/constants/PubSub.d.ts +16 -1
  45. package/lib/cjs/constants/PubSub.js +11 -1
  46. package/lib/cjs/index.d.ts +4 -2
  47. package/lib/cjs/index.js +12 -5
  48. package/lib/cjs/shared/ContributionActionsMenu/index.js +6 -6
  49. package/lib/cjs/shared/InfiniteScroll/index.js +3 -3
  50. package/lib/cjs/shared/Media/Link/DisplayComponent.js +21 -5
  51. package/lib/cjs/utils/formatRelativeTime.js +2 -2
  52. package/lib/esm/components/BottomNavigation/BottomNavigation.js +11 -2
  53. package/lib/esm/components/Composer/Composer.js +10 -2
  54. package/lib/esm/components/Composer/Layer/AudienceLayer/AudienceLayer.js +13 -4
  55. package/lib/esm/components/CreateEventButton/CreateEventButton.js +5 -1
  56. package/lib/esm/components/CreateEventWidget/CreateEventWidget.js +5 -1
  57. package/lib/esm/components/EventForm/EventForm.d.ts +1 -1
  58. package/lib/esm/components/EventForm/EventForm.js +74 -56
  59. package/lib/esm/components/EventForm/constants.d.ts +4 -0
  60. package/lib/esm/components/EventForm/constants.js +4 -0
  61. package/lib/esm/components/EventForm/types.d.ts +1 -2
  62. package/lib/esm/components/EventForm/utils.d.ts +4 -0
  63. package/lib/esm/components/EventForm/utils.js +21 -0
  64. package/lib/esm/components/EventInfoWidget/EventInfoWidget.js +25 -2
  65. package/lib/esm/components/Events/Events.js +18 -8
  66. package/lib/esm/components/Events/LocationEventsFilter.d.ts +14 -0
  67. package/lib/esm/components/Events/LocationEventsFilter.js +41 -0
  68. package/lib/esm/components/Events/PastEventsFilter.js +1 -2
  69. package/lib/esm/components/Feed/Feed.js +14 -5
  70. package/lib/esm/components/GroupActionsMenu/index.d.ts +57 -0
  71. package/lib/esm/components/GroupActionsMenu/index.js +154 -0
  72. package/lib/esm/components/GroupHeader/GroupHeader.d.ts +6 -0
  73. package/lib/esm/components/GroupHeader/GroupHeader.js +9 -5
  74. package/lib/esm/components/Groups/Groups.js +27 -1
  75. package/lib/esm/components/MyEventsWidget/MyEventsWidget.js +7 -3
  76. package/lib/esm/components/NavigationMenuIconButton/NavigationMenuDrawer.d.ts +35 -0
  77. package/lib/esm/components/NavigationMenuIconButton/NavigationMenuDrawer.js +65 -0
  78. package/lib/esm/components/NavigationMenuIconButton/NavigationMenuIconButton.d.ts +9 -20
  79. package/lib/esm/components/NavigationMenuIconButton/NavigationMenuIconButton.js +11 -30
  80. package/lib/esm/components/NavigationMenuIconButton/index.d.ts +2 -1
  81. package/lib/esm/components/NavigationMenuIconButton/index.js +2 -1
  82. package/lib/esm/components/NavigationToolbar/NavigationToolbar.d.ts +5 -0
  83. package/lib/esm/components/NavigationToolbar/NavigationToolbar.js +14 -5
  84. package/lib/esm/components/NavigationToolbarMobile/NavigationToolbarMobile.js +11 -2
  85. package/lib/esm/components/Notification/Event/Event.js +4 -0
  86. package/lib/esm/components/OnBoardingWidget/OnBoardingWidget.d.ts +10 -1
  87. package/lib/esm/components/OnBoardingWidget/OnBoardingWidget.js +71 -28
  88. package/lib/esm/components/OnBoardingWidget/Steps/Appearance/Appearance.js +9 -5
  89. package/lib/esm/components/OnBoardingWidget/Steps/Invite/Invite.js +59 -14
  90. package/lib/esm/components/PlatformWidget/constants.d.ts +0 -4
  91. package/lib/esm/components/PlatformWidget/constants.js +0 -4
  92. package/lib/esm/components/UserSubscribedGroupsWidget/UserSubscribedGroupsWidget.js +8 -3
  93. package/lib/esm/constants/GroupActionsMenu.d.ts +5 -0
  94. package/lib/esm/constants/GroupActionsMenu.js +5 -0
  95. package/lib/esm/constants/PubSub.d.ts +16 -1
  96. package/lib/esm/constants/PubSub.js +10 -0
  97. package/lib/esm/index.d.ts +4 -2
  98. package/lib/esm/index.js +5 -3
  99. package/lib/esm/shared/ContributionActionsMenu/index.js +6 -6
  100. package/lib/esm/shared/InfiniteScroll/index.js +3 -3
  101. package/lib/esm/shared/Media/Link/DisplayComponent.js +21 -5
  102. package/lib/esm/utils/formatRelativeTime.js +2 -2
  103. package/lib/umd/148.js +2 -0
  104. package/lib/umd/react-ui.js +1 -1
  105. package/package.json +7 -7
  106. package/lib/umd/99.js +0 -2
  107. /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
- 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(FormattedMessage, { id: "ui.feed.refreshRelease", defaultMessage: "ui.feed.refreshRelease" }), 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;
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(Widget, Object.assign({ variant: "outlined", className: classes.refresh }, { children: _jsx(CardContent, { 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))) })) })) })) })))] })));
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(() => features && features.includes(SCFeatureName.EVENT) && features.includes(SCFeatureName.TAGGING), [features]);
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 React from 'react';
2
- import { DrawerProps, IconButtonProps } from '@mui/material';
1
+ import { IconButtonProps } from '@mui/material';
2
+ import { NavigationMenuDrawerProps } from './NavigationMenuDrawer';
3
3
  export interface NavigationMenuIconButtonProps extends IconButtonProps {
4
4
  /**
5
- * Props to spread to drawer element
6
- * @default {anchor: 'left'}
5
+ * Prop to show/hide the default drawer component
6
+ * @default true
7
7
  */
8
- DrawerProps?: DrawerProps;
8
+ showDrawer?: boolean;
9
9
  /**
10
- * Custom Drawer header content
10
+ * Callback triggered on menu click
11
11
  * @default null
12
12
  */
13
- drawerHeaderContent?: React.ReactNode;
13
+ onMenuIconClick?: () => void;
14
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
15
+ * Props to spread to default drawer root
23
16
  * @default {}
24
17
  */
25
- ScrollContainerProps?: Record<string, any>;
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
  */