Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: LBA-2311 amélioration cosmétique des éléments de loading #1433

Merged
merged 29 commits into from
Aug 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
50c8b24
feat: illustrations
alanlr Aug 20, 2024
7ab9a24
feat: progress
alanlr Aug 20, 2024
af4e193
feat: en bonne voie
alanlr Aug 21, 2024
5e366c6
feat: cleaning, commentaire et refacto
alanlr Aug 21, 2024
6ed8fad
feat: item detail ok
alanlr Aug 21, 2024
e869e06
feat: illustrations
alanlr Aug 20, 2024
8823254
feat: progress
alanlr Aug 20, 2024
5778d53
feat: en bonne voie
alanlr Aug 21, 2024
bbe30a5
feat: cleaning, commentaire et refacto
alanlr Aug 21, 2024
78dbee5
feat: item detail ok
alanlr Aug 21, 2024
70a3880
Merge branch 'feat/LBA-2311-improve-loadings' of github.com:mission-a…
alanlr Aug 21, 2024
0fe6959
feat: useless
alanlr Aug 21, 2024
eeb69be
feat: simpler and without potential memory leak
alanlr Aug 21, 2024
c0272f7
feat: fix prop and cleaning
alanlr Aug 21, 2024
5f893bd
feat: cleaning old dirt
alanlr Aug 21, 2024
d24d755
Update ResultListsLoading.tsx
guilletmarion Aug 22, 2024
7661084
feat: teal color
alanlr Aug 22, 2024
4056279
feat: no need keeping interval alive
alanlr Aug 22, 2024
7ba66e9
feat: circulation simple
alanlr Aug 22, 2024
8430d7f
fix: correction oubli ajout infos naf pour la création d'un recruteur
alanlr Aug 22, 2024
c3ff9cb
Revert "fix: correction oubli ajout infos naf pour la création d'un r…
alanlr Aug 22, 2024
213cc29
Update ui/components/ItemDetail/ItemDetailLoading.tsx
alanlr Aug 27, 2024
857c778
Merge branch 'main' into feat/LBA-2311-improve-loadings
kevbarns Aug 27, 2024
672d577
Merge branch 'main' into feat/LBA-2311-improve-loadings
alanlr Aug 27, 2024
d228b46
feat: suppression image dupliquée
alanlr Aug 27, 2024
6d9f90b
Merge branch 'feat/LBA-2311-improve-loadings' of https://github.com/m…
alanlr Aug 27, 2024
0d8f4e7
Merge branch 'main' into feat/LBA-2311-improve-loadings
alanlr Aug 29, 2024
ce09d43
Merge branch 'main' into feat/LBA-2311-improve-loadings
alanlr Aug 29, 2024
2b504b4
Merge branch 'main' into feat/LBA-2311-improve-loadings
alanlr Aug 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions ui/components/ItemDetail/ItemDetail.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { assertUnreachable } from "@/../shared"
import { Box, Flex, Spinner, Text } from "@chakra-ui/react"
import { Box, Flex, Text } from "@chakra-ui/react"
import { useContext, useState } from "react"
import { useQuery } from "react-query"
import { LBA_ITEM_TYPE_OLD } from "shared/constants/lbaitem"
Expand All @@ -14,6 +14,7 @@ import { SearchResultContext } from "../../context/SearchResultContextProvider"
import { fetchTrainingDetails } from "../../services/fetchTrainingDetails"
import ErrorMessage from "../ErrorMessage"

