@datagouv/components-next 0.2.0 → 1.0.1
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/README.md +1 -1
- package/assets/main.css +49 -22
- package/dist/Control-BNCDn-8E.js +148 -0
- package/dist/{Datafair.client-x39O4yfF.js → Datafair.client-B5lBpOl8.js} +2 -2
- package/dist/Event-BOgJUhNR.js +738 -0
- package/dist/Image-BN-4XkIn.js +247 -0
- package/dist/{JsonPreview.client-BMsC5JcY.js → JsonPreview.client-Doz1Z0BS.js} +23 -23
- package/dist/Map-BdT3i2C4.js +7609 -0
- package/dist/MapContainer.client-oiieO8H-.js +105 -0
- package/dist/OSM-CamriM9b.js +71 -0
- package/dist/PdfPreview.client-CdAhkDFJ.js +14513 -0
- package/dist/{Pmtiles.client-BaiIo4VZ.js → Pmtiles.client-B0v8tGJQ.js} +3 -3
- package/dist/ScaleLine-BiesrgOv.js +165 -0
- package/dist/Swagger.client-CsK65JnG.js +4 -0
- package/dist/Tile-DCuqwNOI.js +1206 -0
- package/dist/TileImage-CmZf8EdU.js +1067 -0
- package/dist/View-DcDc7N2K.js +2858 -0
- package/dist/{XmlPreview.client-CAdN0w_Y.js → XmlPreview.client-CrjHf74q.js} +17 -17
- package/dist/common-C4rDcQpp.js +243 -0
- package/dist/components-next.css +1 -1
- package/dist/components-next.js +158 -117
- package/dist/components.css +1 -1
- package/dist/{MapContainer.client-DeSo8EvG.js → index-Bbu9rOHt.js} +4975 -21416
- package/dist/leaflet-src-7m1mB8LI.js +6338 -0
- package/dist/{main-Dgri3TQL.js → main-CiH8ZmBI.js} +56973 -51462
- package/dist/proj-CKwYjU38.js +1569 -0
- package/dist/tilecoord-YW3qEH_j.js +884 -0
- package/dist/{vue3-xml-viewer.common-D6skc_Ai.js → vue3-xml-viewer.common-Bi_bsV6C.js} +1 -1
- package/package.json +6 -2
- package/src/components/ActivityList/ActivityList.vue +6 -2
- package/src/components/AppLink.vue +4 -1
- package/src/components/Avatar.vue +2 -2
- package/src/components/AvatarWithName.vue +8 -4
- package/src/components/BouncingDots.vue +21 -0
- package/src/components/BrandedButton.vue +2 -0
- package/src/components/CopyButton.vue +19 -7
- package/src/components/DataserviceCard.vue +85 -120
- package/src/components/DatasetCard.vue +110 -171
- package/src/components/DatasetInformation/DatasetEmbedSection.vue +43 -0
- package/src/components/DatasetInformation/DatasetInformationSection.vue +73 -0
- package/src/components/DatasetInformation/DatasetSchemaSection.vue +74 -0
- package/src/components/DatasetInformation/DatasetSpatialSection.vue +59 -0
- package/src/components/DatasetInformation/DatasetTemporalitySection.vue +45 -0
- package/src/components/DatasetInformation/index.ts +5 -0
- package/src/components/DatasetQuality.vue +23 -16
- package/src/components/DatasetQualityInline.vue +13 -17
- package/src/components/DatasetQualityScore.vue +12 -15
- package/src/components/DatasetQualityTooltipContent.vue +3 -3
- package/src/components/DescriptionList.vue +1 -4
- package/src/components/DescriptionListDetails.vue +5 -0
- package/src/components/DescriptionListTerm.vue +5 -0
- package/src/components/DiscussionMessageCard.vue +63 -0
- package/src/components/ExtraAccordion.vue +4 -4
- package/src/components/Form/BadgeSelect.vue +35 -0
- package/src/components/Form/FormatSelect.vue +28 -0
- package/src/components/Form/GeozoneSelect.vue +52 -0
- package/src/components/Form/GranularitySelect.vue +29 -0
- package/src/components/Form/LicenseSelect.vue +30 -0
- package/src/components/Form/OrganizationSelect.vue +62 -0
- package/src/components/Form/OrganizationTypeSelect.vue +34 -0
- package/src/components/Form/ReuseTopicSelect.vue +29 -0
- package/src/components/Form/SchemaSelect.vue +30 -0
- package/src/components/Form/SearchableSelect.vue +334 -0
- package/src/components/Form/SelectGroup.vue +132 -0
- package/src/components/Form/TagSelect.vue +38 -0
- package/src/components/LeafletMap.vue +31 -0
- package/src/components/LicenseBadge.vue +24 -0
- package/src/components/LoadingBlock.vue +23 -2
- package/src/components/MarkdownViewer.vue +3 -1
- package/src/components/ObjectCard.vue +42 -0
- package/src/components/ObjectCardBadge.vue +22 -0
- package/src/components/ObjectCardHeader.vue +35 -0
- package/src/components/ObjectCardOwner.vue +43 -0
- package/src/components/ObjectCardShortDescription.vue +28 -0
- package/src/components/OrganizationCard.vue +35 -20
- package/src/components/OrganizationHorizontalCard.vue +87 -0
- package/src/components/OrganizationLogo.vue +1 -1
- package/src/components/OrganizationNameWithCertificate.vue +12 -6
- package/src/components/OwnerTypeIcon.vue +1 -0
- package/src/components/Pagination.vue +1 -1
- package/src/components/Placeholder.vue +5 -2
- package/src/components/PostCard.vue +62 -0
- package/src/components/ProgressBar.vue +31 -0
- package/src/components/RadioGroup.vue +32 -0
- package/src/components/RadioInput.vue +64 -0
- package/src/components/ResourceAccordion/Datafair.client.vue +1 -1
- package/src/components/ResourceAccordion/EditButton.vue +2 -3
- package/src/components/ResourceAccordion/JsonPreview.client.vue +3 -3
- package/src/components/ResourceAccordion/MapContainer.client.vue +21 -17
- package/src/components/ResourceAccordion/Metadata.vue +11 -24
- package/src/components/ResourceAccordion/PdfPreview.client.vue +70 -74
- package/src/components/ResourceAccordion/Pmtiles.client.vue +2 -2
- package/src/components/ResourceAccordion/Preview.vue +2 -2
- package/src/components/ResourceAccordion/ResourceAccordion.vue +35 -28
- package/src/components/ResourceAccordion/ResourceIcon.vue +1 -0
- package/src/components/ResourceAccordion/SchemaBadge.vue +2 -2
- package/src/components/ResourceAccordion/XmlPreview.client.vue +3 -3
- package/src/components/ResourceExplorer/ResourceExplorer.vue +243 -0
- package/src/components/ResourceExplorer/ResourceExplorerSidebar.vue +116 -0
- package/src/components/ResourceExplorer/ResourceExplorerViewer.vue +410 -0
- package/src/components/ReuseCard.vue +8 -28
- package/src/components/ReuseHorizontalCard.vue +80 -0
- package/src/components/Search/BasicAndAdvancedFilters.vue +49 -0
- package/src/components/Search/Filter/AccessTypeFilter.vue +37 -0
- package/src/components/Search/Filter/DatasetBadgeFilter.vue +40 -0
- package/src/components/Search/Filter/FilterButtonGroup.vue +78 -0
- package/src/components/Search/Filter/FormatFamilyFilter.vue +39 -0
- package/src/components/Search/Filter/LastUpdateRangeFilter.vue +37 -0
- package/src/components/Search/Filter/ProducerTypeFilter.vue +49 -0
- package/src/components/Search/Filter/ReuseTypeFilter.vue +42 -0
- package/src/components/Search/GlobalSearch.vue +707 -0
- package/src/components/Search/SearchInput.vue +63 -0
- package/src/components/Search/Sidemenu.vue +38 -0
- package/src/components/StatBox.vue +5 -5
- package/src/components/Tag.vue +30 -0
- package/src/components/Toggletip.vue +11 -4
- package/src/components/Tooltip.vue +2 -3
- package/src/components/TopicCard.vue +134 -0
- package/src/components/radioGroupContext.ts +9 -0
- package/src/composables/useDebouncedRef.ts +31 -0
- package/src/composables/useHasTabularData.ts +15 -0
- package/src/composables/useMetrics.ts +4 -3
- package/src/composables/useResourceCapabilities.ts +131 -0
- package/src/composables/useRouteQueryBoolean.ts +10 -0
- package/src/composables/useSelectModelSync.ts +89 -0
- package/src/composables/useStableQueryParams.ts +84 -0
- package/src/composables/useTranslation.ts +2 -1
- package/src/config.ts +4 -0
- package/src/functions/api.ts +25 -6
- package/src/functions/api.types.ts +5 -3
- package/src/functions/datasets.ts +1 -29
- package/src/functions/description.ts +33 -0
- package/src/functions/helpers.ts +11 -0
- package/src/functions/markdown.ts +60 -16
- package/src/functions/metrics.ts +33 -0
- package/src/functions/organizations.ts +5 -5
- package/src/functions/resourceCapabilities.ts +55 -0
- package/src/main.ts +96 -7
- package/src/types/dataservices.ts +14 -12
- package/src/types/datasets.ts +20 -7
- package/src/types/discussions.ts +20 -0
- package/src/types/licenses.ts +3 -3
- package/src/types/organizations.ts +13 -1
- package/src/types/owned.ts +4 -2
- package/src/types/pages.ts +70 -0
- package/src/types/posts.ts +27 -0
- package/src/types/resources.ts +16 -0
- package/src/types/reuses.ts +14 -5
- package/src/types/search.ts +407 -0
- package/src/types/users.ts +12 -3
- package/dist/PdfPreview.client-COOkEkRA.js +0 -107
- package/dist/Swagger.client-CpLgaLg6.js +0 -4
- package/dist/pdf-vue3-IkJO65RH.js +0 -273
- package/dist/pdf.min-f72cfa08-CdgJTooZ.js +0 -9501
- package/src/components/DatasetInformationPanel.vue +0 -211
|
@@ -1,209 +1,148 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
class="absolute top-0 fr-grid-row fr-grid-row--middle fr-mt-n3v fr-ml-n1v"
|
|
6
|
-
>
|
|
7
|
-
<p
|
|
2
|
+
<ObjectCard>
|
|
3
|
+
<template #badge>
|
|
4
|
+
<ObjectCardBadge
|
|
8
5
|
v-if="dataset.private"
|
|
9
|
-
|
|
6
|
+
:icon="RiLockLine"
|
|
10
7
|
>
|
|
11
|
-
<span
|
|
12
|
-
class="fr-icon-lock-line fr-icon--sm"
|
|
13
|
-
aria-hidden="true"
|
|
14
|
-
/>
|
|
15
8
|
{{ t('Brouillon') }}
|
|
16
|
-
</
|
|
17
|
-
<
|
|
18
|
-
v-if="dataset.archived"
|
|
19
|
-
|
|
9
|
+
</ObjectCardBadge>
|
|
10
|
+
<ObjectCardBadge
|
|
11
|
+
v-else-if="dataset.archived"
|
|
12
|
+
:icon="RiArchiveLine"
|
|
20
13
|
>
|
|
21
|
-
<span
|
|
22
|
-
class="fr-icon-archive-line fr-icon--sm"
|
|
23
|
-
aria-hidden="true"
|
|
24
|
-
/>
|
|
25
14
|
{{ t('Archivé') }}
|
|
26
|
-
</
|
|
15
|
+
</ObjectCardBadge>
|
|
16
|
+
</template>
|
|
17
|
+
|
|
18
|
+
<template #media>
|
|
19
|
+
<OrganizationLogo
|
|
20
|
+
v-if="dataset.organization"
|
|
21
|
+
:organization="dataset.organization"
|
|
22
|
+
size-class="size-12"
|
|
23
|
+
/>
|
|
24
|
+
<Avatar
|
|
25
|
+
v-else-if="dataset.owner"
|
|
26
|
+
:user="dataset.owner"
|
|
27
|
+
:size="48"
|
|
28
|
+
/>
|
|
29
|
+
<Placeholder
|
|
30
|
+
v-else
|
|
31
|
+
type="Dataset"
|
|
32
|
+
class="size-12"
|
|
33
|
+
/>
|
|
34
|
+
</template>
|
|
35
|
+
<ObjectCardHeader
|
|
36
|
+
:icon="RiDatabase2Line"
|
|
37
|
+
:url="datasetUrl || dataset.page"
|
|
38
|
+
:target="datasetUrlInNewTab ? '_blank' : undefined"
|
|
39
|
+
>
|
|
40
|
+
{{ dataset.title }}
|
|
41
|
+
<template
|
|
42
|
+
v-if="dataset.acronym"
|
|
43
|
+
#extra
|
|
44
|
+
>
|
|
45
|
+
<small class="flex-1 ml-2">{{ dataset.acronym }}</small>
|
|
46
|
+
</template>
|
|
47
|
+
</ObjectCardHeader>
|
|
48
|
+
<div
|
|
49
|
+
v-if="dataset.organization || dataset.owner"
|
|
50
|
+
class="text-sm flex flex-wrap md:flex-nowrap gap-y-1 items-center truncate"
|
|
51
|
+
>
|
|
52
|
+
<ObjectCardOwner
|
|
53
|
+
:organization="dataset.organization"
|
|
54
|
+
:owner="dataset.owner"
|
|
55
|
+
:organization-url="organizationUrl"
|
|
56
|
+
/>
|
|
57
|
+
<RiSubtractLine class="hidden md:block size-4 flex-none fill-gray-medium" />
|
|
58
|
+
<div class="w-full md:w-auto text-gray-medium whitespace-nowrap">
|
|
59
|
+
{{ t('Mis à jour {date}', { date: formatRelativeIfRecentDate(dataset.last_update, { dateStyle: 'medium' }) }) }}
|
|
60
|
+
</div>
|
|
27
61
|
</div>
|
|
28
|
-
<div class="flex flex-wrap
|
|
29
|
-
<div class="flex-
|
|
30
|
-
<
|
|
31
|
-
<OrganizationLogo
|
|
32
|
-
v-if="dataset.organization"
|
|
33
|
-
:organization="dataset.organization"
|
|
34
|
-
size-class="size-12"
|
|
35
|
-
/>
|
|
36
|
-
<Avatar
|
|
37
|
-
v-else-if="dataset.owner"
|
|
38
|
-
:user="dataset.owner"
|
|
39
|
-
:size="48"
|
|
40
|
-
/>
|
|
41
|
-
<Placeholder
|
|
42
|
-
v-else
|
|
43
|
-
type="Dataset"
|
|
44
|
-
class="size-12"
|
|
45
|
-
/>
|
|
46
|
-
</div>
|
|
62
|
+
<div class="mx-0 -mb-1 flex flex-wrap items-center text-sm text-gray-medium">
|
|
63
|
+
<div class="hidden sm:flex text-gray-medium">
|
|
64
|
+
<DatasetQualityInline :quality="dataset.quality" />
|
|
47
65
|
</div>
|
|
48
|
-
<
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
:to="datasetUrl"
|
|
57
|
-
class="text-gray-title text-base bg-none flex w-full truncate"
|
|
58
|
-
:target="datasetUrlInNewTab ? '_blank' : undefined"
|
|
59
|
-
>
|
|
60
|
-
<span
|
|
61
|
-
class="block truncate"
|
|
62
|
-
:class="dataset.acronym ? 'flex-initial' : 'flex-1'"
|
|
63
|
-
>{{ dataset.title }}</span>
|
|
64
|
-
<small
|
|
65
|
-
v-if="dataset.acronym"
|
|
66
|
-
class="flex-1 ml-2"
|
|
67
|
-
>{{ dataset.acronym }}</small>
|
|
68
|
-
<span class="absolute inset-0" />
|
|
69
|
-
</AppLink>
|
|
70
|
-
</slot>
|
|
71
|
-
</h4>
|
|
72
|
-
<div
|
|
73
|
-
v-if="dataset.organization || dataset.owner"
|
|
74
|
-
class="text-sm m-0 flex flex-wrap md:flex-nowrap gap-y-1 items-center truncate"
|
|
66
|
+
<RiSubtractLine
|
|
67
|
+
aria-hidden="true"
|
|
68
|
+
class="hidden sm:block size-3"
|
|
69
|
+
/>
|
|
70
|
+
<div class="flex flex-wrap items-center gap-1">
|
|
71
|
+
<p
|
|
72
|
+
class="text-sm mb-0 flex items-center gap-0.5"
|
|
73
|
+
:aria-label="t('{n} vues | {n} vue | {n} vues', dataset.metrics.views)"
|
|
75
74
|
>
|
|
76
|
-
<
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
<
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
class="text-sm mb-0 flex items-center gap-0.5"
|
|
109
|
-
:aria-label="t('{n} vues | {n} vue | {n} vues', dataset.metrics.views)"
|
|
110
|
-
>
|
|
111
|
-
<RiEyeLine
|
|
112
|
-
aria-hidden="true"
|
|
113
|
-
class="size-3.5"
|
|
114
|
-
/>{{ summarize(dataset.metrics.views) }}
|
|
115
|
-
</p>
|
|
116
|
-
<p
|
|
117
|
-
class="text-sm mb-0 flex items-center gap-0.5"
|
|
118
|
-
:aria-label="t('{n} téléchargements des ressources | {n} téléchargement des ressources | {n} téléchargements des ressources', dataset.metrics.resources_downloads)"
|
|
119
|
-
>
|
|
120
|
-
<RiDownloadLine
|
|
121
|
-
aria-hidden="true"
|
|
122
|
-
class="size-3.5"
|
|
123
|
-
/>{{ summarize(dataset.metrics.resources_downloads) }}
|
|
124
|
-
</p>
|
|
125
|
-
<p
|
|
126
|
-
class="text-sm mb-0 flex items-center gap-0.5"
|
|
127
|
-
:aria-label="t('{n} réutilisations | {n} réutilisation | {n} réutilisations', dataset.metrics.reuses)"
|
|
128
|
-
>
|
|
129
|
-
<RiLineChartLine
|
|
130
|
-
aria-hidden="true"
|
|
131
|
-
class="size-3.5"
|
|
132
|
-
/>{{ summarize(dataset.metrics.reuses) }}
|
|
133
|
-
</p>
|
|
134
|
-
<p
|
|
135
|
-
class="text-sm mb-0 flex items-center gap-0.5"
|
|
136
|
-
:aria-label="t('{n} abonnés | {n} abonné | {n} abonnés', dataset.metrics.followers)"
|
|
137
|
-
>
|
|
138
|
-
<RiStarLine
|
|
139
|
-
aria-hidden="true"
|
|
140
|
-
class="size-3.5"
|
|
141
|
-
/>{{ summarize(dataset.metrics.followers) }}
|
|
142
|
-
</p>
|
|
143
|
-
</div>
|
|
144
|
-
</div>
|
|
145
|
-
<component
|
|
146
|
-
:is="config.textClamp"
|
|
147
|
-
v-if="showDescriptionShort && config && config.textClamp && descriptionShort"
|
|
148
|
-
class="fr-text--sm fr-mt-1w fr-mb-0 overflow-wrap-anywhere hidden sm:block"
|
|
149
|
-
:auto-resize="true"
|
|
150
|
-
:text="descriptionShort"
|
|
151
|
-
:max-lines="2"
|
|
152
|
-
/>
|
|
75
|
+
<RiEyeLine
|
|
76
|
+
aria-hidden="true"
|
|
77
|
+
class="size-3.5"
|
|
78
|
+
/>{{ summarize(dataset.metrics.views) }}
|
|
79
|
+
</p>
|
|
80
|
+
<p
|
|
81
|
+
class="text-sm mb-0 flex items-center gap-0.5"
|
|
82
|
+
:aria-label="t('{n} téléchargements des ressources | {n} téléchargement des ressources | {n} téléchargements des ressources', dataset.metrics.resources_downloads)"
|
|
83
|
+
>
|
|
84
|
+
<RiDownloadLine
|
|
85
|
+
aria-hidden="true"
|
|
86
|
+
class="size-3.5"
|
|
87
|
+
/>{{ summarize(dataset.metrics.resources_downloads) }}
|
|
88
|
+
</p>
|
|
89
|
+
<p
|
|
90
|
+
class="text-sm mb-0 flex items-center gap-0.5"
|
|
91
|
+
:aria-label="t('{n} réutilisations | {n} réutilisation | {n} réutilisations', dataset.metrics.reuses)"
|
|
92
|
+
>
|
|
93
|
+
<RiLineChartLine
|
|
94
|
+
aria-hidden="true"
|
|
95
|
+
class="size-3.5"
|
|
96
|
+
/>{{ summarize(dataset.metrics.reuses) }}
|
|
97
|
+
</p>
|
|
98
|
+
<p
|
|
99
|
+
class="text-sm mb-0 flex items-center gap-0.5"
|
|
100
|
+
:aria-label="t('{n} abonnés | {n} abonné | {n} abonnés', dataset.metrics.followers)"
|
|
101
|
+
>
|
|
102
|
+
<RiStarLine
|
|
103
|
+
aria-hidden="true"
|
|
104
|
+
class="size-3.5"
|
|
105
|
+
/>{{ summarize(dataset.metrics.followers) }}
|
|
106
|
+
</p>
|
|
153
107
|
</div>
|
|
154
108
|
</div>
|
|
155
|
-
|
|
109
|
+
<ObjectCardShortDescription
|
|
110
|
+
v-if="showDescriptionShort"
|
|
111
|
+
:text="getDescriptionShort(props.dataset)"
|
|
112
|
+
/>
|
|
113
|
+
</ObjectCard>
|
|
156
114
|
</template>
|
|
157
115
|
|
|
158
116
|
<script setup lang="ts">
|
|
159
117
|
import type { RouteLocationRaw } from 'vue-router'
|
|
160
|
-
import {
|
|
161
|
-
import { RiDownloadLine, RiEyeLine, RiLineChartLine, RiStarLine, RiSubtractLine } from '@remixicon/vue'
|
|
118
|
+
import { RiArchiveLine, RiDatabase2Line, RiDownloadLine, RiEyeLine, RiLineChartLine, RiLockLine, RiStarLine, RiSubtractLine } from '@remixicon/vue'
|
|
162
119
|
import type { Dataset, DatasetV2 } from '../types/datasets'
|
|
163
120
|
import { summarize } from '../functions/helpers'
|
|
164
121
|
import { useFormatDate } from '../functions/dates'
|
|
165
|
-
import {
|
|
166
|
-
import { getDescriptionShort } from '../functions/datasets'
|
|
167
|
-
import { useComponentsConfig } from '../config'
|
|
122
|
+
import { getDescriptionShort } from '../functions/description'
|
|
168
123
|
import { useTranslation } from '../composables/useTranslation'
|
|
169
124
|
import DatasetQualityInline from './DatasetQualityInline.vue'
|
|
170
125
|
import Avatar from './Avatar.vue'
|
|
171
126
|
import Placeholder from './Placeholder.vue'
|
|
172
|
-
import OrganizationNameWithCertificate from './OrganizationNameWithCertificate.vue'
|
|
173
|
-
import AppLink from './AppLink.vue'
|
|
174
127
|
import OrganizationLogo from './OrganizationLogo.vue'
|
|
128
|
+
import ObjectCardOwner from './ObjectCardOwner.vue'
|
|
129
|
+
import ObjectCard from './ObjectCard.vue'
|
|
130
|
+
import ObjectCardBadge from './ObjectCardBadge.vue'
|
|
131
|
+
import ObjectCardHeader from './ObjectCardHeader.vue'
|
|
132
|
+
import ObjectCardShortDescription from './ObjectCardShortDescription.vue'
|
|
175
133
|
|
|
176
134
|
type Props = {
|
|
177
135
|
dataset: Dataset | DatasetV2
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* The datasetUrl is a route location object to allow Vue Router to navigate to the details of a dataset.
|
|
181
|
-
* It is used as a separate prop to allow other sites using the package to define their own dataset pages.
|
|
182
|
-
*/
|
|
183
|
-
datasetUrl: RouteLocationRaw
|
|
136
|
+
datasetUrl?: RouteLocationRaw
|
|
184
137
|
datasetUrlInNewTab?: boolean
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* The organizationUrl is an optional route location object to allow Vue Router to navigate to the details of the organization linked to tha dataset.
|
|
188
|
-
* It is used as a separate prop to allow other sites using the package to define their own organization pages.
|
|
189
|
-
*/
|
|
190
138
|
organizationUrl?: RouteLocationRaw
|
|
191
139
|
showDescriptionShort?: boolean
|
|
192
140
|
}
|
|
193
141
|
|
|
194
142
|
const props = withDefaults(defineProps<Props>(), {
|
|
195
|
-
style: () => ({}),
|
|
196
143
|
showDescriptionShort: true,
|
|
197
144
|
})
|
|
198
145
|
|
|
199
146
|
const { t } = useTranslation()
|
|
200
147
|
const { formatRelativeIfRecentDate } = useFormatDate()
|
|
201
|
-
const ownerName = computed(() => getOwnerName(props.dataset))
|
|
202
|
-
const config = useComponentsConfig()
|
|
203
|
-
|
|
204
|
-
const descriptionShort = ref('')
|
|
205
|
-
watchEffect(async () => {
|
|
206
|
-
if (!props.showDescriptionShort) return
|
|
207
|
-
descriptionShort.value = await getDescriptionShort(props.dataset.description, props.dataset.description_short)
|
|
208
|
-
})
|
|
209
148
|
</script>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="space-y-1 py-6">
|
|
3
|
+
<div class="flex items-center space-x-2 mb-1">
|
|
4
|
+
<h3 class="mb-0 uppercase text-gray-plain text-sm font-bold">
|
|
5
|
+
{{ t('Intégrer sur votre site') }}
|
|
6
|
+
</h3>
|
|
7
|
+
<CopyButton
|
|
8
|
+
:hide-label="true"
|
|
9
|
+
:label="t('Copier le code embarqué')"
|
|
10
|
+
:copied-label="t('Code embarqué copié !')"
|
|
11
|
+
:text="embedHtml"
|
|
12
|
+
/>
|
|
13
|
+
</div>
|
|
14
|
+
<textarea
|
|
15
|
+
ref="textAreaRef"
|
|
16
|
+
class="bg-gray-lower text-gray-medium rounded font-mono text-sm px-1 py-[2px] w-full border resize-none"
|
|
17
|
+
:value="embedHtml"
|
|
18
|
+
readonly="true"
|
|
19
|
+
@click="selectContent"
|
|
20
|
+
/>
|
|
21
|
+
</div>
|
|
22
|
+
</template>
|
|
23
|
+
|
|
24
|
+
<script setup lang="ts">
|
|
25
|
+
import { ref, computed } from 'vue'
|
|
26
|
+
import { useTranslation } from '../../composables/useTranslation'
|
|
27
|
+
import { getDatasetOEmbedHtml } from '../../functions/datasets'
|
|
28
|
+
import type { Dataset, DatasetV2, DatasetV2WithFullObject } from '../../types/datasets'
|
|
29
|
+
import CopyButton from '../CopyButton.vue'
|
|
30
|
+
|
|
31
|
+
const props = defineProps<{
|
|
32
|
+
dataset: Dataset | DatasetV2 | DatasetV2WithFullObject
|
|
33
|
+
}>()
|
|
34
|
+
|
|
35
|
+
const { t } = useTranslation()
|
|
36
|
+
const textAreaRef = ref<HTMLTextAreaElement | null>(null)
|
|
37
|
+
|
|
38
|
+
const embedHtml = computed(() => getDatasetOEmbedHtml('dataset', props.dataset.id))
|
|
39
|
+
|
|
40
|
+
function selectContent(e: Event) {
|
|
41
|
+
(e.target as HTMLTextAreaElement).select()
|
|
42
|
+
}
|
|
43
|
+
</script>
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="space-y-1 py-6">
|
|
3
|
+
<h3 class="uppercase text-gray-plain text-sm font-bold">
|
|
4
|
+
{{ t('Informations') }}
|
|
5
|
+
</h3>
|
|
6
|
+
<DescriptionList>
|
|
7
|
+
<div v-if="dataset.tags && dataset.tags.length">
|
|
8
|
+
<DescriptionListTerm>{{ t('Mots-clés') }}</DescriptionListTerm>
|
|
9
|
+
<DescriptionListDetails class="flex flex-wrap gap-2 items-start">
|
|
10
|
+
<AppLink
|
|
11
|
+
v-for="tag in dataset.tags"
|
|
12
|
+
:key="tag"
|
|
13
|
+
class="fr-raw-link"
|
|
14
|
+
:to="getTagUrl(tag)"
|
|
15
|
+
>
|
|
16
|
+
<Tag type="secondary">
|
|
17
|
+
{{ tag }}
|
|
18
|
+
</Tag>
|
|
19
|
+
</AppLink>
|
|
20
|
+
</DescriptionListDetails>
|
|
21
|
+
</div>
|
|
22
|
+
<div>
|
|
23
|
+
<DescriptionListTerm>{{ t('Identifiant') }}</DescriptionListTerm>
|
|
24
|
+
<DescriptionListDetails class="flex items-center gap-2">
|
|
25
|
+
{{ dataset.id }}
|
|
26
|
+
<CopyButton
|
|
27
|
+
class="!-mt-0.5"
|
|
28
|
+
:label="t(`Copier l'identifiant`)"
|
|
29
|
+
:copied-label="t('Identifiant copié !')"
|
|
30
|
+
:text="dataset.id"
|
|
31
|
+
:hide-label="true"
|
|
32
|
+
/>
|
|
33
|
+
</DescriptionListDetails>
|
|
34
|
+
</div>
|
|
35
|
+
<div v-if="dataset.license">
|
|
36
|
+
<DescriptionListTerm>{{ t('Licence') }}</DescriptionListTerm>
|
|
37
|
+
<DescriptionListDetails>
|
|
38
|
+
<LicenseBadge :license="dataset.license" />
|
|
39
|
+
</DescriptionListDetails>
|
|
40
|
+
</div>
|
|
41
|
+
<slot />
|
|
42
|
+
</DescriptionList>
|
|
43
|
+
</div>
|
|
44
|
+
</template>
|
|
45
|
+
|
|
46
|
+
<script setup lang="ts">
|
|
47
|
+
import { useTranslation } from '../../composables/useTranslation'
|
|
48
|
+
import { useComponentsConfig } from '../../config'
|
|
49
|
+
import type { DatasetV2WithFullObject } from '../../types/datasets'
|
|
50
|
+
import DescriptionList from '../DescriptionList.vue'
|
|
51
|
+
import DescriptionListTerm from '../DescriptionListTerm.vue'
|
|
52
|
+
import DescriptionListDetails from '../DescriptionListDetails.vue'
|
|
53
|
+
import AppLink from '../AppLink.vue'
|
|
54
|
+
import CopyButton from '../CopyButton.vue'
|
|
55
|
+
import LicenseBadge from '../LicenseBadge.vue'
|
|
56
|
+
import Tag from '../Tag.vue'
|
|
57
|
+
|
|
58
|
+
const props = defineProps<{
|
|
59
|
+
dataset: DatasetV2WithFullObject
|
|
60
|
+
tagUrl?: (tag: string) => string
|
|
61
|
+
}>()
|
|
62
|
+
|
|
63
|
+
const { t } = useTranslation()
|
|
64
|
+
const config = useComponentsConfig()
|
|
65
|
+
|
|
66
|
+
function getTagUrl(tag: string): string {
|
|
67
|
+
if (props.tagUrl) {
|
|
68
|
+
return props.tagUrl(tag)
|
|
69
|
+
}
|
|
70
|
+
const base = config.baseUrl.endsWith('/') ? config.baseUrl.slice(0, -1) : config.baseUrl
|
|
71
|
+
return `${base}/datasets/search?tag=${tag}`
|
|
72
|
+
}
|
|
73
|
+
</script>
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
v-if="schemas && schemas.length"
|
|
4
|
+
class="space-y-1 py-6"
|
|
5
|
+
>
|
|
6
|
+
<h3 class="uppercase text-gray-plain text-sm font-bold">
|
|
7
|
+
{{ t('Schéma de données') }}
|
|
8
|
+
</h3>
|
|
9
|
+
<div class="space-y-4">
|
|
10
|
+
<div
|
|
11
|
+
v-for="schema, index in schemas"
|
|
12
|
+
:key="index"
|
|
13
|
+
class="flex flex-col md:flex-row gap-2 justify-between items-center"
|
|
14
|
+
>
|
|
15
|
+
<p class="text-sm mb-0">
|
|
16
|
+
{{ t('Les fichiers du jeu de données suivent le schéma :') }}
|
|
17
|
+
<Tag
|
|
18
|
+
type="secondary"
|
|
19
|
+
:icon="RiCheckboxCircleLine"
|
|
20
|
+
>
|
|
21
|
+
{{ schema.name || schema.url }}
|
|
22
|
+
</Tag>
|
|
23
|
+
</p>
|
|
24
|
+
<div v-if="schema.url || schema.name">
|
|
25
|
+
<BrandedButton
|
|
26
|
+
color="secondary"
|
|
27
|
+
:icon="RiBook2Line"
|
|
28
|
+
:href="schema.url ? schema.url : `${config.schemasSiteUrl}${schema.name}`"
|
|
29
|
+
>
|
|
30
|
+
{{ t('Voir la documentation du schéma') }}
|
|
31
|
+
</BrandedButton>
|
|
32
|
+
</div>
|
|
33
|
+
</div>
|
|
34
|
+
<p
|
|
35
|
+
v-if="config.schemasSiteUrl && config.schemasSiteName"
|
|
36
|
+
class="text-sm"
|
|
37
|
+
>
|
|
38
|
+
<TranslationT keypath="Les schémas de données permettent de décrire des modèles de données, découvrez comment les schémas améliorent la qualité des données et quels sont les cas d'usages possibles sur {link}">
|
|
39
|
+
<template #link>
|
|
40
|
+
<AppLink
|
|
41
|
+
:to="config.schemasSiteUrl"
|
|
42
|
+
external
|
|
43
|
+
>
|
|
44
|
+
{{ config.schemasSiteName }}
|
|
45
|
+
</AppLink>
|
|
46
|
+
</template>
|
|
47
|
+
</TranslationT>
|
|
48
|
+
</p>
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
</template>
|
|
52
|
+
|
|
53
|
+
<script setup lang="ts">
|
|
54
|
+
import { RiBook2Line, RiCheckboxCircleLine } from '@remixicon/vue'
|
|
55
|
+
import { useTranslation } from '../../composables/useTranslation'
|
|
56
|
+
import { useComponentsConfig } from '../../config'
|
|
57
|
+
import { useFetch } from '../../functions/api'
|
|
58
|
+
import type { Dataset, DatasetV2, DatasetV2WithFullObject } from '../../types/datasets'
|
|
59
|
+
import type { Schema } from '../../types/schemas'
|
|
60
|
+
import Tag from '../Tag.vue'
|
|
61
|
+
import BrandedButton from '../BrandedButton.vue'
|
|
62
|
+
import TranslationT from '../TranslationT.vue'
|
|
63
|
+
import AppLink from '../AppLink.vue'
|
|
64
|
+
|
|
65
|
+
const props = defineProps<{
|
|
66
|
+
dataset: Dataset | DatasetV2 | DatasetV2WithFullObject
|
|
67
|
+
}>()
|
|
68
|
+
|
|
69
|
+
const { t } = useTranslation()
|
|
70
|
+
const config = useComponentsConfig()
|
|
71
|
+
|
|
72
|
+
const { data } = await useFetch<Array<Schema>>(`/api/2/datasets/${props.dataset.id}/schemas/`)
|
|
73
|
+
const schemas = data
|
|
74
|
+
</script>
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
v-if="dataset.spatial"
|
|
4
|
+
class="space-y-1 py-6"
|
|
5
|
+
>
|
|
6
|
+
<h3 class="uppercase text-gray-plain text-sm font-bold">
|
|
7
|
+
{{ t('Couverture spatiale') }}
|
|
8
|
+
</h3>
|
|
9
|
+
<DescriptionList>
|
|
10
|
+
<div v-if="dataset.spatial.zones && dataset.spatial.zones.length">
|
|
11
|
+
<DescriptionListTerm>{{ t('Zones') }}</DescriptionListTerm>
|
|
12
|
+
<DescriptionListDetails>{{ zonesDisplay }}</DescriptionListDetails>
|
|
13
|
+
</div>
|
|
14
|
+
<div v-if="dataset.spatial.geom">
|
|
15
|
+
<DescriptionListTerm>{{ t('Couverture géographique') }}</DescriptionListTerm>
|
|
16
|
+
<DescriptionListDetails>
|
|
17
|
+
<slot
|
|
18
|
+
name="map"
|
|
19
|
+
:geojson="dataset.spatial.geom"
|
|
20
|
+
/>
|
|
21
|
+
</DescriptionListDetails>
|
|
22
|
+
</div>
|
|
23
|
+
<div v-if="dataset.spatial.granularity">
|
|
24
|
+
<DescriptionListTerm>{{ t('Granularité de la couverture territoriale') }}</DescriptionListTerm>
|
|
25
|
+
<DescriptionListDetails>{{ dataset.spatial.granularity.name }}</DescriptionListDetails>
|
|
26
|
+
</div>
|
|
27
|
+
<slot />
|
|
28
|
+
</DescriptionList>
|
|
29
|
+
</div>
|
|
30
|
+
</template>
|
|
31
|
+
|
|
32
|
+
<script setup lang="ts">
|
|
33
|
+
import { computed } from 'vue'
|
|
34
|
+
import { useTranslation } from '../../composables/useTranslation'
|
|
35
|
+
import type { DatasetV2WithFullObject } from '../../types/datasets'
|
|
36
|
+
import DescriptionList from '../DescriptionList.vue'
|
|
37
|
+
import DescriptionListTerm from '../DescriptionListTerm.vue'
|
|
38
|
+
import DescriptionListDetails from '../DescriptionListDetails.vue'
|
|
39
|
+
|
|
40
|
+
const props = defineProps<{
|
|
41
|
+
dataset: DatasetV2WithFullObject
|
|
42
|
+
}>()
|
|
43
|
+
|
|
44
|
+
const { t } = useTranslation()
|
|
45
|
+
|
|
46
|
+
const zonesDisplay = computed(() => {
|
|
47
|
+
if (!props.dataset.spatial?.zones?.length) return ''
|
|
48
|
+
const names = props.dataset.spatial.zones.map(z => z.name)
|
|
49
|
+
return humanJoin(names)
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
function humanJoin(source: Array<string>): string {
|
|
53
|
+
const array = [...source]
|
|
54
|
+
if (!array.length) return ''
|
|
55
|
+
if (array.length === 1) return array[0]!
|
|
56
|
+
const last = array.pop()!
|
|
57
|
+
return `${array.join(', ')} ${t('et')} ${last}`
|
|
58
|
+
}
|
|
59
|
+
</script>
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="space-y-1 py-6">
|
|
3
|
+
<h3 class="uppercase text-gray-plain text-sm font-bold">
|
|
4
|
+
{{ t('Temporalité') }}
|
|
5
|
+
</h3>
|
|
6
|
+
<DescriptionList>
|
|
7
|
+
<div>
|
|
8
|
+
<DescriptionListTerm>{{ t('Création') }}</DescriptionListTerm>
|
|
9
|
+
<DescriptionListDetails>{{ formatDate(dataset.created_at) }}</DescriptionListDetails>
|
|
10
|
+
</div>
|
|
11
|
+
<div v-if="dataset.frequency">
|
|
12
|
+
<DescriptionListTerm>{{ t('Fréquence') }}</DescriptionListTerm>
|
|
13
|
+
<DescriptionListDetails>{{ dataset.frequency.label }}</DescriptionListDetails>
|
|
14
|
+
</div>
|
|
15
|
+
<div v-if="dataset.temporal_coverage">
|
|
16
|
+
<DescriptionListTerm>{{ t('Couverture temporelle') }}</DescriptionListTerm>
|
|
17
|
+
<DescriptionListDetails>
|
|
18
|
+
<DateRangeDetails :range="dataset.temporal_coverage" />
|
|
19
|
+
</DescriptionListDetails>
|
|
20
|
+
</div>
|
|
21
|
+
<div>
|
|
22
|
+
<DescriptionListTerm>{{ t('Dernière mise à jour') }}</DescriptionListTerm>
|
|
23
|
+
<DescriptionListDetails>{{ formatDate(dataset.last_update) }}</DescriptionListDetails>
|
|
24
|
+
</div>
|
|
25
|
+
<slot />
|
|
26
|
+
</DescriptionList>
|
|
27
|
+
</div>
|
|
28
|
+
</template>
|
|
29
|
+
|
|
30
|
+
<script setup lang="ts">
|
|
31
|
+
import { useTranslation } from '../../composables/useTranslation'
|
|
32
|
+
import { useFormatDate } from '../../functions/dates'
|
|
33
|
+
import type { DatasetV2WithFullObject } from '../../types/datasets'
|
|
34
|
+
import DescriptionList from '../DescriptionList.vue'
|
|
35
|
+
import DescriptionListTerm from '../DescriptionListTerm.vue'
|
|
36
|
+
import DescriptionListDetails from '../DescriptionListDetails.vue'
|
|
37
|
+
import DateRangeDetails from '../DateRangeDetails.vue'
|
|
38
|
+
|
|
39
|
+
defineProps<{
|
|
40
|
+
dataset: DatasetV2WithFullObject
|
|
41
|
+
}>()
|
|
42
|
+
|
|
43
|
+
const { t } = useTranslation()
|
|
44
|
+
const { formatDate } = useFormatDate()
|
|
45
|
+
</script>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { default as DatasetInformationSection } from './DatasetInformationSection.vue'
|
|
2
|
+
export { default as DatasetTemporalitySection } from './DatasetTemporalitySection.vue'
|
|
3
|
+
export { default as DatasetSpatialSection } from './DatasetSpatialSection.vue'
|
|
4
|
+
export { default as DatasetSchemaSection } from './DatasetSchemaSection.vue'
|
|
5
|
+
export { default as DatasetEmbedSection } from './DatasetEmbedSection.vue'
|