Améliorations du module de recherche de code APE
parent
0a7d3a04ad
commit
27cfe59840
|
@ -1,3 +1,3 @@
|
|||
## Description
|
||||
|
||||
Assemble les données des codes APE (en `données-NAF-CPF-APE`) et les données du nombre d'établissements par code APE (dans `nombre-etablissements-par-code-ape-et-departement`) afin d'obtenir les codes APE ainsi que leurs données associées triables par département et par nombre d'établissements en 2021.
|
||||
Assemble les données des codes APE (dans `données-NAF-CPF-APE`), les descriptions des nomenclatures du Guichet (dans `données-NomenclatureGuichet`) et le nombre d’établissements par code APE (dans `nombre-etablissements-par-code-ape`) dans un seul fichier json.
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
@ -5,8 +5,8 @@ import { fileURLToPath } from 'url'
|
|||
import { Data as RawApeData } from '../données-NAF-CPF-APE/convert-pdf.js'
|
||||
import rawApeData from '../données-NAF-CPF-APE/output.json' assert { type: 'json' }
|
||||
import rawApeTags from '../données-NomenclatureGuichet/ape_tags.json' assert { type: 'json' }
|
||||
import { Out as EtablissementsData } from '../nombre-etablissements-par-code-ape-et-departement/convert-json.js'
|
||||
import rawEtablissementsData from '../nombre-etablissements-par-code-ape-et-departement/output.json' assert { type: 'json' }
|
||||
import { Out as NbEtablissementsData } from '../nombre-etablissements-par-code-ape/convert-json.js'
|
||||
import rawEtablissementsData from '../nombre-etablissements-par-code-ape/output.json' assert { type: 'json' }
|
||||
import { multipleCf } from './custom.js'
|
||||
|
||||
const __dirname = fileURLToPath(new URL('.', import.meta.url))
|
||||
|
@ -15,7 +15,7 @@ const OUTPUT_JSON_PATH = join(__dirname, './output.json')
|
|||
const OUTPUT_MIN_JSON_PATH = join(__dirname, './output.min.json')
|
||||
|
||||
const apeData = rawApeData as RawApeData[]
|
||||
const etablissementsData = rawEtablissementsData as EtablissementsData
|
||||
const etablissementsData = rawEtablissementsData as NbEtablissementsData
|
||||
const apeTags = rawApeTags as Record<string, string[]>
|
||||
|
||||
interface ApeData {
|
||||
|
@ -27,8 +27,6 @@ interface ApeData {
|
|||
contenuExclu: string[]
|
||||
}
|
||||
|
||||
type NbEtablissement2021Index = number
|
||||
|
||||
export interface Output {
|
||||
/**
|
||||
* Données textuel pour chaque code APE
|
||||
|
@ -36,15 +34,9 @@ export interface Output {
|
|||
apeData: ApeData[]
|
||||
|
||||
/**
|
||||
* Nombre d'établissement par département et par code APE,
|
||||
* l'index de ce tableau correspond au index dans indexByCodeApe et indexByCodeDepartement.
|
||||
* Cela permet de trouver le nombre d'établissement en 2021 avec un couple code APE + code d'un département.
|
||||
* Nombre d'établissement par code APE,
|
||||
*/
|
||||
nbEtablissements2021: number[]
|
||||
indexByCodeApe: { [codeAPE: string]: NbEtablissement2021Index[] }
|
||||
indexByCodeDepartement: {
|
||||
[codeDepartement: string]: NbEtablissement2021Index[]
|
||||
}
|
||||
indexByCodeApe: NbEtablissementsData
|
||||
}
|
||||
|
||||
const sousClasses = apeData.filter(({ type }) => type === 'sousClasse')
|
||||
|
@ -103,11 +95,8 @@ const output: Output = {
|
|||
}
|
||||
}
|
||||
),
|
||||
nbEtablissements2021: etablissementsData.data.map(
|
||||
({ nombre_d_etablissements_2021: nbEtablissements }) => nbEtablissements
|
||||
),
|
||||
indexByCodeApe: etablissementsData.indexByCodeApe,
|
||||
indexByCodeDepartement: etablissementsData.indexByCodeDepartement,
|
||||
|
||||
indexByCodeApe: etablissementsData,
|
||||
}
|
||||
|
||||
addContenuExcluToContenuCentral.forEach(([i, j, index]) => {
|
||||
|
@ -131,5 +120,26 @@ Object.values(multipleCf).forEach((obj) => {
|
|||
})
|
||||
})
|
||||
|
||||
output.apeData = output.apeData.map(
|
||||
({ contenuCentral, contenuAnnexe, contenuExclu, ...rest }) => ({
|
||||
contenuAnnexe: contenuAnnexe.map(
|
||||
(text) => text[0].toUpperCase() + text.slice(1)
|
||||
),
|
||||
contenuExclu: contenuExclu.map(
|
||||
(text) => text[0].toUpperCase() + text.slice(1)
|
||||
),
|
||||
contenuCentral: contenuCentral.reduce((acc, text) => {
|
||||
if (text.startsWith('•')) {
|
||||
acc[acc.length - 1] = acc[acc.length - 1] + '\n' + text.slice(2)
|
||||
} else {
|
||||
acc.push(text[0].toUpperCase() + text.slice(1))
|
||||
}
|
||||
|
||||
return acc
|
||||
}, [] as string[]),
|
||||
...rest,
|
||||
})
|
||||
)
|
||||
|
||||
writeFileSync(OUTPUT_JSON_PATH, JSON.stringify(output, null, 2))
|
||||
writeFileSync(OUTPUT_MIN_JSON_PATH, JSON.stringify(output))
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
## Description
|
||||
|
||||
Convertit les données du nombre d'établissements employeurs du secteur privé, par commune x APE (2006-2021) pour obtenir le nombre d'établissements en 2021 par code APE ou par département.
|
||||
Les données sont fournies par Open URSSAF et sont disponibles à cette adresse : https://open.urssaf.fr/explore/dataset/etablissements-et-effectifs-salaries-au-niveau-commune-x-ape-last/
|
|
@ -1,158 +0,0 @@
|
|||
/* eslint-disable no-console */
|
||||
/* eslint-disable camelcase */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||
|
||||
import { writeFileSync } from 'fs'
|
||||
import got from 'got'
|
||||
import { Writable } from 'node:stream'
|
||||
import { join } from 'path'
|
||||
import streamJson from 'stream-json'
|
||||
import streamPick from 'stream-json/filters/Pick.js'
|
||||
import streamValues from 'stream-json/streamers/StreamValues.js'
|
||||
import { fileURLToPath } from 'url'
|
||||
|
||||
const __dirname = fileURLToPath(new URL('.', import.meta.url))
|
||||
|
||||
const OUTPUT_JSON_PATH = './output.json'
|
||||
|
||||
const url =
|
||||
'https://open.urssaf.fr/explore/dataset/etablissements-et-effectifs-salaries-au-niveau-commune-x-ape-last/download/?format=json&timezone=Europe/Berlin&lang=fr'
|
||||
|
||||
export interface Data {
|
||||
nombre_d_etablissements_2021: number
|
||||
code_ape: string
|
||||
ape: string
|
||||
code_departement: string
|
||||
departement: string
|
||||
region: string
|
||||
}
|
||||
|
||||
export interface Out {
|
||||
data: Data[]
|
||||
indexByCodeApe: { [codeAPE: string]: number[] }
|
||||
indexByCodeDepartement: { [codeDepartement: string]: number[] }
|
||||
}
|
||||
|
||||
const out: Out = {
|
||||
data: [],
|
||||
indexByCodeApe: {},
|
||||
indexByCodeDepartement: {},
|
||||
}
|
||||
|
||||
const count = { code_ape: 0, code_departement: 0, total: 0 }
|
||||
const stream = got
|
||||
.stream(url)
|
||||
.pipe(streamJson.parser())
|
||||
.pipe(streamPick.pick({ filter: /^\d+\.fields/ }))
|
||||
.pipe(streamValues.streamValues())
|
||||
.pipe(
|
||||
new Writable({
|
||||
objectMode: true,
|
||||
write(data: { value: Data }, _, cb) {
|
||||
const {
|
||||
nombre_d_etablissements_2021,
|
||||
code_ape,
|
||||
ape,
|
||||
code_departement,
|
||||
departement,
|
||||
region,
|
||||
} = data.value
|
||||
|
||||
const elem: Data | null =
|
||||
nombre_d_etablissements_2021 > 0
|
||||
? {
|
||||
nombre_d_etablissements_2021,
|
||||
code_ape,
|
||||
ape,
|
||||
code_departement,
|
||||
departement,
|
||||
region,
|
||||
}
|
||||
: null
|
||||
|
||||
if (!elem) {
|
||||
return cb(null)
|
||||
}
|
||||
|
||||
++count.total
|
||||
const log = [
|
||||
'[elements parsed]:',
|
||||
count.total,
|
||||
'[element added]:',
|
||||
out.data.length,
|
||||
'[estimated percentage done]:',
|
||||
// 730 codes ape * 100 départements
|
||||
Math.round((out.data.length * 100) / (730 * 100)).toString() + '%',
|
||||
]
|
||||
if (!(elem.code_ape in out.indexByCodeApe)) {
|
||||
console.log(
|
||||
'[new ape code]:',
|
||||
elem.code_ape,
|
||||
'[count]:',
|
||||
++count.code_ape,
|
||||
...log
|
||||
)
|
||||
}
|
||||
if (!(elem.code_departement in out.indexByCodeDepartement)) {
|
||||
console.log(
|
||||
'[new departement code]:',
|
||||
elem.code_departement,
|
||||
'[count]:',
|
||||
++count.code_departement,
|
||||
...log
|
||||
)
|
||||
}
|
||||
|
||||
const actualAPE = out.indexByCodeApe[elem.code_ape] ?? []
|
||||
const actualDep =
|
||||
out.indexByCodeDepartement[elem.code_departement] ?? []
|
||||
|
||||
const small =
|
||||
actualAPE.length < actualDep.length ? actualAPE : actualDep
|
||||
const large =
|
||||
actualAPE.length > actualDep.length ? actualAPE : actualDep
|
||||
|
||||
let index = small.find(
|
||||
(a) =>
|
||||
large.includes(a) &&
|
||||
elem.code_ape === out.data[a].code_ape &&
|
||||
elem.code_departement === out.data[a].code_departement
|
||||
)
|
||||
|
||||
if (typeof index === 'undefined') {
|
||||
index = out.data.length
|
||||
out.data.push(elem)
|
||||
out.indexByCodeApe[elem.code_ape] ??= []
|
||||
out.indexByCodeDepartement[elem.code_departement] ??= []
|
||||
} else {
|
||||
out.data[index].nombre_d_etablissements_2021 +=
|
||||
elem.nombre_d_etablissements_2021
|
||||
}
|
||||
|
||||
if (!out.indexByCodeApe[elem.code_ape].includes(index)) {
|
||||
out.indexByCodeApe[elem.code_ape].push(index)
|
||||
}
|
||||
|
||||
if (
|
||||
!out.indexByCodeDepartement[elem.code_departement].includes(index)
|
||||
) {
|
||||
out.indexByCodeDepartement[elem.code_departement].push(index)
|
||||
}
|
||||
|
||||
cb(null)
|
||||
},
|
||||
})
|
||||
)
|
||||
|
||||
stream.on('error', (err: Error) => {
|
||||
console.error(err)
|
||||
throw err
|
||||
})
|
||||
|
||||
stream.on('close', () => {
|
||||
console.log('close')
|
||||
|
||||
writeFileSync(join(__dirname, OUTPUT_JSON_PATH), JSON.stringify(out, null, 1))
|
||||
})
|
||||
|
||||
console.log('conversion in progress...')
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,37 @@
|
|||
/* eslint-disable no-console */
|
||||
/* eslint-disable camelcase */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||
|
||||
import { writeFileSync } from 'fs'
|
||||
import { join } from 'path'
|
||||
import { fileURLToPath } from 'url'
|
||||
|
||||
const __dirname = fileURLToPath(new URL('.', import.meta.url))
|
||||
|
||||
const OUTPUT_JSON_PATH = './output.json'
|
||||
|
||||
const url =
|
||||
'https://open.urssaf.fr/api/explore/v2.1/catalog/datasets/nombre-detablissements-employeurs-et-effectifs-salaries-du-secteur-prive-france-/exports/json?lang=fr&timezone=Europe%2FBerlin'
|
||||
|
||||
export interface Data {
|
||||
nombre_d_etablissements_2021: number
|
||||
code_ape: string
|
||||
}
|
||||
|
||||
export interface Out {
|
||||
[codeAPE: string]: number
|
||||
}
|
||||
|
||||
const response = await fetch(url)
|
||||
if (!response.ok) {
|
||||
throw new Error(`Error while fetching data : ${response.status}`)
|
||||
}
|
||||
const json: Array<Data> = await response.json()
|
||||
|
||||
const out = json.reduce((acc, { code_ape, nombre_d_etablissements_2021 }) => {
|
||||
acc[code_ape] = nombre_d_etablissements_2021 ?? 0
|
||||
|
||||
return acc
|
||||
}, {} as Out)
|
||||
|
||||
writeFileSync(join(__dirname, OUTPUT_JSON_PATH), JSON.stringify(out, null, 1))
|
|
@ -0,0 +1,689 @@
|
|||
{
|
||||
"0610Z": 12,
|
||||
"0811Z": 453,
|
||||
"0891Z": 13,
|
||||
"0990Z": 23,
|
||||
"1013B": 1949,
|
||||
"1031Z": 59,
|
||||
"1042Z": 4,
|
||||
"1051B": 11,
|
||||
"1061A": 318,
|
||||
"1071B": 1440,
|
||||
"1071C": 27062,
|
||||
"1072Z": 589,
|
||||
"1081Z": 22,
|
||||
"1083Z": 513,
|
||||
"1092Z": 81,
|
||||
"1101Z": 400,
|
||||
"1102A": 138,
|
||||
"1104Z": 28,
|
||||
"1107A": 97,
|
||||
"1107B": 120,
|
||||
"1310Z": 125,
|
||||
"1411Z": 39,
|
||||
"1419Z": 417,
|
||||
"1420Z": 16,
|
||||
"1623Z": 1438,
|
||||
"1629Z": 492,
|
||||
"1721C": 63,
|
||||
"1812Z": 2904,
|
||||
"1813Z": 1707,
|
||||
"1820Z": 43,
|
||||
"1910Z": 0,
|
||||
"2013A": 2,
|
||||
"2020Z": 78,
|
||||
"2030Z": 340,
|
||||
"2041Z": 282,
|
||||
"2042Z": 821,
|
||||
"2059Z": 281,
|
||||
"2110Z": 90,
|
||||
"2311Z": 19,
|
||||
"2314Z": 12,
|
||||
"2319Z": 175,
|
||||
"2320Z": 50,
|
||||
"2342Z": 16,
|
||||
"2343Z": 9,
|
||||
"2363Z": 1617,
|
||||
"2410Z": 91,
|
||||
"2420Z": 131,
|
||||
"2432Z": 7,
|
||||
"2441Z": 11,
|
||||
"2445Z": 55,
|
||||
"2452Z": 32,
|
||||
"2454Z": 108,
|
||||
"2512Z": 1130,
|
||||
"2521Z": 46,
|
||||
"2529Z": 108,
|
||||
"2550B": 1017,
|
||||
"2561Z": 1615,
|
||||
"2562A": 413,
|
||||
"2573B": 468,
|
||||
"2591Z": 10,
|
||||
"2594Z": 112,
|
||||
"2612Z": 325,
|
||||
"2712Z": 457,
|
||||
"2720Z": 58,
|
||||
"2751Z": 82,
|
||||
"2790Z": 374,
|
||||
"2813Z": 166,
|
||||
"2814Z": 141,
|
||||
"2829A": 184,
|
||||
"2893Z": 321,
|
||||
"2899B": 486,
|
||||
"2910Z": 194,
|
||||
"3011Z": 152,
|
||||
"3030Z": 264,
|
||||
"3040Z": 5,
|
||||
"3109A": 131,
|
||||
"3109B": 1846,
|
||||
"3212Z": 951,
|
||||
"3213Z": 422,
|
||||
"3220Z": 197,
|
||||
"3250B": 257,
|
||||
"3312Z": 4649,
|
||||
"3320A": 2357,
|
||||
"3320C": 837,
|
||||
"3513Z": 1277,
|
||||
"3521Z": 57,
|
||||
"3522Z": 323,
|
||||
"3530Z": 354,
|
||||
"3700Z": 1127,
|
||||
"3821Z": 807,
|
||||
"3822Z": 189,
|
||||
"4110D": 379,
|
||||
"4212Z": 167,
|
||||
"4213B": 14,
|
||||
"4222Z": 1403,
|
||||
"4299Z": 910,
|
||||
"4311Z": 608,
|
||||
"4312B": 922,
|
||||
"4321A": 26565,
|
||||
"4322B": 13318,
|
||||
"4329B": 2237,
|
||||
"4391B": 9189,
|
||||
"4399B": 1532,
|
||||
"4399E": 551,
|
||||
"4519Z": 1171,
|
||||
"4520B": 1635,
|
||||
"4531Z": 3389,
|
||||
"4532Z": 4693,
|
||||
"4540Z": 3288,
|
||||
"4616Z": 381,
|
||||
"4617A": 220,
|
||||
"4617B": 747,
|
||||
"4622Z": 484,
|
||||
"4624Z": 86,
|
||||
"4631Z": 2207,
|
||||
"4632B": 178,
|
||||
"4642Z": 3375,
|
||||
"4644Z": 672,
|
||||
"4646Z": 2423,
|
||||
"4647Z": 860,
|
||||
"4651Z": 2457,
|
||||
"4661Z": 3625,
|
||||
"4669A": 3139,
|
||||
"4672Z": 1163,
|
||||
"4675Z": 1420,
|
||||
"4711C": 3981,
|
||||
"4719A": 164,
|
||||
"4721Z": 3677,
|
||||
"4722Z": 11091,
|
||||
"4724Z": 3247,
|
||||
"4725Z": 4096,
|
||||
"4759B": 5135,
|
||||
"4761Z": 2421,
|
||||
"4762Z": 4712,
|
||||
"4772B": 1461,
|
||||
"4773Z": 20468,
|
||||
"4778A": 12498,
|
||||
"4778B": 975,
|
||||
"4791A": 2072,
|
||||
"4920Z": 259,
|
||||
"4931Z": 896,
|
||||
"4932Z": 10016,
|
||||
"4939B": 1525,
|
||||
"4939C": 158,
|
||||
"4941C": 721,
|
||||
"4950Z": 200,
|
||||
"5010Z": 460,
|
||||
"5020Z": 124,
|
||||
"5040Z": 412,
|
||||
"5110Z": 446,
|
||||
"5210A": 411,
|
||||
"5222Z": 435,
|
||||
"5224A": 153,
|
||||
"5520Z": 5445,
|
||||
"5610A": 72133,
|
||||
"5610B": 540,
|
||||
"5630Z": 22336,
|
||||
"5812Z": 22,
|
||||
"5819Z": 428,
|
||||
"5821Z": 227,
|
||||
"5911B": 2427,
|
||||
"6202A": 16764,
|
||||
"6391Z": 342,
|
||||
"6399Z": 115,
|
||||
"6491Z": 99,
|
||||
"6520Z": 30,
|
||||
"6611Z": 29,
|
||||
"6612Z": 280,
|
||||
"6622Z": 15304,
|
||||
"6831Z": 25649,
|
||||
"6832B": 321,
|
||||
"6910Z": 21884,
|
||||
"6920Z": 18376,
|
||||
"7010Z": 15285,
|
||||
"7111Z": 10202,
|
||||
"7732Z": 2728,
|
||||
"7740Z": 397,
|
||||
"8020Z": 1513,
|
||||
"8121Z": 12323,
|
||||
"8211Z": 4596,
|
||||
"8423Z": 129,
|
||||
"8551Z": 3073,
|
||||
"8559B": 5079,
|
||||
"8623Z": 19948,
|
||||
"8690B": 3837,
|
||||
"8720B": 127,
|
||||
"8730B": 266,
|
||||
"8810C": 1933,
|
||||
"9101Z": 197,
|
||||
"9313Z": 3048,
|
||||
"9321Z": 1086,
|
||||
"9491Z": 3809,
|
||||
"9601A": 381,
|
||||
"9601B": 3213,
|
||||
"9602A": 39046,
|
||||
"9609Z": 4611,
|
||||
"5920Z": 1508,
|
||||
"6020B": 107,
|
||||
"6110Z": 1853,
|
||||
"6411Z": 125,
|
||||
"6430Z": 2703,
|
||||
"7420Z": 1657,
|
||||
"7500Z": 5294,
|
||||
"7712Z": 530,
|
||||
"7722Z": 12,
|
||||
"7729Z": 2000,
|
||||
"7733Z": 166,
|
||||
"7734Z": 60,
|
||||
"8010Z": 4456,
|
||||
"8110Z": 46556,
|
||||
"8122Z": 3741,
|
||||
"8129A": 912,
|
||||
"8292Z": 895,
|
||||
"8422Z": 0,
|
||||
"8424Z": 1,
|
||||
"8430C": 284,
|
||||
"8553Z": 7459,
|
||||
"8610Z": 2644,
|
||||
"8622C": 9645,
|
||||
"8690A": 5163,
|
||||
"8690E": 6682,
|
||||
"8690F": 1248,
|
||||
"8710B": 1345,
|
||||
"8730A": 1348,
|
||||
"8810B": 1057,
|
||||
"9104Z": 213,
|
||||
"9200Z": 400,
|
||||
"9311Z": 2561,
|
||||
"9319Z": 1937,
|
||||
"9523Z": 924,
|
||||
"9604Z": 2292,
|
||||
"0721Z": 0,
|
||||
"0729Z": 58,
|
||||
"0812Z": 1493,
|
||||
"0892Z": 16,
|
||||
"0893Z": 11,
|
||||
"0899Z": 27,
|
||||
"1012Z": 248,
|
||||
"1013A": 615,
|
||||
"1032Z": 73,
|
||||
"1039A": 222,
|
||||
"1039B": 318,
|
||||
"1041A": 93,
|
||||
"1051C": 488,
|
||||
"1062Z": 12,
|
||||
"1071A": 639,
|
||||
"1085Z": 618,
|
||||
"1102B": 114,
|
||||
"1103Z": 40,
|
||||
"1106Z": 17,
|
||||
"1200Z": 9,
|
||||
"1320Z": 183,
|
||||
"1391Z": 36,
|
||||
"1393Z": 29,
|
||||
"1395Z": 35,
|
||||
"1414Z": 129,
|
||||
"1511Z": 68,
|
||||
"1512Z": 675,
|
||||
"1520Z": 191,
|
||||
"1610A": 553,
|
||||
"1621Z": 83,
|
||||
"1624Z": 736,
|
||||
"1712Z": 126,
|
||||
"1722Z": 50,
|
||||
"1723Z": 92,
|
||||
"1729Z": 290,
|
||||
"1811Z": 43,
|
||||
"2013B": 89,
|
||||
"2016Z": 170,
|
||||
"2017Z": 13,
|
||||
"2051Z": 44,
|
||||
"2120Z": 416,
|
||||
"2221Z": 330,
|
||||
"2312Z": 328,
|
||||
"2332Z": 105,
|
||||
"2341Z": 222,
|
||||
"2344Z": 25,
|
||||
"2351Z": 76,
|
||||
"2362Z": 33,
|
||||
"2364Z": 78,
|
||||
"2365Z": 9,
|
||||
"2391Z": 25,
|
||||
"2399Z": 438,
|
||||
"2434Z": 22,
|
||||
"2443Z": 17,
|
||||
"2444Z": 27,
|
||||
"2451Z": 59,
|
||||
"2453Z": 105,
|
||||
"2511Z": 3035,
|
||||
"2540Z": 56,
|
||||
"2562B": 4754,
|
||||
"2571Z": 131,
|
||||
"2593Z": 391,
|
||||
"2630Z": 318,
|
||||
"2640Z": 121,
|
||||
"2651A": 93,
|
||||
"2651B": 671,
|
||||
"2680Z": 3,
|
||||
"2731Z": 22,
|
||||
"2733Z": 182,
|
||||
"2811Z": 81,
|
||||
"2812Z": 353,
|
||||
"2815Z": 121,
|
||||
"2821Z": 75,
|
||||
"2822Z": 579,
|
||||
"2823Z": 19,
|
||||
"2824Z": 7,
|
||||
"2894Z": 48,
|
||||
"2895Z": 28,
|
||||
"2896Z": 40,
|
||||
"2931Z": 91,
|
||||
"2932Z": 489,
|
||||
"3091Z": 41,
|
||||
"3099Z": 16,
|
||||
"3101Z": 597,
|
||||
"3102Z": 429,
|
||||
"3211Z": 9,
|
||||
"3250A": 3995,
|
||||
"3299Z": 613,
|
||||
"3314Z": 871,
|
||||
"3317Z": 75,
|
||||
"3320B": 1915,
|
||||
"3514Z": 159,
|
||||
"3831Z": 302,
|
||||
"4110A": 3042,
|
||||
"4110B": 90,
|
||||
"4120A": 10811,
|
||||
"4120B": 5451,
|
||||
"4211Z": 1652,
|
||||
"4213A": 129,
|
||||
"4312A": 9358,
|
||||
"4331Z": 10243,
|
||||
"4332A": 19800,
|
||||
"4332B": 8199,
|
||||
"4334Z": 19091,
|
||||
"4399D": 3410,
|
||||
"4511Z": 16799,
|
||||
"4612B": 180,
|
||||
"4615Z": 250,
|
||||
"4623Z": 791,
|
||||
"4633Z": 443,
|
||||
"4637Z": 276,
|
||||
"4639B": 1992,
|
||||
"4641Z": 1000,
|
||||
"4643Z": 711,
|
||||
"4648Z": 355,
|
||||
"4649Z": 4750,
|
||||
"4662Z": 504,
|
||||
"4663Z": 1128,
|
||||
"4664Z": 56,
|
||||
"4665Z": 426,
|
||||
"4666Z": 1058,
|
||||
"4669C": 2997,
|
||||
"4673A": 9169,
|
||||
"4673B": 2537,
|
||||
"4674A": 1631,
|
||||
"4674B": 2077,
|
||||
"4690Z": 5822,
|
||||
"4711D": 10917,
|
||||
"4711E": 179,
|
||||
"4730Z": 3219,
|
||||
"4752B": 2719,
|
||||
"4753Z": 675,
|
||||
"4759A": 7848,
|
||||
"4764Z": 6902,
|
||||
"4771Z": 32956,
|
||||
"4772A": 5799,
|
||||
"4775Z": 5395,
|
||||
"4776Z": 8653,
|
||||
"4778C": 13276,
|
||||
"4779Z": 2294,
|
||||
"4791B": 3497,
|
||||
"4799B": 1201,
|
||||
"4910Z": 1605,
|
||||
"4941B": 14212,
|
||||
"4942Z": 1394,
|
||||
"5030Z": 131,
|
||||
"5122Z": 3,
|
||||
"5210B": 3437,
|
||||
"5223Z": 389,
|
||||
"5229A": 1063,
|
||||
"5510Z": 17258,
|
||||
"5530Z": 3069,
|
||||
"5590Z": 924,
|
||||
"5629A": 4189,
|
||||
"5811Z": 1064,
|
||||
"5813Z": 971,
|
||||
"5814Z": 1565,
|
||||
"5829C": 3223,
|
||||
"5911A": 2981,
|
||||
"5911C": 1839,
|
||||
"5912Z": 682,
|
||||
"5913A": 156,
|
||||
"5913B": 69,
|
||||
"6020A": 138,
|
||||
"6130Z": 40,
|
||||
"6190Z": 1530,
|
||||
"6201Z": 11176,
|
||||
"6312Z": 1252,
|
||||
"6419Z": 18075,
|
||||
"6492Z": 946,
|
||||
"6499Z": 307,
|
||||
"6511Z": 405,
|
||||
"6512Z": 5486,
|
||||
"6619A": 11053,
|
||||
"6810Z": 3800,
|
||||
"6820A": 5512,
|
||||
"6832A": 5997,
|
||||
"7021Z": 4513,
|
||||
"7022Z": 37967,
|
||||
"7112A": 1788,
|
||||
"7112B": 25181,
|
||||
"7312Z": 1436,
|
||||
"7410Z": 3995,
|
||||
"7490A": 1894,
|
||||
"7490B": 4982,
|
||||
"7711A": 2756,
|
||||
"7721Z": 1292,
|
||||
"7735Z": 46,
|
||||
"7739Z": 1560,
|
||||
"7820Z": 20983,
|
||||
"7830Z": 2372,
|
||||
"7912Z": 650,
|
||||
"7990Z": 1757,
|
||||
"8030Z": 104,
|
||||
"8129B": 713,
|
||||
"8130Z": 710,
|
||||
"8219Z": 9332,
|
||||
"8220Z": 751,
|
||||
"8230Z": 2938,
|
||||
"8291Z": 268,
|
||||
"8299Z": 8692,
|
||||
"8411Z": 44,
|
||||
"8412Z": 346,
|
||||
"8430A": 1304,
|
||||
"8430B": 184,
|
||||
"8531Z": 1632,
|
||||
"8532Z": 944,
|
||||
"8541Z": 42,
|
||||
"8552Z": 3125,
|
||||
"8622B": 1880,
|
||||
"8720A": 2132,
|
||||
"8790A": 1832,
|
||||
"8899A": 751,
|
||||
"9003B": 568,
|
||||
"9103Z": 582,
|
||||
"9312Z": 26234,
|
||||
"9411Z": 2483,
|
||||
"9412Z": 1668,
|
||||
"9499Z": 33416,
|
||||
"9521Z": 410,
|
||||
"9522Z": 855,
|
||||
"9525Z": 257,
|
||||
"9529Z": 1699,
|
||||
"9603Z": 5165,
|
||||
"0510Z": 0,
|
||||
"0620Z": 0,
|
||||
"0910Z": 10,
|
||||
"1011Z": 861,
|
||||
"1020Z": 324,
|
||||
"1041B": 42,
|
||||
"1051A": 126,
|
||||
"1051D": 60,
|
||||
"1052Z": 321,
|
||||
"1061B": 61,
|
||||
"1071D": 2944,
|
||||
"1073Z": 173,
|
||||
"1082Z": 1133,
|
||||
"1084Z": 114,
|
||||
"1086Z": 122,
|
||||
"1089Z": 658,
|
||||
"1091Z": 321,
|
||||
"1105Z": 875,
|
||||
"1330Z": 197,
|
||||
"1392Z": 904,
|
||||
"1394Z": 52,
|
||||
"1396Z": 188,
|
||||
"1399Z": 278,
|
||||
"1412Z": 70,
|
||||
"1413Z": 1350,
|
||||
"1431Z": 29,
|
||||
"1439Z": 59,
|
||||
"1610B": 377,
|
||||
"1622Z": 19,
|
||||
"1711Z": 8,
|
||||
"1721A": 239,
|
||||
"1721B": 292,
|
||||
"1724Z": 9,
|
||||
"1814Z": 137,
|
||||
"1920Z": 61,
|
||||
"2011Z": 124,
|
||||
"2012Z": 37,
|
||||
"2014Z": 216,
|
||||
"2015Z": 114,
|
||||
"2052Z": 44,
|
||||
"2053Z": 145,
|
||||
"2060Z": 9,
|
||||
"2211Z": 39,
|
||||
"2219Z": 381,
|
||||
"2222Z": 555,
|
||||
"2223Z": 655,
|
||||
"2229A": 1011,
|
||||
"2229B": 507,
|
||||
"2313Z": 148,
|
||||
"2331Z": 51,
|
||||
"2349Z": 20,
|
||||
"2352Z": 41,
|
||||
"2361Z": 769,
|
||||
"2369Z": 121,
|
||||
"2370Z": 1349,
|
||||
"2431Z": 12,
|
||||
"2433Z": 171,
|
||||
"2442Z": 67,
|
||||
"2446Z": 10,
|
||||
"2530Z": 23,
|
||||
"2550A": 347,
|
||||
"2572Z": 231,
|
||||
"2573A": 378,
|
||||
"2592Z": 90,
|
||||
"2599A": 78,
|
||||
"2599B": 787,
|
||||
"2611Z": 302,
|
||||
"2620Z": 154,
|
||||
"2652Z": 82,
|
||||
"2660Z": 112,
|
||||
"2670Z": 119,
|
||||
"2711Z": 204,
|
||||
"2732Z": 113,
|
||||
"2740Z": 443,
|
||||
"2752Z": 54,
|
||||
"2825Z": 656,
|
||||
"2829B": 414,
|
||||
"2830Z": 476,
|
||||
"2841Z": 157,
|
||||
"2849Z": 86,
|
||||
"2891Z": 17,
|
||||
"2892Z": 122,
|
||||
"2899A": 38,
|
||||
"2920Z": 1059,
|
||||
"3012Z": 232,
|
||||
"3020Z": 47,
|
||||
"3092Z": 96,
|
||||
"3103Z": 125,
|
||||
"3230Z": 260,
|
||||
"3240Z": 148,
|
||||
"3291Z": 57,
|
||||
"3311Z": 631,
|
||||
"3313Z": 380,
|
||||
"3315Z": 1012,
|
||||
"3316Z": 234,
|
||||
"3319Z": 272,
|
||||
"3320D": 946,
|
||||
"3511Z": 1396,
|
||||
"3512Z": 184,
|
||||
"3523Z": 96,
|
||||
"3600Z": 894,
|
||||
"3811Z": 1225,
|
||||
"3812Z": 223,
|
||||
"3832Z": 2349,
|
||||
"3900Z": 527,
|
||||
"4110C": 452,
|
||||
"4221Z": 921,
|
||||
"4291Z": 153,
|
||||
"4313Z": 325,
|
||||
"4321B": 217,
|
||||
"4322A": 16449,
|
||||
"4329A": 3687,
|
||||
"4332C": 1145,
|
||||
"4333Z": 8561,
|
||||
"4339Z": 2688,
|
||||
"4391A": 5756,
|
||||
"4399A": 3039,
|
||||
"4399C": 39891,
|
||||
"4520A": 32910,
|
||||
"4611Z": 217,
|
||||
"4612A": 5,
|
||||
"4613Z": 547,
|
||||
"4614Z": 494,
|
||||
"4618Z": 1968,
|
||||
"4619A": 393,
|
||||
"4619B": 3277,
|
||||
"4621Z": 1638,
|
||||
"4632A": 492,
|
||||
"4632C": 146,
|
||||
"4634Z": 3796,
|
||||
"4635Z": 33,
|
||||
"4636Z": 270,
|
||||
"4638A": 672,
|
||||
"4638B": 1506,
|
||||
"4639A": 469,
|
||||
"4645Z": 1819,
|
||||
"4652Z": 2134,
|
||||
"4669B": 8308,
|
||||
"4671Z": 1007,
|
||||
"4676Z": 1228,
|
||||
"4677Z": 439,
|
||||
"4711A": 1644,
|
||||
"4711B": 13548,
|
||||
"4711F": 1877,
|
||||
"4719B": 3817,
|
||||
"4723Z": 1482,
|
||||
"4726Z": 4328,
|
||||
"4729Z": 7495,
|
||||
"4741Z": 2627,
|
||||
"4742Z": 2766,
|
||||
"4743Z": 645,
|
||||
"4751Z": 2290,
|
||||
"4752A": 3796,
|
||||
"4754Z": 2225,
|
||||
"4763Z": 132,
|
||||
"4765Z": 1496,
|
||||
"4774Z": 5815,
|
||||
"4777Z": 4851,
|
||||
"4781Z": 6120,
|
||||
"4782Z": 412,
|
||||
"4789Z": 1470,
|
||||
"4799A": 1111,
|
||||
"4939A": 1532,
|
||||
"4941A": 11550,
|
||||
"5121Z": 28,
|
||||
"5221Z": 3827,
|
||||
"5224B": 353,
|
||||
"5229B": 4004,
|
||||
"5310Z": 3648,
|
||||
"5320Z": 616,
|
||||
"5610C": 46970,
|
||||
"5621Z": 4279,
|
||||
"5629B": 5630,
|
||||
"5829A": 563,
|
||||
"5829B": 140,
|
||||
"5914Z": 1125,
|
||||
"6120Z": 389,
|
||||
"6202B": 712,
|
||||
"6203Z": 671,
|
||||
"6209Z": 890,
|
||||
"6420Z": 24740,
|
||||
"6530Z": 5,
|
||||
"6619B": 3792,
|
||||
"6621Z": 1273,
|
||||
"7311Z": 7301,
|
||||
"7320Z": 824,
|
||||
"7430Z": 545,
|
||||
"7731Z": 87,
|
||||
"7810Z": 821,
|
||||
"8425Z": 24,
|
||||
"8520Z": 4009,
|
||||
"8559A": 11331,
|
||||
"8621Z": 15537,
|
||||
"8690C": 12,
|
||||
"8690D": 4441,
|
||||
"8790B": 2256,
|
||||
"8810A": 8069,
|
||||
"8891A": 10445,
|
||||
"8891B": 1117,
|
||||
"9002Z": 2513,
|
||||
"9003A": 575,
|
||||
"9102Z": 341,
|
||||
"9329Z": 6593,
|
||||
"9492Z": 194,
|
||||
"9511Z": 1398,
|
||||
"9524Z": 373,
|
||||
"9602B": 11604,
|
||||
"6010Z": 1027,
|
||||
"6311Z": 2469,
|
||||
"6629Z": 286,
|
||||
"6630Z": 5215,
|
||||
"6820B": 11485,
|
||||
"7120A": 5771,
|
||||
"7120B": 5258,
|
||||
"7211Z": 826,
|
||||
"7219Z": 2018,
|
||||
"7220Z": 305,
|
||||
"7711B": 188,
|
||||
"7911Z": 4222,
|
||||
"8413Z": 837,
|
||||
"8421Z": 2,
|
||||
"8510Z": 173,
|
||||
"8542Z": 1216,
|
||||
"8560Z": 364,
|
||||
"8622A": 869,
|
||||
"8710A": 3585,
|
||||
"8710C": 825,
|
||||
"8899B": 9438,
|
||||
"9001Z": 16964,
|
||||
"9004Z": 878,
|
||||
"9420Z": 2237,
|
||||
"9512Z": 456
|
||||
}
|
|
@ -12,19 +12,16 @@
|
|||
"scripts": {
|
||||
"start:données-NAF-CPF-APE": "ts-node-esm ./codeAPESearch/données-NAF-CPF-APE/convert-pdf.ts",
|
||||
"start:données-NomenclatureGuichet": "ts-node-esm ./codeAPESearch/données-NomenclatureGuichet/convert.ts",
|
||||
"start:nombre-etablissements-par-code-ape-et-departement": "ts-node-esm ./codeAPESearch/nombre-etablissements-par-code-ape-et-departement/convert-json.ts",
|
||||
"start:nombre-etablissements-par-code-ape": "ts-node-esm ./codeAPESearch/nombre-etablissements-par-code-ape/convert-json.ts",
|
||||
"start:données-code-APE": "ts-node-esm ./codeAPESearch/données-code-APE/reduce-json.ts",
|
||||
"start:watch:données-NAF-CPF-APE": "nodemon -x 'yarn start:données-NAF-CPF-APE' -e 'ts'",
|
||||
"start:watch:nombre-etablissements-par-code-ape-et-departement": "nodemon -x 'yarn start:nombre-etablissements-par-code-ape-et-departement' -e 'ts'",
|
||||
"start:watch:nombre-etablissements-par-code-ape": "nodemon -x 'yarn start:nombre-etablissements-par-code-ape' -e 'ts'",
|
||||
"start:watch:données-code-APE": "nodemon -x 'yarn start:données-code-APE' -e 'ts'"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/stream-json": "^1.7.3",
|
||||
"csv": "^6.2.7",
|
||||
"csv-parser": "^3.0.0",
|
||||
"got": "^12.5.3",
|
||||
"pdfdataextract": "^3.2.0",
|
||||
"stream-json": "^1.7.5",
|
||||
"ts-node": "^10.9.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import { AriaRadioProps } from '@react-types/radio'
|
||||
import styled from 'styled-components'
|
||||
import { ComponentProps } from 'react'
|
||||
import styled, { css } from 'styled-components'
|
||||
|
||||
import { Markdown } from '@/components/utils/markdown'
|
||||
import { CardContainer } from '@/design-system/card/Card'
|
||||
import { Emoji } from '@/design-system/emoji'
|
||||
|
||||
import { LabelBody, RadioPoint, RadioSkeleton, VisibleRadio } from './Radio'
|
||||
|
@ -17,18 +19,29 @@ const StyledRadioPoint = styled(RadioPoint)`
|
|||
margin-top: 0.2rem;
|
||||
`
|
||||
|
||||
export const StyledRadioSkeleton = styled(RadioSkeleton)`
|
||||
flex: 1 100%;
|
||||
margin-bottom: ${({ theme }) => theme.spacings.xs};
|
||||
export const StyledRadioSkeleton = ({
|
||||
children,
|
||||
...rest
|
||||
}: ComponentProps<typeof RadioSkeleton>) => (
|
||||
<StyledCardContainer $inert={rest.isDisabled} as={RadioSkeleton} {...rest}>
|
||||
{children}
|
||||
</StyledCardContainer>
|
||||
)
|
||||
|
||||
const StyledCardContainer = styled(CardContainer)`
|
||||
${VisibleRadio} {
|
||||
border-radius: var(--radius) !important;
|
||||
display: flex;
|
||||
flex: 1 100%;
|
||||
border-width: 0px;
|
||||
box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.25);
|
||||
padding: ${({ theme }) => theme.spacings.sm};
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
background: transparent;
|
||||
border: none;
|
||||
}
|
||||
${({ theme, $inert }) =>
|
||||
$inert &&
|
||||
css`
|
||||
background-color: ${theme.colors.extended.grey[200]};
|
||||
`}
|
||||
margin: 0.5rem 0;
|
||||
`
|
||||
|
||||
type RadioCardProps = AriaRadioProps & {
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
import { useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import styled, { css } from 'styled-components'
|
||||
|
||||
import { Appear } from '@/components/ui/animate'
|
||||
import { Chip } from '@/design-system'
|
||||
import InfoBulle from '@/design-system/InfoBulle'
|
||||
import { Button } from '@/design-system/buttons'
|
||||
import { ChevronIcon } from '@/design-system/icons'
|
||||
import { Grid } from '@/design-system/layout'
|
||||
import { H3, H4 } from '@/design-system/typography/heading'
|
||||
import { Li, Ul } from '@/design-system/typography/list'
|
||||
|
||||
interface ResultProps {
|
||||
debug: string | null
|
||||
item: {
|
||||
title: string
|
||||
codeApe: string
|
||||
contenuCentral: string[]
|
||||
contenuAnnexe: string[]
|
||||
contenuExclu: string[]
|
||||
}
|
||||
}
|
||||
|
||||
export const Result = ({ item, debug }: ResultProps) => {
|
||||
const { title, codeApe, contenuCentral, contenuAnnexe, contenuExclu } = item
|
||||
const [open, setOpen] = useState(false)
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<Grid container style={{ alignItems: 'center' }}>
|
||||
<Grid item xs={12} sm={8} md={9} xl={10}>
|
||||
<H3 style={{ marginTop: 0, marginBottom: '.5rem' }}>
|
||||
{title} <Chip type="secondary">{codeApe}</Chip>
|
||||
{debug && (
|
||||
<InfoBulle>
|
||||
<pre>{debug}</pre>
|
||||
</InfoBulle>
|
||||
)}
|
||||
</H3>
|
||||
</Grid>
|
||||
|
||||
<StyledGrid item xs={12} sm={4} md={3} xl={2}>
|
||||
<Button
|
||||
light
|
||||
size="XXS"
|
||||
onPress={() => setOpen((x) => !x)}
|
||||
aria-expanded={open}
|
||||
aria-controls={`info-${codeApe}`}
|
||||
aria-label={!open ? t('En savoir plus') : t('Replier')}
|
||||
>
|
||||
{!open ? t('En savoir plus') : t('Replier')}{' '}
|
||||
<StyledChevron aria-hidden $isOpen={open} />
|
||||
</Button>
|
||||
</StyledGrid>
|
||||
|
||||
{open && (
|
||||
<Appear id={`info-${codeApe}`}>
|
||||
{contenuCentral.length ? (
|
||||
<>
|
||||
<H4>Contenu central de cette activité :</H4>
|
||||
<Ul>
|
||||
{contenuCentral.map((contenu, i) => (
|
||||
<Li key={i}>{contenu}</Li>
|
||||
))}
|
||||
</Ul>
|
||||
</>
|
||||
) : null}
|
||||
|
||||
{contenuAnnexe.length ? (
|
||||
<>
|
||||
<H4>Contenu annexe de cette activité :</H4>
|
||||
<Ul>
|
||||
{contenuAnnexe.map((contenu, i) => (
|
||||
<Li key={i}>{contenu}</Li>
|
||||
))}
|
||||
</Ul>
|
||||
</>
|
||||
) : null}
|
||||
|
||||
{contenuExclu.length ? (
|
||||
<>
|
||||
<H4>Contenu exclu de cette activité :</H4>
|
||||
<Ul>
|
||||
{contenuExclu.map((contenu, i) => (
|
||||
<Li key={i}>{contenu}</Li>
|
||||
))}
|
||||
</Ul>
|
||||
</>
|
||||
) : null}
|
||||
</Appear>
|
||||
)}
|
||||
</Grid>
|
||||
)
|
||||
}
|
||||
|
||||
const StyledGrid = styled(Grid)`
|
||||
display: flex;
|
||||
justify-content: end;
|
||||
align-items: center;
|
||||
`
|
||||
|
||||
const StyledChevron = styled(ChevronIcon)<{ $isOpen: boolean }>`
|
||||
vertical-align: middle;
|
||||
transform: rotate(-90deg);
|
||||
transition: transform 0.3s;
|
||||
${({ $isOpen }) =>
|
||||
!$isOpen &&
|
||||
css`
|
||||
transform: rotate(90deg);
|
||||
`}
|
||||
`
|
|
@ -1,26 +1,23 @@
|
|||
import UFuzzy from '@leeoniya/ufuzzy'
|
||||
import { Fragment, useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import styled, { css } from 'styled-components'
|
||||
import styled from 'styled-components'
|
||||
|
||||
import FeedbackForm from '@/components/Feedback/FeedbackForm'
|
||||
import { FromTop } from '@/components/ui/animate'
|
||||
import {
|
||||
Chip,
|
||||
PopoverWithTrigger,
|
||||
RadioCardGroup,
|
||||
TextField,
|
||||
SearchField,
|
||||
} from '@/design-system'
|
||||
import { Button } from '@/design-system/buttons'
|
||||
import { Emoji } from '@/design-system/emoji'
|
||||
import { StyledRadioSkeleton } from '@/design-system/field/Radio/RadioCard'
|
||||
import { ChevronIcon } from '@/design-system/icons'
|
||||
import { Grid, Spacing } from '@/design-system/layout'
|
||||
import { H3 } from '@/design-system/typography/heading'
|
||||
import { Body } from '@/design-system/typography/paragraphs'
|
||||
import { useAsyncData } from '@/hooks/useAsyncData'
|
||||
|
||||
import { Output as Data } from '../../../../../scripts/codeAPESearch/données-code-APE/reduce-json'
|
||||
import { Result } from './Result'
|
||||
|
||||
interface SearchableData {
|
||||
original: string[]
|
||||
|
@ -67,142 +64,6 @@ const buildResearch = (lazyData: Data | null) => {
|
|||
}
|
||||
}
|
||||
|
||||
const nbEtablissementParDepartement = (
|
||||
data: Data,
|
||||
department: string,
|
||||
code: string
|
||||
) => {
|
||||
const { indexByCodeApe, indexByCodeDepartement, nbEtablissements2021 } = data
|
||||
|
||||
const index =
|
||||
indexByCodeApe[code] &&
|
||||
indexByCodeDepartement[department]?.find((i) =>
|
||||
indexByCodeApe[code].includes(i)
|
||||
)
|
||||
|
||||
return typeof index === 'number'
|
||||
? nbEtablissements2021[index]
|
||||
: indexByCodeApe[code]?.reduce(
|
||||
(acc, index) => acc + nbEtablissements2021[index],
|
||||
0
|
||||
) ?? 0
|
||||
}
|
||||
|
||||
interface ResultProps {
|
||||
debug: string | null
|
||||
item: {
|
||||
title: string
|
||||
codeApe: string
|
||||
contenuCentral: string[]
|
||||
contenuAnnexe: string[]
|
||||
contenuExclu: string[]
|
||||
}
|
||||
}
|
||||
|
||||
const Result = ({ item, debug }: ResultProps) => {
|
||||
const { title, codeApe, contenuCentral, contenuAnnexe, contenuExclu } = item
|
||||
const [open, setOpen] = useState(false)
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<Grid container style={{ alignItems: 'center' }}>
|
||||
<Grid item xs={12} sm={8} md={9} xl={10}>
|
||||
<H3 style={{ marginTop: 0, marginBottom: '.5rem' }}>
|
||||
{title}
|
||||
<Chip type="secondary">APE: {codeApe}</Chip>
|
||||
</H3>
|
||||
|
||||
{debug && <pre>{debug}</pre>}
|
||||
</Grid>
|
||||
|
||||
<StyledGrid item xs={12} sm={4} md={3} xl={2}>
|
||||
<Button
|
||||
size="XXS"
|
||||
light
|
||||
onPress={() => setOpen((x) => !x)}
|
||||
aria-label={!open ? t('En savoir plus') : t('Replier')}
|
||||
aria-expanded={open}
|
||||
aria-controls={`info-${codeApe}`}
|
||||
>
|
||||
{!open ? t('En savoir plus') : t('Replier')}{' '}
|
||||
<StyledChevron aria-hidden $isOpen={open} />
|
||||
</Button>
|
||||
</StyledGrid>
|
||||
|
||||
{open && (
|
||||
<FromTop id={`info-${codeApe}`}>
|
||||
<Grid item xs={12}>
|
||||
<p style={{ marginTop: 0 }}>
|
||||
{contenuCentral.length ? (
|
||||
<>
|
||||
<span style={{ fontWeight: 'bold' }}>
|
||||
Contenu central de cette activité :
|
||||
</span>
|
||||
<br />
|
||||
</>
|
||||
) : null}
|
||||
{contenuCentral.map((contenu, i) => (
|
||||
<Fragment key={i}>
|
||||
{contenu}
|
||||
<br />
|
||||
</Fragment>
|
||||
))}
|
||||
{contenuCentral.length ? <br /> : null}
|
||||
|
||||
{contenuAnnexe.length ? (
|
||||
<>
|
||||
<span style={{ fontWeight: 'bold' }}>
|
||||
Contenu annexe de cette activité :
|
||||
</span>
|
||||
<br />
|
||||
</>
|
||||
) : null}
|
||||
{contenuAnnexe.map((contenu, i) => (
|
||||
<Fragment key={i}>
|
||||
{contenu}
|
||||
<br />
|
||||
</Fragment>
|
||||
))}
|
||||
{contenuAnnexe.length ? <br /> : null}
|
||||
|
||||
{contenuExclu.length ? (
|
||||
<>
|
||||
<span style={{ fontWeight: 'bold' }}>
|
||||
Contenu exclu de cette activité :
|
||||
</span>
|
||||
<br />
|
||||
</>
|
||||
) : null}
|
||||
{contenuExclu.map((contenu, i) => (
|
||||
<Fragment key={i}>
|
||||
{contenu}
|
||||
<br />
|
||||
</Fragment>
|
||||
))}
|
||||
</p>
|
||||
</Grid>
|
||||
</FromTop>
|
||||
)}
|
||||
</Grid>
|
||||
)
|
||||
}
|
||||
|
||||
const StyledGrid = styled(Grid)`
|
||||
display: flex;
|
||||
justify-content: end;
|
||||
`
|
||||
|
||||
const StyledChevron = styled(ChevronIcon)<{ $isOpen: boolean }>`
|
||||
vertical-align: middle;
|
||||
transform: rotate(-90deg);
|
||||
transition: transform 0.3s;
|
||||
${({ $isOpen }) =>
|
||||
!$isOpen &&
|
||||
css`
|
||||
transform: rotate(90deg);
|
||||
`}
|
||||
`
|
||||
|
||||
interface ListResult {
|
||||
item: Data['apeData'][0]
|
||||
score: number
|
||||
|
@ -216,11 +77,10 @@ interface SearchCodeApeProps {
|
|||
export default function SearchCodeAPE({ disabled }: SearchCodeApeProps) {
|
||||
const { t } = useTranslation()
|
||||
const [job, setJob] = useState('')
|
||||
const [department, setDepartment] = useState('')
|
||||
const [selected, setSelected] = useState('')
|
||||
const [list, setList] = useState<ListResult[]>([])
|
||||
|
||||
const lazyData = useAsyncData(
|
||||
const lazyData: Data | null = useAsyncData(
|
||||
() =>
|
||||
import(
|
||||
'../../../../../scripts/codeAPESearch/données-code-APE/output.min.json'
|
||||
|
@ -267,11 +127,11 @@ export default function SearchCodeAPE({ disabled }: SearchCodeApeProps) {
|
|||
const genericLatin = search(genericList.latinized, latinizedValue)
|
||||
|
||||
/**
|
||||
* Calcul le score final avec 3/4 * le score de la recherche + 1/4 * le score en fonction
|
||||
* du nombre de création d'entreprise par code APE et departement en 2021
|
||||
* Calcul le score final avec 2/3 * le score de la recherche + 1/3 * le score en fonction
|
||||
* du nombre de création d'entreprise par code APE en 2021
|
||||
*/
|
||||
const computeScore = (scoreFuzzy: number, scoreNbEtablissement: number) =>
|
||||
(3 / 4) * scoreFuzzy + (1 / 4) * scoreNbEtablissement
|
||||
(2 / 3) * scoreFuzzy + (1 / 3) * scoreNbEtablissement
|
||||
|
||||
const results = [
|
||||
...new Set([
|
||||
|
@ -284,11 +144,7 @@ export default function SearchCodeAPE({ disabled }: SearchCodeApeProps) {
|
|||
.map((item, index, arr) => ({
|
||||
item,
|
||||
scoreFuzzy: index / arr.length,
|
||||
nbEtablissement: nbEtablissementParDepartement(
|
||||
lazyData,
|
||||
department,
|
||||
item.codeApe.replace('.', '')
|
||||
),
|
||||
nbEtablissement: lazyData.indexByCodeApe[item.codeApe.replace('.', '')],
|
||||
}))
|
||||
.sort(({ nbEtablissement: a }, { nbEtablissement: b }) => b - a)
|
||||
.map(({ item, scoreFuzzy, nbEtablissement }, index, arr) => {
|
||||
|
@ -310,63 +166,51 @@ export default function SearchCodeAPE({ disabled }: SearchCodeApeProps) {
|
|||
|
||||
setList(results)
|
||||
prevValue.current = job
|
||||
}, [buildedResearch, department, job, lazyData])
|
||||
}, [buildedResearch, job, lazyData])
|
||||
|
||||
const ret = (
|
||||
<Body as="div">
|
||||
<Grid container>
|
||||
<Grid item xs={4}>
|
||||
<TextField
|
||||
value={department}
|
||||
onChange={setDepartment}
|
||||
label={t('Département')}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={8}>
|
||||
<TextField
|
||||
value={job}
|
||||
onChange={setJob}
|
||||
label={t('Votre activité')}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid container>
|
||||
<Grid item lg={12} xl={10}>
|
||||
<SearchField
|
||||
value={job}
|
||||
onChange={setJob}
|
||||
label={t("Mots-clés définissants l'activité")}
|
||||
placeholder={t('Par exemple : coiffure, boulangerie ou restauration')}
|
||||
/>
|
||||
<Spacing xs />
|
||||
{list.length > 0 && (
|
||||
<FromTop>
|
||||
<StyledRadioCardGroup
|
||||
value={selected}
|
||||
onChange={setSelected}
|
||||
isDisabled={disabled}
|
||||
>
|
||||
{list.slice(0, 25).map(({ item, debug }) => {
|
||||
return (
|
||||
<StyledRadioSkeleton
|
||||
isDisabled={disabled}
|
||||
value={item.codeApe}
|
||||
key={item.codeApe}
|
||||
visibleRadioAs="div"
|
||||
>
|
||||
<Result item={item} debug={debug} />
|
||||
</StyledRadioSkeleton>
|
||||
)
|
||||
})}
|
||||
</StyledRadioCardGroup>
|
||||
</FromTop>
|
||||
)}
|
||||
|
||||
<Spacing md />
|
||||
<ActivityNotFound />
|
||||
</Grid>
|
||||
|
||||
{IS_DEVELOPMENT && (
|
||||
<>
|
||||
[selected: <span>{disabled ? 'disabled' : selected || 'none'}</span>]
|
||||
</>
|
||||
)}
|
||||
|
||||
<StyledRadioCardGroup
|
||||
value={selected}
|
||||
onChange={setSelected}
|
||||
isDisabled={disabled}
|
||||
>
|
||||
<Grid container>
|
||||
{list.slice(0, 25).map(({ item, debug }) => {
|
||||
return (
|
||||
<StyledRadioSkeleton
|
||||
value={item.codeApe}
|
||||
key={item.codeApe}
|
||||
visibleRadioAs="div"
|
||||
>
|
||||
<Result item={item} debug={debug} />
|
||||
</StyledRadioSkeleton>
|
||||
)
|
||||
})}
|
||||
</Grid>
|
||||
</StyledRadioCardGroup>
|
||||
|
||||
<Spacing sm />
|
||||
<ActivityNotFound />
|
||||
</Body>
|
||||
</Grid>
|
||||
)
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
const StyledRadioCardGroup = styled(RadioCardGroup)`
|
||||
margin-top: 1rem;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
`
|
||||
|
|
38
yarn.lock
38
yarn.lock
|
@ -9149,25 +9149,6 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/stream-chain@npm:*":
|
||||
version: 2.0.1
|
||||
resolution: "@types/stream-chain@npm:2.0.1"
|
||||
dependencies:
|
||||
"@types/node": "*"
|
||||
checksum: 6a59da0374a74ad6aff48c669c72d3060d428d1015af94b00d290ede68706781a8419daf490af7935f0f9f2796da6965aead74ad1795f72c488630451241db55
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/stream-json@npm:^1.7.3":
|
||||
version: 1.7.3
|
||||
resolution: "@types/stream-json@npm:1.7.3"
|
||||
dependencies:
|
||||
"@types/node": "*"
|
||||
"@types/stream-chain": "*"
|
||||
checksum: cafa47c27bbd0cf446d1c90442cf53240a8a8a3828e73ba456720d6612b03d32d04067c9c0e54105b94584f37c7ed2f1a941b0600fbc6c095c25c1b401d184bb
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/styled-components@npm:^5.1.26":
|
||||
version: 5.1.26
|
||||
resolution: "@types/styled-components@npm:5.1.26"
|
||||
|
@ -26255,13 +26236,10 @@ __metadata:
|
|||
version: 0.0.0-use.local
|
||||
resolution: "scripts@workspace:scripts"
|
||||
dependencies:
|
||||
"@types/stream-json": ^1.7.3
|
||||
csv: ^6.2.7
|
||||
csv-parser: ^3.0.0
|
||||
got: ^12.5.3
|
||||
nodemon: ^2.0.20
|
||||
pdfdataextract: ^3.2.0
|
||||
stream-json: ^1.7.5
|
||||
ts-node: ^10.9.1
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
@ -27228,13 +27206,6 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"stream-chain@npm:^2.2.5":
|
||||
version: 2.2.5
|
||||
resolution: "stream-chain@npm:2.2.5"
|
||||
checksum: c83cbf504bd11e2bcbe761a92801295b3decac7ffa4092ceffca2eb1b5d0763bcc511fa22cd8044e8a18c21ca66794fd10c8d9cd1292a3e6c0d83a4194c6b8ed
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"stream-each@npm:^1.1.0":
|
||||
version: 1.2.3
|
||||
resolution: "stream-each@npm:1.2.3"
|
||||
|
@ -27258,15 +27229,6 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"stream-json@npm:^1.7.5":
|
||||
version: 1.7.5
|
||||
resolution: "stream-json@npm:1.7.5"
|
||||
dependencies:
|
||||
stream-chain: ^2.2.5
|
||||
checksum: d6229cd0342cbfb2f0d4be2b289cd2fe283aaa808329ec5c925b9840fc694fa91400f10bbf3275ac39c039f314fe6ab844d380341e738654ce224482f266ad2b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"stream-shift@npm:^1.0.0":
|
||||
version: 1.0.1
|
||||
resolution: "stream-shift@npm:1.0.1"
|
||||
|
|
Loading…
Reference in New Issue