diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/search/elasticsearch/ElasticSearchClient.java b/openmetadata-service/src/main/java/org/openmetadata/service/search/elasticsearch/ElasticSearchClient.java index 0b3b75e71d39..bc49170a56ad 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/search/elasticsearch/ElasticSearchClient.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/search/elasticsearch/ElasticSearchClient.java @@ -380,10 +380,7 @@ public Response search(SearchRequest request) throws IOException { } if (request.getIndex().equalsIgnoreCase("glossary_term_search_index")) { - searchSourceBuilder.query( - QueryBuilders.boolQuery() - .must(searchSourceBuilder.query()) - .must(QueryBuilders.matchQuery("status", "Approved"))); + searchSourceBuilder.query(QueryBuilders.boolQuery().must(searchSourceBuilder.query())); if (request.isGetHierarchy()) { /* @@ -1170,6 +1167,7 @@ private static SearchSourceBuilder buildGlossaryTermSearchBuilder( AggregationBuilders.terms("glossary.name.keyword").field("glossary.name.keyword")); searchSourceBuilder.aggregation( AggregationBuilders.terms("fqnParts_agg").field("fqnParts").size(1000)); + searchSourceBuilder.aggregation(AggregationBuilders.terms("status").field("status")); return addAggregation(searchSourceBuilder); } diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/search/opensearch/OpenSearchClient.java b/openmetadata-service/src/main/java/org/openmetadata/service/search/opensearch/OpenSearchClient.java index 6da54ad0c59d..7921c7241b49 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/search/opensearch/OpenSearchClient.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/search/opensearch/OpenSearchClient.java @@ -378,10 +378,7 @@ public Response search(SearchRequest request) throws IOException { } if (request.getIndex().equalsIgnoreCase("glossary_term_search_index")) { - searchSourceBuilder.query( - QueryBuilders.boolQuery() - .must(searchSourceBuilder.query()) - .must(QueryBuilders.matchQuery("status", "Approved"))); + searchSourceBuilder.query(QueryBuilders.boolQuery().must(searchSourceBuilder.query())); if (request.isGetHierarchy()) { /* @@ -1169,6 +1166,7 @@ private static SearchSourceBuilder buildGlossaryTermSearchBuilder( AggregationBuilders.terms("glossary.name.keyword").field("glossary.name.keyword")); searchSourceBuilder.aggregation( AggregationBuilders.terms("fqnParts_agg").field("fqnParts").size(1000)); + searchSourceBuilder.aggregation(AggregationBuilders.terms("status").field("status")); return addAggregation(searchSourceBuilder); } diff --git a/openmetadata-service/src/main/resources/elasticsearch/en/glossary_term_index_mapping.json b/openmetadata-service/src/main/resources/elasticsearch/en/glossary_term_index_mapping.json index c6e6febb6311..2f1eb368230c 100644 --- a/openmetadata-service/src/main/resources/elasticsearch/en/glossary_term_index_mapping.json +++ b/openmetadata-service/src/main/resources/elasticsearch/en/glossary_term_index_mapping.json @@ -393,7 +393,8 @@ "type": "text" }, "status": { - "type": "text" + "type": "keyword", + "normalizer": "lowercase_normalizer" }, "entityType": { "type": "keyword" diff --git a/openmetadata-service/src/main/resources/elasticsearch/jp/glossary_term_index_mapping.json b/openmetadata-service/src/main/resources/elasticsearch/jp/glossary_term_index_mapping.json index 21771c29133a..211a6ed5f078 100644 --- a/openmetadata-service/src/main/resources/elasticsearch/jp/glossary_term_index_mapping.json +++ b/openmetadata-service/src/main/resources/elasticsearch/jp/glossary_term_index_mapping.json @@ -394,7 +394,8 @@ "type": "text" }, "status": { - "type": "text" + "type": "keyword", + "normalizer": "lowercase_normalizer" }, "entityType": { "type": "keyword" diff --git a/openmetadata-service/src/main/resources/elasticsearch/zh/glossary_term_index_mapping.json b/openmetadata-service/src/main/resources/elasticsearch/zh/glossary_term_index_mapping.json index a9cf38ba6874..a8a3027c75e5 100644 --- a/openmetadata-service/src/main/resources/elasticsearch/zh/glossary_term_index_mapping.json +++ b/openmetadata-service/src/main/resources/elasticsearch/zh/glossary_term_index_mapping.json @@ -342,7 +342,8 @@ "type": "keyword" }, "state": { - "type": "keyword" + "type": "keyword", + "normalizer": "lowercase_normalizer" } } }, @@ -350,7 +351,7 @@ "type": "text" }, "status": { - "type": "text" + "type": "keyword" }, "suggest": { "type": "completion", diff --git a/openmetadata-ui/src/main/resources/ui/cypress/common/Utils/Entity.ts b/openmetadata-ui/src/main/resources/ui/cypress/common/Utils/Entity.ts index 95fd26fdb243..dee9c4c72a35 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/common/Utils/Entity.ts +++ b/openmetadata-ui/src/main/resources/ui/cypress/common/Utils/Entity.ts @@ -460,7 +460,7 @@ export const deleteEntity = ( 'getDatabaseSchemas' ); - cy.get('[data-testid="breadcrumb-link"]').last().click(); + cy.get('[data-testid="breadcrumb-link"]:last-child').click({ force: true }); verifyResponseStatusCode('@getDatabaseSchemas', 200); cy.get('[data-testid="show-deleted"]') diff --git a/openmetadata-ui/src/main/resources/ui/cypress/constants/advancedSearchQuickFilters.constants.ts b/openmetadata-ui/src/main/resources/ui/cypress/constants/advancedSearchQuickFilters.constants.ts index af518eda0f09..fc2d26029a89 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/constants/advancedSearchQuickFilters.constants.ts +++ b/openmetadata-ui/src/main/resources/ui/cypress/constants/advancedSearchQuickFilters.constants.ts @@ -137,6 +137,10 @@ export const GLOSSARY_DROPDOWN_ITEMS = [ label: 'Glossaries', key: 'glossary.name.keyword', }, + { + label: 'Status', + key: 'status', + }, ]; export const TAG_DROPDOWN_ITEMS = [ diff --git a/openmetadata-ui/src/main/resources/ui/cypress/constants/constants.ts b/openmetadata-ui/src/main/resources/ui/cypress/constants/constants.ts index ac49d67daab5..5f86e4e96ca3 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/constants/constants.ts +++ b/openmetadata-ui/src/main/resources/ui/cypress/constants/constants.ts @@ -423,12 +423,14 @@ export const NEW_GLOSSARY_TERMS = { description: 'This is the Cypress Purchase', synonyms: 'buy,collect,acquire', fullyQualifiedName: `${cypressGlossaryName}.CypressPurchase`, + owner: 'Aaron Johnson', }, term_2: { name: 'CypressSales', description: 'This is the Cypress Sales', synonyms: 'give,disposal,deal', fullyQualifiedName: `${cypressGlossaryName}.CypressSales`, + owner: 'Aaron Johnson', }, term_3: { name: 'Cypress Space', @@ -436,6 +438,7 @@ export const NEW_GLOSSARY_TERMS = { synonyms: 'tea,coffee,water', fullyQualifiedName: `${cypressGlossaryName}.Cypress Space`, assets: COMMON_ASSETS, + owner: 'admin', }, }; export const GLOSSARY_TERM_WITH_DETAILS = { diff --git a/openmetadata-ui/src/main/resources/ui/cypress/constants/glossary.constant.ts b/openmetadata-ui/src/main/resources/ui/cypress/constants/glossary.constant.ts index 448174cc2bee..964f5c964b09 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/constants/glossary.constant.ts +++ b/openmetadata-ui/src/main/resources/ui/cypress/constants/glossary.constant.ts @@ -11,4 +11,28 @@ * limitations under the License. */ +import { uuid } from './constants'; + export const GLOSSARY_OWNER_LINK_TEST_ID = 'glossary-right-panel-owner-link'; + +export const GLOSSARY_DETAILS1 = { + name: `Cypress%QFTEST ${uuid()}`, + displayName: `Cypress % QFTEST ${uuid()}`, + description: 'Test Glossary', + reviewers: [], + tags: [], + mutuallyExclusive: false, +}; + +export const GLOSSARY_TERM_DETAILS1 = { + name: `CypressQFTEST_TERM-${uuid()}`, + displayName: 'Cypress QFTEST_TERM', + description: 'Quick filter test.', + reviewers: [], + relatedTerms: [], + synonyms: [], + mutuallyExclusive: false, + tags: [], + style: {}, + glossary: GLOSSARY_DETAILS1.name, +}; diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Glossary.spec.ts b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Glossary.spec.ts index 9473152107a5..d295c17429c5 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Glossary.spec.ts +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Glossary.spec.ts @@ -28,6 +28,7 @@ import { generateRandomUser, removeOwner, } from '../../common/Utils/Owner'; +import { GLOSSARY_DROPDOWN_ITEMS } from '../../constants/advancedSearchQuickFilters.constants'; import { COLUMN_NAME_FOR_APPLY_GLOSSARY_TERM, CYPRESS_ASSETS_GLOSSARY, @@ -52,6 +53,27 @@ const userName = `${CREDENTIALS.firstName}${CREDENTIALS.lastName}`; let createdUserId = ''; +const selectOwner = (ownerName: string, dataTestId?: string) => { + interceptURL('GET', '/api/v1/users?*isBot=false*', 'getUsers'); + cy.get('[data-testid="add-owner"]').scrollIntoView().click(); + cy.get("[data-testid='select-owner-tabs']").should('be.visible'); + cy.get('.ant-tabs [id*=tab-users]').click(); + verifyResponseStatusCode('@getUsers', 200); + interceptURL( + 'GET', + `api/v1/search/query?q=*&index=user_search_index*`, + 'searchOwner' + ); + + cy.get('[data-testid="owner-select-users-search-bar"]').type(ownerName); + verifyResponseStatusCode('@searchOwner', 200); + cy.get(`.ant-popover [title="${ownerName}"]`).click(); + cy.get(`[data-testid=${dataTestId ?? 'owner-link'}]`).should( + 'contain', + ownerName + ); +}; + const visitGlossaryTermPage = ( termName: string, fqn: string, @@ -175,6 +197,17 @@ const checkDisplayName = (displayName) => { }); }; +const verifyGlossaryTermDataInTable = (term, status: string) => { + const escapedName = Cypress.$.escapeSelector(term.fullyQualifiedName); + const selector = `[data-row-key=${escapedName}]`; + cy.get(selector).scrollIntoView().should('be.visible'); + cy.get(`${selector} [data-testid="${escapedName}-status"]`).contains(status); + // If empty owner, the creator is the owner + cy.get(`${selector} [data-testid="owner-link"]`).contains( + term.owner ?? 'admin' + ); +}; + const checkAssetsCount = (assetsCount) => { cy.get('[data-testid="assets"] [data-testid="filter-count"]') .scrollIntoView() @@ -268,6 +301,10 @@ const fillGlossaryTermDetails = ( .scrollIntoView() .type(term.color); } + + if (term.owner) { + selectOwner(term.owner, 'owner-container'); + } }; const addAssetToGlossaryTerm = (glossaryTerm, glossary) => { @@ -566,7 +603,6 @@ const downVoting = (api: string) => { cy.wait(api).then(({ request, response }) => { expect(request.body.updatedVoteType).to.equal('votedDown'); - expect(response.statusCode).to.equal(200); }); @@ -582,7 +618,6 @@ const initialVoting = (api: string) => { cy.wait(api).then(({ request, response }) => { expect(request.body.updatedVoteType).to.equal('unVoted'); - expect(response.statusCode).to.equal(200); }); @@ -597,9 +632,7 @@ const voteGlossary = (isGlossary?: boolean) => { interceptURL('PUT', '/api/v1/glossaryTerms/*/vote', 'voteGlossaryTerm'); } upVoting(isGlossary ? '@voteGlossary' : '@voteGlossaryTerm'); - downVoting(isGlossary ? '@voteGlossary' : '@voteGlossaryTerm'); - initialVoting(isGlossary ? '@voteGlossary' : '@voteGlossaryTerm'); }; @@ -716,6 +749,29 @@ const deleteUser = () => { }); }; +const verifyStatusFilterInExplore = (statusField: string) => { + const fieldName = Cypress._.toLower(statusField); + const glossaryTermStatusFilter = GLOSSARY_DROPDOWN_ITEMS.find( + (item) => item.key === 'status' + ); + + cy.sidebarClick(SidebarItem.EXPLORE); + cy.get(`[data-testid="glossary terms-tab"]`).scrollIntoView().click(); + cy.get(`[data-testid="search-dropdown-${glossaryTermStatusFilter.label}"]`) + .scrollIntoView() + .click(); + cy.get(`[data-testid=${fieldName}]`) + .should('exist') + .and('be.visible') + .click(); + + const querySearchURL = `/api/v1/search/query?*index=glossary_term_search_index*query_filter=*should*${glossaryTermStatusFilter.key}*${fieldName}*`; + + interceptURL('GET', querySearchURL, 'querySearchAPI'); + cy.get('[data-testid="update-btn"]').click(); + verifyResponseStatusCode('@querySearchAPI', 200); +}; + describe('Glossary page should work properly', { tags: 'Governance' }, () => { before(() => { // Prerequisites - Create a user with data consumer role @@ -841,17 +897,21 @@ describe('Glossary page should work properly', { tags: 'Governance' }, () => { it('Create glossary term should work properly', () => { const terms = Object.values(NEW_GLOSSARY_TERMS); selectActiveGlossary(NEW_GLOSSARY.name); - terms.forEach((term, index) => - createGlossaryTerm(term, NEW_GLOSSARY, 'Draft', true, index === 0) - ); + terms.forEach((term, index) => { + createGlossaryTerm(term, NEW_GLOSSARY, 'Draft', true, index === 0); + verifyGlossaryTermDataInTable(term, 'Draft'); + }); // Glossary term for Product glossary selectActiveGlossary(NEW_GLOSSARY_1.name); const ProductTerms = Object.values(NEW_GLOSSARY_1_TERMS); - ProductTerms.forEach((term) => - createGlossaryTerm(term, NEW_GLOSSARY_1, 'Approved', false, false) - ); + ProductTerms.forEach((term) => { + createGlossaryTerm(term, NEW_GLOSSARY_1, 'Approved', false, false); + verifyGlossaryTermDataInTable(term, 'Approved'); + }); + verifyStatusFilterInExplore('Approved'); + verifyStatusFilterInExplore('Draft'); }); it('Approval Workflow for Glossary Term', () => { diff --git a/openmetadata-ui/src/main/resources/ui/src/components/ExploreV1/ExploreSearchCard/ExploreSearchCard.tsx b/openmetadata-ui/src/main/resources/ui/src/components/ExploreV1/ExploreSearchCard/ExploreSearchCard.tsx index 51f6188df8a5..e76bbac9ec14 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/ExploreV1/ExploreSearchCard/ExploreSearchCard.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/ExploreV1/ExploreSearchCard/ExploreSearchCard.tsx @@ -20,6 +20,10 @@ import { Link, useParams } from 'react-router-dom'; import { useTourProvider } from '../../../context/TourProvider/TourProvider'; import { EntityType } from '../../../enums/entity.enum'; import { OwnerType } from '../../../enums/user.enum'; +import { + GlossaryTerm, + Status, +} from '../../../generated/entity/data/glossaryTerm'; import { EntityReference } from '../../../generated/entity/type'; import { getEntityPlaceHolder, @@ -32,6 +36,7 @@ import { stringToHTML } from '../../../utils/StringsUtils'; import { getEntityIcon, getUsagePercentile } from '../../../utils/TableUtils'; import TitleBreadcrumb from '../../common/TitleBreadcrumb/TitleBreadcrumb.component'; import TableDataCardBody from '../../Database/TableDataCardBody/TableDataCardBody'; +import { GlossaryStatusBadge } from '../../Glossary/GlossaryStatusBadge/GlossaryStatusBadge.component'; import './explore-search-card.less'; import { ExploreSearchCardProps } from './ExploreSearchCard.interface'; @@ -170,6 +175,10 @@ const ExploreSearchCard: React.FC = forwardRef< }, [source, showEntityIcon, getEntityIcon]); const header = useMemo(() => { + const hasGlossaryTermStatus = + source.entityType === EntityType.GLOSSARY_TERM && + (source as GlossaryTerm).status !== Status.Approved; + return ( {showCheckboxes && ( @@ -216,7 +225,10 @@ const ExploreSearchCard: React.FC = forwardRef< {entityIcon} = forwardRef< {stringToHTML(searchClassBase.getEntityName(source))} + + {hasGlossaryTermStatus && ( + + )} )} diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Glossary/GlossaryHeader/GlossaryHeader.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Glossary/GlossaryHeader/GlossaryHeader.component.tsx index dd5509fd998e..7152ddbf8291 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Glossary/GlossaryHeader/GlossaryHeader.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Glossary/GlossaryHeader/GlossaryHeader.component.tsx @@ -11,16 +11,7 @@ * limitations under the License. */ import Icon, { DownOutlined } from '@ant-design/icons'; -import { - Button, - Col, - Divider, - Dropdown, - Row, - Space, - Tooltip, - Typography, -} from 'antd'; +import { Button, Col, Dropdown, Row, Space, Tooltip, Typography } from 'antd'; import ButtonGroup from 'antd/lib/button/button-group'; import { ItemType } from 'antd/lib/menu/hooks/useItems'; import { AxiosError } from 'axios'; @@ -41,7 +32,6 @@ import { ReactComponent as VersionIcon } from '../../../assets/svg/ic-version.sv import { ReactComponent as IconDropdown } from '../../../assets/svg/menu.svg'; import { ReactComponent as StyleIcon } from '../../../assets/svg/style.svg'; import { ManageButtonItemLabel } from '../../../components/common/ManageButtonContentItem/ManageButtonContentItem.component'; -import StatusBadge from '../../../components/common/StatusBadge/StatusBadge.component'; import { useEntityExportModalProvider } from '../../../components/Entity/EntityExportModalProvider/EntityExportModalProvider.component'; import { EntityHeader } from '../../../components/Entity/EntityHeader/EntityHeader.component'; import EntityDeleteModal from '../../../components/Modals/EntityDeleteModal/EntityDeleteModal'; @@ -67,7 +57,6 @@ import { import { getEntityDeleteMessage } from '../../../utils/CommonUtils'; import { getEntityVoteStatus } from '../../../utils/EntityUtils'; import Fqn from '../../../utils/Fqn'; -import { StatusClass } from '../../../utils/GlossaryUtils'; import { getGlossaryPath, getGlossaryPathWithAction, @@ -79,6 +68,7 @@ import { TitleBreadcrumbProps } from '../../common/TitleBreadcrumb/TitleBreadcru import Voting from '../../Entity/Voting/Voting.component'; import ChangeParentHierarchy from '../../Modals/ChangeParentHierarchy/ChangeParentHierarchy.component'; import StyleModal from '../../Modals/StyleModal/StyleModal.component'; +import { GlossaryStatusBadge } from '../GlossaryStatusBadge/GlossaryStatusBadge.component'; import { GlossaryHeaderProps } from './GlossaryHeader.interface'; const GlossaryHeader = ({ @@ -439,15 +429,7 @@ const GlossaryHeader = ({ const entityStatus = (selectedData as GlossaryTerm).status ?? Status.Approved; - return ( - - - - - ); + return ; } return null; diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Glossary/GlossaryStatusBadge/GlossaryStatusBadge.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Glossary/GlossaryStatusBadge/GlossaryStatusBadge.component.tsx new file mode 100644 index 000000000000..f6fadbba4eb7 --- /dev/null +++ b/openmetadata-ui/src/main/resources/ui/src/components/Glossary/GlossaryStatusBadge/GlossaryStatusBadge.component.tsx @@ -0,0 +1,26 @@ +/* + * Copyright 2024 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 { Divider, Space } from 'antd'; +import React from 'react'; +import { Status } from '../../../generated/entity/data/glossaryTerm'; +import { StatusClass } from '../../../utils/GlossaryUtils'; +import StatusBadge from '../../common/StatusBadge/StatusBadge.component'; + +export const GlossaryStatusBadge = ({ status }: { status: Status }) => { + return ( + + + + + ); +}; diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Glossary/GlossaryStatusBadge/GlossaryStatusBadge.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Glossary/GlossaryStatusBadge/GlossaryStatusBadge.test.tsx new file mode 100644 index 000000000000..85aef12fec95 --- /dev/null +++ b/openmetadata-ui/src/main/resources/ui/src/components/Glossary/GlossaryStatusBadge/GlossaryStatusBadge.test.tsx @@ -0,0 +1,46 @@ +/* + * Copyright 2024 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 from 'react'; +import { Status } from '../../../generated/entity/data/glossaryTerm'; +import { GlossaryStatusBadge } from './GlossaryStatusBadge.component'; + +describe('GlossaryStatusBadge', () => { + it('renders the correct status', () => { + render(); + const statusElement = screen.getByText('Approved'); + + expect(statusElement).toHaveClass('success'); + }); + + it('renders the correct class based on draft status', () => { + render(); + const statusElement = screen.getByText('Draft'); + + expect(statusElement).toHaveClass('warning'); + }); + + it('renders the correct class based on rejected status', () => { + render(); + const statusElement = screen.getByText('Rejected'); + + expect(statusElement).toHaveClass('failure'); + }); + + it('renders the correct class based on Deprecated status', () => { + render(); + const statusElement = screen.getByText('Deprecated'); + + expect(statusElement).toHaveClass('warning'); + }); +}); diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Glossary/GlossaryTerms/tabs/RelatedTerms.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Glossary/GlossaryTerms/tabs/RelatedTerms.tsx index e7e3bf99eb01..91991d22f997 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Glossary/GlossaryTerms/tabs/RelatedTerms.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Glossary/GlossaryTerms/tabs/RelatedTerms.tsx @@ -24,21 +24,16 @@ import TagSelectForm from '../../../../components/Tag/TagsSelectForm/TagsSelectF import { DE_ACTIVE_COLOR, NO_DATA_PLACEHOLDER, - PAGE_SIZE, } from '../../../../constants/constants'; import { EntityField } from '../../../../constants/Feeds.constants'; import { NO_PERMISSION_FOR_ACTION } from '../../../../constants/HelperTextUtil'; import { OperationPermission } from '../../../../context/PermissionProvider/PermissionProvider.interface'; import { EntityType } from '../../../../enums/entity.enum'; -import { SearchIndex } from '../../../../enums/search.enum'; import { GlossaryTerm } from '../../../../generated/entity/data/glossaryTerm'; import { ChangeDescription, EntityReference, } from '../../../../generated/entity/type'; -import { Paging } from '../../../../generated/type/paging'; -import { searchData } from '../../../../rest/miscAPI'; -import { formatSearchGlossaryTermResponse } from '../../../../utils/APIUtils'; import { getEntityName, getEntityReferenceFromEntity, @@ -49,7 +44,6 @@ import { getDiffByFieldName, } from '../../../../utils/EntityVersionUtils'; import { VersionStatus } from '../../../../utils/EntityVersionUtils.interface'; -import { getEntityReferenceFromGlossary } from '../../../../utils/GlossaryUtils'; import { getGlossaryPath } from '../../../../utils/RouterUtils'; import TagButton from '../../../common/TagButton/TagButton.component'; @@ -101,46 +95,6 @@ const RelatedTerms = ({ setIsIconVisible(true); }; - const fetchGlossaryTerms = async ( - searchText = '', - page: number - ): Promise<{ - data: { - label: string; - value: string; - }[]; - paging: Paging; - }> => { - const res = await searchData( - searchText, - page, - PAGE_SIZE, - '', - '', - '', - SearchIndex.GLOSSARY_TERM - ); - - const termResult = formatSearchGlossaryTermResponse( - res.data.hits.hits - ).filter( - (item) => item.fullyQualifiedName !== glossaryTerm.fullyQualifiedName - ); - - const results = termResult.map(getEntityReferenceFromGlossary); - - return { - data: results.map((item) => ({ - data: item, - label: item.fullyQualifiedName ?? '', - value: item.fullyQualifiedName ?? '', - })), - paging: { - total: res.data.hits.total.value, - }, - }; - }; - const formatOptions = (data: EntityReference[]) => { return data.map((value) => ({ ...value, @@ -302,7 +256,6 @@ const RelatedTerms = ({ defaultValue={selectedOption.map( (item) => item.fullyQualifiedName ?? '' )} - fetchApi={fetchGlossaryTerms} placeholder={t('label.add-entity', { entity: t('label.related-term-plural'), })} diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsSelectForm/TagsSelectForm.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsSelectForm/TagsSelectForm.component.tsx index 6f3ae81e5509..9dcf637d4e9c 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsSelectForm/TagsSelectForm.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsSelectForm/TagsSelectForm.component.tsx @@ -48,7 +48,7 @@ const TagSelectForm = ({ name="tagsForm" onFinish={handleSave}> - {tagType === TagSource.Classification ? ( + {tagType === TagSource.Classification && fetchApi ? ( Promise; onCancel: () => void; tagType?: TagSource; - fetchApi: ( + fetchApi?: ( search: string, page: number ) => Promise<{ diff --git a/openmetadata-ui/src/main/resources/ui/src/constants/AdvancedSearch.constants.ts b/openmetadata-ui/src/main/resources/ui/src/constants/AdvancedSearch.constants.ts index 809cdd0b7fbd..0d4fb4291db1 100644 --- a/openmetadata-ui/src/main/resources/ui/src/constants/AdvancedSearch.constants.ts +++ b/openmetadata-ui/src/main/resources/ui/src/constants/AdvancedSearch.constants.ts @@ -143,6 +143,10 @@ export const GLOSSARY_DROPDOWN_ITEMS = [ label: t('label.glossary-plural'), key: EntityFields.GLOSSARY, }, + { + label: t('label.status'), + key: EntityFields.GLOSSARY_TERM_STATUS, + }, ]; export const TAG_DROPDOWN_ITEMS = [ diff --git a/openmetadata-ui/src/main/resources/ui/src/enums/AdvancedSearch.enum.ts b/openmetadata-ui/src/main/resources/ui/src/enums/AdvancedSearch.enum.ts index 411214eabd35..bf786b238cd4 100644 --- a/openmetadata-ui/src/main/resources/ui/src/enums/AdvancedSearch.enum.ts +++ b/openmetadata-ui/src/main/resources/ui/src/enums/AdvancedSearch.enum.ts @@ -58,4 +58,5 @@ export enum EntityFields { COLUMN = 'columns.name.keyword', CHART = 'charts.displayName.keyword', TASK = 'tasks.displayName.keyword', + GLOSSARY_TERM_STATUS = 'status', } diff --git a/openmetadata-ui/src/main/resources/ui/src/rest/glossaryAPI.ts b/openmetadata-ui/src/main/resources/ui/src/rest/glossaryAPI.ts index 9d92f87c9412..73013ce72a9a 100644 --- a/openmetadata-ui/src/main/resources/ui/src/rest/glossaryAPI.ts +++ b/openmetadata-ui/src/main/resources/ui/src/rest/glossaryAPI.ts @@ -333,7 +333,7 @@ export const getFirstLevelGlossaryTerms = async (parentFQN: string) => { >(apiUrl, { params: { directChildrenOf: parentFQN, - fields: 'childrenCount', + fields: 'childrenCount,owner', limit: 100000, }, }); diff --git a/openmetadata-ui/src/main/resources/ui/src/rest/miscAPI.ts b/openmetadata-ui/src/main/resources/ui/src/rest/miscAPI.ts index 6b1b24994a62..433e3a2a68da 100644 --- a/openmetadata-ui/src/main/resources/ui/src/rest/miscAPI.ts +++ b/openmetadata-ui/src/main/resources/ui/src/rest/miscAPI.ts @@ -220,19 +220,6 @@ export const getSearchedTeams = ( ); }; -export const getSearchedUsersAndTeams = async ( - queryString: string, - from: number, - size = 10 -) => { - const response = await searchData(queryString, from, size, '', '', '', [ - SearchIndex.USER, - SearchIndex.TEAM, - ]); - - return response.data; -}; - export const deleteEntity = async ( entityType: string, entityId: string, diff --git a/openmetadata-ui/src/main/resources/ui/src/utils/GlossaryUtils.tsx b/openmetadata-ui/src/main/resources/ui/src/utils/GlossaryUtils.tsx index 39b837c8e1e4..ba0e2a0d5809 100644 --- a/openmetadata-ui/src/main/resources/ui/src/utils/GlossaryUtils.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/utils/GlossaryUtils.tsx @@ -22,26 +22,10 @@ import { FQN_SEPARATOR_CHAR } from '../constants/char.constants'; import { EntityType } from '../enums/entity.enum'; import { Glossary } from '../generated/entity/data/glossary'; import { GlossaryTerm, Status } from '../generated/entity/data/glossaryTerm'; -import { EntityReference } from '../generated/type/entityReference'; import { getEntityName } from './EntityUtils'; import Fqn from './Fqn'; import { getGlossaryPath } from './RouterUtils'; -export const getEntityReferenceFromGlossary = ( - glossary: Glossary -): EntityReference => { - return { - deleted: glossary.deleted, - href: glossary.href, - fullyQualifiedName: glossary.fullyQualifiedName ?? '', - id: glossary.id, - type: 'glossaryTerm', - description: glossary.description, - displayName: glossary.displayName, - name: glossary.name, - }; -}; - export const buildTree = (data: GlossaryTerm[]): GlossaryTerm[] => { const nodes: Record = {}; @@ -111,6 +95,22 @@ export const getQueryFilterToExcludeTerm = (fqn: string) => ({ }, }); +export const getQueryFilterToIncludeApprovedTerm = () => { + return { + query: { + bool: { + must: [ + { + term: { + status: Status.Approved, + }, + }, + ], + }, + }, + }; +}; + export const StatusClass = { [Status.Approved]: StatusType.Success, [Status.Draft]: StatusType.Warning, diff --git a/openmetadata-ui/src/main/resources/ui/src/utils/TagsUtils.tsx b/openmetadata-ui/src/main/resources/ui/src/utils/TagsUtils.tsx index e67aec0e2c40..f397b6cd1dec 100644 --- a/openmetadata-ui/src/main/resources/ui/src/utils/TagsUtils.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/utils/TagsUtils.tsx @@ -39,6 +39,7 @@ import { getClassificationByName, getTags, } from '../rest/tagAPI'; +import { getQueryFilterToIncludeApprovedTerm } from './GlossaryUtils'; import { getTagsWithoutTier } from './TableUtils'; export const getClassifications = async ( @@ -269,7 +270,7 @@ export const fetchGlossaryList = async ( query: searchQueryParam ? `*${searchQueryParam}*` : '*', pageNumber: page, pageSize: 10, - queryFilter: {}, + queryFilter: getQueryFilterToIncludeApprovedTerm(), searchIndex: SearchIndex.GLOSSARY_TERM, });