gated hook for resource fetching

This commit is contained in:
typescreep
2025-11-07 17:12:19 +03:00
parent 2ca2c9a84c
commit dd356a200c
5 changed files with 80 additions and 126 deletions

8
package-lock.json generated
View File

@@ -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": "^1.1.0-alpha.1",
"@prorobotech/openapi-k8s-toolkit": "^1.1.0-alpha.2",
"@readme/openapi-parser": "4.0.0",
"@reduxjs/toolkit": "2.2.5",
"@tanstack/react-query": "5.62.2",
@@ -2804,9 +2804,9 @@
}
},
"node_modules/@prorobotech/openapi-k8s-toolkit": {
"version": "1.1.0-alpha.1",
"resolved": "https://registry.npmjs.org/@prorobotech/openapi-k8s-toolkit/-/openapi-k8s-toolkit-1.1.0-alpha.1.tgz",
"integrity": "sha512-vuE+cysEhQj0SAUNO/ByJw1OLih5KQUkTEzoJZ4I135/ciQXpMOY9QnXlcTnFxwafb1rnk4APBsAuYPTR4SpyQ==",
"version": "1.1.0-alpha.2",
"resolved": "https://registry.npmjs.org/@prorobotech/openapi-k8s-toolkit/-/openapi-k8s-toolkit-1.1.0-alpha.2.tgz",
"integrity": "sha512-aNOTBpOevJ1VqZ6e2w1yDpv//+4TGdk0j0fsJa465bOQJbFZLQIAxepZ+T2SY81mnVen24IMZhPBwn9VNEYJWA==",
"license": "MIT",
"dependencies": {
"@monaco-editor/react": "4.6.0",

View File

@@ -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": "1.1.0-alpha.1",
"@prorobotech/openapi-k8s-toolkit": "1.1.0-alpha.2",
"@readme/openapi-parser": "4.0.0",
"@reduxjs/toolkit": "2.2.5",
"@tanstack/react-query": "5.62.2",

View File

@@ -32,7 +32,7 @@ export const ManageableBreadcrumbs: FC<TManageableBreadCrumbsProps> = ({ idToCom
return (
<ManageableBreadcrumbsWithDataProvider
idToCompare={idToCompare}
wsUrl={`/api/clusters/${clusterName}/openapi-bff-ws/listThenWatch/listWatchWs`}
cluster={clusterName}
apiGroup={BASE_API_GROUP}
apiVersion={BASE_API_VERSION}
plural={inside ? 'breadcrumbsinsides' : 'breadcrumbs'}

View File

@@ -67,7 +67,7 @@ export const ManageableSidebar: FC<TManageableSidebarProps> = ({
$maxHeight={height}
>
<ManageableSidebarWithDataProvider
wsUrl={`/api/clusters/${clusterName}/openapi-bff-ws/listThenWatch/listWatchWs`}
cluster={clusterName}
apiGroup={BASE_API_GROUP}
apiVersion={BASE_API_VERSION}
plural="sidebars"

View File

@@ -12,9 +12,10 @@ import {
DeleteModalMany,
// checkIfBuiltInInstanceNamespaceScoped,
// checkIfApiInstanceNamespaceScoped,
useListWatch,
useK8sSmartResource,
Spacer,
getLinkToForm,
TSingleResource,
} from '@prorobotech/openapi-k8s-toolkit'
import { FlexGrow, PaddingContainer } from 'components'
import { TABLE_PROPS } from 'constants/tableProps'
@@ -27,7 +28,7 @@ import {
TABLE_ADD_BUTTON_HEIGHT,
} from 'constants/blocksSizes'
import { OverflowContainer } from './atoms'
import { getDataItems } from './utils'
// import { getDataItems } from './utils'
type TTableApiBuiltinProps = {
namespace?: string
@@ -142,60 +143,18 @@ export const TableApiBuiltin: FC<TTableApiBuiltinProps> = ({
})
const {
state: stateCore,
status: statusCore,
lastError: lastErrorCore,
} = useListWatch({
wsUrl: `/api/clusters/${cluster}/openapi-bff-ws/listThenWatch/listWatchWs`,
paused: false,
ignoreRemove: false,
autoDrain: true,
preserveStateOnUrlChange: true,
pageSize: limit,
query: {
namespace,
apiVersion: apiVersion || '',
plural: typeName,
labelSelector: labels ? encodeURIComponent(labels.join(',')) : undefined,
fieldSelector: fields ? encodeURIComponent(fields.join(',')) : undefined,
},
isEnabled: resourceType === 'builtin',
})
const isPendingBuiltin = statusCore === 'connecting'
const errorBuiltin = statusCore === 'closed' && lastErrorCore ? lastErrorCore : undefined
const dataBuiltin = stateCore.order.map(key => {
const res = stateCore.byKey[key]
return res
})
const {
state: stateApi,
status: statusApi,
lastError: lastErrorApi,
} = useListWatch({
wsUrl: `/api/clusters/${cluster}/openapi-bff-ws/listThenWatch/listWatchWs`,
paused: false,
ignoreRemove: false,
autoDrain: true,
preserveStateOnUrlChange: true,
pageSize: limit,
query: {
namespace,
apiGroup: apiGroup || '',
apiVersion: apiVersion || '',
plural: typeName,
labelSelector: labels ? labels.join(',') : undefined,
fieldSelector: fields ? fields.join(',') : undefined,
},
isEnabled: resourceType === 'api' && !!apiGroup && !!apiVersion,
})
const isPendingApi = statusApi === 'connecting'
const errorApi = statusApi === 'closed' && lastErrorApi ? lastErrorApi : undefined
const dataApi = stateApi.order.map(key => {
const res = stateApi.byKey[key]
return res
data: dataItems,
isLoading,
error,
} = useK8sSmartResource<{ items: TSingleResource[] }>({
cluster,
namespace,
group: apiGroup || undefined,
version: apiVersion || '',
plural: typeName,
labelSelector: labels ? encodeURIComponent(labels.join(',')) : undefined,
fieldSelector: fields ? encodeURIComponent(fields.join(',')) : undefined,
limit,
})
const onDeleteHandle = (name: string, endpoint: string) => {
@@ -218,70 +177,65 @@ export const TableApiBuiltin: FC<TTableApiBuiltinProps> = ({
return (
<>
{((resourceType === 'builtin' && isPendingBuiltin) || (resourceType === 'api' && isPendingApi)) && <Spin />}
{resourceType === 'builtin' && errorBuiltin && (
<Alert message={`An error has occurred: ${errorBuiltin} `} type="error" />
)}
{resourceType === 'api' && errorApi && <Alert message={`An error has occurred: ${errorApi} `} type="error" />}
{isLoading && <Spin />}
{error && <Alert message={`An error has occurred: ${error} `} 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}
namespace={namespace}
theme={theme}
baseprefix={inside ? `${baseprefix}/inside` : baseprefix}
dataItems={getDataItems({ resourceType, dataBuiltin, dataApi })}
k8sResource={{
resource: typeName,
apiGroup,
apiVersion,
}}
// isNamespaced={isNamespaced}
// isNamespacedLoading={isNamespacedLoading}
dataForControls={{
cluster,
syntheticProject: params.syntheticProject,
resource: typeName,
apiGroup,
apiVersion,
}}
dataForControlsInternal={{
onDeleteHandle,
}}
selectData={{
selectedRowKeys,
onChange: (selectedRowKeys: React.Key[], selectedRowsData: { name: string; endpoint: string }[]) => {
setSelectedRowKeys(selectedRowKeys)
setSelectedRowsData(selectedRowsData)
},
}}
tableProps={{ ...TABLE_PROPS, disablePagination: !searchMount }}
// maxHeight={height - 65}
/>
)}
{!error && dataItems && (
<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}
namespace={namespace}
theme={theme}
baseprefix={inside ? `${baseprefix}/inside` : baseprefix}
dataItems={dataItems.items}
k8sResource={{
resource: typeName,
apiGroup,
apiVersion,
}}
// isNamespaced={isNamespaced}
// isNamespacedLoading={isNamespacedLoading}
dataForControls={{
cluster,
syntheticProject: params.syntheticProject,
resource: typeName,
apiGroup,
apiVersion,
}}
dataForControlsInternal={{
onDeleteHandle,
}}
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}>