@selfcommunity/react-ui 0.11.0-alpha.85 → 0.11.0-alpha.87

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.
@@ -72,17 +72,20 @@ function Category(inProps) {
72
72
  // CONTEXT
73
73
  const scRoutingContext = (0, react_core_1.useSCRouting)();
74
74
  // STATE
75
- const { scCategory, setSCCategory } = (0, react_core_1.useSCFetchCategory)(Object.assign({ id: categoryId, category }, (cacheStrategy && { cacheStrategy })));
75
+ const { scCategory } = (0, react_core_1.useSCFetchCategory)(Object.assign({ id: categoryId, category }, (cacheStrategy && { cacheStrategy })));
76
76
  // MEMO
77
77
  const _ButtonBaseProps = (0, react_1.useMemo)(() => ButtonBaseProps ? ButtonBaseProps : { component: react_core_1.Link, to: scCategory ? scRoutingContext.url(react_core_1.SCRoutes.CATEGORY_ROUTE_NAME, scCategory) : '' }, [ButtonBaseProps, scRoutingContext, scCategory]);
78
78
  // HOOKS
79
79
  const intl = (0, react_intl_1.useIntl)();
80
+ const categoryFollowEnabled = (0, react_core_1.useSCPreferenceEnabled)(react_core_1.SCPreferences.CONFIGURATIONS_CATEGORY_FOLLOW_ENABLED);
80
81
  if (!scCategory) {
81
82
  return (0, jsx_runtime_1.jsx)(Skeleton_1.default, Object.assign({ elevation: elevation }, (variant && { variant })));
82
83
  }
83
84
  // RENDER
84
85
  if (!autoHide) {
85
- return ((0, jsx_runtime_1.jsx)(Root, Object.assign({ disableTypography: showTooltip, elevation: elevation }, (variant && { variant }), { className: (0, classnames_1.default)(classes.root, className, { [classes.followed]: scCategory.followed }, { [classes.autoFollowed]: scCategory.auto_follow === types_1.SCCategoryAutoFollowType.FORCED }), ButtonBaseProps: _ButtonBaseProps, image: (0, jsx_runtime_1.jsx)(material_1.Avatar, { alt: scCategory.name, src: scCategory.image_medium, variant: "square", className: classes.categoryImage }), primary: (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: showTooltip ? ((0, jsx_runtime_1.jsx)(material_1.Tooltip, Object.assign({ title: scCategory.name }, { children: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ className: classes.primary, component: "span", variant: "body1" }, { children: scCategory.name })) }))) : (scCategory.name) }), secondary: (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: showTooltip ? ((0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ className: classes.secondary, component: "p", variant: "body2" }, { children: showFollowers ? `${intl.formatMessage(messages.categoryFollowers, { total: scCategory.followers_counter })}` : scCategory.slogan }))) : ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: showFollowers ? `${intl.formatMessage(messages.categoryFollowers, { total: scCategory.followers_counter })}` : scCategory.slogan })) }), actions: (0, jsx_runtime_1.jsx)(CategoryFollowButton_1.default, Object.assign({ category: scCategory }, categoryFollowButtonProps)) }, rest)));
86
+ return ((0, jsx_runtime_1.jsx)(Root, Object.assign({ disableTypography: showTooltip, elevation: elevation }, (variant && { variant }), { className: (0, classnames_1.default)(classes.root, className, { [classes.followed]: scCategory.followed }, { [classes.autoFollowed]: scCategory.auto_follow === types_1.SCCategoryAutoFollowType.FORCED }), ButtonBaseProps: _ButtonBaseProps, image: (0, jsx_runtime_1.jsx)(material_1.Avatar, { alt: scCategory.name, src: scCategory.image_medium, variant: "square", className: classes.categoryImage }), primary: (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: showTooltip ? ((0, jsx_runtime_1.jsx)(material_1.Tooltip, Object.assign({ title: scCategory.name }, { children: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ className: classes.primary, component: "span", variant: "body1" }, { children: scCategory.name })) }))) : (scCategory.name) }), secondary: (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: showTooltip ? ((0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ className: classes.secondary, component: "p", variant: "body2" }, { children: showFollowers ? `${intl.formatMessage(messages.categoryFollowers, { total: scCategory.followers_counter })}` : scCategory.slogan }))) : ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: showFollowers && categoryFollowEnabled
87
+ ? `${intl.formatMessage(messages.categoryFollowers, { total: scCategory.followers_counter })}`
88
+ : scCategory.slogan })) }), actions: (0, jsx_runtime_1.jsx)(CategoryFollowButton_1.default, Object.assign({ category: scCategory }, categoryFollowButtonProps)) }, rest)));
86
89
  }
87
90
  return null;
88
91
  }
@@ -60,5 +60,5 @@ exports.default = (props) => {
60
60
  }, [onClick]);
61
61
  return ((0, jsx_runtime_1.jsxs)(Root, Object.assign({ className: (0, classnames_1.default)(classes.root, className) }, { children: [((_a = value === null || value === void 0 ? void 0 : value.categories) === null || _a === void 0 ? void 0 : _a.length) > 0 &&
62
62
  (value === null || value === void 0 ? void 0 : value.categories.map((c) => ((0, jsx_runtime_1.jsx)(material_1.Chip, { label: c.name, onDelete: handleDeleteCategory(c.id), icon: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "category" }), onClick: handleClickCategory }, c.id)))), (value === null || value === void 0 ? void 0 : value.group) && ((0, jsx_runtime_1.jsx)(material_1.Chip, { label: value === null || value === void 0 ? void 0 : value.group.name, onDelete: handleDeleteGroup, icon: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "groups" }), onClick: handleClickGroup, disabled: !((_b = value === null || value === void 0 ? void 0 : value.group) === null || _b === void 0 ? void 0 : _b.subscription_status) }, value === null || value === void 0 ? void 0 : value.group.id)), (value === null || value === void 0 ? void 0 : value.event) && ((0, jsx_runtime_1.jsx)(material_1.Chip, { label: value === null || value === void 0 ? void 0 : value.event.name, onDelete: handleDeleteEvent, icon: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "CalendarIcon" }), onClick: handleClickEvent, disabled: !((_c = value === null || value === void 0 ? void 0 : value.event) === null || _c === void 0 ? void 0 : _c.subscription_status) }, value === null || value === void 0 ? void 0 : value.event.id)), ((_d = value === null || value === void 0 ? void 0 : value.addressing) === null || _d === void 0 ? void 0 : _d.length) > 0 &&
63
- (value === null || value === void 0 ? void 0 : value.addressing.map((t) => ((0, jsx_runtime_1.jsx)(TagChip_1.default, { tag: t, onDelete: handleDeleteTag(t.id), icon: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "label" }), onClick: handleClickTag }, t.id)))), (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: ((_e = value === null || value === void 0 ? void 0 : value.recipients) === null || _e === void 0 ? void 0 : _e.length) > 0 && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [value.recipients.slice(0, 3).map((r) => ((0, jsx_runtime_1.jsx)(material_1.Chip, { label: typeof r === 'object' ? r.username : r, icon: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "people_alt" }), onClick: handleClickRecipient, onDelete: handleDeleteRecipient(typeof r === 'object' ? r.id : r) }, typeof r === 'object' ? r.id : r))), value.recipients.length > 3 && (0, jsx_runtime_1.jsx)(material_1.Chip, { label: `+${value.recipients.length - 3}` })] })) }), (value === null || value === void 0 ? void 0 : value.location) && ((0, jsx_runtime_1.jsx)(material_1.Chip, { icon: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "add_location_alt" }), label: value === null || value === void 0 ? void 0 : value.location.location, onDelete: handleDeleteLocation, onClick: handleClickLocation }))] })));
63
+ (value === null || value === void 0 ? void 0 : value.addressing.map((t) => ((0, jsx_runtime_1.jsx)(TagChip_1.default, { tag: t, onDelete: handleDeleteTag(t.id), icon: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "label" }), onClick: handleClickTag }, t.id)))), (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: ((_e = value === null || value === void 0 ? void 0 : value.recipients) === null || _e === void 0 ? void 0 : _e.length) > 0 && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [value.recipients.slice(0, 3).map((r) => ((0, jsx_runtime_1.jsx)(material_1.Chip, { label: typeof r === 'object' ? r.username : r, icon: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "people_alt" }), onClick: handleClickRecipient, onDelete: handleDeleteRecipient(typeof r === 'object' ? r.id : r) }, typeof r === 'object' ? r.id : r))), value.recipients.length > 3 && (0, jsx_runtime_1.jsx)(material_1.Chip, { label: `+${value.recipients.length - 3}`, onClick: handleClickRecipient })] })) }), (value === null || value === void 0 ? void 0 : value.location) && ((0, jsx_runtime_1.jsx)(material_1.Chip, { icon: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "add_location_alt" }), label: value === null || value === void 0 ? void 0 : value.location.location, onDelete: handleDeleteLocation, onClick: handleClickLocation }))] })));
64
64
  };
