Cleared of the stuff the EnCoach team wanted changed

This commit is contained in:
Tiago Ribeiro
2024-10-28 14:40:26 +00:00
parent 0becd295b0
commit fa0c502467
34 changed files with 166 additions and 107 deletions

View File

@@ -194,7 +194,7 @@ export default function BatchCreateUser({user, users, entities = [], permissions
<th className="border border-neutral-200 px-2 py-1">E-mail</th>
<th className="border border-neutral-200 px-2 py-1">Phone Number</th>
{user?.type !== "corporate" && <th className="border border-neutral-200 px-2 py-1">Corporate (e-mail)</th>}
<th className="border border-neutral-200 px-2 py-1">Group Name</th>
<th className="border border-neutral-200 px-2 py-1">Classroom Name</th>
<th className="border border-neutral-200 px-2 py-1">Country</th>
</tr>
</thead>

View File

@@ -39,7 +39,7 @@ export default function ExamLoader() {
setExams([exam]);
setSelectedModules([selectedModule]);
router.push("/exercises");
router.push("/exam");
}
setIsLoading(false);

View File

@@ -20,6 +20,8 @@ import Modal from "@/components/Modal";
import {checkAccess} from "@/utils/permissions";
import useGroups from "@/hooks/useGroups";
import Button from "@/components/Low/Button";
import { EntityWithRoles } from "@/interfaces/entity";
import { useAllowedEntities } from "@/hooks/useEntityPermissions";
const searchFields = [["module"], ["id"], ["createdBy"]];
@@ -56,13 +58,36 @@ const ExamOwnerSelector = ({options, exam, onSave}: {options: User[]; exam: Exam
);
};
export default function ExamList({user}: {user: User}) {
export default function ExamList({user, entities = []}: {user: User, entities: EntityWithRoles[]}) {
const [selectedExam, setSelectedExam] = useState<Exam>();
const {exams, reload} = useExams();
const {users} = useUsers();
const {groups} = useGroups({admin: user?.id, userType: user?.type});
const canViewReading = useAllowedEntities(user, entities, 'view_reading')
const canViewListening = useAllowedEntities(user, entities, 'view_listening')
const canViewWriting = useAllowedEntities(user, entities, 'view_writing')
const canViewSpeaking = useAllowedEntities(user, entities, 'view_speaking')
const canViewLevel = useAllowedEntities(user, entities, 'view_level')
const canDeleteReading = useAllowedEntities(user, entities, 'delete_reading')
const canDeleteListening = useAllowedEntities(user, entities, 'delete_listening')
const canDeleteWriting = useAllowedEntities(user, entities, 'delete_writing')
const canDeleteSpeaking = useAllowedEntities(user, entities, 'delete_speaking')
const canDeleteLevel = useAllowedEntities(user, entities, 'delete_level')
const modulePermissions = useMemo(() => ({
reading: {view: canViewReading.length > 0, delete: canDeleteReading.length > 0},
listening: {view: canViewListening.length > 0, delete: canDeleteListening.length > 0},
writing: {view: canViewWriting.length > 0, delete: canDeleteWriting.length > 0},
speaking: {view: canViewSpeaking.length > 0, delete: canDeleteSpeaking.length > 0},
level: {view: canViewLevel.length > 0, delete: canDeleteLevel.length > 0},
}),
[
canDeleteLevel.length, canDeleteListening.length, canDeleteReading.length, canDeleteSpeaking.length, canDeleteWriting.length, canViewLevel.length, canViewListening.length, canViewReading.length, canViewSpeaking.length, canViewWriting.length
])
const filteredCorporates = useMemo(() => {
const participantsAndAdmins = uniq(groups.flatMap((x) => [...x.participants, x.admin])).filter((x) => x !== user?.id);
return users.filter((x) => participantsAndAdmins.includes(x.id) && x.type === "corporate");
@@ -84,7 +109,10 @@ export default function ExamList({user}: {user: User}) {
});
}, [exams, users]);
const {rows: filteredRows, renderSearch} = useListSearch<Exam>(searchFields, parsedExams);
const filteredExams = useMemo(() => parsedExams.filter(({module}) => modulePermissions[module].view),
[parsedExams, modulePermissions])
const {rows: filteredRows, renderSearch} = useListSearch<Exam>(searchFields, filteredExams);
const setExams = useExamStore((state) => state.setExams);
const setSelectedModules = useExamStore((state) => state.setSelectedModules);
@@ -104,7 +132,7 @@ export default function ExamList({user}: {user: User}) {
setExams([exam]);
setSelectedModules([module]);
router.push("/exercises");
router.push("/exam");
};
const privatizeExam = async (exam: Exam) => {
@@ -245,7 +273,7 @@ export default function ExamList({user}: {user: User}) {
onClick={async () => await loadExam(row.original.module, row.original.id)}>
<BsUpload className="hover:text-mti-purple-light transition ease-in-out duration-300" />
</button>
{PERMISSIONS.examManagement.delete.includes(user.type) && (
{modulePermissions[row.original.module].delete && (
<div data-tip="Delete" className="cursor-pointer tooltip" onClick={() => deleteExam(row.original)}>
<BsTrash className="hover:text-mti-purple-light transition ease-in-out duration-300" />
</div>

View File

@@ -8,16 +8,24 @@ import GroupList from "./GroupList";
import PackageList from "./PackageList";
import UserList from "./UserList";
import {checkAccess} from "@/utils/permissions";
import usePermissions from "@/hooks/usePermissions";
import {PermissionType} from "@/interfaces/permissions";
import { EntityWithRoles } from "@/interfaces/entity";
import { useAllowedEntitiesSomePermissions } from "@/hooks/useEntityPermissions";
import { useMemo } from "react";
interface Props {
user: User;
users: User[];
entities: EntityWithRoles[]
permissions: PermissionType[];
}
export default function Lists({user, users, permissions}: Props) {
export default function Lists({user, entities = [], permissions}: Props) {
const entitiesViewExams = useAllowedEntitiesSomePermissions(user, entities, [
'view_reading', 'view_listening', 'view_writing', 'view_speaking', 'view_level'
])
const canViewExams = useMemo(() => entitiesViewExams.length > 0, [entitiesViewExams])
return (
<TabGroup>
<TabList className="flex space-x-1 rounded-xl bg-mti-purple-ultralight/40 p-1">
@@ -32,7 +40,7 @@ export default function Lists({user, users, permissions}: Props) {
}>
User List
</Tab>
{checkAccess(user, ["developer", "admin", "corporate", "mastercorporate", "teacher"]) && (
{canViewExams && (
<Tab
className={({selected}) =>
clsx(
@@ -45,17 +53,6 @@ export default function Lists({user, users, permissions}: Props) {
Exam List
</Tab>
)}
<Tab
className={({selected}) =>
clsx(
"w-full rounded-lg py-2.5 text-sm font-medium leading-5 text-mti-purple-light",
"ring-white ring-opacity-60 ring-offset-2 ring-offset-mti-purple-light focus:outline-none focus:ring-2",
"transition duration-300 ease-in-out",
selected ? "bg-white shadow" : "text-blue-100 hover:bg-white/[0.12] hover:text-mti-purple-dark",
)
}>
Group List
</Tab>
{checkAccess(user, ["developer", "admin", "corporate"]) && (
<Tab
className={({selected}) =>
@@ -100,14 +97,11 @@ export default function Lists({user, users, permissions}: Props) {
<TabPanel className="overflow-y-scroll max-h-[600px] rounded-xl scrollbar-hide">
<UserList user={user} />
</TabPanel>
{checkAccess(user, ["developer", "admin", "corporate", "mastercorporate", "teacher"]) && (
{canViewExams && (
<TabPanel className="overflow-y-scroll max-h-[600px] rounded-xl scrollbar-hide">
<ExamList user={user} />
<ExamList user={user} entities={entities} />
</TabPanel>
)}
<TabPanel className="overflow-y-scroll max-h-[600px] rounded-xl scrollbar-hide">
<GroupList user={user} />
</TabPanel>
{checkAccess(user, ["developer", "admin", "corporate", "mastercorporate"], permissions, "viewCodes") && (
<TabPanel className="overflow-y-scroll max-h-[600px] rounded-xl scrollbar-hide">
<CodeList user={user} />

View File

@@ -196,7 +196,7 @@ export default function UserCreator({ user, users, entities = [], permissions, o
)}
<div className={clsx("flex flex-col gap-4")}>
<label className="font-normal text-base text-mti-gray-dim">Group</label>
<label className="font-normal text-base text-mti-gray-dim">Classroom</label>
<Select
options={groups
.filter((x) => x.entity?.id === entity)