@selfcommunity/react-ui 0.9.0-alpha.1 → 0.9.0-alpha.11

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 (32) hide show
  1. package/lib/cjs/components/Event/Event.js +1 -1
  2. package/lib/cjs/components/EventHeader/EventHeader.js +3 -7
  3. package/lib/cjs/components/EventMediaWidget/EventMediaWidget.d.ts +4 -0
  4. package/lib/cjs/components/EventMediaWidget/EventMediaWidget.js +45 -34
  5. package/lib/cjs/components/EventMembersWidget/EventMembersWidget.d.ts +3 -0
  6. package/lib/cjs/components/EventMembersWidget/EventMembersWidget.js +18 -13
  7. package/lib/cjs/components/Events/Events.js +2 -3
  8. package/lib/cjs/components/NavigationToolbar/NavigationToolbar.js +1 -1
  9. package/lib/cjs/components/OnBoardingWidget/Steps/Appearance/Appearance.js +10 -13
  10. package/lib/cjs/shared/EventActionsMenu/index.d.ts +1 -1
  11. package/lib/cjs/shared/EventActionsMenu/index.js +11 -15
  12. package/lib/cjs/utils/events.d.ts +2 -0
  13. package/lib/cjs/utils/events.js +10 -0
  14. package/lib/cjs/utils/widget.d.ts +1 -0
  15. package/lib/cjs/utils/widget.js +14 -0
  16. package/lib/esm/components/Event/Event.js +1 -1
  17. package/lib/esm/components/EventHeader/EventHeader.js +3 -7
  18. package/lib/esm/components/EventMediaWidget/EventMediaWidget.d.ts +4 -0
  19. package/lib/esm/components/EventMediaWidget/EventMediaWidget.js +46 -35
  20. package/lib/esm/components/EventMembersWidget/EventMembersWidget.d.ts +3 -0
  21. package/lib/esm/components/EventMembersWidget/EventMembersWidget.js +18 -13
  22. package/lib/esm/components/Events/Events.js +2 -3
  23. package/lib/esm/components/NavigationToolbar/NavigationToolbar.js +1 -1
  24. package/lib/esm/components/OnBoardingWidget/Steps/Appearance/Appearance.js +10 -13
  25. package/lib/esm/shared/EventActionsMenu/index.d.ts +1 -1
  26. package/lib/esm/shared/EventActionsMenu/index.js +11 -15
  27. package/lib/esm/utils/events.d.ts +2 -0
  28. package/lib/esm/utils/events.js +6 -0
  29. package/lib/esm/utils/widget.d.ts +1 -0
  30. package/lib/esm/utils/widget.js +14 -0
  31. package/lib/umd/react-ui.js +1 -1
  32. package/package.json +3 -3
@@ -6,7 +6,7 @@ import { styled } from '@mui/material/styles';
6
6
  import { Box, useThemeProps } from '@mui/system';
7
7
  import { Endpoints, EventService, http } from '@selfcommunity/api-services';
8
8
  import { SCCache, useSCFetchEvent, useSCUser } from '@selfcommunity/react-core';
9
- import { Logger } from '@selfcommunity/utils';
9
+ import { CacheStrategies, Logger } from '@selfcommunity/utils';
10
10
  import { Fragment, useCallback, useEffect, useMemo, useReducer, useState } from 'react';
11
11
  import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
12
12
  import { SCOPE_SC_UI } from '../../constants/Errors';
@@ -67,17 +67,22 @@ export default function EventMediaWidget(inProps) {
67
67
  const { event, eventId, limit = DEFAULT_PAGINATION_LIMIT, endpointQueryParams = {
68
68
  limit,
69
69
  offset: DEFAULT_PAGINATION_OFFSET
70
- }, cacheStrategy, dialogProps } = props, rest = __rest(props, ["event", "eventId", "limit", "endpointQueryParams", "cacheStrategy", "dialogProps"]);
70
+ }, cacheStrategy = CacheStrategies.CACHE_FIRST, dialogProps } = props, rest = __rest(props, ["event", "eventId", "limit", "endpointQueryParams", "cacheStrategy", "dialogProps"]);
71
+ // HOOKS
72
+ const { scEvent } = useSCFetchEvent({ id: eventId, event });
73
+ const intl = useIntl();
74
+ const theme = useTheme();
75
+ const isMobile = useMediaQuery(theme.breakpoints.down('md'));
71
76
  // STATE
72
77
  const [state, dispatch] = useReducer(dataWidgetReducer, {
73
78
  isLoadingNext: false,
74
79
  next: null,
75
- cacheKey: SCCache.getWidgetStateCacheKey(SCCache.EVENT_MEDIA_STATE_CACHE_PREFIX_KEY),
80
+ cacheKey: SCCache.getWidgetStateCacheKey(SCCache.EVENT_MEDIA_STATE_CACHE_PREFIX_KEY, event ? event.id : eventId),
76
81
  cacheStrategy,
77
82
  visibleItems: limit
78
83
  }, stateWidgetInitializer);
79
- const [medias, setMedias] = useState([]);
80
- const [mediasCount, setMediasCount] = useState(0);
84
+ const [medias, setMedias] = useState(state.results);
85
+ const [mediasCount, setMediasCount] = useState(state.count);
81
86
  const [openDialog, setOpenDialog] = useState(false);
82
87
  const [openDialogConfirm, setOpenDialogConfirm] = useState(false);
83
88
  const [mediaId, setMediaId] = useState(null);
