Fixed: UI inconsistency as per feedback #4192 (#4840)

This commit is contained in:
Shailesh Parmar 2022-05-11 15:04:27 +05:30 committed by GitHub
parent 0acf88e1ba
commit 4395cae6b7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 738 additions and 697 deletions

View File

@ -467,235 +467,241 @@ const DashboardDetails = ({
tabs={tabs}
/>
<div className="tw-bg-white tw-flex-grow tw--mx-6 tw-px-7 tw-py-4">
{activeTab === 1 && (
<>
<div className="tw-grid tw-grid-cols-4 tw-gap-4 tw-w-full">
<div className="tw-col-span-full">
<Description
description={description}
entityFieldThreads={getEntityFieldThreadCounts(
'description',
entityFieldThreadCount
)}
entityFqn={dashboardFQN}
entityName={entityName}
entityType={EntityType.DASHBOARD}
hasEditAccess={hasEditAccess()}
isEdit={isEdit}
isReadOnly={deleted}
owner={owner}
onCancel={onCancel}
onDescriptionEdit={onDescriptionEdit}
onDescriptionUpdate={onDescriptionUpdate}
onEntityFieldSelect={onEntityFieldSelect}
onThreadLinkSelect={onThreadLinkSelect}
/>
<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-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 tw--ml-5">
<Description
description={description}
entityFieldThreads={getEntityFieldThreadCounts(
'description',
entityFieldThreadCount
)}
entityFqn={dashboardFQN}
entityName={entityName}
entityType={EntityType.DASHBOARD}
hasEditAccess={hasEditAccess()}
isEdit={isEdit}
isReadOnly={deleted}
owner={owner}
onCancel={onCancel}
onDescriptionEdit={onDescriptionEdit}
onDescriptionUpdate={onDescriptionUpdate}
onEntityFieldSelect={onEntityFieldSelect}
onThreadLinkSelect={onThreadLinkSelect}
/>
</div>
</div>
</div>
<div className="tw-table-responsive tw-my-6">
<table className="tw-w-full" data-testid="charts-table">
<thead>
<tr className="tableHead-row">
<th className="tableHead-cell">Chart Name</th>
<th className="tableHead-cell">Chart Type</th>
<th className="tableHead-cell">Description</th>
<th className="tableHead-cell tw-w-60">Tags</th>
</tr>
</thead>
<tbody className="tableBody">
{charts.map((chart, index) => (
<tr
className={classNames(
'tableBody-row',
!isEven(index + 1) ? 'odd-row' : null
)}
key={index}>
<td className="tableBody-cell">
<Link
target="_blank"
to={{ pathname: chart.chartUrl }}>
<span className="tw-flex">
<span className="tw-mr-1">
{chart.displayName}
<div className="tw-table-responsive tw-my-6">
<table className="tw-w-full" data-testid="charts-table">
<thead>
<tr className="tableHead-row">
<th className="tableHead-cell">Chart Name</th>
<th className="tableHead-cell">Chart Type</th>
<th className="tableHead-cell">Description</th>
<th className="tableHead-cell tw-w-60">Tags</th>
</tr>
</thead>
<tbody className="tableBody">
{charts.map((chart, index) => (
<tr
className={classNames(
'tableBody-row',
!isEven(index + 1) ? 'odd-row' : null
)}
key={index}>
<td className="tableBody-cell">
<Link
target="_blank"
to={{ pathname: chart.chartUrl }}>
<span className="tw-flex">
<span className="tw-mr-1">
{chart.displayName}
</span>
<SVGIcons
alt="external-link"
className="tw-align-middle"
icon="external-link"
width="12px"
/>
</span>
<SVGIcons
alt="external-link"
className="tw-align-middle"
icon="external-link"
width="12px"
/>
</span>
</Link>
</td>
<td className="tableBody-cell">{chart.chartType}</td>
<td className="tw-group tableBody-cell tw-relative">
<div className="tw-inline-block">
<div
className="tw-cursor-pointer tw-flex"
data-testid="description">
<div>
{chart.description ? (
<RichTextEditorPreviewer
markdown={chart.description}
/>
) : (
<span className="tw-no-description">
No description
</span>
</Link>
</td>
<td className="tableBody-cell">
{chart.chartType}
</td>
<td className="tw-group tableBody-cell tw-relative">
<div className="tw-inline-block">
<div
className="tw-cursor-pointer tw-flex"
data-testid="description">
<div>
{chart.description ? (
<RichTextEditorPreviewer
markdown={chart.description}
/>
) : (
<span className="tw-no-description">
No description
</span>
)}
</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>
{!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>
</td>
<td
className="tw-group tw-relative tableBody-cell"
onClick={() => {
if (!editChartTags) {
// Fetch tags and terms only once
if (tagList.length === 0 || tagFetchFailed) {
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
</td>
<td
className="tw-group tw-relative tableBody-cell"
onClick={() => {
if (!editChartTags) {
// Fetch tags and terms only once
if (tagList.length === 0 || tagFetchFailed) {
fetchTagsAndGlossaryTerms();
}
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>
handleEditChartTag(chart, index);
}
}}>
{deleted ? (
<div className="tw-flex tw-flex-wrap">
<TagsViewer
sizeCap={-1}
tags={chart.tags || []}
/>
</div>
) : (
<NonAdminAction
html={getHtmlForNonAdminAction(
Boolean(owner)
)}
</TagsContainer>
</NonAdminAction>
)}
</td>
</tr>
))}
</tbody>
</table>
isOwner={hasEditAccess()}
permission={Operation.UpdateTags}
position="left"
trigger="click">
<TagsContainer
editable={editChartTags?.index === index}
isLoading={
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>
</>
)}
{activeTab === 2 && (
)}
{activeTab === 3 && (
<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
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 />
data-testid="observer-element"
id="observer-element"
ref={elementRef as RefObject<HTMLDivElement>}>
{getLoader()}
</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>

View File

@ -579,187 +579,189 @@ const DatasetDetails: React.FC<DatasetDetailsProps> = ({
setActiveTab={setActiveTabHandler}
tabs={tabs}
/>
<div className="tw-bg-white tw-flex-grow tw--mx-6 tw-px-7 tw-py-4">
{activeTab === 1 && (
<div
className="tw-grid tw-grid-cols-4 tw-gap-4 tw-w-full"
id="schemaDetails">
<div className="tw-col-span-3">
<Description
description={description}
entityFieldThreads={getEntityFieldThreadCounts(
'description',
entityFieldThreadCount
)}
entityFqn={datasetFQN}
<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-p-4 tw-shadow tw-rounded-md">
{activeTab === 1 && (
<div
className="tw-grid tw-grid-cols-4 tw-gap-4 tw-w-full"
id="schemaDetails">
<div className="tw-col-span-3 tw--ml-5">
<Description
description={description}
entityFieldThreads={getEntityFieldThreadCounts(
'description',
entityFieldThreadCount
)}
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}
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}
hasEditAccess={hasEditAccess()}
isEdit={isEdit}
isReadOnly={deleted}
owner={owner}
onCancel={onCancel}
onDescriptionEdit={onDescriptionEdit}
onDescriptionUpdate={onDescriptionUpdate}
onEntityFieldSelect={onEntityFieldSelect}
onThreadLinkSelect={onThreadLinkSelect}
manageSectionType={EntityType.TABLE}
onSave={onSettingsUpdate}
/>
</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}
feedList={entityThread}
postFeedHandler={postFeedHandler}
/>
<div />
data-testid="observer-element"
id="observer-element"
ref={elementRef as RefObject<HTMLDivElement>}>
{getLoader()}
</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>
{threadLink ? (

View File

@ -393,226 +393,230 @@ const PipelineDetails = ({
tabs={tabs}
/>
<div className="tw-bg-white tw-flex-grow tw--mx-6 tw-px-7 tw-py-4">
{activeTab === 1 && (
<>
<div className="tw-grid tw-grid-cols-4 tw-gap-4 tw-w-full">
<div className="tw-col-span-full">
<Description
description={description}
entityFieldThreads={getEntityFieldThreadCounts(
'description',
entityFieldThreadCount
)}
entityFqn={pipelineFQN}
entityName={entityName}
entityType={EntityType.PIPELINE}
hasEditAccess={hasEditAccess()}
isEdit={isEdit}
isReadOnly={deleted}
owner={owner}
onCancel={onCancel}
onDescriptionEdit={onDescriptionEdit}
onDescriptionUpdate={onDescriptionUpdate}
onEntityFieldSelect={onEntityFieldSelect}
onThreadLinkSelect={onThreadLinkSelect}
/>
<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-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 tw--ml-5">
<Description
description={description}
entityFieldThreads={getEntityFieldThreadCounts(
'description',
entityFieldThreadCount
)}
entityFqn={pipelineFQN}
entityName={entityName}
entityType={EntityType.PIPELINE}
hasEditAccess={hasEditAccess()}
isEdit={isEdit}
isReadOnly={deleted}
owner={owner}
onCancel={onCancel}
onDescriptionEdit={onDescriptionEdit}
onDescriptionUpdate={onDescriptionUpdate}
onEntityFieldSelect={onEntityFieldSelect}
onThreadLinkSelect={onThreadLinkSelect}
/>
</div>
</div>
</div>
<div className="tw-table-responsive tw-my-6">
{tasks ? (
<table className="tw-w-full" data-testid="tasks-table">
<thead>
<tr className="tableHead-row">
<th className="tableHead-cell">Task Name</th>
<th className="tableHead-cell">Description</th>
<th className="tableHead-cell">Task Type</th>
</tr>
</thead>
<tbody className="tableBody">
{tasks?.map((task, index) => (
<tr
className={classNames(
'tableBody-row',
!isEven(index + 1) ? 'odd-row' : null
)}
key={index}>
<td className="tableBody-cell">
<Link
target="_blank"
to={{ pathname: task.taskUrl }}>
<span className="tw-flex">
<span className="tw-mr-1">
{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{' '}
<div className="tw-table-responsive tw-my-6">
{tasks ? (
<table className="tw-w-full" data-testid="tasks-table">
<thead>
<tr className="tableHead-row">
<th className="tableHead-cell">Task Name</th>
<th className="tableHead-cell">Description</th>
<th className="tableHead-cell">Task Type</th>
</tr>
</thead>
<tbody className="tableBody">
{tasks?.map((task, index) => (
<tr
className={classNames(
'tableBody-row',
!isEven(index + 1) ? 'odd-row' : null
)}
key={index}>
<td className="tableBody-cell">
<Link
target="_blank"
to={{ pathname: task.taskUrl }}>
<span className="tw-flex">
<span className="tw-mr-1">
{task.displayName}
</span>
)}
</div>
{!deleted && (
<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(
<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>
)}
</div>
{!deleted && (
<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,
'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,
'description',
getEntityFieldThreadCounts(
'tasks',
entityFieldThreadCount
) as EntityFieldThreads[],
onThreadLinkSelect,
EntityType.PIPELINE,
pipelineFQN,
`tasks/${task.name}/description`,
Boolean(task.description)
)}
</Fragment>
)}
</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>
)}
onThreadLinkSelect,
EntityType.PIPELINE,
pipelineFQN,
`tasks/${task.name}/description`,
Boolean(task.description)
)}
</Fragment>
)}
</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>
</>
)}
{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 === 2 && (
)}
{activeTab === 3 && (
<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
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 />
data-testid="observer-element"
id="observer-element"
ref={elementRef as RefObject<HTMLDivElement>}>
{getLoader()}
</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>

View File

@ -387,99 +387,100 @@ const TopicDetails: React.FC<TopicDetailsProps> = ({
setActiveTab={setActiveTabHandler}
tabs={tabs}
/>
<div className="tw-bg-white tw-flex-grow tw--mx-6 tw-px-7 tw-py-4">
{activeTab === 1 && (
<>
<div className="tw-grid tw-grid-cols-4 tw-gap-4 tw-w-full">
<div className="tw-col-span-full">
<Description
description={description}
entityFieldThreads={getEntityFieldThreadCounts(
'description',
entityFieldThreadCount
)}
entityFqn={topicFQN}
entityName={entityName}
entityType={EntityType.TOPIC}
hasEditAccess={hasEditAccess()}
isEdit={isEdit}
isReadOnly={deleted}
owner={owner}
onCancel={onCancel}
onDescriptionEdit={onDescriptionEdit}
onDescriptionUpdate={onDescriptionUpdate}
onEntityFieldSelect={onEntityFieldSelect}
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 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-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 tw--ml-5">
<Description
description={description}
entityFieldThreads={getEntityFieldThreadCounts(
'description',
entityFieldThreadCount
)}
entityFqn={topicFQN}
entityName={entityName}
entityType={EntityType.TOPIC}
hasEditAccess={hasEditAccess()}
isEdit={isEdit}
isReadOnly={deleted}
owner={owner}
onCancel={onCancel}
onDescriptionEdit={onDescriptionEdit}
onDescriptionUpdate={onDescriptionUpdate}
onEntityFieldSelect={onEntityFieldSelect}
onThreadLinkSelect={onThreadLinkSelect}
/>
</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 && (
{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>
</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
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 />
data-testid="observer-element"
id="observer-element"
ref={elementRef as RefObject<HTMLDivElement>}>
{getLoader()}
</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>
{threadLink ? (

View File

@ -25,7 +25,7 @@ type Item = {
email: string;
isActiveUser?: boolean;
profilePhoto?: string;
teamCount?: string;
teamCount?: string | JSX.Element;
};
type Props = {
@ -73,7 +73,7 @@ const UserDataCard = ({ item, onClick, onDelete, showTeams = true }: Props) => {
)}
</div>
<p className="tw-truncate">{item.email}</p>
{showTeams && <p>Teams: {item.teamCount}</p>}
{showTeams && <div>Teams: {item.teamCount}</div>}
</div>
</div>
{!isNil(onDelete) && (

View File

@ -18,6 +18,7 @@ import { getUserPath } from '../../constants/constants';
import { EntityReference, User } from '../../generated/entity/teams/user';
import { getEntityName } from '../../utils/CommonUtils';
import ErrorPlaceHolder from '../common/error-with-placeholder/ErrorPlaceHolder';
import PopOver from '../common/popover/PopOver';
import Searchbar from '../common/searchbar/Searchbar';
import Loader from '../Loader/Loader';
import ConfirmationModal from '../Modals/ConfirmationModal/ConfirmationModal';
@ -66,6 +67,35 @@ const UserDetails = ({
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 = () => {
return isUsersLoading ? (
<Loader />
@ -84,10 +114,8 @@ const UserDetails = ({
isActiveUser: !user.deleted,
profilePhoto: user.profile?.images?.image || '',
teamCount:
user.teams && user.teams?.length
? user.teams
?.map((team) => team.displayName ?? team.name)
?.join(', ')
user.teams && user.teams.length
? getTeamsText(user.teams)
: 'No teams',
};