@selfcommunity/react-ui 0.7.50-event.29 → 0.7.50-events.28

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 (58) hide show
  1. package/lib/cjs/components/Category/Category.d.ts +1 -1
  2. package/lib/cjs/components/Category/Category.js +1 -1
  3. package/lib/cjs/components/Event/Event.d.ts +0 -6
  4. package/lib/cjs/components/Event/Event.js +4 -4
  5. package/lib/cjs/components/Event/Skeleton.d.ts +16 -2
  6. package/lib/cjs/components/Event/Skeleton.js +16 -8
  7. package/lib/cjs/components/Event/index.d.ts +2 -2
  8. package/lib/cjs/components/EventForm/EventForm.js +30 -17
  9. package/lib/cjs/components/EventInviteButton/EventInviteButton.d.ts +57 -0
  10. package/lib/cjs/components/EventInviteButton/EventInviteButton.js +284 -0
  11. package/lib/cjs/components/EventInviteButton/index.d.ts +3 -0
  12. package/lib/cjs/components/EventInviteButton/index.js +5 -0
  13. package/lib/cjs/components/Events/Events.d.ts +64 -0
  14. package/lib/cjs/components/Events/Events.js +230 -0
  15. package/lib/cjs/components/Events/Skeleton.d.ts +38 -0
  16. package/lib/cjs/components/Events/Skeleton.js +45 -0
  17. package/lib/cjs/components/Events/constants.d.ts +1 -0
  18. package/lib/cjs/components/Events/constants.js +4 -0
  19. package/lib/cjs/components/Events/index.d.ts +4 -0
  20. package/lib/cjs/components/Events/index.js +8 -0
  21. package/lib/cjs/components/Events/prefetchedEvents.d.ts +271 -0
  22. package/lib/cjs/components/Events/prefetchedEvents.js +278 -0
  23. package/lib/cjs/components/FeedObject/FeedObject.d.ts +1 -0
  24. package/lib/cjs/components/FeedObject/FeedObject.js +16 -4
  25. package/lib/cjs/constants/PubSub.d.ts +3 -8
  26. package/lib/cjs/constants/PubSub.js +2 -1
  27. package/lib/cjs/index.d.ts +4 -2
  28. package/lib/cjs/index.js +7 -2
  29. package/lib/esm/components/Category/Category.d.ts +1 -1
  30. package/lib/esm/components/Category/Category.js +1 -1
  31. package/lib/esm/components/Event/Event.d.ts +0 -6
  32. package/lib/esm/components/Event/Event.js +4 -4
  33. package/lib/esm/components/Event/Skeleton.d.ts +16 -2
  34. package/lib/esm/components/Event/Skeleton.js +17 -9
  35. package/lib/esm/components/Event/index.d.ts +2 -2
  36. package/lib/esm/components/EventForm/EventForm.js +30 -17
  37. package/lib/esm/components/EventInviteButton/EventInviteButton.d.ts +57 -0
  38. package/lib/esm/components/EventInviteButton/EventInviteButton.js +281 -0
  39. package/lib/esm/components/EventInviteButton/index.d.ts +3 -0
  40. package/lib/esm/components/EventInviteButton/index.js +2 -0
  41. package/lib/esm/components/Events/Events.d.ts +64 -0
  42. package/lib/esm/components/Events/Events.js +227 -0
  43. package/lib/esm/components/Events/Skeleton.d.ts +38 -0
  44. package/lib/esm/components/Events/Skeleton.js +42 -0
  45. package/lib/esm/components/Events/constants.d.ts +1 -0
  46. package/lib/esm/components/Events/constants.js +1 -0
  47. package/lib/esm/components/Events/index.d.ts +4 -0
  48. package/lib/esm/components/Events/index.js +4 -0
  49. package/lib/esm/components/Events/prefetchedEvents.d.ts +271 -0
  50. package/lib/esm/components/Events/prefetchedEvents.js +275 -0
  51. package/lib/esm/components/FeedObject/FeedObject.d.ts +1 -0
  52. package/lib/esm/components/FeedObject/FeedObject.js +16 -4
  53. package/lib/esm/constants/PubSub.d.ts +3 -8
  54. package/lib/esm/constants/PubSub.js +2 -1
  55. package/lib/esm/index.d.ts +4 -2
  56. package/lib/esm/index.js +3 -1
  57. package/lib/umd/react-ui.js +1 -1
  58. package/package.json +6 -6
