@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,182 @@
1
+ <!--
2
+ Fiche d'une indication de la liste en sus (LES), portee de la page
3
+ `hubr/heart/indication/[id]` de fr_drugs_app : historique d'inscription des
4
+ produits, et prix des marques quand l'index des prix en connait.
5
+
6
+ Montee par la page de fr_drugs_app et par le tiroir des projets. L'export et
7
+ le bouton Projet de la page passent par le slot `actions` ; le tiroir pose
8
+ son lien « Ouvrir dans... » sous le titre par le slot `title-link`.
9
+ -->
10
+ <template>
11
+ <div class="oip-drugs arg_page_layout">
12
+ <RmPageHeader
13
+ :have-return="haveReturn"
14
+ :eyebrow="t('oipDrugs.heart.indication.lesRef')"
15
+ :tabs="headerTabs"
16
+ :tabs-label="t('oipDrugs.heart.indication.lesRef')"
17
+ @tab="selectTab"
18
+ >
19
+ <template #title>
20
+ <span class="oip-drugs-fiche__title">{{ title }}</span>
21
+ <slot name="title-link" />
22
+ </template>
23
+ <!-- Les lignes de l'indication passent au slot : l'export et le bouton
24
+ Projet de la page de fr_drugs_app s'en servent. -->
25
+ <template v-if="$slots.actions" #actions>
26
+ <slot name="actions" :results="results" />
27
+ </template>
28
+ </RmPageHeader>
29
+
30
+ <div v-if="isLoading || !loaded" class="oip_row v-center centered stretch">
31
+ <RmLoadingState spinner />
32
+ </div>
33
+ <div v-else-if="!results?.length" class="oip_list full centered v-center">
34
+ <RmEmptyState :title="t('oipDrugs.heart.errors.results')" icon="Prohibit" />
35
+ </div>
36
+ <template v-else>
37
+ <div v-if="activeTab === 1" class="arg_page_layout">
38
+ <!-- Le corps est partage avec le tiroir LES de la fiche marque. -->
39
+ <OipDrugsHeartResultsLesIndicationDetail :code="code" :results="results" />
40
+ </div>
41
+ <div v-else-if="activeTab === 2" class="arg_page_layout">
42
+ <OipDrugsHeartResultsDetailsPrice :product="resultsQueryPrice" />
43
+ </div>
44
+ </template>
45
+ </div>
46
+ </template>
47
+
48
+ <script setup lang="ts">
49
+ import { ES_INDEX } from "../../../oip-drugs/esIndices";
50
+ import useOipDrugsElastic from "../../../oip-drugs/composables/useOipDrugsElastic";
51
+ import { useHeartLesIndicationLoader } from "../../../oip-drugs/composables/useHeartLesIndication";
52
+
53
+ // Le surlignage des pages d'indication (cf. TextHighlight) : fr_drugs_app le
54
+ // lisait dans la route.
55
+ provide("oipDrugsIndicationPage", true);
56
+ import { indexedTabs } from "../../../utils/headerTabs";
57
+
58
+ const props = withDefaults(
59
+ defineProps<{
60
+ /** Code de l'indication (CPEMB13, I000711...), l'id de la route de fr_drugs_app. */
61
+ code: string;
62
+ /** Onglet ouvert : "1" historique, "2" prix. */
63
+ tab?: string;
64
+ lang?: "fr" | "en";
65
+ highlight?: string[];
66
+ /** Fleche de retour du bandeau : la page la demande, pas le tiroir. */
67
+ haveReturn?: boolean;
68
+ }>(),
69
+ { tab: "1", lang: undefined, highlight: () => [], haveReturn: false },
70
+ );
71
+
72
+ const emit = defineEmits<{ "update:tab": [key: string] }>();
73
+
74
+ const { t } = useI18n();
75
+ const { queryCustomElastic } = useOipDrugsElastic();
76
+
77
+ const title = computed(() => `Indication ${props.code}`);
78
+
79
+ const activeTab = ref(Number(props.tab) || 1);
80
+ watch(
81
+ () => props.tab,
82
+ (value) => {
83
+ activeTab.value = Number(value) || 1;
84
+ },
85
+ );
86
+
87
+ function selectTab(key: string) {
88
+ activeTab.value = Number(key);
89
+ emit("update:tab", key);
90
+ }
91
+
92
+ const { results, isLoading, load } = useHeartLesIndicationLoader();
93
+
94
+ const resultsQueryPrice = ref<any[]>([]);
95
+ const isLoadingQueryPrice = ref(false);
96
+
97
+ const headerTabs = computed(() =>
98
+ indexedTabs(
99
+ resultsQueryPrice.value.length > 0
100
+ ? [t("oipDrugs.heart.indication.history"), t("oipDrugs.heart.indication.prices")]
101
+ : [t("oipDrugs.heart.indication.history")],
102
+ activeTab.value,
103
+ ),
104
+ );
105
+
106
+ // Marques dedoublonnees et sans trou : une ref imbriquee dans un ref partait
107
+ // telle quelle dans la requete.
108
+ const brands = computed(() =>
109
+ [...new Set((results.value ?? []).map((x: any) => x?.brand).filter(Boolean))],
110
+ );
111
+
112
+ const customQueryPrices = computed(() => ({
113
+ from: 0,
114
+ _source: [],
115
+ query: {
116
+ bool: {
117
+ must: [{ terms: { "brand.keyword": brands.value } }],
118
+ },
119
+ },
120
+ size: 100,
121
+ track_total_hits: true,
122
+ }));
123
+
124
+ // Pour eviter les bugs lors de la navigation
125
+ const isMounted = ref(true);
126
+
127
+ const launchQueryPrices = async () => {
128
+ if (!isMounted.value) return;
129
+ resultsQueryPrice.value = [];
130
+ if (!brands.value.length) return;
131
+
132
+ isLoadingQueryPrice.value = true;
133
+ await queryCustomElastic({
134
+ index: ES_INDEX.DRUG_CARDS,
135
+ customQuery: customQueryPrices.value,
136
+ })
137
+ .then((res) => {
138
+ if (res && res.results && res.results.length > 0 && isMounted.value) {
139
+ resultsQueryPrice.value = res.results;
140
+ }
141
+ if (isMounted.value) {
142
+ isLoadingQueryPrice.value = false;
143
+ }
144
+ })
145
+ .catch((error) => {
146
+ console.error("Error fetching prices:", error);
147
+ if (isMounted.value) {
148
+ isLoadingQueryPrice.value = false;
149
+ }
150
+ });
151
+ };
152
+
153
+ const loaded = ref(false);
154
+
155
+ async function loadAll() {
156
+ await load(props.code);
157
+ loaded.value = true;
158
+ await launchQueryPrices();
159
+ }
160
+
161
+ watch(
162
+ () => props.code,
163
+ () => {
164
+ loadAll();
165
+ },
166
+ );
167
+
168
+ onMounted(async () => {
169
+ isMounted.value = true;
170
+ await loadAll();
171
+ });
172
+
173
+ onBeforeUnmount(() => {
174
+ isMounted.value = false;
175
+ });
176
+ </script>
177
+
178
+ <style scoped>
179
+ .oip-drugs-fiche__title {
180
+ display: block;
181
+ }
182
+ </style>
@@ -0,0 +1,101 @@
1
+ <!--
2
+ Fiche d'une presentation (CIP/UCD) au Journal Officiel, portee de la page
3
+ `hubr/heart/prices/jo/[id]` de fr_drugs_app : la carte JO, historique
4
+ complet des publications.
5
+
6
+ Montee par la page de fr_drugs_app et par le tiroir des projets. L'export de
7
+ la page passe par le slot `actions` ; le tiroir pose son lien « Ouvrir
8
+ dans... » sous le titre par le slot `title-link`.
9
+ -->
10
+ <template>
11
+ <div class="oip-drugs arg_page_layout">
12
+ <RmPageHeader :have-return="haveReturn" :eyebrow="t('oipDrugs.heart.joFeed.title')">
13
+ <template #title>
14
+ <span class="oip-drugs-fiche__title">{{ id }}</span>
15
+ <slot name="title-link" />
16
+ </template>
17
+ <template v-if="$slots.actions" #actions>
18
+ <slot name="actions" />
19
+ </template>
20
+ </RmPageHeader>
21
+ <div class="arg_page_content">
22
+ <div class="oip_row v-center centered stretch" v-if="isLoadingQuery">
23
+ <RmLoadingState spinner />
24
+ </div>
25
+ <OipDrugsHeartJoCard
26
+ v-else-if="resultsQuery !== null"
27
+ in-details
28
+ :product="resultsQuery"
29
+ />
30
+ <div v-else class="oip_list full centered v-center">
31
+ <RmEmptyState :title="t('oipDrugs.heart.errors.results')" icon="Prohibit" />
32
+ </div>
33
+ </div>
34
+ </div>
35
+ </template>
36
+
37
+ <script setup lang="ts">
38
+ import { ES_INDEX } from "../../../oip-drugs/esIndices";
39
+ import useOipDrugsElastic from "../../../oip-drugs/composables/useOipDrugsElastic";
40
+
41
+ const props = withDefaults(
42
+ defineProps<{
43
+ /** `local_drug_id` de la presentation (CIP/UCD), l'id de la route de fr_drugs_app. */
44
+ id: string;
45
+ lang?: "fr" | "en";
46
+ highlight?: string[];
47
+ /** Fleche de retour du bandeau : la page la demande, pas le tiroir. */
48
+ haveReturn?: boolean;
49
+ }>(),
50
+ { lang: undefined, highlight: () => [], haveReturn: false },
51
+ );
52
+
53
+ const { t } = useI18n();
54
+
55
+ const resultsQuery = ref(null as any);
56
+ const isLoadingQuery = ref(true);
57
+ const { queryCustomElastic } = useOipDrugsElastic();
58
+
59
+ // QUERY
60
+ const lanchQuery = async () => {
61
+ isLoadingQuery.value = true;
62
+ resultsQuery.value = null;
63
+ // Meme requete que queryOneElastic, reponse entiere : la carte range le
64
+ // produit par son `_id` (bouton « Projet »), que queryOneElastic ne rend pas.
65
+ await queryCustomElastic({
66
+ index: ES_INDEX.DRUG_CARDS_PRICE_JO,
67
+ customQuery: {
68
+ from: 0,
69
+ _source: [],
70
+ query: { bool: { must: [{ match: { local_drug_id: props.id } }] } },
71
+ size: 1,
72
+ track_total_hits: true,
73
+ },
74
+ allAnswer: true,
75
+ }).then((res) => {
76
+ const hit = res?.hits?.hits?.[0];
77
+ if (hit) {
78
+ resultsQuery.value = { ...hit._source, _id: hit._id };
79
+ }
80
+ isLoadingQuery.value = false;
81
+ });
82
+ };
83
+
84
+ watch(() => props.id, () => {
85
+ lanchQuery();
86
+ });
87
+
88
+ onMounted(async () => {
89
+ await lanchQuery();
90
+ });
91
+
92
+ // La page de fr_drugs_app declare l'export du cadre depuis son script : elle
93
+ // relit ici la presentation chargee plutot que de la redemander.
94
+ defineExpose({ product: resultsQuery });
95
+ </script>
96
+
97
+ <style scoped>
98
+ .oip-drugs-fiche__title {
99
+ display: block;
100
+ }
101
+ </style>
@@ -0,0 +1,279 @@
1
+ <!--
2
+ Fiche d'un protocole national de diagnostic et de soins (PNDS), portee de la
3
+ page `hubr/heart/pnds/[id]` de fr_drugs_app : description, maladies rares,
4
+ documents Tekkare et HAS.
5
+
6
+ Montee par la page de fr_drugs_app et par le tiroir des projets. Le bouton
7
+ Projet de la page passe par le slot `actions` ; le tiroir pose son lien
8
+ « Ouvrir dans... » sous le titre par le slot `title-link`.
9
+ -->
10
+ <template>
11
+ <div class="oip-drugs arg_page_layout">
12
+ <RmPageHeader :have-return="haveReturn" :eyebrow="t('oipDrugs.heart.pnds.titleShort')">
13
+ <template #title>
14
+ <span class="oip-drugs-fiche__title">{{ title }}</span>
15
+ <slot name="title-link" />
16
+ </template>
17
+ <!-- Le document et son titre passent au slot : le bouton Projet de la
18
+ page de fr_drugs_app ne s'affiche qu'une fois le protocole charge. -->
19
+ <template v-if="$slots.actions" #actions>
20
+ <slot
21
+ name="actions"
22
+ :doc="resultPage?.results?.[0]?._source ?? null"
23
+ :title="title"
24
+ />
25
+ </template>
26
+ <p class="oip_filter_label" v-if="resultPage?.results?.[0]?._source?.protocol_date">
27
+ {{ heartFormatDate(resultPage.results[0]._source.protocol_date) }}
28
+ </p>
29
+ </RmPageHeader>
30
+
31
+ <div v-if="isLoadingQuery" class="oip_row v-center centered stretch">
32
+ <RmLoadingState spinner />
33
+ </div>
34
+
35
+ <div v-else-if="resultPage?.results?.[0]" class="oip_list gap-12 full">
36
+ <OipDrugsHeartElasticSourceContainerElastic
37
+ :uuid="HEART_SOURCE_UUIDS.PNDS"
38
+ :last-label="t('oipDrugs.heart.sources.lastProtocol')"
39
+ :last-date="source?.protocol_date"
40
+ />
41
+
42
+ <!-- Tags -->
43
+ <div class="oip_row gap-8 wrap ml-24" v-if="source.theme_fr || source.publication_type_fr">
44
+ <RmTag v-for="(th, i) in detailThemes" :key="'th-' + i" variant="blue">{{ th }}</RmTag>
45
+ <RmTag v-if="locale === 'fr' ? source.publication_type_fr : source.publication_type_en" variant="amber">
46
+ {{ locale === 'fr' ? source.publication_type_fr : source.publication_type_en }}
47
+ </RmTag>
48
+ </div>
49
+
50
+ <!-- Description -->
51
+ <div class="oip_card oip_list gap-24 oip_body full ml-24">
52
+ <p class="oip_heading">{{ t('oipDrugs.heart.pnds.detailsPage.description') }}</p>
53
+ <p>{{ locale === 'fr'
54
+ ? source.protocol_description_fr
55
+ : source.protocol_description_en }}
56
+ </p>
57
+ <!-- Maladies Rares -->
58
+ <div v-if="rareDiseaseTags.length > 0" class="indic_category_row" style="margin-top: 12px">
59
+ <div class="indic_category_label">
60
+ <RmIcon name="Virus" :size="16" color="#4A4A4A" />
61
+ <p class="oip_filter_label">
62
+ {{ t('oipDrugs.heart.filters.rare') }}
63
+ </p>
64
+ </div>
65
+ <div class="indic_tags_wrap">
66
+ <RmTag variant="gray" v-for="(rd, i) in rareDiseaseTags" :key="'rd-' + i">{{ rd }}</RmTag>
67
+ </div>
68
+ </div>
69
+ </div>
70
+
71
+ <!-- Documents Tekkare -->
72
+ <div v-if="tekkareLinks.length > 0" class="oip_card oip_list gap-16 oip_body full ml-24">
73
+ <div class="oip_list gap-4">
74
+ <p class="oip_heading">{{ t('oipDrugs.heart.pnds.detailsPage.documentsTekkare') }}</p>
75
+ <p class="pnds_doc_info">{{ t('oipDrugs.heart.pnds.detailsPage.documentsTekkareInfo') }}</p>
76
+ </div>
77
+ <div class="oip_list gap-12">
78
+ <div v-for="(link, index) in tekkareLinks" :key="'tk-' + index" class="oip_row gap-8 v-center">
79
+ <RmButton
80
+ prefix-icon="DownloadSimple"
81
+ variant="secondary"
82
+ @click="openPdf(link)"
83
+ >
84
+ {{ t('oipDrugs.heart.pnds.detailsPage.downloadPdf') }} - {{ getFileName(link) }}
85
+ </RmButton>
86
+ </div>
87
+ </div>
88
+ </div>
89
+
90
+ <!-- Documents HAS -->
91
+ <div v-if="hasLinks.length > 0" class="oip_card oip_list gap-16 oip_body full ml-24">
92
+ <p class="oip_heading">{{ t('oipDrugs.heart.pnds.detailsPage.documentsHas') }}</p>
93
+ <div class="oip_list gap-12">
94
+ <div v-for="(link, index) in hasLinks" :key="'has-' + index" class="oip_row gap-8 v-center">
95
+ <RmButton
96
+ prefix-icon="ArrowSquareOut"
97
+ variant="secondary"
98
+ @click="openPdf(link)"
99
+ >
100
+ {{ t('oipDrugs.heart.pnds.detailsPage.downloadPdf') }} - {{ getFileName(link) }}
101
+ </RmButton>
102
+ </div>
103
+ </div>
104
+ </div>
105
+
106
+ <!-- Aucun document -->
107
+ <div v-if="tekkareLinks.length === 0 && hasLinks.length === 0" class="oip_card oip_list gap-24 oip_body full ml-24">
108
+ <p class="oip_heading">{{ t('oipDrugs.heart.pnds.detailsPage.documents') }}</p>
109
+ <div class="oip_list full centered v-center">
110
+ <RmEmptyState :title="t('oipDrugs.heart.pnds.detailsPage.noDocuments')" icon="Prohibit" />
111
+ </div>
112
+ </div>
113
+
114
+ <!-- Lien HAS -->
115
+ <div class="oip_card oip_list gap-24 oip_body full ml-24" v-if="source.has_url">
116
+ <a
117
+ :href="source.has_url"
118
+ target="_blank"
119
+ class="oip_row gap-8 v-center has-link"
120
+ >
121
+ <RmButton prefix-icon="ArrowSquareOut" variant="primary">
122
+ {{ t('oipDrugs.heart.pnds.detailsPage.hasLink') }}
123
+ </RmButton>
124
+ </a>
125
+ </div>
126
+ </div>
127
+
128
+ <div v-else class="oip_list full centered v-center">
129
+ <RmEmptyState :title="t('oipDrugs.heart.errors.results')" icon="Prohibit" />
130
+ </div>
131
+ </div>
132
+ </template>
133
+
134
+ <script lang="ts" setup>
135
+ import { ES_INDEX } from "../../../oip-drugs/esIndices";
136
+ import useOipDrugsElastic from "../../../oip-drugs/composables/useOipDrugsElastic";
137
+ import { HEART_SOURCE_UUIDS } from "../../../oip-drugs/utils/sourceUuids";
138
+ import { heartFormatDate } from "../../../oip-drugs/utils/heartStyleAndFormat";
139
+
140
+ const props = withDefaults(
141
+ defineProps<{
142
+ /** `_id` du protocole dans l'index PNDS, l'id de la route de fr_drugs_app. */
143
+ id: string;
144
+ lang?: "fr" | "en";
145
+ highlight?: string[];
146
+ /** Fleche de retour du bandeau : la page la demande, pas le tiroir. */
147
+ haveReturn?: boolean;
148
+ }>(),
149
+ { lang: undefined, highlight: () => [], haveReturn: false },
150
+ );
151
+
152
+ const { t, locale: i18nLocale } = useI18n();
153
+ /** Langue des champs du document : celle passee par l'hote, sinon celle de l'app. */
154
+ const locale = computed(() => props.lang ?? (i18nLocale.value === "en" ? "en" : "fr"));
155
+
156
+ const isLoadingQuery = ref(true);
157
+ const keyName = "pndsDetails";
158
+ const { queryElastic, lists } = useOipDrugsElastic();
159
+
160
+ const resultPage = computed(() => lists[keyName] ?? null);
161
+
162
+ const source = computed<any>(() => {
163
+ return resultPage.value?.results?.[0]?._source ?? {};
164
+ });
165
+
166
+ const title = computed(() =>
167
+ (locale.value === "fr" ? source.value.pathology_fr : source.value.pathology_en)
168
+ || t("oipDrugs.heart.pnds.detailsPage.title"),
169
+ );
170
+
171
+ const detailThemes = computed(() => {
172
+ const val = locale.value === 'fr' ? source.value.theme_fr : source.value.theme_en;
173
+ if (Array.isArray(val)) return val.filter(Boolean);
174
+ if (val) return [val];
175
+ return [];
176
+ });
177
+
178
+ const rareDiseaseTags = computed(() => {
179
+ const src = locale.value === 'fr'
180
+ ? source.value.rare_diseases_fr
181
+ : source.value.rare_diseases_en;
182
+ if (!Array.isArray(src)) return [];
183
+ return src.map((d: any) => d.concat_disease_name_orpha_code).filter(Boolean);
184
+ });
185
+
186
+ const tekkareLinks = computed(() => {
187
+ if (!source.value) return [];
188
+ return (source.value.tekkare_pdf_links || []).filter(Boolean);
189
+ });
190
+
191
+ const hasLinks = computed(() => {
192
+ if (!source.value) return [];
193
+ return (source.value.has_pdf_links || []).filter(Boolean);
194
+ });
195
+
196
+ function openPdf(url: string) {
197
+ if (url) window.open(url, '_blank');
198
+ }
199
+
200
+ function getFileName(url: string) {
201
+ if (!url) return '';
202
+ const parts = url.split('/');
203
+ const fileName = parts[parts.length - 1];
204
+ return decodeURIComponent(fileName ?? "").replace('.pdf', '').replace(/_/g, ' ');
205
+ }
206
+
207
+ const launchQuery = async () => {
208
+ isLoadingQuery.value = true;
209
+ // Sans remise a zero, le document precedent s'affiche le temps de la reponse.
210
+ delete lists[keyName];
211
+ await queryElastic({
212
+ index: ES_INDEX.PNDS,
213
+ // queryElastic attend `{ values }` : un nombre nu retombe sur size 10.
214
+ take: { values: 1 },
215
+ customQuery: [{
216
+ filter: 'id',
217
+ values: {
218
+ term: {
219
+ _id: props.id
220
+ }
221
+ }
222
+ }],
223
+ keyName,
224
+ });
225
+ isLoadingQuery.value = false;
226
+ };
227
+
228
+ watch(() => props.id, () => {
229
+ launchQuery();
230
+ });
231
+
232
+ onBeforeMount(async () => {
233
+ await launchQuery();
234
+ });
235
+ </script>
236
+
237
+ <style scoped>
238
+ .oip-drugs-fiche__title {
239
+ display: block;
240
+ }
241
+
242
+ .ml-24 {
243
+ margin-left: 24px;
244
+ }
245
+
246
+ .has-link {
247
+ text-decoration: none;
248
+ }
249
+
250
+ .pnds_doc_info {
251
+ font-size: 13px;
252
+ color: var(--dark, #6c6c8a);
253
+ font-weight: 500;
254
+ }
255
+
256
+ .indic_category_row {
257
+ display: flex;
258
+ flex-direction: row;
259
+ align-items: flex-start;
260
+ gap: 12px;
261
+ }
262
+
263
+ .indic_category_label {
264
+ display: flex;
265
+ align-items: center;
266
+ gap: 6px;
267
+ min-width: 160px;
268
+ white-space: nowrap;
269
+ padding-top: 4px;
270
+ }
271
+
272
+ .indic_tags_wrap {
273
+ display: flex;
274
+ flex-wrap: wrap;
275
+ gap: 4px;
276
+ flex: 1;
277
+ min-width: 0;
278
+ }
279
+ </style>