@tekkare/romulus 0.1.251 → 0.1.253

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 (267) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/runtime/utils/projects.d.ts +8 -0
  3. package/dist/runtime/utils/projects.js +8 -5
  4. package/layer/app/app.config.ts +6 -0
  5. package/layer/app/components/OipPubmedSummary.vue +223 -0
  6. package/layer/app/components/OipResourceDrawer.vue +331 -0
  7. package/layer/app/components/OipResourceDrawerLink.vue +40 -0
  8. package/layer/app/components/OipResourceField.vue +41 -0
  9. package/layer/app/components/OipResourceGenericCard.vue +54 -0
  10. package/layer/app/components/OipResourceSource.vue +50 -0
  11. package/layer/app/components/OipResourceTags.vue +65 -0
  12. package/layer/app/components/OipResourceView.vue +107 -0
  13. package/layer/app/components/oip-drugs/fiches/AssociationFiche.vue +775 -0
  14. package/layer/app/components/oip-drugs/fiches/BrandFiche.vue +1111 -0
  15. package/layer/app/components/oip-drugs/fiches/IndicationFiche.vue +182 -0
  16. package/layer/app/components/oip-drugs/fiches/JoFiche.vue +101 -0
  17. package/layer/app/components/oip-drugs/fiches/PndsFiche.vue +279 -0
  18. package/layer/app/components/oip-drugs/heart/JoCard.vue +314 -0
  19. package/layer/app/components/oip-drugs/heart/TextHighlight.vue +326 -0
  20. package/layer/app/components/oip-drugs/heart/ansm/BrandCard.vue +187 -0
  21. package/layer/app/components/oip-drugs/heart/ansm/CisDetail.vue +363 -0
  22. package/layer/app/components/oip-drugs/heart/ansm/CisTable.vue +167 -0
  23. package/layer/app/components/oip-drugs/heart/associations/NationalAssemblyCard.vue +373 -0
  24. package/layer/app/components/oip-drugs/heart/associations/NationalAssemblyFiche.vue +372 -0
  25. package/layer/app/components/oip-drugs/heart/associations/TranscriptionCard.vue +55 -0
  26. package/layer/app/components/oip-drugs/heart/elastic/SourceContainerElastic.vue +103 -0
  27. package/layer/app/components/oip-drugs/heart/france/BrandGroupCard.vue +450 -0
  28. package/layer/app/components/oip-drugs/heart/mitm/Card.vue +199 -0
  29. package/layer/app/components/oip-drugs/heart/mitm/Source.vue +23 -0
  30. package/layer/app/components/oip-drugs/heart/mitm/details/Overview.vue +381 -0
  31. package/layer/app/components/oip-drugs/heart/put/Card.vue +212 -0
  32. package/layer/app/components/oip-drugs/heart/results/AccesCard.vue +696 -0
  33. package/layer/app/components/oip-drugs/heart/results/AlertCard.vue +342 -0
  34. package/layer/app/components/oip-drugs/heart/results/AsmrCursor.vue +229 -0
  35. package/layer/app/components/oip-drugs/heart/results/EvalCard.vue +370 -0
  36. package/layer/app/components/oip-drugs/heart/results/IndicCard.vue +743 -0
  37. package/layer/app/components/oip-drugs/heart/results/MatchExplain.vue +243 -0
  38. package/layer/app/components/oip-drugs/heart/results/PrefRows.vue +105 -0
  39. package/layer/app/components/oip-drugs/heart/results/details/HasHistory.vue +487 -0
  40. package/layer/app/components/oip-drugs/heart/results/details/InternationalCountryCard.vue +461 -0
  41. package/layer/app/components/oip-drugs/heart/results/details/InternationalOverview.vue +200 -0
  42. package/layer/app/components/oip-drugs/heart/results/details/InternationalPriceDrawer.vue +647 -0
  43. package/layer/app/components/oip-drugs/heart/results/details/Monograph.vue +128 -0
  44. package/layer/app/components/oip-drugs/heart/results/details/OpinionDrawer.vue +535 -0
  45. package/layer/app/components/oip-drugs/heart/results/details/PresentationDrawer.vue +738 -0
  46. package/layer/app/components/oip-drugs/heart/results/details/Price.vue +227 -0
  47. package/layer/app/components/oip-drugs/heart/results/details/PriceOverview.vue +1261 -0
  48. package/layer/app/components/oip-drugs/heart/results/details/RecordDrawer.vue +494 -0
  49. package/layer/app/components/oip-drugs/heart/results/details/RecordList.vue +426 -0
  50. package/layer/app/components/oip-drugs/heart/results/les/Card.vue +340 -0
  51. package/layer/app/components/oip-drugs/heart/results/les/Drawer.vue +67 -0
  52. package/layer/app/components/oip-drugs/heart/results/les/IndicationDetail.vue +149 -0
  53. package/layer/app/components/oip-drugs/heart/results/les/Source.vue +20 -0
  54. package/layer/app/components/oip-drugs/heart/results/les/SourceTag.vue +39 -0
  55. package/layer/app/components/oip-drugs/heart/searchPage/DynamicSource.vue +29 -0
  56. package/layer/app/components/oip-drugs/medicam/market/Chart.vue +121 -0
  57. package/layer/app/components/oip-drugs/outpatient/ProductEvolution.vue +236 -0
  58. package/layer/app/components/oip-drugs/resources/Ansm.vue +75 -0
  59. package/layer/app/components/oip-drugs/resources/Association.vue +30 -0
  60. package/layer/app/components/oip-drugs/resources/Brand.vue +65 -0
  61. package/layer/app/components/oip-drugs/resources/Contribution.vue +216 -0
  62. package/layer/app/components/oip-drugs/resources/Hospital.vue +151 -0
  63. package/layer/app/components/oip-drugs/resources/Indication.vue +54 -0
  64. package/layer/app/components/oip-drugs/resources/Jo.vue +57 -0
  65. package/layer/app/components/oip-drugs/resources/Medicam.vue +140 -0
  66. package/layer/app/components/oip-drugs/resources/Mitm.vue +84 -0
  67. package/layer/app/components/oip-drugs/resources/NationalAssembly.vue +93 -0
  68. package/layer/app/components/oip-drugs/resources/Outpatient.vue +97 -0
  69. package/layer/app/components/oip-drugs/resources/Pnds.vue +24 -0
  70. package/layer/app/components/oip-drugs/resources/Price.vue +106 -0
  71. package/layer/app/components/oip-drugs/resources/Put.vue +143 -0
  72. package/layer/app/components/oip-science/appel-a-projet/Cards.vue +162 -0
  73. package/layer/app/components/oip-science/clinical-trials/Cards.vue +382 -0
  74. package/layer/app/components/oip-science/clinical-trials/CardsGlobal.vue +273 -0
  75. package/layer/app/components/oip-science/clinical-trials/LinkedList.vue +366 -0
  76. package/layer/app/components/oip-science/clinical-trials/PairBadge.vue +25 -0
  77. package/layer/app/components/oip-science/clinical-trials/PairBody.vue +182 -0
  78. package/layer/app/components/oip-science/clinical-trials/SitesDrawer.vue +95 -0
  79. package/layer/app/components/oip-science/common/Form.vue +73 -0
  80. package/layer/app/components/oip-science/common/MatchAvgTag.vue +283 -0
  81. package/layer/app/components/oip-science/common/NoData.vue +16 -0
  82. package/layer/app/components/oip-science/common/ScoreBadge.vue +35 -0
  83. package/layer/app/components/oip-science/common/Source.vue +31 -0
  84. package/layer/app/components/oip-science/common/TableTags.vue +279 -0
  85. package/layer/app/components/oip-science/common/Timeline.vue +104 -0
  86. package/layer/app/components/oip-science/common/ToolTips.vue +89 -0
  87. package/layer/app/components/oip-science/cross/publicationPubmed.vue +484 -0
  88. package/layer/app/components/oip-science/crossData/CrossDataLocations.vue +71 -0
  89. package/layer/app/components/oip-science/ctgov/Investigators.vue +148 -0
  90. package/layer/app/components/oip-science/ctgov/Locations.vue +102 -0
  91. package/layer/app/components/oip-science/ctgov/Publications.vue +52 -0
  92. package/layer/app/components/oip-science/ctgov/Sponsors.vue +66 -0
  93. package/layer/app/components/oip-science/ctgov/StudyDescription.vue +1136 -0
  94. package/layer/app/components/oip-science/ctgov-centers/ClinicalTrials.vue +40 -0
  95. package/layer/app/components/oip-science/ctgov-centers/Publications.vue +50 -0
  96. package/layer/app/components/oip-science/ctgov-investigators/ClinicalTrials.vue +43 -0
  97. package/layer/app/components/oip-science/ctgov-investigators/Informations.vue +171 -0
  98. package/layer/app/components/oip-science/ctgov-investigators/Publications.vue +44 -0
  99. package/layer/app/components/oip-science/elastic/DateRangeFilter.vue +209 -0
  100. package/layer/app/components/oip-science/elastic/Filter.vue +719 -0
  101. package/layer/app/components/oip-science/elastic/MatchExplain.vue +152 -0
  102. package/layer/app/components/oip-science/establishments/Cards.vue +183 -0
  103. package/layer/app/components/oip-science/establishments/ClinicalTrials.vue +62 -0
  104. package/layer/app/components/oip-science/establishments/Hcps.vue +227 -0
  105. package/layer/app/components/oip-science/establishments/Informations.vue +263 -0
  106. package/layer/app/components/oip-science/establishments/LinkedList.vue +153 -0
  107. package/layer/app/components/oip-science/establishments/MatchedLabels.vue +194 -0
  108. package/layer/app/components/oip-science/establishments/PublicFinance.vue +62 -0
  109. package/layer/app/components/oip-science/euct/Investigators.vue +125 -0
  110. package/layer/app/components/oip-science/euct/Locations.vue +102 -0
  111. package/layer/app/components/oip-science/euct/Products.vue +101 -0
  112. package/layer/app/components/oip-science/euct/Publications.vue +89 -0
  113. package/layer/app/components/oip-science/euct/Sponsors.vue +86 -0
  114. package/layer/app/components/oip-science/euct/StudyDescription.vue +1075 -0
  115. package/layer/app/components/oip-science/euct-centers/ClinicalTrials.vue +40 -0
  116. package/layer/app/components/oip-science/euct-centers/Publications.vue +55 -0
  117. package/layer/app/components/oip-science/euct-investigators/ClinicalTrials.vue +41 -0
  118. package/layer/app/components/oip-science/euct-investigators/Informations.vue +171 -0
  119. package/layer/app/components/oip-science/euct-investigators/Publications.vue +51 -0
  120. package/layer/app/components/oip-science/hcps/AppelsAProjet.vue +62 -0
  121. package/layer/app/components/oip-science/hcps/Cards.vue +237 -0
  122. package/layer/app/components/oip-science/hcps/ClinicalTrials.vue +78 -0
  123. package/layer/app/components/oip-science/hcps/Informations.vue +296 -0
  124. package/layer/app/components/oip-science/hcps/LinkedList.vue +153 -0
  125. package/layer/app/components/oip-science/hcps/MatchedLabels.vue +207 -0
  126. package/layer/app/components/oip-science/hcps/Pubmed.vue +128 -0
  127. package/layer/app/components/oip-science/local/SliderTabs.vue +99 -0
  128. package/layer/app/components/oip-science/local/SliderTabsFull.vue +135 -0
  129. package/layer/app/components/oip-science/pubmed/Authors.vue +128 -0
  130. package/layer/app/components/oip-science/pubmed/Cards.vue +417 -0
  131. package/layer/app/components/oip-science/pubmed/ClinicalTrials.vue +71 -0
  132. package/layer/app/components/oip-science/resources/Phrc.vue +39 -0
  133. package/layer/app/composables/useOipChapterScroll.ts +43 -0
  134. package/layer/app/composables/useOipResourceHooks.ts +27 -0
  135. package/layer/app/composables/useOipResourceNav.ts +66 -0
  136. package/layer/app/composables/useOipResourceViews.ts +117 -0
  137. package/layer/app/composables/useOipResources.ts +83 -0
  138. package/layer/app/oip-drugs/PORTING.md +120 -0
  139. package/layer/app/oip-drugs/composables/useAssociationDetail.ts +220 -0
  140. package/layer/app/oip-drugs/composables/useAssociationExport.ts +63 -0
  141. package/layer/app/oip-drugs/composables/useAssociationLookup.ts +105 -0
  142. package/layer/app/oip-drugs/composables/useCardPrefOptions.ts +201 -0
  143. package/layer/app/oip-drugs/composables/useCurrency.ts +121 -0
  144. package/layer/app/oip-drugs/composables/useDirectusSources.ts +224 -0
  145. package/layer/app/oip-drugs/composables/useHeartBrandMatches.ts +112 -0
  146. package/layer/app/oip-drugs/composables/useHeartDetailSearches.ts +479 -0
  147. package/layer/app/oip-drugs/composables/useHeartIntlApprovals.ts +661 -0
  148. package/layer/app/oip-drugs/composables/useHeartLesIndication.ts +168 -0
  149. package/layer/app/oip-drugs/composables/useHeartMatchExplain.ts +231 -0
  150. package/layer/app/oip-drugs/composables/useHeartReports.ts +239 -0
  151. package/layer/app/oip-drugs/composables/useHeartSearchFields.ts +233 -0
  152. package/layer/app/oip-drugs/composables/useMergeByKey.ts +23 -0
  153. package/layer/app/oip-drugs/composables/useOipDrugsElastic.ts +621 -0
  154. package/layer/app/oip-drugs/composables/usePageEmpty.ts +58 -0
  155. package/layer/app/oip-drugs/composables/v-useSalesSource.ts +64 -0
  156. package/layer/app/oip-drugs/drugs.css +500 -0
  157. package/layer/app/oip-drugs/esIndices.ts +322 -0
  158. package/layer/app/oip-drugs/kinds.ts +264 -0
  159. package/layer/app/oip-drugs/locales/en.json +1571 -0
  160. package/layer/app/oip-drugs/locales/fr.json +1571 -0
  161. package/layer/app/oip-drugs/monographs/blincyto-has.vue +289 -0
  162. package/layer/app/oip-drugs/monographs/darzalex-has.vue +276 -0
  163. package/layer/app/oip-drugs/monographs/dupixent-has.vue +216 -0
  164. package/layer/app/oip-drugs/monographs/enhertu-has.vue +280 -0
  165. package/layer/app/oip-drugs/monographs/has-sein-2023.vue +1649 -0
  166. package/layer/app/oip-drugs/monographs/ibrance-has.vue +277 -0
  167. package/layer/app/oip-drugs/monographs/imfinzi-has.vue +293 -0
  168. package/layer/app/oip-drugs/monographs/keytruda-has.vue +334 -0
  169. package/layer/app/oip-drugs/monographs/kisqali-has.vue +201 -0
  170. package/layer/app/oip-drugs/monographs/opdivo-has.vue +231 -0
  171. package/layer/app/oip-drugs/monographs/ozempic-has.vue +186 -0
  172. package/layer/app/oip-drugs/monographs/tecentriq-has.vue +312 -0
  173. package/layer/app/oip-drugs/monographs/yescarta-has.vue +272 -0
  174. package/layer/app/oip-drugs/types/elastic.ts +113 -0
  175. package/layer/app/oip-drugs/types/es/agencies.ts +152 -0
  176. package/layer/app/oip-drugs/types/es/directory.ts +54 -0
  177. package/layer/app/oip-drugs/types/es/docByIndex.ts +151 -0
  178. package/layer/app/oip-drugs/types/es/openmedic.ts +67 -0
  179. package/layer/app/oip-drugs/types/es/outpatient.ts +71 -0
  180. package/layer/app/oip-drugs/types/es/portal.ts +130 -0
  181. package/layer/app/oip-drugs/types/es/retail.ts +107 -0
  182. package/layer/app/oip-drugs/types/es/statistics.ts +29 -0
  183. package/layer/app/oip-drugs/types/heart/CurrencyRate.ts +16 -0
  184. package/layer/app/oip-drugs/types/heart/ansm.ts +106 -0
  185. package/layer/app/oip-drugs/types/heart/tag.ts +29 -0
  186. package/layer/app/oip-drugs/utils/associationFields.ts +118 -0
  187. package/layer/app/oip-drugs/utils/contributions.ts +36 -0
  188. package/layer/app/oip-drugs/utils/countryMapping.ts +387 -0
  189. package/layer/app/oip-drugs/utils/esHighlight.ts +21 -0
  190. package/layer/app/oip-drugs/utils/exportSheets.ts +57 -0
  191. package/layer/app/oip-drugs/utils/heartIntlPrice.ts +228 -0
  192. package/layer/app/oip-drugs/utils/heartStyleAndFormat.ts +262 -0
  193. package/layer/app/oip-drugs/utils/heartStyleAnsm.ts +71 -0
  194. package/layer/app/oip-drugs/utils/latestDate.ts +31 -0
  195. package/layer/app/oip-drugs/utils/p-heartCardTags.ts +53 -0
  196. package/layer/app/oip-drugs/utils/priceExport.ts +269 -0
  197. package/layer/app/oip-drugs/utils/q-hasRatings.ts +43 -0
  198. package/layer/app/oip-drugs/utils/s-openCard.ts +20 -0
  199. package/layer/app/oip-drugs/utils/sourceUuids.ts +155 -0
  200. package/layer/app/oip-drugs/utils/styleAndFormat.ts +40 -0
  201. package/layer/app/oip-drugs/utils/v-salesSeries.ts +156 -0
  202. package/layer/app/oip-drugs/utils/v-scopeTags.ts +23 -0
  203. package/layer/app/oip-science/PORTING.md +93 -0
  204. package/layer/app/oip-science/assets/smartSelection.json +428 -0
  205. package/layer/app/oip-science/composables/useAuthorMatching.ts +342 -0
  206. package/layer/app/oip-science/composables/useCTCenter.ts +107 -0
  207. package/layer/app/oip-science/composables/useCTInvestigators.ts +107 -0
  208. package/layer/app/oip-science/composables/useEstablishmentCrossData.ts +139 -0
  209. package/layer/app/oip-science/composables/useEstablishmentMatching.ts +176 -0
  210. package/layer/app/oip-science/composables/useEuct.ts +418 -0
  211. package/layer/app/oip-science/composables/useEuctCenter.ts +107 -0
  212. package/layer/app/oip-science/composables/useEuctInvestigators.ts +107 -0
  213. package/layer/app/oip-science/composables/useGlobalClinicalTrials.ts +624 -0
  214. package/layer/app/oip-science/composables/useLinkedTrials.ts +83 -0
  215. package/layer/app/oip-science/composables/useOipElastic.ts +658 -0
  216. package/layer/app/oip-science/composables/useOipSearchExplain.ts +166 -0
  217. package/layer/app/oip-science/composables/usePubmed.ts +487 -0
  218. package/layer/app/oip-science/composables/useSearchFields.ts +153 -0
  219. package/layer/app/oip-science/indexConfig.json +794 -0
  220. package/layer/app/oip-science/locales/en.json +483 -0
  221. package/layer/app/oip-science/locales/fr.json +483 -0
  222. package/layer/app/oip-science/science.css +1182 -0
  223. package/layer/app/oip-science/utils/a-openCard.ts +23 -0
  224. package/layer/app/oip-science/utils/b-openCard.ts +35 -0
  225. package/layer/app/oip-science/utils/c-filterContext.ts +81 -0
  226. package/layer/app/oip-science/utils/f-types.ts +241 -0
  227. package/layer/app/oip-science/utils/frDiseaseTerms.ts +269 -0
  228. package/layer/app/oip-science/utils/matchMethod.ts +53 -0
  229. package/layer/app/oip-science/utils/sliderTabs.ts +13 -0
  230. package/layer/app/oip-science/utils/sources.ts +15 -0
  231. package/layer/app/oip-science/utils/styleAndFormat.ts +608 -0
  232. package/layer/app/oip-science/utils/toPresets.ts +7 -0
  233. package/layer/app/oip-science/utils/valueTable.ts +126 -0
  234. package/layer/app/plugins/oip-science-i18n.ts +17 -0
  235. package/layer/app/utils/oipFicheRoutes.ts +118 -0
  236. package/layer/app/utils/oipResources.ts +440 -0
  237. package/layer/nuxt.config.ts +22 -2
  238. package/layer/public/reports/blincyto-has.html +292 -0
  239. package/layer/public/reports/blincyto-has.pdf +0 -0
  240. package/layer/public/reports/darzalex-has.html +279 -0
  241. package/layer/public/reports/darzalex-has.pdf +0 -0
  242. package/layer/public/reports/dupixent-has.html +217 -0
  243. package/layer/public/reports/dupixent-has.pdf +0 -0
  244. package/layer/public/reports/enhertu-has.html +283 -0
  245. package/layer/public/reports/enhertu-has.pdf +0 -0
  246. package/layer/public/reports/has-sein-2023.html +1639 -0
  247. package/layer/public/reports/ibrance-has.html +280 -0
  248. package/layer/public/reports/ibrance-has.pdf +0 -0
  249. package/layer/public/reports/imfinzi-has.html +297 -0
  250. package/layer/public/reports/imfinzi-has.pdf +0 -0
  251. package/layer/public/reports/keytruda-has.html +337 -0
  252. package/layer/public/reports/keytruda-has.pdf +0 -0
  253. package/layer/public/reports/kisqali-has.html +202 -0
  254. package/layer/public/reports/kisqali-has.pdf +0 -0
  255. package/layer/public/reports/opdivo-has.html +232 -0
  256. package/layer/public/reports/opdivo-has.pdf +0 -0
  257. package/layer/public/reports/ozempic-has.html +188 -0
  258. package/layer/public/reports/ozempic-has.pdf +0 -0
  259. package/layer/public/reports/tecentriq-has.html +315 -0
  260. package/layer/public/reports/tecentriq-has.pdf +0 -0
  261. package/layer/public/reports/yescarta-has.html +275 -0
  262. package/layer/public/reports/yescarta-has.pdf +0 -0
  263. package/layer/server/api/oip/es.post.ts +99 -0
  264. package/layer/server/api/oip/pdf.get.ts +70 -0
  265. package/layer/server/api/oip/reports.get.ts +98 -0
  266. package/layer/server/api/oip/resource-types.get.ts +22 -0
  267. package/package.json +1 -1
