Skip to content

Commit

Permalink
wip: continued with react query + breadcrumb - Ref gestion-de-projet#…
Browse files Browse the repository at this point in the history
…2507
  • Loading branch information
ManelleG committed Jan 9, 2025
1 parent 2a0bf74 commit b2980bf
Show file tree
Hide file tree
Showing 11 changed files with 265 additions and 101 deletions.
23 changes: 17 additions & 6 deletions src/components/Exploration/components/Breadcrumb.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,28 @@
import React from 'react'
import useBreadcrumb from '../hooks/useBreadcrumb'
import { Breadcrumbs, Link } from '@mui/material'
import { Breadcrumbs, Link, Typography } from '@mui/material'
import { Link as RouterLink } from 'react-router-dom'

const Breadcrumb = () => {
const items = useBreadcrumb()
return (
// TODO: style
<Breadcrumbs>
{items.map((item, index) => (
<Link key={index} href={item.url}>
{item.label}
</Link>
))}
{items.map((item, index) => {
// Si c'est le dernier item, pas de lien
const isLast = index === items.length - 1
if (isLast) {
return <Typography key={index}>{item.label}</Typography>
}

return item.url ? (
<Link key={index} component={RouterLink} to={item.url}>
{item.label}
</Link>
) : (
<Typography key={index}>{item.label}</Typography>
)
})}
</Breadcrumbs>
)
}
Expand Down
49 changes: 39 additions & 10 deletions src/components/Exploration/components/CohortsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useContext, useState } from 'react'
import { useAppSelector } from 'state'

import { Box, Grid, IconButton, TableRow, Tooltip, Typography } from '@mui/material'
import { useNavigate, useSearchParams } from 'react-router-dom'
import { useNavigate, useParams, useSearchParams } from 'react-router-dom'
import ResearchesTable from './Table'
import { Cohort, CohortJobStatus, Column } from 'types'
import { TableCellWrapper } from 'components/ui/TableCell/styles'
Expand All @@ -19,28 +19,31 @@ import ColorizeIcon from '@mui/icons-material/Colorize'
import EditIcon from '@mui/icons-material/Edit'
import DeleteOutlineIcon from '@mui/icons-material/DeleteOutline'
import ActionMenu from './ActionMenu'
import useRequest from '../hooks/useRequest'

// TODO: il y a un hook useCohortsList, à checker à la rentrée

