mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-11-02 03:29:03 +00:00
Refactor : UI Pipeline details page (#1102)
* Refactor : UI Pipeline details page * addressing review comment
This commit is contained in:
parent
6d6fdd3de5
commit
f6125a9683
@ -131,11 +131,11 @@ const DashboardDetails = ({
|
||||
|
||||
const onDescriptionUpdate = (updatedHTML: string) => {
|
||||
if (description !== updatedHTML) {
|
||||
const updatedTopicDetails = {
|
||||
const updatedDashboardDetails = {
|
||||
...dashboardDetails,
|
||||
description: updatedHTML,
|
||||
};
|
||||
descriptionUpdateHandler(updatedTopicDetails);
|
||||
descriptionUpdateHandler(updatedDashboardDetails);
|
||||
setIsEdit(false);
|
||||
} else {
|
||||
setIsEdit(false);
|
||||
@ -157,7 +157,7 @@ const DashboardDetails = ({
|
||||
},
|
||||
]
|
||||
: dashboardDetails.tags;
|
||||
const updatedTopicDetails = {
|
||||
const updatedDashboardDetails = {
|
||||
...dashboardDetails,
|
||||
owner: newOwner
|
||||
? {
|
||||
@ -168,7 +168,7 @@ const DashboardDetails = ({
|
||||
tags: tierTag,
|
||||
};
|
||||
|
||||
return settingsUpdateHandler(updatedTopicDetails);
|
||||
return settingsUpdateHandler(updatedDashboardDetails);
|
||||
} else {
|
||||
return Promise.reject();
|
||||
}
|
||||
@ -190,8 +190,8 @@ const DashboardDetails = ({
|
||||
tagFQN: tag,
|
||||
}));
|
||||
const updatedTags = [...prevTags, ...newTags];
|
||||
const updatedTopic = { ...dashboardDetails, tags: updatedTags };
|
||||
tagUpdateHandler(updatedTopic);
|
||||
const updatedDashboard = { ...dashboardDetails, tags: updatedTags };
|
||||
tagUpdateHandler(updatedDashboard);
|
||||
}
|
||||
};
|
||||
const followDashboard = () => {
|
||||
|
||||
@ -1,90 +1,63 @@
|
||||
import { AxiosResponse } from 'axios';
|
||||
import classNames from 'classnames';
|
||||
import { compare } from 'fast-json-patch';
|
||||
import { EntityTags, TableDetail } from 'Models';
|
||||
import { EntityTags } from 'Models';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Link, useParams } from 'react-router-dom';
|
||||
import AppState from '../../AppState';
|
||||
import { getLineageByFQN } from '../../axiosAPIs/lineageAPI';
|
||||
import {
|
||||
addFollower,
|
||||
getPipelineByFqn,
|
||||
patchPipelineDetails,
|
||||
removeFollower,
|
||||
} from '../../axiosAPIs/pipelineAPI';
|
||||
import { getServiceById } from '../../axiosAPIs/serviceAPI';
|
||||
import Description from '../../components/common/description/Description';
|
||||
import EntityPageInfo from '../../components/common/entityPageInfo/EntityPageInfo';
|
||||
import RichTextEditorPreviewer from '../../components/common/rich-text-editor/RichTextEditorPreviewer';
|
||||
import TabsPane from '../../components/common/TabsPane/TabsPane';
|
||||
import { TitleBreadcrumbProps } from '../../components/common/title-breadcrumb/title-breadcrumb.interface';
|
||||
import PageContainer from '../../components/containers/PageContainer';
|
||||
import Entitylineage from '../../components/EntityLineage/EntityLineage.component';
|
||||
import Loader from '../../components/Loader/Loader';
|
||||
import ManageTab from '../../components/ManageTab/ManageTab.component';
|
||||
import { ModalWithMarkdownEditor } from '../../components/Modals/ModalWithMarkdownEditor/ModalWithMarkdownEditor';
|
||||
import {
|
||||
getServiceDetailsPath,
|
||||
getTeamDetailsPath,
|
||||
} from '../../constants/constants';
|
||||
import { EntityType } from '../../enums/entity.enum';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { getTeamDetailsPath } from '../../constants/constants';
|
||||
import { Pipeline, Task } from '../../generated/entity/data/pipeline';
|
||||
import { User } from '../../generated/entity/teams/user';
|
||||
import { EntityLineage } from '../../generated/type/entityLineage';
|
||||
import { TagLabel } from '../../generated/type/tagLabel';
|
||||
import { LabelType, State } from '../../generated/type/tagLabel';
|
||||
import { useAuth } from '../../hooks/authHooks';
|
||||
import {
|
||||
addToRecentViewed,
|
||||
getCurrentUserId,
|
||||
getUserTeams,
|
||||
isEven,
|
||||
} from '../../utils/CommonUtils';
|
||||
import { serviceTypeLogo } from '../../utils/ServiceUtils';
|
||||
import SVGIcons from '../../utils/SvgUtils';
|
||||
import {
|
||||
getOwnerFromId,
|
||||
getTagsWithoutTier,
|
||||
getTierFromTableTags,
|
||||
} from '../../utils/TableUtils';
|
||||
import { getTagCategories, getTaglist } from '../../utils/TagsUtils';
|
||||
|
||||
const MyPipelinePage = () => {
|
||||
const USERId = getCurrentUserId();
|
||||
import { getTagsWithoutTier } from '../../utils/TableUtils';
|
||||
import Description from '../common/description/Description';
|
||||
import EntityPageInfo from '../common/entityPageInfo/EntityPageInfo';
|
||||
import RichTextEditorPreviewer from '../common/rich-text-editor/RichTextEditorPreviewer';
|
||||
import TabsPane from '../common/TabsPane/TabsPane';
|
||||
import PageContainer from '../containers/PageContainer';
|
||||
import Entitylineage from '../EntityLineage/EntityLineage.component';
|
||||
import ManageTabComponent from '../ManageTab/ManageTab.component';
|
||||
import { ModalWithMarkdownEditor } from '../Modals/ModalWithMarkdownEditor/ModalWithMarkdownEditor';
|
||||
import { PipeLineDetailsProp } from './PipelineDetails.interface';
|
||||
|
||||
const PipelineDetails = ({
|
||||
entityName,
|
||||
owner,
|
||||
tagList,
|
||||
tier,
|
||||
slashedPipelineName,
|
||||
pipelineTags,
|
||||
activeTab,
|
||||
pipelineUrl,
|
||||
pipelineDetails,
|
||||
serviceType,
|
||||
setActiveTabHandler,
|
||||
description,
|
||||
descriptionUpdateHandler,
|
||||
entityLineage,
|
||||
followers,
|
||||
users,
|
||||
followPipelineHandler,
|
||||
unfollowPipelineHandler,
|
||||
tagUpdateHandler,
|
||||
settingsUpdateHandler,
|
||||
tasks,
|
||||
taskUpdateHandler,
|
||||
}: PipeLineDetailsProp) => {
|
||||
const { isAuthDisabled } = useAuth();
|
||||
|
||||
const [tagList, setTagList] = useState<Array<string>>([]);
|
||||
const { pipelineFQN } = useParams() as Record<string, string>;
|
||||
const [pipelineDetails, setPipelineDetails] = useState<Pipeline>(
|
||||
{} as Pipeline
|
||||
);
|
||||
const [pipelineId, setPipelineId] = useState<string>('');
|
||||
const [isLoading, setLoading] = useState<boolean>(false);
|
||||
const [description, setDescription] = useState<string>('');
|
||||
const [followers, setFollowers] = useState<Array<User>>([]);
|
||||
const [followersCount, setFollowersCount] = useState<number>(0);
|
||||
const [isEdit, setIsEdit] = useState(false);
|
||||
const [followersCount, setFollowersCount] = useState(0);
|
||||
const [isFollowing, setIsFollowing] = useState(false);
|
||||
const [owner, setOwner] = useState<TableDetail['owner']>();
|
||||
const [tier, setTier] = useState<string>();
|
||||
const [tags, setTags] = useState<Array<EntityTags>>([]);
|
||||
const [activeTab, setActiveTab] = useState<number>(1);
|
||||
const [isEdit, setIsEdit] = useState<boolean>(false);
|
||||
const [tasks, setTasks] = useState<Task[]>([]);
|
||||
const [pipelineUrl, setPipelineUrl] = useState<string>('');
|
||||
const [displayName, setDisplayName] = useState<string>('');
|
||||
const [serviceType, setServiceType] = useState<string>('');
|
||||
const [slashedPipelineName, setSlashedPipelineName] = useState<
|
||||
TitleBreadcrumbProps['titleLinks']
|
||||
>([]);
|
||||
|
||||
const [editTask, setEditTask] = useState<{
|
||||
task: Task;
|
||||
index: number;
|
||||
}>();
|
||||
|
||||
const [entityLineage, setEntityLineage] = useState<EntityLineage>(
|
||||
{} as EntityLineage
|
||||
);
|
||||
const hasEditAccess = () => {
|
||||
if (owner?.type === 'user') {
|
||||
return owner.id === getCurrentUserId();
|
||||
@ -92,6 +65,12 @@ const MyPipelinePage = () => {
|
||||
return getUserTeams().some((team) => team.id === owner?.id);
|
||||
}
|
||||
};
|
||||
const setFollowersData = (followers: Array<User>) => {
|
||||
setIsFollowing(
|
||||
followers.some(({ id }: { id: string }) => id === getCurrentUserId())
|
||||
);
|
||||
setFollowersCount(followers?.length);
|
||||
};
|
||||
const tabs = [
|
||||
{
|
||||
name: 'Details',
|
||||
@ -141,191 +120,11 @@ const MyPipelinePage = () => {
|
||||
{
|
||||
key: `${serviceType} Url`,
|
||||
value: pipelineUrl,
|
||||
placeholderText: displayName,
|
||||
placeholderText: entityName,
|
||||
isLink: true,
|
||||
openInNewTab: true,
|
||||
},
|
||||
];
|
||||
const fetchTags = () => {
|
||||
getTagCategories().then((res) => {
|
||||
if (res.data) {
|
||||
setTagList(getTaglist(res.data));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const setFollowersData = (followers: Array<User>) => {
|
||||
// need to check if already following or not with logedIn user id
|
||||
setIsFollowing(followers.some(({ id }: { id: string }) => id === USERId));
|
||||
setFollowersCount(followers?.length);
|
||||
};
|
||||
|
||||
const fetchPipelineDetail = (pipelineFQN: string) => {
|
||||
setLoading(true);
|
||||
getPipelineByFqn(pipelineFQN, [
|
||||
'owner',
|
||||
'service',
|
||||
'followers',
|
||||
'tags',
|
||||
'tasks',
|
||||
]).then((res: AxiosResponse) => {
|
||||
const {
|
||||
id,
|
||||
description,
|
||||
followers,
|
||||
fullyQualifiedName,
|
||||
service,
|
||||
tags,
|
||||
owner,
|
||||
displayName,
|
||||
tasks,
|
||||
pipelineUrl,
|
||||
} = res.data;
|
||||
setDisplayName(displayName);
|
||||
setPipelineDetails(res.data);
|
||||
setPipelineId(id);
|
||||
setDescription(description ?? '');
|
||||
setFollowers(followers);
|
||||
setFollowersData(followers);
|
||||
setOwner(getOwnerFromId(owner?.id));
|
||||
setTier(getTierFromTableTags(tags));
|
||||
setTags(getTagsWithoutTier(tags));
|
||||
getServiceById('pipelineServices', service?.id).then(
|
||||
(serviceRes: AxiosResponse) => {
|
||||
setServiceType(serviceRes.data.serviceType);
|
||||
setSlashedPipelineName([
|
||||
{
|
||||
name: serviceRes.data.name,
|
||||
url: serviceRes.data.name
|
||||
? getServiceDetailsPath(
|
||||
serviceRes.data.name,
|
||||
serviceRes.data.serviceType
|
||||
)
|
||||
: '',
|
||||
imgSrc: serviceRes.data.serviceType
|
||||
? serviceTypeLogo(serviceRes.data.serviceType)
|
||||
: undefined,
|
||||
},
|
||||
{
|
||||
name: displayName,
|
||||
url: '',
|
||||
activeTitle: true,
|
||||
},
|
||||
]);
|
||||
|
||||
addToRecentViewed({
|
||||
entityType: EntityType.PIPELINE,
|
||||
fqn: fullyQualifiedName,
|
||||
serviceType: serviceRes.data.serviceType,
|
||||
timestamp: 0,
|
||||
});
|
||||
}
|
||||
);
|
||||
setPipelineUrl(pipelineUrl);
|
||||
setTasks(tasks);
|
||||
setLoading(false);
|
||||
});
|
||||
};
|
||||
|
||||
const followPipeline = (): void => {
|
||||
if (isFollowing) {
|
||||
removeFollower(pipelineId, USERId).then((res: AxiosResponse) => {
|
||||
const { followers } = res.data;
|
||||
setFollowers(followers);
|
||||
setFollowersCount((preValu) => preValu - 1);
|
||||
setIsFollowing(false);
|
||||
});
|
||||
} else {
|
||||
addFollower(pipelineId, USERId).then((res: AxiosResponse) => {
|
||||
const { followers } = res.data;
|
||||
setFollowers(followers);
|
||||
setFollowersCount((preValu) => preValu + 1);
|
||||
setIsFollowing(true);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const onDescriptionUpdate = (updatedHTML: string) => {
|
||||
const updatedPipeline = { ...pipelineDetails, description: updatedHTML };
|
||||
|
||||
const jsonPatch = compare(pipelineDetails, updatedPipeline);
|
||||
patchPipelineDetails(pipelineId, jsonPatch).then((res: AxiosResponse) => {
|
||||
setDescription(res.data.description);
|
||||
});
|
||||
setIsEdit(false);
|
||||
};
|
||||
const onDescriptionEdit = (): void => {
|
||||
setIsEdit(true);
|
||||
};
|
||||
const onCancel = () => {
|
||||
setIsEdit(false);
|
||||
};
|
||||
|
||||
const onSettingsUpdate = (
|
||||
newOwner?: TableDetail['owner'],
|
||||
newTier?: TableDetail['tier']
|
||||
): Promise<void> => {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
if (newOwner || newTier) {
|
||||
const tierTag: TableDetail['tags'] = newTier
|
||||
? [
|
||||
...getTagsWithoutTier(pipelineDetails.tags as EntityTags[]),
|
||||
{ tagFQN: newTier, labelType: 'Manual', state: 'Confirmed' },
|
||||
]
|
||||
: (pipelineDetails.tags as EntityTags[]);
|
||||
const updatedPipeline = {
|
||||
...pipelineDetails,
|
||||
owner: newOwner
|
||||
? { ...pipelineDetails.owner, ...newOwner }
|
||||
: pipelineDetails.owner,
|
||||
tags: tierTag,
|
||||
};
|
||||
const jsonPatch = compare(pipelineDetails, updatedPipeline);
|
||||
patchPipelineDetails(pipelineId, jsonPatch)
|
||||
.then((res: AxiosResponse) => {
|
||||
setPipelineDetails(res.data);
|
||||
setOwner(getOwnerFromId(res.data.owner?.id));
|
||||
setTier(getTierFromTableTags(res.data.tags));
|
||||
resolve();
|
||||
})
|
||||
.catch(() => reject());
|
||||
} else {
|
||||
reject();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const onTagUpdate = (selectedTags?: Array<string>) => {
|
||||
if (selectedTags) {
|
||||
const prevTags = pipelineDetails?.tags?.filter((tag) =>
|
||||
selectedTags.includes(tag?.tagFQN as string)
|
||||
);
|
||||
const newTags: Array<EntityTags> = selectedTags
|
||||
.filter((tag) => {
|
||||
return !prevTags?.map((prevTag) => prevTag.tagFQN).includes(tag);
|
||||
})
|
||||
.map((tag) => ({
|
||||
labelType: 'Manual',
|
||||
state: 'Confirmed',
|
||||
tagFQN: tag,
|
||||
}));
|
||||
const updatedTags = [...(prevTags as TagLabel[]), ...newTags];
|
||||
const updatedPipeline = { ...pipelineDetails, tags: updatedTags };
|
||||
const jsonPatch = compare(pipelineDetails, updatedPipeline);
|
||||
patchPipelineDetails(pipelineId, jsonPatch).then((res: AxiosResponse) => {
|
||||
setTier(getTierFromTableTags(res.data.tags));
|
||||
setTags(getTagsWithoutTier(res.data.tags));
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const handleUpdateTask = (task: Task, index: number) => {
|
||||
setEditTask({ task, index });
|
||||
};
|
||||
|
||||
const closeEditTaskModal = (): void => {
|
||||
setEditTask(undefined);
|
||||
};
|
||||
|
||||
const onTaskUpdate = (taskDescription: string) => {
|
||||
if (editTask) {
|
||||
@ -339,42 +138,120 @@ const MyPipelinePage = () => {
|
||||
|
||||
const updatedPipeline = { ...pipelineDetails, tasks: updatedTasks };
|
||||
const jsonPatch = compare(pipelineDetails, updatedPipeline);
|
||||
patchPipelineDetails(pipelineId, jsonPatch).then((res: AxiosResponse) => {
|
||||
setTasks(res.data.tasks || []);
|
||||
});
|
||||
taskUpdateHandler(jsonPatch);
|
||||
setEditTask(undefined);
|
||||
} else {
|
||||
setEditTask(undefined);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchPipelineDetail(pipelineFQN);
|
||||
setActiveTab(1);
|
||||
getLineageByFQN(pipelineFQN, EntityType.PIPELINE).then(
|
||||
(res: AxiosResponse) => setEntityLineage(res.data)
|
||||
);
|
||||
}, [pipelineFQN]);
|
||||
const handleUpdateTask = (task: Task, index: number) => {
|
||||
setEditTask({ task, index });
|
||||
};
|
||||
|
||||
const closeEditTaskModal = (): void => {
|
||||
setEditTask(undefined);
|
||||
};
|
||||
|
||||
const onSettingsUpdate = (newOwner?: Pipeline['owner'], newTier?: string) => {
|
||||
if (newOwner || newTier) {
|
||||
const tierTag: Pipeline['tags'] = newTier
|
||||
? [
|
||||
...getTagsWithoutTier(pipelineDetails.tags as Array<EntityTags>),
|
||||
{
|
||||
tagFQN: newTier,
|
||||
labelType: LabelType.Manual,
|
||||
state: State.Confirmed,
|
||||
},
|
||||
]
|
||||
: pipelineDetails.tags;
|
||||
const updatedPipelineDetails = {
|
||||
...pipelineDetails,
|
||||
owner: newOwner
|
||||
? {
|
||||
...pipelineDetails.owner,
|
||||
...newOwner,
|
||||
}
|
||||
: pipelineDetails.owner,
|
||||
tags: tierTag,
|
||||
};
|
||||
|
||||
return settingsUpdateHandler(updatedPipelineDetails);
|
||||
} else {
|
||||
return Promise.reject();
|
||||
}
|
||||
};
|
||||
|
||||
const onTagUpdate = (selectedTags?: Array<string>) => {
|
||||
if (selectedTags) {
|
||||
const prevTags =
|
||||
pipelineDetails?.tags?.filter((tag) =>
|
||||
selectedTags.includes(tag?.tagFQN as string)
|
||||
) || [];
|
||||
const newTags = selectedTags
|
||||
.filter((tag) => {
|
||||
return !prevTags?.map((prevTag) => prevTag.tagFQN).includes(tag);
|
||||
})
|
||||
.map((tag) => ({
|
||||
labelType: LabelType.Manual,
|
||||
state: State.Confirmed,
|
||||
tagFQN: tag,
|
||||
}));
|
||||
const updatedTags = [...prevTags, ...newTags];
|
||||
const updatedPipeline = { ...pipelineDetails, tags: updatedTags };
|
||||
tagUpdateHandler(updatedPipeline);
|
||||
}
|
||||
};
|
||||
|
||||
const onDescriptionEdit = (): void => {
|
||||
setIsEdit(true);
|
||||
};
|
||||
const onCancel = () => {
|
||||
setIsEdit(false);
|
||||
};
|
||||
|
||||
const onDescriptionUpdate = (updatedHTML: string) => {
|
||||
if (description !== updatedHTML) {
|
||||
const updatedPipelineDetails = {
|
||||
...pipelineDetails,
|
||||
description: updatedHTML,
|
||||
};
|
||||
descriptionUpdateHandler(updatedPipelineDetails);
|
||||
setIsEdit(false);
|
||||
} else {
|
||||
setIsEdit(false);
|
||||
}
|
||||
};
|
||||
|
||||
const followPipeline = () => {
|
||||
if (isFollowing) {
|
||||
setFollowersCount((preValu) => preValu - 1);
|
||||
setIsFollowing(false);
|
||||
unfollowPipelineHandler();
|
||||
} else {
|
||||
setFollowersCount((preValu) => preValu + 1);
|
||||
setIsFollowing(true);
|
||||
followPipelineHandler();
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (isAuthDisabled && AppState.users.length && followers.length) {
|
||||
if (isAuthDisabled && users.length && followers.length) {
|
||||
setFollowersData(followers);
|
||||
}
|
||||
}, [AppState.users, followers]);
|
||||
}, [users, followers]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchTags();
|
||||
}, []);
|
||||
setFollowersData(followers);
|
||||
}, [followers]);
|
||||
|
||||
return (
|
||||
<PageContainer>
|
||||
{isLoading ? (
|
||||
<Loader />
|
||||
) : (
|
||||
<>
|
||||
<PageContainer>
|
||||
<div className="tw-px-4 tw-w-full tw-h-full tw-flex tw-flex-col">
|
||||
<EntityPageInfo
|
||||
isTagEditable
|
||||
entityName={displayName}
|
||||
entityName={entityName}
|
||||
extraInfo={extraInfo}
|
||||
followers={followersCount}
|
||||
followersList={followers}
|
||||
@ -383,7 +260,7 @@ const MyPipelinePage = () => {
|
||||
isFollowing={isFollowing}
|
||||
owner={owner}
|
||||
tagList={tagList}
|
||||
tags={tags}
|
||||
tags={pipelineTags}
|
||||
tagsHandler={onTagUpdate}
|
||||
tier={tier || ''}
|
||||
titleLinks={slashedPipelineName}
|
||||
@ -391,7 +268,7 @@ const MyPipelinePage = () => {
|
||||
<div className="tw-mt-1 tw-flex tw-flex-col tw-flex-grow">
|
||||
<TabsPane
|
||||
activeTab={activeTab}
|
||||
setActiveTab={setActiveTab}
|
||||
setActiveTab={setActiveTabHandler}
|
||||
tabs={tabs}
|
||||
/>
|
||||
|
||||
@ -402,7 +279,7 @@ const MyPipelinePage = () => {
|
||||
<div className="tw-col-span-full">
|
||||
<Description
|
||||
description={description}
|
||||
entityName={displayName}
|
||||
entityName={entityName}
|
||||
hasEditAccess={hasEditAccess()}
|
||||
isEdit={isEdit}
|
||||
owner={owner}
|
||||
@ -487,7 +364,7 @@ const MyPipelinePage = () => {
|
||||
)}
|
||||
{activeTab === 3 && (
|
||||
<div className="tw-mt-4">
|
||||
<ManageTab
|
||||
<ManageTabComponent
|
||||
currentTier={tier}
|
||||
currentUser={owner?.id}
|
||||
hasEditAccess={hasEditAccess()}
|
||||
@ -498,7 +375,7 @@ const MyPipelinePage = () => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</PageContainer>
|
||||
{editTask && (
|
||||
<ModalWithMarkdownEditor
|
||||
header={`Edit Task: "${editTask.task.displayName}"`}
|
||||
@ -508,8 +385,8 @@ const MyPipelinePage = () => {
|
||||
onSave={onTaskUpdate}
|
||||
/>
|
||||
)}
|
||||
</PageContainer>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default MyPipelinePage;
|
||||
export default PipelineDetails;
|
||||
@ -0,0 +1,31 @@
|
||||
import { Operation } from 'fast-json-patch';
|
||||
import { EntityTags, TableDetail } from 'Models';
|
||||
import { Pipeline, Task } from '../../generated/entity/data/pipeline';
|
||||
import { User } from '../../generated/entity/teams/user';
|
||||
import { EntityLineage } from '../../generated/type/entityLineage';
|
||||
import { TitleBreadcrumbProps } from '../common/title-breadcrumb/title-breadcrumb.interface';
|
||||
|
||||
export interface PipeLineDetailsProp {
|
||||
serviceType: string;
|
||||
pipelineUrl: string;
|
||||
entityName: string;
|
||||
tagList: Array<string>;
|
||||
users: Array<User>;
|
||||
pipelineDetails: Pipeline;
|
||||
activeTab: number;
|
||||
owner: TableDetail['owner'];
|
||||
description: string;
|
||||
tier: string;
|
||||
followers: Array<User>;
|
||||
pipelineTags: Array<EntityTags>;
|
||||
slashedPipelineName: TitleBreadcrumbProps['titleLinks'];
|
||||
entityLineage: EntityLineage;
|
||||
tasks: Task[];
|
||||
setActiveTabHandler: (value: number) => void;
|
||||
followPipelineHandler: () => void;
|
||||
unfollowPipelineHandler: () => void;
|
||||
settingsUpdateHandler: (updatedPipeline: Pipeline) => Promise<void>;
|
||||
descriptionUpdateHandler: (updatedPipeline: Pipeline) => void;
|
||||
tagUpdateHandler: (updatedPipeline: Pipeline) => void;
|
||||
taskUpdateHandler: (patch: Array<Operation>) => void;
|
||||
}
|
||||
@ -0,0 +1,243 @@
|
||||
import { AxiosResponse } from 'axios';
|
||||
import { compare, Operation } from 'fast-json-patch';
|
||||
import { observer } from 'mobx-react';
|
||||
import { EntityTags, TableDetail } from 'Models';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import AppState from '../../AppState';
|
||||
import { getLineageByFQN } from '../../axiosAPIs/lineageAPI';
|
||||
import {
|
||||
addFollower,
|
||||
getPipelineByFqn,
|
||||
patchPipelineDetails,
|
||||
removeFollower,
|
||||
} from '../../axiosAPIs/pipelineAPI';
|
||||
import { getServiceById } from '../../axiosAPIs/serviceAPI';
|
||||
import { TitleBreadcrumbProps } from '../../components/common/title-breadcrumb/title-breadcrumb.interface';
|
||||
import Loader from '../../components/Loader/Loader';
|
||||
import PipelineDetails from '../../components/PipelineDetails/PipelineDetails.component';
|
||||
import { getServiceDetailsPath } from '../../constants/constants';
|
||||
import { EntityType } from '../../enums/entity.enum';
|
||||
import { Pipeline, Task } from '../../generated/entity/data/pipeline';
|
||||
import { User } from '../../generated/entity/teams/user';
|
||||
import { EntityLineage } from '../../generated/type/entityLineage';
|
||||
import { addToRecentViewed, getCurrentUserId } from '../../utils/CommonUtils';
|
||||
import { serviceTypeLogo } from '../../utils/ServiceUtils';
|
||||
import {
|
||||
getOwnerFromId,
|
||||
getTagsWithoutTier,
|
||||
getTierFromTableTags,
|
||||
} from '../../utils/TableUtils';
|
||||
import { getTagCategories, getTaglist } from '../../utils/TagsUtils';
|
||||
|
||||
const PipelineDetailsPage = () => {
|
||||
const USERId = getCurrentUserId();
|
||||
|
||||
const [tagList, setTagList] = useState<Array<string>>([]);
|
||||
const { pipelineFQN } = useParams() as Record<string, string>;
|
||||
const [pipelineDetails, setPipelineDetails] = useState<Pipeline>(
|
||||
{} as Pipeline
|
||||
);
|
||||
const [pipelineId, setPipelineId] = useState<string>('');
|
||||
const [isLoading, setLoading] = useState<boolean>(false);
|
||||
const [description, setDescription] = useState<string>('');
|
||||
const [followers, setFollowers] = useState<Array<User>>([]);
|
||||
const [owner, setOwner] = useState<TableDetail['owner']>();
|
||||
const [tier, setTier] = useState<string>();
|
||||
const [tags, setTags] = useState<Array<EntityTags>>([]);
|
||||
const [activeTab, setActiveTab] = useState<number>(1);
|
||||
const [tasks, setTasks] = useState<Task[]>([]);
|
||||
const [pipelineUrl, setPipelineUrl] = useState<string>('');
|
||||
const [displayName, setDisplayName] = useState<string>('');
|
||||
const [serviceType, setServiceType] = useState<string>('');
|
||||
const [slashedPipelineName, setSlashedPipelineName] = useState<
|
||||
TitleBreadcrumbProps['titleLinks']
|
||||
>([]);
|
||||
|
||||
const [entityLineage, setEntityLineage] = useState<EntityLineage>(
|
||||
{} as EntityLineage
|
||||
);
|
||||
const activeTabHandler = (tabValue: number) => {
|
||||
setActiveTab(tabValue);
|
||||
};
|
||||
|
||||
const saveUpdatedPipelineData = (
|
||||
updatedData: Pipeline
|
||||
): Promise<AxiosResponse> => {
|
||||
const jsonPatch = compare(pipelineDetails, updatedData);
|
||||
|
||||
return patchPipelineDetails(
|
||||
pipelineId,
|
||||
jsonPatch
|
||||
) as unknown as Promise<AxiosResponse>;
|
||||
};
|
||||
|
||||
const fetchTags = () => {
|
||||
getTagCategories().then((res) => {
|
||||
if (res.data) {
|
||||
setTagList(getTaglist(res.data));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const fetchPipelineDetail = (pipelineFQN: string) => {
|
||||
setLoading(true);
|
||||
getPipelineByFqn(pipelineFQN, [
|
||||
'owner',
|
||||
'service',
|
||||
'followers',
|
||||
'tags',
|
||||
'tasks',
|
||||
]).then((res: AxiosResponse) => {
|
||||
const {
|
||||
id,
|
||||
description,
|
||||
followers,
|
||||
fullyQualifiedName,
|
||||
service,
|
||||
tags,
|
||||
owner,
|
||||
displayName,
|
||||
tasks,
|
||||
pipelineUrl,
|
||||
} = res.data;
|
||||
setDisplayName(displayName);
|
||||
setPipelineDetails(res.data);
|
||||
setPipelineId(id);
|
||||
setDescription(description ?? '');
|
||||
setFollowers(followers);
|
||||
setOwner(getOwnerFromId(owner?.id));
|
||||
setTier(getTierFromTableTags(tags));
|
||||
setTags(getTagsWithoutTier(tags));
|
||||
getServiceById('pipelineServices', service?.id).then(
|
||||
(serviceRes: AxiosResponse) => {
|
||||
setServiceType(serviceRes.data.serviceType);
|
||||
setSlashedPipelineName([
|
||||
{
|
||||
name: serviceRes.data.name,
|
||||
url: serviceRes.data.name
|
||||
? getServiceDetailsPath(
|
||||
serviceRes.data.name,
|
||||
serviceRes.data.serviceType
|
||||
)
|
||||
: '',
|
||||
imgSrc: serviceRes.data.serviceType
|
||||
? serviceTypeLogo(serviceRes.data.serviceType)
|
||||
: undefined,
|
||||
},
|
||||
{
|
||||
name: displayName,
|
||||
url: '',
|
||||
activeTitle: true,
|
||||
},
|
||||
]);
|
||||
|
||||
addToRecentViewed({
|
||||
entityType: EntityType.PIPELINE,
|
||||
fqn: fullyQualifiedName,
|
||||
serviceType: serviceRes.data.serviceType,
|
||||
timestamp: 0,
|
||||
});
|
||||
}
|
||||
);
|
||||
setPipelineUrl(pipelineUrl);
|
||||
setTasks(tasks);
|
||||
setLoading(false);
|
||||
});
|
||||
};
|
||||
|
||||
const followPipeline = () => {
|
||||
addFollower(pipelineId, USERId).then((res: AxiosResponse) => {
|
||||
const { followers } = res.data;
|
||||
setFollowers(followers);
|
||||
});
|
||||
};
|
||||
const unfollowPipeline = () => {
|
||||
removeFollower(pipelineId, USERId).then((res: AxiosResponse) => {
|
||||
const { followers } = res.data;
|
||||
|
||||
setFollowers(followers);
|
||||
});
|
||||
};
|
||||
|
||||
const descriptionUpdateHandler = (updatedPipeline: Pipeline) => {
|
||||
saveUpdatedPipelineData(updatedPipeline).then((res: AxiosResponse) => {
|
||||
const { description } = res.data;
|
||||
setPipelineDetails(res.data);
|
||||
setDescription(description);
|
||||
});
|
||||
};
|
||||
|
||||
const settingsUpdateHandler = (updatedPipeline: Pipeline): Promise<void> => {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
saveUpdatedPipelineData(updatedPipeline)
|
||||
.then((res) => {
|
||||
setPipelineDetails(res.data);
|
||||
setOwner(getOwnerFromId(res.data.owner?.id));
|
||||
setTier(getTierFromTableTags(res.data.tags));
|
||||
resolve();
|
||||
})
|
||||
.catch(() => reject());
|
||||
});
|
||||
};
|
||||
|
||||
const onTagUpdate = (updatedPipeline: Pipeline) => {
|
||||
saveUpdatedPipelineData(updatedPipeline).then((res: AxiosResponse) => {
|
||||
setTier(getTierFromTableTags(res.data.tags));
|
||||
setTags(getTagsWithoutTier(res.data.tags));
|
||||
});
|
||||
};
|
||||
|
||||
const onTaskUpdate = (jsonPatch: Array<Operation>) => {
|
||||
patchPipelineDetails(pipelineId, jsonPatch).then((res: AxiosResponse) => {
|
||||
setTasks(res.data.tasks || []);
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchPipelineDetail(pipelineFQN);
|
||||
setActiveTab(1);
|
||||
getLineageByFQN(pipelineFQN, EntityType.PIPELINE).then(
|
||||
(res: AxiosResponse) => setEntityLineage(res.data)
|
||||
);
|
||||
}, [pipelineFQN]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchTags();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
{isLoading ? (
|
||||
<Loader />
|
||||
) : (
|
||||
<PipelineDetails
|
||||
activeTab={activeTab}
|
||||
description={description}
|
||||
descriptionUpdateHandler={descriptionUpdateHandler}
|
||||
entityLineage={entityLineage}
|
||||
entityName={displayName}
|
||||
followers={followers}
|
||||
followPipelineHandler={followPipeline}
|
||||
owner={owner}
|
||||
pipelineDetails={pipelineDetails}
|
||||
pipelineTags={tags}
|
||||
pipelineUrl={pipelineUrl}
|
||||
serviceType={serviceType}
|
||||
setActiveTabHandler={activeTabHandler}
|
||||
settingsUpdateHandler={settingsUpdateHandler}
|
||||
slashedPipelineName={slashedPipelineName}
|
||||
tagList={tagList}
|
||||
tagUpdateHandler={onTagUpdate}
|
||||
tasks={tasks}
|
||||
taskUpdateHandler={onTaskUpdate}
|
||||
tier={tier as string}
|
||||
unfollowPipelineHandler={unfollowPipeline}
|
||||
users={AppState.users}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default observer(PipelineDetailsPage);
|
||||
@ -27,7 +27,7 @@ import DatasetDetailsPage from '../pages/DatasetDetailsPage/DatasetDetailsPage.c
|
||||
import EntityVersionPage from '../pages/EntityVersionPage/EntityVersionPage.component';
|
||||
import ExplorePage from '../pages/explore/ExplorePage.component';
|
||||
import MyDataPage from '../pages/MyDataPage/MyDataPage.component';
|
||||
import MyPipelinePage from '../pages/Pipeline-details';
|
||||
import PipelineDetailsPage from '../pages/PipelineDetails/PipelineDetailsPage.component';
|
||||
import ReportsPage from '../pages/reports';
|
||||
import Scorecard from '../pages/scorecard';
|
||||
import ServicePage from '../pages/service';
|
||||
@ -76,7 +76,7 @@ const AuthenticatedAppRouter: FunctionComponent = () => {
|
||||
/>
|
||||
<Route component={TopicDetailsPage} path={ROUTES.TOPIC_DETAILS} />
|
||||
<Route component={DashboardDetailsPage} path={ROUTES.DASHBOARD_DETAILS} />
|
||||
<Route component={MyPipelinePage} path={ROUTES.PIPELINE_DETAILS} />
|
||||
<Route component={PipelineDetailsPage} path={ROUTES.PIPELINE_DETAILS} />
|
||||
<Route component={Onboarding} path={ROUTES.ONBOARDING} />
|
||||
<Route
|
||||
exact
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user