Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import { Tooltip } from '@components';
import { MegaphoneSimple } from '@phosphor-icons/react/dist/csr/MegaphoneSimple';
import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';

import { useEntityData, useRefetch } from '@app/entity/shared/EntityContext';
import { ActionMenuItem } from '@app/entityV2/shared/EntityDropdown/styledComponents';
import CreateEntityAnnouncementModal from '@app/entityV2/shared/announce/CreateEntityAnnouncementModal';

export default function AnnounceMenuAction() {
const { t } = useTranslation('entity.shared.entityDropdown');
const { urn } = useEntityData();
const refetchForEntity = useRefetch();
const [isEntityAnnouncementModalVisible, setIsEntityAnnouncementModalVisible] = useState(false);

return (
<>
<Tooltip placement="bottom" title="Add Note">
<Tooltip placement="bottom" title={t('addNote')}>
<ActionMenuItem
key="announce"
disabled={false}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
import { Tooltip } from '@components';
import { ClockCounterClockwise } from '@phosphor-icons/react/dist/csr/ClockCounterClockwise';
import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';

import { useEntityData } from '@app/entity/shared/EntityContext';
import { ActionMenuItem } from '@app/entityV2/shared/EntityDropdown/styledComponents';
import HistorySidebar from '@app/entityV2/shared/tabs/Dataset/Schema/history/HistorySidebar';

export default function ChangeHistoryMenuAction() {
const { t } = useTranslation('entity.shared.entityDropdown');
const { urn, entityType } = useEntityData();
const [open, setOpen] = useState(false);

return (
<>
<Tooltip placement="bottom" title={open ? 'Close change history' : 'View change history'}>
<Tooltip placement="bottom" title={open ? t('changeHistory.closeTooltip') : t('changeHistory.viewTooltip')}>
<ActionMenuItem key="change-history" onClick={() => setOpen(!open)}>
<ClockCounterClockwise size={16} />
</ActionMenuItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { EditOutlined } from '@ant-design/icons';
import { Collapse, Form, Input, Typography, message } from 'antd';
import DOMPurify from 'dompurify';
import React, { useEffect, useState } from 'react';
import { Trans, useTranslation } from 'react-i18next';
import styled from 'styled-components/macro';

import analytics, { EventType } from '@app/analytics';
Expand Down Expand Up @@ -37,6 +38,10 @@ interface Props {

function CreateGlossaryEntityModal(props: Props) {
const { entityType, onClose, refetchData, canCreateGlossaryEntity, canSelectParentUrn = true } = props;
const { t } = useTranslation('entity.shared.entityDropdown');
const { t: tc } = useTranslation('common.actions');
const { t: tcf } = useTranslation('common.feedback');
const { t: tcl } = useTranslation('common.labels');
const entityData = useEntityData();
const { isInGlossaryContext, urnsToUpdate, setUrnsToUpdate, setNodeToNewEntity } = useGlossaryEntityData();
const [form] = Form.useForm();
Expand Down Expand Up @@ -83,15 +88,17 @@ function CreateGlossaryEntityModal(props: Props) {
},
})
.then((result) => {
message.loading({ content: 'Updating...', duration: 2 });
message.loading({ content: tcf('updating'), duration: 2 });
setTimeout(() => {
analytics.event({
type: EventType.CreateGlossaryEntityEvent,
entityType,
parentNodeUrn: selectedParentUrn || undefined,
});
message.success({
content: `Created ${entityRegistry.getEntityName(entityType)}!`,
content: t('createGlossary.success', {
entityName: entityRegistry.getEntityName(entityType),
}),
duration: 2,
});
refetch();
Expand Down Expand Up @@ -123,7 +130,7 @@ function CreateGlossaryEntityModal(props: Props) {
})
.catch((e) => {
message.destroy();
message.error({ content: `Failed to create: \n ${e.message || ''}`, duration: 3 });
message.error({ content: t('createGlossary.error', { errorMessage: e.message || '' }), duration: 3 });
});
onClose();
}
Expand All @@ -133,21 +140,22 @@ function CreateGlossaryEntityModal(props: Props) {
setIsDocumentationModalVisible(false);
}

const entityName =
!selectedParentUrn && entityType === EntityType.GlossaryNode
? t('glossary')
: entityRegistry.getEntityName(entityType);

return (
<Modal
title={`Create ${
!selectedParentUrn && entityType === EntityType.GlossaryNode
? 'Glossary'
: entityRegistry.getEntityName(entityType)
}`}
title={t('createGlossary.title', { entityName })}
buttons={[
{
text: 'Cancel',
text: tc('cancel'),
variant: 'text',
onClick: onClose,
},
{
text: 'Create',
text: tc('create'),
onClick: createGlossaryEntity,
variant: 'filled',
disabled: createButtonDisabled || !canCreateGlossaryEntity,
Expand All @@ -166,14 +174,16 @@ function CreateGlossaryEntityModal(props: Props) {
setCreateButtonDisabled(form.getFieldsError().some((field) => field.errors.length > 0))
}
>
<Form.Item label={<Typography.Text strong>Name</Typography.Text>}>
<Form.Item label={<Typography.Text strong>{tcl('name')}</Typography.Text>}>
<StyledItem
data-testid="create-glossary-entity-modal-name"
name="name"
rules={[
{
required: true,
message: `Enter a ${entityRegistry.getEntityName(entityType)} name.`,
message: t('createGlossary.nameRequired', {
entityName: entityRegistry.getEntityName(entityType),
}),
},
{ whitespace: true },
{ min: 1, max: 100 },
Expand All @@ -182,7 +192,7 @@ function CreateGlossaryEntityModal(props: Props) {
>
<Input
autoFocus
placeholder="Provide a name..."
placeholder={t('createGlossary.namePlaceholder')}
value={stagedName}
onChange={(event) => setStagedName(event.target.value)}
/>
Expand All @@ -192,7 +202,11 @@ function CreateGlossaryEntityModal(props: Props) {
<Form.Item
label={
<Typography.Text strong>
Parent <OptionalWrapper>(optional)</OptionalWrapper>
<Trans
t={t}
i18nKey="createGlossary.parentLabel"
components={{ optional: <OptionalWrapper /> }}
/>
</Typography.Text>
}
>
Expand All @@ -208,38 +222,42 @@ function CreateGlossaryEntityModal(props: Props) {
<StyledItem
label={
<Typography.Text strong>
Documentation <OptionalWrapper>(optional)</OptionalWrapper>
<Trans
t={t}
i18nKey="createGlossary.documentationLabel"
components={{ optional: <OptionalWrapper /> }}
/>
</Typography.Text>
}
>
<Button variant="text" onClick={() => setIsDocumentationModalVisible(true)}>
<EditOutlined />
{documentation ? 'Edit' : 'Add'} Documentation
{documentation ? t('createGlossary.editDocumentation') : t('createGlossary.addDocumentation')}
</Button>
{isDocumentationModalVisible && (
<DescriptionModal
title="Add Documentation"
title={t('createGlossary.addDocumentation')}
onClose={() => setIsDocumentationModalVisible(false)}
onSubmit={addDocumentation}
description={documentation}
/>
)}
</StyledItem>
<Collapse ghost>
<Collapse.Panel header={<Typography.Text type="secondary">Advanced</Typography.Text>} key="1">
<Collapse.Panel
header={<Typography.Text type="secondary">{t('createGlossary.advanced')}</Typography.Text>}
key="1"
>
<Form.Item
label={
<Typography.Text strong>
{entityRegistry.getEntityName(props.entityType)} Id
{t('createGlossary.idLabel', {
entityName: entityRegistry.getEntityName(props.entityType),
})}
</Typography.Text>
}
>
<Typography.Paragraph>
By default, a random UUID will be generated to uniquely identify this entity. If
you&apos;d like to provide a custom id, you may provide it here. Note that it should be
unique across the entire Glossary. Be careful, you cannot easily change the id after
creation.
</Typography.Paragraph>
<Typography.Paragraph>{t('createGlossary.idHelp')}</Typography.Paragraph>
<Form.Item
name="id"
rules={[
Expand All @@ -248,13 +266,13 @@ function CreateGlossaryEntityModal(props: Props) {
if (value && validateCustomUrnId(value)) {
return Promise.resolve();
}
return Promise.reject(new Error('Please enter a valid entity id'));
return Promise.reject(new Error(t('createGlossary.idInvalid')));
},
}),
]}
>
<Input
placeholder="classification"
placeholder={t('createGlossary.idPlaceholder')}
onChange={(event) => setStagedId(event.target.value)}
/>
</Form.Item>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { DeleteOutlined } from '@ant-design/icons';
import { Tooltip } from '@components';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { Redirect } from 'react-router';

import { useUserContext } from '@app/context/useUserContext';
Expand All @@ -19,6 +20,7 @@ interface Props {
}

export default function DeleteEntityMenuItem({ options, onDelete }: Props) {
const { t } = useTranslation('entity.shared.entityDropdown');
const { urn, entityData, entityType } = useEntityData();
const me = useUserContext();
const entityRegistry = useEntityRegistry();
Expand All @@ -43,13 +45,15 @@ export default function DeleteEntityMenuItem({ options, onDelete }: Props) {
return (
<Tooltip
placement="bottom"
title={
shouldDisplayChildDeletionWarning(entityType, entityData, me.platformPrivileges)
? `Can't delete ${entityRegistry.getEntityName(entityType)} with ${
isDomainEntity ? 'sub-domain' : 'child'
} entities.`
: `Delete this ${entityRegistry.getEntityName(entityType)}`
}
title={(() => {
const entityName = entityRegistry.getEntityName(entityType);
if (shouldDisplayChildDeletionWarning(entityType, entityData, me.platformPrivileges)) {
return isDomainEntity
? t('delete.cantDeleteSubDomain', { entityName })
: t('delete.cantDeleteChild', { entityName });
}
return t('delete.tooltip', { entityName });
})()}
>
<ActionMenuItem
key="delete"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { CloseCircleFilled } from '@ant-design/icons';
import { Empty, Select } from 'antd';
import React, { MouseEvent } from 'react';
import { useTranslation } from 'react-i18next';
import { useTheme } from 'styled-components';

import domainAutocompleteOptions from '@app/domainV2/DomainAutocompleteOptions';
Expand Down Expand Up @@ -30,6 +31,7 @@ interface Props {

export default function DomainParentSelect({ selectedParentUrn, setSelectedParentUrn, isMoving }: Props) {
const theme = useTheme();
const { t } = useTranslation('entity.shared.entityDropdown');
const entityRegistry = useEntityRegistry();
const { entityData } = useDomainsContext();
const domainUrn = entityData?.urn;
Expand Down Expand Up @@ -80,15 +82,15 @@ export default function DomainParentSelect({ selectedParentUrn, setSelectedParen
clearIcon={<CloseCircleFilled onClick={handleClear} />}
filterOption={false}
defaultActiveFirstOption={false}
placeholder="Select"
placeholder={t('domainSelect.placeholder')}
value={selectedParentName}
onSelect={onSelectParent}
onSearch={handleSearch}
onFocus={handleFocus}
dropdownStyle={isShowingDomainNavigator || !searchQuery ? { display: 'none' } : {}}
notFoundContent={
<Empty
description="No Domains Found"
description={t('domainSelect.notFound')}
image={Empty.PRESENTED_IMAGE_SIMPLE}
style={{ color: theme.colors.textTertiary }}
/>
Expand Down
Loading
Loading