From 8f956467ca40f643dcf4c73cc7f2dfce88540fb2 Mon Sep 17 00:00:00 2001 From: Ashish Gupta Date: Mon, 24 Jul 2023 18:41:36 +0530 Subject: [PATCH] feat(ui): supported read more in for tags on entity pages (#12569) * supported readmore in for tags on entity pages * missing props --- .../DashboardDetails.component.tsx | 3 + .../DashboardVersion.test.tsx | 2 +- .../DataModels/DataModelDetails.component.tsx | 3 + .../ContainerSummary.component.tsx | 3 +- .../DashboardSummary.component.tsx | 3 +- .../MlModelSummary.component.tsx | 3 +- .../PipelineSummary.component.tsx | 3 +- .../SummaryListItems.component.tsx | 3 +- .../SummaryListItems.test.tsx | 2 +- .../TableSummary/TableSummary.component.tsx | 3 +- .../TopicSummary/TopicSummary.component.tsx | 3 +- .../MlModelDetail/MlModelDetail.component.tsx | 3 + .../MlModelVersion.component.tsx | 4 +- .../PipelineDetails.component.tsx | 3 + .../PipelineVersion.component.tsx | 9 +- .../PipelineVersion/PipelineVersion.test.tsx | 2 +- .../TableDataCardBody/TableDataCardBody.tsx | 3 +- .../TableProfiler/Component/ColumnSummary.tsx | 2 +- .../TagsContainerV2.interface.ts | 2 + .../Tag/TagsContainerV2/TagsContainerV2.tsx | 7 +- ...r.interface.ts => TagsViewer.interface.ts} | 9 +- .../Tag/TagsViewer/TagsViewer.test.tsx | 114 ++++++++++++++ .../components/Tag/TagsViewer/TagsViewer.tsx | 147 ++++++++++++++++++ .../Tag/TagsViewer/tags-viewer.test.tsx | 61 -------- .../components/Tag/TagsViewer/tags-viewer.tsx | 97 ------------ .../TagsInput/TagsInput.component.tsx | 4 +- .../TopicDetails/TopicDetails.component.tsx | 3 + .../VersionTable/VersionTable.component.tsx | 9 +- .../SummaryTagsDescription.component.tsx | 2 +- .../ui/src/locale/languages/en-us.json | 1 + .../ui/src/locale/languages/es-es.json | 1 + .../ui/src/locale/languages/fr-fr.json | 1 + .../ui/src/locale/languages/ja-jp.json | 1 + .../ui/src/locale/languages/pt-br.json | 1 + .../ui/src/locale/languages/zh-cn.json | 1 + .../src/pages/ContainerPage/ContainerPage.tsx | 3 + .../DatabaseDetailsPage.tsx | 3 + .../DatabaseSchemaPage.component.tsx | 3 + .../ServiceMainTabContent.tsx | 7 +- .../TableDetailsPageV1/TableDetailsPageV1.tsx | 3 + 40 files changed, 332 insertions(+), 205 deletions(-) rename openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsViewer/{tags-viewer.interface.ts => TagsViewer.interface.ts} (84%) create mode 100644 openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsViewer/TagsViewer.test.tsx create mode 100644 openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsViewer/TagsViewer.tsx delete mode 100644 openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsViewer/tags-viewer.test.tsx delete mode 100644 openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsViewer/tags-viewer.tsx diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DashboardDetails/DashboardDetails.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/DashboardDetails/DashboardDetails.component.tsx index c8ac7a691e2..f1bef07124c 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/DashboardDetails/DashboardDetails.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/DashboardDetails/DashboardDetails.component.tsx @@ -67,6 +67,7 @@ import { } from './DashboardDetails.interface'; import TableDescription from 'components/TableDescription/TableDescription.component'; +import { DisplayType } from 'components/Tag/TagsViewer/TagsViewer.interface'; const DashboardDetails = ({ charts, @@ -603,6 +604,7 @@ const DashboardDetails = ({ flex="320px"> jest.fn().mockImplementation(() =>
TagsContainerV2
) ); -jest.mock('components/Tag/TagsViewer/tags-viewer', () => +jest.mock('components/Tag/TagsViewer/TagsViewer', () => jest.fn().mockImplementation(() =>
TagsViewer
) ); diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DataModels/DataModelDetails.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/DataModels/DataModelDetails.component.tsx index 2222aef6e63..4306ef89ab4 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/DataModels/DataModelDetails.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/DataModels/DataModelDetails.component.tsx @@ -26,6 +26,7 @@ import SchemaEditor from 'components/schema-editor/SchemaEditor'; import { SourceType } from 'components/searched-data/SearchedData.interface'; import TabsLabel from 'components/TabsLabel/TabsLabel.component'; import TagsContainerV2 from 'components/Tag/TagsContainerV2/TagsContainerV2'; +import { DisplayType } from 'components/Tag/TagsViewer/TagsViewer.interface'; import { getDataModelDetailsPath, getVersionPath } from 'constants/constants'; import { EntityField } from 'constants/Feeds.constants'; import { CSMode } from 'enums/codemirror.enum'; @@ -203,6 +204,7 @@ const DataModelDetails = ({ flex="320px"> getTagValue(tag))} - type="border" /> ) : ( diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Explore/EntitySummaryPanel/DashboardSummary/DashboardSummary.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Explore/EntitySummaryPanel/DashboardSummary/DashboardSummary.component.tsx index 5fcdbf84253..7d914afd0de 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Explore/EntitySummaryPanel/DashboardSummary/DashboardSummary.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Explore/EntitySummaryPanel/DashboardSummary/DashboardSummary.component.tsx @@ -17,7 +17,7 @@ import { AxiosError } from 'axios'; import classNames from 'classnames'; import SummaryTagsDescription from 'components/common/SummaryTagsDescription/SummaryTagsDescription.component'; import SummaryPanelSkeleton from 'components/Skeleton/SummaryPanelSkeleton/SummaryPanelSkeleton.component'; -import TagsViewer from 'components/Tag/TagsViewer/tags-viewer'; +import TagsViewer from 'components/Tag/TagsViewer/TagsViewer'; import { ExplorePageTabs } from 'enums/Explore.enum'; import { TagLabel } from 'generated/type/tagLabel'; import { ChartType } from 'pages/DashboardDetailsPage/DashboardDetailsPage.component'; @@ -185,7 +185,6 @@ function DashboardSummary({ tags={(entityDetails.tags || []).map((tag) => getTagValue(tag) )} - type="border" /> ) : ( diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Explore/EntitySummaryPanel/MlModelSummary/MlModelSummary.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Explore/EntitySummaryPanel/MlModelSummary/MlModelSummary.component.tsx index 0e9551700c2..2ce24ff7ab2 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Explore/EntitySummaryPanel/MlModelSummary/MlModelSummary.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Explore/EntitySummaryPanel/MlModelSummary/MlModelSummary.component.tsx @@ -16,7 +16,7 @@ import { ReactComponent as IconExternalLink } from 'assets/svg/external-links.sv import classNames from 'classnames'; import SummaryTagsDescription from 'components/common/SummaryTagsDescription/SummaryTagsDescription.component'; import SummaryPanelSkeleton from 'components/Skeleton/SummaryPanelSkeleton/SummaryPanelSkeleton.component'; -import TagsViewer from 'components/Tag/TagsViewer/tags-viewer'; +import TagsViewer from 'components/Tag/TagsViewer/TagsViewer'; import { ExplorePageTabs } from 'enums/Explore.enum'; import { TagLabel } from 'generated/type/tagLabel'; import React, { useMemo } from 'react'; @@ -148,7 +148,6 @@ function MlModelSummary({ tags={(entityDetails.tags || []).map((tag) => getTagValue(tag) )} - type="border" /> ) : ( diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Explore/EntitySummaryPanel/PipelineSummary/PipelineSummary.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Explore/EntitySummaryPanel/PipelineSummary/PipelineSummary.component.tsx index 958faabf0d4..6447e6ff314 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Explore/EntitySummaryPanel/PipelineSummary/PipelineSummary.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Explore/EntitySummaryPanel/PipelineSummary/PipelineSummary.component.tsx @@ -16,7 +16,7 @@ import { ReactComponent as IconExternalLink } from 'assets/svg/external-links.sv import classNames from 'classnames'; import SummaryTagsDescription from 'components/common/SummaryTagsDescription/SummaryTagsDescription.component'; import SummaryPanelSkeleton from 'components/Skeleton/SummaryPanelSkeleton/SummaryPanelSkeleton.component'; -import TagsViewer from 'components/Tag/TagsViewer/tags-viewer'; +import TagsViewer from 'components/Tag/TagsViewer/TagsViewer'; import { ExplorePageTabs } from 'enums/Explore.enum'; import { TagLabel } from 'generated/type/tagLabel'; import React, { useMemo } from 'react'; @@ -152,7 +152,6 @@ function PipelineSummary({ tags={(entityDetails.tags || []).map((tag) => getTagValue(tag) )} - type="border" /> ) : ( diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Explore/EntitySummaryPanel/SummaryList/SummaryListItems/SummaryListItems.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Explore/EntitySummaryPanel/SummaryList/SummaryListItems/SummaryListItems.component.tsx index b323effe307..9d2e8a3eb65 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Explore/EntitySummaryPanel/SummaryList/SummaryListItems/SummaryListItems.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Explore/EntitySummaryPanel/SummaryList/SummaryListItems/SummaryListItems.component.tsx @@ -12,7 +12,7 @@ */ import { Col, Row, Space, Typography } from 'antd'; -import TagsViewer from 'components/Tag/TagsViewer/tags-viewer'; +import TagsViewer from 'components/Tag/TagsViewer/TagsViewer'; import React from 'react'; import { useTranslation } from 'react-i18next'; import { MAX_CHAR_LIMIT_ENTITY_SUMMARY } from '../../../../../constants/constants'; @@ -86,7 +86,6 @@ function SummaryListItem({ getTagValue(tag))} - type="border" /> )} diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Explore/EntitySummaryPanel/SummaryList/SummaryListItems/SummaryListItems.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Explore/EntitySummaryPanel/SummaryList/SummaryListItems/SummaryListItems.test.tsx index e2250316d79..b32cb073401 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Explore/EntitySummaryPanel/SummaryList/SummaryListItems/SummaryListItems.test.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Explore/EntitySummaryPanel/SummaryList/SummaryListItems/SummaryListItems.test.tsx @@ -29,7 +29,7 @@ jest.mock('../../../../common/rich-text-editor/RichTextEditorPreviewer', () => )) ); -jest.mock('components/Tag/TagsViewer/tags-viewer', () => +jest.mock('components/Tag/TagsViewer/TagsViewer', () => jest .fn() .mockImplementation(() =>
TagsViewer
) diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Explore/EntitySummaryPanel/TableSummary/TableSummary.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Explore/EntitySummaryPanel/TableSummary/TableSummary.component.tsx index ff4bf934c9b..699bed19dd0 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Explore/EntitySummaryPanel/TableSummary/TableSummary.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Explore/EntitySummaryPanel/TableSummary/TableSummary.component.tsx @@ -22,7 +22,7 @@ import { ResourceEntity, } from 'components/PermissionProvider/PermissionProvider.interface'; import SummaryPanelSkeleton from 'components/Skeleton/SummaryPanelSkeleton/SummaryPanelSkeleton.component'; -import TagsViewer from 'components/Tag/TagsViewer/tags-viewer'; +import TagsViewer from 'components/Tag/TagsViewer/TagsViewer'; import { mockTablePermission } from 'constants/mockTourData.constants'; import { ClientErrors } from 'enums/axios.enum'; import { ExplorePageTabs } from 'enums/Explore.enum'; @@ -364,7 +364,6 @@ function TableSummary({ tags={(entityDetails.tags || []).map((tag) => getTagValue(tag) )} - type="border" /> ) : ( diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Explore/EntitySummaryPanel/TopicSummary/TopicSummary.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Explore/EntitySummaryPanel/TopicSummary/TopicSummary.component.tsx index d935528bbfa..9e16accae8d 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Explore/EntitySummaryPanel/TopicSummary/TopicSummary.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Explore/EntitySummaryPanel/TopicSummary/TopicSummary.component.tsx @@ -15,7 +15,7 @@ import { Col, Divider, Row, Typography } from 'antd'; import { AxiosError } from 'axios'; import SummaryTagsDescription from 'components/common/SummaryTagsDescription/SummaryTagsDescription.component'; import SummaryPanelSkeleton from 'components/Skeleton/SummaryPanelSkeleton/SummaryPanelSkeleton.component'; -import TagsViewer from 'components/Tag/TagsViewer/tags-viewer'; +import TagsViewer from 'components/Tag/TagsViewer/TagsViewer'; import { getTeamAndUserDetailsPath } from 'constants/constants'; import { ClientErrors } from 'enums/axios.enum'; import { isArray, isEmpty } from 'lodash'; @@ -195,7 +195,6 @@ function TopicSummary({ tags={(entityDetails.tags || []).map((tag) => getTagValue(tag) )} - type="border" /> ) : ( diff --git a/openmetadata-ui/src/main/resources/ui/src/components/MlModelDetail/MlModelDetail.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/MlModelDetail/MlModelDetail.component.tsx index ad349aa9f2a..f3a50588ff3 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/MlModelDetail/MlModelDetail.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/MlModelDetail/MlModelDetail.component.tsx @@ -25,6 +25,7 @@ import { DataAssetsHeader } from 'components/DataAssets/DataAssetsHeader/DataAss import { EntityName } from 'components/Modals/EntityNameModal/EntityNameModal.interface'; import TabsLabel from 'components/TabsLabel/TabsLabel.component'; import TagsContainerV2 from 'components/Tag/TagsContainerV2/TagsContainerV2'; +import { DisplayType } from 'components/Tag/TagsViewer/TagsViewer.interface'; import { ERROR_PLACEHOLDER_TYPE } from 'enums/common.enum'; import { TagLabel, TagSource } from 'generated/type/schema'; import { EntityFieldThreadCount } from 'interface/feed.interface'; @@ -425,6 +426,7 @@ const MlModelDetail: FC = ({ flex="320px"> = ({ /> = ({ getFilterTags(feature.tags ?? []) .Glossary } - type="border" /> @@ -304,7 +303,6 @@ const MlModelVersion: FC = ({ getFilterTags(feature.tags ?? []) .Classification } - type="border" /> diff --git a/openmetadata-ui/src/main/resources/ui/src/components/PipelineDetails/PipelineDetails.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/PipelineDetails/PipelineDetails.component.tsx index 72f780e1c4b..270a16725c6 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/PipelineDetails/PipelineDetails.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/PipelineDetails/PipelineDetails.component.tsx @@ -31,6 +31,7 @@ import TableDescription from 'components/TableDescription/TableDescription.compo import TableTags from 'components/TableTags/TableTags.component'; import TabsLabel from 'components/TabsLabel/TabsLabel.component'; import TagsContainerV2 from 'components/Tag/TagsContainerV2/TagsContainerV2'; +import { DisplayType } from 'components/Tag/TagsViewer/TagsViewer.interface'; import TasksDAGView from 'components/TasksDAGView/TasksDAGView'; import { EntityField } from 'constants/Feeds.constants'; import { ERROR_PLACEHOLDER_TYPE } from 'enums/common.enum'; @@ -601,6 +602,7 @@ const PipelineDetails = ({ flex="320px"> = ({ ), }, @@ -310,11 +309,7 @@ const PipelineVersion: FC = ({ accessor: 'tags', width: 272, render: (tags) => ( - + ), }, ], diff --git a/openmetadata-ui/src/main/resources/ui/src/components/PipelineVersion/PipelineVersion.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/PipelineVersion/PipelineVersion.test.tsx index a2e1b9099c2..d5a96b10f03 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/PipelineVersion/PipelineVersion.test.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/PipelineVersion/PipelineVersion.test.tsx @@ -42,7 +42,7 @@ jest.mock('components/common/rich-text-editor/RichTextEditorPreviewer', () => jest.fn().mockImplementation(() =>
RichTextEditorPreviewer
) ); -jest.mock('components/Tag/TagsViewer/tags-viewer', () => +jest.mock('components/Tag/TagsViewer/TagsViewer', () => jest.fn().mockImplementation(() =>
TagsViewer
) ); diff --git a/openmetadata-ui/src/main/resources/ui/src/components/TableDataCardBody/TableDataCardBody.tsx b/openmetadata-ui/src/main/resources/ui/src/components/TableDataCardBody/TableDataCardBody.tsx index 2b8a6ea3d6f..7d7ab18d43b 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/TableDataCardBody/TableDataCardBody.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/TableDataCardBody/TableDataCardBody.tsx @@ -13,7 +13,7 @@ import EntitySummaryDetails from 'components/common/EntitySummaryDetails/EntitySummaryDetails'; import RichTextEditorPreviewer from 'components/common/rich-text-editor/RichTextEditorPreviewer'; -import TagsViewer from 'components/Tag/TagsViewer/tags-viewer'; +import TagsViewer from 'components/Tag/TagsViewer/TagsViewer'; import { TagLabel } from 'generated/type/tagLabel'; import { isEmpty, isNil } from 'lodash'; import { ExtraInfo } from 'Models'; @@ -69,7 +69,6 @@ const TableDataCardBody: FunctionComponent = ({ getTagValue(tag))} - type="border" /> )} diff --git a/openmetadata-ui/src/main/resources/ui/src/components/TableProfiler/Component/ColumnSummary.tsx b/openmetadata-ui/src/main/resources/ui/src/components/TableProfiler/Component/ColumnSummary.tsx index 809d989e4dc..1d6590dbc9c 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/TableProfiler/Component/ColumnSummary.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/TableProfiler/Component/ColumnSummary.tsx @@ -12,7 +12,7 @@ */ import { Space, Typography } from 'antd'; import RichTextEditorPreviewer from 'components/common/rich-text-editor/RichTextEditorPreviewer'; -import TagsViewer from 'components/Tag/TagsViewer/tags-viewer'; +import TagsViewer from 'components/Tag/TagsViewer/TagsViewer'; import { Column } from 'generated/entity/data/container'; import { isEmpty } from 'lodash'; import React, { FC } from 'react'; diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsContainerV2/TagsContainerV2.interface.ts b/openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsContainerV2/TagsContainerV2.interface.ts index 3e4b1d02fa2..d6ba8e222b7 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsContainerV2/TagsContainerV2.interface.ts +++ b/openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsContainerV2/TagsContainerV2.interface.ts @@ -15,6 +15,7 @@ import { ThreadType } from 'generated/api/feed/createThread'; import { TagSource } from 'generated/type/tagLabel'; import { EntityTags } from 'Models'; import { ReactElement } from 'react'; +import { DisplayType } from '../TagsViewer/TagsViewer.interface'; export type TagsContainerV2Props = { permission: boolean; @@ -28,6 +29,7 @@ export type TagsContainerV2Props = { showBottomEditButton?: boolean; showInlineEditButton?: boolean; children?: ReactElement; + displayType?: DisplayType; onSelectionChange?: (selectedTags: EntityTags[]) => Promise; onThreadLinkSelect?: (value: string, threadType?: ThreadType) => void; }; diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsContainerV2/TagsContainerV2.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsContainerV2/TagsContainerV2.tsx index c857ddaf9e5..c3b3a5f7c78 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsContainerV2/TagsContainerV2.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsContainerV2/TagsContainerV2.tsx @@ -34,7 +34,7 @@ import { ReactComponent as IconComments } from '../../../assets/svg/comment.svg' import { ReactComponent as IconRequest } from '../../../assets/svg/request-icon.svg'; import TagSelectForm from '../TagsSelectForm/TagsSelectForm.component'; import TagsV1 from '../TagsV1/TagsV1.component'; -import TagsViewer from '../TagsViewer/tags-viewer'; +import TagsViewer from '../TagsViewer/TagsViewer'; import { TagsContainerV2Props } from './TagsContainerV2.interface'; const TagsContainerV2 = ({ @@ -45,6 +45,7 @@ const TagsContainerV2 = ({ entityThreadLink, entityFqn, tagType, + displayType, showHeader = true, showBottomEditButton, showInlineEditButton, @@ -166,13 +167,13 @@ const TagsContainerV2 = ({ () => ( ), - [showNoDataPlaceholder, tags?.[tagType]] + [displayType, showNoDataPlaceholder, tags?.[tagType]] ); const tagsSelectContainer = useMemo(() => { diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsViewer/tags-viewer.interface.ts b/openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsViewer/TagsViewer.interface.ts similarity index 84% rename from openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsViewer/tags-viewer.interface.ts rename to openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsViewer/TagsViewer.interface.ts index b8f4d77b99f..d07c6486f74 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsViewer/tags-viewer.interface.ts +++ b/openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsViewer/TagsViewer.interface.ts @@ -14,8 +14,13 @@ import { EntityTags } from 'Models'; export interface TagsViewerProps { - tags: Array; + tags: EntityTags[]; sizeCap?: number; - type?: 'label' | 'contained' | 'outlined' | 'border'; + displayType?: DisplayType; showNoDataPlaceholder?: boolean; } + +export enum DisplayType { + READ_MORE = 'read-more', + POPOVER = 'popover', +} diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsViewer/TagsViewer.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsViewer/TagsViewer.test.tsx new file mode 100644 index 00000000000..d1795a088c9 --- /dev/null +++ b/openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsViewer/TagsViewer.test.tsx @@ -0,0 +1,114 @@ +/* + * Copyright 2023 Collate. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { fireEvent, render, screen } from '@testing-library/react'; +import { NO_DATA_PLACEHOLDER } from 'constants/constants'; +import React from 'react'; +import TagsViewer from './TagsViewer'; +import { DisplayType } from './TagsViewer.interface'; + +const tags = [ + { tagFQN: `tags.tag_1`, source: 'Classification' }, + { tagFQN: `tags.tag_2`, source: 'Classification' }, + { tagFQN: `tags.tag_3`, source: 'Classification' }, + { tagFQN: `test.tags.term_1`, source: 'Glossary' }, + { tagFQN: `test.tags.term_2`, source: 'Glossary' }, + { tagFQN: `test.tags.term_3`, source: 'Glossary' }, +]; + +jest.mock('../TagsV1/TagsV1.component', () => { + return jest.fn().mockReturnValue(

TagsV1

); +}); + +describe('Test TagsViewer Component', () => { + it('Should render placeholder if tags is empty', () => { + render(); + const placeholder = screen.getByText(NO_DATA_PLACEHOLDER); + + expect(placeholder).toBeInTheDocument(); + }); + + it('Should render all tags', () => { + render(); + const allTags = screen.getAllByText('TagsV1'); + + expect(allTags).toHaveLength(6); + }); + + it('Should render tags as per sizeCap', () => { + render(); + const allTags = screen.getAllByText('TagsV1'); + + expect(allTags).toHaveLength(2); + }); + + it('Should render tags on popover style', () => { + render(); + + const sizeTags = screen.getAllByText('TagsV1'); + + expect(sizeTags).toHaveLength(5); + + const popoverElement = screen.getByTestId('popover-element'); + + expect(popoverElement).toBeInTheDocument(); + + const plusButton = screen.getByTestId('plus-more-count'); + + expect(plusButton).toHaveTextContent('+1 more'); + }); + + it('Should render tags on read more style', () => { + render(); + + const sizeTags = screen.getAllByText('TagsV1'); + + expect(sizeTags).toHaveLength(5); + + const readMoreElement = screen.getByTestId('read-more-element'); + + expect(readMoreElement).toBeInTheDocument(); + + const readButton = screen.getByTestId('read-button'); + + expect(readButton).toHaveTextContent('label.read-type'); + }); + + it('Should render all tags on popover click', () => { + render(); + + const plusButton = screen.getByTestId('plus-more-count'); + + expect(plusButton).toHaveTextContent('+1 more'); + + fireEvent.click(plusButton); + + const sizeTags = screen.getAllByText('TagsV1'); + + expect(sizeTags).toHaveLength(6); + }); + + it('Should render all tags on read more click', () => { + render(); + + const readButton = screen.getByTestId('read-button'); + + expect(readButton).toHaveTextContent('label.read-type'); + + fireEvent.click(readButton); + + const sizeTags = screen.getAllByText('TagsV1'); + + expect(sizeTags).toHaveLength(6); + }); +}); diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsViewer/TagsViewer.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsViewer/TagsViewer.tsx new file mode 100644 index 00000000000..95dd3305319 --- /dev/null +++ b/openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsViewer/TagsViewer.tsx @@ -0,0 +1,147 @@ +/* + * Copyright 2023 Collate. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Button, Popover, Tag, Typography } from 'antd'; +import classNames from 'classnames'; +import { TAG_START_WITH } from 'constants/Tag.constants'; +import { isEmpty, sortBy, uniqBy } from 'lodash'; +import { EntityTags } from 'Models'; +import React, { + FunctionComponent, + useCallback, + useMemo, + useState, +} from 'react'; +import { useTranslation } from 'react-i18next'; +import { LIST_SIZE, NO_DATA_PLACEHOLDER } from '../../../constants/constants'; +import { TagSource } from '../../../generated/type/tagLabel'; +import TagsV1 from '../TagsV1/TagsV1.component'; +import './tags-viewer.less'; +import { DisplayType, TagsViewerProps } from './TagsViewer.interface'; + +const TagsViewer: FunctionComponent = ({ + tags, + sizeCap = LIST_SIZE, + displayType = DisplayType.POPOVER, + showNoDataPlaceholder = true, +}: TagsViewerProps) => { + const { t } = useTranslation(); + const [isOpen, setIsOpen] = useState(false); + + const getTagsElement = useCallback( + (tag: EntityTags) => ( + + ), + [] + ); + + // sort tags by source so that "Glossary" tags always comes first + const sortedTagsBySource = useMemo( + () => sortBy(uniqBy(tags, 'tagFQN'), 'source'), + [tags] + ); + + const hasMoreElement = useMemo( + () => sortedTagsBySource.length > (sizeCap ?? 0), + [sizeCap, sortedTagsBySource] + ); + + const readMoreRenderElement = useMemo( + () => ( +
+ {isOpen && + sortedTagsBySource.slice(sizeCap).map((tag) => ( +

+ {getTagsElement(tag)} +

+ ))} + + {hasMoreElement && ( + + )} +
+ ), + [sizeCap, isOpen, hasMoreElement, sortedTagsBySource] + ); + + const popoverRenderElement = useMemo( + () => ( +
+ {sortedTagsBySource.slice(sizeCap).length > 0 && ( + + {sortedTagsBySource.slice(sizeCap).map((tag) => ( +

+ {getTagsElement(tag)} +

+ ))} + + } + overlayClassName="tag-popover-container" + placement="bottom" + trigger="click"> + {`+${ + sortedTagsBySource.length - (sizeCap ?? 0) + } more`} +
+ )} +
+ ), + + [sizeCap, sortedTagsBySource] + ); + + if (isEmpty(sortedTagsBySource) && showNoDataPlaceholder) { + return ( + + {NO_DATA_PLACEHOLDER} + + ); + } + + if (sizeCap < 0) { + return <>{sortedTagsBySource.map(getTagsElement)}; + } + + return ( + <> + {sortedTagsBySource.slice(0, sizeCap).map(getTagsElement)} + {displayType === DisplayType.POPOVER + ? popoverRenderElement + : readMoreRenderElement} + {} + + ); +}; + +export default TagsViewer; diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsViewer/tags-viewer.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsViewer/tags-viewer.test.tsx deleted file mode 100644 index 5ff57a58c60..00000000000 --- a/openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsViewer/tags-viewer.test.tsx +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2022 Collate. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { getAllByTestId, getByText, render } from '@testing-library/react'; -import React from 'react'; -import TagsViewer from './tags-viewer'; - -const tags = [ - { tagFQN: `tags.tag 1`, source: 'Classification' }, - { tagFQN: `tags.tag 2`, source: 'Classification' }, - { tagFQN: `test.tags.term`, source: 'Glossary' }, -]; - -jest.mock('components/common/rich-text-editor/RichTextEditorPreviewer', () => { - return jest.fn().mockReturnValue(

RichTextEditorPreviewer

); -}); - -describe('Test TagsViewer Component', () => { - it('Component should render', () => { - const { container } = render(); - const TagViewer = getAllByTestId(container, 'tags'); - - expect(TagViewer).toHaveLength(3); - }); - - it('Should render tags', () => { - const { container } = render(); - const TagViewer = getAllByTestId(container, 'tags'); - - expect(TagViewer).toHaveLength(3); - - const tag1 = getByText(container, /tags.tag 1/); - const tag2 = getByText(container, /tags.tag 2/); - const tag3 = getByText(container, /tags.term/); - - expect(tag1).toBeInTheDocument(); - expect(tag2).toBeInTheDocument(); - expect(tag3).toBeInTheDocument(); - }); - - it('Should render tags and glossary with their respective symbol', () => { - const { container } = render(); - const TagViewer = getAllByTestId(container, 'tags'); - const tagIcons = getAllByTestId(container, 'tags-icon'); - const glossaryIcons = getAllByTestId(container, 'glossary-icon'); - - expect(TagViewer).toHaveLength(3); - expect(tagIcons).toHaveLength(2); - expect(glossaryIcons).toHaveLength(1); - }); -}); diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsViewer/tags-viewer.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsViewer/tags-viewer.tsx deleted file mode 100644 index 68a4eb7e23d..00000000000 --- a/openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsViewer/tags-viewer.tsx +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2022 Collate. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Popover, Tag, Typography } from 'antd'; -import classNames from 'classnames'; -import { TAG_START_WITH } from 'constants/Tag.constants'; -import { isEmpty, sortBy, uniqBy } from 'lodash'; -import { EntityTags } from 'Models'; -import React, { FunctionComponent, useCallback, useMemo } from 'react'; -import { LIST_SIZE, NO_DATA_PLACEHOLDER } from '../../../constants/constants'; -import { TagSource } from '../../../generated/type/tagLabel'; -import TagsV1 from '../TagsV1/TagsV1.component'; -import { TagsViewerProps } from './tags-viewer.interface'; -import './tags-viewer.less'; - -const TagsViewer: FunctionComponent = ({ - tags, - sizeCap = LIST_SIZE, - type = 'label', - showNoDataPlaceholder = true, -}: TagsViewerProps) => { - const getTagsElement = useCallback( - (tag: EntityTags, index: number) => ( - - ), - [type] - ); - - // sort tags by source so that "Glossary" tags always comes first - const sortedTagsBySource = useMemo( - () => sortBy(uniqBy(tags, 'tagFQN'), 'source'), - [tags] - ); - - if (isEmpty(sortedTagsBySource) && showNoDataPlaceholder) { - return ( - - {NO_DATA_PLACEHOLDER} - - ); - } - - return ( -
- {sizeCap > -1 ? ( - <> - {sortedTagsBySource.slice(0, sizeCap).map(getTagsElement)} - - {sortedTagsBySource.slice(sizeCap).length > 0 && ( - - {sortedTagsBySource.slice(sizeCap).map((tag, index) => ( -

- {getTagsElement(tag, index)} -

- ))} - - } - overlayClassName="tag-popover-container" - placement="bottom" - trigger="click"> - {`+${ - sortedTagsBySource.length - sizeCap - } more`} -
- )} - - ) : ( - sortedTagsBySource.map(getTagsElement) - )} -
- ); -}; - -export default TagsViewer; diff --git a/openmetadata-ui/src/main/resources/ui/src/components/TagsInput/TagsInput.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/TagsInput/TagsInput.component.tsx index 70f99ad5191..89b0fa35ff5 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/TagsInput/TagsInput.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/TagsInput/TagsInput.component.tsx @@ -12,7 +12,7 @@ */ import { Typography } from 'antd'; import TagsContainerV2 from 'components/Tag/TagsContainerV2/TagsContainerV2'; -import TagsViewer from 'components/Tag/TagsViewer/tags-viewer'; +import TagsViewer from 'components/Tag/TagsViewer/TagsViewer'; import { LabelType, State, TagLabel, TagSource } from 'generated/type/tagLabel'; import { EntityTags } from 'Models'; import React from 'react'; @@ -68,7 +68,7 @@ const TagsInput: React.FC = ({ {t('label.tag-plural')}
- + ) : ( = ({ flex="320px"> = ({ /> ), }, @@ -132,11 +131,7 @@ const VersionTable = ({ accessor: 'tags', width: 272, render: (tags: Column['tags']) => ( - + ), }, ], diff --git a/openmetadata-ui/src/main/resources/ui/src/components/common/SummaryTagsDescription/SummaryTagsDescription.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/common/SummaryTagsDescription/SummaryTagsDescription.component.tsx index 972c554872d..f86a31efe13 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/common/SummaryTagsDescription/SummaryTagsDescription.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/common/SummaryTagsDescription/SummaryTagsDescription.component.tsx @@ -12,7 +12,7 @@ */ import { Col, Divider, Row, Typography } from 'antd'; import { EntityUnion } from 'components/Explore/explore.interface'; -import TagsViewer from 'components/Tag/TagsViewer/tags-viewer'; +import TagsViewer from 'components/Tag/TagsViewer/TagsViewer'; import { TagLabel } from 'generated/type/tagLabel'; import React from 'react'; import { useTranslation } from 'react-i18next'; diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/en-us.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/en-us.json index 613a8b4b4f9..0f4c7f4e570 100644 --- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/en-us.json +++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/en-us.json @@ -496,6 +496,7 @@ "last-updated": "Last Updated", "latest": "Latest", "leave-team": "Leave Team", + "less": "Less", "less-lowercase": "less", "line": "Line", "line-plural": "Lines", diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/es-es.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/es-es.json index 52f03527aa9..4a0e5480b82 100644 --- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/es-es.json +++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/es-es.json @@ -496,6 +496,7 @@ "last-updated": "Última actualización", "latest": "Último", "leave-team": "Dejar el equipo", + "less": "Less", "less-lowercase": "menos", "line": "Línea", "line-plural": "Lines", diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/fr-fr.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/fr-fr.json index 34e13d18466..77345b4064c 100644 --- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/fr-fr.json +++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/fr-fr.json @@ -496,6 +496,7 @@ "last-updated": "Dernière Mise à Jour", "latest": "Dernier·ère", "leave-team": "Quitter une Equipe", + "less": "Less", "less-lowercase": "moins", "line": "Ligne", "line-plural": "Lignes", diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/ja-jp.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/ja-jp.json index ee74ee8f828..e3063071cd8 100644 --- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/ja-jp.json +++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/ja-jp.json @@ -496,6 +496,7 @@ "last-updated": "最終更新日", "latest": "最新", "leave-team": "チームを抜ける", + "less": "Less", "less-lowercase": "less", "line": "Line", "line-plural": "Lines", diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/pt-br.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/pt-br.json index d4171af9325..a6dded86773 100644 --- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/pt-br.json +++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/pt-br.json @@ -496,6 +496,7 @@ "last-updated": "Última atualização em", "latest": "Mais recente", "leave-team": "Sair do time", + "less": "Less", "less-lowercase": "menos", "line": "Line", "line-plural": "Lines", diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/zh-cn.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/zh-cn.json index 74daf3fa57a..e268aba80f0 100644 --- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/zh-cn.json +++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/zh-cn.json @@ -496,6 +496,7 @@ "last-updated": "最近更新", "latest": "最新", "leave-team": "离开团队", + "less": "Less", "less-lowercase": "更少", "line": "行", "line-plural": "行", diff --git a/openmetadata-ui/src/main/resources/ui/src/pages/ContainerPage/ContainerPage.tsx b/openmetadata-ui/src/main/resources/ui/src/pages/ContainerPage/ContainerPage.tsx index ef148de93c0..6c817b68ef3 100644 --- a/openmetadata-ui/src/main/resources/ui/src/pages/ContainerPage/ContainerPage.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/pages/ContainerPage/ContainerPage.tsx @@ -36,6 +36,7 @@ import { } from 'components/PermissionProvider/PermissionProvider.interface'; import TabsLabel from 'components/TabsLabel/TabsLabel.component'; import TagsContainerV2 from 'components/Tag/TagsContainerV2/TagsContainerV2'; +import { DisplayType } from 'components/Tag/TagsViewer/TagsViewer.interface'; import { getContainerDetailPath, getVersionPath } from 'constants/constants'; import { EntityField } from 'constants/Feeds.constants'; import { ERROR_PLACEHOLDER_TYPE } from 'enums/common.enum'; @@ -518,6 +519,7 @@ const ContainerPage = () => { flex="320px"> { onThreadLinkSelect={onThreadLinkSelect} /> { flex="320px"> { onThreadLinkSelect={onThreadLinkSelect} /> { flex="320px"> { onThreadLinkSelect={onThreadLinkSelect} /> ( - + ), }, ...(ServiceCategory.DATABASE_SERVICES === serviceCategory @@ -337,6 +338,7 @@ function ServiceMainTabContent({ flex="320px"> { { />