mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-09-01 13:13:10 +00:00
parent
0acf88e1ba
commit
4395cae6b7
@ -467,235 +467,241 @@ const DashboardDetails = ({
|
|||||||
tabs={tabs}
|
tabs={tabs}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className="tw-bg-white tw-flex-grow tw--mx-6 tw-px-7 tw-py-4">
|
<div className="tw-flex-grow tw-flex tw-flex-col tw--mx-6 tw-px-7 tw-py-4">
|
||||||
{activeTab === 1 && (
|
<div className="tw-bg-white tw-flex-grow tw-p-4 tw-shadow tw-rounded-md">
|
||||||
<>
|
{activeTab === 1 && (
|
||||||
<div className="tw-grid tw-grid-cols-4 tw-gap-4 tw-w-full">
|
<>
|
||||||
<div className="tw-col-span-full">
|
<div className="tw-grid tw-grid-cols-4 tw-gap-4 tw-w-full">
|
||||||
<Description
|
<div className="tw-col-span-full tw--ml-5">
|
||||||
description={description}
|
<Description
|
||||||
entityFieldThreads={getEntityFieldThreadCounts(
|
description={description}
|
||||||
'description',
|
entityFieldThreads={getEntityFieldThreadCounts(
|
||||||
entityFieldThreadCount
|
'description',
|
||||||
)}
|
entityFieldThreadCount
|
||||||
entityFqn={dashboardFQN}
|
)}
|
||||||
entityName={entityName}
|
entityFqn={dashboardFQN}
|
||||||
entityType={EntityType.DASHBOARD}
|
entityName={entityName}
|
||||||
hasEditAccess={hasEditAccess()}
|
entityType={EntityType.DASHBOARD}
|
||||||
isEdit={isEdit}
|
hasEditAccess={hasEditAccess()}
|
||||||
isReadOnly={deleted}
|
isEdit={isEdit}
|
||||||
owner={owner}
|
isReadOnly={deleted}
|
||||||
onCancel={onCancel}
|
owner={owner}
|
||||||
onDescriptionEdit={onDescriptionEdit}
|
onCancel={onCancel}
|
||||||
onDescriptionUpdate={onDescriptionUpdate}
|
onDescriptionEdit={onDescriptionEdit}
|
||||||
onEntityFieldSelect={onEntityFieldSelect}
|
onDescriptionUpdate={onDescriptionUpdate}
|
||||||
onThreadLinkSelect={onThreadLinkSelect}
|
onEntityFieldSelect={onEntityFieldSelect}
|
||||||
/>
|
onThreadLinkSelect={onThreadLinkSelect}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div className="tw-table-responsive tw-my-6">
|
||||||
<div className="tw-table-responsive tw-my-6">
|
<table className="tw-w-full" data-testid="charts-table">
|
||||||
<table className="tw-w-full" data-testid="charts-table">
|
<thead>
|
||||||
<thead>
|
<tr className="tableHead-row">
|
||||||
<tr className="tableHead-row">
|
<th className="tableHead-cell">Chart Name</th>
|
||||||
<th className="tableHead-cell">Chart Name</th>
|
<th className="tableHead-cell">Chart Type</th>
|
||||||
<th className="tableHead-cell">Chart Type</th>
|
<th className="tableHead-cell">Description</th>
|
||||||
<th className="tableHead-cell">Description</th>
|
<th className="tableHead-cell tw-w-60">Tags</th>
|
||||||
<th className="tableHead-cell tw-w-60">Tags</th>
|
</tr>
|
||||||
</tr>
|
</thead>
|
||||||
</thead>
|
<tbody className="tableBody">
|
||||||
<tbody className="tableBody">
|
{charts.map((chart, index) => (
|
||||||
{charts.map((chart, index) => (
|
<tr
|
||||||
<tr
|
className={classNames(
|
||||||
className={classNames(
|
'tableBody-row',
|
||||||
'tableBody-row',
|
!isEven(index + 1) ? 'odd-row' : null
|
||||||
!isEven(index + 1) ? 'odd-row' : null
|
)}
|
||||||
)}
|
key={index}>
|
||||||
key={index}>
|
<td className="tableBody-cell">
|
||||||
<td className="tableBody-cell">
|
<Link
|
||||||
<Link
|
target="_blank"
|
||||||
target="_blank"
|
to={{ pathname: chart.chartUrl }}>
|
||||||
to={{ pathname: chart.chartUrl }}>
|
<span className="tw-flex">
|
||||||
<span className="tw-flex">
|
<span className="tw-mr-1">
|
||||||
<span className="tw-mr-1">
|
{chart.displayName}
|
||||||
{chart.displayName}
|
</span>
|
||||||
|
<SVGIcons
|
||||||
|
alt="external-link"
|
||||||
|
className="tw-align-middle"
|
||||||
|
icon="external-link"
|
||||||
|
width="12px"
|
||||||
|
/>
|
||||||
</span>
|
</span>
|
||||||
<SVGIcons
|
</Link>
|
||||||
alt="external-link"
|
</td>
|
||||||
className="tw-align-middle"
|
<td className="tableBody-cell">
|
||||||
icon="external-link"
|
{chart.chartType}
|
||||||
width="12px"
|
</td>
|
||||||
/>
|
<td className="tw-group tableBody-cell tw-relative">
|
||||||
</span>
|
<div className="tw-inline-block">
|
||||||
</Link>
|
<div
|
||||||
</td>
|
className="tw-cursor-pointer tw-flex"
|
||||||
<td className="tableBody-cell">{chart.chartType}</td>
|
data-testid="description">
|
||||||
<td className="tw-group tableBody-cell tw-relative">
|
<div>
|
||||||
<div className="tw-inline-block">
|
{chart.description ? (
|
||||||
<div
|
<RichTextEditorPreviewer
|
||||||
className="tw-cursor-pointer tw-flex"
|
markdown={chart.description}
|
||||||
data-testid="description">
|
/>
|
||||||
<div>
|
) : (
|
||||||
{chart.description ? (
|
<span className="tw-no-description">
|
||||||
<RichTextEditorPreviewer
|
No description
|
||||||
markdown={chart.description}
|
</span>
|
||||||
/>
|
)}
|
||||||
) : (
|
</div>
|
||||||
<span className="tw-no-description">
|
{!deleted && (
|
||||||
No description
|
<NonAdminAction
|
||||||
</span>
|
html={getHtmlForNonAdminAction(
|
||||||
|
Boolean(owner)
|
||||||
|
)}
|
||||||
|
isOwner={hasEditAccess()}
|
||||||
|
permission={Operation.UpdateDescription}
|
||||||
|
position="top">
|
||||||
|
<button
|
||||||
|
className="tw-self-start tw-w-8 tw-h-auto tw-opacity-0 tw-ml-1 group-hover:tw-opacity-100 focus:tw-outline-none"
|
||||||
|
onClick={() =>
|
||||||
|
handleUpdateChart(chart, index)
|
||||||
|
}>
|
||||||
|
<SVGIcons
|
||||||
|
alt="edit"
|
||||||
|
icon="icon-edit"
|
||||||
|
title="Edit"
|
||||||
|
width="10px"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</NonAdminAction>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{!deleted && (
|
|
||||||
<NonAdminAction
|
|
||||||
html={getHtmlForNonAdminAction(
|
|
||||||
Boolean(owner)
|
|
||||||
)}
|
|
||||||
isOwner={hasEditAccess()}
|
|
||||||
permission={Operation.UpdateDescription}
|
|
||||||
position="top">
|
|
||||||
<button
|
|
||||||
className="tw-self-start tw-w-8 tw-h-auto tw-opacity-0 tw-ml-1 group-hover:tw-opacity-100 focus:tw-outline-none"
|
|
||||||
onClick={() =>
|
|
||||||
handleUpdateChart(chart, index)
|
|
||||||
}>
|
|
||||||
<SVGIcons
|
|
||||||
alt="edit"
|
|
||||||
icon="icon-edit"
|
|
||||||
title="Edit"
|
|
||||||
width="10px"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</NonAdminAction>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</td>
|
||||||
</td>
|
<td
|
||||||
<td
|
className="tw-group tw-relative tableBody-cell"
|
||||||
className="tw-group tw-relative tableBody-cell"
|
onClick={() => {
|
||||||
onClick={() => {
|
if (!editChartTags) {
|
||||||
if (!editChartTags) {
|
// Fetch tags and terms only once
|
||||||
// Fetch tags and terms only once
|
if (tagList.length === 0 || tagFetchFailed) {
|
||||||
if (tagList.length === 0 || tagFetchFailed) {
|
fetchTagsAndGlossaryTerms();
|
||||||
fetchTagsAndGlossaryTerms();
|
|
||||||
}
|
|
||||||
handleEditChartTag(chart, index);
|
|
||||||
}
|
|
||||||
}}>
|
|
||||||
{deleted ? (
|
|
||||||
<div className="tw-flex tw-flex-wrap">
|
|
||||||
<TagsViewer
|
|
||||||
sizeCap={-1}
|
|
||||||
tags={chart.tags || []}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<NonAdminAction
|
|
||||||
html={getHtmlForNonAdminAction(Boolean(owner))}
|
|
||||||
isOwner={hasEditAccess()}
|
|
||||||
permission={Operation.UpdateTags}
|
|
||||||
position="left"
|
|
||||||
trigger="click">
|
|
||||||
<TagsContainer
|
|
||||||
editable={editChartTags?.index === index}
|
|
||||||
isLoading={
|
|
||||||
isTagLoading &&
|
|
||||||
editChartTags?.index === index
|
|
||||||
}
|
}
|
||||||
selectedTags={chart.tags as EntityTags[]}
|
handleEditChartTag(chart, index);
|
||||||
size="small"
|
}
|
||||||
tagList={tagList}
|
}}>
|
||||||
type="label"
|
{deleted ? (
|
||||||
onCancel={() => {
|
<div className="tw-flex tw-flex-wrap">
|
||||||
handleChartTagSelection();
|
<TagsViewer
|
||||||
}}
|
sizeCap={-1}
|
||||||
onSelectionChange={(tags) => {
|
tags={chart.tags || []}
|
||||||
handleChartTagSelection(tags);
|
/>
|
||||||
}}>
|
</div>
|
||||||
{chart.tags?.length ? (
|
) : (
|
||||||
<button
|
<NonAdminAction
|
||||||
className="tw-opacity-0 tw-ml-1 group-hover:tw-opacity-100 focus:tw-outline-none"
|
html={getHtmlForNonAdminAction(
|
||||||
data-testid="edit-tags">
|
Boolean(owner)
|
||||||
<SVGIcons
|
|
||||||
alt="edit"
|
|
||||||
icon="icon-edit"
|
|
||||||
title="Edit"
|
|
||||||
width="10px"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
) : (
|
|
||||||
<span className="tw-opacity-60 group-hover:tw-opacity-100 tw-text-grey-muted group-hover:tw-text-primary">
|
|
||||||
<Tags
|
|
||||||
startWith="+ "
|
|
||||||
tag="Add tag"
|
|
||||||
type="outlined"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
)}
|
)}
|
||||||
</TagsContainer>
|
isOwner={hasEditAccess()}
|
||||||
</NonAdminAction>
|
permission={Operation.UpdateTags}
|
||||||
)}
|
position="left"
|
||||||
</td>
|
trigger="click">
|
||||||
</tr>
|
<TagsContainer
|
||||||
))}
|
editable={editChartTags?.index === index}
|
||||||
</tbody>
|
isLoading={
|
||||||
</table>
|
isTagLoading &&
|
||||||
|
editChartTags?.index === index
|
||||||
|
}
|
||||||
|
selectedTags={chart.tags as EntityTags[]}
|
||||||
|
size="small"
|
||||||
|
tagList={tagList}
|
||||||
|
type="label"
|
||||||
|
onCancel={() => {
|
||||||
|
handleChartTagSelection();
|
||||||
|
}}
|
||||||
|
onSelectionChange={(tags) => {
|
||||||
|
handleChartTagSelection(tags);
|
||||||
|
}}>
|
||||||
|
{chart.tags?.length ? (
|
||||||
|
<button
|
||||||
|
className="tw-opacity-0 tw-ml-1 group-hover:tw-opacity-100 focus:tw-outline-none"
|
||||||
|
data-testid="edit-tags">
|
||||||
|
<SVGIcons
|
||||||
|
alt="edit"
|
||||||
|
icon="icon-edit"
|
||||||
|
title="Edit"
|
||||||
|
width="10px"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
) : (
|
||||||
|
<span className="tw-opacity-60 group-hover:tw-opacity-100 tw-text-grey-muted group-hover:tw-text-primary">
|
||||||
|
<Tags
|
||||||
|
startWith="+ "
|
||||||
|
tag="Add tag"
|
||||||
|
type="outlined"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</TagsContainer>
|
||||||
|
</NonAdminAction>
|
||||||
|
)}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{activeTab === 2 && (
|
||||||
|
<div
|
||||||
|
className="tw-py-4 tw-px-7 tw-grid tw-grid-cols-3 entity-feed-list tw--mx-7 tw--my-4"
|
||||||
|
id="activityfeed">
|
||||||
|
<div />
|
||||||
|
<ActivityFeedList
|
||||||
|
isEntityFeed
|
||||||
|
withSidePanel
|
||||||
|
className=""
|
||||||
|
deletePostHandler={deletePostHandler}
|
||||||
|
entityName={entityName}
|
||||||
|
feedList={entityThread}
|
||||||
|
postFeedHandler={postFeedHandler}
|
||||||
|
/>
|
||||||
|
<div />
|
||||||
</div>
|
</div>
|
||||||
</>
|
)}
|
||||||
)}
|
{activeTab === 3 && (
|
||||||
{activeTab === 2 && (
|
<div className="tw-h-full tw-px-3">
|
||||||
|
<Entitylineage
|
||||||
|
addLineageHandler={addLineageHandler}
|
||||||
|
deleted={deleted}
|
||||||
|
entityLineage={entityLineage}
|
||||||
|
entityLineageHandler={entityLineageHandler}
|
||||||
|
isLoading={isLineageLoading}
|
||||||
|
isNodeLoading={isNodeLoading}
|
||||||
|
isOwner={hasEditAccess()}
|
||||||
|
lineageLeafNodes={lineageLeafNodes}
|
||||||
|
loadNodeHandler={loadNodeHandler}
|
||||||
|
removeLineageHandler={removeLineageHandler}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{activeTab === 4 && !deleted && (
|
||||||
|
<div>
|
||||||
|
<ManageTabComponent
|
||||||
|
allowDelete
|
||||||
|
currentTier={tier?.tagFQN}
|
||||||
|
currentUser={owner}
|
||||||
|
deletEntityMessage={getDeleteEntityMessage()}
|
||||||
|
entityId={dashboardDetails.id}
|
||||||
|
entityName={dashboardDetails.name}
|
||||||
|
entityType={EntityType.DASHBOARD}
|
||||||
|
hasEditAccess={hasEditAccess()}
|
||||||
|
manageSectionType={EntityType.DASHBOARD}
|
||||||
|
onSave={onSettingsUpdate}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<div
|
<div
|
||||||
className="tw-py-4 tw-px-7 tw-grid tw-grid-cols-3 entity-feed-list tw--mx-7 tw--my-4"
|
data-testid="observer-element"
|
||||||
id="activityfeed">
|
id="observer-element"
|
||||||
<div />
|
ref={elementRef as RefObject<HTMLDivElement>}>
|
||||||
<ActivityFeedList
|
{getLoader()}
|
||||||
isEntityFeed
|
|
||||||
withSidePanel
|
|
||||||
className=""
|
|
||||||
deletePostHandler={deletePostHandler}
|
|
||||||
entityName={entityName}
|
|
||||||
feedList={entityThread}
|
|
||||||
postFeedHandler={postFeedHandler}
|
|
||||||
/>
|
|
||||||
<div />
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
|
||||||
{activeTab === 3 && (
|
|
||||||
<div className="tw-h-full">
|
|
||||||
<Entitylineage
|
|
||||||
addLineageHandler={addLineageHandler}
|
|
||||||
deleted={deleted}
|
|
||||||
entityLineage={entityLineage}
|
|
||||||
entityLineageHandler={entityLineageHandler}
|
|
||||||
isLoading={isLineageLoading}
|
|
||||||
isNodeLoading={isNodeLoading}
|
|
||||||
isOwner={hasEditAccess()}
|
|
||||||
lineageLeafNodes={lineageLeafNodes}
|
|
||||||
loadNodeHandler={loadNodeHandler}
|
|
||||||
removeLineageHandler={removeLineageHandler}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{activeTab === 4 && !deleted && (
|
|
||||||
<div>
|
|
||||||
<ManageTabComponent
|
|
||||||
allowDelete
|
|
||||||
currentTier={tier?.tagFQN}
|
|
||||||
currentUser={owner}
|
|
||||||
deletEntityMessage={getDeleteEntityMessage()}
|
|
||||||
entityId={dashboardDetails.id}
|
|
||||||
entityName={dashboardDetails.name}
|
|
||||||
entityType={EntityType.DASHBOARD}
|
|
||||||
hasEditAccess={hasEditAccess()}
|
|
||||||
manageSectionType={EntityType.DASHBOARD}
|
|
||||||
onSave={onSettingsUpdate}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<div
|
|
||||||
data-testid="observer-element"
|
|
||||||
id="observer-element"
|
|
||||||
ref={elementRef as RefObject<HTMLDivElement>}>
|
|
||||||
{getLoader()}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -579,187 +579,189 @@ const DatasetDetails: React.FC<DatasetDetailsProps> = ({
|
|||||||
setActiveTab={setActiveTabHandler}
|
setActiveTab={setActiveTabHandler}
|
||||||
tabs={tabs}
|
tabs={tabs}
|
||||||
/>
|
/>
|
||||||
|
<div className="tw-flex-grow tw-flex tw-flex-col tw--mx-6 tw-px-7 tw-py-4">
|
||||||
<div className="tw-bg-white tw-flex-grow tw--mx-6 tw-px-7 tw-py-4">
|
<div className="tw-bg-white tw-flex-grow tw-p-4 tw-shadow tw-rounded-md">
|
||||||
{activeTab === 1 && (
|
{activeTab === 1 && (
|
||||||
<div
|
<div
|
||||||
className="tw-grid tw-grid-cols-4 tw-gap-4 tw-w-full"
|
className="tw-grid tw-grid-cols-4 tw-gap-4 tw-w-full"
|
||||||
id="schemaDetails">
|
id="schemaDetails">
|
||||||
<div className="tw-col-span-3">
|
<div className="tw-col-span-3 tw--ml-5">
|
||||||
<Description
|
<Description
|
||||||
description={description}
|
description={description}
|
||||||
entityFieldThreads={getEntityFieldThreadCounts(
|
entityFieldThreads={getEntityFieldThreadCounts(
|
||||||
'description',
|
'description',
|
||||||
entityFieldThreadCount
|
entityFieldThreadCount
|
||||||
)}
|
)}
|
||||||
entityFqn={datasetFQN}
|
entityFqn={datasetFQN}
|
||||||
|
entityName={entityName}
|
||||||
|
entityType={EntityType.TABLE}
|
||||||
|
hasEditAccess={hasEditAccess()}
|
||||||
|
isEdit={isEdit}
|
||||||
|
isReadOnly={deleted}
|
||||||
|
owner={owner}
|
||||||
|
onCancel={onCancel}
|
||||||
|
onDescriptionEdit={onDescriptionEdit}
|
||||||
|
onDescriptionUpdate={onDescriptionUpdate}
|
||||||
|
onEntityFieldSelect={onEntityFieldSelect}
|
||||||
|
onThreadLinkSelect={onThreadLinkSelect}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="tw-col-span-1 tw-border tw-border-main tw-rounded-md">
|
||||||
|
<FrequentlyJoinedTables
|
||||||
|
header="Frequently Joined Tables"
|
||||||
|
tableList={getFrequentlyJoinedWithTables()}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="tw-col-span-full">
|
||||||
|
<SchemaTab
|
||||||
|
columnName={getPartialNameFromTableFQN(
|
||||||
|
datasetFQN,
|
||||||
|
[FqnPart['Column']],
|
||||||
|
FQN_SEPARATOR_CHAR
|
||||||
|
)}
|
||||||
|
columns={columns}
|
||||||
|
entityFieldThreads={getEntityFieldThreadCounts(
|
||||||
|
'columns',
|
||||||
|
entityFieldThreadCount
|
||||||
|
)}
|
||||||
|
entityFqn={datasetFQN}
|
||||||
|
hasEditAccess={hasEditAccess()}
|
||||||
|
isReadOnly={deleted}
|
||||||
|
joins={tableJoinData.columnJoins as ColumnJoins[]}
|
||||||
|
owner={owner}
|
||||||
|
sampleData={sampleData}
|
||||||
|
onEntityFieldSelect={onEntityFieldSelect}
|
||||||
|
onThreadLinkSelect={onThreadLinkSelect}
|
||||||
|
onUpdate={onColumnsUpdate}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{activeTab === 2 && (
|
||||||
|
<div
|
||||||
|
className="tw-py-4 tw-px-7 tw-grid tw-grid-cols-3 entity-feed-list tw--mx-7 tw--my-4"
|
||||||
|
id="activityfeed">
|
||||||
|
<div />
|
||||||
|
<ActivityFeedList
|
||||||
|
isEntityFeed
|
||||||
|
withSidePanel
|
||||||
|
className=""
|
||||||
|
deletePostHandler={deletePostHandler}
|
||||||
entityName={entityName}
|
entityName={entityName}
|
||||||
|
feedList={entityThread}
|
||||||
|
postFeedHandler={postFeedHandler}
|
||||||
|
/>
|
||||||
|
<div />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{activeTab === 3 && (
|
||||||
|
<div id="sampleDataDetails">
|
||||||
|
<SampleDataTable
|
||||||
|
isLoading={isSampleDataLoading}
|
||||||
|
sampleData={getSampleDataWithType()}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{activeTab === 4 && (
|
||||||
|
<div
|
||||||
|
className="tw-py-4 tw-px-7 tw-grid tw-grid-cols-3 entity-feed-list"
|
||||||
|
id="tablequeries">
|
||||||
|
<div />
|
||||||
|
<TableQueries
|
||||||
|
isLoading={isQueriesLoading}
|
||||||
|
queries={tableQueries}
|
||||||
|
/>
|
||||||
|
<div />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{activeTab === 5 && (
|
||||||
|
<div>
|
||||||
|
<TableProfiler
|
||||||
|
columns={columns.map((col) => ({
|
||||||
|
constraint: col.constraint as string,
|
||||||
|
colName: col.name,
|
||||||
|
colType: col.dataTypeDisplay as string,
|
||||||
|
dataType: col.dataType as string,
|
||||||
|
colTests: col.columnTests,
|
||||||
|
}))}
|
||||||
|
isTableDeleted={deleted}
|
||||||
|
qualityTestFormHandler={qualityTestFormHandler}
|
||||||
|
tableProfiles={tableProfile}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{activeTab === 6 && (
|
||||||
|
<DataQualityTab
|
||||||
|
columnOptions={columns}
|
||||||
|
handleAddColumnTestCase={handleAddColumnTestCase}
|
||||||
|
handleAddTableTestCase={handleAddTableTestCase}
|
||||||
|
handleRemoveColumnTest={handleRemoveColumnTest}
|
||||||
|
handleRemoveTableTest={handleRemoveTableTest}
|
||||||
|
handleSelectedColumn={handleSelectedColumn}
|
||||||
|
handleShowTestForm={handleShowTestForm}
|
||||||
|
handleTestModeChange={handleTestModeChange}
|
||||||
|
isTableDeleted={deleted}
|
||||||
|
selectedColumn={selectedColumn}
|
||||||
|
showTestForm={showTestForm}
|
||||||
|
tableTestCase={tableTestCase}
|
||||||
|
testMode={testMode}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{activeTab === 7 && (
|
||||||
|
<div
|
||||||
|
className={classNames(
|
||||||
|
'tw-px-2',
|
||||||
|
location.pathname.includes(ROUTES.TOUR)
|
||||||
|
? 'tw-h-70vh'
|
||||||
|
: 'tw-h-full'
|
||||||
|
)}
|
||||||
|
id="lineageDetails">
|
||||||
|
<Entitylineage
|
||||||
|
addLineageHandler={addLineageHandler}
|
||||||
|
deleted={deleted}
|
||||||
|
entityLineage={entityLineage}
|
||||||
|
entityLineageHandler={entityLineageHandler}
|
||||||
|
isLoading={isLineageLoading}
|
||||||
|
isNodeLoading={isNodeLoading}
|
||||||
|
isOwner={hasEditAccess()}
|
||||||
|
lineageLeafNodes={lineageLeafNodes}
|
||||||
|
loadNodeHandler={loadNodeHandler}
|
||||||
|
removeLineageHandler={removeLineageHandler}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{activeTab === 8 && Boolean(dataModel?.sql) && (
|
||||||
|
<div className="tw-border tw-border-main tw-rounded-md tw-py-4 tw-h-full cm-h-full">
|
||||||
|
<SchemaEditor
|
||||||
|
className="tw-h-full"
|
||||||
|
mode={{ name: CSMode.SQL }}
|
||||||
|
value={dataModel?.sql || ''}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{activeTab === 9 && !deleted && (
|
||||||
|
<div>
|
||||||
|
<ManageTab
|
||||||
|
allowDelete
|
||||||
|
currentTier={tier?.tagFQN}
|
||||||
|
currentUser={owner}
|
||||||
|
entityId={tableDetails.id}
|
||||||
|
entityName={tableDetails.name}
|
||||||
entityType={EntityType.TABLE}
|
entityType={EntityType.TABLE}
|
||||||
hasEditAccess={hasEditAccess()}
|
hasEditAccess={hasEditAccess()}
|
||||||
isEdit={isEdit}
|
manageSectionType={EntityType.TABLE}
|
||||||
isReadOnly={deleted}
|
onSave={onSettingsUpdate}
|
||||||
owner={owner}
|
|
||||||
onCancel={onCancel}
|
|
||||||
onDescriptionEdit={onDescriptionEdit}
|
|
||||||
onDescriptionUpdate={onDescriptionUpdate}
|
|
||||||
onEntityFieldSelect={onEntityFieldSelect}
|
|
||||||
onThreadLinkSelect={onThreadLinkSelect}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="tw-col-span-1 tw-border tw-border-main tw-rounded-md">
|
)}
|
||||||
<FrequentlyJoinedTables
|
|
||||||
header="Frequently Joined Tables"
|
|
||||||
tableList={getFrequentlyJoinedWithTables()}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="tw-col-span-full">
|
|
||||||
<SchemaTab
|
|
||||||
columnName={getPartialNameFromTableFQN(
|
|
||||||
datasetFQN,
|
|
||||||
[FqnPart['Column']],
|
|
||||||
FQN_SEPARATOR_CHAR
|
|
||||||
)}
|
|
||||||
columns={columns}
|
|
||||||
entityFieldThreads={getEntityFieldThreadCounts(
|
|
||||||
'columns',
|
|
||||||
entityFieldThreadCount
|
|
||||||
)}
|
|
||||||
entityFqn={datasetFQN}
|
|
||||||
hasEditAccess={hasEditAccess()}
|
|
||||||
isReadOnly={deleted}
|
|
||||||
joins={tableJoinData.columnJoins as ColumnJoins[]}
|
|
||||||
owner={owner}
|
|
||||||
sampleData={sampleData}
|
|
||||||
onEntityFieldSelect={onEntityFieldSelect}
|
|
||||||
onThreadLinkSelect={onThreadLinkSelect}
|
|
||||||
onUpdate={onColumnsUpdate}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{activeTab === 2 && (
|
|
||||||
<div
|
<div
|
||||||
className="tw-py-4 tw-px-7 tw-grid tw-grid-cols-3 entity-feed-list tw--mx-7 tw--my-4"
|
data-testid="observer-element"
|
||||||
id="activityfeed">
|
id="observer-element"
|
||||||
<div />
|
ref={elementRef as RefObject<HTMLDivElement>}>
|
||||||
<ActivityFeedList
|
{getLoader()}
|
||||||
isEntityFeed
|
|
||||||
withSidePanel
|
|
||||||
className=""
|
|
||||||
deletePostHandler={deletePostHandler}
|
|
||||||
entityName={entityName}
|
|
||||||
feedList={entityThread}
|
|
||||||
postFeedHandler={postFeedHandler}
|
|
||||||
/>
|
|
||||||
<div />
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
|
||||||
{activeTab === 3 && (
|
|
||||||
<div id="sampleDataDetails">
|
|
||||||
<SampleDataTable
|
|
||||||
isLoading={isSampleDataLoading}
|
|
||||||
sampleData={getSampleDataWithType()}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{activeTab === 4 && (
|
|
||||||
<div
|
|
||||||
className="tw-py-4 tw-px-7 tw-grid tw-grid-cols-3 entity-feed-list"
|
|
||||||
id="tablequeries">
|
|
||||||
<div />
|
|
||||||
<TableQueries
|
|
||||||
isLoading={isQueriesLoading}
|
|
||||||
queries={tableQueries}
|
|
||||||
/>
|
|
||||||
<div />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{activeTab === 5 && (
|
|
||||||
<div>
|
|
||||||
<TableProfiler
|
|
||||||
columns={columns.map((col) => ({
|
|
||||||
constraint: col.constraint as string,
|
|
||||||
colName: col.name,
|
|
||||||
colType: col.dataTypeDisplay as string,
|
|
||||||
dataType: col.dataType as string,
|
|
||||||
colTests: col.columnTests,
|
|
||||||
}))}
|
|
||||||
isTableDeleted={deleted}
|
|
||||||
qualityTestFormHandler={qualityTestFormHandler}
|
|
||||||
tableProfiles={tableProfile}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{activeTab === 6 && (
|
|
||||||
<DataQualityTab
|
|
||||||
columnOptions={columns}
|
|
||||||
handleAddColumnTestCase={handleAddColumnTestCase}
|
|
||||||
handleAddTableTestCase={handleAddTableTestCase}
|
|
||||||
handleRemoveColumnTest={handleRemoveColumnTest}
|
|
||||||
handleRemoveTableTest={handleRemoveTableTest}
|
|
||||||
handleSelectedColumn={handleSelectedColumn}
|
|
||||||
handleShowTestForm={handleShowTestForm}
|
|
||||||
handleTestModeChange={handleTestModeChange}
|
|
||||||
isTableDeleted={deleted}
|
|
||||||
selectedColumn={selectedColumn}
|
|
||||||
showTestForm={showTestForm}
|
|
||||||
tableTestCase={tableTestCase}
|
|
||||||
testMode={testMode}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{activeTab === 7 && (
|
|
||||||
<div
|
|
||||||
className={classNames(
|
|
||||||
location.pathname.includes(ROUTES.TOUR)
|
|
||||||
? 'tw-h-70vh'
|
|
||||||
: 'tw-h-full'
|
|
||||||
)}
|
|
||||||
id="lineageDetails">
|
|
||||||
<Entitylineage
|
|
||||||
addLineageHandler={addLineageHandler}
|
|
||||||
deleted={deleted}
|
|
||||||
entityLineage={entityLineage}
|
|
||||||
entityLineageHandler={entityLineageHandler}
|
|
||||||
isLoading={isLineageLoading}
|
|
||||||
isNodeLoading={isNodeLoading}
|
|
||||||
isOwner={hasEditAccess()}
|
|
||||||
lineageLeafNodes={lineageLeafNodes}
|
|
||||||
loadNodeHandler={loadNodeHandler}
|
|
||||||
removeLineageHandler={removeLineageHandler}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{activeTab === 8 && Boolean(dataModel?.sql) && (
|
|
||||||
<div className="tw-border tw-border-main tw-rounded-md tw-py-4 tw-h-full cm-h-full">
|
|
||||||
<SchemaEditor
|
|
||||||
className="tw-h-full"
|
|
||||||
mode={{ name: CSMode.SQL }}
|
|
||||||
value={dataModel?.sql || ''}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{activeTab === 9 && !deleted && (
|
|
||||||
<div>
|
|
||||||
<ManageTab
|
|
||||||
allowDelete
|
|
||||||
currentTier={tier?.tagFQN}
|
|
||||||
currentUser={owner}
|
|
||||||
entityId={tableDetails.id}
|
|
||||||
entityName={tableDetails.name}
|
|
||||||
entityType={EntityType.TABLE}
|
|
||||||
hasEditAccess={hasEditAccess()}
|
|
||||||
manageSectionType={EntityType.TABLE}
|
|
||||||
onSave={onSettingsUpdate}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<div
|
|
||||||
data-testid="observer-element"
|
|
||||||
id="observer-element"
|
|
||||||
ref={elementRef as RefObject<HTMLDivElement>}>
|
|
||||||
{getLoader()}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{threadLink ? (
|
{threadLink ? (
|
||||||
|
@ -393,226 +393,230 @@ const PipelineDetails = ({
|
|||||||
tabs={tabs}
|
tabs={tabs}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className="tw-bg-white tw-flex-grow tw--mx-6 tw-px-7 tw-py-4">
|
<div className="tw-flex-grow tw-flex tw-flex-col tw--mx-6 tw-px-7 tw-py-4">
|
||||||
{activeTab === 1 && (
|
<div className="tw-bg-white tw-flex-grow tw-p-4 tw-shadow tw-rounded-md">
|
||||||
<>
|
{activeTab === 1 && (
|
||||||
<div className="tw-grid tw-grid-cols-4 tw-gap-4 tw-w-full">
|
<>
|
||||||
<div className="tw-col-span-full">
|
<div className="tw-grid tw-grid-cols-4 tw-gap-4 tw-w-full">
|
||||||
<Description
|
<div className="tw-col-span-full tw--ml-5">
|
||||||
description={description}
|
<Description
|
||||||
entityFieldThreads={getEntityFieldThreadCounts(
|
description={description}
|
||||||
'description',
|
entityFieldThreads={getEntityFieldThreadCounts(
|
||||||
entityFieldThreadCount
|
'description',
|
||||||
)}
|
entityFieldThreadCount
|
||||||
entityFqn={pipelineFQN}
|
)}
|
||||||
entityName={entityName}
|
entityFqn={pipelineFQN}
|
||||||
entityType={EntityType.PIPELINE}
|
entityName={entityName}
|
||||||
hasEditAccess={hasEditAccess()}
|
entityType={EntityType.PIPELINE}
|
||||||
isEdit={isEdit}
|
hasEditAccess={hasEditAccess()}
|
||||||
isReadOnly={deleted}
|
isEdit={isEdit}
|
||||||
owner={owner}
|
isReadOnly={deleted}
|
||||||
onCancel={onCancel}
|
owner={owner}
|
||||||
onDescriptionEdit={onDescriptionEdit}
|
onCancel={onCancel}
|
||||||
onDescriptionUpdate={onDescriptionUpdate}
|
onDescriptionEdit={onDescriptionEdit}
|
||||||
onEntityFieldSelect={onEntityFieldSelect}
|
onDescriptionUpdate={onDescriptionUpdate}
|
||||||
onThreadLinkSelect={onThreadLinkSelect}
|
onEntityFieldSelect={onEntityFieldSelect}
|
||||||
/>
|
onThreadLinkSelect={onThreadLinkSelect}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div className="tw-table-responsive tw-my-6">
|
||||||
<div className="tw-table-responsive tw-my-6">
|
{tasks ? (
|
||||||
{tasks ? (
|
<table className="tw-w-full" data-testid="tasks-table">
|
||||||
<table className="tw-w-full" data-testid="tasks-table">
|
<thead>
|
||||||
<thead>
|
<tr className="tableHead-row">
|
||||||
<tr className="tableHead-row">
|
<th className="tableHead-cell">Task Name</th>
|
||||||
<th className="tableHead-cell">Task Name</th>
|
<th className="tableHead-cell">Description</th>
|
||||||
<th className="tableHead-cell">Description</th>
|
<th className="tableHead-cell">Task Type</th>
|
||||||
<th className="tableHead-cell">Task Type</th>
|
</tr>
|
||||||
</tr>
|
</thead>
|
||||||
</thead>
|
<tbody className="tableBody">
|
||||||
<tbody className="tableBody">
|
{tasks?.map((task, index) => (
|
||||||
{tasks?.map((task, index) => (
|
<tr
|
||||||
<tr
|
className={classNames(
|
||||||
className={classNames(
|
'tableBody-row',
|
||||||
'tableBody-row',
|
!isEven(index + 1) ? 'odd-row' : null
|
||||||
!isEven(index + 1) ? 'odd-row' : null
|
)}
|
||||||
)}
|
key={index}>
|
||||||
key={index}>
|
<td className="tableBody-cell">
|
||||||
<td className="tableBody-cell">
|
<Link
|
||||||
<Link
|
target="_blank"
|
||||||
target="_blank"
|
to={{ pathname: task.taskUrl }}>
|
||||||
to={{ pathname: task.taskUrl }}>
|
<span className="tw-flex">
|
||||||
<span className="tw-flex">
|
<span className="tw-mr-1">
|
||||||
<span className="tw-mr-1">
|
{task.displayName}
|
||||||
{task.displayName}
|
|
||||||
</span>
|
|
||||||
<SVGIcons
|
|
||||||
alt="external-link"
|
|
||||||
className="tw-align-middle"
|
|
||||||
icon="external-link"
|
|
||||||
width="12px"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</Link>
|
|
||||||
</td>
|
|
||||||
<td className="tw-group tableBody-cell tw-relative">
|
|
||||||
<div
|
|
||||||
className="tw-cursor-pointer tw-flex"
|
|
||||||
data-testid="description">
|
|
||||||
<div>
|
|
||||||
{task.description ? (
|
|
||||||
<RichTextEditorPreviewer
|
|
||||||
markdown={task.description}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<span className="tw-no-description">
|
|
||||||
No description{' '}
|
|
||||||
</span>
|
</span>
|
||||||
)}
|
<SVGIcons
|
||||||
</div>
|
alt="external-link"
|
||||||
{!deleted && (
|
className="tw-align-middle"
|
||||||
<Fragment>
|
icon="external-link"
|
||||||
<NonAdminAction
|
width="12px"
|
||||||
html={getHtmlForNonAdminAction(
|
/>
|
||||||
Boolean(owner)
|
</span>
|
||||||
)}
|
</Link>
|
||||||
isOwner={hasEditAccess()}
|
</td>
|
||||||
permission={Operation.UpdateDescription}
|
<td className="tw-group tableBody-cell tw-relative">
|
||||||
position="top">
|
<div
|
||||||
<button
|
className="tw-cursor-pointer tw-flex"
|
||||||
className="tw-self-start tw-w-8 tw-h-auto tw-opacity-0 tw-ml-1 group-hover:tw-opacity-100 focus:tw-outline-none"
|
data-testid="description">
|
||||||
onClick={() =>
|
<div>
|
||||||
handleUpdateTask(task, index)
|
{task.description ? (
|
||||||
}>
|
<RichTextEditorPreviewer
|
||||||
<SVGIcons
|
markdown={task.description}
|
||||||
alt="edit"
|
/>
|
||||||
icon="icon-edit"
|
) : (
|
||||||
title="Edit"
|
<span className="tw-no-description">
|
||||||
width="12px"
|
No description{' '}
|
||||||
/>
|
</span>
|
||||||
</button>
|
)}
|
||||||
</NonAdminAction>
|
</div>
|
||||||
{!isNil(
|
{!deleted && (
|
||||||
getFieldThreadElement(
|
<Fragment>
|
||||||
|
<NonAdminAction
|
||||||
|
html={getHtmlForNonAdminAction(
|
||||||
|
Boolean(owner)
|
||||||
|
)}
|
||||||
|
isOwner={hasEditAccess()}
|
||||||
|
permission={Operation.UpdateDescription}
|
||||||
|
position="top">
|
||||||
|
<button
|
||||||
|
className="tw-self-start tw-w-8 tw-h-auto tw-opacity-0 tw-ml-1 group-hover:tw-opacity-100 focus:tw-outline-none"
|
||||||
|
onClick={() =>
|
||||||
|
handleUpdateTask(task, index)
|
||||||
|
}>
|
||||||
|
<SVGIcons
|
||||||
|
alt="edit"
|
||||||
|
icon="icon-edit"
|
||||||
|
title="Edit"
|
||||||
|
width="12px"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</NonAdminAction>
|
||||||
|
{!isNil(
|
||||||
|
getFieldThreadElement(
|
||||||
|
task.name,
|
||||||
|
'description',
|
||||||
|
getEntityFieldThreadCounts(
|
||||||
|
'tasks',
|
||||||
|
entityFieldThreadCount
|
||||||
|
) as EntityFieldThreads[],
|
||||||
|
onThreadLinkSelect
|
||||||
|
)
|
||||||
|
) &&
|
||||||
|
onEntityFieldSelect &&
|
||||||
|
!task.description ? (
|
||||||
|
<button
|
||||||
|
className="focus:tw-outline-none tw-ml-1 tw-opacity-0 group-hover:tw-opacity-100 tw--mt-2"
|
||||||
|
data-testid="request-description"
|
||||||
|
onClick={() =>
|
||||||
|
onEntityFieldSelect?.(
|
||||||
|
`tasks/${task.name}/description`
|
||||||
|
)
|
||||||
|
}>
|
||||||
|
<PopOver
|
||||||
|
position="top"
|
||||||
|
title="Request description"
|
||||||
|
trigger="mouseenter">
|
||||||
|
<SVGIcons
|
||||||
|
alt="request-description"
|
||||||
|
className="tw-mt-2.5"
|
||||||
|
icon={Icons.REQUEST}
|
||||||
|
/>
|
||||||
|
</PopOver>
|
||||||
|
</button>
|
||||||
|
) : null}
|
||||||
|
{getFieldThreadElement(
|
||||||
task.name,
|
task.name,
|
||||||
'description',
|
'description',
|
||||||
getEntityFieldThreadCounts(
|
getEntityFieldThreadCounts(
|
||||||
'tasks',
|
'tasks',
|
||||||
entityFieldThreadCount
|
entityFieldThreadCount
|
||||||
) as EntityFieldThreads[],
|
) as EntityFieldThreads[],
|
||||||
onThreadLinkSelect
|
onThreadLinkSelect,
|
||||||
)
|
EntityType.PIPELINE,
|
||||||
) &&
|
pipelineFQN,
|
||||||
onEntityFieldSelect &&
|
`tasks/${task.name}/description`,
|
||||||
!task.description ? (
|
Boolean(task.description)
|
||||||
<button
|
)}
|
||||||
className="focus:tw-outline-none tw-ml-1 tw-opacity-0 group-hover:tw-opacity-100 tw--mt-2"
|
</Fragment>
|
||||||
data-testid="request-description"
|
)}
|
||||||
onClick={() =>
|
</div>
|
||||||
onEntityFieldSelect?.(
|
</td>
|
||||||
`tasks/${task.name}/description`
|
<td className="tableBody-cell">
|
||||||
)
|
{task.taskType}
|
||||||
}>
|
</td>
|
||||||
<PopOver
|
</tr>
|
||||||
position="top"
|
))}
|
||||||
title="Request description"
|
</tbody>
|
||||||
trigger="mouseenter">
|
</table>
|
||||||
<SVGIcons
|
) : (
|
||||||
alt="request-description"
|
<div className="tw-mt-4 tw-ml-4 tw-flex tw-justify-center tw-font-medium tw-items-center tw-border tw-border-main tw-rounded-md tw-p-8">
|
||||||
className="tw-mt-2.5"
|
<span>No task data is available</span>
|
||||||
icon={Icons.REQUEST}
|
</div>
|
||||||
/>
|
)}
|
||||||
</PopOver>
|
</div>
|
||||||
</button>
|
</>
|
||||||
) : null}
|
)}
|
||||||
{getFieldThreadElement(
|
{activeTab === 2 && (
|
||||||
task.name,
|
<div
|
||||||
'description',
|
className="tw-py-4 tw-px-7 tw-grid tw-grid-cols-3 entity-feed-list tw--mx-7 tw--my-4"
|
||||||
getEntityFieldThreadCounts(
|
id="activityfeed">
|
||||||
'tasks',
|
<div />
|
||||||
entityFieldThreadCount
|
<ActivityFeedList
|
||||||
) as EntityFieldThreads[],
|
isEntityFeed
|
||||||
onThreadLinkSelect,
|
withSidePanel
|
||||||
EntityType.PIPELINE,
|
className=""
|
||||||
pipelineFQN,
|
deletePostHandler={deletePostHandler}
|
||||||
`tasks/${task.name}/description`,
|
entityName={entityName}
|
||||||
Boolean(task.description)
|
feedList={entityThread}
|
||||||
)}
|
postFeedHandler={postFeedHandler}
|
||||||
</Fragment>
|
/>
|
||||||
)}
|
<div />
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td className="tableBody-cell">{task.taskType}</td>
|
|
||||||
</tr>
|
|
||||||
))}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
) : (
|
|
||||||
<div className="tw-mt-4 tw-ml-4 tw-flex tw-justify-center tw-font-medium tw-items-center tw-border tw-border-main tw-rounded-md tw-p-8">
|
|
||||||
<span>No task data is available</span>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</>
|
)}
|
||||||
)}
|
{activeTab === 3 && (
|
||||||
{activeTab === 2 && (
|
<PipelineStatusList
|
||||||
|
isLoading={isPipelineStatusLoading}
|
||||||
|
pipelineStatus={pipelineStatus}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{activeTab === 4 && (
|
||||||
|
<div className="tw-h-full tw-px-3">
|
||||||
|
<Entitylineage
|
||||||
|
addLineageHandler={addLineageHandler}
|
||||||
|
deleted={deleted}
|
||||||
|
entityLineage={entityLineage}
|
||||||
|
entityLineageHandler={entityLineageHandler}
|
||||||
|
isLoading={isLineageLoading}
|
||||||
|
isNodeLoading={isNodeLoading}
|
||||||
|
isOwner={hasEditAccess()}
|
||||||
|
lineageLeafNodes={lineageLeafNodes}
|
||||||
|
loadNodeHandler={loadNodeHandler}
|
||||||
|
removeLineageHandler={removeLineageHandler}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{activeTab === 5 && !deleted && (
|
||||||
|
<div>
|
||||||
|
<ManageTabComponent
|
||||||
|
allowDelete
|
||||||
|
currentTier={tier?.tagFQN}
|
||||||
|
currentUser={owner}
|
||||||
|
entityId={pipelineDetails.id}
|
||||||
|
entityName={pipelineDetails.name}
|
||||||
|
entityType={EntityType.PIPELINE}
|
||||||
|
hasEditAccess={hasEditAccess()}
|
||||||
|
manageSectionType={EntityType.PIPELINE}
|
||||||
|
onSave={onSettingsUpdate}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<div
|
<div
|
||||||
className="tw-py-4 tw-px-7 tw-grid tw-grid-cols-3 entity-feed-list tw--mx-7 tw--my-4"
|
data-testid="observer-element"
|
||||||
id="activityfeed">
|
id="observer-element"
|
||||||
<div />
|
ref={elementRef as RefObject<HTMLDivElement>}>
|
||||||
<ActivityFeedList
|
{getLoader()}
|
||||||
isEntityFeed
|
|
||||||
withSidePanel
|
|
||||||
className=""
|
|
||||||
deletePostHandler={deletePostHandler}
|
|
||||||
entityName={entityName}
|
|
||||||
feedList={entityThread}
|
|
||||||
postFeedHandler={postFeedHandler}
|
|
||||||
/>
|
|
||||||
<div />
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
|
||||||
{activeTab === 3 && (
|
|
||||||
<PipelineStatusList
|
|
||||||
isLoading={isPipelineStatusLoading}
|
|
||||||
pipelineStatus={pipelineStatus}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{activeTab === 4 && (
|
|
||||||
<div className="tw-h-full">
|
|
||||||
<Entitylineage
|
|
||||||
addLineageHandler={addLineageHandler}
|
|
||||||
deleted={deleted}
|
|
||||||
entityLineage={entityLineage}
|
|
||||||
entityLineageHandler={entityLineageHandler}
|
|
||||||
isLoading={isLineageLoading}
|
|
||||||
isNodeLoading={isNodeLoading}
|
|
||||||
isOwner={hasEditAccess()}
|
|
||||||
lineageLeafNodes={lineageLeafNodes}
|
|
||||||
loadNodeHandler={loadNodeHandler}
|
|
||||||
removeLineageHandler={removeLineageHandler}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{activeTab === 5 && !deleted && (
|
|
||||||
<div>
|
|
||||||
<ManageTabComponent
|
|
||||||
allowDelete
|
|
||||||
currentTier={tier?.tagFQN}
|
|
||||||
currentUser={owner}
|
|
||||||
entityId={pipelineDetails.id}
|
|
||||||
entityName={pipelineDetails.name}
|
|
||||||
entityType={EntityType.PIPELINE}
|
|
||||||
hasEditAccess={hasEditAccess()}
|
|
||||||
manageSectionType={EntityType.PIPELINE}
|
|
||||||
onSave={onSettingsUpdate}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<div
|
|
||||||
data-testid="observer-element"
|
|
||||||
id="observer-element"
|
|
||||||
ref={elementRef as RefObject<HTMLDivElement>}>
|
|
||||||
{getLoader()}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -387,99 +387,100 @@ const TopicDetails: React.FC<TopicDetailsProps> = ({
|
|||||||
setActiveTab={setActiveTabHandler}
|
setActiveTab={setActiveTabHandler}
|
||||||
tabs={tabs}
|
tabs={tabs}
|
||||||
/>
|
/>
|
||||||
|
<div className="tw-flex-grow tw-flex tw-flex-col tw--mx-6 tw-px-7 tw-py-4">
|
||||||
<div className="tw-bg-white tw-flex-grow tw--mx-6 tw-px-7 tw-py-4">
|
<div className="tw-bg-white tw-flex-grow tw-p-4 tw-shadow tw-rounded-md">
|
||||||
{activeTab === 1 && (
|
{activeTab === 1 && (
|
||||||
<>
|
<>
|
||||||
<div className="tw-grid tw-grid-cols-4 tw-gap-4 tw-w-full">
|
<div className="tw-grid tw-grid-cols-4 tw-gap-4 tw-w-full">
|
||||||
<div className="tw-col-span-full">
|
<div className="tw-col-span-full tw--ml-5">
|
||||||
<Description
|
<Description
|
||||||
description={description}
|
description={description}
|
||||||
entityFieldThreads={getEntityFieldThreadCounts(
|
entityFieldThreads={getEntityFieldThreadCounts(
|
||||||
'description',
|
'description',
|
||||||
entityFieldThreadCount
|
entityFieldThreadCount
|
||||||
)}
|
)}
|
||||||
entityFqn={topicFQN}
|
entityFqn={topicFQN}
|
||||||
entityName={entityName}
|
entityName={entityName}
|
||||||
entityType={EntityType.TOPIC}
|
entityType={EntityType.TOPIC}
|
||||||
hasEditAccess={hasEditAccess()}
|
hasEditAccess={hasEditAccess()}
|
||||||
isEdit={isEdit}
|
isEdit={isEdit}
|
||||||
isReadOnly={deleted}
|
isReadOnly={deleted}
|
||||||
owner={owner}
|
owner={owner}
|
||||||
onCancel={onCancel}
|
onCancel={onCancel}
|
||||||
onDescriptionEdit={onDescriptionEdit}
|
onDescriptionEdit={onDescriptionEdit}
|
||||||
onDescriptionUpdate={onDescriptionUpdate}
|
onDescriptionUpdate={onDescriptionUpdate}
|
||||||
onEntityFieldSelect={onEntityFieldSelect}
|
onEntityFieldSelect={onEntityFieldSelect}
|
||||||
onThreadLinkSelect={onThreadLinkSelect}
|
onThreadLinkSelect={onThreadLinkSelect}
|
||||||
/>
|
/>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{schemaText ? (
|
|
||||||
<Fragment>
|
|
||||||
{getInfoBadge([{ key: 'Schema', value: schemaType }])}
|
|
||||||
<div
|
|
||||||
className="tw-my-4 tw-border tw-border-main tw-rounded-md tw-py-4"
|
|
||||||
data-testid="schema">
|
|
||||||
<SchemaEditor value={schemaText} />
|
|
||||||
</div>
|
</div>
|
||||||
</Fragment>
|
|
||||||
) : (
|
|
||||||
<div className="tw-flex tw-justify-center tw-font-medium tw-items-center tw-border tw-border-main tw-rounded-md tw-p-8">
|
|
||||||
No schema data available
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
{schemaText ? (
|
||||||
</>
|
<Fragment>
|
||||||
)}
|
{getInfoBadge([{ key: 'Schema', value: schemaType }])}
|
||||||
{activeTab === 2 && (
|
<div
|
||||||
|
className="tw-my-4 tw-border tw-border-main tw-rounded-md tw-py-4"
|
||||||
|
data-testid="schema">
|
||||||
|
<SchemaEditor value={schemaText} />
|
||||||
|
</div>
|
||||||
|
</Fragment>
|
||||||
|
) : (
|
||||||
|
<div className="tw-flex tw-justify-center tw-font-medium tw-items-center tw-border tw-border-main tw-rounded-md tw-p-8">
|
||||||
|
No schema data available
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{activeTab === 2 && (
|
||||||
|
<div
|
||||||
|
className="tw-py-4 tw-px-7 tw-grid tw-grid-cols-3 entity-feed-list tw--mx-7 tw--my-4 "
|
||||||
|
id="activityfeed">
|
||||||
|
<div />
|
||||||
|
<ActivityFeedList
|
||||||
|
isEntityFeed
|
||||||
|
withSidePanel
|
||||||
|
className=""
|
||||||
|
deletePostHandler={deletePostHandler}
|
||||||
|
entityName={entityName}
|
||||||
|
feedList={entityThread}
|
||||||
|
postFeedHandler={postFeedHandler}
|
||||||
|
/>
|
||||||
|
<div />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{activeTab === 3 && (
|
||||||
|
<div data-testid="sample-data">
|
||||||
|
<SampleDataTopic
|
||||||
|
isLoading={isSampleDataLoading}
|
||||||
|
sampleData={sampleData}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{activeTab === 4 && (
|
||||||
|
<div data-testid="config">
|
||||||
|
<SchemaEditor value={JSON.stringify(getConfigObject())} />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{activeTab === 5 && !deleted && (
|
||||||
|
<div>
|
||||||
|
<ManageTabComponent
|
||||||
|
allowDelete
|
||||||
|
currentTier={tier?.tagFQN}
|
||||||
|
currentUser={owner}
|
||||||
|
entityId={topicDetails.id}
|
||||||
|
entityName={topicDetails.name}
|
||||||
|
entityType={EntityType.TOPIC}
|
||||||
|
hasEditAccess={hasEditAccess()}
|
||||||
|
manageSectionType={EntityType.TOPIC}
|
||||||
|
onSave={onSettingsUpdate}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<div
|
<div
|
||||||
className="tw-py-4 tw-px-7 tw-grid tw-grid-cols-3 entity-feed-list tw--mx-7 tw--my-4 "
|
data-testid="observer-element"
|
||||||
id="activityfeed">
|
id="observer-element"
|
||||||
<div />
|
ref={elementRef as RefObject<HTMLDivElement>}>
|
||||||
<ActivityFeedList
|
{getLoader()}
|
||||||
isEntityFeed
|
|
||||||
withSidePanel
|
|
||||||
className=""
|
|
||||||
deletePostHandler={deletePostHandler}
|
|
||||||
entityName={entityName}
|
|
||||||
feedList={entityThread}
|
|
||||||
postFeedHandler={postFeedHandler}
|
|
||||||
/>
|
|
||||||
<div />
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
|
||||||
{activeTab === 3 && (
|
|
||||||
<div data-testid="sample-data">
|
|
||||||
<SampleDataTopic
|
|
||||||
isLoading={isSampleDataLoading}
|
|
||||||
sampleData={sampleData}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{activeTab === 4 && (
|
|
||||||
<div data-testid="config">
|
|
||||||
<SchemaEditor value={JSON.stringify(getConfigObject())} />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{activeTab === 5 && !deleted && (
|
|
||||||
<div>
|
|
||||||
<ManageTabComponent
|
|
||||||
allowDelete
|
|
||||||
currentTier={tier?.tagFQN}
|
|
||||||
currentUser={owner}
|
|
||||||
entityId={topicDetails.id}
|
|
||||||
entityName={topicDetails.name}
|
|
||||||
entityType={EntityType.TOPIC}
|
|
||||||
hasEditAccess={hasEditAccess()}
|
|
||||||
manageSectionType={EntityType.TOPIC}
|
|
||||||
onSave={onSettingsUpdate}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<div
|
|
||||||
data-testid="observer-element"
|
|
||||||
id="observer-element"
|
|
||||||
ref={elementRef as RefObject<HTMLDivElement>}>
|
|
||||||
{getLoader()}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{threadLink ? (
|
{threadLink ? (
|
||||||
|
@ -25,7 +25,7 @@ type Item = {
|
|||||||
email: string;
|
email: string;
|
||||||
isActiveUser?: boolean;
|
isActiveUser?: boolean;
|
||||||
profilePhoto?: string;
|
profilePhoto?: string;
|
||||||
teamCount?: string;
|
teamCount?: string | JSX.Element;
|
||||||
};
|
};
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
@ -73,7 +73,7 @@ const UserDataCard = ({ item, onClick, onDelete, showTeams = true }: Props) => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<p className="tw-truncate">{item.email}</p>
|
<p className="tw-truncate">{item.email}</p>
|
||||||
{showTeams && <p>Teams: {item.teamCount}</p>}
|
{showTeams && <div>Teams: {item.teamCount}</div>}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{!isNil(onDelete) && (
|
{!isNil(onDelete) && (
|
||||||
|
@ -18,6 +18,7 @@ import { getUserPath } from '../../constants/constants';
|
|||||||
import { EntityReference, User } from '../../generated/entity/teams/user';
|
import { EntityReference, User } from '../../generated/entity/teams/user';
|
||||||
import { getEntityName } from '../../utils/CommonUtils';
|
import { getEntityName } from '../../utils/CommonUtils';
|
||||||
import ErrorPlaceHolder from '../common/error-with-placeholder/ErrorPlaceHolder';
|
import ErrorPlaceHolder from '../common/error-with-placeholder/ErrorPlaceHolder';
|
||||||
|
import PopOver from '../common/popover/PopOver';
|
||||||
import Searchbar from '../common/searchbar/Searchbar';
|
import Searchbar from '../common/searchbar/Searchbar';
|
||||||
import Loader from '../Loader/Loader';
|
import Loader from '../Loader/Loader';
|
||||||
import ConfirmationModal from '../Modals/ConfirmationModal/ConfirmationModal';
|
import ConfirmationModal from '../Modals/ConfirmationModal/ConfirmationModal';
|
||||||
@ -66,6 +67,35 @@ const UserDetails = ({
|
|||||||
setDeletingUser(undefined);
|
setDeletingUser(undefined);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getTeamsText = (teams: EntityReference[]) => {
|
||||||
|
return teams.length > 1 ? (
|
||||||
|
<span>
|
||||||
|
{getEntityName(teams[0])}, &{' '}
|
||||||
|
<PopOver
|
||||||
|
html={
|
||||||
|
<span>
|
||||||
|
{teams.map((t, i) => {
|
||||||
|
return i >= 1 ? (
|
||||||
|
<span className="tw-block tw-text-left" key={i}>
|
||||||
|
{getEntityName(t)}
|
||||||
|
</span>
|
||||||
|
) : null;
|
||||||
|
})}
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
position="bottom"
|
||||||
|
theme="light"
|
||||||
|
trigger="mouseenter">
|
||||||
|
<span className="tw-underline tw-cursor-pointer">
|
||||||
|
{teams.length - 1} more
|
||||||
|
</span>
|
||||||
|
</PopOver>
|
||||||
|
</span>
|
||||||
|
) : (
|
||||||
|
`${getEntityName(teams[0])}`
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const getUserCards = () => {
|
const getUserCards = () => {
|
||||||
return isUsersLoading ? (
|
return isUsersLoading ? (
|
||||||
<Loader />
|
<Loader />
|
||||||
@ -84,10 +114,8 @@ const UserDetails = ({
|
|||||||
isActiveUser: !user.deleted,
|
isActiveUser: !user.deleted,
|
||||||
profilePhoto: user.profile?.images?.image || '',
|
profilePhoto: user.profile?.images?.image || '',
|
||||||
teamCount:
|
teamCount:
|
||||||
user.teams && user.teams?.length
|
user.teams && user.teams.length
|
||||||
? user.teams
|
? getTeamsText(user.teams)
|
||||||
?.map((team) => team.displayName ?? team.name)
|
|
||||||
?.join(', ')
|
|
||||||
: 'No teams',
|
: 'No teams',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user