feat: resource details added to findigns and resource view (#9515)

This commit is contained in:
Alejandro Bailo
2025-12-12 13:12:17 +01:00
committed by GitHub
parent eefe045c18
commit 0495267351
6 changed files with 81 additions and 0 deletions

View File

@@ -2,6 +2,18 @@
All notable changes to the **Prowler UI** are documented in this file.
## [1.16.0] (Prowler Unreleased)
### 🚀 Added
- More extensive resource details (partition, details and metadata) within Findings detail and Resources detail view [(#9515)](https://github.com/prowler-cloud/prowler/pull/9515)
### 🔄 Changed
### 🐞 Fixed
---
## [1.15.0] (Prowler v5.15.0)
### 🚀 Added

View File

@@ -115,6 +115,9 @@ const SSRDataTable = async ({
"inserted_at",
"updated_at",
"uid",
"partition",
"details",
"metadata",
],
});

View File

@@ -307,6 +307,15 @@ export const FindingDetail = ({
<InfoField label="Region">{renderValue(resource.region)}</InfoField>
</div>
<div className="grid grid-cols-1 gap-4 md:grid-cols-2">
<InfoField label="Partition">
{renderValue(resource.partition)}
</InfoField>
<InfoField label="Details">
{renderValue(resource.details)}
</InfoField>
</div>
{resource.tags && Object.entries(resource.tags).length > 0 && (
<div className="flex flex-col gap-4">
<h4 className="text-sm font-bold text-gray-500 dark:text-gray-400">

View File

@@ -51,6 +51,27 @@ const renderValue = (value: string | null | undefined) => {
return value && value.trim() !== "" ? value : "-";
};
const parseMetadata = (
metadata: Record<string, unknown> | string | null | undefined,
): Record<string, unknown> | null => {
if (!metadata) return null;
if (typeof metadata === "string") {
try {
const parsed = JSON.parse(metadata);
return typeof parsed === "object" && parsed !== null ? parsed : null;
} catch {
return null;
}
}
if (typeof metadata === "object" && metadata !== null) {
return metadata as Record<string, unknown>;
}
return null;
};
const buildCustomBreadcrumbs = (
_resourceName: string,
findingTitle?: string,
@@ -287,6 +308,14 @@ export const ResourceDetail = ({
{renderValue(attributes.region)}
</InfoField>
</div>
<div className="grid grid-cols-1 gap-4 md:grid-cols-2">
<InfoField label="Partition">
{renderValue(attributes.partition)}
</InfoField>
<InfoField label="Details">
{renderValue(attributes.details)}
</InfoField>
</div>
<div className="grid grid-cols-1 gap-4 md:grid-cols-2">
<InfoField label="Created At">
<DateWithTime inline dateTime={attributes.inserted_at} />
@@ -296,6 +325,29 @@ export const ResourceDetail = ({
</InfoField>
</div>
{(() => {
const parsedMetadata = parseMetadata(attributes.metadata);
return parsedMetadata &&
Object.entries(parsedMetadata).length > 0 ? (
<InfoField label="Metadata" variant="simple">
<div className="border-border-neutral-tertiary bg-bg-neutral-tertiary relative w-full rounded-lg border">
<Snippet
className="absolute top-2 right-2 z-10 bg-transparent"
classNames={{
base: "bg-transparent p-0 min-w-0",
pre: "hidden",
}}
>
{JSON.stringify(parsedMetadata, null, 2)}
</Snippet>
<pre className="minimal-scrollbar mr-10 max-h-[100px] overflow-auto p-3 text-xs break-words whitespace-pre-wrap">
{JSON.stringify(parsedMetadata, null, 2)}
</pre>
</div>
</InfoField>
) : null;
})()}
{resourceTags && Object.entries(resourceTags).length > 0 ? (
<div className="flex flex-col gap-4">
<h4 className="text-sm font-bold text-gray-500 dark:text-gray-400">

View File

@@ -573,6 +573,8 @@ export interface FindingProps {
type: string;
inserted_at: string;
updated_at: string;
details: string | null;
partition: string | null;
};
relationships: {
provider: {

View File

@@ -11,6 +11,9 @@ export interface ResourceProps {
tags: Record<string, string>;
type: string;
failed_findings_count: number;
details: string | null;
partition: string | null;
metadata: Record<string, unknown> | null;
};
relationships: {
provider: {