@@ -0,0 +1,187 @@
1
+ <template>
2
+ <RmSectionCard class="oip-drugs rcard" :class="{ 'rcard--dense': dense }" @click="openDrugsCard(nav, $event, brandDetailPath)" :position="'top'">
3
+ <template #header>
4
+ <div class="oip_row v-center justify-between full_flex" style="width: 100%">
5
+ <div class="oip_list gap-4">
6
+ <h3 class="card_title">
7
+ <OipDrugsHeartTextHighlight :text="brand.brand || brand.cis_label" :queries="storeSearchBar" />
8
+ </h3>
9
+ <p class="card_context">
10
+ <OipDrugsHeartTextHighlight :text="cardContext" :queries="storeSearchBar" />
11
+ </p>
12
+ </div>
13
+ <div class="oip_row v-center gap-8" style="margin-left: auto">
14
+ <!-- La carte porte une marque et ses presentations (CIS) : ce sont
15
+ ces documents qui partent dans le projet. -->
16
+ <!-- Emplacement libre pour un appelant (la fiche projet y pose son
17
+ bouton « Commenter ») avant le bouton projet. -->
18
+ <slot name="hubr-actions" />
19
+ <component
20
+ :is="projectButton"
21
+ v-if="projectButton"
22
+ :resource-id="cisIds"
23
+ type="FrAnsmProduct"
24
+ :label="brand.brand || brand.cis_label"
25
+ compact
26
+ />
27
+ <RmCardActions
28
+ :lang="locale === 'fr' ? 'fr' : 'en'"
29
+ :name="`ANSM - ${brand.brand || brand.cis_label}`"
30
+ :link="brandDetailHref"
31
+ :payload="exportPayload"
32
+ :visual="false"
33
+ />
34
+ </div>
35
+ </div>
36
+ </template>
37
+
38
+ <OipDrugsHeartAnsmCisTable
39
+ v-if="!dense"
40
+ class="card_body"
41
+ :brand-name="brand.brand || brand.cis_label"
42
+ :cis-hits="cisHits"
43
+ :store-search-bar="storeSearchBar"
44
+ :prefs="prefs"
45
+ />
46
+ <div v-if="!dense" class="rcard_footer">
47
+ <OipDrugsHeartElasticSourceContainerElastic
48
+ :uuid="HEART_SOURCE_UUIDS.ANSM"
49
+ :last-label="t('oipDrugs.heart.sources.lastAuthorization')"
50
+ :last-date="lastAuthorizationDates"
51
+ />
52
+ </div>
53
+ </RmSectionCard>
54
+ </template>
55
+
56
+ <script lang="ts" setup>
57
+ import { HEART_SOURCE_UUIDS } from '../../../../oip-drugs/utils/sourceUuids';
58
+ import { drugsBrandPath } from "../../../../oip-drugs/kinds";
59
+ import { openDrugsCard } from "../../../../oip-drugs/utils/s-openCard";
60
+ // ========================
61
+ // IMPORTS
62
+ // ========================
63
+ import type { OneAnsmResult } from "../../../../oip-drugs/types/heart/ansm";
64
+
65
+ // ========================
66
+ // COMPOSABLES
67
+ // ========================
68
+ const { t, locale } = useI18n();
69
+ const nav = useOipResourceNav();
70
+ const { projectButton } = useOipResourceHooks();
71
+
72
+ // ========================
73
+ // PROPS
74
+ // ========================
75
+ const props = defineProps<{
76
+ brand: OneAnsmResult;
77
+ cisHits: Array<{ _id: string; _source: OneAnsmResult }>;
78
+ storeSearchBar: string[];
79
+ /** Rendu serre de la fiche projet : l'en-tete seul, sans le tableau. */
80
+ dense?: boolean;
81
+ /** Colonnes facultatives du tableau des CIS (ex-cardPrefs, cle « ansm »). */
82
+ prefs?: Record<string, boolean>;
83
+ }>();
84
+
85
+ // ========================
86
+ // COMPUTED
87
+ // ========================
88
+ /** Les documents de la carte : une presentation (CIS) par hit. */
89
+ const cisIds = computed(() => props.cisHits.map((hit) => hit._id).filter(Boolean));
90
+
91
+ /**
92
+ * L'AMM la plus recente des presentations de la marque : c'est le dernier
93
+ * mouvement que l'index ANSM date. Les dates de commercialisation des
94
+ * presentations comptent aussi, une marque autorisee de longue date pouvant
95
+ * n'etre commercialisee que depuis peu.
96
+ */
97
+ const lastAuthorizationDates = computed(() =>
98
+ props.cisHits.flatMap((hit) => [
99
+ (hit._source as any)?.authorization_date,
100
+ ...(((hit._source as any)?.drug ?? []) as any[]).map((d: any) => d?.commercialization_date),
101
+ ]),
102
+ );
103
+
104
+ const cardContext = computed(() => {
105
+ const b = props.brand;
106
+ return [b.atc5_french_code_label, b.atc4_french_code_label, b.owner]
107
+ .filter(Boolean)
108
+ .join(" · ");
109
+ });
110
+
111
+ // Fiche marque unifiee, ouverte sur l'onglet ANSM.
112
+ const brandDetailPath = computed(() => {
113
+ const path = drugsBrandPath(props.brand.brand);
114
+ return path ? `${path}?tab=ansm` : "";
115
+ });
116
+ const brandDetailHref = computed(() =>
117
+ brandDetailPath.value ? nav.appHref("fr_drugs_app", brandDetailPath.value) : undefined,
118
+ );
119
+
120
+ /**
121
+ * Onglet de la carte pour le menu : en fonction, la liste monte la carte
122
+ * vingt fois et le menu ne l'appelle qu'a l'export.
123
+ */
124
+ const exportPayload = () => ({
125
+ title: `ANSM - ${props.brand.brand || props.brand.cis_label}`,
126
+ subtitle: `🇫🇷 ANSM: ${props.brand.brand || props.brand.cis_label}`,
127
+ limit: 10000,
128
+ sheets: exportSheets(),
129
+ });
130
+
131
+ const exportSheets = () => [
132
+ {
133
+ name: "Spécialités",
134
+ data: props.cisHits.map((h) => h._source),
135
+ schema: [
136
+ { column: "Code CIS", type: String, value: (c: any) => c.cis_code, width: 15 },
137
+ { column: "Dénomination", type: String, value: (c: any) => c.cis_label, width: 60, wrap: true },
138
+ { column: "Date d'autorisation", type: String, value: (c: any) => c.authorization_date || "-", width: 20 },
139
+ { column: "État", type: String, value: (c: any) => c.amm_status, width: 25 },
140
+ { column: "Commercialisation", type: String, value: (c: any) => c.commercialization_status, width: 25 },
141
+ { column: "Laboratoire", type: String, value: (c: any) => c.owner, width: 30, wrap: true },
142
+ { column: "ATC5", type: String, value: (c: any) => c.atc5_french_code_label, width: 40, wrap: true },
143
+ ],
144
+ },
145
+ ];
146
+ </script>
147
+
148
+ <style scoped>
149
+ /* Rendu serre : RmSectionCard dessine son corps meme vide. */
150
+ .rcard--dense :deep(.rm-section-card__body) {
151
+ display: none;
152
+ }
153
+
154
+ .card_title {
155
+ font-weight: 900;
156
+ font-size: 20px;
157
+ color: var(--darkest);
158
+ font-family: Figtree, sans-serif !important;
159
+ }
160
+ .card_context {
161
+ font-size: 13px;
162
+ color: var(--dark);
163
+ }
164
+ /* Plus d'air autour du header de la card. */
165
+ :deep(.card_header) {
166
+ padding: 20px 24px;
167
+ }
168
+ /* Tableau a fleur des bords de la carte. La regle visait `.card_content`,
169
+ le corps des cartes Auriga : depuis le passage a `RmSectionCard` ce corps
170
+ s'appelle `rm-section-card__body` et le tableau se retrouvait a 24px des
171
+ deux bords, seul bloc de la carte a ne pas toucher le filet.
172
+
173
+ Marges negatives plutot que padding a zero sur le corps : le pied de
174
+ provenance sort deja par ce chemin (cf. `.rm-shell .rcard_footer` dans
175
+ assets/css/main.css) et garde ainsi son propre calage. Les 24px verticaux
176
+ restent, c'est l'air entre l'en-tete et la premiere ligne. */
177
+ .card_body {
178
+ /* `flex: none` : le corps de la carte est une rangee flex, elle retrecissait
179
+ le tableau elargi pour le faire rentrer et les 24px de droite revenaient. */
180
+ flex: none;
181
+ margin-inline: -24px;
182
+ width: calc(100% + 48px);
183
+ }
184
+ :deep(.flex-table) {
185
+ gap: 0;
186
+ }
187
+ </style>
@@ -0,0 +1,363 @@
1
+ <template>
2
+ <div class="oip-drugs oip_list gap-16 full">
3
+ <!-- Synthèse : badges + strip de stats -->
4
+ <div class="oip_card oip_list gap-16 oip_body full">
5
+ <div class="oip_list gap-4">
6
+ <h3 class="card_title">{{ cis.cis_label }}</h3>
7
+ <p class="oip_filter_label">{{ synthContext }}</p>
8
+ </div>
9
+ <div class="oip_row gap-8 wrap">
10
+ <RmTag :variant="heartGetStatusColor(cis.amm_status)">{{ cis.amm_status }}</RmTag>
11
+ <RmTag :variant="heartGetStatusColor(cis.commercialization_status)">{{ cis.commercialization_status }}</RmTag>
12
+ <RmTag v-if="cis.procedure_type" variant="default">{{ cis.procedure_type }}</RmTag>
13
+ </div>
14
+ <div class="statbar">
15
+ <div class="stat">
16
+ <span class="stat-num">{{ cis.cis_code }}</span>
17
+ <span class="stat-lbl">{{ t('oipDrugs.heart.ansm.card.codeCIS') }}</span>
18
+ </div>
19
+ <div class="stat">
20
+ <span class="stat-num">{{ skuCount ?? '-' }}</span>
21
+ <span class="stat-lbl">{{ t('oipDrugs.heart.ansm.detailsPage.skuOfBrand') }}</span>
22
+ </div>
23
+ <div class="stat">
24
+ <span class="stat-num">{{ avisCount ?? '-' }}</span>
25
+ <span class="stat-lbl">{{ t('oipDrugs.heart.ansm.detailsPage.avisHas') }}</span>
26
+ </div>
27
+ <div class="stat">
28
+ <span class="stat-num">{{ cis.drug?.length ?? 0 }}</span>
29
+ <span class="stat-lbl">{{ t('oipDrugs.heart.ansm.detailsPage.presentations') }}</span>
30
+ </div>
31
+ </div>
32
+ </div>
33
+
34
+ <!-- Composition en substances actives -->
35
+ <div class="oip_card oip_list gap-16 oip_body full">
36
+ <p class="oip_heading">{{ t('oipDrugs.heart.ansm.detailsPage.composition') }}</p>
37
+ <RmTable
38
+ v-if="compoContents.length"
39
+ class="card-table"
40
+ :columns="compoTable.columns"
41
+ :rows="compoTable.rows"
42
+ max-height="600px"
43
+ />
44
+ <div v-else class="oip_list full centered v-center">
45
+ <RmEmptyState :title="t('oipDrugs.heart.ansm.detailsPage.noData')" icon="Prohibit" />
46
+ </div>
47
+ </div>
48
+
49
+ <!-- Titulaire & données administratives -->
50
+ <div class="oip_card oip_list gap-16 oip_body full">
51
+ <p class="oip_heading">{{ t('oipDrugs.heart.ansm.card.administrativeData') }}</p>
52
+ <dl class="admin-grid">
53
+ <div class="col-span">
54
+ <dt>{{ t('oipDrugs.heart.ansm.card.laboratory') }}</dt>
55
+ <dd>
56
+ {{ cis.owner || '-' }}
57
+ <span v-if="ownerSince" class="admin-since">· {{ t('oipDrugs.heart.ansm.detailsPage.holderSince') }} {{ ownerSince }}</span>
58
+ </dd>
59
+ </div>
60
+ <div>
61
+ <dt>{{ t('oipDrugs.heart.ansm.brandCard.authorizationDate') }}</dt>
62
+ <dd>{{ heartFormatDate(cis.authorization_date) }}</dd>
63
+ </div>
64
+ <div>
65
+ <dt>{{ t('oipDrugs.heart.ansm.brandCard.status') }}</dt>
66
+ <dd><RmTag :variant="heartGetStatusColor(cis.amm_status)">{{ cis.amm_status }}</RmTag></dd>
67
+ </div>
68
+ <div>
69
+ <dt>{{ t('oipDrugs.heart.ansm.card.procedure') }}</dt>
70
+ <dd>{{ cis.procedure_type || '-' }}</dd>
71
+ </div>
72
+ <div>
73
+ <dt>{{ t('oipDrugs.heart.ansm.detailsPage.forme') }}</dt>
74
+ <dd>{{ heartFirstLetterUpperCase(cis.pharmaceutical_form) }}</dd>
75
+ </div>
76
+ <div>
77
+ <dt>{{ t('oipDrugs.heart.ansm.detailsPage.administrationMode') }}</dt>
78
+ <dd>{{ heartFormatAdministrations(cis.administration_mode) }}</dd>
79
+ </div>
80
+ <div>
81
+ <dt>{{ t('oipDrugs.heart.ansm.card.molecule') }}</dt>
82
+ <dd>{{ cis.atc5_french_code_label || '-' }}</dd>
83
+ </div>
84
+ <div class="col-span">
85
+ <dt>{{ t('oipDrugs.heart.ansm.card.genericGroup') }}</dt>
86
+ <dd>{{ cis.generic_group_label || t('oipDrugs.heart.ansm.card.noGenericGroup') }}</dd>
87
+ </div>
88
+ </dl>
89
+ </div>
90
+
91
+ <!-- Conditions de prescription et de délivrance -->
92
+ <div class="oip_card oip_list gap-16 oip_body full">
93
+ <p class="oip_heading">{{ t('oipDrugs.heart.ansm.detailsPage.prescription') }}</p>
94
+ <div v-if="cpdGroups.length" class="cpd-groups">
95
+ <div v-for="g in cpdGroups" :key="g.label" class="cpd-group">
96
+ <p class="cpd-group-title">{{ g.label }}</p>
97
+ <ul class="cpd-glist">
98
+ <li v-for="(c, i) in g.items" :key="i">{{ c }}</li>
99
+ </ul>
100
+ </div>
101
+ </div>
102
+ <div v-else class="oip_list full centered v-center">
103
+ <RmEmptyState :title="t('oipDrugs.heart.ansm.detailsPage.noData')" icon="Prohibit" />
104
+ </div>
105
+ </div>
106
+
107
+ <!-- Présentations -->
108
+ <div class="oip_card oip_list gap-16 oip_body full">
109
+ <p class="oip_heading">{{ t('oipDrugs.heart.ansm.detailsPage.presentations') }}</p>
110
+ <RmTable
111
+ v-if="presContents.length"
112
+ class="card-table"
113
+ :columns="presTable.columns"
114
+ :rows="presTable.rows"
115
+ max-height="600px"
116
+ >
117
+ <template v-for="key in presTable.typeKeys.tag" :key="key" #[key]="{ value }">
118
+ <RmTag :variant="heartGetStatusColor(value)">{{ value }}</RmTag>
119
+ </template>
120
+ </RmTable>
121
+ <div v-else class="oip_list full centered v-center">
122
+ <RmEmptyState :title="t('oipDrugs.heart.ansm.detailsPage.noData')" icon="Prohibit" />
123
+ </div>
124
+ </div>
125
+ </div>
126
+ </template>
127
+
128
+ <script lang="ts" setup>
129
+ import type { OneAnsmResult } from "../../../../oip-drugs/types/heart/ansm";
130
+ import {
131
+ heartFirstLetterUpperCase,
132
+ heartFormatAdministrations,
133
+ heartGetStatusColor,
134
+ } from "../../../../oip-drugs/utils/heartStyleAnsm";
135
+ import { heartFormatDate } from "../../../../oip-drugs/utils/heartStyleAndFormat";
136
+ import { valueTable } from "../../../../utils/valueTable";
137
+
138
+ const { t, locale } = useI18n();
139
+
140
+ const props = defineProps<{
141
+ cis: OneAnsmResult;
142
+ skuCount?: number;
143
+ avisCount?: number;
144
+ }>();
145
+
146
+ const synthContext = computed(() =>
147
+ [props.cis.atc5_french_code_label, props.cis.atc4_french_code_label, props.cis.owner]
148
+ .filter(Boolean)
149
+ .join(" · ")
150
+ );
151
+
152
+ const ownerSince = computed(() => {
153
+ const d = (props.cis as any).owner_authorization_date;
154
+ return d && d !== "-" ? heartFormatDate(d) : null;
155
+ });
156
+
157
+ const compoContents = computed(() =>
158
+ (props.cis.compo ?? []).map((c) => ({
159
+ values: [
160
+ c.substance_label,
161
+ heartFirstLetterUpperCase(c.substance_form || c.pharmaceutical_form),
162
+ c.substance_dosage,
163
+ ],
164
+ }))
165
+ );
166
+
167
+ const presContents = computed(() =>
168
+ (props.cis.drug ?? []).map((d) => ({
169
+ values: [
170
+ d.drug_code,
171
+ heartFirstLetterUpperCase(d.presentation_label),
172
+ d.presentation_status,
173
+ d.commercialization_date && d.commercialization_date !== "-"
174
+ ? heartFormatDate(d.commercialization_date)
175
+ : "-",
176
+ ],
177
+ }))
178
+ );
179
+
180
+ // Conditions de prescription regroupées par catégorie (comme le modèle Synappses).
181
+ function cpdCategory(c: string): string {
182
+ const s = (c || "").toLowerCase();
183
+ if (s.includes("surveillance")) return "surveillance";
184
+ if (s.includes("hospital") || s.includes("usage")) return "delivrance";
185
+ if (s.includes("prescription") || s.includes("spécial") || s.includes("special") || s.includes("services") || s.includes("médecin") || s.includes("medecin")) return "prescripteur";
186
+ if (s.includes("liste")) return "classification";
187
+ return "autre";
188
+ }
189
+ const CPD_CATS = [
190
+ { key: "classification", fr: "Classification", en: "Classification" },
191
+ { key: "surveillance", fr: "Surveillance", en: "Monitoring" },
192
+ { key: "prescripteur", fr: "Prescripteur habilité", en: "Authorized prescriber" },
193
+ { key: "delivrance", fr: "Cadre de délivrance", en: "Dispensing setting" },
194
+ { key: "autre", fr: "Autre", en: "Other" },
195
+ ];
196
+ const cpdGroups = computed(() => {
197
+ const map: Record<string, string[]> = {};
198
+ (props.cis.cpd ?? []).forEach((c: any) => {
199
+ const cat = cpdCategory(c.prescription_delivery_condition);
200
+ (map[cat] ||= []).push(c.prescription_delivery_condition);
201
+ });
202
+ return CPD_CATS.filter((c) => map[c.key]).map((c) => ({
203
+ label: locale.value === "en" ? c.en : c.fr,
204
+ items: map[c.key],
205
+ }));
206
+ });
207
+
208
+ // Les deux tableaux de la fiche etaient ecrits pour `arg-table` : des libelles
209
+ // de tete et des lignes `{ values: [...] }`. La conversion en colonnes de
210
+ // RmTable est mecanique, cf. `valueTable`. Ils ne se trient pas : la fiche
211
+ // garde l'ordre de la source.
212
+ const unsorted = (table: ReturnType<typeof valueTable>) => ({
213
+ ...table,
214
+ columns: table.columns.map((column) => ({ ...column, sortable: false })),
215
+ });
216
+
217
+ const compoTable = computed(() =>
218
+ unsorted(
219
+ valueTable(
220
+ [
221
+ t("oipDrugs.heart.ansm.detailsPage.substanceActive"),
222
+ t("oipDrugs.heart.ansm.detailsPage.forme"),
223
+ t("oipDrugs.heart.ansm.detailsPage.dosage"),
224
+ ],
225
+ compoContents.value,
226
+ ["", "", ""],
227
+ { align: ["left", "left", "left"] },
228
+ ),
229
+ ),
230
+ );
231
+
232
+ const presTable = computed(() =>
233
+ unsorted(
234
+ valueTable(
235
+ [
236
+ locale.value === "en" ? "CIP code" : "Code CIP",
237
+ t("oipDrugs.heart.ansm.detailsPage.conditioning"),
238
+ t("oipDrugs.heart.ansm.detailsPage.declaration"),
239
+ t("oipDrugs.heart.ansm.detailsPage.date"),
240
+ ],
241
+ presContents.value,
242
+ ["", "", "tag", ""],
243
+ { align: ["left", "left", "left", "left"] },
244
+ ),
245
+ ),
246
+ );
247
+ </script>
248
+
249
+ <style scoped>
250
+ .card_title {
251
+ font-weight: 900;
252
+ font-size: 20px;
253
+ color: var(--darkest);
254
+ font-family: Figtree, sans-serif !important;
255
+ }
256
+ .wrap {
257
+ flex-wrap: wrap;
258
+ }
259
+
260
+ /* Tableau à fleur des bords de la card (annule le padding 24px de .oip_card).
261
+ Le padding de cellule interne d'arg-table garde le texte aligné sous le titre. */
262
+ .card-table {
263
+ margin: 0 -24px -24px;
264
+ }
265
+
266
+ /* Strip de stats (synthèse). */
267
+ .statbar {
268
+ display: grid;
269
+ grid-template-columns: repeat(4, 1fr);
270
+ border-top: 1px solid var(--light);
271
+ }
272
+ .stat {
273
+ padding: 16px 24px 0;
274
+ border-right: 1px solid var(--light);
275
+ }
276
+ .stat:last-child {
277
+ border-right: none;
278
+ }
279
+ .stat-num {
280
+ display: block;
281
+ font-size: 20px;
282
+ font-weight: 800;
283
+ color: var(--primary);
284
+ line-height: 1.2;
285
+ }
286
+ .stat-lbl {
287
+ display: block;
288
+ margin-top: 4px;
289
+ font-size: 11px;
290
+ font-weight: 600;
291
+ text-transform: uppercase;
292
+ letter-spacing: 0.06em;
293
+ color: var(--medium);
294
+ }
295
+
296
+ /* Grille données administratives (style dl). */
297
+ .admin-grid {
298
+ display: grid;
299
+ grid-template-columns: repeat(3, 1fr);
300
+ gap: 20px 32px;
301
+ margin: 0;
302
+ }
303
+ .admin-grid > div {
304
+ display: flex;
305
+ flex-direction: column;
306
+ gap: 4px;
307
+ }
308
+ .admin-grid .col-span {
309
+ grid-column: 1 / -1;
310
+ }
311
+ .admin-grid dt {
312
+ font-size: 11px;
313
+ font-weight: 600;
314
+ text-transform: uppercase;
315
+ letter-spacing: 0.06em;
316
+ color: var(--medium);
317
+ }
318
+ .admin-grid dd {
319
+ margin: 0;
320
+ font-size: 14px;
321
+ color: var(--darkest);
322
+ font-weight: 500;
323
+ }
324
+ .admin-since {
325
+ color: var(--medium);
326
+ font-weight: 400;
327
+ }
328
+
329
+ /* Conditions de prescription groupées. */
330
+ .cpd-groups {
331
+ display: flex;
332
+ flex-direction: column;
333
+ gap: 16px;
334
+ }
335
+ .cpd-group-title {
336
+ margin: 0 0 6px;
337
+ font-size: 11px;
338
+ font-weight: 600;
339
+ text-transform: uppercase;
340
+ letter-spacing: 0.06em;
341
+ color: var(--primary);
342
+ }
343
+ .cpd-glist {
344
+ margin: 0;
345
+ padding-left: 16px;
346
+ display: flex;
347
+ flex-direction: column;
348
+ gap: 4px;
349
+ }
350
+ .cpd-glist li {
351
+ font-size: 14px;
352
+ color: var(--dark);
353
+ }
354
+
355
+ @media (max-width: 860px) {
356
+ .statbar {
357
+ grid-template-columns: 1fr 1fr;
358
+ }
359
+ .admin-grid {
360
+ grid-template-columns: 1fr 1fr;
361
+ }
362
+ }
363
+ </style>