mirror of
https://github.com/outbackdingo/openapi-ui.git
synced 2026-01-27 18:19:50 +00:00
search wip: tables
This commit is contained in:
8
package-lock.json
generated
8
package-lock.json
generated
@@ -11,7 +11,7 @@
|
||||
"@ant-design/icons": "5.6.0",
|
||||
"@monaco-editor/react": "4.6.0",
|
||||
"@originjs/vite-plugin-federation": "1.3.6",
|
||||
"@prorobotech/openapi-k8s-toolkit": "^0.0.1-alpha.118",
|
||||
"@prorobotech/openapi-k8s-toolkit": "^0.0.1-alpha.119",
|
||||
"@readme/openapi-parser": "4.0.0",
|
||||
"@reduxjs/toolkit": "2.2.5",
|
||||
"@tanstack/react-query": "5.62.2",
|
||||
@@ -2802,9 +2802,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@prorobotech/openapi-k8s-toolkit": {
|
||||
"version": "0.0.1-alpha.118",
|
||||
"resolved": "https://registry.npmjs.org/@prorobotech/openapi-k8s-toolkit/-/openapi-k8s-toolkit-0.0.1-alpha.118.tgz",
|
||||
"integrity": "sha512-DGEug01G2lioiRHNmjSRecL0tOtBMuSOK3tV6EMwsOm8Cwl+HwQvEzEdpIhMU+r8/iUPQ1Q+ZGeoi5dYMmPWpA==",
|
||||
"version": "0.0.1-alpha.119",
|
||||
"resolved": "https://registry.npmjs.org/@prorobotech/openapi-k8s-toolkit/-/openapi-k8s-toolkit-0.0.1-alpha.119.tgz",
|
||||
"integrity": "sha512-e0AwwmMBAyjrpTPWMC9eSiyUimTzxskaNhAzs/+7DV7u0MqjJLOPehsko/AIpm/RkOoU6qOYjAHTjWZHV1hLhA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@monaco-editor/react": "4.6.0",
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
"@ant-design/icons": "5.6.0",
|
||||
"@monaco-editor/react": "4.6.0",
|
||||
"@originjs/vite-plugin-federation": "1.3.6",
|
||||
"@prorobotech/openapi-k8s-toolkit": "0.0.1-alpha.118",
|
||||
"@prorobotech/openapi-k8s-toolkit": "0.0.1-alpha.119",
|
||||
"@readme/openapi-parser": "4.0.0",
|
||||
"@reduxjs/toolkit": "2.2.5",
|
||||
"@tanstack/react-query": "5.62.2",
|
||||
|
||||
341
src/components/molecules/TableApiBuiltin/TableApiBuiltin.tsx
Normal file
341
src/components/molecules/TableApiBuiltin/TableApiBuiltin.tsx
Normal file
@@ -0,0 +1,341 @@
|
||||
/* eslint-disable max-lines-per-function */
|
||||
import React, { FC, useState, useEffect } from 'react'
|
||||
import { useLocation, useNavigate, useParams } from 'react-router-dom'
|
||||
import { Spin, Alert, Button, Flex } from 'antd'
|
||||
import { PlusOutlined, ClearOutlined, MinusOutlined } from '@ant-design/icons'
|
||||
import { useSelector } from 'react-redux'
|
||||
import { RootState } from 'store/store'
|
||||
import {
|
||||
EnrichedTableProvider,
|
||||
usePermissions,
|
||||
DeleteModal,
|
||||
DeleteModalMany,
|
||||
checkIfBuiltInInstanceNamespaceScoped,
|
||||
checkIfApiInstanceNamespaceScoped,
|
||||
useBuiltinResources,
|
||||
useApiResources,
|
||||
} from '@prorobotech/openapi-k8s-toolkit'
|
||||
import { FlexGrow, PaddingContainer } from 'components'
|
||||
import { TABLE_PROPS } from 'constants/tableProps'
|
||||
import {
|
||||
HEAD_FIRST_ROW,
|
||||
HEAD_SECOND_ROW,
|
||||
FOOTER_HEIGHT,
|
||||
NAV_HEIGHT,
|
||||
CONTENT_CARD_PADDING,
|
||||
TABLE_ADD_BUTTON_HEIGHT,
|
||||
} from 'constants/blocksSizes'
|
||||
import { OverflowContainer } from './atoms'
|
||||
import { getBackLinkToTable, getLinkToForm } from './utils'
|
||||
|
||||
type TTableApiBuiltinProps = {
|
||||
namespace?: string
|
||||
resourceType: 'builtin' | 'api'
|
||||
apiGroup?: string // api
|
||||
apiVersion?: string // api
|
||||
typeName: string
|
||||
limit: string | null
|
||||
inside?: boolean
|
||||
customizationIdPrefix: string
|
||||
searchMount?: boolean
|
||||
}
|
||||
|
||||
export const TableApiBuiltin: FC<TTableApiBuiltinProps> = ({
|
||||
namespace,
|
||||
resourceType,
|
||||
apiGroup,
|
||||
apiVersion,
|
||||
typeName,
|
||||
limit,
|
||||
inside,
|
||||
customizationIdPrefix,
|
||||
searchMount,
|
||||
}) => {
|
||||
const location = useLocation()
|
||||
const navigate = useNavigate()
|
||||
const params = useParams()
|
||||
const cluster = useSelector((state: RootState) => state.cluster.cluster)
|
||||
const theme = useSelector((state: RootState) => state.openapiTheme.theme)
|
||||
const baseprefix = useSelector((state: RootState) => state.baseprefix.baseprefix)
|
||||
|
||||
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState<false | { name: string; endpoint: string }>(false)
|
||||
const [isDeleteModalManyOpen, setIsDeleteModalManyOpen] = useState<false | { name: string; endpoint: string }[]>(
|
||||
false,
|
||||
)
|
||||
const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([])
|
||||
const [selectedRowsData, setSelectedRowsData] = useState<{ name: string; endpoint: string }[]>([])
|
||||
const [isNamespaced, setIsNamespaced] = useState<boolean>()
|
||||
|
||||
const [height, setHeight] = useState(0)
|
||||
|
||||
useEffect(() => {
|
||||
const height =
|
||||
window.innerHeight -
|
||||
HEAD_FIRST_ROW -
|
||||
HEAD_SECOND_ROW -
|
||||
NAV_HEIGHT -
|
||||
CONTENT_CARD_PADDING * 2 -
|
||||
FOOTER_HEIGHT -
|
||||
TABLE_ADD_BUTTON_HEIGHT
|
||||
setHeight(height)
|
||||
|
||||
const handleResize = () => {
|
||||
setHeight(height)
|
||||
}
|
||||
|
||||
window.addEventListener('resize', handleResize)
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('resize', handleResize)
|
||||
}
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
if (resourceType === 'builtin') {
|
||||
checkIfBuiltInInstanceNamespaceScoped({
|
||||
typeName,
|
||||
clusterName: cluster,
|
||||
}).then(({ isNamespaceScoped }) => {
|
||||
if (isNamespaceScoped) {
|
||||
setIsNamespaced(isNamespaceScoped)
|
||||
}
|
||||
})
|
||||
}
|
||||
if (resourceType === 'api' && apiGroup && apiVersion) {
|
||||
checkIfApiInstanceNamespaceScoped({
|
||||
apiGroup,
|
||||
apiVersion,
|
||||
typeName,
|
||||
clusterName: cluster,
|
||||
}).then(({ isNamespaceScoped }) => {
|
||||
if (isNamespaceScoped) {
|
||||
setIsNamespaced(true)
|
||||
}
|
||||
})
|
||||
}
|
||||
}, [resourceType, cluster, typeName, apiGroup, apiVersion])
|
||||
|
||||
const createPermission = usePermissions({
|
||||
apiGroup: apiGroup || '',
|
||||
typeName,
|
||||
namespace: '',
|
||||
clusterName: cluster,
|
||||
verb: 'create',
|
||||
refetchInterval: false,
|
||||
})
|
||||
|
||||
const updatePermission = usePermissions({
|
||||
apiGroup: apiGroup || '',
|
||||
typeName,
|
||||
namespace: '',
|
||||
clusterName: cluster,
|
||||
verb: 'update',
|
||||
refetchInterval: false,
|
||||
})
|
||||
|
||||
const deletePermission = usePermissions({
|
||||
apiGroup: apiGroup || '',
|
||||
typeName,
|
||||
namespace: '',
|
||||
clusterName: cluster,
|
||||
verb: 'delete',
|
||||
refetchInterval: false,
|
||||
})
|
||||
|
||||
const {
|
||||
isPending: isPendingBuiltin,
|
||||
error: errorBuiltin,
|
||||
data: dataBuiltin,
|
||||
} = useBuiltinResources({
|
||||
clusterName: cluster,
|
||||
namespace,
|
||||
typeName,
|
||||
limit,
|
||||
isEnabled: resourceType === 'builtin',
|
||||
})
|
||||
|
||||
const {
|
||||
isPending: isPendingApi,
|
||||
error: errorApi,
|
||||
data: dataApi,
|
||||
} = useApiResources({
|
||||
clusterName: cluster,
|
||||
namespace,
|
||||
apiGroup: apiGroup || '',
|
||||
apiVersion: apiVersion || '',
|
||||
typeName,
|
||||
limit,
|
||||
isEnabled: resourceType === 'api' && !!apiGroup && !!apiVersion,
|
||||
})
|
||||
|
||||
const onDeleteHandle = (name: string, endpoint: string) => {
|
||||
setIsDeleteModalOpen({ name, endpoint })
|
||||
}
|
||||
|
||||
const clearSelected = () => {
|
||||
setSelectedRowKeys([])
|
||||
setSelectedRowsData([])
|
||||
}
|
||||
|
||||
const replaceValuesPartsOfUrls = location.pathname
|
||||
.split('/')
|
||||
.reduce<Record<string, string | undefined>>((acc, value, index) => {
|
||||
acc[index.toString()] = value
|
||||
return acc
|
||||
}, {})
|
||||
|
||||
return (
|
||||
<>
|
||||
{((resourceType === 'builtin' && isPendingBuiltin) || (resourceType === 'api' && isPendingApi)) && <Spin />}
|
||||
{resourceType === 'builtin' && errorBuiltin && (
|
||||
<Alert message={`An error has occurred: ${errorBuiltin?.message} `} type="error" />
|
||||
)}
|
||||
{resourceType === 'api' && errorApi && (
|
||||
<Alert message={`An error has occurred: ${errorApi?.message} `} type="error" />
|
||||
)}
|
||||
<OverflowContainer height={height} searchMount={searchMount}>
|
||||
{!errorBuiltin &&
|
||||
!errorApi &&
|
||||
((resourceType === 'builtin' && dataBuiltin) || (resourceType === 'api' && dataApi)) && (
|
||||
<EnrichedTableProvider
|
||||
key={resourceType === 'builtin' ? `/v1/${typeName}` : `/${apiGroup}/${apiVersion}/${typeName}`}
|
||||
customizationId={
|
||||
resourceType === 'builtin'
|
||||
? `${customizationIdPrefix}/v1/${typeName}`
|
||||
: `${customizationIdPrefix}/${apiGroup}/${apiVersion}/${typeName}`
|
||||
}
|
||||
tableMappingsReplaceValues={{
|
||||
clusterName: params.clusterName,
|
||||
projectName: params.projectName,
|
||||
instanceName: params.instanceName,
|
||||
namespace: params.namespace,
|
||||
syntheticProject: params.syntheticProject,
|
||||
entryType: params.entryType,
|
||||
apiGroup: params.apiGroup,
|
||||
apiVersion: params.apiVersion,
|
||||
typeName: params.typeName,
|
||||
entryName: params.entryName,
|
||||
apiExtensionVersion: params.apiExtensionVersion,
|
||||
crdName: params.crdName,
|
||||
...replaceValuesPartsOfUrls,
|
||||
}}
|
||||
cluster={cluster}
|
||||
theme={theme}
|
||||
baseprefix={inside ? `${baseprefix}/inside` : baseprefix}
|
||||
dataItems={resourceType === 'builtin' ? dataBuiltin?.items || [] : dataApi?.items || []}
|
||||
dataForControls={{
|
||||
cluster,
|
||||
syntheticProject: params.syntheticProject,
|
||||
pathPrefix: resourceType === 'builtin' ? 'forms/builtin' : 'forms/apis',
|
||||
typeName,
|
||||
apiVersion: resourceType === 'builtin' ? 'v1' : `${apiGroup}/${apiVersion}`,
|
||||
backlink: getBackLinkToTable({
|
||||
resourceType,
|
||||
cluster,
|
||||
baseprefix,
|
||||
namespace,
|
||||
syntheticProject: params.syntheticProject,
|
||||
apiGroup,
|
||||
apiVersion,
|
||||
typeName,
|
||||
inside,
|
||||
}),
|
||||
deletePathPrefix:
|
||||
resourceType === 'builtin' ? `/api/clusters/${cluster}/k8s/api` : `/api/clusters/${cluster}/k8s/apis`,
|
||||
onDeleteHandle,
|
||||
permissions: {
|
||||
canUpdate: isNamespaced ? true : updatePermission.data?.status.allowed,
|
||||
canDelete: isNamespaced ? true : deletePermission.data?.status.allowed,
|
||||
},
|
||||
}}
|
||||
selectData={{
|
||||
selectedRowKeys,
|
||||
onChange: (selectedRowKeys: React.Key[], selectedRowsData: { name: string; endpoint: string }[]) => {
|
||||
setSelectedRowKeys(selectedRowKeys)
|
||||
setSelectedRowsData(selectedRowsData)
|
||||
},
|
||||
}}
|
||||
tableProps={{ ...TABLE_PROPS, disablePagination: !searchMount }}
|
||||
// maxHeight={height - 65}
|
||||
/>
|
||||
)}
|
||||
{/* {selectedRowKeys.length > 0 && (
|
||||
<MarginTopContainer $top={-40}>
|
||||
<Flex gap={16}>
|
||||
<Button type="primary" onClick={clearSelected}>
|
||||
<ClearOutlined />
|
||||
Clear
|
||||
</Button>
|
||||
<Button type="primary" onClick={() => setIsDeleteModalManyOpen(selectedRowsData)}>
|
||||
<MinusOutlined />
|
||||
Delete
|
||||
</Button>
|
||||
</Flex>
|
||||
</MarginTopContainer>
|
||||
)} */}
|
||||
</OverflowContainer>
|
||||
{!searchMount && (
|
||||
<>
|
||||
<FlexGrow />
|
||||
<PaddingContainer $padding="4px">
|
||||
<Flex justify="space-between">
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={() => {
|
||||
const url = getLinkToForm({
|
||||
resourceType,
|
||||
cluster,
|
||||
baseprefix,
|
||||
namespace,
|
||||
syntheticProject: params.syntheticProject,
|
||||
apiGroup,
|
||||
apiVersion,
|
||||
typeName,
|
||||
inside,
|
||||
})
|
||||
navigate(url)
|
||||
}}
|
||||
loading={isNamespaced ? false : createPermission.isPending}
|
||||
disabled={isNamespaced ? false : !createPermission.data?.status.allowed}
|
||||
>
|
||||
<PlusOutlined />
|
||||
Add
|
||||
</Button>
|
||||
{selectedRowKeys.length > 0 && (
|
||||
<Flex gap={16}>
|
||||
<Button type="primary" onClick={clearSelected}>
|
||||
<ClearOutlined />
|
||||
Clear
|
||||
</Button>
|
||||
<Button type="primary" onClick={() => setIsDeleteModalManyOpen(selectedRowsData)}>
|
||||
<MinusOutlined />
|
||||
Delete
|
||||
</Button>
|
||||
</Flex>
|
||||
)}
|
||||
</Flex>
|
||||
</PaddingContainer>
|
||||
</>
|
||||
)}
|
||||
{isDeleteModalOpen && (
|
||||
<DeleteModal
|
||||
name={isDeleteModalOpen.name}
|
||||
onClose={() => {
|
||||
setIsDeleteModalOpen(false)
|
||||
clearSelected()
|
||||
}}
|
||||
endpoint={isDeleteModalOpen.endpoint}
|
||||
/>
|
||||
)}
|
||||
{isDeleteModalManyOpen !== false && (
|
||||
<DeleteModalMany
|
||||
data={isDeleteModalManyOpen}
|
||||
onClose={() => {
|
||||
setIsDeleteModalManyOpen(false)
|
||||
clearSelected()
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/* eslint-disable max-lines-per-function */
|
||||
import React, { FC, PropsWithChildren } from 'react'
|
||||
import { OverflowMaxHeightContainer } from 'components'
|
||||
|
||||
type TOverflowContainerProps = PropsWithChildren<{
|
||||
height: number
|
||||
searchMount?: boolean
|
||||
}>
|
||||
|
||||
export const OverflowContainer: FC<TOverflowContainerProps> = ({ height, searchMount, children }) => {
|
||||
if (searchMount) {
|
||||
// eslint-disable-next-line react/jsx-no-useless-fragment
|
||||
return <>{children}</>
|
||||
}
|
||||
|
||||
return <OverflowMaxHeightContainer $maxHeight={height}>{children}</OverflowMaxHeightContainer>
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './OverflowContainer'
|
||||
1
src/components/molecules/TableApiBuiltin/atoms/index.ts
Normal file
1
src/components/molecules/TableApiBuiltin/atoms/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './OverflowContainer'
|
||||
1
src/components/molecules/TableApiBuiltin/index.ts
Normal file
1
src/components/molecules/TableApiBuiltin/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './TableApiBuiltin'
|
||||
136
src/components/molecules/TableApiBuiltin/utils.ts
Normal file
136
src/components/molecules/TableApiBuiltin/utils.ts
Normal file
@@ -0,0 +1,136 @@
|
||||
export const getBackLinkToBuiltinTable = ({
|
||||
cluster,
|
||||
baseprefix,
|
||||
namespace,
|
||||
syntheticProject,
|
||||
typeName,
|
||||
inside,
|
||||
}: {
|
||||
cluster: string
|
||||
baseprefix?: string
|
||||
namespace?: string
|
||||
syntheticProject?: string
|
||||
typeName: string
|
||||
inside?: boolean
|
||||
}): string => {
|
||||
const root = `${baseprefix}${inside ? '/inside' : ''}/${cluster}`
|
||||
const mainRoute = `${root}${namespace ? `/${namespace}` : ''}${syntheticProject ? `/${syntheticProject}` : ''}`
|
||||
|
||||
return `${mainRoute}/builtin-table/${typeName}`
|
||||
}
|
||||
|
||||
export const getBackLinkToApiTable = ({
|
||||
cluster,
|
||||
baseprefix,
|
||||
namespace,
|
||||
syntheticProject,
|
||||
apiGroup,
|
||||
apiVersion,
|
||||
typeName,
|
||||
inside,
|
||||
}: {
|
||||
cluster: string
|
||||
baseprefix?: string
|
||||
namespace?: string
|
||||
syntheticProject?: string
|
||||
apiGroup?: string // api
|
||||
apiVersion?: string // api
|
||||
typeName: string
|
||||
inside?: boolean
|
||||
}): string => {
|
||||
const root = `${baseprefix}${inside ? '/inside' : ''}/${cluster}`
|
||||
const mainRoute = `${root}${namespace ? `/${namespace}` : ''}${syntheticProject ? `/${syntheticProject}` : ''}`
|
||||
|
||||
return `${mainRoute}/api-table/${apiGroup}/${apiVersion}/${typeName}`
|
||||
}
|
||||
|
||||
export const getBackLinkToTable = ({
|
||||
resourceType,
|
||||
...rest
|
||||
}: {
|
||||
resourceType: 'builtin' | 'api'
|
||||
cluster: string
|
||||
baseprefix?: string
|
||||
namespace?: string
|
||||
syntheticProject?: string
|
||||
apiGroup?: string // api
|
||||
apiVersion?: string // api
|
||||
typeName: string
|
||||
inside?: boolean
|
||||
}): string => {
|
||||
return resourceType === 'builtin' ? getBackLinkToBuiltinTable({ ...rest }) : getBackLinkToApiTable({ ...rest })
|
||||
}
|
||||
|
||||
export const getLinkToBuiltinForm = ({
|
||||
cluster,
|
||||
baseprefix,
|
||||
namespace,
|
||||
syntheticProject,
|
||||
typeName,
|
||||
inside,
|
||||
}: {
|
||||
cluster: string
|
||||
baseprefix?: string
|
||||
namespace?: string
|
||||
syntheticProject?: string
|
||||
typeName: string
|
||||
inside?: boolean
|
||||
}): string => {
|
||||
const root = `${baseprefix}${inside ? '/inside' : ''}/${cluster}`
|
||||
const mainRoute = `${root}${namespace ? `/${namespace}` : ''}${syntheticProject ? `/${syntheticProject}` : ''}`
|
||||
const backlink = getBackLinkToBuiltinTable({ cluster, baseprefix, namespace, syntheticProject, typeName, inside })
|
||||
|
||||
return `${mainRoute}/forms/builtin/v1/${typeName}?backlink=${backlink}`
|
||||
}
|
||||
|
||||
export const getLinkToApiForm = ({
|
||||
cluster,
|
||||
baseprefix,
|
||||
namespace,
|
||||
syntheticProject,
|
||||
apiGroup,
|
||||
apiVersion,
|
||||
typeName,
|
||||
inside,
|
||||
}: {
|
||||
cluster: string
|
||||
baseprefix?: string
|
||||
namespace?: string
|
||||
syntheticProject?: string
|
||||
apiGroup?: string // api
|
||||
apiVersion?: string // api
|
||||
typeName: string
|
||||
inside?: boolean
|
||||
}): string => {
|
||||
const root = `${baseprefix}${inside ? '/inside' : ''}/${cluster}`
|
||||
const mainRoute = `${root}${namespace ? `/${namespace}` : ''}${syntheticProject ? `/${syntheticProject}` : ''}`
|
||||
const backlink = getBackLinkToApiTable({
|
||||
cluster,
|
||||
baseprefix,
|
||||
namespace,
|
||||
syntheticProject,
|
||||
apiGroup,
|
||||
apiVersion,
|
||||
typeName,
|
||||
inside,
|
||||
})
|
||||
|
||||
return `${mainRoute}/forms/apis/${apiGroup}/${apiVersion}/${typeName}?backlink=${backlink}`
|
||||
}
|
||||
|
||||
export const getLinkToForm = ({
|
||||
resourceType,
|
||||
...rest
|
||||
}: {
|
||||
resourceType: 'builtin' | 'api'
|
||||
cluster: string
|
||||
baseprefix?: string
|
||||
namespace?: string
|
||||
syntheticProject?: string
|
||||
apiGroup?: string // api
|
||||
apiVersion?: string // api
|
||||
typeName: string
|
||||
inside?: boolean
|
||||
}): string => {
|
||||
return resourceType === 'builtin' ? getLinkToBuiltinForm({ ...rest }) : getLinkToApiForm({ ...rest })
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
export * from './BlackholeForm'
|
||||
export * from './ManageableBreadcrumbs'
|
||||
export * from './ManageableSidebar'
|
||||
export * from './TableCrdInfo'
|
||||
export * from './TableApiBuiltin'
|
||||
|
||||
@@ -1,11 +1,24 @@
|
||||
/* eslint-disable max-lines-per-function */
|
||||
import React, { FC } from 'react'
|
||||
import { Search as PackageSearch } from '@prorobotech/openapi-k8s-toolkit'
|
||||
import React, { FC, Fragment, useState } from 'react'
|
||||
import { Search as PackageSearch, Spacer } from '@prorobotech/openapi-k8s-toolkit'
|
||||
import { useSelector } from 'react-redux'
|
||||
import { RootState } from 'store/store'
|
||||
import { SearchEntry } from './molecules'
|
||||
|
||||
export const Search: FC = () => {
|
||||
const cluster = useSelector((state: RootState) => state.cluster.cluster)
|
||||
|
||||
return <PackageSearch cluster={cluster} />
|
||||
const [currentSearch, setCurrentSearch] = useState<string[]>()
|
||||
|
||||
return (
|
||||
<>
|
||||
<PackageSearch cluster={cluster} updateCurrentSearch={value => setCurrentSearch(value)} />
|
||||
{currentSearch?.map(item => (
|
||||
<Fragment key={item}>
|
||||
<SearchEntry resource={item} />
|
||||
<Spacer $space={50} $samespace />
|
||||
</Fragment>
|
||||
))}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
import React, { FC } from 'react'
|
||||
import { useParams, useSearchParams } from 'react-router-dom'
|
||||
import { Typography } from 'antd'
|
||||
import { TableApiBuiltin } from 'components'
|
||||
import { getTableCustomizationIdPrefix } from 'utils/getTableCustomizationIdPrefix'
|
||||
import { BASE_USE_NAMESPACE_NAV } from 'constants/customizationApiGroupAndVersion'
|
||||
|
||||
type TSearchEntryProps = {
|
||||
resource: string
|
||||
}
|
||||
|
||||
export const SearchEntry: FC<TSearchEntryProps> = ({ resource }) => {
|
||||
const { namespace, syntheticProject } = useParams()
|
||||
const [searchParams] = useSearchParams()
|
||||
|
||||
const [apiGroup, apiVersion, typeName] = resource.split('~')
|
||||
|
||||
const tableCustomizationIdPrefix = getTableCustomizationIdPrefix({
|
||||
instance: !!syntheticProject,
|
||||
project: BASE_USE_NAMESPACE_NAV !== 'true' && !!namespace,
|
||||
namespace: !!namespace,
|
||||
search: true,
|
||||
})
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Typography.Title level={4}>
|
||||
{apiGroup.length > 0 ? `${apiGroup}/${apiVersion}/` : 'v1/'}
|
||||
{typeName}
|
||||
</Typography.Title>
|
||||
{typeName && apiGroup && apiVersion && (
|
||||
<TableApiBuiltin
|
||||
resourceType={apiGroup ? 'api' : 'builtin'}
|
||||
namespace={namespace}
|
||||
apiGroup={apiGroup.length > 0 ? apiGroup : undefined}
|
||||
apiVersion={apiGroup.length > 0 ? apiVersion : undefined}
|
||||
typeName={typeName}
|
||||
limit={searchParams.get('limit')}
|
||||
customizationIdPrefix={tableCustomizationIdPrefix}
|
||||
searchMount
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './SearchEntry'
|
||||
1
src/components/organisms/Search/molecules/index.ts
Normal file
1
src/components/organisms/Search/molecules/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './SearchEntry'
|
||||
@@ -1,267 +0,0 @@
|
||||
import React, { FC, useState, useEffect } from 'react'
|
||||
import { useLocation, useNavigate, useParams } from 'react-router-dom'
|
||||
import { Spin, Alert, Button, Flex } from 'antd'
|
||||
import { PlusOutlined, ClearOutlined, MinusOutlined } from '@ant-design/icons'
|
||||
import { useSelector } from 'react-redux'
|
||||
import { RootState } from 'store/store'
|
||||
import {
|
||||
EnrichedTableProvider,
|
||||
usePermissions,
|
||||
DeleteModal,
|
||||
DeleteModalMany,
|
||||
checkIfBuiltInInstanceNamespaceScoped,
|
||||
useBuiltinResources,
|
||||
} from '@prorobotech/openapi-k8s-toolkit'
|
||||
import { FlexGrow, OverflowMaxHeightContainer, PaddingContainer } from 'components'
|
||||
import { TABLE_PROPS } from 'constants/tableProps'
|
||||
import {
|
||||
HEAD_FIRST_ROW,
|
||||
HEAD_SECOND_ROW,
|
||||
FOOTER_HEIGHT,
|
||||
NAV_HEIGHT,
|
||||
CONTENT_CARD_PADDING,
|
||||
TABLE_ADD_BUTTON_HEIGHT,
|
||||
} from 'constants/blocksSizes'
|
||||
|
||||
type TTableBuiltinInfoProps = {
|
||||
namespace?: string
|
||||
typeName: string
|
||||
limit: string | null
|
||||
inside?: boolean
|
||||
customizationIdPrefix: string
|
||||
}
|
||||
|
||||
export const TableBuiltinInfo: FC<TTableBuiltinInfoProps> = ({
|
||||
namespace,
|
||||
typeName,
|
||||
limit,
|
||||
inside,
|
||||
customizationIdPrefix,
|
||||
}) => {
|
||||
const location = useLocation()
|
||||
const navigate = useNavigate()
|
||||
const params = useParams()
|
||||
const cluster = useSelector((state: RootState) => state.cluster.cluster)
|
||||
const theme = useSelector((state: RootState) => state.openapiTheme.theme)
|
||||
const baseprefix = useSelector((state: RootState) => state.baseprefix.baseprefix)
|
||||
|
||||
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState<false | { name: string; endpoint: string }>(false)
|
||||
const [isDeleteModalManyOpen, setIsDeleteModalManyOpen] = useState<false | { name: string; endpoint: string }[]>(
|
||||
false,
|
||||
)
|
||||
const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([])
|
||||
const [selectedRowsData, setSelectedRowsData] = useState<{ name: string; endpoint: string }[]>([])
|
||||
const [isNamespaced, setIsNamespaced] = useState<boolean>()
|
||||
|
||||
const [height, setHeight] = useState(0)
|
||||
|
||||
useEffect(() => {
|
||||
const height =
|
||||
window.innerHeight -
|
||||
HEAD_FIRST_ROW -
|
||||
HEAD_SECOND_ROW -
|
||||
NAV_HEIGHT -
|
||||
CONTENT_CARD_PADDING * 2 -
|
||||
FOOTER_HEIGHT -
|
||||
TABLE_ADD_BUTTON_HEIGHT
|
||||
setHeight(height)
|
||||
|
||||
const handleResize = () => {
|
||||
setHeight(height)
|
||||
}
|
||||
|
||||
window.addEventListener('resize', handleResize)
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('resize', handleResize)
|
||||
}
|
||||
}, [])
|
||||
|
||||
const createPermission = usePermissions({
|
||||
apiGroup: '',
|
||||
typeName,
|
||||
namespace: '',
|
||||
clusterName: cluster,
|
||||
verb: 'create',
|
||||
refetchInterval: false,
|
||||
})
|
||||
|
||||
const updatePermission = usePermissions({
|
||||
apiGroup: '',
|
||||
typeName,
|
||||
namespace: '',
|
||||
clusterName: cluster,
|
||||
verb: 'update',
|
||||
refetchInterval: false,
|
||||
})
|
||||
|
||||
const deletePermission = usePermissions({
|
||||
apiGroup: '',
|
||||
typeName,
|
||||
namespace: '',
|
||||
clusterName: cluster,
|
||||
verb: 'delete',
|
||||
refetchInterval: false,
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
checkIfBuiltInInstanceNamespaceScoped({
|
||||
typeName,
|
||||
clusterName: cluster,
|
||||
}).then(({ isNamespaceScoped }) => {
|
||||
if (isNamespaceScoped) {
|
||||
setIsNamespaced(isNamespaceScoped)
|
||||
}
|
||||
})
|
||||
}, [cluster, typeName])
|
||||
|
||||
const { isPending, error, data } = useBuiltinResources({
|
||||
clusterName: cluster,
|
||||
namespace,
|
||||
typeName,
|
||||
limit,
|
||||
})
|
||||
|
||||
const onDeleteHandle = (name: string, endpoint: string) => {
|
||||
setIsDeleteModalOpen({ name, endpoint })
|
||||
}
|
||||
|
||||
const clearSelected = () => {
|
||||
setSelectedRowKeys([])
|
||||
setSelectedRowsData([])
|
||||
}
|
||||
|
||||
const replaceValuesPartsOfUrls = location.pathname
|
||||
.split('/')
|
||||
.reduce<Record<string, string | undefined>>((acc, value, index) => {
|
||||
acc[index.toString()] = value
|
||||
return acc
|
||||
}, {})
|
||||
|
||||
return (
|
||||
<>
|
||||
{isPending && <Spin />}
|
||||
{error && <Alert message={`An error has occurred: ${error?.message} `} type="error" />}
|
||||
<OverflowMaxHeightContainer $maxHeight={height}>
|
||||
{!error && data && (
|
||||
<EnrichedTableProvider
|
||||
key={`/v1/${typeName}`}
|
||||
customizationId={`${customizationIdPrefix}/v1/${typeName}`}
|
||||
tableMappingsReplaceValues={{
|
||||
clusterName: params.clusterName,
|
||||
projectName: params.projectName,
|
||||
instanceName: params.instanceName,
|
||||
namespace: params.namespace,
|
||||
syntheticProject: params.syntheticProject,
|
||||
entryType: params.entryType,
|
||||
apiGroup: params.apiGroup,
|
||||
apiVersion: params.apiVersion,
|
||||
typeName: params.typeName,
|
||||
entryName: params.entryName,
|
||||
apiExtensionVersion: params.apiExtensionVersion,
|
||||
crdName: params.crdName,
|
||||
...replaceValuesPartsOfUrls,
|
||||
}}
|
||||
cluster={cluster}
|
||||
theme={theme}
|
||||
baseprefix={inside ? `${baseprefix}/inside` : baseprefix}
|
||||
dataItems={data.items}
|
||||
dataForControls={{
|
||||
cluster,
|
||||
syntheticProject: params.syntheticProject,
|
||||
pathPrefix: 'forms/builtin',
|
||||
typeName,
|
||||
apiVersion: 'v1',
|
||||
backlink: `${baseprefix}${inside ? '/inside' : ''}/${cluster}${namespace ? `/${namespace}` : ''}${
|
||||
params.syntheticProject ? `/${params.syntheticProject}` : ''
|
||||
}/builtin-table/${typeName}`,
|
||||
deletePathPrefix: `/api/clusters/${cluster}/k8s/api`,
|
||||
onDeleteHandle,
|
||||
permissions: {
|
||||
canUpdate: isNamespaced ? true : updatePermission.data?.status.allowed,
|
||||
canDelete: isNamespaced ? true : deletePermission.data?.status.allowed,
|
||||
},
|
||||
}}
|
||||
selectData={{
|
||||
selectedRowKeys,
|
||||
onChange: (selectedRowKeys: React.Key[], selectedRowsData: { name: string; endpoint: string }[]) => {
|
||||
setSelectedRowKeys(selectedRowKeys)
|
||||
setSelectedRowsData(selectedRowsData)
|
||||
},
|
||||
}}
|
||||
tableProps={{ ...TABLE_PROPS, disablePagination: true }}
|
||||
// maxHeight={height - 65}
|
||||
/>
|
||||
)}
|
||||
{/* {selectedRowKeys.length > 0 && (
|
||||
<MarginTopContainer $top={-40}>
|
||||
<Flex gap={16}>
|
||||
<Button type="primary" onClick={clearSelected}>
|
||||
<ClearOutlined />
|
||||
Clear
|
||||
</Button>
|
||||
<Button type="primary" onClick={() => setIsDeleteModalManyOpen(selectedRowsData)}>
|
||||
<MinusOutlined />
|
||||
Delete
|
||||
</Button>
|
||||
</Flex>
|
||||
</MarginTopContainer>
|
||||
)} */}
|
||||
</OverflowMaxHeightContainer>
|
||||
<FlexGrow />
|
||||
<PaddingContainer $padding="4px">
|
||||
<Flex justify="space-between">
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={() =>
|
||||
navigate(
|
||||
`${baseprefix}${inside ? '/inside' : ''}/${cluster}${namespace ? `/${namespace}` : ''}${
|
||||
params.syntheticProject ? `/${params.syntheticProject}` : ''
|
||||
}/forms/builtin/v1/${typeName}?backlink=${baseprefix}${inside ? '/inside' : ''}/${cluster}${
|
||||
namespace ? `/${namespace}` : ''
|
||||
}${params.syntheticProject ? `/${params.syntheticProject}` : ''}/builtin-table/${typeName}`,
|
||||
)
|
||||
}
|
||||
loading={isNamespaced ? false : createPermission.isPending}
|
||||
disabled={isNamespaced ? false : !createPermission.data?.status.allowed}
|
||||
>
|
||||
<PlusOutlined />
|
||||
Add
|
||||
</Button>
|
||||
|
||||
{selectedRowKeys.length > 0 && (
|
||||
<Flex gap={16}>
|
||||
<Button type="primary" onClick={clearSelected}>
|
||||
<ClearOutlined />
|
||||
Clear
|
||||
</Button>
|
||||
<Button type="primary" onClick={() => setIsDeleteModalManyOpen(selectedRowsData)}>
|
||||
<MinusOutlined />
|
||||
Delete
|
||||
</Button>
|
||||
</Flex>
|
||||
)}
|
||||
</Flex>
|
||||
</PaddingContainer>
|
||||
{isDeleteModalOpen && (
|
||||
<DeleteModal
|
||||
name={isDeleteModalOpen.name}
|
||||
onClose={() => {
|
||||
setIsDeleteModalOpen(false)
|
||||
clearSelected()
|
||||
}}
|
||||
endpoint={isDeleteModalOpen.endpoint}
|
||||
/>
|
||||
)}
|
||||
{isDeleteModalManyOpen !== false && (
|
||||
<DeleteModalMany
|
||||
data={isDeleteModalManyOpen}
|
||||
onClose={() => {
|
||||
setIsDeleteModalManyOpen(false)
|
||||
clearSelected()
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
export * from './TableBuiltinInfo'
|
||||
@@ -1,277 +0,0 @@
|
||||
/* eslint-disable max-lines-per-function */
|
||||
import React, { FC, useState, useEffect } from 'react'
|
||||
import { useLocation, useNavigate, useParams } from 'react-router-dom'
|
||||
import { Spin, Alert, Button, Flex } from 'antd'
|
||||
import { PlusOutlined, ClearOutlined, MinusOutlined } from '@ant-design/icons'
|
||||
import { useSelector } from 'react-redux'
|
||||
import { RootState } from 'store/store'
|
||||
import {
|
||||
EnrichedTableProvider,
|
||||
usePermissions,
|
||||
DeleteModal,
|
||||
DeleteModalMany,
|
||||
checkIfApiInstanceNamespaceScoped,
|
||||
useApiResources,
|
||||
} from '@prorobotech/openapi-k8s-toolkit'
|
||||
import { FlexGrow, OverflowMaxHeightContainer, PaddingContainer } from 'components'
|
||||
import { TABLE_PROPS } from 'constants/tableProps'
|
||||
import {
|
||||
HEAD_FIRST_ROW,
|
||||
HEAD_SECOND_ROW,
|
||||
FOOTER_HEIGHT,
|
||||
NAV_HEIGHT,
|
||||
CONTENT_CARD_PADDING,
|
||||
TABLE_ADD_BUTTON_HEIGHT,
|
||||
} from 'constants/blocksSizes'
|
||||
|
||||
type TTableNonCrdInfoProps = {
|
||||
namespace?: string
|
||||
apiGroup: string
|
||||
apiVersion: string
|
||||
typeName: string
|
||||
limit: string | null
|
||||
inside?: boolean
|
||||
customizationIdPrefix: string
|
||||
}
|
||||
|
||||
export const TableNonCrdInfo: FC<TTableNonCrdInfoProps> = ({
|
||||
namespace,
|
||||
apiGroup,
|
||||
apiVersion,
|
||||
typeName,
|
||||
limit,
|
||||
inside,
|
||||
customizationIdPrefix,
|
||||
}) => {
|
||||
const location = useLocation()
|
||||
const navigate = useNavigate()
|
||||
const params = useParams()
|
||||
const cluster = useSelector((state: RootState) => state.cluster.cluster)
|
||||
const theme = useSelector((state: RootState) => state.openapiTheme.theme)
|
||||
const baseprefix = useSelector((state: RootState) => state.baseprefix.baseprefix)
|
||||
|
||||
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState<false | { name: string; endpoint: string }>(false)
|
||||
const [isDeleteModalManyOpen, setIsDeleteModalManyOpen] = useState<false | { name: string; endpoint: string }[]>(
|
||||
false,
|
||||
)
|
||||
const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([])
|
||||
const [selectedRowsData, setSelectedRowsData] = useState<{ name: string; endpoint: string }[]>([])
|
||||
const [isNamespaced, setIsNamespaced] = useState<boolean>()
|
||||
|
||||
const [height, setHeight] = useState(0)
|
||||
|
||||
useEffect(() => {
|
||||
const height =
|
||||
window.innerHeight -
|
||||
HEAD_FIRST_ROW -
|
||||
HEAD_SECOND_ROW -
|
||||
NAV_HEIGHT -
|
||||
CONTENT_CARD_PADDING * 2 -
|
||||
FOOTER_HEIGHT -
|
||||
TABLE_ADD_BUTTON_HEIGHT
|
||||
setHeight(height)
|
||||
|
||||
const handleResize = () => {
|
||||
setHeight(height)
|
||||
}
|
||||
|
||||
window.addEventListener('resize', handleResize)
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('resize', handleResize)
|
||||
}
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
checkIfApiInstanceNamespaceScoped({
|
||||
apiGroup,
|
||||
apiVersion,
|
||||
typeName,
|
||||
clusterName: cluster,
|
||||
}).then(({ isNamespaceScoped }) => {
|
||||
if (isNamespaceScoped) {
|
||||
setIsNamespaced(true)
|
||||
}
|
||||
})
|
||||
}, [cluster, typeName, apiGroup, apiVersion])
|
||||
|
||||
const createPermission = usePermissions({
|
||||
apiGroup,
|
||||
typeName,
|
||||
namespace: '',
|
||||
clusterName: cluster,
|
||||
verb: 'create',
|
||||
refetchInterval: false,
|
||||
})
|
||||
|
||||
const updatePermission = usePermissions({
|
||||
apiGroup,
|
||||
typeName,
|
||||
namespace: '',
|
||||
clusterName: cluster,
|
||||
verb: 'update',
|
||||
refetchInterval: false,
|
||||
})
|
||||
|
||||
const deletePermission = usePermissions({
|
||||
apiGroup,
|
||||
typeName,
|
||||
namespace: '',
|
||||
clusterName: cluster,
|
||||
verb: 'delete',
|
||||
refetchInterval: false,
|
||||
})
|
||||
|
||||
const { isPending, error, data } = useApiResources({
|
||||
clusterName: cluster,
|
||||
namespace,
|
||||
apiGroup,
|
||||
apiVersion,
|
||||
typeName,
|
||||
limit,
|
||||
})
|
||||
|
||||
const onDeleteHandle = (name: string, endpoint: string) => {
|
||||
setIsDeleteModalOpen({ name, endpoint })
|
||||
}
|
||||
|
||||
const clearSelected = () => {
|
||||
setSelectedRowKeys([])
|
||||
setSelectedRowsData([])
|
||||
}
|
||||
|
||||
const replaceValuesPartsOfUrls = location.pathname
|
||||
.split('/')
|
||||
.reduce<Record<string, string | undefined>>((acc, value, index) => {
|
||||
acc[index.toString()] = value
|
||||
return acc
|
||||
}, {})
|
||||
|
||||
return (
|
||||
<>
|
||||
{isPending && <Spin />}
|
||||
{error && <Alert message={`An error has occurred: ${error?.message} `} type="error" />}
|
||||
<OverflowMaxHeightContainer $maxHeight={height}>
|
||||
{!error && data && (
|
||||
<EnrichedTableProvider
|
||||
key={`/${apiGroup}/${apiVersion}/${typeName}`}
|
||||
customizationId={`${customizationIdPrefix}/${apiGroup}/${apiVersion}/${typeName}`}
|
||||
tableMappingsReplaceValues={{
|
||||
clusterName: params.clusterName,
|
||||
projectName: params.projectName,
|
||||
instanceName: params.instanceName,
|
||||
namespace: params.namespace,
|
||||
syntheticProject: params.syntheticProject,
|
||||
entryType: params.entryType,
|
||||
apiGroup: params.apiGroup,
|
||||
apiVersion: params.apiVersion,
|
||||
typeName: params.typeName,
|
||||
entryName: params.entryName,
|
||||
apiExtensionVersion: params.apiExtensionVersion,
|
||||
crdName: params.crdName,
|
||||
...replaceValuesPartsOfUrls,
|
||||
}}
|
||||
cluster={cluster}
|
||||
theme={theme}
|
||||
baseprefix={inside ? `${baseprefix}/inside` : baseprefix}
|
||||
dataItems={data.items}
|
||||
dataForControls={{
|
||||
cluster,
|
||||
syntheticProject: params.syntheticProject,
|
||||
pathPrefix: 'forms/apis',
|
||||
typeName,
|
||||
apiVersion: `${apiGroup}/${apiVersion}`,
|
||||
backlink: `${baseprefix}${inside ? '/inside' : ''}/${cluster}${namespace ? `/${namespace}` : ''}${
|
||||
params.syntheticProject ? `/${params.syntheticProject}` : ''
|
||||
}/api-table/${apiGroup}/${apiVersion}/${typeName}`,
|
||||
deletePathPrefix: `/api/clusters/${cluster}/k8s/apis`,
|
||||
onDeleteHandle,
|
||||
permissions: {
|
||||
canUpdate: isNamespaced ? true : updatePermission.data?.status.allowed,
|
||||
canDelete: isNamespaced ? true : deletePermission.data?.status.allowed,
|
||||
},
|
||||
}}
|
||||
selectData={{
|
||||
selectedRowKeys,
|
||||
onChange: (selectedRowKeys: React.Key[], selectedRowsData: { name: string; endpoint: string }[]) => {
|
||||
setSelectedRowKeys(selectedRowKeys)
|
||||
setSelectedRowsData(selectedRowsData)
|
||||
},
|
||||
}}
|
||||
tableProps={{ ...TABLE_PROPS, disablePagination: true }}
|
||||
// maxHeight={height - 65}
|
||||
/>
|
||||
)}
|
||||
{/* {selectedRowKeys.length > 0 && (
|
||||
<MarginTopContainer $top={-40}>
|
||||
<Flex gap={16}>
|
||||
<Button type="primary" onClick={clearSelected}>
|
||||
<ClearOutlined />
|
||||
Clear
|
||||
</Button>
|
||||
<Button type="primary" onClick={() => setIsDeleteModalManyOpen(selectedRowsData)}>
|
||||
<MinusOutlined />
|
||||
Delete
|
||||
</Button>
|
||||
</Flex>
|
||||
</MarginTopContainer>
|
||||
)} */}
|
||||
</OverflowMaxHeightContainer>
|
||||
<FlexGrow />
|
||||
<PaddingContainer $padding="4px">
|
||||
<Flex justify="space-between">
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={() =>
|
||||
navigate(
|
||||
`${baseprefix}${inside ? '/inside' : ''}/${cluster}${namespace ? `/${namespace}` : ''}${
|
||||
params.syntheticProject ? `/${params.syntheticProject}` : ''
|
||||
}/forms/apis/${apiGroup}/${apiVersion}/${typeName}?backlink=${baseprefix}${
|
||||
inside ? '/inside' : ''
|
||||
}/${cluster}${namespace ? `/${namespace}` : ''}${
|
||||
params.syntheticProject ? `/${params.syntheticProject}` : ''
|
||||
}/api-table/${apiGroup}/${apiVersion}/${typeName}`,
|
||||
)
|
||||
}
|
||||
loading={isNamespaced ? false : createPermission.isPending}
|
||||
disabled={isNamespaced ? false : !createPermission.data?.status.allowed}
|
||||
>
|
||||
<PlusOutlined />
|
||||
Add
|
||||
</Button>
|
||||
{selectedRowKeys.length > 0 && (
|
||||
<Flex gap={16}>
|
||||
<Button type="primary" onClick={clearSelected}>
|
||||
<ClearOutlined />
|
||||
Clear
|
||||
</Button>
|
||||
<Button type="primary" onClick={() => setIsDeleteModalManyOpen(selectedRowsData)}>
|
||||
<MinusOutlined />
|
||||
Delete
|
||||
</Button>
|
||||
</Flex>
|
||||
)}
|
||||
</Flex>
|
||||
</PaddingContainer>
|
||||
{isDeleteModalOpen && (
|
||||
<DeleteModal
|
||||
name={isDeleteModalOpen.name}
|
||||
onClose={() => {
|
||||
setIsDeleteModalOpen(false)
|
||||
clearSelected()
|
||||
}}
|
||||
endpoint={isDeleteModalOpen.endpoint}
|
||||
/>
|
||||
)}
|
||||
{isDeleteModalManyOpen !== false && (
|
||||
<DeleteModalMany
|
||||
data={isDeleteModalManyOpen}
|
||||
onClose={() => {
|
||||
setIsDeleteModalManyOpen(false)
|
||||
clearSelected()
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
export * from './TableNonCrdInfo'
|
||||
@@ -3,9 +3,6 @@ export * from './ListInsideClusterAndNs'
|
||||
export * from './ListInsideAllResources'
|
||||
export * from './ListInsideCrdsByApiGroup'
|
||||
export * from './ListInsideApisByApiGroup'
|
||||
export * from './TableCrdInfo'
|
||||
export * from './TableNonCrdInfo'
|
||||
export * from './TableBuiltinInfo'
|
||||
export * from './Forms'
|
||||
export * from './Factory'
|
||||
export * from './Header'
|
||||
|
||||
@@ -3,7 +3,7 @@ import { ContentCard } from '@prorobotech/openapi-k8s-toolkit'
|
||||
import { useParams, useSearchParams } from 'react-router-dom'
|
||||
import { useSelector } from 'react-redux'
|
||||
import type { RootState } from 'store/store'
|
||||
import { TableNonCrdInfo, BackLink, ManageableBreadcrumbs, ManageableSidebar, NavigationContainer } from 'components'
|
||||
import { TableApiBuiltin, BackLink, ManageableBreadcrumbs, ManageableSidebar, NavigationContainer } from 'components'
|
||||
import { getSidebarIdPrefix } from 'utils/getSidebarIdPrefix'
|
||||
import { getBreadcrumbsIdPrefix } from 'utils/getBreadcrumbsIdPrefix'
|
||||
import { getTableCustomizationIdPrefix } from 'utils/getTableCustomizationIdPrefix'
|
||||
@@ -79,7 +79,8 @@ export const TableApiPage: FC<TTableApiPageProps> = ({ forcedTheme, inside }) =>
|
||||
</NavigationContainer>
|
||||
<ContentCard flexGrow={1} displayFlex flexFlow="column">
|
||||
{typeName && apiGroup && apiVersion && (
|
||||
<TableNonCrdInfo
|
||||
<TableApiBuiltin
|
||||
resourceType="api"
|
||||
namespace={namespace}
|
||||
apiGroup={apiGroup}
|
||||
apiVersion={apiVersion}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { ContentCard } from '@prorobotech/openapi-k8s-toolkit'
|
||||
import { useParams, useSearchParams } from 'react-router-dom'
|
||||
import { useSelector } from 'react-redux'
|
||||
import type { RootState } from 'store/store'
|
||||
import { TableBuiltinInfo, BackLink, ManageableBreadcrumbs, ManageableSidebar, NavigationContainer } from 'components'
|
||||
import { TableApiBuiltin, BackLink, ManageableBreadcrumbs, ManageableSidebar, NavigationContainer } from 'components'
|
||||
import { getSidebarIdPrefix } from 'utils/getSidebarIdPrefix'
|
||||
import { getBreadcrumbsIdPrefix } from 'utils/getBreadcrumbsIdPrefix'
|
||||
import { getTableCustomizationIdPrefix } from 'utils/getTableCustomizationIdPrefix'
|
||||
@@ -66,7 +66,8 @@ export const TableBuiltinPage: FC<TTableBuiltinPageProps> = ({ forcedTheme, insi
|
||||
</NavigationContainer>
|
||||
<ContentCard flexGrow={1} displayFlex flexFlow="column">
|
||||
{typeName && (
|
||||
<TableBuiltinInfo
|
||||
<TableApiBuiltin
|
||||
resourceType="builtin"
|
||||
namespace={namespace}
|
||||
typeName={typeName}
|
||||
limit={searchParams.get('limit')}
|
||||
|
||||
@@ -3,13 +3,23 @@ export const getTableCustomizationIdPrefix = ({
|
||||
instance,
|
||||
namespace,
|
||||
inside,
|
||||
search,
|
||||
}: {
|
||||
project?: boolean
|
||||
instance?: boolean
|
||||
namespace?: boolean
|
||||
inside?: boolean
|
||||
search?: boolean
|
||||
}): string => {
|
||||
let result = inside ? 'inside-' : 'stock-'
|
||||
let result: string
|
||||
|
||||
if (inside) {
|
||||
result = 'inside-'
|
||||
} else if (search) {
|
||||
result = 'search-'
|
||||
} else {
|
||||
result = 'stock-'
|
||||
}
|
||||
|
||||
if (instance) {
|
||||
result += 'instance-'
|
||||
|
||||
Reference in New Issue
Block a user