mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-04-01 05:37:14 +00:00
Compare commits
3 Commits
DEVREL-98-
...
PRWLR-7732
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fc1337a4e6 | ||
|
|
71b5f3714c | ||
|
|
ae697d838c |
@@ -10,6 +10,7 @@ All notable changes to the **Prowler UI** are documented in this file.
|
||||
- Amazon AWS S3 integration [(#8391)](https://github.com/prowler-cloud/prowler/pull/8391)
|
||||
- Github provider support [(#8405)](https://github.com/prowler-cloud/prowler/pull/8405)
|
||||
- XML validation for SAML metadata in the UI [(#8429)](https://github.com/prowler-cloud/prowler/pull/8429)
|
||||
- Mutelist menu item under Configuration [(#8440)](https://github.com/prowler-cloud/prowler/pull/8440)
|
||||
|
||||
### 🔄 Changed
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Spacer } from "@nextui-org/react";
|
||||
import { redirect } from "next/navigation";
|
||||
import { Suspense } from "react";
|
||||
|
||||
import { getProviders } from "@/actions/providers";
|
||||
@@ -23,19 +24,27 @@ export default async function Providers({
|
||||
}) {
|
||||
const searchParamsKey = JSON.stringify(searchParams || {});
|
||||
|
||||
const providersData = await getProviders({});
|
||||
const hasProviders = providersData?.data && providersData.data.length > 0;
|
||||
|
||||
// If modal=mutelist is present but no providers, redirect
|
||||
if (searchParams.modal === "mutelist" && !hasProviders) {
|
||||
redirect("/providers");
|
||||
}
|
||||
|
||||
return (
|
||||
<ContentLayout title="Cloud Providers" icon="fluent:cloud-sync-24-regular">
|
||||
<FilterControls search customFilters={filterProviders || []} />
|
||||
<Spacer y={8} />
|
||||
<div className="flex items-center gap-4 md:justify-end">
|
||||
<ManageGroupsButton />
|
||||
<MutedFindingsConfigButton isDisabled={!hasProviders} />
|
||||
<AddProviderButton />
|
||||
</div>
|
||||
<Suspense
|
||||
key={searchParamsKey}
|
||||
fallback={
|
||||
<>
|
||||
<div className="flex items-center gap-4 md:justify-end">
|
||||
<ManageGroupsButton />
|
||||
<MutedFindingsConfigButton isDisabled={true} />
|
||||
<AddProviderButton />
|
||||
</div>
|
||||
<Spacer y={8} />
|
||||
<div className="grid grid-cols-12 gap-4">
|
||||
<div className="col-span-12">
|
||||
@@ -76,8 +85,6 @@ const ProvidersContent = async ({
|
||||
pageSize,
|
||||
});
|
||||
|
||||
const hasProviders = providersData?.data && providersData.data.length > 0;
|
||||
|
||||
const providerGroupDict =
|
||||
providersData?.included
|
||||
?.filter((item: any) => item.type === "provider-groups")
|
||||
@@ -98,11 +105,6 @@ const ProvidersContent = async ({
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="flex items-center gap-4 md:justify-end">
|
||||
<ManageGroupsButton />
|
||||
<MutedFindingsConfigButton isDisabled={!hasProviders} />
|
||||
<AddProviderButton />
|
||||
</div>
|
||||
<Spacer y={8} />
|
||||
|
||||
<div className="grid grid-cols-12 gap-4">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { Textarea } from "@nextui-org/react";
|
||||
import { Dispatch, SetStateAction, useEffect, useState } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useFormState } from "react-dom";
|
||||
|
||||
import {
|
||||
@@ -23,11 +23,11 @@ import {
|
||||
} from "@/types/processors";
|
||||
|
||||
interface MutedFindingsConfigFormProps {
|
||||
setIsOpen: Dispatch<SetStateAction<boolean>>;
|
||||
onCancel: () => void;
|
||||
}
|
||||
|
||||
export const MutedFindingsConfigForm = ({
|
||||
setIsOpen,
|
||||
onCancel,
|
||||
}: MutedFindingsConfigFormProps) => {
|
||||
const [config, setConfig] = useState<ProcessorData | null>(null);
|
||||
const [configText, setConfigText] = useState("");
|
||||
@@ -64,7 +64,7 @@ export const MutedFindingsConfigForm = ({
|
||||
title: "Configuration saved successfully",
|
||||
description: state.success,
|
||||
});
|
||||
setIsOpen(false);
|
||||
onCancel();
|
||||
} else if (state?.errors?.general) {
|
||||
toast({
|
||||
variant: "destructive",
|
||||
@@ -75,7 +75,7 @@ export const MutedFindingsConfigForm = ({
|
||||
// Reset typing state when there are new server errors
|
||||
setHasUserStartedTyping(false);
|
||||
}
|
||||
}, [state, toast, setIsOpen]);
|
||||
}, [state, toast, onCancel]);
|
||||
|
||||
const handleConfigChange = (value: string) => {
|
||||
setConfigText(value);
|
||||
@@ -100,7 +100,7 @@ export const MutedFindingsConfigForm = ({
|
||||
title: "Configuration deleted successfully",
|
||||
description: result.success,
|
||||
});
|
||||
setIsOpen(false);
|
||||
onCancel();
|
||||
} else if (result?.errors?.general) {
|
||||
toast({
|
||||
variant: "destructive",
|
||||
@@ -232,7 +232,8 @@ export const MutedFindingsConfigForm = ({
|
||||
|
||||
<div className="flex flex-col space-y-4">
|
||||
<FormButtons
|
||||
setIsOpen={setIsOpen}
|
||||
setIsOpen={() => {}}
|
||||
onCancel={onCancel}
|
||||
submitText={config ? "Update" : "Save"}
|
||||
isDisabled={!yamlValidation.isValid || !configText.trim()}
|
||||
/>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { SettingsIcon } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import { useSearchParams } from "next/navigation";
|
||||
|
||||
import { CustomAlertModal, CustomButton } from "@/components/ui/custom";
|
||||
|
||||
@@ -14,23 +14,33 @@ interface MutedFindingsConfigButtonProps {
|
||||
export const MutedFindingsConfigButton = ({
|
||||
isDisabled = false,
|
||||
}: MutedFindingsConfigButtonProps) => {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const searchParams = useSearchParams();
|
||||
|
||||
const isOpen = searchParams.get("modal") === "mutelist";
|
||||
|
||||
const handleOpenModal = () => {
|
||||
if (!isDisabled) {
|
||||
setIsOpen(true);
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
params.set("modal", "mutelist");
|
||||
window.history.pushState({}, "", `?${params.toString()}`);
|
||||
}
|
||||
};
|
||||
|
||||
const handleModalClose = () => {
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
params.delete("modal");
|
||||
window.history.pushState({}, "", `?${params.toString()}`);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<CustomAlertModal
|
||||
isOpen={isOpen}
|
||||
onOpenChange={setIsOpen}
|
||||
onOpenChange={handleModalClose}
|
||||
title="Configure Mutelist"
|
||||
size="3xl"
|
||||
>
|
||||
<MutedFindingsConfigForm setIsOpen={setIsOpen} />
|
||||
<MutedFindingsConfigForm onCancel={handleModalClose} />
|
||||
</CustomAlertModal>
|
||||
|
||||
<CustomButton
|
||||
|
||||
@@ -30,6 +30,7 @@ import {
|
||||
KubernetesIcon,
|
||||
LighthouseIcon,
|
||||
M365Icon,
|
||||
MutedIcon,
|
||||
SupportIcon,
|
||||
} from "@/components/icons/Icons";
|
||||
import { GroupProps } from "@/types";
|
||||
@@ -151,6 +152,11 @@ export const getMenuList = (pathname: string): GroupProps[] => {
|
||||
{ href: "/integrations", label: "Integrations", icon: Puzzle },
|
||||
{ href: "/roles", label: "Roles", icon: UserCog },
|
||||
{ href: "/lighthouse/config", label: "Lighthouse AI", icon: Cog },
|
||||
{
|
||||
href: "/providers?modal=mutelist",
|
||||
label: "Mutelist",
|
||||
icon: MutedIcon,
|
||||
},
|
||||
],
|
||||
defaultOpen: true,
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user