mirror of
https://github.com/datahub-project/datahub.git
synced 2025-11-02 03:39:03 +00:00
feat(glossary): add ability to clone glossary term(name and documentation) from term profile menu (#9445)
Co-authored-by: Olga Dimova <38855943+olgadimova@users.noreply.github.com>
This commit is contained in:
parent
a92230b321
commit
3cde9549a2
@ -65,7 +65,12 @@ export class GlossaryTermEntity implements Entity<GlossaryTerm> {
|
||||
useEntityQuery={useGetGlossaryTermQuery as any}
|
||||
headerActionItems={new Set([EntityActionItem.BATCH_ADD_GLOSSARY_TERM])}
|
||||
headerDropdownItems={
|
||||
new Set([EntityMenuItems.UPDATE_DEPRECATION, EntityMenuItems.MOVE, EntityMenuItems.DELETE])
|
||||
new Set([
|
||||
EntityMenuItems.UPDATE_DEPRECATION,
|
||||
EntityMenuItems.CLONE,
|
||||
EntityMenuItems.MOVE,
|
||||
EntityMenuItems.DELETE,
|
||||
])
|
||||
}
|
||||
isNameEditable
|
||||
hideBrowseBar
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
import React, { useState } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import styled from 'styled-components/macro';
|
||||
import { EditOutlined } from '@ant-design/icons';
|
||||
import { message, Button, Input, Modal, Typography, Form, Collapse } from 'antd';
|
||||
import DOMPurify from 'dompurify';
|
||||
import { useHistory } from 'react-router';
|
||||
import {
|
||||
useCreateGlossaryTermMutation,
|
||||
useCreateGlossaryNodeMutation,
|
||||
@ -16,6 +17,7 @@ import DescriptionModal from '../components/legacy/DescriptionModal';
|
||||
import { validateCustomUrnId } from '../../../shared/textUtil';
|
||||
import { useGlossaryEntityData } from '../GlossaryEntityContext';
|
||||
import { getGlossaryRootToUpdate, updateGlossarySidebar } from '../../../glossary/utils';
|
||||
import { getEntityPath } from '../containers/profile/utils';
|
||||
|
||||
const StyledItem = styled(Form.Item)`
|
||||
margin-bottom: 0;
|
||||
@ -33,6 +35,7 @@ interface Props {
|
||||
entityType: EntityType;
|
||||
onClose: () => void;
|
||||
refetchData?: () => void;
|
||||
isCloning?: boolean;
|
||||
}
|
||||
|
||||
function CreateGlossaryEntityModal(props: Props) {
|
||||
@ -43,15 +46,31 @@ function CreateGlossaryEntityModal(props: Props) {
|
||||
const entityRegistry = useEntityRegistry();
|
||||
const [stagedId, setStagedId] = useState<string | undefined>(undefined);
|
||||
const [stagedName, setStagedName] = useState('');
|
||||
const [selectedParentUrn, setSelectedParentUrn] = useState(entityData.urn);
|
||||
const [selectedParentUrn, setSelectedParentUrn] = useState<string>(props.isCloning ? '' : entityData.urn);
|
||||
const [documentation, setDocumentation] = useState('');
|
||||
const [isDocumentationModalVisible, setIsDocumentationModalVisible] = useState(false);
|
||||
const [createButtonDisabled, setCreateButtonDisabled] = useState(true);
|
||||
const refetch = useRefetch();
|
||||
const history = useHistory();
|
||||
|
||||
const [createGlossaryTermMutation] = useCreateGlossaryTermMutation();
|
||||
const [createGlossaryNodeMutation] = useCreateGlossaryNodeMutation();
|
||||
|
||||
useEffect(() => {
|
||||
if (props.isCloning && entityData.entityData) {
|
||||
const { properties } = entityData.entityData;
|
||||
|
||||
if (properties?.name) {
|
||||
setStagedName(properties.name);
|
||||
form.setFieldValue('name', properties.name);
|
||||
}
|
||||
|
||||
if (properties?.description) {
|
||||
setDocumentation(properties.description);
|
||||
}
|
||||
}
|
||||
}, [props.isCloning, entityData.entityData, form]);
|
||||
|
||||
function createGlossaryEntity() {
|
||||
const mutation =
|
||||
entityType === EntityType.GlossaryTerm ? createGlossaryTermMutation : createGlossaryNodeMutation;
|
||||
@ -67,7 +86,7 @@ function CreateGlossaryEntityModal(props: Props) {
|
||||
},
|
||||
},
|
||||
})
|
||||
.then(() => {
|
||||
.then((res) => {
|
||||
message.loading({ content: 'Updating...', duration: 2 });
|
||||
setTimeout(() => {
|
||||
analytics.event({
|
||||
@ -82,12 +101,19 @@ function CreateGlossaryEntityModal(props: Props) {
|
||||
refetch();
|
||||
if (isInGlossaryContext) {
|
||||
// either refresh this current glossary node or the root nodes or root terms
|
||||
const nodeToUpdate = entityData?.urn || getGlossaryRootToUpdate(entityType);
|
||||
const nodeToUpdate = selectedParentUrn || getGlossaryRootToUpdate(entityType);
|
||||
updateGlossarySidebar([nodeToUpdate], urnsToUpdate, setUrnsToUpdate);
|
||||
}
|
||||
if (refetchData) {
|
||||
refetchData();
|
||||
}
|
||||
if (props.isCloning) {
|
||||
const redirectUrn =
|
||||
entityType === EntityType.GlossaryTerm
|
||||
? res.data?.createGlossaryTerm
|
||||
: res.data?.createGlossaryNode;
|
||||
history.push(getEntityPath(entityType, redirectUrn, entityRegistry, false, false));
|
||||
}
|
||||
}, 2000);
|
||||
})
|
||||
.catch((e) => {
|
||||
|
||||
@ -9,6 +9,7 @@ import {
|
||||
LinkOutlined,
|
||||
MoreOutlined,
|
||||
PlusOutlined,
|
||||
CopyOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import { Redirect } from 'react-router';
|
||||
import { EntityType } from '../../../../types.generated';
|
||||
@ -32,6 +33,7 @@ export enum EntityMenuItems {
|
||||
ADD_TERM_GROUP,
|
||||
DELETE,
|
||||
MOVE,
|
||||
CLONE,
|
||||
}
|
||||
|
||||
export const MenuIcon = styled(MoreOutlined)<{ fontSize?: number }>`
|
||||
@ -107,6 +109,7 @@ function EntityDropdown(props: Props) {
|
||||
|
||||
const [isCreateTermModalVisible, setIsCreateTermModalVisible] = useState(false);
|
||||
const [isCreateNodeModalVisible, setIsCreateNodeModalVisible] = useState(false);
|
||||
const [isCloneEntityModalVisible, setIsCloneEntityModalVisible] = useState<boolean>(false);
|
||||
const [isDeprecationModalVisible, setIsDeprecationModalVisible] = useState(false);
|
||||
const [isMoveModalVisible, setIsMoveModalVisible] = useState(false);
|
||||
|
||||
@ -230,6 +233,17 @@ function EntityDropdown(props: Props) {
|
||||
</Tooltip>
|
||||
</StyledMenuItem>
|
||||
)}
|
||||
{menuItems.has(EntityMenuItems.CLONE) && (
|
||||
<StyledMenuItem
|
||||
key="6"
|
||||
disabled={!entityData?.privileges?.canManageEntity}
|
||||
onClick={() => setIsCloneEntityModalVisible(true)}
|
||||
>
|
||||
<MenuItem>
|
||||
<CopyOutlined /> Clone
|
||||
</MenuItem>
|
||||
</StyledMenuItem>
|
||||
)}
|
||||
</Menu>
|
||||
}
|
||||
trigger={['click']}
|
||||
@ -250,6 +264,14 @@ function EntityDropdown(props: Props) {
|
||||
refetchData={refetchForNodes}
|
||||
/>
|
||||
)}
|
||||
{isCloneEntityModalVisible && (
|
||||
<CreateGlossaryEntityModal
|
||||
entityType={entityType}
|
||||
onClose={() => setIsCloneEntityModalVisible(false)}
|
||||
refetchData={entityType === EntityType.GlossaryTerm ? refetchForTerms : refetchForNodes}
|
||||
isCloning
|
||||
/>
|
||||
)}
|
||||
{isDeprecationModalVisible && (
|
||||
<UpdateDeprecationModal
|
||||
urns={[urn]}
|
||||
|
||||
@ -70,6 +70,7 @@ export type GenericEntityProperties = {
|
||||
type?: EntityType;
|
||||
name?: Maybe<string>;
|
||||
properties?: Maybe<{
|
||||
name?: Maybe<string>;
|
||||
description?: Maybe<string>;
|
||||
qualifiedName?: Maybe<string>;
|
||||
sourceUrl?: Maybe<string>;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user