@tekkare/romulus 0.1.251 → 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.
Files changed (265) hide show
  1. package/dist/module.json +1 -1
  2. package/layer/app/app.config.ts +6 -0
  3. package/layer/app/components/OipPubmedSummary.vue +223 -0
  4. package/layer/app/components/OipResourceDrawer.vue +331 -0
  5. package/layer/app/components/OipResourceDrawerLink.vue +40 -0
  6. package/layer/app/components/OipResourceField.vue +41 -0
  7. package/layer/app/components/OipResourceGenericCard.vue +54 -0
  8. package/layer/app/components/OipResourceSource.vue +50 -0
  9. package/layer/app/components/OipResourceTags.vue +65 -0
  10. package/layer/app/components/OipResourceView.vue +107 -0
  11. package/layer/app/components/oip-drugs/fiches/AssociationFiche.vue +775 -0
  12. package/layer/app/components/oip-drugs/fiches/BrandFiche.vue +1111 -0
  13. package/layer/app/components/oip-drugs/fiches/IndicationFiche.vue +182 -0
  14. package/layer/app/components/oip-drugs/fiches/JoFiche.vue +101 -0
  15. package/layer/app/components/oip-drugs/fiches/PndsFiche.vue +279 -0
  16. package/layer/app/components/oip-drugs/heart/JoCard.vue +314 -0
  17. package/layer/app/components/oip-drugs/heart/TextHighlight.vue +326 -0
  18. package/layer/app/components/oip-drugs/heart/ansm/BrandCard.vue +187 -0
  19. package/layer/app/components/oip-drugs/heart/ansm/CisDetail.vue +363 -0
  20. package/layer/app/components/oip-drugs/heart/ansm/CisTable.vue +167 -0
  21. package/layer/app/components/oip-drugs/heart/associations/NationalAssemblyCard.vue +373 -0
  22. package/layer/app/components/oip-drugs/heart/associations/NationalAssemblyFiche.vue +372 -0
  23. package/layer/app/components/oip-drugs/heart/associations/TranscriptionCard.vue +55 -0
  24. package/layer/app/components/oip-drugs/heart/elastic/SourceContainerElastic.vue +103 -0
  25. package/layer/app/components/oip-drugs/heart/france/BrandGroupCard.vue +450 -0
  26. package/layer/app/components/oip-drugs/heart/mitm/Card.vue +199 -0
  27. package/layer/app/components/oip-drugs/heart/mitm/Source.vue +23 -0
  28. package/layer/app/components/oip-drugs/heart/mitm/details/Overview.vue +381 -0
  29. package/layer/app/components/oip-drugs/heart/put/Card.vue +212 -0
  30. package/layer/app/components/oip-drugs/heart/results/AccesCard.vue +696 -0
  31. package/layer/app/components/oip-drugs/heart/results/AlertCard.vue +342 -0
  32. package/layer/app/components/oip-drugs/heart/results/AsmrCursor.vue +229 -0
  33. package/layer/app/components/oip-drugs/heart/results/EvalCard.vue +370 -0
  34. package/layer/app/components/oip-drugs/heart/results/IndicCard.vue +743 -0
  35. package/layer/app/components/oip-drugs/heart/results/MatchExplain.vue +243 -0
  36. package/layer/app/components/oip-drugs/heart/results/PrefRows.vue +105 -0
  37. package/layer/app/components/oip-drugs/heart/results/details/HasHistory.vue +487 -0
  38. package/layer/app/components/oip-drugs/heart/results/details/InternationalCountryCard.vue +461 -0
  39. package/layer/app/components/oip-drugs/heart/results/details/InternationalOverview.vue +200 -0
  40. package/layer/app/components/oip-drugs/heart/results/details/InternationalPriceDrawer.vue +647 -0
  41. package/layer/app/components/oip-drugs/heart/results/details/Monograph.vue +128 -0
  42. package/layer/app/components/oip-drugs/heart/results/details/OpinionDrawer.vue +535 -0
  43. package/layer/app/components/oip-drugs/heart/results/details/PresentationDrawer.vue +738 -0
  44. package/layer/app/components/oip-drugs/heart/results/details/Price.vue +227 -0
  45. package/layer/app/components/oip-drugs/heart/results/details/PriceOverview.vue +1261 -0
  46. package/layer/app/components/oip-drugs/heart/results/details/RecordDrawer.vue +494 -0
  47. package/layer/app/components/oip-drugs/heart/results/details/RecordList.vue +426 -0
  48. package/layer/app/components/oip-drugs/heart/results/les/Card.vue +340 -0
  49. package/layer/app/components/oip-drugs/heart/results/les/Drawer.vue +67 -0
  50. package/layer/app/components/oip-drugs/heart/results/les/IndicationDetail.vue +149 -0
  51. package/layer/app/components/oip-drugs/heart/results/les/Source.vue +20 -0
  52. package/layer/app/components/oip-drugs/heart/results/les/SourceTag.vue +39 -0
  53. package/layer/app/components/oip-drugs/heart/searchPage/DynamicSource.vue +29 -0
  54. package/layer/app/components/oip-drugs/medicam/market/Chart.vue +121 -0
  55. package/layer/app/components/oip-drugs/outpatient/ProductEvolution.vue +236 -0
  56. package/layer/app/components/oip-drugs/resources/Ansm.vue +75 -0
  57. package/layer/app/components/oip-drugs/resources/Association.vue +30 -0
  58. package/layer/app/components/oip-drugs/resources/Brand.vue +65 -0
  59. package/layer/app/components/oip-drugs/resources/Contribution.vue +216 -0
  60. package/layer/app/components/oip-drugs/resources/Hospital.vue +151 -0
  61. package/layer/app/components/oip-drugs/resources/Indication.vue +54 -0
  62. package/layer/app/components/oip-drugs/resources/Jo.vue +57 -0
  63. package/layer/app/components/oip-drugs/resources/Medicam.vue +140 -0
  64. package/layer/app/components/oip-drugs/resources/Mitm.vue +84 -0
  65. package/layer/app/components/oip-drugs/resources/NationalAssembly.vue +93 -0
  66. package/layer/app/components/oip-drugs/resources/Outpatient.vue +97 -0
  67. package/layer/app/components/oip-drugs/resources/Pnds.vue +24 -0
  68. package/layer/app/components/oip-drugs/resources/Price.vue +106 -0
  69. package/layer/app/components/oip-drugs/resources/Put.vue +143 -0
  70. package/layer/app/components/oip-science/appel-a-projet/Cards.vue +162 -0
  71. package/layer/app/components/oip-science/clinical-trials/Cards.vue +382 -0
  72. package/layer/app/components/oip-science/clinical-trials/CardsGlobal.vue +273 -0
  73. package/layer/app/components/oip-science/clinical-trials/LinkedList.vue +366 -0
  74. package/layer/app/components/oip-science/clinical-trials/PairBadge.vue +25 -0
  75. package/layer/app/components/oip-science/clinical-trials/PairBody.vue +182 -0
  76. package/layer/app/components/oip-science/clinical-trials/SitesDrawer.vue +95 -0
  77. package/layer/app/components/oip-science/common/Form.vue +73 -0
  78. package/layer/app/components/oip-science/common/MatchAvgTag.vue +283 -0
  79. package/layer/app/components/oip-science/common/NoData.vue +16 -0
  80. package/layer/app/components/oip-science/common/ScoreBadge.vue +35 -0
  81. package/layer/app/components/oip-science/common/Source.vue +31 -0
  82. package/layer/app/components/oip-science/common/TableTags.vue +279 -0
  83. package/layer/app/components/oip-science/common/Timeline.vue +104 -0
  84. package/layer/app/components/oip-science/common/ToolTips.vue +89 -0
  85. package/layer/app/components/oip-science/cross/publicationPubmed.vue +484 -0
  86. package/layer/app/components/oip-science/crossData/CrossDataLocations.vue +71 -0
  87. package/layer/app/components/oip-science/ctgov/Investigators.vue +148 -0
  88. package/layer/app/components/oip-science/ctgov/Locations.vue +102 -0
  89. package/layer/app/components/oip-science/ctgov/Publications.vue +52 -0
  90. package/layer/app/components/oip-science/ctgov/Sponsors.vue +66 -0
  91. package/layer/app/components/oip-science/ctgov/StudyDescription.vue +1136 -0
  92. package/layer/app/components/oip-science/ctgov-centers/ClinicalTrials.vue +40 -0
  93. package/layer/app/components/oip-science/ctgov-centers/Publications.vue +50 -0
  94. package/layer/app/components/oip-science/ctgov-investigators/ClinicalTrials.vue +43 -0
  95. package/layer/app/components/oip-science/ctgov-investigators/Informations.vue +171 -0
  96. package/layer/app/components/oip-science/ctgov-investigators/Publications.vue +44 -0
  97. package/layer/app/components/oip-science/elastic/DateRangeFilter.vue +209 -0
  98. package/layer/app/components/oip-science/elastic/Filter.vue +719 -0
  99. package/layer/app/components/oip-science/elastic/MatchExplain.vue +152 -0
  100. package/layer/app/components/oip-science/establishments/Cards.vue +183 -0
  101. package/layer/app/components/oip-science/establishments/ClinicalTrials.vue +62 -0
  102. package/layer/app/components/oip-science/establishments/Hcps.vue +227 -0
  103. package/layer/app/components/oip-science/establishments/Informations.vue +263 -0
  104. package/layer/app/components/oip-science/establishments/LinkedList.vue +153 -0
  105. package/layer/app/components/oip-science/establishments/MatchedLabels.vue +194 -0
  106. package/layer/app/components/oip-science/establishments/PublicFinance.vue +62 -0
  107. package/layer/app/components/oip-science/euct/Investigators.vue +125 -0
  108. package/layer/app/components/oip-science/euct/Locations.vue +102 -0
  109. package/layer/app/components/oip-science/euct/Products.vue +101 -0
  110. package/layer/app/components/oip-science/euct/Publications.vue +89 -0
  111. package/layer/app/components/oip-science/euct/Sponsors.vue +86 -0
  112. package/layer/app/components/oip-science/euct/StudyDescription.vue +1075 -0
  113. package/layer/app/components/oip-science/euct-centers/ClinicalTrials.vue +40 -0
  114. package/layer/app/components/oip-science/euct-centers/Publications.vue +55 -0
  115. package/layer/app/components/oip-science/euct-investigators/ClinicalTrials.vue +41 -0
  116. package/layer/app/components/oip-science/euct-investigators/Informations.vue +171 -0
  117. package/layer/app/components/oip-science/euct-investigators/Publications.vue +51 -0
  118. package/layer/app/components/oip-science/hcps/AppelsAProjet.vue +62 -0
  119. package/layer/app/components/oip-science/hcps/Cards.vue +237 -0
  120. package/layer/app/components/oip-science/hcps/ClinicalTrials.vue +78 -0
  121. package/layer/app/components/oip-science/hcps/Informations.vue +296 -0
  122. package/layer/app/components/oip-science/hcps/LinkedList.vue +153 -0
  123. package/layer/app/components/oip-science/hcps/MatchedLabels.vue +207 -0
  124. package/layer/app/components/oip-science/hcps/Pubmed.vue +128 -0
  125. package/layer/app/components/oip-science/local/SliderTabs.vue +99 -0
  126. package/layer/app/components/oip-science/local/SliderTabsFull.vue +135 -0
  127. package/layer/app/components/oip-science/pubmed/Authors.vue +128 -0
  128. package/layer/app/components/oip-science/pubmed/Cards.vue +417 -0
  129. package/layer/app/components/oip-science/pubmed/ClinicalTrials.vue +71 -0
  130. package/layer/app/components/oip-science/resources/Phrc.vue +39 -0
  131. package/layer/app/composables/useOipChapterScroll.ts +43 -0
  132. package/layer/app/composables/useOipResourceHooks.ts +27 -0
  133. package/layer/app/composables/useOipResourceNav.ts +66 -0
  134. package/layer/app/composables/useOipResourceViews.ts +117 -0
  135. package/layer/app/composables/useOipResources.ts +83 -0
  136. package/layer/app/oip-drugs/PORTING.md +120 -0
  137. package/layer/app/oip-drugs/composables/useAssociationDetail.ts +220 -0
  138. package/layer/app/oip-drugs/composables/useAssociationExport.ts +63 -0
  139. package/layer/app/oip-drugs/composables/useAssociationLookup.ts +105 -0
  140. package/layer/app/oip-drugs/composables/useCardPrefOptions.ts +201 -0
  141. package/layer/app/oip-drugs/composables/useCurrency.ts +121 -0
  142. package/layer/app/oip-drugs/composables/useDirectusSources.ts +224 -0
  143. package/layer/app/oip-drugs/composables/useHeartBrandMatches.ts +112 -0
  144. package/layer/app/oip-drugs/composables/useHeartDetailSearches.ts +479 -0
  145. package/layer/app/oip-drugs/composables/useHeartIntlApprovals.ts +661 -0
  146. package/layer/app/oip-drugs/composables/useHeartLesIndication.ts +168 -0
  147. package/layer/app/oip-drugs/composables/useHeartMatchExplain.ts +231 -0
  148. package/layer/app/oip-drugs/composables/useHeartReports.ts +239 -0
  149. package/layer/app/oip-drugs/composables/useHeartSearchFields.ts +233 -0
  150. package/layer/app/oip-drugs/composables/useMergeByKey.ts +23 -0
  151. package/layer/app/oip-drugs/composables/useOipDrugsElastic.ts +621 -0
  152. package/layer/app/oip-drugs/composables/usePageEmpty.ts +58 -0
  153. package/layer/app/oip-drugs/composables/v-useSalesSource.ts +64 -0
  154. package/layer/app/oip-drugs/drugs.css +500 -0
  155. package/layer/app/oip-drugs/esIndices.ts +322 -0
  156. package/layer/app/oip-drugs/kinds.ts +264 -0
  157. package/layer/app/oip-drugs/locales/en.json +1571 -0
  158. package/layer/app/oip-drugs/locales/fr.json +1571 -0
  159. package/layer/app/oip-drugs/monographs/blincyto-has.vue +289 -0
  160. package/layer/app/oip-drugs/monographs/darzalex-has.vue +276 -0
  161. package/layer/app/oip-drugs/monographs/dupixent-has.vue +216 -0
  162. package/layer/app/oip-drugs/monographs/enhertu-has.vue +280 -0
  163. package/layer/app/oip-drugs/monographs/has-sein-2023.vue +1649 -0
  164. package/layer/app/oip-drugs/monographs/ibrance-has.vue +277 -0
  165. package/layer/app/oip-drugs/monographs/imfinzi-has.vue +293 -0
  166. package/layer/app/oip-drugs/monographs/keytruda-has.vue +334 -0
  167. package/layer/app/oip-drugs/monographs/kisqali-has.vue +201 -0
  168. package/layer/app/oip-drugs/monographs/opdivo-has.vue +231 -0
  169. package/layer/app/oip-drugs/monographs/ozempic-has.vue +186 -0
  170. package/layer/app/oip-drugs/monographs/tecentriq-has.vue +312 -0
  171. package/layer/app/oip-drugs/monographs/yescarta-has.vue +272 -0
  172. package/layer/app/oip-drugs/types/elastic.ts +113 -0
  173. package/layer/app/oip-drugs/types/es/agencies.ts +152 -0
  174. package/layer/app/oip-drugs/types/es/directory.ts +54 -0
  175. package/layer/app/oip-drugs/types/es/docByIndex.ts +151 -0
  176. package/layer/app/oip-drugs/types/es/openmedic.ts +67 -0
  177. package/layer/app/oip-drugs/types/es/outpatient.ts +71 -0
  178. package/layer/app/oip-drugs/types/es/portal.ts +130 -0
  179. package/layer/app/oip-drugs/types/es/retail.ts +107 -0
  180. package/layer/app/oip-drugs/types/es/statistics.ts +29 -0
  181. package/layer/app/oip-drugs/types/heart/CurrencyRate.ts +16 -0
  182. package/layer/app/oip-drugs/types/heart/ansm.ts +106 -0
  183. package/layer/app/oip-drugs/types/heart/tag.ts +29 -0
  184. package/layer/app/oip-drugs/utils/associationFields.ts +118 -0
  185. package/layer/app/oip-drugs/utils/contributions.ts +36 -0
  186. package/layer/app/oip-drugs/utils/countryMapping.ts +387 -0
  187. package/layer/app/oip-drugs/utils/esHighlight.ts +21 -0
  188. package/layer/app/oip-drugs/utils/exportSheets.ts +57 -0
  189. package/layer/app/oip-drugs/utils/heartIntlPrice.ts +228 -0
  190. package/layer/app/oip-drugs/utils/heartStyleAndFormat.ts +262 -0
  191. package/layer/app/oip-drugs/utils/heartStyleAnsm.ts +71 -0
  192. package/layer/app/oip-drugs/utils/latestDate.ts +31 -0
  193. package/layer/app/oip-drugs/utils/p-heartCardTags.ts +53 -0
  194. package/layer/app/oip-drugs/utils/priceExport.ts +269 -0
  195. package/layer/app/oip-drugs/utils/q-hasRatings.ts +43 -0
  196. package/layer/app/oip-drugs/utils/s-openCard.ts +20 -0
  197. package/layer/app/oip-drugs/utils/sourceUuids.ts +155 -0
  198. package/layer/app/oip-drugs/utils/styleAndFormat.ts +40 -0
  199. package/layer/app/oip-drugs/utils/v-salesSeries.ts +156 -0
  200. package/layer/app/oip-drugs/utils/v-scopeTags.ts +23 -0
  201. package/layer/app/oip-science/PORTING.md +93 -0
  202. package/layer/app/oip-science/assets/smartSelection.json +428 -0
  203. package/layer/app/oip-science/composables/useAuthorMatching.ts +342 -0
  204. package/layer/app/oip-science/composables/useCTCenter.ts +107 -0
  205. package/layer/app/oip-science/composables/useCTInvestigators.ts +107 -0
  206. package/layer/app/oip-science/composables/useEstablishmentCrossData.ts +139 -0
  207. package/layer/app/oip-science/composables/useEstablishmentMatching.ts +176 -0
  208. package/layer/app/oip-science/composables/useEuct.ts +418 -0
  209. package/layer/app/oip-science/composables/useEuctCenter.ts +107 -0
  210. package/layer/app/oip-science/composables/useEuctInvestigators.ts +107 -0
  211. package/layer/app/oip-science/composables/useGlobalClinicalTrials.ts +624 -0
  212. package/layer/app/oip-science/composables/useLinkedTrials.ts +83 -0
  213. package/layer/app/oip-science/composables/useOipElastic.ts +658 -0
  214. package/layer/app/oip-science/composables/useOipSearchExplain.ts +166 -0
  215. package/layer/app/oip-science/composables/usePubmed.ts +487 -0
  216. package/layer/app/oip-science/composables/useSearchFields.ts +153 -0
  217. package/layer/app/oip-science/indexConfig.json +794 -0
  218. package/layer/app/oip-science/locales/en.json +483 -0
  219. package/layer/app/oip-science/locales/fr.json +483 -0
  220. package/layer/app/oip-science/science.css +1182 -0
  221. package/layer/app/oip-science/utils/a-openCard.ts +23 -0
  222. package/layer/app/oip-science/utils/b-openCard.ts +35 -0
  223. package/layer/app/oip-science/utils/c-filterContext.ts +81 -0
  224. package/layer/app/oip-science/utils/f-types.ts +241 -0
  225. package/layer/app/oip-science/utils/frDiseaseTerms.ts +269 -0
  226. package/layer/app/oip-science/utils/matchMethod.ts +53 -0
  227. package/layer/app/oip-science/utils/sliderTabs.ts +13 -0
  228. package/layer/app/oip-science/utils/sources.ts +15 -0
  229. package/layer/app/oip-science/utils/styleAndFormat.ts +608 -0
  230. package/layer/app/oip-science/utils/toPresets.ts +7 -0
  231. package/layer/app/oip-science/utils/valueTable.ts +126 -0
  232. package/layer/app/plugins/oip-science-i18n.ts +17 -0
  233. package/layer/app/utils/oipFicheRoutes.ts +118 -0
  234. package/layer/app/utils/oipResources.ts +440 -0
  235. package/layer/nuxt.config.ts +22 -2
  236. package/layer/public/reports/blincyto-has.html +292 -0
  237. package/layer/public/reports/blincyto-has.pdf +0 -0
  238. package/layer/public/reports/darzalex-has.html +279 -0
  239. package/layer/public/reports/darzalex-has.pdf +0 -0
  240. package/layer/public/reports/dupixent-has.html +217 -0
  241. package/layer/public/reports/dupixent-has.pdf +0 -0
  242. package/layer/public/reports/enhertu-has.html +283 -0
  243. package/layer/public/reports/enhertu-has.pdf +0 -0
  244. package/layer/public/reports/has-sein-2023.html +1639 -0
  245. package/layer/public/reports/ibrance-has.html +280 -0
  246. package/layer/public/reports/ibrance-has.pdf +0 -0
  247. package/layer/public/reports/imfinzi-has.html +297 -0
  248. package/layer/public/reports/imfinzi-has.pdf +0 -0
  249. package/layer/public/reports/keytruda-has.html +337 -0
  250. package/layer/public/reports/keytruda-has.pdf +0 -0
  251. package/layer/public/reports/kisqali-has.html +202 -0
  252. package/layer/public/reports/kisqali-has.pdf +0 -0
  253. package/layer/public/reports/opdivo-has.html +232 -0
  254. package/layer/public/reports/opdivo-has.pdf +0 -0
  255. package/layer/public/reports/ozempic-has.html +188 -0
  256. package/layer/public/reports/ozempic-has.pdf +0 -0
  257. package/layer/public/reports/tecentriq-has.html +315 -0
  258. package/layer/public/reports/tecentriq-has.pdf +0 -0
  259. package/layer/public/reports/yescarta-has.html +275 -0
  260. package/layer/public/reports/yescarta-has.pdf +0 -0
  261. package/layer/server/api/oip/es.post.ts +99 -0
  262. package/layer/server/api/oip/pdf.get.ts +70 -0
  263. package/layer/server/api/oip/reports.get.ts +98 -0
  264. package/layer/server/api/oip/resource-types.get.ts +22 -0
  265. package/package.json +1 -1