@@ -54,7 +54,7 @@ const Root = (0, material_1.styled)(material_1.Dialog, {
54
54
  const LayerTransitionRoot = (0, material_1.styled)(material_1.Slide, {
55
55
  name: constants_1.PREFIX,
56
56
  slot: 'LayerTransitionRoot'
57
- })(({ theme }) => ({}));
57
+ })(() => ({}));
58
58
  const COMPOSER_INITIAL_STATE = {
59
59
  id: null,
60
60
  type: null,
@@ -377,8 +377,9 @@ function Composer(inProps) {
377
377
  else if (event || (value && Object.prototype.hasOwnProperty.call(value, 'recurring'))) {
378
378
  dispatch({ type: 'event', value });
379
379
  }
380
- else if ((recipients === null || recipients === void 0 ? void 0 : recipients.length) > 0 ||
381
- (Array.isArray(value) && value.some((item) => typeof item === 'object' && item !== null && !('color' in item)))) {
380
+ else if ((Array.isArray(value) &&
381
+ value.some((item) => (typeof item === 'object' && item !== null && !('color' in item)) || typeof item === 'string')) ||
382
+ (Array.isArray(recipients) && recipients.length > 0)) {
382
383
  dispatch({
383
384
  type: 'multiple',
384
385
  value: {
@@ -531,7 +532,7 @@ function Composer(inProps) {
531
532
  data.addressing = addressing.map((t) => t.id);
532
533
  }
533
534
  if (features.includes(types_1.SCFeatureName.TAGGING) && recipients !== null) {
534
- data.recipients = recipients.map((r) => r.username);
535
+ data.recipients = recipients.map((r) => (typeof r === 'string' ? r : r.username));
535
536
  }
536
537
  if (features.includes(types_1.SCFeatureName.TAGGING) &&
537
538
  features.includes(types_1.SCFeatureName.GROUPING) &&
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
- const react_1 = require("react");
5
+ const react_1 = tslib_1.__importStar(require("react"));
6
6
  const react_intl_1 = require("react-intl");
7
7
  const parse_1 = tslib_1.__importDefault(require("autosuggest-highlight/parse"));
8
8
  const match_1 = tslib_1.__importDefault(require("autosuggest-highlight/match"));
@@ -37,41 +37,21 @@ const UserAutocomplete = (inProps) => {
37
37
  // State
38
38
  const [open, setOpen] = (0, react_1.useState)(false);
39
39
  const [inputValue, setInputValue] = (0, react_1.useState)('');
40
- const [usersMap, setUsersMap] = (0, react_1.useState)({});
41
- const [value, setValue] = (0, react_1.useState)([]);
40
+ const [value, setValue] = (0, react_1.useState)(Array.isArray(defaultValue) ? defaultValue : defaultValue ? [defaultValue] : []);
42
41
  const [textAreaValue, setTextAreaValue] = (0, react_1.useState)('');
43
42
  // Fetch users
44
- const { users, isLoading } = (0, react_core_1.useSCFetchUsers)();
45
- // Build map for quick lookup by username
46
- (0, react_1.useEffect)(() => {
47
- const map = {};
48
- users === null || users === void 0 ? void 0 : users.forEach((u) => {
49
- map[u.username] = u;
50
- });
51
- setUsersMap(map);
52
- }, [users]);
53
- // Initialize value from defaultValue (string or object)
54
- (0, react_1.useEffect)(() => {
55
- if (!defaultValue)
56
- return;
57
- const initial = (Array.isArray(defaultValue) ? defaultValue : [defaultValue]).map((v) => {
58
- if (typeof v === 'string') {
59
- // Use fetched user if available, otherwise fallback object
60
- return usersMap[v] || { id: `fallback-${v}`, username: v, avatar: '' };
61
- }
62
- return v;
63
- });
64
- setValue(initial);
65
- setTextAreaValue(initial.map((u) => u.username).join('\n'));
66
- }, [defaultValue, usersMap]);
67
- // Trigger onChange and sync textarea
43
+ const { users, isLoading } = (0, react_core_1.useSCFetchUsers)({ search: inputValue });
68
44
  (0, react_1.useEffect)(() => {
69
45
  onChange === null || onChange === void 0 ? void 0 : onChange(value);
70
- setTextAreaValue(value.map((u) => u.username).join('\n'));
46
+ setTextAreaValue(value.map((u) => (typeof u === 'object' ? u.username : u)).join('\n'));
71
47
  }, [value]);
72
48
  // Handlers
73
- const handleOpen = () => setOpen(true);
74
- const handleClose = () => setOpen(false);
49
+ const handleOpen = () => {
50
+ setOpen(true);
51
+ };
52
+ const handleClose = () => {
53
+ setOpen(false);
54
+ };
75
55
  const handleChange = (_event, newValue) => {
76
56
  setValue(newValue);
77
57
  };
@@ -80,13 +60,29 @@ const UserAutocomplete = (inProps) => {
80
60
  .split(/\s|,|\n/)
81
61
  .map((s) => s.trim())
82
62
  .filter(Boolean);
83
- const matched = names.map((n) => usersMap[n] || { id: `fallback-${n}`, username: n, avatar: '' });
63
+ const matched = names.map((name) => {
64
+ const user = users.find((u) => u.username === name);
65
+ return user || name;
66
+ });
84
67
  setValue(matched);
85
68
  setTextAreaValue(e.target.value);
86
69
  };
87
- return ((0, jsx_runtime_1.jsxs)(Root, Object.assign({ className: classes.root }, { children: [(0, jsx_runtime_1.jsx)(AutocompleteRoot, Object.assign({ multiple: true, className: classes.autocompleteRoot, open: open, onOpen: handleOpen, onClose: handleClose, options: users || [], getOptionLabel: (option) => option.username || '', value: value, inputValue: inputValue, onInputChange: (_e, newInput) => setInputValue(newInput), selectOnFocus: true, clearOnBlur: true, blurOnSelect: true, handleHomeEndKeys: true, clearIcon: null, disabled: disabled || isLoading, noOptionsText: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.userAutocomplete.empty", defaultMessage: "ui.userAutocomplete.empty" }), onChange: handleChange, isOptionEqualToValue: (option, val) => option.id === val.id, renderTags: (value, getTagProps) => value.map((option, index) => ((0, jsx_runtime_1.jsx)(material_1.Chip, Object.assign({ avatar: (0, jsx_runtime_1.jsx)(material_1.Avatar, { src: option.avatar }), label: option.username }, getTagProps({ index })), option.id))), renderOption: (props, option, { inputValue }) => {
88
- const parts = (0, parse_1.default)(option.username, (0, match_1.default)(option.username, inputValue));
89
- return ((0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ component: "li" }, props, { children: [(0, jsx_runtime_1.jsx)(material_1.Avatar, { alt: option.username, src: option.avatar, sx: { mr: 1 } }), parts.map((part, index) => ((0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ sx: { fontWeight: part.highlight ? 700 : 400 } }, { children: part.text }), index)))] })));
70
+ return ((0, jsx_runtime_1.jsxs)(Root, Object.assign({ className: classes.root }, { children: [(0, jsx_runtime_1.jsx)(AutocompleteRoot, Object.assign({ multiple: true, className: classes.autocompleteRoot, open: open, onOpen: handleOpen, onClose: handleClose, options: users || [], getOptionLabel: (option) => option.username || '', value: value, inputValue: inputValue, onInputChange: (_event, newInputValue) => {
71
+ setInputValue(newInputValue);
72
+ }, selectOnFocus: true, clearOnBlur: true, blurOnSelect: true, handleHomeEndKeys: true, clearIcon: null, disabled: disabled || isLoading, noOptionsText: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.userAutocomplete.empty", defaultMessage: "ui.userAutocomplete.empty" }), onChange: handleChange, isOptionEqualToValue: (option, val) => {
73
+ if (typeof val === 'string') {
74
+ return option.username === val;
75
+ }
76
+ return option.id === val.id;
77
+ }, renderTags: (value, getTagProps) => value.map((option, index) => {
78
+ const username = typeof option === 'string' ? option : option.username;
79
+ const avatar = typeof option === 'string' ? '' : option.avatar;
80
+ const id = typeof option === 'string' ? `fallback-${option}` : option.id;
81
+ return (0, jsx_runtime_1.jsx)(material_1.Chip, Object.assign({ avatar: (0, jsx_runtime_1.jsx)(material_1.Avatar, { src: avatar }), label: username }, getTagProps({ index })), id);
82
+ }), renderOption: (props, option, { inputValue }) => {
83
+ const matches = (0, match_1.default)(option.username, inputValue);
84
+ const parts = (0, parse_1.default)(option.username, matches);
85
+ return ((0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ component: "li" }, props, { children: [(0, jsx_runtime_1.jsx)(material_1.Avatar, { alt: option.username, src: option.avatar, sx: { marginRight: 1 } }), (0, jsx_runtime_1.jsx)(react_1.default.Fragment, { children: parts.map((part, index) => ((0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ sx: { fontWeight: part.highlight ? 700 : 400 } }, { children: part.text }), index))) })] })));
90
86
  }, renderInput: (params) => ((0, jsx_runtime_1.jsx)(material_1.TextField, Object.assign({}, params, TextFieldProps, { margin: "dense", InputProps: Object.assign(Object.assign({}, params.InputProps), { autoComplete: 'off', endAdornment: ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [isLoading ? (0, jsx_runtime_1.jsx)(material_1.CircularProgress, { color: "inherit", size: 20 }) : null, params.InputProps.endAdornment] })) }) }))) }, rest)), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2", color: "primary", className: classes.info }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.userAutocomplete.textarea.info", defaultMessage: "ui.userAutocomplete.textarea.info", values: {
91
87
  // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
92
88
  // @ts-ignore
@@ -18,3 +18,4 @@ export declare const SUSPEND_NOTIFICATION_CONTRIBUTION = "_suspend_notification_
18
18
  export declare const SUSPEND_NOTIFICATION_EVENT = "_suspend_notification_event";
19
19
  export declare const MODERATE_CONTRIBUTION_HIDDEN = "_moderate_contribution_hidden";
20
20
  export declare const MODERATE_CONTRIBUTION_DELETED = "_moderate_contribution_deleted";
21
+ export declare const DOWNLOAD_CSV = "_download_csv";
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MODERATE_CONTRIBUTION_DELETED = exports.MODERATE_CONTRIBUTION_HIDDEN = exports.SUSPEND_NOTIFICATION_EVENT = exports.SUSPEND_NOTIFICATION_CONTRIBUTION = exports.RESTORE_CONTRIBUTION = exports.PUBLISH_CONTRIBUTION = exports.DELETE_CONTRIBUTION = exports.EDIT_CONTRIBUTION = exports.GET_CONTRIBUTION_PERMALINK = exports.DELETE_CONTRIBUTION_SECTION = exports.HIDE_CONTRIBUTION_SECTION = exports.FLAG_CONTRIBUTION_SECTION = exports.GENERAL_SECTION = void 0;
3
+ exports.DOWNLOAD_CSV = exports.MODERATE_CONTRIBUTION_DELETED = exports.MODERATE_CONTRIBUTION_HIDDEN = exports.SUSPEND_NOTIFICATION_EVENT = exports.SUSPEND_NOTIFICATION_CONTRIBUTION = exports.RESTORE_CONTRIBUTION = exports.PUBLISH_CONTRIBUTION = exports.DELETE_CONTRIBUTION = exports.EDIT_CONTRIBUTION = exports.GET_CONTRIBUTION_PERMALINK = exports.DELETE_CONTRIBUTION_SECTION = exports.HIDE_CONTRIBUTION_SECTION = exports.FLAG_CONTRIBUTION_SECTION = exports.GENERAL_SECTION = void 0;
4
4
  /**
5
5
  * Sections
6
6
  * @type {string}
@@ -21,3 +21,4 @@ exports.SUSPEND_NOTIFICATION_CONTRIBUTION = '_suspend_notification_contribution'
21
21
  exports.SUSPEND_NOTIFICATION_EVENT = '_suspend_notification_event';
22
22
  exports.MODERATE_CONTRIBUTION_HIDDEN = '_moderate_contribution_hidden';
23
23
  exports.MODERATE_CONTRIBUTION_DELETED = '_moderate_contribution_deleted';
24
+ exports.DOWNLOAD_CSV = '_download_csv';
@@ -522,6 +522,36 @@ function ContributionActionsMenu(props) {
522
522
  setOpenConfirmDialog(true);
523
523
  handleClose();
524
524
  }
525
+ else if (action === ContributionsActionsMenu_1.DOWNLOAD_CSV) {
526
+ api_services_1.http
527
+ .request({
528
+ url: `${api_services_1.Endpoints.GetDownloadCSV.url({ type: contributionObj.type, id: contributionObj.id })}`,
529
+ method: api_services_1.Endpoints.GetDownloadCSV.method
530
+ })
531
+ .then((response) => {
532
+ const blob = new Blob([response.data], { type: 'text/csv' });
533
+ const url = window.URL.createObjectURL(blob);
534
+ const link = document.createElement('a');
535
+ link.href = url;
536
+ const disposition = response.headers['content-disposition'];
537
+ let filename = 'report.csv';
538
+ if (disposition && disposition.includes('filename=')) {
539
+ filename = disposition.split('filename=')[1].replace(/"/g, '');
540
+ }
541
+ link.download = filename;
542
+ link.click();
543
+ // Cleanup
544
+ window.URL.revokeObjectURL(url);
545
+ })
546
+ .catch((error) => {
547
+ utils_1.Logger.error(Errors_1.SCOPE_SC_UI, error);
548
+ enqueueSnackbar((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.common.error.action", defaultMessage: "ui.common.error.action" }), {
549
+ variant: 'error',
550
+ autoHideDuration: 3000
551
+ });
552
+ });
553
+ handleClose();
554
+ }
525
555
  }
526
556
  /**
527
557
  * Perform additional operations at the end of single action
@@ -740,8 +770,8 @@ function ContributionActionsMenu(props) {
740
770
  */
741
771
  function canSuspendNotificationContribution() {
742
772
  return (scUserContext.user &&
743
- scUserContext.user.id !== contributionObj.author.id &&
744
773
  contributionObj &&
774
+ scUserContext.user.id !== contributionObj.author.id &&
745
775
  contributionObj.type !== types_1.SCContributionType.COMMENT);
746
776
  }
747
777
  /**
@@ -749,17 +779,25 @@ function ContributionActionsMenu(props) {
749
779
  */
750
780
  function canSuspendNotificationEvent() {
751
781
  return (scUserContext.user &&
752
- scUserContext.user.id !== contributionObj.author.id &&
753
782
  contributionObj &&
783
+ scUserContext.user.id !== contributionObj.author.id &&
754
784
  contributionObj.type !== types_1.SCContributionType.COMMENT &&
755
785
  Boolean(contributionObj.event) &&
756
786
  Boolean(contributionObj.event.active));
757
787
  }
788
+ /**
789
+ * Can publisher user or admin user download views and clicks csv
790
+ */
791
+ function canDownloadCSV() {
792
+ return (scUserContext.user &&
793
+ contributionObj &&
794
+ ((scUserContext.user.id === contributionObj.author.id && react_core_1.UserUtils.isPublisher(scUserContext.user)) || react_core_1.UserUtils.isAdmin(scUserContext.user)));
795
+ }
758
796
  /**
759
797
  * Renders section general
760
798
  */
761
799
  function renderGeneralSection() {
762
- return ((0, jsx_runtime_1.jsxs)(material_1.Box, { children: [(0, jsx_runtime_1.jsxs)(material_1.MenuItem, Object.assign({ className: classes.subItem, disabled: isFlagging }, { children: [(0, jsx_runtime_1.jsx)(material_1.ListItemIcon, { children: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "link" }) }), (0, jsx_runtime_1.jsx)(material_1.ListItemText, { primary: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.contributionActionMenu.permanentLink", defaultMessage: "ui.contributionActionMenu.permanentLink" }), onClick: () => handleAction(ContributionsActionsMenu_1.GET_CONTRIBUTION_PERMALINK), classes: { root: classes.itemText } })] })), canModifyContribution() && ((0, jsx_runtime_1.jsxs)(material_1.MenuItem, Object.assign({ className: classes.subItem, disabled: isFlagging }, { children: [(0, jsx_runtime_1.jsx)(material_1.ListItemIcon, { children: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "edit" }) }), (0, jsx_runtime_1.jsx)(material_1.ListItemText, { primary: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.contributionActionMenu.editContribution", defaultMessage: "ui.contributionActionMenu.editContribution" }), onClick: () => handleAction(ContributionsActionsMenu_1.EDIT_CONTRIBUTION), classes: { root: classes.itemText } })] }))), canDeleteContribution() && ((0, jsx_runtime_1.jsxs)(material_1.MenuItem, Object.assign({ className: classes.subItem, disabled: isFlagging }, { children: [(0, jsx_runtime_1.jsx)(material_1.ListItemIcon, { children: currentActionLoading === ContributionsActionsMenu_1.DELETE_CONTRIBUTION || currentActionLoading === ContributionsActionsMenu_1.RESTORE_CONTRIBUTION ? ((0, jsx_runtime_1.jsx)(material_1.CircularProgress, { size: 20 })) : ((0, jsx_runtime_1.jsx)(material_1.Icon, { children: "delete" })) }), contributionObj.deleted ? ((0, jsx_runtime_1.jsx)(material_1.ListItemText, { primary: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.contributionActionMenu.restoreContribution", defaultMessage: "ui.contributionActionMenu.restoreContribution" }), onClick: () => handleAction(ContributionsActionsMenu_1.RESTORE_CONTRIBUTION), classes: { root: classes.itemText } })) : ((0, jsx_runtime_1.jsx)(material_1.ListItemText, { primary: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.contributionActionMenu.deleteContribution", defaultMessage: "ui.contributionActionMenu.deleteContribution" }), onClick: () => handleAction(ContributionsActionsMenu_1.DELETE_CONTRIBUTION), classes: { root: classes.itemText } }))] }))), canPublishContribution() && ((0, jsx_runtime_1.jsxs)(material_1.MenuItem, Object.assign({ className: classes.subItem, disabled: isFlagging }, { children: [(0, jsx_runtime_1.jsx)(material_1.ListItemIcon, { children: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "upload" }) }), (0, jsx_runtime_1.jsx)(material_1.ListItemText, { primary: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.contributionActionMenu.publishContribution", defaultMessage: "ui.contributionActionMenu.publishContribution" }), onClick: () => handleAction(ContributionsActionsMenu_1.PUBLISH_CONTRIBUTION), classes: { root: classes.itemText } })] }))), canSuspendNotificationContribution() && ((0, jsx_runtime_1.jsxs)(material_1.MenuItem, Object.assign({ className: classes.subItem, disabled: isFlagging }, { children: [(0, jsx_runtime_1.jsx)(material_1.ListItemIcon, { children: currentActionLoading === ContributionsActionsMenu_1.SUSPEND_NOTIFICATION_CONTRIBUTION ? ((0, jsx_runtime_1.jsx)(material_1.CircularProgress, { size: 20 })) : contributionObj['suspended'] ? ((0, jsx_runtime_1.jsx)(material_1.Icon, { children: "notifications_active" })) : ((0, jsx_runtime_1.jsx)(material_1.Icon, { children: "notifications_off" })) }), (0, jsx_runtime_1.jsx)(material_1.ListItemText, { primary: contributionObj['suspended'] ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.contributionActionMenu.enableNotificationContribution", defaultMessage: "ui.contributionActionMenu.enableNotificationContribution" })) : ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.contributionActionMenu.suspendNotificationContribution", defaultMessage: "ui.contributionActionMenu.suspendNotificationContribution" })), onClick: () => handleAction(ContributionsActionsMenu_1.SUSPEND_NOTIFICATION_CONTRIBUTION), classes: { root: classes.itemText } })] }))), canSuspendNotificationEvent() && ((0, jsx_runtime_1.jsxs)(material_1.MenuItem, Object.assign({ className: classes.subItem, disabled: isFlagging }, { children: [(0, jsx_runtime_1.jsx)(material_1.ListItemIcon, { children: currentActionLoading === ContributionsActionsMenu_1.SUSPEND_NOTIFICATION_EVENT ? ((0, jsx_runtime_1.jsx)(material_1.CircularProgress, { size: 20 })) : contributionObj.event['show_on_feed'] ? ((0, jsx_runtime_1.jsx)(material_1.Icon, { children: "notifications_active" })) : ((0, jsx_runtime_1.jsx)(material_1.Icon, { children: "notifications_off" })) }), (0, jsx_runtime_1.jsx)(material_1.ListItemText, { primary: !contributionObj.event['show_on_feed'] ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.contributionActionMenu.enableNotificationContribution", defaultMessage: "ui.contributionActionMenu.enableNotificationContribution" })) : ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.contributionActionMenu.suspendNotificationContribution", defaultMessage: "ui.contributionActionMenu.suspendNotificationContribution" })), onClick: () => handleAction(ContributionsActionsMenu_1.SUSPEND_NOTIFICATION_EVENT), classes: { root: classes.itemText } })] })))] }, ContributionsActionsMenu_1.GENERAL_SECTION));
800
+ return ((0, jsx_runtime_1.jsxs)(material_1.Box, { children: [(0, jsx_runtime_1.jsxs)(material_1.MenuItem, Object.assign({ className: classes.subItem, disabled: isFlagging }, { children: [(0, jsx_runtime_1.jsx)(material_1.ListItemIcon, { children: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "link" }) }), (0, jsx_runtime_1.jsx)(material_1.ListItemText, { primary: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.contributionActionMenu.permanentLink", defaultMessage: "ui.contributionActionMenu.permanentLink" }), onClick: () => handleAction(ContributionsActionsMenu_1.GET_CONTRIBUTION_PERMALINK), classes: { root: classes.itemText } })] })), canModifyContribution() && ((0, jsx_runtime_1.jsxs)(material_1.MenuItem, Object.assign({ className: classes.subItem, disabled: isFlagging }, { children: [(0, jsx_runtime_1.jsx)(material_1.ListItemIcon, { children: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "edit" }) }), (0, jsx_runtime_1.jsx)(material_1.ListItemText, { primary: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.contributionActionMenu.editContribution", defaultMessage: "ui.contributionActionMenu.editContribution" }), onClick: () => handleAction(ContributionsActionsMenu_1.EDIT_CONTRIBUTION), classes: { root: classes.itemText } })] }))), canDeleteContribution() && ((0, jsx_runtime_1.jsxs)(material_1.MenuItem, Object.assign({ className: classes.subItem, disabled: isFlagging }, { children: [(0, jsx_runtime_1.jsx)(material_1.ListItemIcon, { children: currentActionLoading === ContributionsActionsMenu_1.DELETE_CONTRIBUTION || currentActionLoading === ContributionsActionsMenu_1.RESTORE_CONTRIBUTION ? ((0, jsx_runtime_1.jsx)(material_1.CircularProgress, { size: 20 })) : ((0, jsx_runtime_1.jsx)(material_1.Icon, { children: "delete" })) }), contributionObj.deleted ? ((0, jsx_runtime_1.jsx)(material_1.ListItemText, { primary: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.contributionActionMenu.restoreContribution", defaultMessage: "ui.contributionActionMenu.restoreContribution" }), onClick: () => handleAction(ContributionsActionsMenu_1.RESTORE_CONTRIBUTION), classes: { root: classes.itemText } })) : ((0, jsx_runtime_1.jsx)(material_1.ListItemText, { primary: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.contributionActionMenu.deleteContribution", defaultMessage: "ui.contributionActionMenu.deleteContribution" }), onClick: () => handleAction(ContributionsActionsMenu_1.DELETE_CONTRIBUTION), classes: { root: classes.itemText } }))] }))), canPublishContribution() && ((0, jsx_runtime_1.jsxs)(material_1.MenuItem, Object.assign({ className: classes.subItem, disabled: isFlagging }, { children: [(0, jsx_runtime_1.jsx)(material_1.ListItemIcon, { children: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "upload" }) }), (0, jsx_runtime_1.jsx)(material_1.ListItemText, { primary: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.contributionActionMenu.publishContribution", defaultMessage: "ui.contributionActionMenu.publishContribution" }), onClick: () => handleAction(ContributionsActionsMenu_1.PUBLISH_CONTRIBUTION), classes: { root: classes.itemText } })] }))), canSuspendNotificationContribution() && ((0, jsx_runtime_1.jsxs)(material_1.MenuItem, Object.assign({ className: classes.subItem, disabled: isFlagging }, { children: [(0, jsx_runtime_1.jsx)(material_1.ListItemIcon, { children: currentActionLoading === ContributionsActionsMenu_1.SUSPEND_NOTIFICATION_CONTRIBUTION ? ((0, jsx_runtime_1.jsx)(material_1.CircularProgress, { size: 20 })) : contributionObj['suspended'] ? ((0, jsx_runtime_1.jsx)(material_1.Icon, { children: "notifications_active" })) : ((0, jsx_runtime_1.jsx)(material_1.Icon, { children: "notifications_off" })) }), (0, jsx_runtime_1.jsx)(material_1.ListItemText, { primary: contributionObj['suspended'] ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.contributionActionMenu.enableNotificationContribution", defaultMessage: "ui.contributionActionMenu.enableNotificationContribution" })) : ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.contributionActionMenu.suspendNotificationContribution", defaultMessage: "ui.contributionActionMenu.suspendNotificationContribution" })), onClick: () => handleAction(ContributionsActionsMenu_1.SUSPEND_NOTIFICATION_CONTRIBUTION), classes: { root: classes.itemText } })] }))), canSuspendNotificationEvent() && ((0, jsx_runtime_1.jsxs)(material_1.MenuItem, Object.assign({ className: classes.subItem, disabled: isFlagging }, { children: [(0, jsx_runtime_1.jsx)(material_1.ListItemIcon, { children: currentActionLoading === ContributionsActionsMenu_1.SUSPEND_NOTIFICATION_EVENT ? ((0, jsx_runtime_1.jsx)(material_1.CircularProgress, { size: 20 })) : contributionObj.event['show_on_feed'] ? ((0, jsx_runtime_1.jsx)(material_1.Icon, { children: "notifications_active" })) : ((0, jsx_runtime_1.jsx)(material_1.Icon, { children: "notifications_off" })) }), (0, jsx_runtime_1.jsx)(material_1.ListItemText, { primary: !contributionObj.event['show_on_feed'] ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.contributionActionMenu.enableNotificationContribution", defaultMessage: "ui.contributionActionMenu.enableNotificationContribution" })) : ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.contributionActionMenu.suspendNotificationContribution", defaultMessage: "ui.contributionActionMenu.suspendNotificationContribution" })), onClick: () => handleAction(ContributionsActionsMenu_1.SUSPEND_NOTIFICATION_EVENT), classes: { root: classes.itemText } })] }))), canDownloadCSV() && ((0, jsx_runtime_1.jsxs)(material_1.MenuItem, Object.assign({ className: classes.subItem }, { children: [(0, jsx_runtime_1.jsx)(material_1.ListItemIcon, { children: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "download" }) }), (0, jsx_runtime_1.jsx)(material_1.ListItemText, { primary: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.contributionActionMenu.downloadCSV", defaultMessage: "ui.contributionActionMenu.downloadCSV" }), onClick: () => handleAction(ContributionsActionsMenu_1.DOWNLOAD_CSV), classes: { root: classes.itemText } })] })))] }, ContributionsActionsMenu_1.GENERAL_SECTION));
763
801
  }
