fix glossary tags missing while edit operation (#14125)

This commit is contained in:
Ashish Gupta 2023-11-28 07:32:30 +05:30 committed by GitHub
parent 853a83f8b9
commit ab807164b2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 38 additions and 63 deletions

View File

@ -28,6 +28,7 @@ export interface AsyncSelectListProps {
placeholder?: string; placeholder?: string;
debounceTimeout?: number; debounceTimeout?: number;
defaultValue?: string[]; defaultValue?: string[];
value?: string[];
initialOptions?: SelectOption[]; initialOptions?: SelectOption[];
onChange?: (option: DefaultOptionType | DefaultOptionType[]) => void; onChange?: (option: DefaultOptionType | DefaultOptionType[]) => void;
fetchOptions: ( fetchOptions: (

View File

@ -236,7 +236,7 @@ const AsyncSelectList: FC<AsyncSelectListProps> = ({
{...props}> {...props}>
{tagOptions.map(({ label, value, displayName, data }) => ( {tagOptions.map(({ label, value, displayName, data }) => (
<Select.Option <Select.Option
className={className} className={`${className} w-full`}
data={data} data={data}
data-testid={`tag-${value}`} data-testid={`tag-${value}`}
key={label} key={label}

View File

@ -12,28 +12,24 @@
*/ */
import { PlusOutlined } from '@ant-design/icons'; import { PlusOutlined } from '@ant-design/icons';
import { Button, Col, Form, FormProps, Input, Row, Space } from 'antd'; import { Button, Col, Form, FormProps, Input, Row, Space } from 'antd';
import { DefaultOptionType } from 'antd/lib/select';
import { t } from 'i18next'; import { t } from 'i18next';
import { includes, isEmpty } from 'lodash'; import { isEmpty, isString } from 'lodash';
import React, { useEffect, useState } from 'react'; import React, { useEffect } from 'react';
import { ReactComponent as DeleteIcon } from '../../../assets/svg/ic-delete.svg'; import { ReactComponent as DeleteIcon } from '../../../assets/svg/ic-delete.svg';
import { PAGE_SIZE } from '../../../constants/constants';
import { import {
ENTITY_NAME_REGEX, ENTITY_NAME_REGEX,
HEX_COLOR_CODE_REGEX, HEX_COLOR_CODE_REGEX,
} from '../../../constants/regex.constants'; } from '../../../constants/regex.constants';
import { SearchIndex } from '../../../enums/search.enum';
import { EntityReference } from '../../../generated/entity/type'; import { EntityReference } from '../../../generated/entity/type';
import { Paging } from '../../../generated/type/paging';
import { import {
FieldProp, FieldProp,
FieldTypes, FieldTypes,
FormItemLayout, FormItemLayout,
} from '../../../interface/FormUtils.interface'; } from '../../../interface/FormUtils.interface';
import { searchData } from '../../../rest/miscAPI';
import { formatSearchGlossaryTermResponse } from '../../../utils/APIUtils';
import { getEntityName } from '../../../utils/EntityUtils'; import { getEntityName } from '../../../utils/EntityUtils';
import { generateFormFields, getField } from '../../../utils/formUtils'; import { generateFormFields, getField } from '../../../utils/formUtils';
import { getEntityReferenceFromGlossaryTerm } from '../../../utils/GlossaryUtils'; import { fetchGlossaryList } from '../../../utils/TagsUtils';
import { useAuthContext } from '../../Auth/AuthProviders/AuthProvider'; import { useAuthContext } from '../../Auth/AuthProviders/AuthProvider';
import { UserTag } from '../../common/UserTag/UserTag.component'; import { UserTag } from '../../common/UserTag/UserTag.component';
import { UserTagSize } from '../../common/UserTag/UserTag.interface'; import { UserTagSize } from '../../common/UserTag/UserTag.interface';
@ -50,52 +46,12 @@ const AddGlossaryTermForm = ({
formRef: form, formRef: form,
}: AddGlossaryTermFormProps) => { }: AddGlossaryTermFormProps) => {
const { currentUser } = useAuthContext(); const { currentUser } = useAuthContext();
const [relatedTermsOptions, setRelatedTermsOptions] = useState<
EntityReference[]
>([]);
const owner = Form.useWatch<EntityReference | undefined>('owner', form); const owner = Form.useWatch<EntityReference | undefined>('owner', form);
const reviewersList = const reviewersList =
Form.useWatch<EntityReference[]>('reviewers', form) ?? []; Form.useWatch<EntityReference[]>('reviewers', form) ?? [];
const fetchGlossaryTerms = async ( const getRelatedTermFqnList = (relatedTerms: DefaultOptionType[]): string[] =>
searchText = '', relatedTerms.map((tag: DefaultOptionType) => tag.value as string);
page: number
): Promise<{
data: {
label: string;
value: string;
}[];
paging: Paging;
}> => {
const res = await searchData(
searchText,
page,
PAGE_SIZE,
'',
'',
'',
SearchIndex.GLOSSARY
);
let termResult = formatSearchGlossaryTermResponse(res.data.hits.hits);
if (editMode && glossaryTerm) {
termResult = termResult.filter((item) => {
return item.fullyQualifiedName !== glossaryTerm.fullyQualifiedName;
});
}
const results = termResult.map(getEntityReferenceFromGlossaryTerm);
setRelatedTermsOptions((prev) => [...prev, ...results]);
return {
data: results.map((item) => ({
label: item.fullyQualifiedName ?? '',
value: item.fullyQualifiedName ?? '',
})),
paging: {
total: res.data.hits.total.value,
},
};
};
const handleSave: FormProps['onFinish'] = (formObj) => { const handleSave: FormProps['onFinish'] = (formObj) => {
const { const {
@ -127,10 +83,21 @@ const AddGlossaryTermForm = ({
description: description, description: description,
reviewers: reviewersList, reviewers: reviewersList,
relatedTerms: editMode relatedTerms: editMode
? relatedTermsOptions ? relatedTerms.map((term: DefaultOptionType) => {
.filter((item) => includes(relatedTerms, item.fullyQualifiedName)) if (isString(term)) {
.map((term) => term.id) return glossaryTerm?.relatedTerms?.find(
: relatedTerms, (r) => r.fullyQualifiedName === term
)?.id;
}
if (term.data) {
return term.data.id;
}
return glossaryTerm?.relatedTerms?.find(
(r) => r.fullyQualifiedName === term.value
)?.id;
})
: getRelatedTermFqnList(relatedTerms),
references: references.length > 0 ? references : undefined, references: references.length > 0 ? references : undefined,
synonyms: synonyms, synonyms: synonyms,
mutuallyExclusive, mutuallyExclusive,
@ -169,7 +136,7 @@ const AddGlossaryTermForm = ({
tags, tags,
references, references,
mutuallyExclusive, mutuallyExclusive,
relatedTerms: relatedTerms?.map((r) => r.fullyQualifiedName || ''), relatedTerms: relatedTerms?.map((r) => r.fullyQualifiedName ?? ''),
}); });
if (reviewers) { if (reviewers) {
@ -185,10 +152,6 @@ const AddGlossaryTermForm = ({
if (owner) { if (owner) {
form.setFieldValue('owner', owner); form.setFieldValue('owner', owner);
} }
if (relatedTerms && relatedTerms.length > 0) {
setRelatedTermsOptions((prev) => [...prev, ...relatedTerms]);
}
} }
}, [editMode, glossaryTerm, glossaryReviewers, form]); }, [editMode, glossaryTerm, glossaryReviewers, form]);
@ -249,6 +212,11 @@ const AddGlossaryTermForm = ({
type: FieldTypes.TAG_SUGGESTION, type: FieldTypes.TAG_SUGGESTION,
props: { props: {
'data-testid': 'tags-container', 'data-testid': 'tags-container',
initialOptions: glossaryTerm?.tags?.map((data) => ({
label: data.tagFQN,
value: data.tagFQN,
data,
})),
}, },
}, },
{ {
@ -278,7 +246,12 @@ const AddGlossaryTermForm = ({
placeholder: t('label.add-entity', { placeholder: t('label.add-entity', {
entity: t('label.related-term-plural'), entity: t('label.related-term-plural'),
}), }),
fetchOptions: fetchGlossaryTerms, fetchOptions: fetchGlossaryList,
initialOptions: glossaryTerm?.relatedTerms?.map((data) => ({
label: data.fullyQualifiedName,
value: data.fullyQualifiedName,
data,
})),
}, },
}, },
{ {

View File

@ -71,6 +71,7 @@ import {
import { getCountBadge, Transi18next } from '../../../../utils/CommonUtils'; import { getCountBadge, Transi18next } from '../../../../utils/CommonUtils';
import { getEntityName } from '../../../../utils/EntityUtils'; import { getEntityName } from '../../../../utils/EntityUtils';
import { getEntityTypeFromSearchIndex } from '../../../../utils/SearchUtils'; import { getEntityTypeFromSearchIndex } from '../../../../utils/SearchUtils';
import { getDecodedFqn } from '../../../../utils/StringsUtils';
import { getEntityIcon } from '../../../../utils/TableUtils'; import { getEntityIcon } from '../../../../utils/TableUtils';
import { showErrorToast } from '../../../../utils/ToastUtils'; import { showErrorToast } from '../../../../utils/ToastUtils';
import ErrorPlaceHolder from '../../../common/ErrorWithPlaceholder/ErrorPlaceHolder'; import ErrorPlaceHolder from '../../../common/ErrorWithPlaceholder/ErrorPlaceHolder';
@ -248,7 +249,7 @@ const AssetsTabs = forwardRef(
break; break;
case AssetsOfEntity.GLOSSARY: case AssetsOfEntity.GLOSSARY:
data = await getGlossaryTermByFQN(fqn); data = await getGlossaryTermByFQN(getDecodedFqn(fqn));
break; break;
default: default:

View File

@ -83,7 +83,6 @@ const TagSuggestion: React.FC<TagSuggestionProps> = ({
return ( return (
<AsyncSelectList <AsyncSelectList
defaultValue={value?.map((item) => item.tagFQN) || []}
fetchOptions={isGlossaryType ? fetchGlossaryList : fetchTagsElasticSearch} fetchOptions={isGlossaryType ? fetchGlossaryList : fetchTagsElasticSearch}
initialOptions={initialOptions} initialOptions={initialOptions}
mode="multiple" mode="multiple"
@ -93,6 +92,7 @@ const TagSuggestion: React.FC<TagSuggestionProps> = ({
field: t('label.tag-plural'), field: t('label.tag-plural'),
}) })
} }
value={value?.map((item) => item.tagFQN) ?? []}
onChange={(value) => handleTagSelection(value)} onChange={(value) => handleTagSelection(value)}
/> />
); );