diff --git a/.env b/.env index d117d9b..96fb1a2 100644 --- a/.env +++ b/.env @@ -7,8 +7,10 @@ VITE_CUSTOM_TENANT_TEXT= VITE_CUSTOMIZATION_API_GROUP=incloud.io VITE_CUSTOMIZATION_API_VERSION=v1alpha -VITE_CUSTOMIZATION_NAVIGATION_RESOURCE_NAME=navigations -VITE_CUSTOMIZATION_NAVIGATION_RESOURCE=navigation +VITE_CUSTOMIZATION_NAVIGATION_RESOURCE_PLURAL=navigations +VITE_CUSTOMIZATION_NAVIGATION_RESOURCE_NAME=navigation + +VITE_CUSTOMIZATION_SIDEBAR_FALLBACK_ID = fallback VITE_USE_NAMESPACE_NAV=true @@ -17,15 +19,15 @@ VITE_HIDE_INSIDE=false VITE_NAVIGATE_FROM_CLUSTERLIST=/openapi-ui/~recordValue~/builtin-table/namespaces VITE_PROJECTS_API_GROUP=incloud.io -VITE_PROJECTS_VERSION=v1alpha -VITE_PROJECTS_RESOURCE_NAME=projects +VITE_PROJECTS_API_VERSION=v1alpha +VITE_PROJECTS_PLURAL=projects -VITE_MARKETPLACE_RESOURCE_NAME=marketplacepanels +VITE_MARKETPLACE_PLURAL=marketplacepanels VITE_MARKETPLACE_KIND=MarketplacePanel VITE_INSTANCES_API_GROUP=incloud.io -VITE_INSTANCES_VERSION=v1alpha1 -VITE_INSTANCES_RESOURCE_NAME=v1alpha1 +VITE_INSTANCES_API_VERSION=v1alpha1 +VITE_INSTANCES_PLURAL=v1alpha1 VITE_BFF_URL= @@ -50,4 +52,4 @@ VITE_BASE_NAMESPACE_FACTORY_KEY=base-factory-clusterscoped-builtin VITE_CUSTOM_NAMESPACE_API_RESOURCE_API_GROUP= VITE_CUSTOM_NAMESPACE_API_RESOURCE_API_VERSION= -VITE_CUSTOM_NAMESPACE_API_RESOURCE_RESOURCE_NAME= +VITE_CUSTOM_NAMESPACE_API_RESOURCE_PLURAL= diff --git a/.env.options.dist b/.env.options.dist index d36b462..e1c871c 100644 --- a/.env.options.dist +++ b/.env.options.dist @@ -9,8 +9,10 @@ KUBE_API_URL= CUSTOMIZATION_API_GROUP= CUSTOMIZATION_API_VERSION= +CUSTOMIZATION_NAVIGATION_RESOURCE_PLURAL= CUSTOMIZATION_NAVIGATION_RESOURCE_NAME= -CUSTOMIZATION_NAVIGATION_RESOURCE= + +CUSTOMIZATION_SIDEBAR_FALLBACK_ID= USE_NAMESPACE_NAV= @@ -19,15 +21,15 @@ HIDE_INSIDE= NAVIGATE_FROM_CLUSTERLIST= PROJECTS_API_GROUP= -PROJECTS_VERSION= -PROJECTS_RESOURCE_NAME= +PROJECTS_API_VERSION= +PROJECTS_PLURAL= -MARKETPLACE_RESOURCE_NAME= +MARKETPLACE_PLURAL MARKETPLACE_KIND= INSTANCES_API_GROUP= -INSTANCES_VERSION= -INSTANCES_RESOURCE_NAME= +INSTANCES_API_VERSION= +INSTANCES_PLURAL= BFF_URL= @@ -52,4 +54,4 @@ BASE_NAMESPACE_FACTORY_KEY= CUSTOM_NAMESPACE_API_RESOURCE_API_GROUP= CUSTOM_NAMESPACE_API_RESOURCE_API_VERSION= -CUSTOM_NAMESPACE_API_RESOURCE_RESOURCE_NAME= +CUSTOM_NAMESPACE_API_RESOURCE_PLURAL= diff --git a/README.md b/README.md index 5614994..7bde29c 100644 --- a/README.md +++ b/README.md @@ -9,45 +9,46 @@ Define interfaces in YAML; the app discovers CRDs, watches their objects, and bu This app can be configured through environment variables. -| Variable | Type | Description | -| --------------------------------------------- | --------- | --------------------------------------------------------------------------------------- | -| `BASEPREFIX` | `string` | Base URL for the app. `/openapi-ui` | -| `KUBE_API_URL` | `string` | URL for the Kubernetes API. `http://api.incloud-web.svc.default.in-cloud.internal:8081` | -| `BFF_URL` | `string` | URL for the BFF | -| `TITLE_TEXT` | `string` | Page title | -| `LOGO_TEXT` | `string` | Logo text near icon | -| `ICON_SVG` | `string` | Favicon base64 encoded | -| `FOOTER_TEXT` | `string` | Footer text | -| `CUSTOM_LOGO_SVG` | `string` | Base64 encoded svg | -| `CUSTOM_TENANT_TEXT` | `string` | Custom tenant text override | -| `LOGIN_URL` | `string` | Login endpoint. `/oauth/token` | -| `LOGOUT_URL` | `string` | Logout endpoint. `/oauth/logout` | -| `LOGIN_USERNAME_FIELD` | `string` | Field from login endpoint response. `name` | -| `CUSTOMIZATION_API_GROUP` | `string` | API group for customization resources. `front.in-cloud.io` | -| `CUSTOMIZATION_API_VERSION` | `string` | API version for customization resources. `v1alpha1` | -| `CUSTOMIZATION_NAVIGATION_RESOURCE_NAME` | `string` | Resource plural name for navigation settings. `navigations` | -| `CUSTOMIZATION_NAVIGATION_RESOURCE` | `string` | Resource name for navigation settings. `navigation` | -| `USE_NAMESPACE_NAV` | `boolean` | Use namespaces instead of project/instances. `true` | -| `HIDE_INSIDE` | `boolean` | Use namespaces instead of project/instances. `true` | -| `NAVIGATE_FROM_CLUSTERLIST` | `string` | Location to be navigated after selecting cluster. `/openapi-ui/clusters/~recordValue~` | -| `PROJECTS_API_GROUP` | `string` | API group for projects resources. If not using namespace nav. | -| `PROJECTS_VERSION` | `string` | API version for projects resources. If not using namespace nav. | -| `PROJECTS_RESOURCE_NAME` | `string` | Plural name for projects resources. If not using namespace nav. | -| `INSTANCES_API_GROUP` | `string` | API group for instances resources. If not using namespace nav. | -| `INSTANCES_VERSION` | `string` | API version for instances resources. If not using namespace nav. | -| `INSTANCES_RESOURCE_NAME` | `string` | Plural name for instances resources. If not using namespace nav. | -| `MARKETPLACE_RESOURCE_NAME` | `string` | Plural name for marketplace resources for related factory component. | -| `MARKETPLACE_KIND` | `string` | Kind name for marketplace resources for related factory component. | -| `NODE_TERMINAL_DEFAULT_PROFILE` | `string` | Default profile for node terminal component. `baseline` | -| `REMOVE_BACKLINK` | `boolean` | Remove backlink arrow from right-side navigation | -| `REMOVE_BACKLINK_TEXT` | `boolean` | Remove backlink text from right-side navigation | -| `DOCS_URL` | `string` | URL to navigate from question mark | -| `SEARCH_TABLE_CUSTOMIZATION_PREFIX` | `string` | Search tables Customization id prefix | -| `BASE_FACTORY_NAMESPACED_API_KEY` | `string` | Base factory key for namespaced API resources | -| `BASE_FACTORY_CLUSTERSCOPED_API_KEY` | `string` | Base factory key for clusterscoped API resources | -| `BASE_FACTORY_NAMESPACED_BUILTIN_KEY` | `string` | Base factory key for namespaced builtin (v1) resources | -| `BASE_FACTORY_CLUSTERSCOPED_BUILTIN_KEY` | `string` | Base factory key for clusterscoped builtin (v1) resources | -| `BASE_NAMESPACE_FACTORY_KEY` | `string` | Base factory key for namespaces | -| `CUSTOM_NAMESPACE_API_RESOURCE_API_GROUP` | `string` | Custom namespace resource: api group | -| `CUSTOM_NAMESPACE_API_RESOURCE_API_VERSION` | `string` | Custom namespace resource: api version | -| `CUSTOM_NAMESPACE_API_RESOURCE_RESOURCE_NAME` | `string` | Custom namespace resource: resource name | +| Variable | Type | Description | +| ------------------------------------------- | --------- | --------------------------------------------------------------------------------------- | +| `BASEPREFIX` | `string` | Base URL for the app. `/openapi-ui` | +| `KUBE_API_URL` | `string` | URL for the Kubernetes API. `http://api.incloud-web.svc.default.in-cloud.internal:8081` | +| `BFF_URL` | `string` | URL for the BFF | +| `TITLE_TEXT` | `string` | Page title | +| `LOGO_TEXT` | `string` | Logo text near icon | +| `ICON_SVG` | `string` | Favicon base64 encoded | +| `FOOTER_TEXT` | `string` | Footer text | +| `CUSTOM_LOGO_SVG` | `string` | Base64 encoded svg | +| `CUSTOM_TENANT_TEXT` | `string` | Custom tenant text override | +| `LOGIN_URL` | `string` | Login endpoint. `/oauth/token` | +| `LOGOUT_URL` | `string` | Logout endpoint. `/oauth/logout` | +| `LOGIN_USERNAME_FIELD` | `string` | Field from login endpoint response. `name` | +| `CUSTOMIZATION_API_GROUP` | `string` | API group for customization resources. `front.in-cloud.io` | +| `CUSTOMIZATION_API_VERSION` | `string` | API version for customization resources. `v1alpha1` | +| `CUSTOMIZATION_NAVIGATION_RESOURCE_PLURAL` | `string` | Resource plural name for navigation settings. `navigations` | +| `CUSTOMIZATION_NAVIGATION_RESOURCE_NAME` | `string` | Resource name for navigation settings. `navigation` | +| `CUSTOMIZATION_SIDEBAR_FALLBACK_ID` | `string` | `spec.id` to find in `sidebars` to fallback. Use `-namespaced` for NS-pages | +| `USE_NAMESPACE_NAV` | `boolean` | Use namespaces instead of project/instances. `true` | +| `HIDE_INSIDE` | `boolean` | Use namespaces instead of project/instances. `true` | +| `NAVIGATE_FROM_CLUSTERLIST` | `string` | Location to be navigated after selecting cluster. `/openapi-ui/clusters/~recordValue~` | +| `PROJECTS_API_GROUP` | `string` | API group for projects resources. If not using namespace nav. | +| `PROJECTS_API_VERSION` | `string` | API version for projects resources. If not using namespace nav. | +| `PROJECTS_PLURAL` | `string` | Plural name for projects resources. If not using namespace nav. | +| `INSTANCES_API_GROUP` | `string` | API group for instances resources. If not using namespace nav. | +| `INSTANCES_API_VERSION` | `string` | API version for instances resources. If not using namespace nav. | +| `INSTANCES_PLURAL` | `string` | Plural name for instances resources. If not using namespace nav. | +| `MARKETPLACE_PLURAL` | `string` | Plural name for marketplace resources for related factory component. | +| `MARKETPLACE_KIND` | `string` | Kind name for marketplace resources for related factory component. | +| `NODE_TERMINAL_DEFAULT_PROFILE` | `string` | Default profile for node terminal component. `baseline` | +| `REMOVE_BACKLINK` | `boolean` | Remove backlink arrow from right-side navigation | +| `REMOVE_BACKLINK_TEXT` | `boolean` | Remove backlink text from right-side navigation | +| `DOCS_URL` | `string` | URL to navigate from question mark | +| `SEARCH_TABLE_CUSTOMIZATION_PREFIX` | `string` | Search tables Customization id prefix | +| `BASE_FACTORY_NAMESPACED_API_KEY` | `string` | Base factory key for namespaced API resources | +| `BASE_FACTORY_CLUSTERSCOPED_API_KEY` | `string` | Base factory key for clusterscoped API resources | +| `BASE_FACTORY_NAMESPACED_BUILTIN_KEY` | `string` | Base factory key for namespaced builtin (v1) resources | +| `BASE_FACTORY_CLUSTERSCOPED_BUILTIN_KEY` | `string` | Base factory key for clusterscoped builtin (v1) resources | +| `BASE_NAMESPACE_FACTORY_KEY` | `string` | Base factory key for namespaces | +| `CUSTOM_NAMESPACE_API_RESOURCE_API_GROUP` | `string` | Custom namespace resource: api group | +| `CUSTOM_NAMESPACE_API_RESOURCE_API_VERSION` | `string` | Custom namespace resource: api version | +| `CUSTOM_NAMESPACE_API_RESOURCE_PLURAL` | `string` | Custom namespace resource: plural name | diff --git a/package-lock.json b/package-lock.json index b502cbe..b1a44eb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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.0.3", + "@prorobotech/openapi-k8s-toolkit": "^1.1.0-alpha.20", "@readme/openapi-parser": "4.0.0", "@reduxjs/toolkit": "2.2.5", "@tanstack/react-query": "5.62.2", @@ -146,7 +146,6 @@ "resolved": "https://registry.npmjs.org/@ant-design/icons/-/icons-5.6.0.tgz", "integrity": "sha512-Mb6QkQmPLZsmIHJ6oBsoyKrrT8/kAUdQ6+8q38e2bQSclROi69SiDlI4zZroaIPseae1w110RJH0zGrphAvlSQ==", "license": "MIT", - "peer": true, "dependencies": { "@ant-design/colors": "^7.0.0", "@ant-design/icons-svg": "^4.4.0", @@ -258,7 +257,6 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.27.1.tgz", "integrity": "sha512-IaaGWsQqfsQWVLqMn9OB92MNN7zukfVA4s7KKAI0KfrrDsZ0yhi5uV4baBuLuN7n3vsZpwP8asPPcVwApxvjBQ==", "license": "MIT", - "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.27.1", @@ -1859,6 +1857,7 @@ "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==", "license": "MIT", + "peer": true, "engines": { "node": ">=0.1.90" } @@ -1879,7 +1878,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=18" }, @@ -1903,7 +1901,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=18" } @@ -1960,6 +1957,7 @@ "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", "license": "MIT", + "peer": true, "dependencies": { "colorspace": "1.1.x", "enabled": "2.0.x", @@ -2804,9 +2802,9 @@ } }, "node_modules/@prorobotech/openapi-k8s-toolkit": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@prorobotech/openapi-k8s-toolkit/-/openapi-k8s-toolkit-1.0.3.tgz", - "integrity": "sha512-A8RFEd8CYdvYwnGHSOFEGZ+hotMWvtRRnXsZAcFycBF+oy6GNxCOCSfHv8IWlXfD7Rr4i7Xhp8MtDijAty+80g==", + "version": "1.1.0-alpha.20", + "resolved": "https://registry.npmjs.org/@prorobotech/openapi-k8s-toolkit/-/openapi-k8s-toolkit-1.1.0-alpha.20.tgz", + "integrity": "sha512-jptUG4OV2SLTgt3Z3rBUf2GNOGgS4QCTxOcrrkoreC0wyCkubTcI7+rflc29B2OOGcEi/2F6GCVf/H4qimgDnA==", "license": "MIT", "dependencies": { "@monaco-editor/react": "4.6.0", @@ -3711,7 +3709,6 @@ "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.62.2.tgz", "integrity": "sha512-fkTpKKfwTJtVPKVR+ag7YqFgG/7TRVVPzduPAUF9zRCiiA8Wu305u+KJl8rCrh98Qce77vzIakvtUyzWLtaPGA==", "license": "MIT", - "peer": true, "dependencies": { "@tanstack/query-core": "5.62.2" }, @@ -3728,7 +3725,6 @@ "resolved": "https://registry.npmjs.org/@tanstack/react-query-devtools/-/react-query-devtools-5.62.2.tgz", "integrity": "sha512-s4+88OZ6ygD4ziNfUgh9y1XxsGqpscI77c8EaLP7KwEfa5WqnlB9MT/uslFkFq3vwb8JhMjB7Osv2MYrSMry6w==", "license": "MIT", - "peer": true, "dependencies": { "@tanstack/query-devtools": "5.61.4" }, @@ -3863,7 +3859,6 @@ "integrity": "sha512-24xqse6+VByVLIr+xWaQ9muX1B4bXJKXBbjszbld/UEDslGLY53+ZucF44HCmLbMPejTzGG9XgR+3m2/Wqu1kw==", "devOptional": true, "license": "MIT", - "peer": true, "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -3953,7 +3948,8 @@ "version": "1.3.5", "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz", "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@types/use-sync-external-store": { "version": "0.0.3", @@ -4001,6 +3997,7 @@ "integrity": "sha512-LKMrmwCPoLhM45Z00O1ulb6jwyVr2kr3XJp+G+tSEZcbauNnScewcQwtJqXDhXeYPDEjZ8C1SjXm015CirEmGg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.32.1", "@typescript-eslint/types": "8.32.1", @@ -4026,6 +4023,7 @@ "integrity": "sha512-7IsIaIDeZn7kffk7qXC3o6Z4UblZJKV3UBpkvRNpr5NSyLji7tvTcvmnMNYuYLyh26mN8W723xpo3i4MlD33vA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/types": "8.32.1", "@typescript-eslint/visitor-keys": "8.32.1" @@ -4044,6 +4042,7 @@ "integrity": "sha512-ar0tjQfObzhSaW3C3QNmTc5ofj0hDoNQ5XWrCy6zDyabdr0TWhCkClp+rywGNj/odAFBVzzJrK4tEq5M4Hmu4w==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/types": "8.32.1", "eslint-visitor-keys": "^4.2.0" @@ -4062,6 +4061,7 @@ "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", "dev": true, "license": "Apache-2.0", + "peer": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -4188,6 +4188,7 @@ "integrity": "sha512-YmybwXUJcgGqgAp6bEsgpPXEg6dcCyPyCSr0CAAueacR/CCBi25G3V8gGQ2kRzQRBNol7VQknxMs9HvVa9Rvfg==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -4202,6 +4203,7 @@ "integrity": "sha512-Y3AP9EIfYwBb4kWGb+simvPaqQoT5oJuzzj9m0i6FCY6SPvlomY2Ei4UEMm7+FXtlNJbor80ximyslzaQF6xhg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/types": "8.32.1", "@typescript-eslint/visitor-keys": "8.32.1", @@ -4229,6 +4231,7 @@ "integrity": "sha512-ar0tjQfObzhSaW3C3QNmTc5ofj0hDoNQ5XWrCy6zDyabdr0TWhCkClp+rywGNj/odAFBVzzJrK4tEq5M4Hmu4w==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/types": "8.32.1", "eslint-visitor-keys": "^4.2.0" @@ -4247,6 +4250,7 @@ "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", "dev": true, "license": "Apache-2.0", + "peer": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -4260,6 +4264,7 @@ "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", "dev": true, "license": "ISC", + "peer": true, "bin": { "semver": "bin/semver.js" }, @@ -4273,6 +4278,7 @@ "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=18.12" }, @@ -4433,8 +4439,7 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/@xterm/xterm/-/xterm-5.5.0.tgz", "integrity": "sha512-hqJHYaQb5OptNunnyAnkHyM8aCjZ1MEIDTQu1iIbbTD/xops91NB5yq1ZK/dC2JDbVWtF23zUtl9JE2NqwT87A==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/accepts": { "version": "1.3.8", @@ -4455,7 +4460,6 @@ "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -4478,7 +4482,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -4535,7 +4538,6 @@ "resolved": "https://registry.npmjs.org/antd/-/antd-5.26.4.tgz", "integrity": "sha512-e1EnOvEkvvqcQ18dxfzChBJyJACyih13WpNf2OtnP9z2POh/SF0fXL+ynUemT1zfr+p+P1po/tmHXaMc5PMghg==", "license": "MIT", - "peer": true, "dependencies": { "@ant-design/colors": "^7.2.1", "@ant-design/cssinjs": "^1.23.0", @@ -4853,7 +4855,8 @@ "version": "3.2.6", "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/async-function": { "version": "1.0.0", @@ -5256,7 +5259,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001716", "electron-to-chromium": "^1.5.149", @@ -5506,6 +5508,7 @@ "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", "license": "MIT", + "peer": true, "dependencies": { "color-convert": "^1.9.3", "color-string": "^1.6.0" @@ -5535,6 +5538,7 @@ "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", "license": "MIT", + "peer": true, "dependencies": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" @@ -5545,6 +5549,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "license": "MIT", + "peer": true, "dependencies": { "color-name": "1.1.3" } @@ -5553,7 +5558,8 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/colord": { "version": "2.9.3", @@ -5566,6 +5572,7 @@ "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", "license": "MIT", + "peer": true, "dependencies": { "color": "^3.1.3", "text-hex": "1.0.x" @@ -5963,8 +5970,7 @@ "version": "1.11.13", "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz", "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/debug": { "version": "4.4.1", @@ -6194,7 +6200,8 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/encodeurl": { "version": "1.0.2", @@ -6563,7 +6570,6 @@ "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -6725,7 +6731,6 @@ "integrity": "sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "array-includes": "^3.1.6", "array.prototype.findlastindex": "^1.2.2", @@ -6805,7 +6810,6 @@ "integrity": "sha512-63Bog4iIethyo8smBklORknVjB0T2dwB8Mr/hIC+fBS0uyHdYYpzM/Ed+YC8VxTjlXHEWFOdmgwcDn1U2L9VCA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/runtime": "^7.20.7", "aria-query": "^5.1.3", @@ -6891,7 +6895,6 @@ "integrity": "sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "array-includes": "^3.1.6", "array.prototype.flatmap": "^1.3.1", @@ -6923,7 +6926,6 @@ "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=10" }, @@ -7501,7 +7503,8 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/file-entry-cache": { "version": "6.0.1", @@ -7604,7 +7607,8 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/follow-redirects": { "version": "1.15.9", @@ -8741,6 +8745,7 @@ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "license": "MIT", + "peer": true, "engines": { "node": ">=8" }, @@ -9031,7 +9036,8 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/language-subtag-registry": { "version": "0.3.23", @@ -9127,6 +9133,7 @@ "resolved": "https://registry.npmjs.org/logform/-/logform-2.7.0.tgz", "integrity": "sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ==", "license": "MIT", + "peer": true, "dependencies": { "@colors/colors": "1.6.0", "@types/triple-beam": "^1.3.2", @@ -9672,6 +9679,7 @@ "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", "license": "MIT", + "peer": true, "dependencies": { "fn.name": "1.x.x" } @@ -9680,8 +9688,7 @@ "version": "12.1.3", "resolved": "https://registry.npmjs.org/openapi-types/-/openapi-types-12.1.3.tgz", "integrity": "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/optionator": { "version": "0.9.4", @@ -9967,7 +9974,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "nanoid": "^3.3.8", "picocolors": "^1.1.1", @@ -10017,7 +10023,6 @@ "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -10089,7 +10094,6 @@ "integrity": "sha512-o2YR9qtniXvwEZlOKbveKfDQVyqxbEIWn48Z8m3ZJjBjcCmUy3xZGIv+7AkaeuaTr6yPXJjwv07ZWlsWbEy1rQ==", "dev": true, "license": "MIT", - "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -10135,7 +10139,6 @@ "resolved": "https://registry.npmjs.org/prom-client/-/prom-client-15.1.3.tgz", "integrity": "sha512-6ZiOBfCywsD4k1BN9IX0uZhF+tJkV8q8llP64G5Hajs4JOeVLPCwpPVcpXy3BwYiUGgyJzsJJQeOIv7+hDSq8g==", "license": "Apache-2.0", - "peer": true, "dependencies": { "@opentelemetry/api": "^1.4.0", "tdigest": "^0.1.1" @@ -10912,7 +10915,6 @@ "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "license": "MIT", - "peer": true, "dependencies": { "loose-envify": "^1.1.0" }, @@ -10925,7 +10927,6 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "license": "MIT", - "peer": true, "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" @@ -10984,7 +10985,6 @@ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.25.1.tgz", "integrity": "sha512-0tUDpbFvk35iv+N89dWNrJp+afLgd+y4VtorJZuOCXK0kkCWjEvb3vTJM++SYvMEpbVwXKf3FjeVveVEb6JpDQ==", "license": "MIT", - "peer": true, "dependencies": { "@remix-run/router": "1.18.0", "react-router": "6.25.1" @@ -11028,8 +11028,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/redux-thunk": { "version": "3.1.0", @@ -11261,7 +11260,6 @@ "integrity": "sha512-HqMFpUbWlf/tvcxBFNKnJyzc7Lk+XO3FGc3pbNBLqEbOz0gPLRgcrlS3UF4MfUrVlstOaP/q0kM6GVvi+LrLRg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/estree": "1.0.7" }, @@ -11400,6 +11398,7 @@ "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", "license": "MIT", + "peer": true, "engines": { "node": ">=10" } @@ -11684,6 +11683,7 @@ "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", "license": "MIT", + "peer": true, "dependencies": { "is-arrayish": "^0.3.1" } @@ -11692,7 +11692,8 @@ "version": "0.3.2", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/slash": { "version": "2.0.0", @@ -11758,6 +11759,7 @@ "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", "license": "MIT", + "peer": true, "engines": { "node": "*" } @@ -12282,7 +12284,8 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/text-table": { "version": "0.2.0", @@ -12345,6 +12348,7 @@ "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz", "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==", "license": "MIT", + "peer": true, "engines": { "node": ">= 14.0.0" } @@ -12974,7 +12978,6 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -13211,7 +13214,6 @@ "integrity": "sha512-IeL5f8OO5nylsgzd9tq4qD2QqI0k2CQLGrWD0rCN0EQJZpBK5vJAx0I+GDkMOXxQX/OfFHMuLIx6ddAxGX/k+Q==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.43", @@ -13463,6 +13465,7 @@ "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.9.0.tgz", "integrity": "sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A==", "license": "MIT", + "peer": true, "dependencies": { "logform": "^2.7.0", "readable-stream": "^3.6.2", diff --git a/package.json b/package.json index 9ee35fd..89c514d 100644 --- a/package.json +++ b/package.json @@ -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.0.3", + "@prorobotech/openapi-k8s-toolkit": "1.1.0-alpha.20", "@readme/openapi-parser": "4.0.0", "@reduxjs/toolkit": "2.2.5", "@tanstack/react-query": "5.62.2", diff --git a/server/index.ts b/server/index.ts index f14aca6..dc7abc9 100644 --- a/server/index.ts +++ b/server/index.ts @@ -29,14 +29,19 @@ const CUSTOMIZATION_API_GROUP = const CUSTOMIZATION_API_VERSION = process.env.LOCAL === 'true' ? options?.CUSTOMIZATION_API_VERSION : process.env.CUSTOMIZATION_API_VERSION +const CUSTOMIZATION_NAVIGATION_RESOURCE_PLURAL = + process.env.LOCAL === 'true' + ? options?.CUSTOMIZATION_NAVIGATION_RESOURCE_PLURAL + : process.env.CUSTOMIZATION_NAVIGATION_RESOURCE_PLURAL const CUSTOMIZATION_NAVIGATION_RESOURCE_NAME = process.env.LOCAL === 'true' ? options?.CUSTOMIZATION_NAVIGATION_RESOURCE_NAME : process.env.CUSTOMIZATION_NAVIGATION_RESOURCE_NAME -const CUSTOMIZATION_NAVIGATION_RESOURCE = + +const CUSTOMIZATION_SIDEBAR_FALLBACK_ID = process.env.LOCAL === 'true' - ? options?.CUSTOMIZATION_NAVIGATION_RESOURCE - : process.env.CUSTOMIZATION_NAVIGATION_RESOURCE + ? options?.CUSTOMIZATION_SIDEBAR_FALLBACK_ID + : process.env.CUSTOMIZATION_SIDEBAR_FALLBACK_ID const USE_NAMESPACE_NAV = process.env.LOCAL === 'true' ? options?.USE_NAMESPACE_NAV : process.env.USE_NAMESPACE_NAV const HIDE_INSIDE = process.env.LOCAL === 'true' ? options?.HIDE_INSIDE : process.env.HIDE_INSIDE @@ -45,19 +50,18 @@ const NAVIGATE_FROM_CLUSTERLIST = process.env.LOCAL === 'true' ? options?.NAVIGATE_FROM_CLUSTERLIST : process.env.NAVIGATE_FROM_CLUSTERLIST const PROJECTS_API_GROUP = process.env.LOCAL === 'true' ? options?.PROJECTS_API_GROUP : process.env.PROJECTS_API_GROUP -const PROJECTS_VERSION = process.env.LOCAL === 'true' ? options?.PROJECTS_VERSION : process.env.PROJECTS_VERSION -const PROJECTS_RESOURCE_NAME = - process.env.LOCAL === 'true' ? options?.PROJECTS_RESOURCE_NAME : process.env.PROJECTS_RESOURCE_NAME +const PROJECTS_API_VERSION = + process.env.LOCAL === 'true' ? options?.PROJECTS_API_VERSION : process.env.PROJECTS_API_VERSION +const PROJECTS_PLURAL = process.env.LOCAL === 'true' ? options?.PROJECTS_PLURAL : process.env.PROJECTS_PLURAL -const MARKETPLACE_RESOURCE_NAME = - process.env.LOCAL === 'true' ? options?.MARKETPLACE_RESOURCE_NAME : process.env.MARKETPLACE_RESOURCE_NAME +const MARKETPLACE_PLURAL = process.env.LOCAL === 'true' ? options?.MARKETPLACE_PLURAL : process.env.MARKETPLACE_PLURAL const MARKETPLACE_KIND = process.env.LOCAL === 'true' ? options?.MARKETPLACE_KIND : process.env.MARKETPLACE_KIND const INSTANCES_API_GROUP = process.env.LOCAL === 'true' ? options?.INSTANCES_API_GROUP : process.env.INSTANCES_API_GROUP -const INSTANCES_VERSION = process.env.LOCAL === 'true' ? options?.INSTANCES_VERSION : process.env.INSTANCES_VERSION -const INSTANCES_RESOURCE_NAME = - process.env.LOCAL === 'true' ? options?.INSTANCES_RESOURCE_NAME : process.env.INSTANCES_RESOURCE_NAME +const INSTANCES_API_VERSION = + process.env.LOCAL === 'true' ? options?.INSTANCES_API_VERSION : process.env.INSTANCES_API_VERSION +const INSTANCES_PLURAL = process.env.LOCAL === 'true' ? options?.INSTANCES_PLURAL : process.env.INSTANCES_PLURAL const BFF_URL = process.env.LOCAL === 'true' ? options?.BFF_URL : process.env.BFF_URL @@ -105,10 +109,10 @@ const CUSTOM_NAMESPACE_API_RESOURCE_API_VERSION = process.env.LOCAL === 'true' ? options?.CUSTOM_NAMESPACE_API_RESOURCE_API_VERSION : process.env.CUSTOM_NAMESPACE_API_RESOURCE_API_VERSION -const CUSTOM_NAMESPACE_API_RESOURCE_RESOURCE_NAME = +const CUSTOM_NAMESPACE_API_RESOURCE_PLURAL = process.env.LOCAL === 'true' - ? options?.CUSTOM_NAMESPACE_API_RESOURCE_RESOURCE_NAME - : process.env.CUSTOM_NAMESPACE_API_RESOURCE_RESOURCE_NAME + ? options?.CUSTOM_NAMESPACE_API_RESOURCE_PLURAL + : process.env.CUSTOM_NAMESPACE_API_RESOURCE_PLURAL const healthcheck = require('express-healthcheck') const promBundle = require('express-prom-bundle') @@ -220,6 +224,9 @@ app.get(`${basePrefix ? basePrefix : ''}/env.js`, (_, res) => { ${CUSTOM_TENANT_TEXT ? ` CUSTOM_TENANT_TEXT: "${CUSTOM_TENANT_TEXT}",` : ''} CUSTOMIZATION_API_GROUP: ${JSON.stringify(CUSTOMIZATION_API_GROUP) || '"check envs"'}, CUSTOMIZATION_API_VERSION: ${JSON.stringify(CUSTOMIZATION_API_VERSION) || '"check envs"'}, + CUSTOMIZATION_NAVIGATION_RESOURCE_PLURAL: ${ + JSON.stringify(CUSTOMIZATION_NAVIGATION_RESOURCE_PLURAL) || '"check envs"' + }, CUSTOMIZATION_NAVIGATION_RESOURCE_NAME: ${ JSON.stringify(CUSTOMIZATION_NAVIGATION_RESOURCE_NAME) || '"check envs"' }, @@ -234,22 +241,22 @@ app.get(`${basePrefix ? basePrefix : ''}/env.js`, (_, res) => { : '' } ${ - CUSTOM_NAMESPACE_API_RESOURCE_RESOURCE_NAME - ? ` CUSTOM_NAMESPACE_API_RESOURCE_RESOURCE_NAME: "${CUSTOM_NAMESPACE_API_RESOURCE_RESOURCE_NAME}",` + CUSTOM_NAMESPACE_API_RESOURCE_PLURAL + ? ` CUSTOM_NAMESPACE_API_RESOURCE_PLURAL: "${CUSTOM_NAMESPACE_API_RESOURCE_PLURAL}",` : '' } - CUSTOMIZATION_NAVIGATION_RESOURCE: ${JSON.stringify(CUSTOMIZATION_NAVIGATION_RESOURCE) || '"check envs"'}, + CUSTOMIZATION_SIDEBAR_FALLBACK_ID: ${JSON.stringify(CUSTOMIZATION_SIDEBAR_FALLBACK_ID) || '"check envs"'}, USE_NAMESPACE_NAV: ${USE_NAMESPACE_NAV ? JSON.stringify(USE_NAMESPACE_NAV).toLowerCase() : '"false"'}, HIDE_INSIDE: ${HIDE_INSIDE ? JSON.stringify(HIDE_INSIDE).toLowerCase() : '"false"'}, NAVIGATE_FROM_CLUSTERLIST: ${JSON.stringify(NAVIGATE_FROM_CLUSTERLIST) || '"check envs"'}, PROJECTS_API_GROUP: ${JSON.stringify(PROJECTS_API_GROUP) || '"check envs"'}, - PROJECTS_VERSION: ${JSON.stringify(PROJECTS_VERSION) || '"check envs"'}, - PROJECTS_RESOURCE_NAME: ${JSON.stringify(PROJECTS_RESOURCE_NAME) || '"check envs"'}, - MARKETPLACE_RESOURCE_NAME: ${JSON.stringify(MARKETPLACE_RESOURCE_NAME) || '"check envs"'}, + PROJECTS_API_VERSION: ${JSON.stringify(PROJECTS_API_VERSION) || '"check envs"'}, + PROJECTS_PLURAL: ${JSON.stringify(PROJECTS_PLURAL) || '"check envs"'}, + MARKETPLACE_PLURAL: ${JSON.stringify(MARKETPLACE_PLURAL) || '"check envs"'}, MARKETPLACE_KIND: ${JSON.stringify(MARKETPLACE_KIND) || '"check envs"'}, INSTANCES_API_GROUP: ${JSON.stringify(INSTANCES_API_GROUP) || '"check envs"'}, - INSTANCES_VERSION: ${JSON.stringify(INSTANCES_VERSION) || '"check envs"'}, - INSTANCES_RESOURCE_NAME: ${JSON.stringify(INSTANCES_RESOURCE_NAME) || '"check envs"'}, + INSTANCES_API_VERSION: ${JSON.stringify(INSTANCES_API_VERSION) || '"check envs"'}, + INSTANCES_PLURAL: ${JSON.stringify(INSTANCES_PLURAL) || '"check envs"'}, NODE_TERMINAL_DEFAULT_PROFILE: ${JSON.stringify(NODE_TERMINAL_DEFAULT_PROFILE) || '"general"'}, LOGIN_URL: ${JSON.stringify(LOGIN_URL) || '"check envs"'}, LOGOUT_URL: ${JSON.stringify(LOGOUT_URL) || '"check envs"'}, diff --git a/src/App.tsx b/src/App.tsx index 6711b2b..aff33c1 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -12,25 +12,25 @@ import { setBaseprefix } from 'store/federation/federation/baseprefix' import { MainPage, ListClustersPage, - ListProjectsPage, - ProjectInfoPage, + RedirectProjectsPage, + RedirectProjectInfoPage, ListInsideClustersAndNsPage, ListInsideApiPage, ListInsideCrdByApiGroupPage, ListInsideApiByApiGroupPage, - TableCrdPage, + // TableCrdPage, TableApiPage, TableBuiltinPage, FormBuiltinPage, FormApiPage, - FormCrdPage, + // FormCrdPage, FactoryPage, - FactoryAdminPage, + // FactoryAdminPage, SearchPage, } from 'pages' import { getBasePrefix } from 'utils/getBaseprefix' import { colorsLight, colorsDark, sizes } from 'constants/colors' -import { MainLayout } from 'templates/MainLayout' +import { MainLayout, AppShell } from 'templates' type TAppProps = { isFederation?: boolean @@ -58,73 +58,40 @@ export const App: FC = ({ isFederation, forcedTheme }) => { }> } /> } /> - } /> + + }> + {/* } /> */} + } /> + } /> + {/* } /> */} + } /> + } /> + } /> + } /> + + + }> + {/* } /> */} + } /> + } /> + {/* } /> */} + } /> + } /> + + } /> - } /> } /> - } /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } /> - } /> + }> + } /> + } + /> + } /> + + + } /> + } /> ) diff --git a/src/components/atoms/RedirectProjectInfo/RedirectProjectInfo.tsx b/src/components/atoms/RedirectProjectInfo/RedirectProjectInfo.tsx index 584263b..cde4448 100644 --- a/src/components/atoms/RedirectProjectInfo/RedirectProjectInfo.tsx +++ b/src/components/atoms/RedirectProjectInfo/RedirectProjectInfo.tsx @@ -4,15 +4,15 @@ import { useSelector } from 'react-redux' import { RootState } from 'store/store' export const RedirectProjectInfo: FC = () => { - const { clusterName, namespace } = useParams() + const { cluster, namespace } = useParams() const navigate = useNavigate() const baseprefix = useSelector((state: RootState) => state.baseprefix.baseprefix) - navigate(`${baseprefix}/${clusterName}/${namespace}/factory/project/${namespace}`) + navigate(`${baseprefix}/${cluster}/${namespace}/factory/project/${namespace}`) useEffect(() => { - navigate(`${baseprefix}/${clusterName}/${namespace}/factory/project/${namespace}`) - }, [clusterName, namespace, baseprefix, navigate]) + navigate(`${baseprefix}/${cluster}/${namespace}/factory/project/${namespace}`) + }, [cluster, namespace, baseprefix, navigate]) return null } diff --git a/src/components/atoms/RedirectProjectList/RedirectProjectList.tsx b/src/components/atoms/RedirectProjectList/RedirectProjectList.tsx index 40e8c38..cf08411 100644 --- a/src/components/atoms/RedirectProjectList/RedirectProjectList.tsx +++ b/src/components/atoms/RedirectProjectList/RedirectProjectList.tsx @@ -4,24 +4,24 @@ import { useSelector } from 'react-redux' import { RootState } from 'store/store' import { BASE_PROJECTS_API_GROUP, - BASE_PROJECTS_VERSION, - BASE_PROJECTS_RESOURCE_NAME, + BASE_PROJECTS_API_VERSION, + BASE_PROJECTS_PLURAL, } from 'constants/customizationApiGroupAndVersion' export const RedirectProjectList: FC = () => { - const { clusterName } = useParams() + const { cluster } = useParams() const navigate = useNavigate() const baseprefix = useSelector((state: RootState) => state.baseprefix.baseprefix) navigate( - `${baseprefix}/${clusterName}/api-table/${BASE_PROJECTS_API_GROUP}/${BASE_PROJECTS_VERSION}/${BASE_PROJECTS_RESOURCE_NAME}`, + `${baseprefix}/${cluster}/api-table/${BASE_PROJECTS_API_GROUP}/${BASE_PROJECTS_API_VERSION}/${BASE_PROJECTS_PLURAL}`, ) useEffect(() => { navigate( - `${baseprefix}/${clusterName}/api-table/${BASE_PROJECTS_API_GROUP}/${BASE_PROJECTS_VERSION}/${BASE_PROJECTS_RESOURCE_NAME}`, + `${baseprefix}/${cluster}/api-table/${BASE_PROJECTS_API_GROUP}/${BASE_PROJECTS_API_VERSION}/${BASE_PROJECTS_PLURAL}`, ) - }, [clusterName, baseprefix, navigate]) + }, [cluster, baseprefix, navigate]) return null } diff --git a/src/components/molecules/BlackholeForm/BlackholeForm.tsx b/src/components/molecules/BlackholeForm/BlackholeForm.tsx index ceb2139..1f58752 100644 --- a/src/components/molecules/BlackholeForm/BlackholeForm.tsx +++ b/src/components/molecules/BlackholeForm/BlackholeForm.tsx @@ -1,6 +1,6 @@ import React, { FC, useState, useEffect } from 'react' import { useParams } from 'react-router-dom' -import { BlackholeFormDataProvider, TJSON } from '@prorobotech/openapi-k8s-toolkit' +import { BlackholeFormProvider, TJSON } from '@prorobotech/openapi-k8s-toolkit' import { useSelector } from 'react-redux' import type { RootState } from 'store/store' import { @@ -17,7 +17,7 @@ type TBlackholeFormProps = { data: | { type: 'builtin' - typeName: string + plural: string prefillValuesSchema?: TJSON prefillValueNamespaceOnly?: string } @@ -25,7 +25,7 @@ type TBlackholeFormProps = { type: 'apis' apiGroup: string apiVersion: string - typeName: string + plural: string prefillValuesSchema?: TJSON prefillValueNamespaceOnly?: string } @@ -71,19 +71,19 @@ export const BlackholeForm: FC = ({ data, customizationId, }, []) const urlParams = { - clusterName: params.clusterName, + cluster: params.cluster, namespace: params.namespace, syntheticProject: params.syntheticProject, - entryName: params.entryName, + name: params.name, } const urlParamsForPermissions = { apiGroup: params.apiGroup, - typeName: params.typeName, + plural: params.plural, } return ( - = ({ idToCom const location = useLocation() const { pathname } = useLocation() const params = useParams() - const clusterName = params?.clusterName || '' + const cluster = params?.cluster || '' const namespace = params?.namespace || '' const syntheticProject = params?.syntheticProject || '' const apiGroup = params?.apiGroup || '' const apiVersion = params?.apiVersion || '' - const typeName = params?.typeName || '' - const entryName = params?.entryName || '' + const plural = params?.plural || '' + const name = params?.name || '' const apiExtensionVersion = params?.apiExtensionVersion || '' const crdName = params?.crdName || '' @@ -30,15 +30,15 @@ export const ManageableBreadcrumbs: FC = ({ idToCom }, {}) return ( - = ({ idToCom entryType: '', apiGroup, apiVersion, - typeName, - entryName, + plural, + name, apiExtensionVersion, crdName, ...replaceValuesPartsOfUrls, diff --git a/src/components/molecules/ManageableSidebar/ManageableSidebar.tsx b/src/components/molecules/ManageableSidebar/ManageableSidebar.tsx index c883e28..f5e3246 100644 --- a/src/components/molecules/ManageableSidebar/ManageableSidebar.tsx +++ b/src/components/molecules/ManageableSidebar/ManageableSidebar.tsx @@ -1,12 +1,15 @@ import React, { FC, useState, useEffect } from 'react' import { theme as antdtheme } from 'antd' import { useLocation, useParams } from 'react-router-dom' -import { ManageableSidebarWithDataProvider } from '@prorobotech/openapi-k8s-toolkit' +import { ManageableSidebarProvider } from '@prorobotech/openapi-k8s-toolkit' import { useSelector } from 'react-redux' import type { RootState } from 'store/store' -// import { HEAD_FIRST_ROW, SIDEBAR_CLUSTER_HEIGHT } from 'constants/blocksSizes' import { HEAD_FIRST_ROW } from 'constants/blocksSizes' -import { BASE_API_GROUP, BASE_API_VERSION } from 'constants/customizationApiGroupAndVersion' +import { + BASE_API_GROUP, + BASE_API_VERSION, + CUSTOMIZATION_SIDEBAR_FALLBACK_ID, +} from 'constants/customizationApiGroupAndVersion' import { Styled } from './styled' type TManageableSidebarProps = { @@ -25,7 +28,7 @@ export const ManageableSidebar: FC = ({ const location = useLocation() const { pathname } = useLocation() const params = useParams() - const clusterName = params?.clusterName || '' + const cluster = params?.cluster || '' const namespace = params?.namespace || '' const syntheticProject = params?.syntheticProject || '' const theme = useSelector((state: RootState) => state.openapiTheme.theme) @@ -34,7 +37,6 @@ export const ManageableSidebar: FC = ({ const [height, setHeight] = useState(0) useEffect(() => { - // const height = window.innerHeight - HEAD_FIRST_ROW - SIDEBAR_CLUSTER_HEIGHT - 2 const height = window.innerHeight - HEAD_FIRST_ROW - 2 setHeight(height) @@ -66,12 +68,14 @@ export const ManageableSidebar: FC = ({ $colorBorder={token.colorBorder} $maxHeight={height} > - = ({ }} pathname={pathname} idToCompare={idToCompare} + fallbackIdToCompare={ + namespace ? `${CUSTOMIZATION_SIDEBAR_FALLBACK_ID}-namespaced` : CUSTOMIZATION_SIDEBAR_FALLBACK_ID + } currentTags={currentTags} noMarginTop /> diff --git a/src/components/molecules/TableApiBuiltin/TableApiBuiltin.tsx b/src/components/molecules/TableApiBuiltin/TableApiBuiltin.tsx index 4a27a36..af9fdf5 100644 --- a/src/components/molecules/TableApiBuiltin/TableApiBuiltin.tsx +++ b/src/components/molecules/TableApiBuiltin/TableApiBuiltin.tsx @@ -10,12 +10,10 @@ import { usePermissions, DeleteModal, DeleteModalMany, - // checkIfBuiltInInstanceNamespaceScoped, - // checkIfApiInstanceNamespaceScoped, - useBuiltinResources, - useApiResources, + useK8sSmartResource, Spacer, getLinkToForm, + TSingleResource, } from '@prorobotech/openapi-k8s-toolkit' import { FlexGrow, PaddingContainer } from 'components' import { TABLE_PROPS } from 'constants/tableProps' @@ -28,17 +26,16 @@ import { TABLE_ADD_BUTTON_HEIGHT, } from 'constants/blocksSizes' import { OverflowContainer } from './atoms' -import { getDataItems } from './utils' type TTableApiBuiltinProps = { namespace?: string resourceType: 'builtin' | 'api' apiGroup?: string // api apiVersion: string // api - typeName: string + plural: string labels?: string[] fields?: string[] - limit: string | null + limit?: number inside?: boolean customizationIdPrefix: string searchMount?: boolean @@ -50,7 +47,7 @@ export const TableApiBuiltin: FC = ({ resourceType, apiGroup, apiVersion, - typeName, + plural, labels, fields, limit, @@ -72,8 +69,6 @@ export const TableApiBuiltin: FC = ({ ) const [selectedRowKeys, setSelectedRowKeys] = useState([]) const [selectedRowsData, setSelectedRowsData] = useState<{ name: string; endpoint: string }[]>([]) - // const [isNamespaced, setIsNamespaced] = useState() - // const [isNamespacedLoading, setIsNamespacedLoading] = useState() const [height, setHeight] = useState(0) @@ -99,77 +94,28 @@ export const TableApiBuiltin: FC = ({ } }, []) - // useEffect(() => { - // setIsNamespacedLoading(true) - // if (resourceType === 'builtin') { - // checkIfBuiltInInstanceNamespaceScoped({ - // typeName, - // clusterName: cluster, - // }) - // .then(({ isNamespaceScoped }) => { - // if (isNamespaceScoped) { - // setIsNamespaced(isNamespaceScoped) - // } else { - // setIsNamespaced(false) - // } - // }) - // .finally(() => setIsNamespacedLoading(false)) - // } - // if (resourceType === 'api' && apiGroup && apiVersion) { - // checkIfApiInstanceNamespaceScoped({ - // apiGroup, - // apiVersion, - // typeName, - // clusterName: cluster, - // }) - // .then(({ isNamespaceScoped }) => { - // if (isNamespaceScoped) { - // setIsNamespaced(true) - // } else { - // setIsNamespaced(false) - // } - // }) - // .finally(() => setIsNamespacedLoading(false)) - // } - // }, [resourceType, cluster, typeName, apiGroup, apiVersion]) - const createPermission = usePermissions({ - group: apiGroup || undefined, - resource: typeName, + apiGroup: apiGroup || undefined, + plural, namespace: params.namespace, - clusterName: cluster, + cluster, verb: 'create', refetchInterval: false, }) const { - isPending: isPendingBuiltin, - error: errorBuiltin, - data: dataBuiltin, - } = useBuiltinResources({ - clusterName: cluster, + data: dataItems, + isLoading, + error, + } = useK8sSmartResource<{ items: TSingleResource[] }>({ + cluster, namespace, - typeName, - labels, - fields, - limit, - isEnabled: resourceType === 'builtin', - }) - - const { - isPending: isPendingApi, - error: errorApi, - data: dataApi, - } = useApiResources({ - clusterName: cluster, - namespace, - apiGroup: apiGroup || '', + apiGroup, apiVersion: apiVersion || '', - typeName, - labels, - fields, + plural, + labelSelector: labels ? encodeURIComponent(labels.join(',')) : undefined, + fieldSelector: fields ? encodeURIComponent(fields.join(',')) : undefined, limit, - isEnabled: resourceType === 'api' && !!apiGroup && !!apiVersion, }) const onDeleteHandle = (name: string, endpoint: string) => { @@ -192,86 +138,62 @@ export const TableApiBuiltin: FC = ({ return ( <> - {((resourceType === 'builtin' && isPendingBuiltin) || (resourceType === 'api' && isPendingApi)) && } - {resourceType === 'builtin' && errorBuiltin && ( - - )} - {resourceType === 'api' && errorApi && ( - - )} + {isLoading && } + {error && } - {!errorBuiltin && - !errorApi && - ((resourceType === 'builtin' && dataBuiltin) || (resourceType === 'api' && dataApi)) && ( - { - setSelectedRowKeys(selectedRowKeys) - setSelectedRowsData(selectedRowsData) - }, - }} - tableProps={{ ...TABLE_PROPS, disablePagination: !searchMount }} - // maxHeight={height - 65} - /> - )} - {/* {selectedRowKeys.length > 0 && ( - - - - - - - )} */} + {!error && dataItems && ( + { + setSelectedRowKeys(selectedRowKeys) + setSelectedRowsData(selectedRowsData) + }, + }} + tableProps={{ ...TABLE_PROPS, disablePagination: !searchMount }} + /> + )} {searchMount ? : } @@ -286,15 +208,13 @@ export const TableApiBuiltin: FC = ({ syntheticProject: params.syntheticProject, apiGroup, apiVersion, - typeName, + plural, inside, fullPath, searchMount, }) navigate(url) }} - // loading={isNamespaced ? false : createPermission.isPending} - // disabled={isNamespaced ? false : !createPermission.data?.status.allowed} loading={createPermission.isPending} disabled={!createPermission.data?.status.allowed} > diff --git a/src/components/molecules/TableApiBuiltin/utils.ts b/src/components/molecules/TableApiBuiltin/utils.ts index dde900f..1e4cd77 100644 --- a/src/components/molecules/TableApiBuiltin/utils.ts +++ b/src/components/molecules/TableApiBuiltin/utils.ts @@ -1,4 +1,4 @@ -import { TBuiltinResources, TApiResources, TJSON } from '@prorobotech/openapi-k8s-toolkit' +import { TSingleResource, TJSON } from '@prorobotech/openapi-k8s-toolkit' export const getDataItems = ({ resourceType, @@ -6,8 +6,8 @@ export const getDataItems = ({ dataApi, }: { resourceType: 'builtin' | 'api' - dataBuiltin?: TBuiltinResources - dataApi?: TApiResources + dataBuiltin?: TSingleResource[] + dataApi?: TSingleResource[] }): TJSON[] => { - return resourceType === 'builtin' ? dataBuiltin?.items || [] : dataApi?.items || [] + return resourceType === 'builtin' ? dataBuiltin || [] : dataApi || [] } diff --git a/src/components/molecules/TableCrdInfo/TableCrdInfo.tsx b/src/components/molecules/TableCrdInfo/TableCrdInfo.tsx index fbd8519..2bb728d 100644 --- a/src/components/molecules/TableCrdInfo/TableCrdInfo.tsx +++ b/src/components/molecules/TableCrdInfo/TableCrdInfo.tsx @@ -1,6 +1,12 @@ import React, { FC, useState, useEffect } from 'react' import { Spin, Alert } from 'antd' -import { usePermissions, checkIfApiInstanceNamespaceScoped, useCrdData } from '@prorobotech/openapi-k8s-toolkit' +import { + usePermissions, + checkIfApiInstanceNamespaceScoped, + // useCrdData, + useK8sSmartResource, + TCRD, +} from '@prorobotech/openapi-k8s-toolkit' import { useSelector } from 'react-redux' import { RootState } from 'store/store' import { ResourceInfo } from './molecules' @@ -28,19 +34,29 @@ export const TableCrdInfo: FC = ({ const [isNamespaced, setIsNamespaced] = useState() - const { isPending, error, data } = useCrdData({ - clusterName: cluster, - crdName, - apiExtensionVersion, + const { + data: dataArr, + isLoading: isPending, + error, + } = useK8sSmartResource<{ + items: TCRD[] + }>({ + cluster, + apiGroup: 'apiextensions.k8s.io', + apiVersion: apiExtensionVersion, + plural: 'customresourcedefinitions', + fieldSelector: `metadata.name=${crdName}`, }) + const data = dataArr?.items && dataArr.items.length > 0 ? dataArr.items[0] : undefined + useEffect(() => { if (data && !isPending && !error) { checkIfApiInstanceNamespaceScoped({ apiGroup, apiVersion, - typeName: data.spec.names.plural, - clusterName: cluster, + plural: data.spec.names.plural, + cluster, }).then(({ isNamespaceScoped }) => { if (isNamespaceScoped) { setIsNamespaced(true) @@ -50,28 +66,28 @@ export const TableCrdInfo: FC = ({ }, [cluster, data, isPending, error, apiGroup, apiVersion]) const createPermission = usePermissions({ - group: apiGroup, - resource: data ? data.spec.names.singular : '', + apiGroup, + plural: data ? data.spec.names.singular : '', namespace: '', - clusterName: cluster, + cluster, verb: 'create', refetchInterval: false, }) const updatePermission = usePermissions({ - group: apiGroup, - resource: data ? data.spec.names.singular : '', + apiGroup, + plural: data ? data.spec.names.singular : '', namespace: '', - clusterName: cluster, + cluster, verb: 'update', refetchInterval: false, }) const deletePermission = usePermissions({ - group: apiGroup, - resource: data ? data.spec.names.singular : '', + apiGroup, + plural: data ? data.spec.names.singular : '', namespace: '', - clusterName: cluster, + cluster, verb: 'delete', refetchInterval: false, }) @@ -79,10 +95,12 @@ export const TableCrdInfo: FC = ({ return ( <> {isPending && } - {error && } + {error && ( + + )} {!error && data && data.spec && ( = ({ - clusterName, + cluster, namespace, crdName, crdPluralName, @@ -57,7 +59,6 @@ export const ResourceInfo: FC = ({ 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) @@ -92,12 +93,17 @@ export const ResourceInfo: FC = ({ } }, []) - const { isPending, error, data } = useCrdResources({ - clusterName, - namespace, + const { + data, + isLoading: isPending, + error, + } = useK8sSmartResource<{ + items: TJSON[] + }>({ + cluster, apiGroup, apiVersion, - crdName: crdPluralName, + plural: crdPluralName, }) let resourceSchema = {} @@ -143,7 +149,7 @@ export const ResourceInfo: FC = ({ // key={`/${apiGroup}/${apiVersion}/${crdPluralName}`} // customizationId={`${customizationIdPrefix}/${apiGroup}/${apiVersion}/${crdPluralName}`} // tableMappingsReplaceValues={{ - // clusterName: params.clusterName, + // cluster: params.cluster, // projectName: params.projectName, // instanceName: params.instanceName, // namespace: params.namespace, @@ -151,8 +157,8 @@ export const ResourceInfo: FC = ({ // entryType: params.entryType, // apiGroup: params.apiGroup, // apiVersion: params.apiVersion, - // typeName: params.typeName, - // entryName: params.entryName, + // plural: params.plural, + // name: params.name, // apiExtensionVersion: params.apiExtensionVersion, // crdName: params.crdName, // ...replaceValuesPartsOfUrls, @@ -167,12 +173,12 @@ export const ResourceInfo: FC = ({ // cluster, // syntheticProject: params.syntheticProject, // pathPrefix: 'forms/crds', - // typeName: crdPluralName, + // plural: crdPluralName, // apiVersion: `${apiGroup}/${apiVersion}`, // backlink: `${baseprefix}${inside ? '/inside' : ''}/${cluster}${namespace ? `/${namespace}` : ''}${ // params.syntheticProject ? `/${params.syntheticProject}` : '' // }/crd-table/${apiGroup}/${apiVersion}/${apiExtensionVersion}/${crdName}`, - // deletePathPrefix: `/api/clusters/${clusterName}/k8s/apis`, + // deletePathPrefix: `/api/clusters/${cluster}/k8s/apis`, // onDeleteHandle, // permissions: { // canUpdate: permissions.canUpdate, diff --git a/src/components/organisms/Factory/Factory.tsx b/src/components/organisms/Factory/Factory.tsx index 2da5374..972c0d0 100644 --- a/src/components/organisms/Factory/Factory.tsx +++ b/src/components/organisms/Factory/Factory.tsx @@ -4,7 +4,7 @@ import { DynamicComponents, DynamicRendererWithProviders, TDynamicComponentsAppTypeMap, - useDirectUnknownResource, + useK8sSmartResource, TFactoryResponse, ContentCard, } from '@prorobotech/openapi-k8s-toolkit' @@ -44,11 +44,11 @@ export const Factory: FC = ({ setSidebarTags }) => { } }, []) - const { data: factoryData } = useDirectUnknownResource>({ - uri: `/api/clusters/${cluster}/k8s/apis/${BASE_API_GROUP}/${BASE_API_VERSION}/factories/`, - refetchInterval: false, - queryKey: ['factories', cluster || 'no-cluster'], - isEnabled: cluster !== undefined, + const { data: factoryData } = useK8sSmartResource>({ + cluster, + apiGroup: BASE_API_GROUP, + apiVersion: BASE_API_VERSION, + plural: 'factories', }) const { spec } = factoryData?.items.find(({ spec }) => spec.key === key) ?? { spec: undefined } diff --git a/src/components/organisms/Forms/ApisForms/CreateApisForm.tsx b/src/components/organisms/Forms/ApisForms/CreateApisForm.tsx index 1d9408f..c337e57 100644 --- a/src/components/organisms/Forms/ApisForms/CreateApisForm.tsx +++ b/src/components/organisms/Forms/ApisForms/CreateApisForm.tsx @@ -7,11 +7,11 @@ type TCreateApisFormProps = { namespace?: string apiGroup: string apiVersion: string - typeName: string + plural: string backLink?: string | null } -export const CreateApisForm: FC = ({ namespace, apiGroup, apiVersion, typeName, backLink }) => { +export const CreateApisForm: FC = ({ namespace, apiGroup, apiVersion, plural, backLink }) => { const [currentMode, setCurrentMode] = useState('OpenAPI') const [currentModeDisabled, setCurrentModeDisabled] = useState(false) @@ -45,10 +45,10 @@ export const CreateApisForm: FC = ({ namespace, apiGroup, type: 'apis', apiGroup, apiVersion, - typeName, + plural, prefillValueNamespaceOnly: namespace, }} - customizationId={`default-/${apiGroup}/${apiVersion}/${typeName}`} + customizationId={`default-/${apiGroup}/${apiVersion}/${plural}`} isCreate backlink={backLink} modeData={modeData} diff --git a/src/components/organisms/Forms/ApisForms/UpdateApisForm.tsx b/src/components/organisms/Forms/ApisForms/UpdateApisForm.tsx index f831b7c..05e0b1f 100644 --- a/src/components/organisms/Forms/ApisForms/UpdateApisForm.tsx +++ b/src/components/organisms/Forms/ApisForms/UpdateApisForm.tsx @@ -8,8 +8,8 @@ import { BlackholeForm } from 'components' type TUpdateApisFormProps = { apiGroup: string apiVersion: string - typeName: string - entryName: string + plural: string + name: string namespace?: string backLink?: string | null } @@ -17,8 +17,8 @@ type TUpdateApisFormProps = { export const UpdateApisForm: FC = ({ apiGroup, apiVersion, - typeName, - entryName, + plural, + name, namespace, backLink, }) => { @@ -42,12 +42,12 @@ export const UpdateApisForm: FC = ({ } const { data, isPending, error } = useApiResourceSingle({ - clusterName: cluster, + cluster, namespace, apiGroup, apiVersion, - typeName, - entryName, + plural, + name, refetchInterval: false, }) @@ -59,8 +59,6 @@ export const UpdateApisForm: FC = ({ return } - /* eslint-disable-next-line @typescript-eslint/no-unused-vars */ - // const { status: _, ...noStatusData } = data /* eslint-disable-next-line @typescript-eslint/no-unused-vars */ const { managedFields: __, ...metadata } = data.metadata @@ -80,11 +78,10 @@ export const UpdateApisForm: FC = ({ type: 'apis', apiGroup, apiVersion, - typeName, - // prefillValuesSchema: { ...noStatusData, metadata }, + plural, prefillValuesSchema: { ...data, metadata }, }} - customizationId={`default-/${apiGroup}/${apiVersion}/${typeName}`} + customizationId={`default-/${apiGroup}/${apiVersion}/${plural}`} backlink={backLink} modeData={modeData} /> diff --git a/src/components/organisms/Forms/BuiltinForms/CreateBuiltinForm.tsx b/src/components/organisms/Forms/BuiltinForms/CreateBuiltinForm.tsx index 1faadd8..74ba5b6 100644 --- a/src/components/organisms/Forms/BuiltinForms/CreateBuiltinForm.tsx +++ b/src/components/organisms/Forms/BuiltinForms/CreateBuiltinForm.tsx @@ -5,11 +5,11 @@ import { BlackholeForm } from 'components' type TCreateBuiltinFormProps = { namespace?: string - typeName: string + plural: string backLink?: string | null } -export const CreateBuiltinForm: FC = ({ namespace, typeName, backLink }) => { +export const CreateBuiltinForm: FC = ({ namespace, plural, backLink }) => { const [currentMode, setCurrentMode] = useState('OpenAPI') const [currentModeDisabled, setCurrentModeDisabled] = useState(false) @@ -41,10 +41,10 @@ export const CreateBuiltinForm: FC = ({ namespace, type = ({ typeName, entryName, namespace, backLink }) => { +export const UpdateBuiltinForm: FC = ({ plural, name, namespace, backLink }) => { const cluster = useSelector((state: RootState) => state.cluster.cluster) const [currentMode, setCurrentMode] = useState('OpenAPI') @@ -33,10 +33,10 @@ export const UpdateBuiltinForm: FC = ({ typeName, entry } const { data, isPending, error } = useBuiltinResourceSingle({ - clusterName: cluster, + cluster, namespace, - typeName, - entryName, + plural, + name, refetchInterval: false, }) @@ -48,8 +48,6 @@ export const UpdateBuiltinForm: FC = ({ typeName, entry return } - /* eslint-disable-next-line @typescript-eslint/no-unused-vars */ - // const { status: _, ...noStatusData } = data /* eslint-disable-next-line @typescript-eslint/no-unused-vars */ const { managedFields: __, ...metadata } = data.metadata @@ -67,11 +65,10 @@ export const UpdateBuiltinForm: FC = ({ typeName, entry diff --git a/src/components/organisms/Forms/CrdsForms/CreateCrdsForm.tsx b/src/components/organisms/Forms/CrdsForms/CreateCrdsForm.tsx index 237b0f6..79dd95a 100644 --- a/src/components/organisms/Forms/CrdsForms/CreateCrdsForm.tsx +++ b/src/components/organisms/Forms/CrdsForms/CreateCrdsForm.tsx @@ -7,11 +7,11 @@ type TCreateCrdsFormProps = { namespace?: string apiGroup: string apiVersion: string - typeName: string + plural: string backLink?: string | null } -export const CreateCrdsForm: FC = ({ namespace, apiGroup, apiVersion, typeName, backLink }) => { +export const CreateCrdsForm: FC = ({ namespace, apiGroup, apiVersion, plural, backLink }) => { const [currentMode, setCurrentMode] = useState('OpenAPI') const [currentModeDisabled, setCurrentModeDisabled] = useState(false) @@ -45,10 +45,10 @@ export const CreateCrdsForm: FC = ({ namespace, apiGroup, type: 'apis', apiGroup, apiVersion, - typeName, + plural, prefillValueNamespaceOnly: namespace, }} - customizationId={`default-/${apiGroup}/${apiVersion}/${typeName}`} + customizationId={`default-/${apiGroup}/${apiVersion}/${plural}`} isCreate backlink={backLink} modeData={modeData} diff --git a/src/components/organisms/Forms/CrdsForms/UpdateCrdsForm.tsx b/src/components/organisms/Forms/CrdsForms/UpdateCrdsForm.tsx index 35714cb..ce37e22 100644 --- a/src/components/organisms/Forms/CrdsForms/UpdateCrdsForm.tsx +++ b/src/components/organisms/Forms/CrdsForms/UpdateCrdsForm.tsx @@ -1,6 +1,6 @@ import React, { FC, useState } from 'react' import { Spin, Alert, Segmented } from 'antd' -import { useCrdResourceSingle, Spacer } from '@prorobotech/openapi-k8s-toolkit' +import { useK8sSmartResource, TSingleResource, Spacer } from '@prorobotech/openapi-k8s-toolkit' import { useSelector } from 'react-redux' import { RootState } from 'store/store' import { BlackholeForm } from 'components' @@ -8,8 +8,8 @@ import { BlackholeForm } from 'components' type TUpdateCrdsFormProps = { apiGroup: string apiVersion: string - typeName: string - entryName: string + plural: string + name: string namespace?: string backLink?: string | null } @@ -17,8 +17,8 @@ type TUpdateCrdsFormProps = { export const UpdateCrdsForm: FC = ({ apiGroup, apiVersion, - typeName, - entryName, + plural, + name, namespace, backLink, }) => { @@ -41,26 +41,37 @@ export const UpdateCrdsForm: FC = ({ onDisabled: onCurrentModeDisabled, } - const { data, isPending, error } = useCrdResourceSingle({ - clusterName: cluster, + const { + data: dataArr, + isLoading: isPending, + error, + } = useK8sSmartResource<{ + items: TSingleResource[] + }>({ + cluster, namespace, apiGroup, apiVersion, - crdName: typeName, - entryName, - refetchInterval: false, + plural, + fieldSelector: `metadata.name=${name}`, }) + const data = dataArr?.items && dataArr.items.length > 0 ? dataArr.items[0] : undefined + if (isPending) { return } if (error) { - return + return ( + + ) + } + + if (!data) { + return } - /* eslint-disable-next-line @typescript-eslint/no-unused-vars */ - // const { status: _, ...noStatusData } = data /* eslint-disable-next-line @typescript-eslint/no-unused-vars */ const { managedFields: __, ...metadata } = data.metadata @@ -80,11 +91,10 @@ export const UpdateCrdsForm: FC = ({ type: 'apis', apiGroup, apiVersion, - typeName, - // prefillValuesSchema: { ...noStatusData, metadata }, + plural, prefillValuesSchema: { ...data, metadata }, }} - customizationId={`default-/${apiGroup}/${apiVersion}/${typeName}`} + customizationId={`default-/${apiGroup}/${apiVersion}/${plural}`} backlink={backLink} modeData={modeData} /> diff --git a/src/components/organisms/Header/organisms/User/User.tsx b/src/components/organisms/Header/organisms/User/User.tsx index 69f89ce..71fff86 100644 --- a/src/components/organisms/Header/organisms/User/User.tsx +++ b/src/components/organisms/Header/organisms/User/User.tsx @@ -20,10 +20,6 @@ export const User: FC = () => { placement="top" menu={{ items: [ - // { - // key: '1', - // label: , - // }, ...(BASE_HIDE_INSIDE === 'true' ? [] : [ diff --git a/src/components/organisms/HeaderSecond/HeaderSecond.tsx b/src/components/organisms/HeaderSecond/HeaderSecond.tsx index 10b588f..1faa445 100644 --- a/src/components/organisms/HeaderSecond/HeaderSecond.tsx +++ b/src/components/organisms/HeaderSecond/HeaderSecond.tsx @@ -12,8 +12,7 @@ type THeaderProps = { } export const HeaderSecond: FC = ({ inside, isSearch }) => { - // const { projectName, instanceName, clusterName, entryType, namespace, syntheticProject } = useParams() - const { projectName, instanceName, clusterName, namespace, syntheticProject } = useParams() + const { projectName, instanceName, cluster, namespace, syntheticProject } = useParams() const { token } = theme.useToken() const possibleProject = syntheticProject && namespace ? syntheticProject : namespace @@ -23,17 +22,17 @@ export const HeaderSecond: FC = ({ inside, isSearch }) => { - {inside ? : } - {inside && } + {inside ? : } + {inside && } {!inside && !isSearch && BASE_USE_NAMESPACE_NAV !== 'true' && ( )} {!inside && (isSearch || BASE_USE_NAMESPACE_NAV === 'true') && ( - + )} diff --git a/src/components/organisms/HeaderSecond/organisms/Selector/Selector.tsx b/src/components/organisms/HeaderSecond/organisms/Selector/Selector.tsx index a7c0cdb..f1913e8 100644 --- a/src/components/organisms/HeaderSecond/organisms/Selector/Selector.tsx +++ b/src/components/organisms/HeaderSecond/organisms/Selector/Selector.tsx @@ -1,61 +1,60 @@ import React, { FC, useState } from 'react' import { Flex, Typography } from 'antd' import { useNavigate } from 'react-router-dom' -import { useDirectUnknownResource } from '@prorobotech/openapi-k8s-toolkit' +import { useK8sSmartResource, TNavigationResource } from '@prorobotech/openapi-k8s-toolkit' import { useNavSelector } from 'hooks/useNavSelector' import { useMountEffect } from 'hooks/useMountEffect' import { EntrySelect } from 'components/atoms' import { BASE_API_GROUP, BASE_API_VERSION, + BASE_CUSTOMIZATION_NAVIGATION_RESOURCE_PLURAL, BASE_CUSTOMIZATION_NAVIGATION_RESOURCE_NAME, - BASE_CUSTOMIZATION_NAVIGATION_RESOURCE, } from 'constants/customizationApiGroupAndVersion' type TSelectorProps = { - clusterName?: string + cluster?: string projectName?: string instanceName?: string } -export const Selector: FC = ({ clusterName, projectName, instanceName }) => { +export const Selector: FC = ({ cluster, projectName, instanceName }) => { const navigate = useNavigate() - const [selectedClusterName, setSelectedClusterName] = useState(clusterName) + const [selectedCluster, setSelectedCluster] = useState(cluster) const [selectedProjectName, setSelectedProjectName] = useState(projectName) const [selectedInstanceName, setSelectedInstanceName] = useState(instanceName) - // const { projectsInSidebar, instancesInSidebar, allInstancesLoadingSuccess, clustersInSidebar } = useNavSelector( const { projectsInSidebar, instancesInSidebar, allInstancesLoadingSuccess } = useNavSelector( - selectedClusterName, + selectedCluster, projectName, ) - const { data: navigationData } = useDirectUnknownResource<{ - spec: { projects: { clear: string; change: string }; instances: { clear: string; change: string } } + const { data: navigationDataArr } = useK8sSmartResource<{ + items: TNavigationResource[] }>({ - uri: `/api/clusters/${clusterName}/k8s/apis/${BASE_API_GROUP}/${BASE_API_VERSION}/${BASE_CUSTOMIZATION_NAVIGATION_RESOURCE_NAME}/${BASE_CUSTOMIZATION_NAVIGATION_RESOURCE}`, - refetchInterval: false, - queryKey: ['navigation', clusterName || 'no-cluster'], - isEnabled: clusterName !== undefined, + cluster: cluster || '', + apiGroup: BASE_API_GROUP, + apiVersion: BASE_API_VERSION, + plural: BASE_CUSTOMIZATION_NAVIGATION_RESOURCE_PLURAL, + fieldSelector: `metadata.name=${BASE_CUSTOMIZATION_NAVIGATION_RESOURCE_NAME}`, + isEnabled: cluster !== undefined, }) - // const handleClusterChange = (value: string) => { - // setSelectedClusterName(value) - // navigate(`${baseprefix}/clusters/${value}`) - // } + const navigationData = + navigationDataArr?.items && navigationDataArr.items.length > 0 ? navigationDataArr.items[0] : undefined const handleProjectChange = (value?: string) => { if (value && value !== 'all') { setSelectedProjectName(value) const changeUrl = - navigationData?.spec.projects.change - .replace('{selectedCluster}', selectedClusterName || 'no-cluster') + navigationData?.spec?.projects?.change + .replace('{selectedCluster}', selectedCluster || 'no-cluster') .replace('{value}', value) || 'no navigation data' navigate(changeUrl) } else { const clearUrl = - navigationData?.spec.projects.clear.replace('{selectedCluster}', selectedClusterName || 'no-cluster') || + navigationData?.spec?.projects?.clear.replace('{selectedCluster}', selectedCluster || 'no-cluster') || 'no navigation data' navigate(clearUrl) } @@ -65,32 +64,32 @@ export const Selector: FC = ({ clusterName, projectName, instanc if (value && value !== 'all') { setSelectedInstanceName(value) const changeUrl = - navigationData?.spec.instances.change - .replace('{selectedCluster}', selectedClusterName || 'no-cluster') + navigationData?.spec?.instances?.change + .replace('{selectedCluster}', selectedCluster || 'no-cluster') .replace('{selectedProject}', selectedProjectName || 'no-project') .replace('{value}', value) || 'no navigation data' navigate(changeUrl) } else { const clearUrl = - navigationData?.spec.instances.clear - .replace('{selectedCluster}', selectedClusterName || 'no-cluster') + navigationData?.spec?.instances?.clear + .replace('{selectedCluster}', selectedCluster || 'no-cluster') .replace('{selectedProject}', selectedProjectName || 'no-project') || 'no navigation data' navigate(clearUrl) } } useMountEffect(() => { - setSelectedClusterName(clusterName) + setSelectedCluster(cluster) setSelectedProjectName(projectName) setSelectedInstanceName(instanceName) - }, [projectName, instanceName, clusterName]) + }, [projectName, instanceName, cluster]) return ( {/* */} Project: @@ -99,7 +98,7 @@ export const Selector: FC = ({ clusterName, projectName, instanc options={[{ value: 'all', label: 'All Namespaces' }, ...projectsInSidebar]} value={selectedProjectName || 'all'} onChange={handleProjectChange} - disabled={selectedClusterName === undefined || projectsInSidebar.length === 0} + disabled={selectedCluster === undefined || projectsInSidebar.length === 0} /> Instance: = ({ clusterName, projectName, instanc value={selectedInstanceName || 'all'} onChange={handleInstanceChange} disabled={ - selectedClusterName === undefined || + selectedCluster === undefined || selectedProjectName === undefined || (allInstancesLoadingSuccess && instancesInSidebar.length === 0) } diff --git a/src/components/organisms/HeaderSecond/organisms/SelectorCluster/SelectorCluster.tsx b/src/components/organisms/HeaderSecond/organisms/SelectorCluster/SelectorCluster.tsx index 00c75d7..f647f32 100644 --- a/src/components/organisms/HeaderSecond/organisms/SelectorCluster/SelectorCluster.tsx +++ b/src/components/organisms/HeaderSecond/organisms/SelectorCluster/SelectorCluster.tsx @@ -9,21 +9,20 @@ import { EntrySelect } from 'components/atoms' import { BASE_NAVIGATE_FROM_CLUSTERLIST } from 'constants/customizationApiGroupAndVersion' type TSelectorClusterProps = { - clusterName?: string + cluster?: string } -export const SelectorCluster: FC = ({ clusterName }) => { +export const SelectorCluster: FC = ({ cluster }) => { const navigate = useNavigate() const baseprefix = useSelector((state: RootState) => state.baseprefix.baseprefix) - const [selectedClusterName, setSelectedClusterName] = useState(clusterName) + const [selectedCluster, setSelectedCluster] = useState(cluster) const { clustersInSidebar } = useNavSelectorClusters() const handleClusterChange = (value?: string) => { if (value) { - setSelectedClusterName(value) - // navigate(`${baseprefix}/clusters/${value}`) + setSelectedCluster(value) navigate(BASE_NAVIGATE_FROM_CLUSTERLIST.replace('~recordValue~', value)) } else { navigate(`${baseprefix}/clusters/`) @@ -31,8 +30,8 @@ export const SelectorCluster: FC = ({ clusterName }) => { } useMountEffect(() => { - setSelectedClusterName(clusterName) - }, [clusterName]) + setSelectedCluster(cluster) + }, [cluster]) return ( @@ -40,9 +39,8 @@ export const SelectorCluster: FC = ({ clusterName }) => { ) diff --git a/src/components/organisms/HeaderSecond/organisms/SelectorClusterInside/SelectorClusterInside.tsx b/src/components/organisms/HeaderSecond/organisms/SelectorClusterInside/SelectorClusterInside.tsx index d71663f..697891a 100644 --- a/src/components/organisms/HeaderSecond/organisms/SelectorClusterInside/SelectorClusterInside.tsx +++ b/src/components/organisms/HeaderSecond/organisms/SelectorClusterInside/SelectorClusterInside.tsx @@ -8,20 +8,20 @@ import { useMountEffect } from 'hooks/useMountEffect' import { EntrySelect } from 'components/atoms' type TSelectorClusterInsideProps = { - clusterName?: string + cluster?: string } -export const SelectorClusterInside: FC = ({ clusterName }) => { +export const SelectorClusterInside: FC = ({ cluster }) => { const navigate = useNavigate() const baseprefix = useSelector((state: RootState) => state.baseprefix.baseprefix) - const [selectedClusterName, setSelectedClusterName] = useState(clusterName) + const [selectedCluster, setSelectedCluster] = useState(cluster) - const { clustersInSidebar } = useNavSelectorInside(selectedClusterName) + const { clustersInSidebar } = useNavSelectorInside(selectedCluster) const handleClusterChange = (value?: string) => { if (value) { - setSelectedClusterName(value) + setSelectedCluster(value) navigate(`${baseprefix}/inside/${value}/apis`) } else { navigate(`${baseprefix}/inside/`) @@ -29,8 +29,8 @@ export const SelectorClusterInside: FC = ({ cluster } useMountEffect(() => { - setSelectedClusterName(clusterName) - }, [clusterName]) + setSelectedCluster(cluster) + }, [cluster]) return ( @@ -38,9 +38,8 @@ export const SelectorClusterInside: FC = ({ cluster ) diff --git a/src/components/organisms/HeaderSecond/organisms/SelectorInside/SelectorInside.tsx b/src/components/organisms/HeaderSecond/organisms/SelectorInside/SelectorInside.tsx index bd62b44..31a0ee2 100644 --- a/src/components/organisms/HeaderSecond/organisms/SelectorInside/SelectorInside.tsx +++ b/src/components/organisms/HeaderSecond/organisms/SelectorInside/SelectorInside.tsx @@ -6,24 +6,18 @@ import { useMountEffect } from 'hooks/useMountEffect' import { EntrySelect } from 'components/atoms' type TSelectorInsideProps = { - clusterName?: string + cluster?: string namespace?: string } -export const SelectorInside: FC = ({ clusterName, namespace }) => { +export const SelectorInside: FC = ({ cluster, namespace }) => { const navigate = useNavigate() const params = useParams() - const [selectedClusterName, setSelectedClusterName] = useState(clusterName) + const [selectedCluster, setSelectedCluster] = useState(cluster) const [selectedNamespace, setSelectedNamespace] = useState(namespace) - // const { namespacesInSidebar, clustersInSidebar } = useNavSelectorInside(selectedClusterName) - const { namespacesInSidebar } = useNavSelectorInside(selectedClusterName) - - // const handleClusterChange = (value: string) => { - // setSelectedClusterName(value) - // navigate(`${baseprefix}/inside/${value}/apis`) - // } + const { namespacesInSidebar } = useNavSelectorInside(selectedCluster) const handleNamepsaceChange = (value?: string) => { if (value && value !== 'all' && params.namespace) { @@ -44,25 +38,19 @@ export const SelectorInside: FC = ({ clusterName, namespac } useMountEffect(() => { - setSelectedClusterName(clusterName) + setSelectedCluster(cluster) setSelectedNamespace(namespace) - }, [namespace, clusterName]) + }, [namespace, cluster]) return ( - {/* */} Namespace: ) diff --git a/src/components/organisms/HeaderSecond/organisms/SelectorNamespace/SelectorNamespace.tsx b/src/components/organisms/HeaderSecond/organisms/SelectorNamespace/SelectorNamespace.tsx index c3bf2a1..004a87a 100644 --- a/src/components/organisms/HeaderSecond/organisms/SelectorNamespace/SelectorNamespace.tsx +++ b/src/components/organisms/HeaderSecond/organisms/SelectorNamespace/SelectorNamespace.tsx @@ -1,7 +1,7 @@ import React, { FC, useState } from 'react' import { Flex, Typography } from 'antd' import { useLocation, useNavigate } from 'react-router-dom' -import { useDirectUnknownResource } from '@prorobotech/openapi-k8s-toolkit' +import { useK8sSmartResource, TNavigationResource } from '@prorobotech/openapi-k8s-toolkit' import { useSelector } from 'react-redux' import type { RootState } from 'store/store' import { useNavSelectorInside } from 'hooks/useNavSelectorInside' @@ -11,35 +11,40 @@ import { EntrySelect } from 'components/atoms' import { BASE_API_GROUP, BASE_API_VERSION, + BASE_CUSTOMIZATION_NAVIGATION_RESOURCE_PLURAL, BASE_CUSTOMIZATION_NAVIGATION_RESOURCE_NAME, - BASE_CUSTOMIZATION_NAVIGATION_RESOURCE, } from 'constants/customizationApiGroupAndVersion' type TSelectorNamespaceProps = { - clusterName?: string + cluster?: string namespace?: string } -export const SelectorNamespace: FC = ({ clusterName, namespace }) => { +export const SelectorNamespace: FC = ({ cluster, namespace }) => { const navigate = useNavigate() const location = useLocation() const baseprefix = useSelector((state: RootState) => state.baseprefix.baseprefix) - const [selectedClusterName, setSelectedClusterName] = useState(clusterName) + const [selectedCluster, setSelectedCluster] = useState(cluster) const [selectedNamespace, setSelectedNamespace] = useState(namespace) - const { namespacesInSidebar } = useNavSelectorInside(selectedClusterName) + const { namespacesInSidebar } = useNavSelectorInside(selectedCluster) - const { data: navigationData } = useDirectUnknownResource<{ - spec: { namespaces: { clear: string; change: string } } + const { data: navigationDataArr } = useK8sSmartResource<{ + items: TNavigationResource[] }>({ - uri: `/api/clusters/${clusterName}/k8s/apis/${BASE_API_GROUP}/${BASE_API_VERSION}/${BASE_CUSTOMIZATION_NAVIGATION_RESOURCE_NAME}/${BASE_CUSTOMIZATION_NAVIGATION_RESOURCE}`, - refetchInterval: false, - queryKey: ['navigation', clusterName || 'no-cluster'], - isEnabled: clusterName !== undefined, + cluster: cluster || '', + apiGroup: BASE_API_GROUP, + apiVersion: BASE_API_VERSION, + plural: BASE_CUSTOMIZATION_NAVIGATION_RESOURCE_PLURAL, + fieldSelector: `metadata.name=${BASE_CUSTOMIZATION_NAVIGATION_RESOURCE_NAME}`, + isEnabled: cluster !== undefined, }) + const navigationData = + navigationDataArr?.items && navigationDataArr.items.length > 0 ? navigationDataArr.items[0] : undefined + const isSearchPage = useIsSearchPage(baseprefix || '') const handleNamepsaceChange = (value?: string) => { @@ -47,10 +52,10 @@ export const SelectorNamespace: FC = ({ clusterName, na const { pathname, search, hash } = location const segs = pathname.split('/') - // Assume pattern: /prefix/:clusterName/:namespace?/:syntheticProject?/search/* + // Assume pattern: /prefix/:cluster/:namespace?/:syntheticProject?/search/* // Find the "search" segment index const searchIdx = segs.indexOf('search') - const clusterIdx = segs.indexOf(selectedClusterName || '') + const clusterIdx = segs.indexOf(selectedCluster || '') if (clusterIdx === -1) { return } // bail if we can't find the cluster @@ -82,22 +87,22 @@ export const SelectorNamespace: FC = ({ clusterName, na if (value && value !== 'all') { setSelectedNamespace(value) const changeUrl = - navigationData?.spec.namespaces.change - .replace('{selectedCluster}', selectedClusterName || 'no-cluster') + navigationData?.spec?.namespaces?.change + .replace('{selectedCluster}', selectedCluster || 'no-cluster') .replace('{value}', value) || 'no navigation data' navigate(changeUrl) } else { const clearUrl = - navigationData?.spec.namespaces.clear.replace('{selectedCluster}', selectedClusterName || 'no-cluster') || + navigationData?.spec?.namespaces?.clear.replace('{selectedCluster}', selectedCluster || 'no-cluster') || 'no navigation data' navigate(clearUrl) } } useMountEffect(() => { - setSelectedClusterName(clusterName) + setSelectedCluster(cluster) setSelectedNamespace(namespace) - }, [namespace, clusterName]) + }, [namespace, cluster]) return ( @@ -107,7 +112,7 @@ export const SelectorNamespace: FC = ({ clusterName, na options={[{ value: 'all', label: 'All Namespaces' }, ...namespacesInSidebar]} value={selectedNamespace || 'all'} onChange={handleNamepsaceChange} - disabled={selectedClusterName === undefined || namespacesInSidebar.length === 0} + disabled={selectedCluster === undefined || namespacesInSidebar.length === 0} /> ) diff --git a/src/components/organisms/ListInsideAllResources/ListInsideAllResources.tsx b/src/components/organisms/ListInsideAllResources/ListInsideAllResources.tsx index fc0bf15..9c7a467 100644 --- a/src/components/organisms/ListInsideAllResources/ListInsideAllResources.tsx +++ b/src/components/organisms/ListInsideAllResources/ListInsideAllResources.tsx @@ -33,16 +33,16 @@ export const ListInsideAllResources: FC = ({ names }>() const apiGroupList = useApisResourceTypes({ - clusterName: cluster, + cluster, }) const builtInData = useBuiltinResourceTypes({ - clusterName: cluster, + cluster, }) useEffect(() => { getGroupsByCategory({ - clusterName: cluster, + cluster, namespace, apiGroupListData: apiGroupList.data, builtinResourceTypesData: builtInData.data, diff --git a/src/components/organisms/ListInsideApisByApiGroup/ListInsideApisByApiGroup.tsx b/src/components/organisms/ListInsideApisByApiGroup/ListInsideApisByApiGroup.tsx index 86588bf..f1f0045 100644 --- a/src/components/organisms/ListInsideApisByApiGroup/ListInsideApisByApiGroup.tsx +++ b/src/components/organisms/ListInsideApisByApiGroup/ListInsideApisByApiGroup.tsx @@ -27,13 +27,13 @@ export const ListInsideApisByApiGroup: FC = ({ n const navigate = useNavigate() const { isPending, error, data } = useApiResourceTypesByGroup({ - clusterName: cluster, + cluster, apiGroup, apiVersion, }) useEffect(() => { - filterIfApiInstanceNamespaceScoped({ namespace, data, apiGroup, apiVersion, clusterName: cluster }).then(data => + filterIfApiInstanceNamespaceScoped({ namespace, data, apiGroup, apiVersion, cluster }).then(data => setFilteredResources(data), ) }, [namespace, data, apiGroup, apiVersion, cluster]) diff --git a/src/components/organisms/ListInsideClusterAndNs/ListInsideClusterAndNs.tsx b/src/components/organisms/ListInsideClusterAndNs/ListInsideClusterAndNs.tsx index 4f52a36..6508a08 100644 --- a/src/components/organisms/ListInsideClusterAndNs/ListInsideClusterAndNs.tsx +++ b/src/components/organisms/ListInsideClusterAndNs/ListInsideClusterAndNs.tsx @@ -1,6 +1,7 @@ +/* eslint-disable no-nested-ternary */ import React, { FC, useState } from 'react' import { Button, Alert, Spin, Typography } from 'antd' -import { filterSelectOptions, Spacer, useBuiltinResources, useApiResources } from '@prorobotech/openapi-k8s-toolkit' +import { filterSelectOptions, Spacer, TSingleResource, useK8sSmartResource } from '@prorobotech/openapi-k8s-toolkit' import { useNavigate } from 'react-router-dom' import { useSelector, useDispatch } from 'react-redux' import { RootState } from 'store/store' @@ -8,7 +9,7 @@ import { setCluster } from 'store/cluster/cluster/cluster' import { CUSTOM_NAMESPACE_API_RESOURCE_API_GROUP, CUSTOM_NAMESPACE_API_RESOURCE_API_VERSION, - CUSTOM_NAMESPACE_API_RESOURCE_RESOURCE_NAME, + CUSTOM_NAMESPACE_API_RESOURCE_PLURAL, } from 'constants/customizationApiGroupAndVersion' import { Styled } from './styled' @@ -22,30 +23,33 @@ export const ListInsideClusterAndNs: FC = () => { const [selectedCluster, setSelectedCluster] = useState() const [selectedNamespace, setSelectedNamespace] = useState() - const isCustomNamespaceResource = + const isCustomNamespaceResource: boolean = CUSTOM_NAMESPACE_API_RESOURCE_API_GROUP && typeof CUSTOM_NAMESPACE_API_RESOURCE_API_GROUP === 'string' && CUSTOM_NAMESPACE_API_RESOURCE_API_GROUP.length > 0 && CUSTOM_NAMESPACE_API_RESOURCE_API_VERSION && typeof CUSTOM_NAMESPACE_API_RESOURCE_API_VERSION === 'string' && CUSTOM_NAMESPACE_API_RESOURCE_API_VERSION.length > 0 && - CUSTOM_NAMESPACE_API_RESOURCE_RESOURCE_NAME && - typeof CUSTOM_NAMESPACE_API_RESOURCE_RESOURCE_NAME === 'string' && - CUSTOM_NAMESPACE_API_RESOURCE_RESOURCE_NAME.length > 0 + CUSTOM_NAMESPACE_API_RESOURCE_PLURAL && + typeof CUSTOM_NAMESPACE_API_RESOURCE_PLURAL === 'string' && + CUSTOM_NAMESPACE_API_RESOURCE_PLURAL.length > 0 - const namespacesData = useBuiltinResources({ - clusterName: selectedCluster || '', - typeName: 'namespaces', - limit: null, + const namespacesData = useK8sSmartResource<{ + items: TSingleResource[] + }>({ + cluster: selectedCluster || '', + apiVersion: 'v1', + plural: 'namespaces', isEnabled: Boolean(selectedCluster !== undefined && !isCustomNamespaceResource), }) - const namespacesDataCustom = useApiResources({ - clusterName: selectedCluster || '', + const namespacesDataCustom = useK8sSmartResource<{ + items: TSingleResource[] + }>({ + cluster: selectedCluster || '', apiGroup: CUSTOM_NAMESPACE_API_RESOURCE_API_GROUP, apiVersion: CUSTOM_NAMESPACE_API_RESOURCE_API_VERSION, - typeName: CUSTOM_NAMESPACE_API_RESOURCE_RESOURCE_NAME, - limit: null, + plural: CUSTOM_NAMESPACE_API_RESOURCE_PLURAL, isEnabled: Boolean(selectedCluster !== undefined && isCustomNamespaceResource), }) @@ -70,7 +74,6 @@ export const ListInsideClusterAndNs: FC = () => { if (typeof value === 'string') { dispatch(setCluster(value)) setSelectedCluster(value) - // navigate(`/${value}/apis`) } }} onClear={() => { @@ -80,13 +83,19 @@ export const ListInsideClusterAndNs: FC = () => { /> )} - {selectedCluster && (isCustomNamespaceResource ? namespacesDataCustom.isPending : namespacesData.isPending) && ( + {selectedCluster && (isCustomNamespaceResource ? namespacesDataCustom.isLoading : namespacesData.isLoading) && ( )} {selectedCluster && (isCustomNamespaceResource ? namespacesDataCustom.error : namespacesData.error) && ( diff --git a/src/components/organisms/ListInsideCrdsByApiGroup/ListInsideCrdsByApiGroup.tsx b/src/components/organisms/ListInsideCrdsByApiGroup/ListInsideCrdsByApiGroup.tsx index ed850b2..f55210c 100644 --- a/src/components/organisms/ListInsideCrdsByApiGroup/ListInsideCrdsByApiGroup.tsx +++ b/src/components/organisms/ListInsideCrdsByApiGroup/ListInsideCrdsByApiGroup.tsx @@ -30,13 +30,13 @@ export const ListInsideCrdsByApiGroup: FC = ({ const [filteredResources, setFilteredResources] = useState() const { isPending, error, data } = useApiResourceTypesByGroup({ - clusterName: cluster, + cluster, apiGroup, apiVersion, }) useEffect(() => { - filterIfApiInstanceNamespaceScoped({ namespace, data, apiGroup, apiVersion, clusterName: cluster }).then(data => + filterIfApiInstanceNamespaceScoped({ namespace, data, apiGroup, apiVersion, cluster }).then(data => setFilteredResources(data), ) }, [namespace, data, apiGroup, apiVersion, cluster]) diff --git a/src/components/organisms/Search/Search.tsx b/src/components/organisms/Search/Search.tsx index 3d531b5..b296aff 100644 --- a/src/components/organisms/Search/Search.tsx +++ b/src/components/organisms/Search/Search.tsx @@ -100,7 +100,7 @@ export const Search: FC = () => { useEffect(() => { setIsLoading(true) setError(undefined) - getKinds({ clusterName: cluster }) + getKinds({ cluster }) .then(data => { setKindIndex(data) setKindWithVersion(getSortedKindsAll(data)) diff --git a/src/components/organisms/Search/molecules/SearchEntry/SearchEntry.tsx b/src/components/organisms/Search/molecules/SearchEntry/SearchEntry.tsx index 169bd9f..a6be1ee 100644 --- a/src/components/organisms/Search/molecules/SearchEntry/SearchEntry.tsx +++ b/src/components/organisms/Search/molecules/SearchEntry/SearchEntry.tsx @@ -40,7 +40,7 @@ export const SearchEntry: FC = ({ resource, labels, fields, f const { FIELD_NAME } = constants - const [apiGroup, apiVersion, typeName] = resource.split('~') + const [apiGroup, apiVersion, plural] = resource.split('~') const kindName = kindByGvr(kindsWithVersion)(resource) const abbr = getUppercase(kindName && kindName.length ? kindName : 'Loading') @@ -60,6 +60,8 @@ export const SearchEntry: FC = ({ resource, labels, fields, f form.setFieldsValue({ [FIELD_NAME]: cur.filter(v => v !== value) }) } + const limitSp = searchParams.get('limit') + return ( @@ -89,16 +91,16 @@ export const SearchEntry: FC = ({ resource, labels, fields, f {isOpen && ( <> - {typeName && ( + {plural && ( 0 ? 'api' : 'builtin'} namespace={isNamespaceResource ? namespace : undefined} apiGroup={apiGroup.length > 0 ? apiGroup : undefined} apiVersion={apiVersion} - typeName={typeName} + plural={plural} labels={labels?.length ? labels : undefined} fields={fields?.length ? fields : undefined} - limit={searchParams.get('limit')} + limit={limitSp && limitSp.length > 0 ? Number(limitSp) : undefined} customizationIdPrefix={tableCustomizationIdPrefix} searchMount kindName={kindName} diff --git a/src/components/organisms/Sidebar/styled.ts b/src/components/organisms/Sidebar/styled.ts index ff1f047..216bc6f 100644 --- a/src/components/organisms/Sidebar/styled.ts +++ b/src/components/organisms/Sidebar/styled.ts @@ -1,5 +1,4 @@ import styled from 'styled-components' -// import { HEAD_FIRST_ROW, SIDEBAR_CLUSTER_HEIGHT } from 'constants/blocksSizes' import { HEAD_FIRST_ROW } from 'constants/blocksSizes' type TBackgroundContainerProps = { @@ -16,15 +15,6 @@ const BackgroundContainer = styled.div` height: calc(100vh - ${HEAD_FIRST_ROW}px); ` -// const ClusterSelectorContainer = styled.div` -// height: ${SIDEBAR_CLUSTER_HEIGHT}px; -// display: flex; -// justify-content: center; -// align-items: center; -// padding: 12px; -// ` - export const Styled = { BackgroundContainer, - // ClusterSelectorContainer, } diff --git a/src/constants/blocksSizes.ts b/src/constants/blocksSizes.ts index 545c3d3..a89fc15 100644 --- a/src/constants/blocksSizes.ts +++ b/src/constants/blocksSizes.ts @@ -4,8 +4,6 @@ export const NAV_HEIGHT = 50 export const FOOTER_HEIGHT = 38 export const MAIN_CONTENT_HORIZONTAL_PADDING = 24 export const BACKLINK_HEIGHT = 26 -/* sidebar */ -// export const SIDEBAR_CLUSTER_HEIGHT = 56 /* computed only */ export const BREADCRUMBS_HEIGHT = 26 export const CONTENT_CARD_PADDING = 25 diff --git a/src/constants/customizationApiGroupAndVersion.ts b/src/constants/customizationApiGroupAndVersion.ts index 5700560..c35578a 100644 --- a/src/constants/customizationApiGroupAndVersion.ts +++ b/src/constants/customizationApiGroupAndVersion.ts @@ -27,12 +27,17 @@ export const BASE_API_VERSION = import.meta.env.DEV ? window._env_.CUSTOMIZATION_API_VERSION || import.meta.env.VITE_CUSTOMIZATION_API_VERSION : window._env_.CUSTOMIZATION_API_VERSION +export const BASE_CUSTOMIZATION_NAVIGATION_RESOURCE_PLURAL = import.meta.env.DEV + ? window._env_.CUSTOMIZATION_NAVIGATION_RESOURCE_PLURAL || + import.meta.env.VITE_CUSTOMIZATION_NAVIGATION_RESOURCE_PLURAL + : window._env_.CUSTOMIZATION_NAVIGATION_RESOURCE_PLURAL export const BASE_CUSTOMIZATION_NAVIGATION_RESOURCE_NAME = import.meta.env.DEV ? window._env_.CUSTOMIZATION_NAVIGATION_RESOURCE_NAME || import.meta.env.VITE_CUSTOMIZATION_NAVIGATION_RESOURCE_NAME : window._env_.CUSTOMIZATION_NAVIGATION_RESOURCE_NAME -export const BASE_CUSTOMIZATION_NAVIGATION_RESOURCE = import.meta.env.DEV - ? window._env_.CUSTOMIZATION_NAVIGATION_RESOURCE || import.meta.env.VITE_CUSTOMIZATION_NAVIGATION_RESOURCE - : window._env_.CUSTOMIZATION_NAVIGATION_RESOURCE + +export const CUSTOMIZATION_SIDEBAR_FALLBACK_ID = import.meta.env.DEV + ? window._env_.CUSTOMIZATION_SIDEBAR_FALLBACK_ID || import.meta.env.VITE_CUSTOMIZATION_SIDEBAR_FALLBACK_ID + : window._env_.CUSTOMIZATION_SIDEBAR_FALLBACK_ID export const BASE_USE_NAMESPACE_NAV = import.meta.env.DEV ? window._env_.USE_NAMESPACE_NAV || import.meta.env.VITE_USE_NAMESPACE_NAV @@ -49,29 +54,29 @@ export const BASE_NAVIGATE_FROM_CLUSTERLIST = import.meta.env.DEV export const BASE_PROJECTS_API_GROUP = import.meta.env.DEV ? window._env_.PROJECTS_API_GROUP || import.meta.env.VITE_PROJECTS_API_GROUP : window._env_.PROJECTS_API_GROUP -export const BASE_PROJECTS_VERSION = import.meta.env.DEV - ? window._env_.PROJECTS_VERSION || import.meta.env.VITE_PROJECTS_VERSION - : window._env_.PROJECTS_VERSION -export const BASE_PROJECTS_RESOURCE_NAME = import.meta.env.DEV - ? window._env_.PROJECTS_RESOURCE_NAME || import.meta.env.VITE_PROJECTS_RESOURCE_NAME - : window._env_.PROJECTS_RESOURCE_NAME +export const BASE_PROJECTS_API_VERSION = import.meta.env.DEV + ? window._env_.PROJECTS_API_VERSION || import.meta.env.VITE_PROJECTS_API_VERSION + : window._env_.PROJECTS_API_VERSION +export const BASE_PROJECTS_PLURAL = import.meta.env.DEV + ? window._env_.PROJECTS_PLURAL || import.meta.env.VITE_PROJECTS_PLURAL + : window._env_.PROJECTS_PLURAL -export const BASE_MARKETPLACE_RESOURCE_NAME = import.meta.env.DEV - ? window._env_.MARKETPLACE_RESOURCE_NAME || import.meta.env.VITE_MARKETPLACE_RESOURCE_NAME - : window._env_.MARKETPLACE_RESOURCE_NAME +export const BASE_MARKETPLACE_PLURAL = import.meta.env.DEV + ? window._env_.MARKETPLACE_PLURAL || import.meta.env.VITE_MARKETPLACE_PLURAL + : window._env_.MARKETPLACE_PLURAL export const BASE_MARKETPLACE_KIND = import.meta.env.DEV ? import.meta.env.VITE_MARKETPLACE_KIND : window._env_.MARKETPLACE_KIND -export const BASE_INSTANCES_API_GROUP = import.meta.env.DEV +export const BASE_INSTANCES_API_GROUP: string | undefined = import.meta.env.DEV ? window._env_.INSTANCES_API_GROUP || import.meta.env.VITE_INSTANCES_API_GROUP : window._env_.INSTANCES_API_GROUP -export const BASE_INSTANCES_VERSION = import.meta.env.DEV - ? window._env_.INSTANCES_VERSION || import.meta.env.VITE_INSTANCES_VERSION - : window._env_.INSTANCES_VERSION -export const BASE_INSTANCES_RESOURCE_NAME = import.meta.env.DEV - ? window._env_.INSTANCES_RESOURCE_NAME || import.meta.env.VITE_INSTANCES_RESOURCE_NAME - : window._env_.INSTANCES_RESOURCE_NAME +export const BASE_INSTANCES_API_VERSION = import.meta.env.DEV + ? window._env_.INSTANCES_API_VERSION || import.meta.env.VITE_INSTANCES_API_VERSION + : window._env_.INSTANCES_API_VERSION +export const BASE_INSTANCES_PLURAL = import.meta.env.DEV + ? window._env_.INSTANCES_PLURAL || import.meta.env.VITE_INSTANCES_PLURAL + : window._env_.INSTANCES_PLURAL export const NODE_TERMINAL_DEFAULT_PROFILE = import.meta.env.DEV ? window._env_.NODE_TERMINAL_DEFAULT_PROFILE || import.meta.env.VITE_NODE_TERMINAL_DEFAULT_PROFILE @@ -119,14 +124,13 @@ export const BASE_NAMESPACE_FACTORY_KEY = import.meta.env.DEV ? window._env_.BASE_NAMESPACE_FACTORY_KEY || import.meta.env.VITE_BASE_NAMESPACE_FACTORY_KEY : window._env_.BASE_NAMESPACE_FACTORY_KEY -export const CUSTOM_NAMESPACE_API_RESOURCE_API_GROUP = import.meta.env.DEV +export const CUSTOM_NAMESPACE_API_RESOURCE_API_GROUP: string | undefined = import.meta.env.DEV ? window._env_.CUSTOM_NAMESPACE_API_RESOURCE_API_GROUP || import.meta.env.VITE_CUSTOM_NAMESPACE_API_RESOURCE_API_GROUP : window._env_.CUSTOM_NAMESPACE_API_RESOURCE_API_GROUP export const CUSTOM_NAMESPACE_API_RESOURCE_API_VERSION = import.meta.env.DEV ? window._env_.CUSTOM_NAMESPACE_API_RESOURCE_API_VERSION || import.meta.env.VITE_CUSTOM_NAMESPACE_API_RESOURCE_API_VERSION : window._env_.CUSTOM_NAMESPACE_API_RESOURCE_API_VERSION -export const CUSTOM_NAMESPACE_API_RESOURCE_RESOURCE_NAME = import.meta.env.DEV - ? window._env_.CUSTOM_NAMESPACE_API_RESOURCE_RESOURCE_NAME || - import.meta.env.VITE_CUSTOM_NAMESPACE_API_RESOURCE_RESOURCE_NAME - : window._env_.CUSTOM_NAMESPACE_API_RESOURCE_RESOURCE_NAME +export const CUSTOM_NAMESPACE_API_RESOURCE_PLURAL = import.meta.env.DEV + ? window._env_.CUSTOM_NAMESPACE_API_RESOURCE_PLURAL || import.meta.env.VITE_CUSTOM_NAMESPACE_API_RESOURCE_PLURAL + : window._env_.CUSTOM_NAMESPACE_API_RESOURCE_PLURAL diff --git a/src/hooks/useIsSearchPage/useIsSearchPage.ts b/src/hooks/useIsSearchPage/useIsSearchPage.ts index a7c3ad9..5eadd49 100644 --- a/src/hooks/useIsSearchPage/useIsSearchPage.ts +++ b/src/hooks/useIsSearchPage/useIsSearchPage.ts @@ -3,7 +3,7 @@ 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/*` + const pattern = `${base}/:cluster/:namespace?/:syntheticProject?/search/*` return Boolean(matchPath({ path: pattern }, pathname)) } diff --git a/src/hooks/useNavSelector/useNavSelector.ts b/src/hooks/useNavSelector/useNavSelector.ts index 4bc12ef..155b23e 100644 --- a/src/hooks/useNavSelector/useNavSelector.ts +++ b/src/hooks/useNavSelector/useNavSelector.ts @@ -1,22 +1,22 @@ import { - useApiResources, TClusterList, TSingleResource, - useDirectUnknownResource, + useK8sSmartResource, + TNavigationResource, } from '@prorobotech/openapi-k8s-toolkit' import { useSelector } from 'react-redux' import { RootState } from 'store/store' import { BASE_API_GROUP, BASE_API_VERSION, + BASE_CUSTOMIZATION_NAVIGATION_RESOURCE_PLURAL, BASE_CUSTOMIZATION_NAVIGATION_RESOURCE_NAME, - BASE_CUSTOMIZATION_NAVIGATION_RESOURCE, BASE_PROJECTS_API_GROUP, - BASE_PROJECTS_VERSION, - BASE_PROJECTS_RESOURCE_NAME, + BASE_PROJECTS_API_VERSION, + BASE_PROJECTS_PLURAL, BASE_INSTANCES_API_GROUP, - BASE_INSTANCES_VERSION, - BASE_INSTANCES_RESOURCE_NAME, + BASE_INSTANCES_API_VERSION, + BASE_INSTANCES_PLURAL, } from 'constants/customizationApiGroupAndVersion' import { parseAll } from './utils' @@ -47,48 +47,61 @@ const mappedInstanceToOptionInSidebar = ({ label: instance.metadata.name, }) -export const useNavSelector = (clusterName?: string, projectName?: string) => { +export const useNavSelector = (cluster?: string, projectName?: string) => { const clusterList = useSelector((state: RootState) => state.clusterList.clusterList) - const { data: navigationData } = useDirectUnknownResource<{ - spec: { instances: { mapOptionsPattern: string } } + const { data: navigationDataArr } = useK8sSmartResource<{ + items: TNavigationResource[] }>({ - uri: `/api/clusters/${clusterName}/k8s/apis/${BASE_API_GROUP}/${BASE_API_VERSION}/${BASE_CUSTOMIZATION_NAVIGATION_RESOURCE_NAME}/${BASE_CUSTOMIZATION_NAVIGATION_RESOURCE}`, - refetchInterval: false, - queryKey: ['navigation', clusterName || 'no-cluster'], - isEnabled: clusterName !== undefined, + cluster: cluster || '', + apiGroup: BASE_API_GROUP, + apiVersion: BASE_API_VERSION, + plural: BASE_CUSTOMIZATION_NAVIGATION_RESOURCE_PLURAL, + fieldSelector: `metadata.name=${BASE_CUSTOMIZATION_NAVIGATION_RESOURCE_NAME}`, + isEnabled: cluster !== undefined, }) - const { data: projects } = useApiResources({ - clusterName: clusterName || '', - namespace: '', + const navigationData = + navigationDataArr?.items && navigationDataArr.items.length > 0 ? navigationDataArr.items[0] : undefined + + const { data: projects } = useK8sSmartResource<{ + items: TSingleResource[] + }>({ + cluster: cluster || '', apiGroup: BASE_PROJECTS_API_GROUP, - apiVersion: BASE_PROJECTS_VERSION, - typeName: BASE_PROJECTS_RESOURCE_NAME, - limit: null, - isEnabled: clusterName !== undefined, + apiVersion: BASE_PROJECTS_API_VERSION, + plural: BASE_PROJECTS_PLURAL, + isEnabled: cluster !== undefined, }) - const { data: instances, isSuccess: allInstancesLoadingSuccess } = useApiResources({ - clusterName: clusterName || '', - namespace: '', + const { + data: instances, + isLoading: isInstancesLoading, + isError: isInstancesError, + } = useK8sSmartResource<{ + items: TSingleResource[] + }>({ + cluster: cluster || '', apiGroup: BASE_INSTANCES_API_GROUP, - apiVersion: BASE_INSTANCES_VERSION, - typeName: BASE_INSTANCES_RESOURCE_NAME, - limit: null, - isEnabled: clusterName !== undefined, + apiVersion: BASE_INSTANCES_API_VERSION, + plural: BASE_INSTANCES_PLURAL, + isEnabled: cluster !== undefined, }) + const allInstancesLoadingSuccess: boolean = Boolean( + instances && instances.items && !isInstancesError && !isInstancesLoading, + ) + const clustersInSidebar = clusterList ? clusterList.map(mappedClusterToOptionInSidebar) : [] - const projectsInSidebar = clusterName && projects ? projects.items.map(mappedProjectToOptionInSidebar) : [] + const projectsInSidebar = cluster && projects ? projects.items.map(mappedProjectToOptionInSidebar) : [] const instancesInSidebar = - clusterName && instances + cluster && instances ? instances.items .filter(item => item.metadata.namespace === projectName) .map(item => mappedInstanceToOptionInSidebar({ instance: item, - templateString: navigationData?.spec.instances.mapOptionsPattern, + templateString: navigationData?.spec?.instances?.mapOptionsPattern, }), ) : [] diff --git a/src/hooks/useNavSelectorInside.ts b/src/hooks/useNavSelectorInside.ts index 7358170..c7e5ec5 100644 --- a/src/hooks/useNavSelectorInside.ts +++ b/src/hooks/useNavSelectorInside.ts @@ -1,10 +1,10 @@ -import { TClusterList, TSingleResource, useBuiltinResources, useApiResources } from '@prorobotech/openapi-k8s-toolkit' +import { TClusterList, TSingleResource, useK8sSmartResource } from '@prorobotech/openapi-k8s-toolkit' import { useSelector } from 'react-redux' import { RootState } from 'store/store' import { CUSTOM_NAMESPACE_API_RESOURCE_API_GROUP, CUSTOM_NAMESPACE_API_RESOURCE_API_VERSION, - CUSTOM_NAMESPACE_API_RESOURCE_RESOURCE_NAME, + CUSTOM_NAMESPACE_API_RESOURCE_PLURAL, } from 'constants/customizationApiGroupAndVersion' const mappedClusterToOptionInSidebar = ({ name }: TClusterList[number]): { value: string; label: string } => ({ @@ -17,7 +17,7 @@ const mappedNamespaceToOptionInSidebar = ({ metadata }: TSingleResource): { valu label: metadata.name, }) -export const useNavSelectorInside = (clusterName?: string) => { +export const useNavSelectorInside = (cluster?: string) => { const clusterList = useSelector((state: RootState) => state.clusterList.clusterList) const isCustomNamespaceResource = @@ -27,30 +27,33 @@ export const useNavSelectorInside = (clusterName?: string) => { CUSTOM_NAMESPACE_API_RESOURCE_API_VERSION && typeof CUSTOM_NAMESPACE_API_RESOURCE_API_VERSION === 'string' && CUSTOM_NAMESPACE_API_RESOURCE_API_VERSION.length > 0 && - CUSTOM_NAMESPACE_API_RESOURCE_RESOURCE_NAME && - typeof CUSTOM_NAMESPACE_API_RESOURCE_RESOURCE_NAME === 'string' && - CUSTOM_NAMESPACE_API_RESOURCE_RESOURCE_NAME.length > 0 + CUSTOM_NAMESPACE_API_RESOURCE_PLURAL && + typeof CUSTOM_NAMESPACE_API_RESOURCE_PLURAL === 'string' && + CUSTOM_NAMESPACE_API_RESOURCE_PLURAL.length > 0 - const { data: namespaces } = useBuiltinResources({ - clusterName: clusterName || '', - typeName: 'namespaces', - limit: null, - isEnabled: Boolean(clusterName !== undefined && !isCustomNamespaceResource), + const { data: namespaces } = useK8sSmartResource<{ + items: TSingleResource[] + }>({ + cluster: cluster || '', + apiVersion: 'v1', + plural: 'namespaces', + isEnabled: Boolean(cluster !== undefined && !isCustomNamespaceResource), }) - const { data: namespacesCustom } = useApiResources({ - clusterName: clusterName || '', + const { data: namespacesCustom } = useK8sSmartResource<{ + items: TSingleResource[] + }>({ + cluster: cluster || '', apiGroup: CUSTOM_NAMESPACE_API_RESOURCE_API_GROUP, apiVersion: CUSTOM_NAMESPACE_API_RESOURCE_API_VERSION, - typeName: CUSTOM_NAMESPACE_API_RESOURCE_RESOURCE_NAME, - limit: null, - isEnabled: Boolean(clusterName !== undefined && isCustomNamespaceResource), + plural: CUSTOM_NAMESPACE_API_RESOURCE_PLURAL, + isEnabled: Boolean(cluster !== undefined && !isCustomNamespaceResource), }) const clustersInSidebar = clusterList ? clusterList.map(mappedClusterToOptionInSidebar) : [] - const namespacesInSidebar = clusterName && namespaces ? namespaces.items.map(mappedNamespaceToOptionInSidebar) : [] + const namespacesInSidebar = cluster && namespaces ? namespaces.items.map(mappedNamespaceToOptionInSidebar) : [] const namespacesInSidebarCustom = - clusterName && namespacesCustom ? namespacesCustom.items.map(mappedNamespaceToOptionInSidebar) : [] + cluster && namespacesCustom ? namespacesCustom.items.map(mappedNamespaceToOptionInSidebar) : [] return { clustersInSidebar, diff --git a/src/pages/FactoryAdminPage/AddComponentModal.tsx b/src/pages/FactoryAdminPage/AddComponentModal.tsx deleted file mode 100644 index f2d7616..0000000 --- a/src/pages/FactoryAdminPage/AddComponentModal.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import React, { useState } from 'react' -import { Modal, Button, Form, Select } from 'antd' -import { ComponentType } from './types' - -export const componentTypes: ComponentType[] = [ - 'antdText', - 'antdCard', - 'antdFlex', - 'antdRow', - 'antdCol', - 'partsOfUrl', - 'multiQuery', - 'parsedText', -] - -interface AddComponentModalProps { - onAdd: (type: ComponentType) => void - title?: string -} - -export const AddComponentModal: React.FC = ({ onAdd, title = 'Add Component' }) => { - const [visible, setVisible] = useState(false) - const [form] = Form.useForm() - - const handleSubmit = (values: { type: ComponentType }) => { - onAdd(values.type) - setVisible(false) - form.resetFields() - } - - return ( - <> - - setVisible(false)} footer={null}> -
- - - - -
-
- - ) -} diff --git a/src/pages/FactoryAdminPage/AntdCardForm.tsx b/src/pages/FactoryAdminPage/AntdCardForm.tsx deleted file mode 100644 index 7e97207..0000000 --- a/src/pages/FactoryAdminPage/AntdCardForm.tsx +++ /dev/null @@ -1,73 +0,0 @@ -/* eslint-disable no-console */ -/* eslint-disable no-param-reassign */ -/* eslint-disable @typescript-eslint/no-explicit-any */ -import React, { useEffect } from 'react' -import { Form, Input, Select, Button, Switch } from 'antd' - -const { TextArea } = Input -const { Option } = Select - -interface AntdCardFormProps { - initialValues: any // This would be `TDynamicComponentsAppTypeMap['antdCard']` - onSave: (data: any) => void -} - -export const AntdCardForm: React.FC = ({ initialValues, onSave }) => { - const [form] = Form.useForm() - - useEffect(() => { - form.setFieldsValue(initialValues) - }, [initialValues, form]) - - const handleSubmit = (values: any) => { - try { - if (values.style) { - values.style = JSON.parse(values.style) - } - } catch (e) { - console.log('Invalid JSON for style', e) - return - } - - onSave(values) - } - - return ( -
- - - - - - - - - - - - - - - - - -