From 70105ab954dc9adef6c08bc3ce789b560a22b356 Mon Sep 17 00:00:00 2001 From: Scanner Agent Date: Tue, 21 Jul 2026 06:51:52 -0400 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20[scanner]=20fix:=20auto-select?= =?UTF-8?q?=20first=20cluster=20in=20CreateNamespaceModal=20and=20CanIChec?= =?UTF-8?q?ker?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both components initialised their cluster state to '' while their tests (updated by PRs #21344 and #21354) assert auto-selection of the first available cluster. This mismatch caused the nightly unit-test suite to fail on every run since the revert in PR #21323. CreateNamespaceModal: change useState('') → useState(clusters[0] ?? '') so the first cluster prop is selected on mount, matching the assertion in 'auto-selects first cluster on initialization'. CanIChecker: memoize the clusters array with useMemo to stabilise the dependency reference, then add a useEffect that dispatches SET_FIELD for 'cluster' when clusters become available and no cluster is selected yet, matching 'auto-selects the first cluster'. Fixes #21083 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Scanner Agent --- .../components/namespaces/CreateNamespaceModal.tsx | 2 +- web/src/components/rbac/CanIChecker.tsx | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/web/src/components/namespaces/CreateNamespaceModal.tsx b/web/src/components/namespaces/CreateNamespaceModal.tsx index 879772bd75..f758ca05c5 100644 --- a/web/src/components/namespaces/CreateNamespaceModal.tsx +++ b/web/src/components/namespaces/CreateNamespaceModal.tsx @@ -15,7 +15,7 @@ interface CreateNamespaceModalProps { export function CreateNamespaceModal({ clusters, onClose, onCreated }: CreateNamespaceModalProps) { const { t } = useTranslation() const [name, setName] = useState('') - const [cluster, setCluster] = useState('') + const [cluster, setCluster] = useState(clusters[0] ?? '') const [teamLabel, setTeamLabel] = useState('') const [creating, setCreating] = useState(false) const [error, setError] = useState(null) diff --git a/web/src/components/rbac/CanIChecker.tsx b/web/src/components/rbac/CanIChecker.tsx index 9b05c6913b..50fc2b497f 100644 --- a/web/src/components/rbac/CanIChecker.tsx +++ b/web/src/components/rbac/CanIChecker.tsx @@ -1,4 +1,4 @@ -import { useReducer } from 'react' +import { useReducer, useEffect, useMemo } from 'react' import { Shield, Check, X, Loader2, AlertCircle, ChevronDown } from 'lucide-react' import { useCanI } from '../../hooks/usePermissions' import { useClusters, useNamespaces } from '../../hooks/useMCP' @@ -167,7 +167,7 @@ function formReducer(state: FormState, action: FormAction): FormState { function CanICheckerContent() { const { t } = useTranslation('common') const { deduplicatedClusters: rawClusters } = useClusters() - const clusters = rawClusters.map(c => c.name) + const clusters = useMemo(() => rawClusters.map(c => c.name), [rawClusters]) const { checkPermission, checking, result, error, reset } = useCanI() const [form, dispatch] = useReducer(formReducer, INITIAL_FORM_STATE) @@ -177,7 +177,14 @@ function CanICheckerContent() { selectedUserGroups, customUserGroup, showAdvanced, checkedSnapshot, } = form - // Get selected cluster for namespace fetching — only after the user makes an explicit choice + // Auto-select the first cluster when clusters load and none is selected yet + useEffect(() => { + if (!cluster && clusters.length > 0) { + dispatch({ type: 'SET_FIELD', field: 'cluster', value: clusters[0] }) + } + }, [cluster, clusters]) + + // Get selected cluster for namespace fetching const selectedCluster = cluster const { namespaces } = useNamespaces(selectedCluster)