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 0586cb79321..749773893ae 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
@@ -624,6 +624,7 @@ const DashboardDetails = ({
domain={dashboardDetails?.domain}
editTagPermission={editTagsPermission}
entityFQN={decodedDashboardFQN}
+ entityId={dashboardDetails.id}
entityType={EntityType.DASHBOARD}
selectedTags={dashboardTags}
onTagSelectionChange={handleTagSelection}
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 7bd95a8393b..9bcf11bdbb6 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
@@ -235,6 +235,7 @@ const DataModelDetails = ({
domain={dataModelData?.domain}
editTagPermission={editTagsPermission}
entityFQN={decodedDataModelFQN}
+ entityId={dataModelData.id}
entityType={EntityType.DASHBOARD_DATA_MODEL}
selectedTags={tags}
onTagSelectionChange={handleTagSelection}
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Entity/EntityRightPanel/EntityRightPanel.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Entity/EntityRightPanel/EntityRightPanel.test.tsx
index 458b850a9cc..11a74011058 100644
--- a/openmetadata-ui/src/main/resources/ui/src/components/Entity/EntityRightPanel/EntityRightPanel.test.tsx
+++ b/openmetadata-ui/src/main/resources/ui/src/components/Entity/EntityRightPanel/EntityRightPanel.test.tsx
@@ -15,6 +15,7 @@ import { EntityTags } from 'Models';
import React from 'react';
import { EntityType } from '../../../enums/entity.enum';
import { EntityReference } from '../../../generated/entity/type';
+import entityRightPanelClassBase from '../../../utils/EntityRightPanelClassBase';
import EntityRightPanel from './EntityRightPanel';
jest.mock('../../DataProductsContainer/DataProductsContainer.component', () => {
@@ -25,6 +26,8 @@ jest.mock('../../Tag/TagsContainerV2/TagsContainerV2', () => {
return jest.fn().mockImplementation(() =>
TagsContainerV2
);
});
+jest.mock('../../../utils/EntityRightPanelClassBase');
+
describe('EntityRightPanel component test', () => {
const mockDataProducts: EntityReference[] = [];
const mockSelectedTags: EntityTags[] = [];
@@ -37,6 +40,7 @@ describe('EntityRightPanel component test', () => {
editTagPermission
dataProducts={mockDataProducts}
entityFQN="testEntityFQN"
+ entityId="testEntityId"
entityType={EntityType.TABLE}
selectedTags={mockSelectedTags}
onTagSelectionChange={mockOnTagSelectionChange}
@@ -54,6 +58,7 @@ describe('EntityRightPanel component test', () => {
editTagPermission
dataProducts={mockDataProducts}
entityFQN="testEntityFQN"
+ entityId="testEntityId"
entityType={EntityType.TABLE}
selectedTags={mockSelectedTags}
showDataProductContainer={false}
@@ -73,6 +78,7 @@ describe('EntityRightPanel component test', () => {
beforeSlot={beforeSlot
}
dataProducts={mockDataProducts}
entityFQN="testEntityFQN"
+ entityId="testEntityId"
entityType={EntityType.TABLE}
selectedTags={mockSelectedTags}
showDataProductContainer={false}
@@ -91,6 +97,7 @@ describe('EntityRightPanel component test', () => {
editTagPermission
dataProducts={mockDataProducts}
entityFQN="testEntityFQN"
+ entityId="testEntityId"
entityType={EntityType.TABLE}
selectedTags={mockSelectedTags}
showDataProductContainer={false}
@@ -102,4 +109,53 @@ describe('EntityRightPanel component test', () => {
expect(screen.queryByText('beforeSlot')).not.toBeInTheDocument();
expect(screen.queryByText('afterSlot')).not.toBeInTheDocument();
});
+
+ it('Component should render KnowledgeArticles when getKnowLedgeArticlesWidget is not null', () => {
+ const KnowledgeArticles = () => (
+ KnowledgeArticles
+ );
+ const spy = jest
+ .spyOn(entityRightPanelClassBase, 'getKnowLedgeArticlesWidget')
+ .mockImplementation(() => KnowledgeArticles);
+ render(
+
+ );
+
+ expect(spy).toHaveBeenCalled();
+
+ expect(screen.getByText('KnowledgeArticles')).toBeInTheDocument();
+ });
+
+ it('Component should not render KnowledgeArticles when getKnowLedgeArticlesWidget is null', () => {
+ const spy = jest
+ .spyOn(entityRightPanelClassBase, 'getKnowLedgeArticlesWidget')
+ .mockImplementation(() => null);
+ render(
+
+ );
+
+ expect(spy).toHaveBeenCalled();
+
+ expect(screen.queryByText('KnowledgeArticles')).not.toBeInTheDocument();
+ });
});
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Entity/EntityRightPanel/EntityRightPanel.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Entity/EntityRightPanel/EntityRightPanel.tsx
index 03faffa447c..32d399afdcd 100644
--- a/openmetadata-ui/src/main/resources/ui/src/components/Entity/EntityRightPanel/EntityRightPanel.tsx
+++ b/openmetadata-ui/src/main/resources/ui/src/components/Entity/EntityRightPanel/EntityRightPanel.tsx
@@ -17,6 +17,7 @@ import { EntityType } from '../../../enums/entity.enum';
import { ThreadType } from '../../../generated/entity/feed/thread';
import { EntityReference } from '../../../generated/entity/type';
import { TagSource } from '../../../generated/type/tagLabel';
+import entityRightPanelClassBase from '../../../utils/EntityRightPanelClassBase';
import DataProductsContainer from '../../DataProductsContainer/DataProductsContainer.component';
import TagsContainerV2 from '../../Tag/TagsContainerV2/TagsContainerV2';
import { DisplayType } from '../../Tag/TagsViewer/TagsViewer.interface';
@@ -26,6 +27,7 @@ interface EntityRightPanelProps {
editTagPermission: boolean;
entityType: EntityType;
entityFQN: string;
+ entityId: string;
selectedTags: EntityTags[];
beforeSlot?: React.ReactNode;
showTaskHandler?: boolean;
@@ -47,9 +49,13 @@ const EntityRightPanel: FC = ({
onThreadLinkSelect,
beforeSlot,
afterSlot,
+ entityId,
showTaskHandler = true,
showDataProductContainer = true,
}) => {
+ const KnowledgeArticles =
+ entityRightPanelClassBase.getKnowLedgeArticlesWidget();
+
return (
<>
{beforeSlot}
@@ -85,6 +91,9 @@ const EntityRightPanel: FC = ({
onSelectionChange={onTagSelectionChange}
onThreadLinkSelect={onThreadLinkSelect}
/>
+ {KnowledgeArticles && (
+
+ )}
{afterSlot}
>
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 bcda8b36912..ff926f74cd3 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
@@ -425,6 +425,7 @@ const MlModelDetail: FC = ({
domain={mlModelDetail?.domain}
editTagPermission={editTagsPermission}
entityFQN={decodedMlModelFqn}
+ entityId={mlModelDetail.id}
entityType={EntityType.MLMODEL}
selectedTags={mlModelTags}
onTagSelectionChange={handleTagSelection}
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 02d6e5df394..34a5658c5ef 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
@@ -605,6 +605,7 @@ const PipelineDetails = ({
domain={pipelineDetails?.domain}
editTagPermission={editTagsPermission}
entityFQN={pipelineFQN}
+ entityId={pipelineDetails.id}
entityType={EntityType.PIPELINE}
selectedTags={tags}
onTagSelectionChange={handleTagSelection}
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/TopicDetails/TopicDetails.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/TopicDetails/TopicDetails.component.tsx
index 890e94645e7..94b6b880a70 100644
--- a/openmetadata-ui/src/main/resources/ui/src/components/TopicDetails/TopicDetails.component.tsx
+++ b/openmetadata-ui/src/main/resources/ui/src/components/TopicDetails/TopicDetails.component.tsx
@@ -330,6 +330,7 @@ const TopicDetails: React.FC = ({
domain={topicDetails?.domain}
editTagPermission={editTagsPermission}
entityFQN={decodedTopicFQN}
+ entityId={topicDetails.id}
entityType={EntityType.TOPIC}
selectedTags={topicTags}
onTagSelectionChange={handleTagSelection}
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 942d6378462..50c2fab2c8a 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
@@ -545,6 +545,7 @@ const ContainerPage = () => {
editTagsPermission && !containerData?.deleted
}
entityFQN={decodedContainerName}
+ entityId={containerData?.id ?? ''}
entityType={EntityType.CONTAINER}
selectedTags={tags}
onTagSelectionChange={handleTagSelection}
diff --git a/openmetadata-ui/src/main/resources/ui/src/pages/DatabaseDetailsPage/DatabaseDetailsPage.tsx b/openmetadata-ui/src/main/resources/ui/src/pages/DatabaseDetailsPage/DatabaseDetailsPage.tsx
index 135b457a7a6..cdf2131b6dd 100644
--- a/openmetadata-ui/src/main/resources/ui/src/pages/DatabaseDetailsPage/DatabaseDetailsPage.tsx
+++ b/openmetadata-ui/src/main/resources/ui/src/pages/DatabaseDetailsPage/DatabaseDetailsPage.tsx
@@ -540,6 +540,7 @@ const DatabaseDetails: FunctionComponent = () => {
domain={database?.domain}
editTagPermission={editTagsPermission}
entityFQN={decodedDatabaseFQN}
+ entityId={database?.id ?? ''}
entityType={EntityType.DATABASE}
selectedTags={tags}
onTagSelectionChange={handleTagSelection}
diff --git a/openmetadata-ui/src/main/resources/ui/src/pages/DatabaseSchemaPage/DatabaseSchemaPage.component.tsx b/openmetadata-ui/src/main/resources/ui/src/pages/DatabaseSchemaPage/DatabaseSchemaPage.component.tsx
index 3ddf462bad4..035781b4ce3 100644
--- a/openmetadata-ui/src/main/resources/ui/src/pages/DatabaseSchemaPage/DatabaseSchemaPage.component.tsx
+++ b/openmetadata-ui/src/main/resources/ui/src/pages/DatabaseSchemaPage/DatabaseSchemaPage.component.tsx
@@ -586,6 +586,7 @@ const DatabaseSchemaPage: FunctionComponent = () => {
domain={databaseSchema?.domain}
editTagPermission={editTagsPermission}
entityFQN={decodedDatabaseSchemaFQN}
+ entityId={databaseSchema?.id ?? ''}
entityType={EntityType.DATABASE_SCHEMA}
selectedTags={tags}
onTagSelectionChange={handleTagSelection}
diff --git a/openmetadata-ui/src/main/resources/ui/src/pages/SearchIndexDetailsPage/SearchIndexDetailsPage.tsx b/openmetadata-ui/src/main/resources/ui/src/pages/SearchIndexDetailsPage/SearchIndexDetailsPage.tsx
index 2d5132f0383..c689676fda0 100644
--- a/openmetadata-ui/src/main/resources/ui/src/pages/SearchIndexDetailsPage/SearchIndexDetailsPage.tsx
+++ b/openmetadata-ui/src/main/resources/ui/src/pages/SearchIndexDetailsPage/SearchIndexDetailsPage.tsx
@@ -395,6 +395,7 @@ function SearchIndexDetailsPage() {
domain={searchIndexDetails?.domain}
editTagPermission={editTagsPermission}
entityFQN={decodedSearchIndexFQN}
+ entityId={searchIndexDetails?.id ?? ''}
entityType={EntityType.SEARCH_INDEX}
selectedTags={searchIndexTags}
onTagSelectionChange={handleTagSelection}
diff --git a/openmetadata-ui/src/main/resources/ui/src/pages/ServiceDetailsPage/ServiceMainTabContent.tsx b/openmetadata-ui/src/main/resources/ui/src/pages/ServiceDetailsPage/ServiceMainTabContent.tsx
index 31461e526e1..281fecb56e5 100644
--- a/openmetadata-ui/src/main/resources/ui/src/pages/ServiceDetailsPage/ServiceMainTabContent.tsx
+++ b/openmetadata-ui/src/main/resources/ui/src/pages/ServiceDetailsPage/ServiceMainTabContent.tsx
@@ -220,6 +220,7 @@ function ServiceMainTabContent({
domain={(serviceDetails as DatabaseService)?.domain}
editTagPermission={editTagsPermission}
entityFQN={serviceFQN}
+ entityId={serviceDetails.id}
entityType={entityType}
selectedTags={tags}
showDataProductContainer={entityType !== EntityType.METADATA_SERVICE}
diff --git a/openmetadata-ui/src/main/resources/ui/src/pages/StoredProcedure/StoredProcedurePage.tsx b/openmetadata-ui/src/main/resources/ui/src/pages/StoredProcedure/StoredProcedurePage.tsx
index 23b00f2b601..08ca4a946a7 100644
--- a/openmetadata-ui/src/main/resources/ui/src/pages/StoredProcedure/StoredProcedurePage.tsx
+++ b/openmetadata-ui/src/main/resources/ui/src/pages/StoredProcedure/StoredProcedurePage.tsx
@@ -556,6 +556,7 @@ const StoredProcedurePage = () => {
domain={storedProcedure?.domain}
editTagPermission={editTagsPermission}
entityFQN={decodedStoredProcedureFQN}
+ entityId={storedProcedure?.id ?? ''}
entityType={EntityType.STORED_PROCEDURE}
selectedTags={tags}
onTagSelectionChange={handleTagSelection}
diff --git a/openmetadata-ui/src/main/resources/ui/src/pages/TableDetailsPageV1/TableDetailsPageV1.tsx b/openmetadata-ui/src/main/resources/ui/src/pages/TableDetailsPageV1/TableDetailsPageV1.tsx
index 3e8783dbbce..d0eb147d92f 100644
--- a/openmetadata-ui/src/main/resources/ui/src/pages/TableDetailsPageV1/TableDetailsPageV1.tsx
+++ b/openmetadata-ui/src/main/resources/ui/src/pages/TableDetailsPageV1/TableDetailsPageV1.tsx
@@ -517,7 +517,10 @@ const TableDetailsPageV1 = () => {
flex="320px">
+
@@ -537,6 +540,7 @@ const TableDetailsPageV1 = () => {
domain={tableDetails?.domain}
editTagPermission={editTagsPermission}
entityFQN={decodedTableFQN}
+ entityId={tableDetails?.id ?? ''}
entityType={EntityType.TABLE}
selectedTags={tableTags}
onTagSelectionChange={handleTagSelection}
diff --git a/openmetadata-ui/src/main/resources/ui/src/utils/EntityRightPanelClassBase.test.tsx b/openmetadata-ui/src/main/resources/ui/src/utils/EntityRightPanelClassBase.test.tsx
new file mode 100644
index 00000000000..5524149b7a3
--- /dev/null
+++ b/openmetadata-ui/src/main/resources/ui/src/utils/EntityRightPanelClassBase.test.tsx
@@ -0,0 +1,55 @@
+/*
+ * 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 { render, screen } from '@testing-library/react';
+import React, { FC } from 'react';
+import entityRightPanelClassBase, {
+ EntityRightPanelClassBase,
+} from './EntityRightPanelClassBase';
+
+describe('EntityRightPanelClassBase', () => {
+ let instance: EntityRightPanelClassBase;
+
+ beforeEach(() => {
+ instance = new EntityRightPanelClassBase();
+ });
+
+ it('should create an instance of EntityRightPanelClassBase', () => {
+ expect(instance).toBeInstanceOf(EntityRightPanelClassBase);
+ });
+
+ it('should return null from getKnowLedgeArticlesWidget method', () => {
+ const widget: FC<{ entityId: string; entityType: string }> | null =
+ instance.getKnowLedgeArticlesWidget();
+
+ expect(widget).toBeNull();
+ });
+
+ it('should return a valid React component when getKnowLedgeArticlesWidget is not null', () => {
+ // Mock the getKnowLedgeArticlesWidget method to return a KnowLedgeArticles component
+ instance.getKnowLedgeArticlesWidget = () => () =>
+ ;
+
+ const Widget = instance.getKnowLedgeArticlesWidget();
+ if (Widget) {
+ render();
+ }
+
+ expect(screen.queryByTestId('KnowLedgeArticles')).toBeInTheDocument();
+ });
+});
+
+describe('entityRightPanelClassBase', () => {
+ it('should be an instance of EntityRightPanelClassBase', () => {
+ expect(entityRightPanelClassBase).toBeInstanceOf(EntityRightPanelClassBase);
+ });
+});
diff --git a/openmetadata-ui/src/main/resources/ui/src/utils/EntityRightPanelClassBase.ts b/openmetadata-ui/src/main/resources/ui/src/utils/EntityRightPanelClassBase.ts
new file mode 100644
index 00000000000..21ef7a448c8
--- /dev/null
+++ b/openmetadata-ui/src/main/resources/ui/src/utils/EntityRightPanelClassBase.ts
@@ -0,0 +1,28 @@
+/*
+ * 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 { FC } from 'react';
+
+class EntityRightPanelClassBase {
+ public getKnowLedgeArticlesWidget(): FC<{
+ entityId: string;
+ entityType: string;
+ }> | null {
+ return null;
+ }
+}
+
+const entityRightPanelClassBase = new EntityRightPanelClassBase();
+
+export default entityRightPanelClassBase;
+
+export { EntityRightPanelClassBase };