diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/AddDataQualityTest/EditTestCaseModal.tsx b/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/AddDataQualityTest/EditTestCaseModal.tsx index 27b05365c93..fb1520d53fd 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/AddDataQualityTest/EditTestCaseModal.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/AddDataQualityTest/EditTestCaseModal.tsx @@ -36,8 +36,9 @@ import { updateTestCaseById, } from '../../../rest/testAPI'; import { getNameFromFQN } from '../../../utils/CommonUtils'; +import { getColumnNameFromEntityLink } from '../../../utils/EntityUtils'; +import { getEntityFQN } from '../../../utils/FeedUtils'; import { generateFormFields } from '../../../utils/formUtils'; -import { getEntityFqnFromEntityLink } from '../../../utils/TableUtils'; import { showErrorToast, showSuccessToast } from '../../../utils/ToastUtils'; import Loader from '../../common/Loader/Loader'; import RichTextEditor from '../../common/RichTextEditor/RichTextEditor'; @@ -54,7 +55,7 @@ const EditTestCaseModal: React.FC = ({ const { t } = useTranslation(); const [form] = Form.useForm(); const tableFqn = useMemo( - () => getEntityFqnFromEntityLink(testCase?.entityLink ?? ''), + () => getEntityFQN(testCase?.entityLink ?? ''), [testCase] ); const [selectedDefinition, setSelectedDefinition] = @@ -191,9 +192,7 @@ const EditTestCaseModal: React.FC = ({ displayName: testCase?.displayName, params: getParamsValue(definition), table: getNameFromFQN(tableFqn), - column: getNameFromFQN( - getEntityFqnFromEntityLink(testCase?.entityLink, isColumn) - ), + column: getColumnNameFromEntityLink(testCase?.entityLink), computePassedFailedRowCount: testCase?.computePassedFailedRowCount, }); setSelectedDefinition(definition); diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/AddTestCaseList/AddTestCaseList.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/AddTestCaseList/AddTestCaseList.component.tsx index 419b6f76f82..9ebb5dacf0a 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/AddTestCaseList/AddTestCaseList.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/AddTestCaseList/AddTestCaseList.component.tsx @@ -32,9 +32,12 @@ import { } from '../../../interface/search.interface'; import { searchQuery } from '../../../rest/searchAPI'; import { getNameFromFQN } from '../../../utils/CommonUtils'; -import { getEntityName } from '../../../utils/EntityUtils'; +import { + getColumnNameFromEntityLink, + getEntityName, +} from '../../../utils/EntityUtils'; +import { getEntityFQN } from '../../../utils/FeedUtils'; import { replacePlus } from '../../../utils/StringsUtils'; -import { getEntityFqnFromEntityLink } from '../../../utils/TableUtils'; import ErrorPlaceHolder from '../../common/ErrorWithPlaceholder/ErrorPlaceHolder'; import Loader from '../../common/Loader/Loader'; import Searchbar from '../../common/SearchBarComponent/SearchBar.component'; @@ -186,7 +189,7 @@ export const AddTestCaseList = ({ itemKey="id" onScroll={onScroll}> {({ _source: test }) => { - const tableFqn = getEntityFqnFromEntityLink(test.entityLink); + const tableFqn = getEntityFQN(test.entityLink); const tableName = getNameFromFQN(tableFqn); const isColumn = test.entityLink.includes('::columns::'); @@ -224,13 +227,8 @@ export const AddTestCaseList = ({ 'label.column' )}:`} - {getNameFromFQN( - replacePlus( - getEntityFqnFromEntityLink( - test.entityLink, - isColumn - ) - ) + {replacePlus( + getColumnNameFromEntityLink(test.entityLink) ) ?? '--'} diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/TestSuite/TestSuiteList/TestSuites.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/TestSuite/TestSuiteList/TestSuites.component.tsx index 457c19dcfbc..a0077acb416 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/TestSuite/TestSuiteList/TestSuites.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/TestSuite/TestSuiteList/TestSuites.component.tsx @@ -77,6 +77,23 @@ export const TestSuites = ({ summaryPanel }: { summaryPanel: ReactNode }) => { title: t('label.name'), dataIndex: 'name', key: 'name', + sorter: (a, b) => { + if (a.executable) { + // Sort for executable test suites + return ( + a.executableEntityReference?.fullyQualifiedName?.localeCompare( + b.executableEntityReference?.fullyQualifiedName ?? '' + ) ?? 0 + ); + } else { + // Sort for logical test suites + return ( + a.fullyQualifiedName?.localeCompare(b.fullyQualifiedName ?? '') ?? + 0 + ); + } + }, + sortDirections: ['ascend', 'descend'], render: (name, record) => { return record.executable ? ( = ({ dataIndex: 'name', key: 'name', width: 300, + sorter: (a, b) => a.name.localeCompare(b.name), + sortDirections: ['ascend', 'descend'], render: (name: string, record) => { const status = record.testCaseResult?.testCaseStatus; const urlData = { @@ -166,14 +171,14 @@ const DataQualityTab: React.FC = ({ }, }, ...(showTableColumn - ? [ + ? ([ { title: t('label.table'), dataIndex: 'entityLink', key: 'table', width: 150, render: (entityLink: string) => { - const tableFqn = getEntityFqnFromEntityLink(entityLink); + const tableFqn = getEntityFQN(entityLink); const name = getNameFromFQN(tableFqn); return ( @@ -190,8 +195,18 @@ const DataQualityTab: React.FC = ({ ); }, + sorter: (a, b) => { + // Extract table name from entity link + const tableAFqn = getEntityFQN(a.entityLink); + const tableA = getNameFromFQN(tableAFqn); + const tableBFqn = getEntityFQN(b.entityLink); + const tableB = getNameFromFQN(tableBFqn); + + return tableA.localeCompare(tableB); + }, + sortDirections: ['ascend', 'descend'], }, - ] + ] as ColumnsType) : []), { title: t('label.column'), @@ -201,8 +216,8 @@ const DataQualityTab: React.FC = ({ render: (entityLink) => { const isColumn = entityLink.includes('::columns::'); if (isColumn) { - const name = getNameFromFQN( - replacePlus(getEntityFqnFromEntityLink(entityLink, isColumn)) + const name = replacePlus( + getColumnNameFromEntityLink(entityLink) ?? '' ); return name; @@ -210,6 +225,19 @@ const DataQualityTab: React.FC = ({ return '--'; }, + sorter: (a, b) => { + // Extract column name from entity link if available + const columnA = a.entityLink.includes('::columns::') + ? replacePlus(getColumnNameFromEntityLink(a.entityLink)) + : '--'; + + const columnB = b.entityLink.includes('::columns::') + ? replacePlus(getColumnNameFromEntityLink(b.entityLink)) + : '--'; + + return columnA.localeCompare(columnB); + }, + sortDirections: ['ascend', 'descend'], }, { title: t('label.last-run'), diff --git a/openmetadata-ui/src/main/resources/ui/src/utils/EntityUtils.tsx b/openmetadata-ui/src/main/resources/ui/src/utils/EntityUtils.tsx index a3a8d785e74..2ec570b2268 100644 --- a/openmetadata-ui/src/main/resources/ui/src/utils/EntityUtils.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/utils/EntityUtils.tsx @@ -104,6 +104,7 @@ import { getPartialNameFromTableFQN, getTableFQNFromColumnFQN, } from './CommonUtils'; +import EntityLink from './EntityLink'; import { BasicEntityOverviewInfo } from './EntityUtils.interface'; import Fqn from './Fqn'; import { @@ -1774,3 +1775,12 @@ export const columnSorter = ( return name1.localeCompare(name2); }; + +/** + * Retrieves the column name from an entity link. + * @param entityLink The entity link string. + * @returns The column name extracted from the entity link. + */ +export const getColumnNameFromEntityLink = (entityLink: string) => { + return EntityLink.getTableColumnName(entityLink); +}; diff --git a/openmetadata-ui/src/main/resources/ui/src/utils/TableUtils.tsx b/openmetadata-ui/src/main/resources/ui/src/utils/TableUtils.tsx index 4917f8d3282..8e10ec3b89b 100644 --- a/openmetadata-ui/src/main/resources/ui/src/utils/TableUtils.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/utils/TableUtils.tsx @@ -409,21 +409,6 @@ export const generateEntityLink = (fqn: string, includeColumn = false) => { } }; -export const getEntityFqnFromEntityLink = ( - entityLink: string, - includeColumn = false -) => { - const link = entityLink.split('>')[0]; - const entityLinkData = link.split('::'); - const tableFqn = entityLinkData[2]; - - if (includeColumn) { - return `${tableFqn}.${entityLinkData[entityLinkData.length - 1]}`; - } - - return tableFqn; -}; - export function getTableExpandableConfig( isDraggable?: boolean ): ExpandableConfig {