diff --git a/FRONTEND/src/components/Navbar/Navbar.tsx b/FRONTEND/src/components/Navbar/Navbar.tsx index 48e4687..86c2751 100755 --- a/FRONTEND/src/components/Navbar/Navbar.tsx +++ b/FRONTEND/src/components/Navbar/Navbar.tsx @@ -38,12 +38,13 @@ import { IconSun, IconTicket, IconUsersGroup, - IconZoomExclamation + IconZoomExclamation, } from '@tabler/icons-react' import { useCallback, useEffect, useState } from 'react' import { useLocation, useNavigate } from 'react-router-dom' import PasswordRequirementInput from '../PasswordRequirementInput/PasswordRequirementInput' import classes from './NavbarSimpleColored.module.css' +import { checkPermissions } from '@/utils/checkRoles' const data = [ // { link: '/dashboard', label: 'Dashboard', icon: IconHome }, @@ -51,67 +52,84 @@ const data = [ link: '/timekeeping', label: 'Timekeeping', icon: IconCalendar, - group: 'normal', + permissions: 'admin,hr,staff,tester', + group: 'staff', }, { link: '/tracking', label: 'Check in/out', icon: IconScan, - group: 'admin', + permissions: 'hr,admin', + group: 'other', }, { link: '/worklogs', label: 'Worklogs', icon: IconReport, - group: 'normal', + permissions: 'admin,hr,staff,tester', + group: 'staff', }, { link: '/leave-management', label: 'Leave Management', icon: IconCalendarClock, - group: 'normal', + permissions: 'admin,hr,staff,tester', + group: 'staff', + }, + { + link: '/tickets', + label: 'Tickets', + icon: IconTicket, + permissions: 'admin,hr,staff,tester', + group: 'staff', }, - { link: '/tickets', label: 'Tickets', icon: IconTicket, group: 'normal' }, { link: '/tickets-management', label: 'Tickets Management', icon: IconDevices, - group: 'admin', + permissions: 'hr,admin', + group: 'other', }, { link: '/users', label: 'Users Management', icon: IconUsersGroup, + permissions: 'admin', group: 'admin', }, { link: '/sprint-review', label: 'Sprint Review', icon: IconListCheck, + permissions: 'admin', group: 'admin', }, { link: '/test-report', label: 'Test Report', icon: IconZoomExclamation, - group: 'admin', + permissions: 'admin,tester', + group: 'test', }, { link: '/allocation', label: 'Personnel allocation', icon: IconBinaryTree2, - group: 'normal', + permissions: 'admin,hr,staff,tester', + group: 'staff', }, { link: '/profile', label: 'Profile', icon: IconZoomExclamation, + permissions: 'hidden', group: 'hidden', }, { link: '/staff-avaluation', label: 'Staff evaluation', icon: IconChartDots2, + permissions: 'admin', group: 'admin', }, // { link: '/jira', label: 'Jira', icon: IconSubtask }, @@ -205,22 +223,17 @@ const Navbar = ({ // }) const group = [ - { name: 'normal', label: 'Normal' }, - { name: 'admin', label: 'Admin' }, + { name: 'staff', label: 'General', permissions: 'admin,hr,staff,tester' }, + { name: 'admin', label: 'Admin', permissions: 'admin' }, + { name: 'other', label: 'Other', permissions: 'admin,hr' }, + { name: 'test', label: 'Test', permissions: 'admin,tester' }, ] const links = group.map((g) => { return (
{g.label} @@ -229,12 +242,7 @@ const Navbar = ({ /> {data .filter((i) => { - return ( - i.group === g.name && - (user?.user?.permission.includes('admin') || - user?.user?.permission.includes('hr') || - g.name !== 'admin') - ) + return i.group === g.name && checkPermissions(i.permissions) }) .map((item) => ( { - // setHeader(item.label); setActive(active) if (active !== item.label) { navigate(item.link) diff --git a/FRONTEND/src/pages/StaffEvaluation/StaffEvaluation.tsx b/FRONTEND/src/pages/StaffEvaluation/StaffEvaluation.tsx index 73a3354..7385685 100644 --- a/FRONTEND/src/pages/StaffEvaluation/StaffEvaluation.tsx +++ b/FRONTEND/src/pages/StaffEvaluation/StaffEvaluation.tsx @@ -2,15 +2,14 @@ import { evaluation, getAllTechByUserId, getAllUser, - sprintReview + sprintReview, } from '@/api/Admin' import DataTableAll from '@/components/DataTable/DataTable' import ProjectInvolvement from '@/components/ProjectInvolvement/ProjectInvolvement' -import { get } from '@/rtk/helpers/apiService' +import { get, getDownloadFile } from '@/rtk/helpers/apiService' import { Box, Button, Loader, Select, Text, Title } from '@mantine/core' import { DateInput } from '@mantine/dates' import { notifications } from '@mantine/notifications' -import axios from 'axios' import moment from 'moment' import { useEffect, useState } from 'react' import classes from './StaffEvaluation.module.css' @@ -53,8 +52,6 @@ const StaffEvaluation = () => { toDate: null, }) - console.log(filter, 'filter') - const getListUser = async () => { try { const params = {} @@ -72,35 +69,46 @@ const StaffEvaluation = () => { return [] } + function getFormattedDateTime(): string { + const now = new Date() + const year = now.getFullYear() + const month = String(now.getMonth() + 1).padStart(2, '0') // Tháng bắt đầu từ 0 + const day = String(now.getDate()).padStart(2, '0') + const hours = String(now.getHours()).padStart(2, '0') + const minutes = String(now.getMinutes()).padStart(2, '0') + const seconds = String(now.getSeconds()).padStart(2, '0') + + return `${year}${month}${day}${hours}${minutes}${seconds}` + } + const downloadFile = async () => { - await axios({ - url: evaluation, - method: 'GET', - responseType: 'blob', - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwMDAvYXBpL3YxL2FkbWluL2xvZ2luIiwiaWF0IjoxNzI2ODE3ODU3LCJleHAiOjE3MjY5MDQyNTcsIm5iZiI6MTcyNjgxNzg1NywianRpIjoid0kzeXM5SGZiV21wS3pONSIsInN1YiI6IjE2IiwicHJ2IjoiZDJmZjI5MzM5YThhM2U4MmMzNTgyYTVhOGU3MzlkZjE3ODliYjEyZiJ9.oEHW0cIlQkawYQMVZnz5TZ5twzY18301eLmXjC55LfY`, - }, - params: { - ...filter, - userID: 3, - }, - }) - .then((response) => { - const fileURL = window.URL.createObjectURL(new Blob([response.data])) + try { + const params = { + userID: filter.userID, + } + const res = await getDownloadFile(evaluation, params) + + if (res.status) { + const fileURL = window.URL.createObjectURL(new Blob([res.data])) const fileLink = document.createElement('a') + const fileName = `EXPORT_SPRINT_REVIEW_AND_TECHNICAL_EVALUATION_${getFormattedDateTime()}.docx` + fileLink.href = fileURL - fileLink.setAttribute('download', 'RENAME_WORD_FILE.docx') // -------------> RENAME_WORD_FILE + fileLink.setAttribute('download', fileName) document.body.appendChild(fileLink) fileLink.click() - fileLink.remove() + } + } catch (error: any) { + notifications.show({ + title: 'Error', + message: error.message ?? error, + color: 'red', }) - .catch((error) => { - console.error('Error downloading the file:', error) - }) + } + return [] } useEffect(() => { @@ -224,16 +232,17 @@ const StaffEvaluation = () => { size: '25%', header: 'Last update', render: (row: any) => { - return ( -
- {moment(row?.updated_at).format('DD/MM/YYYY HH:mm:ss')} -
- ) + if (row?.updated_at) + return ( +
+ {moment(row?.updated_at).format('DD/MM/YYYY HH:mm:ss')} +
+ ) }, }, ] @@ -302,6 +311,7 @@ const StaffEvaluation = () => { >