Sprint-3/MS-26 #23
|
|
@ -35,6 +35,7 @@ import {
|
|||
IconSun,
|
||||
IconTicket,
|
||||
IconUsersGroup,
|
||||
IconZoomExclamation,
|
||||
} from '@tabler/icons-react'
|
||||
import { useCallback, useEffect, useState } from 'react'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
|
|
@ -87,6 +88,12 @@ const data = [
|
|||
icon: IconListCheck,
|
||||
group: 'admin',
|
||||
},
|
||||
{
|
||||
link: '/test-report',
|
||||
label: 'Test Report',
|
||||
icon: IconZoomExclamation,
|
||||
group: 'admin',
|
||||
},
|
||||
// { link: '/jira', label: 'Jira', icon: IconSubtask },
|
||||
// { link: '/custom-theme', label: 'Custom Theme', icon: IconBrush },
|
||||
// { link: '/general-setting', label: 'General Setting', icon: IconSettings },
|
||||
|
|
@ -184,7 +191,8 @@ const Navbar = ({
|
|||
display={
|
||||
g.name === 'normal'
|
||||
? 'block'
|
||||
: (user?.user?.permission.includes(g.name) || user?.user?.permission.includes('hr'))
|
||||
: user?.user?.permission.includes(g.name) ||
|
||||
user?.user?.permission.includes('hr')
|
||||
? 'block'
|
||||
: 'none'
|
||||
}
|
||||
|
|
@ -198,7 +206,9 @@ const Navbar = ({
|
|||
.filter((i) => {
|
||||
return (
|
||||
i.group === g.name &&
|
||||
((user?.user?.permission.includes('admin') || user?.user?.permission.includes('hr')) || g.name !== 'admin')
|
||||
(user?.user?.permission.includes('admin') ||
|
||||
user?.user?.permission.includes('hr') ||
|
||||
g.name !== 'admin')
|
||||
)
|
||||
})
|
||||
.map((item) => (
|
||||
|
|
@ -301,10 +311,18 @@ const Navbar = ({
|
|||
|
||||
const renderQRCode = async () => {
|
||||
try {
|
||||
const res = await get(getQRCode+"/"+user?.user?.id)
|
||||
if(res.status){
|
||||
window.open(import.meta.env.VITE_BACKEND_URL.includes('localhost')?`${import.meta.env.VITE_BACKEND_URL}storage/qrcode/qrcode_${user?.user?.id}.svg`:
|
||||
`${import.meta.env.VITE_BACKEND_URL}image/storage/qrcode/qrcode_${user?.user?.id}.svg`, '_blank');
|
||||
const res = await get(getQRCode + '/' + user?.user?.id)
|
||||
if (res.status) {
|
||||
window.open(
|
||||
import.meta.env.VITE_BACKEND_URL.includes('localhost')
|
||||
? `${import.meta.env.VITE_BACKEND_URL}storage/qrcode/qrcode_${
|
||||
user?.user?.id
|
||||
}.svg`
|
||||
: `${import.meta.env.VITE_BACKEND_URL}image/storage/qrcode/qrcode_${
|
||||
user?.user?.id
|
||||
}.svg`,
|
||||
'_blank',
|
||||
)
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
|
|
@ -324,7 +342,17 @@ const Navbar = ({
|
|||
{user.user.name}
|
||||
</Code>
|
||||
<Tooltip label="Your QR code" fz={'xs'}>
|
||||
<IconQrcode onClick={()=>renderQRCode()} color='#fff164' width={28} height={28} style={{border: "solid 2px orange", borderRadius: '5px', cursor:'pointer'}}/>
|
||||
<IconQrcode
|
||||
onClick={() => renderQRCode()}
|
||||
color="#fff164"
|
||||
width={28}
|
||||
height={28}
|
||||
style={{
|
||||
border: 'solid 2px orange',
|
||||
borderRadius: '5px',
|
||||
cursor: 'pointer',
|
||||
}}
|
||||
/>
|
||||
</Tooltip>
|
||||
</Group>
|
||||
{links}
|
||||
|
|
|
|||
|
|
@ -1,33 +1,19 @@
|
|||
import { createOrUpdateUser } from '@/api/Admin'
|
||||
import { ButtonCopy } from '@/components/CopyClipboard/CopyClipboard'
|
||||
import { post } from '@/rtk/helpers/apiService'
|
||||
import { update } from '@/rtk/helpers/CRUD'
|
||||
import { TUser } from '@/variables/types'
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Code,
|
||||
Dialog,
|
||||
Group,
|
||||
Modal,
|
||||
MultiSelect,
|
||||
Select,
|
||||
Table,
|
||||
Text,
|
||||
TextInput,
|
||||
Title,
|
||||
Title
|
||||
} from '@mantine/core'
|
||||
import { useForm } from '@mantine/form'
|
||||
import { notifications } from '@mantine/notifications'
|
||||
import { useEffect, useState } from 'react'
|
||||
import classes from './SprintReview.module.css'
|
||||
|
||||
const SprintReview = () => {
|
||||
// const [users, setUsers] = useState<TUser[]>([])
|
||||
const [action, setAction] = useState('')
|
||||
const [activeBtn, setActiveBtn] = useState(false)
|
||||
// const [item, setItem] = useState({ id: 0 })
|
||||
const [disableBtn, setDisableBtn] = useState(false)
|
||||
const [info, setInfo] = useState('')
|
||||
// const [action, setAction] = useState('')
|
||||
// const [info, setInfo] = useState('')
|
||||
const [filter, setFilter] = useState({
|
||||
typeReason: '',
|
||||
statusFilter: '',
|
||||
|
|
@ -68,14 +54,14 @@ const SprintReview = () => {
|
|||
// fetchData()
|
||||
// }, [])
|
||||
|
||||
const form = useForm({
|
||||
initialValues: {
|
||||
id: 0,
|
||||
name: '',
|
||||
email: '',
|
||||
permission: '',
|
||||
},
|
||||
})
|
||||
// const form = useForm({
|
||||
// initialValues: {
|
||||
// id: 0,
|
||||
// name: '',
|
||||
// email: '',
|
||||
// permission: '',
|
||||
// },
|
||||
// })
|
||||
|
||||
// const getAll = async () => {
|
||||
// try {
|
||||
|
|
@ -88,36 +74,36 @@ const SprintReview = () => {
|
|||
// }
|
||||
// }
|
||||
|
||||
const handleCreate = async (values: TUser) => {
|
||||
try {
|
||||
const { id, ...data } = values
|
||||
const res = await post(createOrUpdateUser, data)
|
||||
if (res.status === true) {
|
||||
setAction('review')
|
||||
form.reset()
|
||||
// getAll()
|
||||
setInfo(JSON.stringify(res.data, null, 2))
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
// const handleCreate = async (values: TUser) => {
|
||||
// try {
|
||||
// const { id, ...data } = values
|
||||
// const res = await post(createOrUpdateUser, data)
|
||||
// if (res.status === true) {
|
||||
// // setAction('review')
|
||||
// form.reset()
|
||||
// // getAll()
|
||||
// // setInfo(JSON.stringify(res.data, null, 2))
|
||||
// }
|
||||
// } catch (error) {
|
||||
// console.log(error)
|
||||
// }
|
||||
// }
|
||||
|
||||
const handleUpdate = async (values: TUser) => {
|
||||
try {
|
||||
const res = await update(
|
||||
createOrUpdateUser,
|
||||
values,
|
||||
// , getAll
|
||||
)
|
||||
if (res === true) {
|
||||
setAction('')
|
||||
form.reset()
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
// const handleUpdate = async (values: TUser) => {
|
||||
// try {
|
||||
// const res = await update(
|
||||
// createOrUpdateUser,
|
||||
// values,
|
||||
// // , getAll
|
||||
// )
|
||||
// if (res === true) {
|
||||
// // setAction('')
|
||||
// form.reset()
|
||||
// }
|
||||
// } catch (error) {
|
||||
// console.log(error)
|
||||
// }
|
||||
// }
|
||||
|
||||
// const handleDelete = async (id: number) => {
|
||||
// try {
|
||||
|
|
@ -156,8 +142,13 @@ const SprintReview = () => {
|
|||
</h3>
|
||||
<Button
|
||||
onClick={() => {
|
||||
setAction('add')
|
||||
form.reset()
|
||||
notifications.show({
|
||||
title: 'Success',
|
||||
message: 'Intergate api update',
|
||||
color: 'green',
|
||||
})
|
||||
// setAction('add')
|
||||
// form.reset()
|
||||
}}
|
||||
>
|
||||
Update
|
||||
|
|
@ -343,151 +334,6 @@ const SprintReview = () => {
|
|||
</Table.Tbody>
|
||||
</Table>
|
||||
</Box>
|
||||
|
||||
{/* Add/Edit User modal */}
|
||||
<Modal
|
||||
opened={action === 'add' || action === 'edit'}
|
||||
onClose={() => {
|
||||
setAction('')
|
||||
form.reset()
|
||||
}}
|
||||
title={
|
||||
<Text pl={'sm'} fw={700} fz={'lg'}>
|
||||
{action === 'add' ? 'Add User' : 'Update User'}
|
||||
</Text>
|
||||
}
|
||||
>
|
||||
<form
|
||||
onSubmit={form.onSubmit(async (values) => {
|
||||
setDisableBtn(true)
|
||||
action === 'edit'
|
||||
? await handleUpdate(values)
|
||||
: await handleCreate(values)
|
||||
setDisableBtn(false)
|
||||
})}
|
||||
>
|
||||
<Box pl={'md'} pr={'md'}>
|
||||
<TextInput
|
||||
label="Name"
|
||||
mb={'md'}
|
||||
value={form.values.name}
|
||||
error={form.errors.name}
|
||||
onChange={(e) => form.setFieldValue('name', e.target.value)}
|
||||
/>
|
||||
|
||||
<TextInput
|
||||
label="Email"
|
||||
mb={'md'}
|
||||
value={form.values.email}
|
||||
error={form.errors.email}
|
||||
onChange={(e) => form.setFieldValue('email', e.target.value)}
|
||||
/>
|
||||
|
||||
<MultiSelect
|
||||
label={'Permission(s)'}
|
||||
required
|
||||
data={['staff', 'admin', 'hr']}
|
||||
value={
|
||||
typeof form.values.permission === 'string'
|
||||
? form.values.permission
|
||||
.split(',')
|
||||
.filter((p) => p.trim() !== '')
|
||||
: form.values.permission
|
||||
}
|
||||
error={form.errors.permisstion}
|
||||
onChange={(e) =>
|
||||
form.setFieldValue(
|
||||
'permission',
|
||||
e!.filter((p) => p.trim() !== '').join(','),
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Box ta={'center'}>
|
||||
{action === 'add' ? (
|
||||
<Button
|
||||
mt={'lg'}
|
||||
bg={'green'}
|
||||
type="submit"
|
||||
disabled={disableBtn}
|
||||
>
|
||||
Create
|
||||
</Button>
|
||||
) : (
|
||||
<Button
|
||||
mt={'lg'}
|
||||
bg={'green'}
|
||||
type="submit"
|
||||
disabled={disableBtn}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
)}
|
||||
</Box>
|
||||
</Box>
|
||||
</form>
|
||||
</Modal>
|
||||
|
||||
<Modal
|
||||
opened={action === 'review'}
|
||||
onClose={() => {
|
||||
setAction('')
|
||||
}}
|
||||
size={'lg'}
|
||||
title={
|
||||
<Text pl={'sm'} fw={700} fz={'lg'}>
|
||||
Information to get started
|
||||
</Text>
|
||||
}
|
||||
>
|
||||
<Text c={'red'} fz={'sm'} fw={700}>
|
||||
!! Important note: Please remind user to change password after logging
|
||||
in !!
|
||||
</Text>
|
||||
<Code block>
|
||||
<Box ta={'right'}>
|
||||
<ButtonCopy value={info} />
|
||||
</Box>
|
||||
{info}
|
||||
</Code>
|
||||
</Modal>
|
||||
|
||||
<Dialog
|
||||
className={classes.dialog}
|
||||
opened={action === 'delete'}
|
||||
withCloseButton
|
||||
onClose={() => setAction('')}
|
||||
size="lg"
|
||||
radius="md"
|
||||
position={{ top: 30, right: 10 }}
|
||||
>
|
||||
<Text className={classes.dialogText} size="sm" mb="xs" fw={500}>
|
||||
Do you want to delete this user?
|
||||
<Group justify="center" m={10}>
|
||||
<Button
|
||||
disabled={activeBtn}
|
||||
fw={700}
|
||||
size="xs"
|
||||
variant="light"
|
||||
onClick={async () => {
|
||||
setActiveBtn(true)
|
||||
// await handleDelete(item.id)
|
||||
setActiveBtn(false)
|
||||
setAction('')
|
||||
}}
|
||||
>
|
||||
Yes
|
||||
</Button>
|
||||
<Button
|
||||
fw={700}
|
||||
size="xs"
|
||||
variant="light"
|
||||
onClick={() => setAction('')}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
</Group>
|
||||
</Text>
|
||||
</Dialog>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
.title {
|
||||
background-color: light-dark(var(white), var(--mantine-color-dark-7));
|
||||
z-index: 100;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 var(--mantine-spacing-sm) var(--mantine-spacing-lg)
|
||||
var(--mantine-spacing-sm);
|
||||
border-bottom: solid rgba(201, 201, 201, 0.377) 1px;
|
||||
}
|
||||
|
||||
.optionIcon {
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
|
||||
.deleteIcon {
|
||||
color: red;
|
||||
cursor: pointer;
|
||||
padding: 2px;
|
||||
border-radius: 25%;
|
||||
}
|
||||
|
||||
.editIcon {
|
||||
color: rgb(9, 132, 132);
|
||||
cursor: pointer;
|
||||
padding: 2px;
|
||||
border-radius: 25%;
|
||||
}
|
||||
|
||||
.editIcon:hover {
|
||||
background-color: rgba(203, 203, 203, 0.809);
|
||||
}
|
||||
|
||||
.deleteIcon:hover {
|
||||
background-color: rgba(203, 203, 203, 0.809);
|
||||
}
|
||||
|
||||
.dialog {
|
||||
background-color: light-dark(white, #2d353c);
|
||||
text-align: center;
|
||||
border: solid 1px rgb(255, 145, 0);
|
||||
}
|
||||
|
||||
.dialogText {
|
||||
color: light-dark(#2d353c, white);
|
||||
}
|
||||
|
|
@ -0,0 +1,548 @@
|
|||
import { TUser } from '@/variables/types'
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Dialog,
|
||||
Group,
|
||||
Modal,
|
||||
Select,
|
||||
Table,
|
||||
Text,
|
||||
Textarea,
|
||||
TextInput,
|
||||
Title,
|
||||
} from '@mantine/core'
|
||||
import { useForm } from '@mantine/form'
|
||||
import { IconInfoSquare, IconSquareXFilled } from '@tabler/icons-react'
|
||||
import { useEffect, useState } from 'react'
|
||||
import classes from './TestReport.module.css'
|
||||
|
||||
const TestReport = () => {
|
||||
// const [users, setUsers] = useState<TUser[]>([])
|
||||
const [action, setAction] = useState('')
|
||||
const [activeBtn, setActiveBtn] = useState(false)
|
||||
// const [item, setItem] = useState({ id: 0 })
|
||||
const [disableBtn, setDisableBtn] = useState(false)
|
||||
// const [info, setInfo] = useState('')
|
||||
const [filter, setFilter] = useState({
|
||||
typeReason: '',
|
||||
statusFilter: '',
|
||||
})
|
||||
// const [dataTimeType, setDataTimeType] = useState<DataTimeType[]>([])
|
||||
// const [dataReason, setDataReason] = useState<DataReason[]>([])
|
||||
|
||||
// const getListMasterByType = async (type: string) => {
|
||||
// try {
|
||||
// const params = {
|
||||
// type: type,
|
||||
// }
|
||||
// const res = await get(getListMaster, params)
|
||||
// if (res.status) {
|
||||
// return res.data
|
||||
// }
|
||||
// } catch (error: any) {
|
||||
// notifications.show({
|
||||
// title: 'Error',
|
||||
// message: error.message ?? error,
|
||||
// color: 'red',
|
||||
// })
|
||||
// }
|
||||
// return []
|
||||
// }
|
||||
|
||||
// useEffect(() => {
|
||||
// const fetchData = async () => {
|
||||
// const resultTimeType = await getListMasterByType('TIME_TYPE')
|
||||
// setDataTimeType(
|
||||
// resultTimeType.filter((item: DataTimeType) => item.c_code !== 'ALL'),
|
||||
// )
|
||||
|
||||
// const resultReason = await getListMasterByType('REASON')
|
||||
// setDataReason(resultReason)
|
||||
// }
|
||||
|
||||
// fetchData()
|
||||
// }, [])
|
||||
|
||||
const form = useForm({
|
||||
initialValues: {
|
||||
id: 0,
|
||||
name: '',
|
||||
email: '',
|
||||
permission: '',
|
||||
},
|
||||
})
|
||||
|
||||
// const getAll = async () => {
|
||||
// try {
|
||||
// const res = await get(getAllUsers)
|
||||
// if (res.status) {
|
||||
// setUsers(res.data)
|
||||
// }
|
||||
// } catch (error) {
|
||||
// console.log(error)
|
||||
// }
|
||||
// }
|
||||
|
||||
const handleCreate = async (values: TUser) => {
|
||||
try {
|
||||
const { id, ...data } = values
|
||||
console.log(data, 'data')
|
||||
|
||||
// const res = await post(createOrUpdateUser, data)
|
||||
// if (res.status === true) {
|
||||
// setAction('review')
|
||||
// form.reset()
|
||||
// // getAll()
|
||||
// setInfo(JSON.stringify(res.data, null, 2))
|
||||
// }
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
|
||||
const handleDelete = async (id: number) => {
|
||||
try {
|
||||
const data = {
|
||||
id: id,
|
||||
}
|
||||
console.log(data, 'data')
|
||||
|
||||
// await Xdelete(
|
||||
// deleteUser,
|
||||
// { id: id },
|
||||
// // , getAll
|
||||
// )
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
// getAll()
|
||||
}, [])
|
||||
|
||||
const rowStyle = {
|
||||
height: '30px', // Điều chỉnh chiều cao hàng
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className={classes.title}>
|
||||
<h3>
|
||||
<Text>Admin/</Text>
|
||||
Test Report
|
||||
</h3>
|
||||
<Button
|
||||
onClick={() => {
|
||||
setAction('add')
|
||||
form.reset()
|
||||
}}
|
||||
>
|
||||
+ Add
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<Box display={'flex'} p={15}>
|
||||
<Box
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexFlow: 'column',
|
||||
}}
|
||||
w={'40%'}
|
||||
>
|
||||
<Box w="100%" display={'flex'}>
|
||||
<Text
|
||||
mr={'xs'}
|
||||
style={{ alignContent: 'center' }}
|
||||
fw={600}
|
||||
size={'md'}
|
||||
>
|
||||
Project:
|
||||
</Text>
|
||||
<Select
|
||||
clearable
|
||||
w="50%"
|
||||
value={filter.typeReason}
|
||||
size="xs"
|
||||
label=""
|
||||
data={[]}
|
||||
onChange={(e) => {
|
||||
setFilter({ ...filter, typeReason: e! })
|
||||
}}
|
||||
></Select>
|
||||
<Text
|
||||
ml={'lg'}
|
||||
style={{ alignContent: 'center' }}
|
||||
fw={600}
|
||||
size={'md'}
|
||||
>
|
||||
Sprint:
|
||||
</Text>
|
||||
<Select
|
||||
clearable
|
||||
w="50%"
|
||||
value={filter.statusFilter}
|
||||
size="xs"
|
||||
ml={'sm'}
|
||||
label=""
|
||||
data={
|
||||
[
|
||||
// { value: 'WAITING', label: 'WAITING' },
|
||||
// { value: 'CONFIRMED', label: 'CONFIRMED' },
|
||||
// { value: 'REFUSED', label: 'REFUSED' },
|
||||
]
|
||||
}
|
||||
onChange={(e) => {
|
||||
setFilter({ ...filter, statusFilter: e! })
|
||||
}}
|
||||
></Select>
|
||||
</Box>
|
||||
</Box>
|
||||
<Box
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexFlow: 'column',
|
||||
// backgroundColor: 'yellow',
|
||||
alignSelf: 'center',
|
||||
}}
|
||||
w={'60%'}
|
||||
>
|
||||
<Text style={{ textAlign: 'center' }} fw={600}>
|
||||
Project Name/ Sprint Name
|
||||
</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
<Box>
|
||||
{/* Tiêu đề Criteria for Sprint */}
|
||||
<Title order={5} ml="xs">
|
||||
List bug:
|
||||
</Title>
|
||||
|
||||
{/* Bảng Criteria for Sprint */}
|
||||
<Table
|
||||
striped
|
||||
highlightOnHover
|
||||
withTableBorder
|
||||
withColumnBorders
|
||||
// me={'xs'}
|
||||
>
|
||||
<Table.Thead>
|
||||
<Table.Tr bg="#228be66b" style={rowStyle}>
|
||||
<Table.Th style={{ textAlign: 'center', width: '150px' }}>
|
||||
Test case
|
||||
</Table.Th>
|
||||
<Table.Th style={{ textAlign: 'center', width: '150px' }}>
|
||||
Position
|
||||
</Table.Th>
|
||||
<Table.Th style={{ textAlign: 'center', width: '150px' }}>
|
||||
Input
|
||||
</Table.Th>
|
||||
<Table.Th style={{ textAlign: 'center', width: '150px' }}>
|
||||
Note
|
||||
</Table.Th>
|
||||
<Table.Th style={{ textAlign: 'center', width: '150px' }}>
|
||||
Expect output
|
||||
</Table.Th>
|
||||
<Table.Th style={{ textAlign: 'center', width: '150px' }}>
|
||||
Actual output
|
||||
</Table.Th>
|
||||
<Table.Th style={{ textAlign: 'center' }}>Note</Table.Th>
|
||||
<Table.Th style={{ textAlign: 'center', width: '100px' }}>
|
||||
Action
|
||||
</Table.Th>
|
||||
</Table.Tr>
|
||||
</Table.Thead>
|
||||
<Table.Tbody>
|
||||
{[...Array(5)].map((_, index) => (
|
||||
<Table.Tr key={index} style={rowStyle}>
|
||||
<Table.Td>string</Table.Td>
|
||||
<Table.Td>string</Table.Td>
|
||||
<Table.Td>string</Table.Td>
|
||||
<Table.Td>string</Table.Td>
|
||||
<Table.Td>string</Table.Td>
|
||||
<Table.Td>string</Table.Td>
|
||||
<Table.Td>string</Table.Td>
|
||||
<Table.Td>
|
||||
<Box className={classes.optionIcon}>
|
||||
<IconInfoSquare
|
||||
className={classes.editIcon}
|
||||
onClick={() => {
|
||||
setAction('review')
|
||||
// setItem(row)
|
||||
form.reset()
|
||||
}}
|
||||
width={20}
|
||||
height={20}
|
||||
/>
|
||||
<IconSquareXFilled
|
||||
className={classes.deleteIcon}
|
||||
onClick={() => {
|
||||
setAction('delete')
|
||||
// setItem(row)
|
||||
form.reset()
|
||||
}}
|
||||
width={20}
|
||||
height={20}
|
||||
/>
|
||||
</Box>
|
||||
</Table.Td>
|
||||
</Table.Tr>
|
||||
))}
|
||||
</Table.Tbody>
|
||||
</Table>
|
||||
</Box>
|
||||
|
||||
{/* Add Test modal */}
|
||||
<Modal
|
||||
opened={action === 'add'}
|
||||
onClose={() => {
|
||||
setAction('')
|
||||
form.reset()
|
||||
}}
|
||||
title={
|
||||
<Text pl={'sm'} fw={700} fz={'lg'}>
|
||||
{action === 'add' ? 'Add Test' : ''}
|
||||
</Text>
|
||||
}
|
||||
>
|
||||
<form
|
||||
onSubmit={form.onSubmit(async (values) => {
|
||||
setDisableBtn(true)
|
||||
await handleCreate(values)
|
||||
setDisableBtn(false)
|
||||
})}
|
||||
>
|
||||
<Box pl={'md'} pr={'md'}>
|
||||
<TextInput
|
||||
required
|
||||
label="Name"
|
||||
mb={'md'}
|
||||
value={form.values.name}
|
||||
error={form.errors.name}
|
||||
onChange={(e) => form.setFieldValue('name', e.target.value)}
|
||||
/>
|
||||
|
||||
<TextInput
|
||||
required
|
||||
label="Position"
|
||||
mb={'md'}
|
||||
value={form.values.email}
|
||||
error={form.errors.email}
|
||||
onChange={(e) => form.setFieldValue('email', e.target.value)}
|
||||
/>
|
||||
<TextInput
|
||||
required
|
||||
label="Input"
|
||||
mb={'md'}
|
||||
value={form.values.email}
|
||||
error={form.errors.email}
|
||||
onChange={(e) => form.setFieldValue('email', e.target.value)}
|
||||
/>
|
||||
<Box display={'flex'}>
|
||||
<Box style={{ display: 'flex', flexFlow: 'column' }} w={'45%'}>
|
||||
<TextInput
|
||||
label="Expect Output"
|
||||
mb={'md'}
|
||||
value={form.values.email}
|
||||
error={form.errors.email}
|
||||
onChange={(e) => form.setFieldValue('email', e.target.value)}
|
||||
/>
|
||||
<TextInput
|
||||
label="Issue ID On Jira"
|
||||
mb={'md'}
|
||||
value={form.values.email}
|
||||
error={form.errors.email}
|
||||
onChange={(e) => form.setFieldValue('email', e.target.value)}
|
||||
/>
|
||||
</Box>
|
||||
<Box
|
||||
style={{ display: 'flex', flexFlow: 'column' }}
|
||||
w={'10%'}
|
||||
></Box>
|
||||
<Box style={{ display: 'flex', flexFlow: 'column' }} w={'45%'}>
|
||||
<TextInput
|
||||
label="Actual Output"
|
||||
mb={'md'}
|
||||
value={form.values.email}
|
||||
error={form.errors.email}
|
||||
onChange={(e) => form.setFieldValue('email', e.target.value)}
|
||||
/>
|
||||
<TextInput
|
||||
label="Bug ID On Jira"
|
||||
mb={'md'}
|
||||
value={form.values.email}
|
||||
error={form.errors.email}
|
||||
onChange={(e) => form.setFieldValue('email', e.target.value)}
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
<Textarea
|
||||
label="Note"
|
||||
required
|
||||
value={form.values.email}
|
||||
onChange={(e) => form.setFieldValue('email', e.target.value)}
|
||||
/>
|
||||
<Box ta={'center'}>
|
||||
<Button
|
||||
mt={'lg'}
|
||||
bg={'green'}
|
||||
type="submit"
|
||||
disabled={disableBtn}
|
||||
>
|
||||
Create
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
</form>
|
||||
</Modal>
|
||||
|
||||
<Modal
|
||||
opened={action === 'review'}
|
||||
onClose={() => {
|
||||
setAction('')
|
||||
}}
|
||||
size={'lg'}
|
||||
title={
|
||||
<Text pl={'sm'} fw={700} fz={'lg'}>
|
||||
Detail Test Report
|
||||
</Text>
|
||||
}
|
||||
>
|
||||
<Box pl={'md'} pr={'md'}>
|
||||
<TextInput
|
||||
label="Name"
|
||||
readOnly
|
||||
style={{ pointerEvents: 'none' }}
|
||||
mb={'md'}
|
||||
value={'!23123'}
|
||||
error={form.errors.name}
|
||||
onChange={(e) => form.setFieldValue('name', e.target.value)}
|
||||
/>
|
||||
|
||||
<TextInput
|
||||
label="Position"
|
||||
readOnly
|
||||
style={{ pointerEvents: 'none' }}
|
||||
mb={'md'}
|
||||
value={'12312231'}
|
||||
error={form.errors.email}
|
||||
onChange={(e) => form.setFieldValue('email', e.target.value)}
|
||||
/>
|
||||
<TextInput
|
||||
readOnly
|
||||
style={{ pointerEvents: 'none' }}
|
||||
label="Input"
|
||||
mb={'md'}
|
||||
value={form.values.email}
|
||||
error={form.errors.email}
|
||||
onChange={(e) => form.setFieldValue('email', e.target.value)}
|
||||
/>
|
||||
<Box display={'flex'}>
|
||||
<Box style={{ display: 'flex', flexFlow: 'column' }} w={'40%'}>
|
||||
<TextInput
|
||||
readOnly
|
||||
style={{ pointerEvents: 'none' }}
|
||||
label="Expect Output"
|
||||
mb={'md'}
|
||||
value={form.values.email}
|
||||
error={form.errors.email}
|
||||
onChange={(e) => form.setFieldValue('email', e.target.value)}
|
||||
/>
|
||||
<TextInput
|
||||
readOnly
|
||||
style={{ pointerEvents: 'none' }}
|
||||
label="Actual Output"
|
||||
mb={'md'}
|
||||
value={form.values.email}
|
||||
error={form.errors.email}
|
||||
onChange={(e) => form.setFieldValue('email', e.target.value)}
|
||||
/>
|
||||
</Box>
|
||||
<Box
|
||||
style={{ display: 'flex', flexFlow: 'column' }}
|
||||
w={'20%'}
|
||||
></Box>
|
||||
<Box style={{ display: 'flex', flexFlow: 'column' }} w={'40%'}>
|
||||
<TextInput
|
||||
readOnly
|
||||
style={{ pointerEvents: 'none' }}
|
||||
label="Issue ID On Jira"
|
||||
mb={'md'}
|
||||
value={form.values.email}
|
||||
error={form.errors.email}
|
||||
onChange={(e) => form.setFieldValue('email', e.target.value)}
|
||||
/>
|
||||
<TextInput
|
||||
readOnly
|
||||
style={{ pointerEvents: 'none' }}
|
||||
label="Bug ID On Jira"
|
||||
mb={'md'}
|
||||
value={form.values.email}
|
||||
error={form.errors.email}
|
||||
onChange={(e) => form.setFieldValue('email', e.target.value)}
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
<Textarea
|
||||
readOnly
|
||||
style={{ pointerEvents: 'none' }}
|
||||
label="Note"
|
||||
value={form.values.email}
|
||||
onChange={(e) => form.setFieldValue('email', e.target.value)}
|
||||
/>
|
||||
<TextInput
|
||||
readOnly
|
||||
style={{ pointerEvents: 'none', marginTop: '10px' }}
|
||||
label="Create By"
|
||||
mb={'md'}
|
||||
value={form.values.email}
|
||||
error={form.errors.email}
|
||||
onChange={(e) => form.setFieldValue('email', e.target.value)}
|
||||
/>
|
||||
</Box>
|
||||
</Modal>
|
||||
|
||||
<Dialog
|
||||
className={classes.dialog}
|
||||
opened={action === 'delete'}
|
||||
withCloseButton
|
||||
onClose={() => setAction('')}
|
||||
size="lg"
|
||||
radius="md"
|
||||
position={{ top: 30, right: 10 }}
|
||||
>
|
||||
<Text className={classes.dialogText} size="sm" mb="xs" fw={500}>
|
||||
Do you want to delete this record?
|
||||
<Group justify="center" m={10}>
|
||||
<Button
|
||||
disabled={activeBtn}
|
||||
fw={700}
|
||||
size="xs"
|
||||
variant="light"
|
||||
onClick={async () => {
|
||||
setActiveBtn(true)
|
||||
await handleDelete(2)
|
||||
setActiveBtn(false)
|
||||
setAction('')
|
||||
}}
|
||||
>
|
||||
Yes
|
||||
</Button>
|
||||
<Button
|
||||
fw={700}
|
||||
size="xs"
|
||||
variant="light"
|
||||
onClick={() => setAction('')}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
</Group>
|
||||
</Text>
|
||||
</Dialog>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default TestReport
|
||||
|
|
@ -6,6 +6,7 @@ import PageLogin from '@/pages/Auth/Login/Login'
|
|||
import LeaveManagement from '@/pages/LeaveManagement/LeaveManagement'
|
||||
import PageNotFound from '@/pages/NotFound/NotFound'
|
||||
import SprintReview from '@/pages/SprintReview/SprintReview'
|
||||
import TestReport from '@/pages/TestReport/TestReport'
|
||||
import Tickets from '@/pages/Tickets/Tickets'
|
||||
import TicketsManagement from '@/pages/TicketsManagement/TicketsManagement'
|
||||
import Timekeeping from '@/pages/Timekeeping/Timekeeping'
|
||||
|
|
@ -159,6 +160,20 @@ const mainRoutes = [
|
|||
</ProtectedRoute>
|
||||
),
|
||||
},
|
||||
{
|
||||
path: '/test-report',
|
||||
element: (
|
||||
<ProtectedRoute mode="route" permission="admin,hr">
|
||||
<BasePage
|
||||
main={
|
||||
<>
|
||||
<TestReport />
|
||||
</>
|
||||
}
|
||||
></BasePage>
|
||||
</ProtectedRoute>
|
||||
),
|
||||
},
|
||||
// {
|
||||
// path: '/packages',
|
||||
// element: (
|
||||
|
|
|
|||
Loading…
Reference in New Issue