import ItemDetailLoading from "./ItemDetailLoading"
import getActualTitle from "./ItemDetailServices/getActualTitle"
import { BuildSwipe, getNavigationButtons } from "./ItemDetailServices/getButtons"
import getTags from "./ItemDetailServices/getTags"
Expand Down Expand Up @@ -161,14 +162,11 @@ const ItemDetail = ({ handleClose, handleSelectItem }) => {
<ItemDetailCard selectedItem={selectedItem} />
</Box>
</Box>
<Box>
<Box margin="auto" maxWidth="700px">
{hasError ? (
<ErrorMessage message={hasError === "not_found" ? "Fiche introuvable" : "Une erreur s'est produite. Détail de la fiche momentanément indisponible"} />
) : (
<Flex alignItems="center" m={4} color={kindColor}>
Chargement des informations en cours
<Spinner ml={3} />
</Flex>
<ItemDetailLoading item={selectedItem} />
)}
</Box>
</Box>
Expand Down
96 changes: 96 additions & 0 deletions ui/components/ItemDetail/ItemDetailLoading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { LBA_ITEM_TYPE_OLD } from "@/../shared/constants/lbaitem"
import { Box, Image, Progress, SkeletonCircle, SkeletonText, Text } from "@chakra-ui/react"
import React, { useEffect, useState } from "react"

const ItemDetailLoading = ({ item }) => {
const getNextLoadingIllustration = (currentIllustration) => {
const currentIndex = loadingIllustrations.findIndex((ill) => ill.src === currentIllustration.src)
return loadingIllustrations[(currentIndex + 1) % loadingIllustrations.length]
}

const loadingIllustrations: { src: string; text: string }[] =
item.ideaType === LBA_ITEM_TYPE_OLD.FORMATION
? [
{
src: "/images/loading/training_description.svg",
text: "Chargement du descriptif de la formation",
},
{
src: "/images/loading/search_training.svg",
text: "Vérification des coordonnées du centre de formation",
},
{
src: "/images/loading/training_help.svg",
text: "Lien vers le simulateur d’aides aux alternants",
},
]
: [
{
src: "/images/loading/job_description.svg",
text: "Chargement du descriptif de l’offre",
},
{
src: "/images/loading/job_contact_info.svg",
text: "Vérification des coordonnées de l’entreprise",
},
{
src: "/images/loading/job_help.svg",
text: "Lien vers le simulateur d’aides aux alternants",
},
]

const [currentIllustration, setCurrentIllustration] = useState(loadingIllustrations[0])

useEffect(() => {
let interval: NodeJS.Timeout | null = null

let iterations = 0
let current = currentIllustration
interval = setInterval(() => {
if (iterations < 5) {
current = getNextLoadingIllustration(current)
setCurrentIllustration(current)
} else {
setCurrentIllustration({
src: "/images/loading/hourglass.svg",
text: "Hum... Ce chargement semble plus long que prévu",
})
clearInterval(interval)
}
iterations++
}, 1000)

return () => {
clearInterval(interval)
}
}, [item.loadedItemDetail, item.id])

const resultListProperties = {
color: "grey.425",
fontWeight: 500,
fontSize: "18px",
mt: [0, 0, 2],
}

return (
<Box pt="0">
<Box {...resultListProperties}>
<Box textAlign="center">
<Image margin="auto" src={currentIllustration.src} aria-hidden={true} alt="" />
<Text mt={1}>{currentIllustration.text}</Text>

<Box maxWidth="400px" mx="auto" my={4}>
<Progress colorScheme={item.ideaType === LBA_ITEM_TYPE_OLD.FORMATION ? "teal" : "orange"} isIndeterminate size="sm" borderRadius="20px" />
</Box>

<Box padding="6" boxShadow="lg" bg="white">
<SkeletonCircle size="10" />
<SkeletonText mt="4" noOfLines={4} spacing="4" skeletonHeight="2" />
</Box>
</Box>
</Box>
</Box>
)
}

export default ItemDetailLoading
10 changes: 1 addition & 9 deletions ui/components/ItemDetail/ItemDetailServices/getButtons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,7 @@ export const BuildSwipe = ({ jobs, trainings, extendedSearch, activeFilters, sel
}
}

export const getNavigationButtons = ({
goPrev,
goNext,
setSeeInfo = (t) => {
console.log(t)
},
handleClose,
}) => {
export const getNavigationButtons = ({ goPrev, goNext, handleClose }) => {
return (
<>
<Box>
Expand Down Expand Up @@ -102,7 +95,6 @@ export const getNavigationButtons = ({
<Button
{...navigationButtonProperties}
onClick={() => {
setSeeInfo(false)
handleClose()
}}
data-testid="close-detail-button"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@ const SearchForTrainingsAndJobs = () => {
const { formValues, setFormValues, visiblePane, setVisiblePane, isFormVisible, setIsFormVisible, setShouldMapBeVisible } = displayContext

const [searchRadius, setSearchRadius] = useState(30)
const [isTrainingSearchLoading, setIsTrainingSearchLoading] = useState(hasSearch ? false : true)
const [isTrainingSearchLoading, setIsTrainingSearchLoading] = useState(hasSearch || !scopeContext.isTraining ? false : true)
const [shouldShowWelcomeMessage, setShouldShowWelcomeMessage] = useState(hasSearch ? false : true)

const [isJobSearchLoading, setIsJobSearchLoading] = useState(hasSearch ? false : true)
const [isPartnerJobSearchLoading, setIsPartnerJobSearchLoading] = useState(hasSearch ? false : true)
const [isJobSearchLoading, setIsJobSearchLoading] = useState(hasSearch || !scopeContext.isJob ? false : true)
const [isPartnerJobSearchLoading, setIsPartnerJobSearchLoading] = useState(hasSearch || !scopeContext.isJob ? false : true)
const [jobSearchError, setJobSearchError] = useState("")
const [partnerJobSearchError, setPartnerJobSearchError] = useState("")
const [trainingSearchError, setTrainingSearchError] = useState("")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,54 +1,110 @@
import { Box, Flex, Spinner, Text } from "@chakra-ui/react"
import React, { useContext } from "react"
import { Box, Image, Progress, Text } from "@chakra-ui/react"
import React, { useEffect, useState } from "react"

import { ScopeContext } from "../../../context/ScopeContext"
enum LOADING_ILLUSTRATION_TYPES {
PARTNER = "PARTNER",
FORMATION = "FORMATION",
JOB = "JOB",
}

const ResultListsLoading = ({ jobSearchError, partnerJobSearchError, trainingSearchError, isTrainingSearchLoading, isJobSearchLoading, isPartnerJobSearchLoading }) => {
const scopeContext = useContext(ScopeContext)
const isLoading = isTrainingSearchLoading || isJobSearchLoading || isPartnerJobSearchLoading

if (jobSearchError && partnerJobSearchError && trainingSearchError) {
return <></>
}
const getNextLoadingIllustration = (currentIllustrationIndex: number | null) => {
const initialIndex = currentIllustrationIndex ?? Math.floor(Math.random() * loadingIllustrations.length)

// filtered relevant illustrations
const filteredIllustrationIndexes = loadingIllustrations
.map((item, index) => {
if (
((item.type === LOADING_ILLUSTRATION_TYPES.PARTNER && isPartnerJobSearchLoading) ||
(item.type === LOADING_ILLUSTRATION_TYPES.JOB && isJobSearchLoading) ||
(item.type === LOADING_ILLUSTRATION_TYPES.FORMATION && isTrainingSearchLoading)) &&
index !== initialIndex
)
return index
else {
return -1
}
})
.filter((index) => index !== -1)

if (filteredIllustrationIndexes.length === 0) {
return initialIndex
}

let jobLoading = <></>
// Select a random index from the filtered indexes
const randomIndex = Math.floor(Math.random() * filteredIllustrationIndexes.length)

if (scopeContext.isJob && (isJobSearchLoading || isPartnerJobSearchLoading)) {
jobLoading = (
<Flex p={5} color="pinksoft.600">
<Text mr={4}>Recherche d'entreprises en cours</Text>
<Spinner thickness="4px" />
</Flex>
)
// Return the original array's index corresponding to the random filtered index
return filteredIllustrationIndexes[randomIndex]
}

let trainingLoading = <></>
const loadingIllustrations: { type: LOADING_ILLUSTRATION_TYPES; src: string; text: string }[] = [
{
type: LOADING_ILLUSTRATION_TYPES.PARTNER,
src: "/images/loading/search_partners.svg",
text: "Chargement des offres partenaires",
},
{
type: LOADING_ILLUSTRATION_TYPES.JOB,
src: "/images/loading/search_companies.svg",
text: "Identification des entreprises qui recrutent",
},
{
type: LOADING_ILLUSTRATION_TYPES.FORMATION,
src: "/images/loading/search_trainings.svg",
text: "Tri des formations par métier",
},
{
type: LOADING_ILLUSTRATION_TYPES.FORMATION,
src: "/images/loading/search_qualiopi.svg",
text: "Sélection des formations",
},
]

if (scopeContext.isTraining && isTrainingSearchLoading) {
trainingLoading = (
<Flex p={5} color="greensoft.500">
<Text mr={4}>Recherche des formations en cours</Text>
<Spinner thickness="4px" />
</Flex>
)
const [currentIllustrationIndex, setCurrentIllustrationIndex] = useState(isJobSearchLoading ? 0 : 2)

useEffect(() => {
const interval = setInterval(() => {
const nextIndex = getNextLoadingIllustration(currentIllustrationIndex)
setCurrentIllustrationIndex(nextIndex)
}, 1000)

if (!isLoading) {
clearInterval(interval)
}

return () => {
clearInterval(interval)
}
}, [isLoading])

if (jobSearchError && partnerJobSearchError && trainingSearchError) {
return <></>
}

const resultListProperties = {
textAlign: "left",
marginLeft: "10px",
color: "grey.650",
fontWeight: 600,
fontSize: "22px",
marginBottom: "0px",
padding: "0 20px",
color: "grey.425",
fontWeight: 500,
fontSize: "18px",
mt: [0, 0, 2],
}

return (
<Box pt="0">
{/* @ts-expect-error: TODO */}
<Box {...resultListProperties}>
{trainingLoading}
{jobLoading}
{isLoading ? (
<Box textAlign="center">
<Image margin="auto" src={loadingIllustrations[currentIllustrationIndex].src} aria-hidden={true} alt="" />
<Text mt={1}>{loadingIllustrations[currentIllustrationIndex].text}</Text>
<Box maxWidth="400px" mx="auto" my={4}>
<Progress isIndeterminate size="sm" borderRadius="20px" />
</Box>
</Box>
) : (
<></>
)}
</Box>
</Box>
)
Expand Down
6 changes: 6 additions & 0 deletions ui/public/images/loading/hourglass.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions ui/public/images/loading/job_contact_info.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading