diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Users.spec.js b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Users.spec.js index ffe519b57e15..35775888365a 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Users.spec.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Users.spec.js @@ -66,7 +66,7 @@ describe('Users flow should work properly', () => { it('Search for bot user', () => { interceptURL( 'GET', - `/api/v1/search/query?q=*${searchBotText}***isBot:false&from=0&size=15&index=user_search_index`, + `/api/v1/search/query?q=*${searchBotText}***isBot:false&from=0&size=25&index=user_search_index`, 'searchUser' ); cy.get('[data-testid="searchbar"]') diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DataModels/DataModelsTable.tsx b/openmetadata-ui/src/main/resources/ui/src/components/DataModels/DataModelsTable.tsx index f95aa2109e6e..59e5ee635b15 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/DataModels/DataModelsTable.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/DataModels/DataModelsTable.tsx @@ -11,7 +11,7 @@ * limitations under the License. */ -import { Col } from 'antd'; +import { Col, Row, Switch, Typography } from 'antd'; import { ColumnsType } from 'antd/lib/table'; import { AxiosError } from 'axios'; import { isUndefined } from 'lodash'; @@ -23,6 +23,8 @@ import RichTextEditorPreviewer from '../../components/common/RichTextEditor/Rich import Table from '../../components/common/Table/Table'; import { getDataModelDetailsPath, + INITIAL_PAGING_VALUE, + PAGE_SIZE_BASE, pagingObject, } from '../../constants/constants'; import { Include } from '../../generated/type/include'; @@ -35,10 +37,11 @@ import { showErrorToast } from '../../utils/ToastUtils'; import NextPrevious from '../common/NextPrevious/NextPrevious'; import { NextPreviousProps } from '../common/NextPrevious/NextPrevious.interface'; -const DataModelTable = ({ showDeleted }: { showDeleted?: boolean }) => { +const DataModelTable = () => { const { t } = useTranslation(); const { fqn } = useParams<{ fqn: string }>(); const [dataModels, setDataModels] = useState>(); + const [showDeleted, setShowDeleted] = useState(false); const { currentPage, pageSize, @@ -94,7 +97,6 @@ const DataModelTable = ({ showDeleted }: { showDeleted?: boolean }) => { setIsLoading(true); const { data, paging: resPaging } = await getDataModels({ service: fqn, - fields: 'owner,tags,followers', limit: pageSize, include: showDeleted ? Include.Deleted : Include.NonDeleted, ...pagingData, @@ -122,12 +124,32 @@ const DataModelTable = ({ showDeleted }: { showDeleted?: boolean }) => { handlePageChange(currentPage); }; + const handleShowDeletedChange = (checked: boolean) => { + setShowDeleted(checked); + handlePageChange(INITIAL_PAGING_VALUE); + handlePageSizeChange(PAGE_SIZE_BASE); + }; + useEffect(() => { fetchDashboardsDataModel(); }, [pageSize, showDeleted]); return ( - <> + + + + + + + {t('label.deleted')} + {' '} + + + { /> )} - + ); }; diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/TestCases/TestCases.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/TestCases/TestCases.component.tsx index c694bd1cebdb..88083b6f00c4 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/TestCases/TestCases.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/TestCases/TestCases.component.tsx @@ -15,7 +15,6 @@ import { AxiosError } from 'axios'; import QueryString from 'qs'; import React, { ReactNode, useEffect, useMemo, useState } from 'react'; import { useHistory, useLocation, useParams } from 'react-router-dom'; -import { PAGE_SIZE } from '../../../constants/constants'; import { ERROR_PLACEHOLDER_TYPE } from '../../../enums/common.enum'; import { SearchIndex } from '../../../enums/search.enum'; import { TestCase } from '../../../generated/tests/testCase'; @@ -67,6 +66,7 @@ export const TestCases = ({ summaryPanel }: { summaryPanel: ReactNode }) => { handlePageSizeChange, paging, handlePagingChange, + showPagination, } = usePaging(); const handleSearchParam = ( @@ -127,7 +127,7 @@ export const TestCases = ({ summaryPanel }: { summaryPanel: ReactNode }) => { try { const response = await searchQuery({ pageNumber: page, - pageSize: PAGE_SIZE, + pageSize: pageSize, searchIndex: SearchIndex.TEST_CASE, query: searchValue, fetchSource: false, @@ -154,6 +154,7 @@ export const TestCases = ({ summaryPanel }: { summaryPanel: ReactNode }) => { }, [] as TestCase[]); setTestCase(testSuites); + handlePageChange(page); handlePagingChange({ total: response.hits.total.value ?? 0 }); } catch (error) { setTestCase([]); @@ -232,6 +233,7 @@ export const TestCases = ({ summaryPanel }: { summaryPanel: ReactNode }) => { afterDeleteAction={fetchTestCases} isLoading={isLoading} pagingData={pagingData} + showPagination={showPagination} testCases={testCase} onTestCaseResultUpdate={handleStatusSubmit} onTestUpdate={handleTestCaseUpdate} diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/TestCases/TestCases.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/TestCases/TestCases.test.tsx index 080e70574b0e..1bb457403861 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/TestCases/TestCases.test.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/TestCases/TestCases.test.tsx @@ -139,7 +139,7 @@ describe('TestCases component', () => { expect(mockSearchQuery).toHaveBeenCalledWith({ fetchSource: false, pageNumber: 1, - pageSize: 10, + pageSize: 15, query: 'sale', searchIndex: 'test_case_search_index', }); diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Database/DatabaseSchema/DatabaseSchemaTable/DatabaseSchemaTable.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Database/DatabaseSchema/DatabaseSchemaTable/DatabaseSchemaTable.tsx new file mode 100644 index 000000000000..ab3591e57dda --- /dev/null +++ b/openmetadata-ui/src/main/resources/ui/src/components/Database/DatabaseSchema/DatabaseSchemaTable/DatabaseSchemaTable.tsx @@ -0,0 +1,207 @@ +/* + * 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 { Col, Row, Switch, Typography } from 'antd'; +import { AxiosError } from 'axios'; +import { t } from 'i18next'; +import { isEmpty } from 'lodash'; +import QueryString from 'qs'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import { useHistory, useLocation, useParams } from 'react-router-dom'; +import { + INITIAL_PAGING_VALUE, + PAGE_SIZE, +} from '../../../../constants/constants'; +import { SearchIndex } from '../../../../enums/search.enum'; +import { DatabaseSchema } from '../../../../generated/entity/data/databaseSchema'; +import { Include } from '../../../../generated/type/include'; +import { Paging } from '../../../../generated/type/paging'; +import { usePaging } from '../../../../hooks/paging/usePaging'; +import { getDatabaseSchemas } from '../../../../rest/databaseAPI'; +import { searchQuery } from '../../../../rest/searchAPI'; +import { schemaTableColumns } from '../../../../utils/DatabaseDetails.utils'; +import { showErrorToast } from '../../../../utils/ToastUtils'; +import ErrorPlaceHolder from '../../../common/ErrorWithPlaceholder/ErrorPlaceHolder'; +import NextPrevious from '../../../common/NextPrevious/NextPrevious'; +import { PagingHandlerParams } from '../../../common/NextPrevious/NextPrevious.interface'; +import Searchbar from '../../../common/SearchBarComponent/SearchBar.component'; +import Table from '../../../common/Table/Table'; + +export const DatabaseSchemaTable = () => { + const { fqn } = useParams<{ fqn: string }>(); + const history = useHistory(); + const location = useLocation(); + const [schemas, setSchemas] = useState([]); + const [isLoading, setIsLoading] = useState(true); + const [showDeletedSchemas, setShowDeletedSchemas] = useState(false); + const searchValue = useMemo(() => { + const param = location.search; + const searchData = QueryString.parse( + param.startsWith('?') ? param.substring(1) : param + ); + + return searchData.schema as string | undefined; + }, [location.search]); + const { + currentPage, + handlePageChange, + pageSize, + handlePageSizeChange, + paging, + handlePagingChange, + showPagination, + } = usePaging(); + + const fetchDatabaseSchema = useCallback( + async (params?: Partial) => { + if (isEmpty(fqn)) { + return; + } + + try { + setIsLoading(true); + const { data, paging } = await getDatabaseSchemas({ + databaseName: fqn, + limit: pageSize, + after: params?.after, + before: params?.before, + include: showDeletedSchemas ? Include.Deleted : Include.NonDeleted, + fields: ['owner', 'usageSummary'], + }); + + setSchemas(data); + handlePagingChange(paging); + } catch (error) { + showErrorToast(error); + } finally { + setIsLoading(false); + } + }, + [pageSize, fqn, showDeletedSchemas] + ); + + const searchSchema = async ( + searchValue: string, + pageNumber = INITIAL_PAGING_VALUE + ) => { + setIsLoading(true); + try { + const response = await searchQuery({ + query: `(name.keyword:*${searchValue}*) OR (description.keyword:*${searchValue}*)`, + pageNumber, + pageSize: PAGE_SIZE, + queryFilter: { + query: { + bool: { + must: [{ term: { 'database.fullyQualifiedName': fqn } }], + }, + }, + }, + searchIndex: SearchIndex.DATABASE_SCHEMA, + includeDeleted: showDeletedSchemas, + trackTotalHits: true, + }); + const data = response.hits.hits.map((schema) => schema._source); + const total = response.hits.total.value; + setSchemas(data); + handlePagingChange({ total }); + } catch (error) { + showErrorToast(error as AxiosError); + } finally { + setIsLoading(false); + } + }; + + const handleShowDeletedSchemas = useCallback((value: boolean) => { + setShowDeletedSchemas(value); + handlePageChange(INITIAL_PAGING_VALUE); + }, []); + + const handleSchemaPageChange = useCallback( + ({ currentPage, cursorType }: PagingHandlerParams) => { + if (cursorType) { + fetchDatabaseSchema({ [cursorType]: paging[cursorType] }); + } + handlePageChange(currentPage); + }, + [paging, fetchDatabaseSchema] + ); + + const onSchemaSearch = (value: string) => { + history.push({ + search: QueryString.stringify({ + schema: isEmpty(value) ? undefined : value, + }), + }); + if (value) { + searchSchema(value); + } else { + fetchDatabaseSchema(); + } + }; + + useEffect(() => { + fetchDatabaseSchema(); + }, [fqn, pageSize, showDeletedSchemas]); + + return ( + + + + + + + + {t('label.deleted')} + {' '} + + +
, + }} + pagination={false} + rowKey="id" + size="small" + /> + + + {showPagination && ( + + )} + + + ); +}; diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Domain/AddDataProductModal/AddDataProductModal.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Domain/AddDataProductModal/AddDataProductModal.component.tsx index bc42ba072cb5..7e75978eb169 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Domain/AddDataProductModal/AddDataProductModal.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Domain/AddDataProductModal/AddDataProductModal.component.tsx @@ -36,6 +36,7 @@ const AddDataProductModal = ({ return ( = forwardRef< if (source.style?.iconURL) { return ( { {} as EntityHistory ); const [selectedData, setSelectedData] = useState(); + const [isVersionLoading, setIsVersionLoading] = useState(true); const fetchVersionsInfo = async () => { try { @@ -63,6 +65,7 @@ const GlossaryVersion = ({ isGlossary = false }: GlossaryVersionProps) => { }; const fetchActiveVersion = async () => { + setIsVersionLoading(true); try { const res = isGlossary ? await getGlossaryVersion(glossaryName, version) @@ -71,6 +74,8 @@ const GlossaryVersion = ({ isGlossary = false }: GlossaryVersionProps) => { setSelectedData(res); } catch (error) { showErrorToast(error as AxiosError); + } finally { + setIsVersionLoading(false); } }; @@ -88,6 +93,9 @@ const GlossaryVersion = ({ isGlossary = false }: GlossaryVersionProps) => { useEffect(() => { fetchVersionsInfo(); + }, [glossaryName]); + + useEffect(() => { fetchActiveVersion(); }, [glossaryName, version]); @@ -95,17 +103,21 @@ const GlossaryVersion = ({ isGlossary = false }: GlossaryVersionProps) => {
{/* TODO: Need to implement version component for Glossary */} - Promise.resolve()} - onGlossaryDelete={noop} - onGlossaryTermDelete={noop} - onGlossaryTermUpdate={() => Promise.resolve()} - /> + {isVersionLoading ? ( + + ) : ( + Promise.resolve()} + onGlossaryDelete={noop} + onGlossaryTermDelete={noop} + onGlossaryTermUpdate={() => Promise.resolve()} + /> + )}
= ({ const res = await patchQueries(selectedQuery.id ?? '', jsonPatch); setSelectedQuery((pre) => (pre ? { ...pre, ...res } : res)); setTableQueries((pre) => { - return { - ...pre, - data: pre.map((query) => - query.id === updatedQuery.id ? { ...query, ...res } : query - ), - }; + return pre.map((query) => + query.id === updatedQuery.id ? { ...query, ...res } : query + ); }); } catch (error) { showErrorToast(error as AxiosError); @@ -150,12 +147,9 @@ const TableQueries: FC = ({ }); setSelectedQuery(response); setTableQueries((pre) => { - return { - ...pre, - data: pre.map((query) => - query.id === response.id ? response : query - ), - }; + return pre.map((query) => + query.id === response.id ? response : query + ); }); } catch (error) { showErrorToast(error as AxiosError); diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Team/TeamDetails/TeamDetailsV1.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Team/TeamDetails/TeamDetailsV1.tsx index ef851827ba03..617e9bac3986 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Team/TeamDetails/TeamDetailsV1.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Team/TeamDetails/TeamDetailsV1.tsx @@ -1153,8 +1153,8 @@ const TeamDetailsV1 = ({
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Team/TeamDetails/UserTab/UserTab.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Team/TeamDetails/UserTab/UserTab.component.tsx index 930686101572..e549f321e375 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Team/TeamDetails/UserTab/UserTab.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Team/TeamDetails/UserTab/UserTab.component.tsx @@ -30,7 +30,6 @@ import { UserSelectableList } from '../../../../components/common/UserSelectable import { useEntityExportModalProvider } from '../../../../components/Entity/EntityExportModalProvider/EntityExportModalProvider.component'; import { INITIAL_PAGING_VALUE, - PAGE_SIZE_BASE, PAGE_SIZE_MEDIUM, } from '../../../../constants/constants'; import { @@ -95,7 +94,7 @@ export const UserTab = ({ setIsLoading(true); getUsers({ fields: 'teams,roles', - limit: PAGE_SIZE_BASE, + limit: pageSize, team: getDecodedFqn(team), ...paging, }) @@ -119,7 +118,7 @@ export const UserTab = ({ searchData( text, currentPage, - PAGE_SIZE_BASE, + pageSize, `(teams.id:${currentTeam?.id})`, '', '', @@ -171,7 +170,7 @@ export const UserTab = ({ useEffect(() => { getCurrentTeamUsers(getEncodedFqn(currentTeam.name)); - }, [currentTeam]); + }, [currentTeam, pageSize]); const isTeamDeleted = useMemo( () => currentTeam.deleted ?? false, @@ -389,6 +388,8 @@ export const UserTab = ({ rowKey="name" size="small" /> + + {showPagination && ( ({ getUsagePercentile: jest.fn().mockReturnValue('Medium - 45th pctile'), getTierTags: jest.fn().mockImplementation(() => ({})), getTagsWithoutTier: jest.fn().mockImplementation(() => []), + getTableExpandableConfig: jest.fn().mockReturnValue({}), })); jest.mock('../../components/common/NextPrevious/NextPrevious', () => { @@ -266,16 +267,19 @@ jest.mock( }) ); -jest.mock('../../utils/DatabaseDetails.utils', () => ({ - getDatabaseSchemaTable: jest - .fn() - .mockReturnValue(<>testDatabaseSchemaTable), -})); - jest.mock('../../components/AppRouter/withActivityFeed', () => ({ withActivityFeed: jest.fn().mockImplementation((Some) => Some), })); +jest.mock( + '../../components/Database/DatabaseSchema/DatabaseSchemaTable/DatabaseSchemaTable', + () => ({ + DatabaseSchemaTable: jest + .fn() + .mockImplementation(() => <>testDatabaseSchemaTable), + }) +); + describe('Test DatabaseDetails page', () => { it('Component should render', async () => { const { container } = render(, { 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 b5af80e170fc..f0d9b0768585 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 @@ -11,13 +11,12 @@ * limitations under the License. */ -import { Col, Row, Space, Switch, Tabs, Typography } from 'antd'; +import { Col, Row, Space, Tabs } from 'antd'; import { AxiosError } from 'axios'; import { compare, Operation } from 'fast-json-patch'; -import { isEmpty, isString, isUndefined, toString } from 'lodash'; +import { isEmpty, isUndefined, toString } from 'lodash'; import { observer } from 'mobx-react'; import { EntityTags } from 'Models'; -import QueryString from 'qs'; import React, { FunctionComponent, useCallback, @@ -36,9 +35,8 @@ import { withActivityFeed } from '../../components/AppRouter/withActivityFeed'; import { CustomPropertyTable } from '../../components/common/CustomPropertyTable/CustomPropertyTable'; import DescriptionV1 from '../../components/common/EntityDescription/DescriptionV1'; import ErrorPlaceHolder from '../../components/common/ErrorWithPlaceholder/ErrorPlaceHolder'; -import { PagingHandlerParams } from '../../components/common/NextPrevious/NextPrevious.interface'; -import Searchbar from '../../components/common/SearchBarComponent/SearchBar.component'; import { DataAssetsHeader } from '../../components/DataAssets/DataAssetsHeader/DataAssetsHeader.component'; +import { DatabaseSchemaTable } from '../../components/Database/DatabaseSchema/DatabaseSchemaTable/DatabaseSchemaTable'; import DataProductsContainer from '../../components/DataProductsContainer/DataProductsContainer.component'; import Loader from '../../components/Loader/Loader'; import { EntityName } from '../../components/Modals/EntityNameModal/EntityNameModal.interface'; @@ -58,19 +56,13 @@ import { getDatabaseDetailsPath, getExplorePath, getVersionPathWithTab, - INITIAL_PAGING_VALUE, - PAGE_SIZE, - pagingObject, } from '../../constants/constants'; import { ERROR_PLACEHOLDER_TYPE } from '../../enums/common.enum'; import { EntityTabs, EntityType } from '../../enums/entity.enum'; -import { SearchIndex } from '../../enums/search.enum'; import { CreateThread } from '../../generated/api/feed/createThread'; import { Tag } from '../../generated/entity/classification/tag'; import { Database } from '../../generated/entity/data/database'; -import { DatabaseSchema } from '../../generated/entity/data/databaseSchema'; import { Include } from '../../generated/type/include'; -import { Paging } from '../../generated/type/paging'; import { TagSource } from '../../generated/type/tagLabel'; import { EntityFieldThreadCount } from '../../interface/feed.interface'; import { @@ -81,12 +73,10 @@ import { updateDatabaseVotes, } from '../../rest/databaseAPI'; import { getFeedCount, postThread } from '../../rest/feedsAPI'; -import { searchQuery } from '../../rest/searchAPI'; import { getEntityMissingError, sortTagsCaseInsensitive, } from '../../utils/CommonUtils'; -import { getDatabaseSchemaTable } from '../../utils/DatabaseDetails.utils'; import { getEntityFeedLink, getEntityName } from '../../utils/EntityUtils'; import { DEFAULT_ENTITY_PERMISSION } from '../../utils/PermissionsUtils'; import { getDecodedFqn } from '../../utils/StringsUtils'; @@ -98,23 +88,13 @@ const DatabaseDetails: FunctionComponent = () => { const { t } = useTranslation(); const { postFeed, deleteFeed, updateFeed } = useActivityFeedProvider(); const { getEntityPermissionByFqn } = usePermissionProvider(); - const searchValue = useMemo(() => { - const param = location.search; - const searchData = QueryString.parse( - param.startsWith('?') ? param.substring(1) : param - ); - - return searchData.schema as string | undefined; - }, [location.search]); const { fqn: databaseFQN, tab: activeTab = EntityTabs.SCHEMA } = useParams<{ fqn: string; tab: EntityTabs }>(); const [isLoading, setIsLoading] = useState(true); - const [showDeletedSchemas, setShowDeletedSchemas] = useState(false); + const [database, setDatabase] = useState({} as Database); const [serviceType, setServiceType] = useState(); - const [schemaData, setSchemaData] = useState([]); - const [schemaDataLoading, setSchemaDataLoading] = useState(true); const [databaseName, setDatabaseName] = useState( databaseFQN.split(FQN_SEPARATOR_CHAR).slice(-1).pop() ?? '' @@ -124,8 +104,7 @@ const DatabaseDetails: FunctionComponent = () => { const [isEdit, setIsEdit] = useState(false); const [description, setDescription] = useState(''); const [databaseId, setDatabaseId] = useState(''); - const [databaseSchemaPaging, setSchemaPaging] = - useState(pagingObject); + const [databaseSchemaInstanceCount, setSchemaInstanceCount] = useState(0); @@ -135,7 +114,6 @@ const DatabaseDetails: FunctionComponent = () => { >([]); const [threadLink, setThreadLink] = useState(''); - const [currentPage, setCurrentPage] = useState(INITIAL_PAGING_VALUE); const [updateProfilerSetting, setUpdateProfilerSetting] = useState(false); @@ -171,70 +149,6 @@ const DatabaseDetails: FunctionComponent = () => { } }; - const fetchDatabaseSchemas = async (pagingObj?: string) => { - try { - const response = await getDatabaseSchemas( - databaseFQN, - pagingObj, - ['owner', 'usageSummary'], - showDeletedSchemas ? Include.Deleted : Include.NonDeleted - ); - if (response.data) { - setSchemaData(response.data); - setSchemaPaging(response.paging); - setSchemaInstanceCount(response.paging.total); - } else { - setSchemaData([]); - setSchemaPaging(pagingObject); - - throw t('server.unexpected-response'); - } - } finally { - setSchemaDataLoading(false); - } - }; - - const searchSchema = async ( - searchValue: string, - pageNumber = INITIAL_PAGING_VALUE - ) => { - setSchemaDataLoading(true); - try { - const response = await searchQuery({ - query: `(name.keyword:*${searchValue}*) OR (description.keyword:*${searchValue}*)`, - pageNumber, - pageSize: PAGE_SIZE, - queryFilter: { - query: { - bool: { - must: [{ term: { 'database.fullyQualifiedName': databaseFQN } }], - }, - }, - }, - searchIndex: SearchIndex.DATABASE_SCHEMA, - includeDeleted: showDeletedSchemas, - trackTotalHits: true, - }); - const data = response.hits.hits.map((schema) => schema._source); - const total = response.hits.total.value; - setSchemaData(data); - setSchemaPaging({ total }); - } catch (error) { - showErrorToast(error as AxiosError); - } finally { - setSchemaDataLoading(false); - } - }; - - const fetchDatabaseSchemasAndDBTModels = () => { - setIsLoading(true); - Promise.allSettled([ - searchValue ? searchSchema(searchValue) : fetchDatabaseSchemas(), - ]).finally(() => { - setIsLoading(false); - }); - }; - const onThreadLinkSelect = (link: string) => { setThreadLink(link); }; @@ -258,6 +172,26 @@ const DatabaseDetails: FunctionComponent = () => { }); }; + const fetchDatabaseSchemaCount = useCallback(async () => { + if (isEmpty(databaseFQN)) { + return; + } + + try { + setIsLoading(true); + const { paging } = await getDatabaseSchemas({ + databaseName: databaseFQN, + limit: 0, + }); + + setSchemaInstanceCount(paging.total); + } catch (error) { + showErrorToast(error); + } finally { + setIsLoading(false); + } + }, [databaseFQN]); + const getDetailsByFQN = () => { setIsDatabaseDetailsLoading(true); getDatabaseDetailsByFQN( @@ -273,8 +207,6 @@ const DatabaseDetails: FunctionComponent = () => { setDatabaseId(id ?? ''); setDatabaseName(name); setServiceType(serviceType); - setShowDeletedSchemas(res.deleted ?? false); - fetchDatabaseSchemasAndDBTModels(); } }) .catch(() => { @@ -336,27 +268,6 @@ const DatabaseDetails: FunctionComponent = () => { } }; - const databaseSchemaPagingHandler = ({ - cursorType, - currentPage, - }: PagingHandlerParams) => { - if (cursorType) { - if (isString(cursorType)) { - const pagingString = `&${cursorType}=${ - databaseSchemaPaging[cursorType as keyof typeof databaseSchemaPaging] - }`; - setSchemaDataLoading(true); - fetchDatabaseSchemas(pagingString).finally(() => { - setSchemaDataLoading(false); - }); - setCurrentPage(currentPage); - } else { - setCurrentPage(cursorType); - searchValue && searchSchema(searchValue, cursorType); - } - } - }; - const settingsUpdateHandler = async ( data: Database, key?: keyof Database @@ -435,6 +346,7 @@ const DatabaseDetails: FunctionComponent = () => { useEffect(() => { if (databasePermission.ViewAll || databasePermission.ViewBasic) { getDetailsByFQN(); + fetchDatabaseSchemaCount(); } }, [databasePermission, databaseFQN]); @@ -505,26 +417,6 @@ const DatabaseDetails: FunctionComponent = () => { } }; - const databaseTable = useMemo( - () => - getDatabaseSchemaTable( - schemaData, - schemaDataLoading, - databaseSchemaPaging, - currentPage, - databaseSchemaPagingHandler, - Boolean(searchSchema) - ), - [ - schemaData, - schemaDataLoading, - databaseSchemaPaging, - currentPage, - databaseSchemaPagingHandler, - searchSchema, - ] - ); - const handleToggleDelete = () => { setDatabase((prev) => { if (!prev) { @@ -555,11 +447,6 @@ const DatabaseDetails: FunctionComponent = () => { } }, [databaseId]); - const handleShowDeletedSchemas = useCallback((value: boolean) => { - setShowDeletedSchemas(value); - setCurrentPage(INITIAL_PAGING_VALUE); - }, []); - const versionHandler = useCallback(() => { currentVersion && history.push( @@ -608,19 +495,6 @@ const DatabaseDetails: FunctionComponent = () => { })); }, []); - const onSchemaSearch = (value: string) => { - history.push({ - search: QueryString.stringify({ - schema: isEmpty(value) ? undefined : value, - }), - }); - if (value) { - searchSchema(value); - } else { - fetchDatabaseSchemas(); - } - }; - const tabs = useMemo( () => [ { @@ -653,31 +527,8 @@ const DatabaseDetails: FunctionComponent = () => { /> - - - - - - - - {t('label.deleted')} - {' '} - - + - {databaseTable} { entityFieldThreadCount, decodedDatabaseFQN, activeTab, - databaseTable, databasePermission, databaseSchemaInstanceCount, feedCount, - showDeletedSchemas, editTagsPermission, editDescriptionPermission, editCustomAttributePermission, viewAllPermission, - handleShowDeletedSchemas, ] ); @@ -790,10 +638,6 @@ const DatabaseDetails: FunctionComponent = () => { } }; - useEffect(() => { - fetchDatabaseSchemas(); - }, [showDeletedSchemas]); - if (isLoading || isDatabaseDetailsLoading) { return ; } diff --git a/openmetadata-ui/src/main/resources/ui/src/pages/DatabaseVersionPage/DatabaseVersionPage.tsx b/openmetadata-ui/src/main/resources/ui/src/pages/DatabaseVersionPage/DatabaseVersionPage.tsx index 3213ab863c61..257f218c2416 100644 --- a/openmetadata-ui/src/main/resources/ui/src/pages/DatabaseVersionPage/DatabaseVersionPage.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/pages/DatabaseVersionPage/DatabaseVersionPage.tsx @@ -20,8 +20,8 @@ import { useHistory, useParams } from 'react-router-dom'; import { CustomPropertyTable } from '../../components/common/CustomPropertyTable/CustomPropertyTable'; import DescriptionV1 from '../../components/common/EntityDescription/DescriptionV1'; import ErrorPlaceHolder from '../../components/common/ErrorWithPlaceholder/ErrorPlaceHolder'; -import { PagingHandlerParams } from '../../components/common/NextPrevious/NextPrevious.interface'; import DataAssetsVersionHeader from '../../components/DataAssets/DataAssetsVersionHeader/DataAssetsVersionHeader'; +import { DatabaseSchemaTable } from '../../components/Database/DatabaseSchema/DatabaseSchemaTable/DatabaseSchemaTable'; import DataProductsContainer from '../../components/DataProductsContainer/DataProductsContainer.component'; import EntityVersionTimeLine from '../../components/Entity/EntityVersionTimeLine/EntityVersionTimeLine'; import Loader from '../../components/Loader/Loader'; @@ -37,24 +37,18 @@ import { DisplayType } from '../../components/Tag/TagsViewer/TagsViewer.interfac import { getDatabaseDetailsPath, getVersionPathWithTab, - INITIAL_PAGING_VALUE, - pagingObject, } from '../../constants/constants'; import { ERROR_PLACEHOLDER_TYPE } from '../../enums/common.enum'; import { EntityTabs, EntityType } from '../../enums/entity.enum'; import { Database } from '../../generated/entity/data/database'; -import { DatabaseSchema } from '../../generated/entity/data/databaseSchema'; import { ChangeDescription } from '../../generated/entity/type'; import { EntityHistory } from '../../generated/type/entityHistory'; -import { Paging } from '../../generated/type/paging'; import { TagSource } from '../../generated/type/tagLabel'; import { getDatabaseDetailsByFQN, - getDatabaseSchemas, getDatabaseVersionData, getDatabaseVersions, } from '../../rest/databaseAPI'; -import { getDatabaseSchemaTable } from '../../utils/DatabaseDetails.utils'; import { getEntityName } from '../../utils/EntityUtils'; import { getBasicEntityInfoFromVersionData, @@ -77,15 +71,13 @@ function DatabaseVersionPage() { version: string; tab: EntityTabs; }>(); - const [paging, setPaging] = useState(pagingObject); - const [currentPage, setCurrentPage] = useState(INITIAL_PAGING_VALUE); - const [schemaData, setSchemaData] = useState([]); + const [servicePermissions, setServicePermissions] = useState(DEFAULT_ENTITY_PERMISSION); const [isLoading, setIsLoading] = useState(true); const [isVersionDataLoading, setIsVersionDataLoading] = useState(true); - const [isSchemaDataLoading, setIsSchemaDataLoading] = useState(true); + const [databaseId, setDatabaseId] = useState(''); const [currentVersionData, setCurrentVersionData] = useState( {} as Database @@ -171,40 +163,6 @@ function DatabaseVersionPage() { [viewVersionPermission, version] ); - const fetchDatabaseSchemas = useCallback( - async (pagingObj?: string) => { - setIsSchemaDataLoading(true); - try { - const response = await getDatabaseSchemas(databaseFQN, pagingObj, [ - 'owner', - 'usageSummary', - ]); - setSchemaData(response.data); - setPaging(response.paging); - } catch { - setSchemaData([]); - setPaging(pagingObject); - } finally { - setIsSchemaDataLoading(false); - } - }, - [databaseFQN] - ); - - const databaseSchemaPagingHandler = useCallback( - ({ cursorType, currentPage }: PagingHandlerParams) => { - if (cursorType) { - const pagingString = `&${cursorType}=${paging[cursorType]}`; - setIsSchemaDataLoading(true); - fetchDatabaseSchemas(pagingString).finally(() => { - setIsSchemaDataLoading(false); - }); - setCurrentPage(currentPage); - } - }, - [paging, fetchDatabaseSchemas] - ); - const { versionHandler, backHandler } = useMemo( () => ({ versionHandler: (newVersion = version) => { @@ -240,24 +198,6 @@ function DatabaseVersionPage() { [currentVersionData, changeDescription] ); - const databaseTable = useMemo( - () => - getDatabaseSchemaTable( - schemaData, - isSchemaDataLoading, - paging, - currentPage, - databaseSchemaPagingHandler - ), - [ - schemaData, - isSchemaDataLoading, - paging, - currentPage, - databaseSchemaPagingHandler, - ] - ); - const tabs = useMemo( () => [ { @@ -276,7 +216,9 @@ function DatabaseVersionPage() { showActions={false} /> - {databaseTable} + + + { @@ -417,12 +359,6 @@ function DatabaseVersionPage() { } }, [version, databaseId]); - useEffect(() => { - if (!isEmpty(currentVersionData)) { - fetchDatabaseSchemas(); - } - }, [currentVersionData]); - return ( { - {isLoading && - [1, 2, 3].map((key) => ( - - - - - - ))} + {isLoading + ? [1, 2, 3].map((key) => ( + + + + + + )) + : persona?.map((persona) => ( + + + + ))} {isEmpty(persona) && !isLoading && errorPlaceHolder} - {persona?.map((persona) => ( - - - - ))} - {showPagination && ( { ); setServiceDetails(response); setConnectionDetails(response.connection?.config as DashboardConnection); - await getOtherDetails(); } catch (error) { // Error } finally { @@ -774,30 +763,6 @@ const ServiceDetailsPage: FunctionComponent = () => { })); }, []); - const dataModalTab = useMemo( - () => ( - - - - - - - {t('label.deleted')} - {' '} - - - - - - - ), - [showDeleted] - ); - const ingestionTab = useMemo( () => ( @@ -1024,7 +989,7 @@ const ServiceDetailsPage: FunctionComponent = () => { name: t('label.data-model'), key: EntityTabs.DATA_Model, count: dataModelPaging.total, - children: dataModalTab, + children: , }); } @@ -1073,7 +1038,7 @@ const ServiceDetailsPage: FunctionComponent = () => { getOtherDetails, saveUpdatedServiceData, dataModelPaging, - dataModalTab, + ingestionPaging, ingestionTab, testConnectionTab, diff --git a/openmetadata-ui/src/main/resources/ui/src/pages/StoredProcedure/StoredProcedureTab.tsx b/openmetadata-ui/src/main/resources/ui/src/pages/StoredProcedure/StoredProcedureTab.tsx index bb4aa990c402..74040376a663 100644 --- a/openmetadata-ui/src/main/resources/ui/src/pages/StoredProcedure/StoredProcedureTab.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/pages/StoredProcedure/StoredProcedureTab.tsx @@ -55,7 +55,6 @@ const StoredProcedureTab = () => { setIsLoading(true); const { data, paging } = await getStoredProceduresList({ databaseSchema: fqn, - fields: 'owner,tags,followers', include: showDeleted ? Include.Deleted : Include.NonDeleted, ...params, limit: pageSize, 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 a3911cd17b20..2d7691c20986 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 @@ -326,11 +326,18 @@ const TableDetailsPageV1 = () => { }; } - return { + const updatedObj = { ...previous, version: res.version, [key]: res[key], }; + + // If operation was to remove let's remove the key itself + if (res[key] === undefined) { + delete updatedObj[key]; + } + + return updatedObj; }); getEntityFeedCount(); } catch (error) { diff --git a/openmetadata-ui/src/main/resources/ui/src/pages/TestSuiteDetailsPage/TestSuiteDetailsPage.component.tsx b/openmetadata-ui/src/main/resources/ui/src/pages/TestSuiteDetailsPage/TestSuiteDetailsPage.component.tsx index f180265de44a..d5eed19a0e6a 100644 --- a/openmetadata-ui/src/main/resources/ui/src/pages/TestSuiteDetailsPage/TestSuiteDetailsPage.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/pages/TestSuiteDetailsPage/TestSuiteDetailsPage.component.tsx @@ -72,7 +72,7 @@ const TestSuiteDetailsPage = () => { }; const [testSuite, setTestSuite] = useState(); const [isDescriptionEditable, setIsDescriptionEditable] = useState(false); - const [isTestCaseLoading, setIsTestCaseLoading] = useState(false); + const [isTestCaseLoading, setIsTestCaseLoading] = useState(true); const [testCaseResult, setTestCaseResult] = useState>([]); const { diff --git a/openmetadata-ui/src/main/resources/ui/src/pages/UserListPage/UserListPageV1.test.tsx b/openmetadata-ui/src/main/resources/ui/src/pages/UserListPage/UserListPageV1.test.tsx index 94688329ebda..f7b0825215fb 100644 --- a/openmetadata-ui/src/main/resources/ui/src/pages/UserListPage/UserListPageV1.test.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/pages/UserListPage/UserListPageV1.test.tsx @@ -81,9 +81,9 @@ describe('Test UserListPage component', () => { expect(getUsers).toHaveBeenCalledWith({ fields: 'profile,teams,roles', - isAdmin: undefined, + isAdmin: false, isBot: false, - limit: 15, + limit: 25, }); const deletedSwitch = await findByTestId('show-deleted'); @@ -99,7 +99,7 @@ describe('Test UserListPage component', () => { include: 'deleted', isAdmin: false, isBot: false, - limit: 15, + limit: 25, }); }); @@ -108,9 +108,9 @@ describe('Test UserListPage component', () => { expect(getUsers).toHaveBeenCalledWith({ fields: 'profile,teams,roles', - isAdmin: undefined, + isAdmin: false, isBot: false, - limit: 15, + limit: 25, }); const searchBar = await findByTestId('search-bar-container'); diff --git a/openmetadata-ui/src/main/resources/ui/src/pages/UserListPage/UserListPageV1.tsx b/openmetadata-ui/src/main/resources/ui/src/pages/UserListPage/UserListPageV1.tsx index 41db2de59a9c..48de2c8aedbd 100644 --- a/openmetadata-ui/src/main/resources/ui/src/pages/UserListPage/UserListPageV1.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/pages/UserListPage/UserListPageV1.tsx @@ -31,7 +31,6 @@ import PageHeader from '../../components/PageHeader/PageHeader.component'; import { WILD_CARD_CHAR } from '../../constants/char.constants'; import { INITIAL_PAGING_VALUE, - PAGE_SIZE_BASE, PAGE_SIZE_MEDIUM, ROUTES, } from '../../constants/constants'; @@ -95,7 +94,6 @@ const UserListPageV1 = () => { try { const { data, paging: userPaging } = await getUsers({ isBot: false, - limit: PAGE_SIZE_BASE, fields: 'profile,teams,roles', ...params, }); @@ -117,6 +115,7 @@ const UserListPageV1 = () => { fetchUsersList({ isAdmin: isAdminPage, include: showDeletedUser ? Include.Deleted : Include.NonDeleted, + limit: pageSize, }); }; @@ -135,7 +134,7 @@ const UserListPageV1 = () => { searchData( text, currentPage, - PAGE_SIZE_BASE, + pageSize, filters, '', '', @@ -185,6 +184,7 @@ const UserListPageV1 = () => { isAdmin: isAdminPage, [cursorType]: paging[cursorType], include: showDeletedUser ? Include.Deleted : Include.NonDeleted, + limit: pageSize, }); } }; @@ -196,6 +196,7 @@ const UserListPageV1 = () => { fetchUsersList({ isAdmin: isAdminPage, include: value ? Include.Deleted : Include.NonDeleted, + limit: pageSize, }); }; @@ -232,7 +233,8 @@ const UserListPageV1 = () => { setIsDataLoading(false); } else { fetchUsersList({ - isAdmin: tab === GlobalSettingOptions.ADMINS || undefined, + isAdmin: tab === GlobalSettingOptions.ADMINS, + limit: pageSize, }); } } else { diff --git a/openmetadata-ui/src/main/resources/ui/src/rest/databaseAPI.ts b/openmetadata-ui/src/main/resources/ui/src/rest/databaseAPI.ts index 636728f47597..168ce2ebd9c4 100644 --- a/openmetadata-ui/src/main/resources/ui/src/rest/databaseAPI.ts +++ b/openmetadata-ui/src/main/resources/ui/src/rest/databaseAPI.ts @@ -23,6 +23,7 @@ import { DatabaseSchema } from '../generated/entity/data/databaseSchema'; import { EntityHistory } from '../generated/type/entityHistory'; import { Include } from '../generated/type/include'; import { Paging } from '../generated/type/paging'; +import { ListParams } from '../interface/API.interface'; import { getURLWithQueryFields } from '../utils/APIUtils'; import APIClient from './index'; @@ -106,28 +107,33 @@ export const patchDatabaseSchemaDetails = async ( return response.data; }; -export const getDatabaseSchemas = async ( - databaseName: string, - paging?: string, - arrQueryFields?: string | string[], - include: Include = Include.NonDeleted -) => { - const url = `${getURLWithQueryFields( - `/databaseSchemas`, - arrQueryFields - )}&database=${databaseName}${paging ? paging : ''}`; - +export const getDatabaseSchemas = async ({ + include = Include.NonDeleted, + databaseName, + after, + before, + limit, + fields, +}: { + databaseName: string; +} & ListParams) => { const response = await APIClient.get<{ data: DatabaseSchema[]; paging: Paging; - }>(url, { + }>('/databaseSchemas', { params: { + fields, + database: databaseName, include, + after, + before, + limit, }, }); return response.data; }; + export const getDatabaseSchemaDetailsByFQN = async ( databaseSchemaName: string, arrQueryFields?: string | string[], diff --git a/openmetadata-ui/src/main/resources/ui/src/styles/app.less b/openmetadata-ui/src/main/resources/ui/src/styles/app.less index 27cf8b8206ea..2b41e0afaad3 100644 --- a/openmetadata-ui/src/main/resources/ui/src/styles/app.less +++ b/openmetadata-ui/src/main/resources/ui/src/styles/app.less @@ -135,6 +135,12 @@ a[href].link-text-grey, text-decoration: underline; } +// image property + +.object-contain { + object-fit: contain; +} + // Border .no-border { border: none; diff --git a/openmetadata-ui/src/main/resources/ui/src/utils/DatabaseDetails.utils.tsx b/openmetadata-ui/src/main/resources/ui/src/utils/DatabaseDetails.utils.tsx index 3960a19f434b..40e96650d7c6 100644 --- a/openmetadata-ui/src/main/resources/ui/src/utils/DatabaseDetails.utils.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/utils/DatabaseDetails.utils.tsx @@ -11,25 +11,19 @@ * limitations under the License. */ -import { Col, Space } from 'antd'; import { ColumnsType } from 'antd/lib/table'; import { t } from 'i18next'; import React from 'react'; import { Link } from 'react-router-dom'; -import ErrorPlaceHolder from '../components/common/ErrorWithPlaceholder/ErrorPlaceHolder'; -import NextPrevious from '../components/common/NextPrevious/NextPrevious'; -import { NextPreviousProps } from '../components/common/NextPrevious/NextPrevious.interface'; import RichTextEditorPreviewer from '../components/common/RichTextEditor/RichTextEditorPreviewer'; -import Table from '../components/common/Table/Table'; import { getDatabaseSchemaDetailsPath, - PAGE_SIZE, + NO_DATA_PLACEHOLDER, } from '../constants/constants'; import { TabSpecificField } from '../enums/entity.enum'; import { DatabaseSchema } from '../generated/entity/data/databaseSchema'; import { EntityReference } from '../generated/entity/type'; import { UsageDetails } from '../generated/type/entityUsage'; -import { Paging } from '../generated/type/paging'; import { getEntityName } from '../utils/EntityUtils'; import { getUsagePercentile } from '../utils/TableUtils'; @@ -69,7 +63,8 @@ export const schemaTableColumns: ColumnsType = [ dataIndex: 'owner', key: 'owner', width: 120, - render: (text: EntityReference) => getEntityName(text) || '--', + render: (text: EntityReference) => + getEntityName(text) || NO_DATA_PLACEHOLDER, }, { title: t('label.usage'), @@ -80,41 +75,3 @@ export const schemaTableColumns: ColumnsType = [ getUsagePercentile(text?.weeklyStats?.percentileRank ?? 0), }, ]; - -export const getDatabaseSchemaTable = ( - schemaData: DatabaseSchema[], - schemaDataLoading: boolean, - databaseSchemaPaging: Paging, - currentPage: number, - databaseSchemaPagingHandler: NextPreviousProps['pagingHandler'], - isNumberBased = false -) => { - return ( - - -
, - }} - pagination={false} - rowKey="id" - size="small" - /> - {databaseSchemaPaging.total > PAGE_SIZE && ( - - )} - - - ); -};