@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.
- package/dist/module.json +1 -1
- package/layer/app/app.config.ts +6 -0
- package/layer/app/components/OipPubmedSummary.vue +223 -0
- package/layer/app/components/OipResourceDrawer.vue +331 -0
- package/layer/app/components/OipResourceDrawerLink.vue +40 -0
- package/layer/app/components/OipResourceField.vue +41 -0
- package/layer/app/components/OipResourceGenericCard.vue +54 -0
- package/layer/app/components/OipResourceSource.vue +50 -0
- package/layer/app/components/OipResourceTags.vue +65 -0
- package/layer/app/components/OipResourceView.vue +107 -0
- package/layer/app/components/oip-drugs/fiches/AssociationFiche.vue +775 -0
- package/layer/app/components/oip-drugs/fiches/BrandFiche.vue +1111 -0
- package/layer/app/components/oip-drugs/fiches/IndicationFiche.vue +182 -0
- package/layer/app/components/oip-drugs/fiches/JoFiche.vue +101 -0
- package/layer/app/components/oip-drugs/fiches/PndsFiche.vue +279 -0
- package/layer/app/components/oip-drugs/heart/JoCard.vue +314 -0
- package/layer/app/components/oip-drugs/heart/TextHighlight.vue +326 -0
- package/layer/app/components/oip-drugs/heart/ansm/BrandCard.vue +187 -0
- package/layer/app/components/oip-drugs/heart/ansm/CisDetail.vue +363 -0
- package/layer/app/components/oip-drugs/heart/ansm/CisTable.vue +167 -0
- package/layer/app/components/oip-drugs/heart/associations/NationalAssemblyCard.vue +373 -0
- package/layer/app/components/oip-drugs/heart/associations/NationalAssemblyFiche.vue +372 -0
- package/layer/app/components/oip-drugs/heart/associations/TranscriptionCard.vue +55 -0
- package/layer/app/components/oip-drugs/heart/elastic/SourceContainerElastic.vue +103 -0
- package/layer/app/components/oip-drugs/heart/france/BrandGroupCard.vue +450 -0
- package/layer/app/components/oip-drugs/heart/mitm/Card.vue +199 -0
- package/layer/app/components/oip-drugs/heart/mitm/Source.vue +23 -0
- package/layer/app/components/oip-drugs/heart/mitm/details/Overview.vue +381 -0
- package/layer/app/components/oip-drugs/heart/put/Card.vue +212 -0
- package/layer/app/components/oip-drugs/heart/results/AccesCard.vue +696 -0
- package/layer/app/components/oip-drugs/heart/results/AlertCard.vue +342 -0
- package/layer/app/components/oip-drugs/heart/results/AsmrCursor.vue +229 -0
- package/layer/app/components/oip-drugs/heart/results/EvalCard.vue +370 -0
- package/layer/app/components/oip-drugs/heart/results/IndicCard.vue +743 -0
- package/layer/app/components/oip-drugs/heart/results/MatchExplain.vue +243 -0
- package/layer/app/components/oip-drugs/heart/results/PrefRows.vue +105 -0
- package/layer/app/components/oip-drugs/heart/results/details/HasHistory.vue +487 -0
- package/layer/app/components/oip-drugs/heart/results/details/InternationalCountryCard.vue +461 -0
- package/layer/app/components/oip-drugs/heart/results/details/InternationalOverview.vue +200 -0
- package/layer/app/components/oip-drugs/heart/results/details/InternationalPriceDrawer.vue +647 -0
- package/layer/app/components/oip-drugs/heart/results/details/Monograph.vue +128 -0
- package/layer/app/components/oip-drugs/heart/results/details/OpinionDrawer.vue +535 -0
- package/layer/app/components/oip-drugs/heart/results/details/PresentationDrawer.vue +738 -0
- package/layer/app/components/oip-drugs/heart/results/details/Price.vue +227 -0
- package/layer/app/components/oip-drugs/heart/results/details/PriceOverview.vue +1261 -0
- package/layer/app/components/oip-drugs/heart/results/details/RecordDrawer.vue +494 -0
- package/layer/app/components/oip-drugs/heart/results/details/RecordList.vue +426 -0
- package/layer/app/components/oip-drugs/heart/results/les/Card.vue +340 -0
- package/layer/app/components/oip-drugs/heart/results/les/Drawer.vue +67 -0
- package/layer/app/components/oip-drugs/heart/results/les/IndicationDetail.vue +149 -0
- package/layer/app/components/oip-drugs/heart/results/les/Source.vue +20 -0
- package/layer/app/components/oip-drugs/heart/results/les/SourceTag.vue +39 -0
- package/layer/app/components/oip-drugs/heart/searchPage/DynamicSource.vue +29 -0
- package/layer/app/components/oip-drugs/medicam/market/Chart.vue +121 -0
- package/layer/app/components/oip-drugs/outpatient/ProductEvolution.vue +236 -0
- package/layer/app/components/oip-drugs/resources/Ansm.vue +75 -0
- package/layer/app/components/oip-drugs/resources/Association.vue +30 -0
- package/layer/app/components/oip-drugs/resources/Brand.vue +65 -0
- package/layer/app/components/oip-drugs/resources/Contribution.vue +216 -0
- package/layer/app/components/oip-drugs/resources/Hospital.vue +151 -0
- package/layer/app/components/oip-drugs/resources/Indication.vue +54 -0
- package/layer/app/components/oip-drugs/resources/Jo.vue +57 -0
- package/layer/app/components/oip-drugs/resources/Medicam.vue +140 -0
- package/layer/app/components/oip-drugs/resources/Mitm.vue +84 -0
- package/layer/app/components/oip-drugs/resources/NationalAssembly.vue +93 -0
- package/layer/app/components/oip-drugs/resources/Outpatient.vue +97 -0
- package/layer/app/components/oip-drugs/resources/Pnds.vue +24 -0
- package/layer/app/components/oip-drugs/resources/Price.vue +106 -0
- package/layer/app/components/oip-drugs/resources/Put.vue +143 -0
- package/layer/app/components/oip-science/appel-a-projet/Cards.vue +162 -0
- package/layer/app/components/oip-science/clinical-trials/Cards.vue +382 -0
- package/layer/app/components/oip-science/clinical-trials/CardsGlobal.vue +273 -0
- package/layer/app/components/oip-science/clinical-trials/LinkedList.vue +366 -0
- package/layer/app/components/oip-science/clinical-trials/PairBadge.vue +25 -0
- package/layer/app/components/oip-science/clinical-trials/PairBody.vue +182 -0
- package/layer/app/components/oip-science/clinical-trials/SitesDrawer.vue +95 -0
- package/layer/app/components/oip-science/common/Form.vue +73 -0
- package/layer/app/components/oip-science/common/MatchAvgTag.vue +283 -0
- package/layer/app/components/oip-science/common/NoData.vue +16 -0
- package/layer/app/components/oip-science/common/ScoreBadge.vue +35 -0
- package/layer/app/components/oip-science/common/Source.vue +31 -0
- package/layer/app/components/oip-science/common/TableTags.vue +279 -0
- package/layer/app/components/oip-science/common/Timeline.vue +104 -0
- package/layer/app/components/oip-science/common/ToolTips.vue +89 -0
- package/layer/app/components/oip-science/cross/publicationPubmed.vue +484 -0
- package/layer/app/components/oip-science/crossData/CrossDataLocations.vue +71 -0
- package/layer/app/components/oip-science/ctgov/Investigators.vue +148 -0
- package/layer/app/components/oip-science/ctgov/Locations.vue +102 -0
- package/layer/app/components/oip-science/ctgov/Publications.vue +52 -0
- package/layer/app/components/oip-science/ctgov/Sponsors.vue +66 -0
- package/layer/app/components/oip-science/ctgov/StudyDescription.vue +1136 -0
- package/layer/app/components/oip-science/ctgov-centers/ClinicalTrials.vue +40 -0
- package/layer/app/components/oip-science/ctgov-centers/Publications.vue +50 -0
- package/layer/app/components/oip-science/ctgov-investigators/ClinicalTrials.vue +43 -0
- package/layer/app/components/oip-science/ctgov-investigators/Informations.vue +171 -0
- package/layer/app/components/oip-science/ctgov-investigators/Publications.vue +44 -0
- package/layer/app/components/oip-science/elastic/DateRangeFilter.vue +209 -0
- package/layer/app/components/oip-science/elastic/Filter.vue +719 -0
- package/layer/app/components/oip-science/elastic/MatchExplain.vue +152 -0
- package/layer/app/components/oip-science/establishments/Cards.vue +183 -0
- package/layer/app/components/oip-science/establishments/ClinicalTrials.vue +62 -0
- package/layer/app/components/oip-science/establishments/Hcps.vue +227 -0
- package/layer/app/components/oip-science/establishments/Informations.vue +263 -0
- package/layer/app/components/oip-science/establishments/LinkedList.vue +153 -0
- package/layer/app/components/oip-science/establishments/MatchedLabels.vue +194 -0
- package/layer/app/components/oip-science/establishments/PublicFinance.vue +62 -0
- package/layer/app/components/oip-science/euct/Investigators.vue +125 -0
- package/layer/app/components/oip-science/euct/Locations.vue +102 -0
- package/layer/app/components/oip-science/euct/Products.vue +101 -0
- package/layer/app/components/oip-science/euct/Publications.vue +89 -0
- package/layer/app/components/oip-science/euct/Sponsors.vue +86 -0
- package/layer/app/components/oip-science/euct/StudyDescription.vue +1075 -0
- package/layer/app/components/oip-science/euct-centers/ClinicalTrials.vue +40 -0
- package/layer/app/components/oip-science/euct-centers/Publications.vue +55 -0
- package/layer/app/components/oip-science/euct-investigators/ClinicalTrials.vue +41 -0
- package/layer/app/components/oip-science/euct-investigators/Informations.vue +171 -0
- package/layer/app/components/oip-science/euct-investigators/Publications.vue +51 -0
- package/layer/app/components/oip-science/hcps/AppelsAProjet.vue +62 -0
- package/layer/app/components/oip-science/hcps/Cards.vue +237 -0
- package/layer/app/components/oip-science/hcps/ClinicalTrials.vue +78 -0
- package/layer/app/components/oip-science/hcps/Informations.vue +296 -0
- package/layer/app/components/oip-science/hcps/LinkedList.vue +153 -0
- package/layer/app/components/oip-science/hcps/MatchedLabels.vue +207 -0
- package/layer/app/components/oip-science/hcps/Pubmed.vue +128 -0
- package/layer/app/components/oip-science/local/SliderTabs.vue +99 -0
- package/layer/app/components/oip-science/local/SliderTabsFull.vue +135 -0
- package/layer/app/components/oip-science/pubmed/Authors.vue +128 -0
- package/layer/app/components/oip-science/pubmed/Cards.vue +417 -0
- package/layer/app/components/oip-science/pubmed/ClinicalTrials.vue +71 -0
- package/layer/app/components/oip-science/resources/Phrc.vue +39 -0
- package/layer/app/composables/useOipChapterScroll.ts +43 -0
- package/layer/app/composables/useOipResourceHooks.ts +27 -0
- package/layer/app/composables/useOipResourceNav.ts +66 -0
- package/layer/app/composables/useOipResourceViews.ts +117 -0
- package/layer/app/composables/useOipResources.ts +83 -0
- package/layer/app/oip-drugs/PORTING.md +120 -0
- package/layer/app/oip-drugs/composables/useAssociationDetail.ts +220 -0
- package/layer/app/oip-drugs/composables/useAssociationExport.ts +63 -0
- package/layer/app/oip-drugs/composables/useAssociationLookup.ts +105 -0
- package/layer/app/oip-drugs/composables/useCardPrefOptions.ts +201 -0
- package/layer/app/oip-drugs/composables/useCurrency.ts +121 -0
- package/layer/app/oip-drugs/composables/useDirectusSources.ts +224 -0
- package/layer/app/oip-drugs/composables/useHeartBrandMatches.ts +112 -0
- package/layer/app/oip-drugs/composables/useHeartDetailSearches.ts +479 -0
- package/layer/app/oip-drugs/composables/useHeartIntlApprovals.ts +661 -0
- package/layer/app/oip-drugs/composables/useHeartLesIndication.ts +168 -0
- package/layer/app/oip-drugs/composables/useHeartMatchExplain.ts +231 -0
- package/layer/app/oip-drugs/composables/useHeartReports.ts +239 -0
- package/layer/app/oip-drugs/composables/useHeartSearchFields.ts +233 -0
- package/layer/app/oip-drugs/composables/useMergeByKey.ts +23 -0
- package/layer/app/oip-drugs/composables/useOipDrugsElastic.ts +621 -0
- package/layer/app/oip-drugs/composables/usePageEmpty.ts +58 -0
- package/layer/app/oip-drugs/composables/v-useSalesSource.ts +64 -0
- package/layer/app/oip-drugs/drugs.css +500 -0
- package/layer/app/oip-drugs/esIndices.ts +322 -0
- package/layer/app/oip-drugs/kinds.ts +264 -0
- package/layer/app/oip-drugs/locales/en.json +1571 -0
- package/layer/app/oip-drugs/locales/fr.json +1571 -0
- package/layer/app/oip-drugs/monographs/blincyto-has.vue +289 -0
- package/layer/app/oip-drugs/monographs/darzalex-has.vue +276 -0
- package/layer/app/oip-drugs/monographs/dupixent-has.vue +216 -0
- package/layer/app/oip-drugs/monographs/enhertu-has.vue +280 -0
- package/layer/app/oip-drugs/monographs/has-sein-2023.vue +1649 -0
- package/layer/app/oip-drugs/monographs/ibrance-has.vue +277 -0
- package/layer/app/oip-drugs/monographs/imfinzi-has.vue +293 -0
- package/layer/app/oip-drugs/monographs/keytruda-has.vue +334 -0
- package/layer/app/oip-drugs/monographs/kisqali-has.vue +201 -0
- package/layer/app/oip-drugs/monographs/opdivo-has.vue +231 -0
- package/layer/app/oip-drugs/monographs/ozempic-has.vue +186 -0
- package/layer/app/oip-drugs/monographs/tecentriq-has.vue +312 -0
- package/layer/app/oip-drugs/monographs/yescarta-has.vue +272 -0
- package/layer/app/oip-drugs/types/elastic.ts +113 -0
- package/layer/app/oip-drugs/types/es/agencies.ts +152 -0
- package/layer/app/oip-drugs/types/es/directory.ts +54 -0
- package/layer/app/oip-drugs/types/es/docByIndex.ts +151 -0
- package/layer/app/oip-drugs/types/es/openmedic.ts +67 -0
- package/layer/app/oip-drugs/types/es/outpatient.ts +71 -0
- package/layer/app/oip-drugs/types/es/portal.ts +130 -0
- package/layer/app/oip-drugs/types/es/retail.ts +107 -0
- package/layer/app/oip-drugs/types/es/statistics.ts +29 -0
- package/layer/app/oip-drugs/types/heart/CurrencyRate.ts +16 -0
- package/layer/app/oip-drugs/types/heart/ansm.ts +106 -0
- package/layer/app/oip-drugs/types/heart/tag.ts +29 -0
- package/layer/app/oip-drugs/utils/associationFields.ts +118 -0
- package/layer/app/oip-drugs/utils/contributions.ts +36 -0
- package/layer/app/oip-drugs/utils/countryMapping.ts +387 -0
- package/layer/app/oip-drugs/utils/esHighlight.ts +21 -0
- package/layer/app/oip-drugs/utils/exportSheets.ts +57 -0
- package/layer/app/oip-drugs/utils/heartIntlPrice.ts +228 -0
- package/layer/app/oip-drugs/utils/heartStyleAndFormat.ts +262 -0
- package/layer/app/oip-drugs/utils/heartStyleAnsm.ts +71 -0
- package/layer/app/oip-drugs/utils/latestDate.ts +31 -0
- package/layer/app/oip-drugs/utils/p-heartCardTags.ts +53 -0
- package/layer/app/oip-drugs/utils/priceExport.ts +269 -0
- package/layer/app/oip-drugs/utils/q-hasRatings.ts +43 -0
- package/layer/app/oip-drugs/utils/s-openCard.ts +20 -0
- package/layer/app/oip-drugs/utils/sourceUuids.ts +155 -0
- package/layer/app/oip-drugs/utils/styleAndFormat.ts +40 -0
- package/layer/app/oip-drugs/utils/v-salesSeries.ts +156 -0
- package/layer/app/oip-drugs/utils/v-scopeTags.ts +23 -0
- package/layer/app/oip-science/PORTING.md +93 -0
- package/layer/app/oip-science/assets/smartSelection.json +428 -0
- package/layer/app/oip-science/composables/useAuthorMatching.ts +342 -0
- package/layer/app/oip-science/composables/useCTCenter.ts +107 -0
- package/layer/app/oip-science/composables/useCTInvestigators.ts +107 -0
- package/layer/app/oip-science/composables/useEstablishmentCrossData.ts +139 -0
- package/layer/app/oip-science/composables/useEstablishmentMatching.ts +176 -0
- package/layer/app/oip-science/composables/useEuct.ts +418 -0
- package/layer/app/oip-science/composables/useEuctCenter.ts +107 -0
- package/layer/app/oip-science/composables/useEuctInvestigators.ts +107 -0
- package/layer/app/oip-science/composables/useGlobalClinicalTrials.ts +624 -0
- package/layer/app/oip-science/composables/useLinkedTrials.ts +83 -0
- package/layer/app/oip-science/composables/useOipElastic.ts +658 -0
- package/layer/app/oip-science/composables/useOipSearchExplain.ts +166 -0
- package/layer/app/oip-science/composables/usePubmed.ts +487 -0
- package/layer/app/oip-science/composables/useSearchFields.ts +153 -0
- package/layer/app/oip-science/indexConfig.json +794 -0
- package/layer/app/oip-science/locales/en.json +483 -0
- package/layer/app/oip-science/locales/fr.json +483 -0
- package/layer/app/oip-science/science.css +1182 -0
- package/layer/app/oip-science/utils/a-openCard.ts +23 -0
- package/layer/app/oip-science/utils/b-openCard.ts +35 -0
- package/layer/app/oip-science/utils/c-filterContext.ts +81 -0
- package/layer/app/oip-science/utils/f-types.ts +241 -0
- package/layer/app/oip-science/utils/frDiseaseTerms.ts +269 -0
- package/layer/app/oip-science/utils/matchMethod.ts +53 -0
- package/layer/app/oip-science/utils/sliderTabs.ts +13 -0
- package/layer/app/oip-science/utils/sources.ts +15 -0
- package/layer/app/oip-science/utils/styleAndFormat.ts +608 -0
- package/layer/app/oip-science/utils/toPresets.ts +7 -0
- package/layer/app/oip-science/utils/valueTable.ts +126 -0
- package/layer/app/plugins/oip-science-i18n.ts +17 -0
- package/layer/app/utils/oipFicheRoutes.ts +118 -0
- package/layer/app/utils/oipResources.ts +440 -0
- package/layer/nuxt.config.ts +22 -2
- package/layer/public/reports/blincyto-has.html +292 -0
- package/layer/public/reports/blincyto-has.pdf +0 -0
- package/layer/public/reports/darzalex-has.html +279 -0
- package/layer/public/reports/darzalex-has.pdf +0 -0
- package/layer/public/reports/dupixent-has.html +217 -0
- package/layer/public/reports/dupixent-has.pdf +0 -0
- package/layer/public/reports/enhertu-has.html +283 -0
- package/layer/public/reports/enhertu-has.pdf +0 -0
- package/layer/public/reports/has-sein-2023.html +1639 -0
- package/layer/public/reports/ibrance-has.html +280 -0
- package/layer/public/reports/ibrance-has.pdf +0 -0
- package/layer/public/reports/imfinzi-has.html +297 -0
- package/layer/public/reports/imfinzi-has.pdf +0 -0
- package/layer/public/reports/keytruda-has.html +337 -0
- package/layer/public/reports/keytruda-has.pdf +0 -0
- package/layer/public/reports/kisqali-has.html +202 -0
- package/layer/public/reports/kisqali-has.pdf +0 -0
- package/layer/public/reports/opdivo-has.html +232 -0
- package/layer/public/reports/opdivo-has.pdf +0 -0
- package/layer/public/reports/ozempic-has.html +188 -0
- package/layer/public/reports/ozempic-has.pdf +0 -0
- package/layer/public/reports/tecentriq-has.html +315 -0
- package/layer/public/reports/tecentriq-has.pdf +0 -0
- package/layer/public/reports/yescarta-has.html +275 -0
- package/layer/public/reports/yescarta-has.pdf +0 -0
- package/layer/server/api/oip/es.post.ts +99 -0
- package/layer/server/api/oip/pdf.get.ts +70 -0
- package/layer/server/api/oip/reports.get.ts +98 -0
- package/layer/server/api/oip/resource-types.get.ts +22 -0
- package/package.json +1 -1
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Carte d'une publication PubMed, portee de France Augmented Science. Le menu
|
|
3
|
+
d'export de la carte n'exporte plus que les champs lus dans la carte (cf.
|
|
4
|
+
RmResultCard) : l'export complet (useGenerateExcel, auteurs RPPS) reste a FAS.
|
|
5
|
+
-->
|
|
6
|
+
<template>
|
|
7
|
+
<RmResultCard
|
|
8
|
+
class="pub_card oip-science"
|
|
9
|
+
clickable
|
|
10
|
+
:count="dateFormat(data.article_date)"
|
|
11
|
+
:count-label="$t('oipScience.cards.firstPublished')"
|
|
12
|
+
:count-extra="[$t('oipScience.cards.lastRevised'), dateFormat(data.revised_date)]"
|
|
13
|
+
:lang="lang"
|
|
14
|
+
:link="detailsUrl"
|
|
15
|
+
@click="openCard($event, nav, 'PubMed', id)"
|
|
16
|
+
>
|
|
17
|
+
<template #code>
|
|
18
|
+
<RmCopyCode v-if="id" label="PMID" :value="String(id)" :lang="lang" />
|
|
19
|
+
<RmButton
|
|
20
|
+
v-if="getSection"
|
|
21
|
+
class="abstract_btn"
|
|
22
|
+
variant="secondary"
|
|
23
|
+
size="sm"
|
|
24
|
+
@click.stop="() => (showModal = true)"
|
|
25
|
+
>
|
|
26
|
+
{{ $t('oipScience.cards.readAbstract') }}
|
|
27
|
+
</RmButton>
|
|
28
|
+
</template>
|
|
29
|
+
|
|
30
|
+
<template #title>
|
|
31
|
+
<RmTextHighlight
|
|
32
|
+
:queries="getSearchHighlight"
|
|
33
|
+
:text="ifNoRes(data.title)"
|
|
34
|
+
/>
|
|
35
|
+
</template>
|
|
36
|
+
|
|
37
|
+
<template #actions>
|
|
38
|
+
<component
|
|
39
|
+
:is="projectButton"
|
|
40
|
+
v-if="projectButton"
|
|
41
|
+
:resource-id="id"
|
|
42
|
+
type="PubMed"
|
|
43
|
+
:label="data.title"
|
|
44
|
+
compact
|
|
45
|
+
/>
|
|
46
|
+
</template>
|
|
47
|
+
|
|
48
|
+
<template #meta>
|
|
49
|
+
<RmTag v-if="data.delete" variant="rose">{{ $t('oipScience.cards.articleDeleted') }}</RmTag>
|
|
50
|
+
<span
|
|
51
|
+
v-if="typeof matchScore === 'number'"
|
|
52
|
+
class="match-score-badge"
|
|
53
|
+
:class="matchScore >= 0.85 ? 'score-high' : 'score-low'"
|
|
54
|
+
:data-tooltip="$t('oipScience.common.matchingScoreTooltip')"
|
|
55
|
+
>{{ $t('oipScience.cards.matchingScore') }} : {{ Math.round(matchScore * 100) }}%</span>
|
|
56
|
+
</template>
|
|
57
|
+
|
|
58
|
+
<RmDrawer v-model="showModal" size="md" :label="$t('oipScience.cards.pubmedAbstract')">
|
|
59
|
+
<template #header>
|
|
60
|
+
<p class="abstract_drawer_title">{{ $t('oipScience.cards.pubmedAbstract') }}</p>
|
|
61
|
+
</template>
|
|
62
|
+
<div class="oip-science oip_column_grid gap-24">
|
|
63
|
+
<RmTextHighlight
|
|
64
|
+
:queries="getSearchHighlight"
|
|
65
|
+
:text="ifNoRes(data.title)"
|
|
66
|
+
class="kk_title_medium"
|
|
67
|
+
/>
|
|
68
|
+
<div v-if="getSection" class="oip_grid gap-16">
|
|
69
|
+
<div v-for="(item, index) in getSection" :key="index">
|
|
70
|
+
<div
|
|
71
|
+
class="oip_grid gap-24"
|
|
72
|
+
:id="item?.label?.toLowerCase()"
|
|
73
|
+
>
|
|
74
|
+
<div class="oip_grid gap-4">
|
|
75
|
+
<h1 class="kk_title_medium_2">
|
|
76
|
+
{{ formatName(item.label) }}
|
|
77
|
+
</h1>
|
|
78
|
+
</div>
|
|
79
|
+
|
|
80
|
+
<RmTextHighlight
|
|
81
|
+
:queries="getSearchHighlight"
|
|
82
|
+
:text="item.text"
|
|
83
|
+
class="oip_body"
|
|
84
|
+
/>
|
|
85
|
+
</div>
|
|
86
|
+
</div>
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
<template v-if="data.pmc && data.pmc !== ''" #footer>
|
|
90
|
+
<RmButton suffix-icon="ArrowSquareOut" @click="openLink()">
|
|
91
|
+
{{ $t('oipScience.cards.openFreeArticle') }}
|
|
92
|
+
</RmButton>
|
|
93
|
+
</template>
|
|
94
|
+
</RmDrawer>
|
|
95
|
+
|
|
96
|
+
<div class="oip_grid gap-16">
|
|
97
|
+
<OipScienceCommonTableTags
|
|
98
|
+
icon="Users"
|
|
99
|
+
:title="$t('oipScience.cards.authors')"
|
|
100
|
+
:values="getAuthors.filter((x) => x && x !== ' ')"
|
|
101
|
+
:highlightQueries="getSearchHighlight"
|
|
102
|
+
:is-full-results="false"
|
|
103
|
+
></OipScienceCommonTableTags>
|
|
104
|
+
|
|
105
|
+
<OipScienceCommonTableTags
|
|
106
|
+
v-if="prefs.articleType"
|
|
107
|
+
icon="Article"
|
|
108
|
+
:title="$t('oipScience.common.articleType')"
|
|
109
|
+
:values="getArticleType"
|
|
110
|
+
:highlightQueries="getSearchHighlight"
|
|
111
|
+
></OipScienceCommonTableTags>
|
|
112
|
+
<OipScienceCommonTableTags
|
|
113
|
+
icon="BookOpen"
|
|
114
|
+
:title="$t('oipScience.common.journalName')"
|
|
115
|
+
:values="getJournalName"
|
|
116
|
+
:highlightQueries="getSearchHighlight"
|
|
117
|
+
></OipScienceCommonTableTags>
|
|
118
|
+
|
|
119
|
+
<OipScienceCommonTableTags
|
|
120
|
+
v-if="prefs.molecules"
|
|
121
|
+
icon="Molecule"
|
|
122
|
+
:title="$t('oipScience.common.molecules')"
|
|
123
|
+
:values="getDrugs"
|
|
124
|
+
:highlightQueries="getSearchHighlight"
|
|
125
|
+
></OipScienceCommonTableTags>
|
|
126
|
+
|
|
127
|
+
<OipScienceCommonTableTags
|
|
128
|
+
v-if="prefs.keywords"
|
|
129
|
+
icon="TextAa"
|
|
130
|
+
:title="$t('oipScience.common.keywords')"
|
|
131
|
+
:values="getKeywords"
|
|
132
|
+
:highlightQueries="getSearchHighlight"
|
|
133
|
+
:is-full-results="false"
|
|
134
|
+
></OipScienceCommonTableTags>
|
|
135
|
+
<OipScienceCommonTableTags
|
|
136
|
+
v-if="prefs.mesh"
|
|
137
|
+
icon="Tag"
|
|
138
|
+
:title="$t('oipScience.common.meshTerms')"
|
|
139
|
+
:values="getMeshTerms"
|
|
140
|
+
:highlightQueries="getSearchHighlight"
|
|
141
|
+
:is-full-results="false"
|
|
142
|
+
></OipScienceCommonTableTags>
|
|
143
|
+
|
|
144
|
+
<OipScienceCommonTableTags
|
|
145
|
+
v-if="prefs.rare && getRareDiseases.length > 0"
|
|
146
|
+
icon="Bandaids"
|
|
147
|
+
:title="$t('oipScience.common.rareDiseases')"
|
|
148
|
+
:values="getRareDiseases"
|
|
149
|
+
:highlightQueries="getSearchHighlight"
|
|
150
|
+
></OipScienceCommonTableTags>
|
|
151
|
+
<OipScienceCommonTableTags
|
|
152
|
+
v-if="prefs.oncoIcd10 && (shouldShowCancerTags && getICD10.length > 0)"
|
|
153
|
+
icon="FaceMask"
|
|
154
|
+
title="ICD 10"
|
|
155
|
+
:values="getICD10"
|
|
156
|
+
:highlightQueries="getSearchHighlight"
|
|
157
|
+
:isFullResults="false"
|
|
158
|
+
:result-size-limit="2"
|
|
159
|
+
></OipScienceCommonTableTags>
|
|
160
|
+
<OipScienceCommonTableTags
|
|
161
|
+
v-if="prefs.oncoTerms && (shouldShowCancerTags && getOncologyTerms.length > 0)"
|
|
162
|
+
icon="ListMagnifyingGlass"
|
|
163
|
+
:title="$t('oipScience.common.oncologyTerms')"
|
|
164
|
+
:values="getOncologyTerms"
|
|
165
|
+
:highlightQueries="getSearchHighlight"
|
|
166
|
+
:isFullResults="false"
|
|
167
|
+
:result-size-limit="2"
|
|
168
|
+
:hoverText="$t('oipScience.cards.oncologyTermsHover')"
|
|
169
|
+
></OipScienceCommonTableTags>
|
|
170
|
+
</div>
|
|
171
|
+
|
|
172
|
+
<!-- Ce que la recherche a reellement matche, extraits compris : souvent
|
|
173
|
+
dans un texte que la carte ne montre pas. -->
|
|
174
|
+
<OipScienceElasticMatchExplain :match="data._match" />
|
|
175
|
+
|
|
176
|
+
<template #footer>
|
|
177
|
+
<div class="oip_grid gap-8">
|
|
178
|
+
<OipScienceCommonSource :sources="['PubMed']" :lang="lang" />
|
|
179
|
+
<p v-if="data.pmc && data.pmc !== ''">
|
|
180
|
+
{{ $t('oipScience.cards.freeArticleAvailable') }}
|
|
181
|
+
<a
|
|
182
|
+
target="_blank"
|
|
183
|
+
class="kk_text link cool_grey"
|
|
184
|
+
:href="`https://pmc.ncbi.nlm.nih.gov/articles/${data.pmc}/pdf`"
|
|
185
|
+
>
|
|
186
|
+
{{ $t('oipScience.cards.read') }} ↗
|
|
187
|
+
</a>
|
|
188
|
+
</p>
|
|
189
|
+
</div>
|
|
190
|
+
</template>
|
|
191
|
+
</RmResultCard>
|
|
192
|
+
</template>
|
|
193
|
+
|
|
194
|
+
<script setup lang="ts">
|
|
195
|
+
import type { PropType } from 'vue';
|
|
196
|
+
import {
|
|
197
|
+
ifNoRes,
|
|
198
|
+
dateFormat,
|
|
199
|
+
formatName,
|
|
200
|
+
removeDuplicate,
|
|
201
|
+
dedupNormalized,
|
|
202
|
+
capitalizeFirstLetter,
|
|
203
|
+
} from '../../../oip-science/utils/styleAndFormat';
|
|
204
|
+
import { openCard } from '../../../oip-science/utils/b-openCard';
|
|
205
|
+
|
|
206
|
+
// Types de France Augmented Science (types/Pubmed) : pas portes.
|
|
207
|
+
type Pubmed = any;
|
|
208
|
+
type PubmedGenomics = any;
|
|
209
|
+
type PubmedAuthor = any;
|
|
210
|
+
type PubmedRareDiseases = any;
|
|
211
|
+
type PubmedMolecule = any;
|
|
212
|
+
|
|
213
|
+
const showModal = ref(false);
|
|
214
|
+
const { locale } = useI18n();
|
|
215
|
+
const lang = computed(() => (locale.value === 'en' ? 'en' : 'fr'));
|
|
216
|
+
const nav = useOipResourceNav();
|
|
217
|
+
const { projectButton } = useOipResourceHooks();
|
|
218
|
+
|
|
219
|
+
const props = defineProps({
|
|
220
|
+
data: {
|
|
221
|
+
type: Object as PropType<Pubmed>,
|
|
222
|
+
default: () => ({} as Pubmed),
|
|
223
|
+
},
|
|
224
|
+
id: {
|
|
225
|
+
type: String,
|
|
226
|
+
default: '',
|
|
227
|
+
},
|
|
228
|
+
matchScore: {
|
|
229
|
+
type: Number,
|
|
230
|
+
default: null,
|
|
231
|
+
},
|
|
232
|
+
matchMethod: {
|
|
233
|
+
type: String,
|
|
234
|
+
default: null,
|
|
235
|
+
},
|
|
236
|
+
/** Termes de la recherche a surligner (filterStore dans FAS). */
|
|
237
|
+
highlight: {
|
|
238
|
+
type: Array as PropType<string[]>,
|
|
239
|
+
default: () => [],
|
|
240
|
+
},
|
|
241
|
+
/**
|
|
242
|
+
* Rangees choisies dans « Personnaliser » (store cardPrefs de FAS). Sans
|
|
243
|
+
* choix, FAS n'en affiche aucune en plus pour PubMed.
|
|
244
|
+
*/
|
|
245
|
+
prefs: {
|
|
246
|
+
type: Object as PropType<Record<string, boolean>>,
|
|
247
|
+
default: () => ({}),
|
|
248
|
+
},
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
function openLink() {
|
|
252
|
+
const url = `https://pmc.ncbi.nlm.nih.gov/articles/${props.data.pmc}/pdf`;
|
|
253
|
+
window.open(url, '_blank');
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
const getArticleType = computed(() => {
|
|
257
|
+
return removeDuplicate(
|
|
258
|
+
(props.data.publication_types &&
|
|
259
|
+
props.data.publication_types.map((res: string) => res)) ??
|
|
260
|
+
[]
|
|
261
|
+
);
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
const shouldShowCancerTags = computed( () => {
|
|
265
|
+
return getArticleType.value.some( (type) =>
|
|
266
|
+
['Meta-Analysis', 'Systematic Review'].includes(type)
|
|
267
|
+
);
|
|
268
|
+
})
|
|
269
|
+
|
|
270
|
+
const getJournalName = computed(() => {
|
|
271
|
+
return [ifNoRes(props.data.journal)];
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
const getDrugs = computed(() => {
|
|
275
|
+
return removeDuplicate(
|
|
276
|
+
(props.data.chemical_list &&
|
|
277
|
+
props.data.chemical_list.map((res: string) => res)) ??
|
|
278
|
+
[]
|
|
279
|
+
);
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
const getKeywords = computed(() => {
|
|
283
|
+
return removeDuplicate(
|
|
284
|
+
(props.data.keywords &&
|
|
285
|
+
props.data.keywords.map((res: string) => res).filter((y: string) => y !== '')) ??
|
|
286
|
+
[]
|
|
287
|
+
);
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
const getMeshTerms = computed(() => {
|
|
291
|
+
return removeDuplicate(
|
|
292
|
+
(props.data.mesh_terms &&
|
|
293
|
+
props.data.mesh_terms.map((res: string) => res)) ??
|
|
294
|
+
[]
|
|
295
|
+
);
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
const getAuthors = computed(() => {
|
|
299
|
+
return removeDuplicate(
|
|
300
|
+
(props.data.authors &&
|
|
301
|
+
props.data.authors.map(
|
|
302
|
+
(res: PubmedAuthor) => `${res.forename} ${res.lastname}`
|
|
303
|
+
)) ??
|
|
304
|
+
[]
|
|
305
|
+
);
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
const getRareDiseases = computed(() => {
|
|
309
|
+
return removeDuplicate(
|
|
310
|
+
(props.data.rare_diseases &&
|
|
311
|
+
props.data.rare_diseases.map(
|
|
312
|
+
(res: PubmedRareDiseases) => res.concat_disease_name_orpha_code
|
|
313
|
+
)) ??
|
|
314
|
+
[]
|
|
315
|
+
);
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
const getGenomicsSymbols = computed(() => {
|
|
319
|
+
if (!props.data.genomics) return [];
|
|
320
|
+
return props.data.genomics.map((g: PubmedGenomics) => g.gene_symbol);
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
const getSearchHighlight = computed(() => props.highlight);
|
|
324
|
+
|
|
325
|
+
const getSection = computed(() => {
|
|
326
|
+
if (props.data?.sections && props.data?.sections.length) {
|
|
327
|
+
return props.data?.sections.sort((a: any, b: any) => a?.order - b?.order);
|
|
328
|
+
} else {
|
|
329
|
+
return null;
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
const getMolecules = computed(() => {
|
|
334
|
+
const molecules = props.data.molecules ?? [];
|
|
335
|
+
return molecules
|
|
336
|
+
.map((m: PubmedMolecule) => m?.label?.trim())
|
|
337
|
+
.filter((label: any): label is string => !!label)
|
|
338
|
+
.map((label: string) => capitalizeFirstLetter(label));
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
const getICD10 = computed(() => {
|
|
342
|
+
const list = props.data.diseases?.flatMap((d: any) => d.icd10?.map((i: any) => i.combined_label)) ?? [];
|
|
343
|
+
// dedupNormalized collapses case + singular/plural duplicates
|
|
344
|
+
// (Cancer/cancer, Neoplasms/Neoplasm) so the tag list stays tight.
|
|
345
|
+
return dedupNormalized(list);
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
const getOncologyTerms = computed(() => {
|
|
349
|
+
const terms = props.data.diseases?.flatMap((o: any) => o.section?.map((x: any) => x.label) ?? []) ?? [];
|
|
350
|
+
return dedupNormalized(terms.filter((term: any): term is string => !!term));
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
const detailsUrl = computed(() => nav.href('PubMed', props.id));
|
|
354
|
+
</script>
|
|
355
|
+
|
|
356
|
+
<style scoped>
|
|
357
|
+
.match-score-badge {
|
|
358
|
+
display: inline-block;
|
|
359
|
+
padding: 2px 8px;
|
|
360
|
+
border-radius: 12px;
|
|
361
|
+
font-size: 12px;
|
|
362
|
+
font-weight: 600;
|
|
363
|
+
margin-left: 4px;
|
|
364
|
+
cursor: help;
|
|
365
|
+
}
|
|
366
|
+
.score-high { background: var(--color-success-bg); color: var(--color-success); }
|
|
367
|
+
.score-low { background: var(--color-warning-bg); color: var(--color-warning); }
|
|
368
|
+
|
|
369
|
+
.abstract_drawer_title {
|
|
370
|
+
margin: 0;
|
|
371
|
+
font-size: var(--font-16);
|
|
372
|
+
font-weight: var(--weight-bold);
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/* Bouton « Read abstract » a la hauteur du tag PMID (RmCopyCode), dans le
|
|
376
|
+
violet clair du bandeau de projet. */
|
|
377
|
+
.abstract_btn.rm-button {
|
|
378
|
+
background: color-mix(in srgb, var(--rm-shell-accent) 16%, var(--rm-shell-surface));
|
|
379
|
+
border-color: color-mix(in srgb, var(--rm-shell-accent) 40%, transparent);
|
|
380
|
+
color: var(--color-primary);
|
|
381
|
+
padding: var(--space-2) var(--space-8);
|
|
382
|
+
border-radius: var(--radius-sm);
|
|
383
|
+
font-size: var(--font-13);
|
|
384
|
+
line-height: 1.4;
|
|
385
|
+
}
|
|
386
|
+
.abstract_btn.rm-button:hover:not(:disabled) {
|
|
387
|
+
background: color-mix(in srgb, var(--rm-shell-accent) 28%, var(--rm-shell-surface));
|
|
388
|
+
border-color: var(--rm-shell-accent);
|
|
389
|
+
color: var(--color-primary);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/* Memes dates que les cartes d'essais : libelle au-dessus de sa date,
|
|
393
|
+
countExtra porte [libellé, date]. */
|
|
394
|
+
.pub_card :deep(.rm-rcard__count) {
|
|
395
|
+
flex-basis: 176px;
|
|
396
|
+
align-items: flex-start;
|
|
397
|
+
text-align: left;
|
|
398
|
+
}
|
|
399
|
+
.pub_card :deep(.rm-rcard__count-label) { order: 1; font-size: 10px; }
|
|
400
|
+
.pub_card :deep(.rm-rcard__count-value) { order: 2; font-size: 16px; white-space: nowrap; }
|
|
401
|
+
.pub_card :deep(.rm-rcard__count-extra) { order: 3; }
|
|
402
|
+
.pub_card :deep(.rm-rcard__count-extra:nth-child(3)) {
|
|
403
|
+
margin-top: 10px;
|
|
404
|
+
color: var(--text-muted);
|
|
405
|
+
font-size: 10px;
|
|
406
|
+
font-weight: var(--weight-semibold);
|
|
407
|
+
letter-spacing: 0.08em;
|
|
408
|
+
text-transform: uppercase;
|
|
409
|
+
}
|
|
410
|
+
.pub_card :deep(.rm-rcard__count-extra:nth-child(4)) {
|
|
411
|
+
margin-top: var(--space-2);
|
|
412
|
+
font-size: 16px;
|
|
413
|
+
font-weight: var(--weight-bold);
|
|
414
|
+
line-height: 1.1;
|
|
415
|
+
white-space: nowrap;
|
|
416
|
+
}
|
|
417
|
+
</style>
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Onglet « Essais cliniques » d'une publication PubMed (portage de la page
|
|
3
|
+
/pubmed/[id]/clinical-trials de France Augmented Science).
|
|
4
|
+
-->
|
|
5
|
+
<template>
|
|
6
|
+
<div class="oip-science">
|
|
7
|
+
<OipScienceClinicalTrialsLinkedList
|
|
8
|
+
:nct-ids="nctIds"
|
|
9
|
+
:euct-ids="euctIds"
|
|
10
|
+
:title="$t('oipScience.common.clinicalTrials')"
|
|
11
|
+
:sources="['PubMed', 'CT.gov', 'EUCT']"
|
|
12
|
+
index-last-update="PubMed"
|
|
13
|
+
:loading="isLoadingQueryPubmed || isLoadingEuct"
|
|
14
|
+
/>
|
|
15
|
+
</div>
|
|
16
|
+
</template>
|
|
17
|
+
|
|
18
|
+
<script setup lang="ts">
|
|
19
|
+
import indexConfig from '../../../oip-science/indexConfig.json';
|
|
20
|
+
import usePubmed from '../../../oip-science/composables/usePubmed';
|
|
21
|
+
import useOipElastic from '../../../oip-science/composables/useOipElastic';
|
|
22
|
+
|
|
23
|
+
const props = withDefaults(
|
|
24
|
+
defineProps<{
|
|
25
|
+
/** PMID de la publication. */
|
|
26
|
+
id: string;
|
|
27
|
+
highlight?: string[];
|
|
28
|
+
lang?: 'fr' | 'en';
|
|
29
|
+
}>(),
|
|
30
|
+
{ highlight: () => [], lang: 'fr' },
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
const { findPubmedById, resultsQueryPubmed, isLoadingQueryPubmed } = usePubmed();
|
|
34
|
+
const { queryCustomElastic } = useOipElastic();
|
|
35
|
+
|
|
36
|
+
const nctIds = computed<string[]>(() => (resultsQueryPubmed.value as any)?.nct_ids || []);
|
|
37
|
+
|
|
38
|
+
// Les essais EUCT lies : ceux que la publication cite, et ceux qui citent la
|
|
39
|
+
// publication (`pubmed_citations_id`).
|
|
40
|
+
const euctIds = ref<string[]>([]);
|
|
41
|
+
const isLoadingEuct = ref(true);
|
|
42
|
+
|
|
43
|
+
async function load() {
|
|
44
|
+
if (!props.id) return;
|
|
45
|
+
const pubmedId = props.id.toString();
|
|
46
|
+
isLoadingEuct.value = true;
|
|
47
|
+
try {
|
|
48
|
+
await findPubmedById({ id: pubmedId });
|
|
49
|
+
const cited: string[] = (resultsQueryPubmed.value as any)?.euct_ids || [];
|
|
50
|
+
const should: any[] = [{ match: { pubmed_citations_id: pubmedId } }];
|
|
51
|
+
if (cited.length) should.push({ terms: { 'euct_number.keyword': cited } });
|
|
52
|
+
const res = await queryCustomElastic({
|
|
53
|
+
index: indexConfig.euct.index,
|
|
54
|
+
cluster: indexConfig.euct.cluster,
|
|
55
|
+
customQuery: {
|
|
56
|
+
size: 1000,
|
|
57
|
+
_source: ['euct_number'],
|
|
58
|
+
query: { bool: { should, minimum_should_match: 1 } },
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
euctIds.value = [...new Set<string>((res?.results || []).map((d: any) => d?.euct_number).filter(Boolean))];
|
|
62
|
+
} catch (e) {
|
|
63
|
+
console.error(e);
|
|
64
|
+
} finally {
|
|
65
|
+
isLoadingEuct.value = false;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
onMounted(load);
|
|
70
|
+
watch(() => props.id, load);
|
|
71
|
+
</script>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Un appel a projets (PHRC) range dans un projet : sa carte de resultat, celle
|
|
3
|
+
de la liste des appels a projets de France Augmented Science, relue dans
|
|
4
|
+
l'index par son identifiant.
|
|
5
|
+
-->
|
|
6
|
+
<template>
|
|
7
|
+
<div class="oip-science oip-sc-phrc">
|
|
8
|
+
<RmLoadingState v-if="pending" spinner />
|
|
9
|
+
<OipScienceAppelAProjetCards v-else-if="doc" :data="doc" :highlight="highlight" />
|
|
10
|
+
<RmEmptyState
|
|
11
|
+
v-else
|
|
12
|
+
icon="FileX"
|
|
13
|
+
:title="lang === 'en' ? 'Record unavailable' : 'Fiche indisponible'"
|
|
14
|
+
:text="lang === 'en' ? 'The record is no longer in the data.' : 'La fiche n\'est plus dans la donnée.'"
|
|
15
|
+
/>
|
|
16
|
+
</div>
|
|
17
|
+
</template>
|
|
18
|
+
|
|
19
|
+
<script setup lang="ts">
|
|
20
|
+
import { oipEsGet } from "../../../composables/useOipResources";
|
|
21
|
+
import indexConfig from "../../../oip-science/indexConfig.json";
|
|
22
|
+
|
|
23
|
+
const props = withDefaults(defineProps<{ id: string; highlight?: string[]; lang?: "fr" | "en" }>(), {
|
|
24
|
+
highlight: () => [],
|
|
25
|
+
lang: "fr",
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const { data: doc, pending } = useAsyncData(
|
|
29
|
+
() => `oip-phrc-${props.id}`,
|
|
30
|
+
async () => (await oipEsGet("science", indexConfig.phrc.index, props.id))?._source ?? null,
|
|
31
|
+
{ server: false, watch: [() => props.id] },
|
|
32
|
+
);
|
|
33
|
+
</script>
|
|
34
|
+
|
|
35
|
+
<style scoped>
|
|
36
|
+
.oip-sc-phrc {
|
|
37
|
+
padding: var(--space-24);
|
|
38
|
+
}
|
|
39
|
+
</style>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { Ref } from "vue";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Le sommaire d'une fiche de ressource (RmChaptersNav), ou qu'elle soit
|
|
5
|
+
* montee : page du cadre OIP 7 (qui defile `.rm-shell__main`, pas la fenetre)
|
|
6
|
+
* ou tiroir d'un projet. On defile le premier ancetre defilant, sous l'en-tete
|
|
7
|
+
* de fiche qui y colle.
|
|
8
|
+
*/
|
|
9
|
+
export function useOipChapterScroll(root: Ref<HTMLElement | null>) {
|
|
10
|
+
/** Le haut de la zone lue, dans la fenetre : le sommaire s'en sert pour l'onglet actif. */
|
|
11
|
+
const chaptersOffset = ref(0);
|
|
12
|
+
/** La hauteur ou le sommaire colle, sous l'en-tete de fiche. */
|
|
13
|
+
const stickyTop = ref(0);
|
|
14
|
+
|
|
15
|
+
function scroller(): HTMLElement | null {
|
|
16
|
+
let node = root.value?.parentElement ?? null;
|
|
17
|
+
while (node) {
|
|
18
|
+
const { overflowY } = getComputedStyle(node);
|
|
19
|
+
if (overflowY === "auto" || overflowY === "scroll") return node;
|
|
20
|
+
node = node.parentElement;
|
|
21
|
+
}
|
|
22
|
+
return document.querySelector(".rm-shell__main");
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function stickyHeaderHeight() {
|
|
26
|
+
return (scroller()?.querySelector(".rm-page-header") as HTMLElement | null)?.offsetHeight ?? 0;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
onMounted(() => {
|
|
30
|
+
stickyTop.value = stickyHeaderHeight() + 8;
|
|
31
|
+
chaptersOffset.value = (scroller()?.getBoundingClientRect().top ?? 0) + stickyTop.value;
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
function scrollToChapter(id: string) {
|
|
35
|
+
const main = scroller();
|
|
36
|
+
const section = root.value?.querySelector(`#${CSS.escape(id)}`) as HTMLElement | null;
|
|
37
|
+
if (!main || !section) return;
|
|
38
|
+
const top = section.getBoundingClientRect().top - main.getBoundingClientRect().top + main.scrollTop;
|
|
39
|
+
main.scrollTo({ top: top - stickyHeaderHeight() - 8, behavior: "smooth" });
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return { chaptersOffset, stickyTop, scrollToChapter };
|
|
43
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { Component, InjectionKey } from "vue";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Ce que l'app prete aux vues de ressources du layer, et qu'elles ne peuvent
|
|
5
|
+
* pas porter elles-memes : son bouton Projet (son client de l'API, son projet
|
|
6
|
+
* actif) et l'ouverture de son panneau Sources. Une app les fournit une fois,
|
|
7
|
+
* par un plugin :
|
|
8
|
+
*
|
|
9
|
+
* nuxtApp.vueApp.provide(OIP_RESOURCE_HOOKS, { projectButton, openSource })
|
|
10
|
+
*
|
|
11
|
+
* Absents, la vue s'en passe : pas de bouton, source non cliquable.
|
|
12
|
+
*/
|
|
13
|
+
export interface OipResourceHooks {
|
|
14
|
+
/**
|
|
15
|
+
* Bouton « Projet » d'une carte ou d'une fiche. Props : `resourceId`,
|
|
16
|
+
* `type` (le resourceType), `label` facultatif, `compact` facultatif.
|
|
17
|
+
*/
|
|
18
|
+
projectButton?: Component | null;
|
|
19
|
+
/** Ouvre le panneau Sources du rail sur la fiche Directus `uuid`. */
|
|
20
|
+
openSource?: (uuid: string) => void;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const OIP_RESOURCE_HOOKS: InjectionKey<OipResourceHooks> = Symbol("oip-resource-hooks");
|
|
24
|
+
|
|
25
|
+
export function useOipResourceHooks(): OipResourceHooks {
|
|
26
|
+
return inject(OIP_RESOURCE_HOOKS, {});
|
|
27
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { InjectionKey } from "vue";
|
|
2
|
+
import { oipResourceAppUrl, oipResourceSpec, type OipResourceApp } from "../utils/oipResources";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Les liens d'une fiche de ressource vers une autre (l'auteur d'une
|
|
6
|
+
* publication vers sa fiche professionnel, un essai vers son centre...).
|
|
7
|
+
*
|
|
8
|
+
* Une vue du layer ne sait pas ou elle est montee : dans une page, le lien
|
|
9
|
+
* navigue (sur place si la fiche est de l'app, dans un onglet sinon) ; dans le
|
|
10
|
+
* tiroir d'un projet, il empile un tiroir de plus. Le tiroir fournit son
|
|
11
|
+
* propre `open` ; ailleurs, c'est la navigation par defaut.
|
|
12
|
+
*/
|
|
13
|
+
export interface OipResourceNav {
|
|
14
|
+
/** Ouvre la fiche (onglet `tab`, sinon le premier). */
|
|
15
|
+
open: (type: string, id: string, tab?: string) => void;
|
|
16
|
+
/** L'URL de la fiche, pour un vrai lien (Ctrl/Cmd-clic). */
|
|
17
|
+
href: (type: string, id: string, tab?: string) => string;
|
|
18
|
+
/**
|
|
19
|
+
* Une page d'une app qui n'est pas une fiche du layer (un appel a projets
|
|
20
|
+
* de France Augmented Science...) : sur place dans cette app, dans un
|
|
21
|
+
* onglet ailleurs. `appHref` en donne l'URL.
|
|
22
|
+
*/
|
|
23
|
+
openApp: (app: OipResourceApp, path: string) => void;
|
|
24
|
+
appHref: (app: OipResourceApp, path: string) => string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export const OIP_RESOURCE_NAV: InjectionKey<OipResourceNav> = Symbol("oip-resource-nav");
|
|
28
|
+
|
|
29
|
+
/** L'app qui affiche : `oip.resourceApp` de son app.config. */
|
|
30
|
+
export function useOipResourceApp(): OipResourceApp | "" {
|
|
31
|
+
return ((useAppConfig() as any).oip?.resourceApp ?? "") as OipResourceApp | "";
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** La navigation par defaut : celle d'une page. */
|
|
35
|
+
export function useOipDefaultResourceNav(): OipResourceNav {
|
|
36
|
+
const app = useOipResourceApp();
|
|
37
|
+
const localePath = useLocalePath();
|
|
38
|
+
const { locale } = useI18n();
|
|
39
|
+
|
|
40
|
+
function target(type: string, id: string, tab?: string) {
|
|
41
|
+
const spec = oipResourceSpec(type);
|
|
42
|
+
if (!spec) return null;
|
|
43
|
+
const path = spec.detailPath(id, tab);
|
|
44
|
+
if (spec.app === app) return { local: true, url: localePath(path) };
|
|
45
|
+
return { local: false, url: oipResourceAppUrl(spec.app, path, lang()) };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const lang = () => (locale.value === "en" ? "en" : "fr");
|
|
49
|
+
const appHref = (target: OipResourceApp, path: string) =>
|
|
50
|
+
target === app ? localePath(path) : oipResourceAppUrl(target, path, lang());
|
|
51
|
+
const go = (url: string, local: boolean) => (local ? navigateTo(url) : window.open(url, "_blank", "noopener"));
|
|
52
|
+
|
|
53
|
+
return {
|
|
54
|
+
href: (type, id, tab) => target(type, id, tab)?.url ?? "",
|
|
55
|
+
open(type, id, tab) {
|
|
56
|
+
const to = target(type, id, tab);
|
|
57
|
+
if (to) go(to.url, to.local);
|
|
58
|
+
},
|
|
59
|
+
appHref,
|
|
60
|
+
openApp: (target, path) => go(appHref(target, path), target === app),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function useOipResourceNav(): OipResourceNav {
|
|
65
|
+
return inject(OIP_RESOURCE_NAV, null) ?? useOipDefaultResourceNav();
|
|
66
|
+
}
|