mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-24 21:11:53 +00:00
fix(RBAC): tweaks for edit role form (#6609)
This commit is contained in:
@@ -158,10 +158,10 @@ export const updateProviderGroup = async (
|
||||
const providersJson = formData.get("providers") as string;
|
||||
const rolesJson = formData.get("roles") as string;
|
||||
|
||||
const providers = providersJson ? JSON.parse(providersJson) : [];
|
||||
const roles = rolesJson ? JSON.parse(rolesJson) : [];
|
||||
const providers = providersJson ? JSON.parse(providersJson) : null;
|
||||
const roles = rolesJson ? JSON.parse(rolesJson) : null;
|
||||
|
||||
const payload: ManageGroupPayload = {
|
||||
const payload: Partial<ManageGroupPayload> = {
|
||||
data: {
|
||||
type: "provider-groups",
|
||||
id: providerGroupId,
|
||||
@@ -170,14 +170,15 @@ export const updateProviderGroup = async (
|
||||
},
|
||||
};
|
||||
|
||||
// Add relationships only if there are items
|
||||
if (providers.length >= 0) {
|
||||
payload.data.relationships!.providers = { data: providers };
|
||||
// Add relationships only if changes are detected
|
||||
if (providers) {
|
||||
payload.data!.relationships!.providers = { data: providers };
|
||||
}
|
||||
|
||||
if (roles.length >= 0) {
|
||||
payload.data.relationships!.roles = { data: roles };
|
||||
if (roles) {
|
||||
payload.data!.relationships!.roles = { data: roles };
|
||||
}
|
||||
|
||||
try {
|
||||
const url = `${keyServer}/provider-groups/${providerGroupId}`;
|
||||
const response = await fetch(url, {
|
||||
@@ -192,8 +193,6 @@ export const updateProviderGroup = async (
|
||||
|
||||
if (!response.ok) {
|
||||
const errorResponse = await response.json();
|
||||
// eslint-disable-next-line no-console
|
||||
console.error("Error response:", errorResponse);
|
||||
throw new Error(
|
||||
`Failed to update provider group: ${response.status} ${response.statusText}`,
|
||||
);
|
||||
@@ -203,7 +202,6 @@ export const updateProviderGroup = async (
|
||||
revalidatePath("/manage-groups");
|
||||
return parseStringify(data);
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error("Unexpected error:", error);
|
||||
return {
|
||||
error: getErrorMessage(error),
|
||||
|
||||
@@ -50,10 +50,12 @@ export const EditGroupForm = ({
|
||||
try {
|
||||
const updatedFields: Partial<FormValues> = {};
|
||||
|
||||
// Detect changes in the name
|
||||
if (values.name !== providerGroupData.name) {
|
||||
updatedFields.name = values.name;
|
||||
}
|
||||
|
||||
// Detect changes in providers
|
||||
if (
|
||||
JSON.stringify(values.providers) !==
|
||||
JSON.stringify(providerGroupData.providers)
|
||||
@@ -61,12 +63,14 @@ export const EditGroupForm = ({
|
||||
updatedFields.providers = values.providers;
|
||||
}
|
||||
|
||||
// Detect changes in roles
|
||||
if (
|
||||
JSON.stringify(values.roles) !== JSON.stringify(providerGroupData.roles)
|
||||
) {
|
||||
updatedFields.roles = values.roles;
|
||||
}
|
||||
|
||||
// If no changes, notify the user and exit
|
||||
if (Object.keys(updatedFields).length === 0) {
|
||||
toast({
|
||||
title: "No changes detected",
|
||||
@@ -75,6 +79,7 @@ export const EditGroupForm = ({
|
||||
return;
|
||||
}
|
||||
|
||||
// Create FormData dynamically
|
||||
const formData = new FormData();
|
||||
if (updatedFields.name) {
|
||||
formData.append("name", updatedFields.name);
|
||||
@@ -94,6 +99,7 @@ export const EditGroupForm = ({
|
||||
formData.append("roles", JSON.stringify(rolesData));
|
||||
}
|
||||
|
||||
// Call the update action
|
||||
const data = await updateProviderGroup(providerGroupId, formData);
|
||||
|
||||
if (data?.errors && data.errors.length > 0) {
|
||||
|
||||
@@ -31,66 +31,50 @@ export const CustomDropdownSelection: React.FC<
|
||||
const [selectedValues, setSelectedValues] = useState<Set<string>>(
|
||||
new Set(selectedKeys),
|
||||
);
|
||||
const allValues = values.map((item) => item.id);
|
||||
|
||||
const memoizedValues = useMemo(() => values, [values]);
|
||||
const allValues = useMemo(() => values.map((item) => item.id), [values]);
|
||||
|
||||
// Update the internal state when selectedKeys changes from props
|
||||
// Update internal state when selectedKeys changes
|
||||
useEffect(() => {
|
||||
const newSelection = new Set(selectedKeys);
|
||||
if (
|
||||
JSON.stringify(Array.from(selectedValues)) !==
|
||||
JSON.stringify(Array.from(newSelection))
|
||||
) {
|
||||
if (selectedKeys.length === allValues.length) {
|
||||
newSelection.add("all");
|
||||
}
|
||||
setSelectedValues(newSelection);
|
||||
if (selectedKeys.length === allValues.length) {
|
||||
newSelection.add("all");
|
||||
}
|
||||
}, [selectedKeys, allValues.length, selectedValues]);
|
||||
setSelectedValues(newSelection);
|
||||
}, [selectedKeys, allValues]);
|
||||
|
||||
const onSelectionChange = useCallback(
|
||||
(keys: string[]) => {
|
||||
setSelectedValues((prevSelected) => {
|
||||
const newSelection = new Set(keys);
|
||||
const newSelection = new Set(keys);
|
||||
|
||||
// If all values are selected and "all" is not included,
|
||||
// add "all" automatically
|
||||
if (
|
||||
newSelection.size === allValues.length &&
|
||||
!newSelection.has("all")
|
||||
) {
|
||||
return new Set(["all", ...allValues]);
|
||||
} else if (prevSelected.has("all")) {
|
||||
// If "all" was previously selected, remove it
|
||||
if (newSelection.has("all")) {
|
||||
// Handle "Select All" behavior
|
||||
if (newSelection.size === allValues.length + 1) {
|
||||
setSelectedValues(new Set(["all", ...allValues]));
|
||||
onChange(name, allValues); // Exclude "all" in the callback
|
||||
} else {
|
||||
newSelection.delete("all");
|
||||
return new Set(allValues.filter((key) => newSelection.has(key)));
|
||||
setSelectedValues(newSelection);
|
||||
onChange(name, Array.from(newSelection));
|
||||
}
|
||||
return newSelection;
|
||||
});
|
||||
|
||||
// Notify the change without including "all"
|
||||
const selectedValues = keys.filter((key) => key !== "all");
|
||||
onChange(name, selectedValues);
|
||||
} else {
|
||||
setSelectedValues(newSelection);
|
||||
onChange(name, Array.from(newSelection));
|
||||
}
|
||||
},
|
||||
[allValues, name, onChange],
|
||||
);
|
||||
|
||||
const handleSelectAllClick = useCallback(() => {
|
||||
setSelectedValues((prevSelected: Set<string>) => {
|
||||
const newSelection: Set<string> = prevSelected.has("all")
|
||||
? new Set()
|
||||
: new Set(["all", ...allValues]);
|
||||
|
||||
// Notify the change without including "all"
|
||||
const selectedValues = Array.from(newSelection).filter(
|
||||
(key) => key !== "all",
|
||||
);
|
||||
onChange(name, selectedValues);
|
||||
|
||||
return newSelection;
|
||||
});
|
||||
}, [allValues, name, onChange]);
|
||||
if (selectedValues.has("all")) {
|
||||
setSelectedValues(new Set());
|
||||
onChange(name, []);
|
||||
} else {
|
||||
const newSelection = new Set(["all", ...allValues]);
|
||||
setSelectedValues(newSelection);
|
||||
onChange(name, allValues);
|
||||
}
|
||||
}, [allValues, name, onChange, selectedValues]);
|
||||
|
||||
return (
|
||||
<div className="relative flex w-full flex-col gap-2">
|
||||
@@ -119,7 +103,8 @@ export const CustomDropdownSelection: React.FC<
|
||||
wrapper: "checkbox-update",
|
||||
}}
|
||||
value="all"
|
||||
onClick={handleSelectAllClick}
|
||||
isSelected={selectedValues.has("all")}
|
||||
onChange={handleSelectAllClick}
|
||||
>
|
||||
Select All
|
||||
</Checkbox>
|
||||
@@ -128,7 +113,7 @@ export const CustomDropdownSelection: React.FC<
|
||||
hideScrollBar
|
||||
className="flex max-h-96 max-w-56 flex-col gap-y-2 py-2"
|
||||
>
|
||||
{memoizedValues.map(({ id, name }) => (
|
||||
{values.map(({ id, name }) => (
|
||||
<Checkbox
|
||||
classNames={{
|
||||
label: "text-small font-normal",
|
||||
|
||||
Reference in New Issue
Block a user