@selfcommunity/react-ui 0.7.50-event.28 → 0.7.50-event.30

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 (50) hide show
  1. package/lib/cjs/components/Event/Event.d.ts +0 -6
  2. package/lib/cjs/components/Event/Event.js +4 -4
  3. package/lib/cjs/components/Event/Skeleton.d.ts +16 -2
  4. package/lib/cjs/components/Event/Skeleton.js +16 -8
  5. package/lib/cjs/components/Event/index.d.ts +2 -2
  6. package/lib/cjs/components/EventForm/EventForm.js +13 -13
  7. package/lib/cjs/components/EventInviteButton/EventInviteButton.d.ts +57 -0
  8. package/lib/cjs/components/EventInviteButton/EventInviteButton.js +284 -0
  9. package/lib/cjs/components/EventInviteButton/index.d.ts +3 -0
  10. package/lib/cjs/components/EventInviteButton/index.js +5 -0
  11. package/lib/cjs/components/Events/Events.d.ts +64 -0
  12. package/lib/cjs/components/Events/Events.js +230 -0
  13. package/lib/cjs/components/Events/Skeleton.d.ts +38 -0
  14. package/lib/cjs/components/Events/Skeleton.js +45 -0
  15. package/lib/cjs/components/Events/constants.d.ts +1 -0
  16. package/lib/cjs/components/Events/constants.js +4 -0
  17. package/lib/cjs/components/Events/index.d.ts +4 -0
  18. package/lib/cjs/components/Events/index.js +8 -0
  19. package/lib/cjs/components/Events/prefetchedEvents.d.ts +271 -0
  20. package/lib/cjs/components/Events/prefetchedEvents.js +275 -0
  21. package/lib/cjs/constants/PubSub.d.ts +4 -3
  22. package/lib/cjs/constants/PubSub.js +2 -1
  23. package/lib/cjs/index.d.ts +4 -2
  24. package/lib/cjs/index.js +7 -2
  25. package/lib/esm/components/Event/Event.d.ts +0 -6
  26. package/lib/esm/components/Event/Event.js +4 -4
  27. package/lib/esm/components/Event/Skeleton.d.ts +16 -2
  28. package/lib/esm/components/Event/Skeleton.js +17 -9
  29. package/lib/esm/components/Event/index.d.ts +2 -2
  30. package/lib/esm/components/EventForm/EventForm.js +13 -13
  31. package/lib/esm/components/EventInviteButton/EventInviteButton.d.ts +57 -0
  32. package/lib/esm/components/EventInviteButton/EventInviteButton.js +281 -0
  33. package/lib/esm/components/EventInviteButton/index.d.ts +3 -0
  34. package/lib/esm/components/EventInviteButton/index.js +2 -0
  35. package/lib/esm/components/Events/Events.d.ts +64 -0
  36. package/lib/esm/components/Events/Events.js +227 -0
  37. package/lib/esm/components/Events/Skeleton.d.ts +38 -0
  38. package/lib/esm/components/Events/Skeleton.js +42 -0
  39. package/lib/esm/components/Events/constants.d.ts +1 -0
  40. package/lib/esm/components/Events/constants.js +1 -0
  41. package/lib/esm/components/Events/index.d.ts +4 -0
  42. package/lib/esm/components/Events/index.js +4 -0
  43. package/lib/esm/components/Events/prefetchedEvents.d.ts +271 -0
  44. package/lib/esm/components/Events/prefetchedEvents.js +275 -0
  45. package/lib/esm/constants/PubSub.d.ts +4 -3
  46. package/lib/esm/constants/PubSub.js +2 -1
  47. package/lib/esm/index.d.ts +4 -2
  48. package/lib/esm/index.js +3 -1
  49. package/lib/umd/react-ui.js +1 -1
  50. package/package.json +6 -6
@@ -1,4 +1,3 @@
1
- import { ButtonBaseProps } from '@mui/material';
2
1
  import { SCEventType } from '@selfcommunity/types';
3
2
  import { WidgetProps } from '../Widget';
