Skip to content

Commit 29f21d6

Browse files
committed
Compacting admin lists in group tree view where there are more than 2 admins per group.
1 parent 9714169 commit 29f21d6

File tree

5 files changed

+54
-21
lines changed

5 files changed

+54
-21
lines changed

src/components/Groups/GroupsTree/GroupsTreeNode.js

Lines changed: 44 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import Icon, { GroupIcon, GroupExamsIcon, LoadingIcon } from '../../icons';
1111
import withLinks from '../../../helpers/withLinks.js';
1212
import { isRegularObject } from '../../../helpers/common.js';
1313
import { isExam } from '../../../helpers/groups.js';
14+
import { OverlayTrigger, Popover } from 'react-bootstrap';
1415

1516
/**
1617
* Assemble the right CSS classes for the list item.
@@ -30,7 +31,22 @@ const prepareClassList = lruMemoize((clickable, archived) => {
3031

3132
const DEFAULT_ICON = ['far', 'square'];
3233

33-
const clickEventDisipator = ev => ev.stopPropagation();
34+
const clickEventDissipator = ev => ev.stopPropagation();
35+
36+
const adminsList = (primaryAdmins, autoloadAuthors, simpleClassName = '') =>
37+
primaryAdmins.map(admin => (
38+
<React.Fragment key={isRegularObject(admin) ? admin.id : admin}>
39+
{isRegularObject(admin) ? (
40+
<span className={`${simpleClassName} simpleName text-nowrap`}>
41+
{admin.firstName} {admin.lastName}
42+
</span>
43+
) : autoloadAuthors ? (
44+
<UsersNameContainer userId={admin} isSimple simpleClassName={simpleClassName} />
45+
) : (
46+
<LoadingIcon />
47+
)}
48+
</React.Fragment>
49+
));
3450

3551
const GroupsTreeNode = React.memo(
3652
({ group, selectedGroupId = null, autoloadAuthors = false, isExpanded = false, buttonsCreator, links }) => {
@@ -69,21 +85,32 @@ const GroupsTreeNode = React.memo(
6985
{primaryAdmins && primaryAdmins.length > 0 && (
7086
<span className="ps-2">
7187
(
72-
<em className="small">
73-
{primaryAdmins.map(admin => (
74-
<React.Fragment key={isRegularObject(admin) ? admin.id : admin}>
75-
{isRegularObject(admin) ? (
76-
<span className="simpleName text-nowrap">
77-
{admin.firstName} {admin.lastName}
78-
</span>
79-
) : autoloadAuthors ? (
80-
<UsersNameContainer userId={admin} isSimple />
81-
) : (
82-
<LoadingIcon />
83-
)}
84-
</React.Fragment>
85-
))}
86-
</em>
88+
{primaryAdmins.length > 2 ? (
89+
<OverlayTrigger
90+
placement="bottom"
91+
overlay={
92+
<Popover id={`admins-${id}`}>
93+
<Popover.Header>
94+
<FormattedMessage
95+
id="app.groupTree.treeViewLeaf.adminPopover.title"
96+
defaultMessage="Group administrators"
97+
/>
98+
:
99+
</Popover.Header>
100+
<Popover.Body>{adminsList(primaryAdmins, autoloadAuthors, 'd-block')}</Popover.Body>
101+
</Popover>
102+
}>
103+
<em className="small">
104+
<FormattedMessage
105+
id="app.groupTree.treeViewLeaf.adminsCount"
106+
defaultMessage="{count} {count, plural, one {admin} other {admins}}"
107+
values={{ count: primaryAdmins.length }}
108+
/>
109+
</em>
110+
</OverlayTrigger>
111+
) : (
112+
<em className="small">{adminsList(primaryAdmins, autoloadAuthors)}</em>
113+
)}
87114
)
88115
</span>
89116
)}
@@ -156,7 +183,7 @@ const GroupsTreeNode = React.memo(
156183
)}
157184

158185
{buttonsCreator && (
159-
<span className="float-end" onClick={clickEventDisipator}>
186+
<span className="float-end" onClick={clickEventDissipator}>
160187
{buttonsCreator(group, selectedGroupId, links)}
161188
</span>
162189
)}

src/containers/GroupsTreeContainer/GroupsTreeContainer.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ const prepareGroupObject = (
6868
};
6969

7070
/**
71-
* Prepares plain-js datastructure that could be fed to GroupsTree component.
71+
* Prepares plain-js data structure that could be fed to GroupsTree component.
7272
* With memoization, this is basically a higher-level selector that creates hiarchial augmented group objects.
7373
*/
7474
const prepareGroupsTree = lruMemoize(

src/containers/UsersNameContainer/UsersNameContainer.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class UsersNameContainer extends Component {
3232
noAvatar = false,
3333
currentUser,
3434
isSimple = false,
35+
simpleClassName = '',
3536
showEmail = null,
3637
showExternalIdentifiers = false,
3738
showRoleIcon = false,
@@ -45,7 +46,7 @@ class UsersNameContainer extends Component {
4546
failed={isSimple ? <FailureIcon /> : <FailedUsersName size={size} />}>
4647
{(user, currentUser) =>
4748
isSimple ? (
48-
<span className="simpleName text-nowrap">
49+
<span className={`${simpleClassName} simpleName text-nowrap`}>
4950
{user.name.firstName} {user.name.lastName}
5051
</span>
5152
) : (
@@ -76,6 +77,7 @@ UsersNameContainer.propTypes = {
7677
link: PropTypes.oneOfType([PropTypes.string, PropTypes.func, PropTypes.bool]),
7778
noAvatar: PropTypes.bool,
7879
isSimple: PropTypes.bool,
80+
simpleClassName: PropTypes.string,
7981
showEmail: PropTypes.string,
8082
showExternalIdentifiers: PropTypes.bool,
8183
showRoleIcon: PropTypes.bool,

src/locales/cs.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1128,6 +1128,8 @@
11281128
"app.groupStudents.privateStats": "Administrátor skupiny omezil přístup k výsledkům studentů. Z toho důvodu můžete vidět pouze vlastní výsledky, nikoli výsledky ostatních studentů.",
11291129
"app.groupStudents.studentsResultsTable": "Studenti a jejich výsledky",
11301130
"app.groupStudents.title": "Studenti ve skupině",
1131+
"app.groupTree.treeViewLeaf.adminPopover.title": "Administrátoři skupiny",
1132+
"app.groupTree.treeViewLeaf.adminsCount": "{count} {count, plural, one {administrátor} =2 {administrátoři} =3 {administrátoři} =4 {administrátoři} other {administrátorů}}",
11311133
"app.groupTree.treeViewLeaf.archivedTooltip": "Tato skupina byla odsunuta do archivu",
11321134
"app.groupTree.treeViewLeaf.examTooltip": "Zkoušková skupina",
11331135
"app.groupTree.treeViewLeaf.organizationalTooltip": "Skupina je organizační (nemá žádné studenty ani zadané úlohy)",
@@ -2126,4 +2128,4 @@
21262128
"recodex-judge-shuffle-all": "Sudí neuspořádaných tokenů a řádků",
21272129
"recodex-judge-shuffle-newline": "Sudí neuspořádaných tokenů (ignorující konce řádků)",
21282130
"recodex-judge-shuffle-rows": "Sudí neuspořádaných řádků"
2129-
}
2131+
}

src/locales/en.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1128,6 +1128,8 @@
11281128
"app.groupStudents.privateStats": "The admin of the group has restricted the access to the results of students. Therefore, you can see only your own results, not the results of other students.",
11291129
"app.groupStudents.studentsResultsTable": "Students and Their Results",
11301130
"app.groupStudents.title": "Group Students",
1131+
"app.groupTree.treeViewLeaf.adminPopover.title": "Group administrators",
1132+
"app.groupTree.treeViewLeaf.adminsCount": "{count} {count, plural, one {admin} other {admins}}",
11311133
"app.groupTree.treeViewLeaf.archivedTooltip": "The group is archived",
11321134
"app.groupTree.treeViewLeaf.examTooltip": "Exam group",
11331135
"app.groupTree.treeViewLeaf.organizationalTooltip": "The group is organizational (it does not have any students or assignments)",
@@ -2126,4 +2128,4 @@
21262128
"recodex-judge-shuffle-all": "Unordered-tokens-and-rows judge",
21272129
"recodex-judge-shuffle-newline": "Unordered-tokens judge (ignoring ends of lines)",
21282130
"recodex-judge-shuffle-rows": "Unordered-rows judge"
2129-
}
2131+
}

0 commit comments

Comments
 (0)