@tekkare/romulus 0.1.250 → 0.1.252
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/module.json +1 -1
- package/dist/runtime/components/BarChart.vue +1 -0
- package/dist/runtime/components/ChoroplethMap.vue +4 -1
- package/dist/runtime/internal/geo/fr-regions.json +1 -1
- package/dist/runtime/utils/chart.d.ts +6 -3
- package/dist/runtime/utils/chart.js +15 -2
- package/layer/app/app.config.ts +6 -0
- package/layer/app/components/OipPubmedSummary.vue +223 -0
- package/layer/app/components/OipResourceDrawer.vue +331 -0
- package/layer/app/components/OipResourceDrawerLink.vue +40 -0
- package/layer/app/components/OipResourceField.vue +41 -0
- package/layer/app/components/OipResourceGenericCard.vue +54 -0
- package/layer/app/components/OipResourceSource.vue +50 -0
- package/layer/app/components/OipResourceTags.vue +65 -0
- package/layer/app/components/OipResourceView.vue +107 -0
- package/layer/app/components/oip-drugs/fiches/AssociationFiche.vue +775 -0
- package/layer/app/components/oip-drugs/fiches/BrandFiche.vue +1111 -0
- package/layer/app/components/oip-drugs/fiches/IndicationFiche.vue +182 -0
- package/layer/app/components/oip-drugs/fiches/JoFiche.vue +101 -0
- package/layer/app/components/oip-drugs/fiches/PndsFiche.vue +279 -0
- package/layer/app/components/oip-drugs/heart/JoCard.vue +314 -0
- package/layer/app/components/oip-drugs/heart/TextHighlight.vue +326 -0
- package/layer/app/components/oip-drugs/heart/ansm/BrandCard.vue +187 -0
- package/layer/app/components/oip-drugs/heart/ansm/CisDetail.vue +363 -0
- package/layer/app/components/oip-drugs/heart/ansm/CisTable.vue +167 -0
- package/layer/app/components/oip-drugs/heart/associations/NationalAssemblyCard.vue +373 -0
- package/layer/app/components/oip-drugs/heart/associations/NationalAssemblyFiche.vue +372 -0
- package/layer/app/components/oip-drugs/heart/associations/TranscriptionCard.vue +55 -0
- package/layer/app/components/oip-drugs/heart/elastic/SourceContainerElastic.vue +103 -0
- package/layer/app/components/oip-drugs/heart/france/BrandGroupCard.vue +450 -0
- package/layer/app/components/oip-drugs/heart/mitm/Card.vue +199 -0
- package/layer/app/components/oip-drugs/heart/mitm/Source.vue +23 -0
- package/layer/app/components/oip-drugs/heart/mitm/details/Overview.vue +381 -0
- package/layer/app/components/oip-drugs/heart/put/Card.vue +212 -0
- package/layer/app/components/oip-drugs/heart/results/AccesCard.vue +696 -0
- package/layer/app/components/oip-drugs/heart/results/AlertCard.vue +342 -0
- package/layer/app/components/oip-drugs/heart/results/AsmrCursor.vue +229 -0
- package/layer/app/components/oip-drugs/heart/results/EvalCard.vue +370 -0
- package/layer/app/components/oip-drugs/heart/results/IndicCard.vue +743 -0
- package/layer/app/components/oip-drugs/heart/results/MatchExplain.vue +243 -0
- package/layer/app/components/oip-drugs/heart/results/PrefRows.vue +105 -0
- package/layer/app/components/oip-drugs/heart/results/details/HasHistory.vue +487 -0
- package/layer/app/components/oip-drugs/heart/results/details/InternationalCountryCard.vue +461 -0
- package/layer/app/components/oip-drugs/heart/results/details/InternationalOverview.vue +200 -0
- package/layer/app/components/oip-drugs/heart/results/details/InternationalPriceDrawer.vue +647 -0
- package/layer/app/components/oip-drugs/heart/results/details/Monograph.vue +128 -0
- package/layer/app/components/oip-drugs/heart/results/details/OpinionDrawer.vue +535 -0
- package/layer/app/components/oip-drugs/heart/results/details/PresentationDrawer.vue +738 -0
- package/layer/app/components/oip-drugs/heart/results/details/Price.vue +227 -0
- package/layer/app/components/oip-drugs/heart/results/details/PriceOverview.vue +1261 -0
- package/layer/app/components/oip-drugs/heart/results/details/RecordDrawer.vue +494 -0
- package/layer/app/components/oip-drugs/heart/results/details/RecordList.vue +426 -0
- package/layer/app/components/oip-drugs/heart/results/les/Card.vue +340 -0
- package/layer/app/components/oip-drugs/heart/results/les/Drawer.vue +67 -0
- package/layer/app/components/oip-drugs/heart/results/les/IndicationDetail.vue +149 -0
- package/layer/app/components/oip-drugs/heart/results/les/Source.vue +20 -0
- package/layer/app/components/oip-drugs/heart/results/les/SourceTag.vue +39 -0
- package/layer/app/components/oip-drugs/heart/searchPage/DynamicSource.vue +29 -0
- package/layer/app/components/oip-drugs/medicam/market/Chart.vue +121 -0
- package/layer/app/components/oip-drugs/outpatient/ProductEvolution.vue +236 -0
- package/layer/app/components/oip-drugs/resources/Ansm.vue +75 -0
- package/layer/app/components/oip-drugs/resources/Association.vue +30 -0
- package/layer/app/components/oip-drugs/resources/Brand.vue +65 -0
- package/layer/app/components/oip-drugs/resources/Contribution.vue +216 -0
- package/layer/app/components/oip-drugs/resources/Hospital.vue +151 -0
- package/layer/app/components/oip-drugs/resources/Indication.vue +54 -0
- package/layer/app/components/oip-drugs/resources/Jo.vue +57 -0
- package/layer/app/components/oip-drugs/resources/Medicam.vue +140 -0
- package/layer/app/components/oip-drugs/resources/Mitm.vue +84 -0
- package/layer/app/components/oip-drugs/resources/NationalAssembly.vue +93 -0
- package/layer/app/components/oip-drugs/resources/Outpatient.vue +97 -0
- package/layer/app/components/oip-drugs/resources/Pnds.vue +24 -0
- package/layer/app/components/oip-drugs/resources/Price.vue +106 -0
- package/layer/app/components/oip-drugs/resources/Put.vue +143 -0
- package/layer/app/components/oip-science/appel-a-projet/Cards.vue +162 -0
- package/layer/app/components/oip-science/clinical-trials/Cards.vue +382 -0
- package/layer/app/components/oip-science/clinical-trials/CardsGlobal.vue +273 -0
- package/layer/app/components/oip-science/clinical-trials/LinkedList.vue +366 -0
- package/layer/app/components/oip-science/clinical-trials/PairBadge.vue +25 -0
- package/layer/app/components/oip-science/clinical-trials/PairBody.vue +182 -0
- package/layer/app/components/oip-science/clinical-trials/SitesDrawer.vue +95 -0
- package/layer/app/components/oip-science/common/Form.vue +73 -0
- package/layer/app/components/oip-science/common/MatchAvgTag.vue +283 -0
- package/layer/app/components/oip-science/common/NoData.vue +16 -0
- package/layer/app/components/oip-science/common/ScoreBadge.vue +35 -0
- package/layer/app/components/oip-science/common/Source.vue +31 -0
- package/layer/app/components/oip-science/common/TableTags.vue +279 -0
- package/layer/app/components/oip-science/common/Timeline.vue +104 -0
- package/layer/app/components/oip-science/common/ToolTips.vue +89 -0
- package/layer/app/components/oip-science/cross/publicationPubmed.vue +484 -0
- package/layer/app/components/oip-science/crossData/CrossDataLocations.vue +71 -0
- package/layer/app/components/oip-science/ctgov/Investigators.vue +148 -0
- package/layer/app/components/oip-science/ctgov/Locations.vue +102 -0
- package/layer/app/components/oip-science/ctgov/Publications.vue +52 -0
- package/layer/app/components/oip-science/ctgov/Sponsors.vue +66 -0
- package/layer/app/components/oip-science/ctgov/StudyDescription.vue +1136 -0
- package/layer/app/components/oip-science/ctgov-centers/ClinicalTrials.vue +40 -0
- package/layer/app/components/oip-science/ctgov-centers/Publications.vue +50 -0
- package/layer/app/components/oip-science/ctgov-investigators/ClinicalTrials.vue +43 -0
- package/layer/app/components/oip-science/ctgov-investigators/Informations.vue +171 -0
- package/layer/app/components/oip-science/ctgov-investigators/Publications.vue +44 -0
- package/layer/app/components/oip-science/elastic/DateRangeFilter.vue +209 -0
- package/layer/app/components/oip-science/elastic/Filter.vue +719 -0
- package/layer/app/components/oip-science/elastic/MatchExplain.vue +152 -0
- package/layer/app/components/oip-science/establishments/Cards.vue +183 -0
- package/layer/app/components/oip-science/establishments/ClinicalTrials.vue +62 -0
- package/layer/app/components/oip-science/establishments/Hcps.vue +227 -0
- package/layer/app/components/oip-science/establishments/Informations.vue +263 -0
- package/layer/app/components/oip-science/establishments/LinkedList.vue +153 -0
- package/layer/app/components/oip-science/establishments/MatchedLabels.vue +194 -0
- package/layer/app/components/oip-science/establishments/PublicFinance.vue +62 -0
- package/layer/app/components/oip-science/euct/Investigators.vue +125 -0
- package/layer/app/components/oip-science/euct/Locations.vue +102 -0
- package/layer/app/components/oip-science/euct/Products.vue +101 -0
- package/layer/app/components/oip-science/euct/Publications.vue +89 -0
- package/layer/app/components/oip-science/euct/Sponsors.vue +86 -0
- package/layer/app/components/oip-science/euct/StudyDescription.vue +1075 -0
- package/layer/app/components/oip-science/euct-centers/ClinicalTrials.vue +40 -0
- package/layer/app/components/oip-science/euct-centers/Publications.vue +55 -0
- package/layer/app/components/oip-science/euct-investigators/ClinicalTrials.vue +41 -0
- package/layer/app/components/oip-science/euct-investigators/Informations.vue +171 -0
- package/layer/app/components/oip-science/euct-investigators/Publications.vue +51 -0
- package/layer/app/components/oip-science/hcps/AppelsAProjet.vue +62 -0
- package/layer/app/components/oip-science/hcps/Cards.vue +237 -0
- package/layer/app/components/oip-science/hcps/ClinicalTrials.vue +78 -0
- package/layer/app/components/oip-science/hcps/Informations.vue +296 -0
- package/layer/app/components/oip-science/hcps/LinkedList.vue +153 -0
- package/layer/app/components/oip-science/hcps/MatchedLabels.vue +207 -0
- package/layer/app/components/oip-science/hcps/Pubmed.vue +128 -0
- package/layer/app/components/oip-science/local/SliderTabs.vue +99 -0
- package/layer/app/components/oip-science/local/SliderTabsFull.vue +135 -0
- package/layer/app/components/oip-science/pubmed/Authors.vue +128 -0
- package/layer/app/components/oip-science/pubmed/Cards.vue +417 -0
- package/layer/app/components/oip-science/pubmed/ClinicalTrials.vue +71 -0
- package/layer/app/components/oip-science/resources/Phrc.vue +39 -0
- package/layer/app/composables/useOipChapterScroll.ts +43 -0
- package/layer/app/composables/useOipResourceHooks.ts +27 -0
- package/layer/app/composables/useOipResourceNav.ts +66 -0
- package/layer/app/composables/useOipResourceViews.ts +117 -0
- package/layer/app/composables/useOipResources.ts +83 -0
- package/layer/app/oip-drugs/PORTING.md +120 -0
- package/layer/app/oip-drugs/composables/useAssociationDetail.ts +220 -0
- package/layer/app/oip-drugs/composables/useAssociationExport.ts +63 -0
- package/layer/app/oip-drugs/composables/useAssociationLookup.ts +105 -0
- package/layer/app/oip-drugs/composables/useCardPrefOptions.ts +201 -0
- package/layer/app/oip-drugs/composables/useCurrency.ts +121 -0
- package/layer/app/oip-drugs/composables/useDirectusSources.ts +224 -0
- package/layer/app/oip-drugs/composables/useHeartBrandMatches.ts +112 -0
- package/layer/app/oip-drugs/composables/useHeartDetailSearches.ts +479 -0
- package/layer/app/oip-drugs/composables/useHeartIntlApprovals.ts +661 -0
- package/layer/app/oip-drugs/composables/useHeartLesIndication.ts +168 -0
- package/layer/app/oip-drugs/composables/useHeartMatchExplain.ts +231 -0
- package/layer/app/oip-drugs/composables/useHeartReports.ts +239 -0
- package/layer/app/oip-drugs/composables/useHeartSearchFields.ts +233 -0
- package/layer/app/oip-drugs/composables/useMergeByKey.ts +23 -0
- package/layer/app/oip-drugs/composables/useOipDrugsElastic.ts +621 -0
- package/layer/app/oip-drugs/composables/usePageEmpty.ts +58 -0
- package/layer/app/oip-drugs/composables/v-useSalesSource.ts +64 -0
- package/layer/app/oip-drugs/drugs.css +500 -0
- package/layer/app/oip-drugs/esIndices.ts +322 -0
- package/layer/app/oip-drugs/kinds.ts +264 -0
- package/layer/app/oip-drugs/locales/en.json +1571 -0
- package/layer/app/oip-drugs/locales/fr.json +1571 -0
- package/layer/app/oip-drugs/monographs/blincyto-has.vue +289 -0
- package/layer/app/oip-drugs/monographs/darzalex-has.vue +276 -0
- package/layer/app/oip-drugs/monographs/dupixent-has.vue +216 -0
- package/layer/app/oip-drugs/monographs/enhertu-has.vue +280 -0
- package/layer/app/oip-drugs/monographs/has-sein-2023.vue +1649 -0
- package/layer/app/oip-drugs/monographs/ibrance-has.vue +277 -0
- package/layer/app/oip-drugs/monographs/imfinzi-has.vue +293 -0
- package/layer/app/oip-drugs/monographs/keytruda-has.vue +334 -0
- package/layer/app/oip-drugs/monographs/kisqali-has.vue +201 -0
- package/layer/app/oip-drugs/monographs/opdivo-has.vue +231 -0
- package/layer/app/oip-drugs/monographs/ozempic-has.vue +186 -0
- package/layer/app/oip-drugs/monographs/tecentriq-has.vue +312 -0
- package/layer/app/oip-drugs/monographs/yescarta-has.vue +272 -0
- package/layer/app/oip-drugs/types/elastic.ts +113 -0
- package/layer/app/oip-drugs/types/es/agencies.ts +152 -0
- package/layer/app/oip-drugs/types/es/directory.ts +54 -0
- package/layer/app/oip-drugs/types/es/docByIndex.ts +151 -0
- package/layer/app/oip-drugs/types/es/openmedic.ts +67 -0
- package/layer/app/oip-drugs/types/es/outpatient.ts +71 -0
- package/layer/app/oip-drugs/types/es/portal.ts +130 -0
- package/layer/app/oip-drugs/types/es/retail.ts +107 -0
- package/layer/app/oip-drugs/types/es/statistics.ts +29 -0
- package/layer/app/oip-drugs/types/heart/CurrencyRate.ts +16 -0
- package/layer/app/oip-drugs/types/heart/ansm.ts +106 -0
- package/layer/app/oip-drugs/types/heart/tag.ts +29 -0
- package/layer/app/oip-drugs/utils/associationFields.ts +118 -0
- package/layer/app/oip-drugs/utils/contributions.ts +36 -0
- package/layer/app/oip-drugs/utils/countryMapping.ts +387 -0
- package/layer/app/oip-drugs/utils/esHighlight.ts +21 -0
- package/layer/app/oip-drugs/utils/exportSheets.ts +57 -0
- package/layer/app/oip-drugs/utils/heartIntlPrice.ts +228 -0
- package/layer/app/oip-drugs/utils/heartStyleAndFormat.ts +262 -0
- package/layer/app/oip-drugs/utils/heartStyleAnsm.ts +71 -0
- package/layer/app/oip-drugs/utils/latestDate.ts +31 -0
- package/layer/app/oip-drugs/utils/p-heartCardTags.ts +53 -0
- package/layer/app/oip-drugs/utils/priceExport.ts +269 -0
- package/layer/app/oip-drugs/utils/q-hasRatings.ts +43 -0
- package/layer/app/oip-drugs/utils/s-openCard.ts +20 -0
- package/layer/app/oip-drugs/utils/sourceUuids.ts +155 -0
- package/layer/app/oip-drugs/utils/styleAndFormat.ts +40 -0
- package/layer/app/oip-drugs/utils/v-salesSeries.ts +156 -0
- package/layer/app/oip-drugs/utils/v-scopeTags.ts +23 -0
- package/layer/app/oip-science/PORTING.md +93 -0
- package/layer/app/oip-science/assets/smartSelection.json +428 -0
- package/layer/app/oip-science/composables/useAuthorMatching.ts +342 -0
- package/layer/app/oip-science/composables/useCTCenter.ts +107 -0
- package/layer/app/oip-science/composables/useCTInvestigators.ts +107 -0
- package/layer/app/oip-science/composables/useEstablishmentCrossData.ts +139 -0
- package/layer/app/oip-science/composables/useEstablishmentMatching.ts +176 -0
- package/layer/app/oip-science/composables/useEuct.ts +418 -0
- package/layer/app/oip-science/composables/useEuctCenter.ts +107 -0
- package/layer/app/oip-science/composables/useEuctInvestigators.ts +107 -0
- package/layer/app/oip-science/composables/useGlobalClinicalTrials.ts +624 -0
- package/layer/app/oip-science/composables/useLinkedTrials.ts +83 -0
- package/layer/app/oip-science/composables/useOipElastic.ts +658 -0
- package/layer/app/oip-science/composables/useOipSearchExplain.ts +166 -0
- package/layer/app/oip-science/composables/usePubmed.ts +487 -0
- package/layer/app/oip-science/composables/useSearchFields.ts +153 -0
- package/layer/app/oip-science/indexConfig.json +794 -0
- package/layer/app/oip-science/locales/en.json +483 -0
- package/layer/app/oip-science/locales/fr.json +483 -0
- package/layer/app/oip-science/science.css +1182 -0
- package/layer/app/oip-science/utils/a-openCard.ts +23 -0
- package/layer/app/oip-science/utils/b-openCard.ts +35 -0
- package/layer/app/oip-science/utils/c-filterContext.ts +81 -0
- package/layer/app/oip-science/utils/f-types.ts +241 -0
- package/layer/app/oip-science/utils/frDiseaseTerms.ts +269 -0
- package/layer/app/oip-science/utils/matchMethod.ts +53 -0
- package/layer/app/oip-science/utils/sliderTabs.ts +13 -0
- package/layer/app/oip-science/utils/sources.ts +15 -0
- package/layer/app/oip-science/utils/styleAndFormat.ts +608 -0
- package/layer/app/oip-science/utils/toPresets.ts +7 -0
- package/layer/app/oip-science/utils/valueTable.ts +126 -0
- package/layer/app/plugins/oip-science-i18n.ts +17 -0
- package/layer/app/utils/oipFicheRoutes.ts +118 -0
- package/layer/app/utils/oipResources.ts +440 -0
- package/layer/nuxt.config.ts +22 -2
- package/layer/public/reports/blincyto-has.html +292 -0
- package/layer/public/reports/blincyto-has.pdf +0 -0
- package/layer/public/reports/darzalex-has.html +279 -0
- package/layer/public/reports/darzalex-has.pdf +0 -0
- package/layer/public/reports/dupixent-has.html +217 -0
- package/layer/public/reports/dupixent-has.pdf +0 -0
- package/layer/public/reports/enhertu-has.html +283 -0
- package/layer/public/reports/enhertu-has.pdf +0 -0
- package/layer/public/reports/has-sein-2023.html +1639 -0
- package/layer/public/reports/ibrance-has.html +280 -0
- package/layer/public/reports/ibrance-has.pdf +0 -0
- package/layer/public/reports/imfinzi-has.html +297 -0
- package/layer/public/reports/imfinzi-has.pdf +0 -0
- package/layer/public/reports/keytruda-has.html +337 -0
- package/layer/public/reports/keytruda-has.pdf +0 -0
- package/layer/public/reports/kisqali-has.html +202 -0
- package/layer/public/reports/kisqali-has.pdf +0 -0
- package/layer/public/reports/opdivo-has.html +232 -0
- package/layer/public/reports/opdivo-has.pdf +0 -0
- package/layer/public/reports/ozempic-has.html +188 -0
- package/layer/public/reports/ozempic-has.pdf +0 -0
- package/layer/public/reports/tecentriq-has.html +315 -0
- package/layer/public/reports/tecentriq-has.pdf +0 -0
- package/layer/public/reports/yescarta-has.html +275 -0
- package/layer/public/reports/yescarta-has.pdf +0 -0
- package/layer/server/api/oip/es.post.ts +99 -0
- package/layer/server/api/oip/pdf.get.ts +70 -0
- package/layer/server/api/oip/reports.get.ts +98 -0
- package/layer/server/api/oip/resource-types.get.ts +22 -0
- package/package.json +1 -1
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ouvre le detail depuis une carte de resultat (portage de utils/openCard de
|
|
3
|
+
* France Augmented Science).
|
|
4
|
+
*
|
|
5
|
+
* La carte entiere mene au detail (cf. RmResultCard). Les elements qui portent
|
|
6
|
+
* leur propre action (lien, bouton projet, bulle d'etiquettes) gardent la
|
|
7
|
+
* main : le clic qui en vient est ignore. Le detail s'ouvre par
|
|
8
|
+
* useOipResourceNav (`open`) et non par navigateTo : dans le tiroir d'un
|
|
9
|
+
* projet, il empile un tiroir.
|
|
10
|
+
*/
|
|
11
|
+
const OWN_ACTION = "a, button, input, select, textarea, [role='menu'], .rm-tooltip";
|
|
12
|
+
|
|
13
|
+
export function openCard(event: MouseEvent, href: string | null | undefined, open: () => void) {
|
|
14
|
+
const target = event.target as HTMLElement | null;
|
|
15
|
+
if (target?.closest(OWN_ACTION)) return;
|
|
16
|
+
if (!href) return;
|
|
17
|
+
// Ctrl/Cmd + clic : nouvel onglet, comme sur un vrai lien.
|
|
18
|
+
if (event.metaKey || event.ctrlKey) {
|
|
19
|
+
window.open(href, "_blank", "noopener");
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
open();
|
|
23
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// Portage de utils/openCard de France Augmented Science pour les cartes du
|
|
2
|
+
// layer : la fiche s'ouvre par useOipResourceNav (page ou tiroir empile)
|
|
3
|
+
// au lieu de navigateTo.
|
|
4
|
+
|
|
5
|
+
import type { OipResourceNav } from "../../composables/useOipResourceNav";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Les elements qui portent leur propre action (menu d'export, lien, bouton
|
|
9
|
+
* projet, bulle d'etiquettes) gardent la main : le clic qui en vient est ignore.
|
|
10
|
+
*/
|
|
11
|
+
const OWN_ACTION = "a, button, input, select, textarea, [role='menu'], .rm-tooltip";
|
|
12
|
+
|
|
13
|
+
/** Clic sur une carte entiere : ouvre la fiche `type` / `id`. */
|
|
14
|
+
export function openCard(event: MouseEvent, nav: OipResourceNav, type: string, id: string | null | undefined) {
|
|
15
|
+
const target = event.target as HTMLElement | null;
|
|
16
|
+
if (target?.closest(OWN_ACTION)) return;
|
|
17
|
+
if (!id) return;
|
|
18
|
+
// Ctrl/Cmd + clic : nouvel onglet, comme sur un vrai lien.
|
|
19
|
+
if (event.metaKey || event.ctrlKey) {
|
|
20
|
+
const url = nav.href(type, id);
|
|
21
|
+
if (url) window.open(url, "_blank", "noopener");
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
nav.open(type, id);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Clic sur un vrai lien (<a :href="nav.href(...)">) vers une autre fiche :
|
|
29
|
+
* une touche modificatrice laisse faire le navigateur, sinon nav.open.
|
|
30
|
+
*/
|
|
31
|
+
export function followCardLink(event: MouseEvent, nav: OipResourceNav, type: string, id: string | null | undefined) {
|
|
32
|
+
if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;
|
|
33
|
+
event.preventDefault();
|
|
34
|
+
if (id) nav.open(type, id);
|
|
35
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { InjectionKey, Ref } from 'vue';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Etat des filtres d'une liste (anciennement filterStore et elasticQueryStore
|
|
5
|
+
* de France Augmented Science, ranges par chemin de route).
|
|
6
|
+
*
|
|
7
|
+
* Le layer n'a ni route ni store : la liste cree son contexte et le fournit a
|
|
8
|
+
* ses filtres (ElasticFilter, ElasticDateRangeFilter, LocalSliderTabs). Deux
|
|
9
|
+
* listes a l'ecran ont chacune le leur. Le `keyName` des stores (`&ListName=`)
|
|
10
|
+
* reste une sous-cle du contexte.
|
|
11
|
+
*
|
|
12
|
+
* - appFilters : les valeurs choisies dans chaque filtre (ex. `getStore`).
|
|
13
|
+
* - queriesFilters : la clause Elasticsearch de chaque filtre.
|
|
14
|
+
*/
|
|
15
|
+
export interface OipFilterEntry {
|
|
16
|
+
filter: string;
|
|
17
|
+
keyName: string | null;
|
|
18
|
+
values: any;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface OipFilterContext {
|
|
22
|
+
appFilters: Ref<OipFilterEntry[]>;
|
|
23
|
+
queriesFilters: Ref<OipFilterEntry[]>;
|
|
24
|
+
setAppFilters: (info: { filter: string; values: any; keyName?: string | null }) => void;
|
|
25
|
+
resetSelectedFilters: (info: { filter: string; keyName?: string | null }) => void;
|
|
26
|
+
findValuesStore: (info: { filter: string; keyName?: string | null }) => any[];
|
|
27
|
+
setQueryFilters: (info: { filter: string; values: any; keyName?: string | null }) => void;
|
|
28
|
+
removeQueryFilter: (info: { filter: string; keyName?: string | null }) => void;
|
|
29
|
+
findQueryFromPage: (info: { keyName?: string | null }) => OipFilterEntry[];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const same = (entry: OipFilterEntry, filter: string, keyName?: string | null) =>
|
|
33
|
+
entry.filter === filter && entry.keyName === (keyName ?? null);
|
|
34
|
+
|
|
35
|
+
export function createOipFilterContext(): OipFilterContext {
|
|
36
|
+
const appFilters = ref<OipFilterEntry[]>([]);
|
|
37
|
+
const queriesFilters = ref<OipFilterEntry[]>([]);
|
|
38
|
+
|
|
39
|
+
// Meme regle que les stores : l'entree n'est remplacee que si sa valeur change.
|
|
40
|
+
function upsert(list: Ref<OipFilterEntry[]>, info: { filter: string; values: any; keyName?: string | null }) {
|
|
41
|
+
const entry = { filter: info.filter, keyName: info.keyName ?? null, values: info.values };
|
|
42
|
+
const index = list.value.findIndex((x) => same(x, info.filter, info.keyName));
|
|
43
|
+
if (index === -1) list.value.push(entry);
|
|
44
|
+
else if (list.value[index]!.values !== entry.values) list.value[index] = entry;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Sans entree a retirer, la liste garde son identite : pas de relance inutile.
|
|
48
|
+
function remove(list: Ref<OipFilterEntry[]>, filter: string, keyName?: string | null) {
|
|
49
|
+
if (list.value.some((x) => same(x, filter, keyName))) {
|
|
50
|
+
list.value = list.value.filter((x) => !same(x, filter, keyName));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
appFilters,
|
|
56
|
+
queriesFilters,
|
|
57
|
+
setAppFilters: (info) => upsert(appFilters, info),
|
|
58
|
+
resetSelectedFilters: ({ filter, keyName }) => remove(appFilters, filter, keyName),
|
|
59
|
+
findValuesStore: ({ filter, keyName }) => {
|
|
60
|
+
const hit = appFilters.value.find((x) => same(x, filter, keyName));
|
|
61
|
+
return Array.isArray(hit?.values) ? [...hit!.values] : [];
|
|
62
|
+
},
|
|
63
|
+
setQueryFilters: (info) => upsert(queriesFilters, info),
|
|
64
|
+
removeQueryFilter: ({ filter, keyName }) => remove(queriesFilters, filter, keyName),
|
|
65
|
+
findQueryFromPage: ({ keyName }) => queriesFilters.value.filter((x) => x.keyName === (keyName ?? null)),
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const OIP_FILTER_CONTEXT: InjectionKey<OipFilterContext> = Symbol('oip-science-filter-context');
|
|
70
|
+
|
|
71
|
+
/** Cree le contexte d'une liste et le donne a ses filtres. */
|
|
72
|
+
export function provideOipFilterContext(): OipFilterContext {
|
|
73
|
+
const context = createOipFilterContext();
|
|
74
|
+
provide(OIP_FILTER_CONTEXT, context);
|
|
75
|
+
return context;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** Le contexte de la liste parente ; un filtre monte seul a le sien. */
|
|
79
|
+
export function useOipFilterContext(): OipFilterContext {
|
|
80
|
+
return inject(OIP_FILTER_CONTEXT, null) ?? createOipFilterContext();
|
|
81
|
+
}
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
// Types des fiches investigateurs et centres de France Augmented Science
|
|
2
|
+
// (types/{CTInvestigators,EuctInvestigators,CTCenters,EuctCenters}.ts), regroupes
|
|
3
|
+
// pour le lot F : le layer n'a pas de dossier types/ partage.
|
|
4
|
+
|
|
5
|
+
export interface CTInvestigators {
|
|
6
|
+
id: string;
|
|
7
|
+
investigator_name?: string;
|
|
8
|
+
country?: string;
|
|
9
|
+
city?: string;
|
|
10
|
+
state?: string;
|
|
11
|
+
institution?: string;
|
|
12
|
+
pubmed_data?: CTInvestigatorsPubmedData[];
|
|
13
|
+
pubmed_ids?: string[];
|
|
14
|
+
records?: CTInvestigatorsRecords[];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface CTInvestigatorsRecords {
|
|
18
|
+
affiliation?: string;
|
|
19
|
+
brief_title?: string;
|
|
20
|
+
conditions?: string[];
|
|
21
|
+
countries?: string;
|
|
22
|
+
funder_type?: string;
|
|
23
|
+
interventions?: string[];
|
|
24
|
+
keywords?: string;
|
|
25
|
+
last_update_posted_date?: string; // ISO date string
|
|
26
|
+
nct_id?: string;
|
|
27
|
+
phase?: string;
|
|
28
|
+
results_first_posted_date?: string; // ISO date string
|
|
29
|
+
role?: string;
|
|
30
|
+
sponsors?: string[];
|
|
31
|
+
status?: string;
|
|
32
|
+
study_first_posted_date?: string; // ISO date string
|
|
33
|
+
study_type?: string;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface CTInvestigatorsPubmedData {
|
|
37
|
+
affiliation?: string;
|
|
38
|
+
fore_name?: string;
|
|
39
|
+
initials?: string;
|
|
40
|
+
last_name?: string;
|
|
41
|
+
article_title?: string;
|
|
42
|
+
doi?: string;
|
|
43
|
+
gender?: {
|
|
44
|
+
code?: string;
|
|
45
|
+
label?: string;
|
|
46
|
+
};
|
|
47
|
+
journal_name?: string;
|
|
48
|
+
keywords?: string;
|
|
49
|
+
mesh_terms?: {
|
|
50
|
+
code?: string;
|
|
51
|
+
label?: string;
|
|
52
|
+
}[];
|
|
53
|
+
name_of_substance?: {
|
|
54
|
+
code?: string;
|
|
55
|
+
label?: string;
|
|
56
|
+
}[];
|
|
57
|
+
pmid?: string;
|
|
58
|
+
publication_date?: string;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export interface EuctInvestigators {
|
|
62
|
+
id: string;
|
|
63
|
+
full_name?: string;
|
|
64
|
+
country?: string;
|
|
65
|
+
city?: string;
|
|
66
|
+
state?: string;
|
|
67
|
+
institution?: string;
|
|
68
|
+
pubmed_data?: EuctInvestigatorsPubmedData[];
|
|
69
|
+
pubmed_ids?: string[];
|
|
70
|
+
records?: EuctInvestigatorsRecords[];
|
|
71
|
+
}
|
|
72
|
+
export interface EuctInvestigatorsPubmedData {
|
|
73
|
+
abstract?: string;
|
|
74
|
+
age?: string[];
|
|
75
|
+
all_authors?: string[];
|
|
76
|
+
article_title?: string;
|
|
77
|
+
doi: string;
|
|
78
|
+
gender?: string[];
|
|
79
|
+
journal_name?: string;
|
|
80
|
+
keywords?: string[];
|
|
81
|
+
mesh_terms?: string[];
|
|
82
|
+
name_of_substance?: Array<{
|
|
83
|
+
label: string;
|
|
84
|
+
code: string;
|
|
85
|
+
}>;
|
|
86
|
+
pmid: string;
|
|
87
|
+
publication_date?: string;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export interface EuctInvestigatorRareDisease {
|
|
91
|
+
concat_disease_name_orpha_code?: string;
|
|
92
|
+
disease_name?: string;
|
|
93
|
+
disease_synonyms?: string;
|
|
94
|
+
has_rare_diseases_context?: boolean;
|
|
95
|
+
is_quoted?: boolean;
|
|
96
|
+
label?: string;
|
|
97
|
+
orpha_code?: string;
|
|
98
|
+
quoted_disease_name?: boolean;
|
|
99
|
+
section?: string;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export interface EuctInvestigatorMedicalCondition {
|
|
103
|
+
condition_name_en?: string;
|
|
104
|
+
condition_name_translation?: Record<string, string>;
|
|
105
|
+
is_rare_disease?: boolean;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export interface EuctInvestigatorsRecords {
|
|
109
|
+
euct_number: string;
|
|
110
|
+
full_title?: string;
|
|
111
|
+
ct_status?: string;
|
|
112
|
+
trial_phase?: string;
|
|
113
|
+
first_submitted_date?: string; // ISO date string
|
|
114
|
+
public_title?: string;
|
|
115
|
+
therapeutic_area?: string[];
|
|
116
|
+
medical_condition?: EuctInvestigatorMedicalCondition[];
|
|
117
|
+
countries?: string[];
|
|
118
|
+
co_sponsors?: EuctInvestigatorCoSponsor[];
|
|
119
|
+
record_id: string;
|
|
120
|
+
study_title?: string;
|
|
121
|
+
start_date?: string;
|
|
122
|
+
end_date?: string;
|
|
123
|
+
status?: string;
|
|
124
|
+
sponsor?: string;
|
|
125
|
+
phase?: string;
|
|
126
|
+
condition?: string;
|
|
127
|
+
intervention?: string;
|
|
128
|
+
nct_number?: string;
|
|
129
|
+
eudra_ct_number?: string;
|
|
130
|
+
country?: string;
|
|
131
|
+
city?: string;
|
|
132
|
+
site_name?: string;
|
|
133
|
+
enrollment?: number;
|
|
134
|
+
last_update?: string;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export interface EuctInvestigatorCoSponsor {
|
|
138
|
+
organisation: {
|
|
139
|
+
name: string;
|
|
140
|
+
[key: string]: any;
|
|
141
|
+
};
|
|
142
|
+
[key: string]: any;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export interface CTCenters {
|
|
146
|
+
id: string;
|
|
147
|
+
'@timestamp'?: string;
|
|
148
|
+
facility_name?: string;
|
|
149
|
+
facility_country?: string;
|
|
150
|
+
facility_city?: string;
|
|
151
|
+
records?: CTCentersRecords[];
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export interface CTCentersRecords {
|
|
155
|
+
brief_title?: string;
|
|
156
|
+
condition_name?: string;
|
|
157
|
+
conditions?: string[];
|
|
158
|
+
countries?: string;
|
|
159
|
+
|
|
160
|
+
funder_type?: string;
|
|
161
|
+
intervention_name?: string;
|
|
162
|
+
interventions?: string[];
|
|
163
|
+
|
|
164
|
+
keywords?: string[];
|
|
165
|
+
last_update_posted_date?: string; // ISO date string
|
|
166
|
+
nct_id?: string;
|
|
167
|
+
phase?: string;
|
|
168
|
+
pubmed_name?: string[];
|
|
169
|
+
results_first_posted_date?: string; // ISO date string
|
|
170
|
+
sponsor_name?: string;
|
|
171
|
+
sponsors?: string[];
|
|
172
|
+
status?: string;
|
|
173
|
+
study_first_posted_date?: string; // ISO date string
|
|
174
|
+
study_type?: string;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export interface EuctCenters {
|
|
178
|
+
id: string;
|
|
179
|
+
'@timestamp'?: string;
|
|
180
|
+
organisation_name?: string;
|
|
181
|
+
post_code?: string;
|
|
182
|
+
location?: string;
|
|
183
|
+
facility_name?: string;
|
|
184
|
+
country?: string;
|
|
185
|
+
city?: string;
|
|
186
|
+
records?: EuctCentersRecords[];
|
|
187
|
+
rare_diseases: EuctCentersRareDisease[];
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
export interface EuctCentersRecords {
|
|
191
|
+
euct_number: string;
|
|
192
|
+
full_title?: string;
|
|
193
|
+
therapeutic_area?: string[];
|
|
194
|
+
medical_condition?: EuctCentersMedicalCondition[];
|
|
195
|
+
countries?: string[];
|
|
196
|
+
co_sponsors?: EuctCentersCoSponsor[];
|
|
197
|
+
record_id: string;
|
|
198
|
+
study_title?: string;
|
|
199
|
+
start_date?: string;
|
|
200
|
+
end_date?: string;
|
|
201
|
+
status?: string;
|
|
202
|
+
sponsor?: string;
|
|
203
|
+
phase?: string;
|
|
204
|
+
condition?: string;
|
|
205
|
+
intervention?: string;
|
|
206
|
+
nct_number?: string;
|
|
207
|
+
eudra_ct_number?: string;
|
|
208
|
+
country?: string;
|
|
209
|
+
city?: string;
|
|
210
|
+
site_name?: string;
|
|
211
|
+
enrollment?: number;
|
|
212
|
+
last_update?: string;
|
|
213
|
+
pubmed_citations_id?: string[];
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
export interface EuctCentersRareDisease {
|
|
217
|
+
concat_disease_name_orpha_code?: string;
|
|
218
|
+
disease_name?: string;
|
|
219
|
+
disease_synonyms?: string;
|
|
220
|
+
has_rare_diseases_context?: boolean;
|
|
221
|
+
is_quoted?: boolean;
|
|
222
|
+
label?: string;
|
|
223
|
+
orpha_code?: string;
|
|
224
|
+
quoted_disease_name?: boolean;
|
|
225
|
+
section?: string;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
export interface EuctCentersMedicalCondition {
|
|
229
|
+
condition_name_en?: string;
|
|
230
|
+
condition_name_translation?: Record<string, string>;
|
|
231
|
+
is_rare_disease?: boolean;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
export interface EuctCentersCoSponsor {
|
|
235
|
+
organisation: {
|
|
236
|
+
name: string;
|
|
237
|
+
[key: string]: any;
|
|
238
|
+
};
|
|
239
|
+
[key: string]: any;
|
|
240
|
+
}
|
|
241
|
+
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recherche en francais dans les filtres maladie et oncologie.
|
|
3
|
+
*
|
|
4
|
+
* Les libelles des index (conditions, maladies rares, CIM-10, termes
|
|
5
|
+
* oncologie) sont en anglais : « sein » ne trouve rien. On traduit la saisie
|
|
6
|
+
* mot a mot avec un petit lexique medical et on cherche aussi l'anglais :
|
|
7
|
+
* « cancer du sein » cherche en plus `breast.*cancer` ou `cancer.*breast`.
|
|
8
|
+
*
|
|
9
|
+
* La regex rendue n'utilise que `( ) | .*`, compris par Lucene (regexp et
|
|
10
|
+
* `include` d'agregation) comme par JavaScript. Elle est en minuscules : la
|
|
11
|
+
* casse se gere a l'appel (case_insensitive, drapeau `i`, ou caseInsensitive).
|
|
12
|
+
*
|
|
13
|
+
* Mots francais sans accents, en minuscules. Les variantes UK/US sont listees
|
|
14
|
+
* toutes les deux, les index melangent les deux orthographes.
|
|
15
|
+
*/
|
|
16
|
+
const LEXICON: Record<string, string[]> = {
|
|
17
|
+
// Organes et localisations
|
|
18
|
+
sein: ['breast', 'mammary'],
|
|
19
|
+
mammaire: ['breast', 'mammary'],
|
|
20
|
+
poumon: ['lung', 'pulmonary'],
|
|
21
|
+
pulmonaire: ['lung', 'pulmonary'],
|
|
22
|
+
bronche: ['bronch'],
|
|
23
|
+
bronchique: ['bronch'],
|
|
24
|
+
foie: ['liver', 'hepat'],
|
|
25
|
+
hepatique: ['liver', 'hepat'],
|
|
26
|
+
hepatocellulaire: ['hepatocellular'],
|
|
27
|
+
rein: ['kidney', 'renal'],
|
|
28
|
+
renal: ['kidney', 'renal'],
|
|
29
|
+
vessie: ['bladder', 'urothelial'],
|
|
30
|
+
prostate: ['prostat'],
|
|
31
|
+
prostatique: ['prostat'],
|
|
32
|
+
colon: ['colon', 'colorectal'],
|
|
33
|
+
colorectal: ['colorectal'],
|
|
34
|
+
rectum: ['rect'],
|
|
35
|
+
rectal: ['rect'],
|
|
36
|
+
intestin: ['intestin', 'bowel'],
|
|
37
|
+
estomac: ['stomach', 'gastric'],
|
|
38
|
+
gastrique: ['stomach', 'gastric'],
|
|
39
|
+
oesophage: ['oesophag', 'esophag'],
|
|
40
|
+
pancreas: ['pancrea'],
|
|
41
|
+
pancreatique: ['pancrea'],
|
|
42
|
+
'voies biliaires': ['biliary', 'bile duct', 'cholangio'],
|
|
43
|
+
biliaire: ['biliary', 'bile duct'],
|
|
44
|
+
'vesicule biliaire': ['gallbladder'],
|
|
45
|
+
ovaire: ['ovar'],
|
|
46
|
+
ovarien: ['ovar'],
|
|
47
|
+
uterus: ['uter', 'endometri'],
|
|
48
|
+
uterin: ['uter', 'endometri'],
|
|
49
|
+
endometre: ['endometri'],
|
|
50
|
+
'col de l uterus': ['cervix', 'cervical'],
|
|
51
|
+
'col uterin': ['cervix', 'cervical'],
|
|
52
|
+
vulve: ['vulv'],
|
|
53
|
+
vagin: ['vagin'],
|
|
54
|
+
testicule: ['testic', 'testis', 'germ cell'],
|
|
55
|
+
testiculaire: ['testic', 'germ cell'],
|
|
56
|
+
penis: ['penile', 'penis'],
|
|
57
|
+
peau: ['skin', 'cutaneous'],
|
|
58
|
+
cutane: ['skin', 'cutaneous'],
|
|
59
|
+
cerveau: ['brain', 'cerebr'],
|
|
60
|
+
cerebral: ['brain', 'cerebr'],
|
|
61
|
+
moelle: ['marrow', 'spinal cord'],
|
|
62
|
+
os: ['bone'],
|
|
63
|
+
osseux: ['bone'],
|
|
64
|
+
sang: ['blood'],
|
|
65
|
+
thyroide: ['thyroid'],
|
|
66
|
+
surrenale: ['adrenal'],
|
|
67
|
+
tete: ['head'],
|
|
68
|
+
cou: ['neck'],
|
|
69
|
+
'tete et cou': ['head and neck'],
|
|
70
|
+
orl: ['head and neck', 'oropharyn', 'laryn'],
|
|
71
|
+
gorge: ['throat', 'pharyn'],
|
|
72
|
+
larynx: ['laryn'],
|
|
73
|
+
pharynx: ['pharyn'],
|
|
74
|
+
bouche: ['mouth', 'oral'],
|
|
75
|
+
langue: ['tongue'],
|
|
76
|
+
oeil: ['eye', 'ocular', 'uveal'],
|
|
77
|
+
yeux: ['eye', 'ocular'],
|
|
78
|
+
retine: ['retin'],
|
|
79
|
+
coeur: ['heart', 'cardiac'],
|
|
80
|
+
cardiaque: ['heart', 'cardiac'],
|
|
81
|
+
muscle: ['muscle', 'muscular'],
|
|
82
|
+
musculaire: ['muscle', 'muscular'],
|
|
83
|
+
nerf: ['nerve', 'neur'],
|
|
84
|
+
ganglion: ['lymph node'],
|
|
85
|
+
lymphatique: ['lymph'],
|
|
86
|
+
plevre: ['pleura'],
|
|
87
|
+
peritoine: ['periton'],
|
|
88
|
+
articulation: ['joint'],
|
|
89
|
+
// Tumeurs
|
|
90
|
+
tumeur: ['tumour', 'tumor', 'neoplasm'],
|
|
91
|
+
tumoral: ['tumour', 'tumor'],
|
|
92
|
+
cancer: ['cancer', 'carcinoma', 'neoplasm'],
|
|
93
|
+
cancereux: ['cancer'],
|
|
94
|
+
carcinome: ['carcinoma'],
|
|
95
|
+
adenocarcinome: ['adenocarcinoma'],
|
|
96
|
+
sarcome: ['sarcoma'],
|
|
97
|
+
'osteosarcome': ['osteosarcoma'],
|
|
98
|
+
lymphome: ['lymphoma'],
|
|
99
|
+
leucemie: ['leukaemia', 'leukemia'],
|
|
100
|
+
myelome: ['myeloma'],
|
|
101
|
+
melanome: ['melanoma'],
|
|
102
|
+
gliome: ['glioma'],
|
|
103
|
+
glioblastome: ['glioblastoma'],
|
|
104
|
+
neuroblastome: ['neuroblastoma'],
|
|
105
|
+
mesotheliome: ['mesothelioma'],
|
|
106
|
+
metastase: ['metasta'],
|
|
107
|
+
metastatique: ['metasta'],
|
|
108
|
+
avance: ['advanced'],
|
|
109
|
+
'localement avance': ['locally advanced'],
|
|
110
|
+
'petites cellules': ['small cell', 'small-cell'],
|
|
111
|
+
'non a petites cellules': ['non-small cell', 'non small cell', 'nsclc'],
|
|
112
|
+
benin: ['benign'],
|
|
113
|
+
malin: ['malignant'],
|
|
114
|
+
maligne: ['malignant'],
|
|
115
|
+
solide: ['solid'],
|
|
116
|
+
// Maladies frequentes
|
|
117
|
+
diabete: ['diabet'],
|
|
118
|
+
obesite: ['obesity'],
|
|
119
|
+
hypertension: ['hypertension'],
|
|
120
|
+
insuffisance: ['failure', 'insufficiency'],
|
|
121
|
+
'insuffisance cardiaque': ['heart failure', 'cardiac failure'],
|
|
122
|
+
'insuffisance renale': ['kidney failure', 'renal failure', 'kidney disease', 'renal insufficiency'],
|
|
123
|
+
infarctus: ['infarction'],
|
|
124
|
+
'accident vasculaire cerebral': ['stroke'],
|
|
125
|
+
avc: ['stroke'],
|
|
126
|
+
asthme: ['asthma'],
|
|
127
|
+
bpco: ['copd', 'chronic obstructive pulmonary'],
|
|
128
|
+
mucoviscidose: ['cystic fibrosis'],
|
|
129
|
+
epilepsie: ['epilep'],
|
|
130
|
+
alzheimer: ['alzheimer'],
|
|
131
|
+
parkinson: ['parkinson'],
|
|
132
|
+
'sclerose en plaques': ['multiple sclerosis'],
|
|
133
|
+
'sclerose laterale amyotrophique': ['amyotrophic lateral sclerosis', 'als'],
|
|
134
|
+
sclerose: ['sclerosis'],
|
|
135
|
+
myopathie: ['myopath', 'muscular dystrophy'],
|
|
136
|
+
dystrophie: ['dystroph'],
|
|
137
|
+
'polyarthrite rhumatoide': ['rheumatoid arthritis'],
|
|
138
|
+
polyarthrite: ['polyarthritis', 'rheumatoid arthritis'],
|
|
139
|
+
arthrite: ['arthritis'],
|
|
140
|
+
arthrose: ['osteoarthritis'],
|
|
141
|
+
lupus: ['lupus'],
|
|
142
|
+
psoriasis: ['psoria'],
|
|
143
|
+
eczema: ['eczema', 'atopic dermatitis'],
|
|
144
|
+
'dermatite atopique': ['atopic dermatitis'],
|
|
145
|
+
dermatite: ['dermatitis'],
|
|
146
|
+
'maladie de crohn': ['crohn'],
|
|
147
|
+
crohn: ['crohn'],
|
|
148
|
+
'rectocolite hemorragique': ['ulcerative colitis'],
|
|
149
|
+
colite: ['colitis'],
|
|
150
|
+
hepatite: ['hepatitis'],
|
|
151
|
+
cirrhose: ['cirrhosis'],
|
|
152
|
+
steatose: ['steatosis', 'fatty liver', 'masld', 'nafld'],
|
|
153
|
+
vih: ['hiv'],
|
|
154
|
+
sida: ['aids', 'hiv'],
|
|
155
|
+
tuberculose: ['tuberculosis'],
|
|
156
|
+
paludisme: ['malaria'],
|
|
157
|
+
grippe: ['influenza'],
|
|
158
|
+
pneumonie: ['pneumonia'],
|
|
159
|
+
infection: ['infection'],
|
|
160
|
+
septicemie: ['sepsis'],
|
|
161
|
+
sepsis: ['sepsis'],
|
|
162
|
+
depression: ['depress'],
|
|
163
|
+
schizophrenie: ['schizophren'],
|
|
164
|
+
bipolaire: ['bipolar'],
|
|
165
|
+
autisme: ['autis'],
|
|
166
|
+
anxiete: ['anxiety'],
|
|
167
|
+
douleur: ['pain'],
|
|
168
|
+
migraine: ['migraine'],
|
|
169
|
+
anemie: ['anaemia', 'anemia'],
|
|
170
|
+
drepanocytose: ['sickle cell'],
|
|
171
|
+
thalassemie: ['thalass'],
|
|
172
|
+
hemophilie: ['haemophilia', 'hemophilia'],
|
|
173
|
+
thrombose: ['thrombosis'],
|
|
174
|
+
embolie: ['embolism'],
|
|
175
|
+
fibrose: ['fibrosis'],
|
|
176
|
+
'fibrose pulmonaire': ['pulmonary fibrosis'],
|
|
177
|
+
amylose: ['amyloidosis'],
|
|
178
|
+
osteoporose: ['osteoporosis'],
|
|
179
|
+
cataracte: ['cataract'],
|
|
180
|
+
glaucome: ['glaucoma'],
|
|
181
|
+
'degenerescence maculaire': ['macular degeneration'],
|
|
182
|
+
surdite: ['hearing loss', 'deafness'],
|
|
183
|
+
cecite: ['blindness'],
|
|
184
|
+
rare: ['rare'],
|
|
185
|
+
maladie: ['disease', 'disorder'],
|
|
186
|
+
syndrome: ['syndrome'],
|
|
187
|
+
chronique: ['chronic'],
|
|
188
|
+
aigu: ['acute'],
|
|
189
|
+
aigue: ['acute'],
|
|
190
|
+
enfant: ['child', 'paediatric', 'pediatric'],
|
|
191
|
+
pediatrique: ['paediatric', 'pediatric'],
|
|
192
|
+
adulte: ['adult'],
|
|
193
|
+
hereditaire: ['hereditary', 'inherited'],
|
|
194
|
+
genetique: ['genetic'],
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
const STOPWORDS = new Set(['de', 'du', 'des', 'd', 'la', 'le', 'les', 'l', 'et', 'a', 'au', 'aux', 'en', 'un', 'une']);
|
|
198
|
+
|
|
199
|
+
/** Minuscules, sans accents, apostrophes et tirets en espaces. */
|
|
200
|
+
const normalize = (text: string) =>
|
|
201
|
+
text
|
|
202
|
+
.toLowerCase()
|
|
203
|
+
.normalize('NFD')
|
|
204
|
+
.replace(/[̀-ͯ]/g, '')
|
|
205
|
+
.replace(/[^a-z0-9 ]+/g, ' ')
|
|
206
|
+
.replace(/\s+/g, ' ')
|
|
207
|
+
.trim();
|
|
208
|
+
|
|
209
|
+
const PHRASES = Object.keys(LEXICON)
|
|
210
|
+
.filter((key) => key.includes(' '))
|
|
211
|
+
.sort((a, b) => b.length - a.length);
|
|
212
|
+
|
|
213
|
+
/** Les traductions d'un mot : cle exacte, pluriel/feminin (« seins »), ou saisie en cours (« poum »). */
|
|
214
|
+
const translateWord = (word: string): string[] => {
|
|
215
|
+
const exact = LEXICON[word];
|
|
216
|
+
if (exact) return exact;
|
|
217
|
+
const found = Object.entries(LEXICON).filter(
|
|
218
|
+
([key]) =>
|
|
219
|
+
!key.includes(' ') &&
|
|
220
|
+
((word.length >= 4 && key.startsWith(word)) ||
|
|
221
|
+
(word.startsWith(key) && word.length - key.length <= 2 && key.length >= 3))
|
|
222
|
+
);
|
|
223
|
+
return [...new Set(found.flatMap(([, english]) => english))];
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
const escapeRegex = (text: string) => text.replace(/[.*+?^${}()|[\]\\"<>#@&~]/g, '\\$&');
|
|
227
|
+
|
|
228
|
+
const permutations = <T>(items: T[]): T[][] =>
|
|
229
|
+
items.length <= 1
|
|
230
|
+
? [items]
|
|
231
|
+
: items.flatMap((item, i) => permutations([...items.slice(0, i), ...items.slice(i + 1)]).map((rest) => [item, ...rest]));
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* La regex anglaise de la saisie, sans ancres (`breast|mammary`,
|
|
235
|
+
* `(breast|mammary).*(cancer|carcinoma)|...`), ou null quand aucun mot n'est
|
|
236
|
+
* traduit : la recherche reste alors celle d'avant.
|
|
237
|
+
*/
|
|
238
|
+
export function frDiseaseRegex(query: string): string | null {
|
|
239
|
+
let text = normalize(query);
|
|
240
|
+
if (text.length < 3) return null;
|
|
241
|
+
|
|
242
|
+
// Les expressions d'abord (« col de l uterus »), puis les mots.
|
|
243
|
+
const groups: string[][] = [];
|
|
244
|
+
let translated = false;
|
|
245
|
+
for (const phrase of PHRASES) {
|
|
246
|
+
if (` ${text} `.includes(` ${phrase} `)) {
|
|
247
|
+
groups.push(LEXICON[phrase] ?? []);
|
|
248
|
+
translated = true;
|
|
249
|
+
text = ` ${text} `.replace(` ${phrase} `, ' ').trim();
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
for (const word of text.split(' ')) {
|
|
253
|
+
if (!word || STOPWORDS.has(word)) continue;
|
|
254
|
+
const english = translateWord(word);
|
|
255
|
+
if (english.length > 0) translated = true;
|
|
256
|
+
groups.push(english.length > 0 ? english : [word]);
|
|
257
|
+
}
|
|
258
|
+
if (!translated || groups.length === 0) return null;
|
|
259
|
+
|
|
260
|
+
// Trois mots au plus : l'ordre anglais differe du francais, on essaie tous les ordres.
|
|
261
|
+
const parts = groups.slice(0, 3).map((alternatives) => `(${alternatives.map(escapeRegex).join('|')})`);
|
|
262
|
+
return permutations(parts)
|
|
263
|
+
.map((order) => order.join('.*'))
|
|
264
|
+
.join('|');
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/** `breast` → `[bB][rR]...` pour les `include` d'agregation, qui n'ont pas de case_insensitive. */
|
|
268
|
+
export const caseInsensitive = (regex: string) =>
|
|
269
|
+
regex.replace(/[a-z]/g, (char) => `[${char}${char.toUpperCase()}]`);
|