mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-10-13 01:38:13 +00:00
* ✨ Refactor : Refactor Conversation and Task Flow Logic #5734 * Fix emoji multiple API call issue * Fix table query editor issue * Addressing review comments
This commit is contained in:
parent
e3223f6a20
commit
38b04b76a9
@ -0,0 +1,8 @@
|
|||||||
|
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M11.2778 2.16615H9.95472V1.57424C9.95472 1.38273 9.74582 1.29569 9.55432 1.29569H8.52718C8.28346 0.599316 7.67412 0.251127 6.97774 0.251127C6.28903 0.225235 5.66259 0.647534 5.4283 1.29569H4.41856C4.22705 1.29569 4.03554 1.38273 4.03554 1.57424V2.16615H2.7124C1.92832 2.17451 1.28685 2.79305 1.25 3.5763V12.4269C1.25 13.1929 1.94638 13.75 2.7124 13.75H11.2778C12.0439 13.75 12.7402 13.1929 12.7402 12.4269V3.57633C12.7034 2.79305 12.0619 2.17451 11.2778 2.16615ZM4.73189 1.99207H5.68942C5.85656 1.97168 5.99082 1.84452 6.02021 1.67871C6.12331 1.22972 6.51722 0.907418 6.97774 0.895289C7.43399 0.909118 7.82197 1.23241 7.91784 1.67871C7.94906 1.85025 8.09218 1.97904 8.26603 1.99207H9.25838V3.38483H4.73189V1.99207ZM12.0439 12.4269C12.0439 12.8099 11.6608 13.0537 11.2778 13.0537H2.7124C2.32939 13.0537 1.94638 12.8099 1.94638 12.4269V3.57633C1.9819 3.17766 2.31219 2.86986 2.7124 2.86256H4.03551V3.75045C4.05391 3.94552 4.22285 4.09144 4.41852 4.08124H9.55428C9.75355 4.09214 9.9278 3.94822 9.95469 3.75045V2.86253H11.2778C11.678 2.86986 12.0083 3.17763 12.0438 3.5763L12.0439 12.4269Z" fill="#7147E8" stroke="#7147E8" stroke-width="0.2"/>
|
||||||
|
<path d="M5.66293 9.52502C5.55676 9.4131 5.3805 9.40679 5.2666 9.51088L4.36072 10.3743L3.97856 9.97795C3.87239 9.86603 3.69613 9.85974 3.58223 9.9638C3.47259 10.0787 3.47259 10.2594 3.58223 10.3743L4.16254 10.9688C4.21277 11.025 4.28532 11.0561 4.3607 11.0537C4.43536 11.0526 4.50659 11.0221 4.55885 10.9688L5.66288 9.92135C5.77233 9.82095 5.77964 9.65081 5.67921 9.54139C5.67407 9.53567 5.66862 9.53022 5.66293 9.52502Z" fill="#7147E8" stroke="#7147E8" stroke-width="0.2"/>
|
||||||
|
<path d="M10.2427 9.99927H7.36768C7.2296 9.99927 7.11768 10.1671 7.11768 10.3742C7.11768 10.5813 7.2296 10.7492 7.36768 10.7492H10.2427C10.3808 10.7492 10.4927 10.5813 10.4927 10.3742C10.4927 10.1671 10.3808 9.99927 10.2427 9.99927Z" fill="#7147E8" stroke="#7147E8" stroke-width="0.2"/>
|
||||||
|
<path d="M5.66293 6.52575C5.55676 6.41384 5.3805 6.40752 5.2666 6.51161L4.36072 7.37501L3.97856 6.97868C3.87239 6.86676 3.69613 6.86045 3.58223 6.96454C3.47259 7.07941 3.47259 7.26014 3.58223 7.37501L4.16254 7.96949C4.21277 8.02574 4.28532 8.05684 4.3607 8.05443C4.43536 8.05337 4.50659 8.02284 4.55885 7.96949L5.66288 6.92209C5.77233 6.82168 5.77964 6.65154 5.67921 6.54212C5.67407 6.5364 5.66862 6.53096 5.66293 6.52575Z" fill="#7147E8" stroke="#7147E8" stroke-width="0.2"/>
|
||||||
|
<path d="M10.2427 7H7.36768C7.2296 7 7.11768 7.16788 7.11768 7.37497C7.11768 7.58207 7.2296 7.74995 7.36768 7.74995H10.2427C10.3808 7.74995 10.4927 7.58207 10.4927 7.37497C10.4927 7.16788 10.3808 7 10.2427 7Z" fill="#7147E8" stroke="#7147E8" stroke-width="0.2"/>
|
||||||
|
</svg>
|
||||||
|
|
After Width: | Height: | Size: 2.7 KiB |
@ -66,11 +66,13 @@ export const getFeedsWithFilter: Function = (
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const getFeedCount: Function = (
|
export const getFeedCount: Function = (
|
||||||
entityLink?: string
|
entityLink?: string,
|
||||||
|
type?: ThreadType
|
||||||
): Promise<AxiosResponse> => {
|
): Promise<AxiosResponse> => {
|
||||||
return APIClient.get(`/feed/count`, {
|
return APIClient.get(`/feed/count`, {
|
||||||
params: {
|
params: {
|
||||||
entityLink: entityLink,
|
entityLink: entityLink,
|
||||||
|
type,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -20,6 +20,7 @@ import { ConfirmState } from '../ActivityFeedCard/ActivityFeedCard.interface';
|
|||||||
export interface ActivityThreadPanelProp
|
export interface ActivityThreadPanelProp
|
||||||
extends HTMLAttributes<HTMLDivElement> {
|
extends HTMLAttributes<HTMLDivElement> {
|
||||||
threadLink: string;
|
threadLink: string;
|
||||||
|
threadType?: ThreadType;
|
||||||
open?: boolean;
|
open?: boolean;
|
||||||
postFeedHandler: (value: string, id: string) => void;
|
postFeedHandler: (value: string, id: string) => void;
|
||||||
createThread: (data: CreateThread) => void;
|
createThread: (data: CreateThread) => void;
|
||||||
|
@ -13,8 +13,10 @@
|
|||||||
|
|
||||||
import { Tabs } from 'antd';
|
import { Tabs } from 'antd';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
import { isEqual } from 'lodash';
|
||||||
import React, { FC, useEffect, useState } from 'react';
|
import React, { FC, useEffect, useState } from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
|
import { PanelTab } from '../../../constants/feed.constants';
|
||||||
import { ThreadType } from '../../../generated/entity/feed/thread';
|
import { ThreadType } from '../../../generated/entity/feed/thread';
|
||||||
import FeedPanelOverlay from '../ActivityFeedPanel/FeedPanelOverlay';
|
import FeedPanelOverlay from '../ActivityFeedPanel/FeedPanelOverlay';
|
||||||
import { ActivityThreadPanelProp } from './ActivityThreadPanel.interface';
|
import { ActivityThreadPanelProp } from './ActivityThreadPanel.interface';
|
||||||
@ -29,14 +31,21 @@ const ActivityThreadPanel: FC<ActivityThreadPanelProp> = ({
|
|||||||
createThread,
|
createThread,
|
||||||
deletePostHandler,
|
deletePostHandler,
|
||||||
updateThreadHandler,
|
updateThreadHandler,
|
||||||
|
threadType,
|
||||||
}) => {
|
}) => {
|
||||||
const { TabPane } = Tabs;
|
const { TabPane } = Tabs;
|
||||||
const [activeTab, setActiveTab] = useState<string>('1');
|
const [activeTab, setActiveTab] = useState<PanelTab>(PanelTab.TASKS);
|
||||||
|
|
||||||
const onTabChange = (key: string) => {
|
const onTabChange = (key: string) => {
|
||||||
setActiveTab(key);
|
setActiveTab(key as PanelTab);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (isEqual(threadType, ThreadType.Conversation)) {
|
||||||
|
setActiveTab(PanelTab.CONVERSATIONS);
|
||||||
|
}
|
||||||
|
}, [threadType]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
document.body.style.overflow = 'hidden';
|
document.body.style.overflow = 'hidden';
|
||||||
}, []);
|
}, []);
|
||||||
@ -60,7 +69,7 @@ const ActivityThreadPanel: FC<ActivityThreadPanelProp> = ({
|
|||||||
activeKey={activeTab}
|
activeKey={activeTab}
|
||||||
className="ant-tabs-custom-line ant-tabs-custom-threadpanel"
|
className="ant-tabs-custom-line ant-tabs-custom-threadpanel"
|
||||||
onChange={onTabChange}>
|
onChange={onTabChange}>
|
||||||
<TabPane key="1" tab="Tasks">
|
<TabPane key={PanelTab.TASKS} tab="Tasks">
|
||||||
<ActivityThreadPanelBody
|
<ActivityThreadPanelBody
|
||||||
createThread={createThread}
|
createThread={createThread}
|
||||||
deletePostHandler={deletePostHandler}
|
deletePostHandler={deletePostHandler}
|
||||||
@ -72,7 +81,7 @@ const ActivityThreadPanel: FC<ActivityThreadPanelProp> = ({
|
|||||||
onTabChange={onTabChange}
|
onTabChange={onTabChange}
|
||||||
/>
|
/>
|
||||||
</TabPane>
|
</TabPane>
|
||||||
<TabPane key="2" tab="Conversations">
|
<TabPane key={PanelTab.CONVERSATIONS} tab="Conversations">
|
||||||
<ActivityThreadPanelBody
|
<ActivityThreadPanelBody
|
||||||
createThread={createThread}
|
createThread={createThread}
|
||||||
deletePostHandler={deletePostHandler}
|
deletePostHandler={deletePostHandler}
|
||||||
|
@ -18,7 +18,10 @@ import { isEqual, isUndefined } from 'lodash';
|
|||||||
import React, { FC, Fragment, RefObject, useEffect, useState } from 'react';
|
import React, { FC, Fragment, RefObject, useEffect, useState } from 'react';
|
||||||
import AppState from '../../../AppState';
|
import AppState from '../../../AppState';
|
||||||
import { getAllFeeds } from '../../../axiosAPIs/feedsAPI';
|
import { getAllFeeds } from '../../../axiosAPIs/feedsAPI';
|
||||||
import { confirmStateInitialValue } from '../../../constants/feed.constants';
|
import {
|
||||||
|
confirmStateInitialValue,
|
||||||
|
PanelTab,
|
||||||
|
} from '../../../constants/feed.constants';
|
||||||
import { observerOptions } from '../../../constants/Mydata.constants';
|
import { observerOptions } from '../../../constants/Mydata.constants';
|
||||||
import { Thread, ThreadType } from '../../../generated/entity/feed/thread';
|
import { Thread, ThreadType } from '../../../generated/entity/feed/thread';
|
||||||
import { Paging } from '../../../generated/type/paging';
|
import { Paging } from '../../../generated/type/paging';
|
||||||
@ -200,7 +203,9 @@ const ActivityThreadPanelBody: FC<ActivityThreadPanelBodyProp> = ({
|
|||||||
|
|
||||||
useAfterMount(() => {
|
useAfterMount(() => {
|
||||||
if (threadType === ThreadType.Task && !isThreadLoading) {
|
if (threadType === ThreadType.Task && !isThreadLoading) {
|
||||||
isEqual(threads.length, 0) && onTabChange && onTabChange('2');
|
isEqual(threads.length, 0) &&
|
||||||
|
onTabChange &&
|
||||||
|
onTabChange(PanelTab.CONVERSATIONS);
|
||||||
}
|
}
|
||||||
}, [threads, isThreadLoading]);
|
}, [threads, isThreadLoading]);
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ import { Link } from 'react-router-dom';
|
|||||||
import AppState from '../../AppState';
|
import AppState from '../../AppState';
|
||||||
import { FQN_SEPARATOR_CHAR } from '../../constants/char.constants';
|
import { FQN_SEPARATOR_CHAR } from '../../constants/char.constants';
|
||||||
import { getTeamAndUserDetailsPath } from '../../constants/constants';
|
import { getTeamAndUserDetailsPath } from '../../constants/constants';
|
||||||
|
import { EntityField } from '../../constants/feed.constants';
|
||||||
import { observerOptions } from '../../constants/Mydata.constants';
|
import { observerOptions } from '../../constants/Mydata.constants';
|
||||||
import { SettledStatus } from '../../enums/axios.enum';
|
import { SettledStatus } from '../../enums/axios.enum';
|
||||||
import { EntityType } from '../../enums/entity.enum';
|
import { EntityType } from '../../enums/entity.enum';
|
||||||
@ -497,7 +498,7 @@ const DashboardDetails = ({
|
|||||||
<Description
|
<Description
|
||||||
description={description}
|
description={description}
|
||||||
entityFieldThreads={getEntityFieldThreadCounts(
|
entityFieldThreads={getEntityFieldThreadCounts(
|
||||||
'description',
|
EntityField.DESCRIPTION,
|
||||||
entityFieldThreadCount
|
entityFieldThreadCount
|
||||||
)}
|
)}
|
||||||
entityFqn={dashboardFQN}
|
entityFqn={dashboardFQN}
|
||||||
|
@ -17,6 +17,7 @@ import { ExtraInfo } from 'Models';
|
|||||||
import React, { FC, useEffect, useState } from 'react';
|
import React, { FC, useEffect, useState } from 'react';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { FQN_SEPARATOR_CHAR } from '../../constants/char.constants';
|
import { FQN_SEPARATOR_CHAR } from '../../constants/char.constants';
|
||||||
|
import { EntityField } from '../../constants/feed.constants';
|
||||||
import { OwnerType } from '../../enums/user.enum';
|
import { OwnerType } from '../../enums/user.enum';
|
||||||
import { ChangeDescription } from '../../generated/entity/data/dashboard';
|
import { ChangeDescription } from '../../generated/entity/data/dashboard';
|
||||||
import { TagLabel } from '../../generated/type/tagLabel';
|
import { TagLabel } from '../../generated/type/tagLabel';
|
||||||
@ -68,7 +69,7 @@ const DashboardVersion: FC<DashboardVersionProp> = ({
|
|||||||
|
|
||||||
const getDashboardDescription = () => {
|
const getDashboardDescription = () => {
|
||||||
const descriptionDiff = getDiffByFieldName(
|
const descriptionDiff = getDiffByFieldName(
|
||||||
'description',
|
EntityField.DESCRIPTION,
|
||||||
changeDescription
|
changeDescription
|
||||||
);
|
);
|
||||||
const oldDescription =
|
const oldDescription =
|
||||||
|
@ -24,6 +24,7 @@ import React, {
|
|||||||
import AppState from '../../AppState';
|
import AppState from '../../AppState';
|
||||||
import { FQN_SEPARATOR_CHAR } from '../../constants/char.constants';
|
import { FQN_SEPARATOR_CHAR } from '../../constants/char.constants';
|
||||||
import { getTeamAndUserDetailsPath, ROUTES } from '../../constants/constants';
|
import { getTeamAndUserDetailsPath, ROUTES } from '../../constants/constants';
|
||||||
|
import { EntityField } from '../../constants/feed.constants';
|
||||||
import { observerOptions } from '../../constants/Mydata.constants';
|
import { observerOptions } from '../../constants/Mydata.constants';
|
||||||
import { CSMode } from '../../enums/codemirror.enum';
|
import { CSMode } from '../../enums/codemirror.enum';
|
||||||
import { EntityType, FqnPart } from '../../enums/entity.enum';
|
import { EntityType, FqnPart } from '../../enums/entity.enum';
|
||||||
@ -34,6 +35,7 @@ import {
|
|||||||
TableJoins,
|
TableJoins,
|
||||||
TypeUsedToReturnUsageDetailsOfAnEntity,
|
TypeUsedToReturnUsageDetailsOfAnEntity,
|
||||||
} from '../../generated/entity/data/table';
|
} from '../../generated/entity/data/table';
|
||||||
|
import { ThreadType } from '../../generated/entity/feed/thread';
|
||||||
import { EntityReference } from '../../generated/type/entityReference';
|
import { EntityReference } from '../../generated/type/entityReference';
|
||||||
import { Paging } from '../../generated/type/paging';
|
import { Paging } from '../../generated/type/paging';
|
||||||
import { LabelType, State } from '../../generated/type/tagLabel';
|
import { LabelType, State } from '../../generated/type/tagLabel';
|
||||||
@ -138,6 +140,7 @@ const DatasetDetails: React.FC<DatasetDetailsProps> = ({
|
|||||||
fetchFeedHandler,
|
fetchFeedHandler,
|
||||||
handleExtentionUpdate,
|
handleExtentionUpdate,
|
||||||
updateThreadHandler,
|
updateThreadHandler,
|
||||||
|
entityFieldTaskCount,
|
||||||
}: DatasetDetailsProps) => {
|
}: DatasetDetailsProps) => {
|
||||||
const [isEdit, setIsEdit] = useState(false);
|
const [isEdit, setIsEdit] = useState(false);
|
||||||
const [followersCount, setFollowersCount] = useState(0);
|
const [followersCount, setFollowersCount] = useState(0);
|
||||||
@ -152,6 +155,9 @@ const DatasetDetails: React.FC<DatasetDetailsProps> = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const [threadLink, setThreadLink] = useState<string>('');
|
const [threadLink, setThreadLink] = useState<string>('');
|
||||||
|
const [threadType, setThreadType] = useState<ThreadType>(
|
||||||
|
ThreadType.Conversation
|
||||||
|
);
|
||||||
const [selectedField, setSelectedField] = useState<string>('');
|
const [selectedField, setSelectedField] = useState<string>('');
|
||||||
|
|
||||||
const [elementRef, isInView] = useInfiniteScroll(observerOptions);
|
const [elementRef, isInView] = useInfiniteScroll(observerOptions);
|
||||||
@ -527,8 +533,11 @@ const DatasetDetails: React.FC<DatasetDetailsProps> = ({
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const onThreadLinkSelect = (link: string) => {
|
const onThreadLinkSelect = (link: string, threadType?: ThreadType) => {
|
||||||
setThreadLink(link);
|
setThreadLink(link);
|
||||||
|
if (threadType) {
|
||||||
|
setThreadType(threadType);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const onThreadPanelClose = () => {
|
const onThreadPanelClose = () => {
|
||||||
@ -615,8 +624,12 @@ const DatasetDetails: React.FC<DatasetDetailsProps> = ({
|
|||||||
<div className="tw-col-span-3 tw--ml-5">
|
<div className="tw-col-span-3 tw--ml-5">
|
||||||
<Description
|
<Description
|
||||||
description={description}
|
description={description}
|
||||||
|
entityFieldTasks={getEntityFieldThreadCounts(
|
||||||
|
EntityField.DESCRIPTION,
|
||||||
|
entityFieldTaskCount
|
||||||
|
)}
|
||||||
entityFieldThreads={getEntityFieldThreadCounts(
|
entityFieldThreads={getEntityFieldThreadCounts(
|
||||||
'description',
|
EntityField.DESCRIPTION,
|
||||||
entityFieldThreadCount
|
entityFieldThreadCount
|
||||||
)}
|
)}
|
||||||
entityFqn={datasetFQN}
|
entityFqn={datasetFQN}
|
||||||
@ -647,8 +660,12 @@ const DatasetDetails: React.FC<DatasetDetailsProps> = ({
|
|||||||
FQN_SEPARATOR_CHAR
|
FQN_SEPARATOR_CHAR
|
||||||
)}
|
)}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
|
entityFieldTasks={getEntityFieldThreadCounts(
|
||||||
|
EntityField.COLUMNS,
|
||||||
|
entityFieldTaskCount
|
||||||
|
)}
|
||||||
entityFieldThreads={getEntityFieldThreadCounts(
|
entityFieldThreads={getEntityFieldThreadCounts(
|
||||||
'columns',
|
EntityField.COLUMNS,
|
||||||
entityFieldThreadCount
|
entityFieldThreadCount
|
||||||
)}
|
)}
|
||||||
entityFqn={datasetFQN}
|
entityFqn={datasetFQN}
|
||||||
@ -818,6 +835,7 @@ const DatasetDetails: React.FC<DatasetDetailsProps> = ({
|
|||||||
open={Boolean(threadLink)}
|
open={Boolean(threadLink)}
|
||||||
postFeedHandler={postFeedHandler}
|
postFeedHandler={postFeedHandler}
|
||||||
threadLink={threadLink}
|
threadLink={threadLink}
|
||||||
|
threadType={threadType}
|
||||||
updateThreadHandler={updateThreadHandler}
|
updateThreadHandler={updateThreadHandler}
|
||||||
onCancel={onThreadPanelClose}
|
onCancel={onThreadPanelClose}
|
||||||
/>
|
/>
|
||||||
|
@ -75,6 +75,7 @@ export interface DatasetDetailsProps {
|
|||||||
isentityThreadLoading: boolean;
|
isentityThreadLoading: boolean;
|
||||||
feedCount: number;
|
feedCount: number;
|
||||||
entityFieldThreadCount: EntityFieldThreadCount[];
|
entityFieldThreadCount: EntityFieldThreadCount[];
|
||||||
|
entityFieldTaskCount: EntityFieldThreadCount[];
|
||||||
testMode: DatasetTestModeType;
|
testMode: DatasetTestModeType;
|
||||||
tableTestCase: TableTest[];
|
tableTestCase: TableTest[];
|
||||||
showTestForm: boolean;
|
showTestForm: boolean;
|
||||||
|
@ -145,6 +145,7 @@ const DatasetDetailsProps = {
|
|||||||
postFeedHandler: jest.fn(),
|
postFeedHandler: jest.fn(),
|
||||||
feedCount: 0,
|
feedCount: 0,
|
||||||
entityFieldThreadCount: [],
|
entityFieldThreadCount: [],
|
||||||
|
entityFieldTaskCount: [],
|
||||||
showTestForm: false,
|
showTestForm: false,
|
||||||
testMode: 'table' as DatasetTestModeType,
|
testMode: 'table' as DatasetTestModeType,
|
||||||
handleAddTableTestCase: jest.fn(),
|
handleAddTableTestCase: jest.fn(),
|
||||||
|
@ -16,6 +16,7 @@ import { cloneDeep, isEqual, isUndefined } from 'lodash';
|
|||||||
import { ExtraInfo } from 'Models';
|
import { ExtraInfo } from 'Models';
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { FQN_SEPARATOR_CHAR } from '../../constants/char.constants';
|
import { FQN_SEPARATOR_CHAR } from '../../constants/char.constants';
|
||||||
|
import { EntityField } from '../../constants/feed.constants';
|
||||||
import { FqnPart } from '../../enums/entity.enum';
|
import { FqnPart } from '../../enums/entity.enum';
|
||||||
import { OwnerType } from '../../enums/user.enum';
|
import { OwnerType } from '../../enums/user.enum';
|
||||||
import {
|
import {
|
||||||
@ -138,7 +139,7 @@ const DatasetVersion: React.FC<DatasetVersionProp> = ({
|
|||||||
|
|
||||||
const getTableDescription = () => {
|
const getTableDescription = () => {
|
||||||
const descriptionDiff = getDiffByFieldName(
|
const descriptionDiff = getDiffByFieldName(
|
||||||
'description',
|
EntityField.DESCRIPTION,
|
||||||
changeDescription
|
changeDescription
|
||||||
);
|
);
|
||||||
const oldDescription =
|
const oldDescription =
|
||||||
@ -159,7 +160,10 @@ const DatasetVersion: React.FC<DatasetVersionProp> = ({
|
|||||||
|
|
||||||
const updatedColumns = (): Table['columns'] => {
|
const updatedColumns = (): Table['columns'] => {
|
||||||
const colList = cloneDeep(currentVersionData.columns);
|
const colList = cloneDeep(currentVersionData.columns);
|
||||||
const columnsDiff = getDiffByFieldName('columns', changeDescription);
|
const columnsDiff = getDiffByFieldName(
|
||||||
|
EntityField.COLUMNS,
|
||||||
|
changeDescription
|
||||||
|
);
|
||||||
const changedColName = getChangeColName(
|
const changedColName = getChangeColName(
|
||||||
columnsDiff?.added?.name ??
|
columnsDiff?.added?.name ??
|
||||||
columnsDiff?.deleted?.name ??
|
columnsDiff?.deleted?.name ??
|
||||||
@ -171,7 +175,7 @@ const DatasetVersion: React.FC<DatasetVersionProp> = ({
|
|||||||
columnsDiff?.added?.name ??
|
columnsDiff?.added?.name ??
|
||||||
columnsDiff?.deleted?.name ??
|
columnsDiff?.deleted?.name ??
|
||||||
columnsDiff?.updated?.name,
|
columnsDiff?.updated?.name,
|
||||||
'description'
|
EntityField.DESCRIPTION
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
const oldDescription =
|
const oldDescription =
|
||||||
@ -249,7 +253,7 @@ const DatasetVersion: React.FC<DatasetVersionProp> = ({
|
|||||||
return colList ?? [];
|
return colList ?? [];
|
||||||
} else {
|
} else {
|
||||||
const columnsDiff = getDiffByFieldName(
|
const columnsDiff = getDiffByFieldName(
|
||||||
'columns',
|
EntityField.COLUMNS,
|
||||||
changeDescription,
|
changeDescription,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
import { faCaretDown, faCaretRight } from '@fortawesome/free-solid-svg-icons';
|
import { faCaretDown, faCaretRight } from '@fortawesome/free-solid-svg-icons';
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
|
import { Popover } from 'antd';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { cloneDeep, isNil, isUndefined, lowerCase } from 'lodash';
|
import { cloneDeep, isNil, isUndefined, lowerCase } from 'lodash';
|
||||||
import { EntityFieldThreads, EntityTags, TagOption } from 'Models';
|
import { EntityFieldThreads, EntityTags, TagOption } from 'Models';
|
||||||
@ -22,6 +23,7 @@ import { useExpanded, useTable } from 'react-table';
|
|||||||
import { useAuthContext } from '../../authentication/auth-provider/AuthProvider';
|
import { useAuthContext } from '../../authentication/auth-provider/AuthProvider';
|
||||||
import { FQN_SEPARATOR_CHAR } from '../../constants/char.constants';
|
import { FQN_SEPARATOR_CHAR } from '../../constants/char.constants';
|
||||||
import { getTableDetailsPath } from '../../constants/constants';
|
import { getTableDetailsPath } from '../../constants/constants';
|
||||||
|
import { EntityField } from '../../constants/feed.constants';
|
||||||
import { SettledStatus } from '../../enums/axios.enum';
|
import { SettledStatus } from '../../enums/axios.enum';
|
||||||
import { EntityType, FqnPart } from '../../enums/entity.enum';
|
import { EntityType, FqnPart } from '../../enums/entity.enum';
|
||||||
import {
|
import {
|
||||||
@ -31,6 +33,7 @@ import {
|
|||||||
JoinedWith,
|
JoinedWith,
|
||||||
Table,
|
Table,
|
||||||
} from '../../generated/entity/data/table';
|
} from '../../generated/entity/data/table';
|
||||||
|
import { ThreadType } from '../../generated/entity/feed/thread';
|
||||||
import { Operation } from '../../generated/entity/policies/accessControl/rule';
|
import { Operation } from '../../generated/entity/policies/accessControl/rule';
|
||||||
import { TestCaseStatus } from '../../generated/tests/tableTest';
|
import { TestCaseStatus } from '../../generated/tests/tableTest';
|
||||||
import { LabelType, State, TagLabel } from '../../generated/type/tagLabel';
|
import { LabelType, State, TagLabel } from '../../generated/type/tagLabel';
|
||||||
@ -43,7 +46,6 @@ import {
|
|||||||
} from '../../utils/CommonUtils';
|
} from '../../utils/CommonUtils';
|
||||||
import { ENTITY_LINK_SEPARATOR } from '../../utils/EntityUtils';
|
import { ENTITY_LINK_SEPARATOR } from '../../utils/EntityUtils';
|
||||||
import { getFieldThreadElement } from '../../utils/FeedElementUtils';
|
import { getFieldThreadElement } from '../../utils/FeedElementUtils';
|
||||||
import { getThreadValue } from '../../utils/FeedUtils';
|
|
||||||
import {
|
import {
|
||||||
fetchGlossaryTerms,
|
fetchGlossaryTerms,
|
||||||
getGlossaryTermlist,
|
getGlossaryTermlist,
|
||||||
@ -77,8 +79,9 @@ interface Props {
|
|||||||
isReadOnly?: boolean;
|
isReadOnly?: boolean;
|
||||||
entityFqn?: string;
|
entityFqn?: string;
|
||||||
entityFieldThreads?: EntityFieldThreads[];
|
entityFieldThreads?: EntityFieldThreads[];
|
||||||
|
entityFieldTasks?: EntityFieldThreads[];
|
||||||
onUpdate?: (columns: ModifiedTableColumn[]) => void;
|
onUpdate?: (columns: ModifiedTableColumn[]) => void;
|
||||||
onThreadLinkSelect?: (value: string) => void;
|
onThreadLinkSelect?: (value: string, threadType?: ThreadType) => void;
|
||||||
onEntityFieldSelect?: (value: string) => void;
|
onEntityFieldSelect?: (value: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,6 +97,7 @@ const EntityTable = ({
|
|||||||
onThreadLinkSelect,
|
onThreadLinkSelect,
|
||||||
entityFqn,
|
entityFqn,
|
||||||
tableConstraints,
|
tableConstraints,
|
||||||
|
entityFieldTasks,
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
const { isAdminUser, userPermissions } = useAuth();
|
const { isAdminUser, userPermissions } = useAuth();
|
||||||
const { isAuthDisabled } = useAuthContext();
|
const { isAuthDisabled } = useAuthContext();
|
||||||
@ -356,7 +360,13 @@ const EntityTable = ({
|
|||||||
return searchedValue;
|
return searchedValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* eslint-disable-next-line */
|
const checkPermission = () =>
|
||||||
|
isAdminUser ||
|
||||||
|
hasEditAccess ||
|
||||||
|
isAuthDisabled ||
|
||||||
|
userPermissions[Operation.UpdateDescription];
|
||||||
|
|
||||||
|
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
||||||
const getColumnName = (cell: any) => {
|
const getColumnName = (cell: any) => {
|
||||||
const fqn = cell?.row?.original?.fullyQualifiedName || '';
|
const fqn = cell?.row?.original?.fullyQualifiedName || '';
|
||||||
const columnName = getPartialNameFromTableFQN(fqn, [FqnPart.NestedColumn]);
|
const columnName = getPartialNameFromTableFQN(fqn, [FqnPart.NestedColumn]);
|
||||||
@ -367,9 +377,9 @@ const EntityTable = ({
|
|||||||
: columnName;
|
: columnName;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* eslint-disable-next-line */
|
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
||||||
const onRequestDescriptionHandler = (cell: any) => {
|
const onRequestDescriptionHandler = (cell: any) => {
|
||||||
const field = 'columns';
|
const field = EntityField.COLUMNS;
|
||||||
const value = getColumnName(cell);
|
const value = getColumnName(cell);
|
||||||
history.push(
|
history.push(
|
||||||
getRequestDescriptionPath(
|
getRequestDescriptionPath(
|
||||||
@ -381,6 +391,20 @@ const EntityTable = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
||||||
|
const onUpdateDescriptionHandler = (cell: any) => {
|
||||||
|
const field = EntityField.COLUMNS;
|
||||||
|
const value = getColumnName(cell);
|
||||||
|
history.push(
|
||||||
|
getUpdateDescriptionPath(
|
||||||
|
EntityType.TABLE,
|
||||||
|
entityFqn as string,
|
||||||
|
field,
|
||||||
|
value
|
||||||
|
)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const prepareConstraintIcon = (
|
const prepareConstraintIcon = (
|
||||||
columnName: string,
|
columnName: string,
|
||||||
columnConstraint?: string
|
columnConstraint?: string
|
||||||
@ -399,28 +423,41 @@ const EntityTable = ({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* eslint-disable-next-line */
|
const handleUpdate = (column: Column, index: number) => {
|
||||||
const handleUpdate = (column: Column, index: number, cell: any) => {
|
handleEditColumn(column, index);
|
||||||
const check =
|
};
|
||||||
isAdminUser ||
|
|
||||||
hasEditAccess ||
|
|
||||||
isAuthDisabled ||
|
|
||||||
userPermissions[Operation.UpdateDescription];
|
|
||||||
if (check) {
|
|
||||||
handleEditColumn(column, index);
|
|
||||||
} else {
|
|
||||||
const field = 'columns';
|
|
||||||
const value = getColumnName(cell);
|
|
||||||
|
|
||||||
history.push(
|
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
||||||
getUpdateDescriptionPath(
|
const getRequestDescriptionElement = (cell: any) => {
|
||||||
EntityType.TABLE,
|
const hasDescription = Boolean(cell.value);
|
||||||
entityFqn as string,
|
|
||||||
field,
|
return (
|
||||||
value
|
<button
|
||||||
)
|
className="tw-w-8 tw-h-8 tw-mr-1 tw-flex-none link-text focus:tw-outline-none tw-opacity-0 group-hover:tw-opacity-100"
|
||||||
);
|
data-testid="request-description"
|
||||||
}
|
onClick={() =>
|
||||||
|
hasDescription
|
||||||
|
? onUpdateDescriptionHandler(cell)
|
||||||
|
: onRequestDescriptionHandler(cell)
|
||||||
|
}>
|
||||||
|
<Popover
|
||||||
|
destroyTooltipOnHide
|
||||||
|
content={
|
||||||
|
hasDescription
|
||||||
|
? 'Request update description'
|
||||||
|
: 'Request description'
|
||||||
|
}
|
||||||
|
overlayClassName="ant-popover-request-description"
|
||||||
|
trigger="hover"
|
||||||
|
zIndex={9999}>
|
||||||
|
<SVGIcons
|
||||||
|
alt="request-description"
|
||||||
|
icon={Icons.REQUEST}
|
||||||
|
width="16px"
|
||||||
|
/>
|
||||||
|
</Popover>
|
||||||
|
</button>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -675,60 +712,52 @@ const EntityTable = ({
|
|||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{!isReadOnly ? (
|
<div className="tw-flex tw--mt-1.5">
|
||||||
<Fragment>
|
{!isReadOnly ? (
|
||||||
<button
|
<Fragment>
|
||||||
className="tw-self-start tw-w-8 tw-h-auto tw-opacity-0 tw-ml-1 group-hover:tw-opacity-100 focus:tw-outline-none"
|
{checkPermission() && (
|
||||||
onClick={() =>
|
<button
|
||||||
handleUpdate(row.original, row.id, cell)
|
className="tw-self-start tw-w-8 tw-h-8 tw-opacity-0 tw-ml-1 group-hover:tw-opacity-100 focus:tw-outline-none tw-flex-none"
|
||||||
}>
|
onClick={() =>
|
||||||
<SVGIcons
|
handleUpdate(row.original, row.id)
|
||||||
alt="edit"
|
}>
|
||||||
icon="icon-edit"
|
|
||||||
title="Edit"
|
|
||||||
width="12px"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
{isNil(
|
|
||||||
getThreadValue(
|
|
||||||
getColumnName(cell),
|
|
||||||
'description',
|
|
||||||
entityFieldThreads as EntityFieldThreads[]
|
|
||||||
)
|
|
||||||
) && !cell.value ? (
|
|
||||||
<button
|
|
||||||
className="focus:tw-outline-none tw-ml-1 tw-opacity-0 group-hover:tw-opacity-100 tw--mt-2"
|
|
||||||
data-testid="request-description"
|
|
||||||
onClick={() =>
|
|
||||||
onRequestDescriptionHandler(cell)
|
|
||||||
}>
|
|
||||||
<PopOver
|
|
||||||
position="top"
|
|
||||||
title="Request description"
|
|
||||||
trigger="mouseenter">
|
|
||||||
<SVGIcons
|
<SVGIcons
|
||||||
alt="request-description"
|
alt="edit"
|
||||||
className="tw-mt-2.5"
|
icon="icon-edit"
|
||||||
icon={Icons.REQUEST}
|
title="Edit"
|
||||||
|
width="14px"
|
||||||
/>
|
/>
|
||||||
</PopOver>
|
</button>
|
||||||
</button>
|
)}
|
||||||
) : null}
|
{getRequestDescriptionElement(cell)}
|
||||||
{getFieldThreadElement(
|
{getFieldThreadElement(
|
||||||
getColumnName(cell),
|
getColumnName(cell),
|
||||||
'description',
|
EntityField.DESCRIPTION,
|
||||||
entityFieldThreads as EntityFieldThreads[],
|
entityFieldThreads as EntityFieldThreads[],
|
||||||
onThreadLinkSelect,
|
onThreadLinkSelect,
|
||||||
EntityType.TABLE,
|
EntityType.TABLE,
|
||||||
entityFqn,
|
entityFqn,
|
||||||
`columns${ENTITY_LINK_SEPARATOR}${getColumnName(
|
`columns${ENTITY_LINK_SEPARATOR}${getColumnName(
|
||||||
cell
|
cell
|
||||||
)}${ENTITY_LINK_SEPARATOR}description`,
|
)}${ENTITY_LINK_SEPARATOR}description`,
|
||||||
Boolean(cell.value)
|
Boolean(cell.value)
|
||||||
)}
|
)}
|
||||||
</Fragment>
|
{getFieldThreadElement(
|
||||||
) : null}
|
getColumnName(cell),
|
||||||
|
EntityField.DESCRIPTION,
|
||||||
|
entityFieldTasks as EntityFieldThreads[],
|
||||||
|
onThreadLinkSelect,
|
||||||
|
EntityType.TABLE,
|
||||||
|
entityFqn,
|
||||||
|
`columns${ENTITY_LINK_SEPARATOR}${getColumnName(
|
||||||
|
cell
|
||||||
|
)}${ENTITY_LINK_SEPARATOR}description`,
|
||||||
|
Boolean(cell.value),
|
||||||
|
ThreadType.Task
|
||||||
|
)}
|
||||||
|
</Fragment>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{checkIfJoinsAvailable(row.original.name) && (
|
{checkIfJoinsAvailable(row.original.name) && (
|
||||||
|
@ -17,6 +17,7 @@ import React, { RefObject, useCallback, useEffect, useState } from 'react';
|
|||||||
import AppState from '../../AppState';
|
import AppState from '../../AppState';
|
||||||
import { FQN_SEPARATOR_CHAR } from '../../constants/char.constants';
|
import { FQN_SEPARATOR_CHAR } from '../../constants/char.constants';
|
||||||
import { getTeamAndUserDetailsPath } from '../../constants/constants';
|
import { getTeamAndUserDetailsPath } from '../../constants/constants';
|
||||||
|
import { EntityField } from '../../constants/feed.constants';
|
||||||
import { observerOptions } from '../../constants/Mydata.constants';
|
import { observerOptions } from '../../constants/Mydata.constants';
|
||||||
import { EntityType } from '../../enums/entity.enum';
|
import { EntityType } from '../../enums/entity.enum';
|
||||||
import { OwnerType } from '../../enums/user.enum';
|
import { OwnerType } from '../../enums/user.enum';
|
||||||
@ -392,7 +393,7 @@ const PipelineDetails = ({
|
|||||||
<Description
|
<Description
|
||||||
description={description}
|
description={description}
|
||||||
entityFieldThreads={getEntityFieldThreadCounts(
|
entityFieldThreads={getEntityFieldThreadCounts(
|
||||||
'description',
|
EntityField.DESCRIPTION,
|
||||||
entityFieldThreadCount
|
entityFieldThreadCount
|
||||||
)}
|
)}
|
||||||
entityFqn={pipelineFQN}
|
entityFqn={pipelineFQN}
|
||||||
|
@ -17,6 +17,7 @@ import { ExtraInfo } from 'Models';
|
|||||||
import React, { FC, useEffect, useState } from 'react';
|
import React, { FC, useEffect, useState } from 'react';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { FQN_SEPARATOR_CHAR } from '../../constants/char.constants';
|
import { FQN_SEPARATOR_CHAR } from '../../constants/char.constants';
|
||||||
|
import { EntityField } from '../../constants/feed.constants';
|
||||||
import { OwnerType } from '../../enums/user.enum';
|
import { OwnerType } from '../../enums/user.enum';
|
||||||
import { ChangeDescription } from '../../generated/entity/data/pipeline';
|
import { ChangeDescription } from '../../generated/entity/data/pipeline';
|
||||||
import { TagLabel } from '../../generated/type/tagLabel';
|
import { TagLabel } from '../../generated/type/tagLabel';
|
||||||
@ -68,7 +69,7 @@ const PipelineVersion: FC<PipelineVersionProp> = ({
|
|||||||
|
|
||||||
const getPipelineDescription = () => {
|
const getPipelineDescription = () => {
|
||||||
const descriptionDiff = getDiffByFieldName(
|
const descriptionDiff = getDiffByFieldName(
|
||||||
'description',
|
EntityField.DESCRIPTION,
|
||||||
changeDescription
|
changeDescription
|
||||||
);
|
);
|
||||||
const oldDescription =
|
const oldDescription =
|
||||||
|
@ -16,17 +16,20 @@ import { Button, Popover } from 'antd';
|
|||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React, { useMemo } from 'react';
|
import React, { useEffect, useMemo, useState } from 'react';
|
||||||
import AppState from '../../AppState';
|
import AppState from '../../AppState';
|
||||||
import { REACTION_LIST } from '../../constants/reactions.constant';
|
import { REACTION_LIST } from '../../constants/reactions.constant';
|
||||||
import { ReactionOperation } from '../../enums/reactions.enum';
|
import { ReactionOperation } from '../../enums/reactions.enum';
|
||||||
import useImage from '../../hooks/useImage';
|
import useImage from '../../hooks/useImage';
|
||||||
|
|
||||||
const Emoji = ({ reaction, reactionList, onReactionSelect }) => {
|
const Emoji = ({ reaction, reactionList, onReactionSelect }) => {
|
||||||
// get reaction object based on cureent reaction
|
const [reactionType, setReactionType] = useState(reaction);
|
||||||
|
const [isClicked, setIsClicked] = useState(false);
|
||||||
|
|
||||||
|
// get reaction object based on cureent reactionType
|
||||||
const reactionObject = useMemo(
|
const reactionObject = useMemo(
|
||||||
() => REACTION_LIST.find((value) => value.reaction === reaction),
|
() => REACTION_LIST.find((value) => value.reaction === reactionType),
|
||||||
[reaction]
|
[reactionType]
|
||||||
);
|
);
|
||||||
|
|
||||||
const { image } = useImage(`emojis/${reactionObject.reaction}.png`);
|
const { image } = useImage(`emojis/${reactionObject.reaction}.png`);
|
||||||
@ -45,10 +48,13 @@ const Emoji = ({ reaction, reactionList, onReactionSelect }) => {
|
|||||||
const userList = reactionList.map((reactionItem) => reactionItem.user.name);
|
const userList = reactionList.map((reactionItem) => reactionItem.user.name);
|
||||||
|
|
||||||
const handleOnClick = () => {
|
const handleOnClick = () => {
|
||||||
const operation = isReacted
|
if (!isClicked) {
|
||||||
? ReactionOperation.REMOVE
|
const operation = isReacted
|
||||||
: ReactionOperation.ADD;
|
? ReactionOperation.REMOVE
|
||||||
onReactionSelect(reactionObject.reaction, operation);
|
: ReactionOperation.ADD;
|
||||||
|
onReactionSelect(reactionObject.reaction, operation);
|
||||||
|
setIsClicked(true);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const popoverContent = (
|
const popoverContent = (
|
||||||
@ -56,10 +62,15 @@ const Emoji = ({ reaction, reactionList, onReactionSelect }) => {
|
|||||||
className="tw-w-44 tw-break-normal tw-m-0 tw-p-0"
|
className="tw-w-44 tw-break-normal tw-m-0 tw-p-0"
|
||||||
data-testid="popover-content">
|
data-testid="popover-content">
|
||||||
{`${userList.join(', ')}`}{' '}
|
{`${userList.join(', ')}`}{' '}
|
||||||
<span className="tw-font-semibold">{`reacted with ${reaction} emoji`}</span>
|
<span className="tw-font-semibold">{`reacted with ${reactionType} emoji`}</span>
|
||||||
</p>
|
</p>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setReactionType(reaction);
|
||||||
|
setIsClicked(false);
|
||||||
|
}, [reaction]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Popover
|
<Popover
|
||||||
destroyTooltipOnHide
|
destroyTooltipOnHide
|
||||||
|
@ -19,6 +19,7 @@ import {
|
|||||||
Table,
|
Table,
|
||||||
TableData,
|
TableData,
|
||||||
} from '../../generated/entity/data/table';
|
} from '../../generated/entity/data/table';
|
||||||
|
import { ThreadType } from '../../generated/entity/feed/thread';
|
||||||
import Searchbar from '../common/searchbar/Searchbar';
|
import Searchbar from '../common/searchbar/Searchbar';
|
||||||
import EntityTable from '../EntityTable/EntityTable.component';
|
import EntityTable from '../EntityTable/EntityTable.component';
|
||||||
|
|
||||||
@ -33,7 +34,8 @@ type Props = {
|
|||||||
isReadOnly?: boolean;
|
isReadOnly?: boolean;
|
||||||
entityFqn?: string;
|
entityFqn?: string;
|
||||||
entityFieldThreads?: EntityFieldThreads[];
|
entityFieldThreads?: EntityFieldThreads[];
|
||||||
onThreadLinkSelect?: (value: string) => void;
|
entityFieldTasks?: EntityFieldThreads[];
|
||||||
|
onThreadLinkSelect?: (value: string, threadType?: ThreadType) => void;
|
||||||
onEntityFieldSelect?: (value: string) => void;
|
onEntityFieldSelect?: (value: string) => void;
|
||||||
onUpdate?: (columns: Table['columns']) => void;
|
onUpdate?: (columns: Table['columns']) => void;
|
||||||
};
|
};
|
||||||
@ -51,6 +53,7 @@ const SchemaTab: FunctionComponent<Props> = ({
|
|||||||
isReadOnly = false,
|
isReadOnly = false,
|
||||||
entityFqn,
|
entityFqn,
|
||||||
tableConstraints,
|
tableConstraints,
|
||||||
|
entityFieldTasks,
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
const [searchText, setSearchText] = useState('');
|
const [searchText, setSearchText] = useState('');
|
||||||
|
|
||||||
@ -75,6 +78,7 @@ const SchemaTab: FunctionComponent<Props> = ({
|
|||||||
<div className="col-sm-12">
|
<div className="col-sm-12">
|
||||||
<EntityTable
|
<EntityTable
|
||||||
columnName={columnName}
|
columnName={columnName}
|
||||||
|
entityFieldTasks={entityFieldTasks}
|
||||||
entityFieldThreads={entityFieldThreads}
|
entityFieldThreads={entityFieldThreads}
|
||||||
entityFqn={entityFqn}
|
entityFqn={entityFqn}
|
||||||
hasEditAccess={Boolean(hasEditAccess)}
|
hasEditAccess={Boolean(hasEditAccess)}
|
||||||
|
@ -22,6 +22,7 @@ import React, {
|
|||||||
import AppState from '../../AppState';
|
import AppState from '../../AppState';
|
||||||
import { FQN_SEPARATOR_CHAR } from '../../constants/char.constants';
|
import { FQN_SEPARATOR_CHAR } from '../../constants/char.constants';
|
||||||
import { getTeamAndUserDetailsPath } from '../../constants/constants';
|
import { getTeamAndUserDetailsPath } from '../../constants/constants';
|
||||||
|
import { EntityField } from '../../constants/feed.constants';
|
||||||
import { observerOptions } from '../../constants/Mydata.constants';
|
import { observerOptions } from '../../constants/Mydata.constants';
|
||||||
import { EntityType } from '../../enums/entity.enum';
|
import { EntityType } from '../../enums/entity.enum';
|
||||||
import { OwnerType } from '../../enums/user.enum';
|
import { OwnerType } from '../../enums/user.enum';
|
||||||
@ -407,7 +408,7 @@ const TopicDetails: React.FC<TopicDetailsProps> = ({
|
|||||||
<Description
|
<Description
|
||||||
description={description}
|
description={description}
|
||||||
entityFieldThreads={getEntityFieldThreadCounts(
|
entityFieldThreads={getEntityFieldThreadCounts(
|
||||||
'description',
|
EntityField.DESCRIPTION,
|
||||||
entityFieldThreadCount
|
entityFieldThreadCount
|
||||||
)}
|
)}
|
||||||
entityFqn={topicFQN}
|
entityFqn={topicFQN}
|
||||||
|
@ -16,6 +16,7 @@ import { isUndefined } from 'lodash';
|
|||||||
import { ExtraInfo } from 'Models';
|
import { ExtraInfo } from 'Models';
|
||||||
import React, { FC, useEffect, useState } from 'react';
|
import React, { FC, useEffect, useState } from 'react';
|
||||||
import { FQN_SEPARATOR_CHAR } from '../../constants/char.constants';
|
import { FQN_SEPARATOR_CHAR } from '../../constants/char.constants';
|
||||||
|
import { EntityField } from '../../constants/feed.constants';
|
||||||
import { OwnerType } from '../../enums/user.enum';
|
import { OwnerType } from '../../enums/user.enum';
|
||||||
import { ChangeDescription } from '../../generated/entity/data/topic';
|
import { ChangeDescription } from '../../generated/entity/data/topic';
|
||||||
import { TagLabel } from '../../generated/type/tagLabel';
|
import { TagLabel } from '../../generated/type/tagLabel';
|
||||||
@ -99,7 +100,7 @@ const TopicVersion: FC<TopicVersionProp> = ({
|
|||||||
|
|
||||||
const getTableDescription = () => {
|
const getTableDescription = () => {
|
||||||
const descriptionDiff = getDiffByFieldName(
|
const descriptionDiff = getDiffByFieldName(
|
||||||
'description',
|
EntityField.DESCRIPTION,
|
||||||
changeDescription
|
changeDescription
|
||||||
);
|
);
|
||||||
const oldDescription =
|
const oldDescription =
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
import { EntityFieldThreads } from 'Models';
|
import { EntityFieldThreads } from 'Models';
|
||||||
import { Table } from '../../../generated/entity/data/table';
|
import { Table } from '../../../generated/entity/data/table';
|
||||||
|
import { ThreadType } from '../../../generated/entity/feed/thread';
|
||||||
|
|
||||||
export interface DescriptionProps {
|
export interface DescriptionProps {
|
||||||
entityName?: string;
|
entityName?: string;
|
||||||
@ -26,7 +27,8 @@ export interface DescriptionProps {
|
|||||||
entityType?: string;
|
entityType?: string;
|
||||||
entityFqn?: string;
|
entityFqn?: string;
|
||||||
entityFieldThreads?: EntityFieldThreads[];
|
entityFieldThreads?: EntityFieldThreads[];
|
||||||
onThreadLinkSelect?: (value: string) => void;
|
entityFieldTasks?: EntityFieldThreads[];
|
||||||
|
onThreadLinkSelect?: (value: string, threadType?: ThreadType) => void;
|
||||||
onDescriptionEdit?: () => void;
|
onDescriptionEdit?: () => void;
|
||||||
onCancel?: () => void;
|
onCancel?: () => void;
|
||||||
onDescriptionUpdate?: (value: string) => void;
|
onDescriptionUpdate?: (value: string) => void;
|
||||||
|
@ -11,14 +11,15 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { Popover } from 'antd';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { isUndefined } from 'lodash';
|
import { isUndefined } from 'lodash';
|
||||||
import { EntityFieldThreads } from 'Models';
|
import { EntityFieldThreads } from 'Models';
|
||||||
import React, { FC, Fragment } from 'react';
|
import React, { FC, Fragment } from 'react';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
import { useAuthContext } from '../../../authentication/auth-provider/AuthProvider';
|
import { useAuthContext } from '../../../authentication/auth-provider/AuthProvider';
|
||||||
import { TITLE_FOR_UPDATE_DESCRIPTION } from '../../../constants/constants';
|
import { EntityField } from '../../../constants/feed.constants';
|
||||||
import { EntityType } from '../../../enums/entity.enum';
|
import { ThreadType } from '../../../generated/entity/feed/thread';
|
||||||
import { Operation } from '../../../generated/entity/policies/accessControl/rule';
|
import { Operation } from '../../../generated/entity/policies/accessControl/rule';
|
||||||
import { useAuth } from '../../../hooks/authHooks';
|
import { useAuth } from '../../../hooks/authHooks';
|
||||||
import { getEntityFeedLink } from '../../../utils/EntityUtils';
|
import { getEntityFeedLink } from '../../../utils/EntityUtils';
|
||||||
@ -26,11 +27,8 @@ import SVGIcons, { Icons } from '../../../utils/SvgUtils';
|
|||||||
import {
|
import {
|
||||||
getRequestDescriptionPath,
|
getRequestDescriptionPath,
|
||||||
getUpdateDescriptionPath,
|
getUpdateDescriptionPath,
|
||||||
TASK_ENTITIES,
|
|
||||||
} from '../../../utils/TasksUtils';
|
} from '../../../utils/TasksUtils';
|
||||||
import { ModalWithMarkdownEditor } from '../../Modals/ModalWithMarkdownEditor/ModalWithMarkdownEditor';
|
import { ModalWithMarkdownEditor } from '../../Modals/ModalWithMarkdownEditor/ModalWithMarkdownEditor';
|
||||||
import NonAdminAction from '../non-admin-action/NonAdminAction';
|
|
||||||
import PopOver from '../popover/PopOver';
|
|
||||||
import RichTextEditorPreviewer from '../rich-text-editor/RichTextEditorPreviewer';
|
import RichTextEditorPreviewer from '../rich-text-editor/RichTextEditorPreviewer';
|
||||||
import { DescriptionProps } from './Description.interface';
|
import { DescriptionProps } from './Description.interface';
|
||||||
|
|
||||||
@ -50,6 +48,7 @@ const Description: FC<DescriptionProps> = ({
|
|||||||
onEntityFieldSelect,
|
onEntityFieldSelect,
|
||||||
entityType,
|
entityType,
|
||||||
entityFqn,
|
entityFqn,
|
||||||
|
entityFieldTasks,
|
||||||
}) => {
|
}) => {
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
|
|
||||||
@ -57,6 +56,7 @@ const Description: FC<DescriptionProps> = ({
|
|||||||
const { isAuthDisabled } = useAuthContext();
|
const { isAuthDisabled } = useAuthContext();
|
||||||
|
|
||||||
const thread = entityFieldThreads?.[0];
|
const thread = entityFieldThreads?.[0];
|
||||||
|
const tasks = entityFieldTasks?.[0];
|
||||||
|
|
||||||
const handleRequestDescription = () => {
|
const handleRequestDescription = () => {
|
||||||
history.push(
|
history.push(
|
||||||
@ -71,45 +71,44 @@ const Description: FC<DescriptionProps> = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const checkPermission = () => {
|
const checkPermission = () => {
|
||||||
if (!isAuthDisabled && !isAdminUser) {
|
return (
|
||||||
return Boolean(
|
isAdminUser ||
|
||||||
hasEditAccess || userPermissions[Operation.UpdateDescription]
|
Boolean(hasEditAccess) ||
|
||||||
);
|
userPermissions[Operation.UpdateDescription] ||
|
||||||
}
|
isAuthDisabled
|
||||||
|
);
|
||||||
return true;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleUpdate = () => {
|
const handleUpdate = () => {
|
||||||
if (checkPermission()) {
|
onDescriptionEdit && onDescriptionEdit();
|
||||||
onDescriptionEdit && onDescriptionEdit();
|
|
||||||
} else if (TASK_ENTITIES.includes(entityType as EntityType)) {
|
|
||||||
handleUpdateDescription();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const RequestDescriptionEl = ({
|
const RequestDescriptionEl = () => {
|
||||||
descriptionThread,
|
const hasDescription = Boolean(description.trim());
|
||||||
}: {
|
|
||||||
descriptionThread?: EntityFieldThreads;
|
return onEntityFieldSelect ? (
|
||||||
}) => {
|
|
||||||
return isUndefined(descriptionThread) &&
|
|
||||||
onEntityFieldSelect &&
|
|
||||||
!description?.trim() ? (
|
|
||||||
<button
|
<button
|
||||||
className="focus:tw-outline-none tw-ml-2 tw--mt-6"
|
className="tw-w-8 tw-h-8 tw-mr-1 tw-flex-none link-text focus:tw-outline-none"
|
||||||
data-testid="request-description"
|
data-testid="request-description"
|
||||||
onClick={handleRequestDescription}>
|
onClick={
|
||||||
<PopOver
|
hasDescription ? handleUpdateDescription : handleRequestDescription
|
||||||
position="top"
|
}>
|
||||||
title="Request description"
|
<Popover
|
||||||
trigger="mouseenter">
|
destroyTooltipOnHide
|
||||||
|
content={
|
||||||
|
hasDescription
|
||||||
|
? 'Request update description'
|
||||||
|
: 'Request description'
|
||||||
|
}
|
||||||
|
overlayClassName="ant-popover-request-description"
|
||||||
|
trigger="hover"
|
||||||
|
zIndex={9999}>
|
||||||
<SVGIcons
|
<SVGIcons
|
||||||
alt="request-description"
|
alt="request-description"
|
||||||
className="tw-mt-2"
|
|
||||||
icon={Icons.REQUEST}
|
icon={Icons.REQUEST}
|
||||||
|
width="16px"
|
||||||
/>
|
/>
|
||||||
</PopOver>
|
</Popover>
|
||||||
</button>
|
</button>
|
||||||
) : null;
|
) : null;
|
||||||
};
|
};
|
||||||
@ -120,8 +119,8 @@ const Description: FC<DescriptionProps> = ({
|
|||||||
descriptionThread?: EntityFieldThreads;
|
descriptionThread?: EntityFieldThreads;
|
||||||
}) => {
|
}) => {
|
||||||
return !isUndefined(descriptionThread) ? (
|
return !isUndefined(descriptionThread) ? (
|
||||||
<p
|
<button
|
||||||
className="link-text tw-ml-2 tw-w-8 tw-h-8 tw-flex-none"
|
className="tw-w-8 tw-h-8 tw-mr-2 tw-flex-none link-text focus:tw-outline-none"
|
||||||
data-testid="description-thread"
|
data-testid="description-thread"
|
||||||
onClick={() => onThreadLinkSelect?.(descriptionThread.entityLink)}>
|
onClick={() => onThreadLinkSelect?.(descriptionThread.entityLink)}>
|
||||||
<span className="tw-flex">
|
<span className="tw-flex">
|
||||||
@ -131,48 +130,61 @@ const Description: FC<DescriptionProps> = ({
|
|||||||
{descriptionThread.count}
|
{descriptionThread.count}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</button>
|
||||||
) : (
|
) : (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
{description?.trim() && onThreadLinkSelect ? (
|
{description?.trim() && onThreadLinkSelect ? (
|
||||||
<p
|
<button
|
||||||
className="link-text tw-flex-none tw-ml-2"
|
className="tw-w-8 tw-h-8 tw-mr-2 tw-flex-none link-text focus:tw-outline-none"
|
||||||
data-testid="start-description-thread"
|
data-testid="start-description-thread"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
onThreadLinkSelect?.(
|
onThreadLinkSelect?.(
|
||||||
getEntityFeedLink(entityType, entityFqn, 'description')
|
getEntityFeedLink(
|
||||||
|
entityType,
|
||||||
|
entityFqn,
|
||||||
|
EntityField.DESCRIPTION
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}>
|
}>
|
||||||
<SVGIcons alt="comments" icon={Icons.COMMENT_PLUS} width="20px" />
|
<SVGIcons alt="comments" icon={Icons.COMMENT_PLUS} width="20px" />
|
||||||
</p>
|
</button>
|
||||||
) : null}
|
) : null}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getDescriptionTaskElement = () => {
|
||||||
|
return !isUndefined(tasks) ? (
|
||||||
|
<button
|
||||||
|
className="tw-w-8 tw-h-8 tw-mr-2 tw-flex-none link-text focus:tw-outline-none"
|
||||||
|
data-testid="description-task"
|
||||||
|
onClick={() => onThreadLinkSelect?.(tasks.entityLink, ThreadType.Task)}>
|
||||||
|
<span className="tw-flex">
|
||||||
|
<SVGIcons alt="tasks" icon={Icons.TASK_ICON} width="16px" />{' '}
|
||||||
|
<span className="tw-ml-1" data-testid="description-tasks-count">
|
||||||
|
{' '}
|
||||||
|
{tasks.count}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
) : null;
|
||||||
|
};
|
||||||
|
|
||||||
const DescriptionActions = () => {
|
const DescriptionActions = () => {
|
||||||
return !isReadOnly ? (
|
return !isReadOnly ? (
|
||||||
<div
|
<div className={classNames('tw-w-5 tw-min-w-max tw-flex tw--mt-0.5')}>
|
||||||
className={classNames(
|
{checkPermission() && (
|
||||||
'tw-w-5 tw-min-w-max tw-flex',
|
|
||||||
description?.trim() ? 'tw-pl-1' : ''
|
|
||||||
)}>
|
|
||||||
<NonAdminAction
|
|
||||||
isOwner={
|
|
||||||
checkPermission() ||
|
|
||||||
TASK_ENTITIES.includes(entityType as EntityType)
|
|
||||||
}
|
|
||||||
title={TITLE_FOR_UPDATE_DESCRIPTION}>
|
|
||||||
<button
|
<button
|
||||||
className="focus:tw-outline-none tw-self-baseline"
|
className="tw-w-7 tw-h-8 tw-flex-none focus:tw-outline-none"
|
||||||
data-testid="edit-description"
|
data-testid="edit-description"
|
||||||
onClick={handleUpdate}>
|
onClick={handleUpdate}>
|
||||||
<SVGIcons alt="edit" icon="icon-edit" title="Edit" width="16px" />
|
<SVGIcons alt="edit" icon="icon-edit" title="Edit" width="16px" />
|
||||||
</button>
|
</button>
|
||||||
</NonAdminAction>
|
)}
|
||||||
|
|
||||||
<RequestDescriptionEl descriptionThread={thread} />
|
<RequestDescriptionEl />
|
||||||
<DescriptionThreadEl descriptionThread={thread} />
|
<DescriptionThreadEl descriptionThread={thread} />
|
||||||
|
{getDescriptionTaskElement()}
|
||||||
</div>
|
</div>
|
||||||
) : null;
|
) : null;
|
||||||
};
|
};
|
||||||
|
@ -15,6 +15,7 @@ import classNames from 'classnames';
|
|||||||
import { isUndefined } from 'lodash';
|
import { isUndefined } from 'lodash';
|
||||||
import { EntityFieldThreads } from 'Models';
|
import { EntityFieldThreads } from 'Models';
|
||||||
import React, { Fragment } from 'react';
|
import React, { Fragment } from 'react';
|
||||||
|
import { EntityField } from '../../../constants/feed.constants';
|
||||||
import { Table } from '../../../generated/entity/data/table';
|
import { Table } from '../../../generated/entity/data/table';
|
||||||
import { Operation } from '../../../generated/entity/policies/accessControl/rule';
|
import { Operation } from '../../../generated/entity/policies/accessControl/rule';
|
||||||
import { getHtmlForNonAdminAction } from '../../../utils/CommonUtils';
|
import { getHtmlForNonAdminAction } from '../../../utils/CommonUtils';
|
||||||
@ -130,7 +131,7 @@ const DescriptionV1 = ({
|
|||||||
<button
|
<button
|
||||||
className="focus:tw-outline-none tw-ml-2 tw--mt-6"
|
className="focus:tw-outline-none tw-ml-2 tw--mt-6"
|
||||||
data-testid="request-description"
|
data-testid="request-description"
|
||||||
onClick={() => onEntityFieldSelect?.('description')}>
|
onClick={() => onEntityFieldSelect?.(EntityField.DESCRIPTION)}>
|
||||||
<PopOver
|
<PopOver
|
||||||
position="top"
|
position="top"
|
||||||
title="Request description"
|
title="Request description"
|
||||||
@ -168,7 +169,11 @@ const DescriptionV1 = ({
|
|||||||
data-testid="start-description-thread"
|
data-testid="start-description-thread"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
onThreadLinkSelect?.(
|
onThreadLinkSelect?.(
|
||||||
getEntityFeedLink(entityType, entityFqn, 'description')
|
getEntityFeedLink(
|
||||||
|
entityType,
|
||||||
|
entityFqn,
|
||||||
|
EntityField.DESCRIPTION
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}>
|
}>
|
||||||
<SVGIcons
|
<SVGIcons
|
||||||
|
@ -62,3 +62,15 @@ export enum TaskOperation {
|
|||||||
RESOLVE = 'resolve',
|
RESOLVE = 'resolve',
|
||||||
REJECT = 'close',
|
REJECT = 'close',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum PanelTab {
|
||||||
|
TASKS = 'tasks',
|
||||||
|
CONVERSATIONS = 'conversations',
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum EntityField {
|
||||||
|
DESCRIPTION = 'description',
|
||||||
|
COLUMNS = 'columns',
|
||||||
|
TAGS = 'tags',
|
||||||
|
TASKS = 'tasks',
|
||||||
|
}
|
||||||
|
@ -56,6 +56,7 @@ import {
|
|||||||
getServiceDetailsPath,
|
getServiceDetailsPath,
|
||||||
getTeamAndUserDetailsPath,
|
getTeamAndUserDetailsPath,
|
||||||
} from '../../constants/constants';
|
} from '../../constants/constants';
|
||||||
|
import { EntityField } from '../../constants/feed.constants';
|
||||||
import { observerOptions } from '../../constants/Mydata.constants';
|
import { observerOptions } from '../../constants/Mydata.constants';
|
||||||
import { EntityType, FqnPart, TabSpecificField } from '../../enums/entity.enum';
|
import { EntityType, FqnPart, TabSpecificField } from '../../enums/entity.enum';
|
||||||
import { ServiceCategory } from '../../enums/service.enum';
|
import { ServiceCategory } from '../../enums/service.enum';
|
||||||
@ -657,7 +658,7 @@ const DatabaseSchemaPage: FunctionComponent = () => {
|
|||||||
blurWithBodyBG
|
blurWithBodyBG
|
||||||
description={description}
|
description={description}
|
||||||
entityFieldThreads={getEntityFieldThreadCounts(
|
entityFieldThreads={getEntityFieldThreadCounts(
|
||||||
'description',
|
EntityField.DESCRIPTION,
|
||||||
entityFieldThreadCount
|
entityFieldThreadCount
|
||||||
)}
|
)}
|
||||||
entityFqn={databaseSchemaFQN}
|
entityFqn={databaseSchemaFQN}
|
||||||
|
@ -27,7 +27,6 @@ import { useHistory, useParams } from 'react-router-dom';
|
|||||||
import AppState from '../../AppState';
|
import AppState from '../../AppState';
|
||||||
import {
|
import {
|
||||||
getAllFeeds,
|
getAllFeeds,
|
||||||
getFeedCount,
|
|
||||||
postFeedById,
|
postFeedById,
|
||||||
postThread,
|
postThread,
|
||||||
} from '../../axiosAPIs/feedsAPI';
|
} from '../../axiosAPIs/feedsAPI';
|
||||||
@ -90,6 +89,7 @@ import {
|
|||||||
getCurrentUserId,
|
getCurrentUserId,
|
||||||
getEntityMissingError,
|
getEntityMissingError,
|
||||||
getEntityName,
|
getEntityName,
|
||||||
|
getFeedCounts,
|
||||||
getFields,
|
getFields,
|
||||||
getPartialNameFromTableFQN,
|
getPartialNameFromTableFQN,
|
||||||
} from '../../utils/CommonUtils';
|
} from '../../utils/CommonUtils';
|
||||||
@ -174,6 +174,9 @@ const DatasetDetailsPage: FunctionComponent = () => {
|
|||||||
const [entityFieldThreadCount, setEntityFieldThreadCount] = useState<
|
const [entityFieldThreadCount, setEntityFieldThreadCount] = useState<
|
||||||
EntityFieldThreadCount[]
|
EntityFieldThreadCount[]
|
||||||
>([]);
|
>([]);
|
||||||
|
const [entityFieldTaskCount, setEntityFieldTaskCount] = useState<
|
||||||
|
EntityFieldThreadCount[]
|
||||||
|
>([]);
|
||||||
|
|
||||||
// Data Quality tab state
|
// Data Quality tab state
|
||||||
const [testMode, setTestMode] = useState<DatasetTestModeType>('table');
|
const [testMode, setTestMode] = useState<DatasetTestModeType>('table');
|
||||||
@ -490,23 +493,13 @@ const DatasetDetailsPage: FunctionComponent = () => {
|
|||||||
}, [activeTab]);
|
}, [activeTab]);
|
||||||
|
|
||||||
const getEntityFeedCount = () => {
|
const getEntityFeedCount = () => {
|
||||||
getFeedCount(getEntityFeedLink(EntityType.TABLE, tableFQN))
|
getFeedCounts(
|
||||||
.then((res: AxiosResponse) => {
|
EntityType.TABLE,
|
||||||
if (res.data) {
|
tableFQN,
|
||||||
setFeedCount(res.data.totalCount);
|
setEntityFieldThreadCount,
|
||||||
setEntityFieldThreadCount(res.data.counts);
|
setEntityFieldTaskCount,
|
||||||
} else {
|
setFeedCount
|
||||||
showErrorToast(
|
);
|
||||||
jsonData['api-error-messages']['fetch-entity-feed-count-error']
|
|
||||||
);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((err: AxiosError) => {
|
|
||||||
showErrorToast(
|
|
||||||
err,
|
|
||||||
jsonData['api-error-messages']['fetch-entity-feed-count-error']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const saveUpdatedTableData = (updatedData: Table): Promise<AxiosResponse> => {
|
const saveUpdatedTableData = (updatedData: Table): Promise<AxiosResponse> => {
|
||||||
@ -1030,6 +1023,7 @@ const DatasetDetailsPage: FunctionComponent = () => {
|
|||||||
deleted={deleted}
|
deleted={deleted}
|
||||||
description={description}
|
description={description}
|
||||||
descriptionUpdateHandler={descriptionUpdateHandler}
|
descriptionUpdateHandler={descriptionUpdateHandler}
|
||||||
|
entityFieldTaskCount={entityFieldTaskCount}
|
||||||
entityFieldThreadCount={entityFieldThreadCount}
|
entityFieldThreadCount={entityFieldThreadCount}
|
||||||
entityLineage={entityLineage}
|
entityLineage={entityLineage}
|
||||||
entityLineageHandler={entityLineageHandler}
|
entityLineageHandler={entityLineageHandler}
|
||||||
|
@ -31,6 +31,7 @@ import ProfilePicture from '../../../components/common/ProfilePicture/ProfilePic
|
|||||||
import RichTextEditor from '../../../components/common/rich-text-editor/RichTextEditor';
|
import RichTextEditor from '../../../components/common/rich-text-editor/RichTextEditor';
|
||||||
import TitleBreadcrumb from '../../../components/common/title-breadcrumb/title-breadcrumb.component';
|
import TitleBreadcrumb from '../../../components/common/title-breadcrumb/title-breadcrumb.component';
|
||||||
import { FQN_SEPARATOR_CHAR } from '../../../constants/char.constants';
|
import { FQN_SEPARATOR_CHAR } from '../../../constants/char.constants';
|
||||||
|
import { EntityField } from '../../../constants/feed.constants';
|
||||||
import { EntityType } from '../../../enums/entity.enum';
|
import { EntityType } from '../../../enums/entity.enum';
|
||||||
import {
|
import {
|
||||||
CreateThread,
|
CreateThread,
|
||||||
@ -99,7 +100,7 @@ const RequestDescription = () => {
|
|||||||
const back = () => history.goBack();
|
const back = () => history.goBack();
|
||||||
|
|
||||||
const getColumnDetails = useCallback(() => {
|
const getColumnDetails = useCallback(() => {
|
||||||
if (!isNil(field) && !isNil(value) && field === 'columns') {
|
if (!isNil(field) && !isNil(value) && field === EntityField.COLUMNS) {
|
||||||
const column = getSanitizeValue.split(FQN_SEPARATOR_CHAR).slice(-1);
|
const column = getSanitizeValue.split(FQN_SEPARATOR_CHAR).slice(-1);
|
||||||
|
|
||||||
const columnObject = getColumnObject(column[0], entityData.columns || []);
|
const columnObject = getColumnObject(column[0], entityData.columns || []);
|
||||||
@ -127,7 +128,7 @@ const RequestDescription = () => {
|
|||||||
if (field && value) {
|
if (field && value) {
|
||||||
return `${field}${ENTITY_LINK_SEPARATOR}${value}${ENTITY_LINK_SEPARATOR}description`;
|
return `${field}${ENTITY_LINK_SEPARATOR}${value}${ENTITY_LINK_SEPARATOR}description`;
|
||||||
} else {
|
} else {
|
||||||
return 'description';
|
return EntityField.DESCRIPTION;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ import { postThread } from '../../../axiosAPIs/feedsAPI';
|
|||||||
import ProfilePicture from '../../../components/common/ProfilePicture/ProfilePicture';
|
import ProfilePicture from '../../../components/common/ProfilePicture/ProfilePicture';
|
||||||
import TitleBreadcrumb from '../../../components/common/title-breadcrumb/title-breadcrumb.component';
|
import TitleBreadcrumb from '../../../components/common/title-breadcrumb/title-breadcrumb.component';
|
||||||
import { FQN_SEPARATOR_CHAR } from '../../../constants/char.constants';
|
import { FQN_SEPARATOR_CHAR } from '../../../constants/char.constants';
|
||||||
|
import { EntityField } from '../../../constants/feed.constants';
|
||||||
import { EntityType } from '../../../enums/entity.enum';
|
import { EntityType } from '../../../enums/entity.enum';
|
||||||
import {
|
import {
|
||||||
CreateThread,
|
CreateThread,
|
||||||
@ -104,7 +105,7 @@ const UpdateDescription = () => {
|
|||||||
}, [field, entityData]);
|
}, [field, entityData]);
|
||||||
|
|
||||||
const getColumnDetails = useCallback(() => {
|
const getColumnDetails = useCallback(() => {
|
||||||
if (!isNil(field) && !isNil(value) && field === 'columns') {
|
if (!isNil(field) && !isNil(value) && field === EntityField.COLUMNS) {
|
||||||
return (
|
return (
|
||||||
<div data-testid="column-details">
|
<div data-testid="column-details">
|
||||||
<p className="tw-font-semibold">Column Details</p>
|
<p className="tw-font-semibold">Column Details</p>
|
||||||
@ -136,7 +137,7 @@ const UpdateDescription = () => {
|
|||||||
if (field && value) {
|
if (field && value) {
|
||||||
return `${field}${ENTITY_LINK_SEPARATOR}${value}${ENTITY_LINK_SEPARATOR}description`;
|
return `${field}${ENTITY_LINK_SEPARATOR}${value}${ENTITY_LINK_SEPARATOR}description`;
|
||||||
} else {
|
} else {
|
||||||
return 'description';
|
return EntityField.DESCRIPTION;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -61,6 +61,7 @@ import {
|
|||||||
PAGE_SIZE,
|
PAGE_SIZE,
|
||||||
pagingObject,
|
pagingObject,
|
||||||
} from '../../constants/constants';
|
} from '../../constants/constants';
|
||||||
|
import { EntityField } from '../../constants/feed.constants';
|
||||||
import { observerOptions } from '../../constants/Mydata.constants';
|
import { observerOptions } from '../../constants/Mydata.constants';
|
||||||
import { EntityType, TabSpecificField } from '../../enums/entity.enum';
|
import { EntityType, TabSpecificField } from '../../enums/entity.enum';
|
||||||
import { ServiceCategory } from '../../enums/service.enum';
|
import { ServiceCategory } from '../../enums/service.enum';
|
||||||
@ -674,7 +675,7 @@ const DatabaseDetails: FunctionComponent = () => {
|
|||||||
blurWithBodyBG
|
blurWithBodyBG
|
||||||
description={description}
|
description={description}
|
||||||
entityFieldThreads={getEntityFieldThreadCounts(
|
entityFieldThreads={getEntityFieldThreadCounts(
|
||||||
'description',
|
EntityField.DESCRIPTION,
|
||||||
entityFieldThreadCount
|
entityFieldThreadCount
|
||||||
)}
|
)}
|
||||||
entityFqn={databaseFQN}
|
entityFqn={databaseFQN}
|
||||||
|
@ -193,6 +193,7 @@ const TourPage = () => {
|
|||||||
deletePostHandler={handleCountChange}
|
deletePostHandler={handleCountChange}
|
||||||
description={mockDatasetData.description}
|
description={mockDatasetData.description}
|
||||||
descriptionUpdateHandler={handleCountChange}
|
descriptionUpdateHandler={handleCountChange}
|
||||||
|
entityFieldTaskCount={[]}
|
||||||
entityFieldThreadCount={[]}
|
entityFieldThreadCount={[]}
|
||||||
entityLineage={mockDatasetData.entityLineage}
|
entityLineage={mockDatasetData.entityLineage}
|
||||||
entityLineageHandler={handleCountChange}
|
entityLineageHandler={handleCountChange}
|
||||||
|
@ -1132,6 +1132,7 @@ code {
|
|||||||
}
|
}
|
||||||
.ant-popover-feed > .ant-popover-content > .ant-popover-inner,
|
.ant-popover-feed > .ant-popover-content > .ant-popover-inner,
|
||||||
.ant-popover-card > .ant-popover-content > .ant-popover-inner,
|
.ant-popover-card > .ant-popover-content > .ant-popover-inner,
|
||||||
|
.ant-popover-request-description > .ant-popover-content > .ant-popover-inner,
|
||||||
.ant-popover-feed-reactions > .ant-popover-content > .ant-popover-inner {
|
.ant-popover-feed-reactions > .ant-popover-content > .ant-popover-inner {
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
border: 1px solid #dde3ea;
|
border: 1px solid #dde3ea;
|
||||||
@ -1341,3 +1342,7 @@ div.ant-typography-ellipsis-custom {
|
|||||||
color: #7147e8;
|
color: #7147e8;
|
||||||
background-color: #7147e825;
|
background-color: #7147e825;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.table-query-editor pre.CodeMirror-line {
|
||||||
|
padding-right: 60px !important;
|
||||||
|
}
|
||||||
|
@ -11,9 +11,11 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { AxiosError, AxiosResponse } from 'axios';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { capitalize, isEmpty, isNull, isUndefined } from 'lodash';
|
import { capitalize, isEmpty, isNull, isUndefined } from 'lodash';
|
||||||
import {
|
import {
|
||||||
|
EntityFieldThreadCount,
|
||||||
RecentlySearched,
|
RecentlySearched,
|
||||||
RecentlySearchedData,
|
RecentlySearchedData,
|
||||||
RecentlyViewed,
|
RecentlyViewed,
|
||||||
@ -22,6 +24,7 @@ import {
|
|||||||
import React, { FormEvent } from 'react';
|
import React, { FormEvent } from 'react';
|
||||||
import { reactLocalStorage } from 'reactjs-localstorage';
|
import { reactLocalStorage } from 'reactjs-localstorage';
|
||||||
import AppState from '../AppState';
|
import AppState from '../AppState';
|
||||||
|
import { getFeedCount } from '../axiosAPIs/feedsAPI';
|
||||||
import { Button } from '../components/buttons/Button/Button';
|
import { Button } from '../components/buttons/Button/Button';
|
||||||
import { FQN_SEPARATOR_CHAR } from '../constants/char.constants';
|
import { FQN_SEPARATOR_CHAR } from '../constants/char.constants';
|
||||||
import {
|
import {
|
||||||
@ -36,12 +39,15 @@ import {
|
|||||||
} from '../constants/regex.constants';
|
} from '../constants/regex.constants';
|
||||||
import { EntityType, FqnPart, TabSpecificField } from '../enums/entity.enum';
|
import { EntityType, FqnPart, TabSpecificField } from '../enums/entity.enum';
|
||||||
import { Ownership } from '../enums/mydata.enum';
|
import { Ownership } from '../enums/mydata.enum';
|
||||||
|
import { ThreadType } from '../generated/entity/feed/thread';
|
||||||
import { EntityReference, User } from '../generated/entity/teams/user';
|
import { EntityReference, User } from '../generated/entity/teams/user';
|
||||||
import { getTitleCase } from './EntityUtils';
|
import jsonData from '../jsons/en';
|
||||||
|
import { getEntityFeedLink, getTitleCase } from './EntityUtils';
|
||||||
import Fqn from './Fqn';
|
import Fqn from './Fqn';
|
||||||
import { getExplorePathWithInitFilters } from './RouterUtils';
|
import { getExplorePathWithInitFilters } from './RouterUtils';
|
||||||
import { serviceTypeLogo } from './ServiceUtils';
|
import { serviceTypeLogo } from './ServiceUtils';
|
||||||
import SVGIcons, { Icons } from './SvgUtils';
|
import SVGIcons, { Icons } from './SvgUtils';
|
||||||
|
import { showErrorToast } from './ToastUtils';
|
||||||
|
|
||||||
export const arraySorterByKey = (
|
export const arraySorterByKey = (
|
||||||
key: string,
|
key: string,
|
||||||
@ -631,3 +637,48 @@ export const getExploreLinkByFilter = (
|
|||||||
export const replaceSpaceWith_ = (text: string) => {
|
export const replaceSpaceWith_ = (text: string) => {
|
||||||
return text.replace(/\s/g, '_');
|
return text.replace(/\s/g, '_');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getFeedCounts = (
|
||||||
|
entityType: string,
|
||||||
|
entityFQN: string,
|
||||||
|
conversationCallback: (
|
||||||
|
value: React.SetStateAction<EntityFieldThreadCount[]>
|
||||||
|
) => void,
|
||||||
|
taskCallback: (value: React.SetStateAction<EntityFieldThreadCount[]>) => void,
|
||||||
|
entityCallback: (value: React.SetStateAction<number>) => void
|
||||||
|
) => {
|
||||||
|
getFeedCount(
|
||||||
|
getEntityFeedLink(entityType, entityFQN),
|
||||||
|
ThreadType.Conversation
|
||||||
|
)
|
||||||
|
.then((res: AxiosResponse) => {
|
||||||
|
if (res.data) {
|
||||||
|
entityCallback(res.data.totalCount);
|
||||||
|
conversationCallback(res.data.counts);
|
||||||
|
} else {
|
||||||
|
throw jsonData['api-error-messages']['fetch-entity-feed-count-error'];
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((err: AxiosError) => {
|
||||||
|
showErrorToast(
|
||||||
|
err,
|
||||||
|
jsonData['api-error-messages']['fetch-entity-feed-count-error']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
getFeedCount(getEntityFeedLink(entityType, entityFQN), ThreadType.Task)
|
||||||
|
.then((res: AxiosResponse) => {
|
||||||
|
if (res.data) {
|
||||||
|
entityCallback(res.data.totalCount);
|
||||||
|
taskCallback(res.data.counts);
|
||||||
|
} else {
|
||||||
|
throw jsonData['api-error-messages']['fetch-entity-feed-count-error'];
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((err: AxiosError) => {
|
||||||
|
showErrorToast(
|
||||||
|
err,
|
||||||
|
jsonData['api-error-messages']['fetch-entity-feed-count-error']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
@ -26,6 +26,7 @@ import {
|
|||||||
DESCRIPTIONLENGTH,
|
DESCRIPTIONLENGTH,
|
||||||
getTeamAndUserDetailsPath,
|
getTeamAndUserDetailsPath,
|
||||||
} from '../constants/constants';
|
} from '../constants/constants';
|
||||||
|
import { EntityField } from '../constants/feed.constants';
|
||||||
import { ChangeType } from '../enums/entity.enum';
|
import { ChangeType } from '../enums/entity.enum';
|
||||||
import { Column } from '../generated/entity/data/table';
|
import { Column } from '../generated/entity/data/table';
|
||||||
import {
|
import {
|
||||||
@ -301,7 +302,7 @@ export const feedSummaryFromatter = (
|
|||||||
);
|
);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
} else if (fieldChange?.name?.endsWith('description')) {
|
} else if (fieldChange?.name?.endsWith(EntityField.DESCRIPTION)) {
|
||||||
summary = (
|
summary = (
|
||||||
<p key={uniqueId()}>
|
<p key={uniqueId()}>
|
||||||
{`${
|
{`${
|
||||||
@ -321,7 +322,7 @@ export const feedSummaryFromatter = (
|
|||||||
);
|
);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
} else if (fieldChange?.name === 'columns') {
|
} else if (fieldChange?.name === EntityField.COLUMNS) {
|
||||||
const length = value?.length ?? 0;
|
const length = value?.length ?? 0;
|
||||||
summary = (
|
summary = (
|
||||||
<p key={uniqueId()}>
|
<p key={uniqueId()}>
|
||||||
@ -419,7 +420,7 @@ export const feedSummaryFromatter = (
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case fieldChange?.name === 'description': {
|
case fieldChange?.name === EntityField.DESCRIPTION: {
|
||||||
summary = (
|
summary = (
|
||||||
<p key={uniqueId()}>
|
<p key={uniqueId()}>
|
||||||
{`${
|
{`${
|
||||||
@ -523,7 +524,7 @@ export const summaryFormatter = (fieldChange: FieldChange) => {
|
|||||||
? fieldChange?.oldValue
|
? fieldChange?.oldValue
|
||||||
: '{}'
|
: '{}'
|
||||||
);
|
);
|
||||||
if (fieldChange.name === 'columns') {
|
if (fieldChange.name === EntityField.COLUMNS) {
|
||||||
return `columns ${value?.map((val: any) => val?.name).join(', ')}`;
|
return `columns ${value?.map((val: any) => val?.name).join(', ')}`;
|
||||||
} else if (
|
} else if (
|
||||||
fieldChange.name === 'tags' ||
|
fieldChange.name === 'tags' ||
|
||||||
|
@ -11,10 +11,11 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { isEmpty, isUndefined } from 'lodash';
|
import { isEmpty, isEqual, isUndefined } from 'lodash';
|
||||||
import { EntityFieldThreads } from 'Models';
|
import { EntityFieldThreads } from 'Models';
|
||||||
import React, { Fragment } from 'react';
|
import React, { Fragment } from 'react';
|
||||||
import { entityUrlMap } from '../constants/feed.constants';
|
import { entityUrlMap } from '../constants/feed.constants';
|
||||||
|
import { ThreadType } from '../generated/entity/feed/thread';
|
||||||
import { EntityReference } from '../generated/entity/teams/user';
|
import { EntityReference } from '../generated/entity/teams/user';
|
||||||
import { getEntityFeedLink } from './EntityUtils';
|
import { getEntityFeedLink } from './EntityUtils';
|
||||||
import { getThreadField } from './FeedUtils';
|
import { getThreadField } from './FeedUtils';
|
||||||
@ -24,11 +25,12 @@ export const getFieldThreadElement = (
|
|||||||
columnName: string,
|
columnName: string,
|
||||||
columnField: string,
|
columnField: string,
|
||||||
entityFieldThreads: EntityFieldThreads[],
|
entityFieldThreads: EntityFieldThreads[],
|
||||||
onThreadLinkSelect?: (value: string) => void,
|
onThreadLinkSelect?: (value: string, threadType?: ThreadType) => void,
|
||||||
entityType?: string,
|
entityType?: string,
|
||||||
entityFqn?: string,
|
entityFqn?: string,
|
||||||
entityField?: string,
|
entityField?: string,
|
||||||
flag = true
|
flag = true,
|
||||||
|
threadType?: ThreadType
|
||||||
) => {
|
) => {
|
||||||
let threadValue: EntityFieldThreads = {} as EntityFieldThreads;
|
let threadValue: EntityFieldThreads = {} as EntityFieldThreads;
|
||||||
|
|
||||||
@ -39,27 +41,36 @@ export const getFieldThreadElement = (
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const isTaskType = isEqual(threadType, ThreadType.Task);
|
||||||
|
|
||||||
return !isEmpty(threadValue) ? (
|
return !isEmpty(threadValue) ? (
|
||||||
<p
|
<button
|
||||||
className="link-text tw-w-8 tw-h-8 tw-flex-none"
|
className="link-text tw-self-start tw-w-8 tw-h-8 tw-flex-none tw-mx-1"
|
||||||
data-testid="field-thread"
|
data-testid="field-thread"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
onThreadLinkSelect?.(threadValue.entityLink);
|
onThreadLinkSelect?.(
|
||||||
|
threadValue.entityLink,
|
||||||
|
isTaskType ? ThreadType.Task : ThreadType.Conversation
|
||||||
|
);
|
||||||
}}>
|
}}>
|
||||||
<span className="tw-flex">
|
<span className="tw-flex">
|
||||||
<SVGIcons alt="comments" icon={Icons.COMMENT} width="20px" />
|
<SVGIcons
|
||||||
|
alt="comments"
|
||||||
|
icon={isTaskType ? Icons.TASK_ICON : Icons.COMMENT}
|
||||||
|
width={isTaskType ? '16px' : '20px'}
|
||||||
|
/>
|
||||||
<span className="tw-ml-1" data-testid="field-thread-count">
|
<span className="tw-ml-1" data-testid="field-thread-count">
|
||||||
{threadValue.count}
|
{threadValue.count}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</button>
|
||||||
) : (
|
) : (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
{entityType && entityFqn && entityField && flag ? (
|
{entityType && entityFqn && entityField && flag && !isTaskType ? (
|
||||||
<p
|
<button
|
||||||
className="link-text tw-self-start tw-w-8 tw-h-8 tw-opacity-0 tw-ml-1 group-hover:tw-opacity-100 tw-flex-none"
|
className="link-text tw-self-start tw-w-8 tw-h-8 tw-flex-none tw-mx-1 tw-opacity-0 group-hover:tw-opacity-100"
|
||||||
data-testid="start-field-thread"
|
data-testid="start-field-thread"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@ -69,7 +80,7 @@ export const getFieldThreadElement = (
|
|||||||
);
|
);
|
||||||
}}>
|
}}>
|
||||||
<SVGIcons alt="comments" icon={Icons.COMMENT_PLUS} width="20px" />
|
<SVGIcons alt="comments" icon={Icons.COMMENT_PLUS} width="20px" />
|
||||||
</p>
|
</button>
|
||||||
) : null}
|
) : null}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
|
@ -144,6 +144,7 @@ import IconTableGrey from '../assets/svg/table-grey.svg';
|
|||||||
import IconTable from '../assets/svg/table.svg';
|
import IconTable from '../assets/svg/table.svg';
|
||||||
import IconTagGrey from '../assets/svg/tag-grey.svg';
|
import IconTagGrey from '../assets/svg/tag-grey.svg';
|
||||||
import IconTag from '../assets/svg/tag.svg';
|
import IconTag from '../assets/svg/tag.svg';
|
||||||
|
import IconTaskColor from '../assets/svg/Task-ic.svg';
|
||||||
import IconTeamsGrey from '../assets/svg/teams-grey.svg';
|
import IconTeamsGrey from '../assets/svg/teams-grey.svg';
|
||||||
import IconTerns from '../assets/svg/terms.svg';
|
import IconTerns from '../assets/svg/terms.svg';
|
||||||
import IconTier from '../assets/svg/tier.svg';
|
import IconTier from '../assets/svg/tier.svg';
|
||||||
@ -313,6 +314,7 @@ export const Icons = {
|
|||||||
STAR: 'ic-star',
|
STAR: 'ic-star',
|
||||||
MENTIONS: 'ic-mentions',
|
MENTIONS: 'ic-mentions',
|
||||||
COMMENT_GREY: 'ic-comment-grey',
|
COMMENT_GREY: 'ic-comment-grey',
|
||||||
|
TASK_ICON: 'task-icon',
|
||||||
};
|
};
|
||||||
|
|
||||||
const SVGIcons: FunctionComponent<Props> = ({
|
const SVGIcons: FunctionComponent<Props> = ({
|
||||||
@ -890,6 +892,10 @@ const SVGIcons: FunctionComponent<Props> = ({
|
|||||||
case Icons.ALERT_BELL:
|
case Icons.ALERT_BELL:
|
||||||
IconComponent = IconAlertBell;
|
IconComponent = IconAlertBell;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case Icons.TASK_ICON:
|
||||||
|
IconComponent = IconTaskColor;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Icons.TASK:
|
case Icons.TASK:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user