mirror of
https://github.com/outbackdingo/openapi-ui.git
synced 2026-01-27 18:19:50 +00:00
custom navigation for search
This commit is contained in:
@@ -8,9 +8,10 @@ import { Styled } from './styled'
|
||||
|
||||
type THeaderProps = {
|
||||
inside?: boolean
|
||||
isSearch?: boolean
|
||||
}
|
||||
|
||||
export const HeaderSecond: FC<THeaderProps> = ({ inside }) => {
|
||||
export const HeaderSecond: FC<THeaderProps> = ({ inside, isSearch }) => {
|
||||
// const { projectName, instanceName, clusterName, entryType, namespace, syntheticProject } = useParams()
|
||||
const { projectName, instanceName, clusterName, namespace, syntheticProject } = useParams()
|
||||
const { token } = theme.useToken()
|
||||
@@ -24,14 +25,14 @@ export const HeaderSecond: FC<THeaderProps> = ({ inside }) => {
|
||||
<Flex gap={18}>
|
||||
{inside ? <SelectorClusterInside clusterName={clusterName} /> : <SelectorCluster clusterName={clusterName} />}
|
||||
{inside && <SelectorInside clusterName={clusterName} namespace={namespace} />}
|
||||
{!inside && BASE_USE_NAMESPACE_NAV !== 'true' && (
|
||||
{!inside && !isSearch && BASE_USE_NAMESPACE_NAV !== 'true' && (
|
||||
<Selector
|
||||
clusterName={clusterName}
|
||||
projectName={projectName || possibleProject}
|
||||
instanceName={instanceName || possibleInstance}
|
||||
/>
|
||||
)}
|
||||
{!inside && BASE_USE_NAMESPACE_NAV === 'true' && (
|
||||
{!inside && (isSearch || BASE_USE_NAMESPACE_NAV === 'true') && (
|
||||
<SelectorNamespace clusterName={clusterName} namespace={namespace} />
|
||||
)}
|
||||
</Flex>
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
import React, { FC, useState } from 'react'
|
||||
import { Flex, Typography } from 'antd'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
import { useDirectUnknownResource } from '@prorobotech/openapi-k8s-toolkit'
|
||||
import { useSelector } from 'react-redux'
|
||||
import type { RootState } from 'store/store'
|
||||
import { useNavSelectorInside } from 'hooks/useNavSelectorInside'
|
||||
import { useMountEffect } from 'hooks/useMountEffect'
|
||||
import { useIsSearchPage } from 'hooks/useIsSearchPage'
|
||||
import { EntrySelect } from 'components/atoms'
|
||||
import {
|
||||
BASE_API_GROUP,
|
||||
@@ -19,6 +22,9 @@ type TSelectorNamespaceProps = {
|
||||
|
||||
export const SelectorNamespace: FC<TSelectorNamespaceProps> = ({ clusterName, namespace }) => {
|
||||
const navigate = useNavigate()
|
||||
const location = useLocation()
|
||||
|
||||
const baseprefix = useSelector((state: RootState) => state.baseprefix.baseprefix)
|
||||
|
||||
const [selectedClusterName, setSelectedClusterName] = useState(clusterName)
|
||||
const [selectedNamespace, setSelectedNamespace] = useState(namespace)
|
||||
@@ -34,7 +40,45 @@ export const SelectorNamespace: FC<TSelectorNamespaceProps> = ({ clusterName, na
|
||||
isEnabled: clusterName !== undefined,
|
||||
})
|
||||
|
||||
const isSearchPage = useIsSearchPage(baseprefix || '')
|
||||
|
||||
const handleNamepsaceChange = (value?: string) => {
|
||||
if (isSearchPage) {
|
||||
const { pathname, search, hash } = location
|
||||
const segs = pathname.split('/')
|
||||
|
||||
// Assume pattern: /prefix/:clusterName/:namespace?/:syntheticProject?/search/*
|
||||
// Find the "search" segment index
|
||||
const searchIdx = segs.indexOf('search')
|
||||
const clusterIdx = segs.indexOf(selectedClusterName || '')
|
||||
if (clusterIdx === -1) {
|
||||
return
|
||||
} // bail if we can't find the cluster
|
||||
|
||||
const nsIdx = clusterIdx + 1 // where namespace would live if present
|
||||
const spIdx = clusterIdx + 2 // where syntheticProject would live if present
|
||||
const nsExists = nsIdx < searchIdx // true if something occupies ns slot
|
||||
const spExists = spIdx < searchIdx // true if something occupies sp slot
|
||||
|
||||
if (value && value !== 'all') {
|
||||
setSelectedNamespace(value)
|
||||
|
||||
if (nsExists) {
|
||||
// replace namespace in place
|
||||
segs[nsIdx] = value
|
||||
} else {
|
||||
// insert namespace before "search" (or before syntheticProject if present)
|
||||
const insertAt = spExists ? spIdx : searchIdx
|
||||
segs.splice(insertAt, 0, value)
|
||||
}
|
||||
} else if (nsExists) {
|
||||
segs.splice(nsIdx, 1) // removes namespace; syntheticProject (if any) shifts left
|
||||
}
|
||||
// if ns didn't exist, nothing to clear
|
||||
|
||||
navigate(segs.join('/') + search + hash, { replace: true })
|
||||
return
|
||||
}
|
||||
if (value && value !== 'all') {
|
||||
setSelectedNamespace(value)
|
||||
const changeUrl =
|
||||
|
||||
1
src/hooks/useIsSearchPage/index.ts
Normal file
1
src/hooks/useIsSearchPage/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './useIsSearchPage'
|
||||
9
src/hooks/useIsSearchPage/useIsSearchPage.ts
Normal file
9
src/hooks/useIsSearchPage/useIsSearchPage.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { useLocation, matchPath } from 'react-router-dom'
|
||||
|
||||
export const useIsSearchPage = (prefix: string) => {
|
||||
const { pathname } = useLocation()
|
||||
const base = `/${prefix}`.replace(/\/{2,}/g, '/').replace(/\/$/, '')
|
||||
const pattern = `${base}/:clusterName/:namespace?/:syntheticProject?/search/*`
|
||||
|
||||
return Boolean(matchPath({ path: pattern }, pathname))
|
||||
}
|
||||
@@ -26,6 +26,7 @@ export const SearchPage: FC<TSearchPageProps> = ({ forcedTheme }) => {
|
||||
<BaseTemplate
|
||||
forcedTheme={forcedTheme}
|
||||
inside={false}
|
||||
isSearch
|
||||
sidebar={
|
||||
<ManageableSidebar
|
||||
instanceName={possibleInstance}
|
||||
|
||||
@@ -24,10 +24,18 @@ type TBaseTemplateProps = {
|
||||
children?: ReactNode | undefined
|
||||
forcedTheme?: 'dark' | 'light'
|
||||
inside?: boolean
|
||||
isSearch?: boolean
|
||||
sidebar?: ReactNode
|
||||
}
|
||||
|
||||
export const BaseTemplate: FC<TBaseTemplateProps> = ({ children, withNoCluster, forcedTheme, inside, sidebar }) => {
|
||||
export const BaseTemplate: FC<TBaseTemplateProps> = ({
|
||||
children,
|
||||
withNoCluster,
|
||||
forcedTheme,
|
||||
inside,
|
||||
isSearch,
|
||||
sidebar,
|
||||
}) => {
|
||||
const navigate = useNavigate()
|
||||
const { clusterName } = useParams()
|
||||
const { useToken } = antdtheme
|
||||
@@ -106,7 +114,7 @@ export const BaseTemplate: FC<TBaseTemplateProps> = ({ children, withNoCluster,
|
||||
</Col>
|
||||
<FlexCol flex="auto">
|
||||
<DefaultLayout.ContentPadding $isFederation={isFederation}>
|
||||
<HeaderSecond inside={inside} />
|
||||
<HeaderSecond inside={inside} isSearch={isSearch} />
|
||||
{clusterListQuery.error && (
|
||||
<Alert message={`Cluster List Error: ${clusterListQuery.error?.message} `} type="error" />
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user