[TEST REPORT] Đồng bộ project_id và sprint_id lên URL
This commit is contained in:
		
							parent
							
								
									a11861efb1
								
							
						
					
					
						commit
						b48ed4e622
					
				| 
						 | 
				
			
			@ -23,6 +23,7 @@ import {
 | 
			
		|||
} from '@mantine/core'
 | 
			
		||||
import { notifications } from '@mantine/notifications'
 | 
			
		||||
import { useEffect, useState } from 'react'
 | 
			
		||||
import { useLocation, useNavigate } from 'react-router-dom'
 | 
			
		||||
import classes from './SprintReview.module.css'
 | 
			
		||||
 | 
			
		||||
type DataProject = {
 | 
			
		||||
| 
						 | 
				
			
			@ -72,12 +73,70 @@ const SprintReview = () => {
 | 
			
		|||
  const [criteriaUsers, setCriteriaUsers] = useState<DataCriteriaUsers[]>([])
 | 
			
		||||
  const [infoBoard, setInfoBoard] = useState('')
 | 
			
		||||
  const [filter, setFilter] = useState({
 | 
			
		||||
    project: '',
 | 
			
		||||
    sprint: '',
 | 
			
		||||
    projectID: '',
 | 
			
		||||
    sprintID: '',
 | 
			
		||||
  })
 | 
			
		||||
  const [dataProject, setDataProject] = useState<DataProject[]>([])
 | 
			
		||||
  const [dataSprint, setDataSprint] = useState<DataSprint[]>([])
 | 
			
		||||
  const [finalPoint, setFinalPoint] = useState('')
 | 
			
		||||
 | 
			
		||||
  const navigate = useNavigate()
 | 
			
		||||
  const location = useLocation()
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    const searchParams = new URLSearchParams(location.search)
 | 
			
		||||
    const allParams: { [key: string]: string } = {}
 | 
			
		||||
 | 
			
		||||
    searchParams.forEach((value, key) => {
 | 
			
		||||
      allParams[key] = value
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    const newFilter = {
 | 
			
		||||
      projectID: allParams.projectID || '',
 | 
			
		||||
      sprintID: allParams.sprintID || '',
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!allParams.projectID) {
 | 
			
		||||
      searchParams.delete('sprintID')
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    setFilter(newFilter)
 | 
			
		||||
    navigate(`?${searchParams.toString()}`)
 | 
			
		||||
  }, [location.search]) // Mỗi khi URL thay đổi, cập nhật giá trị
 | 
			
		||||
 | 
			
		||||
  const handleSelectChangeSprint = (sprintID: any) => {
 | 
			
		||||
    const searchParams = new URLSearchParams(location.search)
 | 
			
		||||
    if (sprintID) {
 | 
			
		||||
      searchParams.set('sprintID', sprintID)
 | 
			
		||||
    } else {
 | 
			
		||||
      searchParams.delete('sprintID')
 | 
			
		||||
    }
 | 
			
		||||
    if (filter.projectID) {
 | 
			
		||||
      searchParams.set('projectID', filter.projectID)
 | 
			
		||||
    }
 | 
			
		||||
    navigate(`?${searchParams.toString()}`)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const handleSelectChangeProject = (projectID: any) => {
 | 
			
		||||
    if (projectID === null) {
 | 
			
		||||
      setFilter({ projectID: '', sprintID: '' })
 | 
			
		||||
      setInfoBoard('')
 | 
			
		||||
    } else {
 | 
			
		||||
      setFilter({ projectID: projectID, sprintID: '' })
 | 
			
		||||
    }
 | 
			
		||||
    setDataSprint([])
 | 
			
		||||
    setIsDisabledSprint(true)
 | 
			
		||||
    const searchParams = new URLSearchParams(location.search)
 | 
			
		||||
 | 
			
		||||
    if (projectID) {
 | 
			
		||||
      searchParams.set('projectID', projectID)
 | 
			
		||||
    } else {
 | 
			
		||||
      searchParams.delete('projectID')
 | 
			
		||||
      searchParams.delete('sprintID')
 | 
			
		||||
    }
 | 
			
		||||
    navigate(`?${searchParams.toString()}`)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const getListDataProject = async () => {
 | 
			
		||||
    try {
 | 
			
		||||
      const params = {}
 | 
			
		||||
| 
						 | 
				
			
			@ -156,10 +215,10 @@ const SprintReview = () => {
 | 
			
		|||
  }, [])
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    if (filter.project) {
 | 
			
		||||
    if (filter.projectID) {
 | 
			
		||||
      setLoading(true)
 | 
			
		||||
      const fetchData = async () => {
 | 
			
		||||
        const result = await getBoardByIdProject(filter.project)
 | 
			
		||||
        const result = await getBoardByIdProject(filter.projectID)
 | 
			
		||||
        if (result.values[0]) {
 | 
			
		||||
          setInfoBoard(result.values[0].id ?? '')
 | 
			
		||||
          setLoading(false)
 | 
			
		||||
| 
						 | 
				
			
			@ -170,7 +229,7 @@ const SprintReview = () => {
 | 
			
		|||
      setIsDisabledSprint(true)
 | 
			
		||||
      setDataSprint([])
 | 
			
		||||
    }
 | 
			
		||||
  }, [filter.project])
 | 
			
		||||
  }, [filter.projectID])
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    if (infoBoard != '') {
 | 
			
		||||
| 
						 | 
				
			
			@ -195,9 +254,9 @@ const SprintReview = () => {
 | 
			
		|||
    setLoading(true)
 | 
			
		||||
    setCriteriaSprint([])
 | 
			
		||||
    setCriteriaUsers([])
 | 
			
		||||
    if (filter.sprint) {
 | 
			
		||||
    if (filter.sprintID) {
 | 
			
		||||
      const fetchData = async () => {
 | 
			
		||||
        const result = await getListCriteriasBySprint(filter.sprint)
 | 
			
		||||
        const result = await getListCriteriasBySprint(filter.sprintID)
 | 
			
		||||
        if (result) {
 | 
			
		||||
          setCriteriaSprint(result.criterias ?? [])
 | 
			
		||||
          setCriteriaUsers(result.users ?? [])
 | 
			
		||||
| 
						 | 
				
			
			@ -213,7 +272,7 @@ const SprintReview = () => {
 | 
			
		|||
 | 
			
		||||
  const getAll = () => {
 | 
			
		||||
    const fetchData = async () => {
 | 
			
		||||
      const result = await getListCriteriasBySprint(filter.sprint)
 | 
			
		||||
      const result = await getListCriteriasBySprint(filter.sprintID)
 | 
			
		||||
      if (result) {
 | 
			
		||||
        setCriteriaSprint(result.criterias ?? [])
 | 
			
		||||
        setCriteriaUsers(result.users ?? [])
 | 
			
		||||
| 
						 | 
				
			
			@ -226,24 +285,24 @@ const SprintReview = () => {
 | 
			
		|||
 | 
			
		||||
  const handleUpdate = async () => {
 | 
			
		||||
    const dataSprintSearch = dataSprint.find(
 | 
			
		||||
      (item: DataSprint) => item.id == Number(filter.sprint),
 | 
			
		||||
      (item: DataSprint) => item.id == Number(filter.sprintID),
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    const values = {
 | 
			
		||||
      name: dataSprint.find((item: any) => item.id == filter.sprint)?.name,
 | 
			
		||||
      name: dataSprint.find((item: any) => item.id == filter.sprintID)?.name,
 | 
			
		||||
 | 
			
		||||
      start_date: dataSprintSearch?.startDate,
 | 
			
		||||
      end_date: dataSprintSearch?.endDate,
 | 
			
		||||
      complete_date: dataSprintSearch?.completeDate,
 | 
			
		||||
 | 
			
		||||
      project_id: filter.project,
 | 
			
		||||
      project_id: filter.projectID,
 | 
			
		||||
      criterias: criteriaSprint,
 | 
			
		||||
      users: criteriaUsers,
 | 
			
		||||
      finalPoint: finalPoint,
 | 
			
		||||
    }
 | 
			
		||||
    try {
 | 
			
		||||
      const res = await update(
 | 
			
		||||
        `${updateSprintReview}/${filter.sprint}`,
 | 
			
		||||
        `${updateSprintReview}/${filter.sprintID}`,
 | 
			
		||||
        values,
 | 
			
		||||
        getAll,
 | 
			
		||||
      )
 | 
			
		||||
| 
						 | 
				
			
			@ -302,7 +361,7 @@ const SprintReview = () => {
 | 
			
		|||
            setAction('update')
 | 
			
		||||
          }}
 | 
			
		||||
          style={{
 | 
			
		||||
            display: filter.sprint ? 'block' : 'none',
 | 
			
		||||
            display: filter.sprintID ? 'block' : 'none',
 | 
			
		||||
          }}
 | 
			
		||||
        >
 | 
			
		||||
          Update
 | 
			
		||||
| 
						 | 
				
			
			@ -345,7 +404,7 @@ const SprintReview = () => {
 | 
			
		|||
              searchable
 | 
			
		||||
              clearable
 | 
			
		||||
              w="60%"
 | 
			
		||||
              value={filter.project || null}
 | 
			
		||||
              value={filter.projectID || null}
 | 
			
		||||
              size="xs"
 | 
			
		||||
              label=""
 | 
			
		||||
              data={dataProject.map((project) => ({
 | 
			
		||||
| 
						 | 
				
			
			@ -353,18 +412,7 @@ const SprintReview = () => {
 | 
			
		|||
                label: project.name,
 | 
			
		||||
              }))}
 | 
			
		||||
              onChange={(e) => {
 | 
			
		||||
                if (e === null) {
 | 
			
		||||
                  // Clear project
 | 
			
		||||
                  setFilter({ project: '', sprint: '' }) // Clear cả project và sprint
 | 
			
		||||
                  setDataSprint([]) // Reset dataSprint để không hiển thị các giá trị sprint cũ
 | 
			
		||||
                  setInfoBoard('')
 | 
			
		||||
                  setIsDisabledSprint(true) // Vô hiệu hóa Select của sprint
 | 
			
		||||
                } else {
 | 
			
		||||
                  // Chọn project mới
 | 
			
		||||
                  setFilter({ project: e, sprint: '' }) // Clear sprint khi chọn project mới
 | 
			
		||||
                  setDataSprint([]) // Xóa dữ liệu sprint khi đổi project
 | 
			
		||||
                  setIsDisabledSprint(true) // Vô hiệu hóa lại Select sprint cho đến khi load xong
 | 
			
		||||
                }
 | 
			
		||||
                handleSelectChangeProject(e)
 | 
			
		||||
              }}
 | 
			
		||||
            ></Select>
 | 
			
		||||
            <Text
 | 
			
		||||
| 
						 | 
				
			
			@ -380,7 +428,7 @@ const SprintReview = () => {
 | 
			
		|||
              searchable
 | 
			
		||||
              clearable
 | 
			
		||||
              w="40%"
 | 
			
		||||
              value={filter.sprint || null} // Đảm bảo rằng nếu filter.sprint trống, thì giá trị sẽ là null
 | 
			
		||||
              value={filter.sprintID || null} // Đảm bảo rằng nếu filter.sprint trống, thì giá trị sẽ là null
 | 
			
		||||
              size="xs"
 | 
			
		||||
              ml={'sm'}
 | 
			
		||||
              label=""
 | 
			
		||||
| 
						 | 
				
			
			@ -389,7 +437,8 @@ const SprintReview = () => {
 | 
			
		|||
                label: sprint.name,
 | 
			
		||||
              }))}
 | 
			
		||||
              onChange={(e) => {
 | 
			
		||||
                setFilter({ ...filter, sprint: e! })
 | 
			
		||||
                setFilter({ ...filter, sprintID: e! })
 | 
			
		||||
                handleSelectChangeSprint(e) // Gọi hàm để cập nhật URL với sprintID
 | 
			
		||||
              }}
 | 
			
		||||
            ></Select>
 | 
			
		||||
          </Box>
 | 
			
		||||
| 
						 | 
				
			
			@ -404,12 +453,18 @@ const SprintReview = () => {
 | 
			
		|||
          w={'50%'}
 | 
			
		||||
        >
 | 
			
		||||
          <Text style={{ textAlign: 'center' }} fw={600}>
 | 
			
		||||
            {dataProject.find((item: any) => item.id === filter.project)?.name}{' '}
 | 
			
		||||
            {dataSprint.find((item: any) => item.id === Number(filter.sprint))
 | 
			
		||||
            {
 | 
			
		||||
              dataProject.find((item: any) => item.id === filter.projectID)
 | 
			
		||||
                ?.name
 | 
			
		||||
            }{' '}
 | 
			
		||||
            {dataSprint.find((item: any) => item.id === Number(filter.sprintID))
 | 
			
		||||
              ?.name
 | 
			
		||||
              ? '/'
 | 
			
		||||
              : ''}{' '}
 | 
			
		||||
            {dataSprint.find((item) => item.id === Number(filter.sprint))?.name}
 | 
			
		||||
            {
 | 
			
		||||
              dataSprint.find((item) => item.id === Number(filter.sprintID))
 | 
			
		||||
                ?.name
 | 
			
		||||
            }
 | 
			
		||||
          </Text>
 | 
			
		||||
        </Box>
 | 
			
		||||
      </Box>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,6 +26,7 @@ import { useForm } from '@mantine/form'
 | 
			
		|||
import { notifications } from '@mantine/notifications'
 | 
			
		||||
import { IconInfoSquare, IconSquareXFilled } from '@tabler/icons-react'
 | 
			
		||||
import { useEffect, useState } from 'react'
 | 
			
		||||
import { useLocation, useNavigate } from 'react-router-dom'
 | 
			
		||||
import classes from './TestReport.module.css'
 | 
			
		||||
 | 
			
		||||
type DataProject = {
 | 
			
		||||
| 
						 | 
				
			
			@ -79,14 +80,69 @@ const TestReport = () => {
 | 
			
		|||
  const [isDisabledSprint, setIsDisabledSprint] = useState(true)
 | 
			
		||||
  const [infoBoard, setInfoBoard] = useState('')
 | 
			
		||||
  const [filter, setFilter] = useState({
 | 
			
		||||
    project: '',
 | 
			
		||||
    sprint: '',
 | 
			
		||||
    projectID: '',
 | 
			
		||||
    sprintID: '',
 | 
			
		||||
  })
 | 
			
		||||
  const [dataProject, setDataProject] = useState<DataProject[]>([])
 | 
			
		||||
  const [dataSprint, setDataSprint] = useState<DataSprint[]>([])
 | 
			
		||||
 | 
			
		||||
  const [dataListTestCases, setDataListTestCases] = useState<any[]>([])
 | 
			
		||||
 | 
			
		||||
  const navigate = useNavigate()
 | 
			
		||||
  const location = useLocation()
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    const searchParams = new URLSearchParams(location.search)
 | 
			
		||||
    const allParams: { [key: string]: string } = {}
 | 
			
		||||
 | 
			
		||||
    searchParams.forEach((value, key) => {
 | 
			
		||||
      allParams[key] = value
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    const newFilter = {
 | 
			
		||||
      projectID: allParams.projectID || '',
 | 
			
		||||
      sprintID: allParams.sprintID || '',
 | 
			
		||||
    }
 | 
			
		||||
    setFilter(newFilter)
 | 
			
		||||
    if (!allParams.projectID) {
 | 
			
		||||
      searchParams.delete('sprintID')
 | 
			
		||||
    }
 | 
			
		||||
    navigate(`?${searchParams.toString()}`)
 | 
			
		||||
  }, [location.search]) // Mỗi khi URL thay đổi, cập nhật giá trị
 | 
			
		||||
 | 
			
		||||
  const handleSelectChangeSprint = (sprintID: any) => {
 | 
			
		||||
    const searchParams = new URLSearchParams(location.search)
 | 
			
		||||
    if (sprintID) {
 | 
			
		||||
      searchParams.set('sprintID', sprintID)
 | 
			
		||||
    } else {
 | 
			
		||||
      searchParams.delete('sprintID')
 | 
			
		||||
    }
 | 
			
		||||
    if (filter.projectID) {
 | 
			
		||||
      searchParams.set('projectID', filter.projectID)
 | 
			
		||||
    }
 | 
			
		||||
    navigate(`?${searchParams.toString()}`)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const handleSelectChangeProject = (projectID: any) => {
 | 
			
		||||
    if (projectID === null) {
 | 
			
		||||
      setFilter({ projectID: '', sprintID: '' })
 | 
			
		||||
      setInfoBoard('')
 | 
			
		||||
    } else {
 | 
			
		||||
      setFilter({ projectID: projectID, sprintID: '' })
 | 
			
		||||
    }
 | 
			
		||||
    setDataSprint([])
 | 
			
		||||
    setIsDisabledSprint(true)
 | 
			
		||||
    const searchParams = new URLSearchParams(location.search)
 | 
			
		||||
 | 
			
		||||
    if (projectID) {
 | 
			
		||||
      searchParams.set('projectID', projectID)
 | 
			
		||||
    } else {
 | 
			
		||||
      searchParams.delete('projectID')
 | 
			
		||||
      searchParams.delete('sprintID')
 | 
			
		||||
    }
 | 
			
		||||
    navigate(`?${searchParams.toString()}`)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const getListDataProject = async () => {
 | 
			
		||||
    try {
 | 
			
		||||
      const params = {}
 | 
			
		||||
| 
						 | 
				
			
			@ -165,10 +221,10 @@ const TestReport = () => {
 | 
			
		|||
  }, [])
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    if (filter.project) {
 | 
			
		||||
    if (filter.projectID) {
 | 
			
		||||
      setLoading(true)
 | 
			
		||||
      const fetchData = async () => {
 | 
			
		||||
        const result = await getBoardByIdProject(filter.project)
 | 
			
		||||
        const result = await getBoardByIdProject(filter.projectID)
 | 
			
		||||
        if (result.values[0]) {
 | 
			
		||||
          setInfoBoard(result.values[0].id ?? '')
 | 
			
		||||
          setLoading(false)
 | 
			
		||||
| 
						 | 
				
			
			@ -180,7 +236,7 @@ const TestReport = () => {
 | 
			
		|||
      setDataSprint([])
 | 
			
		||||
      setInfoBoard('')
 | 
			
		||||
    }
 | 
			
		||||
  }, [filter.project])
 | 
			
		||||
  }, [filter.projectID])
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    if (infoBoard != '') {
 | 
			
		||||
| 
						 | 
				
			
			@ -204,9 +260,9 @@ const TestReport = () => {
 | 
			
		|||
  useEffect(() => {
 | 
			
		||||
    setLoading(true)
 | 
			
		||||
    setDataListTestCases([])
 | 
			
		||||
    if (filter.sprint) {
 | 
			
		||||
    if (filter.sprintID) {
 | 
			
		||||
      const fetchData = async () => {
 | 
			
		||||
        const result = await getListTestCase(filter.sprint)
 | 
			
		||||
        const result = await getListTestCase(filter.sprintID)
 | 
			
		||||
        if (result) {
 | 
			
		||||
          setDataListTestCases(result ?? [])
 | 
			
		||||
          setLoading(false)
 | 
			
		||||
| 
						 | 
				
			
			@ -234,17 +290,17 @@ const TestReport = () => {
 | 
			
		|||
  const handleCreate = async (values: DataTestCases) => {
 | 
			
		||||
    try {
 | 
			
		||||
      const dataSprintSearch = dataSprint.find(
 | 
			
		||||
        (item: DataSprint) => item.id == Number(filter.sprint),
 | 
			
		||||
        (item: DataSprint) => item.id == Number(filter.sprintID),
 | 
			
		||||
      )
 | 
			
		||||
      const { ...data } = values
 | 
			
		||||
      data.sprint_name = dataSprintSearch?.name
 | 
			
		||||
      data.project_id = filter.project
 | 
			
		||||
      data.project_id = filter.projectID
 | 
			
		||||
      data.start_date = dataSprintSearch?.startDate
 | 
			
		||||
      data.end_date = dataSprintSearch?.endDate
 | 
			
		||||
      data.complete_date = dataSprintSearch?.completeDate
 | 
			
		||||
      delete data.id
 | 
			
		||||
 | 
			
		||||
      const res = await post(`${createTestCase}/${filter.sprint}`, data)
 | 
			
		||||
      const res = await post(`${createTestCase}/${filter.sprintID}`, data)
 | 
			
		||||
      if (res.status === true) {
 | 
			
		||||
        setAction('')
 | 
			
		||||
        form.reset()
 | 
			
		||||
| 
						 | 
				
			
			@ -262,7 +318,7 @@ const TestReport = () => {
 | 
			
		|||
 | 
			
		||||
  const getAll = async () => {
 | 
			
		||||
    const fetchData = async () => {
 | 
			
		||||
      const result = await getListTestCase(filter.sprint)
 | 
			
		||||
      const result = await getListTestCase(filter.sprintID)
 | 
			
		||||
      if (result) {
 | 
			
		||||
        setDataListTestCases(result ?? [])
 | 
			
		||||
        setLoading(false)
 | 
			
		||||
| 
						 | 
				
			
			@ -296,7 +352,7 @@ const TestReport = () => {
 | 
			
		|||
            form.reset()
 | 
			
		||||
          }}
 | 
			
		||||
          style={{
 | 
			
		||||
            display: filter.sprint ? 'block' : 'none',
 | 
			
		||||
            display: filter.sprintID && filter.projectID ? 'block' : 'none',
 | 
			
		||||
          }}
 | 
			
		||||
        >
 | 
			
		||||
          + Add
 | 
			
		||||
| 
						 | 
				
			
			@ -339,7 +395,7 @@ const TestReport = () => {
 | 
			
		|||
              searchable
 | 
			
		||||
              clearable
 | 
			
		||||
              w="60%"
 | 
			
		||||
              value={filter.project || null}
 | 
			
		||||
              value={filter.projectID || null}
 | 
			
		||||
              size="xs"
 | 
			
		||||
              label=""
 | 
			
		||||
              data={dataProject.map((project) => ({
 | 
			
		||||
| 
						 | 
				
			
			@ -347,18 +403,7 @@ const TestReport = () => {
 | 
			
		|||
                label: project.name,
 | 
			
		||||
              }))}
 | 
			
		||||
              onChange={(e) => {
 | 
			
		||||
                if (e === null) {
 | 
			
		||||
                  // Clear project
 | 
			
		||||
                  setFilter({ project: '', sprint: '' }) // Clear cả project và sprint
 | 
			
		||||
                  setDataSprint([]) // Reset dataSprint để không hiển thị các giá trị sprint cũ
 | 
			
		||||
                  setInfoBoard('')
 | 
			
		||||
                  setIsDisabledSprint(true) // Vô hiệu hóa Select của sprint
 | 
			
		||||
                } else {
 | 
			
		||||
                  // Chọn project mới
 | 
			
		||||
                  setFilter({ project: e, sprint: '' }) // Clear sprint khi chọn project mới
 | 
			
		||||
                  setDataSprint([]) // Xóa dữ liệu sprint khi đổi project
 | 
			
		||||
                  setIsDisabledSprint(true) // Vô hiệu hóa lại Select sprint cho đến khi load xong
 | 
			
		||||
                }
 | 
			
		||||
                handleSelectChangeProject(e)
 | 
			
		||||
              }}
 | 
			
		||||
            ></Select>
 | 
			
		||||
            <Text
 | 
			
		||||
| 
						 | 
				
			
			@ -374,7 +419,7 @@ const TestReport = () => {
 | 
			
		|||
              searchable
 | 
			
		||||
              clearable
 | 
			
		||||
              w="40%"
 | 
			
		||||
              value={filter.sprint || null} // Đảm bảo rằng nếu filter.sprint trống, thì giá trị sẽ là null
 | 
			
		||||
              value={filter.sprintID || null} // Đảm bảo rằng nếu filter.sprintID trống, thì giá trị sẽ là null
 | 
			
		||||
              size="xs"
 | 
			
		||||
              ml={'sm'}
 | 
			
		||||
              label=""
 | 
			
		||||
| 
						 | 
				
			
			@ -383,7 +428,8 @@ const TestReport = () => {
 | 
			
		|||
                label: sprint.name,
 | 
			
		||||
              }))}
 | 
			
		||||
              onChange={(e) => {
 | 
			
		||||
                setFilter({ ...filter, sprint: e! })
 | 
			
		||||
                setFilter({ ...filter, sprintID: e! })
 | 
			
		||||
                handleSelectChangeSprint(e) // Gọi hàm để cập nhật URL với sprintID
 | 
			
		||||
              }}
 | 
			
		||||
            ></Select>
 | 
			
		||||
          </Box>
 | 
			
		||||
| 
						 | 
				
			
			@ -398,12 +444,18 @@ const TestReport = () => {
 | 
			
		|||
          w={'50%'}
 | 
			
		||||
        >
 | 
			
		||||
          <Text style={{ textAlign: 'center' }} fw={600}>
 | 
			
		||||
            {dataProject.find((item: any) => item.id === filter.project)?.name}{' '}
 | 
			
		||||
            {dataSprint.find((item: any) => item.id === Number(filter.sprint))
 | 
			
		||||
            {
 | 
			
		||||
              dataProject.find((item: any) => item.id === filter.projectID)
 | 
			
		||||
                ?.name
 | 
			
		||||
            }{' '}
 | 
			
		||||
            {dataSprint.find((item: any) => item.id === Number(filter.sprintID))
 | 
			
		||||
              ?.name
 | 
			
		||||
              ? '/'
 | 
			
		||||
              : ''}{' '}
 | 
			
		||||
            {dataSprint.find((item) => item.id === Number(filter.sprint))?.name}
 | 
			
		||||
            {
 | 
			
		||||
              dataSprint.find((item) => item.id === Number(filter.sprintID))
 | 
			
		||||
                ?.name
 | 
			
		||||
            }
 | 
			
		||||
          </Text>
 | 
			
		||||
        </Box>
 | 
			
		||||
      </Box>
 | 
			
		||||
| 
						 | 
				
			
			@ -421,7 +473,13 @@ const TestReport = () => {
 | 
			
		|||
          Loading . . .
 | 
			
		||||
        </Text>
 | 
			
		||||
      </Box>
 | 
			
		||||
      <Box style={loading || !filter.sprint ? { display: 'none' } : {}}>
 | 
			
		||||
      <Box
 | 
			
		||||
        style={
 | 
			
		||||
          loading || !filter.sprintID || !filter.projectID
 | 
			
		||||
            ? { display: 'none' }
 | 
			
		||||
            : {}
 | 
			
		||||
        }
 | 
			
		||||
      >
 | 
			
		||||
        {/* Tiêu đề Criteria for Sprint */}
 | 
			
		||||
        <Title order={5} ml="xs">
 | 
			
		||||
          List bug:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue