Skip to content

Commit

Permalink
Merge pull request #90 from SocialGouv/feat/ouverture-regions
Browse files Browse the repository at this point in the history
feat: region selector
  • Loading branch information
ClementNumericite authored Feb 2, 2024
2 parents 66f9ed5 + fd0be4c commit 2517e11
Show file tree
Hide file tree
Showing 14 changed files with 517 additions and 140 deletions.
29 changes: 26 additions & 3 deletions faker/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
fake = Faker('fr_FR')

department_dict = {
# IDF
'75': ['Paris', 'Paris 2', 'Paris 3'],
'77': ['Meaux', 'Chelles', 'Melun'],
'78': ['Versailles', 'Yvelines', 'Rambouillet'],
Expand All @@ -15,9 +16,31 @@
'93': ['Saint-Denis', 'Montreuil', 'Aubervilliers'],
'94': ['Créteil', 'Vincennes', 'Ivry-sur-Seine'],
'95': ['Cergy', 'Argenteuil', 'Sarcelles'],
'86': ['Poitiers', 'Jaunay-clan', 'Chatellerault'],
'17': ['La Rochelle', 'Aytré', 'Ronce-les-bains'],
'14': ['Cabourg', 'Honfleur', 'Trouville'],
# NORMANDIE
'14': ['a'],
'27': ['a'],
'50': ['a'],
'61': ['a'],
'76': ['a'],
# NOUVELLE AQUITAINE
'16': ['B'],
'17': ['B'],
'19': ['B'],
'23': ['B'],
'24': ['B'],
'33': ['B'],
'40': ['B'],
'47': ['B'],
'64': ['B'],
'79': ['B'],
'86': ['B'],
'87': ['B'],
# HAUTS DE FRANCE
'02': ['c'],
'59': ['c'],
'60': ['c'],
'62': ['c'],
'80': ['c'],
}

category_1 = ['suicide', 'avc', 'cancer', 'tuberculose', 'thrombose']
Expand Down
3 changes: 3 additions & 0 deletions webapp-next/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ OPENAI_API_KEY=xxx
# ElasticApi key name
NEXT_PUBLIC_ELASTIC_API_KEY_NAME=cm2d_api_key

# Max associate causes
NEXT_PUBLIC_MAX_ASSOCIATE_CAUSE_SELECTION=3

# Mailer
NODEMAILER_HOST=ex4.mail.ovh.net
NODEMAILER_PORT=587
Expand Down
1 change: 1 addition & 0 deletions webapp-next/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ FROM node:16-alpine3.17 AS builder
ARG ELASTIC_HOST
ARG ELASTIC_PASSWORD
ARG NEXT_PUBLIC_ELASTIC_API_KEY_NAME
ARG NEXT_PUBLIC_MAX_ASSOCIATE_CAUSE_SELECTION
ARG NODEMAILER_HOST
ARG NODEMAILER_PORT
ARG NODEMAILER_USER
Expand Down
1 change: 0 additions & 1 deletion webapp-next/components/charts/doughnut/Doughnut.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
chartsAvailableColors,
getLabelFromKey
} from '@/utils/tools';
import { Box, Flex } from '@chakra-ui/react';
import { useContext, useEffect, useState } from 'react';
import { Doughnut } from 'react-chartjs-2';

Expand Down
9 changes: 7 additions & 2 deletions webapp-next/components/charts/map/Map.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,19 @@ export default function MapIframe(props: Props) {
throw new Error('Menu must be used within a Cm2dProvider');
}

const { saveAggregateX } = context;
const { filters, saveAggregateX } = context;

const writeHTMLToIframe = () => {
const iframe = iframeRef.current;

if (iframe) {
const doc = (iframe as any).contentWindow.document;
const mapProps = getMapProps(id, datasets, saveAggregateX);
const mapProps = getMapProps(
id,
datasets,
filters.region_departments,
saveAggregateX
);
doc.open();
doc.write(`
<html>
Expand Down
23 changes: 21 additions & 2 deletions webapp-next/components/filters/AssociateCauses.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@ import { useAssociateCauses } from '@/utils/api';
import { Cm2dContext } from '@/utils/cm2d-provider';
import { capitalizeString, removeAccents } from '@/utils/tools';
import { CloseIcon } from '@chakra-ui/icons';
import { InfoOutlineIcon } from '@chakra-ui/icons';
import {
Box,
Button,
Checkbox,
Flex,
Input,
InputGroup,
InputRightElement,
Link,
ListItem,
Modal,
ModalBody,
ModalCloseButton,
Expand All @@ -20,6 +23,7 @@ import {
Spinner,
Tag,
Text,
UnorderedList,
useDisclosure
} from '@chakra-ui/react';
import { useContext, useEffect, useState } from 'react';
Expand All @@ -38,6 +42,9 @@ export const FilterAssociateCauses = (props: Props) => {
const [isSearching, setIsSearching] = useState(false);
const [search, setSearch] = useState('');
const debouncedSearchTerm = useDebounce(search, 300);
const maxSelection = parseInt(
(process.env.NEXT_PUBLIC_MAX_ASSOCIATE_CAUSE_SELECTION as string) || '2'
);
const { isOpen, onOpen, onClose } = useDisclosure();

useEffect(() => {
Expand Down Expand Up @@ -118,7 +125,9 @@ export const FilterAssociateCauses = (props: Props) => {
<Modal isOpen={isOpen} onClose={onClose} isCentered size={'6xl'}>
<ModalOverlay />
<ModalContent>
<ModalHeader>Gestion des causes associées</ModalHeader>
<ModalHeader>
Gestion des causes associées (maximum {maxSelection})
</ModalHeader>
<ModalCloseButton />
<ModalBody>
<Box mb={6}>
Expand Down Expand Up @@ -164,6 +173,10 @@ export const FilterAssociateCauses = (props: Props) => {
<Box key={ac.label} mb={3}>
<Checkbox
colorScheme="primary"
disabled={
!filters.categories_associate.includes(ac.value) &&
filters.categories_associate.length === maxSelection
}
onChange={e => {
if (e.target.checked) {
filters.categories_associate.push(ac.value);
Expand All @@ -190,7 +203,13 @@ export const FilterAssociateCauses = (props: Props) => {
</Box>
</ModalBody>

<ModalFooter>
<ModalFooter justifyContent={'space-between'} alignItems={'center'}>
<Text fontSize={'sm'} color="highlight.500" pr={4}>
<InfoOutlineIcon mr={0.5} mb={0.5} /> <b>Attention : </b> sont
comptabilisés tous les certificats faisant mention de la cause{' '}
{capitalizeString(filters.categories[0])} et d&apos;au moins une
des causes associées sélectionnées.
</Text>
<Button colorScheme="primary" mr={3} onClick={onClose}>
Fermer
</Button>
Expand Down
6 changes: 4 additions & 2 deletions webapp-next/components/filters/Departments.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const FiltersDepartments = (props: Props) => {

const { filters, setFilters, selectedFiltersPile, setSelectedFiltersPile } =
context;
const { data } = useDepartments();
const { data } = useDepartments(filters.region_departments);

if (!data) return <>...</>;

Expand Down Expand Up @@ -76,7 +76,9 @@ export const FiltersDepartments = (props: Props) => {
departmentRefs[
department.label as keyof typeof departmentRefs
]
} (${department.label})`
} (${department.label.toString().length > 1 ? '' : `0`}${
department.label
})`
: `Inconnu (${department.label})`}
</Text>
</Checkbox>
Expand Down
156 changes: 156 additions & 0 deletions webapp-next/components/filters/Regions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import { Cm2dContext } from '@/utils/cm2d-provider';
import { ChevronDownIcon } from '@chakra-ui/icons';
import { Flex, Menu, MenuButton, MenuItem, MenuList } from '@chakra-ui/react';
import { useRouter } from 'next/router';
import { useContext, useEffect, useState } from 'react';

type Props = {};

export const RegionFilter = (props: Props) => {
const context = useContext(Cm2dContext);
const router = useRouter();
const { mode } = router.query;

if (!context) {
throw new Error('Menu must be used within a Cm2dProvider');
}

const { filters, setFilters } = context;

const [selectedFilter, setSelectedFilter] = useState<string[]>(
filters.region_departments
);

let regionFilters: { label: string; value: string[] }[] = [
{
label: 'Ile-de-France',
value: ['75', '77', '78', '91', '92', '93', '94', '95']
},
{ label: 'Normandie', value: ['14', '27', '50', '61', '76'] },
{
label: 'Nouvelle-Aquitaine',
value: [
'16',
'17',
'19',
'23',
'24',
'33',
'40',
'47',
'64',
'79',
'86',
'87'
]
},
{ label: 'Hauts-de-France', value: ['2', '59', '60', '62', '80'] }
];

if (mode === 'dev') {
regionFilters = [
...regionFilters,
{
label: 'Auvergne-Rhône-Alpes',
value: [
'1',
'3',
'7',
'15',
'26',
'38',
'42',
'43',
'63',
'69',
'73',
'74'
]
},
{
label: 'Bourgogne-Franche-Comté',
value: ['21', '25', '39', '58', '70', '71', '89', '90']
},
{ label: 'Bretagne', value: ['22', '29', '35', '56'] },
{
label: 'Centre-Val de Loire',
value: ['18', '28', '36', '37', '41', '45']
},
{ label: 'Corse', value: ['2A', '2B'] },
{
label: 'Grand Est',
value: ['8', '10', '51', '52', '54', '55', '57', '67', '68', '88']
},
{
label: 'Occitanie',
value: [
'9',
'11',
'12',
'30',
'31',
'32',
'34',
'46',
'48',
'65',
'66',
'81',
'82'
]
},
{ label: 'Pays de la Loire', value: ['44', '49', '53', '72', '85'] },
{
label: "Provence-Alpes-Côte d'Azur",
value: ['4', '5', '6', '13', '83', '84']
}
];
}

const getLabelFromValue = (value: string[]) => {
return (
regionFilters.find(
df => JSON.stringify(df.value) === JSON.stringify(value)
)?.label || ''
);
};

useEffect(() => {
if (selectedFilter)
setFilters({ ...filters, region_departments: selectedFilter });
}, [selectedFilter]);

return (
<Menu>
<MenuButton
px={4}
py={3}
w="full"
textAlign="left"
transition="all 0.2s"
borderRadius="md"
borderWidth="1px"
>
<Flex alignItems={'center'}>
{getLabelFromValue(selectedFilter)}
<ChevronDownIcon ml="auto" fontSize="2xl" />
</Flex>
</MenuButton>
<MenuList zIndex={999}>
{regionFilters.map(filter => (
<MenuItem
key={`option-${filter.value}`}
defaultChecked={
JSON.stringify(filter.value) === JSON.stringify(selectedFilter)
}
onClick={e => {
setSelectedFilter(filter.value);
}}
>
{filter.label}
</MenuItem>
))}
</MenuList>
</Menu>
);
};
Loading

0 comments on commit 2517e11

Please sign in to comment.