764
802
  /**
765
803
  * Renders contribution menu content
@@ -2,7 +2,7 @@ import { __rest } from "tslib";
2
2
  import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import { useMemo } from 'react';
4
4
  import { Avatar, Tooltip, Typography, styled } from '@mui/material';
5
- import { Link, SCRoutes, useSCFetchCategory, useSCRouting } from '@selfcommunity/react-core';
5
+ import { Link, SCPreferences, SCRoutes, useSCFetchCategory, useSCPreferenceEnabled, useSCRouting } from '@selfcommunity/react-core';
6
6
  import { SCCategoryAutoFollowType } from '@selfcommunity/types';
7
7
  import CategorySkeleton from './Skeleton';
8
8
  import CategoryFollowButton from '../CategoryFollowButton';
@@ -70,17 +70,20 @@ export default function Category(inProps) {
70
70
  // CONTEXT
71
71
  const scRoutingContext = useSCRouting();
72
72
  // STATE
73
- const { scCategory, setSCCategory } = useSCFetchCategory(Object.assign({ id: categoryId, category }, (cacheStrategy && { cacheStrategy })));
73
+ const { scCategory } = useSCFetchCategory(Object.assign({ id: categoryId, category }, (cacheStrategy && { cacheStrategy })));
74
74
  // MEMO
75
75
  const _ButtonBaseProps = useMemo(() => ButtonBaseProps ? ButtonBaseProps : { component: Link, to: scCategory ? scRoutingContext.url(SCRoutes.CATEGORY_ROUTE_NAME, scCategory) : '' }, [ButtonBaseProps, scRoutingContext, scCategory]);
76
76
  // HOOKS
77
77
  const intl = useIntl();
78
+ const categoryFollowEnabled = useSCPreferenceEnabled(SCPreferences.CONFIGURATIONS_CATEGORY_FOLLOW_ENABLED);
78
79
  if (!scCategory) {
79
80
  return _jsx(CategorySkeleton, Object.assign({ elevation: elevation }, (variant && { variant })));
80
81
  }
81
82
  // RENDER
82
83
  if (!autoHide) {
83
- return (_jsx(Root, Object.assign({ disableTypography: showTooltip, elevation: elevation }, (variant && { variant }), { className: classNames(classes.root, className, { [classes.followed]: scCategory.followed }, { [classes.autoFollowed]: scCategory.auto_follow === SCCategoryAutoFollowType.FORCED }), ButtonBaseProps: _ButtonBaseProps, image: _jsx(Avatar, { alt: scCategory.name, src: scCategory.image_medium, variant: "square", className: classes.categoryImage }), primary: _jsx(_Fragment, { children: showTooltip ? (_jsx(Tooltip, Object.assign({ title: scCategory.name }, { children: _jsx(Typography, Object.assign({ className: classes.primary, component: "span", variant: "body1" }, { children: scCategory.name })) }))) : (scCategory.name) }), secondary: _jsx(_Fragment, { children: showTooltip ? (_jsx(Typography, Object.assign({ className: classes.secondary, component: "p", variant: "body2" }, { children: showFollowers ? `${intl.formatMessage(messages.categoryFollowers, { total: scCategory.followers_counter })}` : scCategory.slogan }))) : (_jsx(_Fragment, { children: showFollowers ? `${intl.formatMessage(messages.categoryFollowers, { total: scCategory.followers_counter })}` : scCategory.slogan })) }), actions: _jsx(CategoryFollowButton, Object.assign({ category: scCategory }, categoryFollowButtonProps)) }, rest)));
84
+ return (_jsx(Root, Object.assign({ disableTypography: showTooltip, elevation: elevation }, (variant && { variant }), { className: classNames(classes.root, className, { [classes.followed]: scCategory.followed }, { [classes.autoFollowed]: scCategory.auto_follow === SCCategoryAutoFollowType.FORCED }), ButtonBaseProps: _ButtonBaseProps, image: _jsx(Avatar, { alt: scCategory.name, src: scCategory.image_medium, variant: "square", className: classes.categoryImage }), primary: _jsx(_Fragment, { children: showTooltip ? (_jsx(Tooltip, Object.assign({ title: scCategory.name }, { children: _jsx(Typography, Object.assign({ className: classes.primary, component: "span", variant: "body1" }, { children: scCategory.name })) }))) : (scCategory.name) }), secondary: _jsx(_Fragment, { children: showTooltip ? (_jsx(Typography, Object.assign({ className: classes.secondary, component: "p", variant: "body2" }, { children: showFollowers ? `${intl.formatMessage(messages.categoryFollowers, { total: scCategory.followers_counter })}` : scCategory.slogan }))) : (_jsx(_Fragment, { children: showFollowers && categoryFollowEnabled
85
+ ? `${intl.formatMessage(messages.categoryFollowers, { total: scCategory.followers_counter })}`
86
+ : scCategory.slogan })) }), actions: _jsx(CategoryFollowButton, Object.assign({ category: scCategory }, categoryFollowButtonProps)) }, rest)));
84
87
  }
85
88
  return null;
86
89
  }
@@ -57,5 +57,5 @@ export default (props) => {
57
57
  }, [onClick]);
58
58
  return (_jsxs(Root, Object.assign({ className: classNames(classes.root, className) }, { children: [((_a = value === null || value === void 0 ? void 0 : value.categories) === null || _a === void 0 ? void 0 : _a.length) > 0 &&
59
59
  (value === null || value === void 0 ? void 0 : value.categories.map((c) => (_jsx(Chip, { label: c.name, onDelete: handleDeleteCategory(c.id), icon: _jsx(Icon, { children: "category" }), onClick: handleClickCategory }, c.id)))), (value === null || value === void 0 ? void 0 : value.group) && (_jsx(Chip, { label: value === null || value === void 0 ? void 0 : value.group.name, onDelete: handleDeleteGroup, icon: _jsx(Icon, { children: "groups" }), onClick: handleClickGroup, disabled: !((_b = value === null || value === void 0 ? void 0 : value.group) === null || _b === void 0 ? void 0 : _b.subscription_status) }, value === null || value === void 0 ? void 0 : value.group.id)), (value === null || value === void 0 ? void 0 : value.event) && (_jsx(Chip, { label: value === null || value === void 0 ? void 0 : value.event.name, onDelete: handleDeleteEvent, icon: _jsx(Icon, { children: "CalendarIcon" }), onClick: handleClickEvent, disabled: !((_c = value === null || value === void 0 ? void 0 : value.event) === null || _c === void 0 ? void 0 : _c.subscription_status) }, value === null || value === void 0 ? void 0 : value.event.id)), ((_d = value === null || value === void 0 ? void 0 : value.addressing) === null || _d === void 0 ? void 0 : _d.length) > 0 &&
60
- (value === null || value === void 0 ? void 0 : value.addressing.map((t) => (_jsx(TagChip, { tag: t, onDelete: handleDeleteTag(t.id), icon: _jsx(Icon, { children: "label" }), onClick: handleClickTag }, t.id)))), _jsx(_Fragment, { children: ((_e = value === null || value === void 0 ? void 0 : value.recipients) === null || _e === void 0 ? void 0 : _e.length) > 0 && (_jsxs(_Fragment, { children: [value.recipients.slice(0, 3).map((r) => (_jsx(Chip, { label: typeof r === 'object' ? r.username : r, icon: _jsx(Icon, { children: "people_alt" }), onClick: handleClickRecipient, onDelete: handleDeleteRecipient(typeof r === 'object' ? r.id : r) }, typeof r === 'object' ? r.id : r))), value.recipients.length > 3 && _jsx(Chip, { label: `+${value.recipients.length - 3}` })] })) }), (value === null || value === void 0 ? void 0 : value.location) && (_jsx(Chip, { icon: _jsx(Icon, { children: "add_location_alt" }), label: value === null || value === void 0 ? void 0 : value.location.location, onDelete: handleDeleteLocation, onClick: handleClickLocation }))] })));
60
+ (value === null || value === void 0 ? void 0 : value.addressing.map((t) => (_jsx(TagChip, { tag: t, onDelete: handleDeleteTag(t.id), icon: _jsx(Icon, { children: "label" }), onClick: handleClickTag }, t.id)))), _jsx(_Fragment, { children: ((_e = value === null || value === void 0 ? void 0 : value.recipients) === null || _e === void 0 ? void 0 : _e.length) > 0 && (_jsxs(_Fragment, { children: [value.recipients.slice(0, 3).map((r) => (_jsx(Chip, { label: typeof r === 'object' ? r.username : r, icon: _jsx(Icon, { children: "people_alt" }), onClick: handleClickRecipient, onDelete: handleDeleteRecipient(typeof r === 'object' ? r.id : r) }, typeof r === 'object' ? r.id : r))), value.recipients.length > 3 && _jsx(Chip, { label: `+${value.recipients.length - 3}`, onClick: handleClickRecipient })] })) }), (value === null || value === void 0 ? void 0 : value.location) && (_jsx(Chip, { icon: _jsx(Icon, { children: "add_location_alt" }), label: value === null || value === void 0 ? void 0 : value.location.location, onDelete: handleDeleteLocation, onClick: handleClickLocation }))] })));
61
61
  };
@@ -52,7 +52,7 @@ const Root = styled(Dialog, {
52
52
  const LayerTransitionRoot = styled(Slide, {
53
53
  name: PREFIX,
54
54
  slot: 'LayerTransitionRoot'
55
- })(({ theme }) => ({}));
55
+ })(() => ({}));
56
56
  const COMPOSER_INITIAL_STATE = {
57
57
  id: null,
58
58
  type: null,
@@ -375,8 +375,9 @@ export default function Composer(inProps) {
375
375
  else if (event || (value && Object.prototype.hasOwnProperty.call(value, 'recurring'))) {
376
376
  dispatch({ type: 'event', value });
377
377
  }
378
- else if ((recipients === null || recipients === void 0 ? void 0 : recipients.length) > 0 ||
379
- (Array.isArray(value) && value.some((item) => typeof item === 'object' && item !== null && !('color' in item)))) {
378
+ else if ((Array.isArray(value) &&
379
+ value.some((item) => (typeof item === 'object' && item !== null && !('color' in item)) || typeof item === 'string')) ||
380
+ (Array.isArray(recipients) && recipients.length > 0)) {
380
381
  dispatch({
381
382
  type: 'multiple',
382
383
  value: {
@@ -529,7 +530,7 @@ export default function Composer(inProps) {
529
530
  data.addressing = addressing.map((t) => t.id);
530
531
  }
531
532
  if (features.includes(SCFeatureName.TAGGING) && recipients !== null) {
532
- data.recipients = recipients.map((r) => r.username);
533
+ data.recipients = recipients.map((r) => (typeof r === 'string' ? r : r.username));
533
534
  }
534
535
  if (features.includes(SCFeatureName.TAGGING) &&
535
536
  features.includes(SCFeatureName.GROUPING) &&
@@ -1,6 +1,6 @@
1
1
  import { __rest } from "tslib";
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { Fragment, useEffect, useState } from 'react';
3
+ import React, { Fragment, useEffect, useState } from 'react';
4
4
  import { FormattedMessage } from 'react-intl';
5
5
  import parse from 'autosuggest-highlight/parse';
6
6
  import match from 'autosuggest-highlight/match';
@@ -35,41 +35,21 @@ const UserAutocomplete = (inProps) => {
35
35
  // State
36
36
  const [open, setOpen] = useState(false);
37
37
  const [inputValue, setInputValue] = useState('');
38
- const [usersMap, setUsersMap] = useState({});
39
- const [value, setValue] = useState([]);
38
+ const [value, setValue] = useState(Array.isArray(defaultValue) ? defaultValue : defaultValue ? [defaultValue] : []);
40
39
  const [textAreaValue, setTextAreaValue] = useState('');
41
40
  // Fetch users
42
- const { users, isLoading } = useSCFetchUsers();
43
- // Build map for quick lookup by username
44
- useEffect(() => {
45
- const map = {};
46
- users === null || users === void 0 ? void 0 : users.forEach((u) => {
47
- map[u.username] = u;
48
- });
49
- setUsersMap(map);
50
- }, [users]);
51
- // Initialize value from defaultValue (string or object)
52
- useEffect(() => {
53
- if (!defaultValue)
54
- return;
55
- const initial = (Array.isArray(defaultValue) ? defaultValue : [defaultValue]).map((v) => {
56
- if (typeof v === 'string') {
57
- // Use fetched user if available, otherwise fallback object
58
- return usersMap[v] || { id: `fallback-${v}`, username: v, avatar: '' };
59
- }
60
- return v;
61
- });
62
- setValue(initial);
63
- setTextAreaValue(initial.map((u) => u.username).join('\n'));
64
- }, [defaultValue, usersMap]);
65
- // Trigger onChange and sync textarea
41
+ const { users, isLoading } = useSCFetchUsers({ search: inputValue });
66
42
  useEffect(() => {
67
43
  onChange === null || onChange === void 0 ? void 0 : onChange(value);
68
- setTextAreaValue(value.map((u) => u.username).join('\n'));
44
+ setTextAreaValue(value.map((u) => (typeof u === 'object' ? u.username : u)).join('\n'));
69
45
  }, [value]);
70
46
  // Handlers
71
- const handleOpen = () => setOpen(true);
72
- const handleClose = () => setOpen(false);
47
+ const handleOpen = () => {
48
+ setOpen(true);
49
+ };
50
+ const handleClose = () => {
51
+ setOpen(false);
52
+ };
73
53
  const handleChange = (_event, newValue) => {
74
54
  setValue(newValue);
75
55
  };
@@ -78,13 +58,29 @@ const UserAutocomplete = (inProps) => {
78
58
  .split(/\s|,|\n/)
79
59
  .map((s) => s.trim())
80
60
  .filter(Boolean);
81
- const matched = names.map((n) => usersMap[n] || { id: `fallback-${n}`, username: n, avatar: '' });
61
+ const matched = names.map((name) => {
62
+ const user = users.find((u) => u.username === name);
63
+ return user || name;
64
+ });
82
65
  setValue(matched);
83
66
  setTextAreaValue(e.target.value);
84
67
  };
85
- return (_jsxs(Root, Object.assign({ className: classes.root }, { children: [_jsx(AutocompleteRoot, Object.assign({ multiple: true, className: classes.autocompleteRoot, open: open, onOpen: handleOpen, onClose: handleClose, options: users || [], getOptionLabel: (option) => option.username || '', value: value, inputValue: inputValue, onInputChange: (_e, newInput) => setInputValue(newInput), selectOnFocus: true, clearOnBlur: true, blurOnSelect: true, handleHomeEndKeys: true, clearIcon: null, disabled: disabled || isLoading, noOptionsText: _jsx(FormattedMessage, { id: "ui.userAutocomplete.empty", defaultMessage: "ui.userAutocomplete.empty" }), onChange: handleChange, isOptionEqualToValue: (option, val) => option.id === val.id, renderTags: (value, getTagProps) => value.map((option, index) => (_jsx(Chip, Object.assign({ avatar: _jsx(Avatar, { src: option.avatar }), label: option.username }, getTagProps({ index })), option.id))), renderOption: (props, option, { inputValue }) => {
86
- const parts = parse(option.username, match(option.username, inputValue));
87
- return (_jsxs(Box, Object.assign({ component: "li" }, props, { children: [_jsx(Avatar, { alt: option.username, src: option.avatar, sx: { mr: 1 } }), parts.map((part, index) => (_jsx(Typography, Object.assign({ sx: { fontWeight: part.highlight ? 700 : 400 } }, { children: part.text }), index)))] })));
68
+ return (_jsxs(Root, Object.assign({ className: classes.root }, { children: [_jsx(AutocompleteRoot, Object.assign({ multiple: true, className: classes.autocompleteRoot, open: open, onOpen: handleOpen, onClose: handleClose, options: users || [], getOptionLabel: (option) => option.username || '', value: value, inputValue: inputValue, onInputChange: (_event, newInputValue) => {
69
+ setInputValue(newInputValue);
70
+ }, selectOnFocus: true, clearOnBlur: true, blurOnSelect: true, handleHomeEndKeys: true, clearIcon: null, disabled: disabled || isLoading, noOptionsText: _jsx(FormattedMessage, { id: "ui.userAutocomplete.empty", defaultMessage: "ui.userAutocomplete.empty" }), onChange: handleChange, isOptionEqualToValue: (option, val) => {
71
+ if (typeof val === 'string') {
72
+ return option.username === val;
73
+ }
74
+ return option.id === val.id;
75
+ }, renderTags: (value, getTagProps) => value.map((option, index) => {
76
+ const username = typeof option === 'string' ? option : option.username;
77
+ const avatar = typeof option === 'string' ? '' : option.avatar;
78
+ const id = typeof option === 'string' ? `fallback-${option}` : option.id;
79
+ return _jsx(Chip, Object.assign({ avatar: _jsx(Avatar, { src: avatar }), label: username }, getTagProps({ index })), id);
80
+ }), renderOption: (props, option, { inputValue }) => {
81
+ const matches = match(option.username, inputValue);
82
+ const parts = parse(option.username, matches);
83
+ return (_jsxs(Box, Object.assign({ component: "li" }, props, { children: [_jsx(Avatar, { alt: option.username, src: option.avatar, sx: { marginRight: 1 } }), _jsx(React.Fragment, { children: parts.map((part, index) => (_jsx(Typography, Object.assign({ sx: { fontWeight: part.highlight ? 700 : 400 } }, { children: part.text }), index))) })] })));
88
84
  }, renderInput: (params) => (_jsx(TextField, Object.assign({}, params, TextFieldProps, { margin: "dense", InputProps: Object.assign(Object.assign({}, params.InputProps), { autoComplete: 'off', endAdornment: (_jsxs(Fragment, { children: [isLoading ? _jsx(CircularProgress, { color: "inherit", size: 20 }) : null, params.InputProps.endAdornment] })) }) }))) }, rest)), _jsx(Typography, Object.assign({ variant: "body2", color: "primary", className: classes.info }, { children: _jsx(FormattedMessage, { id: "ui.userAutocomplete.textarea.info", defaultMessage: "ui.userAutocomplete.textarea.info", values: {
89
85
  // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
90
86
  // @ts-ignore
@@ -18,3 +18,4 @@ export declare const SUSPEND_NOTIFICATION_CONTRIBUTION = "_suspend_notification_
18
18
  export declare const SUSPEND_NOTIFICATION_EVENT = "_suspend_notification_event";
19
19
  export declare const MODERATE_CONTRIBUTION_HIDDEN = "_moderate_contribution_hidden";
20
20
  export declare const MODERATE_CONTRIBUTION_DELETED = "_moderate_contribution_deleted";
21
+ export declare const DOWNLOAD_CSV = "_download_csv";
@@ -18,3 +18,4 @@ export const SUSPEND_NOTIFICATION_CONTRIBUTION = '_suspend_notification_contribu
18
18
  export const SUSPEND_NOTIFICATION_EVENT = '_suspend_notification_event';
19
19
  export const MODERATE_CONTRIBUTION_HIDDEN = '_moderate_contribution_hidden';
20
20
  export const MODERATE_CONTRIBUTION_DELETED = '_moderate_contribution_deleted';
21
+ export const DOWNLOAD_CSV = '_download_csv';
@@ -14,7 +14,7 @@ import { MODERATION_CONTRIBUTION_STATE_DELETED, MODERATION_CONTRIBUTION_STATE_HI
14
14
  import { Endpoints, http } from '@selfcommunity/api-services';
15
15
  import { SCContext, SCPreferences, SCUserContext, UserUtils, useSCFetchCommentObject, useSCFetchFeedObject, useSCPreferences, useSCRouting } from '@selfcommunity/react-core';
16
16
  import { SCContributionType } from '@selfcommunity/types';
17
- import { DELETE_CONTRIBUTION, DELETE_CONTRIBUTION_SECTION, EDIT_CONTRIBUTION, FLAG_CONTRIBUTION_SECTION, GENERAL_SECTION, GET_CONTRIBUTION_PERMALINK, HIDE_CONTRIBUTION_SECTION, MODERATE_CONTRIBUTION_DELETED, MODERATE_CONTRIBUTION_HIDDEN, PUBLISH_CONTRIBUTION, RESTORE_CONTRIBUTION, SUSPEND_NOTIFICATION_CONTRIBUTION, SUSPEND_NOTIFICATION_EVENT } from '../../constants/ContributionsActionsMenu';
17
+ import { DELETE_CONTRIBUTION, DELETE_CONTRIBUTION_SECTION, DOWNLOAD_CSV, EDIT_CONTRIBUTION, FLAG_CONTRIBUTION_SECTION, GENERAL_SECTION, GET_CONTRIBUTION_PERMALINK, HIDE_CONTRIBUTION_SECTION, MODERATE_CONTRIBUTION_DELETED, MODERATE_CONTRIBUTION_HIDDEN, PUBLISH_CONTRIBUTION, RESTORE_CONTRIBUTION, SUSPEND_NOTIFICATION_CONTRIBUTION, SUSPEND_NOTIFICATION_EVENT } from '../../constants/ContributionsActionsMenu';
18
18
  const PREFIX = 'SCContributionActionsMenu';
19
19
  const classes = {
20
20
  root: `${PREFIX}-root`,
@@ -520,6 +520,36 @@ export default function ContributionActionsMenu(props) {
520
520
  setOpenConfirmDialog(true);
521
521
  handleClose();
522
522
  }
523
+ else if (action === DOWNLOAD_CSV) {
524
+ http
525
+ .request({
526
+ url: `${Endpoints.GetDownloadCSV.url({ type: contributionObj.type, id: contributionObj.id })}`,
527
+ method: Endpoints.GetDownloadCSV.method
528
+ })
529
+ .then((response) => {
530
+ const blob = new Blob([response.data], { type: 'text/csv' });
531
+ const url = window.URL.createObjectURL(blob);
532
+ const link = document.createElement('a');
533
+ link.href = url;
534
+ const disposition = response.headers['content-disposition'];
535
+ let filename = 'report.csv';
536
+ if (disposition && disposition.includes('filename=')) {
537
+ filename = disposition.split('filename=')[1].replace(/"/g, '');
538
+ }
539
+ link.download = filename;
540
+ link.click();
541
+ // Cleanup
542
+ window.URL.revokeObjectURL(url);
543
+ })
544
+ .catch((error) => {
545
+ Logger.error(SCOPE_SC_UI, error);
546
+ enqueueSnackbar(_jsx(FormattedMessage, { id: "ui.common.error.action", defaultMessage: "ui.common.error.action" }), {
547
+ variant: 'error',
548
+ autoHideDuration: 3000
549
+ });
550
+ });
551
+ handleClose();
552
+ }
523
553
  }
524
554
  /**
525
555
  * Perform additional operations at the end of single action
@@ -738,8 +768,8 @@ export default function ContributionActionsMenu(props) {
738
768
  */
739
769
  function canSuspendNotificationContribution() {
740
770
  return (scUserContext.user &&
741
- scUserContext.user.id !== contributionObj.author.id &&
742
771
  contributionObj &&
772
+ scUserContext.user.id !== contributionObj.author.id &&
743
773
  contributionObj.type !== SCContributionType.COMMENT);
744
774
  }
745
775
  /**
@@ -747,17 +777,25 @@ export default function ContributionActionsMenu(props) {
747
777
  */
748
778
  function canSuspendNotificationEvent() {
749
779
  return (scUserContext.user &&
750
- scUserContext.user.id !== contributionObj.author.id &&
751
780
  contributionObj &&
781
+ scUserContext.user.id !== contributionObj.author.id &&
752
782
  contributionObj.type !== SCContributionType.COMMENT &&
753
783
  Boolean(contributionObj.event) &&
754
784
  Boolean(contributionObj.event.active));
755
785
  }
786
+ /**
787
+ * Can publisher user or admin user download views and clicks csv
788
+ */
789
+ function canDownloadCSV() {
790
+ return (scUserContext.user &&
791
+ contributionObj &&
792
+ ((scUserContext.user.id === contributionObj.author.id && UserUtils.isPublisher(scUserContext.user)) || UserUtils.isAdmin(scUserContext.user)));
793
+ }
756
794
  /**
757
795
  * Renders section general
758
796
  */
