Feat(ui): update displayName part 2 (#11584)

* Feat(ui): update displayName part 2

* updated entity name

* fixed cypress failure
This commit is contained in:
Shailesh Parmar 2023-05-15 13:59:09 +05:30 committed by GitHub
parent 019014b8d3
commit 004626320d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 216 additions and 363 deletions

View File

@ -17,6 +17,7 @@ import { ReactComponent as EditIcon } from 'assets/svg/edit-new.svg';
import { AxiosError } from 'axios';
import { ActivityFilters } from 'components/ActivityFeed/ActivityFeedList/ActivityFeedList.interface';
import ErrorPlaceHolder from 'components/common/error-with-placeholder/ErrorPlaceHolder';
import { EntityName } from 'components/Modals/EntityNameModal/EntityNameModal.interface';
import { ENTITY_CARD_CLASS } from 'constants/entity.constants';
import { compare } from 'fast-json-patch';
import { isEmpty, isUndefined } from 'lodash';
@ -87,9 +88,6 @@ const DashboardDetails = ({
activeTab,
setActiveTabHandler,
dashboardDetails,
descriptionUpdateHandler,
settingsUpdateHandler,
tagUpdateHandler,
charts,
chartDescriptionUpdateHandler,
chartTagUpdateHandler,
@ -106,7 +104,7 @@ const DashboardDetails = ({
fetchFeedHandler,
updateThreadHandler,
entityFieldTaskCount,
onExtensionUpdate,
onDashboardUpdate,
}: DashboardDetailsProps) => {
const { t } = useTranslation();
const [isEdit, setIsEdit] = useState(false);
@ -312,12 +310,12 @@ const DashboardDetails = ({
const onDescriptionUpdate = async (updatedHTML: string) => {
if (description !== updatedHTML) {
const updatedDashboardDetails = {
const updatedDashboard = {
...dashboardDetails,
description: updatedHTML,
};
try {
await descriptionUpdateHandler(updatedDashboardDetails);
await onDashboardUpdate(updatedDashboard, 'description');
} catch (error) {
showErrorToast(error as AxiosError);
} finally {
@ -330,11 +328,11 @@ const DashboardDetails = ({
const onOwnerUpdate = useCallback(
(newOwner?: Dashboard['owner']) => {
const updatedDashboardDetails = {
const updatedDashboard = {
...dashboardDetails,
owner: newOwner ? { ...owner, ...newOwner } : undefined,
};
settingsUpdateHandler(updatedDashboardDetails);
onDashboardUpdate(updatedDashboard, 'owner');
},
[owner]
);
@ -351,21 +349,21 @@ const DashboardDetails = ({
},
]
: dashboardDetails.tags;
const updatedDashboardDetails = {
const updatedDashboard = {
...dashboardDetails,
tags: tierTag,
};
settingsUpdateHandler(updatedDashboardDetails);
onDashboardUpdate(updatedDashboard, 'tags');
}
};
const onRemoveTier = () => {
if (dashboardDetails) {
const updatedDashboardDetails = {
const updatedDashboard = {
...dashboardDetails,
tags: getTagsWithoutTier(dashboardDetails.tags ?? []),
};
settingsUpdateHandler(updatedDashboardDetails);
onDashboardUpdate(updatedDashboard, 'tags');
}
};
@ -373,10 +371,21 @@ const DashboardDetails = ({
if (selectedTags) {
const updatedTags = [...(tier ? [tier] : []), ...selectedTags];
const updatedDashboard = { ...dashboardDetails, tags: updatedTags };
tagUpdateHandler(updatedDashboard);
onDashboardUpdate(updatedDashboard, 'tags');
}
};
const onUpdateDisplayName = async (data: EntityName) => {
const updatedData = {
...dashboardDetails,
displayName: data.displayName,
};
await onDashboardUpdate(updatedData, 'displayName');
};
const onExtensionUpdate = async (updatedData: Dashboard) => {
await onDashboardUpdate(updatedData, 'extension');
};
const handleRestoreDashboard = async () => {
try {
await restoreDashboard(dashboardDetails.id);
@ -734,7 +743,7 @@ const DashboardDetails = ({
)}
entityFqn={dashboardFQN}
entityId={dashboardDetails.id}
entityName={entityName}
entityName={dashboardDetails.name}
entityType={EntityType.DASHBOARD}
extraInfo={extraInfo}
followHandler={followDashboard}
@ -766,6 +775,7 @@ const DashboardDetails = ({
versionHandler={versionHandler}
onRestoreEntity={handleRestoreDashboard}
onThreadLinkSelect={onThreadLinkSelect}
onUpdateDisplayName={onUpdateDisplayName}
/>
<div className="tw-mt-4 tw-flex tw-flex-col tw-flex-grow">
<TabsPane

View File

@ -54,8 +54,6 @@ export interface DashboardDetailsProps {
setActiveTabHandler: (value: number) => void;
followDashboardHandler: () => void;
unfollowDashboardHandler: () => void;
settingsUpdateHandler: (updatedDashboard: Dashboard) => Promise<void>;
descriptionUpdateHandler: (updatedDashboard: Dashboard) => Promise<void>;
chartDescriptionUpdateHandler: (
index: number,
chartId: string,
@ -66,7 +64,6 @@ export interface DashboardDetailsProps {
chartId: string,
patch: Array<Operation>
) => void;
tagUpdateHandler: (updatedDashboard: Dashboard) => void;
versionHandler: () => void;
postFeedHandler: (value: string, id: string) => void;
deletePostHandler: (
@ -75,5 +72,8 @@ export interface DashboardDetailsProps {
isThread: boolean
) => void;
updateThreadHandler: ThreadUpdatedFunc;
onExtensionUpdate: (updatedDashboard: Dashboard) => Promise<void>;
onDashboardUpdate: (
updatedDashboard: Dashboard,
key: keyof Dashboard
) => Promise<void>;
}

View File

@ -27,17 +27,11 @@ import React from 'react';
import { MemoryRouter } from 'react-router-dom';
import { Dashboard } from '../../generated/entity/data/dashboard';
import { GlossaryTerm } from '../../generated/entity/data/glossaryTerm';
import { EntityLineage } from '../../generated/type/entityLineage';
import { EntityReference } from '../../generated/type/entityReference';
import { Paging } from '../../generated/type/paging';
import { TagLabel } from '../../generated/type/tagLabel';
import { fetchGlossaryTerms } from '../../utils/GlossaryUtils';
import { getClassifications } from '../../utils/TagsUtils';
import {
LeafNodes,
LoadingNodeState,
} from '../EntityLineage/EntityLineage.interface';
import DashboardDetails from './DashboardDetails.component';
import { DashboardDetailsProps } from './DashboardDetails.interface';
const mockUserTeam = [
{
@ -58,7 +52,7 @@ const mockUserTeam = [
},
];
const DashboardDetailsProps = {
const dashboardDetailsProps: DashboardDetailsProps = {
charts: [
{
chartUrl: 'http://localhost',
@ -70,36 +64,16 @@ const DashboardDetailsProps = {
service: { id: '', type: '' },
},
],
serviceType: '',
dashboardUrl: '',
tagList: [],
users: [],
dashboardDetails: {} as Dashboard,
entityLineage: {} as EntityLineage,
entityName: '',
activeTab: 1,
owner: {} as EntityReference,
description: '',
tier: {} as TagLabel,
followers: [],
dashboardTags: [],
slashedDashboardName: [],
setActiveTabHandler: jest.fn(),
followDashboardHandler: jest.fn(),
unfollowDashboardHandler: jest.fn(),
settingsUpdateHandler: jest.fn(),
descriptionUpdateHandler: jest.fn(),
chartDescriptionUpdateHandler: jest.fn(),
chartTagUpdateHandler: jest.fn(),
tagUpdateHandler: jest.fn(),
loadNodeHandler: jest.fn(),
lineageLeafNodes: {} as LeafNodes,
isNodeLoading: {} as LoadingNodeState,
version: '',
onDashboardUpdate: jest.fn(),
versionHandler: jest.fn(),
addLineageHandler: jest.fn(),
removeLineageHandler: jest.fn(),
entityLineageHandler: jest.fn(),
entityThread: [],
isEntityThreadLoading: false,
postFeedHandler: jest.fn(),
@ -112,7 +86,6 @@ const DashboardDetailsProps = {
paging: {} as Paging,
fetchFeedHandler: jest.fn(),
updateThreadHandler: jest.fn(),
onExtensionUpdate: jest.fn(),
};
const mockEntityPermissions = {
@ -146,8 +119,8 @@ jest.mock('components/Tag/TagsContainer/tags-container', () => {
return jest.fn().mockImplementation(({ tagList }) => {
return (
<>
{tagList.map((tag: TagOption, idx: number) => (
<p key={idx}>{tag.fqn}</p>
{tagList.map((tag: TagOption) => (
<p key={tag.fqn}>{tag.fqn}</p>
))}
</>
);
@ -221,7 +194,7 @@ jest.mock('../../utils/TagsUtils', () => ({
describe('Test DashboardDetails component', () => {
it('Checks if the DashboardDetails component has all the proper components rendered', async () => {
const { container } = render(
<DashboardDetails {...DashboardDetailsProps} />,
<DashboardDetails {...dashboardDetailsProps} />,
{
wrapper: MemoryRouter,
}
@ -246,7 +219,7 @@ describe('Test DashboardDetails component', () => {
it('Check if active tab is details', async () => {
const { container } = render(
<DashboardDetails {...DashboardDetailsProps} />,
<DashboardDetails {...dashboardDetailsProps} />,
{
wrapper: MemoryRouter,
}
@ -258,7 +231,7 @@ describe('Test DashboardDetails component', () => {
it('Check if active tab is activity feed', async () => {
const { container } = render(
<DashboardDetails {...DashboardDetailsProps} activeTab={2} />,
<DashboardDetails {...dashboardDetailsProps} activeTab={2} />,
{
wrapper: MemoryRouter,
}
@ -270,7 +243,7 @@ describe('Test DashboardDetails component', () => {
it('Check if active tab is lineage', async () => {
const { container } = render(
<DashboardDetails {...DashboardDetailsProps} activeTab={3} />,
<DashboardDetails {...dashboardDetailsProps} activeTab={3} />,
{
wrapper: MemoryRouter,
}
@ -282,7 +255,7 @@ describe('Test DashboardDetails component', () => {
it('Check if active tab is custom properties', async () => {
const { container } = render(
<DashboardDetails {...DashboardDetailsProps} activeTab={4} />,
<DashboardDetails {...dashboardDetailsProps} activeTab={4} />,
{
wrapper: MemoryRouter,
}
@ -297,7 +270,7 @@ describe('Test DashboardDetails component', () => {
it('Should create an observer if IntersectionObserver is available', async () => {
const { container } = render(
<DashboardDetails {...DashboardDetailsProps} activeTab={4} />,
<DashboardDetails {...dashboardDetailsProps} activeTab={4} />,
{
wrapper: MemoryRouter,
}
@ -310,7 +283,7 @@ describe('Test DashboardDetails component', () => {
it('Check if tags and glossary-terms are present', async () => {
await act(async () => {
render(<DashboardDetails {...DashboardDetailsProps} />, {
render(<DashboardDetails {...dashboardDetailsProps} />, {
wrapper: MemoryRouter,
});
});
@ -332,7 +305,7 @@ describe('Test DashboardDetails component', () => {
Promise.reject()
);
await act(async () => {
render(<DashboardDetails {...DashboardDetailsProps} />, {
render(<DashboardDetails {...dashboardDetailsProps} />, {
wrapper: MemoryRouter,
});
});
@ -354,7 +327,7 @@ describe('Test DashboardDetails component', () => {
Promise.reject()
);
await act(async () => {
render(<DashboardDetails {...DashboardDetailsProps} />, {
render(<DashboardDetails {...dashboardDetailsProps} />, {
wrapper: MemoryRouter,
});
});
@ -381,7 +354,7 @@ describe('Test DashboardDetails component', () => {
Promise.reject()
);
const { getByTestId, queryByText } = render(
<DashboardDetails {...DashboardDetailsProps} />,
<DashboardDetails {...dashboardDetailsProps} />,
{
wrapper: MemoryRouter,
}

View File

@ -115,7 +115,6 @@ const DatasetDetails: React.FC<DatasetDetailsProps> = ({
deletePostHandler,
paging,
fetchFeedHandler,
handleExtensionUpdate,
updateThreadHandler,
entityFieldTaskCount,
isTableProfileLoading,
@ -151,7 +150,6 @@ const DatasetDetails: React.FC<DatasetDetailsProps> = ({
usageSummary,
joins,
entityName,
displayName,
} = useMemo(() => {
const { tags } = tableDetails;
@ -159,7 +157,7 @@ const DatasetDetails: React.FC<DatasetDetailsProps> = ({
...tableDetails,
tier: getTierTags(tags ?? []),
tableTags: getTagsWithoutTier(tags || []),
entityName: tableDetails.name,
entityName: getEntityName(tableDetails),
};
}, [tableDetails]);
const isTourPage = location.pathname.includes(ROUTES.TOUR);
@ -574,6 +572,9 @@ const DatasetDetails: React.FC<DatasetDetailsProps> = ({
const updatedTable = { ...tableDetails, displayName: data.displayName };
await onTableUpdate(updatedTable, 'displayName');
};
const onExtensionUpdate = async (updatedData: Table) => {
await onTableUpdate(updatedData, 'extension');
};
const followTable = () => {
isFollowing ? unfollowTableHandler() : followTableHandler();
@ -652,7 +653,7 @@ const DatasetDetails: React.FC<DatasetDetailsProps> = ({
canDelete={tablePermissions.Delete}
currentOwner={tableDetails.owner}
deleted={deleted}
displayName={displayName}
displayName={tableDetails.displayName}
entityFieldTasks={getEntityFieldThreadCounts(
EntityField.TAGS,
entityFieldTaskCount
@ -663,7 +664,7 @@ const DatasetDetails: React.FC<DatasetDetailsProps> = ({
)}
entityFqn={datasetFQN}
entityId={tableDetails.id}
entityName={entityName}
entityName={tableDetails.name}
entityType={EntityType.TABLE}
extraInfo={extraInfo}
followHandler={followTable}
@ -849,7 +850,7 @@ const DatasetDetails: React.FC<DatasetDetailsProps> = ({
tableDetails as CustomPropertyProps['entityDetails']
}
entityType={EntityType.TABLE}
handleExtensionUpdate={handleExtensionUpdate}
handleExtensionUpdate={onExtensionUpdate}
hasEditAccess={
tablePermissions.EditAll || tablePermissions.EditCustomFields
}

View File

@ -55,7 +55,6 @@ export interface DatasetDetailsProps {
feedType?: FeedFilter,
threadType?: ThreadType
) => void;
handleExtensionUpdate: (updatedTable: Table) => Promise<void>;
updateThreadHandler: ThreadUpdatedFunc;
onTableUpdate: (updatedTable: Table, key: keyof Table) => Promise<void>;
}

View File

@ -110,7 +110,6 @@ const datasetDetailsProps: DatasetDetailsProps = {
createThread: jest.fn(),
deletePostHandler: jest.fn(),
fetchFeedHandler: jest.fn(),
handleExtensionUpdate: jest.fn(),
updateThreadHandler: jest.fn(),
onTableUpdate: jest.fn(),
};

View File

@ -451,6 +451,9 @@ const GlossaryHeader = ({
<EntityNameModal
allowRename
entity={selectedData as EntityReference}
title={t('label.edit-entity', {
entity: t('label.name'),
})}
visible={isNameEditing}
onCancel={() => setIsNameEditing(false)}
onSave={onNameSave}

View File

@ -20,6 +20,7 @@ const EntityNameModal: React.FC<EntityNameModalProps> = ({
entity,
onCancel,
onSave,
title,
// re-name will update actual name of the entity, it will impact across application
// By default its disabled, send allowRename true to get the functionality
allowRename = false,
@ -61,9 +62,7 @@ const EntityNameModal: React.FC<EntityNameModalProps> = ({
open={visible}
title={
<Typography.Text strong data-testid="header">
{t('label.edit-entity', {
entity: allowRename ? t('label.name') : t('label.display-name'),
})}
{title}
</Typography.Text>
}
onCancel={onCancel}>

View File

@ -18,4 +18,5 @@ export interface EntityNameModalProps {
onCancel: () => void;
onSave: (obj: EntityName) => void;
entity: Partial<EntityName>;
title: string;
}

View File

@ -14,6 +14,7 @@
import { Card } from 'antd';
import { AxiosError } from 'axios';
import { ActivityFilters } from 'components/ActivityFeed/ActivityFeedList/ActivityFeedList.interface';
import { EntityName } from 'components/Modals/EntityNameModal/EntityNameModal.interface';
import { ENTITY_CARD_CLASS } from 'constants/entity.constants';
import { EntityTags, ExtraInfo } from 'Models';
import React, {
@ -72,11 +73,8 @@ const TopicDetails: React.FC<TopicDetailsProps> = ({
activeTab,
slashedTopicName,
setActiveTabHandler,
settingsUpdateHandler,
followTopicHandler,
unfollowTopicHandler,
descriptionUpdateHandler,
tagUpdateHandler,
versionHandler,
entityThread,
isEntityThreadLoading,
@ -90,7 +88,7 @@ const TopicDetails: React.FC<TopicDetailsProps> = ({
fetchFeedHandler,
updateThreadHandler,
entityFieldTaskCount,
onExtensionUpdate,
onTopicUpdate,
}: TopicDetailsProps) => {
const { t } = useTranslation();
const [isEdit, setIsEdit] = useState(false);
@ -284,7 +282,7 @@ const TopicDetails: React.FC<TopicDetailsProps> = ({
description: updatedHTML,
};
try {
await descriptionUpdateHandler(updatedTopicDetails);
await onTopicUpdate(updatedTopicDetails, 'description');
} catch (error) {
showErrorToast(error as AxiosError);
} finally {
@ -305,7 +303,7 @@ const TopicDetails: React.FC<TopicDetailsProps> = ({
}
: undefined,
};
settingsUpdateHandler(updatedTopicDetails);
onTopicUpdate(updatedTopicDetails, 'owner');
},
[owner]
);
@ -316,7 +314,7 @@ const TopicDetails: React.FC<TopicDetailsProps> = ({
...topicDetails,
tags: getTagsWithoutTier(topicDetails.tags ?? []),
};
settingsUpdateHandler(updatedTopicDetails);
onTopicUpdate(updatedTopicDetails, 'tags');
}
};
@ -337,7 +335,7 @@ const TopicDetails: React.FC<TopicDetailsProps> = ({
tags: tierTag,
};
return settingsUpdateHandler(updatedTopicDetails);
return onTopicUpdate(updatedTopicDetails, 'tags');
} else {
return Promise.reject();
}
@ -371,10 +369,21 @@ const TopicDetails: React.FC<TopicDetailsProps> = ({
if (selectedTags) {
const updatedTags = [...(tier ? [tier] : []), ...selectedTags];
const updatedTopic = { ...topicDetails, tags: updatedTags };
tagUpdateHandler(updatedTopic);
onTopicUpdate(updatedTopic, 'tags');
}
};
const handleUpdateDisplayName = async (data: EntityName) => {
const updatedData = {
...topicDetails,
displayName: data.displayName,
};
await onTopicUpdate(updatedData, 'displayName');
};
const onExtensionUpdate = async (updatedData: Topic) => {
await onTopicUpdate(updatedData, 'extension');
};
const onThreadLinkSelect = (link: string, threadType?: ThreadType) => {
setThreadLink(link);
if (threadType) {
@ -408,10 +417,13 @@ const TopicDetails: React.FC<TopicDetailsProps> = ({
updatedMessageSchema: Topic['messageSchema']
) => {
try {
await settingsUpdateHandler({
...topicDetails,
messageSchema: updatedMessageSchema,
});
await onTopicUpdate(
{
...topicDetails,
messageSchema: updatedMessageSchema,
},
'messageSchema'
);
} catch (error) {
showErrorToast(error as AxiosError);
}
@ -447,7 +459,7 @@ const TopicDetails: React.FC<TopicDetailsProps> = ({
)}
entityFqn={topicFQN}
entityId={topicDetails.id}
entityName={entityName}
entityName={topicDetails.name}
entityType={EntityType.TOPIC}
extraInfo={extraInfo}
followHandler={followTopic}
@ -479,6 +491,7 @@ const TopicDetails: React.FC<TopicDetailsProps> = ({
versionHandler={versionHandler}
onRestoreEntity={handleRestoreTopic}
onThreadLinkSelect={onThreadLinkSelect}
onUpdateDisplayName={handleUpdateDisplayName}
/>
<div className="tw-mt-4 tw-flex tw-flex-col tw-flex-grow">
<TabsPane

View File

@ -44,9 +44,6 @@ export interface TopicDetailsProps {
setActiveTabHandler: (value: number) => void;
followTopicHandler: () => void;
unfollowTopicHandler: () => void;
settingsUpdateHandler: (updatedTopic: Topic) => Promise<void>;
descriptionUpdateHandler: (updatedTopic: Topic) => Promise<void>;
tagUpdateHandler: (updatedTopic: Topic) => void;
versionHandler: () => void;
postFeedHandler: (value: string, id: string) => void;
deletePostHandler: (
@ -55,7 +52,7 @@ export interface TopicDetailsProps {
isThread: boolean
) => void;
updateThreadHandler: ThreadUpdatedFunc;
onExtensionUpdate: (updatedTopic: Topic) => Promise<void>;
onTopicUpdate: (updatedData: Topic, key: keyof Topic) => Promise<void>;
}
export interface TopicConfigObjectInterface {

View File

@ -19,14 +19,9 @@ import {
} from '@testing-library/react';
import React from 'react';
import { MemoryRouter } from 'react-router-dom';
import { EntityReference } from '../../generated/type/entityReference';
import { Paging } from '../../generated/type/paging';
import { TagLabel } from '../../generated/type/tagLabel';
import {
LeafNodes,
LoadingNodeState,
} from '../EntityLineage/EntityLineage.interface';
import TopicDetails from './TopicDetails.component';
import { TopicDetailsProps } from './TopicDetails.interface';
import { TOPIC_DETAILS } from './TopicDetails.mock';
jest.mock('../common/EntitySummaryDetails/EntitySummaryDetails', () => {
@ -53,37 +48,15 @@ const mockUserTeam = [
},
];
const TopicDetailsProps = {
partitions: 0,
cleanupPolicies: [],
maximumMessageSize: 0,
replicationFactor: 0,
retentionSize: 0,
serviceType: '',
users: [],
const topicDetailsProps: TopicDetailsProps = {
topicDetails: TOPIC_DETAILS,
entityName: '',
activeTab: 1,
owner: {} as EntityReference,
description: '',
tier: {} as TagLabel,
followers: [],
topicTags: [],
slashedTopicName: [],
setActiveTabHandler: jest.fn(),
followTopicHandler: jest.fn(),
unfollowTopicHandler: jest.fn(),
settingsUpdateHandler: jest.fn(),
descriptionUpdateHandler: jest.fn(),
tagUpdateHandler: jest.fn(),
loadNodeHandler: jest.fn(),
lineageLeafNodes: {} as LeafNodes,
isNodeLoading: {} as LoadingNodeState,
version: '',
onTopicUpdate: jest.fn(),
versionHandler: jest.fn(),
addLineageHandler: jest.fn(),
removeLineageHandler: jest.fn(),
entityLineageHandler: jest.fn(),
entityThread: [],
isEntityThreadLoading: false,
postFeedHandler: jest.fn(),
@ -96,17 +69,6 @@ const TopicDetailsProps = {
paging: {} as Paging,
fetchFeedHandler: jest.fn(),
updateThreadHandler: jest.fn(),
lineageTabData: {
loadNodeHandler: jest.fn(),
addLineageHandler: jest.fn(),
removeLineageHandler: jest.fn(),
entityLineageHandler: jest.fn(),
isLineageLoading: false,
entityLineage: { entity: { id: 'test', type: 'topic' } },
lineageLeafNodes: {} as LeafNodes,
isNodeLoading: { id: undefined, state: false },
},
onExtensionUpdate: jest.fn(),
};
jest.mock('../EntityLineage/EntityLineage.component', () => {
@ -174,7 +136,7 @@ jest.mock('../../utils/CommonUtils', () => ({
describe('Test TopicDetails component', () => {
it('Checks if the TopicDetails component has all the proper components rendered', async () => {
const { container } = render(<TopicDetails {...TopicDetailsProps} />, {
const { container } = render(<TopicDetails {...topicDetailsProps} />, {
wrapper: MemoryRouter,
});
const EntityPageInfo = await findByText(container, /EntityPageInfo/i);
@ -196,7 +158,7 @@ describe('Test TopicDetails component', () => {
});
it('Check if active tab is schema', async () => {
const { container } = render(<TopicDetails {...TopicDetailsProps} />, {
const { container } = render(<TopicDetails {...topicDetailsProps} />, {
wrapper: MemoryRouter,
});
const schema = await findByTestId(container, 'label.schema');
@ -208,7 +170,7 @@ describe('Test TopicDetails component', () => {
it('Check if active tab is activity feed', async () => {
const { container } = render(
<TopicDetails {...TopicDetailsProps} activeTab={2} />,
<TopicDetails {...topicDetailsProps} activeTab={2} />,
{
wrapper: MemoryRouter,
}
@ -220,7 +182,7 @@ describe('Test TopicDetails component', () => {
it('Check if active tab is sample data', async () => {
const { container } = render(
<TopicDetails {...TopicDetailsProps} activeTab={3} />,
<TopicDetails {...topicDetailsProps} activeTab={3} />,
{
wrapper: MemoryRouter,
}
@ -232,7 +194,7 @@ describe('Test TopicDetails component', () => {
it('Check if active tab is config', async () => {
const { container } = render(
<TopicDetails {...TopicDetailsProps} activeTab={4} />,
<TopicDetails {...topicDetailsProps} activeTab={4} />,
{
wrapper: MemoryRouter,
}
@ -244,7 +206,7 @@ describe('Test TopicDetails component', () => {
it('Should render lineage tab', async () => {
const { container } = render(
<TopicDetails {...TopicDetailsProps} activeTab={5} />,
<TopicDetails {...topicDetailsProps} activeTab={5} />,
{
wrapper: MemoryRouter,
}
@ -257,7 +219,7 @@ describe('Test TopicDetails component', () => {
it('Check if active tab is custom properties', async () => {
const { container } = render(
<TopicDetails {...TopicDetailsProps} activeTab={6} />,
<TopicDetails {...topicDetailsProps} activeTab={6} />,
{
wrapper: MemoryRouter,
}
@ -272,7 +234,7 @@ describe('Test TopicDetails component', () => {
it('Should create an observer if IntersectionObserver is available', async () => {
const { container } = render(
<TopicDetails {...TopicDetailsProps} activeTab={4} />,
<TopicDetails {...topicDetailsProps} activeTab={4} />,
{
wrapper: MemoryRouter,
}

View File

@ -54,7 +54,7 @@ const mockProps = {
entityFQN: 'string',
entityName: 'string',
onClose: jest.fn(),
createAnnouncementPermission: true,
createPermission: true,
};
describe('Test Announcement drawer component', () => {

View File

@ -38,7 +38,7 @@ interface Props {
entityFQN: string;
entityName: string;
onClose: () => void;
createAnnouncementPermission?: boolean;
createPermission?: boolean;
}
const AnnouncementDrawer: FC<Props> = ({
@ -47,7 +47,7 @@ const AnnouncementDrawer: FC<Props> = ({
entityFQN,
entityType,
entityName,
createAnnouncementPermission,
createPermission,
}) => {
const { t } = useTranslation();
const [isAnnouncement, setIsAnnouncement] = useState<boolean>(false);
@ -119,13 +119,10 @@ const AnnouncementDrawer: FC<Props> = ({
onClose={onClose}>
<div className="tw-flex tw-justify-end">
<Tooltip
title={
!createAnnouncementPermission &&
t('message.no-permission-to-view')
}>
title={!createPermission && t('message.no-permission-to-view')}>
<Button
data-testid="add-announcement"
disabled={!createAnnouncementPermission}
disabled={!createPermission}
type="primary"
onClick={() => setIsAnnouncement(true)}>
{t('label.add-entity', { entity: t('label.announcement') })}
@ -137,7 +134,7 @@ const AnnouncementDrawer: FC<Props> = ({
className="tw-p-0"
createThread={createThread}
deletePostHandler={deletePostHandler}
editAnnouncementPermission={createAnnouncementPermission}
editAnnouncementPermission={createPermission}
key={uniqueId()}
postFeedHandler={postFeedHandler}
showHeader={false}

View File

@ -547,7 +547,7 @@ const EntityPageInfo = ({
/>
{isAnnouncementDrawerOpen && (
<AnnouncementDrawer
createAnnouncementPermission={permission?.EditAll}
createPermission={permission?.EditAll}
entityFQN={entityFqn || ''}
entityName={entityName || ''}
entityType={entityType || ''}

View File

@ -315,6 +315,9 @@ const ManageButton: FC<Props> = ({
name: entityName,
displayName,
}}
title={t('label.edit-entity', {
entity: t('label.display-name'),
})}
visible={isDisplayNameEditing}
onCancel={() => setIsDisplayNameEditing(false)}
onSave={handleDisplayNameUpdate}

View File

@ -257,10 +257,20 @@ const DashboardDetailsPage = () => {
}
};
const descriptionUpdateHandler = async (updatedDashboard: Dashboard) => {
const onDashboardUpdate = async (
updatedDashboard: Dashboard,
key: keyof Dashboard
) => {
try {
const response = await saveUpdatedDashboardData(updatedDashboard);
setDashboardDetails(response);
setDashboardDetails((previous) => {
return {
...previous,
version: response.version,
[key]: response[key],
};
});
getEntityFeedCount();
} catch (error) {
showErrorToast(error as AxiosError);
@ -310,37 +320,6 @@ const DashboardDetailsPage = () => {
}
};
const onTagUpdate = async (updatedDashboard: Dashboard) => {
try {
const res = await saveUpdatedDashboardData(updatedDashboard);
setDashboardDetails(res);
getEntityFeedCount();
} catch (error) {
showErrorToast(
error as AxiosError,
t('server.entity-updating-error', {
entity: t('label.tag-plural'),
})
);
}
};
const settingsUpdateHandler = async (
updatedDashboard: Dashboard
): Promise<void> => {
try {
const res = await saveUpdatedDashboardData(updatedDashboard);
setDashboardDetails(res);
getEntityFeedCount();
} catch (error) {
showErrorToast(
t('server.entity-updating-error', {
entity: getEntityName(updatedDashboard),
})
);
}
};
const onChartUpdate = async (
index: number,
chartId: string,
@ -456,21 +435,6 @@ const DashboardDetailsPage = () => {
updateThreadData(threadId, postId, isThread, data, setEntityThread);
};
const handleExtensionUpdate = async (updatedDashboard: Dashboard) => {
try {
const data = await saveUpdatedDashboardData(updatedDashboard);
setDashboardDetails(data);
getEntityFeedCount();
} catch (error) {
showErrorToast(
error as AxiosError,
t('server.entity-updating-error', {
entity: dashboardDetails.name,
})
);
}
};
useEffect(() => {
if (
dashboardDetailsTabs[activeTab - 1].field ===
@ -501,50 +465,43 @@ const DashboardDetailsPage = () => {
if (isLoading) {
return <Loader />;
}
if (isError) {
return (
<ErrorPlaceHolder>
{getEntityMissingError('dashboard', dashboardFQN)}
</ErrorPlaceHolder>
);
}
if (!dashboardPermissions.ViewAll && !dashboardPermissions.ViewBasic) {
return <ErrorPlaceHolder type={ERROR_PLACEHOLDER_TYPE.PERMISSION} />;
}
return (
<>
{isError ? (
<ErrorPlaceHolder>
{getEntityMissingError('dashboard', dashboardFQN)}
</ErrorPlaceHolder>
) : (
<>
{dashboardPermissions.ViewAll || dashboardPermissions.ViewBasic ? (
<DashboardDetails
activeTab={activeTab}
chartDescriptionUpdateHandler={onChartUpdate}
chartTagUpdateHandler={handleChartTagSelection}
charts={charts}
createThread={createThread}
dashboardDetails={dashboardDetails}
dashboardFQN={dashboardFQN}
deletePostHandler={deletePostHandler}
descriptionUpdateHandler={descriptionUpdateHandler}
entityFieldTaskCount={entityFieldTaskCount}
entityFieldThreadCount={entityFieldThreadCount}
entityThread={entityThread}
feedCount={feedCount}
fetchFeedHandler={getFeedData}
followDashboardHandler={followDashboard}
isEntityThreadLoading={isEntityThreadLoading}
paging={paging}
postFeedHandler={postFeedHandler}
setActiveTabHandler={activeTabHandler}
settingsUpdateHandler={settingsUpdateHandler}
slashedDashboardName={slashedDashboardName}
tagUpdateHandler={onTagUpdate}
unfollowDashboardHandler={unFollowDashboard}
updateThreadHandler={updateThreadHandler}
versionHandler={versionHandler}
onExtensionUpdate={handleExtensionUpdate}
/>
) : (
<ErrorPlaceHolder type={ERROR_PLACEHOLDER_TYPE.PERMISSION} />
)}
</>
)}
</>
<DashboardDetails
activeTab={activeTab}
chartDescriptionUpdateHandler={onChartUpdate}
chartTagUpdateHandler={handleChartTagSelection}
charts={charts}
createThread={createThread}
dashboardDetails={dashboardDetails}
dashboardFQN={dashboardFQN}
deletePostHandler={deletePostHandler}
entityFieldTaskCount={entityFieldTaskCount}
entityFieldThreadCount={entityFieldThreadCount}
entityThread={entityThread}
feedCount={feedCount}
fetchFeedHandler={getFeedData}
followDashboardHandler={followDashboard}
isEntityThreadLoading={isEntityThreadLoading}
paging={paging}
postFeedHandler={postFeedHandler}
setActiveTabHandler={activeTabHandler}
slashedDashboardName={slashedDashboardName}
unfollowDashboardHandler={unFollowDashboard}
updateThreadHandler={updateThreadHandler}
versionHandler={versionHandler}
onDashboardUpdate={onDashboardUpdate}
/>
);
};

View File

@ -493,27 +493,6 @@ const DatasetDetailsPage: FunctionComponent = () => {
updateThreadData(threadId, postId, isThread, data, setEntityThread);
};
const handleExtensionUpdate = async (updatedTable: Table) => {
try {
const {
version,
owner: ownerValue,
tags,
extension,
} = await saveUpdatedTableData(updatedTable);
setTableDetails((previous) => ({
...previous,
version,
owner: ownerValue,
tags,
extension,
}));
getEntityFeedCount();
} catch (error) {
showErrorToast(error as AxiosError);
}
};
useEffect(() => {
if (tablePermissions.ViewAll || tablePermissions.ViewBasic) {
fetchTableDetail();
@ -568,7 +547,6 @@ const DatasetDetailsPage: FunctionComponent = () => {
feedCount={feedCount}
fetchFeedHandler={handleFeedFetchFromFeedList}
followTableHandler={followTable}
handleExtensionUpdate={handleExtensionUpdate}
isEntityThreadLoading={isEntityThreadLoading}
isSampleDataLoading={isSampleDataLoading}
isTableProfileLoading={isTableProfileLoading}

View File

@ -62,7 +62,6 @@ import { DEFAULT_ENTITY_PERMISSION } from '../../utils/PermissionsUtils';
import { showErrorToast } from '../../utils/ToastUtils';
import {
getCurrentTopicTab,
getFormattedTopicDetails,
topicDetailsTabs,
} from '../../utils/TopicDetailsUtils';
@ -167,6 +166,31 @@ const TopicDetailsPage: FunctionComponent = () => {
return patchTopicDetails(topicId, jsonPatch);
};
const onTopicUpdate = async (updatedData: Topic, key: keyof Topic) => {
try {
const res = await saveUpdatedTopicData(updatedData);
setTopicDetails((previous) => {
if (key === 'tags') {
return {
...previous,
version: res.version,
[key]: sortTagsCaseInsensitive(res.tags ?? []),
};
}
return {
...previous,
version: res.version,
[key]: res[key],
};
});
getEntityFeedCount();
} catch (error) {
showErrorToast(error as AxiosError);
}
};
const fetchResourcePermission = async (entityFqn: string) => {
setLoading(true);
try {
@ -275,51 +299,6 @@ const TopicDetailsPage: FunctionComponent = () => {
}
};
const descriptionUpdateHandler = async (updatedTopic: Topic) => {
try {
const response = await saveUpdatedTopicData(updatedTopic);
setTopicDetails(response);
getEntityFeedCount();
} catch (error) {
showErrorToast(error as AxiosError);
}
};
const settingsUpdateHandler = async (updatedTopic: Topic): Promise<void> => {
try {
const res = await saveUpdatedTopicData(updatedTopic);
const formattedTopicDetails = getFormattedTopicDetails(res);
setTopicDetails(formattedTopicDetails);
getEntityFeedCount();
} catch (error) {
showErrorToast(
error as AxiosError,
t('server.entity-updating-error', {
entity: getEntityName(topicDetails),
})
);
}
};
const onTagUpdate = async (updatedTopic: Topic) => {
try {
const res = await saveUpdatedTopicData(updatedTopic);
setTopicDetails({
...res,
tags: sortTagsCaseInsensitive(res.tags || []),
});
getEntityFeedCount();
} catch (error) {
showErrorToast(
error as AxiosError,
t('server.entity-updating-error', {
entity: t('label.tag-plural'),
})
);
}
};
const versionHandler = () => {
currentVersion &&
history.push(
@ -390,21 +369,6 @@ const TopicDetailsPage: FunctionComponent = () => {
updateThreadData(threadId, postId, isThread, data, setEntityThread);
};
const handleExtensionUpdate = async (updatedTopic: Topic) => {
try {
const data = await saveUpdatedTopicData(updatedTopic);
setTopicDetails(data);
getEntityFeedCount();
} catch (error) {
showErrorToast(
error as AxiosError,
t('server.entity-updating-error', {
entity: topicDetails.name,
})
);
}
};
useEffect(() => {
if (topicDetailsTabs[activeTab - 1].path !== tab) {
setActiveTab(getCurrentTopicTab(tab));
@ -429,48 +393,43 @@ const TopicDetailsPage: FunctionComponent = () => {
}
}, [topicPermissions, topicFQN]);
if (isLoading) {
return <Loader />;
}
if (isError) {
return (
<ErrorPlaceHolder>
{getEntityMissingError('topic', topicFQN)}
</ErrorPlaceHolder>
);
}
if (!topicPermissions.ViewAll && !topicPermissions.ViewBasic) {
return <ErrorPlaceHolder type={ERROR_PLACEHOLDER_TYPE.PERMISSION} />;
}
return (
<>
{isLoading ? (
<Loader />
) : isError ? (
<ErrorPlaceHolder>
{getEntityMissingError('topic', topicFQN)}
</ErrorPlaceHolder>
) : (
<>
{topicPermissions.ViewAll || topicPermissions.ViewBasic ? (
<TopicDetails
activeTab={activeTab}
createThread={createThread}
deletePostHandler={deletePostHandler}
descriptionUpdateHandler={descriptionUpdateHandler}
entityFieldTaskCount={entityFieldTaskCount}
entityFieldThreadCount={entityFieldThreadCount}
entityThread={entityThread}
feedCount={feedCount}
fetchFeedHandler={handleFeedFetchFromFeedList}
followTopicHandler={followTopic}
isEntityThreadLoading={isEntityThreadLoading}
paging={paging}
postFeedHandler={postFeedHandler}
setActiveTabHandler={activeTabHandler}
settingsUpdateHandler={settingsUpdateHandler}
slashedTopicName={slashedTopicName}
tagUpdateHandler={onTagUpdate}
topicDetails={topicDetails}
topicFQN={topicFQN}
unfollowTopicHandler={unFollowTopic}
updateThreadHandler={updateThreadHandler}
versionHandler={versionHandler}
onExtensionUpdate={handleExtensionUpdate}
/>
) : (
<ErrorPlaceHolder type={ERROR_PLACEHOLDER_TYPE.PERMISSION} />
)}
</>
)}
</>
<TopicDetails
activeTab={activeTab}
createThread={createThread}
deletePostHandler={deletePostHandler}
entityFieldTaskCount={entityFieldTaskCount}
entityFieldThreadCount={entityFieldThreadCount}
entityThread={entityThread}
feedCount={feedCount}
fetchFeedHandler={handleFeedFetchFromFeedList}
followTopicHandler={followTopic}
isEntityThreadLoading={isEntityThreadLoading}
paging={paging}
postFeedHandler={postFeedHandler}
setActiveTabHandler={activeTabHandler}
slashedTopicName={slashedTopicName}
topicDetails={topicDetails}
topicFQN={topicFQN}
unfollowTopicHandler={unFollowTopic}
updateThreadHandler={updateThreadHandler}
versionHandler={versionHandler}
onTopicUpdate={onTopicUpdate}
/>
);
};

View File

@ -977,6 +977,9 @@ const TagsPage = () => {
<EntityNameModal
allowRename
entity={currentClassification as EntityReference}
title={t('label.edit-entity', {
entity: t('label.name'),
})}
visible={isNameEditing}
onCancel={() => setIsNameEditing(false)}
onSave={handleRenameSave}

View File

@ -171,7 +171,6 @@ const TourPage = () => {
feedCount={0}
fetchFeedHandler={handleCountChange}
followTableHandler={handleCountChange}
handleExtensionUpdate={handleCountChange}
isEntityThreadLoading={false}
paging={{} as Paging}
postFeedHandler={handleCountChange}