feat: add per-namespace detail pages with dynamic sidebar sub-items
Add drill-down namespace views under the Polaris sidebar entry. Each namespace gets a sidebar sub-item registered dynamically from audit data, linking to /polaris/:namespace with a score summary and per-resource table. Introduces a shared PolarisDataContext so the sidebar registrar and view components share a single data fetch. Also updates the Artifact Hub repository ID. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
import React from 'react';
|
||||
import { AuditData, getRefreshInterval, usePolarisData } from './polaris';
|
||||
|
||||
interface PolarisDataContextValue {
|
||||
data: AuditData | null;
|
||||
loading: boolean;
|
||||
error: string | null;
|
||||
}
|
||||
|
||||
const PolarisDataContext = React.createContext<PolarisDataContextValue | null>(null);
|
||||
|
||||
export function PolarisDataProvider(props: { children: React.ReactNode }) {
|
||||
const interval = getRefreshInterval();
|
||||
const state = usePolarisData(interval);
|
||||
|
||||
return (
|
||||
<PolarisDataContext.Provider value={state}>{props.children}</PolarisDataContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export function usePolarisDataContext(): PolarisDataContextValue {
|
||||
const ctx = React.useContext(PolarisDataContext);
|
||||
if (ctx === null) {
|
||||
throw new Error('usePolarisDataContext must be used within a PolarisDataProvider');
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
+22
-2
@@ -77,9 +77,9 @@ function countResultSet(rs: ResultSet, counts: ResultCounts): void {
|
||||
}
|
||||
}
|
||||
|
||||
export function countResults(data: AuditData): ResultCounts {
|
||||
function countResultItems(results: Result[]): ResultCounts {
|
||||
const counts: ResultCounts = { total: 0, pass: 0, warning: 0, danger: 0 };
|
||||
for (const result of data.Results) {
|
||||
for (const result of results) {
|
||||
countResultSet(result.Results, counts);
|
||||
if (result.PodResult) {
|
||||
countResultSet(result.PodResult.Results, counts);
|
||||
@@ -91,6 +91,26 @@ export function countResults(data: AuditData): ResultCounts {
|
||||
return counts;
|
||||
}
|
||||
|
||||
export function countResults(data: AuditData): ResultCounts {
|
||||
return countResultItems(data.Results);
|
||||
}
|
||||
|
||||
export function countResultsForItems(results: Result[]): ResultCounts {
|
||||
return countResultItems(results);
|
||||
}
|
||||
|
||||
export function getNamespaces(data: AuditData): string[] {
|
||||
const namespaces = new Set<string>();
|
||||
for (const result of data.Results) {
|
||||
namespaces.add(result.Namespace);
|
||||
}
|
||||
return Array.from(namespaces).sort();
|
||||
}
|
||||
|
||||
export function filterResultsByNamespace(data: AuditData, namespace: string): Result[] {
|
||||
return data.Results.filter(r => r.Namespace === namespace);
|
||||
}
|
||||
|
||||
// --- Settings ---
|
||||
|
||||
export const INTERVAL_OPTIONS = [
|
||||
|
||||
Reference in New Issue
Block a user