From 0ae87be669046f609796a4fa01989b1fb80c9ba9 Mon Sep 17 00:00:00 2001 From: arunjaindev Date: Fri, 22 Nov 2024 11:53:05 +0530 Subject: [PATCH 01/18] chore: version bump --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 2e23f10e92..7e431b6dae 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "private": true, "homepage": "/dashboard", "dependencies": { - "@devtron-labs/devtron-fe-common-lib": "0.6.5-patch-1", + "@devtron-labs/devtron-fe-common-lib": "0.6.5-patch-1-beta-1", "@esbuild-plugins/node-globals-polyfill": "0.2.3", "@rjsf/core": "^5.13.3", "@rjsf/utils": "^5.13.3", diff --git a/yarn.lock b/yarn.lock index 592c5e04cd..2fcc846df3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1061,10 +1061,10 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" -"@devtron-labs/devtron-fe-common-lib@0.6.5-patch-1": - version "0.6.5-patch-1" - resolved "https://registry.yarnpkg.com/@devtron-labs/devtron-fe-common-lib/-/devtron-fe-common-lib-0.6.5-patch-1.tgz#a30621f79a099b6f611a03b0a354d381f7231e2f" - integrity sha512-6xoY2Y2oTbx1jdVkaFHIPXpCbaT1mfOIOyulxI+yrj3Y9nxe5rBCGQWN7m/dhgfGYuxQqi81V8GqwKGU4JC4pQ== +"@devtron-labs/devtron-fe-common-lib@0.6.5-patch-1-beta-1": + version "0.6.5-patch-1-beta-1" + resolved "https://registry.yarnpkg.com/@devtron-labs/devtron-fe-common-lib/-/devtron-fe-common-lib-0.6.5-patch-1-beta-1.tgz#b8f577d4b467500452e4ee2145c31d7e9244be27" + integrity sha512-7GB7YFeX0nE408uNvvIddOhYpmPcTMNkWimjeeQi6fFvo+ftKBONF6RRqAbw9wBuc2bsQlr4nPQsMmCw7dytpg== dependencies: "@types/react-dates" "^21.8.6" ansi_up "^5.2.1" From 5cfe8311a1b5e3a7b893fdf407640f419d226869 Mon Sep 17 00:00:00 2001 From: arunjaindev Date: Fri, 22 Nov 2024 12:51:38 +0530 Subject: [PATCH 02/18] fix: hide templateType from devtron and flux --- src/components/app/list-new/list.utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/app/list-new/list.utils.ts b/src/components/app/list-new/list.utils.ts index 3a4639b718..46372e73ce 100644 --- a/src/components/app/list-new/list.utils.ts +++ b/src/components/app/list-new/list.utils.ts @@ -206,6 +206,6 @@ export const getFilterChipConfig = ( case AppListConstants.AppType.FLUX_APPS: return { cluster, namespace, templateType } default: - return filterConfig + return { ...filterConfig, templateType: [] } } } From 13a7934ef0264e4f59e127cff5484c79546b79e0 Mon Sep 17 00:00:00 2001 From: arunjaindev Date: Fri, 22 Nov 2024 12:59:43 +0530 Subject: [PATCH 03/18] chore: version bump --- package.json | 2 +- yarn.lock | 58 ++++++++++++++++++++++++++-------------------------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/package.json b/package.json index 7e431b6dae..cb19fb4bd9 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "private": true, "homepage": "/dashboard", "dependencies": { - "@devtron-labs/devtron-fe-common-lib": "0.6.5-patch-1-beta-1", + "@devtron-labs/devtron-fe-common-lib": "0.6.5-patch-2", "@esbuild-plugins/node-globals-polyfill": "0.2.3", "@rjsf/core": "^5.13.3", "@rjsf/utils": "^5.13.3", diff --git a/yarn.lock b/yarn.lock index 2fcc846df3..cab32a9eaf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1061,10 +1061,10 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" -"@devtron-labs/devtron-fe-common-lib@0.6.5-patch-1-beta-1": - version "0.6.5-patch-1-beta-1" - resolved "https://registry.yarnpkg.com/@devtron-labs/devtron-fe-common-lib/-/devtron-fe-common-lib-0.6.5-patch-1-beta-1.tgz#b8f577d4b467500452e4ee2145c31d7e9244be27" - integrity sha512-7GB7YFeX0nE408uNvvIddOhYpmPcTMNkWimjeeQi6fFvo+ftKBONF6RRqAbw9wBuc2bsQlr4nPQsMmCw7dytpg== +"@devtron-labs/devtron-fe-common-lib@0.6.5-patch-2": + version "0.6.5-patch-2" + resolved "https://registry.yarnpkg.com/@devtron-labs/devtron-fe-common-lib/-/devtron-fe-common-lib-0.6.5-patch-2.tgz#7f6d4877a148c28c100378691240e0bac14058e9" + integrity sha512-8DUAD7EfJ9bO5LfDAUTfUAqjEmgiF0Q9UZmdVCio1GZQYaLYD+MaFgVldToz8ZwMPSInaYmMjF3w3SHTCwWTDg== dependencies: "@types/react-dates" "^21.8.6" ansi_up "^5.2.1" @@ -3644,14 +3644,14 @@ browser-assert@^1.2.1: integrity sha512-nfulgvOR6S4gt9UKCeGJOuSGBPGiFT6oQ/2UBnvTY/5aQ1PnksW72fhZkM30DzoRRv2WpwZf1vHHEr3mtuXIWQ== browserslist@^4.23.1, browserslist@^4.23.3: - version "4.23.3" - resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz" - integrity sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA== + version "4.24.2" + resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz" + integrity sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg== dependencies: - caniuse-lite "^1.0.30001646" - electron-to-chromium "^1.5.4" + caniuse-lite "^1.0.30001669" + electron-to-chromium "^1.5.41" node-releases "^2.0.18" - update-browserslist-db "^1.1.0" + update-browserslist-db "^1.1.1" bs-logger@^0.2.6: version "0.2.6" @@ -3734,10 +3734,10 @@ camelcase@^6.2.0: resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -caniuse-lite@^1.0.30001646: - version "1.0.30001667" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001667.tgz" - integrity sha512-7LTwJjcRkzKFmtqGsibMeuXmvFDfZq/nzIjnmgCGzKKRVzjD72selLDK1oPF/Oxzmt4fNcPvTDvGqSDG4tCALw== +caniuse-lite@^1.0.30001669: + version "1.0.30001683" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001683.tgz" + integrity sha512-iqmNnThZ0n70mNwvxpEC2nBJ037ZHZUoBI5Gorh1Mw6IlEAZujEoU1tXA628iZfzm7R9FvFzxbfdgml82a3k8Q== chai@^4.3.10: version "4.5.0" @@ -4537,10 +4537,10 @@ ejs@^3.1.10, ejs@^3.1.6: dependencies: jake "^10.8.5" -electron-to-chromium@^1.5.4: - version "1.5.32" - resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.32.tgz" - integrity sha512-M+7ph0VGBQqqpTT2YrabjNKSQ2fEl9PVx6AK3N558gDH9NO8O6XN9SXXFWRo9u9PbEg/bWq+tjXQr+eXmxubCw== +electron-to-chromium@^1.5.41: + version "1.5.64" + resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.64.tgz" + integrity sha512-IXEuxU+5ClW2IGEYFC2T7szbyVgehupCWQe5GNh+H065CD6U6IFN0s4KeAMFGNmQolRU4IV7zGBWSYMmZ8uuqQ== emoji-regex@^8.0.0: version "8.0.0" @@ -4780,10 +4780,10 @@ esbuild-register@^3.5.0: "@esbuild/win32-ia32" "0.21.5" "@esbuild/win32-x64" "0.21.5" -escalade@^3.1.2: - version "3.1.2" - resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz" - integrity sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA== +escalade@^3.2.0: + version "3.2.0" + resolved "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz" + integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== escape-html@~1.0.3: version "1.0.3" @@ -7573,7 +7573,7 @@ performance-now@^2.1.0: resolved "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz" integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow== -picocolors@^1.0.0, picocolors@^1.0.1, picocolors@^1.1.0: +picocolors@^1.0.0, picocolors@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz" integrity sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw== @@ -9720,13 +9720,13 @@ upath@^1.2.0: resolved "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz" integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== -update-browserslist-db@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz" - integrity sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ== +update-browserslist-db@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz" + integrity sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A== dependencies: - escalade "^3.1.2" - picocolors "^1.0.1" + escalade "^3.2.0" + picocolors "^1.1.0" uri-js@^4.2.2, uri-js@^4.4.1: version "4.4.1" From 29700fe1ba2ec146bd69199bc455a105fce99044 Mon Sep 17 00:00:00 2001 From: Amrit Kashyap Borah Date: Fri, 22 Nov 2024 12:48:15 +0530 Subject: [PATCH 04/18] fix: dont check for namespaced in kind selector of user permission --- .../K8sObjectPermissions/K8sListItemCard.tsx | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/Pages/GlobalConfigurations/Authorization/Shared/components/K8sObjectPermissions/K8sListItemCard.tsx b/src/Pages/GlobalConfigurations/Authorization/Shared/components/K8sObjectPermissions/K8sListItemCard.tsx index a94728ab54..3960401f3e 100644 --- a/src/Pages/GlobalConfigurations/Authorization/Shared/components/K8sObjectPermissions/K8sListItemCard.tsx +++ b/src/Pages/GlobalConfigurations/Authorization/Shared/components/K8sObjectPermissions/K8sListItemCard.tsx @@ -30,6 +30,7 @@ import { GVKType, getK8sResourceList, EntityTypes, + ApiResourceGroupType, } from '@devtron-labs/devtron-fe-common-lib' import CreatableSelect from 'react-select/creatable' import Tippy from '@tippyjs/react' @@ -85,7 +86,7 @@ const K8sListItemCard = ({ const { showStatus, userStatus } = usePermissionConfiguration() const [clusterOptions, setClusterOptions] = useState([]) const [processedData, setProcessedData] = useState>() - const [allInKindMapping, setAllInKindMapping] = useState([]) + const allInKindMapping = { label: 'All kind', value: SELECT_ALL_VALUE } const [ { isClusterListLoading, isNamespaceListLoading, isApiGroupListLoading, isResourceListLoading }, setLoadingState, @@ -174,16 +175,19 @@ const K8sListItemCard = ({ } } - const createKindData = (selected, _allKindMapping, _k8SObjectMap = null) => { + const createKindData = (selected, _k8SObjectMap = null) => { const kind = [] let selectedGvk: GVKType + const isAllNamespaceSelected = k8sPermission.namespace.some((option) => option.value === SELECT_ALL_VALUE) if (_k8SObjectMap ?? processedData) { if (selected.value === SELECT_ALL_VALUE) { // eslint-disable-next-line no-restricted-syntax for (const value of (_k8SObjectMap ?? processedData).values()) { // eslint-disable-next-line no-loop-func - value?.child.forEach((ele: { gvk: GVKType }) => { - kind.push({ value: ele.gvk.Kind, label: ele.gvk.Kind, gvk: ele.gvk }) + value?.child.forEach((ele: ApiResourceGroupType) => { + if (isAllNamespaceSelected || ele.namespaced) { + kind.push({ label: ele.gvk.Kind, value: ele.gvk.Kind, gvk: ele.gvk }) + } if (!selectedGvk && ele.gvk.Kind === k8sPermission.kind?.value) { selectedGvk = ele.gvk } @@ -191,8 +195,9 @@ const K8sListItemCard = ({ } } else { const data = (_k8SObjectMap ?? processedData).get(selected.value === 'k8sempty' ? '' : selected.value) + data?.child?.forEach((ele) => { - if (ele.namespaced) { + if (isAllNamespaceSelected || ele.namespaced) { kind.push({ label: ele.gvk.Kind, value: ele.gvk.Kind, gvk: ele.gvk }) } if (!selectedGvk && ele.gvk.Kind === k8sPermission.kind?.value) { @@ -201,12 +206,12 @@ const K8sListItemCard = ({ }) } } else { - _allKindMapping = [{ label: 'All kind', value: SELECT_ALL_VALUE }] + kind.push(allInKindMapping[0]) } setKindMapping((prevMapping) => ({ ...prevMapping, - [k8sPermission.key]: [..._allKindMapping, ...kind.sort(sortOptionsByLabel)], + [k8sPermission.key]: [...kind.sort(sortOptionsByLabel)], })) if (k8sPermission?.resource) { if (k8sPermission.kind.value !== SELECT_ALL_VALUE && k8sPermission.kind.value !== 'Event') { @@ -238,15 +243,12 @@ const K8sListItemCard = ({ const _processedNamespacedGvk = processK8SObjects(namespacedGvkList, '', true) const _allApiGroupMapping = [] - const _allKindMapping = [] if (resourceGroupList.allowedAll) { _allApiGroupMapping.push( { label: 'All API groups', value: SELECT_ALL_VALUE }, { label: 'K8s core groups (eg. service, pod, etc.)', value: 'k8sempty' }, ) - _allKindMapping.push({ label: 'All kind', value: SELECT_ALL_VALUE }) } - setAllInKindMapping(_allKindMapping) setApiGroupMapping((prevMapping) => ({ ...prevMapping, [k8sPermission.key]: [..._allApiGroupMapping, ..._k8SObjectList.sort(sortOptionsByLabel)], @@ -255,7 +257,6 @@ const K8sListItemCard = ({ if (k8sPermission?.kind) { createKindData( k8sPermission.group, - _allKindMapping, k8sPermission?.namespace.some((el) => el.value === SELECT_ALL_VALUE) ? _k8SObjectMap : _processedNamespacedGvk.k8SObjectMap, @@ -336,7 +337,7 @@ const K8sListItemCard = ({ const onApiGroupSelect = (selected) => { if (selected.value !== k8sPermission?.group?.value) { handleK8sPermission(K8sPermissionActionType.onApiGroupChange, index, selected) - createKindData(selected, allInKindMapping) + createKindData(selected) } } From 9ae069678be9b996300aef385eb536199dbe19f6 Mon Sep 17 00:00:00 2001 From: Eshank Vaish <48060426+eshankvaish@users.noreply.github.com> Date: Fri, 22 Nov 2024 19:16:19 +0530 Subject: [PATCH 05/18] fix: key mismatch for resource list and redirection for events --- .../ResourceBrowser/ResourceList/BaseResourceList.tsx | 5 ++--- .../ResourceBrowser/ResourceList/K8SResourceList.tsx | 5 ++++- src/components/ResourceBrowser/ResourceList/ResourceList.tsx | 5 ++++- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/components/ResourceBrowser/ResourceList/BaseResourceList.tsx b/src/components/ResourceBrowser/ResourceList/BaseResourceList.tsx index cdbb3e4f45..37bd1f7f77 100644 --- a/src/components/ResourceBrowser/ResourceList/BaseResourceList.tsx +++ b/src/components/ResourceBrowser/ResourceList/BaseResourceList.tsx @@ -369,7 +369,7 @@ const BaseResourceListContent = ({ {resourceList?.headers.map((columnName) => columnName === 'name' ? (
@@ -436,7 +436,7 @@ const BaseResourceListContent = ({
) : (
)} ({ id: `${data.name}-${data.namespace}`, ...data })) + result.data = result.data.map((data, index) => ({ + id: `${selectedResource?.gvk?.Kind}-${data.name}-${data.namespace}-${index}`, + ...data, + })) return result }, [_resourceList]) diff --git a/src/components/ResourceBrowser/ResourceList/ResourceList.tsx b/src/components/ResourceBrowser/ResourceList/ResourceList.tsx index c265a2fdc6..7616609ba3 100644 --- a/src/components/ResourceBrowser/ResourceList/ResourceList.tsx +++ b/src/components/ResourceBrowser/ResourceList/ResourceList.tsx @@ -358,7 +358,7 @@ const ResourceList = () => { const handleResourceClick = (e, shouldOverrideSelectedResourceKind: boolean) => { const { name, tab, namespace: currentNamespace, origin, kind: kindFromResource } = e.currentTarget.dataset const lowercaseKindFromResource = shouldOverrideSelectedResourceKind ? kindFromResource.toLowerCase() : null - const _group: string = + let _group: string = (shouldOverrideSelectedResourceKind ? lowercaseKindToResourceGroupMap[lowercaseKindFromResource]?.gvk?.Group?.toLowerCase() : selectedResource?.gvk.Group.toLowerCase()) || K8S_EMPTY_GROUP @@ -371,6 +371,9 @@ const ResourceList = () => { if (origin === 'event') { const [_kind, _resourceName] = name.split('/') const eventKind = shouldOverrideSelectedResourceKind ? lowercaseKindFromResource : _kind + // For event, we should read the group for kind from the resource group map else fallback to empty group + _group = lowercaseKindToResourceGroupMap[eventKind]?.gvk?.Group || K8S_EMPTY_GROUP + resourceParam = `${eventKind}/${_group}/${_resourceName}` kind = eventKind resourceName = _resourceName From e3b4333e084c086e54f0d8171d45808c30fb6c5e Mon Sep 17 00:00:00 2001 From: Amrit Kashyap Borah Date: Mon, 25 Nov 2024 13:53:14 +0530 Subject: [PATCH 06/18] feat: remove super admin checks for terminal, node details, etc --- .../K8sObjectPermissions/K8sListItemCard.tsx | 15 +++-- .../ClusterNodes/ClusterOverview.tsx | 7 ++- .../ClusterNodes/ClusterSelectionList.tsx | 3 +- src/components/ClusterNodes/NodeDetails.tsx | 39 +++--------- src/components/ClusterNodes/types.ts | 2 - .../ResourceBrowser/ResourceBrowser.tsx | 10 +--- .../ResourceList/AdminTerminal.tsx | 6 +- .../ResourceList/BaseResourceList.tsx | 2 +- .../ResourceList/NodeActionsMenu.tsx | 60 +++++-------------- .../ResourceList/ResourceList.tsx | 27 ++------- src/components/ResourceBrowser/Types.ts | 4 -- src/components/ResourceBrowser/Utils.tsx | 33 ++++------ 12 files changed, 60 insertions(+), 148 deletions(-) diff --git a/src/Pages/GlobalConfigurations/Authorization/Shared/components/K8sObjectPermissions/K8sListItemCard.tsx b/src/Pages/GlobalConfigurations/Authorization/Shared/components/K8sObjectPermissions/K8sListItemCard.tsx index 3960401f3e..9f68bd3ee8 100644 --- a/src/Pages/GlobalConfigurations/Authorization/Shared/components/K8sObjectPermissions/K8sListItemCard.tsx +++ b/src/Pages/GlobalConfigurations/Authorization/Shared/components/K8sObjectPermissions/K8sListItemCard.tsx @@ -86,7 +86,7 @@ const K8sListItemCard = ({ const { showStatus, userStatus } = usePermissionConfiguration() const [clusterOptions, setClusterOptions] = useState([]) const [processedData, setProcessedData] = useState>() - const allInKindMapping = { label: 'All kind', value: SELECT_ALL_VALUE } + const [allInKindMapping, setAllInKindMapping] = useState([]) const [ { isClusterListLoading, isNamespaceListLoading, isApiGroupListLoading, isResourceListLoading }, setLoadingState, @@ -175,7 +175,7 @@ const K8sListItemCard = ({ } } - const createKindData = (selected, _k8SObjectMap = null) => { + const createKindData = (selected, _allKindMapping, _k8SObjectMap = null) => { const kind = [] let selectedGvk: GVKType const isAllNamespaceSelected = k8sPermission.namespace.some((option) => option.value === SELECT_ALL_VALUE) @@ -195,7 +195,6 @@ const K8sListItemCard = ({ } } else { const data = (_k8SObjectMap ?? processedData).get(selected.value === 'k8sempty' ? '' : selected.value) - data?.child?.forEach((ele) => { if (isAllNamespaceSelected || ele.namespaced) { kind.push({ label: ele.gvk.Kind, value: ele.gvk.Kind, gvk: ele.gvk }) @@ -206,12 +205,12 @@ const K8sListItemCard = ({ }) } } else { - kind.push(allInKindMapping[0]) + _allKindMapping = [{ label: 'All kind', value: SELECT_ALL_VALUE }] } setKindMapping((prevMapping) => ({ ...prevMapping, - [k8sPermission.key]: [...kind.sort(sortOptionsByLabel)], + [k8sPermission.key]: [..._allKindMapping, ...kind.sort(sortOptionsByLabel)], })) if (k8sPermission?.resource) { if (k8sPermission.kind.value !== SELECT_ALL_VALUE && k8sPermission.kind.value !== 'Event') { @@ -243,12 +242,15 @@ const K8sListItemCard = ({ const _processedNamespacedGvk = processK8SObjects(namespacedGvkList, '', true) const _allApiGroupMapping = [] + const _allKindMapping = [] if (resourceGroupList.allowedAll) { _allApiGroupMapping.push( { label: 'All API groups', value: SELECT_ALL_VALUE }, { label: 'K8s core groups (eg. service, pod, etc.)', value: 'k8sempty' }, ) + _allKindMapping.push({ label: 'All kind', value: SELECT_ALL_VALUE }) } + setAllInKindMapping(_allKindMapping) setApiGroupMapping((prevMapping) => ({ ...prevMapping, [k8sPermission.key]: [..._allApiGroupMapping, ..._k8SObjectList.sort(sortOptionsByLabel)], @@ -257,6 +259,7 @@ const K8sListItemCard = ({ if (k8sPermission?.kind) { createKindData( k8sPermission.group, + _allKindMapping, k8sPermission?.namespace.some((el) => el.value === SELECT_ALL_VALUE) ? _k8SObjectMap : _processedNamespacedGvk.k8SObjectMap, @@ -337,7 +340,7 @@ const K8sListItemCard = ({ const onApiGroupSelect = (selected) => { if (selected.value !== k8sPermission?.group?.value) { handleK8sPermission(K8sPermissionActionType.onApiGroupChange, index, selected) - createKindData(selected) + createKindData(selected, allInKindMapping) } } diff --git a/src/components/ClusterNodes/ClusterOverview.tsx b/src/components/ClusterNodes/ClusterOverview.tsx index b820b52049..9edd1bab77 100644 --- a/src/components/ClusterNodes/ClusterOverview.tsx +++ b/src/components/ClusterNodes/ClusterOverview.tsx @@ -24,6 +24,7 @@ import { EditableTextArea, ResourceKindType, getUrlWithSearchParams, + showError, } from '@devtron-labs/devtron-fe-common-lib' import { ClusterErrorType, @@ -89,7 +90,7 @@ const tippyForMetricsApi = () => { ) } -function ClusterOverview({ isSuperAdmin, selectedCluster, addTab }: ClusterOverviewProps) { +function ClusterOverview({ selectedCluster, addTab }: ClusterOverviewProps) { const { clusterId, namespace } = useParams<{ clusterId: string namespace: string @@ -132,7 +133,7 @@ function ClusterOverview({ isSuperAdmin, selectedCluster, addTab }: ClusterOverv }) } } catch (error) { - setErrorCode(error['code']) + showError(error) throw error } } @@ -512,7 +513,7 @@ function ClusterOverview({ isSuperAdmin, selectedCluster, addTab }: ClusterOverv ({ const ClusterSelectionList: React.FC = ({ clusterOptions, - isSuperAdmin, clusterListLoader, initialLoading, refreshData, @@ -190,7 +189,7 @@ const ClusterSelectionList: React.FC = ({ {/* NOTE: visible-hover plays with display prop; therefore need to set display: flex on a new div */}
- {!!clusterData.nodeCount && !clusterListLoader && isSuperAdmin && ( + {!!clusterData.nodeCount && !clusterListLoader && (
{ +const NodeDetails = ({ addTab, lowercaseKindToResourceGroupMap, updateTabUrl }: ClusterListType) => { const { clusterId, node } = useParams<{ clusterId: string; nodeType: string; node: string }>() const [loader, setLoader] = useState(true) const [apiInProgress, setApiInProgress] = useState(false) @@ -799,12 +799,10 @@ const NodeDetails = ({ isSuperAdmin, addTab, lowercaseKindToResourceGroupMap, up return (
- {isSuperAdmin && ( - - - {NODE_DETAILS_TABS.debug} - - )} + + + {NODE_DETAILS_TABS.debug} + | {renderTabControls()}
@@ -996,21 +994,8 @@ const NodeDetails = ({ isSuperAdmin, addTab, lowercaseKindToResourceGroupMap, up return renderSummary() } - const isAuthorized = (): boolean => { - if (!isSuperAdmin) { - ToastManager.showToast({ - variant: ToastVariantType.notAuthorized, - description: TOAST_ACCESS_DENIED.SUBTITLE, - }) - return false - } - return true - } - const showCordonNodeModal = (): void => { - if (isAuthorized()) { - setCordonNodeDialog(true) - } + setCordonNodeDialog(true) } const hideCordonNodeModal = (refreshData?: boolean): void => { @@ -1021,9 +1006,7 @@ const NodeDetails = ({ isSuperAdmin, addTab, lowercaseKindToResourceGroupMap, up } const showDrainNodeModal = (): void => { - if (isAuthorized()) { - setDrainNodeDialog(true) - } + setDrainNodeDialog(true) } const hideDrainNodeModal = (refreshData?: boolean): void => { @@ -1034,9 +1017,7 @@ const NodeDetails = ({ isSuperAdmin, addTab, lowercaseKindToResourceGroupMap, up } const showDeleteNodeModal = (): void => { - if (isAuthorized()) { - setDeleteNodeDialog(true) - } + setDeleteNodeDialog(true) } const hideDeleteNodeModal = (refreshData?: boolean): void => { @@ -1047,9 +1028,7 @@ const NodeDetails = ({ isSuperAdmin, addTab, lowercaseKindToResourceGroupMap, up } const showEditTaintsModal = (): void => { - if (isAuthorized()) { - setShowEditTaints(true) - } + setShowEditTaints(true) } const hideEditTaintsModal = (refreshData?: boolean): void => { diff --git a/src/components/ClusterNodes/types.ts b/src/components/ClusterNodes/types.ts index 49b5ed8863..cba282716a 100644 --- a/src/components/ClusterNodes/types.ts +++ b/src/components/ClusterNodes/types.ts @@ -161,7 +161,6 @@ export interface ColumnMetadataType { } export interface ClusterListType extends Pick { - isSuperAdmin: boolean addTab?: ReturnType['addTab'] updateTabUrl: (params: Omit) => void } @@ -344,7 +343,6 @@ export interface ClusterErrorType { filterText: string[] } export interface ClusterOverviewProps { - isSuperAdmin: boolean selectedCluster: ClusterOptionType addTab: ReturnType['addTab'] } diff --git a/src/components/ResourceBrowser/ResourceBrowser.tsx b/src/components/ResourceBrowser/ResourceBrowser.tsx index 19f7079aa9..50a14bfd9e 100644 --- a/src/components/ResourceBrowser/ResourceBrowser.tsx +++ b/src/components/ResourceBrowser/ResourceBrowser.tsx @@ -17,7 +17,6 @@ import React, { useEffect, useMemo, useRef } from 'react' import { showError, - getUserRole, DevtronProgressing, useAsync, PageHeader, @@ -44,11 +43,7 @@ const ResourceBrowser: React.FC = () => { return null } }) - const [initialLoading, data, error] = useAsync(() => - Promise.all([getClusterListMin(), window._env_?.K8S_CLIENT ? null : getUserRole()]), - ) - /* transpose the data */ - const [clusterListMinData = null, userRoleData = null] = data || [] + const [initialLoading, clusterListMinData, error] = useAsync(() => getClusterListMin()) useEffect( () => () => { @@ -67,8 +62,6 @@ const ResourceBrowser: React.FC = () => { [detailClusterList, clusterListMinData], ) - const isSuperAdmin = userRoleData?.result.superAdmin || false - const renderContent = () => { if (error) { return @@ -77,7 +70,6 @@ const ResourceBrowser: React.FC = () => { return ( = ({ isSuperAdmin, updateTerminalTabUrl }: AdminTerminalProps) => { +const AdminTerminal: React.FC = ({ updateTerminalTabUrl }: AdminTerminalProps) => { const { clusterId } = useParams() const [loading, data, error] = useAsync( @@ -65,7 +65,7 @@ const AdminTerminal: React.FC = ({ isSuperAdmin, updateTermi const errCode = error?.code || 403 return (
- {isSuperAdmin ? : } +
) } diff --git a/src/components/ResourceBrowser/ResourceList/BaseResourceList.tsx b/src/components/ResourceBrowser/ResourceList/BaseResourceList.tsx index 075f3924f7..027d47ff21 100644 --- a/src/components/ResourceBrowser/ResourceList/BaseResourceList.tsx +++ b/src/components/ResourceBrowser/ResourceList/BaseResourceList.tsx @@ -261,7 +261,7 @@ const BaseResourceListContent = ({ handleFilterChanges(searchText) setResourceListOffset(0) - }, [resourceList, sortBy, sortOrder, location.search]) + }, [resourceList, sortBy, sortOrder, location.search, isOpen]) const getHandleCheckedForId = (resourceData: K8sResourceDetailDataType) => () => { const { id } = resourceData as Record<'id', string> diff --git a/src/components/ResourceBrowser/ResourceList/NodeActionsMenu.tsx b/src/components/ResourceBrowser/ResourceList/NodeActionsMenu.tsx index 8634373e8d..bcd1215e11 100644 --- a/src/components/ResourceBrowser/ResourceList/NodeActionsMenu.tsx +++ b/src/components/ResourceBrowser/ResourceList/NodeActionsMenu.tsx @@ -16,14 +16,7 @@ import { useState } from 'react' import { useHistory, useLocation, useRouteMatch } from 'react-router-dom' -import { - noop, - PopupMenu, - TOAST_ACCESS_DENIED, - ToastManager, - ToastVariantType, - useMainContext, -} from '@devtron-labs/devtron-fe-common-lib' +import { noop, PopupMenu } from '@devtron-labs/devtron-fe-common-lib' import { AppDetailsTabs } from '@Components/v2/appDetails/appDetails.store' import { TaintType } from '@Components/ClusterNodes/types' import { ReactComponent as TerminalIcon } from '../../../assets/icons/ic-terminal-fill.svg' @@ -55,42 +48,23 @@ const NodeActionsMenu = ({ nodeData, getNodeListData, addTab }: NodeActionsMenuP const { name, version, kind } = nodeData as Record - const { isSuperAdmin } = useMainContext() - - const isAuthorized = (): boolean => { - if (!isSuperAdmin) { - ToastManager.showToast({ - variant: ToastVariantType.notAuthorized, - description: TOAST_ACCESS_DENIED.SUBTITLE, - }) - return false - } - return true - } - const handleOpenTerminalAction = () => { - if (isAuthorized()) { - const queryParams = new URLSearchParams(location.search) - queryParams.set('node', name) - history.push( - `${location.pathname.split('/').slice(0, -2).join('/')}/${AppDetailsTabs.terminal}/${K8S_EMPTY_GROUP}?${queryParams.toString()}`, - ) - } + const queryParams = new URLSearchParams(location.search) + queryParams.set('node', name) + history.push( + `${location.pathname.split('/').slice(0, -2).join('/')}/${AppDetailsTabs.terminal}/${K8S_EMPTY_GROUP}?${queryParams.toString()}`, + ) } const handleEditYamlAction = () => { - if (isAuthorized()) { - const _url = `${url.split('/').slice(0, -2).join('/')}/node/${K8S_EMPTY_GROUP}/${nodeData.name}?tab=yaml` - addTab({ idPrefix: K8S_EMPTY_GROUP, kind: 'node', name, url: _url }) - .then(() => history.push(_url)) - .catch(noop) - } + const _url = `${url.split('/').slice(0, -2).join('/')}/node/${K8S_EMPTY_GROUP}/${nodeData.name}?tab=yaml` + addTab({ idPrefix: K8S_EMPTY_GROUP, kind: 'node', name, url: _url }) + .then(() => history.push(_url)) + .catch(noop) } const showCordonNodeModal = (): void => { - if (isAuthorized()) { - setShowCordonNodeDialog(true) - } + setShowCordonNodeDialog(true) } const hideCordonNodeModal = (refreshData?: boolean): void => { @@ -101,9 +75,7 @@ const NodeActionsMenu = ({ nodeData, getNodeListData, addTab }: NodeActionsMenuP } const showDrainNodeModal = (): void => { - if (isAuthorized()) { - setShowDrainNodeDialog(true) - } + setShowDrainNodeDialog(true) } const hideDrainNodeModal = (refreshData?: boolean): void => { @@ -114,9 +86,7 @@ const NodeActionsMenu = ({ nodeData, getNodeListData, addTab }: NodeActionsMenuP } const showDeleteNodeModal = (): void => { - if (isAuthorized()) { - setShowDeleteNodeDialog(true) - } + setShowDeleteNodeDialog(true) } const hideDeleteNodeModal = (refreshData?: boolean): void => { @@ -127,9 +97,7 @@ const NodeActionsMenu = ({ nodeData, getNodeListData, addTab }: NodeActionsMenuP } const showEditTaintsModal = (): void => { - if (isAuthorized()) { - setShowEditTaintNodeDialog(true) - } + setShowEditTaintNodeDialog(true) } const hideEditTaintsModal = (refreshData?: boolean): void => { diff --git a/src/components/ResourceBrowser/ResourceList/ResourceList.tsx b/src/components/ResourceBrowser/ResourceList/ResourceList.tsx index c265a2fdc6..0a45cad98d 100644 --- a/src/components/ResourceBrowser/ResourceList/ResourceList.tsx +++ b/src/components/ResourceBrowser/ResourceList/ResourceList.tsx @@ -17,7 +17,6 @@ import { useState, useEffect, useMemo, useRef } from 'react' import { useHistory, useParams, useRouteMatch, useLocation } from 'react-router-dom' import { - getUserRole, BreadCrumb, useBreadcrumb, ErrorScreenManager, @@ -98,11 +97,7 @@ const ResourceList = () => { const [rawGVKLoader, k8SObjectMapRaw] = useAsync(() => getResourceGroupListRaw(clusterId), [clusterId]) - const [loading, data, error] = useAsync(() => - Promise.all([getClusterListMin(), window._env_.K8S_CLIENT ? null : getUserRole()]), - ) - - const [clusterListData = null, userRole = null] = data || [] + const [loading, clusterListData, error] = useAsync(() => getClusterListMin()) const clusterList = clusterListData?.result || null @@ -144,8 +139,6 @@ const ResourceList = () => { [k8SObjectMapRaw], ) - const isSuperAdmin = !!userRole?.result.superAdmin - const isOverviewNodeType = nodeType === SIDEBAR_KEYS.overviewGVK.Kind.toLowerCase() const isMonitoringNodeType = nodeType === SIDEBAR_KEYS.monitoringGVK.Kind.toLowerCase() const isTerminalNodeType = nodeType === AppDetailsTabs.terminal @@ -200,25 +193,19 @@ const ResourceList = () => { }) const initTabsBasedOnRole = (reInit: boolean) => { - /* NOTE: selectedCluster is not in useEffect dep list since it arrives with isSuperAdmin (Promise.all) */ const _tabs = getTabsBasedOnRole({ selectedCluster, namespace, - isSuperAdmin, /* NOTE: if node is available in url but no associated dynamicTab we create a dynamicTab */ dynamicTabData: (node || isUpgradeClusterNodeType) && getDynamicTabData(), isTerminalSelected: isTerminalNodeType, isOverviewSelected: isOverviewNodeType, isMonitoringDashBoardSelected: isMonitoringNodeType, }) - initTabs( - _tabs, - reInit, - !isSuperAdmin ? [getTabId(ResourceBrowserTabsId.terminal, AppDetailsTabs.terminal, '')] : null, - ) + initTabs(_tabs, reInit) } - useEffect(() => initTabsBasedOnRole(false), [isSuperAdmin]) + useEffect(() => initTabsBasedOnRole(false), []) useEffectAfterMount(() => initTabsBasedOnRole(true), [clusterId]) useEffectAfterMount(() => { @@ -413,7 +400,6 @@ const ResourceList = () => { return nodeType.toLowerCase() === SIDEBAR_KEYS.nodeGVK.Kind.toLowerCase() ? ( { } const fixedTabComponents = [ - , + , { getTabById(ResourceBrowserTabsId.k8s_Resources)?.lastSyncMoment?.toString(), refreshData, )} - isSuperAdmin={isSuperAdmin} isOpen={!!getTabById(ResourceBrowserTabsId.k8s_Resources)?.isSelected} showStaleDataWarning={isDataStale} updateK8sResourceTab={getUpdateTabUrlForId(getTabById(ResourceBrowserTabsId.k8s_Resources)?.id)} @@ -458,8 +443,8 @@ const ResourceList = () => { lowercaseKindToResourceGroupMap={lowercaseKindToResourceGroupMap} />, ...(MonitoringDashboard ? [] : []), - ...(isSuperAdmin && getTabById(ResourceBrowserTabsId.terminal)?.isAlive - ? [] + ...(getTabById(ResourceBrowserTabsId.terminal)?.isAlive + ? [] : []), ] diff --git a/src/components/ResourceBrowser/Types.ts b/src/components/ResourceBrowser/Types.ts index e3addd935e..10a87c6329 100644 --- a/src/components/ResourceBrowser/Types.ts +++ b/src/components/ResourceBrowser/Types.ts @@ -94,7 +94,6 @@ export interface ResourceDetailsPropType extends LogSearchTermType { export interface ClusterSelectionType { clusterOptions: ClusterDetail[] - isSuperAdmin: boolean clusterListLoader: boolean initialLoading: boolean refreshData: () => void @@ -221,7 +220,6 @@ export interface K8SResourceTabComponentProps 'setWidgetEventDetails' | 'handleResourceClick' | 'clusterName' | 'lowercaseKindToResourceGroupMap' > { selectedCluster: ClusterOptionType - isSuperAdmin: boolean renderRefreshBar: () => JSX.Element addTab: ReturnType['addTab'] showStaleDataWarning: boolean @@ -230,7 +228,6 @@ export interface K8SResourceTabComponentProps } export interface AdminTerminalProps { - isSuperAdmin: boolean updateTerminalTabUrl: (queryParams: string) => void } @@ -271,7 +268,6 @@ export interface RBSidebarKeysType { export interface GetTabsBasedOnRoleParamsType { selectedCluster: ClusterOptionType namespace: string - isSuperAdmin: boolean dynamicTabData: InitTabType /** * @default false diff --git a/src/components/ResourceBrowser/Utils.tsx b/src/components/ResourceBrowser/Utils.tsx index a65a6b5479..305e620f38 100644 --- a/src/components/ResourceBrowser/Utils.tsx +++ b/src/components/ResourceBrowser/Utils.tsx @@ -289,7 +289,6 @@ export const getURLBasedOnSidebarGVK = (kind: GVKType['Kind'], clusterId: string export const getTabsBasedOnRole = ({ selectedCluster, namespace, - isSuperAdmin, dynamicTabData, isTerminalSelected = false, isOverviewSelected = false, @@ -311,11 +310,7 @@ export const getTabsBasedOnRole = ({ id: ResourceBrowserTabsId.k8s_Resources, name: AppDetailsTabs.k8s_Resources, url: getURLBasedOnSidebarGVK(SIDEBAR_KEYS.nodeGVK.Kind, clusterId, namespace), - isSelected: - (!isSuperAdmin || !isTerminalSelected) && - !dynamicTabData && - !isOverviewSelected && - !isMonitoringDashBoardSelected, + isSelected: !isTerminalSelected && !dynamicTabData && !isOverviewSelected && !isMonitoringDashBoardSelected, type: 'fixed', iconPath: K8ResourceIcon, showNameOnSelect: false, @@ -331,21 +326,17 @@ export const getTabsBasedOnRole = ({ ), ] : []), - ...(isSuperAdmin - ? [ - { - id: ResourceBrowserTabsId.terminal, - name: AppDetailsTabs.terminal, - url: `${URLS.RESOURCE_BROWSER}/${clusterId}/${namespace}/${AppDetailsTabs.terminal}/${K8S_EMPTY_GROUP}`, - isSelected: isTerminalSelected, - type: 'fixed', - iconPath: TerminalIcon, - showNameOnSelect: true, - isAlive: isTerminalSelected, - dynamicTitle: `${AppDetailsTabs.terminal} '${selectedCluster.label}'`, - }, - ] - : []), + { + id: ResourceBrowserTabsId.terminal, + name: AppDetailsTabs.terminal, + url: `${URLS.RESOURCE_BROWSER}/${clusterId}/${namespace}/${AppDetailsTabs.terminal}/${K8S_EMPTY_GROUP}`, + isSelected: isTerminalSelected, + type: 'fixed', + iconPath: TerminalIcon, + showNameOnSelect: true, + isAlive: isTerminalSelected, + dynamicTitle: `${AppDetailsTabs.terminal} '${selectedCluster.label}'`, + }, ...(dynamicTabData ? [dynamicTabData] : []), ] From afc83a878cee8af7460215db5c3b97143795274b Mon Sep 17 00:00:00 2001 From: Amrit Kashyap Borah Date: Mon, 25 Nov 2024 16:07:43 +0530 Subject: [PATCH 07/18] feat: hide node option from sidebar if no permission for it --- package.json | 2 +- src/components/ResourceBrowser/Constants.ts | 3 +- .../ResourceList/BaseResourceList.tsx | 6 +- .../ResourceList/K8SResourceList.tsx | 18 +- .../ResourceList/ResourceList.tsx | 8 +- .../ResourceBrowser/ResourceList/Sidebar.tsx | 41 +- src/components/ResourceBrowser/Utils.tsx | 27 +- .../app/details/appDetails/utils.tsx | 2 + src/components/app/types.ts | 2 + src/components/common/helpers/Helpers.tsx | 6 + yarn.lock | 455 +++++++++--------- 11 files changed, 292 insertions(+), 278 deletions(-) diff --git a/package.json b/package.json index 46190716ea..773d0138fe 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "private": true, "homepage": "/dashboard", "dependencies": { - "@devtron-labs/devtron-fe-common-lib": "1.1.3", + "@devtron-labs/devtron-fe-common-lib": "1.1.3-beta-2", "@esbuild-plugins/node-globals-polyfill": "0.2.3", "@rjsf/core": "^5.13.3", "@rjsf/utils": "^5.13.3", diff --git a/src/components/ResourceBrowser/Constants.ts b/src/components/ResourceBrowser/Constants.ts index 5a343b5b93..a22b078ad4 100644 --- a/src/components/ResourceBrowser/Constants.ts +++ b/src/components/ResourceBrowser/Constants.ts @@ -114,6 +114,7 @@ export const NAMESPACE_NOT_APPLICABLE_TEXT = 'Namespace is not applicable for th export const CLUSTER_NOT_REACHABLE = 'Cluster is not reachable' export const ORDERED_AGGREGATORS: AggregationKeysType[] = [ + AggregationKeys.Nodes, AggregationKeys.Events, AggregationKeys.Namespaces, AggregationKeys.Workloads, @@ -222,7 +223,7 @@ export const UPGRADE_CLUSTER_CONSTANTS = { export const JUMP_TO_KIND_SHORT_NAMES: Record = { events: null, - nodes: ['no'], // NOTE: hardcoding cuz backend doesn't send nodeGVK + nodes: null, namespaces: null, } diff --git a/src/components/ResourceBrowser/ResourceList/BaseResourceList.tsx b/src/components/ResourceBrowser/ResourceList/BaseResourceList.tsx index 027d47ff21..5d1300beff 100644 --- a/src/components/ResourceBrowser/ResourceList/BaseResourceList.tsx +++ b/src/components/ResourceBrowser/ResourceList/BaseResourceList.tsx @@ -115,7 +115,7 @@ const BaseResourceListContent = ({ const { searchParams } = useSearchString() - const isNodeListing = selectedResource.gvk.Kind === SIDEBAR_KEYS.nodeGVK.Kind + const isNodeListing = selectedResource?.gvk.Kind === SIDEBAR_KEYS.nodeGVK.Kind const { selectedIdentifiers: bulkSelectionState, @@ -579,7 +579,7 @@ const BaseResourceListContent = ({ } const renderContent = () => { - if (!resourceListError && (isLoading || !resourceList || !filteredResourceList)) { + if (!resourceListError && (isLoading || !resourceList || !filteredResourceList || !selectedResource)) { return } @@ -690,7 +690,7 @@ const BaseResourceListContent = ({ /> ) : ( - abortPreviousRequests( - async () => - getResourceData({ selectedResource, selectedNamespace, clusterId, filters, abortControllerRef }), - abortControllerRef, - ), + abortPreviousRequests(async () => { + if (selectedResource) { + return getResourceData({ + selectedResource, + selectedNamespace, + clusterId, + filters, + abortControllerRef, + }) + } + + return null + }, abortControllerRef), [selectedResource, clusterId, selectedNamespace, filters], ) diff --git a/src/components/ResourceBrowser/ResourceList/ResourceList.tsx b/src/components/ResourceBrowser/ResourceList/ResourceList.tsx index 0a45cad98d..622ac3174a 100644 --- a/src/components/ResourceBrowser/ResourceList/ResourceList.tsx +++ b/src/components/ResourceBrowser/ResourceList/ResourceList.tsx @@ -88,11 +88,7 @@ const ResourceList = () => { const [logSearchTerms, setLogSearchTerms] = useState>() const [widgetEventDetails, setWidgetEventDetails] = useState(null) const [isDataStale, setIsDataStale] = useState(false) - const [selectedResource, setSelectedResource] = useState({ - gvk: SIDEBAR_KEYS.nodeGVK, - namespaced: false, - isGrouped: false, - }) + const [selectedResource, setSelectedResource] = useState(null) const { targetK8sVersion } = useUrlFilters({ parseSearchParams }) const [rawGVKLoader, k8SObjectMapRaw] = useAsync(() => getResourceGroupListRaw(clusterId), [clusterId]) @@ -348,7 +344,7 @@ const ResourceList = () => { const _group: string = (shouldOverrideSelectedResourceKind ? lowercaseKindToResourceGroupMap[lowercaseKindFromResource]?.gvk?.Group?.toLowerCase() - : selectedResource?.gvk.Group.toLowerCase()) || K8S_EMPTY_GROUP + : selectedResource.gvk.Group.toLowerCase()) || K8S_EMPTY_GROUP const _namespace = currentNamespace ?? ALL_NAMESPACE_OPTION.value let resourceParam: string diff --git a/src/components/ResourceBrowser/ResourceList/Sidebar.tsx b/src/components/ResourceBrowser/ResourceList/Sidebar.tsx index ada9246fd1..5c2992c514 100644 --- a/src/components/ResourceBrowser/ResourceList/Sidebar.tsx +++ b/src/components/ResourceBrowser/ResourceList/Sidebar.tsx @@ -151,15 +151,13 @@ const Sidebar = ({ useEffect(() => { /* NOTE: this effect accommodates for user navigating through browser history (push) */ - if (!isOpen || nodeType === selectedResource.gvk.Kind.toLowerCase()) { + if (!isOpen || nodeType === selectedResource?.gvk.Kind.toLowerCase() || !k8sObjectOptionsList?.length) { return } /* NOTE: match will never be null; due to node fallback */ const match = k8sObjectOptionsList.find((option) => option.dataset.kind.toLowerCase() === nodeType) || - k8sObjectOptionsList.find( - (option) => option.dataset.kind.toLowerCase() === SIDEBAR_KEYS.nodeGVK.Kind.toLowerCase(), - ) + k8sObjectOptionsList[0] /* NOTE: if nodeType doesn't match the selectedResource kind, set it accordingly */ selectNode( { @@ -169,9 +167,9 @@ const Sidebar = ({ }, match.groupName, /* NOTE: if we push here the history will be lost */ - false, + !selectedResource, ) - }, [nodeType]) + }, [nodeType, k8sObjectOptionsList]) const selectedChildRef: React.Ref = (node) => { /** @@ -342,17 +340,19 @@ const Sidebar = ({
- - {list?.size && list.get(AggregationKeys.Events) && ( + {!!list?.size && !!list.get(AggregationKeys.Nodes) && ( + + )} + {!!list?.size && !!list.get(AggregationKeys.Events) && ( )} - {list?.size && list.get(AggregationKeys.Namespaces) && ( + {!!list?.size && !!list.get(AggregationKeys.Namespaces) && ( )}
- {list?.size && + {!!list?.size && [...list.values()].map((k8sObject) => k8sObject.name === AggregationKeys.Events || - k8sObject.name === AggregationKeys.Namespaces ? null : ( + k8sObject.name === AggregationKeys.Namespaces || + k8sObject.name === AggregationKeys.Nodes ? null : (