@@ -120,13 +120,13 @@ export default function EventForm(inProps) {
120
120
  // INTL
121
121
  const intl = useIntl();
122
122
  const initialFieldState = {
123
- emotionalImageOriginal: '',
124
- emotionalImageOriginalFile: '',
123
+ imageOriginal: '',
124
+ imageOriginalFile: '',
125
125
  startDate: null,
126
126
  startTime: null,
127
127
  endDate: null,
128
128
  endTime: null,
129
- location: '',
129
+ location: SCEventLocationType.PERSON,
130
130
  geolocation: '',
131
131
  lat: null,
132
132
  lng: null,
@@ -144,8 +144,9 @@ export default function EventForm(inProps) {
144
144
  // PREFERENCES
145
145
  const scPreferences = useSCPreferences();
146
146
  const privateEnabled = useMemo(() => scPreferences.preferences[SCPreferences.CONFIGURATIONS_EVENTS_PRIVATE_ENABLED].value, [scPreferences.preferences]);
147
- const _backgroundCover = Object.assign({}, (field.emotionalImageOriginal
148
- ? { background: `url('${field.emotionalImageOriginal}') center / cover` }
147
+ const visibilityEnabled = useMemo(() => scPreferences.preferences[SCPreferences.CONFIGURATIONS_EVENTS_VISIBILITY_ENABLED].value, [scPreferences.preferences]);
148
+ const _backgroundCover = Object.assign({}, (field.imageOriginal
149
+ ? { background: `url('${field.imageOriginal}') center / cover` }
149
150
  : { background: `url('${scPreferences.preferences[SCPreferences.IMAGES_USER_DEFAULT_COVER].value}') center / cover` }));
150
151
  const combineDateAndTime = (date, time) => {
151
152
  if (date && time) {
@@ -159,14 +160,14 @@ export default function EventForm(inProps) {
159
160
  return null;
160
161
  };
161
162
  function handleChangeCover(cover) {
162
- setField((prev) => (Object.assign(Object.assign({}, prev), { ['emotionalImageOriginalFile']: cover })));
163
+ setField((prev) => (Object.assign(Object.assign({}, prev), { ['imageOriginalFile']: cover })));
163
164
  const reader = new FileReader();
164
165
  reader.onloadend = () => {
165
- setField((prev) => (Object.assign(Object.assign({}, prev), { ['emotionalImageOriginal']: reader.result })));
166
+ setField((prev) => (Object.assign(Object.assign({}, prev), { ['imageOriginal']: reader.result })));
166
167
  };
167
168
  reader.readAsDataURL(cover);
168
- if (error.emotionalImageOriginalError) {
169
- delete error.emotionalImageOriginalError;
169
+ if (error.imageOriginalError) {
170
+ delete error.imageOriginalError;
170
171
  setError(error);
171
172
  }
172
173
  }
@@ -176,8 +177,8 @@ export default function EventForm(inProps) {
176
177
  const handleSubmit = () => {
177
178
  setField((prev) => (Object.assign(Object.assign({}, prev), { ['isSubmitting']: true })));
178
179
  const formData = new FormData();
179
- if (field.emotionalImageOriginalFile) {
180
- formData.append('emotional_image_original', field.emotionalImageOriginalFile);
180
+ if (field.imageOriginalFile) {
181
+ formData.append('image_original', field.imageOriginalFile);
181
182
  }
182
183
  formData.append('name', field.name);
183
184
  formData.append('start_date', combineDateAndTime(field.startDate, field.startTime));
@@ -197,6 +198,9 @@ export default function EventForm(inProps) {
197
198
  if (privateEnabled) {
198
199
  formData.append('privacy', field.isPublic ? SCEventPrivacyType.PUBLIC : SCEventPrivacyType.PRIVATE);
199
200
  }
201
+ if (visibilityEnabled) {
202
+ formData.append('visible', true);
203
+ }
200
204
  formData.append('description', field.description);
201
205
  EventService.createEvent(formData, { headers: { 'Content-Type': 'multipart/form-data' } })
202
206
  .then((data) => {
@@ -205,7 +209,15 @@ export default function EventForm(inProps) {
205
209
  setField((prev) => (Object.assign(Object.assign({}, prev), { ['isSubmitting']: false })));
206
210
  })
207
211
  .catch((e) => {
208
- setError(Object.assign(Object.assign({}, error), formatHttpErrorCode(e)));
212
+ const _error = formatHttpErrorCode(e);
213
+ // eslint-disable-next-line @typescript-eslint/ban-ts-ignore,@typescript-eslint/ban-ts-comment
214
+ // @ts-ignore
215
+ if (Object.values(_error)[0].error === 'unique') {
216
+ setError(Object.assign(Object.assign({}, error), { ['nameError']: React.createElement(FormattedMessage, { id: "ui.eventForm.name.error.unique", defaultMessage: "ui.eventForm.name.error.unique" }) }));
217
+ }
218
+ else {
219
+ setError(Object.assign(Object.assign({}, error), _error));
220
+ }
209
221
  setField((prev) => (Object.assign(Object.assign({}, prev), { ['isSubmitting']: false })));
210
222
  Logger.error(SCOPE_SC_UI, e);
211
223
  });
@@ -231,7 +243,8 @@ export default function EventForm(inProps) {
231
243
  return (React.createElement(Root, Object.assign({ DialogContentProps: { dividers: false }, title: React.createElement(FormattedMessage, { id: "ui.eventForm.title", defaultMessage: "ui.eventForm.title" }), open: open, onClose: onClose, className: classNames(classes.root, className), actions: React.createElement(LoadingButton, { loading: field.isSubmitting, disabled: !field.name ||
232
244
  (!field.startDate && !field.startTime) ||
233
245
  (field.location === SCEventLocationType.ONLINE && !field.link) ||
234
- ((field.recurring !== SCEventRecurrenceType.NEVER) && (!field.endDate && !field.endTime)) ||
246
+ (field.location === SCEventLocationType.PERSON && !field.geolocation) ||
247
+ (field.recurring !== SCEventRecurrenceType.NEVER && !field.endDate && !field.endTime) ||
235
248
  Object.keys(error).length !== 0 ||
236
249
  field.name.length > EVENT_TITLE_MAX_LENGTH ||
237
250
  field.description.length > EVENT_DESCRIPTION_MAX_LENGTH, variant: "contained", onClick: handleSubmit, color: "secondary" }, React.createElement(FormattedMessage, { id: "ui.eventForm.button.create", defaultMessage: "ui.eventForm.button.create" })) }, rest),
@@ -241,7 +254,7 @@ export default function EventForm(inProps) {
241
254
  React.createElement(FormGroup, { className: classes.form },
242
255
  React.createElement(TextField, { required: true, className: classes.name, placeholder: `${intl.formatMessage(messages.name)}`, margin: "normal", value: field.name, name: "name", onChange: handleChange, InputProps: {
243
256
  endAdornment: React.createElement(Typography, { variant: "body2" }, EVENT_TITLE_MAX_LENGTH - field.name.length)
244
- }, error: Boolean(((_a = field === null || field === void 0 ? void 0 : field.name) === null || _a === void 0 ? void 0 : _a.length) > EVENT_TITLE_MAX_LENGTH), helperText: ((_b = field === null || field === void 0 ? void 0 : field.name) === null || _b === void 0 ? void 0 : _b.length) > EVENT_TITLE_MAX_LENGTH ? (React.createElement(FormattedMessage, { id: "ui.eventForm.name.error.maxLength", defaultMessage: "ui.eventForm.name.error.maxLength" })) : null }),
257
+ }, error: Boolean(((_a = field === null || field === void 0 ? void 0 : field.name) === null || _a === void 0 ? void 0 : _a.length) > EVENT_TITLE_MAX_LENGTH) || Boolean(error[`nameError`]), helperText: ((_b = field === null || field === void 0 ? void 0 : field.name) === null || _b === void 0 ? void 0 : _b.length) > EVENT_TITLE_MAX_LENGTH ? (React.createElement(FormattedMessage, { id: "ui.eventForm.name.error.maxLength", defaultMessage: "ui.eventForm.name.error.maxLength" })) : error[`nameError`] ? (error[`nameError`]) : null }),
245
258
  React.createElement(Box, { className: classes.dateTime },
246
259
  React.createElement(LocalizationProvider, { dateAdapter: AdapterDateFns, adapterLocale: scContext.settings.locale.default === 'it' ? itLocale : enLocale },
247
260
  React.createElement(MobileDatePicker, { className: classes.picker, disablePast: true, label: field.startDate && React.createElement(FormattedMessage, { id: "ui.eventForm.date.placeholder", defaultMessage: "ui.eventForm.date.placeholder" }), value: field.startDate, slots: {
@@ -255,7 +268,7 @@ export default function EventForm(inProps) {
255
268
  toolbarTitle: React.createElement(FormattedMessage, { id: "ui.eventForm.date.title", defaultMessage: "ui.eventForm.date.title" })
256
269
  }
257
270
  }, onChange: (value) => handleChangeDateTime(value, 'startDate') }),
258
- React.createElement(MobileTimePicker, { className: classes.picker, label: field.startTime && React.createElement(FormattedMessage, { id: "ui.eventForm.time.placeholder", defaultMessage: "ui.eventForm.time.placeholder" }), value: field.startTime, slots: {
271
+ React.createElement(MobileTimePicker, { className: classes.picker, disablePast: true, label: field.startTime && React.createElement(FormattedMessage, { id: "ui.eventForm.time.placeholder", defaultMessage: "ui.eventForm.time.placeholder" }), value: field.startTime, slots: {
259
272
  textField: (params) => (React.createElement(TextField, Object.assign({}, params, { InputProps: Object.assign(Object.assign({}, params.InputProps), { placeholder: `${intl.formatMessage(messages.startTime)}`, startAdornment: (React.createElement(InputAdornment, { position: "start" },
260
273
  React.createElement(IconButton, null,
261
274
  React.createElement(Icon, null, "access_time")))) }) })))
@@ -284,12 +297,12 @@ export default function EventForm(inProps) {
284
297
  React.createElement(IconButton, null,
285
298
  React.createElement(Icon, null, "calendar_off")))) }) })))
286
299
  }, onChange: (value) => handleChangeDateTime(value, 'endDate') }),
287
- React.createElement(MobileTimePicker, { className: classes.picker, label: field.endTime && React.createElement(FormattedMessage, { id: "ui.eventForm.time.end.placeholder", defaultMessage: "ui.eventForm.time.end.placeholder" }), value: field.endTime, slots: {
300
+ React.createElement(MobileTimePicker, { className: classes.picker, disablePast: true, label: field.endTime && React.createElement(FormattedMessage, { id: "ui.eventForm.time.end.placeholder", defaultMessage: "ui.eventForm.time.end.placeholder" }), value: field.endTime, slots: {
288
301
  textField: (params) => (React.createElement(TextField, Object.assign({}, params, { InputProps: Object.assign(Object.assign({}, params.InputProps), { placeholder: `${intl.formatMessage(messages.endTime)}`, startAdornment: (React.createElement(InputAdornment, { position: "start" },
289
302
  React.createElement(IconButton, null,
290
303
  React.createElement(Icon, null, "access_time")))) }) })))
291
304
  }, onChange: (value) => handleChangeDateTime(value, 'endTime') })))),
292
- React.createElement(Button, { variant: "text", color: "secondary", onClick: () => setField((prev) => (Object.assign(Object.assign({}, prev), { ['showEndDateTime']: !field.showEndDateTime }))) },
305
+ React.createElement(Button, { variant: "text", color: "secondary", onClick: () => setField((prev) => (Object.assign(Object.assign({}, prev), { ['showEndDateTime']: !field.showEndDateTime }))), disabled: field.showEndDateTime && field.recurring !== SCEventRecurrenceType.NEVER },
293
306
  React.createElement(FormattedMessage, { id: "ui.eventForm.dateTime.placeholder", defaultMessage: "ui.eventForm.dateTime.placeholder", values: { symbol: field.showEndDateTime ? '-' : '+' } })),
294
307
  React.createElement(EventAddress, { forwardGeolocationData: handleGeoData }),
295
308
  privateEnabled && (React.createElement(Box, { className: classes.privacySection },
@@ -0,0 +1,57 @@
1
+ import { ButtonProps } from '@mui/material/Button/Button';
2
+ import { SCEventType } from '@selfcommunity/types';
3
+ export interface EventInviteButtonProps extends ButtonProps {
4
+ /**
5
+ * Overrides or extends the styles applied to the component.
6
+ * @default null
7
+ */
8
+ className?: string;
9
+ /**
10
+ * Event Object
11
+ * @default null
12
+ */
13
+ event?: SCEventType;
14
+ /**
15
+ * Id of the event
16
+ * @default null
17
+ */
18
+ eventId?: number | string;
19
+ /**
20
+ * Functions to handle invitations sending in event creation mode
21
+ * @default null
22
+ */
23
+ handleInvitations?: (data: any) => any;
24
+ /**
25
+ * Any other properties
26
+ */
27
+ [p: string]: any;
28
+ }
29
+ /**
30
+ *> API documentation for the Community-JS Event Invite Button component. Learn about the available props and the CSS API.
31
+ *
32
+ #### Import
33
+ ```jsx
34
+ import {SCEventInviteButton} from '@selfcommunity/react-ui';
35
+ ```
36
+
37
+ #### Component Name
38
+ The name `SCEventInviteButton` can be used when providing style overrides in the theme.
39
+
40
+ #### CSS
41
+
42
+ |Rule Name|Global class|Description|
43
+ |---|---|---|
44
+ |root|.SCEventInviteButton-root|Styles applied to the root element.|
45
+ |dialogRoot|.SCEventInviteButton-dialog-root|Styles applied to the dialog root.|
46
+ |dialogTitle|.SCEventInviteButton-dialog-title|Styles applied to the dialog title element.|
47
+ |dialogContent|.SCEventInviteButton-dialog-content|Styles applied to the dialog content.|
48
+ |autocomplete|.SCEventInviteButton-autocomplete|Styles applied to the autocomplete element.|
49
+ |icon|.SCEventInviteButton-icon|Styles applied to the autocomplete icon element.|
50
+ |input|.SCEventInviteButton-input|Styles applied to the autocomplete input element.|
51
+ |clear|.SCEventInviteButton-clear|Styles applied to the autocomplete clear icon element.|
52
+ |invitedBox|.SCEventInviteButton-invited-box|Styles applied to the invited users box.|
53
+ |suggested|.SCEventInviteButton-suggested|Styles applied to the suggested users box.|
54
+
55
+ * @param inProps
56
+ */
57
+ export default function EventInviteButton(inProps: EventInviteButtonProps): JSX.Element;
@@ -0,0 +1,281 @@
1
+ import { __rest } from "tslib";
2
+ import React, { useContext, useEffect, useMemo, useState } from 'react';
3
+ import { useThemeProps } from '@mui/system';
4
+ import { styled } from '@mui/material/styles';
5
+ import { Avatar, Box, Button, Chip, Icon, IconButton, InputAdornment, TextField, Typography } from '@mui/material';
6
+ import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
7
+ import { SCUserContext, useSCFetchEvent } from '@selfcommunity/react-core';
8
+ import classNames from 'classnames';
9
+ import BaseDialog from '../../shared/BaseDialog';
10
+ import { LoadingButton } from '@mui/lab';
11
+ import { EventService } from '@selfcommunity/api-services';
12
+ import Autocomplete from '@mui/material/Autocomplete';
13
+ import User from '../User';
14
+ import { SCOPE_SC_UI } from '../../constants/Errors';
15
+ import { Logger } from '@selfcommunity/utils';
16
+ import { SCGroupEventType, SCTopicType } from '../../constants/PubSub';
17
+ import PubSub from 'pubsub-js';
18
+ const messages = defineMessages({
19
+ placeholder: {
20
+ id: 'ui.eventInviteButton.searchBar.placeholder',
21
+ defaultMessage: 'ui.eventInviteButton.searchBar.placeholder'
22
+ }
23
+ });
24
+ const PREFIX = 'SCEventInviteButton';
25
+ const classes = {
26
+ root: `${PREFIX}-root`,
27
+ dialogRoot: `${PREFIX}-dialog-root`,
28
+ dialogTitle: `${PREFIX}-dialog-title`,
29
+ dialogContent: `${PREFIX}-dialog-content`,
30
+ autocomplete: `${PREFIX}-autocomplete`,
31
+ icon: `${PREFIX}-icon`,
32
+ input: `${PREFIX}-input`,
33
+ clear: `${PREFIX}-clear`,
34
+ invitedBox: `${PREFIX}-invited-box`,
35
+ suggested: `${PREFIX}-suggested`
36
+ };
37
+ const Root = styled(Button, {
38
+ name: PREFIX,
39
+ slot: 'Root',
40
+ overridesResolver: (props, styles) => styles.root
41
+ })(({ theme }) => ({}));
42
+ const DialogRoot = styled(BaseDialog, {
43
+ name: PREFIX,
44
+ slot: 'Root',
45
+ overridesResolver: (props, styles) => styles.dialogRoot
46
+ })(({ theme }) => ({}));
47
+ /**
48
+ *> API documentation for the Community-JS Event Invite Button component. Learn about the available props and the CSS API.
49
+ *
50
+ #### Import
51
+ ```jsx
52
+ import {SCEventInviteButton} from '@selfcommunity/react-ui';
53
+ ```
54
+
55
+ #### Component Name
56
+ The name `SCEventInviteButton` can be used when providing style overrides in the theme.
57
+
58
+ #### CSS
59
+
60
+ |Rule Name|Global class|Description|
61
+ |---|---|---|
62
+ |root|.SCEventInviteButton-root|Styles applied to the root element.|
63
+ |dialogRoot|.SCEventInviteButton-dialog-root|Styles applied to the dialog root.|
64
+ |dialogTitle|.SCEventInviteButton-dialog-title|Styles applied to the dialog title element.|
65
+ |dialogContent|.SCEventInviteButton-dialog-content|Styles applied to the dialog content.|
66
+ |autocomplete|.SCEventInviteButton-autocomplete|Styles applied to the autocomplete element.|
67
+ |icon|.SCEventInviteButton-icon|Styles applied to the autocomplete icon element.|
68
+ |input|.SCEventInviteButton-input|Styles applied to the autocomplete input element.|
69
+ |clear|.SCEventInviteButton-clear|Styles applied to the autocomplete clear icon element.|
70
+ |invitedBox|.SCEventInviteButton-invited-box|Styles applied to the invited users box.|
71
+ |suggested|.SCEventInviteButton-suggested|Styles applied to the suggested users box.|
72
+
73
+ * @param inProps
74
+ */
75
+ export default function EventInviteButton(inProps) {
76
+ var _a;
77
+ //PROPS
78
+ const props = useThemeProps({
79
+ props: inProps,
80
+ name: PREFIX
81
+ });
82
+ const { className, event, eventId, handleInvitations = null } = props, rest = __rest(props, ["className", "event", "eventId", "handleInvitations"]);
83
+ // CONTEXT
84
+ const scUserContext = useContext(SCUserContext);
85
+ // STATE
86
+ const [open, setOpen] = useState(false);
87
+ const [isSending, setIsSending] = useState(false);
88
+ const [value, setValue] = useState('');
89
+ const [suggested, setSuggested] = useState([]);
90
+ const [list, setList] = useState([]);
91
+ const [loading, setLoading] = useState(false);
92
+ const [invited, setInvited] = useState([]);
93
+ /**
94
+ * Notify UI when a member is invited to a event
95
+ * @param event
96
+ * @param usersInvited
97
+ */
98
+ function notifyChanges(event, usersInvited) {
99
+ if (event && usersInvited) {
100
+ PubSub.publish(`${SCTopicType.EVENT}.${SCGroupEventType.INVITE_MEMBER}`, usersInvited);
101
+ }
102
+ }
103
+ function convertToInvitedUsersObject(data) {
104
+ const invite_users = {};
105
+ data.forEach((user, index) => {
106
+ invite_users[`invite_users[${index}]`] = user.id;
107
+ });
108
+ return invite_users;
109
+ }
110
+ /**
111
+ * Memoized users invited ids
112
+ */
113
+ const ids = useMemo(() => {
114
+ if (invited) {
115
+ return invited.map((u) => {
116
+ return parseInt(u.id, 10);
117
+ });
118
+ }
119
+ return [invited];
120
+ }, [invited]);
121
+ // HOOKS
122
+ const { scEvent } = useSCFetchEvent({ id: eventId, event });
123
+ 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]);
124
+ // INTL
125
+ const intl = useIntl();
126
+ function fetchResults() {
127
+ setLoading(true);
128
+ EventService.getEventSuggestedUsers(scEvent === null || scEvent === void 0 ? void 0 : scEvent.id, value)
129
+ .then((data) => {
130
+ setLoading(false);
131
+ setSuggested(data.results);
132
+ })
133
+ .catch((error) => {
134
+ setLoading(false);
135
+ Logger.error(SCOPE_SC_UI, error);
136
+ });
137
+ }
138
+ function fetchGeneralResults() {
139
+ setLoading(true);
140
+ EventService.getEventsSuggestedUsers(value)
141
+ .then((data) => {
142
+ setLoading(false);
143
+ setSuggested(data.results);
144
+ })
145
+ .catch((error) => {
146
+ setLoading(false);
147
+ Logger.error(SCOPE_SC_UI, error);
148
+ });
149
+ }
150
+ useEffect(() => {
151
+ if (scEvent === null || scEvent === void 0 ? void 0 : scEvent.id) {
152
+ EventService.getEventSuggestedUsers(scEvent === null || scEvent === void 0 ? void 0 : scEvent.id, value).then((data) => {
153
+ setLoading(false);
154
+ setList(data.results);
155
+ });
156
+ }
157
+ else {
158
+ EventService.getEventsSuggestedUsers(value).then((data) => {
159
+ setLoading(false);
160
+ setList(data.results);
161
+ });
162
+ }
163
+ }, [scEvent === null || scEvent === void 0 ? void 0 : scEvent.id]);
164
+ /**
165
+ * If a value is entered in new message field, it fetches user suggested
166
+ */
167
+ useEffect(() => {
168
+ if (scEvent) {
169
+ fetchResults();
170
+ }
171
+ else {
172
+ fetchGeneralResults();
173
+ }
174
+ }, [value, scEvent]);
175
+ /**
176
+ * Handles dialog close
177
+ */
178
+ const handleClose = () => {
179
+ setOpen((p) => !p);
180
+ };
181
+ /**
182
+ * Handles invitation sending
183
+ */
184
+ const handleSendInvitations = () => {
185
+ if (handleInvitations) {
186
+ handleInvitations(convertToInvitedUsersObject(invited));
187
+ setOpen(false);
188
+ }
189
+ else {
190
+ const data = { users: ids };
191
+ setIsSending(true);
192
+ EventService.inviteOrAcceptEventRequest(scEvent.id, data)
193
+ .then(() => {
194
+ setIsSending(false);
195
+ setOpen(false);
196
+ setInvited([]);
197
+ notifyChanges(scEvent, invited);
198
+ })
199
+ .catch((error) => {
200
+ setOpen(false);
201
+ setLoading(false);
202
+ Logger.error(SCOPE_SC_UI, error);
203
+ });
204
+ }
205
+ };
206
+ // Autocomplete Handlers
207
+ const handleInputChange = (event, value, reason) => {
208
+ switch (reason) {
209
+ case 'input':
210
+ setValue(value);
211
+ !value && setSuggested([]);
212
+ break;
213
+ case 'reset':
214
+ setValue(value);
215
+ break;
216
+ }
217
+ };
218
+ const handleChange = (event, value, reason, details) => {
219
+ event.preventDefault();
220
+ event.stopPropagation();
221
+ switch (reason) {
222
+ case 'selectOption':
223
+ setInvited(value);
224
+ setList((prev) => prev.filter((u) => u.id !== details.option.id));
225
+ break;
226
+ case 'removeOption':
227
+ setInvited(value);
228
+ setList((prev) => [...prev, details.option]);
229
+ break;
230
+ }
231
+ return false;
232
+ };
233
+ const handleUserInvite = (user) => {
234
+ setInvited((prev) => [...prev, user]);
235
+ setList((prev) => prev.filter((u) => u.id !== user.id));
236
+ };
237
+ const handleDelete = (option) => {
238
+ setInvited(invited.filter((v) => v !== option));
239
+ setList((prev) => [...prev, option]);
240
+ };
241
+ const filterOptions = (options, { inputValue }) => {
242
+ return options.filter((option) => {
243
+ const usernameMatch = option.username.toLowerCase().includes(inputValue.toLowerCase());
244
+ const nameMatch = option.real_name.toLowerCase().includes(inputValue.toLowerCase());
245
+ return usernameMatch || nameMatch;
246
+ });
247
+ };
248
+ /**
249
+ * If in event edit mode and logged-in user is not also the event manager, the component is hidden.
250
+ // */
251
+ if (event && !isEventAdmin) {
252
+ return null;
253
+ }
254
+ /**
255
+ * Renders root object
256
+ */
257
+ return (React.createElement(React.Fragment, null,
258
+ React.createElement(Root, Object.assign({ className: classNames(classes.root, className), onClick: handleClose, variant: scEvent ? 'contained' : 'outlined', color: scEvent ? 'secondary' : 'inherit', startIcon: React.createElement(Icon, null, "add") }, rest),
259
+ React.createElement(FormattedMessage, { id: "ui.eventInviteButton", defaultMessage: "ui.eventInviteButton" })),
260
+ open && (React.createElement(DialogRoot, { DialogContentProps: { dividers: false }, open: true, className: classes.dialogRoot, title: React.createElement(React.Fragment, null,
261
+ React.createElement(IconButton, { onClick: handleClose },
262
+ React.createElement(Icon, null, "arrow_back")),
263
+ React.createElement(Typography, { className: classes.dialogTitle },
264
+ React.createElement(FormattedMessage, { id: "ui.eventInviteButton.dialog.title", defaultMessage: "ui.eventInviteButton.dialog.title" })),
265
+ React.createElement(LoadingButton, { size: "small", color: "secondary", variant: "contained", onClick: handleSendInvitations, loading: isSending, disabled: !invited.length },
266
+ React.createElement(FormattedMessage, { id: "ui.eventInviteButton.dialog.button.end", defaultMessage: "ui.eventInviteButton.dialog.button.end" }))) },
267
+ React.createElement(Box, { className: classes.dialogContent },
268
+ React.createElement(Autocomplete, { className: classes.autocomplete, loading: loading, size: "small", multiple: true, freeSolo: true, disableClearable: true, options: suggested, onChange: handleChange, onInputChange: handleInputChange, inputValue: value, filterOptions: filterOptions, value: invited, getOptionLabel: (option) => (option ? option.username : '...'), isOptionEqualToValue: (option, value) => (option ? value.id === option.id : false), renderTags: () => null, renderOption: (props, option) => (React.createElement(Box, Object.assign({ component: "li" }, props),
269
+ React.createElement(Avatar, { alt: option.username, src: option.avatar }),
270
+ React.createElement(Typography, { ml: 1 }, option.username))), renderInput: (params) => (React.createElement(TextField, Object.assign({}, params, { variant: "outlined", placeholder: `${intl.formatMessage(messages.placeholder)}`, InputProps: Object.assign(Object.assign({}, params.InputProps), { className: classes.input, startAdornment: (React.createElement(React.Fragment, null,
271
+ React.createElement(InputAdornment, { position: "start" },
272
+ React.createElement(Icon, { className: classes.icon }, "search")),
273
+ params.InputProps.startAdornment)) }) }))) }),
274
+ React.createElement(Box, { className: classes.invitedBox }, invited.map((option, index) => (React.createElement(Chip, { key: index, avatar: React.createElement(Avatar, { alt: option.username, src: option.avatar }), label: option.username, onDelete: () => {
275
+ handleDelete(option);
276
+ }, style: { marginRight: 8 } })))),
277
+ React.createElement(Box, { className: classes.suggested },
278
+ list.length !== 0 && (React.createElement(Typography, { variant: "h4", fontWeight: "bold" },
279
+ React.createElement(FormattedMessage, { id: "ui.eventInviteButton.dialog.content.list", defaultMessage: "ui.eventInviteButton.dialog.content.list" }))),
280
+ list.slice(0, 5).map((user, index) => (React.createElement(User, { elevation: 0, actions: React.createElement(React.Fragment, null), user: user, userId: user.id, key: index, buttonProps: { onClick: () => handleUserInvite(user) } })))))))));
281
+ }
@@ -0,0 +1,3 @@
1
+ import EventInviteButton, { EventInviteButtonProps } from './EventInviteButton';
2
+ export default EventInviteButton;
3
+ export { EventInviteButtonProps };
@@ -0,0 +1,2 @@
1
+ import EventInviteButton from './EventInviteButton';
2
+ export default EventInviteButton;
@@ -0,0 +1,64 @@
1
+ import { EventProps } from '../Event';
2
+ export interface EventsProps {
3
+ /**
4
+ * Overrides or extends the styles applied to the component.
5
+ * @default null
6
+ */
7
+ className?: string;
8
+ /**
9
+ * Feed API Query Params
10
+ * @default [{'limit': 20, 'offset': 0}]
11
+ */
12
+ endpointQueryParams?: Record<string, string | number>;
13
+ /**
14
+ * Props to spread to single event object
15
+ * @default {}
16
+ */
17
+ EventComponentProps?: EventProps;
18
+ /**
19
+ * Show/Hide filters
20
+ * @default true
21
+ */
22
+ showFilters?: boolean;
23
+ /**
24
+ * Filters component
25
+ * @param props
26
+ */
27
+ filters?: JSX.Element;
28
+ /** If true, it means that the endpoint fetches all events available
29
+ * @default true
30
+ */
31
+ general?: boolean;
32
+ /**
33
+ * Other props
34
+ */
35
+ [p: string]: any;
36
+ }
37
+ /**
38
+ * > API documentation for the Community-JS Events component. Learn about the available props and the CSS API.
39
+ *
40
+ *
41
+ * The Events component renders the list of all available events.
42
+ * Take a look at our <strong>demo</strong> component [here](/docs/sdk/community-js/react-ui/Components/Events)
43
+
44
+ #### Import
45
+ ```jsx
46
+ import {Events} from '@selfcommunity/react-ui';
47
+ ```
48
+ #### Component Name
49
+ The name `SCEvents` can be used when providing style overrides in the theme.
50
+
51
+ #### CSS
52
+
53
+ |Rule Name|Global class|Description|
54
+ |---|---|---|
55
+ |root|.SCEvents-root|Styles applied to the root element.|
56
+ |filters|.SCEvents-filters|Styles applied to the title element.|
57
+ |events|.SCEvents-events|Styles applied to the title element.|
58
+ |item|.SCEvents-item|Styles applied to the title element.|
59
+ |noResults|.SCEvents-no-results|Styles applied to no results section.|
60
+ |showMore|.SCEvents-show-more|Styles applied to show more button element.|
61
+
62
+ * @param inProps
63
+ */
64
+ export default function Events(inProps: EventsProps): JSX.Element;