diff --git a/.github/playwright/impact-map.generated.json b/.github/playwright/impact-map.generated.json index 74eddbaf5b6b..a9ae94f44f0f 100644 --- a/.github/playwright/impact-map.generated.json +++ b/.github/playwright/impact-map.generated.json @@ -5165,6 +5165,7 @@ "openmetadata-ui/src/main/resources/ui/playwright/utils/userDetails.ts" ], "specs": [ + "playwright/e2e/Pages/Teams.spec.ts", "playwright/e2e/Pages/UserDetails.spec.ts" ] }, @@ -5660,6 +5661,16 @@ "playwright/e2e/Features/BlockEditorEmbedLink.spec.ts" ] }, + { + "sources": [ + "openmetadata-ui/src/main/resources/ui/src/components/BlockEditor/Extensions/image/UploadFile/UploadFileTab.tsx" + ], + "specs": [ + "playwright/e2e/Features/BulkImport.spec.ts", + "playwright/e2e/Features/BulkImportWithDotInName.spec.ts", + "playwright/e2e/Features/MetricBulkImportExportEdit.spec.ts" + ] + }, { "sources": [ "openmetadata-ui/src/main/resources/ui/src/components/BulkEditEntity/BulkEditEntity.component.tsx" @@ -5885,6 +5896,7 @@ "playwright/e2e/Features/ContextCenterDashboard.spec.ts", "playwright/e2e/Features/ContextCenterDocument.spec.ts", "playwright/e2e/Features/ContextCenterPermission.spec.ts", + "playwright/e2e/Features/SSOConfiguration.spec.ts", "playwright/e2e/Pages/DataContracts.spec.ts", "playwright/e2e/Pages/ODCSImportExport.spec.ts" ] @@ -6147,6 +6159,7 @@ "playwright/e2e/Features/ContextCenterDocument.spec.ts", "playwright/e2e/Features/ContextCenterPermission.spec.ts", "playwright/e2e/Features/DataQuality/TestCaseImportExportBasic.spec.ts", + "playwright/e2e/Features/SSOConfiguration.spec.ts", "playwright/e2e/Pages/DataContracts.spec.ts", "playwright/e2e/Pages/ODCSImportExport.spec.ts", "playwright/e2e/Pages/Users.spec.ts" @@ -7798,6 +7811,7 @@ "playwright/e2e/Features/AppMode/AppModeResolver.spec.ts", "playwright/e2e/Features/CustomizeNavigationNewItems.spec.ts", "playwright/e2e/Features/DataQuality/IncidentManagerLocaleLayout.spec.ts", + "playwright/e2e/Features/NavigationBlocker.spec.ts", "playwright/e2e/Features/RoleFixtureSessions.spec.ts", "playwright/e2e/Features/SettingsNavigationPage.spec.ts", "playwright/e2e/Pages/DataInsight.spec.ts" @@ -8072,33 +8086,6 @@ "playwright/e2e/Pages/SearchSettings.spec.ts" ] }, - { - "sources": [ - "openmetadata-ui/src/main/resources/ui/src/components/PaginationComponent/PaginationComponent.tsx" - ], - "specs": [ - "playwright/e2e/Features/AIMode/ConnectionServiceDetails.spec.ts", - "playwright/e2e/Features/Container.spec.ts", - "playwright/e2e/Features/Dashboards.spec.ts", - "playwright/e2e/Features/DataQuality/DataQuality.spec.ts", - "playwright/e2e/Features/DataQuality/DataQualityListAfterReindex.spec.ts", - "playwright/e2e/Features/DataQuality/IncidentManagerAfterReindex.spec.ts", - "playwright/e2e/Features/DataQuality/TableTestCasePagination.spec.ts", - "playwright/e2e/Features/DataQuality/TestDefinitionFilters.spec.ts", - "playwright/e2e/Features/DataQuality/TestDefinitionSortAndSearch.spec.ts", - "playwright/e2e/Features/DataQuality/TestLibrary.spec.ts", - "playwright/e2e/Features/Glossary/LargeGlossaryPerformance.spec.ts", - "playwright/e2e/Features/IncidentManagerPagination.spec.ts", - "playwright/e2e/Features/IngestionListNameSorting.spec.ts", - "playwright/e2e/Features/Pagination.spec.ts", - "playwright/e2e/Features/QueryEntity.spec.ts", - "playwright/e2e/Features/Table.spec.ts", - "playwright/e2e/Flow/UsersPagination.spec.ts", - "playwright/e2e/Pages/DataContracts.spec.ts", - "playwright/e2e/Pages/TestSuite.spec.ts", - "playwright/e2e/Search/ExploreSearchCounts.spec.ts" - ] - }, { "sources": [ "openmetadata-ui/src/main/resources/ui/src/components/Pipeline/Execution/Execution.component.tsx" @@ -8730,8 +8717,13 @@ "openmetadata-ui/src/main/resources/ui/src/components/SettingsSso/SSOConfigurationForm/SSOConfigurationForm.tsx" ], "specs": [ + "playwright/e2e/Features/ContextCenterDashboard.spec.ts", + "playwright/e2e/Features/ContextCenterDocument.spec.ts", + "playwright/e2e/Features/ContextCenterPermission.spec.ts", "playwright/e2e/Features/ProfileSsoSettings.spec.ts", - "playwright/e2e/Features/SSOConfiguration.spec.ts" + "playwright/e2e/Features/SSOConfiguration.spec.ts", + "playwright/e2e/Pages/DataContracts.spec.ts", + "playwright/e2e/Pages/ODCSImportExport.spec.ts" ] }, { @@ -8816,7 +8808,9 @@ ], "specs": [ "playwright/e2e/Features/BulkImport.spec.ts", - "playwright/e2e/Features/BulkImportWithDotInName.spec.ts" + "playwright/e2e/Features/BulkImportWithDotInName.spec.ts", + "playwright/e2e/Features/ClassificationImportExport.spec.ts", + "playwright/e2e/Features/MetricBulkImportExportEdit.spec.ts" ] }, { @@ -9834,6 +9828,7 @@ ], "specs": [ "playwright/e2e/Features/TeamsDragAndDrop.spec.ts", + "playwright/e2e/Pages/Entity.spec.ts", "playwright/e2e/Pages/ServiceListing.spec.ts" ] }, diff --git a/openmetadata-ui-core-components/src/main/resources/ui/src/components/application/accordion/accordion.test.tsx b/openmetadata-ui-core-components/src/main/resources/ui/src/components/application/accordion/accordion.test.tsx new file mode 100644 index 000000000000..4aa0de629d0b --- /dev/null +++ b/openmetadata-ui-core-components/src/main/resources/ui/src/components/application/accordion/accordion.test.tsx @@ -0,0 +1,45 @@ +/* + * Copyright 2025 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 { fireEvent, render, screen } from '@testing-library/react'; +import { describe, expect, it } from 'vitest'; +import { + Accordion, + AccordionHeader, + AccordionItem, + AccordionPanel, +} from './accordion'; + +describe('AccordionPanel', () => { + it('keeps validation fields mounted while collapsed', () => { + render( + + + Advanced + + + + + + ); + + expect(screen.getByLabelText('Token validity')).toBeInTheDocument(); + fireEvent.click(screen.getByRole('button', { name: 'Advanced' })); + fireEvent.change(screen.getByLabelText('Token validity'), { + target: { value: '7200' }, + }); + fireEvent.click(screen.getByRole('button', { name: 'Advanced' })); + fireEvent.click(screen.getByRole('button', { name: 'Advanced' })); + expect(screen.getByLabelText('Token validity')).toHaveValue('7200'); + }); +}); diff --git a/openmetadata-ui-core-components/src/main/resources/ui/src/components/application/app-navigation/base-components/nav-item-button.test.tsx b/openmetadata-ui-core-components/src/main/resources/ui/src/components/application/app-navigation/base-components/nav-item-button.test.tsx new file mode 100644 index 000000000000..c91b5766d295 --- /dev/null +++ b/openmetadata-ui-core-components/src/main/resources/ui/src/components/application/app-navigation/base-components/nav-item-button.test.tsx @@ -0,0 +1,53 @@ +/* + * Copyright 2026 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 { fireEvent, render, screen } from '@testing-library/react'; +import { RouterProvider } from 'react-aria-components'; +import { describe, expect, it, vi } from 'vitest'; +import { NavItemButton } from './nav-item-button'; + +const Icon = () => ; + +const renderButton = (navigate = vi.fn(), onClick = vi.fn()) => { + render( + + + + ); + + return { navigate, onClick, link: screen.getByRole('link') }; +}; + +describe('NavItemButton', () => { + it('navigates through the client router instead of reloading the page', () => { + const { navigate, onClick, link } = renderButton(); + + const notPrevented = fireEvent.click(link); + + expect(onClick).toHaveBeenCalled(); + expect(navigate).toHaveBeenCalledWith('/settings', undefined); + expect(notPrevented).toBe(false); + }); + + it('leaves modified clicks to the browser', () => { + const { navigate, link } = renderButton(); + + fireEvent.click(link, { metaKey: true }); + + expect(navigate).not.toHaveBeenCalled(); + }); +}); diff --git a/openmetadata-ui-core-components/src/main/resources/ui/src/components/application/app-navigation/base-components/nav-item-button.tsx b/openmetadata-ui-core-components/src/main/resources/ui/src/components/application/app-navigation/base-components/nav-item-button.tsx index 50ffb0c949e3..356978628e85 100644 --- a/openmetadata-ui-core-components/src/main/resources/ui/src/components/application/app-navigation/base-components/nav-item-button.tsx +++ b/openmetadata-ui-core-components/src/main/resources/ui/src/components/application/app-navigation/base-components/nav-item-button.tsx @@ -1,4 +1,5 @@ -import type { FC, MouseEventHandler } from 'react'; +import { shouldClientNavigate, useRouter } from '@react-aria/utils'; +import type { FC, MouseEvent, MouseEventHandler } from 'react'; import { Pressable } from 'react-aria-components'; import { Tooltip } from '@/components/base/tooltip/tooltip'; import { cx } from '@/utils/cx'; @@ -45,6 +46,23 @@ export const NavItemButton = ({ tooltipPlacement = 'right', onClick, }: NavItemButtonProps) => { + const router = useRouter(); + + // A plain anchor would reload the whole app; under a RouterProvider, hand + // same-tab clicks to the client router the way react-aria's Link does. + const handleClick = (event: MouseEvent) => { + onClick?.(event); + if ( + href && + !event.defaultPrevented && + !router.isNative && + shouldClientNavigate(event.currentTarget, event) + ) { + event.preventDefault(); + router.open(event.currentTarget, event, href, undefined); + } + }; + return ( @@ -52,13 +70,15 @@ export const NavItemButton = ({ aria-label={label} className={cx( 'tw:relative tw:flex tw:w-full tw:cursor-pointer tw:items-center tw:justify-center tw:rounded-md tw:bg-primary tw:dark:bg-transparent tw:p-2 tw:text-fg-quaternary tw:outline-focus-ring tw:transition tw:duration-100 tw:ease-linear tw:select-none tw:hover:bg-primary_hover tw:hover:text-fg-quaternary_hover tw:focus-visible:z-10 tw:focus-visible:outline-2 tw:focus-visible:outline-offset-2', + // Same current-page treatment as the expanded NavItemBase, so the + // collapsed rail still shows where the user is. current && - 'tw:bg-active tw:text-fg-quaternary_hover tw:hover:bg-secondary_hover', + 'tw:bg-brand-primary_alt tw:text-fg-brand-secondary_alt tw:hover:bg-brand-primary_alt tw:hover:text-fg-brand-secondary_alt', styles[size].root, className )} href={href} - onClick={onClick}> + onClick={handleClick}>