Continued with clearing more of the team's requests
This commit is contained in:
@@ -3,6 +3,7 @@ import { User } from "@/interfaces/user";
|
|||||||
import { RolePermission } from "@/resources/entityPermissions";
|
import { RolePermission } from "@/resources/entityPermissions";
|
||||||
import { mapBy } from "@/utils";
|
import { mapBy } from "@/utils";
|
||||||
import { doesEntityAllow, findAllowedEntities, findAllowedEntitiesSomePermissions } from "@/utils/permissions";
|
import { doesEntityAllow, findAllowedEntities, findAllowedEntitiesSomePermissions } from "@/utils/permissions";
|
||||||
|
import { isAdmin } from "@/utils/users";
|
||||||
import { useMemo, useState } from "react";
|
import { useMemo, useState } from "react";
|
||||||
|
|
||||||
export const useAllowedEntities = (user: User, entities: EntityWithRoles[], permission: RolePermission) => {
|
export const useAllowedEntities = (user: User, entities: EntityWithRoles[], permission: RolePermission) => {
|
||||||
@@ -15,7 +16,9 @@ export const useAllowedEntitiesSomePermissions = (user: User, entities: EntityWi
|
|||||||
return allowedEntityIds
|
return allowedEntityIds
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useEntityPermission = (user: User, entity: EntityWithRoles, permission: RolePermission) => {
|
export const useEntityPermission = (user: User, entity?: EntityWithRoles, permission?: RolePermission) => {
|
||||||
const isAllowed = useMemo(() => doesEntityAllow(user, entity, permission), [user, entity, permission])
|
if (isAdmin(user)) return true
|
||||||
return isAllowed
|
if (!entity || !permission) return false
|
||||||
|
|
||||||
|
return doesEntityAllow(user, entity, permission)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,15 +49,19 @@ export default function UserList({
|
|||||||
|
|
||||||
const isAdmin = useMemo(() => ["admin", "developer"].includes(user?.type), [user?.type])
|
const isAdmin = useMemo(() => ["admin", "developer"].includes(user?.type), [user?.type])
|
||||||
|
|
||||||
|
const entitiesViewStudents = useAllowedEntities(user, entities, "view_students")
|
||||||
const entitiesEditStudents = useAllowedEntities(user, entities, "edit_students")
|
const entitiesEditStudents = useAllowedEntities(user, entities, "edit_students")
|
||||||
const entitiesDeleteStudents = useAllowedEntities(user, entities, "delete_students")
|
const entitiesDeleteStudents = useAllowedEntities(user, entities, "delete_students")
|
||||||
|
|
||||||
|
const entitiesViewTeachers = useAllowedEntities(user, entities, "view_teachers")
|
||||||
const entitiesEditTeachers = useAllowedEntities(user, entities, "edit_teachers")
|
const entitiesEditTeachers = useAllowedEntities(user, entities, "edit_teachers")
|
||||||
const entitiesDeleteTeachers = useAllowedEntities(user, entities, "delete_teachers")
|
const entitiesDeleteTeachers = useAllowedEntities(user, entities, "delete_teachers")
|
||||||
|
|
||||||
|
const entitiesViewCorporates = useAllowedEntities(user, entities, "view_corporates")
|
||||||
const entitiesEditCorporates = useAllowedEntities(user, entities, "edit_corporates")
|
const entitiesEditCorporates = useAllowedEntities(user, entities, "edit_corporates")
|
||||||
const entitiesDeleteCorporates = useAllowedEntities(user, entities, "delete_corporates")
|
const entitiesDeleteCorporates = useAllowedEntities(user, entities, "delete_corporates")
|
||||||
|
|
||||||
|
const entitiesViewMasterCorporates = useAllowedEntities(user, entities, "view_mastercorporates")
|
||||||
const entitiesEditMasterCorporates = useAllowedEntities(user, entities, "edit_mastercorporates")
|
const entitiesEditMasterCorporates = useAllowedEntities(user, entities, "edit_mastercorporates")
|
||||||
const entitiesDeleteMasterCorporates = useAllowedEntities(user, entities, "delete_mastercorporates")
|
const entitiesDeleteMasterCorporates = useAllowedEntities(user, entities, "delete_mastercorporates")
|
||||||
|
|
||||||
@@ -74,7 +78,23 @@ export default function UserList({
|
|||||||
if (today.add(1, "months").isAfter(momentDate)) return "!text-mti-orange-light";
|
if (today.add(1, "months").isAfter(momentDate)) return "!text-mti-orange-light";
|
||||||
};
|
};
|
||||||
|
|
||||||
const displayUsers = useMemo(() => filters.length > 0 ? filters.reduce((d, f) => d.filter(f), users) : users, [filters, users])
|
const allowedUsers = useMemo(() => users.filter((u) => {
|
||||||
|
if (isAdmin) return true
|
||||||
|
if (u.id === user?.id) return false
|
||||||
|
|
||||||
|
switch (u.type) {
|
||||||
|
case "student": return mapBy((u.entities || []), 'id').some((id) => mapBy(entitiesViewStudents, 'id').includes(id))
|
||||||
|
case "teacher": return mapBy((u.entities || []), 'id').some((id) => mapBy(entitiesViewTeachers, 'id').includes(id))
|
||||||
|
case 'corporate': return mapBy((u.entities || []), 'id').some((id) => mapBy(entitiesViewCorporates, 'id').includes(id))
|
||||||
|
case 'mastercorporate': return mapBy((u.entities || []), 'id').some((id) => mapBy(entitiesViewMasterCorporates, 'id').includes(id))
|
||||||
|
default: return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
, [entitiesViewCorporates, entitiesViewMasterCorporates, entitiesViewStudents, entitiesViewTeachers, isAdmin, user?.id, users])
|
||||||
|
|
||||||
|
const displayUsers = useMemo(() =>
|
||||||
|
filters.length > 0 ? filters.reduce((d, f) => d.filter(f), allowedUsers) : allowedUsers,
|
||||||
|
[filters, allowedUsers])
|
||||||
|
|
||||||
const deleteAccount = (user: User) => {
|
const deleteAccount = (user: User) => {
|
||||||
if (!confirm(`Are you sure you want to delete ${user.name}'s account?`)) return;
|
if (!confirm(`Are you sure you want to delete ${user.name}'s account?`)) return;
|
||||||
@@ -149,6 +169,7 @@ export default function UserList({
|
|||||||
|
|
||||||
const canEditUser = (u: User) =>
|
const canEditUser = (u: User) =>
|
||||||
isAdmin || u.entities.some(e => mapBy(getEditPermission(u.type), 'id').includes(e.id))
|
isAdmin || u.entities.some(e => mapBy(getEditPermission(u.type), 'id').includes(e.id))
|
||||||
|
|
||||||
const canDeleteUser = (u: User) =>
|
const canDeleteUser = (u: User) =>
|
||||||
isAdmin || u.entities.some(e => mapBy(getDeletePermission(u.type), 'id').includes(e.id))
|
isAdmin || u.entities.some(e => mapBy(getDeletePermission(u.type), 'id').includes(e.id))
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,10 @@ export const getServerSideProps = withIronSessionSsr(async ({req, res, params})
|
|||||||
if (!assignment) return redirect("/assignments")
|
if (!assignment) return redirect("/assignments")
|
||||||
|
|
||||||
const entity = await getEntityWithRoles(assignment.entity || "")
|
const entity = await getEntityWithRoles(assignment.entity || "")
|
||||||
if (!entity) return redirect("/assignments")
|
if (!entity){
|
||||||
|
const users = await getUsers()
|
||||||
|
return {props: serialize({user, users, assignment})};
|
||||||
|
}
|
||||||
|
|
||||||
if (!doesEntityAllow(user, entity, 'view_assignments')) return redirect("/assignments")
|
if (!doesEntityAllow(user, entity, 'view_assignments')) return redirect("/assignments")
|
||||||
|
|
||||||
@@ -63,7 +66,7 @@ interface Props {
|
|||||||
user: User;
|
user: User;
|
||||||
users: User[];
|
users: User[];
|
||||||
assignment: Assignment;
|
assignment: Assignment;
|
||||||
entity: EntityWithRoles
|
entity?: EntityWithRoles
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function AssignmentView({user, users, entity, assignment}: Props) {
|
export default function AssignmentView({user, users, entity, assignment}: Props) {
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ interface Props {
|
|||||||
export default function AssignmentsPage({assignments, corporateAssignments, entities, user, users, groups}: Props) {
|
export default function AssignmentsPage({assignments, corporateAssignments, entities, user, users, groups}: Props) {
|
||||||
const entitiesAllowCreate = useAllowedEntities(user, entities, 'create_assignment')
|
const entitiesAllowCreate = useAllowedEntities(user, entities, 'create_assignment')
|
||||||
const entitiesAllowEdit = useAllowedEntities(user, entities, 'edit_assignment')
|
const entitiesAllowEdit = useAllowedEntities(user, entities, 'edit_assignment')
|
||||||
|
const entitiesAllowArchive = useAllowedEntities(user, entities, 'archive_assignment')
|
||||||
|
|
||||||
const activeAssignments = useMemo(() => assignments.filter(activeAssignmentFilter), [assignments]);
|
const activeAssignments = useMemo(() => assignments.filter(activeAssignmentFilter), [assignments]);
|
||||||
const plannedAssignments = useMemo(() => assignments.filter(futureAssignmentFilter), [assignments]);
|
const plannedAssignments = useMemo(() => assignments.filter(futureAssignmentFilter), [assignments]);
|
||||||
@@ -177,7 +178,7 @@ export default function AssignmentsPage({assignments, corporateAssignments, enti
|
|||||||
onClick={() => router.push(`/assignments/${a.id}`)}
|
onClick={() => router.push(`/assignments/${a.id}`)}
|
||||||
key={a.id}
|
key={a.id}
|
||||||
allowDownload
|
allowDownload
|
||||||
allowArchive
|
allowArchive={mapBy(entitiesAllowArchive, 'id').includes(a.entity || "")}
|
||||||
allowExcelDownload
|
allowExcelDownload
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
@@ -197,7 +198,7 @@ export default function AssignmentsPage({assignments, corporateAssignments, enti
|
|||||||
onClick={() => router.push(`/assignments/${a.id}`)}
|
onClick={() => router.push(`/assignments/${a.id}`)}
|
||||||
key={a.id}
|
key={a.id}
|
||||||
allowDownload
|
allowDownload
|
||||||
allowArchive
|
allowArchive={mapBy(entitiesAllowArchive, 'id').includes(a.entity || "")}
|
||||||
allowExcelDownload
|
allowExcelDownload
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import { checkAccess } from "@/utils/permissions";
|
|||||||
import { calculateAverageLevel, calculateBandScore } from "@/utils/score";
|
import { calculateAverageLevel, calculateBandScore } from "@/utils/score";
|
||||||
import { groupByExam } from "@/utils/stats";
|
import { groupByExam } from "@/utils/stats";
|
||||||
import { getStatsByUsers } from "@/utils/stats.be";
|
import { getStatsByUsers } from "@/utils/stats.be";
|
||||||
|
import { filterAllowedUsers } from "@/utils/users.be";
|
||||||
import { getEntitiesUsers } from "@/utils/users.be";
|
import { getEntitiesUsers } from "@/utils/users.be";
|
||||||
import { withIronSessionSsr } from "iron-session/next";
|
import { withIronSessionSsr } from "iron-session/next";
|
||||||
import { uniqBy } from "lodash";
|
import { uniqBy } from "lodash";
|
||||||
@@ -52,9 +53,9 @@ export const getServerSideProps = withIronSessionSsr(async ({ req, res }) => {
|
|||||||
if (!checkAccess(user, ["admin", "developer", "corporate"])) return redirect("/")
|
if (!checkAccess(user, ["admin", "developer", "corporate"])) return redirect("/")
|
||||||
|
|
||||||
const entityIDS = mapBy(user.entities, "id") || [];
|
const entityIDS = mapBy(user.entities, "id") || [];
|
||||||
|
|
||||||
const users = await getEntitiesUsers(entityIDS);
|
|
||||||
const entities = await getEntitiesWithRoles(entityIDS);
|
const entities = await getEntitiesWithRoles(entityIDS);
|
||||||
|
const users = await filterAllowedUsers(user, entities)
|
||||||
|
|
||||||
const assignments = await getEntitiesAssignments(entityIDS);
|
const assignments = await getEntitiesAssignments(entityIDS);
|
||||||
const stats = await getStatsByUsers(users.map((u) => u.id));
|
const stats = await getStatsByUsers(users.map((u) => u.id));
|
||||||
const groups = await getGroupsByEntities(entityIDS);
|
const groups = await getGroupsByEntities(entityIDS);
|
||||||
|
|||||||
@@ -12,10 +12,11 @@ import { requestUser } from "@/utils/api";
|
|||||||
import { getEntitiesAssignments } from "@/utils/assignments.be";
|
import { getEntitiesAssignments } from "@/utils/assignments.be";
|
||||||
import { getEntitiesWithRoles } from "@/utils/entities.be";
|
import { getEntitiesWithRoles } from "@/utils/entities.be";
|
||||||
import { getGroupsByEntities } from "@/utils/groups.be";
|
import { getGroupsByEntities } from "@/utils/groups.be";
|
||||||
import { checkAccess } from "@/utils/permissions";
|
import { checkAccess, findAllowedEntities } from "@/utils/permissions";
|
||||||
import { calculateAverageLevel, calculateBandScore } from "@/utils/score";
|
import { calculateAverageLevel, calculateBandScore } from "@/utils/score";
|
||||||
import { groupByExam } from "@/utils/stats";
|
import { groupByExam } from "@/utils/stats";
|
||||||
import { getStatsByUsers } from "@/utils/stats.be";
|
import { getStatsByUsers } from "@/utils/stats.be";
|
||||||
|
import { filterAllowedUsers } from "@/utils/users.be";
|
||||||
import { getEntitiesUsers } from "@/utils/users.be";
|
import { getEntitiesUsers } from "@/utils/users.be";
|
||||||
import { withIronSessionSsr } from "iron-session/next";
|
import { withIronSessionSsr } from "iron-session/next";
|
||||||
import { uniqBy } from "lodash";
|
import { uniqBy } from "lodash";
|
||||||
@@ -55,9 +56,9 @@ export const getServerSideProps = withIronSessionSsr(async ({ req, res }) => {
|
|||||||
return redirect("/")
|
return redirect("/")
|
||||||
|
|
||||||
const entityIDS = mapBy(user.entities, "id") || [];
|
const entityIDS = mapBy(user.entities, "id") || [];
|
||||||
|
|
||||||
const users = await getEntitiesUsers(entityIDS);
|
|
||||||
const entities = await getEntitiesWithRoles(entityIDS);
|
const entities = await getEntitiesWithRoles(entityIDS);
|
||||||
|
const users = await filterAllowedUsers(user, entities)
|
||||||
|
|
||||||
const assignments = await getEntitiesAssignments(entityIDS);
|
const assignments = await getEntitiesAssignments(entityIDS);
|
||||||
const stats = await getStatsByUsers(users.map((u) => u.id));
|
const stats = await getStatsByUsers(users.map((u) => u.id));
|
||||||
const groups = await getGroupsByEntities(entityIDS);
|
const groups = await getGroupsByEntities(entityIDS);
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import { dateSorter, filterBy, mapBy, redirect, serialize } from "@/utils";
|
|||||||
import { getEntitiesAssignments } from "@/utils/assignments.be";
|
import { getEntitiesAssignments } from "@/utils/assignments.be";
|
||||||
import { getEntitiesWithRoles } from "@/utils/entities.be";
|
import { getEntitiesWithRoles } from "@/utils/entities.be";
|
||||||
import { getGroupsByEntities } from "@/utils/groups.be";
|
import { getGroupsByEntities } from "@/utils/groups.be";
|
||||||
import { checkAccess } from "@/utils/permissions";
|
import { checkAccess, findAllowedEntities } from "@/utils/permissions";
|
||||||
import { calculateAverageLevel, calculateBandScore } from "@/utils/score";
|
import { calculateAverageLevel, calculateBandScore } from "@/utils/score";
|
||||||
import { groupByExam } from "@/utils/stats";
|
import { groupByExam } from "@/utils/stats";
|
||||||
import { getStatsByUsers } from "@/utils/stats.be";
|
import { getStatsByUsers } from "@/utils/stats.be";
|
||||||
@@ -24,6 +24,8 @@ import { useMemo } from "react";
|
|||||||
import { BsClipboard2Data, BsEnvelopePaper, BsPaperclip, BsPeople, BsPersonFill } from "react-icons/bs";
|
import { BsClipboard2Data, BsEnvelopePaper, BsPaperclip, BsPeople, BsPersonFill } from "react-icons/bs";
|
||||||
import { ToastContainer } from "react-toastify";
|
import { ToastContainer } from "react-toastify";
|
||||||
import { requestUser } from "@/utils/api";
|
import { requestUser } from "@/utils/api";
|
||||||
|
import { useAllowedEntities } from "@/hooks/useEntityPermissions";
|
||||||
|
import { filterAllowedUsers } from "@/utils/users.be";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
user: User;
|
user: User;
|
||||||
@@ -42,9 +44,9 @@ export const getServerSideProps = withIronSessionSsr(async ({ req, res }) => {
|
|||||||
return redirect("/")
|
return redirect("/")
|
||||||
|
|
||||||
const entityIDS = mapBy(user.entities, "id") || [];
|
const entityIDS = mapBy(user.entities, "id") || [];
|
||||||
|
|
||||||
const users = await getEntitiesUsers(entityIDS);
|
|
||||||
const entities = await getEntitiesWithRoles(entityIDS);
|
const entities = await getEntitiesWithRoles(entityIDS);
|
||||||
|
const users = await filterAllowedUsers(user, entities)
|
||||||
|
|
||||||
const assignments = await getEntitiesAssignments(entityIDS);
|
const assignments = await getEntitiesAssignments(entityIDS);
|
||||||
const stats = await getStatsByUsers(users.map((u) => u.id));
|
const stats = await getStatsByUsers(users.map((u) => u.id));
|
||||||
const groups = await getGroupsByEntities(entityIDS);
|
const groups = await getGroupsByEntities(entityIDS);
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ export function findAllowedEntitiesSomePermissions(user: User, entities: EntityW
|
|||||||
export function doesEntityAllow(user: User, entity: EntityWithRoles, permission: RolePermission) {
|
export function doesEntityAllow(user: User, entity: EntityWithRoles, permission: RolePermission) {
|
||||||
if (["admin", "developer"].includes(user?.type)) return true
|
if (["admin", "developer"].includes(user?.type)) return true
|
||||||
|
|
||||||
const userEntity = findBy(user.entities, 'id', entity.id)
|
const userEntity = findBy(user.entities, 'id', entity?.id)
|
||||||
if (!userEntity) return false
|
if (!userEntity) return false
|
||||||
|
|
||||||
const role = findBy(entity.roles, 'id', userEntity.role)
|
const role = findBy(entity.roles, 'id', userEntity.role)
|
||||||
|
|||||||
@@ -3,9 +3,11 @@ import { getGroupsForUser, getParticipantGroups, getUserGroups, getUsersGroups }
|
|||||||
import { uniq } from "lodash";
|
import { uniq } from "lodash";
|
||||||
import { getUserCodes } from "./codes.be";
|
import { getUserCodes } from "./codes.be";
|
||||||
import client from "@/lib/mongodb";
|
import client from "@/lib/mongodb";
|
||||||
import { WithEntities } from "@/interfaces/entity";
|
import { EntityWithRoles, WithEntities } from "@/interfaces/entity";
|
||||||
import { getEntity } from "./entities.be";
|
import { getEntity } from "./entities.be";
|
||||||
import { getRole } from "./roles.be";
|
import { getRole } from "./roles.be";
|
||||||
|
import { findAllowedEntities } from "./permissions";
|
||||||
|
import { mapBy } from ".";
|
||||||
|
|
||||||
const db = client.db(process.env.MONGODB_DB);
|
const db = client.db(process.env.MONGODB_DB);
|
||||||
|
|
||||||
@@ -138,3 +140,17 @@ export async function getUserBalance(user: User) {
|
|||||||
codes.filter((x) => !participants.includes(x.userId || "") && !corporateUsers.map((u) => u.id).includes(x.userId || "")).length
|
codes.filter((x) => !participants.includes(x.userId || "") && !corporateUsers.map((u) => u.id).includes(x.userId || "")).length
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const filterAllowedUsers = async (user: User, entities: EntityWithRoles[]) => {
|
||||||
|
const studentsAllowedEntities = findAllowedEntities(user, entities, 'view_students')
|
||||||
|
const teachersAllowedEntities = findAllowedEntities(user, entities, 'view_teachers')
|
||||||
|
const corporateAllowedEntities = findAllowedEntities(user, entities, 'view_corporates')
|
||||||
|
const masterCorporateAllowedEntities = findAllowedEntities(user, entities, 'view_mastercorporates')
|
||||||
|
|
||||||
|
const students = await getEntitiesUsers(mapBy(studentsAllowedEntities, 'id'), {type: "student"})
|
||||||
|
const teachers = await getEntitiesUsers(mapBy(teachersAllowedEntities, 'id'), {type: "teacher"})
|
||||||
|
const corporates = await getEntitiesUsers(mapBy(corporateAllowedEntities, 'id'), {type: "corporate"})
|
||||||
|
const masterCorporates = await getEntitiesUsers(mapBy(masterCorporateAllowedEntities, 'id'), {type: "mastercorporate"})
|
||||||
|
|
||||||
|
return [...students, ...teachers, ...corporates, ...masterCorporates]
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
import { WithLabeledEntities } from "@/interfaces/entity";
|
import { EntityWithRoles, WithLabeledEntities } from "@/interfaces/entity";
|
||||||
import { Group, User } from "@/interfaces/user";
|
import { Group, User } from "@/interfaces/user";
|
||||||
import { getUserCompanyName, USER_TYPE_LABELS } from "@/resources/user";
|
import { getUserCompanyName, USER_TYPE_LABELS } from "@/resources/user";
|
||||||
import { capitalize } from "lodash";
|
import { capitalize } from "lodash";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
|
import { mapBy } from ".";
|
||||||
|
import { findAllowedEntities } from "./permissions";
|
||||||
|
import { getEntitiesUsers } from "./users.be";
|
||||||
|
|
||||||
export interface UserListRow {
|
export interface UserListRow {
|
||||||
name: string;
|
name: string;
|
||||||
|
|||||||
Reference in New Issue
Block a user