759
797
  function renderGeneralSection() {
760
- return (_jsxs(Box, { children: [_jsxs(MenuItem, Object.assign({ className: classes.subItem, disabled: isFlagging }, { children: [_jsx(ListItemIcon, { children: _jsx(Icon, { children: "link" }) }), _jsx(ListItemText, { primary: _jsx(FormattedMessage, { id: "ui.contributionActionMenu.permanentLink", defaultMessage: "ui.contributionActionMenu.permanentLink" }), onClick: () => handleAction(GET_CONTRIBUTION_PERMALINK), classes: { root: classes.itemText } })] })), canModifyContribution() && (_jsxs(MenuItem, Object.assign({ className: classes.subItem, disabled: isFlagging }, { children: [_jsx(ListItemIcon, { children: _jsx(Icon, { children: "edit" }) }), _jsx(ListItemText, { primary: _jsx(FormattedMessage, { id: "ui.contributionActionMenu.editContribution", defaultMessage: "ui.contributionActionMenu.editContribution" }), onClick: () => handleAction(EDIT_CONTRIBUTION), classes: { root: classes.itemText } })] }))), canDeleteContribution() && (_jsxs(MenuItem, Object.assign({ className: classes.subItem, disabled: isFlagging }, { children: [_jsx(ListItemIcon, { children: currentActionLoading === DELETE_CONTRIBUTION || currentActionLoading === RESTORE_CONTRIBUTION ? (_jsx(CircularProgress, { size: 20 })) : (_jsx(Icon, { children: "delete" })) }), contributionObj.deleted ? (_jsx(ListItemText, { primary: _jsx(FormattedMessage, { id: "ui.contributionActionMenu.restoreContribution", defaultMessage: "ui.contributionActionMenu.restoreContribution" }), onClick: () => handleAction(RESTORE_CONTRIBUTION), classes: { root: classes.itemText } })) : (_jsx(ListItemText, { primary: _jsx(FormattedMessage, { id: "ui.contributionActionMenu.deleteContribution", defaultMessage: "ui.contributionActionMenu.deleteContribution" }), onClick: () => handleAction(DELETE_CONTRIBUTION), classes: { root: classes.itemText } }))] }))), canPublishContribution() && (_jsxs(MenuItem, Object.assign({ className: classes.subItem, disabled: isFlagging }, { children: [_jsx(ListItemIcon, { children: _jsx(Icon, { children: "upload" }) }), _jsx(ListItemText, { primary: _jsx(FormattedMessage, { id: "ui.contributionActionMenu.publishContribution", defaultMessage: "ui.contributionActionMenu.publishContribution" }), onClick: () => handleAction(PUBLISH_CONTRIBUTION), classes: { root: classes.itemText } })] }))), canSuspendNotificationContribution() && (_jsxs(MenuItem, Object.assign({ className: classes.subItem, disabled: isFlagging }, { children: [_jsx(ListItemIcon, { children: currentActionLoading === SUSPEND_NOTIFICATION_CONTRIBUTION ? (_jsx(CircularProgress, { size: 20 })) : contributionObj['suspended'] ? (_jsx(Icon, { children: "notifications_active" })) : (_jsx(Icon, { children: "notifications_off" })) }), _jsx(ListItemText, { primary: contributionObj['suspended'] ? (_jsx(FormattedMessage, { id: "ui.contributionActionMenu.enableNotificationContribution", defaultMessage: "ui.contributionActionMenu.enableNotificationContribution" })) : (_jsx(FormattedMessage, { id: "ui.contributionActionMenu.suspendNotificationContribution", defaultMessage: "ui.contributionActionMenu.suspendNotificationContribution" })), onClick: () => handleAction(SUSPEND_NOTIFICATION_CONTRIBUTION), classes: { root: classes.itemText } })] }))), canSuspendNotificationEvent() && (_jsxs(MenuItem, Object.assign({ className: classes.subItem, disabled: isFlagging }, { children: [_jsx(ListItemIcon, { children: currentActionLoading === SUSPEND_NOTIFICATION_EVENT ? (_jsx(CircularProgress, { size: 20 })) : contributionObj.event['show_on_feed'] ? (_jsx(Icon, { children: "notifications_active" })) : (_jsx(Icon, { children: "notifications_off" })) }), _jsx(ListItemText, { primary: !contributionObj.event['show_on_feed'] ? (_jsx(FormattedMessage, { id: "ui.contributionActionMenu.enableNotificationContribution", defaultMessage: "ui.contributionActionMenu.enableNotificationContribution" })) : (_jsx(FormattedMessage, { id: "ui.contributionActionMenu.suspendNotificationContribution", defaultMessage: "ui.contributionActionMenu.suspendNotificationContribution" })), onClick: () => handleAction(SUSPEND_NOTIFICATION_EVENT), classes: { root: classes.itemText } })] })))] }, GENERAL_SECTION));
798
+ return (_jsxs(Box, { children: [_jsxs(MenuItem, Object.assign({ className: classes.subItem, disabled: isFlagging }, { children: [_jsx(ListItemIcon, { children: _jsx(Icon, { children: "link" }) }), _jsx(ListItemText, { primary: _jsx(FormattedMessage, { id: "ui.contributionActionMenu.permanentLink", defaultMessage: "ui.contributionActionMenu.permanentLink" }), onClick: () => handleAction(GET_CONTRIBUTION_PERMALINK), classes: { root: classes.itemText } })] })), canModifyContribution() && (_jsxs(MenuItem, Object.assign({ className: classes.subItem, disabled: isFlagging }, { children: [_jsx(ListItemIcon, { children: _jsx(Icon, { children: "edit" }) }), _jsx(ListItemText, { primary: _jsx(FormattedMessage, { id: "ui.contributionActionMenu.editContribution", defaultMessage: "ui.contributionActionMenu.editContribution" }), onClick: () => handleAction(EDIT_CONTRIBUTION), classes: { root: classes.itemText } })] }))), canDeleteContribution() && (_jsxs(MenuItem, Object.assign({ className: classes.subItem, disabled: isFlagging }, { children: [_jsx(ListItemIcon, { children: currentActionLoading === DELETE_CONTRIBUTION || currentActionLoading === RESTORE_CONTRIBUTION ? (_jsx(CircularProgress, { size: 20 })) : (_jsx(Icon, { children: "delete" })) }), contributionObj.deleted ? (_jsx(ListItemText, { primary: _jsx(FormattedMessage, { id: "ui.contributionActionMenu.restoreContribution", defaultMessage: "ui.contributionActionMenu.restoreContribution" }), onClick: () => handleAction(RESTORE_CONTRIBUTION), classes: { root: classes.itemText } })) : (_jsx(ListItemText, { primary: _jsx(FormattedMessage, { id: "ui.contributionActionMenu.deleteContribution", defaultMessage: "ui.contributionActionMenu.deleteContribution" }), onClick: () => handleAction(DELETE_CONTRIBUTION), classes: { root: classes.itemText } }))] }))), canPublishContribution() && (_jsxs(MenuItem, Object.assign({ className: classes.subItem, disabled: isFlagging }, { children: [_jsx(ListItemIcon, { children: _jsx(Icon, { children: "upload" }) }), _jsx(ListItemText, { primary: _jsx(FormattedMessage, { id: "ui.contributionActionMenu.publishContribution", defaultMessage: "ui.contributionActionMenu.publishContribution" }), onClick: () => handleAction(PUBLISH_CONTRIBUTION), classes: { root: classes.itemText } })] }))), canSuspendNotificationContribution() && (_jsxs(MenuItem, Object.assign({ className: classes.subItem, disabled: isFlagging }, { children: [_jsx(ListItemIcon, { children: currentActionLoading === SUSPEND_NOTIFICATION_CONTRIBUTION ? (_jsx(CircularProgress, { size: 20 })) : contributionObj['suspended'] ? (_jsx(Icon, { children: "notifications_active" })) : (_jsx(Icon, { children: "notifications_off" })) }), _jsx(ListItemText, { primary: contributionObj['suspended'] ? (_jsx(FormattedMessage, { id: "ui.contributionActionMenu.enableNotificationContribution", defaultMessage: "ui.contributionActionMenu.enableNotificationContribution" })) : (_jsx(FormattedMessage, { id: "ui.contributionActionMenu.suspendNotificationContribution", defaultMessage: "ui.contributionActionMenu.suspendNotificationContribution" })), onClick: () => handleAction(SUSPEND_NOTIFICATION_CONTRIBUTION), classes: { root: classes.itemText } })] }))), canSuspendNotificationEvent() && (_jsxs(MenuItem, Object.assign({ className: classes.subItem, disabled: isFlagging }, { children: [_jsx(ListItemIcon, { children: currentActionLoading === SUSPEND_NOTIFICATION_EVENT ? (_jsx(CircularProgress, { size: 20 })) : contributionObj.event['show_on_feed'] ? (_jsx(Icon, { children: "notifications_active" })) : (_jsx(Icon, { children: "notifications_off" })) }), _jsx(ListItemText, { primary: !contributionObj.event['show_on_feed'] ? (_jsx(FormattedMessage, { id: "ui.contributionActionMenu.enableNotificationContribution", defaultMessage: "ui.contributionActionMenu.enableNotificationContribution" })) : (_jsx(FormattedMessage, { id: "ui.contributionActionMenu.suspendNotificationContribution", defaultMessage: "ui.contributionActionMenu.suspendNotificationContribution" })), onClick: () => handleAction(SUSPEND_NOTIFICATION_EVENT), classes: { root: classes.itemText } })] }))), canDownloadCSV() && (_jsxs(MenuItem, Object.assign({ className: classes.subItem }, { children: [_jsx(ListItemIcon, { children: _jsx(Icon, { children: "download" }) }), _jsx(ListItemText, { primary: _jsx(FormattedMessage, { id: "ui.contributionActionMenu.downloadCSV", defaultMessage: "ui.contributionActionMenu.downloadCSV" }), onClick: () => handleAction(DOWNLOAD_CSV), classes: { root: classes.itemText } })] })))] }, GENERAL_SECTION));
761
799
  }
762
800
  /**
763
801
  * Renders contribution menu content