mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-23 20:42:02 +00:00
feat: GET and POST provider are working as expected and the error is shown correctly
This commit is contained in:
@@ -13,8 +13,8 @@ export const getProvider = async () => {
|
||||
"X-Tenant-ID": `${process.env.HEADER_TENANT_ID}`,
|
||||
},
|
||||
});
|
||||
|
||||
const data = await providers.json();
|
||||
revalidatePath("/providers")
|
||||
return parseStringify(data);
|
||||
} catch (error) {
|
||||
return undefined;
|
||||
@@ -47,10 +47,8 @@ export const addProvider = async (formData: FormData) => {
|
||||
}),
|
||||
});
|
||||
const data = await response.json();
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.message || "Request error");
|
||||
}
|
||||
revalidatePath("/providers")
|
||||
return parseStringify(data);
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
return {
|
||||
@@ -58,7 +56,6 @@ export const addProvider = async (formData: FormData) => {
|
||||
}
|
||||
}
|
||||
revalidatePath("/providers")
|
||||
|
||||
};
|
||||
|
||||
export const deleteProvider = async (formData: FormData) => {
|
||||
@@ -73,15 +70,12 @@ export const deleteProvider = async (formData: FormData) => {
|
||||
"X-Tenant-ID": `${process.env.HEADER_TENANT_ID}`,
|
||||
},
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
return {
|
||||
error: getErrorMessage(error),
|
||||
}
|
||||
}
|
||||
revalidatePath("/providers")
|
||||
|
||||
};
|
||||
|
||||
export const getErrorMessage = (error: unknown): string => {
|
||||
|
||||
@@ -304,6 +304,30 @@ export const WifiPendingIcon: React.FC<IconSvgProps> = ({
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const DeleteIcon: React.FC<IconSvgProps> = ({
|
||||
size = 24,
|
||||
width,
|
||||
height,
|
||||
...props
|
||||
}) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
aria-hidden="true"
|
||||
fill="none"
|
||||
focusable="false"
|
||||
height={size || height}
|
||||
role="presentation"
|
||||
viewBox="0 0 24 24"
|
||||
width={size || width}
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M10 5h4a2 2 0 1 0-4 0M8.5 5a3.5 3.5 0 1 1 7 0h5.75a.75.75 0 0 1 0 1.5h-1.32l-1.17 12.111A3.75 3.75 0 0 1 15.026 22H8.974a3.75 3.75 0 0 1-3.733-3.389L4.07 6.5H2.75a.75.75 0 0 1 0-1.5zm2 4.75a.75.75 0 0 0-1.5 0v7.5a.75.75 0 0 0 1.5 0zM14.25 9a.75.75 0 0 1 .75.75v7.5a.75.75 0 0 1-1.5 0v-7.5a.75.75 0 0 1 .75-.75m-7.516 9.467a2.25 2.25 0 0 0 2.24 2.033h6.052a2.25 2.25 0 0 0 2.24-2.033L18.424 6.5H5.576z"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const RocketIcon: React.FC<IconSvgProps> = ({
|
||||
size = 24,
|
||||
width,
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
export * from "./providers/AddProvider";
|
||||
export * from "./providers/ButtonAddProvider";
|
||||
export * from "./providers/ButtonDeleteProvider";
|
||||
export * from "./providers/DateWithTime";
|
||||
export * from "./providers/ProviderInfo";
|
||||
export * from "./providers/ScanStatus";
|
||||
|
||||
@@ -2,34 +2,35 @@
|
||||
|
||||
import { addProvider } from "@/actions";
|
||||
import { useRef } from "react";
|
||||
import { useToast } from "../ui/toast";
|
||||
import { ButtonAddProvider } from "./ButtonAddProvider";
|
||||
import { toast, useToast } from "../ui/toast";
|
||||
import { ToastAction } from "@radix-ui/react-toast";
|
||||
|
||||
export const AddProvider = () => {
|
||||
const ref = useRef<HTMLFormElement>(null)
|
||||
const { toast } = useToast()
|
||||
|
||||
async function clientAction(formData:FormData) {
|
||||
// reset the form
|
||||
ref.current?.reset();
|
||||
// client-side validation
|
||||
const result = await addProvider(formData)
|
||||
if (result?.error) {
|
||||
|
||||
const error = result.error
|
||||
//show error
|
||||
toast({
|
||||
title: `${error}`,
|
||||
description: "There was a problem with your request.",
|
||||
})
|
||||
if (result?.errors) {
|
||||
result.errors.forEach((error: { detail: string }) => {
|
||||
let errorMessage = `${error.detail}`;
|
||||
// show error
|
||||
toast({
|
||||
title: "Wops! Something went wrong",
|
||||
description: errorMessage,
|
||||
});
|
||||
});
|
||||
} else {
|
||||
toast({
|
||||
title: "Success!",
|
||||
description: "The provider was added successfully.",
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return (
|
||||
<form ref={ref} action={clientAction} className="flex gap-x-2">
|
||||
<input
|
||||
@@ -51,8 +52,6 @@ export const AddProvider = () => {
|
||||
className="py-2 px-3 rounded-sm"
|
||||
/>
|
||||
<ButtonAddProvider />
|
||||
|
||||
|
||||
</form>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use client";
|
||||
|
||||
import { Button } from "@nextui-org/react";
|
||||
import React from "react";
|
||||
import { useFormStatus } from "react-dom";
|
||||
@@ -5,6 +7,8 @@ import { useFormStatus } from "react-dom";
|
||||
export const ButtonAddProvider = () => {
|
||||
const { pending } = useFormStatus();
|
||||
return (
|
||||
<Button type="submit">{pending ? "Adding..." : "Add provider"}</Button>
|
||||
<Button type="submit" area-disabled={pending}>
|
||||
{pending ? "Adding..." : "Add provider"}
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
"use client";
|
||||
|
||||
import { Button } from "@nextui-org/react";
|
||||
import React from "react";
|
||||
import { useFormStatus } from "react-dom";
|
||||
|
||||
import { DeleteIcon } from "../icons";
|
||||
|
||||
export const ButtonDeleteProvider = () => {
|
||||
const { pending } = useFormStatus();
|
||||
return (
|
||||
<Button
|
||||
variant="light"
|
||||
spinner={pending ? "Removing..." : " Remove"}
|
||||
type="submit"
|
||||
area-disabled={pending}
|
||||
>
|
||||
<DeleteIcon size={20} /> Delete
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,58 @@
|
||||
"use client";
|
||||
|
||||
import { useRef } from "react";
|
||||
|
||||
import { deleteProvider } from "@/actions";
|
||||
|
||||
import { useToast } from "../ui/toast";
|
||||
import { ButtonDeleteProvider } from "./ButtonDeleteProvider";
|
||||
|
||||
export const DeleteProvider = ({ id }: { id: string }) => {
|
||||
const ref = useRef<HTMLFormElement>(null);
|
||||
const { toast } = useToast();
|
||||
|
||||
// const [state, formAction] = useFormState(deleteProvider, initialState);
|
||||
|
||||
async function clientAction(formData: FormData) {
|
||||
// reset the form
|
||||
ref.current?.reset();
|
||||
// client-side validation
|
||||
const result = await deleteProvider(formData);
|
||||
if (result?.error) {
|
||||
const error = result.error;
|
||||
//show error
|
||||
toast({
|
||||
title: `${error}`,
|
||||
description: "There was a problem with your request.",
|
||||
});
|
||||
} else {
|
||||
toast({
|
||||
title: "Success!",
|
||||
description: "The provider was removed successfully.",
|
||||
});
|
||||
}
|
||||
}
|
||||
return (
|
||||
<form ref={ref} action={clientAction} className="flex gap-x-2">
|
||||
<input type="hidden" name="id" value={id} />
|
||||
|
||||
<ButtonDeleteProvider />
|
||||
{/* <p aria-live="polite" className="sr-only" role="status">
|
||||
{state?.message}
|
||||
</p> */}
|
||||
</form>
|
||||
);
|
||||
};
|
||||
|
||||
// const [state, formAction] = useFormState(deleteTodo, initialState);
|
||||
|
||||
// return (
|
||||
// <form action={formAction}>
|
||||
// <input type="hidden" name="id" value={id} />
|
||||
// <input type="hidden" name="todo" value={todo} />
|
||||
// <DeleteButton />
|
||||
// <p aria-live="polite" className="sr-only" role="status">
|
||||
// {state?.message}
|
||||
// </p>
|
||||
// </form>
|
||||
// );
|
||||
@@ -16,9 +16,10 @@ import { ProviderProps } from "@/types";
|
||||
|
||||
import { DateWithTime } from "../DateWithTime";
|
||||
import { ProviderInfo } from "../ProviderInfo";
|
||||
import { DeleteProvider } from "../DeleteProvider";
|
||||
|
||||
const getProviderAttributes = (row: { original: ProviderProps }) => {
|
||||
return row.original.attributes;
|
||||
const getProviderData= (row: { original: ProviderProps }) => {
|
||||
return row.original;
|
||||
};
|
||||
|
||||
export const ColumnsProviders: ColumnDef<ProviderProps>[] = [
|
||||
@@ -30,8 +31,7 @@ export const ColumnsProviders: ColumnDef<ProviderProps>[] = [
|
||||
accessorKey: "account",
|
||||
header: "Account",
|
||||
cell: ({ row }) => {
|
||||
const { connection, provider, alias, provider_id } =
|
||||
getProviderAttributes(row);
|
||||
const { attributes: { connection, provider, alias, provider_id } } = getProviderData(row);
|
||||
return (
|
||||
<ProviderInfo
|
||||
connected={connection.connected}
|
||||
@@ -54,7 +54,7 @@ export const ColumnsProviders: ColumnDef<ProviderProps>[] = [
|
||||
accessorKey: "lastScan",
|
||||
header: "Last Scan",
|
||||
cell: ({ row }) => {
|
||||
const { updated_at } = getProviderAttributes(row);
|
||||
const { attributes: {updated_at} } = getProviderData(row);
|
||||
return <DateWithTime dateTime={updated_at} />;
|
||||
},
|
||||
},
|
||||
@@ -62,7 +62,7 @@ export const ColumnsProviders: ColumnDef<ProviderProps>[] = [
|
||||
accessorKey: "nextScan",
|
||||
header: "Next Scan",
|
||||
cell: ({ row }) => {
|
||||
const { updated_at } = getProviderAttributes(row);
|
||||
const { attributes: {updated_at} } = getProviderData(row);
|
||||
const nextDay = add(new Date(updated_at), {
|
||||
hours: 24,
|
||||
});
|
||||
@@ -81,7 +81,7 @@ export const ColumnsProviders: ColumnDef<ProviderProps>[] = [
|
||||
accessorKey: "added",
|
||||
header: "Added",
|
||||
cell: ({ row }) => {
|
||||
const { inserted_at } = getProviderAttributes(row);
|
||||
const { attributes: {inserted_at} } = getProviderData(row);
|
||||
return <DateWithTime dateTime={inserted_at} showTime={false} />;
|
||||
},
|
||||
},
|
||||
@@ -89,7 +89,8 @@ export const ColumnsProviders: ColumnDef<ProviderProps>[] = [
|
||||
accessorKey: "actions",
|
||||
header: () => <div className="text-right">Actions</div>,
|
||||
id: "actions",
|
||||
cell: () => {
|
||||
cell: ({ row }) => {
|
||||
const { id } = getProviderData(row);
|
||||
return (
|
||||
<div className="relative flex justify-end items-center gap-2">
|
||||
<Dropdown className="bg-background border-1 border-default-200">
|
||||
@@ -101,7 +102,9 @@ export const ColumnsProviders: ColumnDef<ProviderProps>[] = [
|
||||
<DropdownMenu>
|
||||
<DropdownItem>Check connection</DropdownItem>
|
||||
<DropdownItem>Manage</DropdownItem>
|
||||
<DropdownItem>Delete</DropdownItem>
|
||||
<DropdownItem>
|
||||
<DeleteProvider id={id} />
|
||||
</DropdownItem>
|
||||
</DropdownMenu>
|
||||
</Dropdown>
|
||||
</div>
|
||||
|
||||
@@ -5,7 +5,7 @@ import * as React from "react";
|
||||
|
||||
import type { ToastActionElement, ToastProps } from "@/components";
|
||||
|
||||
const TOAST_LIMIT = 1;
|
||||
const TOAST_LIMIT = 6;
|
||||
const TOAST_REMOVE_DELAY = 1000000;
|
||||
|
||||
type ToasterToast = ToastProps & {
|
||||
|
||||
Reference in New Issue
Block a user