Skip to content

Commit

Permalink
EPMRPP-91927 || Update "All users" page at instance level (#4140)
Browse files Browse the repository at this point in the history
* Feat: add the main files

* fix: add export line to index.js

* feat: add buttons

* feat: add pagination

* feat: add the you tag

* refactor: reuse messages

* feat: add new endpoint, remove unused element

* feat: add changes in the localization file after running "manage translations"

* EPMRPP-91927 || Code review fixes - 1

* EPMRPP-91927 || Code review fixes - 2

* refactor: refactor the code

* refactor: delete unused files

* EPMRPP-91927 || Code review fixes - 3

* EPMRPP-91927 || Code review fixes - 4
  • Loading branch information
iso9000t authored Dec 23, 2024
1 parent 301ab54 commit 1fc554a
Show file tree
Hide file tree
Showing 48 changed files with 888 additions and 4,024 deletions.
277 changes: 42 additions & 235 deletions app/localization/translated/be.json

Large diffs are not rendered by default.

322 changes: 67 additions & 255 deletions app/localization/translated/es.json

Large diffs are not rendered by default.

269 changes: 39 additions & 230 deletions app/localization/translated/ru.json

Large diffs are not rendered by default.

273 changes: 40 additions & 233 deletions app/localization/translated/uk.json

Large diffs are not rendered by default.

271 changes: 39 additions & 232 deletions app/localization/translated/zh.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions app/src/common/urls.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export const URLS = {
dataPhoto: (at, loadThumbnail) => `${urlBase}data/photo${getQueryParams({ at, loadThumbnail })}`,
dataUserPhoto: (projectKey, login, loadThumbnail) =>
`${urlBase}data/${projectKey}/userphoto${getQueryParams({ login, loadThumbnail })}`,
userAvatar: (userId) => `${urlCommonBase}users/${userId}/avatar`,

dashboard: (projectKey, id) => `${urlBase}${projectKey}/dashboard/${id}`,
dashboards: (projectKey, params) =>
Expand Down
3 changes: 2 additions & 1 deletion app/src/controllers/instance/allUsers/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import { DEFAULT_PAGINATION } from 'controllers/pagination';
import { createQueryParametersSelector } from 'controllers/pages';
import { createSelectedItemsSelector } from 'controllers/groupOperations';
import { DEFAULT_SORTING } from './constants';
import { DEFAULT_SORTING, NAMESPACE } from './constants';
import { administrateDomainSelector } from '../selectors';

const domainSelector = (state) => administrateDomainSelector(state).allUsers || {};
Expand All @@ -32,4 +32,5 @@ export const selectedUsersSelector = createSelectedItemsSelector(groupOperations
export const querySelector = createQueryParametersSelector({
defaultPagination: DEFAULT_PAGINATION,
defaultSorting: DEFAULT_SORTING,
namespace: NAMESPACE,
});
76 changes: 76 additions & 0 deletions app/src/pages/common/membersPage/userNameCell/userNameCell.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Copyright 2024 EPAM Systems
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import PropTypes from 'prop-types';
import { useIntl } from 'react-intl';
import classNames from 'classnames/bind';
import { Tooltip } from '@reportportal/ui-kit';
import { ADMIN_TYPE } from 'common/utils/permissions/constants';
import { messages } from 'pages/common/users/membersListTable/messages';
import styles from './userNameCell.scss';

const cx = classNames.bind(styles);

export const UserNameCell = ({ user, badges, userAvatar: UserAvatar }) => {
const { formatMessage } = useIntl();

return (
<div className={cx('user-name-cell')}>
<UserAvatar className={cx('user-avatar')} userId={user.id} />
<div className={cx('full-name')}>{user.fullName}</div>
<div className={cx('badges')}>
{badges.map(({ title, type }) => {
const badgeContent = (
<div key={`${user.id}-${type}`} className={cx('badge', type)}>
{formatMessage(title)}
</div>
);

return type === ADMIN_TYPE ? (
<Tooltip
key={`${user.id}-${type}-tooltip`}
content={formatMessage(messages.adminAccessInfo)}
placement="top"
width={248}
>
{badgeContent}
</Tooltip>
) : (
badgeContent
);
})}
</div>
</div>
);
};

UserNameCell.propTypes = {
user: PropTypes.shape({
id: PropTypes.string.isRequired,
fullName: PropTypes.string.isRequired,
}).isRequired,
badges: PropTypes.arrayOf(
PropTypes.shape({
title: PropTypes.object.isRequired,
type: PropTypes.string.isRequired,
}),
),
userAvatar: PropTypes.elementType.isRequired,
};

UserNameCell.defaultProps = {
badges: [],
};
64 changes: 64 additions & 0 deletions app/src/pages/common/membersPage/userNameCell/userNameCell.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* Copyright 2024 EPAM Systems
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

.user-name-cell {
display: flex;
align-items: center;

.user-avatar {
width: 32px;
height: 32px;

img {
border-radius: 50%;
}
}

.full-name {
margin-left: 16px;
}

.badges {
display: flex;
align-items: center;
margin-left: 16px;
gap: 8px;

.badge {
display: inline-flex;
justify-content: center;
align-items: center;
padding: 2px 8px;
border-radius: 6px;
color: $COLOR--white-two;
font-family: $FONT-ROBOTO-BOLD;
font-size: 11px;
line-height: 16px;

&.admin {
background-color: $COLOR--tag-value-text;
}

&.manager {
background-color: $COLOR--test-execution-status-passed;
}

&.you {
background-color: $COLOR--topaz-focused;
}
}
}
}
1 change: 1 addition & 0 deletions app/src/pages/inside/common/userAvatar/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@
*/

export { UserAvatar } from './userAvatar';
export { UserAvatarWithNewApi } from './userAvatarWithNewApi';
32 changes: 19 additions & 13 deletions app/src/pages/inside/common/userAvatar/userAvatar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,25 +24,31 @@ import styles from './userAvatar.scss';

const cx = classNames.bind(styles);

export const UserAvatar = ({ className, projectKey, userId }) => (
<div className={cx('user-avatar', className)}>
<Image
className={cx('avatar')}
src={URLS.dataUserPhoto(projectKey, userId, true)}
alt="avatar"
fallback={DefaultUserImage}
preloaderColor="charcoal"
/>
</div>
);
export const UserAvatar = ({ className, userId, projectKey, isNewApi }) => {
const src = isNewApi ? URLS.userAvatar(userId) : URLS.dataUserPhoto(projectKey, userId, true);

return (
<div className={cx('user-avatar', className)}>
<Image
className={cx('avatar')}
src={src}
alt="avatar"
fallback={DefaultUserImage}
preloaderColor="charcoal"
/>
</div>
);
};

UserAvatar.propTypes = {
className: PropTypes.string,
userId: PropTypes.string.isRequired,
projectKey: PropTypes.string,
userId: PropTypes.string,
isNewApi: PropTypes.bool,
};

UserAvatar.defaultProps = {
className: '',
projectKey: '',
userId: '',
isNewApi: false,
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*!
* Copyright 2019 EPAM Systems
* Copyright 2024 EPAM Systems
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -14,10 +14,6 @@
* limitations under the License.
*/

.generate-password-link {
font-size: 13px;
color: $COLOR--topaz;
position: absolute;
bottom: 75px;
cursor: pointer;
}
import { UserAvatar } from './userAvatar';

export const UserAvatarWithNewApi = (props) => <UserAvatar {...props} isNewApi />;
Loading

0 comments on commit 1fc554a

Please sign in to comment.