@@ -86,33 +91,9 @@ export default function EventMediaWidget(inProps) {
86
91
  const [showSkeleton, setShowSkeleton] = useState(null);
87
92
  // CONTEXT
88
93
  const scUserContext = useSCUser();
89
- // HOOKS
90
- const { scEvent } = useSCFetchEvent({ id: eventId, event });
91
- const intl = useIntl();
92
- const theme = useTheme();
93
- const isMobile = useMediaQuery(theme.breakpoints.down('md'));
94
94
  // CONSTS
95
95
  const hasAllow = useMemo(() => { var _a; return ((_a = scUserContext.user) === null || _a === void 0 ? void 0 : _a.id) === (scEvent === null || scEvent === void 0 ? void 0 : scEvent.managed_by.id); }, [scUserContext, scEvent]);
96
96
  const countHiddenMedia = useMemo(() => mediasCount - MEDIAS_TO_SHOW, [mediasCount]);
97
- /**
98
- * Initialize component
99
- * Fetch data only if the component is not initialized and it is not loading data
100
- */
101
- const _initComponent = useCallback(() => {
102
- if (!state.initialized && !state.isLoadingNext) {
103
- dispatch({ type: actionWidgetTypes.LOADING_NEXT });
104
- EventService.getEventPhotoGallery(scEvent.id, Object.assign({}, endpointQueryParams))
105
- .then((payload) => {
106
- dispatch({ type: actionWidgetTypes.LOAD_NEXT_SUCCESS, payload: Object.assign(Object.assign({}, payload), { initialized: true }) });
107
- setMedias(payload.results);
108
- setMediasCount(payload.count);
109
- })
110
- .catch((error) => {
111
- dispatch({ type: actionWidgetTypes.LOAD_NEXT_FAILURE, payload: { errorLoadNext: error } });
112
- Logger.error(SCOPE_SC_UI, error);
113
- });
114
- }
115
- }, [state.isLoadingNext, state.initialized, scEvent, dispatch, setMedias, setMediasCount]);
116
97
  const _fetchNext = useCallback((index) => {
117
98
  if (mediasCount > medias.length && index >= 6 && !state.isLoadingNext && state.next) {
118
99
  setPreview(index);
@@ -210,25 +191,55 @@ export default function EventMediaWidget(inProps) {
210
191
  // EFFECTS
211
192
  useEffect(() => {
212
193
  let _t;
213
- if (scUserContext.user && scEvent) {
194
+ if (scUserContext.user &&
195
+ scEvent &&
196
+ !state.initialized &&
197
+ Boolean((eventId !== undefined && scEvent.id === eventId) || (event && scEvent.id === event.id))) {
214
198
  _t = setTimeout(_initComponent);
215
199
  return () => {
216
200
  clearTimeout(_t);
217
201
  };
218
202
  }
219
- }, [scUserContext.user, scEvent]);
203
+ }, [scUserContext.user, scEvent, state.initialized]);
204
+ useEffect(() => {
205
+ if (state.initialized && scEvent && Boolean((eventId !== undefined && scEvent.id !== eventId) || (event && scEvent.id !== event.id))) {
206
+ dispatch({ type: actionWidgetTypes.RESET, payload: {} });
207
+ }
208
+ }, [state.initialized, scEvent, eventId, event]);
209
+ /**
210
+ * Initialize component
211
+ * Fetch data only if the component is not initialized and it is not loading data
212
+ */
213
+ const _initComponent = useCallback(() => {
214
+ if (!state.isLoadingNext) {
215
+ dispatch({ type: actionWidgetTypes.LOADING_NEXT });
216
+ EventService.getEventPhotoGallery(scEvent.id, Object.assign({}, endpointQueryParams))
217
+ .then((payload) => {
218
+ dispatch({ type: actionWidgetTypes.LOAD_NEXT_SUCCESS, payload: Object.assign(Object.assign({}, payload), { initialized: true }) });
219
+ setMedias(payload.results);
220
+ setMediasCount(payload.count);
221
+ })
222
+ .catch((error) => {
223
+ dispatch({ type: actionWidgetTypes.LOAD_NEXT_FAILURE, payload: { errorLoadNext: error } });
224
+ Logger.error(SCOPE_SC_UI, error);
225
+ });
226
+ }
227
+ }, [state.isLoadingNext, scEvent, eventId, dispatch, setMedias, setMediasCount]);
220
228
  useEffect(() => {
221
229
  if (isMobile && openDialog && state.next) {
222
230
  handleNext();
223
231
  }
224
232
  }, [isMobile, openDialog, state.next]);
225
233
  // RENDER
226
- if (!scEvent || (state.initialized && mediasCount === 0 && !hasAllow)) {
227
- return _jsx(HiddenPlaceholder, {});
228
- }
229
- if (!state.initialized || (state.isLoadingNext && mediasCount === 0)) {
234
+ if (!scEvent ||
235
+ !state.initialized ||
236
+ (scEvent && ((eventId !== undefined && scEvent.id !== eventId) || (event && scEvent.id !== event.id))) ||
237
+ (state.isLoadingNext && !state.initialized)) {
230
238
  return _jsx(SkeletonComponent, {});
231
239
  }
240
+ if (state.initialized && state.count === 0 && !hasAllow) {
241
+ return _jsx(HiddenPlaceholder, {});
242
+ }
232
243
  return (_jsxs(Root, Object.assign({ className: classes.root }, rest, { showPadding: hasAllow }, { children: [_jsx(CardHeader, { title: _jsxs(Stack, Object.assign({ direction: "row", justifyContent: "space-between", alignItems: "center" }, { children: [_jsx(Typography, Object.assign({ variant: "h5" }, { children: _jsx(FormattedMessage, { id: "ui.eventMediaWidget.title", defaultMessage: "ui.eventMediaWidget.title" }) })), hasAllow && mediasCount > 0 && _jsx(TriggerButton, { size: "small", onAdd: handleAddMedia })] })), className: classes.header }), _jsx(Divider, {}), _jsxs(CardContent, Object.assign({ className: classes.content }, { children: [_jsxs(Box, Object.assign({ className: classes.grid }, { children: [showSkeleton === 'widget' && _jsx(EventMediaSkeleton, {}), medias.slice(0, MEDIAS_TO_SHOW).map((media, i, array) => (_jsx(Box, Object.assign({ onClick: () => handleOpenLightbox(i), sx: {
233
244
  background: `url(${media.image}) no-repeat center`
234
245
  }, className: classes.media }, { children: medias.length > array.length && i === array.length - 1 && (_jsxs(Fragment, { children: [_jsx(Box, { className: classes.mediaLayer }), _jsx(Box, Object.assign({ className: classes.countHiddenMediaWrapper }, { children: _jsxs(Typography, Object.assign({ className: classes.countHiddenMedia }, { children: ["+", countHiddenMedia] })) }))] })) }), media.id))), hasAllow && mediasCount === 0 && (_jsx(Tooltip, Object.assign({ title: _jsx(FormattedMessage, { id: "ui.eventMediaWidget.add", defaultMessage: "ui.eventMediaWidget.add" }) }, { children: _jsx(TriggerButton, { size: "large", onAdd: handleAddMedia, isSquare: true }) })))] })), preview !== -1 && _jsx(Lightbox, { onClose: handleCloseLightbox, index: preview, medias: medias, onIndexChange: _fetchNext })] })), hasAllow && mediasCount > 0 && (_jsx(CardActions, Object.assign({ className: classes.actions }, { children: _jsx(Button, Object.assign({ onClick: handleToggleDialogOpen }, { children: _jsx(Typography, Object.assign({ variant: "caption" }, { children: _jsx(FormattedMessage, { id: "ui.eventMediaWidget.showAll", defaultMessage: "ui.eventMediaWidget.showAll" }) })) })) }))), openDialog && (_jsx(DialogRoot, Object.assign({ className: classes.dialogRoot, title: intl.formatMessage(messages.title, { user: scEvent.managed_by.username }), onClose: handleToggleDialogOpen, open: openDialog }, dialogProps, { children: _jsx(InfiniteScroll, Object.assign({ dataLength: medias.length, height: isMobile ? '100%' : '515px', next: handleNext, hasMoreNext: Boolean(state.next), className: classes.dialogInfiniteScroll, endMessage: _jsx(Typography, Object.assign({ className: classes.endMessage }, { children: _jsx(FormattedMessage, { id: "ui.eventMediaWidget.noMoreResults", defaultMessage: "ui.eventMediaWidget.noMoreResults" }) })) }, { children: _jsxs(Box, Object.assign({ className: classes.grid }, { children: [medias.map((media) => (_jsx(Box, Object.assign({ sx: {
@@ -35,6 +35,9 @@ export interface EventMembersWidgetProps extends WidgetProps {
35
35
  * @default {}
36
36
  */
37
37
  dialogProps?: BaseDialogProps;
38
+ /**
39
+ * Limit items
40
+ */
38
41
  limit?: number;
39
42
  /**
40
43
  * Other props
@@ -11,7 +11,6 @@ import { FormattedMessage } from 'react-intl';
11
11
  import 'swiper/css';
12
12
  import { SCOPE_SC_UI } from '../../constants/Errors';
13
13
  import { DEFAULT_PAGINATION_OFFSET } from '../../constants/Pagination';
14
- import HiddenPlaceholder from '../../shared/HiddenPlaceholder';
15
14
  import { actionWidgetTypes, dataWidgetReducer, stateWidgetInitializer } from '../../utils/widget';
16
15
  import Widget from '../Widget';
17
16
  import { PREFIX } from './constants';
@@ -60,10 +59,10 @@ export default function EventMembersWidget(inProps) {
60
59
  cacheStrategy,
61
60
  visibleItems: limit
62
61
  }, stateWidgetInitializer);
63
- const [participantsCount, setParticipantsCount] = useState(0);
64
- const [invitedCount, setInvitedCount] = useState(0);
65
- const [requestsCount, setRequestsCount] = useState(0);
66
- const [requestsUsers, setRequestsUsers] = useState([]);
62
+ const [participantsCount, setParticipantsCount] = useState(participants.count);
63
+ const [invitedCount, setInvitedCount] = useState(invited.count);
64
+ const [requestsCount, setRequestsCount] = useState(requests.count);
65
+ const [requestsUsers, setRequestsUsers] = useState(requests.results);
67
66
  const [tabValue, setTabValue] = useState(TabContentEnum.PARTICIPANTS);
68
67
  const [refresh, setRefresh] = useState(null);
69
68
  // CONTEXT
@@ -97,7 +96,7 @@ export default function EventMembersWidget(inProps) {
97
96
  Logger.error(SCOPE_SC_UI, error);
98
97
  });
99
98
  }
100
- }, [participants.isLoadingNext, participants.initialized, scEvent]);
99
+ }, [participants.isLoadingNext, participants.initialized, scEvent, dispatchParticipants, setParticipantsCount]);
101
100
  const _initInvited = useCallback(() => {
102
101
  if (!invited.initialized && !invited.isLoadingNext && hasAllow) {
103
102
  dispatchInvited({ type: actionWidgetTypes.LOADING_NEXT });
@@ -111,7 +110,7 @@ export default function EventMembersWidget(inProps) {
111
110
  Logger.error(SCOPE_SC_UI, error);
112
111
  });
113
112
  }
114
- }, [invited.isLoadingNext, invited.initialized, scUserContext.user, scEvent]);
113
+ }, [invited.isLoadingNext, invited.initialized, scEvent, dispatchInvited, setInvitedCount]);
115
114
  const _initRequests = useCallback(() => {
116
115
  if (!requests.initialized && !requests.isLoadingNext && hasAllow) {
117
116
  dispatchRequests({ type: actionWidgetTypes.LOADING_NEXT });
@@ -126,7 +125,7 @@ export default function EventMembersWidget(inProps) {
126
125
  Logger.error(SCOPE_SC_UI, error);
127
126
  });
128
127
  }
129
- }, [requests.isLoadingNext, requests.initialized, scUserContext.user, scEvent]);
128
+ }, [requests.isLoadingNext, requests.initialized, scEvent, dispatchRequests, setRequestsCount, setRequestsUsers]);
130
129
  // EFFECTS
131
130
  useEffect(() => {
132
131
  let _t;
@@ -151,6 +150,13 @@ export default function EventMembersWidget(inProps) {
151
150
  };
152
151
  }
153
152
  }, [scUserContext.user, scEvent, refresh]);
153
+ useEffect(() => {
154
+ if (participants.initialized && scEvent && Boolean((eventId !== undefined && scEvent.id !== eventId) || (event && scEvent.id !== event.id))) {
155
+ dispatchParticipants({ type: actionWidgetTypes.RESET, payload: {} });
156
+ dispatchRequests({ type: actionWidgetTypes.RESET, payload: {} });
157
+ dispatchInvited({ type: actionWidgetTypes.RESET, payload: {} });
158
+ }
159
+ }, [participants.initialized, scEvent, eventId, event]);
154
160
  // HANDLERS
155
161
  const handleTabChange = useCallback((_evt, newTabValue) => {
156
162
  setTabValue(newTabValue);
@@ -164,13 +170,12 @@ export default function EventMembersWidget(inProps) {
164
170
  }
165
171
  setRefresh(_tabValue);
166
172
  }, []);
167
- if (!scEvent && !participants.initialized) {
173
+ if (!scEvent ||
174
+ !participants.initialized ||
175
+ (scEvent && ((eventId !== undefined && scEvent.id !== eventId) || (event && scEvent.id !== event.id))) ||
176
+ (tabValue === TabContentEnum.PARTICIPANTS && participants.isLoadingNext && !participants.initialized)) {
168
177
  return _jsx(Skeleton, {});
169
178
  }
170
- // RENDER
171
- if (!scEvent) {
172
- return _jsx(HiddenPlaceholder, {});
173
- }
174
179
  return (_jsx(Root, Object.assign({ className: classes.root }, rest, { children: _jsxs(CardContent, Object.assign({ className: classes.content }, { children: [_jsx(Typography, Object.assign({ variant: "h5", className: classes.title }, { children: _jsx(FormattedMessage, { id: title, defaultMessage: title }) })), _jsxs(TabContext, Object.assign({ value: tabValue }, { children: [_jsxs(TabList, Object.assign({ className: classes.tabsWrapper, onChange: handleTabChange, textColor: "primary", indicatorColor: "primary", variant: "fullWidth" }, { children: [_jsx(Tab, { label: _jsxs(Stack, Object.assign({ className: classes.tabLabelWrapper }, { children: [_jsx(Typography, Object.assign({ variant: "h3" }, { children: participantsCount })), _jsx(Typography, Object.assign({ variant: "subtitle2" }, { children: _jsx(FormattedMessage, { id: "ui.eventMembersWidget.participants", defaultMessage: "ui.eventMembersWidget.participants" }) }))] })), value: TabContentEnum.PARTICIPANTS }), hasAllow && (_jsx(Tab, { label: _jsxs(Stack, Object.assign({ className: classes.tabLabelWrapper }, { children: [_jsx(Typography, Object.assign({ variant: "h3" }, { children: invitedCount })), _jsx(Typography, Object.assign({ variant: "subtitle2" }, { children: _jsx(FormattedMessage, { id: "ui.eventMembersWidget.invited", defaultMessage: "ui.eventMembersWidget.invited" }) }))] })), value: TabContentEnum.INVITED })), hasAllow && (_jsx(Tab, { label: _jsxs(Stack, Object.assign({ className: classes.tabLabelWrapper }, { children: [_jsx(Typography, Object.assign({ variant: "h3" }, { children: requestsCount })), _jsx(Typography, Object.assign({ variant: "subtitle2" }, { children: _jsx(FormattedMessage, { id: "ui.eventMembersWidget.requests", defaultMessage: "ui.eventMembersWidget.requests" }) }))] })), value: TabContentEnum.REQUESTS }))] })), _jsx(TabPanel, Object.assign({ value: TabContentEnum.PARTICIPANTS, className: classes.tabPanel }, { children: _jsx(TabContentComponent, { tabValue: TabContentEnum.PARTICIPANTS, state: participants, dispatch: dispatchParticipants, userProps: userProps, dialogProps: dialogProps, handleRefresh: handleRefresh }) })), hasAllow && (_jsx(TabPanel, Object.assign({ value: TabContentEnum.INVITED, className: classes.tabPanel }, { children: _jsx(TabContentComponent, { tabValue: TabContentEnum.INVITED, state: invited, dispatch: dispatchInvited, userProps: userProps, dialogProps: dialogProps, actionProps: {
175
180
  scEvent,
176
181
  setCount: setInvitedCount
@@ -142,13 +142,13 @@ export default function Events(inProps) {
142
142
  * On mount, fetches events list
143
143
  */
144
144
  useEffect(() => {
145
- if (!contentAvailability) {
145
+ if (!contentAvailability && !authUserId) {
146
146
  return;
147
147
  }
148
148
  else {
149
149
  query === '' && fetchEvents();
150
150
  }
151
- }, [contentAvailability, dateSearch, location, showFollowed, showPastEvents, showMyEvents, query]);
151
+ }, [contentAvailability, authUserId, dateSearch, location, showFollowed, showPastEvents, showMyEvents, query]);
152
152
  /**
153
153
  * Subscriber for pubsub callback
154
154
  */
@@ -211,7 +211,6 @@ export default function Events(inProps) {
211
211
  /**
212
212
  * Renders events list
213
213
  */
214
- console.log(location);
215
214
  const c = (_jsxs(_Fragment, { children: [showFilters && (_jsx(Grid, Object.assign({ container: true, className: classes.filters, gap: 2 }, { children: filters ? (filters) : !general ? (_jsxs(_Fragment, { children: [(events.length !== 0 || (events.length === 0 && showMyEvents)) && (_jsx(Grid, Object.assign({ item: true }, { children: _jsx(EventsChipRoot
216
215
  // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
217
216
  // @ts-ignore
@@ -142,7 +142,7 @@ export default function NavigationToolbar(inProps) {
142
142
  (preferences[SCPreferences.CONFIGURATIONS_CONTENT_AVAILABILITY] || scUserContext.user) && (_jsx(IconButton, Object.assign({ className: classNames(classes.explore, { [classes.active]: value.startsWith(scRoutingContext.url(SCRoutes.EXPLORE_ROUTE_NAME, {})) }), "aria-label": "Explore", to: scRoutingContext.url(SCRoutes.EXPLORE_ROUTE_NAME, {}), component: Link }, { children: _jsx(Icon, { children: "explore" }) }))), groupsEnabled && scUserContext.user && (_jsx(IconButton, Object.assign({ className: classNames(classes.groups, {
143
143
  [classes.active]: value.startsWith(scRoutingContext.url(SCRoutes.GROUPS_SUBSCRIBED_ROUTE_NAME, {})) ||
144
144
  value.startsWith(scRoutingContext.url(SCRoutes.GROUPS_ROUTE_NAME, {}))
145
- }), "aria-label": "Groups", to: scRoutingContext.url(SCRoutes.GROUPS_SUBSCRIBED_ROUTE_NAME, {}), component: Link }, { children: _jsx(Icon, { children: "groups" }) }))), eventsEnabled && (_jsx(IconButton, Object.assign({ className: classNames(classes.events, {
145
+ }), "aria-label": "Groups", to: scRoutingContext.url(SCRoutes.GROUPS_SUBSCRIBED_ROUTE_NAME, {}), component: Link }, { children: _jsx(Icon, { children: "groups" }) }))), eventsEnabled && (scUserContext.user || preferences[SCPreferences.CONFIGURATIONS_CONTENT_AVAILABILITY]) && (_jsx(IconButton, Object.assign({ className: classNames(classes.events, {
146
146
  [classes.active]: value.startsWith(scRoutingContext.url(SCRoutes.EVENTS_ROUTE_NAME, {}))
147
147
  }), "aria-label": "Groups", to: scRoutingContext.url(SCRoutes.EVENTS_ROUTE_NAME, {}), component: Link }, { children: _jsx(Icon, { children: "CalendarIcon" }) })))] })));
148
148
  return (_jsxs(Root, Object.assign({ className: classNames(className, classes.root) }, rest, { children: [_jsx(NavigationMenuIconButtonComponent, Object.assign({}, NavigationMenuIconButtonComponentProps)), _jsx(Link, Object.assign({ to: scRoutingContext.url(SCRoutes.HOME_ROUTE_NAME, {}), className: classes.logo }, { children: _jsx("img", { src: preferences[SCPreferences.LOGO_NAVBAR_LOGO], alt: "logo" }) })), !scUserContext.user && !preferences[SCPreferences.ADDONS_CLOSED_COMMUNITY] && (_jsx(Button, Object.assign({ color: "inherit", component: Link, to: scRoutingContext.url(SCRoutes.SIGNUP_ROUTE_NAME, {}), className: classes.register }, { children: _jsx(FormattedMessage, { id: "ui.appBar.navigation.register", defaultMessage: "ui.appBar.navigation.register" }) }))), preferences[SCPreferences.CONFIGURATIONS_CUSTOM_NAVBAR_ITEM_ENABLED] && (_jsx(_Fragment, { children: preferences[SCPreferences.CONFIGURATIONS_CUSTOM_NAVBAR_ITEM_TEXT] ? (_jsx(Tooltip, Object.assign({ title: preferences[SCPreferences.CONFIGURATIONS_CUSTOM_NAVBAR_ITEM_TEXT] }, { children: _jsx(Link, Object.assign({ target: "blank", to: preferences[SCPreferences.CONFIGURATIONS_CUSTOM_NAVBAR_ITEM_URL], className: classes.customItem }, { children: _jsx("img", { src: preferences[SCPreferences.CONFIGURATIONS_CUSTOM_NAVBAR_ITEM_IMAGE], alt: "custom_item" }) })) }))) : (_jsx(Link, Object.assign({ target: "blank", to: preferences[SCPreferences.CONFIGURATIONS_CUSTOM_NAVBAR_ITEM_URL], className: classes.customItem }, { children: _jsx("img", { src: preferences[SCPreferences.CONFIGURATIONS_CUSTOM_NAVBAR_ITEM_IMAGE], alt: "custom_item" }) }))) })), _children, (preferences[SCPreferences.CONFIGURATIONS_CONTENT_AVAILABILITY] || scUserContext.user) && !disableSearch ? (_jsx(SearchAutocomplete, Object.assign({ className: classes.search, blurOnSelect: true }, SearchAutocompleteProps))) : (_jsx(Box, { className: classes.search })), startActions, scUserContext.user ? (_jsxs(_Fragment, { children: [showComposer && _jsx(ComposerIconButton, Object.assign({ className: classes.composer }, ComposerIconButtonProps)), _jsx(Tooltip, Object.assign({ title: scUserContext.user.username }, { children: _jsx(IconButton, Object.assign({ component: Link, to: scRoutingContext.url(SCRoutes.USER_PROFILE_ROUTE_NAME, scUserContext.user), "aria-label": "Profile", className: classes.profile }, { children: _jsx(Avatar, { alt: scUserContext.user.username, src: scUserContext.user.avatar }) })) })), _jsxs(_Fragment, { children: [_jsx(IconButton, Object.assign({ className: classNames(classes.notification, {
@@ -63,8 +63,7 @@ export default function Appearance(inProps) {
63
63
  const { className, onCompleteAction } = props;
64
64
  // STATE
65
65
  const [state, dispatch] = useReducer(reducer, getInitialState(null));
66
- let fileInput = useRef(null);
67
- const [loadingLogo, setLoadingLogo] = useState(false);
66
+ const [loadingLogo, setLoadingLogo] = useState('');
68
67
  const [anchorEl, setAnchorEl] = useState(null);
69
68
  const [tab, setTab] = useState(0);
70
69
  const [updating, setUpdating] = useState(false);
@@ -160,15 +159,13 @@ export default function Appearance(inProps) {
160
159
  setUpdating(false);
161
160
  }
162
161
  });
163
- const updateLogoPreference = (name) => __awaiter(this, void 0, void 0, function* () {
164
- setLoadingLogo(true);
162
+ const updateLogoPreference = (name, file) => __awaiter(this, void 0, void 0, function* () {
163
+ setLoadingLogo(name);
165
164
  const formData = new FormData();
166
- // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
167
- // @ts-ignore
168
- formData.append(name, fileInput);
165
+ formData.append(name, file);
169
166
  yield PreferenceService.updatePreferences(formData)
170
167
  .then((preference) => {
171
- setLoadingLogo(false);
168
+ setLoadingLogo('');
172
169
  dispatch({
173
170
  type: actionTypes.SET_LOGOS,
174
171
  payload: { logos: state.logos.map((l) => (l.name === name ? Object.assign(Object.assign({}, l), { value: preference[name].value }) : l)) }
@@ -176,7 +173,7 @@ export default function Appearance(inProps) {
176
173
  onCompleteAction();
177
174
  })
178
175
  .catch((e) => {
179
- setLoadingLogo(false);
176
+ setLoadingLogo('');
180
177
  Logger.error(SCOPE_SC_UI, e);
181
178
  });
182
179
  });
@@ -186,9 +183,9 @@ export default function Appearance(inProps) {
186
183
  * @param name
187
184
  */
188
185
  const handleUpload = (event, name) => {
189
- fileInput = event.target.files[0];
190
- if (fileInput) {
191
- updateLogoPreference(name);
186
+ const file = event.target.files[0];
187
+ if (file) {
188
+ updateLogoPreference(name, file);
192
189
  }
193
190
  };
194
191
  useEffect(() => {
@@ -221,7 +218,7 @@ export default function Appearance(inProps) {
221
218
  colorRef.current.blur();
222
219
  }
223
220
  };
224
- return (_jsxs(Root, Object.assign({ className: classNames(classes.root, className) }, { children: [_jsx(Typography, Object.assign({ variant: "h4", className: classes.title, alignSelf: "self-start" }, { children: _jsx(FormattedMessage, { id: "ui.onBoardingWidget.appearance", defaultMessage: "ui.onBoardingWidget.appearance" }) })), _jsx(Typography, Object.assign({ className: classes.summary }, { children: _jsx(FormattedMessage, { id: "ui.onBoardingWidget.step.appearance.summary", defaultMessage: "ui.onBoardingWidget.step.appearance.summary" }) })), _jsx(Button, Object.assign({ variant: "outlined", size: "small", color: "primary", onClick: handleOpen }, { children: _jsx(FormattedMessage, { id: "ui.onBoardingWidget.step.appearance.button", defaultMessage: "ui.onBoardingWidget.step.appearance.button" }) })), _jsxs(DrawerRoot, Object.assign({ className: classes.drawerRoot, anchor: "right", open: Boolean(anchorEl), onClose: handleClose }, { children: [_jsxs(Box, Object.assign({ className: classes.drawerHeader }, { children: [_jsx(Typography, Object.assign({ variant: "h4", color: "primary" }, { children: _jsx(FormattedMessage, { id: "ui.onBoardingWidget.step.appearance.header.title", defaultMessage: "ui.onBoardingWidget.step.appearance.header.title" }) })), _jsx(IconButton, Object.assign({ className: classes.drawerHeaderAction, onClick: handleClose }, { children: _jsx(Icon, { children: "close" }) }))] })), _jsxs(Tabs, Object.assign({ value: tab, onChange: handleTabChange, variant: "scrollable", scrollButtons: "auto", "aria-label": "scrollable-tabs" }, { children: [_jsx(Tab, { label: _jsx(FormattedMessage, { id: "ui.onBoardingWidget.step.appearance.colors.title", defaultMessage: "ui.onBoardingWidget.step.appearance.colors.title" }) }), _jsx(Tab, { label: _jsx(FormattedMessage, { id: "ui.onBoardingWidget.step.appearance.logo.title", defaultMessage: "ui.onBoardingWidget.step.appearance.logo.title" }) }), _jsx(Tab, { label: _jsx(FormattedMessage, { id: "ui.onBoardingWidget.step.appearance.titleSlogan.title", defaultMessage: "ui.onBoardingWidget.step.appearance.titleSlogan.title" }) })] })), _jsx(ScrollContainer, { children: _jsxs(Box, Object.assign({ className: classes.drawerContent }, { children: [tab === 0 && (_jsx(_Fragment, { children: state.colors.map((color) => (_jsxs(React.Fragment, { children: [_jsx(Typography, Object.assign({ variant: "h6" }, { children: formatColorLabel(color) })), _jsxs(Box, Object.assign({ className: classes.colorContainer }, { children: [_jsx(MuiColorInput, { inputRef: colorRef, className: classes.color, format: "hex", value: color.value, onChange: (newColor) => handleColorChange(newColor, color.name), isAlphaHidden: true, PopoverProps: { onClose: handleClosePopover } }), updatingColor && updatingColor === color.name && (_jsx(CircularProgress, { className: classes.colorProgress, color: "secondary", size: 24 }))] }))] }, color.id))) })), tab === 1 && (_jsx(_Fragment, { children: state.logos.map((logo) => (_jsxs(React.Fragment, { children: [_jsx(Typography, Object.assign({ variant: "h6" }, { children: formatLogoLabel(logo.name) })), _jsxs(Box, Object.assign({ className: classes.logoContainer }, { children: [_jsx("img", { src: logo.value, className: classes.logo }), _jsx("input", { type: "file", onChange: (event) => handleUpload(event, logo.name), ref: fileInput, hidden: true, accept: ".gif,.png,.jpg,.jpeg" }), _jsx(LoadingButton, Object.assign({ className: classes.uploadButton, onClick: () => fileInput.current.click(), loading: loadingLogo, disabled: loadingLogo }, { children: _jsx(Icon, { children: "upload" }) }))] }))] }, logo.id))) })), tab === 2 && (_jsxs(Box, { children: [_jsx(TextField, { multiline: true, fullWidth: true,
221
+ return (_jsxs(Root, Object.assign({ className: classNames(classes.root, className) }, { children: [_jsx(Typography, Object.assign({ variant: "h4", className: classes.title, alignSelf: "self-start" }, { children: _jsx(FormattedMessage, { id: "ui.onBoardingWidget.appearance", defaultMessage: "ui.onBoardingWidget.appearance" }) })), _jsx(Typography, Object.assign({ className: classes.summary }, { children: _jsx(FormattedMessage, { id: "ui.onBoardingWidget.step.appearance.summary", defaultMessage: "ui.onBoardingWidget.step.appearance.summary" }) })), _jsx(Button, Object.assign({ variant: "outlined", size: "small", color: "primary", onClick: handleOpen }, { children: _jsx(FormattedMessage, { id: "ui.onBoardingWidget.step.appearance.button", defaultMessage: "ui.onBoardingWidget.step.appearance.button" }) })), _jsxs(DrawerRoot, Object.assign({ className: classes.drawerRoot, anchor: "right", open: Boolean(anchorEl), onClose: handleClose }, { children: [_jsxs(Box, Object.assign({ className: classes.drawerHeader }, { children: [_jsx(Typography, Object.assign({ variant: "h4", color: "primary" }, { children: _jsx(FormattedMessage, { id: "ui.onBoardingWidget.step.appearance.header.title", defaultMessage: "ui.onBoardingWidget.step.appearance.header.title" }) })), _jsx(IconButton, Object.assign({ className: classes.drawerHeaderAction, onClick: handleClose }, { children: _jsx(Icon, { children: "close" }) }))] })), _jsxs(Tabs, Object.assign({ value: tab, onChange: handleTabChange, variant: "scrollable", scrollButtons: "auto", "aria-label": "scrollable-tabs" }, { children: [_jsx(Tab, { label: _jsx(FormattedMessage, { id: "ui.onBoardingWidget.step.appearance.colors.title", defaultMessage: "ui.onBoardingWidget.step.appearance.colors.title" }) }), _jsx(Tab, { label: _jsx(FormattedMessage, { id: "ui.onBoardingWidget.step.appearance.logo.title", defaultMessage: "ui.onBoardingWidget.step.appearance.logo.title" }) }), _jsx(Tab, { label: _jsx(FormattedMessage, { id: "ui.onBoardingWidget.step.appearance.titleSlogan.title", defaultMessage: "ui.onBoardingWidget.step.appearance.titleSlogan.title" }) })] })), _jsx(ScrollContainer, { children: _jsxs(Box, Object.assign({ className: classes.drawerContent }, { children: [tab === 0 && (_jsx(_Fragment, { children: state.colors.map((color) => (_jsxs(React.Fragment, { children: [_jsx(Typography, Object.assign({ variant: "h6" }, { children: formatColorLabel(color) })), _jsxs(Box, Object.assign({ className: classes.colorContainer }, { children: [_jsx(MuiColorInput, { inputRef: colorRef, className: classes.color, format: "hex", value: color.value, onChange: (newColor) => handleColorChange(newColor, color.name), isAlphaHidden: true, PopoverProps: { onClose: handleClosePopover } }), updatingColor && updatingColor === color.name && (_jsx(CircularProgress, { className: classes.colorProgress, color: "secondary", size: 24 }))] }))] }, color.id))) })), tab === 1 && (_jsx(_Fragment, { children: state.logos.map((logo) => (_jsxs(React.Fragment, { children: [_jsx(Typography, Object.assign({ variant: "h6" }, { children: formatLogoLabel(logo.name) })), _jsxs(Box, Object.assign({ className: classes.logoContainer }, { children: [_jsx("img", { src: logo.value, className: classes.logo }), _jsx("input", { type: "file", onChange: (event) => handleUpload(event, logo.name), hidden: true, accept: ".gif,.png,.jpg,.jpeg", id: logo.name }), _jsx(LoadingButton, Object.assign({ className: classes.uploadButton, onClick: () => document.getElementById(`${logo.name}`).click(), loading: Boolean(loadingLogo) && Boolean(logo.name === loadingLogo), disabled: Boolean(loadingLogo) && Boolean(logo.name !== loadingLogo) }, { children: _jsx(Icon, { children: "upload" }) }))] }))] }, logo.id))) })), tab === 2 && (_jsxs(Box, { children: [_jsx(TextField, { multiline: true, fullWidth: true,
225
222
  //className={classes.field}
226
223
  label: `${intl.formatMessage(messages.titleField)}`, margin: "normal", value: (_a = state === null || state === void 0 ? void 0 : state.slogans[0]) === null || _a === void 0 ? void 0 : _a.value, name: "application_slogan1", onChange: handleChange, InputProps: {
227
224
  endAdornment: _jsx(Typography, Object.assign({ variant: "body2" }, { children: ((_b = state.slogans[0].value) === null || _b === void 0 ? void 0 : _b.length) ? 50 - ((_c = state.slogans[0].value) === null || _c === void 0 ? void 0 : _c.length) : 50 }))
@@ -9,7 +9,7 @@ export interface EventActionsMenuProps extends IconButtonProps {
9
9
  /**
10
10
  * The event
11
11
  */
12
- event: SCEventType;
12
+ event?: SCEventType;
13
13
  /**
14
14
  * The event id
15
15
  */
@@ -1,21 +1,22 @@
1
1
  import { __rest } from "tslib";
2
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
3
  import { Divider, IconButton, List, ListItemIcon, Menu, MenuItem, SwipeableDrawer, useMediaQuery, useTheme } from '@mui/material';
6
- import { FormattedMessage } from 'react-intl';
7
4
  import Icon from '@mui/material/Icon';
8
- import classNames from 'classnames';
5
+ import { styled } from '@mui/material/styles';
9
6
  import { useThemeProps } from '@mui/system';
10
- import { SCRoutes, useSCFetchEvent, useSCRouting, useSCUser } from '@selfcommunity/react-core';
11
- import ConfirmDialog from '../../shared/ConfirmDialog/ConfirmDialog';
12
7
  import { EventService } from '@selfcommunity/api-services';
13
- import { ADD_EVENT_TO_CALENDAR, CANCEL_EVENT, GET_EVENT_LINK } from '../../constants/EventActionsMenu';
8
+ import { SCRoutes, useSCFetchEvent, useSCRouting, useSCUser } from '@selfcommunity/react-core';
14
9
  import { copyTextToClipboard } from '@selfcommunity/utils';
10
+ import classNames from 'classnames';
15
11
  import { enqueueSnackbar } from 'notistack';
16
12
  import PubSub from 'pubsub-js';
17
- import { SCGroupEventType, SCTopicType } from '../../constants/PubSub';
13
+ import { useMemo, useState } from 'react';
14
+ import { FormattedMessage } from 'react-intl';
18
15
  import EventForm from '../../components/EventForm';
16
+ import { ADD_EVENT_TO_CALENDAR, CANCEL_EVENT, GET_EVENT_LINK } from '../../constants/EventActionsMenu';
17
+ import { SCGroupEventType, SCTopicType } from '../../constants/PubSub';
18
+ import ConfirmDialog from '../../shared/ConfirmDialog/ConfirmDialog';
19
+ import { checkEventFinished } from '../../utils/events';
19
20
  const PREFIX = 'SCEventActionsMenu';
20
21
  const classes = {
21
22
  root: `${PREFIX}-root`,
@@ -82,12 +83,7 @@ export default function EventActionsMenu(inProps) {
82
83
  const scUserContext = useSCUser();
83
84
  const { scEvent, setSCEvent } = useSCFetchEvent({ id: eventId, event });
84
85
  const isEventAdmin = useMemo(() => { var _a; return scUserContext.user && ((_a = scEvent === null || scEvent === void 0 ? void 0 : scEvent.managed_by) === null || _a === void 0 ? void 0 : _a.id) === scUserContext.user.id; }, [scUserContext.user, (_a = scEvent === null || scEvent === void 0 ? void 0 : scEvent.managed_by) === null || _a === void 0 ? void 0 : _a.id]);
85
- const isEventFinished = useMemo(() => {
86
- if (scEvent && !scEvent.running) {
87
- return new Date().getTime() > new Date(scEvent.end_date || scEvent.start_date).getTime();
88
- }
89
- return false;
90
- }, [scEvent]);
86
+ const isEventFinished = useMemo(() => checkEventFinished(scEvent), [scEvent]);
91
87
  // HANDLERS
92
88
  const handleOpen = (event) => {
93
89
  setAnchorEl(event.currentTarget);
@@ -153,7 +149,7 @@ export default function EventActionsMenu(inProps) {
153
149
  const renderList = () => {
154
150
  return [
155
151
  _jsxs(MenuItem, Object.assign({ className: classes.item, onClick: () => handleAction(GET_EVENT_LINK) }, { children: [_jsx(ListItemIcon, { children: _jsx(Icon, { children: "link" }) }), _jsx(FormattedMessage, { id: "ui.shared.eventActionsMenu.item.link", defaultMessage: "ui.shared.eventActionsMenu.item.link" })] }), "link"),
156
- _jsxs(MenuItem, Object.assign({ className: classes.item, onClick: () => handleAction(ADD_EVENT_TO_CALENDAR) }, { children: [_jsx(ListItemIcon, { children: _jsx(Icon, { children: "CalendarIcon" }) }), _jsx(FormattedMessage, { id: "ui.shared.eventActionsMenu.item.calendar", defaultMessage: "ui.shared.eventActionsMenu.item.calendar" })] }), "calendar"),
152
+ !isEventFinished && (_jsxs(MenuItem, Object.assign({ className: classes.item, onClick: () => handleAction(ADD_EVENT_TO_CALENDAR) }, { children: [_jsx(ListItemIcon, { children: _jsx(Icon, { children: "CalendarIcon" }) }), _jsx(FormattedMessage, { id: "ui.shared.eventActionsMenu.item.calendar", defaultMessage: "ui.shared.eventActionsMenu.item.calendar" })] }), "calendar")),
157
153
  isEventAdmin &&
158
154
  !isEventFinished && [
159
155
  _jsx(Divider, {}, "divider"),
@@ -0,0 +1,2 @@
1
+ import { SCEventType } from '@selfcommunity/types';
2
+ export declare function checkEventFinished(event: SCEventType | null): boolean;
@@ -0,0 +1,6 @@
1
+ export function checkEventFinished(event) {
2
+ if (event && !event.running) {
3
+ return new Date().getTime() > new Date(event.end_date || event.start_date).getTime();
4
+ }
5
+ return false;
6
+ }
@@ -14,6 +14,7 @@ export declare const actionWidgetTypes: {
14
14
  LOAD_PREVIOUS_FAILURE: string;
15
15
  SET_RESULTS: string;
16
16
  SET_VISIBLE_ITEMS: string;
17
+ INITIALIZE: string;
17
18
  RESET: string;
18
19
  };
19
20
  /**
@@ -15,6 +15,7 @@ export const actionWidgetTypes = {
15
15
  LOAD_PREVIOUS_FAILURE: '_load_previous_failure',
16
16
  SET_RESULTS: '_set_results',
17
17
  SET_VISIBLE_ITEMS: '_set_visible_items',
18
+ INITIALIZE: '_initialize',
18
19
  RESET: '_reset'
19
20
  };
20
21
  /**
@@ -53,6 +54,19 @@ export function dataWidgetReducer(state, action) {
53
54
  case actionWidgetTypes.RESET:
54
55
  _state = { isLoadingNext: false, next: null, results: [], count: 0, errorLoadNext: null, initialized: false };
55
56
  break;
57
+ case actionWidgetTypes.INITIALIZE:
58
+ _state = {
59
+ cacheKey: action.payload.cacheKey ? action.payload.cacheKey : null,
60
+ count: action.payload.count ? action.payload.count : 0,
61
+ results: action.payload.results ? action.payload.results : [],
62
+ next: action.payload.next ? action.payload.next : null,
63
+ previous: action.payload.previous ? action.payload.previous : null,
64
+ isLoadingNext: action.payload.isLoadingNext ? action.payload.isLoadingNext : false,
65
+ isLoadingPrevious: action.payload.isLoadingPrevious ? action.payload.isLoadingPrevious : false,
66
+ visibleItems: action.payload.visibleItems ? action.payload.visibleItems : null,
67
+ initialized: false
68
+ };
69
+ break;
56
70
  }
57
71
  LRUCache.set(_state.cacheKey, _state);
58
72
  return _state;