mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-08-30 20:06:19 +00:00
parent
f4fc1b6438
commit
40b68ca841
@ -1 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none"><path stroke="#37352F" stroke-width=".9" d="M2 3.426v9.04c.026 1.678 2.755 3.034 6.116 3.034 3.362 0 6.09-1.356 6.116-3.034v-9.04c0 1.772-2.58 3.17-5.942 3.17C4.93 6.597 2 5.34 2 3.427Z"/><path stroke="#37352F" stroke-width=".9" d="M8.116 6.616c3.378 0 6.117-1.369 6.117-3.058C14.233 1.87 11.494.5 8.116.5S2 1.87 2 3.558c0 1.69 2.738 3.058 6.116 3.058Zm.025-1.492c1.689 0 3.058-.685 3.058-1.53 0-.844-1.37-1.528-3.058-1.528-1.69 0-3.058.684-3.058 1.529 0 .844 1.369 1.529 3.058 1.529Z" clip-rule="evenodd"/><path stroke="#37352F" stroke-width=".9" d="M6.16 11.252v2.093a.2.2 0 0 1-.3.173l-1.655-.945a.2.2 0 0 1-.101-.174V7.684a.2.2 0 0 1 .304-.171l3.581 2.175a.2.2 0 0 0 .206.001l3.68-2.182a.2.2 0 0 1 .303.172v4.813a.2.2 0 0 1-.108.177l-1.655.867a.2.2 0 0 1-.292-.177v-2.116a.2.2 0 0 0-.3-.174l-1.63.924a.2.2 0 0 1-.2-.002l-1.532-.91a.2.2 0 0 0-.302.171Z"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none"><path stroke="currentColor" stroke-width=".9" d="M2 3.426v9.04c.026 1.678 2.755 3.034 6.116 3.034 3.362 0 6.09-1.356 6.116-3.034v-9.04c0 1.772-2.58 3.17-5.942 3.17C4.93 6.597 2 5.34 2 3.427Z"/><path stroke="currentColor" stroke-width=".9" d="M8.116 6.616c3.378 0 6.117-1.369 6.117-3.058C14.233 1.87 11.494.5 8.116.5S2 1.87 2 3.558c0 1.69 2.738 3.058 6.116 3.058Zm.025-1.492c1.689 0 3.058-.685 3.058-1.53 0-.844-1.37-1.528-3.058-1.528-1.69 0-3.058.684-3.058 1.529 0 .844 1.369 1.529 3.058 1.529Z" clip-rule="evenodd"/><path stroke="currentColor" stroke-width=".9" d="M6.16 11.252v2.093a.2.2 0 0 1-.3.173l-1.655-.945a.2.2 0 0 1-.101-.174V7.684a.2.2 0 0 1 .304-.171l3.581 2.175a.2.2 0 0 0 .206.001l3.68-2.182a.2.2 0 0 1 .303.172v4.813a.2.2 0 0 1-.108.177l-1.655.867a.2.2 0 0 1-.292-.177v-2.116a.2.2 0 0 0-.3-.174l-1.63.924a.2.2 0 0 1-.2-.002l-1.532-.91a.2.2 0 0 0-.302.171Z"/></svg>
|
Before Width: | Height: | Size: 939 B After Width: | Height: | Size: 954 B |
@ -11,7 +11,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Popover, Space, Table, Typography } from 'antd';
|
||||
import { Button, Popover, Space, Table, Typography } from 'antd';
|
||||
import { ColumnsType } from 'antd/lib/table';
|
||||
import classNames from 'classnames';
|
||||
import { cloneDeep, isEmpty, isUndefined, lowerCase, toLower } from 'lodash';
|
||||
@ -25,6 +25,8 @@ import React, {
|
||||
} from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { ReactComponent as IconEdit } from '../../assets/svg/ic-edit.svg';
|
||||
import { ReactComponent as IconRequest } from '../../assets/svg/request-icon.svg';
|
||||
import { FQN_SEPARATOR_CHAR } from '../../constants/char.constants';
|
||||
import { EntityField } from '../../constants/Feeds.constants';
|
||||
import { SettledStatus } from '../../enums/axios.enum';
|
||||
@ -43,7 +45,6 @@ import {
|
||||
fetchGlossaryTerms,
|
||||
getGlossaryTermlist,
|
||||
} from '../../utils/GlossaryUtils';
|
||||
import SVGIcons, { Icons } from '../../utils/SvgUtils';
|
||||
import {
|
||||
getDataTypeString,
|
||||
getTableExpandableConfig,
|
||||
@ -346,9 +347,10 @@ const EntityTable = ({
|
||||
const hasDescription = Boolean(cell?.description ?? '');
|
||||
|
||||
return (
|
||||
<button
|
||||
className="tw-w-7 tw-h-7 tw-flex-none link-text focus:tw-outline-none hover-cell-icon"
|
||||
<Button
|
||||
className="p-0 w-7 h-7 tw-flex-none flex-center link-text focus:tw-outline-none hover-cell-icon m-r-xss"
|
||||
data-testid="request-description"
|
||||
type="text"
|
||||
onClick={() =>
|
||||
hasDescription
|
||||
? onUpdateDescriptionHandler(cell)
|
||||
@ -364,13 +366,13 @@ const EntityTable = ({
|
||||
overlayClassName="ant-popover-request-description"
|
||||
trigger="hover"
|
||||
zIndex={9999}>
|
||||
<SVGIcons
|
||||
alt={t('message.request-description')}
|
||||
icon={Icons.REQUEST}
|
||||
width="16px"
|
||||
<IconRequest
|
||||
height={16}
|
||||
name={t('message.request-description')}
|
||||
width={16}
|
||||
/>
|
||||
</Popover>
|
||||
</button>
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
|
||||
@ -381,9 +383,10 @@ const EntityTable = ({
|
||||
: t('label.request-tag-plural');
|
||||
|
||||
return (
|
||||
<button
|
||||
className="tw-w-7 tw-h-7 tw-flex-none link-text focus:tw-outline-none tw-align-top hover-cell-icon"
|
||||
<Button
|
||||
className="p-0 w-7 h-7 tw-flex-none link-text focus:tw-outline-none tw-align-top hover-cell-icon"
|
||||
data-testid="request-tags"
|
||||
type="text"
|
||||
onClick={() =>
|
||||
hasTags ? onUpdateTagsHandler(cell) : onRequestTagsHandler(cell)
|
||||
}>
|
||||
@ -393,13 +396,13 @@ const EntityTable = ({
|
||||
overlayClassName="ant-popover-request-description"
|
||||
trigger="hover"
|
||||
zIndex={9999}>
|
||||
<SVGIcons
|
||||
alt={t('label.request-tag-plural')}
|
||||
icon={Icons.REQUEST}
|
||||
width="16px"
|
||||
<IconRequest
|
||||
height={16}
|
||||
name={t('label.request-tag-plural')}
|
||||
width={16}
|
||||
/>
|
||||
</Popover>
|
||||
</button>
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
|
||||
@ -441,10 +444,11 @@ const EntityTable = ({
|
||||
return (
|
||||
<div className="hover-icon-group">
|
||||
<div className="d-inline-block">
|
||||
<div
|
||||
className="d-flex"
|
||||
<Space
|
||||
align="end"
|
||||
data-testid="description"
|
||||
id={`column-description-${index}`}>
|
||||
id={`column-description-${index}`}
|
||||
size={4}>
|
||||
<div>
|
||||
{description ? (
|
||||
<RichTextEditorPreviewer markdown={description} />
|
||||
@ -461,16 +465,16 @@ const EntityTable = ({
|
||||
<Fragment>
|
||||
{hasDescriptionEditAccess && (
|
||||
<>
|
||||
<button
|
||||
className="tw-self-start tw-w-7 tw-h-7 focus:tw-outline-none tw-flex-none hover-cell-icon"
|
||||
<Button
|
||||
className="p-0 tw-self-start flex-center w-7 h-7 focus:tw-outline-none tw-flex-none hover-cell-icon"
|
||||
type="text"
|
||||
onClick={() => handleUpdate(record, index)}>
|
||||
<SVGIcons
|
||||
alt={t('label.edit')}
|
||||
icon="icon-edit"
|
||||
title={t('label.edit')}
|
||||
width="16px"
|
||||
<IconEdit
|
||||
height={16}
|
||||
name={t('label.edit')}
|
||||
width={16}
|
||||
/>
|
||||
</button>
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
{getRequestDescriptionElement(record)}
|
||||
@ -502,7 +506,7 @@ const EntityTable = ({
|
||||
</Fragment>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
</Space>
|
||||
</div>
|
||||
{getFrequentlyJoinedColumns(
|
||||
record?.name,
|
||||
|
@ -12,7 +12,7 @@
|
||||
*/
|
||||
|
||||
import { CheckOutlined, CloseOutlined } from '@ant-design/icons';
|
||||
import { Select, Space } from 'antd';
|
||||
import { Button, Select, Space } from 'antd';
|
||||
import classNames from 'classnames';
|
||||
import Tags from 'components/Tag/Tags/tags';
|
||||
import { isEmpty } from 'lodash';
|
||||
@ -28,7 +28,6 @@ import React, {
|
||||
import { FQN_SEPARATOR_CHAR } from '../../../constants/char.constants';
|
||||
import { TagSource } from '../../../generated/type/tagLabel';
|
||||
import { withLoader } from '../../../hoc/withLoader';
|
||||
import { Button } from '../../buttons/Button/Button';
|
||||
import { TagsContainerProps } from './tags-container.interface';
|
||||
|
||||
const TagsContainer: FunctionComponent<TagsContainerProps> = ({
|
||||
@ -166,22 +165,20 @@ const TagsContainer: FunctionComponent<TagsContainerProps> = ({
|
||||
<Space
|
||||
className={classNames('', buttonContainerClass)}
|
||||
data-testid="buttons"
|
||||
size={8}>
|
||||
size={4}>
|
||||
<Button
|
||||
className="tw-px-1 tw-py-1 tw-rounded tw-text-sm tw-mr-1"
|
||||
className="h-8"
|
||||
data-testid="cancelAssociatedTag"
|
||||
size="custom"
|
||||
theme="primary"
|
||||
variant="contained"
|
||||
size="small"
|
||||
type="primary"
|
||||
onMouseDown={handleCancel}>
|
||||
<CloseOutlined />
|
||||
</Button>
|
||||
<Button
|
||||
className="tw-px-1 tw-py-1 tw-rounded tw-text-sm"
|
||||
className="h-8"
|
||||
data-testid="saveAssociatedTag"
|
||||
size="custom"
|
||||
theme="primary"
|
||||
variant="contained"
|
||||
size="small"
|
||||
type="primary"
|
||||
onMouseDown={handleSave}>
|
||||
<CheckOutlined />
|
||||
</Button>
|
||||
|
@ -13,11 +13,14 @@
|
||||
|
||||
import { Button, Popover, Space, Typography } from 'antd';
|
||||
import { AxiosError } from 'axios';
|
||||
import classNames from 'classnames';
|
||||
import { t } from 'i18next';
|
||||
import { isFunction, isUndefined } from 'lodash';
|
||||
import React, { FC, Fragment } from 'react';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { ReactComponent as IconCommentPlus } from '../../../assets/svg/add-chat.svg';
|
||||
import { ReactComponent as IconComments } from '../../../assets/svg/comment.svg';
|
||||
import { ReactComponent as IconEdit } from '../../../assets/svg/ic-edit.svg';
|
||||
import { ReactComponent as IconRequest } from '../../../assets/svg/request-icon.svg';
|
||||
import { ReactComponent as IconTaskColor } from '../../../assets/svg/Task-ic.svg';
|
||||
import { EntityField } from '../../../constants/Feeds.constants';
|
||||
import { EntityType } from '../../../enums/entity.enum';
|
||||
@ -25,7 +28,6 @@ import { ThreadType } from '../../../generated/entity/feed/thread';
|
||||
import { EntityFieldThreads } from '../../../interface/feed.interface';
|
||||
import { isTaskSupported } from '../../../utils/CommonUtils';
|
||||
import { getEntityFeedLink } from '../../../utils/EntityUtils';
|
||||
import SVGIcons, { Icons } from '../../../utils/SvgUtils';
|
||||
import {
|
||||
getRequestDescriptionPath,
|
||||
getUpdateDescriptionPath,
|
||||
@ -90,9 +92,10 @@ const Description: FC<DescriptionProps> = ({
|
||||
const hasDescription = Boolean(description.trim());
|
||||
|
||||
return TASK_ENTITIES.includes(entityType as EntityType) ? (
|
||||
<button
|
||||
className="tw-w-7 tw-h-7 tw-flex-none link-text focus:tw-outline-none"
|
||||
<Button
|
||||
className="w-7 h-7 p-0 flex-center"
|
||||
data-testid="request-entity-description"
|
||||
type="text"
|
||||
onClick={
|
||||
hasDescription ? handleUpdateDescription : handleRequestDescription
|
||||
}>
|
||||
@ -106,13 +109,13 @@ const Description: FC<DescriptionProps> = ({
|
||||
overlayClassName="ant-popover-request-description"
|
||||
trigger="hover"
|
||||
zIndex={9999}>
|
||||
<SVGIcons
|
||||
alt={t('message.request-description')}
|
||||
icon={Icons.REQUEST}
|
||||
width="16px"
|
||||
<IconRequest
|
||||
height={16}
|
||||
name={t('message.request-description')}
|
||||
width={16}
|
||||
/>
|
||||
</Popover>
|
||||
</button>
|
||||
</Button>
|
||||
) : null;
|
||||
};
|
||||
|
||||
@ -120,26 +123,27 @@ const Description: FC<DescriptionProps> = ({
|
||||
descriptionThread,
|
||||
}: {
|
||||
descriptionThread?: EntityFieldThreads;
|
||||
}) => {
|
||||
return !isUndefined(descriptionThread) ? (
|
||||
<button
|
||||
className="tw-w-7 tw-h-7 tw-flex-none link-text focus:tw-outline-none"
|
||||
}) =>
|
||||
!isUndefined(descriptionThread) ? (
|
||||
<Button
|
||||
className="w-9 h-7 p-0"
|
||||
data-testid="description-thread"
|
||||
type="text"
|
||||
onClick={() => onThreadLinkSelect?.(descriptionThread.entityLink)}>
|
||||
<span className="tw-flex">
|
||||
<SVGIcons alt="comments" icon={Icons.COMMENT} width="16px" />{' '}
|
||||
<span className="tw-ml-1" data-testid="description-thread-count">
|
||||
{' '}
|
||||
<Space align="center" className="h-full" size={2}>
|
||||
<IconComments height={16} name="tasks" width={16} />
|
||||
<Typography.Text data-testid="description-thread-count">
|
||||
{descriptionThread.count}
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
</Typography.Text>
|
||||
</Space>
|
||||
</Button>
|
||||
) : (
|
||||
<Fragment>
|
||||
{description?.trim() && onThreadLinkSelect ? (
|
||||
<button
|
||||
className="tw-w-7 tw-h-7 tw-flex-none link-text focus:tw-outline-none"
|
||||
<Button
|
||||
className="w-7 h-7 link-text p-0"
|
||||
data-testid="start-description-thread"
|
||||
type="text"
|
||||
onClick={() =>
|
||||
onThreadLinkSelect?.(
|
||||
getEntityFeedLink(
|
||||
@ -149,21 +153,20 @@ const Description: FC<DescriptionProps> = ({
|
||||
)
|
||||
)
|
||||
}>
|
||||
<SVGIcons alt="comments" icon={Icons.COMMENT_PLUS} width="16px" />
|
||||
</button>
|
||||
<IconCommentPlus height={16} name="comments" width={16} />
|
||||
</Button>
|
||||
) : null}
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
const getDescriptionTaskElement = () => {
|
||||
return !isUndefined(tasks) ? (
|
||||
const getDescriptionTaskElement = () =>
|
||||
!isUndefined(tasks) ? (
|
||||
<Button
|
||||
className="w-7 h-7 m-r-xs p-0"
|
||||
className="w-9 h-7 p-0"
|
||||
data-testid="description-task"
|
||||
type="text"
|
||||
onClick={() => onThreadLinkSelect?.(tasks.entityLink, ThreadType.Task)}>
|
||||
<Space align="center" className="w-full h-full" size={3}>
|
||||
<Space align="center" className="h-full" size={2}>
|
||||
<IconTaskColor height={16} name="tasks" width={16} />
|
||||
<Typography.Text data-testid="description-tasks-count">
|
||||
{tasks.count}
|
||||
@ -171,35 +174,34 @@ const Description: FC<DescriptionProps> = ({
|
||||
</Space>
|
||||
</Button>
|
||||
) : null;
|
||||
};
|
||||
|
||||
const DescriptionActions = () => {
|
||||
return !isReadOnly ? (
|
||||
<div className={classNames('tw-w-5 tw-min-w-max tw-flex')}>
|
||||
<Space align="end" size={0}>
|
||||
{hasEditAccess && (
|
||||
<button
|
||||
className="tw-w-7 tw-h-7 tw-flex-none focus:tw-outline-none"
|
||||
<Button
|
||||
className="w-7 h-7 p-0 flex-center"
|
||||
data-testid="edit-description"
|
||||
type="text"
|
||||
onClick={handleUpdate}>
|
||||
<SVGIcons alt="edit" icon="icon-edit" title="Edit" width="16px" />
|
||||
</button>
|
||||
<IconEdit height={16} width={16} />
|
||||
</Button>
|
||||
)}
|
||||
{isTaskSupported(entityType as EntityType) ? (
|
||||
<Fragment>
|
||||
{' '}
|
||||
<RequestDescriptionEl />
|
||||
{getDescriptionTaskElement()}
|
||||
</Fragment>
|
||||
) : null}
|
||||
|
||||
<DescriptionThreadEl descriptionThread={thread} />
|
||||
</div>
|
||||
</Space>
|
||||
) : null;
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={`schema-description tw-relative ${className}`}>
|
||||
<div className="tw-flex description-inner-main-container tw-items-end">
|
||||
<Space align="end" className="description-inner-main-container" size={4}>
|
||||
<div className="tw-relative">
|
||||
<div
|
||||
className="description tw-h-full tw-overflow-y-scroll tw-relative "
|
||||
@ -230,7 +232,7 @@ const Description: FC<DescriptionProps> = ({
|
||||
/>
|
||||
</div>
|
||||
<DescriptionActions />
|
||||
</div>
|
||||
</Space>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -420,6 +420,7 @@
|
||||
"lineage-ingestion": "Lineage Ingestion",
|
||||
"lineage-lowercase": "lineage",
|
||||
"list": "List",
|
||||
"list-entity": "List {{entity}}",
|
||||
"loading": "Loading",
|
||||
"local-config-source": "Local Config Source",
|
||||
"log-plural": "Logs",
|
||||
|
@ -11,16 +11,26 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Button, Popover, Space, Typography } from 'antd';
|
||||
import { t } from 'i18next';
|
||||
import { isEmpty, isEqual, isUndefined } from 'lodash';
|
||||
import React, { Fragment } from 'react';
|
||||
import { ReactComponent as IconCommentPlus } from '../assets/svg/add-chat.svg';
|
||||
import { ReactComponent as IconComments } from '../assets/svg/comment.svg';
|
||||
import { ReactComponent as IconTaskColor } from '../assets/svg/Task-ic.svg';
|
||||
|
||||
import { entityUrlMap } from '../constants/Feeds.constants';
|
||||
import { ThreadType } from '../generated/entity/feed/thread';
|
||||
import { EntityReference } from '../generated/entity/teams/user';
|
||||
import { EntityFieldThreads } from '../interface/feed.interface';
|
||||
import { getEntityFeedLink } from './EntityUtils';
|
||||
import { getThreadField } from './FeedUtils';
|
||||
import SVGIcons, { Icons } from './SvgUtils';
|
||||
|
||||
const iconsProps = {
|
||||
height: 16,
|
||||
name: 'comments',
|
||||
width: 16,
|
||||
};
|
||||
|
||||
export const getFieldThreadElement = (
|
||||
columnName: string,
|
||||
@ -45,9 +55,10 @@ export const getFieldThreadElement = (
|
||||
const isTaskType = isEqual(threadType, ThreadType.Task);
|
||||
|
||||
return !isEmpty(threadValue) ? (
|
||||
<button
|
||||
className="link-text tw-self-start tw-w-7 tw-h-7 tw-mr-1 tw-flex tw-items-center hover-cell-icon"
|
||||
<Button
|
||||
className="link-text tw-self-start w-8 h-7 m-r-xss tw-flex tw-items-center hover-cell-icon p-0"
|
||||
data-testid="field-thread"
|
||||
type="text"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
@ -56,23 +67,33 @@ export const getFieldThreadElement = (
|
||||
isTaskType ? ThreadType.Task : ThreadType.Conversation
|
||||
);
|
||||
}}>
|
||||
<SVGIcons
|
||||
alt="comments"
|
||||
className="tw-mt-0.5"
|
||||
height="16px"
|
||||
icon={isTaskType ? Icons.TASK_ICON : Icons.COMMENT}
|
||||
width="16px"
|
||||
/>
|
||||
<span className="tw-ml-1" data-testid="field-thread-count">
|
||||
{threadValue.count}
|
||||
</span>
|
||||
</button>
|
||||
<Popover
|
||||
destroyTooltipOnHide
|
||||
content={t('label.list-entity', {
|
||||
entity: isTaskType ? t('label.task') : t('label.conversation'),
|
||||
})}
|
||||
overlayClassName="ant-popover-request-description"
|
||||
trigger="hover">
|
||||
<Space align="center" className="w-full h-full" size={4}>
|
||||
{isTaskType ? (
|
||||
<IconTaskColor {...iconsProps} />
|
||||
) : (
|
||||
<IconComments {...iconsProps} />
|
||||
)}
|
||||
|
||||
<Typography.Text data-testid="field-thread-count">
|
||||
{threadValue.count}
|
||||
</Typography.Text>
|
||||
</Space>
|
||||
</Popover>
|
||||
</Button>
|
||||
) : (
|
||||
<Fragment>
|
||||
{entityType && entityFqn && entityField && flag && !isTaskType ? (
|
||||
<button
|
||||
className="link-text tw-self-start tw-w-7 tw-h-7 tw-mr-1 tw-flex-none hover-cell-icon"
|
||||
<Button
|
||||
className="link-text tw-self-start w-7 h-7 m-r-xss tw-flex-none hover-cell-icon p-0"
|
||||
data-testid="start-field-thread"
|
||||
type="text"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
@ -80,8 +101,16 @@ export const getFieldThreadElement = (
|
||||
getEntityFeedLink(entityType, entityFqn, entityField)
|
||||
);
|
||||
}}>
|
||||
<SVGIcons alt="comments" icon={Icons.COMMENT_PLUS} width="16px" />
|
||||
</button>
|
||||
<Popover
|
||||
destroyTooltipOnHide
|
||||
content={t('label.start-entity', {
|
||||
entity: t('label.conversation'),
|
||||
})}
|
||||
overlayClassName="ant-popover-request-description"
|
||||
trigger="hover">
|
||||
<IconCommentPlus {...iconsProps} />
|
||||
</Popover>
|
||||
</Button>
|
||||
) : null}
|
||||
</Fragment>
|
||||
);
|
||||
|
Loading…
x
Reference in New Issue
Block a user