4
3
  export interface EventProps extends WidgetProps {
@@ -12,11 +11,6 @@ export interface EventProps extends WidgetProps {
12
11
  * @default null
13
12
  */
14
13
  eventId?: number;
15
- /**
16
- * Props to spread to the button
17
- * @default {}
18
- */
19
- buttonProps?: ButtonBaseProps;
20
14
  /**
21
15
  * Any other properties
22
16
  */
@@ -9,7 +9,7 @@ const react_core_1 = require("@selfcommunity/react-core");
9
9
  const react_intl_1 = require("react-intl");
10
10
  const classnames_1 = tslib_1.__importDefault(require("classnames"));
11
11
  const system_1 = require("@mui/system");
12
- const BaseItemButton_1 = tslib_1.__importDefault(require("../../shared/BaseItemButton"));
12
+ const BaseItem_1 = tslib_1.__importDefault(require("../../shared/BaseItem"));
13
13
  const constants_1 = require("./constants");
14
14
  const Skeleton_1 = tslib_1.__importDefault(require("./Skeleton"));
15
15
  const classes = {
@@ -19,7 +19,7 @@ const classes = {
19
19
  secondary: `${constants_1.PREFIX}-secondary`,
20
20
  actions: `${constants_1.PREFIX}-actions`
21
21
  };
22
- const Root = (0, styles_1.styled)(BaseItemButton_1.default, {
22
+ const Root = (0, styles_1.styled)(BaseItem_1.default, {
23
23
  name: constants_1.PREFIX,
24
24
  slot: 'Root',
25
25
  overridesResolver: (props, styles) => styles.root
@@ -62,7 +62,7 @@ function Event(inProps) {
62
62
  props: inProps,
63
63
  name: constants_1.PREFIX
64
64
  });
65
- const { eventId = null, event = null, className = null, elevation } = props, rest = tslib_1.__rest(props, ["eventId", "event", "className", "elevation"]);
65
+ const { eventId = null, event = null, className = null, elevation = 0 } = props, rest = tslib_1.__rest(props, ["eventId", "event", "className", "elevation"]);
66
66
  // STATE
67
67
  const { scEvent } = (0, react_core_1.useSCFetchEvent)({ id: eventId, event });
68
68
  // CONTEXT
@@ -78,7 +78,7 @@ function Event(inProps) {
78
78
  /**
79
79
  * Renders root object
80
80
  */
81
- return (react_1.default.createElement(Root, Object.assign({ elevation: elevation, disableTypography: true }, rest, { className: (0, classnames_1.default)(classes.root, className), ButtonBaseProps: { component: react_core_1.Link, to: scRoutingContext.url(react_core_1.SCRoutes.EVENT_ROUTE_NAME, scEvent) }, image: react_1.default.createElement(material_1.Avatar, { variant: "square", alt: scEvent.name, src: scEvent.image_medium, className: classes.avatar }), primary: react_1.default.createElement(material_1.Typography, { component: "div", className: classes.primary },
81
+ return (react_1.default.createElement(Root, Object.assign({ elevation: elevation, disableTypography: true }, rest, { className: (0, classnames_1.default)(classes.root, className), image: react_1.default.createElement(material_1.Avatar, { variant: "square", alt: scEvent.name, src: scEvent.image_medium, className: classes.avatar }), primary: react_1.default.createElement(material_1.Typography, { component: "div", className: classes.primary },
82
82
  react_1.default.createElement(material_1.Typography, { component: "span" }, `${intl.formatDate(scEvent.start_date, { weekday: 'long', month: 'long', day: 'numeric' })}`),
83
83
  react_1.default.createElement(material_1.Typography, { variant: "body1" }, scEvent.name)), secondary: react_1.default.createElement(material_1.Typography, { component: "p", variant: "body2", className: classes.secondary },
84
84
  react_1.default.createElement(react_intl_1.FormattedMessage, { id: `ui.eventForm.privacy.${scEvent.privacy}`, defaultMessage: `ui.eventForm.privacy.${scEvent.privacy}` }),
@@ -1,4 +1,16 @@
1
- import { WidgetProps } from '../Widget';
1
+ import React from 'react';
2
+ import { BaseItemProps } from '../../shared/BaseItem';
3
+ export interface EventSkeletonProps extends BaseItemProps {
4
+ /**
5
+ * Overrides or extends the styles applied to the component.
6
+ * @default null
7
+ */
8
+ className?: string;
9
+ /**
10
+ * Prop to pass an action to be rendered next to the skeleton
11
+ */
12
+ action?: React.ReactNode;
13
+ }
2
14
  /**
3
15
  * > API documentation for the Community-JS Event Skeleton component. Learn about the available props and the CSS API.
4
16
 
@@ -17,6 +29,8 @@ import { WidgetProps } from '../Widget';
17
29
  |Rule Name|Global class|Description|
18
30
  |---|---|---|
19
31
  |root|.SCEvent-skeleton-root|Styles applied to the root element.|
32
+ |image|.SCEvent-skeleton-image|Styles applied to the image element.|
33
+ |action|.SCEvent-skeleton-action|Styles applied to action section.|
20
34
  *
21
35
  */
22
- export default function EventSkeleton(props: WidgetProps): JSX.Element;
36
+ export default function EventSkeleton(inProps: EventSkeletonProps): JSX.Element;
@@ -5,10 +5,13 @@ const react_1 = tslib_1.__importDefault(require("react"));
5
5
  const material_1 = require("@mui/material");
6
6
  const styles_1 = require("@mui/material/styles");
7
7
  const Skeleton_1 = tslib_1.__importDefault(require("@mui/material/Skeleton"));
8
- const BaseItem_1 = tslib_1.__importDefault(require("../../shared/BaseItem"));
9
8
  const constants_1 = require("./constants");
9
+ const classnames_1 = tslib_1.__importDefault(require("classnames"));
10
+ const BaseItem_1 = tslib_1.__importDefault(require("../../shared/BaseItem"));
10
11
  const classes = {
11
- root: `${constants_1.PREFIX}-skeleton-root`
12
+ root: `${constants_1.PREFIX}-skeleton-root`,
13
+ image: `${constants_1.PREFIX}-skeleton-image`,
14
+ action: `${constants_1.PREFIX}-skeleton-action`
12
15
  };
13
16
  const Root = (0, styles_1.styled)(BaseItem_1.default, {
14
17
  name: constants_1.PREFIX,
@@ -32,13 +35,18 @@ const Root = (0, styles_1.styled)(BaseItem_1.default, {
32
35
  |Rule Name|Global class|Description|
33
36
  |---|---|---|
34
37
  |root|.SCEvent-skeleton-root|Styles applied to the root element.|
38
+ |image|.SCEvent-skeleton-image|Styles applied to the image element.|
39
+ |action|.SCEvent-skeleton-action|Styles applied to action section.|
35
40
  *
36
41
  */
37
- function EventSkeleton(props) {
38
- //const theme = useTheme<SCThemeType>();
39
- return (react_1.default.createElement(Root, Object.assign({ className: classes.root }, props, { image: react_1.default.createElement(Skeleton_1.default, { animation: "wave", variant: "rectangular", width: 100, height: 60 }), primary: react_1.default.createElement(Skeleton_1.default, { animation: "wave", height: 10, width: 120, style: { marginBottom: 10 } }), secondary: react_1.default.createElement(react_1.default.Fragment, null,
40
- react_1.default.createElement(Skeleton_1.default, { animation: "wave", height: 10, width: 120, style: { marginBottom: 10 } }),
41
- react_1.default.createElement(Skeleton_1.default, { animation: "wave", height: 10, width: 120, style: { marginBottom: 10 } })), actions: react_1.default.createElement(material_1.Button, { size: "small", variant: "outlined", disabled: true },
42
- react_1.default.createElement(Skeleton_1.default, { animation: "wave", height: 10, width: 30, style: { marginTop: 5, marginBottom: 5 } })) })));
42
+ function EventSkeleton(inProps) {
43
+ const { className, action } = inProps;
44
+ return (react_1.default.createElement(Root, { elevation: 0, className: (0, classnames_1.default)(classes.root, className), image: react_1.default.createElement(material_1.Box, { className: classes.image },
45
+ react_1.default.createElement(Skeleton_1.default, { animation: "wave", variant: "rectangular", width: 100, height: 60 }),
46
+ " ",
47
+ react_1.default.createElement(material_1.Icon, { fontSize: "large" }, "CalendarIcon")), primary: react_1.default.createElement(Skeleton_1.default, { animation: "wave", variant: "rectangular", height: 10, width: 100, style: { marginBottom: 12 } }), secondary: react_1.default.createElement(react_1.default.Fragment, null,
48
+ react_1.default.createElement(Skeleton_1.default, { animation: "wave", variant: "rectangular", height: 10, width: 160, style: { marginBottom: 10 } }),
49
+ react_1.default.createElement(Skeleton_1.default, { animation: "wave", variant: "rectangular", height: 10, width: 90 })), actions: react_1.default.createElement(react_1.default.Fragment, null, action !== null && action !== void 0 ? action : (react_1.default.createElement(material_1.Button, { size: "small", variant: "outlined", disabled: true },
50
+ react_1.default.createElement(Skeleton_1.default, { animation: "wave", height: 10, width: 30, style: { marginTop: 5, marginBottom: 5 } })))) }));
43
51
  }
44
52
  exports.default = EventSkeleton;
@@ -1,4 +1,4 @@
1
1
  import Event, { EventProps } from './Event';
2
- import EventSkeleton from './Skeleton';
2
+ import EventSkeleton, { EventSkeletonProps } from './Skeleton';
3
3
  export default Event;
4
- export { EventProps, EventSkeleton };
4
+ export { EventProps, EventSkeleton, EventSkeletonProps };
@@ -122,8 +122,8 @@ function EventForm(inProps) {
122
122
  // INTL
123
123
  const intl = (0, react_intl_1.useIntl)();
124
124
  const initialFieldState = {
125
- emotionalImageOriginal: '',
126
- emotionalImageOriginalFile: '',
125
+ imageOriginal: '',
126
+ imageOriginalFile: '',
127
127
  startDate: null,
128
128
  startTime: null,
129
129
  endDate: null,
@@ -146,8 +146,8 @@ function EventForm(inProps) {
146
146
  // PREFERENCES
147
147
  const scPreferences = (0, react_core_1.useSCPreferences)();
148
148
  const privateEnabled = (0, react_1.useMemo)(() => scPreferences.preferences[react_core_1.SCPreferences.CONFIGURATIONS_EVENTS_PRIVATE_ENABLED].value, [scPreferences.preferences]);
149
- const _backgroundCover = Object.assign({}, (field.emotionalImageOriginal
150
- ? { background: `url('${field.emotionalImageOriginal}') center / cover` }
149
+ const _backgroundCover = Object.assign({}, (field.imageOriginal
150
+ ? { background: `url('${field.imageOriginal}') center / cover` }
151
151
  : { background: `url('${scPreferences.preferences[react_core_1.SCPreferences.IMAGES_USER_DEFAULT_COVER].value}') center / cover` }));
152
152
  const combineDateAndTime = (date, time) => {
153
153
  if (date && time) {
@@ -161,14 +161,14 @@ function EventForm(inProps) {
161
161
  return null;
162
162
  };
163
163
  function handleChangeCover(cover) {
164
- setField((prev) => (Object.assign(Object.assign({}, prev), { ['emotionalImageOriginalFile']: cover })));
164
+ setField((prev) => (Object.assign(Object.assign({}, prev), { ['imageOriginalFile']: cover })));
165
165
  const reader = new FileReader();
166
166
  reader.onloadend = () => {
167
- setField((prev) => (Object.assign(Object.assign({}, prev), { ['emotionalImageOriginal']: reader.result })));
167
+ setField((prev) => (Object.assign(Object.assign({}, prev), { ['imageOriginal']: reader.result })));
168
168
  };
169
169
  reader.readAsDataURL(cover);
170
- if (error.emotionalImageOriginalError) {
171
- delete error.emotionalImageOriginalError;
170
+ if (error.imageOriginalError) {
171
+ delete error.imageOriginalError;
172
172
  setError(error);
173
173
  }
174
174
  }
@@ -178,8 +178,8 @@ function EventForm(inProps) {
178
178
  const handleSubmit = () => {
179
179
  setField((prev) => (Object.assign(Object.assign({}, prev), { ['isSubmitting']: true })));
180
180
  const formData = new FormData();
181
- if (field.emotionalImageOriginalFile) {
182
- formData.append('emotional_image_original', field.emotionalImageOriginalFile);
181
+ if (field.imageOriginalFile) {
182
+ formData.append('image_original', field.imageOriginalFile);
183
183
  }
184
184
  formData.append('name', field.name);
185
185
  formData.append('start_date', combineDateAndTime(field.startDate, field.startTime));
@@ -232,7 +232,7 @@ function EventForm(inProps) {
232
232
  */
233
233
  return (react_1.default.createElement(Root, Object.assign({ DialogContentProps: { dividers: false }, title: react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.eventForm.title", defaultMessage: "ui.eventForm.title" }), open: open, onClose: onClose, className: (0, classnames_1.default)(classes.root, className), actions: react_1.default.createElement(lab_1.LoadingButton, { loading: field.isSubmitting, disabled: !field.name ||
234
234
  (!field.startDate && !field.startTime) ||
235
- (types_1.SCEventLocationType.ONLINE && !field.link) ||
235
+ (field.location === types_1.SCEventLocationType.ONLINE && !field.link) ||
236
236
  ((field.recurring !== types_1.SCEventRecurrenceType.NEVER) && (!field.endDate && !field.endTime)) ||
237
237
  Object.keys(error).length !== 0 ||
238
238
  field.name.length > Event_1.EVENT_TITLE_MAX_LENGTH ||
@@ -249,7 +249,7 @@ function EventForm(inProps) {
249
249
  react_1.default.createElement(x_date_pickers_1.MobileDatePicker, { className: classes.picker, disablePast: true, label: field.startDate && react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.eventForm.date.placeholder", defaultMessage: "ui.eventForm.date.placeholder" }), value: field.startDate, slots: {
250
250
  textField: (params) => (react_1.default.createElement(material_1.TextField, Object.assign({}, params, { InputProps: Object.assign(Object.assign({}, params.InputProps), { placeholder: `${intl.formatMessage(messages.startDate)}`, startAdornment: (react_1.default.createElement(material_1.InputAdornment, { position: "start" },
251
251
  react_1.default.createElement(material_1.IconButton, null,
252
- react_1.default.createElement(material_1.Icon, null, "calendar_off")))) }) })))
252
+ react_1.default.createElement(material_1.Icon, null, "CalendarIcon")))) }) })))
253
253
  }, slotProps: {
254
254
  toolbar: {
255
255
  // eslint-disable-next-line @typescript-eslint/ban-ts-ignore,@typescript-eslint/ban-ts-comment
@@ -269,7 +269,7 @@ function EventForm(inProps) {
269
269
  }
270
270
  }, onChange: (value) => handleChangeDateTime(value, 'startTime') }))),
271
271
  react_1.default.createElement(material_1.FormControl, { className: classes.frequency },
272
- field.recurring !== types_1.SCEventRecurrenceType.NEVER && react_1.default.createElement(material_1.InputLabel, { id: "frequency" }, `${intl.formatMessage(messages.frequency)}`),
272
+ field.recurring !== types_1.SCEventRecurrenceType.NEVER && react_1.default.createElement(material_1.InputLabel, { id: "recurring" }, `${intl.formatMessage(messages.frequency)}`),
273
273
  react_1.default.createElement(material_1.Select, { name: "recurring", label: field.recurring !== types_1.SCEventRecurrenceType.NEVER && `${intl.formatMessage(messages.frequency)}`, labelId: "recurring", value: field.recurring, onChange: handleChange, displayEmpty: true, renderValue: (selected) => {
274
274
  if (!selected) {
275
275
  return react_1.default.createElement("em", null, `${intl.formatMessage(messages.frequencyPlaceholder)}`);
@@ -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,284 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const react_1 = tslib_1.__importStar(require("react"));
5
+ const system_1 = require("@mui/system");
6
+ const styles_1 = require("@mui/material/styles");
7
+ const material_1 = require("@mui/material");
8
+ const react_intl_1 = require("react-intl");
9
+ const react_core_1 = require("@selfcommunity/react-core");
10
+ const classnames_1 = tslib_1.__importDefault(require("classnames"));
11
+ const BaseDialog_1 = tslib_1.__importDefault(require("../../shared/BaseDialog"));
12
+ const lab_1 = require("@mui/lab");
13
+ const api_services_1 = require("@selfcommunity/api-services");
14
+ const Autocomplete_1 = tslib_1.__importDefault(require("@mui/material/Autocomplete"));
15
+ const User_1 = tslib_1.__importDefault(require("../User"));
16
+ const Errors_1 = require("../../constants/Errors");
17
+ const utils_1 = require("@selfcommunity/utils");
18
+ const PubSub_1 = require("../../constants/PubSub");
19
+ const pubsub_js_1 = tslib_1.__importDefault(require("pubsub-js"));
20
+ const messages = (0, react_intl_1.defineMessages)({
21
+ placeholder: {
22
+ id: 'ui.eventInviteButton.searchBar.placeholder',
23
+ defaultMessage: 'ui.eventInviteButton.searchBar.placeholder'
24
+ }
25
+ });
26
+ const PREFIX = 'SCEventInviteButton';
27
+ const classes = {
28
+ root: `${PREFIX}-root`,
29
+ dialogRoot: `${PREFIX}-dialog-root`,
30
+ dialogTitle: `${PREFIX}-dialog-title`,
31
+ dialogContent: `${PREFIX}-dialog-content`,
32
+ autocomplete: `${PREFIX}-autocomplete`,
33
+ icon: `${PREFIX}-icon`,
34
+ input: `${PREFIX}-input`,
35
+ clear: `${PREFIX}-clear`,
36
+ invitedBox: `${PREFIX}-invited-box`,
37
+ suggested: `${PREFIX}-suggested`
38
+ };
39
+ const Root = (0, styles_1.styled)(material_1.Button, {
40
+ name: PREFIX,
41
+ slot: 'Root',
42
+ overridesResolver: (props, styles) => styles.root
43
+ })(({ theme }) => ({}));
44
+ const DialogRoot = (0, styles_1.styled)(BaseDialog_1.default, {
45
+ name: PREFIX,
46
+ slot: 'Root',
47
+ overridesResolver: (props, styles) => styles.dialogRoot
48
+ })(({ theme }) => ({}));
49
+ /**
50
+ *> API documentation for the Community-JS Event Invite Button component. Learn about the available props and the CSS API.
51
+ *
52
+ #### Import
53
+ ```jsx
54
+ import {SCEventInviteButton} from '@selfcommunity/react-ui';
55
+ ```
56
+
57
+ #### Component Name
58
+ The name `SCEventInviteButton` can be used when providing style overrides in the theme.
59
+
60
+ #### CSS
61
+
62
+ |Rule Name|Global class|Description|
63
+ |---|---|---|
64
+ |root|.SCEventInviteButton-root|Styles applied to the root element.|
65
+ |dialogRoot|.SCEventInviteButton-dialog-root|Styles applied to the dialog root.|
66
+ |dialogTitle|.SCEventInviteButton-dialog-title|Styles applied to the dialog title element.|
67
+ |dialogContent|.SCEventInviteButton-dialog-content|Styles applied to the dialog content.|
68
+ |autocomplete|.SCEventInviteButton-autocomplete|Styles applied to the autocomplete element.|
69
+ |icon|.SCEventInviteButton-icon|Styles applied to the autocomplete icon element.|
70
+ |input|.SCEventInviteButton-input|Styles applied to the autocomplete input element.|
71
+ |clear|.SCEventInviteButton-clear|Styles applied to the autocomplete clear icon element.|
72
+ |invitedBox|.SCEventInviteButton-invited-box|Styles applied to the invited users box.|
73
+ |suggested|.SCEventInviteButton-suggested|Styles applied to the suggested users box.|
74
+
75
+ * @param inProps
76
+ */
77
+ function EventInviteButton(inProps) {
78
+ var _a;
79
+ //PROPS
80
+ const props = (0, system_1.useThemeProps)({
81
+ props: inProps,
82
+ name: PREFIX
83
+ });
84
+ const { className, event, eventId, handleInvitations = null } = props, rest = tslib_1.__rest(props, ["className", "event", "eventId", "handleInvitations"]);
85
+ // CONTEXT
86
+ const scUserContext = (0, react_1.useContext)(react_core_1.SCUserContext);
87
+ // STATE
88
+ const [open, setOpen] = (0, react_1.useState)(false);
89
+ const [isSending, setIsSending] = (0, react_1.useState)(false);
90
+ const [value, setValue] = (0, react_1.useState)('');
91
+ const [suggested, setSuggested] = (0, react_1.useState)([]);
92
+ const [list, setList] = (0, react_1.useState)([]);
93
+ const [loading, setLoading] = (0, react_1.useState)(false);
94
+ const [invited, setInvited] = (0, react_1.useState)([]);
95
+ /**
96
+ * Notify UI when a member is invited to a event
97
+ * @param event
98
+ * @param usersInvited
99
+ */
100
+ function notifyChanges(event, usersInvited) {
101
+ if (event && usersInvited) {
102
+ pubsub_js_1.default.publish(`${PubSub_1.SCTopicType.EVENT}.${PubSub_1.SCGroupEventType.INVITE_MEMBER}`, usersInvited);
103
+ }
104
+ }
105
+ function convertToInvitedUsersObject(data) {
106
+ const invite_users = {};
107
+ data.forEach((user, index) => {
108
+ invite_users[`invite_users[${index}]`] = user.id;
109
+ });
110
+ return invite_users;
111
+ }
112
+ /**
113
+ * Memoized users invited ids
114
+ */
115
+ const ids = (0, react_1.useMemo)(() => {
116
+ if (invited) {
117
+ return invited.map((u) => {
118
+ return parseInt(u.id, 10);
119
+ });
120
+ }
121
+ return [invited];
122
+ }, [invited]);
123
+ // HOOKS
124
+ const { scEvent } = (0, react_core_1.useSCFetchEvent)({ id: eventId, event });
125
+ const isEventAdmin = (0, react_1.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]);
126
+ // INTL
127
+ const intl = (0, react_intl_1.useIntl)();
128
+ function fetchResults() {
129
+ setLoading(true);
130
+ api_services_1.EventService.getEventSuggestedUsers(scEvent === null || scEvent === void 0 ? void 0 : scEvent.id, value)
131
+ .then((data) => {
132
+ setLoading(false);
133
+ setSuggested(data.results);
134
+ })
135
+ .catch((error) => {
136
+ setLoading(false);
137
+ utils_1.Logger.error(Errors_1.SCOPE_SC_UI, error);
138
+ });
139
+ }
140
+ function fetchGeneralResults() {
141
+ setLoading(true);
142
+ api_services_1.EventService.getEventsSuggestedUsers(value)
143
+ .then((data) => {
144
+ setLoading(false);
145
+ setSuggested(data.results);
146
+ })
147
+ .catch((error) => {
148
+ setLoading(false);
149
+ utils_1.Logger.error(Errors_1.SCOPE_SC_UI, error);
150
+ });
151
+ }
152
+ (0, react_1.useEffect)(() => {
153
+ if (scEvent === null || scEvent === void 0 ? void 0 : scEvent.id) {
154
+ api_services_1.EventService.getEventSuggestedUsers(scEvent === null || scEvent === void 0 ? void 0 : scEvent.id, value).then((data) => {
155
+ setLoading(false);
156
+ setList(data.results);
157
+ });
158
+ }
159
+ else {
160
+ api_services_1.EventService.getEventsSuggestedUsers(value).then((data) => {
161
+ setLoading(false);
162
+ setList(data.results);
163
+ });
164
+ }
165
+ }, [scEvent === null || scEvent === void 0 ? void 0 : scEvent.id]);
166
+ /**
167
+ * If a value is entered in new message field, it fetches user suggested
168
+ */
169
+ (0, react_1.useEffect)(() => {
170
+ if (scEvent) {
171
+ fetchResults();
172
+ }
173
+ else {
174
+ fetchGeneralResults();
175
+ }
176
+ }, [value, scEvent]);
177
+ /**
178
+ * Handles dialog close
179
+ */
180
+ const handleClose = () => {
181
+ setOpen((p) => !p);
182
+ };
183
+ /**
184
+ * Handles invitation sending
185
+ */
186
+ const handleSendInvitations = () => {
187
+ if (handleInvitations) {
188
+ handleInvitations(convertToInvitedUsersObject(invited));
189
+ setOpen(false);
190
+ }
191
+ else {
192
+ const data = { users: ids };
193
+ setIsSending(true);
194
+ api_services_1.EventService.inviteOrAcceptEventRequest(scEvent.id, data)
195
+ .then(() => {
196
+ setIsSending(false);
197
+ setOpen(false);
198
+ setInvited([]);
199
+ notifyChanges(scEvent, invited);
200
+ })
201
+ .catch((error) => {
202
+ setOpen(false);
203
+ setLoading(false);
204
+ utils_1.Logger.error(Errors_1.SCOPE_SC_UI, error);
205
+ });
206
+ }
207
+ };
208
+ // Autocomplete Handlers
209
+ const handleInputChange = (event, value, reason) => {
210
+ switch (reason) {
211
+ case 'input':
212
+ setValue(value);
213
+ !value && setSuggested([]);
214
+ break;
215
+ case 'reset':
216
+ setValue(value);
217
+ break;
218
+ }
219
+ };
220
+ const handleChange = (event, value, reason, details) => {
221
+ event.preventDefault();
222
+ event.stopPropagation();
223
+ switch (reason) {
224
+ case 'selectOption':
225
+ setInvited(value);
226
+ setList((prev) => prev.filter((u) => u.id !== details.option.id));
227
+ break;
228
+ case 'removeOption':
229
+ setInvited(value);
230
+ setList((prev) => [...prev, details.option]);
231
+ break;
232
+ }
233
+ return false;
234
+ };
235
+ const handleUserInvite = (user) => {
236
+ setInvited((prev) => [...prev, user]);
237
+ setList((prev) => prev.filter((u) => u.id !== user.id));
238
+ };
239
+ const handleDelete = (option) => {
240
+ setInvited(invited.filter((v) => v !== option));
241
+ setList((prev) => [...prev, option]);
242
+ };
243
+ const filterOptions = (options, { inputValue }) => {
244
+ return options.filter((option) => {
245
+ const usernameMatch = option.username.toLowerCase().includes(inputValue.toLowerCase());
246
+ const nameMatch = option.real_name.toLowerCase().includes(inputValue.toLowerCase());
247
+ return usernameMatch || nameMatch;
248
+ });
249
+ };
250
+ /**
251
+ * If in event edit mode and logged-in user is not also the event manager, the component is hidden.
252
+ // */
253
+ if (event && !isEventAdmin) {
254
+ return null;
255
+ }
256
+ /**
257
+ * Renders root object
258
+ */
259
+ return (react_1.default.createElement(react_1.default.Fragment, null,
260
+ react_1.default.createElement(Root, Object.assign({ className: (0, classnames_1.default)(classes.root, className), onClick: handleClose, variant: scEvent ? 'contained' : 'outlined', color: scEvent ? 'secondary' : 'inherit', startIcon: react_1.default.createElement(material_1.Icon, null, "add") }, rest),
261
+ react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.eventInviteButton", defaultMessage: "ui.eventInviteButton" })),
262
+ open && (react_1.default.createElement(DialogRoot, { DialogContentProps: { dividers: false }, open: true, className: classes.dialogRoot, title: react_1.default.createElement(react_1.default.Fragment, null,
263
+ react_1.default.createElement(material_1.IconButton, { onClick: handleClose },
264
+ react_1.default.createElement(material_1.Icon, null, "arrow_back")),
265
+ react_1.default.createElement(material_1.Typography, { className: classes.dialogTitle },
266
+ react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.eventInviteButton.dialog.title", defaultMessage: "ui.eventInviteButton.dialog.title" })),
267
+ react_1.default.createElement(lab_1.LoadingButton, { size: "small", color: "secondary", variant: "contained", onClick: handleSendInvitations, loading: isSending, disabled: !invited.length },
268
+ react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.eventInviteButton.dialog.button.end", defaultMessage: "ui.eventInviteButton.dialog.button.end" }))) },
269
+ react_1.default.createElement(material_1.Box, { className: classes.dialogContent },
270
+ react_1.default.createElement(Autocomplete_1.default, { 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_1.default.createElement(material_1.Box, Object.assign({ component: "li" }, props),
271
+ react_1.default.createElement(material_1.Avatar, { alt: option.username, src: option.avatar }),
272
+ react_1.default.createElement(material_1.Typography, { ml: 1 }, option.username))), renderInput: (params) => (react_1.default.createElement(material_1.TextField, Object.assign({}, params, { variant: "outlined", placeholder: `${intl.formatMessage(messages.placeholder)}`, InputProps: Object.assign(Object.assign({}, params.InputProps), { className: classes.input, startAdornment: (react_1.default.createElement(react_1.default.Fragment, null,
273
+ react_1.default.createElement(material_1.InputAdornment, { position: "start" },
274
+ react_1.default.createElement(material_1.Icon, { className: classes.icon }, "search")),
275
+ params.InputProps.startAdornment)) }) }))) }),
276
+ react_1.default.createElement(material_1.Box, { className: classes.invitedBox }, invited.map((option, index) => (react_1.default.createElement(material_1.Chip, { key: index, avatar: react_1.default.createElement(material_1.Avatar, { alt: option.username, src: option.avatar }), label: option.username, onDelete: () => {
277
+ handleDelete(option);
278
+ }, style: { marginRight: 8 } })))),
279
+ react_1.default.createElement(material_1.Box, { className: classes.suggested },
280
+ list.length !== 0 && (react_1.default.createElement(material_1.Typography, { variant: "h4", fontWeight: "bold" },
281
+ react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.eventInviteButton.dialog.content.list", defaultMessage: "ui.eventInviteButton.dialog.content.list" }))),
282
+ list.slice(0, 5).map((user, index) => (react_1.default.createElement(User_1.default, { elevation: 0, actions: react_1.default.createElement(react_1.default.Fragment, null), user: user, userId: user.id, key: index, buttonProps: { onClick: () => handleUserInvite(user) } })))))))));
283
+ }
284
+ exports.default = EventInviteButton;
@@ -0,0 +1,3 @@
1
+ import EventInviteButton, { EventInviteButtonProps } from './EventInviteButton';
2
+ export default EventInviteButton;
3
+ export { EventInviteButtonProps };
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const EventInviteButton_1 = tslib_1.__importDefault(require("./EventInviteButton"));
5
+ exports.default = EventInviteButton_1.default;
@@ -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;