@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,494 @@
1
+ <!--
2
+ Tiroir d'un enregistrement de liste (alerte, P.U.T, contribution).
3
+
4
+ Meme comportement que le tiroir des avis HAS : il arrive par la droite, se
5
+ ferme au clic ailleurs ou sur Echap, et decoupe le detail en rubriques — seules
6
+ celles qui portent un texte apparaissent. La page fournit ces rubriques deja
7
+ redigees, le tiroir ne connait rien du metier.
8
+ -->
9
+ <script setup lang="ts">
10
+ import { OIP_RESOURCE_NAV, useOipResourceNav } from "../../../../../composables/useOipResourceNav";
11
+
12
+ const props = defineProps<{
13
+ record:
14
+ | {
15
+ typeLabel: string;
16
+ icon?: string;
17
+ date?: string | null;
18
+ /** Qualificatif fort, en tag a la suite du statut. */
19
+ badge?: string | null;
20
+ badgeTone?: "pre" | "post" | "good" | "warn" | "neutral";
21
+ title: string;
22
+ status?: string | null;
23
+ statusTone?: "good" | "bad" | "neutral";
24
+ url?: string | null;
25
+ /** « accordion » quand les rubriques sont trop nombreuses pour des
26
+ onglets (contributions patients) ; onglets par defaut. */
27
+ layout?: "tabs" | "accordion";
28
+ /**
29
+ * Renvoi vers une autre fiche du hub, quand la page en connait un pour
30
+ * cet enregistrement (la fiche de l'association qui signe une
31
+ * contribution). Le tiroir n'en sait rien d'autre que son libelle et
32
+ * son chemin, celui de fr_drugs_app (cf. useOipResourceNav).
33
+ */
34
+ link?: { label: string; to: string; icon?: string } | null;
35
+ sections?: { key: string; label: string; body: string }[];
36
+ }
37
+ | null;
38
+ /** Nom de la source affichee en pied. */
39
+ sourceLabel?: string | null;
40
+ checkedAt?: string | null;
41
+ /** Panneau elargi, pour un corps qui porte une table (tiroir LES). */
42
+ wide?: boolean;
43
+ }>();
44
+
45
+ const emit = defineEmits<{ (event: "close"): void }>();
46
+
47
+ const { locale } = useI18n();
48
+
49
+ const sections = computed(() => (props.record?.sections ?? []).filter((s) => s.body?.trim()));
50
+
51
+ const accordion = computed(() => props.record?.layout === "accordion");
52
+
53
+ /** Onglets : la rubrique affichee. */
54
+ const active = ref(0);
55
+
56
+ /** Accordeon : les rubriques depliees, par cle. */
57
+ const opened = ref<Record<string, boolean>>({});
58
+
59
+ function toggle(key: string) {
60
+ opened.value = { ...opened.value, [key]: !opened.value[key] };
61
+ }
62
+
63
+ // Un autre enregistrement s'ouvre : on repart de sa premiere rubrique, sinon le
64
+ // tiroir s'ouvre sur une rubrique qui n'existe pas pour lui.
65
+ watch(
66
+ () => props.record,
67
+ () => {
68
+ active.value = 0;
69
+ const first = sections.value[0]?.key;
70
+ opened.value = first ? { [first]: true } : {};
71
+ },
72
+ { immediate: true }
73
+ );
74
+
75
+ /**
76
+ * Le renvoi quitte la page, le tiroir part avec elle : pas de `close` ici.
77
+ * Le fermer d'abord lance sa transition de sortie, et le demontage de la page
78
+ * en pleine transition laissait le panneau colle dans `body` par-dessus la
79
+ * fiche d'arrivee (le contenu d'un `Teleport` en cours de `Transition` ne se
80
+ * retire pas quand son parent disparait). `to` est un chemin de fr_drugs_app :
81
+ * dans une page le layer navigue, dans le tiroir d'un projet il empile la fiche.
82
+ */
83
+ const nav = useOipResourceNav();
84
+ // Dans le tiroir d'un projet, la page reste : la fiche visee s'empile, et ce
85
+ // tiroir-ci, pose au-dessus de tout, doit lui laisser la place.
86
+ const embedded = inject(OIP_RESOURCE_NAV, null) !== null;
87
+
88
+ function follow(to: string) {
89
+ nav.openApp("fr_drugs_app", to);
90
+ if (embedded) emit("close");
91
+ }
92
+
93
+ function onKeydown(event: KeyboardEvent) {
94
+ if (event.key === "Escape") emit("close");
95
+ }
96
+
97
+ onMounted(() => document.addEventListener("keydown", onKeydown));
98
+ onBeforeUnmount(() => document.removeEventListener("keydown", onKeydown));
99
+ </script>
100
+
101
+ <template>
102
+ <!-- Pose dans `body` : un ancetre du contenu de page etablit un bloc conteneur
103
+ pour les elements `fixed`, et le voile s'arretait au bord de la colonne
104
+ au lieu de couvrir le cadre entier. -->
105
+ <Teleport to="body">
106
+ <Transition name="drawer">
107
+ <div v-if="record" class="rdr oip-drugs" @click.self="emit('close')">
108
+ <aside class="rdr_panel" :class="{ rdr_panel_wide: wide }">
109
+ <header class="rdr_head">
110
+ <p class="rdr_type">
111
+ <RmIcon :name="record.icon || 'FileText'" :size="16" />
112
+ {{ record.typeLabel }}
113
+ </p>
114
+ <button
115
+ type="button"
116
+ class="rdr_close"
117
+ :aria-label="locale === 'en' ? 'Close' : 'Fermer'"
118
+ @click="emit('close')"
119
+ >
120
+ <RmIcon name="X" :size="16" />
121
+ </button>
122
+ </header>
123
+
124
+ <div class="rdr_body">
125
+ <p v-if="record.date" class="rdr_date">
126
+ <RmDate :date="record.date" :lang="locale" />
127
+ </p>
128
+ <h2 class="rdr_title">{{ record.title }}</h2>
129
+
130
+ <div v-if="record.status || record.badge" class="rdr_tags">
131
+ <span v-if="record.status" class="rdr_status" :class="`is_${record.statusTone || 'neutral'}`">
132
+ {{ record.status }}
133
+ </span>
134
+ <span
135
+ v-if="record.badge"
136
+ class="rdr_badge"
137
+ :class="`is_${record.badgeTone || 'neutral'}`"
138
+ >{{ record.badge }}</span>
139
+ </div>
140
+
141
+ <!-- Le renvoi tient sous l'identite de l'enregistrement, pas en
142
+ pied : les sept rubriques d'une contribution le repoussaient a
143
+ une hauteur d'ecran du titre. -->
144
+ <RmButton
145
+ v-if="record.link"
146
+ class="rdr_follow"
147
+ variant="secondary"
148
+ :prefix-icon="record.link.icon || 'ArrowRight'"
149
+ @click="follow(record.link.to)"
150
+ >
151
+ {{ record.link.label }}
152
+ </RmButton>
153
+
154
+ <!-- Par defaut, les rubriques redigees par la page ; un parent peut
155
+ poser son propre corps a la place (tiroir LES). -->
156
+ <slot>
157
+ <template v-if="accordion">
158
+ <div class="rdr_sections">
159
+ <section
160
+ v-for="section in sections"
161
+ :key="section.key"
162
+ class="rdr_section"
163
+ :class="{ is_open: opened[section.key] }"
164
+ >
165
+ <button type="button" class="rdr_section_head" @click="toggle(section.key)">
166
+ <RmIcon name="CaretRight" :size="14" class="rdr_caret" />
167
+ {{ section.label }}
168
+ </button>
169
+ <p v-if="opened[section.key]" class="rdr_text">{{ section.body }}</p>
170
+ </section>
171
+ </div>
172
+ </template>
173
+
174
+ <template v-else>
175
+ <div v-if="sections.length > 1" class="rdr_tabs">
176
+ <button
177
+ v-for="(section, index) in sections"
178
+ :key="section.key"
179
+ type="button"
180
+ class="rdr_tab"
181
+ :class="{ is_active: index === active }"
182
+ @click="active = index"
183
+ >
184
+ {{ section.label }}
185
+ </button>
186
+ </div>
187
+
188
+ <p class="rdr_text rdr_text--tab">{{ sections[active]?.body }}</p>
189
+ </template>
190
+ </slot>
191
+
192
+ <a
193
+ v-if="record.url"
194
+ class="rdr_link"
195
+ :href="record.url"
196
+ target="_blank"
197
+ rel="noopener noreferrer"
198
+ >
199
+ {{ locale === "en" ? "Open the source document" : "Ouvrir le document source" }} →
200
+ </a>
201
+ </div>
202
+
203
+ <footer class="rdr_foot">
204
+ <span>Source : <b>{{ sourceLabel || "HAS" }}</b></span>
205
+ <span v-if="checkedAt">
206
+ ·
207
+ {{ locale === "en" ? "Last updated" : "Dernière mise à jour le" }}
208
+ <RmDate :date="checkedAt" :lang="locale" />
209
+ </span>
210
+ </footer>
211
+ </aside>
212
+ </div>
213
+ </Transition>
214
+ </Teleport>
215
+ </template>
216
+
217
+ <style scoped>
218
+ /* Le voile epouse le cadre de la coque (marge de 8px, coins arrondis) plutot
219
+ que la fenetre : sinon il deborde sur la bordure du cadre. */
220
+ .rdr {
221
+ position: fixed;
222
+ inset: var(--rm-shell-inset, 8px);
223
+ border-radius: var(--rm-shell-radius, 12px);
224
+ overflow: hidden;
225
+ z-index: 300;
226
+ display: flex;
227
+ justify-content: flex-end;
228
+ background: rgba(30, 41, 59, 0.35);
229
+ -webkit-backdrop-filter: blur(2px);
230
+ backdrop-filter: blur(2px);
231
+ }
232
+
233
+ .rdr_panel {
234
+ display: flex;
235
+ flex-direction: column;
236
+ /* Les textes d'avis font plusieurs paragraphes : a 560px, chaque ligne etait
237
+ trop courte pour se lire d'une traite. */
238
+ width: min(760px, 100%);
239
+ height: 100%;
240
+ background: var(--white);
241
+ box-shadow: var(--overlay-shadow);
242
+ }
243
+
244
+ .rdr_panel_wide {
245
+ width: min(1040px, 100%);
246
+ }
247
+
248
+ .rdr_head {
249
+ display: flex;
250
+ align-items: center;
251
+ justify-content: space-between;
252
+ gap: 16px;
253
+ padding: 16px 20px;
254
+ border-bottom: 1px solid var(--light);
255
+ }
256
+
257
+ .rdr_type {
258
+ display: flex;
259
+ align-items: center;
260
+ gap: 8px;
261
+ color: var(--primary);
262
+ font-size: 15px;
263
+ font-weight: 700;
264
+ }
265
+
266
+ .rdr_close {
267
+ display: flex;
268
+ align-items: center;
269
+ justify-content: center;
270
+ width: 32px;
271
+ height: 32px;
272
+ border: 1px solid var(--light);
273
+ border-radius: 8px;
274
+ background: var(--white);
275
+ color: var(--dark);
276
+ cursor: pointer;
277
+ }
278
+
279
+ .rdr_close:hover {
280
+ background: var(--lightest);
281
+ }
282
+
283
+ .rdr_body {
284
+ flex: 1 1 auto;
285
+ overflow-y: auto;
286
+ display: flex;
287
+ flex-direction: column;
288
+ gap: 12px;
289
+ padding: 20px;
290
+ }
291
+
292
+ /* Le texte peut faire plusieurs milliers de caracteres : sans ce garde, il
293
+ ecrase les blocs au-dessus de lui dans la colonne flex. */
294
+ .rdr_date,
295
+ .rdr_title,
296
+ .rdr_tabs,
297
+ .rdr_tags,
298
+ .rdr_follow,
299
+ .rdr_link {
300
+ flex: 0 0 auto;
301
+ }
302
+
303
+ .rdr_follow {
304
+ align-self: flex-start;
305
+ }
306
+
307
+ .rdr_date {
308
+ color: var(--medium);
309
+ font-size: 14px;
310
+ }
311
+
312
+ .rdr_title {
313
+ max-height: 2.6em;
314
+ overflow: hidden;
315
+ font-size: 20px;
316
+ font-weight: 800;
317
+ line-height: 1.3;
318
+ }
319
+
320
+ .rdr_tabs {
321
+ display: flex;
322
+ flex-wrap: wrap;
323
+ gap: 4px;
324
+ border-bottom: 1px solid var(--light);
325
+ }
326
+
327
+ .rdr_tab {
328
+ padding: 8px 12px;
329
+ border: none;
330
+ border-bottom: 2px solid transparent;
331
+ background: none;
332
+ color: var(--medium);
333
+ font-size: 14px;
334
+ font-weight: 600;
335
+ cursor: pointer;
336
+ }
337
+
338
+ .rdr_tab.is_active {
339
+ border-bottom-color: var(--primary);
340
+ background: color-mix(in srgb, var(--primary) 6%, transparent);
341
+ color: var(--primary);
342
+ }
343
+
344
+ .rdr_sections {
345
+ display: flex;
346
+ flex-direction: column;
347
+ border-top: 1px solid var(--light);
348
+ }
349
+
350
+ .rdr_section {
351
+ border-bottom: 1px solid var(--light);
352
+ }
353
+
354
+ .rdr_section_head {
355
+ display: flex;
356
+ align-items: center;
357
+ gap: 8px;
358
+ width: 100%;
359
+ padding: 12px 4px;
360
+ border: none;
361
+ background: none;
362
+ color: var(--dark);
363
+ font-size: 14px;
364
+ font-weight: 700;
365
+ text-align: left;
366
+ cursor: pointer;
367
+ }
368
+
369
+ .rdr_section_head:hover,
370
+ .rdr_section.is_open .rdr_section_head {
371
+ color: var(--primary);
372
+ }
373
+
374
+ .rdr_caret {
375
+ flex: 0 0 auto;
376
+ transition: transform 0.15s linear;
377
+ }
378
+
379
+ .rdr_section.is_open .rdr_caret {
380
+ transform: rotate(90deg);
381
+ }
382
+
383
+ .rdr_tags {
384
+ align-self: flex-start;
385
+ display: flex;
386
+ flex-wrap: wrap;
387
+ align-items: center;
388
+ gap: 6px;
389
+ }
390
+
391
+ .rdr_badge {
392
+ padding: 2px 8px;
393
+ border-radius: 4px;
394
+ font-size: 13px;
395
+ font-weight: 600;
396
+ white-space: nowrap;
397
+ }
398
+
399
+ .rdr_badge.is_pre {
400
+ background: rgba(245, 158, 11, 0.16);
401
+ color: #b45309;
402
+ }
403
+
404
+ .rdr_badge.is_post {
405
+ background: color-mix(in srgb, var(--primary) 12%, transparent);
406
+ color: var(--primary);
407
+ }
408
+
409
+ .rdr_badge.is_good {
410
+ background: rgba(34, 197, 94, 0.14);
411
+ color: var(--system-success-hover);
412
+ }
413
+
414
+ .rdr_badge.is_warn {
415
+ background: rgba(245, 158, 11, 0.16);
416
+ color: #b45309;
417
+ }
418
+
419
+ .rdr_badge.is_neutral {
420
+ background: var(--lightest);
421
+ color: var(--dark);
422
+ }
423
+
424
+ .rdr_status {
425
+ padding: 2px 8px;
426
+ border-radius: 4px;
427
+ font-size: 13px;
428
+ font-weight: 600;
429
+ }
430
+
431
+ .rdr_status.is_good {
432
+ background: rgba(34, 197, 94, 0.14);
433
+ color: var(--system-success-hover);
434
+ }
435
+
436
+ .rdr_status.is_bad {
437
+ background: rgba(239, 68, 68, 0.12);
438
+ color: var(--system-alert-hover);
439
+ }
440
+
441
+ .rdr_status.is_neutral {
442
+ background: var(--lightest);
443
+ color: var(--dark);
444
+ }
445
+
446
+ .rdr_text {
447
+ padding: 0 4px 16px;
448
+ color: var(--dark);
449
+ font-size: 15px;
450
+ line-height: 1.6;
451
+ white-space: pre-line;
452
+ }
453
+
454
+ .rdr_text--tab {
455
+ padding: 0;
456
+ }
457
+
458
+ .rdr_link {
459
+ color: var(--primary);
460
+ font-size: 14px;
461
+ font-weight: 600;
462
+ }
463
+
464
+ .rdr_foot {
465
+ display: flex;
466
+ align-items: center;
467
+ gap: 6px;
468
+ padding: 14px 20px;
469
+ border-top: 1px solid var(--light);
470
+ background: var(--demi-fond);
471
+ color: var(--medium);
472
+ font-size: 13px;
473
+ }
474
+
475
+ .drawer-enter-active,
476
+ .drawer-leave-active {
477
+ transition: opacity 0.2s ease;
478
+ }
479
+
480
+ .drawer-enter-active .rdr_panel,
481
+ .drawer-leave-active .rdr_panel {
482
+ transition: transform 0.2s ease;
483
+ }
484
+
485
+ .drawer-enter-from,
486
+ .drawer-leave-to {
487
+ opacity: 0;
488
+ }
489
+
490
+ .drawer-enter-from .rdr_panel,
491
+ .drawer-leave-to .rdr_panel {
492
+ transform: translateX(24px);
493
+ }
494
+ </style>