@@ -0,0 +1,156 @@
1
+ /**
2
+ * Evolutions des ventes d'une marque (Medic'AM, Outpatient, liste en sus,
3
+ * retrocession), pour les vues de ressource du lot V : les constantes des
4
+ * stores `retail`, `outpatient` et `hospital` de fr_drugs_app, la marque lue
5
+ * dans le `resourceId`, et le calcul des courbes des graphes de ventes
6
+ * (medicam/market/chart, outpatient/productEvolution).
7
+ *
8
+ * Le calcul des courbes reprend celui de fr_drugs_app pas a pas, sans lodash
9
+ * (le layer ne le declare pas) : arrondi, part de marche par periode, trous
10
+ * bouches a null, jointure des libelles, une courbe par libelle.
11
+ */
12
+ import useMergeByKey from "../composables/useMergeByKey";
13
+ import { DRUG_PROJECT_KINDS } from "../kinds";
14
+
15
+ type MeasureList = { variables: string[]; en: string[]; fr: string[] };
16
+
17
+ /** cf. store/retail de fr_drugs_app (medicamMeasure*). */
18
+ export const MEDICAM_MEASURES: MeasureList = {
19
+ variables: ["unit_reimbursed", "value_public_price", "factory_value", "amount_reimbursed"],
20
+ en: ["# Packages", "Value in Public Price (€)", "Value ex-factory (€) - PFHT", "Amount Reimbursed (€)"],
21
+ fr: ["# Boîtes", "Valeur en prix public (€)", "Prix Fabricant HT (€)", "Montant remboursé (€)"],
22
+ };
23
+
24
+ /** cf. store/outpatient de fr_drugs_app (outpatientMeasure*), mesure par defaut : prix public. */
25
+ export const OUTPATIENT_MEASURES: MeasureList = {
26
+ variables: ["unit_reimbursed", "value_public_price", "amount_reimbursed"],
27
+ en: ["# Packages", "Value in Public Price (€)", "Amount Reimbursed (€)"],
28
+ fr: ["# Boîtes", "Valeur en prix public (€)", "Montant Remboursé (€)"],
29
+ };
30
+ export const OUTPATIENT_DEFAULT_MEASURE = 1;
31
+
32
+ /** cf. store/hospital de fr_drugs_app (susMeasure*, retrocessionMeasure*). */
33
+ export const HOSPITAL_MEASURES: Record<"FrSusBrand" | "FrRetrocessionBrand", MeasureList> = {
34
+ FrSusBrand: {
35
+ variables: ["unit", "bse"],
36
+ en: ["UCD Administered", "Amount Invoiced (€)"],
37
+ fr: ["UCD administrées", "Montant Facturé (€)"],
38
+ },
39
+ FrRetrocessionBrand: {
40
+ variables: ["unit", "bse", "rem"],
41
+ en: ["UCD Administered", "Value in Public Price (€)", "Amount Reimbursed (€)"],
42
+ fr: ["UCD administrées", "Valeur en prix public (€)", "Montant remboursé (€)"],
43
+ },
44
+ };
45
+
46
+ /** Options d'un RmSegmented de mesures, dans la langue de la vue. */
47
+ export function measureOptions(list: MeasureList, en: boolean) {
48
+ return list.variables.map((value, index) => ({ value, label: (en ? list.en : list.fr)[index] ?? value }));
49
+ }
50
+
51
+ /**
52
+ * La marque d'un element de projet de ventes, par son `resourceId` : l'ancre
53
+ * (dernier mois, derniere annee) n'est qu'un repere, l'element designe la
54
+ * marque entiere (cf. medicamBrandOf de fr_drugs_app, titleFromId de kinds.ts).
55
+ */
56
+ export function salesBrandOf(type: string, id: string): string {
57
+ const kind = DRUG_PROJECT_KINDS.find((k) => k.type === type) as any;
58
+ return kind?.titleFromId ? String(kind.titleFromId(String(id ?? ""))) : String(id ?? "");
59
+ }
60
+
61
+ /** _.round de lodash : arrondi a `precision` decimales sans erreur de flottant. */
62
+ function round(value: unknown, precision = 0): number {
63
+ const n = Number(value);
64
+ if (!precision || !Number.isFinite(n)) return Math.round(n);
65
+ let [m, e] = `${n}e`.split("e");
66
+ const shifted = Math.round(Number(`${m}e${Number(e) + precision}`));
67
+ [m, e] = `${shifted}e`.split("e");
68
+ return Number(`${m}e${Number(e) - precision}`);
69
+ }
70
+
71
+ function compare(a: any, b: any): number {
72
+ if (a === b) return 0;
73
+ if (a === undefined) return 1;
74
+ if (b === undefined) return -1;
75
+ return a > b ? 1 : a < b ? -1 : 0;
76
+ }
77
+
78
+ /** _.orderBy ascendant, stable. */
79
+ function orderBy(rows: any[], keys: string[]): any[] {
80
+ return [...rows].sort((x, y) => {
81
+ for (const key of keys) {
82
+ const c = compare(x[key], y[key]);
83
+ if (c) return c;
84
+ }
85
+ return 0;
86
+ });
87
+ }
88
+
89
+ /** _.groupBy : cle en texte, dans l'ordre d'arrivee. */
90
+ function groupBy(rows: any[], key: string): Map<string, any[]> {
91
+ const groups = new Map<string, any[]>();
92
+ for (const row of rows) {
93
+ const k = String(row[key]);
94
+ if (!groups.has(k)) groups.set(k, []);
95
+ groups.get(k)!.push(row);
96
+ }
97
+ return groups;
98
+ }
99
+
100
+ /** Les periodes des lignes, une fois chacune, triees. */
101
+ export function salesPeriods(rows: any[]): any[] {
102
+ return rows
103
+ .map((i: any) => i.period)
104
+ .filter((v: any, i: number, a: any[]) => a.indexOf(v) === i)
105
+ .sort();
106
+ }
107
+
108
+ /**
109
+ * Les courbes d'un graphe de ventes : `rows` portent `code`, `period` et
110
+ * `volume` (la mesure lue) ; `selectedLabel` donne le libelle de chaque code
111
+ * (`code`, `code_label`). Volume ou part de marche selon `selectedSwitch`.
112
+ */
113
+ export function salesCurves(rows: any[], selectedLabel: any[], selectedSwitch: boolean) {
114
+ // Round and arrange selectedMetric
115
+ let result = orderBy(
116
+ rows.map((i: any) => ({ ...i, volume: round(i.volume, 0) })),
117
+ ["period"],
118
+ );
119
+
120
+ // Calculate market share
121
+ const total = [...groupBy(result, "period")].map(([period, list]) => ({
122
+ period,
123
+ total_volume: list.reduce((sum: number, i: any) => sum + i.volume, 0),
124
+ }));
125
+ result = useMergeByKey(result, total, "period");
126
+ result = result.map((i: any) => ({
127
+ ...i,
128
+ // Un total nul donnait 0/0 = NaN, trace comme un point
129
+ percentage: i.total_volume ? round((i.volume / i.total_volume) * 100, 1) : null,
130
+ }));
131
+
132
+ // Fill null values
133
+ const codes = [...new Set(result.map((i: any) => i.code))];
134
+ const periods = [...new Set(result.map((i: any) => i.period))];
135
+ const product = codes.flatMap((code) => periods.map((period) => ({ code, period, volume: null, percentage: 0 })));
136
+ const seen = new Set<string>();
137
+ result = [...result, ...product].filter((i: any) => {
138
+ const key = [i.code, i.period].join();
139
+ if (seen.has(key)) return false;
140
+ seen.add(key);
141
+ return true;
142
+ });
143
+ result = orderBy(result, ["code", "period"]);
144
+
145
+ // Add labels
146
+ result = useMergeByKey(result, selectedLabel, "code");
147
+
148
+ // Detect variable for chart
149
+ const variable = selectedSwitch ? "volume" : "percentage";
150
+
151
+ // Create chart_content
152
+ return [...groupBy(result, "code_label")].map(([name, list]) => ({
153
+ name,
154
+ data: list.map((i: any) => i[variable]),
155
+ }));
156
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Perimetre lu par une carte, en etiquettes sous son titre : une couleur par
3
+ * sorte (element, mesure, specialite, periode, geographie), la meme d'une page
4
+ * a l'autre, pour que l'oeil retrouve la periode sans lire. Les parties vides
5
+ * tombent ; l'ordre est celui des sortes, pas celui de l'appel.
6
+ *
7
+ * Copie de utils/scopeTags de fr_drugs_app (lot V).
8
+ */
9
+ const SCOPE_TAG_COLORS = {
10
+ item: "indigo",
11
+ measure: "sky",
12
+ specialty: "pink",
13
+ period: "emerald",
14
+ geo: "amber",
15
+ } as const;
16
+
17
+ export type ScopeTagKind = keyof typeof SCOPE_TAG_COLORS;
18
+
19
+ export function scopeTags(parts: Partial<Record<ScopeTagKind, string>>) {
20
+ return (Object.keys(SCOPE_TAG_COLORS) as ScopeTagKind[])
21
+ .filter((kind) => parts[kind])
22
+ .map((kind) => ({ label: parts[kind]!, variant: SCOPE_TAG_COLORS[kind] }));
23
+ }
@@ -0,0 +1,93 @@
1
+ # Porter une fiche de France Augmented Science dans le layer
2
+
3
+ Les fiches (essais, publications, professionnels, établissements, investigateurs,
4
+ centres) vivent ici pour s'afficher **à l'identique** dans toutes les apps du
5
+ portail : la page de France Augmented Science (FAS) et le tiroir des projets de
6
+ n'importe quelle app montent le même composant. Source : `~/Projects/france_augmented_science_app/app`.
7
+
8
+ Le rendu est la spec : on porte le code de FAS presque tel quel, en ne
9
+ changeant que ce qui l'attache à l'app. Pas de refonte, pas d'amélioration.
10
+
11
+ ## Où ranger
12
+
13
+ | Quoi | Où | Nom / import |
14
+ |---|---|---|
15
+ | Composant | `app/components/oip-science/<famille>/<Nom>.vue` | auto-importé sous `OipScience<Famille><Nom>` (ex. `oip-science/hcps/Cards.vue` → `<OipScienceHcpsCards>`) |
16
+ | Composable, util | `app/oip-science/composables/*.ts`, `app/oip-science/utils/*.ts` | **pas** auto-importés : import relatif explicite. Garder les noms de FAS. |
17
+ | Index ES | `app/oip-science/indexConfig.json` (copie de celui de FAS) | `import indexConfig from "<rel>/oip-science/indexConfig.json"` |
18
+
19
+ Composants déjà là : `OipScienceCommonSource` (`sources: string[]`, ex. `['PubMed']`),
20
+ `OipResourceSource` (`uuid`), `OipResourceField`, `OipResourceTags`, `OipPubmedSummary`.
21
+
22
+ ## Remplacements obligatoires
23
+
24
+ - **Racine** : chaque onglet et chaque composant monté seul a la classe `oip-science`
25
+ sur sa racine. Les classes globales de FAS (`oip_*`, `kk_*`, variables `--cool-grey`…)
26
+ marchent dessous (cf. `science.css`). Ne pas les réécrire.
27
+ - **Elasticsearch** : `useElastic()` → `useOipElastic()` (`app/oip-science/composables/useOipElastic.ts`,
28
+ mêmes fonctions et signatures). `/api/es` n'existe pas hors FAS. Aucun autre accès réseau à ES.
29
+ - **i18n** : toutes les clés passent sous `oipScience.` : `$t('trial.phase')` →
30
+ `$t('oipScience.trial.phase')`, idem `t(...)` de `useI18n()`. Seuls les préfixes
31
+ `trial, common, cards, publication, resultKpis, kpi, ui` existent (`app/oip-science/locales/*.json`).
32
+ Une clé hors de ces préfixes : **la signaler dans le compte rendu**, ne pas éditer les fichiers de locales.
33
+ - **Identifiant** : jamais `useRoute()` / `route.params`. L'onglet reçoit la prop `id`
34
+ (identifiant de route de FAS : PMID, NCT, numéro EUCT, RPPS sans `10_`, FINESS, id investigateur/centre).
35
+ - **Liens vers une autre fiche** (`openCard`, `navigateTo`, `NuxtLink`, `localePath`, `router.push`) :
36
+ `const nav = useOipResourceNav()` (auto-importé) puis `nav.open(type, id)` au clic et
37
+ `:href="nav.href(type, id)"` pour garder le Ctrl/Cmd-clic (`@click.prevent` sauf touche modificatrice,
38
+ comme `openCard`). Types : `PubMed`, `ClinicalTrialsNCT`, `ClinicalTrialsEUCT`, `HCP` (id = `10_<RPPS>`),
39
+ `Establishment` (FINESS), `ClinicalTrialsInvestigatorsNCT/EUCT`, `ClinicalTrialsCentersNCT/EUCT`.
40
+ Une page qui n'est pas une fiche du layer (appel à projets `/appel-a-projet/<id>`) :
41
+ `nav.openApp('france_augmented_science_app', path)` / `nav.appHref(...)`. Liens externes (pubmed.ncbi…) inchangés.
42
+ - **Bouton Projet** (`ProjectAddButton`, `project-add-button`) :
43
+ `const { projectButton } = useOipResourceHooks()` puis
44
+ `<component :is="projectButton" v-if="projectButton" :resource-id="…" type="…" :label="…" compact />` (mêmes props qu'avant).
45
+ - **Source cliquable** (`CommonSource`) → `<OipScienceCommonSource :sources="[…]" />`.
46
+ - **Surlignage de la recherche** (`useFilterStore().getHiglightValues(...)`) : prop `highlight: string[]` (défaut `[]`).
47
+ - **Sommaire** (`useChapterScroll()`) → `useOipChapterScroll(rootRef)` (auto-importé), `rootRef` = ref de la racine.
48
+ - **Cadre de l'app** : retirer `useExportSource`, `declareRecord`, `useAlertSource`, `useViews`,
49
+ `useAppLayout().openInfo()`, `definePageMeta`, `usePosthogTracking`, les stores Pinia de FAS
50
+ (`elasticQueryStore`, `filterStore`, `layoutConfig`, `scopeStore`, `cardPrefs`…). Un état
51
+ partagé par un store devient un état local du composant. Le menu d'export d'une carte
52
+ (`payload` construit avec `useGenerateExcel`) est retiré : **le signaler**.
53
+ - **État partagé en-tête / onglet** (`useState('current-hcp')`, `useState('current-establishment')`) :
54
+ l'onglet relit lui-même son document.
55
+ - `<client-only>`, `Suspense` : seulement si FAS en avait besoin pour la même raison.
56
+ - Utils de FAS (`styleAndFormat`, `valueTable`, `matchMethod`…) : copier ce qui sert dans
57
+ `app/oip-science/utils/` (un fichier par util de FAS, même nom), imports explicites.
58
+
59
+ ## Contrat d'un onglet
60
+
61
+ `props: { id: string; highlight?: string[]; lang?: 'fr' | 'en' }`. Il charge ses données
62
+ lui-même (`onMounted` ou `watch(id, …, { immediate: true })`), affiche `RmLoadingState`
63
+ pendant le chargement et l'état vide de FAS (`CommonNoData` → `RmEmptyState` avec les mêmes textes).
64
+
65
+ ## Règles de texte
66
+
67
+ Aucun tiret cadratin (—) dans un texte visible : parenthèses ou virgules.
68
+ Commentaires en français, sans accents dans le code comme le reste du layer, densité de FAS.
69
+
70
+ ## Répartition du portage (six lots en parallèle)
71
+
72
+ Chaque fichier de FAS a **un seul** lot propriétaire. Un lot n'écrit que ses fichiers ;
73
+ il peut utiliser ceux des autres lots par leur nom cible (même API que l'original de FAS),
74
+ même s'ils n'existent pas encore. Chemins FAS relatifs à `app/`, cibles relatives au layer `app/`.
75
+
76
+ | Lot | Fichiers de FAS | Cibles |
77
+ |---|---|---|
78
+ | A, personnes et lieux | components/hcps/{Cards,LinkedList}.vue, components/establishments/{Cards,LinkedList}.vue, components/appel-a-projet/Cards.vue, components/common/{ScoreBadge,MatchAvgTag,ToolTips,TableTags,Form,Timeline,NoData}.vue, components/elastic/MatchExplain.vue, components/crossData/CrossDataLocations.vue ; composables useAuthorMatching, useEstablishmentMatching, useEstablishmentCrossData, useSearchFields (si utilisé) ; utils styleAndFormat, valueTable, matchMethod | components/oip-science/{hcps,establishments,appel-a-projet,common,elastic,crossData}/<même nom>.vue ; oip-science/composables/<même nom>.ts ; oip-science/utils/<même nom>.ts |
79
+ | B, essais et publications (cartes) | components/clinical-trials/{LinkedList,Cards,CardsGlobal,PairBadge,PairBody,SitesDrawer}.vue, components/pubmed/Cards.vue ; composables useLinkedTrials, useGlobalClinicalTrials, useEuct, usePubmed | components/oip-science/{clinical-trials,pubmed}/<même nom>.vue ; oip-science/composables/<même nom>.ts |
80
+ | C, liste de publications filtrée | components/cross/publicationPubmed.vue, components/elastic/{Filter,DateRangeFilter}.vue, components/local/{SliderTabs,SliderTabsFull}.vue ; utils frDiseaseTerms, toPresets, sliderTabs ; assets allCountries.json, smartSelection.json | components/oip-science/{cross,elastic,local}/<même nom>.vue ; oip-science/utils/<même nom>.ts ; oip-science/assets/<même nom>.json |
81
+ | D, onglets PubMed, CT.gov, EUCT | pages/pubmed/[id]/{authors,clinical-trials}.vue, pages/ctgov/[id]/{study-description,investigators,locations,sponsors,publications}.vue, pages/euct/[id]/{study-description,products,investigators,locations,sponsors,publications}.vue | components/oip-science/pubmed/{Authors,ClinicalTrials}.vue, components/oip-science/ctgov/{StudyDescription,Investigators,Locations,Sponsors,Publications}.vue, components/oip-science/euct/{StudyDescription,Products,Investigators,Locations,Sponsors,Publications}.vue |
82
+ | E, onglets professionnel et établissement | pages/hcps/[id]/{informations,clinical-trials,appels-a-projet,pubmed,matched-labels}.vue, pages/establishments/[id]/{informations,clinical-trials,public-finance,hcps,matched-labels}.vue (et ce que leurs en-têtes components/hcps/HeaderComponent.vue, components/establishments/HeaderComponent.vue calculent pour eux) | components/oip-science/hcps/{Informations,ClinicalTrials,AppelsAProjet,Pubmed,MatchedLabels}.vue, components/oip-science/establishments/{Informations,ClinicalTrials,PublicFinance,Hcps,MatchedLabels}.vue |
83
+ | F, onglets investigateurs et centres | pages/{ctgov,euct}/investigators/[id]/{informations,clinical-trials,publications}.vue, pages/{ctgov,euct}/centers/[id]/{clinical-trials,publications}.vue ; composables useCTInvestigators, useEuctInvestigators, useCTCenter, useEuctCenter | components/oip-science/{ctgov-investigators,euct-investigators}/{Informations,ClinicalTrials,Publications}.vue, components/oip-science/{ctgov-centers,euct-centers}/{ClinicalTrials,Publications}.vue ; oip-science/composables/<même nom>.ts |
84
+
85
+ Un onglet porté depuis une page garde le contenu de la page ; ce que l'en-tête de FAS
86
+ calculait **pour la page** (document courant, état partagé) est relu par l'onglet.
87
+ Un fichier utile mais absent du tableau : le créer dans son propre lot sous un nom
88
+ préfixé par la lettre du lot (`oip-science/utils/d-<nom>.ts`) et le signaler.
89
+
90
+ ## Compte rendu attendu de chaque lot
91
+
92
+ Fichiers créés, écarts de rendu volontaires (export de carte retiré…), clés i18n
93
+ manquantes, dépendances vers d'autres lots, et tout ce qui n'a pas pu être porté.