@selfcommunity/react-ui 0.11.0-alpha.101 → 0.11.0-alpha.103
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.
- package/lib/cjs/components/Composer/Composer.js +15 -11
- package/lib/cjs/components/Composer/Layer/AudienceLayer/AudienceLayer.js +27 -25
- package/lib/cjs/components/UserAutocomplete/UserAutocomplete.js +31 -16
- package/lib/esm/components/Composer/Composer.js +15 -11
- package/lib/esm/components/Composer/Layer/AudienceLayer/AudienceLayer.js +27 -25
- package/lib/esm/components/UserAutocomplete/UserAutocomplete.js +32 -17
- package/lib/umd/react-ui.js +1 -1
- package/package.json +5 -5
|
@@ -377,13 +377,13 @@ 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 ((Array.isArray(value) &&
|
|
381
|
-
value
|
|
382
|
-
(Array.isArray(recipients) && recipients.length > 0)) {
|
|
380
|
+
else if ((value && Array.isArray(value) && value.some((item) => typeof item === 'object' && !('color' in item))) ||
|
|
381
|
+
(value === null && Array.isArray(recipients) && recipients.length > 0)) {
|
|
383
382
|
dispatch({
|
|
384
383
|
type: 'multiple',
|
|
385
384
|
value: {
|
|
386
385
|
recipients: value,
|
|
386
|
+
addressing: [],
|
|
387
387
|
addressingError: addressingRequiredEnabled && !value ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.composer.addressing.error.missing", defaultMessage: "ui.composer.addressing.error.missing" })) : null
|
|
388
388
|
}
|
|
389
389
|
});
|
|
@@ -393,6 +393,7 @@ function Composer(inProps) {
|
|
|
393
393
|
type: 'multiple',
|
|
394
394
|
value: {
|
|
395
395
|
addressing: value,
|
|
396
|
+
recipients: [],
|
|
396
397
|
addressingError: addressingRequiredEnabled && !value ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.composer.addressing.error.missing", defaultMessage: "ui.composer.addressing.error.missing" })) : null
|
|
397
398
|
}
|
|
398
399
|
});
|
|
@@ -400,19 +401,20 @@ function Composer(inProps) {
|
|
|
400
401
|
setLayer(null);
|
|
401
402
|
}, [group, event, recipients]);
|
|
402
403
|
const handleAddAudienceLayer = (0, react_1.useCallback)(() => {
|
|
404
|
+
const defaultValue = group || (addressing && Object.prototype.hasOwnProperty.call(addressing, 'emotional_image_position'))
|
|
405
|
+
? group
|
|
406
|
+
: event || (addressing && Object.prototype.hasOwnProperty.call(addressing, 'recurring'))
|
|
407
|
+
? event
|
|
408
|
+
: Array.isArray(recipients) && recipients.some((item) => typeof item === 'object' && item !== null && !('color' in item))
|
|
409
|
+
? recipients
|
|
410
|
+
: addressing;
|
|
403
411
|
handleAddLayer({
|
|
404
412
|
name: 'audience',
|
|
405
413
|
Component: AudienceLayer_1.default,
|
|
406
414
|
ComponentProps: {
|
|
407
415
|
onClose: handleRemoveLayer,
|
|
408
416
|
onSave: handleChangeAudience,
|
|
409
|
-
defaultValue:
|
|
410
|
-
? group
|
|
411
|
-
: event || (addressing && Object.prototype.hasOwnProperty.call(addressing, 'recurring'))
|
|
412
|
-
? event
|
|
413
|
-
: (recipients === null || recipients === void 0 ? void 0 : recipients.length) !== 0 || ((recipients === null || recipients === void 0 ? void 0 : recipients.length) !== 0 && !recipients.some((r) => 'color' in r))
|
|
414
|
-
? recipients
|
|
415
|
-
: addressing
|
|
417
|
+
defaultValue: defaultValue
|
|
416
418
|
}
|
|
417
419
|
});
|
|
418
420
|
}, [handleAddLayer, handleRemoveLayer, handleChangeAudience, addressing, event, group, recipients]);
|
|
@@ -705,6 +707,8 @@ function Composer(inProps) {
|
|
|
705
707
|
.map((mediaObjectType) => {
|
|
706
708
|
const props = mediaObjectType.layerComponent ? { onClick: handleMediaTriggerClick(mediaObjectType) } : { onAdd: handleAddMedia };
|
|
707
709
|
return ((0, jsx_runtime_1.jsx)(mediaObjectType.triggerButton, Object.assign({ disabled: isSubmitting || hasMediaShare, color: medias.filter(mediaObjectType.filter).length > 0 ? 'primary' : 'default' }, props), mediaObjectType.name));
|
|
708
|
-
}), (0, jsx_runtime_1.jsx)(material_1.IconButton, Object.assign({ disabled: isSubmitting, onClick: handleAddCategoryLayer, color: (categories === null || categories === void 0 ? void 0 : categories.length) !== 0 ? 'primary' : 'default' }, { children: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "category" }) })), (0, jsx_runtime_1.jsx)(material_1.IconButton, Object.assign({ color: group || event || (addressing !== null && (addressing === null || addressing === void 0 ? void 0 : addressing.length) > 0)
|
|
710
|
+
}), (0, jsx_runtime_1.jsx)(material_1.IconButton, Object.assign({ disabled: isSubmitting, onClick: handleAddCategoryLayer, color: (categories === null || categories === void 0 ? void 0 : categories.length) !== 0 ? 'primary' : 'default' }, { children: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "category" }) })), (0, jsx_runtime_1.jsx)(material_1.IconButton, Object.assign({ color: group || event || (addressing !== null && (addressing === null || addressing === void 0 ? void 0 : addressing.length) > 0) || (recipients !== null && (recipients === null || recipients === void 0 ? void 0 : recipients.length) > 0)
|
|
711
|
+
? 'primary'
|
|
712
|
+
: 'default', disabled: isSubmitting || !features.includes(types_1.SCFeatureName.TAGGING) || Boolean(feedObject === null || feedObject === void 0 ? void 0 : feedObject.group) || Boolean(feedObject === null || feedObject === void 0 ? void 0 : feedObject.event), onClick: handleAddAudienceLayer }, { children: group ? ((0, jsx_runtime_1.jsx)(material_1.Icon, { children: "groups" })) : event ? ((0, jsx_runtime_1.jsx)(material_1.Icon, { children: "CalendarIcon" })) : addressing === null || (addressing === null || addressing === void 0 ? void 0 : addressing.length) === 0 ? (addressingRequiredEnabled ? ((0, jsx_runtime_1.jsx)(material_1.Icon, { children: "label" })) : ((0, jsx_runtime_1.jsx)(material_1.Icon, { children: "public" }))) : ((0, jsx_runtime_1.jsx)(material_1.Icon, { children: "label" })) })), preferences[react_core_1.SCPreferences.ADDONS_POST_GEOLOCATION_ENABLED].value && ((0, jsx_runtime_1.jsx)(material_1.IconButton, Object.assign({ disabled: isSubmitting, onClick: handleAddLocationLayer, color: location !== null ? 'primary' : 'default' }, { children: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "add_location_alt" }) }))), preferences[react_core_1.SCPreferences.CONFIGURATIONS_SCHEDULED_POSTS_ENABLED].value && ((0, jsx_runtime_1.jsx)(material_1.IconButton, Object.assign({ disabled: isSubmitting || (Boolean(feedObject === null || feedObject === void 0 ? void 0 : feedObject.scheduled_at) && Boolean(!(feedObject === null || feedObject === void 0 ? void 0 : feedObject.draft))), onClick: handleAddScheduledLayer, color: scheduled_at !== null ? 'primary' : 'default' }, { children: (0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ className: classes.selectedAction }, { children: [(0, jsx_runtime_1.jsx)(material_1.Icon, { children: "access_time" }), scheduled_at !== null && ((0, jsx_runtime_1.jsx)(material_1.Icon, Object.assign({ color: "primary", className: classes.actionSelectedIcon }, { children: "fiber_manual_record" })))] })) })))] }))] })), layer && ((0, jsx_runtime_1.jsx)(LayerTransitionRoot, Object.assign({ className: classes.layerTransitionRoot, in: true, container: dialogRef.current, direction: "left" }, { children: (0, jsx_runtime_1.jsx)(layer.Component, Object.assign({}, layer.ComponentProps)) })))] })));
|
|
709
713
|
}
|
|
710
714
|
exports.default = Composer;
|
|
@@ -83,12 +83,7 @@ const AudienceLayer = react_1.default.forwardRef((props, ref) => {
|
|
|
83
83
|
? AudienceTypes.AUDIENCE_EVENT
|
|
84
84
|
: Object.prototype.hasOwnProperty.call(defaultValue, 'managed_by')
|
|
85
85
|
? AudienceTypes.AUDIENCE_GROUP
|
|
86
|
-
: Array.isArray(defaultValue) &&
|
|
87
|
-
defaultValue.length > 0 &&
|
|
88
|
-
// case: array of user objects
|
|
89
|
-
(((_a = defaultValue[0]) === null || _a === void 0 ? void 0 : _a.username) !== undefined ||
|
|
90
|
-
// case: array of strings
|
|
91
|
-
typeof defaultValue[0] === 'string')
|
|
86
|
+
: Array.isArray(defaultValue) && defaultValue.length > 0 && ((_a = defaultValue[0]) === null || _a === void 0 ? void 0 : _a.username) !== undefined
|
|
92
87
|
? AudienceTypes.AUDIENCE_USERS
|
|
93
88
|
: AudienceTypes.AUDIENCE_TAG);
|
|
94
89
|
// HANDLERS
|
|
@@ -107,24 +102,31 @@ const AudienceLayer = react_1.default.forwardRef((props, ref) => {
|
|
|
107
102
|
const handleChangeAudience = (0, react_1.useCallback)((_event, data) => setAudience(data), []);
|
|
108
103
|
const handleAutocompleteOpen = (0, react_1.useCallback)(() => setAutocompleteOpen(true), []);
|
|
109
104
|
const handleAutocompleteClose = (0, react_1.useCallback)(() => setAutocompleteOpen(false), []);
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
105
|
+
const isAudienceTypeSelected = (type) => {
|
|
106
|
+
// "ALL" tab is never disabled
|
|
107
|
+
if (type === AudienceTypes.AUDIENCE_ALL)
|
|
108
|
+
return false;
|
|
109
|
+
// Empty value → nothing is disabled
|
|
110
|
+
if (!value || (Array.isArray(value) && value.length === 0))
|
|
111
|
+
return false;
|
|
112
|
+
const valueType = (() => {
|
|
113
|
+
if (Array.isArray(value)) {
|
|
114
|
+
if (value.some((v) => 'color' in v))
|
|
115
|
+
return AudienceTypes.AUDIENCE_TAG;
|
|
116
|
+
return AudienceTypes.AUDIENCE_USERS;
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
if ('recurring' in value)
|
|
120
|
+
return AudienceTypes.AUDIENCE_EVENT;
|
|
121
|
+
if ('managed_by' in value)
|
|
122
|
+
return AudienceTypes.AUDIENCE_GROUP;
|
|
123
|
+
return AudienceTypes.AUDIENCE_USERS;
|
|
124
|
+
}
|
|
125
|
+
})();
|
|
126
|
+
// Disable all tabs except the currently selected type
|
|
127
|
+
return type !== valueType;
|
|
128
|
+
};
|
|
129
|
+
return ((0, jsx_runtime_1.jsxs)(Root, Object.assign({ ref: ref, className: (0, classnames_1.default)(className, classes.root) }, rest, { children: [(0, jsx_runtime_1.jsxs)(material_1.DialogTitle, Object.assign({ className: classes.title }, { children: [(0, jsx_runtime_1.jsx)(material_1.IconButton, Object.assign({ onClick: onClose }, { children: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "arrow_back" }) })), (0, jsx_runtime_1.jsx)(material_1.Typography, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.composer.layer.audience.title", defaultMessage: "ui.composer.layer.audience.title" }) }), (0, jsx_runtime_1.jsx)(material_1.Button, Object.assign({ size: "small", color: "secondary", variant: "contained", onClick: handleSave }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.composer.layer.save", defaultMessage: "ui.composer.layer.save" }) }))] })), (0, jsx_runtime_1.jsxs)(material_1.DialogContent, Object.assign({ className: classes.content }, { children: [(0, jsx_runtime_1.jsxs)(material_1.Tabs, Object.assign({ value: audience, onChange: handleChangeAudience, "aria-label": "audience type" }, { children: [!taggingRequiredEnabled && ((0, jsx_runtime_1.jsx)(material_1.Tab, { value: AudienceTypes.AUDIENCE_ALL, icon: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "public" }), label: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.composer.layer.audience.all", defaultMessage: "ui.composer.layer.audience.all" }) })), eventsEnabled && ((0, jsx_runtime_1.jsx)(material_1.Tab, { disabled: isAudienceTypeSelected(AudienceTypes.AUDIENCE_EVENT), value: AudienceTypes.AUDIENCE_EVENT, icon: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "CalendarIcon" }), label: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.composer.layer.audience.event", defaultMessage: "ui.composer.layer.audience.event" }) })), groupsEnabled && ((0, jsx_runtime_1.jsx)(material_1.Tab, { disabled: isAudienceTypeSelected(AudienceTypes.AUDIENCE_GROUP), value: AudienceTypes.AUDIENCE_GROUP, icon: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "groups" }), label: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.composer.layer.audience.group", defaultMessage: "ui.composer.layer.audience.group" }) })), (0, jsx_runtime_1.jsx)(material_1.Tab, { disabled: isAudienceTypeSelected(AudienceTypes.AUDIENCE_TAG), value: AudienceTypes.AUDIENCE_TAG, icon: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "label" }), label: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.composer.layer.audience.tag", defaultMessage: "ui.composer.layer.audience.tag" }) }), usersTaggingEnabled && ((0, jsx_runtime_1.jsx)(material_1.Tab, { disabled: isAudienceTypeSelected(AudienceTypes.AUDIENCE_USERS), value: AudienceTypes.AUDIENCE_USERS, icon: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "people_alt" }), label: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.composer.layer.audience.users", defaultMessage: "ui.composer.layer.audience.users" }) }))] })), (0, jsx_runtime_1.jsxs)(material_1.Typography, Object.assign({ className: classes.message }, { children: [audience === AudienceTypes.AUDIENCE_ALL && !taggingRequiredEnabled && ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.composer.layer.audience.all.message", defaultMessage: "ui.composer.layer.audience.all.message" })), audience === AudienceTypes.AUDIENCE_EVENT && ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.composer.layer.audience.event.message", defaultMessage: "ui.composer.layer.audience.event.message" })), audience === AudienceTypes.AUDIENCE_GROUP && ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.composer.layer.audience.group.message", defaultMessage: "ui.composer.layer.audience.group.message" })), audience === AudienceTypes.AUDIENCE_TAG && ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.composer.layer.audience.tag.message", defaultMessage: "ui.composer.layer.audience.tag.message" })), audience === AudienceTypes.AUDIENCE_USERS && ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.composer.layer.audience.users.message", defaultMessage: "ui.composer.layer.audience.users.message" }))] })), audience === AudienceTypes.AUDIENCE_TAG && ((0, jsx_runtime_1.jsx)(material_1.Autocomplete, { className: classes.autocomplete, open: autocompleteOpen, onOpen: handleAutocompleteOpen, onClose: handleAutocompleteClose, multiple: true, options: scAddressingTags || [], getOptionLabel: (option) => option.name || '', value: value, selectOnFocus: true, clearOnBlur: true, handleHomeEndKeys: true, clearIcon: null, noOptionsText: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.composer.layer.audience.tags.empty", defaultMessage: "ui.composer.layer.audience.tags.empty" }), onChange: handleChange, isOptionEqualToValue: (option, value) => value.id === option.id, renderTags: (value, getTagProps) => {
|
|
128
130
|
return value.map((option, index) => (0, jsx_runtime_1.jsx)(TagChip_1.default, Object.assign({ tag: option }, getTagProps({ index })), option.id));
|
|
129
131
|
}, renderOption: (props, option, { selected, inputValue }) => {
|
|
130
132
|
const matches = (0, match_1.default)(option.name, inputValue);
|
|
@@ -132,6 +134,6 @@ const AudienceLayer = react_1.default.forwardRef((props, ref) => {
|
|
|
132
134
|
return ((0, jsx_runtime_1.jsx)("li", Object.assign({}, props, { children: (0, jsx_runtime_1.jsx)(TagChip_1.default, { disposable: false, tag: option, label: (0, jsx_runtime_1.jsx)(react_1.default.Fragment, { children: parts.map((part, index) => ((0, jsx_runtime_1.jsx)("span", Object.assign({ style: { fontWeight: part.highlight ? 700 : 400 } }, { children: part.text }), index))) }) }, option.id) })));
|
|
133
135
|
}, renderInput: (params) => {
|
|
134
136
|
return ((0, jsx_runtime_1.jsx)(material_1.TextField, Object.assign({}, params, TextFieldProps, { InputProps: Object.assign(Object.assign({}, params.InputProps), { autoComplete: 'addressing', endAdornment: (0, jsx_runtime_1.jsx)(react_1.default.Fragment, { children: params.InputProps.endAdornment }) }) })));
|
|
135
|
-
} })), audience === AudienceTypes.AUDIENCE_USERS && (0, jsx_runtime_1.jsx)(UserAutocomplete_1.default, { onChange: handleUsersChange, defaultValue:
|
|
137
|
+
} })), audience === AudienceTypes.AUDIENCE_USERS && (0, jsx_runtime_1.jsx)(UserAutocomplete_1.default, { onChange: handleUsersChange, defaultValue: value }), audience === AudienceTypes.AUDIENCE_GROUP && (0, jsx_runtime_1.jsx)(GroupAutocomplete_1.default, { onChange: handleGroupChange, defaultValue: value }), audience === AudienceTypes.AUDIENCE_EVENT && (0, jsx_runtime_1.jsx)(EventAutocomplete_1.default, { onChange: handleEventChange, defaultValue: value })] }))] })));
|
|
136
138
|
});
|
|
137
139
|
exports.default = AudienceLayer;
|
|
@@ -46,16 +46,18 @@ const UserAutocomplete = (inProps) => {
|
|
|
46
46
|
.filter(Boolean)
|
|
47
47
|
.join(','), [value]);
|
|
48
48
|
// Fetch users excluding selected ones
|
|
49
|
-
const { users, isLoading } = (0, react_core_1.useSCFetchUsers)({ search: inputValue, exclude: excludeIds });
|
|
49
|
+
const { users, isLoading } = (0, react_core_1.useSCFetchUsers)({ search: (inputValue === null || inputValue === void 0 ? void 0 : inputValue.length) >= 3 ? inputValue : '', exclude: excludeIds });
|
|
50
50
|
const filteredUsers = users.filter((u) => !excludeIds.includes(u.id));
|
|
51
51
|
(0, react_1.useEffect)(() => {
|
|
52
52
|
onChange === null || onChange === void 0 ? void 0 : onChange(value);
|
|
53
53
|
setTextAreaValue(value.map((u) => (typeof u === 'object' ? u.username : u)).join('\n'));
|
|
54
54
|
}, [value]);
|
|
55
55
|
// Handlers
|
|
56
|
-
const handleOpen = () => {
|
|
57
|
-
filteredUsers.length > 0
|
|
58
|
-
|
|
56
|
+
const handleOpen = (0, react_1.useCallback)(() => {
|
|
57
|
+
if (filteredUsers.length > 0) {
|
|
58
|
+
setOpen(true);
|
|
59
|
+
}
|
|
60
|
+
}, [filteredUsers]);
|
|
59
61
|
const handleClose = () => {
|
|
60
62
|
setOpen(false);
|
|
61
63
|
};
|
|
@@ -67,24 +69,37 @@ const UserAutocomplete = (inProps) => {
|
|
|
67
69
|
.split(/\s|,|\n/)
|
|
68
70
|
.map((s) => s.trim())
|
|
69
71
|
.filter(Boolean)));
|
|
70
|
-
let resolvedUsers = [];
|
|
71
72
|
try {
|
|
72
73
|
if (names.length > 0) {
|
|
73
|
-
const resp = yield api_services_1.UserService.matchUsernames(names
|
|
74
|
-
const
|
|
75
|
-
resolvedUsers =
|
|
74
|
+
const resp = yield api_services_1.UserService.matchUsernames(names);
|
|
75
|
+
const resolvedUsernames = new Set(resp.map((u) => u.username));
|
|
76
|
+
const resolvedUsers = resp.filter((u) => resolvedUsernames.has(u.username));
|
|
77
|
+
setValue(resolvedUsers);
|
|
78
|
+
setTextAreaValue(resolvedUsers.map((u) => u.username).join('\n'));
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
setValue([]);
|
|
82
|
+
setTextAreaValue('');
|
|
76
83
|
}
|
|
77
84
|
}
|
|
78
85
|
catch (err) {
|
|
79
|
-
console.error(`Failed fetching
|
|
80
|
-
|
|
86
|
+
console.error(`Failed fetching matching usernames`, err);
|
|
87
|
+
setValue([]);
|
|
88
|
+
setTextAreaValue('');
|
|
81
89
|
}
|
|
82
|
-
setValue(resolvedUsers);
|
|
83
|
-
setTextAreaValue(e.target.value);
|
|
84
90
|
});
|
|
85
|
-
|
|
91
|
+
const filterOptions = (0, react_1.useCallback)((options, state) => {
|
|
92
|
+
const search = state.inputValue.toLowerCase();
|
|
93
|
+
return options.filter((option) => {
|
|
94
|
+
var _a, _b;
|
|
95
|
+
const usernameMatch = (_a = option.username) === null || _a === void 0 ? void 0 : _a.toLowerCase().includes(search);
|
|
96
|
+
const nameMatch = (_b = option.real_name) === null || _b === void 0 ? void 0 : _b.toLowerCase().includes(search);
|
|
97
|
+
return usernameMatch || nameMatch;
|
|
98
|
+
});
|
|
99
|
+
}, []);
|
|
100
|
+
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: filteredUsers || [], filterOptions: filterOptions, getOptionLabel: (option) => option.username || '', value: value, inputValue: inputValue, onInputChange: (_event, newInputValue) => {
|
|
86
101
|
setInputValue(newInputValue);
|
|
87
|
-
}, 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 ===
|
|
102
|
+
}, 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 ? val.id === option.id : false), renderTags: (value, getTagProps) => value.map((option, index) => {
|
|
88
103
|
const username = typeof option === 'string' ? option : option.username;
|
|
89
104
|
const avatar = typeof option === 'string' ? '' : option.avatar;
|
|
90
105
|
const id = typeof option === 'string' ? `fallback-${option}` : option.id;
|
|
@@ -92,8 +107,8 @@ const UserAutocomplete = (inProps) => {
|
|
|
92
107
|
}), renderOption: (props, option, { inputValue }) => {
|
|
93
108
|
const matches = (0, match_1.default)(option.username, inputValue);
|
|
94
109
|
const parts = (0, parse_1.default)(option.username, matches);
|
|
95
|
-
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,
|
|
96
|
-
}, 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
|
|
110
|
+
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, { children: part.text }, index))) })] })));
|
|
111
|
+
}, 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: filteredUsers.length > 0 ? ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [isLoading && (0, jsx_runtime_1.jsx)(material_1.CircularProgress, { color: "inherit", size: 20 }), params.InputProps.endAdornment] })) : null }) }))) }, 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: {
|
|
97
112
|
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
|
98
113
|
// @ts-ignore
|
|
99
114
|
icon: (...chunks) => (0, jsx_runtime_1.jsx)(material_1.Icon, { children: chunks })
|
|
@@ -375,13 +375,13 @@ 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 ((Array.isArray(value) &&
|
|
379
|
-
value
|
|
380
|
-
(Array.isArray(recipients) && recipients.length > 0)) {
|
|
378
|
+
else if ((value && Array.isArray(value) && value.some((item) => typeof item === 'object' && !('color' in item))) ||
|
|
379
|
+
(value === null && Array.isArray(recipients) && recipients.length > 0)) {
|
|
381
380
|
dispatch({
|
|
382
381
|
type: 'multiple',
|
|
383
382
|
value: {
|
|
384
383
|
recipients: value,
|
|
384
|
+
addressing: [],
|
|
385
385
|
addressingError: addressingRequiredEnabled && !value ? (_jsx(FormattedMessage, { id: "ui.composer.addressing.error.missing", defaultMessage: "ui.composer.addressing.error.missing" })) : null
|
|
386
386
|
}
|
|
387
387
|
});
|
|
@@ -391,6 +391,7 @@ export default function Composer(inProps) {
|
|
|
391
391
|
type: 'multiple',
|
|
392
392
|
value: {
|
|
393
393
|
addressing: value,
|
|
394
|
+
recipients: [],
|
|
394
395
|
addressingError: addressingRequiredEnabled && !value ? (_jsx(FormattedMessage, { id: "ui.composer.addressing.error.missing", defaultMessage: "ui.composer.addressing.error.missing" })) : null
|
|
395
396
|
}
|
|
396
397
|
});
|
|
@@ -398,19 +399,20 @@ export default function Composer(inProps) {
|
|
|
398
399
|
setLayer(null);
|
|
399
400
|
}, [group, event, recipients]);
|
|
400
401
|
const handleAddAudienceLayer = useCallback(() => {
|
|
402
|
+
const defaultValue = group || (addressing && Object.prototype.hasOwnProperty.call(addressing, 'emotional_image_position'))
|
|
403
|
+
? group
|
|
404
|
+
: event || (addressing && Object.prototype.hasOwnProperty.call(addressing, 'recurring'))
|
|
405
|
+
? event
|
|
406
|
+
: Array.isArray(recipients) && recipients.some((item) => typeof item === 'object' && item !== null && !('color' in item))
|
|
407
|
+
? recipients
|
|
408
|
+
: addressing;
|
|
401
409
|
handleAddLayer({
|
|
402
410
|
name: 'audience',
|
|
403
411
|
Component: AudienceLayer,
|
|
404
412
|
ComponentProps: {
|
|
405
413
|
onClose: handleRemoveLayer,
|
|
406
414
|
onSave: handleChangeAudience,
|
|
407
|
-
defaultValue:
|
|
408
|
-
? group
|
|
409
|
-
: event || (addressing && Object.prototype.hasOwnProperty.call(addressing, 'recurring'))
|
|
410
|
-
? event
|
|
411
|
-
: (recipients === null || recipients === void 0 ? void 0 : recipients.length) !== 0 || ((recipients === null || recipients === void 0 ? void 0 : recipients.length) !== 0 && !recipients.some((r) => 'color' in r))
|
|
412
|
-
? recipients
|
|
413
|
-
: addressing
|
|
415
|
+
defaultValue: defaultValue
|
|
414
416
|
}
|
|
415
417
|
});
|
|
416
418
|
}, [handleAddLayer, handleRemoveLayer, handleChangeAudience, addressing, event, group, recipients]);
|
|
@@ -703,5 +705,7 @@ export default function Composer(inProps) {
|
|
|
703
705
|
.map((mediaObjectType) => {
|
|
704
706
|
const props = mediaObjectType.layerComponent ? { onClick: handleMediaTriggerClick(mediaObjectType) } : { onAdd: handleAddMedia };
|
|
705
707
|
return (_jsx(mediaObjectType.triggerButton, Object.assign({ disabled: isSubmitting || hasMediaShare, color: medias.filter(mediaObjectType.filter).length > 0 ? 'primary' : 'default' }, props), mediaObjectType.name));
|
|
706
|
-
}), _jsx(IconButton, Object.assign({ disabled: isSubmitting, onClick: handleAddCategoryLayer, color: (categories === null || categories === void 0 ? void 0 : categories.length) !== 0 ? 'primary' : 'default' }, { children: _jsx(Icon, { children: "category" }) })), _jsx(IconButton, Object.assign({ color: group || event || (addressing !== null && (addressing === null || addressing === void 0 ? void 0 : addressing.length) > 0)
|
|
708
|
+
}), _jsx(IconButton, Object.assign({ disabled: isSubmitting, onClick: handleAddCategoryLayer, color: (categories === null || categories === void 0 ? void 0 : categories.length) !== 0 ? 'primary' : 'default' }, { children: _jsx(Icon, { children: "category" }) })), _jsx(IconButton, Object.assign({ color: group || event || (addressing !== null && (addressing === null || addressing === void 0 ? void 0 : addressing.length) > 0) || (recipients !== null && (recipients === null || recipients === void 0 ? void 0 : recipients.length) > 0)
|
|
709
|
+
? 'primary'
|
|
710
|
+
: 'default', disabled: isSubmitting || !features.includes(SCFeatureName.TAGGING) || Boolean(feedObject === null || feedObject === void 0 ? void 0 : feedObject.group) || Boolean(feedObject === null || feedObject === void 0 ? void 0 : feedObject.event), onClick: handleAddAudienceLayer }, { children: group ? (_jsx(Icon, { children: "groups" })) : event ? (_jsx(Icon, { children: "CalendarIcon" })) : addressing === null || (addressing === null || addressing === void 0 ? void 0 : addressing.length) === 0 ? (addressingRequiredEnabled ? (_jsx(Icon, { children: "label" })) : (_jsx(Icon, { children: "public" }))) : (_jsx(Icon, { children: "label" })) })), preferences[SCPreferences.ADDONS_POST_GEOLOCATION_ENABLED].value && (_jsx(IconButton, Object.assign({ disabled: isSubmitting, onClick: handleAddLocationLayer, color: location !== null ? 'primary' : 'default' }, { children: _jsx(Icon, { children: "add_location_alt" }) }))), preferences[SCPreferences.CONFIGURATIONS_SCHEDULED_POSTS_ENABLED].value && (_jsx(IconButton, Object.assign({ disabled: isSubmitting || (Boolean(feedObject === null || feedObject === void 0 ? void 0 : feedObject.scheduled_at) && Boolean(!(feedObject === null || feedObject === void 0 ? void 0 : feedObject.draft))), onClick: handleAddScheduledLayer, color: scheduled_at !== null ? 'primary' : 'default' }, { children: _jsxs(Box, Object.assign({ className: classes.selectedAction }, { children: [_jsx(Icon, { children: "access_time" }), scheduled_at !== null && (_jsx(Icon, Object.assign({ color: "primary", className: classes.actionSelectedIcon }, { children: "fiber_manual_record" })))] })) })))] }))] })), layer && (_jsx(LayerTransitionRoot, Object.assign({ className: classes.layerTransitionRoot, in: true, container: dialogRef.current, direction: "left" }, { children: _jsx(layer.Component, Object.assign({}, layer.ComponentProps)) })))] })));
|
|
707
711
|
}
|
|
@@ -80,12 +80,7 @@ const AudienceLayer = React.forwardRef((props, ref) => {
|
|
|
80
80
|
? AudienceTypes.AUDIENCE_EVENT
|
|
81
81
|
: Object.prototype.hasOwnProperty.call(defaultValue, 'managed_by')
|
|
82
82
|
? AudienceTypes.AUDIENCE_GROUP
|
|
83
|
-
: Array.isArray(defaultValue) &&
|
|
84
|
-
defaultValue.length > 0 &&
|
|
85
|
-
// case: array of user objects
|
|
86
|
-
(((_a = defaultValue[0]) === null || _a === void 0 ? void 0 : _a.username) !== undefined ||
|
|
87
|
-
// case: array of strings
|
|
88
|
-
typeof defaultValue[0] === 'string')
|
|
83
|
+
: Array.isArray(defaultValue) && defaultValue.length > 0 && ((_a = defaultValue[0]) === null || _a === void 0 ? void 0 : _a.username) !== undefined
|
|
89
84
|
? AudienceTypes.AUDIENCE_USERS
|
|
90
85
|
: AudienceTypes.AUDIENCE_TAG);
|
|
91
86
|
// HANDLERS
|
|
@@ -104,24 +99,31 @@ const AudienceLayer = React.forwardRef((props, ref) => {
|
|
|
104
99
|
const handleChangeAudience = useCallback((_event, data) => setAudience(data), []);
|
|
105
100
|
const handleAutocompleteOpen = useCallback(() => setAutocompleteOpen(true), []);
|
|
106
101
|
const handleAutocompleteClose = useCallback(() => setAutocompleteOpen(false), []);
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
102
|
+
const isAudienceTypeSelected = (type) => {
|
|
103
|
+
// "ALL" tab is never disabled
|
|
104
|
+
if (type === AudienceTypes.AUDIENCE_ALL)
|
|
105
|
+
return false;
|
|
106
|
+
// Empty value → nothing is disabled
|
|
107
|
+
if (!value || (Array.isArray(value) && value.length === 0))
|
|
108
|
+
return false;
|
|
109
|
+
const valueType = (() => {
|
|
110
|
+
if (Array.isArray(value)) {
|
|
111
|
+
if (value.some((v) => 'color' in v))
|
|
112
|
+
return AudienceTypes.AUDIENCE_TAG;
|
|
113
|
+
return AudienceTypes.AUDIENCE_USERS;
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
if ('recurring' in value)
|
|
117
|
+
return AudienceTypes.AUDIENCE_EVENT;
|
|
118
|
+
if ('managed_by' in value)
|
|
119
|
+
return AudienceTypes.AUDIENCE_GROUP;
|
|
120
|
+
return AudienceTypes.AUDIENCE_USERS;
|
|
121
|
+
}
|
|
122
|
+
})();
|
|
123
|
+
// Disable all tabs except the currently selected type
|
|
124
|
+
return type !== valueType;
|
|
125
|
+
};
|
|
126
|
+
return (_jsxs(Root, Object.assign({ ref: ref, className: classNames(className, classes.root) }, rest, { children: [_jsxs(DialogTitle, Object.assign({ className: classes.title }, { children: [_jsx(IconButton, Object.assign({ onClick: onClose }, { children: _jsx(Icon, { children: "arrow_back" }) })), _jsx(Typography, { children: _jsx(FormattedMessage, { id: "ui.composer.layer.audience.title", defaultMessage: "ui.composer.layer.audience.title" }) }), _jsx(Button, Object.assign({ size: "small", color: "secondary", variant: "contained", onClick: handleSave }, { children: _jsx(FormattedMessage, { id: "ui.composer.layer.save", defaultMessage: "ui.composer.layer.save" }) }))] })), _jsxs(DialogContent, Object.assign({ className: classes.content }, { children: [_jsxs(Tabs, Object.assign({ value: audience, onChange: handleChangeAudience, "aria-label": "audience type" }, { children: [!taggingRequiredEnabled && (_jsx(Tab, { value: AudienceTypes.AUDIENCE_ALL, icon: _jsx(Icon, { children: "public" }), label: _jsx(FormattedMessage, { id: "ui.composer.layer.audience.all", defaultMessage: "ui.composer.layer.audience.all" }) })), eventsEnabled && (_jsx(Tab, { disabled: isAudienceTypeSelected(AudienceTypes.AUDIENCE_EVENT), value: AudienceTypes.AUDIENCE_EVENT, icon: _jsx(Icon, { children: "CalendarIcon" }), label: _jsx(FormattedMessage, { id: "ui.composer.layer.audience.event", defaultMessage: "ui.composer.layer.audience.event" }) })), groupsEnabled && (_jsx(Tab, { disabled: isAudienceTypeSelected(AudienceTypes.AUDIENCE_GROUP), value: AudienceTypes.AUDIENCE_GROUP, icon: _jsx(Icon, { children: "groups" }), label: _jsx(FormattedMessage, { id: "ui.composer.layer.audience.group", defaultMessage: "ui.composer.layer.audience.group" }) })), _jsx(Tab, { disabled: isAudienceTypeSelected(AudienceTypes.AUDIENCE_TAG), value: AudienceTypes.AUDIENCE_TAG, icon: _jsx(Icon, { children: "label" }), label: _jsx(FormattedMessage, { id: "ui.composer.layer.audience.tag", defaultMessage: "ui.composer.layer.audience.tag" }) }), usersTaggingEnabled && (_jsx(Tab, { disabled: isAudienceTypeSelected(AudienceTypes.AUDIENCE_USERS), value: AudienceTypes.AUDIENCE_USERS, icon: _jsx(Icon, { children: "people_alt" }), label: _jsx(FormattedMessage, { id: "ui.composer.layer.audience.users", defaultMessage: "ui.composer.layer.audience.users" }) }))] })), _jsxs(Typography, Object.assign({ className: classes.message }, { children: [audience === AudienceTypes.AUDIENCE_ALL && !taggingRequiredEnabled && (_jsx(FormattedMessage, { id: "ui.composer.layer.audience.all.message", defaultMessage: "ui.composer.layer.audience.all.message" })), audience === AudienceTypes.AUDIENCE_EVENT && (_jsx(FormattedMessage, { id: "ui.composer.layer.audience.event.message", defaultMessage: "ui.composer.layer.audience.event.message" })), audience === AudienceTypes.AUDIENCE_GROUP && (_jsx(FormattedMessage, { id: "ui.composer.layer.audience.group.message", defaultMessage: "ui.composer.layer.audience.group.message" })), audience === AudienceTypes.AUDIENCE_TAG && (_jsx(FormattedMessage, { id: "ui.composer.layer.audience.tag.message", defaultMessage: "ui.composer.layer.audience.tag.message" })), audience === AudienceTypes.AUDIENCE_USERS && (_jsx(FormattedMessage, { id: "ui.composer.layer.audience.users.message", defaultMessage: "ui.composer.layer.audience.users.message" }))] })), audience === AudienceTypes.AUDIENCE_TAG && (_jsx(Autocomplete, { className: classes.autocomplete, open: autocompleteOpen, onOpen: handleAutocompleteOpen, onClose: handleAutocompleteClose, multiple: true, options: scAddressingTags || [], getOptionLabel: (option) => option.name || '', value: value, selectOnFocus: true, clearOnBlur: true, handleHomeEndKeys: true, clearIcon: null, noOptionsText: _jsx(FormattedMessage, { id: "ui.composer.layer.audience.tags.empty", defaultMessage: "ui.composer.layer.audience.tags.empty" }), onChange: handleChange, isOptionEqualToValue: (option, value) => value.id === option.id, renderTags: (value, getTagProps) => {
|
|
125
127
|
return value.map((option, index) => _jsx(TagChip, Object.assign({ tag: option }, getTagProps({ index })), option.id));
|
|
126
128
|
}, renderOption: (props, option, { selected, inputValue }) => {
|
|
127
129
|
const matches = match(option.name, inputValue);
|
|
@@ -129,6 +131,6 @@ const AudienceLayer = React.forwardRef((props, ref) => {
|
|
|
129
131
|
return (_jsx("li", Object.assign({}, props, { children: _jsx(TagChip, { disposable: false, tag: option, label: _jsx(React.Fragment, { children: parts.map((part, index) => (_jsx("span", Object.assign({ style: { fontWeight: part.highlight ? 700 : 400 } }, { children: part.text }), index))) }) }, option.id) })));
|
|
130
132
|
}, renderInput: (params) => {
|
|
131
133
|
return (_jsx(TextField, Object.assign({}, params, TextFieldProps, { InputProps: Object.assign(Object.assign({}, params.InputProps), { autoComplete: 'addressing', endAdornment: _jsx(React.Fragment, { children: params.InputProps.endAdornment }) }) })));
|
|
132
|
-
} })), audience === AudienceTypes.AUDIENCE_USERS && _jsx(UserAutocomplete, { onChange: handleUsersChange, defaultValue:
|
|
134
|
+
} })), audience === AudienceTypes.AUDIENCE_USERS && _jsx(UserAutocomplete, { onChange: handleUsersChange, defaultValue: value }), audience === AudienceTypes.AUDIENCE_GROUP && _jsx(GroupAutocomplete, { onChange: handleGroupChange, defaultValue: value }), audience === AudienceTypes.AUDIENCE_EVENT && _jsx(EventAutocomplete, { onChange: handleEventChange, defaultValue: value })] }))] })));
|
|
133
135
|
});
|
|
134
136
|
export default AudienceLayer;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { __awaiter, __rest } from "tslib";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import React, { Fragment, useEffect, useMemo, useState } from 'react';
|
|
3
|
+
import React, { Fragment, useCallback, useEffect, useMemo, 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';
|
|
@@ -44,16 +44,18 @@ const UserAutocomplete = (inProps) => {
|
|
|
44
44
|
.filter(Boolean)
|
|
45
45
|
.join(','), [value]);
|
|
46
46
|
// Fetch users excluding selected ones
|
|
47
|
-
const { users, isLoading } = useSCFetchUsers({ search: inputValue, exclude: excludeIds });
|
|
47
|
+
const { users, isLoading } = useSCFetchUsers({ search: (inputValue === null || inputValue === void 0 ? void 0 : inputValue.length) >= 3 ? inputValue : '', exclude: excludeIds });
|
|
48
48
|
const filteredUsers = users.filter((u) => !excludeIds.includes(u.id));
|
|
49
49
|
useEffect(() => {
|
|
50
50
|
onChange === null || onChange === void 0 ? void 0 : onChange(value);
|
|
51
51
|
setTextAreaValue(value.map((u) => (typeof u === 'object' ? u.username : u)).join('\n'));
|
|
52
52
|
}, [value]);
|
|
53
53
|
// Handlers
|
|
54
|
-
const handleOpen = () => {
|
|
55
|
-
filteredUsers.length > 0
|
|
56
|
-
|
|
54
|
+
const handleOpen = useCallback(() => {
|
|
55
|
+
if (filteredUsers.length > 0) {
|
|
56
|
+
setOpen(true);
|
|
57
|
+
}
|
|
58
|
+
}, [filteredUsers]);
|
|
57
59
|
const handleClose = () => {
|
|
58
60
|
setOpen(false);
|
|
59
61
|
};
|
|
@@ -65,24 +67,37 @@ const UserAutocomplete = (inProps) => {
|
|
|
65
67
|
.split(/\s|,|\n/)
|
|
66
68
|
.map((s) => s.trim())
|
|
67
69
|
.filter(Boolean)));
|
|
68
|
-
let resolvedUsers = [];
|
|
69
70
|
try {
|
|
70
71
|
if (names.length > 0) {
|
|
71
|
-
const resp = yield UserService.matchUsernames(names
|
|
72
|
-
const
|
|
73
|
-
resolvedUsers =
|
|
72
|
+
const resp = yield UserService.matchUsernames(names);
|
|
73
|
+
const resolvedUsernames = new Set(resp.map((u) => u.username));
|
|
74
|
+
const resolvedUsers = resp.filter((u) => resolvedUsernames.has(u.username));
|
|
75
|
+
setValue(resolvedUsers);
|
|
76
|
+
setTextAreaValue(resolvedUsers.map((u) => u.username).join('\n'));
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
setValue([]);
|
|
80
|
+
setTextAreaValue('');
|
|
74
81
|
}
|
|
75
82
|
}
|
|
76
83
|
catch (err) {
|
|
77
|
-
console.error(`Failed fetching
|
|
78
|
-
|
|
84
|
+
console.error(`Failed fetching matching usernames`, err);
|
|
85
|
+
setValue([]);
|
|
86
|
+
setTextAreaValue('');
|
|
79
87
|
}
|
|
80
|
-
setValue(resolvedUsers);
|
|
81
|
-
setTextAreaValue(e.target.value);
|
|
82
88
|
});
|
|
83
|
-
|
|
89
|
+
const filterOptions = useCallback((options, state) => {
|
|
90
|
+
const search = state.inputValue.toLowerCase();
|
|
91
|
+
return options.filter((option) => {
|
|
92
|
+
var _a, _b;
|
|
93
|
+
const usernameMatch = (_a = option.username) === null || _a === void 0 ? void 0 : _a.toLowerCase().includes(search);
|
|
94
|
+
const nameMatch = (_b = option.real_name) === null || _b === void 0 ? void 0 : _b.toLowerCase().includes(search);
|
|
95
|
+
return usernameMatch || nameMatch;
|
|
96
|
+
});
|
|
97
|
+
}, []);
|
|
98
|
+
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: filteredUsers || [], filterOptions: filterOptions, getOptionLabel: (option) => option.username || '', value: value, inputValue: inputValue, onInputChange: (_event, newInputValue) => {
|
|
84
99
|
setInputValue(newInputValue);
|
|
85
|
-
}, 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 ===
|
|
100
|
+
}, 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 ? val.id === option.id : false), renderTags: (value, getTagProps) => value.map((option, index) => {
|
|
86
101
|
const username = typeof option === 'string' ? option : option.username;
|
|
87
102
|
const avatar = typeof option === 'string' ? '' : option.avatar;
|
|
88
103
|
const id = typeof option === 'string' ? `fallback-${option}` : option.id;
|
|
@@ -90,8 +105,8 @@ const UserAutocomplete = (inProps) => {
|
|
|
90
105
|
}), renderOption: (props, option, { inputValue }) => {
|
|
91
106
|
const matches = match(option.username, inputValue);
|
|
92
107
|
const parts = parse(option.username, matches);
|
|
93
|
-
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,
|
|
94
|
-
}, renderInput: (params) => (_jsx(TextField, Object.assign({}, params, TextFieldProps, { margin: "dense", InputProps: Object.assign(Object.assign({}, params.InputProps), { autoComplete: 'off', endAdornment: (_jsxs(Fragment, { children: [isLoading
|
|
108
|
+
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, { children: part.text }, index))) })] })));
|
|
109
|
+
}, renderInput: (params) => (_jsx(TextField, Object.assign({}, params, TextFieldProps, { margin: "dense", InputProps: Object.assign(Object.assign({}, params.InputProps), { autoComplete: 'off', endAdornment: filteredUsers.length > 0 ? (_jsxs(Fragment, { children: [isLoading && _jsx(CircularProgress, { color: "inherit", size: 20 }), params.InputProps.endAdornment] })) : null }) }))) }, 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: {
|
|
95
110
|
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
|
96
111
|
// @ts-ignore
|
|
97
112
|
icon: (...chunks) => _jsx(Icon, { children: chunks })
|