@tekkare/romulus 0.1.250 → 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/dist/runtime/components/BarChart.vue +1 -0
- package/dist/runtime/components/ChoroplethMap.vue +4 -1
- package/dist/runtime/internal/geo/fr-regions.json +1 -1
- package/dist/runtime/utils/chart.d.ts +6 -3
- package/dist/runtime/utils/chart.js +15 -2
- 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
package/dist/module.json
CHANGED
|
@@ -12,6 +12,7 @@ const props = withDefaults(defineProps<{
|
|
|
12
12
|
/** Categories de l'axe : annees, libelles d'indicateur. */
|
|
13
13
|
categories: (string | number)[]
|
|
14
14
|
series: RmSeriesInput[]
|
|
15
|
+
/** Barres couchees, la premiere categorie en haut, comme dans un classement. */
|
|
15
16
|
horizontal?: boolean
|
|
16
17
|
height?: keyof typeof RM_CHART_HEIGHTS | number
|
|
17
18
|
description?: string
|
|
@@ -133,10 +133,13 @@ const ramp = computed(() => {
|
|
|
133
133
|
return props.reverseColors ? [...seq].reverse() : seq
|
|
134
134
|
})
|
|
135
135
|
|
|
136
|
+
// Les noms sont compares en NFC des deux cotes : un meme « ô » s'ecrit en un
|
|
137
|
+
// caractere ou en « o » suivi d'un accent combinant, et la region restait
|
|
138
|
+
// grise quand l'app et le trace ne l'ecrivaient pas pareil.
|
|
136
139
|
const byName = computed(() => {
|
|
137
140
|
const out = new Map<string, number | null>()
|
|
138
141
|
for (const entry of props.data) {
|
|
139
|
-
out.set(entry.name, entry.value === null || entry.value === undefined ? null : Number(entry.value))
|
|
142
|
+
out.set(entry.name.normalize('NFC'), entry.value === null || entry.value === undefined ? null : Number(entry.value))
|
|
140
143
|
}
|
|
141
144
|
return out
|
|
142
145
|
})
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"Auvergne-
|
|
2
|
+
"Auvergne-Rhône-Alpes": {
|
|
3
3
|
"path": "M1594.02 905.625L1592.46 900.11L1587.06 899.714L1587.64 896.318L1581.84 894.741L1581.35 884.209L1579.37 882.144L1581.8 874.258L1578.2 872.067L1572.78 872.447L1561.24 861.188L1562.65 844.212L1575.52 842.67L1581.44 838.84L1582.11 834.563L1586.54 830.972L1585.84 826.218L1582.86 823.834L1584.5 822.596L1575.11 809.523L1570.15 812.68L1568.32 811.301L1571.03 800.142L1560.23 798.149L1560.96 788.003L1567.44 776.23L1557.43 764.763L1561.16 761.018L1562.7 753.713L1547.99 749.472L1530.59 749.102L1502.15 764.039L1498.72 771.46L1501.65 772.752L1500.55 776.782L1503.01 780.764L1508.21 780.042L1506.7 784.792L1499.96 787.756L1488.89 797.902L1480.74 796.045L1479.07 798.637L1474.54 797.134L1470.66 799.636L1474.62 791.488L1471.42 789.171L1473.07 786.084L1488.46 780.797L1486.08 775.552L1493.31 762.945L1482.08 755.362L1461.26 778.642L1445.88 779.241L1444.65 771.796L1437.48 769.503L1437.09 766.346L1432.06 773.857L1428.87 774.088L1426 778.056L1419.05 778.701L1417.26 777.147L1418.29 769.549L1415.13 770.841L1413.77 765.837L1411.6 771.596L1411.5 767.27L1407.06 762.39L1408.75 760.54L1400.44 755.793L1403.08 753.435L1402.09 750.674L1393.71 748.883L1390.12 741.056L1386.49 739.451L1386.36 741.783L1383.03 741.072L1374.64 744.856L1366.9 740.114L1363.32 742.277L1362.39 739.51L1345.1 792.238L1339.33 791.671L1340.34 786.695L1338.64 784.376L1340.43 783.484L1334.4 779.549L1337.72 776.52L1334.44 772.29L1329.9 773.073L1327.87 778.534L1324.16 777.949L1322.55 774.165L1319.37 777.751L1315.68 778.211L1310.85 773.659L1305.19 773.872L1303.29 786.569L1300.55 788.688L1301.67 790.761L1296.88 790.885L1291.91 795.182L1288.57 794.951L1289.06 790.499L1286.02 792.002L1284.09 789.439L1280.94 792.601L1276.11 792.079L1272.91 788.778L1265.07 793.292L1260.82 793.307L1259.04 788.177L1250.26 786.379L1252.29 781.447L1250.34 775.495L1255.99 773.127L1256.23 769.88L1260.6 770.941L1262.44 768.986L1260.32 768.77L1259.4 758.033L1261.91 748.269L1256.92 745.847L1256.62 743.468L1247.99 744.224L1244.78 737.535L1241.2 739.482L1234.44 736.422L1233.84 726.602L1231.39 725.567L1232.28 722.749L1229.69 717.794L1223.35 710.324L1221.91 702.911L1218.05 701.84L1216.67 703.794L1218.92 707.624L1213.65 707.874L1215.06 713.114L1213.44 714.742L1211.82 713.006L1207.12 718.798L1203.97 718.922L1203.51 712.973L1200.1 709.238L1195.68 709.422L1192.24 713.887L1188.67 713.034L1187.31 708.927L1183.96 708.77L1176.56 715.063L1169 707.157L1161.44 703.481L1158.6 696.697L1151.38 695.238L1146.82 697.008L1139.23 704.334L1138.87 707.419L1133.78 706.024L1129.77 708.783L1126.84 704.069L1124.94 704.395L1123.43 708.521L1115.19 712.924L1115.58 717.82L1113.14 715.852L1109.41 717.789L1112.16 720.841L1109.02 725.577L1112.99 727.774L1114.16 734.144L1105.82 739.443L1100.53 737.357L1087.09 739.816L1083.08 746.934L1080.43 746.949L1078.52 754.755L1079.27 760.658L1084.24 762.076L1080.86 766.543L1087.55 771.593L1089.98 768.347L1093.59 775.793L1094.67 773.792L1100.08 776.238L1104.73 790.499L1108.99 795.395L1107.32 806.022L1109.61 811.966L1112.82 813.849L1111.9 820.554L1113.87 823.492L1108.86 825.832L1106.72 829.562L1108.02 832.403L1101.99 836.541L1101.18 839.991L1097.81 839.534L1097.33 839.642L1094.54 844.479L1091.58 843.852L1090.08 845.881L1095.94 855.989L1100.37 857.559L1104.5 863.436L1104.29 873.78L1100.49 873.993L1097.84 880.788L1100.83 886.133L1103.86 887.15L1100.64 907.634L1104.97 911.736L1099.87 915.08L1089.87 908.769L1085.79 908.738L1087.94 912.463L1087 920.13L1082.34 922.414L1079.46 927.446L1077.33 927.007L1074.29 933.442L1069.3 937.546L1070.04 943.624L1073.39 946.021L1067.77 950.303L1067.06 958.587L1063.87 957.94L1059.13 961.929L1063.86 970.727L1060.31 973.688L1059.43 973.462L1055.17 974.559L1056.82 980.776L1059.6 982.861L1057.68 985.368L1058.34 989.9L1066.92 1002.59L1062.44 1016.36L1065.57 1016.49L1066.93 1025.28L1070.78 1028.26L1072.6 1027.28L1071.58 1023.44L1080.09 1020.57L1083.47 1020.27L1086.2 1024.74L1100.23 1023.21L1101.9 1017.5L1108.37 1012.85L1107.28 1007.87L1112.67 1002.08L1113.12 994.033L1127.24 979.692L1131.23 984.076L1131.05 992.53L1134.46 989.74L1140.29 989.756L1143.35 1002.51L1146.78 1001.85L1148.56 1004.79L1145.83 1006.69L1148.34 1009.25L1148.52 1018.87L1153.31 1024.17L1157.1 1013.84L1159.42 1013.53L1158.08 1011.63L1160.17 1000.88L1162.98 995.248L1165.81 995.846L1166.29 991.032H1166.9L1166.27 987.989L1169.27 985.363L1175.7 991.528L1180.43 987.75L1179.07 984.508L1181.86 983.442L1181.03 980.575L1183.71 979.525L1185.72 981.883L1194.82 974.629L1194.88 976.912L1199.53 979.63L1199.71 986.175L1207.12 999.936L1209.2 997.269L1216.06 995.53L1218.03 997.015L1218.56 989.566L1225.01 989.535L1227.2 992.802L1226.36 996.609L1234.55 995.217L1241.6 1006.23L1244.25 1004.44L1244.4 1008.74L1248.65 1009.88L1247.09 1014.2L1249.55 1016.37L1248 1019.12L1251.06 1024.08L1251.59 1031.66L1254.37 1035.39L1256.88 1035.17L1260.68 1049.85L1269.29 1059.79L1266.25 1061.88L1268.11 1066L1265.83 1070.99L1267.06 1072.63L1275.78 1070.01L1277.16 1073.49L1280.96 1072.77L1289.36 1080.64L1292.71 1076.59L1292.62 1073.21L1296.73 1069.76L1303.74 1068.54L1304.12 1076.86L1308.63 1077.92L1310.25 1069.73L1315.81 1068.94L1316.52 1071.18L1320.44 1071.67L1321.48 1075.1L1331.16 1079.81L1331.29 1070.98L1346.01 1073.46L1349.25 1086.19L1355.74 1081.24L1360.26 1081.39L1374.94 1074.29L1376.7 1077.81L1380.12 1078.76L1384.65 1074.01L1386.35 1073.2L1384.8 1085.52L1393.06 1088.61L1395.13 1085.64L1400.35 1089.24L1406.44 1088.17L1409.6 1090.25L1409.41 1096.94L1415 1097.45L1417.09 1102.27L1422.25 1102.8L1426.31 1100.3L1430.72 1096.61L1428.75 1094.65L1429.84 1092.31L1432.73 1091.6L1436.76 1095.08L1435.86 1097.64L1440.91 1098.25L1441.35 1095.72L1437.84 1094.1L1438.06 1091.88L1441.76 1090.87L1441.78 1080.37H1437.57L1436.45 1075.37L1433.39 1074.54L1435.66 1070.48L1426.97 1070.96L1424.15 1067.91L1421.15 1069.86L1414.45 1064.34L1415.82 1061.91L1413.25 1056.86L1415.3 1055.66L1419.4 1057.73L1421.64 1055.08L1418.06 1053.52L1417.36 1045.86L1434 1049.99L1435.55 1045.73L1439.32 1045.4L1432.19 1039.2L1437.62 1029.08L1437.1 1023.13L1446.28 1025.04L1448.44 1021.6L1452.72 1022.89L1457.09 1017.36L1453.73 1014.97L1456.73 1007.02L1462.67 1008.96L1469.96 1006.87L1473.07 1003.71L1469.79 1000.22L1477.06 995.61L1481.2 998.546L1489.46 991.307L1501.56 993.167L1506.26 989.869L1511.03 993.737L1513.11 992.718L1513.38 980.038L1509.59 977.86L1509.71 971.115L1502 971.461L1496.97 968.5L1498.62 961.233L1501.23 960.3L1499.76 955.589L1501.36 952.774L1503.24 951.87L1506.52 954.641L1510.72 952.365L1514.01 955.468L1514.07 960.344L1523.26 963.082L1527.06 962.615L1526.39 956.909L1529.6 954.441L1532.94 955.887L1536.81 952.257L1542.43 954.487L1547.67 949.876L1554.28 950.254L1557.01 947.015L1565.67 951.895L1570.38 950.449L1570.4 945.671L1576 945.461L1581.98 937.844L1590.55 938.358L1596.23 932.427L1593.57 921.625L1599.22 916.603L1600.48 909.188L1594.02 905.625Z",
|
|
4
4
|
"departments": [
|
|
5
5
|
"Ain",
|
|
@@ -418,15 +418,18 @@ export declare function rmBarHorizontalOption(labels: string[], values: (number
|
|
|
418
418
|
type: string;
|
|
419
419
|
};
|
|
420
420
|
yAxis: {
|
|
421
|
-
|
|
422
|
-
show: boolean;
|
|
423
|
-
};
|
|
421
|
+
inverse: boolean;
|
|
424
422
|
axisLabel: {
|
|
423
|
+
width: number;
|
|
424
|
+
overflow: string;
|
|
425
425
|
formatter?: ((value: number) => string) | undefined;
|
|
426
426
|
fontSize: number;
|
|
427
427
|
color: string;
|
|
428
428
|
fontFamily: string;
|
|
429
429
|
};
|
|
430
|
+
splitLine: {
|
|
431
|
+
show: boolean;
|
|
432
|
+
};
|
|
430
433
|
axisLine: {
|
|
431
434
|
lineStyle: {
|
|
432
435
|
color: string;
|
|
@@ -193,9 +193,22 @@ export function rmBarHorizontalOption(labels, values, theme, palette, decal = fa
|
|
|
193
193
|
return {
|
|
194
194
|
...rmBaseOption(theme, decal),
|
|
195
195
|
tooltip: { ...rmBaseOption(theme, decal).tooltip, ...rmTooltipValue(valueFormatter) },
|
|
196
|
-
|
|
196
|
+
// `containLabel` reserve deja la place des libelles : une marge gauche
|
|
197
|
+
// fixe s'y ajoutait, et un libelle long ecrasait le trace au point de
|
|
198
|
+
// faire se chevaucher les graduations de l'axe des valeurs.
|
|
199
|
+
grid: { left: 8, right: 60, top: 16, bottom: 24, containLabel: true },
|
|
197
200
|
xAxis: { type: "value", ...axisCommon(theme, valueFormatter) },
|
|
198
|
-
yAxis: {
|
|
201
|
+
yAxis: {
|
|
202
|
+
type: "category",
|
|
203
|
+
data: labels,
|
|
204
|
+
...axisCommon(theme),
|
|
205
|
+
// ECharts empile les categories de bas en haut : la premiere valeur se
|
|
206
|
+
// lisait en bas, a l'inverse d'un classement ou d'un tableau.
|
|
207
|
+
inverse: true,
|
|
208
|
+
// Au-dela, le libelle est coupe ; l'infobulle le donne en entier.
|
|
209
|
+
axisLabel: { ...axisCommon(theme).axisLabel, width: 180, overflow: "truncate" },
|
|
210
|
+
splitLine: { show: false }
|
|
211
|
+
},
|
|
199
212
|
series: [{
|
|
200
213
|
type: "bar",
|
|
201
214
|
data: values,
|
package/layer/app/app.config.ts
CHANGED
|
@@ -39,6 +39,12 @@ export default defineAppConfig({
|
|
|
39
39
|
* pointe la route qui nourrit le panneau : une app peut la detourner vers
|
|
40
40
|
* la sienne (ou une autre API) sans toucher au panneau.
|
|
41
41
|
*/
|
|
42
|
+
/**
|
|
43
|
+
* L'app, pour les vues de ressources (cf. utils/oipResources) : une fiche
|
|
44
|
+
* dont c'est l'app d'origine s'ouvre sur place, les autres dans leur app.
|
|
45
|
+
* « france_augmented_science_app », « fr_drugs_app »... Vide : aucune.
|
|
46
|
+
*/
|
|
47
|
+
resourceApp: "",
|
|
42
48
|
/**
|
|
43
49
|
* Registre des index Elasticsearch (collection Directus ElasticIndices).
|
|
44
50
|
* `preload` : charge les noms au demarrage, pour les apps qui designent
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Resume d'une publication PubMed : l'onglet « Summary » de la fiche de France
|
|
3
|
+
Augmented Science, son app d'origine.
|
|
4
|
+
|
|
5
|
+
Une seule vue pour toutes les apps : la page /pubmed/[id]/summary de France
|
|
6
|
+
Augmented Science la monte, et le tiroir d'un projet la monte dans
|
|
7
|
+
n'importe quelle app du portail. Elle ne lit ni route ni store : l'id et
|
|
8
|
+
les termes a surligner lui sont donnes.
|
|
9
|
+
-->
|
|
10
|
+
<template>
|
|
11
|
+
<div ref="root" class="oip-pm">
|
|
12
|
+
<RmLoadingState v-if="pending" :lines="3" :chart-height="240" />
|
|
13
|
+
<RmEmptyState
|
|
14
|
+
v-else-if="!doc"
|
|
15
|
+
icon="FileX"
|
|
16
|
+
:title="en ? 'Record unavailable' : 'Fiche indisponible'"
|
|
17
|
+
:text="en ? 'The record is no longer in the data.' : 'La fiche n\'est plus dans la donnée.'"
|
|
18
|
+
/>
|
|
19
|
+
<div v-else class="oip-pm__layout">
|
|
20
|
+
<div class="oip-pm__nav">
|
|
21
|
+
<RmChaptersNav
|
|
22
|
+
class="oip-pm__chapters"
|
|
23
|
+
:chapters="chapters"
|
|
24
|
+
:title="en ? 'Chapters' : 'Chapitres'"
|
|
25
|
+
:offset="chaptersOffset"
|
|
26
|
+
:style="{ top: `${stickyTop}px` }"
|
|
27
|
+
@select="scrollToChapter"
|
|
28
|
+
/>
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
<div class="oip-pm__content">
|
|
32
|
+
<section id="introduction" class="oip-pm__card">
|
|
33
|
+
<div class="oip-pm__head">
|
|
34
|
+
<RmTag v-if="doc.delete" variant="rose">
|
|
35
|
+
{{ en ? "Article has been deleted" : "L'article a été supprimé" }}
|
|
36
|
+
</RmTag>
|
|
37
|
+
<h2 class="oip-pm__title">Introduction</h2>
|
|
38
|
+
<OipResourceSource :uuid="PUBMED_SOURCE_UUID" :lang="lang" />
|
|
39
|
+
</div>
|
|
40
|
+
|
|
41
|
+
<OipResourceField :label="en ? 'Full Title' : 'Titre complet'" :text="orNA(doc.title)" :highlight="highlight" :lang="lang" />
|
|
42
|
+
<OipResourceField
|
|
43
|
+
:label="en ? 'First Published' : 'Première publication'"
|
|
44
|
+
:text="doc.article_date ? longDate(doc.article_date) : 'N/A'"
|
|
45
|
+
:lang="lang"
|
|
46
|
+
/>
|
|
47
|
+
<OipResourceTags v-for="group in tagGroups" :key="group.label" v-bind="group" :highlight="highlight" :lang="lang" />
|
|
48
|
+
</section>
|
|
49
|
+
|
|
50
|
+
<section v-for="section in sections" :id="anchor(section.label)" :key="section.label" class="oip-pm__card">
|
|
51
|
+
<h2 class="oip-pm__title">{{ titleCase(section.label) }}</h2>
|
|
52
|
+
<RmTextHighlight class="oip-pm__body" :queries="highlight" :text="section.text" :lang="lang" />
|
|
53
|
+
</section>
|
|
54
|
+
|
|
55
|
+
<section v-if="hasLinks" id="links" class="oip-pm__card">
|
|
56
|
+
<h2 class="oip-pm__title">{{ en ? "Links" : "Liens" }}</h2>
|
|
57
|
+
<div v-if="!doc.delete" class="oip-pm__link">
|
|
58
|
+
<p class="oip-pm__link-label">
|
|
59
|
+
<RmIcon name="Link" :size="12" color="var(--text-muted)" />
|
|
60
|
+
{{ en ? "Pubmed article" : "Article PubMed" }}
|
|
61
|
+
</p>
|
|
62
|
+
<a :href="`https://pubmed.ncbi.nlm.nih.gov/${id}/`" target="_blank" rel="noopener">
|
|
63
|
+
https://pubmed.ncbi.nlm.nih.gov/<b>{{ id }}</b>/
|
|
64
|
+
</a>
|
|
65
|
+
</div>
|
|
66
|
+
<div v-if="doc.doi" class="oip-pm__link">
|
|
67
|
+
<p class="oip-pm__link-label">
|
|
68
|
+
<RmIcon name="Link" :size="12" color="var(--text-muted)" />
|
|
69
|
+
{{ en ? "Complete article" : "Article complet" }}
|
|
70
|
+
</p>
|
|
71
|
+
<a :href="`https://www.doi.org/${doc.doi}`" target="_blank" rel="noopener">
|
|
72
|
+
https://www.doi.org/<b>{{ doc.doi }}</b>
|
|
73
|
+
</a>
|
|
74
|
+
</div>
|
|
75
|
+
</section>
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
</div>
|
|
79
|
+
</template>
|
|
80
|
+
|
|
81
|
+
<script setup lang="ts">
|
|
82
|
+
import { oipResourceSpec } from "../utils/oipResources";
|
|
83
|
+
import { oipEsGet } from "../composables/useOipResources";
|
|
84
|
+
|
|
85
|
+
const props = withDefaults(
|
|
86
|
+
defineProps<{
|
|
87
|
+
/** `_id` de la publication (son PMID). */
|
|
88
|
+
id: string;
|
|
89
|
+
/** Termes de la recherche en cours, surlignes dans la fiche. */
|
|
90
|
+
highlight?: string[];
|
|
91
|
+
lang?: "fr" | "en";
|
|
92
|
+
}>(),
|
|
93
|
+
{ highlight: () => [], lang: "fr" },
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
/** `source` : l'uuid Directus d'une source citee, pour ouvrir le panneau Sources. */
|
|
97
|
+
const emit = defineEmits<{ source: [uuid: string] }>();
|
|
98
|
+
|
|
99
|
+
/** La fiche Directus « PubMed » (cf. useSources de France Augmented Science). */
|
|
100
|
+
const PUBMED_SOURCE_UUID = "63805e97-48ac-4c04-afd6-8a15055dec97";
|
|
101
|
+
|
|
102
|
+
const en = computed(() => props.lang === "en");
|
|
103
|
+
const root = ref<HTMLElement | null>(null);
|
|
104
|
+
const { chaptersOffset, stickyTop, scrollToChapter } = useOipChapterScroll(root);
|
|
105
|
+
|
|
106
|
+
const spec = oipResourceSpec("PubMed")!;
|
|
107
|
+
const { data: doc, pending } = useAsyncData(
|
|
108
|
+
() => `oip-pubmed-${props.id}`,
|
|
109
|
+
async () => (await oipEsGet(spec.cluster, spec.kind.index, props.id))?._source ?? null,
|
|
110
|
+
{ server: false, watch: [() => props.id] },
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
const orNA = (value: unknown) => (value == null || value === "" ? "N/A" : String(value));
|
|
114
|
+
const unique = (values: unknown[]) => [...new Set(values.filter((v): v is string => typeof v === "string" && v !== ""))];
|
|
115
|
+
const titleCase = (value: string) => (value || "").toLowerCase().replace(/(^|\s)\S/g, (c) => c.toUpperCase());
|
|
116
|
+
const anchor = (label: string) => (label || "").toLowerCase();
|
|
117
|
+
const longDate = (value: string) =>
|
|
118
|
+
new Date(value).toLocaleDateString(en.value ? "en-US" : "fr-FR", { year: "numeric", month: "long", day: "numeric" });
|
|
119
|
+
|
|
120
|
+
const tagGroups = computed(() => {
|
|
121
|
+
const d = doc.value ?? {};
|
|
122
|
+
const diseases: any[] = d.diseases ?? [];
|
|
123
|
+
return [
|
|
124
|
+
{ icon: "Article", label: en.value ? "Article type" : "Type d'article", values: unique(d.publication_types ?? []) },
|
|
125
|
+
{ icon: "BookOpen", label: en.value ? "Journal name" : "Nom de la revue", values: [orNA(d.journal)] },
|
|
126
|
+
{ icon: "Molecule", label: en.value ? "Molecules" : "Molécules", values: unique(d.chemical_list ?? []) },
|
|
127
|
+
{ icon: "TextAa", label: en.value ? "Keywords" : "Mots-clés", values: unique(d.keywords ?? []) },
|
|
128
|
+
{ icon: "Tag", label: en.value ? "Mesh Terms" : "Termes MeSH", values: unique(d.mesh_terms ?? []) },
|
|
129
|
+
{
|
|
130
|
+
icon: "Bandaids",
|
|
131
|
+
label: en.value ? "Rare diseases" : "Maladies rares",
|
|
132
|
+
values: unique((d.rare_diseases ?? []).map((r: any) => r.concat_disease_name_orpha_code)),
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
icon: "FaceMask",
|
|
136
|
+
label: "ICD 10",
|
|
137
|
+
values: unique(diseases.flatMap((x) => x.icd10?.map((i: any) => i.combined_label) ?? [])),
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
icon: "ListMagnifyingGlass",
|
|
141
|
+
label: en.value ? "Oncology Terms" : "Termes oncologiques",
|
|
142
|
+
values: unique(diseases.flatMap((x) => x.section?.map((s: any) => s.label) ?? [])),
|
|
143
|
+
},
|
|
144
|
+
];
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
const sections = computed<{ label: string; text: string; order: number }[]>(() =>
|
|
148
|
+
[...(doc.value?.sections ?? [])].sort((a, b) => a?.order - b?.order),
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
const hasLinks = computed(() => !doc.value?.delete || !!doc.value?.doi);
|
|
152
|
+
|
|
153
|
+
const chapters = computed(() => [
|
|
154
|
+
{ label: "Introduction", value: "introduction" },
|
|
155
|
+
...sections.value.map((s) => ({ label: titleCase(s.label), value: anchor(s.label) })),
|
|
156
|
+
...(hasLinks.value ? [{ label: en.value ? "Links" : "Liens", value: "links" }] : []),
|
|
157
|
+
]);
|
|
158
|
+
</script>
|
|
159
|
+
|
|
160
|
+
<style scoped>
|
|
161
|
+
.oip-pm__layout {
|
|
162
|
+
display: flex;
|
|
163
|
+
gap: var(--space-16);
|
|
164
|
+
align-items: flex-start;
|
|
165
|
+
}
|
|
166
|
+
.oip-pm__nav {
|
|
167
|
+
flex: 0 0 auto;
|
|
168
|
+
align-self: stretch;
|
|
169
|
+
}
|
|
170
|
+
.oip-pm__chapters {
|
|
171
|
+
position: sticky;
|
|
172
|
+
}
|
|
173
|
+
.oip-pm__content {
|
|
174
|
+
flex: 1 1 auto;
|
|
175
|
+
min-width: 0;
|
|
176
|
+
display: grid;
|
|
177
|
+
gap: var(--space-16);
|
|
178
|
+
}
|
|
179
|
+
.oip-pm__card {
|
|
180
|
+
display: grid;
|
|
181
|
+
gap: var(--space-24);
|
|
182
|
+
padding: var(--space-24);
|
|
183
|
+
border: 1px solid var(--border-default);
|
|
184
|
+
border-radius: 12px;
|
|
185
|
+
background: var(--bg-surface);
|
|
186
|
+
box-shadow: var(--shadow-sm);
|
|
187
|
+
}
|
|
188
|
+
.oip-pm__head {
|
|
189
|
+
display: grid;
|
|
190
|
+
gap: var(--space-4);
|
|
191
|
+
justify-items: start;
|
|
192
|
+
}
|
|
193
|
+
.oip-pm__title {
|
|
194
|
+
margin: 0;
|
|
195
|
+
color: var(--text-primary);
|
|
196
|
+
font-size: var(--font-18);
|
|
197
|
+
font-weight: 800;
|
|
198
|
+
line-height: normal;
|
|
199
|
+
}
|
|
200
|
+
.oip-pm__body {
|
|
201
|
+
color: var(--text-primary);
|
|
202
|
+
font-size: var(--font-14);
|
|
203
|
+
line-height: 160%;
|
|
204
|
+
}
|
|
205
|
+
.oip-pm__link {
|
|
206
|
+
display: grid;
|
|
207
|
+
gap: var(--space-4);
|
|
208
|
+
}
|
|
209
|
+
.oip-pm__link-label {
|
|
210
|
+
display: flex;
|
|
211
|
+
align-items: center;
|
|
212
|
+
gap: var(--space-4);
|
|
213
|
+
margin: 0;
|
|
214
|
+
color: var(--text-primary);
|
|
215
|
+
font-size: var(--font-12);
|
|
216
|
+
}
|
|
217
|
+
.oip-pm__link a {
|
|
218
|
+
color: var(--color-primary);
|
|
219
|
+
font-size: var(--font-14);
|
|
220
|
+
text-decoration: underline;
|
|
221
|
+
word-break: break-all;
|
|
222
|
+
}
|
|
223
|
+
</style>
|
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Le detail d'une ressource de projet, ouvert sans quitter la page, dans
|
|
3
|
+
n'importe quelle app du portail.
|
|
4
|
+
|
|
5
|
+
- Un type que le layer sait montrer (cf. OIP_RESOURCE_SPECS) s'affiche avec
|
|
6
|
+
la fiche de son app d'origine, ses onglets compris : une publication comme
|
|
7
|
+
dans France Augmented Science, une marque comme dans fr_drugs_app, dans
|
|
8
|
+
l'une comme dans l'autre.
|
|
9
|
+
- Les autres passent par la carte generique, decrite dans le registre des
|
|
10
|
+
types de l'API : un type ajoute la-bas s'affiche ici sans deploiement.
|
|
11
|
+
|
|
12
|
+
Sous le titre, un lien mene a la fiche dans son app d'origine. Dans l'app
|
|
13
|
+
d'origine elle-meme, il navigue sur place ; ailleurs, il ouvre l'autre app
|
|
14
|
+
dans un onglet.
|
|
15
|
+
|
|
16
|
+
Une fiche ouverte depuis la fiche du tiroir (l'auteur d'une publication, la
|
|
17
|
+
marque d'une contribution...) s'empile dans un tiroir de plus ; celui de
|
|
18
|
+
dessous reste ou il etait. Un lien vers une page qui n'est pas une fiche
|
|
19
|
+
quitte le tiroir.
|
|
20
|
+
-->
|
|
21
|
+
<template>
|
|
22
|
+
<RmDrawer
|
|
23
|
+
v-for="(entry, index) in entries"
|
|
24
|
+
:key="`${index}-${entry.type ?? entry.fiche?.view}-${entry.id ?? entry.fiche?.path}`"
|
|
25
|
+
:model-value="index === 0 ? open : true"
|
|
26
|
+
:size="index === 0 ? size : `min(${1180 - index * 40}px, calc(100vw - ${96 + index * 24}px))`"
|
|
27
|
+
:z-index="index === 0 ? undefined : 100 + index * 2"
|
|
28
|
+
:label="entry.title || entry.id || ''"
|
|
29
|
+
@update:model-value="(value: boolean) => !value && close(index)"
|
|
30
|
+
>
|
|
31
|
+
<!-- Carte generique : l'en-tete du tiroir porte le titre et le lien. -->
|
|
32
|
+
<template v-if="!isPage(entry)" #header>
|
|
33
|
+
<div class="oip-rd__head">
|
|
34
|
+
<p class="oip-rd__title">{{ entry.title || entry.id }}</p>
|
|
35
|
+
<OipResourceDrawerLink :origin="originOf(entry)" :lang="lang" @leave="close(0)" />
|
|
36
|
+
</div>
|
|
37
|
+
</template>
|
|
38
|
+
|
|
39
|
+
<div v-if="index > 0 || open" class="oip-rd__body" :class="{ 'oip-rd__body--page': isPage(entry) }">
|
|
40
|
+
<!-- Une fiche porte son bandeau (titre, lien dessous, onglets) : l'en-tete
|
|
41
|
+
du tiroir s'efface, sa croix se pose au bout du bandeau. -->
|
|
42
|
+
<RmButton
|
|
43
|
+
v-if="isPage(entry)"
|
|
44
|
+
class="oip-rd__close"
|
|
45
|
+
variant="tertiary"
|
|
46
|
+
size="md"
|
|
47
|
+
icon-only
|
|
48
|
+
ghost
|
|
49
|
+
prefix-icon="X"
|
|
50
|
+
:aria-label="en ? 'Close' : 'Fermer'"
|
|
51
|
+
@click="close(index)"
|
|
52
|
+
/>
|
|
53
|
+
<!-- Une fiche visee par un lien, montee par sa vue. -->
|
|
54
|
+
<div v-if="entry.fiche && !entry.fiche.view.startsWith('resource:')" class="oip-rv oip-rv--whole">
|
|
55
|
+
<component :is="oipResourceViewComponent(entry.fiche.view)" v-bind="entry.fiche.props" :lang="lang">
|
|
56
|
+
<template #title-link>
|
|
57
|
+
<OipResourceDrawerLink :origin="originOf(entry)" :lang="lang" @leave="close(0)" />
|
|
58
|
+
</template>
|
|
59
|
+
</component>
|
|
60
|
+
</div>
|
|
61
|
+
<OipResourceView
|
|
62
|
+
v-else-if="entry.type && oipResourceViewSpec(entry.type)"
|
|
63
|
+
:type="entry.type"
|
|
64
|
+
:id="entry.id ?? ''"
|
|
65
|
+
:title="entry.title"
|
|
66
|
+
:tab="entry.tab"
|
|
67
|
+
:highlight="index === 0 ? highlight : []"
|
|
68
|
+
:lang="lang"
|
|
69
|
+
@source="emit('source', $event)"
|
|
70
|
+
>
|
|
71
|
+
<template v-if="isPage(entry)" #title-link>
|
|
72
|
+
<OipResourceDrawerLink :origin="originOf(entry)" :lang="lang" @leave="close(0)" />
|
|
73
|
+
</template>
|
|
74
|
+
</OipResourceView>
|
|
75
|
+
<OipResourceGenericCard
|
|
76
|
+
v-else
|
|
77
|
+
:type="entry.type ?? ''"
|
|
78
|
+
:id="entry.id ?? ''"
|
|
79
|
+
:title="entry.title"
|
|
80
|
+
:source="source"
|
|
81
|
+
:lang="lang"
|
|
82
|
+
/>
|
|
83
|
+
</div>
|
|
84
|
+
</RmDrawer>
|
|
85
|
+
</template>
|
|
86
|
+
|
|
87
|
+
<script setup lang="ts">
|
|
88
|
+
import {
|
|
89
|
+
OIP_RESOURCE_APPS,
|
|
90
|
+
oipFillTemplate,
|
|
91
|
+
oipResourceAppUrl,
|
|
92
|
+
oipResourceViewSpec,
|
|
93
|
+
type OipResourceApp,
|
|
94
|
+
} from "../utils/oipResources";
|
|
95
|
+
import { oipFicheOf, type OipFicheTarget } from "../utils/oipFicheRoutes";
|
|
96
|
+
import { oipHydrate, useOipResourceTypes } from "../composables/useOipResources";
|
|
97
|
+
import { OIP_RESOURCE_NAV, useOipResourceApp } from "../composables/useOipResourceNav";
|
|
98
|
+
import { oipResourceViewComponent } from "../composables/useOipResourceViews";
|
|
99
|
+
|
|
100
|
+
const props = withDefaults(
|
|
101
|
+
defineProps<{
|
|
102
|
+
modelValue: boolean;
|
|
103
|
+
/** `resourceType` de l'API. */
|
|
104
|
+
type: string;
|
|
105
|
+
/** `resourceId` de l'API : l'`_id` du document. */
|
|
106
|
+
id: string;
|
|
107
|
+
title?: string;
|
|
108
|
+
/** L'app qui ouvre le tiroir. Absente : `oip.resourceApp` de l'app.config. */
|
|
109
|
+
app?: OipResourceApp | "";
|
|
110
|
+
/** Le document deja relu par l'app, pour la carte generique. */
|
|
111
|
+
source?: Record<string, unknown> | null;
|
|
112
|
+
highlight?: string[];
|
|
113
|
+
lang?: "fr" | "en";
|
|
114
|
+
size?: string;
|
|
115
|
+
}>(),
|
|
116
|
+
{
|
|
117
|
+
title: "",
|
|
118
|
+
app: "",
|
|
119
|
+
source: null,
|
|
120
|
+
highlight: () => [],
|
|
121
|
+
lang: "fr",
|
|
122
|
+
size: "min(1280px, calc(100vw - 48px))",
|
|
123
|
+
},
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
const emit = defineEmits<{
|
|
127
|
+
"update:modelValue": [value: boolean];
|
|
128
|
+
/** Une source citee dans la fiche : l'app ouvre son panneau Sources. */
|
|
129
|
+
source: [uuid: string];
|
|
130
|
+
}>();
|
|
131
|
+
|
|
132
|
+
const open = computed({
|
|
133
|
+
get: () => props.modelValue,
|
|
134
|
+
set: (value: boolean) => emit("update:modelValue", value),
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
const en = computed(() => props.lang === "en");
|
|
138
|
+
const configuredApp = useOipResourceApp();
|
|
139
|
+
const app = computed(() => props.app || configuredApp);
|
|
140
|
+
const localePath = useLocalePath();
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Une fiche ouverte : une ressource (`type`, `id`, l'onglet et le document
|
|
144
|
+
* relu pour son lien) ou une fiche visee par un lien (`fiche`).
|
|
145
|
+
*/
|
|
146
|
+
interface Entry {
|
|
147
|
+
type?: string;
|
|
148
|
+
id?: string;
|
|
149
|
+
tab?: string;
|
|
150
|
+
title: string;
|
|
151
|
+
doc?: Record<string, any> | null;
|
|
152
|
+
fiche?: OipFicheTarget & { app: OipResourceApp; path: string };
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/** Les fiches ouvertes au-dessus de celle du projet, de bas en haut. */
|
|
156
|
+
const stacked = ref<Entry[]>([]);
|
|
157
|
+
/** Le document de la ressource du projet : certaines fiches s'adressent par un de ses champs. */
|
|
158
|
+
const rootDoc = ref<Record<string, any> | null>(null);
|
|
159
|
+
const entries = computed<Entry[]>(() => [
|
|
160
|
+
{ type: props.type, id: props.id, title: props.title, doc: rootDoc.value },
|
|
161
|
+
...stacked.value,
|
|
162
|
+
]);
|
|
163
|
+
|
|
164
|
+
watch(
|
|
165
|
+
() => [props.modelValue, props.type, props.id] as const,
|
|
166
|
+
async ([isOpen, type, id]) => {
|
|
167
|
+
rootDoc.value = null;
|
|
168
|
+
const spec = oipResourceViewSpec(type);
|
|
169
|
+
if (!isOpen || !spec) return;
|
|
170
|
+
rootDoc.value = (await oipHydrate(spec.type, [id]).catch(() => ({})))[id] ?? null;
|
|
171
|
+
},
|
|
172
|
+
{ immediate: true },
|
|
173
|
+
);
|
|
174
|
+
|
|
175
|
+
/** Fermer un tiroir ferme aussi ceux qui sont au-dessus de lui. */
|
|
176
|
+
function close(index: number) {
|
|
177
|
+
if (index === 0) open.value = false;
|
|
178
|
+
stacked.value = stacked.value.slice(0, Math.max(0, index - 1));
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
watch(open, (isOpen) => {
|
|
182
|
+
if (!isOpen) stacked.value = [];
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
/** Empile une ressource, titree par la description de son type des que son document arrive. */
|
|
186
|
+
async function pushResource(type: string, id: string, tab?: string) {
|
|
187
|
+
const spec = oipResourceViewSpec(type);
|
|
188
|
+
if (!spec) return;
|
|
189
|
+
const entry = reactive<Entry>({ type, id, tab, title: "", doc: null });
|
|
190
|
+
stacked.value = [...stacked.value, entry];
|
|
191
|
+
const doc = (await oipHydrate(spec.type, [id]).catch(() => ({})))[id];
|
|
192
|
+
if (doc) {
|
|
193
|
+
entry.doc = doc;
|
|
194
|
+
entry.title = spec.kind.title(doc, props.lang);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const appHref = (target: OipResourceApp, path: string) =>
|
|
199
|
+
target === app.value ? localePath(path) : oipResourceAppUrl(target, path, props.lang);
|
|
200
|
+
|
|
201
|
+
// Les liens des fiches du tiroir empilent un tiroir de plus ; un lien vers une
|
|
202
|
+
// page qui n'est pas une fiche quitte le tiroir (sur place dans l'app, dans un
|
|
203
|
+
// onglet ailleurs).
|
|
204
|
+
provide(OIP_RESOURCE_NAV, {
|
|
205
|
+
href: (type, id, tab) => urlOf(type, id, tab)?.url ?? "",
|
|
206
|
+
open: (type, id, tab) => pushResource(type, id, tab),
|
|
207
|
+
appHref,
|
|
208
|
+
openApp(target, path) {
|
|
209
|
+
const fiche = oipFicheOf(target, path);
|
|
210
|
+
if (fiche?.view.startsWith("resource:")) {
|
|
211
|
+
pushResource(fiche.props.type!, fiche.props.id!, fiche.props.tab || undefined);
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
if (fiche) {
|
|
215
|
+
stacked.value = [...stacked.value, { title: fiche.title, fiche: { ...fiche, app: target, path } }];
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
const url = appHref(target, path);
|
|
219
|
+
if (target === app.value) {
|
|
220
|
+
close(0);
|
|
221
|
+
navigateTo(url);
|
|
222
|
+
} else window.open(url, "_blank", "noopener");
|
|
223
|
+
},
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
/** L'URL de la fiche : locale dans son app d'origine, absolue ailleurs. */
|
|
227
|
+
function urlOf(type: string, id: string, tab?: string, doc?: Record<string, any> | null) {
|
|
228
|
+
const spec = oipResourceViewSpec(type);
|
|
229
|
+
if (!spec) return null;
|
|
230
|
+
const path = spec.detailPath(id, tab, doc);
|
|
231
|
+
if (!path) return null;
|
|
232
|
+
if (spec.app === app.value) return { local: true, url: localePath(path), name: "" };
|
|
233
|
+
return { local: false, url: oipResourceAppUrl(spec.app, path, props.lang), name: OIP_RESOURCE_APPS[spec.app].name };
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Les vues sans bandeau a elles (une carte de resultat) : le tiroir garde son
|
|
238
|
+
* en-tete, titre et lien.
|
|
239
|
+
*/
|
|
240
|
+
const CARD_VIEWS = new Set(["drugs-national-assembly", "science-phrc"]);
|
|
241
|
+
|
|
242
|
+
/** Une fiche du layer : elle porte son bandeau, le tiroir efface le sien. */
|
|
243
|
+
function isPage(entry: Entry) {
|
|
244
|
+
if (entry.fiche) return true;
|
|
245
|
+
const spec = entry.type ? oipResourceViewSpec(entry.type) : undefined;
|
|
246
|
+
return !!spec && !CARD_VIEWS.has(spec.view ?? "");
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
function originOf(entry: Entry) {
|
|
250
|
+
if (entry.fiche) {
|
|
251
|
+
const local = entry.fiche.app === app.value;
|
|
252
|
+
return { local, url: appHref(entry.fiche.app, entry.fiche.path), name: OIP_RESOURCE_APPS[entry.fiche.app].name };
|
|
253
|
+
}
|
|
254
|
+
if (entry.type && oipResourceViewSpec(entry.type)) return urlOf(entry.type, entry.id ?? "", entry.tab, entry.doc);
|
|
255
|
+
return registryUrl.value ? { local: false, url: registryUrl.value, name: registryName.value } : null;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Un type sans vue : son lien vient du registre de l'API.
|
|
259
|
+
const registryUrl = ref("");
|
|
260
|
+
const registryName = ref("");
|
|
261
|
+
watch(
|
|
262
|
+
() => [props.modelValue, props.type, props.id] as const,
|
|
263
|
+
async ([isOpen, type, id]) => {
|
|
264
|
+
registryUrl.value = "";
|
|
265
|
+
registryName.value = "";
|
|
266
|
+
if (!isOpen || oipResourceViewSpec(type)) return;
|
|
267
|
+
const entry = (await useOipResourceTypes()).find((e) => e.key === type);
|
|
268
|
+
registryUrl.value = entry?.display?.detailUrl ? oipFillTemplate(entry.display.detailUrl, props.source ?? {}, id) : "";
|
|
269
|
+
const owner = entry?.ownerApp ?? "";
|
|
270
|
+
registryName.value = OIP_RESOURCE_APPS[owner as OipResourceApp]?.name ?? owner;
|
|
271
|
+
},
|
|
272
|
+
{ immediate: true },
|
|
273
|
+
);
|
|
274
|
+
</script>
|
|
275
|
+
|
|
276
|
+
<style scoped>
|
|
277
|
+
.oip-rd__head {
|
|
278
|
+
display: grid;
|
|
279
|
+
gap: var(--space-4);
|
|
280
|
+
min-width: 0;
|
|
281
|
+
}
|
|
282
|
+
.oip-rd__title {
|
|
283
|
+
margin: 0;
|
|
284
|
+
color: var(--text-primary);
|
|
285
|
+
font-size: var(--font-18);
|
|
286
|
+
font-weight: 700;
|
|
287
|
+
line-height: 1.3;
|
|
288
|
+
}
|
|
289
|
+
.oip-rd__body {
|
|
290
|
+
padding: var(--space-16) 0;
|
|
291
|
+
}
|
|
292
|
+
.oip-rd__body.oip-rd__body--page {
|
|
293
|
+
padding: 0 0 var(--space-32);
|
|
294
|
+
}
|
|
295
|
+
.oip-rd__close {
|
|
296
|
+
position: absolute;
|
|
297
|
+
top: var(--space-16);
|
|
298
|
+
right: var(--space-24);
|
|
299
|
+
z-index: 96;
|
|
300
|
+
}
|
|
301
|
+
/* La place de la croix, au bout de la rangee titre + actions du bandeau. */
|
|
302
|
+
.oip-rd__body--page :deep(.rm-page-header__row) {
|
|
303
|
+
padding-right: 72px;
|
|
304
|
+
}
|
|
305
|
+
/* La fleche de retour des pages remonterait l'historique de l'ecran dessous. */
|
|
306
|
+
.oip-rd__body--page :deep(.rm-page-header__back) {
|
|
307
|
+
display: none;
|
|
308
|
+
}
|
|
309
|
+
/* Le contenu d'une fiche d'un seul tenant recoit les gouttieres de la colonne
|
|
310
|
+
de contenu ; son bandeau reste bord a bord. On vise l'element qui porte le
|
|
311
|
+
bandeau, a quelque profondeur qu'il soit : une vue de ressource enveloppe
|
|
312
|
+
souvent sa fiche, et la marge posee sur l'enveloppe decalerait le bandeau. */
|
|
313
|
+
.oip-rd__body--page :deep(.oip-rv--whole :has(> .rm-page-header) > :not(.rm-page-header)) {
|
|
314
|
+
box-sizing: border-box;
|
|
315
|
+
padding-inline: var(--space-24);
|
|
316
|
+
}
|
|
317
|
+
.oip-rd__body--page :deep(.oip-rv--whole :has(> .rm-page-header) > .rm-page-header + *) {
|
|
318
|
+
margin-top: var(--space-24);
|
|
319
|
+
}
|
|
320
|
+
</style>
|
|
321
|
+
|
|
322
|
+
<style>
|
|
323
|
+
/* Hors portee : l'en-tete et le corps appartiennent au tiroir (teleporte).
|
|
324
|
+
Sans marge interne, le bandeau colle de la fiche tient le haut du tiroir. */
|
|
325
|
+
.rm-drawer:has(> .rm-drawer__body .oip-rd__body--page) > .rm-drawer__header {
|
|
326
|
+
display: none;
|
|
327
|
+
}
|
|
328
|
+
.rm-drawer:has(> .rm-drawer__body .oip-rd__body--page) > .rm-drawer__body {
|
|
329
|
+
padding: 0;
|
|
330
|
+
}
|
|
331
|
+
</style>
|