fix: hardcoded color, missing async cancellation, a11y gaps, any types

SealingKeysView: replace hardcoded #666 with var(--mui-palette-text-secondary)
SealedSecretDetail:
- Add cancelled flag to canDecryptSecrets useEffect
- Add aria-label to close button, decrypt buttons, delete dialog
- Replace any types in SimpleTable column getters with { key, value }

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
DevContainer User
2026-03-04 12:40:46 +00:00
parent 761f7cf242
commit 479d0c315e
2 changed files with 16 additions and 10 deletions
+15 -9
View File
@@ -69,9 +69,15 @@ export function SealedSecretDetail() {
// Check if user can decrypt secrets (requires get permission on Secrets) // Check if user can decrypt secrets (requires get permission on Secrets)
React.useEffect(() => { React.useEffect(() => {
let cancelled = false;
if (namespace) { if (namespace) {
canDecryptSecrets(namespace).then(setCanDecrypt); canDecryptSecrets(namespace).then((result) => {
if (!cancelled) setCanDecrypt(result);
});
} }
return () => {
cancelled = true;
};
}, [namespace]); }, [namespace]);
// Wait for required params before rendering // Wait for required params before rendering
@@ -154,7 +160,7 @@ export function SealedSecretDetail() {
title={ title={
<Box display="flex" alignItems="center" justifyContent="space-between"> <Box display="flex" alignItems="center" justifyContent="space-between">
<Box display="flex" alignItems="center" gap={1}> <Box display="flex" alignItems="center" gap={1}>
<IconButton onClick={handleClose} edge="start" size="small"> <IconButton onClick={handleClose} edge="start" size="small" aria-label="Close detail panel">
<Icon icon="mdi:close" /> <Icon icon="mdi:close" />
</IconButton> </IconButton>
<span>{sealedSecret.metadata.name}</span> <span>{sealedSecret.metadata.name}</span>
@@ -233,24 +239,24 @@ export function SealedSecretDetail() {
columns={[ columns={[
{ {
label: 'Key', label: 'Key',
getter: (row: any) => row.key, getter: (row: { key: string; value: string }) => row.key,
}, },
{ {
label: 'Encrypted Value', label: 'Encrypted Value',
getter: (row: any) => { getter: (row: { key: string; value: string }) => {
const val = row.value; const val = row.value;
return val.length > 40 ? val.substring(0, 40) + '...' : val; return val.length > 40 ? val.substring(0, 40) + '...' : val;
}, },
}, },
{ {
label: 'Actions', label: 'Actions',
getter: (row: any) => getter: (row: { key: string; value: string }) =>
canDecrypt ? ( canDecrypt ? (
<Button size="small" onClick={() => setDecryptKey(row.key)}> <Button size="small" onClick={() => setDecryptKey(row.key)} aria-label={`Decrypt ${row.key}`}>
Decrypt Decrypt
</Button> </Button>
) : ( ) : (
<Button size="small" disabled title="No permission to access Secrets"> <Button size="small" disabled title="No permission to access Secrets" aria-label={`Decrypt ${row.key} (no permission)`}>
Decrypt Decrypt
</Button> </Button>
), ),
@@ -331,8 +337,8 @@ export function SealedSecretDetail() {
/> />
)} )}
<Dialog open={deleteDialogOpen} onClose={() => setDeleteDialogOpen(false)}> <Dialog open={deleteDialogOpen} onClose={() => setDeleteDialogOpen(false)} aria-labelledby="delete-dialog-title">
<DialogTitle>Delete SealedSecret?</DialogTitle> <DialogTitle id="delete-dialog-title">Delete SealedSecret?</DialogTitle>
<DialogContent> <DialogContent>
Are you sure you want to delete the SealedSecret <strong>{name}</strong>? This will also Are you sure you want to delete the SealedSecret <strong>{name}</strong>? This will also
delete the resulting Kubernetes Secret. delete the resulting Kubernetes Secret.
+1 -1
View File
@@ -189,7 +189,7 @@ export function SealingKeysView() {
return ( return (
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}> <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
<span>{expiryDate}</span> <span>{expiryDate}</span>
<span style={{ color: '#666', fontSize: '0.9em' }}> <span style={{ color: 'var(--mui-palette-text-secondary, #666)', fontSize: '0.9em' }}>
({certInfo.daysUntilExpiry} days) ({certInfo.daysUntilExpiry} days)
</span> </span>
</Box> </Box>