[dashboard] Fix resource quota table on Tenant page (#1934)
<!-- Thank you for making a contribution! Here are some tips for you: - Start the PR title with the [label] of Cozystack component: - For system components: [platform], [system], [linstor], [cilium], [kube-ovn], [dashboard], [cluster-api], etc. - For managed apps: [apps], [tenant], [kubernetes], [postgres], [virtual-machine] etc. - For development and maintenance: [tests], [ci], [docs], [maintenance]. - If it's a work in progress, consider creating this PR as a draft. - Don't hesistate to ask for opinion and review in the community chats, even if it's still a draft. - Add the label `backport` if it's a bugfix that needs to be backported to a previous version. --> ## What this PR does - Fix `Used` column to show correct data - Removes table from `Info` page - Add patch to let flatMap work with jsonpath <img width="1800" height="940" alt="resource quota table example" src="https://github.com/user-attachments/assets/421d1d32-fdc8-4269-838f-b02db0ed6712" /> ### Release note <!-- Write a release note: - Explain what has changed internally and for users. - Start with the same [label] as in the PR title - Follow the guidelines at https://github.com/kubernetes/community/blob/master/contributors/guide/release-notes.md. --> ```release-note [dashboard] fix resource quota table on tenant details page ``` <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Fixed resource quota data fetching for tenant resources to use correct namespace references from status fields. * **Refactor** * Refined dashboard layout for resource quota displays and improved custom field resolution with enhanced dynamic key mapping for complex data structures. <sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub> <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
commit
b558489d22
3 changed files with 92 additions and 23 deletions
|
|
@ -174,27 +174,6 @@ func detailsTab(kind, endpoint, schemaJSON string, keysOrder [][]string) map[str
|
|||
}),
|
||||
)
|
||||
}
|
||||
if kind == "Info" {
|
||||
rightColStack = append(rightColStack,
|
||||
antdFlexVertical("resource-quotas-block", 4, []any{
|
||||
antdText("resource-quotas-label", true, "Resource Quotas", map[string]any{
|
||||
"fontSize": float64(20),
|
||||
"marginBottom": float64(12),
|
||||
}),
|
||||
map[string]any{
|
||||
"type": "EnrichedTable",
|
||||
"data": map[string]any{
|
||||
"id": "resource-quotas-table",
|
||||
"baseprefix": "/openapi-ui",
|
||||
"clusterNamePartOfUrl": "{2}",
|
||||
"customizationId": "factory-resource-quotas",
|
||||
"fetchUrl": "/api/clusters/{2}/k8s/api/v1/namespaces/{3}/resourcequotas",
|
||||
"pathToItems": []any{`items`},
|
||||
},
|
||||
},
|
||||
}),
|
||||
)
|
||||
}
|
||||
if kind == "Tenant" {
|
||||
rightColStack = append(rightColStack,
|
||||
antdFlexVertical("resource-quotas-block", 4, []any{
|
||||
|
|
@ -209,7 +188,7 @@ func detailsTab(kind, endpoint, schemaJSON string, keysOrder [][]string) map[str
|
|||
"baseprefix": "/openapi-ui",
|
||||
"clusterNamePartOfUrl": "{2}",
|
||||
"customizationId": "factory-resource-quotas",
|
||||
"fetchUrl": "/api/clusters/{2}/k8s/api/v1/namespaces/{3}/resourcequotas",
|
||||
"fetchUrl": "/api/clusters/{2}/k8s/api/v1/namespaces/{reqsJsonPath[0]['.status.namespace']}/resourcequotas",
|
||||
"pathToItems": []any{`items`},
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -194,7 +194,7 @@ func CreateAllCustomColumnsOverrides() []*dashboardv1alpha1.CustomColumnsOverrid
|
|||
createFlatMapColumn("Data", ".spec.hard"),
|
||||
createStringColumn("Resource", "_flatMapData_Key"),
|
||||
createStringColumn("Hard", "_flatMapData_Value"),
|
||||
createStringColumn("Used", ".status.used['{_flatMapData_Key}']"),
|
||||
createStringColumn("Used", ".status.used[_flatMapData_Key]"),
|
||||
}),
|
||||
|
||||
// Factory ingress details rules
|
||||
|
|
|
|||
|
|
@ -0,0 +1,90 @@
|
|||
diff --git a/src/components/molecules/EnrichedTable/organisms/EnrichedTableProvider/utils.ts b/src/components/molecules/EnrichedTable/organisms/EnrichedTableProvider/utils.ts
|
||||
index 87a0f12..fb2e1cc 100644
|
||||
--- a/src/components/molecules/EnrichedTable/organisms/EnrichedTableProvider/utils.ts
|
||||
+++ b/src/components/molecules/EnrichedTable/organisms/EnrichedTableProvider/utils.ts
|
||||
@@ -134,22 +134,6 @@ export const prepare = ({
|
||||
// impossible in k8s
|
||||
return {}
|
||||
})
|
||||
- if (customFields.length > 0) {
|
||||
- dataSource = dataSource.map((el: TJSON) => {
|
||||
- const newFieldsForComplexJsonPath: Record<string, TJSON> = {}
|
||||
- customFields.forEach(({ dataIndex, jsonPath }) => {
|
||||
- const jpQueryResult = jp.query(el, `$${jsonPath}`)
|
||||
- newFieldsForComplexJsonPath[dataIndex] =
|
||||
- Array.isArray(jpQueryResult) && jpQueryResult.length === 1 ? jpQueryResult[0] : jpQueryResult
|
||||
- })
|
||||
- if (typeof el === 'object') {
|
||||
- return { ...el, ...newFieldsForComplexJsonPath }
|
||||
- }
|
||||
- // impossible in k8s
|
||||
- return { ...newFieldsForComplexJsonPath }
|
||||
- })
|
||||
- }
|
||||
-
|
||||
// Handle flatMap: expand rows for map objects
|
||||
// Process all flatMap columns sequentially
|
||||
if (flatMapColumns.length > 0 && dataSource) {
|
||||
@@ -204,6 +188,62 @@ export const prepare = ({
|
||||
currentDataSource = expandedDataSource
|
||||
})
|
||||
dataSource = currentDataSource
|
||||
+ }
|
||||
+
|
||||
+ if (customFields.length > 0) {
|
||||
+ dataSource = dataSource.map((el: TJSON) => {
|
||||
+ const newFieldsForComplexJsonPath: Record<string, TJSON> = {}
|
||||
+ customFields.forEach(({ dataIndex, jsonPath }) => {
|
||||
+ let fieldValue: TJSON = null
|
||||
+ let handled = false
|
||||
+
|
||||
+ const flatMapMatch = jsonPath.match(/^(.*)\[(_flatMap[^\]]+_Key)\](.*)$/)
|
||||
+ if (flatMapMatch && el && typeof el === 'object' && !Array.isArray(el)) {
|
||||
+ const basePath = flatMapMatch[1]
|
||||
+ const keyField = flatMapMatch[2]
|
||||
+ const tailPath = flatMapMatch[3]
|
||||
+ const keyValue = (el as Record<string, unknown>)[keyField]
|
||||
+ if (keyValue !== null && keyValue !== undefined) {
|
||||
+ const baseResult = jp.query(el, `$${basePath}`)[0]
|
||||
+ if (baseResult && typeof baseResult === 'object' && !Array.isArray(baseResult)) {
|
||||
+ const baseValue = (baseResult as Record<string, unknown>)[String(keyValue)]
|
||||
+ if (tailPath) {
|
||||
+ const normalizedTailPath =
|
||||
+ tailPath.startsWith('.') || tailPath.startsWith('[') ? tailPath : `.${tailPath}`
|
||||
+ const tailResult = jp.query(baseValue, `$${normalizedTailPath}`)
|
||||
+ fieldValue = Array.isArray(tailResult) && tailResult.length === 1 ? tailResult[0] : tailResult
|
||||
+ } else {
|
||||
+ fieldValue = baseValue as TJSON
|
||||
+ }
|
||||
+ handled = true
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (!handled) {
|
||||
+ let resolvedJsonPath = jsonPath
|
||||
+ if (el && typeof el === 'object' && !Array.isArray(el)) {
|
||||
+ resolvedJsonPath = jsonPath.replace(/\[(_flatMap[^\]]+_Key)\]/g, (match, keyField) => {
|
||||
+ const keyValue = (el as Record<string, unknown>)[keyField]
|
||||
+ if (keyValue === null || keyValue === undefined) {
|
||||
+ return match
|
||||
+ }
|
||||
+ const escaped = String(keyValue).replace(/'/g, "\\'")
|
||||
+ return `['${escaped}']`
|
||||
+ })
|
||||
+ }
|
||||
+ const jpQueryResult = jp.query(el, `$${resolvedJsonPath}`)
|
||||
+ fieldValue = Array.isArray(jpQueryResult) && jpQueryResult.length === 1 ? jpQueryResult[0] : jpQueryResult
|
||||
+ }
|
||||
+
|
||||
+ newFieldsForComplexJsonPath[dataIndex] = fieldValue
|
||||
+ })
|
||||
+ if (typeof el === 'object') {
|
||||
+ return { ...el, ...newFieldsForComplexJsonPath }
|
||||
+ }
|
||||
+ // impossible in k8s
|
||||
+ return { ...newFieldsForComplexJsonPath }
|
||||
+ })
|
||||
}
|
||||
} else {
|
||||
dataSource = dataItems.map((el: TJSON) => {
|
||||
Loading…
Add table
Add a link
Reference in a new issue