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 = () => {
>