diff --git a/plugins/plugin-api-permissions/admin/src/pages/Roles/CreatePage.tsx b/plugins/plugin-api-permissions/admin/src/pages/Roles/CreatePage.tsx index 7e4354c..7b0a40f 100644 --- a/plugins/plugin-api-permissions/admin/src/pages/Roles/CreatePage.tsx +++ b/plugins/plugin-api-permissions/admin/src/pages/Roles/CreatePage.tsx @@ -17,56 +17,51 @@ import { useNotification, useRBAC, } from "@strapi/strapi/admin"; -import type React from "react"; -import { useRef, useState } from "react"; +import type { FormEvent } from "react"; +import { useMemo, useState } from "react"; import { useIntl } from "react-intl"; import { useMutation, useQuery } from "react-query"; +import { useNavigate } from "react-router-dom"; import type { GenericResponse } from "../../types/content-api"; -import { Permissions, type PermissionsRef } from "./components/Permissions"; +import { Permissions } from "./components/Permissions"; import { PERMISSIONS } from "./constants"; -import { PermissionsProvider } from "./contexts/PermissionsContext"; -import { ROLES_BASE } from "./paths"; +import { + PermissionsProvider, + usePermissions, +} from "./contexts/PermissionsContext"; +import { ROLES_BASE, ROLES_ROUTE_BASE } from "./paths"; import { createEmptyFormState, type PermissionsFormState, type PermissionsLayout, } from "./utils/transform"; -export const RolesCreatePage = () => { +type RolesCreatePageContentProps = { + layout: PermissionsLayout; + permissions: PermissionsFormState; +}; + +const RolesCreatePageContent = ({ + layout, + permissions, +}: RolesCreatePageContentProps) => { const { formatMessage } = useIntl(); const { toggleNotification } = useNotification(); - const { get, post } = useFetchClient(); - const permissionsRef = useRef(null); - const goBack = () => { - if (typeof window !== "undefined") window.location.href = ROLES_BASE; - }; - - const { - allowedActions: { canCreate }, - } = useRBAC({ - create: PERMISSIONS.createRole, - }); + const { post } = useFetchClient(); + const { modifiedData } = usePermissions(); + const navigate = useNavigate(); + const goBack = () => navigate(ROLES_ROUTE_BASE); const [name, setName] = useState(""); const [description, setDescription] = useState(""); const [error, setError] = useState(null); - const { data: layoutData, isLoading: isLoadingLayout } = useQuery( - ["api-permissions", "permissions", "layout"], - async () => - get>( - "/api-permissions/permissions/layout", - ), - ); - - const layout = layoutData?.data?.data?.sections ?? null; - - const permissionsForm: PermissionsFormState = layout - ? createEmptyFormState(layout) - : { collectionTypes: {}, singleTypes: {}, plugins: {}, settings: {} }; - const createMutation = useMutation( - (body: { name: string; description: string }) => + (body: { + name: string; + description: string; + permissions: PermissionsFormState; + }) => post("/api-permissions/roles", { data: body, }), @@ -93,7 +88,7 @@ export const RolesCreatePage = () => { }, ); - const handleSubmit = (e: React.FormEvent) => { + const handleSubmit = (e: FormEvent) => { e.preventDefault(); setError(null); if (!name || name.length < 3) { @@ -105,17 +100,9 @@ export const RolesCreatePage = () => { ); return; } - createMutation.mutate({ name, description }); + createMutation.mutate({ name, description, permissions: modifiedData }); }; - if (!canCreate) { - return ; - } - - if (isLoadingLayout || !layout) { - return ; - } - return ( @@ -173,6 +160,7 @@ export const RolesCreatePage = () => { defaultMessage: "Details", })} +
{formatMessage({ id: "Settings.roles.form.description", @@ -259,13 +247,7 @@ export const RolesCreatePage = () => { - - - + @@ -274,6 +256,49 @@ export const RolesCreatePage = () => { ); }; +export const RolesCreatePage = () => { + const { get } = useFetchClient(); + + const { + isLoading: isLoadingForPermissions, + allowedActions: { canCreate }, + } = useRBAC({ + create: PERMISSIONS.createRole, + }); + + const { data: layoutData, isLoading: isLoadingLayout } = useQuery( + ["api-permissions", "permissions", "layout"], + async () => + get>( + "/api-permissions/permissions/layout", + ), + ); + + const layout = layoutData?.data?.data?.sections ?? null; + const permissions = useMemo( + () => (layout ? createEmptyFormState(layout) : null), + [layout], + ); + + if (isLoadingForPermissions) { + return ; + } + + if (!canCreate) { + return ; + } + + if (isLoadingLayout || !layout || !permissions) { + return ; + } + + return ( + + + + ); +}; + export const ProtectedRolesCreatePage = () => ( diff --git a/plugins/plugin-api-permissions/admin/src/pages/Roles/EditPage.tsx b/plugins/plugin-api-permissions/admin/src/pages/Roles/EditPage.tsx index b161871..90072d7 100644 --- a/plugins/plugin-api-permissions/admin/src/pages/Roles/EditPage.tsx +++ b/plugins/plugin-api-permissions/admin/src/pages/Roles/EditPage.tsx @@ -17,83 +17,71 @@ import { useNotification, useRBAC, } from "@strapi/strapi/admin"; -import type React from "react"; +import type { FormEvent } from "react"; import { useMemo, useRef, useState } from "react"; import { useIntl } from "react-intl"; import { useMutation, useQuery } from "react-query"; +import { useNavigate } from "react-router-dom"; import type { GenericResponse } from "../../types/content-api"; import { Permissions, type PermissionsRef } from "./components/Permissions"; import { PERMISSIONS } from "./constants"; -import { PermissionsProvider } from "./contexts/PermissionsContext"; -import { ROLES_BASE } from "./paths"; -import { apiToFormState, type PermissionsLayout } from "./utils/transform"; +import { + PermissionsProvider, + usePermissions, +} from "./contexts/PermissionsContext"; +import { ROLES_BASE, ROLES_ROUTE_BASE } from "./paths"; +import { + apiToFormState, + type PermissionEntry, + type PermissionsFormState, + type PermissionsLayout, +} from "./utils/transform"; type RoleData = { name?: string; description?: string; nb_users?: number; - permissions?: Record< - string, - { controllers: Record> } - >; + permissions?: PermissionEntry[]; +}; + +type RolesEditPageProps = { + description?: string; + id: string; + layout: PermissionsLayout; + name: string; + permissions: PermissionsFormState; + usersCount: number; }; -export const RolesEditPage = ({ id }: { id: string }) => { +export const RolesEditPage = ({ + description, + id, + layout, + name, + permissions, + usersCount = 0, +}: RolesEditPageProps) => { const { formatMessage } = useIntl(); const { toggleNotification } = useNotification(); - const { get, put } = useFetchClient(); + const { put } = useFetchClient(); const permissionsRef = useRef(null); - const goBack = () => { - if (typeof window !== "undefined") window.location.href = ROLES_BASE; - }; + const navigate = useNavigate(); + const goBack = () => navigate(ROLES_ROUTE_BASE); const { + isLoading: isLoadingForPermissions, allowedActions: { canUpdate }, - } = useRBAC({ - update: PERMISSIONS.updateRole, - }); + } = useRBAC({ update: PERMISSIONS.updateRole }); - const [name, setName] = useState(""); - const [description, setDescription] = useState(""); const [error, setError] = useState(null); - const [initialised, setInitialised] = useState(false); - - const { data: layoutData, isLoading: isLoadingLayout } = useQuery( - ["api-permissions", "permissions", "layout"], - async () => - get>( - "/api-permissions/permissions/layout", - ), - ); - - const { data: roleData, isLoading: isLoadingRole } = useQuery( - ["api-permissions", "roles", id], - async () => get>(`/api-permissions/roles/${id}`), - { - enabled: !!id, - onSuccess: (res) => { - if (!initialised) { - setName(res.data?.data?.name ?? ""); - setDescription(res.data?.data?.description ?? ""); - setInitialised(true); - } - }, - }, - ); - - const layout = layoutData?.data?.data?.sections ?? null; - const roleApiData = roleData?.data?.data ?? null; - - const permissionsForm = useMemo( - () => - layout && roleApiData - ? apiToFormState(roleApiData?.permissions ?? {}, layout) - : null, - [layout, roleApiData], - ); + const { modifiedData } = usePermissions(); const updateMutation = useMutation( - (body: { name: string; description: string }) => + (body: { + name: string; + description: string; + permissions: PermissionsFormState; + }) => put(`/api-permissions/roles/${id}`, { data: body, }), @@ -120,8 +108,13 @@ export const RolesEditPage = ({ id }: { id: string }) => { }, ); - const handleSubmit = (e: React.FormEvent) => { + const handleSubmit = (e: FormEvent) => { e.preventDefault(); + + const { name = "", description = "" } = Object.fromEntries( + new FormData(e.currentTarget as HTMLFormElement).entries(), + ) as Record; + setError(null); if (!name || name.length < 3) { setError( @@ -132,10 +125,10 @@ export const RolesEditPage = ({ id }: { id: string }) => { ); return; } - updateMutation.mutate({ name, description }); + updateMutation.mutate({ name, description, permissions: modifiedData }); }; - if (isLoadingLayout || isLoadingRole || !permissionsForm || !layout) { + if (isLoadingForPermissions) { return ; } @@ -143,8 +136,6 @@ export const RolesEditPage = ({ id }: { id: string }) => { return ; } - const usersCount = roleApiData?.nb_users ?? 0; - return ( @@ -202,6 +193,7 @@ export const RolesEditPage = ({ id }: { id: string }) => { defaultMessage: "Details", })} +
{formatMessage({ id: "Settings.roles.form.description", @@ -256,11 +248,7 @@ export const RolesEditPage = ({ id }: { id: string }) => { defaultMessage: "Name", })} - setName(e.target.value)} - type="text" - /> + @@ -277,10 +265,7 @@ export const RolesEditPage = ({ id }: { id: string }) => { defaultMessage: "Description", })} -