fix: repair brace mismatch in DataContext and replace PV Pool column with Dataset

- TnsCsiDataContext: pool stats fetch was outside the outer try block due
  to a brace mismatch introduced when adding TrueNAS API integration;
  this caused the entire fetchAsync function to throw a syntax-level
  error, breaking the OverviewPage
- StorageClassColumns (PV): replace non-populating Pool column with
  Dataset column (tns-csi driver writes datasetName, not pool, into
  PV volumeAttributes)

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
This commit is contained in:
2026-02-19 06:48:01 -05:00
parent 96ea9e1207
commit e082c60677
2 changed files with 29 additions and 29 deletions
+23 -23
View File
@@ -168,32 +168,32 @@ export function TnsCsiDataProvider({ children }: { children: React.ReactNode })
setVolumeSnapshots([]);
}
}
// TrueNAS pool stats (only when API key is configured)
const config = getTnsCsiConfig();
if (config.truenasApiKey.trim()) {
// Determine server: explicit override → first SC server param → fail gracefully
const server = config.truenasServerOverride.trim();
if (server) {
try {
const pools = await fetchTruenasPoolStats(server, config.truenasApiKey.trim());
if (!cancelled) {
setPoolStats(pools);
setPoolStatsError(null);
}
} catch (err: unknown) {
if (!cancelled) {
setPoolStats([]);
setPoolStatsError(err instanceof Error ? err.message : String(err));
// TrueNAS pool stats (only when API key is configured)
const config = getTnsCsiConfig();
if (config.truenasApiKey.trim()) {
const server = config.truenasServerOverride.trim();
if (server) {
try {
const pools = await fetchTruenasPoolStats(server, config.truenasApiKey.trim());
if (!cancelled) {
setPoolStats(pools);
setPoolStatsError(null);
}
} catch (err: unknown) {
if (!cancelled) {
setPoolStats([]);
setPoolStatsError(err instanceof Error ? err.message : String(err));
}
}
}
} else {
if (!cancelled) {
setPoolStats([]);
setPoolStatsError(null);
}
}
} else {
if (!cancelled) {
setPoolStats([]);
setPoolStatsError(null);
}
}
} catch (err: unknown) {
} catch (err: unknown) {
if (!cancelled) {
setAsyncError(err instanceof Error ? err.message : String(err));
}
@@ -2,7 +2,7 @@
* StorageClassColumns — registerResourceTableColumnsProcessor for StorageClass and PV tables.
*
* Adds Protocol/Pool/Server columns to the native /storage-classes table and
* Protocol/Volume Handle columns to the native /persistent-volumes table.
* Protocol/Dataset columns to the native /persistent-volumes table.
*
* Items in column processors are KubeObject class instances from Headlamp.
* Raw Kubernetes JSON fields (parameters, spec, status) must be accessed
@@ -131,18 +131,18 @@ export function buildPVColumns() {
},
},
{
label: 'Volume Handle',
label: 'Dataset',
getValue: (pv: unknown): string | null => {
const driver = getField(pv, 'spec', 'csi', 'driver') as string | undefined;
if (driver !== TNS_CSI_PROVISIONER) return null;
const h = getField(pv, 'spec', 'csi', 'volumeHandle');
return typeof h === 'string' ? h : null;
const d = getField(pv, 'spec', 'csi', 'volumeAttributes', 'datasetName');
return typeof d === 'string' ? d : null;
},
render: (pv: unknown) => {
const driver = getField(pv, 'spec', 'csi', 'driver') as string | undefined;
if (driver !== TNS_CSI_PROVISIONER) return <span></span>;
const handle = getField(pv, 'spec', 'csi', 'volumeHandle') as string | undefined;
return <span style={{ fontFamily: 'monospace', fontSize: '0.85em' }}>{handle ?? '—'}</span>;
const dataset = getField(pv, 'spec', 'csi', 'volumeAttributes', 'datasetName') as string | undefined;
return <span style={{ fontFamily: 'monospace', fontSize: '0.85em' }}>{dataset ?? '—'}</span>;
},
},
];