Cleared of the stuff the EnCoach team wanted changed
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -39,7 +39,7 @@ export default function ExamLoader() {
|
||||
setExams([exam]);
|
||||
setSelectedModules([selectedModule]);
|
||||
|
||||
router.push("/exercises");
|
||||
router.push("/exam");
|
||||
}
|
||||
|
||||
setIsLoading(false);
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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} />
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user