mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-09-03 06:03:12 +00:00
made consistent owner (#20576)
Co-authored-by: Chirag Madlani <12962843+chirag-madlani@users.noreply.github.com>
This commit is contained in:
parent
acd2926413
commit
2b8106e933
@ -47,7 +47,7 @@ import React, {
|
|||||||
useState,
|
useState,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { Link, useHistory } from 'react-router-dom';
|
||||||
import { ReactComponent as EditIcon } from '../../../../assets/svg/edit-new.svg';
|
import { ReactComponent as EditIcon } from '../../../../assets/svg/edit-new.svg';
|
||||||
import { ReactComponent as AssigneesIcon } from '../../../../assets/svg/ic-assignees.svg';
|
import { ReactComponent as AssigneesIcon } from '../../../../assets/svg/ic-assignees.svg';
|
||||||
import { ReactComponent as TaskCloseIcon } from '../../../../assets/svg/ic-close-task.svg';
|
import { ReactComponent as TaskCloseIcon } from '../../../../assets/svg/ic-close-task.svg';
|
||||||
@ -124,6 +124,7 @@ import {
|
|||||||
getEntityName,
|
getEntityName,
|
||||||
getEntityReferenceListFromEntities,
|
getEntityReferenceListFromEntities,
|
||||||
} from '../../../../utils/EntityUtils';
|
} from '../../../../utils/EntityUtils';
|
||||||
|
import { getUserPath } from '../../../../utils/RouterUtils';
|
||||||
import { UserAvatarGroup } from '../../../common/OwnerLabel/UserAvatarGroup.component';
|
import { UserAvatarGroup } from '../../../common/OwnerLabel/UserAvatarGroup.component';
|
||||||
import EntityPopOverCard from '../../../common/PopOverCard/EntityPopOverCard';
|
import EntityPopOverCard from '../../../common/PopOverCard/EntityPopOverCard';
|
||||||
import UserPopOverCard from '../../../common/PopOverCard/UserPopOverCard';
|
import UserPopOverCard from '../../../common/PopOverCard/UserPopOverCard';
|
||||||
@ -875,13 +876,21 @@ export const TaskTabNew = ({
|
|||||||
{t('label.created-by')}
|
{t('label.created-by')}
|
||||||
</Typography.Text>
|
</Typography.Text>
|
||||||
</Col>
|
</Col>
|
||||||
<Col className="flex items-center gap-2" span={16}>
|
<Col span={16}>
|
||||||
<UserPopOverCard userName={taskThread.createdBy ?? ''}>
|
<Link
|
||||||
<div className="d-flex items-center">
|
className="no-underline flex items-center gap-2"
|
||||||
<ProfilePicture name={taskThread.createdBy ?? ''} width="24" />
|
to={getUserPath(taskThread.createdBy ?? '')}>
|
||||||
</div>
|
<UserPopOverCard userName={taskThread.createdBy ?? ''}>
|
||||||
</UserPopOverCard>
|
<div className="d-flex items-center">
|
||||||
<Typography.Text>{taskThread.createdBy}</Typography.Text>
|
<ProfilePicture
|
||||||
|
name={taskThread.createdBy ?? ''}
|
||||||
|
width="24"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</UserPopOverCard>
|
||||||
|
|
||||||
|
<Typography.Text>{taskThread.createdBy}</Typography.Text>
|
||||||
|
</Link>
|
||||||
</Col>
|
</Col>
|
||||||
|
|
||||||
{isEditAssignee ? (
|
{isEditAssignee ? (
|
||||||
|
@ -57,7 +57,10 @@ export const OwnerItem: React.FC<OwnerItemProps> = ({
|
|||||||
}}>
|
}}>
|
||||||
{!isCompactView ? (
|
{!isCompactView ? (
|
||||||
<UserPopOverCard userName={owner.name ?? ''}>
|
<UserPopOverCard userName={owner.name ?? ''}>
|
||||||
<Link className="d-flex" data-testid="owner-link" to={ownerPath}>
|
<Link
|
||||||
|
className="d-flex no-underline"
|
||||||
|
data-testid="owner-link"
|
||||||
|
to={ownerPath}>
|
||||||
<OwnerAvatar
|
<OwnerAvatar
|
||||||
inheritedIcon={inheritedIcon}
|
inheritedIcon={inheritedIcon}
|
||||||
isCompactView={isCompactView}
|
isCompactView={isCompactView}
|
||||||
|
@ -16,8 +16,10 @@ import classNames from 'classnames';
|
|||||||
import { isEmpty } from 'lodash';
|
import { isEmpty } from 'lodash';
|
||||||
import React, { ReactNode, useMemo } from 'react';
|
import React, { ReactNode, useMemo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
import { ReactComponent as IconUser } from '../../../assets/svg/user.svg';
|
import { ReactComponent as IconUser } from '../../../assets/svg/user.svg';
|
||||||
import { EntityReference } from '../../../generated/entity/data/table';
|
import { EntityReference } from '../../../generated/entity/data/table';
|
||||||
|
import { getOwnerPath } from '../../../utils/ownerUtils';
|
||||||
import UserPopOverCard from '../PopOverCard/UserPopOverCard';
|
import UserPopOverCard from '../PopOverCard/UserPopOverCard';
|
||||||
import ProfilePicture from '../ProfilePicture/ProfilePicture';
|
import ProfilePicture from '../ProfilePicture/ProfilePicture';
|
||||||
import './owner-label.less';
|
import './owner-label.less';
|
||||||
@ -57,7 +59,9 @@ export const UserAvatarGroup = ({
|
|||||||
items: remainingOwners.map((owner) => ({
|
items: remainingOwners.map((owner) => ({
|
||||||
key: owner.id,
|
key: owner.id,
|
||||||
label: (
|
label: (
|
||||||
<div className="d-flex items-center gap-2">
|
<Link
|
||||||
|
className="d-flex items-center gap-2 no-underlines"
|
||||||
|
to={getOwnerPath(owner)}>
|
||||||
<UserPopOverCard userName={owner.displayName ?? ''}>
|
<UserPopOverCard userName={owner.displayName ?? ''}>
|
||||||
<div className="d-flex items-center">
|
<div className="d-flex items-center">
|
||||||
<ProfilePicture
|
<ProfilePicture
|
||||||
@ -67,8 +71,9 @@ export const UserAvatarGroup = ({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</UserPopOverCard>
|
</UserPopOverCard>
|
||||||
|
|
||||||
<Typography.Text>{owner.displayName}</Typography.Text>
|
<Typography.Text>{owner.displayName}</Typography.Text>
|
||||||
</div>
|
</Link>
|
||||||
),
|
),
|
||||||
})),
|
})),
|
||||||
};
|
};
|
||||||
|
@ -0,0 +1,142 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2022 Collate.
|
||||||
|
* 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 { Avatar, Tooltip } from 'antd';
|
||||||
|
import classNames from 'classnames';
|
||||||
|
import { parseInt } from 'lodash';
|
||||||
|
import { ImageShape } from 'Models';
|
||||||
|
import React, { useMemo } from 'react';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
import { usePermissionProvider } from '../../../context/PermissionProvider/PermissionProvider';
|
||||||
|
import { ResourceEntity } from '../../../context/PermissionProvider/PermissionProvider.interface';
|
||||||
|
import { User } from '../../../generated/entity/teams/user';
|
||||||
|
import { useUserProfile } from '../../../hooks/user-profile/useUserProfile';
|
||||||
|
import { getRandomColor } from '../../../utils/CommonUtils';
|
||||||
|
import { userPermissions } from '../../../utils/PermissionsUtils';
|
||||||
|
import { getUserPath } from '../../../utils/RouterUtils';
|
||||||
|
import Loader from '../Loader/Loader';
|
||||||
|
import UserPopOverCard from '../PopOverCard/UserPopOverCard';
|
||||||
|
|
||||||
|
type UserData = Pick<User, 'name' | 'displayName'>;
|
||||||
|
|
||||||
|
interface Props extends UserData {
|
||||||
|
width?: string;
|
||||||
|
type?: ImageShape;
|
||||||
|
className?: string;
|
||||||
|
height?: string;
|
||||||
|
isTeam?: boolean;
|
||||||
|
size?: number | 'small' | 'default' | 'large';
|
||||||
|
avatarType?: 'solid' | 'outlined';
|
||||||
|
}
|
||||||
|
|
||||||
|
const ProfilePictureNew = ({
|
||||||
|
name,
|
||||||
|
displayName,
|
||||||
|
className = '',
|
||||||
|
type = 'circle',
|
||||||
|
width = '36',
|
||||||
|
height,
|
||||||
|
isTeam = false,
|
||||||
|
size,
|
||||||
|
avatarType = 'solid',
|
||||||
|
}: Props) => {
|
||||||
|
const { permissions } = usePermissionProvider();
|
||||||
|
const { color, character, backgroundColor } = getRandomColor(
|
||||||
|
displayName ?? name
|
||||||
|
);
|
||||||
|
|
||||||
|
const viewUserPermission = useMemo(() => {
|
||||||
|
return userPermissions.hasViewPermissions(ResourceEntity.USER, permissions);
|
||||||
|
}, [permissions]);
|
||||||
|
|
||||||
|
const [profileURL, isPicLoading] = useUserProfile({
|
||||||
|
permission: viewUserPermission,
|
||||||
|
name,
|
||||||
|
isTeam,
|
||||||
|
});
|
||||||
|
|
||||||
|
const getAvatarByName = () => {
|
||||||
|
const avatar = (
|
||||||
|
<Avatar
|
||||||
|
className={classNames('flex-center', className)}
|
||||||
|
data-testid="profile-avatar"
|
||||||
|
icon={character}
|
||||||
|
shape={type}
|
||||||
|
size={size ?? parseInt(width)}
|
||||||
|
style={{
|
||||||
|
color: avatarType === 'solid' ? 'default' : color,
|
||||||
|
backgroundColor: avatarType === 'solid' ? color : backgroundColor,
|
||||||
|
fontWeight: avatarType === 'solid' ? 400 : 500,
|
||||||
|
border: `0.5px solid ${avatarType === 'solid' ? 'default' : color}`,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<UserPopOverCard userName={name ?? ''}>
|
||||||
|
<Link className="no-underline" to={getUserPath(name ?? '')}>
|
||||||
|
{avatar}
|
||||||
|
</Link>
|
||||||
|
</UserPopOverCard>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const getAvatarElement = () => {
|
||||||
|
return isPicLoading ? (
|
||||||
|
<div
|
||||||
|
className="d-inline-block relative"
|
||||||
|
style={{
|
||||||
|
height: typeof size === 'number' ? `${size}px` : height,
|
||||||
|
width: typeof size === 'number' ? `${size}px` : width,
|
||||||
|
}}>
|
||||||
|
{getAvatarByName()}
|
||||||
|
<div
|
||||||
|
className="absolute inset-0 opacity-60 bg-grey-4 rounded-full"
|
||||||
|
data-testid="loader-cntnr">
|
||||||
|
<Loader
|
||||||
|
className="absolute inset-0"
|
||||||
|
size="small"
|
||||||
|
style={{
|
||||||
|
height: typeof size === 'number' ? `${size}px` : `${+width}px`,
|
||||||
|
width: typeof size === 'number' ? `${size}px` : `${+width}px`,
|
||||||
|
}}
|
||||||
|
type="white"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
getAvatarByName()
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return profileURL ? (
|
||||||
|
<Tooltip placement="top" title={displayName ?? name}>
|
||||||
|
<Link
|
||||||
|
className="d-flex no-underline"
|
||||||
|
data-testid="owner-link"
|
||||||
|
to={getUserPath(name ?? '')}>
|
||||||
|
<Avatar
|
||||||
|
className={className}
|
||||||
|
data-testid="profile-image"
|
||||||
|
shape={type}
|
||||||
|
size={size ?? parseInt(width)}
|
||||||
|
src={profileURL}
|
||||||
|
/>
|
||||||
|
</Link>
|
||||||
|
</Tooltip>
|
||||||
|
) : (
|
||||||
|
getAvatarElement()
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ProfilePictureNew;
|
@ -10,10 +10,12 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import { Button, Dropdown } from 'antd';
|
import { Button, Dropdown, Typography } from 'antd';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
import { getEntityName } from '../../../utils/EntityUtils';
|
import { getEntityName } from '../../../utils/EntityUtils';
|
||||||
|
import { getOwnerPath } from '../../../utils/ownerUtils';
|
||||||
import UserPopOverCard from '../PopOverCard/UserPopOverCard';
|
import UserPopOverCard from '../PopOverCard/UserPopOverCard';
|
||||||
import ProfilePicture from '../ProfilePicture/ProfilePicture';
|
import ProfilePicture from '../ProfilePicture/ProfilePicture';
|
||||||
import { OwnerRevealProps } from './OwnerReveal.interface';
|
import { OwnerRevealProps } from './OwnerReveal.interface';
|
||||||
@ -60,18 +62,24 @@ export const OwnerReveal: React.FC<OwnerRevealProps> = ({
|
|||||||
key: owner.id,
|
key: owner.id,
|
||||||
label: (
|
label: (
|
||||||
<UserPopOverCard userName={owner.name ?? ''}>
|
<UserPopOverCard userName={owner.name ?? ''}>
|
||||||
<div className="flex items-center gap-2">
|
<Link
|
||||||
<div className="relative">
|
className="d-flex no-underline items-center gap-2 relative"
|
||||||
<ProfilePicture
|
data-testid="owner-link"
|
||||||
displayName={getEntityName(owner)}
|
to={getOwnerPath(owner)}>
|
||||||
key="profile-picture"
|
<ProfilePicture
|
||||||
name={owner.name ?? ''}
|
displayName={getEntityName(owner)}
|
||||||
type="circle"
|
key="profile-picture"
|
||||||
width="32"
|
name={owner.name ?? ''}
|
||||||
/>
|
type="circle"
|
||||||
</div>
|
width="32"
|
||||||
<span>{getEntityName(owner)}</span>
|
/>
|
||||||
</div>
|
|
||||||
|
<Typography.Text
|
||||||
|
className="w-36"
|
||||||
|
ellipsis={{ tooltip: true }}>
|
||||||
|
{getEntityName(owner)}{' '}
|
||||||
|
</Typography.Text>
|
||||||
|
</Link>
|
||||||
</UserPopOverCard>
|
</UserPopOverCard>
|
||||||
),
|
),
|
||||||
})),
|
})),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user