Fix: Add status in group member modal (#27776)
* Fix: Add status in group member modal * Fix: Optional values for members info and fix css for user button * Fix: remove useless props and classname in status icon * Fix: types eslint * Fix: snap --------- Co-authored-by: Boris Trombert <boris.trombert@infomaniak.com> Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
@@ -1016,24 +1016,60 @@ exports[`component/user_group_popover should match snapshot 1`] = `
|
||||
>
|
||||
<UserButton>
|
||||
<button
|
||||
className="UserButton-bZNeGd lLsMM"
|
||||
className="UserButton-bZNeGd gDRhSF"
|
||||
>
|
||||
<Memo(Avatar)
|
||||
className="avatar-post-preview"
|
||||
size="sm"
|
||||
tabIndex={-1}
|
||||
url="/api/v4/users/id0/image?_=0"
|
||||
username="username0"
|
||||
<span
|
||||
className="status-wrapper"
|
||||
>
|
||||
<img
|
||||
alt="username0 profile image"
|
||||
className="Avatar Avatar-sm avatar-post-preview"
|
||||
loading="lazy"
|
||||
onError={[Function]}
|
||||
src="/api/v4/users/id0/image?_=0"
|
||||
<Memo(Avatar)
|
||||
className="avatar-post-preview"
|
||||
size="sm"
|
||||
tabIndex={-1}
|
||||
/>
|
||||
</Memo(Avatar)>
|
||||
url="/api/v4/users/id0/image?_=0"
|
||||
username="username0"
|
||||
>
|
||||
<img
|
||||
alt="username0 profile image"
|
||||
className="Avatar Avatar-sm avatar-post-preview"
|
||||
loading="lazy"
|
||||
onError={[Function]}
|
||||
src="/api/v4/users/id0/image?_=0"
|
||||
tabIndex={-1}
|
||||
/>
|
||||
</Memo(Avatar)>
|
||||
<Memo(StatusIcon)
|
||||
status="offline"
|
||||
>
|
||||
<StatusOfflineIcon
|
||||
className="status "
|
||||
>
|
||||
<span
|
||||
className="status "
|
||||
>
|
||||
<svg
|
||||
aria-label="Offline Icon"
|
||||
className="offline--icon"
|
||||
height="100%"
|
||||
role="img"
|
||||
style={
|
||||
Object {
|
||||
"clipRule": "evenodd",
|
||||
"fillRule": "evenodd",
|
||||
"strokeLinejoin": "round",
|
||||
"strokeMiterlimit": 1.41421,
|
||||
}
|
||||
}
|
||||
viewBox="0 0 20 20"
|
||||
width="100%"
|
||||
>
|
||||
<path
|
||||
d="M10,0c5.519,0 10,4.481 10,10c0,5.519 -4.481,10 -10,10c-5.519,0 -10,-4.481 -10,-10c0,-5.519 4.481,-10 10,-10Zm0,2c4.415,0 8,3.585 8,8c0,4.415 -3.585,8 -8,8c-4.415,0 -8,-3.585 -8,-8c0,-4.415 3.585,-8 8,-8Z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</StatusOfflineIcon>
|
||||
</Memo(StatusIcon)>
|
||||
</span>
|
||||
<Username
|
||||
className="overflow--ellipsis text-nowrap"
|
||||
>
|
||||
@@ -1224,24 +1260,60 @@ exports[`component/user_group_popover should match snapshot 1`] = `
|
||||
>
|
||||
<UserButton>
|
||||
<button
|
||||
className="UserButton-bZNeGd lLsMM"
|
||||
className="UserButton-bZNeGd gDRhSF"
|
||||
>
|
||||
<Memo(Avatar)
|
||||
className="avatar-post-preview"
|
||||
size="sm"
|
||||
tabIndex={-1}
|
||||
url="/api/v4/users/id1/image?_=0"
|
||||
username="username1"
|
||||
<span
|
||||
className="status-wrapper"
|
||||
>
|
||||
<img
|
||||
alt="username1 profile image"
|
||||
className="Avatar Avatar-sm avatar-post-preview"
|
||||
loading="lazy"
|
||||
onError={[Function]}
|
||||
src="/api/v4/users/id1/image?_=0"
|
||||
<Memo(Avatar)
|
||||
className="avatar-post-preview"
|
||||
size="sm"
|
||||
tabIndex={-1}
|
||||
/>
|
||||
</Memo(Avatar)>
|
||||
url="/api/v4/users/id1/image?_=0"
|
||||
username="username1"
|
||||
>
|
||||
<img
|
||||
alt="username1 profile image"
|
||||
className="Avatar Avatar-sm avatar-post-preview"
|
||||
loading="lazy"
|
||||
onError={[Function]}
|
||||
src="/api/v4/users/id1/image?_=0"
|
||||
tabIndex={-1}
|
||||
/>
|
||||
</Memo(Avatar)>
|
||||
<Memo(StatusIcon)
|
||||
status="offline"
|
||||
>
|
||||
<StatusOfflineIcon
|
||||
className="status "
|
||||
>
|
||||
<span
|
||||
className="status "
|
||||
>
|
||||
<svg
|
||||
aria-label="Offline Icon"
|
||||
className="offline--icon"
|
||||
height="100%"
|
||||
role="img"
|
||||
style={
|
||||
Object {
|
||||
"clipRule": "evenodd",
|
||||
"fillRule": "evenodd",
|
||||
"strokeLinejoin": "round",
|
||||
"strokeMiterlimit": 1.41421,
|
||||
}
|
||||
}
|
||||
viewBox="0 0 20 20"
|
||||
width="100%"
|
||||
>
|
||||
<path
|
||||
d="M10,0c5.519,0 10,4.481 10,10c0,5.519 -4.481,10 -10,10c-5.519,0 -10,-4.481 -10,-10c0,-5.519 4.481,-10 10,-10Zm0,2c4.415,0 8,3.585 8,8c0,4.415 -3.585,8 -8,8c-4.415,0 -8,-3.585 -8,-8c0,-4.415 3.585,-8 8,-8Z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</StatusOfflineIcon>
|
||||
</Memo(StatusIcon)>
|
||||
</span>
|
||||
<Username
|
||||
className="overflow--ellipsis text-nowrap"
|
||||
>
|
||||
@@ -1432,24 +1504,60 @@ exports[`component/user_group_popover should match snapshot 1`] = `
|
||||
>
|
||||
<UserButton>
|
||||
<button
|
||||
className="UserButton-bZNeGd lLsMM"
|
||||
className="UserButton-bZNeGd gDRhSF"
|
||||
>
|
||||
<Memo(Avatar)
|
||||
className="avatar-post-preview"
|
||||
size="sm"
|
||||
tabIndex={-1}
|
||||
url="/api/v4/users/id10/image?_=0"
|
||||
username="username10"
|
||||
<span
|
||||
className="status-wrapper"
|
||||
>
|
||||
<img
|
||||
alt="username10 profile image"
|
||||
className="Avatar Avatar-sm avatar-post-preview"
|
||||
loading="lazy"
|
||||
onError={[Function]}
|
||||
src="/api/v4/users/id10/image?_=0"
|
||||
<Memo(Avatar)
|
||||
className="avatar-post-preview"
|
||||
size="sm"
|
||||
tabIndex={-1}
|
||||
/>
|
||||
</Memo(Avatar)>
|
||||
url="/api/v4/users/id10/image?_=0"
|
||||
username="username10"
|
||||
>
|
||||
<img
|
||||
alt="username10 profile image"
|
||||
className="Avatar Avatar-sm avatar-post-preview"
|
||||
loading="lazy"
|
||||
onError={[Function]}
|
||||
src="/api/v4/users/id10/image?_=0"
|
||||
tabIndex={-1}
|
||||
/>
|
||||
</Memo(Avatar)>
|
||||
<Memo(StatusIcon)
|
||||
status="offline"
|
||||
>
|
||||
<StatusOfflineIcon
|
||||
className="status "
|
||||
>
|
||||
<span
|
||||
className="status "
|
||||
>
|
||||
<svg
|
||||
aria-label="Offline Icon"
|
||||
className="offline--icon"
|
||||
height="100%"
|
||||
role="img"
|
||||
style={
|
||||
Object {
|
||||
"clipRule": "evenodd",
|
||||
"fillRule": "evenodd",
|
||||
"strokeLinejoin": "round",
|
||||
"strokeMiterlimit": 1.41421,
|
||||
}
|
||||
}
|
||||
viewBox="0 0 20 20"
|
||||
width="100%"
|
||||
>
|
||||
<path
|
||||
d="M10,0c5.519,0 10,4.481 10,10c0,5.519 -4.481,10 -10,10c-5.519,0 -10,-4.481 -10,-10c0,-5.519 4.481,-10 10,-10Zm0,2c4.415,0 8,3.585 8,8c0,4.415 -3.585,8 -8,8c-4.415,0 -8,-3.585 -8,-8c0,-4.415 3.585,-8 8,-8Z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</StatusOfflineIcon>
|
||||
</Memo(StatusIcon)>
|
||||
</span>
|
||||
<Username
|
||||
className="overflow--ellipsis text-nowrap"
|
||||
>
|
||||
@@ -1640,24 +1748,60 @@ exports[`component/user_group_popover should match snapshot 1`] = `
|
||||
>
|
||||
<UserButton>
|
||||
<button
|
||||
className="UserButton-bZNeGd lLsMM"
|
||||
className="UserButton-bZNeGd gDRhSF"
|
||||
>
|
||||
<Memo(Avatar)
|
||||
className="avatar-post-preview"
|
||||
size="sm"
|
||||
tabIndex={-1}
|
||||
url="/api/v4/users/id11/image?_=0"
|
||||
username="username11"
|
||||
<span
|
||||
className="status-wrapper"
|
||||
>
|
||||
<img
|
||||
alt="username11 profile image"
|
||||
className="Avatar Avatar-sm avatar-post-preview"
|
||||
loading="lazy"
|
||||
onError={[Function]}
|
||||
src="/api/v4/users/id11/image?_=0"
|
||||
<Memo(Avatar)
|
||||
className="avatar-post-preview"
|
||||
size="sm"
|
||||
tabIndex={-1}
|
||||
/>
|
||||
</Memo(Avatar)>
|
||||
url="/api/v4/users/id11/image?_=0"
|
||||
username="username11"
|
||||
>
|
||||
<img
|
||||
alt="username11 profile image"
|
||||
className="Avatar Avatar-sm avatar-post-preview"
|
||||
loading="lazy"
|
||||
onError={[Function]}
|
||||
src="/api/v4/users/id11/image?_=0"
|
||||
tabIndex={-1}
|
||||
/>
|
||||
</Memo(Avatar)>
|
||||
<Memo(StatusIcon)
|
||||
status="offline"
|
||||
>
|
||||
<StatusOfflineIcon
|
||||
className="status "
|
||||
>
|
||||
<span
|
||||
className="status "
|
||||
>
|
||||
<svg
|
||||
aria-label="Offline Icon"
|
||||
className="offline--icon"
|
||||
height="100%"
|
||||
role="img"
|
||||
style={
|
||||
Object {
|
||||
"clipRule": "evenodd",
|
||||
"fillRule": "evenodd",
|
||||
"strokeLinejoin": "round",
|
||||
"strokeMiterlimit": 1.41421,
|
||||
}
|
||||
}
|
||||
viewBox="0 0 20 20"
|
||||
width="100%"
|
||||
>
|
||||
<path
|
||||
d="M10,0c5.519,0 10,4.481 10,10c0,5.519 -4.481,10 -10,10c-5.519,0 -10,-4.481 -10,-10c0,-5.519 4.481,-10 10,-10Zm0,2c4.415,0 8,3.585 8,8c0,4.415 -3.585,8 -8,8c-4.415,0 -8,-3.585 -8,-8c0,-4.415 3.585,-8 8,-8Z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</StatusOfflineIcon>
|
||||
</Memo(StatusIcon)>
|
||||
</span>
|
||||
<Username
|
||||
className="overflow--ellipsis text-nowrap"
|
||||
>
|
||||
@@ -1848,24 +1992,60 @@ exports[`component/user_group_popover should match snapshot 1`] = `
|
||||
>
|
||||
<UserButton>
|
||||
<button
|
||||
className="UserButton-bZNeGd lLsMM"
|
||||
className="UserButton-bZNeGd gDRhSF"
|
||||
>
|
||||
<Memo(Avatar)
|
||||
className="avatar-post-preview"
|
||||
size="sm"
|
||||
tabIndex={-1}
|
||||
url="/api/v4/users/id12/image?_=0"
|
||||
username="username12"
|
||||
<span
|
||||
className="status-wrapper"
|
||||
>
|
||||
<img
|
||||
alt="username12 profile image"
|
||||
className="Avatar Avatar-sm avatar-post-preview"
|
||||
loading="lazy"
|
||||
onError={[Function]}
|
||||
src="/api/v4/users/id12/image?_=0"
|
||||
<Memo(Avatar)
|
||||
className="avatar-post-preview"
|
||||
size="sm"
|
||||
tabIndex={-1}
|
||||
/>
|
||||
</Memo(Avatar)>
|
||||
url="/api/v4/users/id12/image?_=0"
|
||||
username="username12"
|
||||
>
|
||||
<img
|
||||
alt="username12 profile image"
|
||||
className="Avatar Avatar-sm avatar-post-preview"
|
||||
loading="lazy"
|
||||
onError={[Function]}
|
||||
src="/api/v4/users/id12/image?_=0"
|
||||
tabIndex={-1}
|
||||
/>
|
||||
</Memo(Avatar)>
|
||||
<Memo(StatusIcon)
|
||||
status="offline"
|
||||
>
|
||||
<StatusOfflineIcon
|
||||
className="status "
|
||||
>
|
||||
<span
|
||||
className="status "
|
||||
>
|
||||
<svg
|
||||
aria-label="Offline Icon"
|
||||
className="offline--icon"
|
||||
height="100%"
|
||||
role="img"
|
||||
style={
|
||||
Object {
|
||||
"clipRule": "evenodd",
|
||||
"fillRule": "evenodd",
|
||||
"strokeLinejoin": "round",
|
||||
"strokeMiterlimit": 1.41421,
|
||||
}
|
||||
}
|
||||
viewBox="0 0 20 20"
|
||||
width="100%"
|
||||
>
|
||||
<path
|
||||
d="M10,0c5.519,0 10,4.481 10,10c0,5.519 -4.481,10 -10,10c-5.519,0 -10,-4.481 -10,-10c0,-5.519 4.481,-10 10,-10Zm0,2c4.415,0 8,3.585 8,8c0,4.415 -3.585,8 -8,8c-4.415,0 -8,-3.585 -8,-8c0,-4.415 3.585,-8 8,-8Z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</StatusOfflineIcon>
|
||||
</Memo(StatusIcon)>
|
||||
</span>
|
||||
<Username
|
||||
className="overflow--ellipsis text-nowrap"
|
||||
>
|
||||
|
||||
@@ -401,24 +401,60 @@ exports[`component/user_group_popover/group_member_list should match snapshot 1`
|
||||
>
|
||||
<UserButton>
|
||||
<button
|
||||
className="UserButton-bZNeGd lLsMM"
|
||||
className="UserButton-bZNeGd gDRhSF"
|
||||
>
|
||||
<Memo(Avatar)
|
||||
className="avatar-post-preview"
|
||||
size="sm"
|
||||
tabIndex={-1}
|
||||
url="/api/v4/users/id0/image?_=0"
|
||||
username="username0"
|
||||
<span
|
||||
className="status-wrapper"
|
||||
>
|
||||
<img
|
||||
alt="username0 profile image"
|
||||
className="Avatar Avatar-sm avatar-post-preview"
|
||||
loading="lazy"
|
||||
onError={[Function]}
|
||||
src="/api/v4/users/id0/image?_=0"
|
||||
<Memo(Avatar)
|
||||
className="avatar-post-preview"
|
||||
size="sm"
|
||||
tabIndex={-1}
|
||||
/>
|
||||
</Memo(Avatar)>
|
||||
url="/api/v4/users/id0/image?_=0"
|
||||
username="username0"
|
||||
>
|
||||
<img
|
||||
alt="username0 profile image"
|
||||
className="Avatar Avatar-sm avatar-post-preview"
|
||||
loading="lazy"
|
||||
onError={[Function]}
|
||||
src="/api/v4/users/id0/image?_=0"
|
||||
tabIndex={-1}
|
||||
/>
|
||||
</Memo(Avatar)>
|
||||
<Memo(StatusIcon)
|
||||
status="offline"
|
||||
>
|
||||
<StatusOfflineIcon
|
||||
className="status "
|
||||
>
|
||||
<span
|
||||
className="status "
|
||||
>
|
||||
<svg
|
||||
aria-label="Offline Icon"
|
||||
className="offline--icon"
|
||||
height="100%"
|
||||
role="img"
|
||||
style={
|
||||
Object {
|
||||
"clipRule": "evenodd",
|
||||
"fillRule": "evenodd",
|
||||
"strokeLinejoin": "round",
|
||||
"strokeMiterlimit": 1.41421,
|
||||
}
|
||||
}
|
||||
viewBox="0 0 20 20"
|
||||
width="100%"
|
||||
>
|
||||
<path
|
||||
d="M10,0c5.519,0 10,4.481 10,10c0,5.519 -4.481,10 -10,10c-5.519,0 -10,-4.481 -10,-10c0,-5.519 4.481,-10 10,-10Zm0,2c4.415,0 8,3.585 8,8c0,4.415 -3.585,8 -8,8c-4.415,0 -8,-3.585 -8,-8c0,-4.415 3.585,-8 8,-8Z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</StatusOfflineIcon>
|
||||
</Memo(StatusIcon)>
|
||||
</span>
|
||||
<Username
|
||||
className="overflow--ellipsis text-nowrap"
|
||||
>
|
||||
@@ -609,24 +645,60 @@ exports[`component/user_group_popover/group_member_list should match snapshot 1`
|
||||
>
|
||||
<UserButton>
|
||||
<button
|
||||
className="UserButton-bZNeGd lLsMM"
|
||||
className="UserButton-bZNeGd gDRhSF"
|
||||
>
|
||||
<Memo(Avatar)
|
||||
className="avatar-post-preview"
|
||||
size="sm"
|
||||
tabIndex={-1}
|
||||
url="/api/v4/users/id1/image?_=0"
|
||||
username="username1"
|
||||
<span
|
||||
className="status-wrapper"
|
||||
>
|
||||
<img
|
||||
alt="username1 profile image"
|
||||
className="Avatar Avatar-sm avatar-post-preview"
|
||||
loading="lazy"
|
||||
onError={[Function]}
|
||||
src="/api/v4/users/id1/image?_=0"
|
||||
<Memo(Avatar)
|
||||
className="avatar-post-preview"
|
||||
size="sm"
|
||||
tabIndex={-1}
|
||||
/>
|
||||
</Memo(Avatar)>
|
||||
url="/api/v4/users/id1/image?_=0"
|
||||
username="username1"
|
||||
>
|
||||
<img
|
||||
alt="username1 profile image"
|
||||
className="Avatar Avatar-sm avatar-post-preview"
|
||||
loading="lazy"
|
||||
onError={[Function]}
|
||||
src="/api/v4/users/id1/image?_=0"
|
||||
tabIndex={-1}
|
||||
/>
|
||||
</Memo(Avatar)>
|
||||
<Memo(StatusIcon)
|
||||
status="offline"
|
||||
>
|
||||
<StatusOfflineIcon
|
||||
className="status "
|
||||
>
|
||||
<span
|
||||
className="status "
|
||||
>
|
||||
<svg
|
||||
aria-label="Offline Icon"
|
||||
className="offline--icon"
|
||||
height="100%"
|
||||
role="img"
|
||||
style={
|
||||
Object {
|
||||
"clipRule": "evenodd",
|
||||
"fillRule": "evenodd",
|
||||
"strokeLinejoin": "round",
|
||||
"strokeMiterlimit": 1.41421,
|
||||
}
|
||||
}
|
||||
viewBox="0 0 20 20"
|
||||
width="100%"
|
||||
>
|
||||
<path
|
||||
d="M10,0c5.519,0 10,4.481 10,10c0,5.519 -4.481,10 -10,10c-5.519,0 -10,-4.481 -10,-10c0,-5.519 4.481,-10 10,-10Zm0,2c4.415,0 8,3.585 8,8c0,4.415 -3.585,8 -8,8c-4.415,0 -8,-3.585 -8,-8c0,-4.415 3.585,-8 8,-8Z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</StatusOfflineIcon>
|
||||
</Memo(StatusIcon)>
|
||||
</span>
|
||||
<Username
|
||||
className="overflow--ellipsis text-nowrap"
|
||||
>
|
||||
@@ -817,24 +889,60 @@ exports[`component/user_group_popover/group_member_list should match snapshot 1`
|
||||
>
|
||||
<UserButton>
|
||||
<button
|
||||
className="UserButton-bZNeGd lLsMM"
|
||||
className="UserButton-bZNeGd gDRhSF"
|
||||
>
|
||||
<Memo(Avatar)
|
||||
className="avatar-post-preview"
|
||||
size="sm"
|
||||
tabIndex={-1}
|
||||
url="/api/v4/users/id2/image?_=0"
|
||||
username="username2"
|
||||
<span
|
||||
className="status-wrapper"
|
||||
>
|
||||
<img
|
||||
alt="username2 profile image"
|
||||
className="Avatar Avatar-sm avatar-post-preview"
|
||||
loading="lazy"
|
||||
onError={[Function]}
|
||||
src="/api/v4/users/id2/image?_=0"
|
||||
<Memo(Avatar)
|
||||
className="avatar-post-preview"
|
||||
size="sm"
|
||||
tabIndex={-1}
|
||||
/>
|
||||
</Memo(Avatar)>
|
||||
url="/api/v4/users/id2/image?_=0"
|
||||
username="username2"
|
||||
>
|
||||
<img
|
||||
alt="username2 profile image"
|
||||
className="Avatar Avatar-sm avatar-post-preview"
|
||||
loading="lazy"
|
||||
onError={[Function]}
|
||||
src="/api/v4/users/id2/image?_=0"
|
||||
tabIndex={-1}
|
||||
/>
|
||||
</Memo(Avatar)>
|
||||
<Memo(StatusIcon)
|
||||
status="offline"
|
||||
>
|
||||
<StatusOfflineIcon
|
||||
className="status "
|
||||
>
|
||||
<span
|
||||
className="status "
|
||||
>
|
||||
<svg
|
||||
aria-label="Offline Icon"
|
||||
className="offline--icon"
|
||||
height="100%"
|
||||
role="img"
|
||||
style={
|
||||
Object {
|
||||
"clipRule": "evenodd",
|
||||
"fillRule": "evenodd",
|
||||
"strokeLinejoin": "round",
|
||||
"strokeMiterlimit": 1.41421,
|
||||
}
|
||||
}
|
||||
viewBox="0 0 20 20"
|
||||
width="100%"
|
||||
>
|
||||
<path
|
||||
d="M10,0c5.519,0 10,4.481 10,10c0,5.519 -4.481,10 -10,10c-5.519,0 -10,-4.481 -10,-10c0,-5.519 4.481,-10 10,-10Zm0,2c4.415,0 8,3.585 8,8c0,4.415 -3.585,8 -8,8c-4.415,0 -8,-3.585 -8,-8c0,-4.415 3.585,-8 8,-8Z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</StatusOfflineIcon>
|
||||
</Memo(StatusIcon)>
|
||||
</span>
|
||||
<Username
|
||||
className="overflow--ellipsis text-nowrap"
|
||||
>
|
||||
@@ -1025,24 +1133,60 @@ exports[`component/user_group_popover/group_member_list should match snapshot 1`
|
||||
>
|
||||
<UserButton>
|
||||
<button
|
||||
className="UserButton-bZNeGd lLsMM"
|
||||
className="UserButton-bZNeGd gDRhSF"
|
||||
>
|
||||
<Memo(Avatar)
|
||||
className="avatar-post-preview"
|
||||
size="sm"
|
||||
tabIndex={-1}
|
||||
url="/api/v4/users/id3/image?_=0"
|
||||
username="username3"
|
||||
<span
|
||||
className="status-wrapper"
|
||||
>
|
||||
<img
|
||||
alt="username3 profile image"
|
||||
className="Avatar Avatar-sm avatar-post-preview"
|
||||
loading="lazy"
|
||||
onError={[Function]}
|
||||
src="/api/v4/users/id3/image?_=0"
|
||||
<Memo(Avatar)
|
||||
className="avatar-post-preview"
|
||||
size="sm"
|
||||
tabIndex={-1}
|
||||
/>
|
||||
</Memo(Avatar)>
|
||||
url="/api/v4/users/id3/image?_=0"
|
||||
username="username3"
|
||||
>
|
||||
<img
|
||||
alt="username3 profile image"
|
||||
className="Avatar Avatar-sm avatar-post-preview"
|
||||
loading="lazy"
|
||||
onError={[Function]}
|
||||
src="/api/v4/users/id3/image?_=0"
|
||||
tabIndex={-1}
|
||||
/>
|
||||
</Memo(Avatar)>
|
||||
<Memo(StatusIcon)
|
||||
status="offline"
|
||||
>
|
||||
<StatusOfflineIcon
|
||||
className="status "
|
||||
>
|
||||
<span
|
||||
className="status "
|
||||
>
|
||||
<svg
|
||||
aria-label="Offline Icon"
|
||||
className="offline--icon"
|
||||
height="100%"
|
||||
role="img"
|
||||
style={
|
||||
Object {
|
||||
"clipRule": "evenodd",
|
||||
"fillRule": "evenodd",
|
||||
"strokeLinejoin": "round",
|
||||
"strokeMiterlimit": 1.41421,
|
||||
}
|
||||
}
|
||||
viewBox="0 0 20 20"
|
||||
width="100%"
|
||||
>
|
||||
<path
|
||||
d="M10,0c5.519,0 10,4.481 10,10c0,5.519 -4.481,10 -10,10c-5.519,0 -10,-4.481 -10,-10c0,-5.519 4.481,-10 10,-10Zm0,2c4.415,0 8,3.585 8,8c0,4.415 -3.585,8 -8,8c-4.415,0 -8,-3.585 -8,-8c0,-4.415 3.585,-8 8,-8Z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</StatusOfflineIcon>
|
||||
</Memo(StatusIcon)>
|
||||
</span>
|
||||
<Username
|
||||
className="overflow--ellipsis text-nowrap"
|
||||
>
|
||||
@@ -1233,24 +1377,60 @@ exports[`component/user_group_popover/group_member_list should match snapshot 1`
|
||||
>
|
||||
<UserButton>
|
||||
<button
|
||||
className="UserButton-bZNeGd lLsMM"
|
||||
className="UserButton-bZNeGd gDRhSF"
|
||||
>
|
||||
<Memo(Avatar)
|
||||
className="avatar-post-preview"
|
||||
size="sm"
|
||||
tabIndex={-1}
|
||||
url="/api/v4/users/id4/image?_=0"
|
||||
username="username4"
|
||||
<span
|
||||
className="status-wrapper"
|
||||
>
|
||||
<img
|
||||
alt="username4 profile image"
|
||||
className="Avatar Avatar-sm avatar-post-preview"
|
||||
loading="lazy"
|
||||
onError={[Function]}
|
||||
src="/api/v4/users/id4/image?_=0"
|
||||
<Memo(Avatar)
|
||||
className="avatar-post-preview"
|
||||
size="sm"
|
||||
tabIndex={-1}
|
||||
/>
|
||||
</Memo(Avatar)>
|
||||
url="/api/v4/users/id4/image?_=0"
|
||||
username="username4"
|
||||
>
|
||||
<img
|
||||
alt="username4 profile image"
|
||||
className="Avatar Avatar-sm avatar-post-preview"
|
||||
loading="lazy"
|
||||
onError={[Function]}
|
||||
src="/api/v4/users/id4/image?_=0"
|
||||
tabIndex={-1}
|
||||
/>
|
||||
</Memo(Avatar)>
|
||||
<Memo(StatusIcon)
|
||||
status="offline"
|
||||
>
|
||||
<StatusOfflineIcon
|
||||
className="status "
|
||||
>
|
||||
<span
|
||||
className="status "
|
||||
>
|
||||
<svg
|
||||
aria-label="Offline Icon"
|
||||
className="offline--icon"
|
||||
height="100%"
|
||||
role="img"
|
||||
style={
|
||||
Object {
|
||||
"clipRule": "evenodd",
|
||||
"fillRule": "evenodd",
|
||||
"strokeLinejoin": "round",
|
||||
"strokeMiterlimit": 1.41421,
|
||||
}
|
||||
}
|
||||
viewBox="0 0 20 20"
|
||||
width="100%"
|
||||
>
|
||||
<path
|
||||
d="M10,0c5.519,0 10,4.481 10,10c0,5.519 -4.481,10 -10,10c-5.519,0 -10,-4.481 -10,-10c0,-5.519 4.481,-10 10,-10Zm0,2c4.415,0 8,3.585 8,8c0,4.415 -3.585,8 -8,8c-4.415,0 -8,-3.585 -8,-8c0,-4.415 3.585,-8 8,-8Z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</StatusOfflineIcon>
|
||||
</Memo(StatusIcon)>
|
||||
</span>
|
||||
<Username
|
||||
className="overflow--ellipsis text-nowrap"
|
||||
>
|
||||
|
||||
@@ -6,6 +6,9 @@ import React from 'react';
|
||||
import {Provider} from 'react-redux';
|
||||
import {BrowserRouter} from 'react-router-dom';
|
||||
|
||||
import type {Group} from '@mattermost/types/groups';
|
||||
import type {UserProfile} from '@mattermost/types/users';
|
||||
|
||||
import {General} from 'mattermost-redux/constants';
|
||||
import {displayUsername} from 'mattermost-redux/utils/user_utils';
|
||||
|
||||
@@ -40,6 +43,10 @@ const actImmediate = (wrapper: ReactWrapper) =>
|
||||
);
|
||||
|
||||
describe('component/user_group_popover/group_member_list', () => {
|
||||
const profiles: Record<string, UserProfile> = {};
|
||||
const profilesInGroup: Record<Group['id'], Set<UserProfile['id']>> = {};
|
||||
const statuses: Record<UserProfile['id'], string> = {};
|
||||
|
||||
const group = TestHelper.getGroupMock({
|
||||
member_count: 5,
|
||||
});
|
||||
@@ -58,6 +65,39 @@ describe('component/user_group_popover/group_member_list', () => {
|
||||
members.push({user, displayName});
|
||||
}
|
||||
|
||||
const initialState = {
|
||||
entities: {
|
||||
teams: {
|
||||
currentTeamId: 'team_id1',
|
||||
teams: {
|
||||
team_id1: {
|
||||
id: 'team_id1',
|
||||
name: 'team1',
|
||||
},
|
||||
},
|
||||
},
|
||||
general: {
|
||||
config: {},
|
||||
},
|
||||
users: {
|
||||
profiles,
|
||||
profilesInGroup,
|
||||
statuses,
|
||||
},
|
||||
preferences: {
|
||||
myPreferences: {},
|
||||
},
|
||||
},
|
||||
views: {
|
||||
modals: {
|
||||
modalState: {},
|
||||
},
|
||||
search: {
|
||||
popoverSearch: '',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const baseProps = {
|
||||
searchTerm: '',
|
||||
group,
|
||||
@@ -75,7 +115,7 @@ describe('component/user_group_popover/group_member_list', () => {
|
||||
};
|
||||
|
||||
test('should match snapshot', async () => {
|
||||
const store = await mockStore({});
|
||||
const store = await mockStore(initialState);
|
||||
const wrapper = mountWithIntl(
|
||||
<Provider store={store}>
|
||||
<BrowserRouter>
|
||||
@@ -91,7 +131,7 @@ describe('component/user_group_popover/group_member_list', () => {
|
||||
});
|
||||
|
||||
test('should open dms', async () => {
|
||||
const store = await mockStore({});
|
||||
const store = await mockStore(initialState);
|
||||
const wrapper = mountWithIntl(
|
||||
<Provider store={store}>
|
||||
<BrowserRouter>
|
||||
@@ -108,7 +148,7 @@ describe('component/user_group_popover/group_member_list', () => {
|
||||
});
|
||||
|
||||
test('should show user overlay and hide', async () => {
|
||||
const store = await mockStore({});
|
||||
const store = await mockStore(initialState);
|
||||
const wrapper = mountWithIntl(
|
||||
<Provider store={store}>
|
||||
<BrowserRouter>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
import React, {useEffect, useState, useRef} from 'react';
|
||||
import {useIntl} from 'react-intl';
|
||||
import {useSelector} from 'react-redux';
|
||||
import {useHistory} from 'react-router-dom';
|
||||
import AutoSizer from 'react-virtualized-auto-sizer';
|
||||
import {VariableSizeList} from 'react-window';
|
||||
@@ -13,17 +14,22 @@ import styled, {css} from 'styled-components';
|
||||
import type {Group} from '@mattermost/types/groups';
|
||||
import type {UserProfile} from '@mattermost/types/users';
|
||||
|
||||
import {getStatusForUserId} from 'mattermost-redux/selectors/entities/users';
|
||||
import type {ActionResult} from 'mattermost-redux/types/actions';
|
||||
|
||||
import NoResultsIndicator from 'components/no_results_indicator';
|
||||
import {NoResultsVariant} from 'components/no_results_indicator/types';
|
||||
import ProfilePopover from 'components/profile_popover';
|
||||
import StatusIcon from 'components/status_icon';
|
||||
import LoadingSpinner from 'components/widgets/loading/loading_spinner';
|
||||
import Avatar from 'components/widgets/users/avatar';
|
||||
import WithTooltip from 'components/with_tooltip';
|
||||
|
||||
import {UserStatuses} from 'utils/constants';
|
||||
import * as Utils from 'utils/utils';
|
||||
|
||||
import type {GlobalState} from 'types/store';
|
||||
|
||||
import {Load} from '../constants';
|
||||
|
||||
const USERS_PER_PAGE = 100;
|
||||
@@ -149,6 +155,8 @@ const GroupMemberList = (props: Props) => {
|
||||
};
|
||||
|
||||
const Item = ({index, style}: ListChildComponentProps) => {
|
||||
const status = useSelector((state: GlobalState) => getStatusForUserId(state, members[index]?.user?.id) || UserStatuses.OFFLINE);
|
||||
|
||||
// Remove explicit height provided by VariableSizeList
|
||||
style.height = undefined;
|
||||
|
||||
@@ -171,13 +179,18 @@ const GroupMemberList = (props: Props) => {
|
||||
hideStatus={user.is_bot}
|
||||
>
|
||||
<UserButton>
|
||||
<Avatar
|
||||
username={user.username}
|
||||
size={'sm'}
|
||||
url={Utils.imageURLForUser(user?.id ?? '')}
|
||||
className={'avatar-post-preview'}
|
||||
tabIndex={-1}
|
||||
/>
|
||||
<span className='status-wrapper'>
|
||||
<Avatar
|
||||
username={user.username}
|
||||
size={'sm'}
|
||||
url={Utils.imageURLForUser(user?.id ?? '')}
|
||||
className={'avatar-post-preview'}
|
||||
tabIndex={-1}
|
||||
/>
|
||||
<StatusIcon
|
||||
status={status}
|
||||
/>
|
||||
</span>
|
||||
<Username className='overflow--ellipsis text-nowrap'>{name}</Username>
|
||||
<Gap className='group-member-list_gap'/>
|
||||
</UserButton>
|
||||
@@ -332,10 +345,11 @@ const UserListItem = styled.div<{first?: boolean; last?: boolean}>`
|
||||
const UserButton = styled.button`
|
||||
display: flex;
|
||||
width: 100%;
|
||||
padding: 8px 20px;
|
||||
padding: 5px 20px;
|
||||
border: none;
|
||||
background: unset;
|
||||
text-align: unset;
|
||||
align-items: center;
|
||||
`;
|
||||
|
||||
// A gap to make space for the DM button to be positioned on
|
||||
|
||||
@@ -40,6 +40,7 @@ const actImmediate = (wrapper: ReactWrapper) =>
|
||||
describe('component/user_group_popover', () => {
|
||||
const profiles: Record<string, UserProfile> = {};
|
||||
const profilesInGroup: Record<Group['id'], Set<UserProfile['id']>> = {};
|
||||
const statuses: Record<UserProfile['id'], string> = {};
|
||||
|
||||
const group1 = TestHelper.getGroupMock({
|
||||
id: 'group1',
|
||||
@@ -86,6 +87,7 @@ describe('component/user_group_popover', () => {
|
||||
users: {
|
||||
profiles,
|
||||
profilesInGroup,
|
||||
statuses,
|
||||
},
|
||||
preferences: {
|
||||
myPreferences: {},
|
||||
|
||||
@@ -2,17 +2,23 @@
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React, {useCallback} from 'react';
|
||||
import {useSelector} from 'react-redux';
|
||||
|
||||
import {GroupSource} from '@mattermost/types/groups';
|
||||
import type {Group} from '@mattermost/types/groups';
|
||||
import type {UserProfile} from '@mattermost/types/users';
|
||||
|
||||
import {getStatusForUserId} from 'mattermost-redux/selectors/entities/users';
|
||||
import type {ActionResult} from 'mattermost-redux/types/actions';
|
||||
|
||||
import StatusIcon from 'components/status_icon';
|
||||
import Avatar from 'components/widgets/users/avatar';
|
||||
|
||||
import {UserStatuses} from 'utils/constants';
|
||||
import * as Utils from 'utils/utils';
|
||||
|
||||
import type {GlobalState} from 'types/store';
|
||||
|
||||
export type Props = {
|
||||
groupId: string;
|
||||
user: UserProfile;
|
||||
@@ -41,19 +47,25 @@ const ViewUserGroupListItem = (props: Props) => {
|
||||
});
|
||||
}, [user.id, groupId, props.decrementMemberCount, props.actions.removeUsersFromGroup]);
|
||||
|
||||
const status = useSelector((state: GlobalState) => getStatusForUserId(state, user?.id) || UserStatuses.OFFLINE);
|
||||
|
||||
return (
|
||||
<div
|
||||
key={user.id}
|
||||
className='group-member-row'
|
||||
>
|
||||
<>
|
||||
<span className='status-wrapper'>
|
||||
|
||||
<Avatar
|
||||
username={user.username}
|
||||
size={'sm'}
|
||||
url={Utils.imageURLForUser(user?.id ?? '')}
|
||||
className={'avatar-post-preview'}
|
||||
/>
|
||||
</>
|
||||
<StatusIcon
|
||||
status={status}
|
||||
/>
|
||||
</span>
|
||||
<div className='group-member-name'>
|
||||
{Utils.getFullName(user)}
|
||||
</div>
|
||||
|
||||
Ссылка в новой задаче
Block a user