mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-07-13 20:18:24 +00:00
feat(ui): supported separate column for Pipeline entity (#11600)
* Supported separate column for Pipline entity * fix code smell and bug * fix code bug * fix code bug
This commit is contained in:
parent
2570ef7795
commit
1df322a704
@ -47,6 +47,7 @@ export const TAGS_ADD_REMOVE_ENTITIES = [
|
||||
serviceName: 'sample_airflow',
|
||||
fieldName: 'dim_address_task',
|
||||
tags: ['PersonalData.Personal', 'PII.Sensitive'],
|
||||
separate: true,
|
||||
},
|
||||
// Todo: need to investigate on below test
|
||||
// more details:- https://cloud.cypress.io/projects/a9yxci/runs/18306/test-results/abe5ab43-84c9-49da-b50f-4936bbcfdd3d
|
||||
|
@ -474,7 +474,7 @@ const DashboardDetails = ({
|
||||
}
|
||||
};
|
||||
|
||||
const handleChartTagSelection = (
|
||||
const handleChartTagSelection = async (
|
||||
selectedTags: Array<EntityTags>,
|
||||
editColumnTag: ChartType,
|
||||
otherTags: TagLabel[]
|
||||
@ -505,7 +505,7 @@ const DashboardDetails = ({
|
||||
tags: [...(prevTags as TagLabel[]), ...newTags],
|
||||
};
|
||||
const jsonPatch = compare(editColumnTag, updatedChart);
|
||||
chartTagUpdateHandler(editColumnTag.id, jsonPatch);
|
||||
await chartTagUpdateHandler(editColumnTag.id, jsonPatch);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -59,7 +59,10 @@ export interface DashboardDetailsProps {
|
||||
chartId: string,
|
||||
patch: Array<Operation>
|
||||
) => Promise<void>;
|
||||
chartTagUpdateHandler: (chartId: string, patch: Array<Operation>) => void;
|
||||
chartTagUpdateHandler: (
|
||||
chartId: string,
|
||||
patch: Array<Operation>
|
||||
) => Promise<void>;
|
||||
versionHandler: () => void;
|
||||
postFeedHandler: (value: string, id: string) => void;
|
||||
deletePostHandler: (
|
||||
|
@ -105,11 +105,6 @@ const EntityTable = ({
|
||||
index: number;
|
||||
}>();
|
||||
|
||||
const [editColumnTag, setEditColumnTag] = useState<{
|
||||
column: Column;
|
||||
index: number;
|
||||
}>();
|
||||
|
||||
const [isTagLoading, setIsTagLoading] = useState<boolean>(false);
|
||||
const [tagFetchFailed, setTagFetchFailed] = useState<boolean>(false);
|
||||
|
||||
@ -228,14 +223,14 @@ const EntityTable = ({
|
||||
editColumn.column.fullyQualifiedName,
|
||||
columnDescription
|
||||
);
|
||||
await onUpdate?.(tableCols);
|
||||
await onUpdate(tableCols);
|
||||
setEditColumn(undefined);
|
||||
} else {
|
||||
setEditColumn(undefined);
|
||||
}
|
||||
};
|
||||
|
||||
const handleTagSelection = (
|
||||
const handleTagSelection = async (
|
||||
selectedTags: EntityTags[],
|
||||
editColumnTag: Column,
|
||||
otherTags: TagLabel[]
|
||||
@ -247,9 +242,8 @@ const EntityTable = ({
|
||||
if (newSelectedTags && editColumnTag) {
|
||||
const tableCols = cloneDeep(tableColumns);
|
||||
updateColumnTags(tableCols, editColumnTag.name, newSelectedTags);
|
||||
onUpdate?.(tableCols);
|
||||
await onUpdate(tableCols);
|
||||
}
|
||||
setEditColumnTag(undefined);
|
||||
};
|
||||
|
||||
const searchInColumns = (table: Column[], searchText: string): Column[] => {
|
||||
@ -590,7 +584,6 @@ const EntityTable = ({
|
||||
entityFieldThreads,
|
||||
entityFqn,
|
||||
tableConstraints,
|
||||
editColumnTag,
|
||||
isTagLoading,
|
||||
handleUpdate,
|
||||
handleTagSelection,
|
||||
|
@ -28,7 +28,7 @@ export interface EntityTableProps {
|
||||
entityFqn?: string;
|
||||
entityFieldThreads?: EntityFieldThreads[];
|
||||
entityFieldTasks?: EntityFieldThreads[];
|
||||
onUpdate?: (columns: Column[]) => Promise<void>;
|
||||
onUpdate: (columns: Column[]) => Promise<void>;
|
||||
onThreadLinkSelect?: (value: string, threadType?: ThreadType) => void;
|
||||
onEntityFieldSelect?: (value: string) => void;
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ import EntityTableV1 from './EntityTable.component';
|
||||
|
||||
const onEntityFieldSelect = jest.fn();
|
||||
const onThreadLinkSelect = jest.fn();
|
||||
const onUpdate = jest.fn();
|
||||
|
||||
const mockTableConstraints = [
|
||||
{
|
||||
@ -114,6 +115,7 @@ const mockEntityTableProp = {
|
||||
tableConstraints: mockTableConstraints,
|
||||
onEntityFieldSelect,
|
||||
onThreadLinkSelect,
|
||||
onUpdate,
|
||||
};
|
||||
|
||||
const mockTagList = [
|
||||
|
@ -27,8 +27,10 @@ import { ReactComponent as EditIcon } from 'assets/svg/edit-new.svg';
|
||||
import { AxiosError } from 'axios';
|
||||
import { ActivityFilters } from 'components/ActivityFeed/ActivityFeedList/ActivityFeedList.interface';
|
||||
import { EntityName } from 'components/Modals/EntityNameModal/EntityNameModal.interface';
|
||||
import TableTags from 'components/TableTags/TableTags.component';
|
||||
import { compare, Operation } from 'fast-json-patch';
|
||||
import { isEmpty, isUndefined } from 'lodash';
|
||||
import { TagSource } from 'generated/type/schema';
|
||||
import { isEmpty, isUndefined, map } from 'lodash';
|
||||
import { EntityTags, ExtraInfo, TagOption } from 'Models';
|
||||
import React, {
|
||||
RefObject,
|
||||
@ -41,6 +43,8 @@ import { useTranslation } from 'react-i18next';
|
||||
import { Link, Redirect, useHistory, useParams } from 'react-router-dom';
|
||||
import { getAllFeeds, postFeedById, postThread } from 'rest/feedsAPI';
|
||||
import { restorePipeline } from 'rest/pipelineAPI';
|
||||
import { fetchGlossaryTerms, getGlossaryTermlist } from 'utils/GlossaryUtils';
|
||||
import { getFilterTags } from 'utils/TableTags/TableTags.utils';
|
||||
import AppState from '../../AppState';
|
||||
import { ReactComponent as ExternalLinkIcon } from '../../assets/svg/external-link.svg';
|
||||
import { FQN_SEPARATOR_CHAR } from '../../constants/char.constants';
|
||||
@ -87,7 +91,7 @@ import {
|
||||
} from '../../utils/FeedUtils';
|
||||
import { DEFAULT_ENTITY_PERMISSION } from '../../utils/PermissionsUtils';
|
||||
import { getTagsWithoutTier, getTierTags } from '../../utils/TableUtils';
|
||||
import { fetchTagsAndGlossaryTerms } from '../../utils/TagsUtils';
|
||||
import { getClassifications, getTaglist } from '../../utils/TagsUtils';
|
||||
import { showErrorToast, showSuccessToast } from '../../utils/ToastUtils';
|
||||
import ActivityFeedList from '../ActivityFeed/ActivityFeedList/ActivityFeedList';
|
||||
import ActivityThreadPanel from '../ActivityFeed/ActivityThreadPanel/ActivityThreadPanel';
|
||||
@ -103,8 +107,6 @@ import Loader from '../Loader/Loader';
|
||||
import { ModalWithMarkdownEditor } from '../Modals/ModalWithMarkdownEditor/ModalWithMarkdownEditor';
|
||||
import { usePermissionProvider } from '../PermissionProvider/PermissionProvider';
|
||||
import { ResourceEntity } from '../PermissionProvider/PermissionProvider.interface';
|
||||
import TagsContainer from '../Tag/TagsContainer/tags-container';
|
||||
import TagsViewer from '../Tag/TagsViewer/tags-viewer';
|
||||
import TasksDAGView from '../TasksDAGView/TasksDAGView';
|
||||
import { PipeLineDetailsProp } from './PipelineDetails.interface';
|
||||
|
||||
@ -150,10 +152,7 @@ const PipelineDetails = ({
|
||||
}, [pipelineDetails]);
|
||||
|
||||
// local state variables
|
||||
const [editTaskTags, setEditTaskTags] = useState<{
|
||||
task: Task;
|
||||
index: number;
|
||||
}>();
|
||||
|
||||
const [isEdit, setIsEdit] = useState(false);
|
||||
const [followersCount, setFollowersCount] = useState(0);
|
||||
const [isFollowing, setIsFollowing] = useState(false);
|
||||
@ -175,8 +174,6 @@ const PipelineDetails = ({
|
||||
EntityFieldThreadCount[]
|
||||
>([]);
|
||||
|
||||
const [tagList, setTagList] = useState<TagOption[]>();
|
||||
|
||||
const [threadLink, setThreadLink] = useState<string>('');
|
||||
|
||||
const [elementRef, isInView] = useElementInView(observerOptions);
|
||||
@ -195,6 +192,11 @@ const PipelineDetails = ({
|
||||
|
||||
const [activityFilter, setActivityFilter] = useState<ActivityFilters>();
|
||||
|
||||
const [isTagLoading, setIsTagLoading] = useState<boolean>(false);
|
||||
const [tagFetchFailed, setTagFetchFailed] = useState<boolean>(false);
|
||||
const [glossaryTags, setGlossaryTags] = useState<TagOption[]>([]);
|
||||
const [classificationTags, setClassificationTags] = useState<TagOption[]>([]);
|
||||
|
||||
// local state ends
|
||||
|
||||
const USERId = getCurrentUserId();
|
||||
@ -213,6 +215,11 @@ const PipelineDetails = ({
|
||||
[entityThreadLoading]
|
||||
);
|
||||
|
||||
const hasTagEditAccess = useMemo(
|
||||
() => pipelinePermissions.EditAll || pipelinePermissions.EditTags,
|
||||
[pipelinePermissions]
|
||||
);
|
||||
|
||||
const getEntityFeedCount = () => {
|
||||
getFeedCounts(
|
||||
EntityType.PIPELINE,
|
||||
@ -239,6 +246,41 @@ const PipelineDetails = ({
|
||||
}
|
||||
}, [pipelineDetails.id, getEntityPermission, setPipelinePermissions]);
|
||||
|
||||
const fetchGlossaryTags = async () => {
|
||||
setIsTagLoading(true);
|
||||
try {
|
||||
const res = await fetchGlossaryTerms();
|
||||
|
||||
const glossaryTerms: TagOption[] = getGlossaryTermlist(res).map(
|
||||
(tag) => ({ fqn: tag, source: TagSource.Glossary })
|
||||
);
|
||||
setGlossaryTags(glossaryTerms);
|
||||
} catch {
|
||||
setTagFetchFailed(true);
|
||||
} finally {
|
||||
setIsTagLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const fetchClassificationTags = async () => {
|
||||
setIsTagLoading(true);
|
||||
try {
|
||||
const res = await getClassifications();
|
||||
const tagList = await getTaglist(res.data);
|
||||
|
||||
const classificationTag: TagOption[] = map(tagList, (tag) => ({
|
||||
fqn: tag,
|
||||
source: TagSource.Classification,
|
||||
}));
|
||||
|
||||
setClassificationTags(classificationTag);
|
||||
} catch {
|
||||
setTagFetchFailed(true);
|
||||
} finally {
|
||||
setIsTagLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (pipelineDetails.id) {
|
||||
fetchResourcePermission();
|
||||
@ -497,105 +539,47 @@ const PipelineDetails = ({
|
||||
getFeedData(undefined, feedFilter, threadType);
|
||||
}, []);
|
||||
|
||||
const handleEditTaskTag = (task: Task, index: number): void => {
|
||||
setEditTaskTags({ task: { ...task, tags: [] }, index });
|
||||
};
|
||||
|
||||
const handleTableTagSelection = (
|
||||
selectedTags: Array<EntityTags> = [],
|
||||
task: {
|
||||
task: Task;
|
||||
index: number;
|
||||
}
|
||||
const handleTableTagSelection = async (
|
||||
selectedTags: EntityTags[],
|
||||
editColumnTag: Task,
|
||||
otherTags: TagLabel[]
|
||||
) => {
|
||||
const selectedTask = isUndefined(editTask) ? task : editTask;
|
||||
const prevTags = selectedTask.task.tags?.filter((tag) =>
|
||||
selectedTags.some((selectedTag) => selectedTag.tagFQN === tag.tagFQN)
|
||||
const newSelectedTags: TagOption[] = map(
|
||||
[...selectedTags, ...otherTags],
|
||||
(tag) => ({ fqn: tag.tagFQN, source: tag.source })
|
||||
);
|
||||
|
||||
const newTags = selectedTags
|
||||
const prevTags = editColumnTag.tags?.filter((tag) =>
|
||||
newSelectedTags.some((selectedTag) => selectedTag.fqn === tag.tagFQN)
|
||||
);
|
||||
|
||||
const newTags = newSelectedTags
|
||||
.filter(
|
||||
(selectedTag) =>
|
||||
!selectedTask.task.tags?.some(
|
||||
(tag) => tag.tagFQN === selectedTag.tagFQN
|
||||
)
|
||||
!editColumnTag.tags?.some((tag) => tag.tagFQN === selectedTag.fqn)
|
||||
)
|
||||
.map((tag) => ({
|
||||
labelType: 'Manual',
|
||||
state: 'Confirmed',
|
||||
source: tag.source,
|
||||
tagFQN: tag.tagFQN,
|
||||
tagFQN: tag.fqn,
|
||||
}));
|
||||
|
||||
const updatedTasks: Task[] = [...(pipelineDetails.tasks || [])];
|
||||
|
||||
const updatedTask = {
|
||||
...selectedTask.task,
|
||||
...editColumnTag,
|
||||
tags: [...(prevTags as TagLabel[]), ...newTags],
|
||||
} as Task;
|
||||
|
||||
updatedTasks[selectedTask.index] = updatedTask;
|
||||
const updatedTasks: Task[] = [...(pipelineDetails.tasks ?? [])].map(
|
||||
(task) => (task.name === editColumnTag.name ? updatedTask : task)
|
||||
);
|
||||
|
||||
const updatedPipeline = { ...pipelineDetails, tasks: updatedTasks };
|
||||
const jsonPatch = compare(pipelineDetails, updatedPipeline);
|
||||
|
||||
taskUpdateHandler(jsonPatch);
|
||||
setEditTaskTags(undefined);
|
||||
await taskUpdateHandler(jsonPatch);
|
||||
};
|
||||
|
||||
useMemo(() => {
|
||||
fetchTagsAndGlossaryTerms().then((response) => {
|
||||
setTagList(response);
|
||||
});
|
||||
}, [setTagList]);
|
||||
|
||||
const addButtonHandler = useCallback((record, index) => {
|
||||
handleEditTaskTag(record, index);
|
||||
}, []);
|
||||
|
||||
const renderTags = useCallback(
|
||||
(tags, record, index) => (
|
||||
<div className="relative tableBody-cell" data-testid="tags-wrapper">
|
||||
{deleted ? (
|
||||
<TagsViewer sizeCap={-1} tags={tags || []} />
|
||||
) : (
|
||||
<TagsContainer
|
||||
editable={editTaskTags?.index === index}
|
||||
selectedTags={tags as EntityTags[]}
|
||||
showAddTagButton={
|
||||
(pipelinePermissions.EditAll || pipelinePermissions.EditTags) &&
|
||||
isEmpty(tags)
|
||||
}
|
||||
showEditTagButton={
|
||||
pipelinePermissions.EditAll || pipelinePermissions.EditTags
|
||||
}
|
||||
size="small"
|
||||
tagList={tagList ?? []}
|
||||
type="label"
|
||||
onAddButtonClick={() => addButtonHandler(record, index)}
|
||||
onCancel={() => {
|
||||
setEditTask(undefined);
|
||||
}}
|
||||
onEditButtonClick={() => addButtonHandler(record, index)}
|
||||
onSelectionChange={(tags) => {
|
||||
handleTableTagSelection(tags, {
|
||||
task: record,
|
||||
index: index,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
),
|
||||
[
|
||||
tagList,
|
||||
editTaskTags,
|
||||
pipelinePermissions.EditAll,
|
||||
pipelinePermissions.EditTags,
|
||||
deleted,
|
||||
]
|
||||
);
|
||||
|
||||
const taskColumns: ColumnsType<Task> = useMemo(
|
||||
() => [
|
||||
{
|
||||
@ -669,14 +653,65 @@ const PipelineDetails = ({
|
||||
),
|
||||
},
|
||||
{
|
||||
key: t('label.tag-plural'),
|
||||
dataIndex: 'tags',
|
||||
title: t('label.tag-plural'),
|
||||
width: 350,
|
||||
render: renderTags,
|
||||
dataIndex: 'tags',
|
||||
key: 'tags',
|
||||
accessor: 'tags',
|
||||
width: 300,
|
||||
render: (tags, record, index) => (
|
||||
<TableTags<Task>
|
||||
dataTestId="classification-tags"
|
||||
fetchTags={fetchClassificationTags}
|
||||
handleTagSelection={handleTableTagSelection}
|
||||
hasTagEditAccess={hasTagEditAccess}
|
||||
index={index}
|
||||
isReadOnly={deleted}
|
||||
isTagLoading={isTagLoading}
|
||||
record={record}
|
||||
tagFetchFailed={tagFetchFailed}
|
||||
tagList={classificationTags}
|
||||
tags={getFilterTags(tags)}
|
||||
type={TagSource.Classification}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: t('label.glossary-term-plural'),
|
||||
dataIndex: 'tags',
|
||||
key: 'tags',
|
||||
accessor: 'tags',
|
||||
width: 300,
|
||||
render: (tags, record, index) => (
|
||||
<TableTags<Task>
|
||||
dataTestId="glossary-tags"
|
||||
fetchTags={fetchGlossaryTags}
|
||||
handleTagSelection={handleTableTagSelection}
|
||||
hasTagEditAccess={hasTagEditAccess}
|
||||
index={index}
|
||||
isReadOnly={deleted}
|
||||
isTagLoading={isTagLoading}
|
||||
record={record}
|
||||
tagFetchFailed={tagFetchFailed}
|
||||
tagList={glossaryTags}
|
||||
tags={getFilterTags(tags)}
|
||||
type={TagSource.Glossary}
|
||||
/>
|
||||
),
|
||||
},
|
||||
],
|
||||
[pipelinePermissions, editTask, editTaskTags, tagList, deleted]
|
||||
[
|
||||
fetchGlossaryTags,
|
||||
fetchClassificationTags,
|
||||
handleTableTagSelection,
|
||||
classificationTags,
|
||||
hasTagEditAccess,
|
||||
pipelinePermissions,
|
||||
editTask,
|
||||
deleted,
|
||||
isTagLoading,
|
||||
tagFetchFailed,
|
||||
glossaryTags,
|
||||
]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -12,6 +12,7 @@
|
||||
*/
|
||||
|
||||
import {
|
||||
findAllByTestId,
|
||||
findByTestId,
|
||||
findByText,
|
||||
fireEvent,
|
||||
@ -19,7 +20,6 @@ import {
|
||||
render,
|
||||
screen,
|
||||
} from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import React from 'react';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import { act } from 'react-test-renderer';
|
||||
@ -81,17 +81,6 @@ const mockTasks = [
|
||||
},
|
||||
];
|
||||
|
||||
const mockTags = [
|
||||
{
|
||||
tagFQN: 'PII.Sensitive',
|
||||
source: 'Tag',
|
||||
},
|
||||
{
|
||||
tagFQN: 'PersonalData.Personal',
|
||||
source: 'Tag',
|
||||
},
|
||||
];
|
||||
|
||||
const mockTaskUpdateHandler = jest.fn();
|
||||
|
||||
const PipelineDetailsProps = {
|
||||
@ -147,14 +136,6 @@ jest.mock('../common/rich-text-editor/RichTextEditorPreviewer', () => {
|
||||
return jest.fn().mockReturnValue(<p>RichTextEditorPreviwer</p>);
|
||||
});
|
||||
|
||||
jest.mock('components/Tag/TagsContainer/tags-container', () => {
|
||||
return jest.fn().mockReturnValue(<p>Tag Container</p>);
|
||||
});
|
||||
|
||||
jest.mock('components/Tag/Tags/tags', () => {
|
||||
return jest.fn().mockReturnValue(<p>Tags</p>);
|
||||
});
|
||||
|
||||
jest.mock('../EntityLineage/EntityLineage.component', () => {
|
||||
return jest.fn().mockReturnValue(<p>EntityLineage</p>);
|
||||
});
|
||||
@ -201,17 +182,12 @@ jest.mock('../../utils/CommonUtils', () => ({
|
||||
jest.mock('../Execution/Execution.component', () => {
|
||||
return jest.fn().mockImplementation(() => <p>Executions</p>);
|
||||
});
|
||||
|
||||
jest.mock('../Tag/TagsContainer/tags-container', () =>
|
||||
jest.fn().mockImplementation(({ onSelectionChange }) => (
|
||||
<div data-testid="tags-container">
|
||||
<div
|
||||
data-testid="onSelectionChange"
|
||||
onClick={() => onSelectionChange(mockTags)}>
|
||||
onSelectionChange
|
||||
</div>
|
||||
</div>
|
||||
))
|
||||
jest.mock('components/TableTags/TableTags.component', () =>
|
||||
jest
|
||||
.fn()
|
||||
.mockImplementation(() => (
|
||||
<div data-testid="table-tag-container">Table Tag Container</div>
|
||||
))
|
||||
);
|
||||
|
||||
describe('Test PipelineDetails component', () => {
|
||||
@ -235,6 +211,10 @@ describe('Test PipelineDetails component', () => {
|
||||
container,
|
||||
'label.custom-property-plural'
|
||||
);
|
||||
const tagsContainer = await findAllByTestId(
|
||||
container,
|
||||
'table-tag-container'
|
||||
);
|
||||
|
||||
expect(EntityPageInfo).toBeInTheDocument();
|
||||
expect(description).toBeInTheDocument();
|
||||
@ -243,6 +223,7 @@ describe('Test PipelineDetails component', () => {
|
||||
expect(lineageTab).toBeInTheDocument();
|
||||
expect(executionsTab).toBeInTheDocument();
|
||||
expect(customPropertiesTab).toBeInTheDocument();
|
||||
expect(tagsContainer).toHaveLength(4);
|
||||
});
|
||||
|
||||
it('Check if active tab is tasks', async () => {
|
||||
@ -381,22 +362,4 @@ describe('Test PipelineDetails component', () => {
|
||||
|
||||
expect(obServerElement).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('taskUpdateHandler should be called after the tags are added or removed to a task', async () => {
|
||||
render(<PipelineDetails {...PipelineDetailsProps} />, {
|
||||
wrapper: MemoryRouter,
|
||||
});
|
||||
|
||||
const tagsContainer = screen.getAllByTestId('tags-container');
|
||||
|
||||
expect(tagsContainer).toHaveLength(2);
|
||||
|
||||
const onSelectionChange = screen.getAllByTestId('onSelectionChange');
|
||||
|
||||
expect(onSelectionChange).toHaveLength(2);
|
||||
|
||||
await act(async () => userEvent.click(onSelectionChange[0]));
|
||||
|
||||
expect(mockTaskUpdateHandler).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
@ -33,5 +33,5 @@ export type Props = {
|
||||
entityFieldTasks?: EntityFieldThreads[];
|
||||
onThreadLinkSelect?: (value: string, threadType?: ThreadType) => void;
|
||||
onEntityFieldSelect?: (value: string) => void;
|
||||
onUpdate?: (columns: Table['columns']) => Promise<void>;
|
||||
onUpdate: (columns: Table['columns']) => Promise<void>;
|
||||
};
|
||||
|
@ -140,8 +140,8 @@ const TableTags = <T extends TableUnion>({
|
||||
type="label"
|
||||
onAddButtonClick={addButtonHandler}
|
||||
onCancel={() => setIsEdit(false)}
|
||||
onSelectionChange={(selectedTags) => {
|
||||
handleTagSelection(selectedTags, record, otherTags);
|
||||
onSelectionChange={async (selectedTags) => {
|
||||
await handleTagSelection(selectedTags, record, otherTags);
|
||||
setIsEdit(false);
|
||||
}}
|
||||
/>
|
||||
|
@ -11,6 +11,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Task } from 'generated/entity/data/pipeline';
|
||||
import { Field } from 'generated/entity/data/topic';
|
||||
import { TagLabel, TagSource } from 'generated/type/tagLabel';
|
||||
import { EntityTags, TagOption } from 'Models';
|
||||
@ -33,7 +34,7 @@ export interface TableTagsComponentProps<T> {
|
||||
selectedTags: Array<EntityTags>,
|
||||
editColumnTag: T,
|
||||
otherTags: TagLabel[]
|
||||
) => void;
|
||||
) => Promise<void>;
|
||||
onRequestTagsHandler?: (cell: T) => void;
|
||||
getColumnName?: (cell: T) => string;
|
||||
getColumnFieldFQN?: string;
|
||||
@ -42,7 +43,7 @@ export interface TableTagsComponentProps<T> {
|
||||
entityFieldThreads?: EntityFieldThreads[];
|
||||
tagFetchFailed: boolean;
|
||||
type: TagSource;
|
||||
fetchTags: () => void;
|
||||
fetchTags: () => Promise<void>;
|
||||
dataTestId: string;
|
||||
}
|
||||
|
||||
@ -56,4 +57,4 @@ export interface TableTagsProps {
|
||||
Glossary: TagLabel[];
|
||||
}
|
||||
|
||||
export type TableUnion = Column | Field | ChartType;
|
||||
export type TableUnion = Column | Field | Task | ChartType;
|
||||
|
Loading…
x
Reference in New Issue
Block a user