mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-10-11 08:43:31 +00:00
Fix: UI changes from feedback (#1731)
* Fix: UI changes from feedback * Minor change
This commit is contained in:
parent
52571efdc9
commit
324573dc76
@ -0,0 +1,3 @@
|
|||||||
|
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M6.85588 12C6.85617 12 6.85654 12 6.8569 12C7.23244 11.9997 7.58557 11.8532 7.85102 11.5874L11.5899 7.84343C12.1367 7.29558 12.1367 6.40415 11.5899 5.85637L6.54985 0.807056C6.03045 0.28667 5.33936 0 4.60396 0H1.40635C0.630953 0 0 0.630762 0 1.40625V4.59382C0 5.32866 0.286397 6.01941 0.806307 6.5387L5.86198 11.5887C6.12758 11.854 6.48056 12 6.85588 12ZM4.60396 0.9375C5.08857 0.9375 5.54394 1.12639 5.88623 1.46931L10.9263 6.51863C11.1086 6.70129 11.1086 6.99836 10.9263 7.18103L7.18747 10.925C7.09906 11.0135 6.98142 11.0624 6.85617 11.0625H6.8558C6.7307 11.0625 6.61306 11.0138 6.52458 10.9255L1.4689 5.87549C1.12625 5.5333 0.937566 5.07803 0.937566 4.59382V1.40625C0.937566 1.14778 1.14786 0.9375 1.40635 0.9375H4.60396ZM3.39875 4.75781C4.17422 4.75781 4.8051 4.12705 4.8051 3.35156C4.8051 2.57607 4.17422 1.94531 3.39875 1.94531C2.62328 1.94531 1.9924 2.57607 1.9924 3.35156C1.9924 4.12705 2.62328 4.75781 3.39875 4.75781ZM3.39875 2.88281C3.65724 2.88281 3.86753 3.09309 3.86753 3.35156C3.86753 3.61003 3.65724 3.82031 3.39875 3.82031C3.14019 3.82031 2.92997 3.61003 2.92997 3.35156C2.92997 3.09309 3.14019 2.88281 3.39875 2.88281Z" fill="#6b7280"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
@ -424,6 +424,7 @@ const DashboardDetails = ({
|
|||||||
editable={editChartTags?.index === index}
|
editable={editChartTags?.index === index}
|
||||||
selectedTags={chart.tags as EntityTags[]}
|
selectedTags={chart.tags as EntityTags[]}
|
||||||
tagList={tagList}
|
tagList={tagList}
|
||||||
|
type="label"
|
||||||
onCancel={() => {
|
onCancel={() => {
|
||||||
handleChartTagSelection();
|
handleChartTagSelection();
|
||||||
}}
|
}}
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { isEqual, isNil, isUndefined } from 'lodash';
|
import { isEqual, isNil, isUndefined } from 'lodash';
|
||||||
import { ColumnJoins, EntityTags } from 'Models';
|
import { ColumnJoins, EntityTags, ExtraInfo } from 'Models';
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { getTeamDetailsPath } from '../../constants/constants';
|
import { getTeamDetailsPath } from '../../constants/constants';
|
||||||
import { CSMode } from '../../enums/codemirror.enum';
|
import { CSMode } from '../../enums/codemirror.enum';
|
||||||
@ -93,7 +93,8 @@ const DatasetDetails: React.FC<DatasetDetailsProps> = ({
|
|||||||
) => {
|
) => {
|
||||||
if (!isNil(usageSummary?.weeklyStats?.percentileRank)) {
|
if (!isNil(usageSummary?.weeklyStats?.percentileRank)) {
|
||||||
const percentile = getUsagePercentile(
|
const percentile = getUsagePercentile(
|
||||||
usageSummary?.weeklyStats?.percentileRank || 0
|
usageSummary?.weeklyStats?.percentileRank || 0,
|
||||||
|
true
|
||||||
);
|
);
|
||||||
setUsage(percentile);
|
setUsage(percentile);
|
||||||
} else {
|
} else {
|
||||||
@ -201,13 +202,7 @@ const DatasetDetails: React.FC<DatasetDetailsProps> = ({
|
|||||||
return freqJoin;
|
return freqJoin;
|
||||||
};
|
};
|
||||||
|
|
||||||
const extraInfo: Array<{
|
const extraInfo: Array<ExtraInfo> = [
|
||||||
key?: string;
|
|
||||||
value: string | number | React.ReactNode;
|
|
||||||
isLink?: boolean;
|
|
||||||
placeholderText?: string;
|
|
||||||
openInNewTab?: boolean;
|
|
||||||
}> = [
|
|
||||||
{
|
{
|
||||||
key: 'Owner',
|
key: 'Owner',
|
||||||
value:
|
value:
|
||||||
@ -219,19 +214,22 @@ const DatasetDetails: React.FC<DatasetDetailsProps> = ({
|
|||||||
openInNewTab: false,
|
openInNewTab: false,
|
||||||
},
|
},
|
||||||
{ key: 'Tier', value: tier?.tagFQN ? tier.tagFQN.split('.')[1] : '' },
|
{ key: 'Tier', value: tier?.tagFQN ? tier.tagFQN.split('.')[1] : '' },
|
||||||
{ key: 'Usage', value: usage },
|
{ value: usage },
|
||||||
{ key: 'Queries', value: `${weeklyUsageCount} past week` },
|
{ value: `${weeklyUsageCount} queries past week` },
|
||||||
{
|
{
|
||||||
key: 'Columns',
|
key: 'Columns',
|
||||||
value:
|
value:
|
||||||
tableProfile && tableProfile[0]?.columnCount
|
tableProfile && tableProfile[0]?.columnCount
|
||||||
? tableProfile[0].columnCount
|
? `${tableProfile[0].columnCount} columns`
|
||||||
: '--',
|
: columns.length
|
||||||
|
? `${columns.length} columns`
|
||||||
|
: '',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'Rows',
|
key: 'Rows',
|
||||||
value:
|
value:
|
||||||
!isUndefined(tableProfile) && tableProfile.length > 0 ? (
|
!isUndefined(tableProfile) && tableProfile.length > 0 ? (
|
||||||
|
<>
|
||||||
<TableProfilerGraph
|
<TableProfilerGraph
|
||||||
className="tw--mt-5"
|
className="tw--mt-5"
|
||||||
data={
|
data={
|
||||||
@ -248,8 +246,10 @@ const DatasetDetails: React.FC<DatasetDetailsProps> = ({
|
|||||||
height={38}
|
height={38}
|
||||||
toolTipPos={{ x: 20, y: -30 }}
|
toolTipPos={{ x: 20, y: -30 }}
|
||||||
/>
|
/>
|
||||||
|
rows
|
||||||
|
</>
|
||||||
) : (
|
) : (
|
||||||
'--'
|
''
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { cloneDeep, isEqual, isUndefined } from 'lodash';
|
import { cloneDeep, isEqual, isUndefined } from 'lodash';
|
||||||
|
import { ExtraInfo } from 'Models';
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import {
|
import {
|
||||||
ChangeDescription,
|
ChangeDescription,
|
||||||
@ -103,7 +104,7 @@ const DatasetVersion: React.FC<DatasetVersionProp> = ({
|
|||||||
),
|
),
|
||||||
].find((t) => (t?.tagFQN as string).startsWith('Tier'));
|
].find((t) => (t?.tagFQN as string).startsWith('Tier'));
|
||||||
|
|
||||||
const extraInfo = [
|
const extraInfo: Array<ExtraInfo> = [
|
||||||
{
|
{
|
||||||
key: 'Owner',
|
key: 'Owner',
|
||||||
value:
|
value:
|
||||||
|
@ -529,6 +529,7 @@ const EntityTable = ({
|
|||||||
key={i}
|
key={i}
|
||||||
startWith="#"
|
startWith="#"
|
||||||
tag={tag}
|
tag={tag}
|
||||||
|
type="label"
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
)}
|
)}
|
||||||
@ -549,6 +550,7 @@ const EntityTable = ({
|
|||||||
editable={editColumnTag?.index === row.id}
|
editable={editColumnTag?.index === row.id}
|
||||||
selectedTags={cell.value || []}
|
selectedTags={cell.value || []}
|
||||||
tagList={allTags}
|
tagList={allTags}
|
||||||
|
type="label"
|
||||||
onCancel={() => {
|
onCancel={() => {
|
||||||
handleTagSelection();
|
handleTagSelection();
|
||||||
}}
|
}}
|
||||||
|
@ -383,7 +383,7 @@ const Explore: React.FC<ExploreProps> = ({
|
|||||||
const getTabs = () => {
|
const getTabs = () => {
|
||||||
return (
|
return (
|
||||||
<div className="tw-mb-5">
|
<div className="tw-mb-5">
|
||||||
<nav className="tw-flex tw-flex-row tw-gh-tabs-container tw-mx-6 tw-justify-around">
|
<nav className="tw-flex tw-flex-row tw-gh-tabs-container tw-mx-9 tw-pl-72 tw-pr-80 tw-justify-between">
|
||||||
<div>
|
<div>
|
||||||
{tabsInfo.map((tabDetail, index) => (
|
{tabsInfo.map((tabDetail, index) => (
|
||||||
<button
|
<button
|
||||||
|
@ -76,11 +76,23 @@ const TopicDetails: React.FC<TopicDetailsProps> = ({
|
|||||||
|
|
||||||
const getConfigDetails = () => {
|
const getConfigDetails = () => {
|
||||||
return [
|
return [
|
||||||
{ key: 'Partitions', value: partitions },
|
{ key: 'Partitions', value: `${partitions} partitions` },
|
||||||
{ key: 'Replication Factor', value: replicationFactor },
|
{
|
||||||
{ key: 'Retention Size', value: bytesToSize(retentionSize) },
|
key: 'Replication Factor',
|
||||||
{ key: 'CleanUp Policies', value: cleanupPolicies.join(',') },
|
value: `${replicationFactor} replication factor`,
|
||||||
{ key: 'Max Message Size', value: bytesToSize(maximumMessageSize) },
|
},
|
||||||
|
{
|
||||||
|
key: 'Retention Size',
|
||||||
|
value: `${bytesToSize(retentionSize)} retention size`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'Clean-up Policies',
|
||||||
|
value: `${cleanupPolicies.join(', ')} clean-up policies`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'Max Message Size',
|
||||||
|
value: `${bytesToSize(maximumMessageSize)} maximum size`,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -12,13 +12,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { isNil, isUndefined } from 'lodash';
|
import { isUndefined } from 'lodash';
|
||||||
import { EntityTags, TableDetail } from 'Models';
|
import { EntityTags, ExtraInfo, TableDetail } from 'Models';
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { FOLLOWERS_VIEW_CAP, LIST_SIZE } from '../../../constants/constants';
|
import { FOLLOWERS_VIEW_CAP, LIST_SIZE } from '../../../constants/constants';
|
||||||
import { User } from '../../../generated/entity/teams/user';
|
import { User } from '../../../generated/entity/teams/user';
|
||||||
import { TagLabel } from '../../../generated/type/tagLabel';
|
import { TagLabel } from '../../../generated/type/tagLabel';
|
||||||
import { getHtmlForNonAdminAction } from '../../../utils/CommonUtils';
|
import { getHtmlForNonAdminAction } from '../../../utils/CommonUtils';
|
||||||
|
import { getInfoElements } from '../../../utils/EntityUtils';
|
||||||
import SVGIcons from '../../../utils/SvgUtils';
|
import SVGIcons from '../../../utils/SvgUtils';
|
||||||
import { getFollowerDetail } from '../../../utils/TableUtils';
|
import { getFollowerDetail } from '../../../utils/TableUtils';
|
||||||
import TagsContainer from '../../tags-container/tags-container';
|
import TagsContainer from '../../tags-container/tags-container';
|
||||||
@ -30,14 +31,6 @@ import TitleBreadcrumb from '../title-breadcrumb/title-breadcrumb.component';
|
|||||||
import { TitleBreadcrumbProps } from '../title-breadcrumb/title-breadcrumb.interface';
|
import { TitleBreadcrumbProps } from '../title-breadcrumb/title-breadcrumb.interface';
|
||||||
import FollowersModal from './FollowersModal';
|
import FollowersModal from './FollowersModal';
|
||||||
|
|
||||||
type ExtraInfo = {
|
|
||||||
key?: string;
|
|
||||||
value: string | number | React.ReactNode;
|
|
||||||
isLink?: boolean;
|
|
||||||
placeholderText?: string;
|
|
||||||
openInNewTab?: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
titleLinks: TitleBreadcrumbProps['titleLinks'];
|
titleLinks: TitleBreadcrumbProps['titleLinks'];
|
||||||
isFollowing?: boolean;
|
isFollowing?: boolean;
|
||||||
@ -253,80 +246,40 @@ const EntityPageInfo = ({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="tw-flex tw-gap-1 tw-mb-2 tw-mt-1">
|
<div className="tw-flex tw-gap-1 tw-mb-2 tw-mt-1 tw-ml-7">
|
||||||
{extraInfo.map((info, index) => (
|
{extraInfo.map((info, index) => (
|
||||||
<span className="tw-flex" key={index}>
|
<span className="tw-flex" key={index}>
|
||||||
{!isNil(info.key) ? (
|
{getInfoElements(info)}
|
||||||
<>
|
|
||||||
<span className="tw-text-grey-muted tw-font-normal">
|
|
||||||
{info.key} :
|
|
||||||
</span>{' '}
|
|
||||||
<span className="tw-pl-1 tw-font-normal">
|
|
||||||
{info.isLink ? (
|
|
||||||
<a
|
|
||||||
className="link-text"
|
|
||||||
href={info.value as string}
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
target={info.openInNewTab ? '_blank' : '_self'}>
|
|
||||||
<>
|
|
||||||
<span className="tw-mr-1">
|
|
||||||
{info.placeholderText || info.value}
|
|
||||||
</span>
|
|
||||||
{info.openInNewTab && (
|
|
||||||
<SVGIcons
|
|
||||||
alt="external-link"
|
|
||||||
className="tw-align-middle"
|
|
||||||
icon="external-link"
|
|
||||||
width="12px"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
</a>
|
|
||||||
) : (
|
|
||||||
info.value || '--'
|
|
||||||
)}
|
|
||||||
</span>
|
|
||||||
{extraInfo.length !== 1 && index < extraInfo.length - 1 ? (
|
{extraInfo.length !== 1 && index < extraInfo.length - 1 ? (
|
||||||
<span className="tw-mx-3 tw-inline-block tw-text-gray-400">
|
<span className="tw-mx-3 tw-inline-block tw-text-gray-400">
|
||||||
•
|
|
|
||||||
</span>
|
</span>
|
||||||
) : null}
|
) : null}
|
||||||
</>
|
|
||||||
) : !isNil(info.value) ? (
|
|
||||||
<>
|
|
||||||
<span className="tw-font-normal">{info.value}</span>
|
|
||||||
{extraInfo.length !== 1 && index < extraInfo.length - 1 ? (
|
|
||||||
<span className="tw-mx-3 tw-inline-block tw-text-gray-400">
|
|
||||||
•
|
|
||||||
</span>
|
|
||||||
) : null}
|
|
||||||
</>
|
|
||||||
) : null}
|
|
||||||
</span>
|
</span>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<div className="tw-flex tw-flex-wrap tw-pt-1 tw-group">
|
<div className="tw-flex tw-flex-wrap tw-pt-1 tw-ml-7 tw-group">
|
||||||
{(!isEditable || !isTagEditable) && (
|
{(!isEditable || !isTagEditable) && (
|
||||||
<>
|
<>
|
||||||
{(tags.length > 0 || tier) && (
|
{(tags.length > 0 || tier) && (
|
||||||
<i className="fas fa-tags tw-px-1 tw-mt-2 tw-text-grey-muted" />
|
<SVGIcons
|
||||||
|
alt="icon-tag"
|
||||||
|
className="tw-mx-1"
|
||||||
|
icon="icon-tag-grey"
|
||||||
|
width="16"
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
{tier?.tagFQN && (
|
{tier?.tagFQN && (
|
||||||
<Tags
|
<Tags
|
||||||
className="tw-bg-tag"
|
|
||||||
startWith="#"
|
startWith="#"
|
||||||
tag={{ ...tier, tagFQN: tier.tagFQN.split('.')[1] }}
|
tag={{ ...tier, tagFQN: tier.tagFQN.split('.')[1] }}
|
||||||
|
type="label"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{tags.length > 0 && (
|
{tags.length > 0 && (
|
||||||
<>
|
<>
|
||||||
{tags.slice(0, LIST_SIZE).map((tag, index) => (
|
{tags.slice(0, LIST_SIZE).map((tag, index) => (
|
||||||
<Tags
|
<Tags key={index} startWith="#" tag={tag} type="label" />
|
||||||
className="tw-bg-tag"
|
|
||||||
key={index}
|
|
||||||
startWith="#"
|
|
||||||
tag={tag}
|
|
||||||
/>
|
|
||||||
))}
|
))}
|
||||||
|
|
||||||
{tags.slice(LIST_SIZE).length > 0 && (
|
{tags.slice(LIST_SIZE).length > 0 && (
|
||||||
@ -335,11 +288,7 @@ const EntityPageInfo = ({
|
|||||||
<>
|
<>
|
||||||
{tags.slice(LIST_SIZE).map((tag, index) => (
|
{tags.slice(LIST_SIZE).map((tag, index) => (
|
||||||
<p className="tw-text-left" key={index}>
|
<p className="tw-text-left" key={index}>
|
||||||
<Tags
|
<Tags startWith="#" tag={tag} type="label" />
|
||||||
className="tw-bg-tag tw-px-2"
|
|
||||||
startWith="#"
|
|
||||||
tag={tag}
|
|
||||||
/>
|
|
||||||
</p>
|
</p>
|
||||||
))}
|
))}
|
||||||
</>
|
</>
|
||||||
@ -386,12 +335,12 @@ const EntityPageInfo = ({
|
|||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
) : (
|
) : (
|
||||||
<span className="">
|
<span>
|
||||||
<Tags
|
<Tags
|
||||||
className="tw-border-main tw-text-primary"
|
className="tw-text-primary"
|
||||||
startWith="+ "
|
startWith="+ "
|
||||||
tag="Add tag"
|
tag="Add tag"
|
||||||
type="outlined"
|
type="label"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
@ -12,16 +12,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { isString, isUndefined, startCase, uniqueId } from 'lodash';
|
import { isString, isUndefined, startCase, uniqueId } from 'lodash';
|
||||||
|
import { ExtraInfo } from 'Models';
|
||||||
import React, { FunctionComponent } from 'react';
|
import React, { FunctionComponent } from 'react';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { SearchIndex } from '../../../enums/search.enum';
|
import { SearchIndex } from '../../../enums/search.enum';
|
||||||
import { TagLabel } from '../../../generated/type/tagLabel';
|
import { TagLabel } from '../../../generated/type/tagLabel';
|
||||||
|
import { serviceTypeLogo } from '../../../utils/ServiceUtils';
|
||||||
import { stringToHTML } from '../../../utils/StringsUtils';
|
import { stringToHTML } from '../../../utils/StringsUtils';
|
||||||
import {
|
import { getEntityLink, getUsagePercentile } from '../../../utils/TableUtils';
|
||||||
getEntityIcon,
|
|
||||||
getEntityLink,
|
|
||||||
getUsagePercentile,
|
|
||||||
} from '../../../utils/TableUtils';
|
|
||||||
import TableDataCardBody from './TableDataCardBody';
|
import TableDataCardBody from './TableDataCardBody';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
@ -44,7 +42,7 @@ type Props = {
|
|||||||
|
|
||||||
const TableDataCard: FunctionComponent<Props> = ({
|
const TableDataCard: FunctionComponent<Props> = ({
|
||||||
name,
|
name,
|
||||||
owner = '--',
|
owner = '',
|
||||||
description,
|
description,
|
||||||
tier = '',
|
tier = '',
|
||||||
usage,
|
usage,
|
||||||
@ -60,12 +58,12 @@ const TableDataCard: FunctionComponent<Props> = ({
|
|||||||
return isString(tier) ? tier : tier.tagFQN.split('.')[1];
|
return isString(tier) ? tier : tier.tagFQN.split('.')[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
return 'No Tier';
|
return '';
|
||||||
};
|
};
|
||||||
|
|
||||||
const OtherDetails = [
|
const OtherDetails: Array<ExtraInfo> = [
|
||||||
{ key: 'Owner', value: owner },
|
{ key: 'Owner', value: owner },
|
||||||
{ key: 'Service', value: serviceType },
|
// { key: 'Service', value: serviceType },
|
||||||
{ key: 'Tier', value: getTier() },
|
{ key: 'Tier', value: getTier() },
|
||||||
];
|
];
|
||||||
if (indexType !== SearchIndex.DASHBOARD && usage !== undefined) {
|
if (indexType !== SearchIndex.DASHBOARD && usage !== undefined) {
|
||||||
@ -81,6 +79,7 @@ const TableDataCard: FunctionComponent<Props> = ({
|
|||||||
OtherDetails.push({
|
OtherDetails.push({
|
||||||
key: 'Database',
|
key: 'Database',
|
||||||
value: database,
|
value: database,
|
||||||
|
showLabel: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const getAssetTags = () => {
|
const getAssetTags = () => {
|
||||||
@ -100,7 +99,12 @@ const TableDataCard: FunctionComponent<Props> = ({
|
|||||||
data-testid="table-data-card">
|
data-testid="table-data-card">
|
||||||
<div>
|
<div>
|
||||||
<div className="tw-flex">
|
<div className="tw-flex">
|
||||||
{getEntityIcon(indexType)}
|
{/* {getEntityIcon(indexType)} */}
|
||||||
|
<img
|
||||||
|
alt=""
|
||||||
|
className="tw-inline tw-h-5 tw-w-5"
|
||||||
|
src={serviceTypeLogo(serviceType || '')}
|
||||||
|
/>
|
||||||
<h6 className="tw-flex tw-items-center tw-m-0 tw-heading tw-pl-2">
|
<h6 className="tw-flex tw-items-center tw-m-0 tw-heading tw-pl-2">
|
||||||
<Link
|
<Link
|
||||||
data-testid="table-link"
|
data-testid="table-link"
|
||||||
|
@ -12,20 +12,17 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { isNil, isString } from 'lodash';
|
import { isNil, isString } from 'lodash';
|
||||||
|
import { ExtraInfo } from 'Models';
|
||||||
import React, { FunctionComponent } from 'react';
|
import React, { FunctionComponent } from 'react';
|
||||||
import { TagLabel } from '../../../generated/type/tagLabel';
|
import { TagLabel } from '../../../generated/type/tagLabel';
|
||||||
import { serviceTypeLogo } from '../../../utils/ServiceUtils';
|
import { getInfoElements } from '../../../utils/EntityUtils';
|
||||||
import SVGIcons from '../../../utils/SvgUtils';
|
import SVGIcons from '../../../utils/SvgUtils';
|
||||||
import Tag from '../../tags/tags';
|
import Tag from '../../tags/tags';
|
||||||
import Avatar from '../avatar/Avatar';
|
|
||||||
import RichTextEditorPreviewer from '../rich-text-editor/RichTextEditorPreviewer';
|
import RichTextEditorPreviewer from '../rich-text-editor/RichTextEditorPreviewer';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
description: string;
|
description: string;
|
||||||
extraInfo: {
|
extraInfo: Array<ExtraInfo>;
|
||||||
key: string;
|
|
||||||
value?: string;
|
|
||||||
}[];
|
|
||||||
tags?: string[] | TagLabel[];
|
tags?: string[] | TagLabel[];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -46,42 +43,14 @@ const TableDataCardBody: FunctionComponent<Props> = ({
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const getInfoLabel = (data: { key: string; value: string }) => {
|
|
||||||
switch (data.key) {
|
|
||||||
case 'Owner':
|
|
||||||
return data.value !== '--' ? (
|
|
||||||
<div className="tw-inline-block">
|
|
||||||
<Avatar name={data.value} textClass="tw-text-xs" width="22" />
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
`${data.key} : `
|
|
||||||
);
|
|
||||||
case 'Service':
|
|
||||||
return (
|
|
||||||
<img
|
|
||||||
alt=""
|
|
||||||
className="tw-inline tw-h-5 tw-w-5"
|
|
||||||
src={serviceTypeLogo(data.value)}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
case 'Tier':
|
|
||||||
return <SVGIcons alt="icon-tier" icon="icon-tier" width="16px" />;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return `${data.key} : `;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div data-testid="table-body">
|
<div data-testid="table-body">
|
||||||
<div className="tw-mb-4">
|
<div className="tw-mb-4">
|
||||||
{extraInfo.map(({ key, value }, i) =>
|
{extraInfo.map((info, i) =>
|
||||||
!isNil(value) ? (
|
!isNil(info.value) ? (
|
||||||
<span key={i}>
|
<span key={i}>
|
||||||
<span className="tw-text-grey-muted">
|
{getInfoElements(info)}
|
||||||
{getInfoLabel({ key, value })}
|
|
||||||
</span>{' '}
|
|
||||||
<span className="tw-pl-1 ">{value}</span>
|
|
||||||
{i !== extraInfo.length - 1 && (
|
{i !== extraInfo.length - 1 && (
|
||||||
<span className="tw-mx-3 tw-inline-block tw-text-gray-400">
|
<span className="tw-mx-3 tw-inline-block tw-text-gray-400">
|
||||||
|
|
|
|
||||||
@ -105,9 +74,10 @@ const TableDataCardBody: FunctionComponent<Props> = ({
|
|||||||
<SVGIcons
|
<SVGIcons
|
||||||
alt="icon-tag"
|
alt="icon-tag"
|
||||||
className="tw-absolute tw-top-1.5"
|
className="tw-absolute tw-top-1.5"
|
||||||
icon="icon-tag"
|
icon="icon-tag-grey"
|
||||||
|
width="14"
|
||||||
/>
|
/>
|
||||||
<div className="tw-ml-2">
|
<div className="tw-ml-4">
|
||||||
{tags?.map((tag, index) => (
|
{tags?.map((tag, index) => (
|
||||||
<Tag
|
<Tag
|
||||||
key={index}
|
key={index}
|
||||||
|
@ -13,12 +13,14 @@
|
|||||||
|
|
||||||
import { EntityTags } from 'Models';
|
import { EntityTags } from 'Models';
|
||||||
import { ReactNode } from 'react';
|
import { ReactNode } from 'react';
|
||||||
|
import { TagProps } from '../tags/tags.interface';
|
||||||
|
|
||||||
export type TagsContainerProps = {
|
export type TagsContainerProps = {
|
||||||
children?: ReactNode;
|
children?: ReactNode;
|
||||||
editable?: boolean;
|
editable?: boolean;
|
||||||
selectedTags: Array<EntityTags>;
|
selectedTags: Array<EntityTags>;
|
||||||
tagList: Array<string>;
|
tagList: Array<string>;
|
||||||
|
type?: TagProps['type'];
|
||||||
showTags?: boolean;
|
showTags?: boolean;
|
||||||
onSelectionChange: (selectedTags: Array<EntityTags>) => void;
|
onSelectionChange: (selectedTags: Array<EntityTags>) => void;
|
||||||
onCancel: (event: React.MouseEvent<HTMLElement, MouseEvent>) => void;
|
onCancel: (event: React.MouseEvent<HTMLElement, MouseEvent>) => void;
|
||||||
|
@ -32,6 +32,7 @@ const TagsContainer: FunctionComponent<TagsContainerProps> = ({
|
|||||||
onCancel,
|
onCancel,
|
||||||
onSelectionChange,
|
onSelectionChange,
|
||||||
showTags = true,
|
showTags = true,
|
||||||
|
type,
|
||||||
}: TagsContainerProps) => {
|
}: TagsContainerProps) => {
|
||||||
const [tags, setTags] = useState<Array<EntityTags>>(selectedTags);
|
const [tags, setTags] = useState<Array<EntityTags>>(selectedTags);
|
||||||
const [newTag, setNewTag] = useState<string>('');
|
const [newTag, setNewTag] = useState<string>('');
|
||||||
@ -129,7 +130,9 @@ const TagsContainer: FunctionComponent<TagsContainerProps> = ({
|
|||||||
const getTagsElement = (tag: EntityTags, index: number) => {
|
const getTagsElement = (tag: EntityTags, index: number) => {
|
||||||
return (
|
return (
|
||||||
<Tags
|
<Tags
|
||||||
className="tw-bg-gray-200"
|
className={classNames({
|
||||||
|
'tw-bg-gray-200': editable || type === 'contained',
|
||||||
|
})}
|
||||||
editable={editable}
|
editable={editable}
|
||||||
isRemovable={tag.isRemovable}
|
isRemovable={tag.isRemovable}
|
||||||
key={index}
|
key={index}
|
||||||
@ -138,6 +141,7 @@ const TagsContainer: FunctionComponent<TagsContainerProps> = ({
|
|||||||
}}
|
}}
|
||||||
startWith="#"
|
startWith="#"
|
||||||
tag={tag}
|
tag={tag}
|
||||||
|
type={editable ? 'contained' : type}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -12,18 +12,18 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export const tagStyles = {
|
export const tagStyles = {
|
||||||
base: `tw-relative tw-inline-flex tw-text-xs tw-font-medium
|
base: `tw-relative tw-inline-flex tw-text-xs tw-font-normal
|
||||||
tw-rounded tw-whitespace-nowrap`,
|
tw-rounded tw-whitespace-nowrap`,
|
||||||
contained: 'tw-bg-tag tw-mr-2 tw-my-0.5 tw-font-medium ',
|
contained: 'tw-bg-tag tw-mr-2 tw-my-0.5 tw-font-medium ',
|
||||||
outlined: 'tw-bg-transparent tw-mr-2 tw-my-0.5 tw-font-medium ',
|
outlined: 'tw-bg-transparent tw-mr-2 tw-my-0.5 tw-font-medium ',
|
||||||
label: 'tw-bg-transparent tw-border-none tw-text-primary',
|
label: 'tw-bg-transparent tw-border-none tw-text-grey-body tw-text-body',
|
||||||
|
|
||||||
text: {
|
text: {
|
||||||
base: 'tw-no-underline hover:tw-no-underline',
|
base: 'tw-no-underline hover:tw-no-underline',
|
||||||
default: 'tw-px-2',
|
default: 'tw-px-2',
|
||||||
editable: 'tw-pl-2 tw-pr-1',
|
editable: 'tw-pl-2 tw-pr-1',
|
||||||
contained: 'tw-py-0.5',
|
contained: 'tw-py-0.5 tw-px-2',
|
||||||
outlined: 'tw-py-0.5',
|
outlined: 'tw-py-0.5 tw-px-2',
|
||||||
label: '',
|
label: 'tw-px-1',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -31,9 +31,8 @@ const Tags: FunctionComponent<TagProps> = ({
|
|||||||
const baseStyle = tagStyles.base;
|
const baseStyle = tagStyles.base;
|
||||||
const layoutStyles = tagStyles[type];
|
const layoutStyles = tagStyles[type];
|
||||||
const textBaseStyle = tagStyles.text.base;
|
const textBaseStyle = tagStyles.text.base;
|
||||||
const textLayoutStyles = editable
|
const textLayoutStyles = tagStyles.text[type] || tagStyles.text.default;
|
||||||
? tagStyles.text.editable
|
const textEditStyles = editable ? tagStyles.text.editable : '';
|
||||||
: tagStyles.text.default;
|
|
||||||
|
|
||||||
const getTagString = (tag: string) => {
|
const getTagString = (tag: string) => {
|
||||||
return tag.startsWith('#') ? tag.slice(1) : tag;
|
return tag.startsWith('#') ? tag.slice(1) : tag;
|
||||||
@ -44,12 +43,17 @@ const Tags: FunctionComponent<TagProps> = ({
|
|||||||
<span
|
<span
|
||||||
className={classNames(baseStyle, layoutStyles, className)}
|
className={classNames(baseStyle, layoutStyles, className)}
|
||||||
data-testid="tags">
|
data-testid="tags">
|
||||||
<span className={classNames(textBaseStyle, textLayoutStyles)}>
|
<span
|
||||||
|
className={classNames(
|
||||||
|
textBaseStyle,
|
||||||
|
textLayoutStyles,
|
||||||
|
textEditStyles
|
||||||
|
)}>
|
||||||
{`${startWith}${tag}`}
|
{`${startWith}${tag}`}
|
||||||
</span>
|
</span>
|
||||||
{editable && isRemovable && (
|
{editable && isRemovable && (
|
||||||
<span
|
<span
|
||||||
className="tw-py-1 tw-px-2 tw-rounded tw-cursor-pointer"
|
className="tw-py-0.5 tw-px-2 tw-rounded tw-cursor-pointer"
|
||||||
data-testid="remove"
|
data-testid="remove"
|
||||||
onClick={(e: React.MouseEvent<HTMLElement, MouseEvent>) => {
|
onClick={(e: React.MouseEvent<HTMLElement, MouseEvent>) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
@ -413,4 +413,13 @@ declare module 'Models' {
|
|||||||
id: string | undefined;
|
id: string | undefined;
|
||||||
state: boolean;
|
state: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type ExtraInfo = {
|
||||||
|
key?: string;
|
||||||
|
value: string | number | React.ReactNode;
|
||||||
|
isLink?: boolean;
|
||||||
|
placeholderText?: string;
|
||||||
|
openInNewTab?: boolean;
|
||||||
|
showLabel?: boolean;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@ -408,7 +408,6 @@ const DatabaseDetails: FunctionComponent = () => {
|
|||||||
<td className="tableBody-cell">
|
<td className="tableBody-cell">
|
||||||
{table.tags?.map((tag, tagIndex) => (
|
{table.tags?.map((tag, tagIndex) => (
|
||||||
<Tags
|
<Tags
|
||||||
className="tw-bg-gray-200"
|
|
||||||
key={tagIndex}
|
key={tagIndex}
|
||||||
startWith="#"
|
startWith="#"
|
||||||
tag={{
|
tag={{
|
||||||
@ -419,15 +418,16 @@ const DatabaseDetails: FunctionComponent = () => {
|
|||||||
? tag.tagFQN.split('.')[1]
|
? tag.tagFQN.split('.')[1]
|
||||||
: tag.tagFQN,
|
: tag.tagFQN,
|
||||||
}}
|
}}
|
||||||
|
type="label"
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
{getTableTags(table.columns).map(
|
{getTableTags(table.columns).map(
|
||||||
(tag, tagIdx) => (
|
(tag, tagIdx) => (
|
||||||
<Tags
|
<Tags
|
||||||
className="tw-bg-gray-200"
|
|
||||||
key={tagIdx}
|
key={tagIdx}
|
||||||
startWith="#"
|
startWith="#"
|
||||||
tag={tag}
|
tag={tag}
|
||||||
|
type="label"
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
)}
|
)}
|
||||||
|
@ -11,9 +11,10 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { isEmpty, isNil } from 'lodash';
|
import { isEmpty, isNil, isString } from 'lodash';
|
||||||
import { Bucket, LeafNodes, LineagePos } from 'Models';
|
import { Bucket, ExtraInfo, LeafNodes, LineagePos } from 'Models';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import Avatar from '../components/common/avatar/Avatar';
|
||||||
import TableProfilerGraph from '../components/TableProfiler/TableProfilerGraph.component';
|
import TableProfilerGraph from '../components/TableProfiler/TableProfilerGraph.component';
|
||||||
import {
|
import {
|
||||||
getDatabaseDetailsPath,
|
getDatabaseDetailsPath,
|
||||||
@ -30,6 +31,7 @@ import { Edge, EntityLineage } from '../generated/type/entityLineage';
|
|||||||
import { EntityReference } from '../generated/type/entityUsage';
|
import { EntityReference } from '../generated/type/entityUsage';
|
||||||
import { TagLabel } from '../generated/type/tagLabel';
|
import { TagLabel } from '../generated/type/tagLabel';
|
||||||
import { getPartialNameFromFQN } from './CommonUtils';
|
import { getPartialNameFromFQN } from './CommonUtils';
|
||||||
|
import SVGIcons from './SvgUtils';
|
||||||
import {
|
import {
|
||||||
getOwnerFromId,
|
getOwnerFromId,
|
||||||
getTierFromTableTags,
|
getTierFromTableTags,
|
||||||
@ -324,3 +326,81 @@ export const isLeafNode = (
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getInfoElements = (data: ExtraInfo) => {
|
||||||
|
let retVal = <></>;
|
||||||
|
const displayVal = data.placeholderText || data.value;
|
||||||
|
|
||||||
|
switch (data.key) {
|
||||||
|
case 'Owner':
|
||||||
|
{
|
||||||
|
retVal =
|
||||||
|
displayVal && displayVal !== '--' ? (
|
||||||
|
isString(displayVal) ? (
|
||||||
|
<div className="tw-inline-block tw-mr-2">
|
||||||
|
<Avatar name={displayVal} textClass="tw-text-xs" width="22" />
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<></>
|
||||||
|
)
|
||||||
|
) : (
|
||||||
|
<>No Owner</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 'Tier':
|
||||||
|
{
|
||||||
|
retVal = !displayVal || displayVal === '--' ? <>No Tier</> : <></>;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
retVal = (
|
||||||
|
<>
|
||||||
|
{data.key
|
||||||
|
? displayVal
|
||||||
|
? data.showLabel
|
||||||
|
? `${data.key}: `
|
||||||
|
: null
|
||||||
|
: `No ${data.key}`
|
||||||
|
: null}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<span className="tw-text-grey-muted">{retVal}</span>
|
||||||
|
{displayVal ? (
|
||||||
|
<span>
|
||||||
|
{data.isLink ? (
|
||||||
|
<a
|
||||||
|
className="link-text"
|
||||||
|
href={data.value as string}
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
target={data.openInNewTab ? '_blank' : '_self'}>
|
||||||
|
<>
|
||||||
|
<span className="tw-mr-1">{displayVal}</span>
|
||||||
|
{data.openInNewTab && (
|
||||||
|
<SVGIcons
|
||||||
|
alt="external-link"
|
||||||
|
className="tw-align-middle"
|
||||||
|
icon="external-link"
|
||||||
|
width="12px"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
</a>
|
||||||
|
) : (
|
||||||
|
displayVal
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
) : null}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
@ -82,6 +82,7 @@ import IconSlackGrey from '../assets/svg/slack-grey.svg';
|
|||||||
import IconSlack from '../assets/svg/slack.svg';
|
import IconSlack from '../assets/svg/slack.svg';
|
||||||
import IconTableGrey from '../assets/svg/table-grey.svg';
|
import IconTableGrey from '../assets/svg/table-grey.svg';
|
||||||
import IconTable from '../assets/svg/table.svg';
|
import IconTable from '../assets/svg/table.svg';
|
||||||
|
import IconTagGrey from '../assets/svg/tag-grey.svg';
|
||||||
import IconTag from '../assets/svg/tag.svg';
|
import IconTag from '../assets/svg/tag.svg';
|
||||||
import IconTerns from '../assets/svg/terms.svg';
|
import IconTerns from '../assets/svg/terms.svg';
|
||||||
import IconTier from '../assets/svg/tier.svg';
|
import IconTier from '../assets/svg/tier.svg';
|
||||||
@ -179,6 +180,7 @@ export const Icons = {
|
|||||||
ICON_PLUS: 'icon-plus',
|
ICON_PLUS: 'icon-plus',
|
||||||
ICON_MINUS: 'icon-minus',
|
ICON_MINUS: 'icon-minus',
|
||||||
TAG: 'icon-tag',
|
TAG: 'icon-tag',
|
||||||
|
TAG_GREY: 'icon-tag-grey',
|
||||||
TIER: 'icon-tier',
|
TIER: 'icon-tier',
|
||||||
SEARCHV1: 'icon-searchv1',
|
SEARCHV1: 'icon-searchv1',
|
||||||
};
|
};
|
||||||
@ -506,6 +508,10 @@ const SVGIcons: FunctionComponent<Props> = ({
|
|||||||
case Icons.TAG:
|
case Icons.TAG:
|
||||||
IconComponent = IconTag;
|
IconComponent = IconTag;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case Icons.TAG_GREY:
|
||||||
|
IconComponent = IconTagGrey;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case Icons.TIER:
|
case Icons.TIER:
|
||||||
IconComponent = IconTier;
|
IconComponent = IconTier;
|
||||||
|
@ -51,11 +51,13 @@ export const usageSeverity = (value: number): string => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getUsagePercentile = (pctRank: number) => {
|
export const getUsagePercentile = (pctRank: number, isLiteral = false) => {
|
||||||
const percentile = Math.round(pctRank * 10) / 10;
|
const percentile = Math.round(pctRank * 10) / 10;
|
||||||
const ordinalPercentile = ordinalize(percentile);
|
const ordinalPercentile = ordinalize(percentile);
|
||||||
const strSeverity = usageSeverity(percentile);
|
const strSeverity = usageSeverity(percentile);
|
||||||
const usagePercentile = `${strSeverity} - ${ordinalPercentile} pctile`;
|
const usagePercentile = `${strSeverity}${
|
||||||
|
isLiteral ? ' usage' : ''
|
||||||
|
} - ${ordinalPercentile} pctile`;
|
||||||
|
|
||||||
return usagePercentile;
|
return usagePercentile;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user