386 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			386 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| "use client";
 | |
| 
 | |
| import { createRole, updateRole, useRoleItem } from "@/hooks/role";
 | |
| import { Module, Permission, Role } from "@/lib/interfaces";
 | |
| import { usePathname, useRouter } from "next/navigation";
 | |
| import Link from "next/link";
 | |
| import { useEffect, useState } from "react";
 | |
| import { Status } from "@/lib/Enums";
 | |
| import { Applications } from "@/lib/Enums";
 | |
| import { usePermissionItems } from "@/hooks/permission";
 | |
| import { useModuleItems } from "@/hooks/module";
 | |
| 
 | |
| export default function RoleDetails() {
 | |
|   const [item, setItem] = useState<Role>();
 | |
|   const pathName = usePathname();
 | |
|   const router = useRouter();
 | |
|   let isUpdateMode = false;
 | |
|   let selectedApplications: string[];
 | |
|   const [permissions, setPermissions] = useState<Permission[]>([]);
 | |
|   const [modules, setModules] = useState<Module[]>([]);
 | |
|   let initialPermissions: string[];
 | |
|   let initialApplications: string[];
 | |
|   let initialModules: string[];
 | |
| 
 | |
|   const setSelectedValuesGlobal = (values: string[]) => {
 | |
|     selectedApplications = values;
 | |
|   };
 | |
| 
 | |
|   let selectedPermissions: string[];
 | |
|   const setSelectedPermissionsGlobal = (values: string[]) => {
 | |
|     selectedPermissions = values;
 | |
|   };
 | |
| 
 | |
|   let selectedModules: string[];
 | |
|   const setSelectedModulesGlobal = (values: string[]) => {
 | |
|     selectedModules = values;
 | |
|   };
 | |
| 
 | |
|   const formatDate = (date: Date) =>
 | |
|     new Intl.DateTimeFormat("en-US").format(date);
 | |
| 
 | |
|   const StatusDropDown = (data: any) => {
 | |
|     return (
 | |
|       <select
 | |
|         id="status"
 | |
|         className="p-3 rounded"
 | |
|         defaultValue={data.statusCode}
 | |
|       >
 | |
|         <option value={Status.Active}>{Status.Active}</option>
 | |
|         <option value={Status.Inactive}>{Status.Inactive}</option>
 | |
|         <option value={Status.Deleted}>{Status.Deleted}</option>
 | |
|       </select>
 | |
|     );
 | |
|   };
 | |
| 
 | |
|   const ApplicationsDropDown = ({
 | |
|     selectedApplications,
 | |
|   }: {
 | |
|     selectedApplications: string[];
 | |
|   }) => {
 | |
|     const [localSelectedValues, setLocalSelectedValues] =
 | |
|       useState<string[]>(selectedApplications);
 | |
| 
 | |
|     const handleSelection = (event: React.ChangeEvent<HTMLSelectElement>) => {
 | |
|       const selectedOptions = Array.from(event.target.selectedOptions);
 | |
|       const values = selectedOptions.map((option) => option.value);
 | |
|       setLocalSelectedValues(values);
 | |
|       setSelectedValuesGlobal(values);
 | |
|     };
 | |
| 
 | |
|     return (
 | |
|       <select
 | |
|         id="applications"
 | |
|         className="p-3 rounded"
 | |
|         multiple
 | |
|         value={localSelectedValues}
 | |
|         onChange={handleSelection}
 | |
|       >
 | |
|         <option value={Applications.LSAWebPortal}>
 | |
|           {Applications.LSAWebPortal}
 | |
|         </option>
 | |
|         <option value={Applications.CustomerDashboard}>
 | |
|           CustomerDashboard
 | |
|         </option>
 | |
|         <option value={Applications.Discover}>{Applications.Discover}</option>
 | |
|         <option value={Applications.LSAMobile}>{Applications.LSAMobile}</option>
 | |
|         <option value={Applications.BluePrint}>{Applications.BluePrint}</option>
 | |
|       </select>
 | |
|     );
 | |
|   };
 | |
| 
 | |
|   const PermissionsDropDown = ({
 | |
|     selectedPermissions,
 | |
|   }: {
 | |
|     selectedPermissions: string[];
 | |
|   }) => {
 | |
|     const [localSelectedValues, setLocalSelectedValues] =
 | |
|       useState<string[]>(selectedPermissions);
 | |
| 
 | |
|     useEffect(() => {
 | |
|       setLocalSelectedValues(selectedPermissions);
 | |
|     }, [selectedPermissions]);
 | |
| 
 | |
|     const handleSelection = (event: React.ChangeEvent<HTMLSelectElement>) => {
 | |
|       const selectedOptions = Array.from(event.target.selectedOptions);
 | |
|       const values = selectedOptions.map((option) => option.value);
 | |
|       setLocalSelectedValues(values);
 | |
|       setSelectedPermissionsGlobal(values);
 | |
|     };
 | |
| 
 | |
|     if (!selectedPermissions) setSelectedPermissionsGlobal(selectedPermissions);
 | |
| 
 | |
|     return (
 | |
|       <select
 | |
|         id="permissions"
 | |
|         className="p-3 rounded"
 | |
|         multiple
 | |
|         value={localSelectedValues}
 | |
|         onChange={handleSelection}
 | |
|       >
 | |
|         {permissions.map((permission) => (
 | |
|           <option key={permission.id} value={`${permission.id}`}>
 | |
|             {permission.name} ({permission.accessLevel})
 | |
|           </option>
 | |
|         ))}
 | |
|       </select>
 | |
|     );
 | |
|   };
 | |
| 
 | |
|   const ModulesDropDown = ({
 | |
|     selectedModules,
 | |
|   }: {
 | |
|     selectedModules: string[];
 | |
|   }) => {
 | |
|     const [localSelectedValues, setLocalSelectedValues] =
 | |
|       useState<string[]>(selectedModules);
 | |
| 
 | |
|     useEffect(() => {
 | |
|       setLocalSelectedValues(selectedModules);
 | |
|     }, [selectedModules]);
 | |
| 
 | |
|     const handleSelection = (event: React.ChangeEvent<HTMLSelectElement>) => {
 | |
|       const selectedOptions = Array.from(event.target.selectedOptions);
 | |
|       const values = selectedOptions.map((option) => option.value);
 | |
|       setLocalSelectedValues(values);
 | |
|       setSelectedModulesGlobal(values);
 | |
|     };
 | |
| 
 | |
|     if (!selectedModules) setSelectedModulesGlobal(selectedModules);
 | |
| 
 | |
|     return (
 | |
|       <select
 | |
|         id="modules"
 | |
|         className="p-3 rounded"
 | |
|         multiple
 | |
|         value={localSelectedValues}
 | |
|         onChange={handleSelection}
 | |
|       >
 | |
|         {modules.map((module) => (
 | |
|           <option key={module.id} value={`${module.id}`}>
 | |
|             {module.name} ({module.application})
 | |
|           </option>
 | |
|         ))}
 | |
|       </select>
 | |
|     );
 | |
|   };
 | |
| 
 | |
|   const handleSaveClick = () => {
 | |
|     let id = (document.getElementById("id") as HTMLInputElement)?.value;
 | |
|     let name = (document.getElementById("name") as HTMLInputElement)?.value;
 | |
|     let description = (
 | |
|       document.getElementById("description") as HTMLInputElement
 | |
|     )?.value;
 | |
|     let applications = selectedApplications
 | |
|       ? selectedApplications
 | |
|       : initialApplications;
 | |
|     let permissions = selectedPermissions
 | |
|       ? selectedPermissions
 | |
|       : initialPermissions;
 | |
|     let modules = selectedModules ? selectedModules : initialModules;
 | |
|     let status = (document.getElementById("status") as HTMLSelectElement)
 | |
|       ?.value;
 | |
| 
 | |
|     let updatedRole = {
 | |
|       id,
 | |
|       name,
 | |
|       description,
 | |
|       applications,
 | |
|       permissions,
 | |
|       modules,
 | |
|       status,
 | |
|     } as unknown as Role;
 | |
|     if (isUpdateMode) {
 | |
|       updateRole(updatedRole);
 | |
|     } else {
 | |
|       updatedRole.id = null;
 | |
|       createRole(updatedRole);
 | |
|     }
 | |
|     setItem(updatedRole);
 | |
|     router.push("/role");
 | |
|   };
 | |
| 
 | |
|   const renderForm = (role: Role) => {
 | |
|     return (
 | |
|       <>
 | |
|         <div className="flex flex-col p-5">
 | |
|           <label>Id:</label>
 | |
|           <div className="flex pt-2 flex-col">
 | |
|             <input
 | |
|               id="id"
 | |
|               className="p-2 rounded"
 | |
|               type="text"
 | |
|               defaultValue={role.id ?? ""}
 | |
|               readOnly
 | |
|               placeholder={role.id ?? ""}
 | |
|             />
 | |
|           </div>
 | |
|         </div>
 | |
|         <div className="flex flex-col p-5">
 | |
|           <label>Name:</label>
 | |
|           <div className="flex pt-2 flex-col">
 | |
|             <input
 | |
|               id="name"
 | |
|               className="p-2 rounded"
 | |
|               type="text"
 | |
|               defaultValue={role.name}
 | |
|             />
 | |
|           </div>
 | |
|         </div>
 | |
|         <div className="flex flex-col p-5">
 | |
|           <label>Description:</label>
 | |
|           <div className="flex pt-2 flex-col">
 | |
|             <input
 | |
|               id="description"
 | |
|               className="p-2 rounded"
 | |
|               type="text"
 | |
|               defaultValue={role.description}
 | |
|             />
 | |
|           </div>
 | |
|         </div>
 | |
|         <div className="flex flex-col p-5">
 | |
|           <label>Applications:</label>
 | |
|           <div className="flex pt-2 flex-col">
 | |
|             <ApplicationsDropDown selectedApplications={role.applications} />
 | |
|           </div>
 | |
|         </div>
 | |
|         <div className="flex flex-col p-5">
 | |
|           <label>Permissions:</label>
 | |
|           <div className="flex pt-2 flex-col">
 | |
|             <PermissionsDropDown selectedPermissions={role.permissions} />
 | |
|           </div>
 | |
|         </div>
 | |
|         <div className="flex flex-col p-5">
 | |
|           <label>Modules:</label>
 | |
|           <div className="flex pt-2 flex-col">
 | |
|             <ModulesDropDown selectedModules={role.modules} />
 | |
|           </div>
 | |
|         </div>
 | |
|         <div className="flex flex-col p-5">
 | |
|           <label>CreatedAt:</label>
 | |
|           <div className="flex pt-2 flex-col">
 | |
|             <input
 | |
|               id="createdAt"
 | |
|               className="p-2 rounded"
 | |
|               type="text"
 | |
|               readOnly
 | |
|               defaultValue={formatDate(new Date(role.createdAt))}
 | |
|             />
 | |
|           </div>
 | |
|         </div>
 | |
|         <div className="flex flex-col p-5">
 | |
|           <label>CreatedBy:</label>
 | |
|           <div className="flex pt-2 flex-col">
 | |
|             <input
 | |
|               id="createdBy"
 | |
|               className="p-2 rounded"
 | |
|               type="text"
 | |
|               readOnly
 | |
|               defaultValue={role.createdBy}
 | |
|             />
 | |
|           </div>
 | |
|         </div>
 | |
|         <div className="flex flex-col p-5">
 | |
|           <label>UpdatedAt:</label>
 | |
|           <div className="flex pt-2 flex-col">
 | |
|             <input
 | |
|               id="updatedAt"
 | |
|               className="p-2 rounded"
 | |
|               type="text"
 | |
|               readOnly
 | |
|               defaultValue={formatDate(new Date(role.updatedAt))}
 | |
|             />
 | |
|           </div>
 | |
|         </div>
 | |
|         <div className="flex flex-col p-5">
 | |
|           <label>UpdatedBy:</label>
 | |
|           <div className="flex pt-2 flex-col">
 | |
|             <input
 | |
|               id="updatedBy"
 | |
|               className="p-2 rounded"
 | |
|               type="text"
 | |
|               readOnly
 | |
|               defaultValue={role.updatedBy}
 | |
|             />
 | |
|           </div>
 | |
|         </div>
 | |
|         <div className="flex flex-col p-5">
 | |
|           <label>Status:</label>
 | |
|           <div className="flex pt-2 flex-col">
 | |
|             <StatusDropDown statusCode={role.status}></StatusDropDown>
 | |
|           </div>
 | |
|         </div>
 | |
|       </>
 | |
|     );
 | |
|   };
 | |
| 
 | |
|   const ItemData = () => {
 | |
|     const id = pathName.split("/");
 | |
|     const idValue = id[id.length - 1];
 | |
|     isUpdateMode = idValue != "create";
 | |
|     if (isUpdateMode) {
 | |
|       const { item, isLoading, error } = useRoleItem(idValue);
 | |
|       const {
 | |
|         items: permissionItems,
 | |
|         error: permissionError,
 | |
|         isLoading: isPermissionLoading,
 | |
|         mutate: mutatePermission,
 | |
|       } = usePermissionItems();
 | |
|       const {
 | |
|         items: moduleItems,
 | |
|         error: moduleError,
 | |
|         isLoading: isModuleLoading,
 | |
|         mutate: mutateModule,
 | |
|       } = useModuleItems();
 | |
|       initialApplications = item.applications;
 | |
|       initialPermissions = item.permissions;
 | |
|       initialModules = item.modules;
 | |
|       useEffect(() => {
 | |
|         if (permissionItems && permissionItems.length > 0) {
 | |
|           setPermissions(permissionItems); // Solo actualiza si hay cambios
 | |
|         }
 | |
|       }, [permissionItems]); // Solo se ejecuta si permissionItems cambia
 | |
| 
 | |
|       useEffect(() => {
 | |
|         if (moduleItems && moduleItems.length > 0) {
 | |
|           setModules(moduleItems); // Solo actualiza si hay cambios
 | |
|         }
 | |
|       }, [moduleItems]);
 | |
| 
 | |
|       if (!isLoading && !error && item) {
 | |
|         return renderForm(item);
 | |
|       } else return <>Loading</>;
 | |
|     } else {
 | |
|       return renderForm({
 | |
|         id: "",
 | |
|         name: "",
 | |
|         description: "",
 | |
|         applications: [],
 | |
|         permissions: [],
 | |
|         modules: [],
 | |
|         status: Status.Active,
 | |
|         createdAt: new Date(),
 | |
|         createdBy: "",
 | |
|         updatedAt: new Date(),
 | |
|         updatedBy: "",
 | |
|       });
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   return (
 | |
|     <div id="formContainer" className="flex flex-col">
 | |
|       <div>
 | |
|         <ItemData></ItemData>
 | |
|         <div className="flex flex-row justify-center pb-10">
 | |
|           <a onClick={handleSaveClick} className="button saveBtn">
 | |
|             Save
 | |
|           </a>
 | |
|           <Link className="button cancelBtn" href="../role">
 | |
|             Cancel
 | |
|           </Link>
 | |
|         </div>
 | |
|       </div>
 | |
|     </div>
 | |
|   );
 | |
| }
 | 
