+
{selectedColumn && (
-
-
-
-
-
-
-
-
- {t('label.data-quality-test-plural')}
-
-
-
-
-
-
-
-
- {activeColumnTests?.total ?? 0}
-
-
- {t('label.total-test-plural')}
-
-
- }
- data={columnTestData}
- height={PIE_SIZE}
- innerRadius="62%"
- legend={LEGEND_HIDDEN}
- outerRadius="88%"
- />
-
+ // Side by side on the page; wraps to a stack in narrow columns such as
+ // the custom metric drawer preview (each card needs at least 20rem).
+
+
+
+
+
+
+
+
+
+ {activeColumnTests?.total ?? 0}
+
+
+ {t('label.total-test-plural')}
+
+
+ }
+ data={columnTestData}
+ height={PIE_SIZE}
+ innerRadius="62%"
+ legend={LEGEND_HIDDEN}
+ outerRadius="88%"
+ />
-
-
-
- {columnTestData.map((item, index) => (
-
-
- {item.name}
-
-
- {formatNumberWithComma(item.value)}
-
-
- ))}
-
+
+ {columnTestData.map((item, index) => (
+
+
+ {item.name}
+
+
+ {formatNumberWithComma(item.value)}
+
+
+ ))}
-
-
-
-
+
+
+
+
)}
= ({
customMetricsGraphData={columnCustomMetrics}
isLoading={isLoading || isProfilerDataLoading}
/>
-
+
);
};
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Database/Profiler/TableProfiler/TableProfiler.interface.ts b/openmetadata-ui/src/main/resources/ui/src/components/Database/Profiler/TableProfiler/TableProfiler.interface.ts
index c480136f1a6e..36bf76f86876 100644
--- a/openmetadata-ui/src/main/resources/ui/src/components/Database/Profiler/TableProfiler/TableProfiler.interface.ts
+++ b/openmetadata-ui/src/main/resources/ui/src/components/Database/Profiler/TableProfiler/TableProfiler.interface.ts
@@ -16,6 +16,7 @@ import { OperationPermission } from '../../../../context/PermissionProvider/Perm
import {
Column,
ColumnProfilerConfig,
+ CustomMetric,
PartitionProfilerConfig,
ProfileSampleType,
Table,
@@ -40,7 +41,8 @@ export interface TableProfilerProviderProps extends TableProfilerProps {
export interface TableProfilerContextInterface {
isTableDeleted?: boolean;
testCaseSummary?: Record
;
- permissions: OperationPermission;
+ /** Unset in read-only previews (the custom metric drawer), which hides edit actions. */
+ permissions?: OperationPermission;
isTestsLoading: boolean;
isProfilerDataLoading: boolean;
tableProfiler?: Table;
@@ -57,6 +59,10 @@ export interface TableProfilerContextInterface {
table?: Table;
isTestCaseDrawerOpen: boolean;
onTestCaseDrawerOpen: (type: TestLevel) => void;
+ onCustomMetricDrawerOpen: (
+ isColumnMetric: boolean,
+ metric?: CustomMetric
+ ) => void;
}
export type TableTestsType = {
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Database/Profiler/TableProfiler/TableProfilerChart/TableProfilerChart.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Database/Profiler/TableProfiler/TableProfilerChart/TableProfilerChart.test.tsx
index 09192d8b6ee7..ae070c753c26 100644
--- a/openmetadata-ui/src/main/resources/ui/src/components/Database/Profiler/TableProfiler/TableProfilerChart/TableProfilerChart.test.tsx
+++ b/openmetadata-ui/src/main/resources/ui/src/components/Database/Profiler/TableProfiler/TableProfilerChart/TableProfilerChart.test.tsx
@@ -88,7 +88,6 @@ jest.mock('../../../../../rest/tableAPI', () => ({
}));
jest.mock('../../../../../utils/RouterUtils', () => ({
- getAddCustomMetricPath: jest.fn(),
getAddDataQualityTableTestPath: jest.fn(),
}));
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Database/Profiler/TableProfiler/TableProfilerChart/TableProfilerChart.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Database/Profiler/TableProfiler/TableProfilerChart/TableProfilerChart.tsx
index ad04c486c931..97a5c4df80bd 100644
--- a/openmetadata-ui/src/main/resources/ui/src/components/Database/Profiler/TableProfiler/TableProfilerChart/TableProfilerChart.tsx
+++ b/openmetadata-ui/src/main/resources/ui/src/components/Database/Profiler/TableProfiler/TableProfilerChart/TableProfilerChart.tsx
@@ -112,7 +112,9 @@ const TableProfilerChart = ({
return isProfilingEnabled ? (
t('message.profiler-is-enabled-but-no-data-available')
) : (
-
+ // tw:w-auto overrides the trigger's w-max so the sentence wraps in
+ // narrow containers such as the custom metric drawer preview.
+
jest.fn().mockReturnValue(null)
);
+jest.mock('../../../DataQuality/CustomMetricForm/CustomMetricFormDrawer', () =>
+ jest.fn(
+ ({
+ open,
+ isColumnMetric,
+ metric,
+ onClose,
+ }: {
+ open: boolean;
+ isColumnMetric: boolean;
+ metric?: { name: string };
+ onClose: () => void;
+ }) => {
+ const { TableProfilerContext: ProfilerContext } = jest.requireActual(
+ './TableProfilerProvider'
+ );
+ const profilerContext = jest
+ .requireActual('react')
+ .useContext(ProfilerContext);
+
+ return open ? (
+
+
+ {String(isColumnMetric)}
+
+ {metric?.name ?? 'new'}
+
+ {String(profilerContext.permissions)}
+
+
+ {String(profilerContext.isProfilingEnabled)}
+
+
+ {String(
+ profilerContext.testCaseSummary?.[
+ 'sample.db.schema.table.address_id'
+ ]?.total
+ )}
+
+ close drawer
+
+ ) : null;
+ }
+ )
+);
+jest.mock('../../../../rest/dataQualityDashboardAPI', () => ({
+ fetchTestCaseResultByTestSuiteId: jest.fn().mockResolvedValue({
+ data: [
+ {
+ document_count: '2',
+ entityFQN: 'sample.db.schema.table.address_id',
+ 'testCaseResult.testCaseStatus': 'success',
+ },
+ {
+ document_count: '1',
+ entityFQN: 'sample.db.schema.table.address_id',
+ 'testCaseResult.testCaseStatus': 'failed',
+ },
+ ],
+ }),
+}));
jest.mock('../../../../constants/constants', () => ({
PAGE_SIZE: 10,
ROUTES: {
@@ -255,4 +322,86 @@ describe('TableProfilerProvider', () => {
});
});
});
+
+ describe('Custom metric drawer', () => {
+ const DrawerOpener = () => {
+ const { onCustomMetricDrawerOpen } = useContext(TableProfilerContext);
+
+ return (
+ <>
+ onCustomMetricDrawerOpen(false)}>
+ add table metric
+
+
+ onCustomMetricDrawerOpen(true, {
+ name: 'column_metric',
+ expression: 'SELECT 1',
+ columnName: 'address_id',
+ })
+ }>
+ edit column metric
+
+ >
+ );
+ };
+
+ const renderProvider = async () => {
+ await act(async () => {
+ render(
+
+
+
+ );
+ });
+ };
+
+ it('opens one shared drawer for adding and editing, with a read-only profiler context', async () => {
+ await renderProvider();
+
+ expect(
+ screen.queryByTestId('custom-metric-drawer')
+ ).not.toBeInTheDocument();
+
+ fireEvent.click(screen.getByText('add table metric'));
+
+ expect(
+ await screen.findByTestId('drawer-column-metric')
+ ).toHaveTextContent('false');
+ expect(screen.getByTestId('drawer-metric')).toHaveTextContent('new');
+
+ // The preview reads the profiler's data (test summary, profiling state)…
+ await waitFor(() =>
+ expect(screen.getByTestId('drawer-column-tests')).toHaveTextContent('3')
+ );
+
+ expect(screen.getByTestId('drawer-profiling-enabled')).toHaveTextContent(
+ 'false'
+ );
+ // …but not its permissions, so its metric graphs offer no edit/delete.
+ expect(screen.getByTestId('drawer-permissions')).toHaveTextContent(
+ 'undefined'
+ );
+
+ fireEvent.click(screen.getByText('edit column metric'));
+
+ expect(screen.getByTestId('drawer-column-metric')).toHaveTextContent(
+ 'true'
+ );
+ expect(screen.getByTestId('drawer-metric')).toHaveTextContent(
+ 'column_metric'
+ );
+
+ fireEvent.click(screen.getByText('close drawer'));
+
+ expect(
+ screen.queryByTestId('custom-metric-drawer')
+ ).not.toBeInTheDocument();
+ });
+ });
});
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Database/Profiler/TableProfiler/TableProfilerProvider.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Database/Profiler/TableProfiler/TableProfilerProvider.tsx
index 1dfbf72b9472..1a1408e9f321 100644
--- a/openmetadata-ui/src/main/resources/ui/src/components/Database/Profiler/TableProfiler/TableProfilerProvider.tsx
+++ b/openmetadata-ui/src/main/resources/ui/src/components/Database/Profiler/TableProfiler/TableProfilerProvider.tsx
@@ -32,7 +32,7 @@ import { ReactComponent as TotalSizeIcon } from '../../../../assets/svg/data-obs
import { DEFAULT_SORT_ORDER } from '../../../../constants/profiler.constant';
import { useTourProvider } from '../../../../context/TourProvider/TourProvider';
import { TabSpecificField } from '../../../../enums/entity.enum';
-import { Table } from '../../../../generated/entity/data/table';
+import { CustomMetric, Table } from '../../../../generated/entity/data/table';
import { ResourcePermission } from '../../../../generated/entity/policies/accessControl/resourcePermission';
import { ProfileSampleType } from '../../../../generated/metadataIngestion/databaseServiceProfilerPipeline';
import { TestCase } from '../../../../generated/tests/testCase';
@@ -72,6 +72,11 @@ const TestCaseFormDrawer = withSuspenseFallback(
)
)
);
+const CustomMetricFormDrawer = withSuspenseFallback(
+ lazy(
+ () => import('../../../DataQuality/CustomMetricForm/CustomMetricFormDrawer')
+ )
+);
export const TableProfilerContext =
createContext(
@@ -102,6 +107,10 @@ export const TableProfilerProvider = ({
const [settingModalVisible, setSettingModalVisible] = useState(false);
const [isTestCaseDrawerOpen, setIsTestCaseDrawerOpen] = useState(false);
const [testLevel, setTestLevel] = useState();
+ const [customMetricDrawer, setCustomMetricDrawer] = useState<{
+ isColumnMetric: boolean;
+ metric?: CustomMetric;
+ }>();
const [table, setTable] = useState(tableEntity);
const [testCaseSummary, setTestCaseSummary] =
useState>();
@@ -236,6 +245,17 @@ export const TableProfilerProvider = ({
setCustomMetric(customMetric);
};
+ const handleOpenCustomMetricDrawer = useCallback(
+ (isColumnMetric: boolean, metric?: CustomMetric) =>
+ setCustomMetricDrawer({ isColumnMetric, metric }),
+ []
+ );
+
+ const handleCloseCustomMetricDrawer = useCallback(
+ () => setCustomMetricDrawer(undefined),
+ []
+ );
+
const onTestCaseSubmit = (testCase: TestCase) => {
setTable((prev) => {
if (!prev) {
@@ -392,6 +412,7 @@ export const TableProfilerProvider = ({
testCaseSummary,
onTestCaseDrawerOpen: handleOpenTestCaseDrawer,
isTestCaseDrawerOpen,
+ onCustomMetricDrawerOpen: handleOpenCustomMetricDrawer,
};
}, [
isTestsLoading,
@@ -409,27 +430,48 @@ export const TableProfilerProvider = ({
testCaseSummary,
isTestCaseDrawerOpen,
handleOpenTestCaseDrawer,
+ handleOpenCustomMetricDrawer,
]);
+ const readOnlyProfilerContext = useMemo(
+ () => ({ ...tableProfilerPropsData, permissions: undefined }),
+ [tableProfilerPropsData]
+ );
+
return (
-
- {children}
- {settingModalVisible && (
-
+
+ {children}
+ {settingModalVisible && (
+
+ )}
+
+
+ {/* The profile preview inside the drawer reads the profiler's data but
+ gets no permissions, so its custom metric graphs offer no edit/delete
+ actions that would reopen this drawer. */}
+
+
- )}
-
-
+
+ >
);
};
diff --git a/openmetadata-ui/src/main/resources/ui/src/constants/constants.ts b/openmetadata-ui/src/main/resources/ui/src/constants/constants.ts
index c3ad9ec96bb6..f0ddf6fa8f89 100644
--- a/openmetadata-ui/src/main/resources/ui/src/constants/constants.ts
+++ b/openmetadata-ui/src/main/resources/ui/src/constants/constants.ts
@@ -122,7 +122,6 @@ export const PLACEHOLDER_SETTING_CATEGORY = ':settingCategory';
export const PLACEHOLDER_USER_BOT = ':bot';
export const PLACEHOLDER_WEBHOOK_TYPE = ':webhookType';
export const PLACEHOLDER_RULE_NAME = ':ruleName';
-export const PLACEHOLDER_DASHBOARD_TYPE = ':dashboardType';
export const PLACEHOLDER_ACTION = ':action';
export const PLACEHOLDER_ROUTE_DIMENSION_KEY = ':dimensionKey';
@@ -314,7 +313,6 @@ export const ROUTES = {
CUSTOMIZE_PAGE: `/customize-page/${PLACEHOLDER_ROUTE_FQN}/:pageFqn`,
- ADD_CUSTOM_METRIC: `/add-custom-metric/${PLACEHOLDER_DASHBOARD_TYPE}/${PLACEHOLDER_ROUTE_FQN}`,
CHART_DETAILS: `/chart/${PLACEHOLDER_ROUTE_FQN}`,
CHART_DETAILS_WITH_TAB: `/chart/${PLACEHOLDER_ROUTE_FQN}/${PLACEHOLDER_ROUTE_TAB}`,
diff --git a/openmetadata-ui/src/main/resources/ui/src/pages/AddCustomMetricPage/AddCustomMetricPage.test.tsx b/openmetadata-ui/src/main/resources/ui/src/pages/AddCustomMetricPage/AddCustomMetricPage.test.tsx
deleted file mode 100644
index 91e08fa27f09..000000000000
--- a/openmetadata-ui/src/main/resources/ui/src/pages/AddCustomMetricPage/AddCustomMetricPage.test.tsx
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * 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 { MemoryRouter } from 'react-router-dom';
-import { MOCK_TABLE } from '../../mocks/TableData.mock';
-import { getTableDetailsByFQN } from '../../rest/tableAPI';
-import AddCustomMetricPage from './AddCustomMetricPage';
-const mockUseParams = {
- fqn: 'sample_data.ecommerce_db.shopify.dim_address',
- dashboardType: 'table',
-};
-jest.mock(
- '../../components/common/TitleBreadcrumb/TitleBreadcrumb.component',
- () => {
- return jest.fn().mockImplementation(() => TitleBreadcrumb
);
- }
-);
-jest.mock(
- '../../components/DataQuality/CustomMetricForm/CustomMetricForm.component',
- () => {
- return jest.fn().mockImplementation(() => CustomMetricForm
);
- }
-);
-jest.mock(
- '../../components/Database/Profiler/TableProfiler/SingleColumnProfile',
- () => {
- return jest.fn().mockImplementation(() => SingleColumnProfile
);
- }
-);
-jest.mock(
- '../../components/Database/Profiler/TableProfiler/TableProfilerChart/TableProfilerChart',
- () => {
- return jest.fn().mockImplementation(() => TableProfilerChart
);
- }
-);
-jest.mock('../../components/common/Loader/Loader', () => {
- return jest.fn().mockImplementation(() => Loader
);
-});
-jest.mock('../../hooks/useCustomLocation/useCustomLocation', () => {
- return jest.fn().mockImplementation(() => ({ search: '' }));
-});
-jest.mock('react-router-dom', () => ({
- ...jest.requireActual('react-router-dom'),
- useParams: jest.fn().mockImplementation(() => mockUseParams),
-}));
-jest.mock('../../rest/tableAPI', () => ({
- getTableDetailsByFQN: jest
- .fn()
- .mockImplementation(() => Promise.resolve(MOCK_TABLE)),
-}));
-jest.mock('../../rest/customMetricAPI', () => ({
- putCustomMetric: jest.fn(),
-}));
-jest.mock('../../hoc/withPageLayout', () => ({
- withPageLayout: jest.fn().mockImplementation((Component) => Component),
-}));
-jest.mock('../../components/common/ResizablePanels/ResizablePanels', () =>
- jest.fn().mockImplementation(({ firstPanel, secondPanel }) => (
- <>
- {firstPanel.children}
- {secondPanel.children}
- >
- ))
-);
-
-const mockProps = {
- pageTitle: 'add-custom-metric',
-};
-
-describe('AddCustomMetricPage', () => {
- it('should render component', async () => {
- render( , {
- wrapper: MemoryRouter,
- });
-
- expect(getTableDetailsByFQN).toHaveBeenCalled();
-
- expect(
- await screen.findByTestId('add-custom-metric-page-container')
- ).toBeInTheDocument();
- expect(await screen.findByTestId('heading')).toBeInTheDocument();
- expect(await screen.findByTestId('cancel-button')).toBeInTheDocument();
- expect(await screen.findByTestId('submit-button')).toBeInTheDocument();
- expect(await screen.findByText('TitleBreadcrumb')).toBeInTheDocument();
- expect(await screen.findByText('CustomMetricForm')).toBeInTheDocument();
- expect(await screen.findByText('TableProfilerChart')).toBeInTheDocument();
- });
-
- it("should render column profiler if dashboardType is 'column'", async () => {
- mockUseParams.dashboardType = 'column';
- render( , {
- wrapper: MemoryRouter,
- });
-
- expect(await screen.findByText('SingleColumnProfile')).toBeInTheDocument();
- });
-});
diff --git a/openmetadata-ui/src/main/resources/ui/src/pages/AddCustomMetricPage/AddCustomMetricPage.tsx b/openmetadata-ui/src/main/resources/ui/src/pages/AddCustomMetricPage/AddCustomMetricPage.tsx
deleted file mode 100644
index a738c2fa1d0b..000000000000
--- a/openmetadata-ui/src/main/resources/ui/src/pages/AddCustomMetricPage/AddCustomMetricPage.tsx
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * 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 {
- Box,
- Button,
- Grid,
- Typography,
-} from '@openmetadata/ui-core-components';
-import { AxiosError } from 'axios';
-import QueryString from 'qs';
-import { useEffect, useMemo, useState } from 'react';
-import { useForm, useWatch } from 'react-hook-form';
-import { useTranslation } from 'react-i18next';
-import { useNavigate } from 'react-router-dom';
-import Loader from '../../components/common/Loader/Loader';
-import ResizablePanels from '../../components/common/ResizablePanels/ResizablePanels';
-import TitleBreadcrumb from '../../components/common/TitleBreadcrumb/TitleBreadcrumb.component';
-import { TitleBreadcrumbProps } from '../../components/common/TitleBreadcrumb/TitleBreadcrumb.interface';
-import { ProfilerTabPath } from '../../components/Database/Profiler/ProfilerDashboard/profilerDashboard.interface';
-import SingleColumnProfile from '../../components/Database/Profiler/TableProfiler/SingleColumnProfile';
-import TableProfilerChart from '../../components/Database/Profiler/TableProfiler/TableProfilerChart/TableProfilerChart';
-import RightPanel from '../../components/DataQuality/AddDataQualityTest/components/RightPanel';
-import CustomMetricForm from '../../components/DataQuality/CustomMetricForm/CustomMetricForm.component';
-import { DEFAULT_RANGE_DATA } from '../../constants/profiler.constant';
-import {
- EntityTabs,
- EntityType,
- TabSpecificField,
-} from '../../enums/entity.enum';
-import { ProfilerDashboardType } from '../../enums/table.enum';
-import { CustomMetric, Table } from '../../generated/entity/data/table';
-import { withPageLayout } from '../../hoc/withPageLayout';
-import useCustomLocation from '../../hooks/useCustomLocation/useCustomLocation';
-import { useFqn } from '../../hooks/useFqn';
-import { putCustomMetric } from '../../rest/customMetricAPI';
-import { getTableDetailsByFQN } from '../../rest/tableAPI';
-import { getEntityBreadcrumbs } from '../../utils/EntityBreadcrumbPureUtils';
-import { getEntityName } from '../../utils/EntityNameUtils';
-import { getNameFromFQN } from '../../utils/FqnUtils';
-import { getEntityDetailsPath } from '../../utils/RouterUtils';
-import { showErrorToast, showSuccessToast } from '../../utils/ToastUtils';
-import { useRequiredParams } from '../../utils/useRequiredParams';
-
-const AddCustomMetricPage = () => {
- const { dashboardType } = useRequiredParams<{
- dashboardType: ProfilerDashboardType;
- }>();
- const { fqn } = useFqn();
- const { t } = useTranslation();
-
- const navigate = useNavigate();
- const location = useCustomLocation();
- const isColumnMetric = dashboardType === ProfilerDashboardType.COLUMN;
- const form = useForm({
- defaultValues: { name: '', expression: '' },
- });
- const [table, setTable] = useState();
- const [isLoading, setIsLoading] = useState(true);
- const [isActionLoading, setIsActionLoading] = useState(false);
- const columnName = useWatch({ control: form.control, name: 'columnName' });
- const entityFqn = useMemo(() => table?.fullyQualifiedName ?? '', [table]);
-
- const breadcrumb = useMemo(() => {
- const data: TitleBreadcrumbProps['titleLinks'] = table
- ? [
- ...getEntityBreadcrumbs(table, EntityType.TABLE),
- {
- name: getEntityName(table),
- url: getEntityDetailsPath(
- EntityType.TABLE,
- entityFqn,
- EntityTabs.PROFILER
- ),
- },
- {
- name: t('label.add-entity-metric', {
- entity: isColumnMetric ? t('label.column') : t('label.table'),
- }),
- url: '',
- activeTitle: true,
- },
- ]
- : [];
-
- return data;
- }, [table, isColumnMetric]);
-
- const { activeColumnFqn } = useMemo(() => {
- const param = location.search;
- const searchData = QueryString.parse(
- param.startsWith('?') ? param.substring(1) : param
- );
-
- return searchData as { activeColumnFqn: string };
- }, [location.search]);
-
- const initialValues = useMemo(
- () =>
- activeColumnFqn
- ? { columnName: getNameFromFQN(activeColumnFqn) }
- : undefined,
- [activeColumnFqn]
- );
-
- const handleBackClick = () => {
- navigate({
- pathname: getEntityDetailsPath(
- EntityType.TABLE,
- entityFqn,
- EntityTabs.PROFILER,
- isColumnMetric
- ? ProfilerTabPath.COLUMN_PROFILE
- : ProfilerTabPath.TABLE_PROFILE
- ),
- search: QueryString.stringify({
- activeColumnFqn,
- }),
- });
- };
-
- const handleFormSubmit = async (values: CustomMetric) => {
- if (table) {
- setIsActionLoading(true);
- try {
- await putCustomMetric(table.id, values);
- showSuccessToast(
- t('server.create-entity-success', {
- entity: values.name,
- })
- );
- handleBackClick();
- } catch (error) {
- showErrorToast(error as AxiosError);
- setIsActionLoading(false);
- }
- }
- };
-
- const fetchTableData = async () => {
- setIsLoading(true);
- try {
- const table = await getTableDetailsByFQN(fqn, {
- fields: [
- TabSpecificField.TESTSUITE,
- TabSpecificField.CUSTOM_METRICS,
- TabSpecificField.COLUMNS,
- ],
- });
- setTable(table);
- } catch (error) {
- showErrorToast(error as AxiosError);
- } finally {
- setIsLoading(false);
- }
- };
-
- useEffect(() => {
- fetchTableData();
- }, [fqn]);
-
- useEffect(() => {
- const selectedColumn = table?.columns.find(
- (column) => column.name === columnName
- );
- if (selectedColumn) {
- navigate({
- search: QueryString.stringify({
- activeColumnFqn: selectedColumn?.fullyQualifiedName,
- }),
- });
- }
- }, [columnName]);
-
- const secondPanel = (
- <>
-
- {isColumnMetric ? (
-
- ) : (
-
- )}
- >
- );
-
- if (isLoading) {
- return ;
- }
-
- return (
-
-
-
-
-
-
-
- {t('label.add-entity-metric', {
- entity: isColumnMetric
- ? t('label.column')
- : t('label.table'),
- })}
-
-
-
-
-
-
- {t('label.cancel')}
-
-
- {t('label.create')}
-
-
-
-
-
- ),
- minWidth: 700,
- flex: 0.5,
- }}
- pageTitle={t('label.add-entity', {
- entity: t('label.custom-metric'),
- })}
- secondPanel={{
- children: secondPanel,
- className: 'content-resizable-panel-container',
- flex: 0.5,
- minWidth: 400,
- }}
- />
- );
-};
-
-export default withPageLayout(AddCustomMetricPage);
diff --git a/openmetadata-ui/src/main/resources/ui/src/utils/RouterUtils.ts b/openmetadata-ui/src/main/resources/ui/src/utils/RouterUtils.ts
index 9af22f3a4806..36db6e840dbf 100644
--- a/openmetadata-ui/src/main/resources/ui/src/utils/RouterUtils.ts
+++ b/openmetadata-ui/src/main/resources/ui/src/utils/RouterUtils.ts
@@ -17,7 +17,6 @@ import QueryString from 'qs';
import {
IN_PAGE_SEARCH_ROUTES,
PLACEHOLDER_ACTION,
- PLACEHOLDER_DASHBOARD_TYPE,
PLACEHOLDER_ROUTE_DIMENSION_KEY,
PLACEHOLDER_ROUTE_ENTITY_TYPE,
PLACEHOLDER_ROUTE_FQN,
@@ -43,7 +42,6 @@ import { arrServiceTypes } from '../constants/Services.constant';
import { AlertDetailTabs } from '../enums/Alerts.enum';
import { EntityTabs, EntityType } from '../enums/entity.enum';
import { ServiceAgentSubTabs } from '../enums/service.enum';
-import { ProfilerDashboardType } from '../enums/table.enum';
import { PipelineType } from '../generated/api/services/ingestionPipelines/createIngestionPipeline';
import { useMarketplaceStore } from '../hooks/useMarketplaceStore';
import type { DataQualityPageTabs } from '../pages/DataQuality/DataQualityPage.interface';
@@ -373,19 +371,6 @@ export const getTagPath = (fqn?: string) => {
return path;
};
-export const getAddCustomMetricPath = (
- dashboardType: ProfilerDashboardType,
- fqn: string
-) => {
- let path = ROUTES.ADD_CUSTOM_METRIC;
-
- path = path
- .replace(PLACEHOLDER_DASHBOARD_TYPE, dashboardType)
- .replace(PLACEHOLDER_ROUTE_FQN, getEncodedFqn(fqn));
-
- return path;
-};
-
export const getChartDetailsPath = (fqn: string, tab?: string) => {
let path = tab ? ROUTES.CHART_DETAILS_WITH_TAB : ROUTES.CHART_DETAILS;
path = path.replace(PLACEHOLDER_ROUTE_FQN, getEncodedFqn(fqn));