Skip to content

Commit

Permalink
Fix masterdesk users view (#4282)
Browse files Browse the repository at this point in the history
  • Loading branch information
thecalcc authored Jul 4, 2023
1 parent 092c48c commit dd59331
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 73 deletions.
85 changes: 44 additions & 41 deletions scripts/apps/master-desk/components/UserListComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import classNames from 'classnames';

import {UserAvatar} from 'apps/users/components/UserAvatar';
import {IDesk, IUserRole, IUser} from 'superdesk-api';
import {gettext} from 'core/utils';

export interface IUserExtra {
user: IUser;
Expand All @@ -14,12 +15,12 @@ export interface IUserExtra {

interface IProps {
desk: IDesk;
role: IUserRole;
role?: IUserRole;
users: Array<IUserExtra>;
onUserSelect(user: IUser): void;
}

export class UserListComponent extends React.Component<IProps, {}> {
export class UserListComponent extends React.Component<IProps> {
constructor(props: IProps) {
super(props);

Expand All @@ -32,52 +33,54 @@ export class UserListComponent extends React.Component<IProps, {}> {

render() {
return (
this.props.users ? (
<React.Fragment>
<div className="sd-board__subheader">
<h5 className="sd-board__subheader-title">{this.props.role.name}</h5>
</div>
<ul className="sd-list-item-group sd-shadow--z2">
{this.props.users.map((user, index) => (
<li className="sd-list-item" key={index} onClick={() => this.selectUser(user)}>
<div className="sd-list-item__border" />
<div
className={classNames(
'sd-list-item__column',
'sd-list-item__column--no-border',
'sd-padding-x--0-5',
)}
>
<UserAvatar user={user.user} displayStatus={true} />
</div>
<div
className={classNames(
'sd-list-item__column',
'sd-list-item__column--grow',
'sd-list-item__column--no-border,',
)}
>
<div className="sd-list-item__row">
<span className="sd-overflow-ellipsis sd-list-item--element-grow">
{user.user.display_name}
</span>
{user.data.locked > 0 ? (
<>
<div className="sd-board__subheader">
<h5 className="sd-board__subheader-title">{this.props.role?.name ?? gettext('No role')}</h5>
</div>
<ul className="sd-list-item-group sd-shadow--z2">
{this.props.users.map((user, index) => (
<li className="sd-list-item" key={index} onClick={() => this.selectUser(user)}>
<div className="sd-list-item__border" />
<div
className={classNames(
'sd-list-item__column',
'sd-list-item__column--no-border',
'sd-padding-x--0-5',
)}
>
<UserAvatar user={user.user} displayStatus={true} />
</div>
<div
className={classNames(
'sd-list-item__column',
'sd-list-item__column--grow',
'sd-list-item__column--no-border,',
)}
>
<div className="sd-list-item__row">
<span className="sd-overflow-ellipsis sd-list-item--element-grow">
{user.user.display_name}
</span>
{
(user.data.locked ?? 0) > 0 && (
<span className="sd-text-icon sd-text-icon--aligned-r user-items--locked">
<i className="icon-lock" />{user.data.locked}
</span>
) : null}
{user.data.assigned > 0 ? (
)
}
{
(user.data.assigned ?? 0) > 0 && (
<span className="sd-text-icon sd-text-icon--aligned-r user-items--assigned">
<i className="icon-pick" />{user.data.assigned}
</span>
) : null}
</div>
)
}
</div>
</li>
))}
</ul>
</React.Fragment>
) : null
</div>
</li>
))}
</ul>
</>
);
}
}
107 changes: 75 additions & 32 deletions scripts/apps/master-desk/components/UsersComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {dataApi} from 'core/helpers/CrudManager';
import {IStoreState} from 'core/data';
import {IDesk, IUser, IUserRole} from 'superdesk-api';
import {UserListComponent, IUserExtra} from './UserListComponent';
import {partition} from 'lodash';

interface IProps {
desks: Array<IDesk>;
Expand All @@ -25,7 +26,8 @@ interface IUserByRole {

interface IState {
roles: Array<IUserRole>;
usersByRole: Array<IUserByRole>;
usersWithRole: Array<IUserByRole>;
usersWithoutRole: IUserByRole | undefined;
deskMembers: {[id: string]: Array<IUser['_id']>};
}

Expand All @@ -41,8 +43,9 @@ class UsersComponent extends React.Component<IProps, IState> {

this.state = {
roles: [],
usersByRole: [],
usersWithRole: [],
deskMembers,
usersWithoutRole: null,
};

this.selectUser.bind(this);
Expand All @@ -58,17 +61,21 @@ class UsersComponent extends React.Component<IProps, IState> {
dataApi.query('desks/all/overview/users', 1, {field: null, direction: 'ascending'}, {}),
]).then((res: any) => {
const [roles, users] = res;
const [withRole, withoutRole] = partition(users._items, (item) => item.role != null);

this.setState({
roles: roles._items,
usersByRole: users._items,
usersWithRole: withRole,

// we get the first element since users without role are always grouped in one object with `null` role
usersWithoutRole: withoutRole[0],
});
});
}

getUsers(desk: IDesk, role: IUserRole): Array<IUserExtra> {
const deskMembers = this.state.deskMembers[desk._id];
const roleUsers = this.state.usersByRole.find((item) => item.role === role._id);
const roleUsers = this.state.usersWithRole.find((item) => item.role === role._id);
const users: Array<IUserExtra> = [];

deskMembers.forEach((userId) => {
Expand All @@ -82,38 +89,74 @@ class UsersComponent extends React.Component<IProps, IState> {
return users;
}

getUsersWithoutRole(desk: IDesk): Array<IUserExtra> | null {
const deskMembers = this.state.deskMembers[desk._id];
const users: Array<IUserExtra> = [];

deskMembers.forEach((userId) => {
const user = this.props.usersById[userId];
const data = this.state.usersWithoutRole?.authors?.[user._id];

if (data != null) {
users.push({user, data});
}
});

return users;
}

render() {
return (
<div className="sd-kanban-list sd-pdding-x--2 sd-padding-t--2">
{this.props.desks.map((desk) => (
<div className="sd-board" key={desk._id}>
<div className="sd-board__header">
<h3 className="sd-board__header-title">{desk.name}</h3>
</div>
<div className="sd-board__content sd-padding-t--1">
{this.state.roles.map((role) => (
this.getUsers(desk, role).length ? (
<UserListComponent
key={role._id}
desk={desk}
role={role}
users={this.getUsers(desk, role)}
onUserSelect={(user) => this.selectUser(user)}
/>
) : null
))}

{!this.state.deskMembers[desk._id].length ? (
<div className="sd-board__subheader">
<h5 className="sd-board__subheader-title">
{gettext('There are no users assigned to this desk')}
</h5>
{
this.props.desks.map((desk) => {
const usersWithoutRole = this.getUsersWithoutRole(desk);

return (
<div className="sd-board" key={desk._id}>
<div className="sd-board__header">
<h3 className="sd-board__header-title">{desk.name}</h3>
</div>
<div className="sd-board__content sd-padding-t--1">
{
(usersWithoutRole?.length ?? 0) > 0 && (
<UserListComponent
key="no-role"
desk={desk}
users={usersWithoutRole}
onUserSelect={(user) => this.selectUser(user)}
/>
)
}
{
this.state.roles.map((role) => {
const users = this.getUsers(desk, role);

return users.length && (
<UserListComponent
key={role._id}
desk={desk}
role={role}
users={users}
onUserSelect={(user) => this.selectUser(user)}
/>
);
})
}
{
!this.state.deskMembers[desk._id].length && (
<div className="sd-board__subheader">
<h5 className="sd-board__subheader-title">
{gettext('There are no users assigned to this desk')}
</h5>
</div>
)
}
</div>
) : null}
</div>
</div>
),
)}
</div>
);
})
}
</div>
);
}
Expand Down

0 comments on commit dd59331

Please sign in to comment.