const CohortsList = () => {
const appConfig = useContext(AppConfig)
const navigate = useNavigate()
const { projectId, requestId } = useParams()
const [searchParams, setSearchParams] = useSearchParams()
const searchInput = searchParams.get('searchInput') ?? ''
const startDate = searchParams.get('startDate') ?? undefined
const endDate = searchParams.get('endDate') ?? undefined
const page = parseInt(searchParams.get('page') ?? '1', 10)
const maintenanceIsActive = useAppSelector((state) => state?.me?.maintenance?.active ?? false)

const { cohortsList, total, loading } = useCohorts('', searchInput, startDate, endDate)
const { request: parentRequest, requestLoading, requestIsError } = useRequest(requestId)
const { cohortsList, total, loading } = useCohorts(requestId ?? '', searchInput, startDate, endDate)

// TODO: add les params pour les filtres exclusifs aux cohortes + bien penser à les suppr en changeant d'onglet
// TODO: ne pas oublier les websockets

const columns: Column[] = [
{ label: '', align: 'left' },
{ label: 'nom de la cohorte', align: 'left' },
{ label: 'requête parent' }, // TODO: conditionner à si onglet cohortes, cliquable ou pas?
...(!requestId ? [{ label: 'requête parent' }] : []), //TODO: cliquable ou pas?
{ label: 'statut' },
{ label: 'nb de patients' },
{ label: 'estimation du nombre de patients ap-hp' },
Expand Down Expand Up @@ -90,9 +93,22 @@ const CohortsList = () => {
}

return (
<Grid container gap="50px">
<Typography>CohortsList</Typography>

<Grid container gap="20px">
{requestId && (
<Box display={'flex'} justifyContent={'center'} width={'100%'} alignItems={'center'}>
<Typography fontWeight={'bold'} fontSize={'24px'} fontFamily={"'Montserrat', sans-serif"}>
{parentRequest?.name}
</Typography>
<Typography>{parentRequest?.description}</Typography>
{/* TODO: ajouter les actions sur projet parent */}
<IconButton>
<EditIcon />
</IconButton>
<IconButton>
<DeleteOutlineIcon />
</IconButton>
</Box>
)}
{/* TODO: add circular progress */}

<ResearchesTable columns={columns} page={page} setPage={handlePageChange} total={total}>
Expand All @@ -119,7 +135,7 @@ const CohortsList = () => {
<TableRow
key={cohort.name}
sx={{ borderBottom: '1px solid #000', borderRadius: 20 }}
onClick={() => onClickRow(cohort)}
// onClick={() => onClickRow(cohort)}
>
<TableCellWrapper align="left" headCell>
<IconButton
Expand Down Expand Up @@ -186,14 +202,27 @@ const CohortsList = () => {
<ActionMenu actions={actions} />
</Box>
</TableCellWrapper>
<TableCellWrapper>{cohort.request}</TableCellWrapper>
{!requestId && <TableCellWrapper>{cohort.request}</TableCellWrapper>}
<TableCellWrapper>{cohort.request_job_status}</TableCellWrapper>
<TableCellWrapper>{displayDigit(cohort.result_size)}</TableCellWrapper>
<TableCellWrapper>{getGlobalEstimation(cohort)}</TableCellWrapper>
<TableCellWrapper>{formatDate(cohort.created_at, true)}</TableCellWrapper>
<TableCellWrapper>
<Button endIcon={<ArrowRightAltIcon />} onClick={() => console.log('hey coucou')}>
{/* {cohort.samples} échantillons */}
{/* TODO: rendre non cliquable si pas d'enfant dispo */}
<Button
// endIcon={cohortTotal >= 1 && <ArrowRightAltIcon />}
onClick={() =>
// TODO: pourquoi le preventDefault ne fonctionne pas ?
{
if (projectId && requestId)
navigate(`/researches/projects/${projectId}/${requestId}/${cohort.uuid}${location.search}`)
if (!projectId && requestId)
navigate(`/researches/requests/${requestId}/${cohort.uuid}${location.search}`)
if (!projectId && !requestId) navigate(`/researches/cohorts/${cohort.uuid}${location.search}`)
}
}
>
0 échantillon
</Button>
</TableCellWrapper>
</TableRow>
Expand Down
21 changes: 11 additions & 10 deletions src/components/Exploration/components/RequestsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import Button from 'components/ui/Button'
import ArrowRightAltIcon from '@mui/icons-material/ArrowRightAlt'
import useRequests from '../hooks/useRequests'
import { formatDate } from 'utils/formatDate'
import { Delete, Edit } from '@mui/icons-material'
import ActionMenu from './ActionMenu'
import EditIcon from '@mui/icons-material/Edit'
import DeleteOutlineIcon from '@mui/icons-material/DeleteOutline'
Expand All @@ -31,7 +30,6 @@ const RequestsList = () => {
const page = parseInt(searchParams.get('page') ?? '1', 10)
const maintenanceIsActive = useAppSelector((state) => state?.me?.maintenance?.active ?? false)

console.log('test useProject(projectId)', useProject(projectId))
const { project: parentProject, projectLoading, projectIsError } = useProject(projectId)
const { requestsList, total, loading } = useRequests(projectId, searchInput, startDate, endDate, page)

Expand All @@ -40,11 +38,9 @@ const RequestsList = () => {
setSearchParams(searchParams)
}

console.log('test parentProject', parentProject)

const columns: Column[] = [
{ label: 'nom de la requête', align: 'left' },
{ label: 'projet' }, // TODO: conditionner à si onglet requêtes + réfléchir si cliquable ou pas?
...(!projectId ? [{ label: 'projet' }] : []), // TODO: réfléchir si cliquable ou pas?
{ label: 'date de modification' },
{ label: 'nb de cohortes' }
]
Expand Down Expand Up @@ -97,10 +93,10 @@ const RequestsList = () => {
<Typography>{parentProject?.description}</Typography>
{/* TODO: ajouter les actions sur projet parent */}
<IconButton>
<Edit />
<EditIcon />
</IconButton>
<IconButton>
<Delete />
<DeleteOutlineIcon />
</IconButton>
</Box>
)}
Expand All @@ -116,7 +112,7 @@ const RequestsList = () => {
<TableRow
key={request.uuid}
sx={{ borderBottom: '1px solid #000', borderRadius: 20 }}
onClick={() => navigate(`/cohort/new/${request.uuid}`)}
// onClick={() => navigate(`/cohort/new/${request.uuid}`)}
>
<TableCellWrapper align="left" headCell>
{getRequestName(request)}
Expand All @@ -131,16 +127,21 @@ const RequestsList = () => {
</Tooltip>
<ActionMenu actions={actions} />
</TableCellWrapper>
<TableCellWrapper>{request.parent_folder}</TableCellWrapper>
{!projectId && <TableCellWrapper>{request.parent_folder}</TableCellWrapper>}
<TableCellWrapper>{formatDate(request.created_at, true)}</TableCellWrapper>
<TableCellWrapper>
{/* TODO: rendre non cliquable si pas d'enfant dispo */}
<Button
endIcon={cohortTotal >= 1 && <ArrowRightAltIcon />}
onClick={() =>
// TODO: pourquoi le preventDefault ne fonctionne pas ?
// TODO: gérer où on navigate en fonction de l'onglet où l'on se trouve
// à obtenir à partir de l'url
navigate('')
navigate(
projectId
? `/researches/projects/${projectId}/${request.uuid}${location.search}`
: `/researches/requests/${request.uuid}${location.search}`
)
}
>
{cohortTotal} cohorte{cohortTotal > 1 && 's'}
Expand Down
51 changes: 37 additions & 14 deletions src/components/Exploration/hooks/useBreadcrumb.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,48 @@
import React from 'react'
import { useLocation } from 'react-router'
import { useLocation, useParams } from 'react-router-dom'
import useProject from './useProject'
import useRequest from './useRequest'

const useBreadCrumb = () => {
const { projectId, requestId, cohortId } = useParams()
const location = useLocation()
const pathParts = location.pathname.split('/').filter(Boolean)
console.log('test pathParts', pathParts)

const { project } = useProject(projectId)
const { request } = useRequest(requestId)
// TODO: same with cohorts

const items = []
if (location.pathname.includes('/projects')) {
items.push({ label: 'Tous mes projets', url: '/researches/projects' })

if (projectId && project) {
items.push({
label: `Projet ${project.name}`,
url: `/researches/projects/${projectId}`
})

// TODO: clean et externaliser
// TODO: faire une fonction plus jolie pour trouver où je suis et récup les noms
if (pathParts[1] === 'projects') {
items.push({ label: 'Mes projets', url: 'researches/projects' })
} else if (pathParts[1] === 'requests') {
items.push({ label: 'Mes requêtes', url: 'researches/requests' })
} else if (pathParts[1] === 'cohorts') {
items.push({ label: 'Mes cohortes', url: 'researches/cohorts' })
} else if (pathParts[1] === 'samples') {
items.push({ label: 'Mes échantillons', url: 'researches/samples' })
if (requestId && request) {
items.push({
label: `Requête ${request.name}`,
url: `/researches/projects/${projectId}/${requestId}`
})
}
}
}

if (location.pathname.includes('/requests')) {
items.push({ label: 'Requêtes', url: '/researches/requests' })
if (requestId && request) {
items.push({
label: `Requête ${request.name}`,
url: `/researches/${requestId}`
})
}
}

if (location.pathname.includes('/cohorts')) {
items.push({ label: 'Mes Cohortes', url: '/researches/requests' })
// TODO: a adapter
}
return items
}

Expand Down
55 changes: 31 additions & 24 deletions src/components/Exploration/hooks/useCohorts.tsx
Original file line number Diff line number Diff line change
@@ -1,45 +1,52 @@
import React, { useEffect, useState } from 'react'
import { useQuery } from '@tanstack/react-query'
import services from 'services/aphp'
import { Cohort } from 'types'
import { CohortsType } from 'types/cohorts'
import { Direction, Order } from 'types/searchCriterias'

const useCohorts = (parentRequestId: string, searchInput: string, startDate?: string, endDate?: string, page = 1) => {
const [cohortsList, setCohortsList] = useState<Cohort[]>([])
const [total, setTotal] = useState(0)
const [loading, setLoading] = useState(false)

const useCohorts = (parentId: string, searchInput: string, startDate?: string, endDate?: string, page = 1) => {
// TODO: à externaliser
const fetchCohortsList = async () => {
// TODO: modifier le service de sorte à ajouter les filtres + try/catch
const rowsPerPage = 20
const offset = (page - 1) * rowsPerPage
const cohortsList = await services.projects.fetchCohortsList(
{
startDate: startDate ?? null,
endDate: endDate ?? null,
status: [],
favorite: CohortsType.ALL,
minPatients: null,
maxPatients: null
},
searchInput,
parentId
? {
startDate: null,
endDate: null,
status: [],
favorite: CohortsType.ALL,
minPatients: null,
maxPatients: null,
parentId
}
: {
startDate: startDate ?? null,
endDate: endDate ?? null,
status: [],
favorite: CohortsType.ALL,
minPatients: null,
maxPatients: null,
parentId
},
!parentId ? searchInput : '',
{ orderBy: Order.CREATED_AT, orderDirection: Direction.DESC },
rowsPerPage,
offset
// AbortSignal???
)
console.log('test cohortsList', cohortsList)
setCohortsList(cohortsList.results)
setTotal(cohortsList.count)
return cohortsList
}

useEffect(() => {
// setLoading(true)
console.log('test fetchCohortsList()', fetchCohortsList())
}, [parentRequestId, searchInput, startDate, endDate, page])
const { data, isLoading, isError, error, refetch } = useQuery({
queryKey: ['cohorts', searchInput, startDate, endDate, page],
queryFn: fetchCohortsList
})

const cohortsList = data?.results ?? []
const total = data?.count ?? 0

return { cohortsList, total, loading }
return { cohortsList, total, loading: isLoading, isError, error, refetch }
}

export default useCohorts
Loading

0 comments on commit b2980bf

Please sign in to comment.