cozy-ui 146.2.2 → 146.3.0
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/CHANGELOG.md +13 -0
- package/package.json +1 -1
- package/react/DropdownText/index.jsx +3 -5
- package/react/MemberAutocomplete/MemberAutocomplete.spec.jsx +83 -0
- package/react/MemberAutocomplete/MemberAutocompleteActions.jsx +77 -0
- package/react/MemberAutocomplete/MemberChip.jsx +29 -0
- package/react/MemberAutocomplete/MemberSuggestion.jsx +32 -0
- package/react/MemberAutocomplete/Readme.md +65 -0
- package/react/MemberAutocomplete/helpers.js +70 -0
- package/react/MemberAutocomplete/helpers.spec.js +51 -0
- package/react/MemberAutocomplete/index.jsx +247 -0
- package/react/MemberAutocomplete/locales/de.json +5 -0
- package/react/MemberAutocomplete/locales/en.json +5 -0
- package/react/MemberAutocomplete/locales/es.json +5 -0
- package/react/MemberAutocomplete/locales/fr.json +5 -0
- package/react/MemberAutocomplete/locales/index.js +17 -0
- package/react/MemberAutocomplete/locales/it.json +5 -0
- package/react/MemberAutocomplete/locales/ru.json +5 -0
- package/react/MemberAutocomplete/locales/vi.json +5 -0
- package/react/MemberAutocomplete/useMemberInput.js +80 -0
- package/react/MemberAutocomplete/useMemberSuggestions.js +65 -0
- package/react/MemberAutocomplete/useMemberSuggestions.spec.js +97 -0
- package/react/MemberAutocomplete/useRoleMenuFocus.js +35 -0
- package/react/MemberRow/MemberOrGroupAvatar.jsx +21 -0
- package/react/MemberRow/MemberRoleMenu.jsx +29 -4
- package/react/MemberRow/MemberRoleMenuHeader.jsx +3 -8
- package/react/MemberRow/Readme.md +5 -4
- package/react/MemberRow/index.jsx +3 -19
- package/react/MemberRow/propTypes.js +1 -0
- package/transpiled/react/DropdownText/index.js +3 -3
- package/transpiled/react/MemberAutocomplete/MemberAutocomplete.spec.d.ts +1 -0
- package/transpiled/react/MemberAutocomplete/MemberAutocompleteActions.d.ts +25 -0
- package/transpiled/react/MemberAutocomplete/MemberAutocompleteActions.js +69 -0
- package/transpiled/react/MemberAutocomplete/MemberChip.d.ts +39 -0
- package/transpiled/react/MemberAutocomplete/MemberChip.js +33 -0
- package/transpiled/react/MemberAutocomplete/MemberSuggestion.d.ts +36 -0
- package/transpiled/react/MemberAutocomplete/MemberSuggestion.js +31 -0
- package/transpiled/react/MemberAutocomplete/helpers.d.ts +7 -0
- package/transpiled/react/MemberAutocomplete/helpers.js +73 -0
- package/transpiled/react/MemberAutocomplete/helpers.spec.d.ts +1 -0
- package/transpiled/react/MemberAutocomplete/index.d.ts +71 -0
- package/transpiled/react/MemberAutocomplete/index.js +295 -0
- package/transpiled/react/MemberAutocomplete/locales/index.d.ts +16 -0
- package/transpiled/react/MemberAutocomplete/locales/index.js +44 -0
- package/transpiled/react/MemberAutocomplete/useMemberInput.d.ts +14 -0
- package/transpiled/react/MemberAutocomplete/useMemberInput.js +76 -0
- package/transpiled/react/MemberAutocomplete/useMemberSuggestions.d.ts +11 -0
- package/transpiled/react/MemberAutocomplete/useMemberSuggestions.js +120 -0
- package/transpiled/react/MemberAutocomplete/useMemberSuggestions.spec.d.ts +1 -0
- package/transpiled/react/MemberAutocomplete/useRoleMenuFocus.d.ts +6 -0
- package/transpiled/react/MemberAutocomplete/useRoleMenuFocus.js +37 -0
- package/transpiled/react/MemberList/index.d.ts +1 -0
- package/transpiled/react/MemberRow/MemberOrGroupAvatar.d.ts +39 -0
- package/transpiled/react/MemberRow/MemberOrGroupAvatar.js +29 -0
- package/transpiled/react/MemberRow/MemberRoleMenu.d.ts +9 -1
- package/transpiled/react/MemberRow/MemberRoleMenu.js +26 -9
- package/transpiled/react/MemberRow/MemberRoleMenuHeader.d.ts +1 -0
- package/transpiled/react/MemberRow/MemberRoleMenuHeader.js +4 -13
- package/transpiled/react/MemberRow/MemberRowActions.d.ts +1 -0
- package/transpiled/react/MemberRow/index.d.ts +1 -10
- package/transpiled/react/MemberRow/index.js +4 -13
- package/transpiled/react/MemberRow/propTypes.d.ts +1 -0
- package/transpiled/react/MemberRow/propTypes.js +1 -0
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import { useI18n, useExtendI18n } from 'twake-i18n'
|
|
3
3
|
|
|
4
|
-
import
|
|
5
|
-
import MemberGroupAvatar from './MemberGroupAvatar'
|
|
4
|
+
import MemberOrGroupAvatar from './MemberOrGroupAvatar'
|
|
6
5
|
import { locales } from './locales'
|
|
7
6
|
import { memberPropType } from './propTypes'
|
|
8
7
|
import ActionsMenuMobileHeader from '../ActionsMenu/ActionsMenuMobileHeader'
|
|
@@ -12,16 +11,12 @@ import ListItemText from '../ListItemText'
|
|
|
12
11
|
const MemberRoleMenuHeader = ({ member }) => {
|
|
13
12
|
useExtendI18n(locales)
|
|
14
13
|
const { t } = useI18n()
|
|
15
|
-
const { name,
|
|
14
|
+
const { name, isCurrentUser } = member
|
|
16
15
|
|
|
17
16
|
return (
|
|
18
17
|
<ActionsMenuMobileHeader>
|
|
19
18
|
<ListItemIcon>
|
|
20
|
-
{
|
|
21
|
-
<MemberGroupAvatar size="m" color={color} />
|
|
22
|
-
) : (
|
|
23
|
-
<MemberAvatar size="m" initials={initials} avatarUrl={avatarUrl} />
|
|
24
|
-
)}
|
|
19
|
+
<MemberOrGroupAvatar member={member} size="m" />
|
|
25
20
|
</ListItemIcon>
|
|
26
21
|
<ListItemText
|
|
27
22
|
primary={
|
|
@@ -7,12 +7,13 @@ Displays a member of a sharing: avatar, name, subtitle, and on the right its rol
|
|
|
7
7
|
* **subtitle**: email, status… (any node)
|
|
8
8
|
* **avatarUrl** and **initials**: picture of the member, initials when there is no picture or it fails to load
|
|
9
9
|
* **isGroup** and **color**: shows a group avatar
|
|
10
|
-
* **isOwner**: shows the "Owner" label and no action
|
|
11
|
-
* **role
|
|
10
|
+
* **isOwner**: shows the "Owner" label and no action, whatever the other props
|
|
11
|
+
* **role**: current role of the member, among its roles
|
|
12
|
+
* **roles**: roles of this member, when they differ from the `roles` of the row
|
|
12
13
|
* **canChangeRole**: shows the role in a menu, as text otherwise
|
|
13
14
|
* **canRemove**, **removeIcon** and **removeLabel**: remove button, its icon and its accessible label
|
|
14
|
-
* **action**: `{ label, onClick }` button shown in place of the role and the remove button
|
|
15
|
-
* **isPending**: shows a spinner
|
|
15
|
+
* **action**: `{ label, onClick }` button shown in place of the role and the remove button, so `canChangeRole`, `canRemove` and `isPending` are ignored
|
|
16
|
+
* **isPending**: shows a spinner and the role as text, without the role menu and the remove button
|
|
16
17
|
* **onClick**: makes the row clickable
|
|
17
18
|
* **data**: anything the app needs back in its callbacks, not read by the row
|
|
18
19
|
|
|
@@ -2,8 +2,7 @@ import PropTypes from 'prop-types'
|
|
|
2
2
|
import React, { Fragment } from 'react'
|
|
3
3
|
import { useI18n, useExtendI18n } from 'twake-i18n'
|
|
4
4
|
|
|
5
|
-
import
|
|
6
|
-
import MemberGroupAvatar from './MemberGroupAvatar'
|
|
5
|
+
import MemberOrGroupAvatar from './MemberOrGroupAvatar'
|
|
7
6
|
import MemberRowActions from './MemberRowActions'
|
|
8
7
|
import { locales } from './locales'
|
|
9
8
|
import { memberPropType, rolesPropType } from './propTypes'
|
|
@@ -32,18 +31,7 @@ const MemberRow = ({ member, roles, isNew, onRoleChange, onRemove }) => {
|
|
|
32
31
|
useExtendI18n(locales)
|
|
33
32
|
const { t } = useI18n()
|
|
34
33
|
const { isMobile } = useBreakpoints()
|
|
35
|
-
const {
|
|
36
|
-
name,
|
|
37
|
-
subtitle,
|
|
38
|
-
avatarUrl,
|
|
39
|
-
initials,
|
|
40
|
-
color,
|
|
41
|
-
isGroup,
|
|
42
|
-
isOwner,
|
|
43
|
-
isCurrentUser,
|
|
44
|
-
action,
|
|
45
|
-
onClick
|
|
46
|
-
} = member
|
|
34
|
+
const { name, subtitle, isOwner, isCurrentUser, action, onClick } = member
|
|
47
35
|
|
|
48
36
|
const ActionsWrapper = onClick ? ListItemSecondaryAction : Fragment
|
|
49
37
|
const actionsWrapperProps = onClick
|
|
@@ -59,11 +47,7 @@ const MemberRow = ({ member, roles, isNew, onRoleChange, onRemove }) => {
|
|
|
59
47
|
size="small"
|
|
60
48
|
>
|
|
61
49
|
<ListItemIcon>
|
|
62
|
-
{
|
|
63
|
-
<MemberGroupAvatar size="m" color={color} />
|
|
64
|
-
) : (
|
|
65
|
-
<MemberAvatar size="m" initials={initials} avatarUrl={avatarUrl} />
|
|
66
|
-
)}
|
|
50
|
+
<MemberOrGroupAvatar member={member} size="m" />
|
|
67
51
|
</ListItemIcon>
|
|
68
52
|
<ListItemText
|
|
69
53
|
primary={
|
|
@@ -20,7 +20,7 @@ var useStyles = makeStyles(function (theme) {
|
|
|
20
20
|
typography: {
|
|
21
21
|
color: function color(_ref2) {
|
|
22
22
|
var disabled = _ref2.disabled;
|
|
23
|
-
return disabled ? theme.palette.text.disabled :
|
|
23
|
+
return disabled ? theme.palette.text.disabled : null;
|
|
24
24
|
}
|
|
25
25
|
},
|
|
26
26
|
endIcon: {
|
|
@@ -28,11 +28,11 @@ var useStyles = makeStyles(function (theme) {
|
|
|
28
28
|
marginLeft: '5px',
|
|
29
29
|
marginTop: function marginTop(_ref3) {
|
|
30
30
|
var variant = _ref3.variant;
|
|
31
|
-
return variant === 'body1' ? '3px' :
|
|
31
|
+
return variant === 'body1' ? '3px' : null;
|
|
32
32
|
},
|
|
33
33
|
color: function color(_ref4) {
|
|
34
34
|
var disabled = _ref4.disabled;
|
|
35
|
-
return disabled ? theme.palette.text.disabled :
|
|
35
|
+
return disabled ? theme.palette.text.disabled : null;
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export default MemberAutocompleteActions;
|
|
2
|
+
declare function MemberAutocompleteActions({ roles, role, isLoading, disabled, onRoleChange, onRoleMenuOpen, onRoleMenuClose, onWidthChange }: {
|
|
3
|
+
roles: any;
|
|
4
|
+
role: any;
|
|
5
|
+
isLoading: any;
|
|
6
|
+
disabled: any;
|
|
7
|
+
onRoleChange: any;
|
|
8
|
+
onRoleMenuOpen: any;
|
|
9
|
+
onRoleMenuClose: any;
|
|
10
|
+
onWidthChange: any;
|
|
11
|
+
}): JSX.Element | null;
|
|
12
|
+
declare namespace MemberAutocompleteActions {
|
|
13
|
+
namespace propTypes {
|
|
14
|
+
export { rolesPropType as roles };
|
|
15
|
+
export const role: PropTypes.Requireable<string>;
|
|
16
|
+
export const isLoading: PropTypes.Validator<boolean>;
|
|
17
|
+
export const disabled: PropTypes.Validator<boolean>;
|
|
18
|
+
export const onRoleChange: PropTypes.Requireable<(...args: any[]) => any>;
|
|
19
|
+
export const onRoleMenuOpen: PropTypes.Validator<(...args: any[]) => any>;
|
|
20
|
+
export const onRoleMenuClose: PropTypes.Validator<(...args: any[]) => any>;
|
|
21
|
+
export const onWidthChange: PropTypes.Validator<(...args: any[]) => any>;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
import { rolesPropType } from "../MemberRow/propTypes";
|
|
25
|
+
import PropTypes from "prop-types";
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import cx from 'classnames';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import React, { useLayoutEffect, useRef } from 'react';
|
|
4
|
+
import CircularProgress from "cozy-ui/transpiled/react/CircularProgress";
|
|
5
|
+
import MemberRoleMenu from "cozy-ui/transpiled/react/MemberRow/MemberRoleMenu";
|
|
6
|
+
import { rolesPropType } from "cozy-ui/transpiled/react/MemberRow/propTypes";
|
|
7
|
+
import { makeStyles } from "cozy-ui/transpiled/react/styles";
|
|
8
|
+
var useStyles = makeStyles({
|
|
9
|
+
root: {
|
|
10
|
+
top: '.375rem',
|
|
11
|
+
height: '2.375rem'
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
var MemberAutocompleteActions = function MemberAutocompleteActions(_ref) {
|
|
16
|
+
var roles = _ref.roles,
|
|
17
|
+
role = _ref.role,
|
|
18
|
+
isLoading = _ref.isLoading,
|
|
19
|
+
disabled = _ref.disabled,
|
|
20
|
+
onRoleChange = _ref.onRoleChange,
|
|
21
|
+
onRoleMenuOpen = _ref.onRoleMenuOpen,
|
|
22
|
+
onRoleMenuClose = _ref.onRoleMenuClose,
|
|
23
|
+
onWidthChange = _ref.onWidthChange;
|
|
24
|
+
var classes = useStyles();
|
|
25
|
+
var rootRef = useRef();
|
|
26
|
+
var isRoleMenuShown = roles !== undefined && role !== undefined;
|
|
27
|
+
var hasActions = isLoading || isRoleMenuShown;
|
|
28
|
+
useLayoutEffect(function () {
|
|
29
|
+
onWidthChange(rootRef.current ? rootRef.current.offsetWidth : 0);
|
|
30
|
+
}, [roles, role, isLoading, onWidthChange]);
|
|
31
|
+
if (!hasActions) return null;
|
|
32
|
+
return (
|
|
33
|
+
/*#__PURE__*/
|
|
34
|
+
// Clicks and keys in the role menu, portaled or not, bubble to the Autocomplete root,
|
|
35
|
+
// which would focus the input, remove the last member or pick a suggestion
|
|
36
|
+
React.createElement("div", {
|
|
37
|
+
ref: rootRef,
|
|
38
|
+
className: cx('u-pos-absolute u-right-m u-flex u-flex-items-center u-g-half', classes.root),
|
|
39
|
+
onClick: function onClick(event) {
|
|
40
|
+
return event.stopPropagation();
|
|
41
|
+
},
|
|
42
|
+
onKeyDown: function onKeyDown(event) {
|
|
43
|
+
return event.stopPropagation();
|
|
44
|
+
}
|
|
45
|
+
}, isLoading && /*#__PURE__*/React.createElement(CircularProgress, {
|
|
46
|
+
size: 16
|
|
47
|
+
}), isRoleMenuShown && /*#__PURE__*/React.createElement(MemberRoleMenu, {
|
|
48
|
+
value: role,
|
|
49
|
+
roles: roles,
|
|
50
|
+
size: "small",
|
|
51
|
+
disabled: disabled,
|
|
52
|
+
onChange: onRoleChange,
|
|
53
|
+
onOpen: onRoleMenuOpen,
|
|
54
|
+
onClose: onRoleMenuClose
|
|
55
|
+
}))
|
|
56
|
+
);
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
MemberAutocompleteActions.propTypes = {
|
|
60
|
+
roles: rolesPropType,
|
|
61
|
+
role: PropTypes.string,
|
|
62
|
+
isLoading: PropTypes.bool.isRequired,
|
|
63
|
+
disabled: PropTypes.bool.isRequired,
|
|
64
|
+
onRoleChange: PropTypes.func,
|
|
65
|
+
onRoleMenuOpen: PropTypes.func.isRequired,
|
|
66
|
+
onRoleMenuClose: PropTypes.func.isRequired,
|
|
67
|
+
onWidthChange: PropTypes.func.isRequired
|
|
68
|
+
};
|
|
69
|
+
export default MemberAutocompleteActions;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export default MemberChip;
|
|
2
|
+
declare function MemberChip({ member, tagProps }: {
|
|
3
|
+
member: any;
|
|
4
|
+
tagProps: any;
|
|
5
|
+
}): JSX.Element;
|
|
6
|
+
declare namespace MemberChip {
|
|
7
|
+
namespace propTypes {
|
|
8
|
+
const member: PropTypes.Validator<PropTypes.InferProps<{
|
|
9
|
+
id: PropTypes.Validator<string>;
|
|
10
|
+
name: PropTypes.Requireable<string>;
|
|
11
|
+
subtitle: PropTypes.Requireable<PropTypes.ReactNodeLike>;
|
|
12
|
+
email: PropTypes.Requireable<string>;
|
|
13
|
+
avatarUrl: PropTypes.Requireable<string>;
|
|
14
|
+
initials: PropTypes.Requireable<string>;
|
|
15
|
+
color: PropTypes.Requireable<string>;
|
|
16
|
+
isGroup: PropTypes.Requireable<boolean>;
|
|
17
|
+
isOwner: PropTypes.Requireable<boolean>;
|
|
18
|
+
isCurrentUser: PropTypes.Requireable<boolean>;
|
|
19
|
+
role: PropTypes.Requireable<string>;
|
|
20
|
+
roles: PropTypes.Requireable<(PropTypes.InferProps<{
|
|
21
|
+
value: PropTypes.Validator<string>;
|
|
22
|
+
label: PropTypes.Validator<string>;
|
|
23
|
+
}> | null)[]>;
|
|
24
|
+
canChangeRole: PropTypes.Requireable<boolean>;
|
|
25
|
+
canRemove: PropTypes.Requireable<boolean>;
|
|
26
|
+
removeIcon: PropTypes.Requireable<object>;
|
|
27
|
+
removeLabel: PropTypes.Requireable<string>;
|
|
28
|
+
action: PropTypes.Requireable<PropTypes.InferProps<{
|
|
29
|
+
label: PropTypes.Validator<string>;
|
|
30
|
+
onClick: PropTypes.Validator<(...args: any[]) => any>;
|
|
31
|
+
}>>;
|
|
32
|
+
isPending: PropTypes.Requireable<boolean>;
|
|
33
|
+
onClick: PropTypes.Requireable<(...args: any[]) => any>;
|
|
34
|
+
data: PropTypes.Requireable<any>;
|
|
35
|
+
}>>;
|
|
36
|
+
const tagProps: PropTypes.Validator<object>;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
import PropTypes from "prop-types";
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { useI18n, useExtendI18n } from 'twake-i18n';
|
|
5
|
+
import Chip from "cozy-ui/transpiled/react/Chips";
|
|
6
|
+
import MemberOrGroupAvatar from "cozy-ui/transpiled/react/MemberRow/MemberOrGroupAvatar";
|
|
7
|
+
import { locales } from "cozy-ui/transpiled/react/MemberRow/locales";
|
|
8
|
+
import { memberPropType } from "cozy-ui/transpiled/react/MemberRow/propTypes";
|
|
9
|
+
|
|
10
|
+
var MemberChip = function MemberChip(_ref) {
|
|
11
|
+
var member = _ref.member,
|
|
12
|
+
tagProps = _ref.tagProps;
|
|
13
|
+
useExtendI18n(locales);
|
|
14
|
+
|
|
15
|
+
var _useI18n = useI18n(),
|
|
16
|
+
t = _useI18n.t;
|
|
17
|
+
|
|
18
|
+
return /*#__PURE__*/React.createElement(Chip, _extends({}, tagProps, {
|
|
19
|
+
label: member.name || t('MemberRow.defaultName'),
|
|
20
|
+
avatar: /*#__PURE__*/React.createElement(MemberOrGroupAvatar, {
|
|
21
|
+
member: member,
|
|
22
|
+
size: "xs"
|
|
23
|
+
})
|
|
24
|
+
}));
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
MemberChip.propTypes = {
|
|
28
|
+
member: memberPropType.isRequired,
|
|
29
|
+
|
|
30
|
+
/** Props given by the Autocomplete for each tag */
|
|
31
|
+
tagProps: PropTypes.object.isRequired
|
|
32
|
+
};
|
|
33
|
+
export default MemberChip;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export default MemberSuggestion;
|
|
2
|
+
declare function MemberSuggestion({ suggestion }: {
|
|
3
|
+
suggestion: any;
|
|
4
|
+
}): JSX.Element;
|
|
5
|
+
declare namespace MemberSuggestion {
|
|
6
|
+
namespace propTypes {
|
|
7
|
+
const suggestion: import("prop-types").Validator<import("prop-types").InferProps<{
|
|
8
|
+
id: import("prop-types").Validator<string>;
|
|
9
|
+
name: import("prop-types").Requireable<string>;
|
|
10
|
+
subtitle: import("prop-types").Requireable<import("prop-types").ReactNodeLike>;
|
|
11
|
+
email: import("prop-types").Requireable<string>;
|
|
12
|
+
avatarUrl: import("prop-types").Requireable<string>;
|
|
13
|
+
initials: import("prop-types").Requireable<string>;
|
|
14
|
+
color: import("prop-types").Requireable<string>;
|
|
15
|
+
isGroup: import("prop-types").Requireable<boolean>;
|
|
16
|
+
isOwner: import("prop-types").Requireable<boolean>;
|
|
17
|
+
isCurrentUser: import("prop-types").Requireable<boolean>;
|
|
18
|
+
role: import("prop-types").Requireable<string>;
|
|
19
|
+
roles: import("prop-types").Requireable<(import("prop-types").InferProps<{
|
|
20
|
+
value: import("prop-types").Validator<string>;
|
|
21
|
+
label: import("prop-types").Validator<string>;
|
|
22
|
+
}> | null)[]>;
|
|
23
|
+
canChangeRole: import("prop-types").Requireable<boolean>;
|
|
24
|
+
canRemove: import("prop-types").Requireable<boolean>;
|
|
25
|
+
removeIcon: import("prop-types").Requireable<object>;
|
|
26
|
+
removeLabel: import("prop-types").Requireable<string>;
|
|
27
|
+
action: import("prop-types").Requireable<import("prop-types").InferProps<{
|
|
28
|
+
label: import("prop-types").Validator<string>;
|
|
29
|
+
onClick: import("prop-types").Validator<(...args: any[]) => any>;
|
|
30
|
+
}>>;
|
|
31
|
+
isPending: import("prop-types").Requireable<boolean>;
|
|
32
|
+
onClick: import("prop-types").Requireable<(...args: any[]) => any>;
|
|
33
|
+
data: import("prop-types").Requireable<any>;
|
|
34
|
+
}>>;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { useI18n, useExtendI18n } from 'twake-i18n';
|
|
3
|
+
import ListItem from "cozy-ui/transpiled/react/ListItem";
|
|
4
|
+
import ListItemIcon from "cozy-ui/transpiled/react/ListItemIcon";
|
|
5
|
+
import ListItemText from "cozy-ui/transpiled/react/ListItemText";
|
|
6
|
+
import MemberOrGroupAvatar from "cozy-ui/transpiled/react/MemberRow/MemberOrGroupAvatar";
|
|
7
|
+
import { locales } from "cozy-ui/transpiled/react/MemberRow/locales";
|
|
8
|
+
import { memberPropType } from "cozy-ui/transpiled/react/MemberRow/propTypes";
|
|
9
|
+
|
|
10
|
+
var MemberSuggestion = function MemberSuggestion(_ref) {
|
|
11
|
+
var suggestion = _ref.suggestion;
|
|
12
|
+
useExtendI18n(locales);
|
|
13
|
+
|
|
14
|
+
var _useI18n = useI18n(),
|
|
15
|
+
t = _useI18n.t;
|
|
16
|
+
|
|
17
|
+
return /*#__PURE__*/React.createElement(ListItem, {
|
|
18
|
+
component: "div"
|
|
19
|
+
}, /*#__PURE__*/React.createElement(ListItemIcon, null, /*#__PURE__*/React.createElement(MemberOrGroupAvatar, {
|
|
20
|
+
member: suggestion,
|
|
21
|
+
size: "m"
|
|
22
|
+
})), /*#__PURE__*/React.createElement(ListItemText, {
|
|
23
|
+
primary: suggestion.name || t('MemberRow.defaultName'),
|
|
24
|
+
secondary: suggestion.subtitle
|
|
25
|
+
}));
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
MemberSuggestion.propTypes = {
|
|
29
|
+
suggestion: memberPropType.isRequired
|
|
30
|
+
};
|
|
31
|
+
export default MemberSuggestion;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export function isEmailLike(text: any): boolean;
|
|
2
|
+
export function isSameMember(member: any, other: any): boolean;
|
|
3
|
+
export function removeDuplicateMembers(members: any): any;
|
|
4
|
+
export function getUnpickedMembers(members: any, pickedMembers: any): any;
|
|
5
|
+
export function resolveKnownMembers(members: object[], knownMembers: object[]): object[];
|
|
6
|
+
export function makeMembersFromValue(value: Array<object | string>, getMembersFromText: Function): object[];
|
|
7
|
+
export function makeSuggestions(matchingSuggestions: object[], textSuggestions: object[]): object[];
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
var EMAIL_LIKE = /\S+@\S+/;
|
|
2
|
+
var MAX_SUGGESTIONS = 20;
|
|
3
|
+
export var isEmailLike = function isEmailLike(text) {
|
|
4
|
+
return EMAIL_LIKE.test(text);
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
var normalizeEmail = function normalizeEmail(email) {
|
|
8
|
+
return email.trim().toLowerCase();
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Whether two members are the same person: same id, or same email whatever its case
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
export var isSameMember = function isSameMember(member, other) {
|
|
16
|
+
return member.id === other.id || Boolean(member.email) && Boolean(other.email) && normalizeEmail(member.email) === normalizeEmail(other.email);
|
|
17
|
+
};
|
|
18
|
+
export var removeDuplicateMembers = function removeDuplicateMembers(members) {
|
|
19
|
+
return members.filter(function (member, index) {
|
|
20
|
+
return members.findIndex(function (other) {
|
|
21
|
+
return isSameMember(member, other);
|
|
22
|
+
}) === index;
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
export var getUnpickedMembers = function getUnpickedMembers(members, pickedMembers) {
|
|
26
|
+
return members.filter(function (member) {
|
|
27
|
+
return !pickedMembers.some(function (picked) {
|
|
28
|
+
return isSameMember(member, picked);
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Replaces each member by the known one for the same person, so that a typed email
|
|
34
|
+
* gives the suggested contact rather than a second member
|
|
35
|
+
*
|
|
36
|
+
* @param {object[]} members - Members made from a text
|
|
37
|
+
* @param {object[]} knownMembers - Picked and suggested members
|
|
38
|
+
* @returns {object[]}
|
|
39
|
+
*/
|
|
40
|
+
|
|
41
|
+
export var resolveKnownMembers = function resolveKnownMembers(members, knownMembers) {
|
|
42
|
+
return removeDuplicateMembers(members.map(function (member) {
|
|
43
|
+
var _knownMembers$find;
|
|
44
|
+
|
|
45
|
+
return (_knownMembers$find = knownMembers.find(function (known) {
|
|
46
|
+
return isSameMember(member, known);
|
|
47
|
+
})) !== null && _knownMembers$find !== void 0 ? _knownMembers$find : member;
|
|
48
|
+
}));
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Turns the value of the Autocomplete, where typed texts stay strings, into members without duplicates
|
|
52
|
+
*
|
|
53
|
+
* @param {Array<object|string>} value - Picked members and typed texts
|
|
54
|
+
* @param {Function} getMembersFromText - Turns a text into members
|
|
55
|
+
* @returns {object[]}
|
|
56
|
+
*/
|
|
57
|
+
|
|
58
|
+
export var makeMembersFromValue = function makeMembersFromValue(value, getMembersFromText) {
|
|
59
|
+
return removeDuplicateMembers(value.flatMap(function (item) {
|
|
60
|
+
return typeof item === 'string' ? getMembersFromText(item) : [item];
|
|
61
|
+
}));
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Members to suggest: the matching ones without duplicates, else the ones made from the text
|
|
65
|
+
*
|
|
66
|
+
* @param {object[]} matchingSuggestions - Fetched then local members matching the text
|
|
67
|
+
* @param {object[]} textSuggestions - Members made from the text
|
|
68
|
+
* @returns {object[]}
|
|
69
|
+
*/
|
|
70
|
+
|
|
71
|
+
export var makeSuggestions = function makeSuggestions(matchingSuggestions, textSuggestions) {
|
|
72
|
+
return (matchingSuggestions.length > 0 ? removeDuplicateMembers(matchingSuggestions) : textSuggestions).slice(0, MAX_SUGGESTIONS);
|
|
73
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
export default MemberAutocomplete;
|
|
2
|
+
/**
|
|
3
|
+
* Field to pick the members to invite among suggestions, shown as chips
|
|
4
|
+
*/
|
|
5
|
+
declare function MemberAutocomplete({ value, getSuggestions, fetchSuggestions, getMembersFromText, minQueryLength, debounceMs, roles, role, title, placeholder, loading, disabled, autoFocus, onChange, onRoleChange, onSubmit }: {
|
|
6
|
+
value: any;
|
|
7
|
+
getSuggestions?: (() => never[]) | undefined;
|
|
8
|
+
fetchSuggestions: any;
|
|
9
|
+
getMembersFromText?: (() => never[]) | undefined;
|
|
10
|
+
minQueryLength?: number | undefined;
|
|
11
|
+
debounceMs?: number | undefined;
|
|
12
|
+
roles: any;
|
|
13
|
+
role: any;
|
|
14
|
+
title: any;
|
|
15
|
+
placeholder: any;
|
|
16
|
+
loading?: boolean | undefined;
|
|
17
|
+
disabled?: boolean | undefined;
|
|
18
|
+
autoFocus?: boolean | undefined;
|
|
19
|
+
onChange: any;
|
|
20
|
+
onRoleChange: any;
|
|
21
|
+
onSubmit: any;
|
|
22
|
+
}): JSX.Element;
|
|
23
|
+
declare namespace MemberAutocomplete {
|
|
24
|
+
namespace propTypes {
|
|
25
|
+
export const value: PropTypes.Validator<(PropTypes.InferProps<{
|
|
26
|
+
id: PropTypes.Validator<string>;
|
|
27
|
+
name: PropTypes.Requireable<string>;
|
|
28
|
+
subtitle: PropTypes.Requireable<PropTypes.ReactNodeLike>;
|
|
29
|
+
email: PropTypes.Requireable<string>;
|
|
30
|
+
avatarUrl: PropTypes.Requireable<string>;
|
|
31
|
+
initials: PropTypes.Requireable<string>;
|
|
32
|
+
color: PropTypes.Requireable<string>;
|
|
33
|
+
isGroup: PropTypes.Requireable<boolean>;
|
|
34
|
+
isOwner: PropTypes.Requireable<boolean>;
|
|
35
|
+
isCurrentUser: PropTypes.Requireable<boolean>;
|
|
36
|
+
role: PropTypes.Requireable<string>;
|
|
37
|
+
roles: PropTypes.Requireable<(PropTypes.InferProps<{
|
|
38
|
+
value: PropTypes.Validator<string>;
|
|
39
|
+
label: PropTypes.Validator<string>;
|
|
40
|
+
}> | null)[]>;
|
|
41
|
+
canChangeRole: PropTypes.Requireable<boolean>;
|
|
42
|
+
canRemove: PropTypes.Requireable<boolean>;
|
|
43
|
+
removeIcon: PropTypes.Requireable<object>;
|
|
44
|
+
removeLabel: PropTypes.Requireable<string>;
|
|
45
|
+
action: PropTypes.Requireable<PropTypes.InferProps<{
|
|
46
|
+
label: PropTypes.Validator<string>;
|
|
47
|
+
onClick: PropTypes.Validator<(...args: any[]) => any>;
|
|
48
|
+
}>>;
|
|
49
|
+
isPending: PropTypes.Requireable<boolean>;
|
|
50
|
+
onClick: PropTypes.Requireable<(...args: any[]) => any>;
|
|
51
|
+
data: PropTypes.Requireable<any>;
|
|
52
|
+
}> | null)[]>;
|
|
53
|
+
export const getSuggestions: PropTypes.Requireable<(...args: any[]) => any>;
|
|
54
|
+
export const fetchSuggestions: PropTypes.Requireable<(...args: any[]) => any>;
|
|
55
|
+
export const getMembersFromText: PropTypes.Requireable<(...args: any[]) => any>;
|
|
56
|
+
export const minQueryLength: PropTypes.Requireable<number>;
|
|
57
|
+
export const debounceMs: PropTypes.Requireable<number>;
|
|
58
|
+
export { rolesPropType as roles };
|
|
59
|
+
export const role: PropTypes.Requireable<string>;
|
|
60
|
+
export const title: PropTypes.Requireable<string>;
|
|
61
|
+
export const placeholder: PropTypes.Requireable<string>;
|
|
62
|
+
export const loading: PropTypes.Requireable<boolean>;
|
|
63
|
+
export const disabled: PropTypes.Requireable<boolean>;
|
|
64
|
+
export const autoFocus: PropTypes.Requireable<boolean>;
|
|
65
|
+
export const onChange: PropTypes.Validator<(...args: any[]) => any>;
|
|
66
|
+
export const onRoleChange: PropTypes.Requireable<(...args: any[]) => any>;
|
|
67
|
+
export const onSubmit: PropTypes.Requireable<(...args: any[]) => any>;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
import PropTypes from "prop-types";
|
|
71
|
+
import { rolesPropType } from "../MemberRow/propTypes";
|