diff --git a/packages/javascript/bh-shared-ui/src/components/Navigation/AppLink.test.tsx b/packages/javascript/bh-shared-ui/src/components/Navigation/AppLink.test.tsx index c9f90477330..fb61a9dc9c5 100644 --- a/packages/javascript/bh-shared-ui/src/components/Navigation/AppLink.test.tsx +++ b/packages/javascript/bh-shared-ui/src/components/Navigation/AppLink.test.tsx @@ -16,7 +16,7 @@ import userEvent from '@testing-library/user-event'; import { Route, Routes } from 'react-router-dom'; -import { GloballySupportedSearchParams } from '../..'; +import { GloballySupportedSearchParams } from '../../hooks/useGlobalParamsExtension'; import { render } from '../../test-utils'; import { AppLink } from './AppLink'; diff --git a/packages/javascript/bh-shared-ui/src/components/Navigation/AppLink.tsx b/packages/javascript/bh-shared-ui/src/components/Navigation/AppLink.tsx index 93dcfd94aa7..e38a7b64992 100644 --- a/packages/javascript/bh-shared-ui/src/components/Navigation/AppLink.tsx +++ b/packages/javascript/bh-shared-ui/src/components/Navigation/AppLink.tsx @@ -15,12 +15,8 @@ // SPDX-License-Identifier: Apache-2.0 import { Link, LinkProps, Path } from 'react-router-dom'; -import { - AppNavigateProps, - GloballySupportedSearchParams, - applyPreservedParams, - persistSearchParams, -} from '../../utils/searchParams/searchParams'; +import { GloballySupportedSearchParams } from '../../hooks/useGlobalParamsExtension'; +import { AppNavigateProps, applyPreservedParams, persistSearchParams } from '../../utils/searchParams/searchParams'; export const AppLink = ({ children, to, discardQueryParams, ...props }: LinkProps & AppNavigateProps) => { const path = typeof to === 'string' ? to : (to as Partial).pathname || ''; diff --git a/packages/javascript/bh-shared-ui/src/components/Navigation/AppNavigate.test.tsx b/packages/javascript/bh-shared-ui/src/components/Navigation/AppNavigate.test.tsx index ffcb8bf39c4..dbff66d7543 100644 --- a/packages/javascript/bh-shared-ui/src/components/Navigation/AppNavigate.test.tsx +++ b/packages/javascript/bh-shared-ui/src/components/Navigation/AppNavigate.test.tsx @@ -15,7 +15,8 @@ // SPDX-License-Identifier: Apache-2.0 import { Route, Routes } from 'react-router-dom'; -import { GloballySupportedSearchParams } from '../..'; + +import { GloballySupportedSearchParams } from '../../hooks/useGlobalParamsExtension'; import { render } from '../../test-utils'; import { AppNavigate } from './AppNavigate'; diff --git a/packages/javascript/bh-shared-ui/src/components/Navigation/AppNavigate.tsx b/packages/javascript/bh-shared-ui/src/components/Navigation/AppNavigate.tsx index bcf8adc4472..2ffd81af2c0 100644 --- a/packages/javascript/bh-shared-ui/src/components/Navigation/AppNavigate.tsx +++ b/packages/javascript/bh-shared-ui/src/components/Navigation/AppNavigate.tsx @@ -15,12 +15,8 @@ // SPDX-License-Identifier: Apache-2.0 import React from 'react'; import { Navigate, NavigateProps } from 'react-router-dom'; -import { - AppNavigateProps, - GloballySupportedSearchParams, - applyPreservedParams, - persistSearchParams, -} from '../../utils/searchParams/searchParams'; +import { GloballySupportedSearchParams } from '../../hooks'; +import { AppNavigateProps, applyPreservedParams, persistSearchParams } from '../../utils/searchParams/searchParams'; export const AppNavigate: React.FC = (props) => { const { discardQueryParams, to, ...rest } = props; diff --git a/packages/javascript/bh-shared-ui/src/hooks/index.ts b/packages/javascript/bh-shared-ui/src/hooks/index.ts index eec43476d5e..34bf4a4164a 100644 --- a/packages/javascript/bh-shared-ui/src/hooks/index.ts +++ b/packages/javascript/bh-shared-ui/src/hooks/index.ts @@ -37,6 +37,7 @@ export * from './useFileIngest'; export * from './useFileUploadDialogContext'; export * from './useFileUploadQuery'; export * from './useFinishedJobs'; +export * from './useGlobalParamsExtension'; export * from './useGraphHasData'; export * from './useGraphItem'; export * from './useInitialEnvironment'; diff --git a/packages/javascript/bh-shared-ui/src/hooks/useGlobalParamsExtension.test.tsx b/packages/javascript/bh-shared-ui/src/hooks/useGlobalParamsExtension.test.tsx new file mode 100644 index 00000000000..3e3286d0cc9 --- /dev/null +++ b/packages/javascript/bh-shared-ui/src/hooks/useGlobalParamsExtension.test.tsx @@ -0,0 +1,31 @@ +// Copyright 2026 Specter Ops, Inc. +// +// Licensed under the Apache License, Version 2.0 +// 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. +// +// SPDX-License-Identifier: Apache-2.0 + +import { expectTypeOf } from 'vitest'; +import { type EnvironmentQueryParams } from './useEnvironmentParams'; +import { useGlobalParamsExtension } from './useGlobalParamsExtension'; + +type PageQueryParams = { + findingName: string | null; +}; + +describe('useGlobalParamsExtension', () => { + it('allows page query params to be appended to the return type', () => { + type ExtendedGlobalParams = ReturnType>; + + expectTypeOf().toEqualTypeOf(); + }); +}); diff --git a/packages/javascript/bh-shared-ui/src/hooks/useGlobalParamsExtension.tsx b/packages/javascript/bh-shared-ui/src/hooks/useGlobalParamsExtension.tsx new file mode 100644 index 00000000000..ee306b48e03 --- /dev/null +++ b/packages/javascript/bh-shared-ui/src/hooks/useGlobalParamsExtension.tsx @@ -0,0 +1,21 @@ +import { EnvironmentQueryParams, useEnvironmentParams } from './useEnvironmentParams'; +import { PZQueryParams, usePZQueryParams } from './usePZParams'; + +type GlobalParams = EnvironmentQueryParams & PZQueryParams; + +type GloballySupportedParamKeys = keyof GlobalParams; + +export type GlobalParamsExtension = GlobalParams & T; + +export const GloballySupportedSearchParams = [ + 'environmentId', + 'environmentAggregation', + 'assetGroupTagId', +] satisfies GloballySupportedParamKeys[]; + +// Params pulled into this hook will be plumbed into each page level param hook. +export const useGlobalParamsExtension = (): GlobalParams => { + const { setEnvironmentParams, ...environmentRest } = useEnvironmentParams(); + const { assetGroupTagId } = usePZQueryParams(); + return { ...environmentRest, assetGroupTagId }; +}; diff --git a/packages/javascript/bh-shared-ui/src/utils/searchParams/searchParams.ts b/packages/javascript/bh-shared-ui/src/utils/searchParams/searchParams.ts index 9666afb45a7..7c5d11de751 100644 --- a/packages/javascript/bh-shared-ui/src/utils/searchParams/searchParams.ts +++ b/packages/javascript/bh-shared-ui/src/utils/searchParams/searchParams.ts @@ -15,16 +15,11 @@ // SPDX-License-Identifier: Apache-2.0 import { createSearchParams, NavigateOptions, Path, To, useSearchParams } from 'react-router-dom'; -import { EnvironmentQueryParams } from '../../hooks/useEnvironmentParams'; -import { ExploreQueryParams } from '../../hooks/useExploreParams'; // FUTURE DEV: SetURLSearchParams is in both v6 and v7, but v6 uses this type internally and v7 exports it. // When we upgrade to v7, we can import SetURLSearchParams from react-router-dom type SetURLSearchParams = ReturnType[1]; -export type SearchParamKeys = keyof EnvironmentQueryParams | keyof ExploreQueryParams; -export const GloballySupportedSearchParams = ['environmentId', 'environmentAggregation'] satisfies SearchParamKeys[]; - type EmptyParam = undefined | null | ''; export type AppNavigateProps = { discardQueryParams?: boolean }; diff --git a/packages/javascript/bh-shared-ui/src/utils/searchParams/useAppNavigate.ts b/packages/javascript/bh-shared-ui/src/utils/searchParams/useAppNavigate.ts index c67e9c8e656..64436f27be3 100644 --- a/packages/javascript/bh-shared-ui/src/utils/searchParams/useAppNavigate.ts +++ b/packages/javascript/bh-shared-ui/src/utils/searchParams/useAppNavigate.ts @@ -15,12 +15,8 @@ // SPDX-License-Identifier: Apache-2.0 import { NavigateOptions, To, useNavigate } from 'react-router-dom'; -import { - AppNavigateProps, - GloballySupportedSearchParams, - applyPreservedParams, - persistSearchParams, -} from './searchParams'; +import { GloballySupportedSearchParams } from '../../hooks/useGlobalParamsExtension'; +import { AppNavigateProps, applyPreservedParams, persistSearchParams } from './searchParams'; export type AppNavigateOptions = NavigateOptions & AppNavigateProps;