@datagouv/components-next 0.0.7 → 0.0.9
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 +34 -14
- package/assets/json/vector.json +2377 -0
- package/assets/main.css +3 -0
- package/assets/swagger-themes/newspaper.css +1669 -0
- package/assets/tailwind.config.js +1 -1
- package/dist/JsonPreview.client-BIz1_EiB.js +92 -0
- package/dist/MapContainer.client-ZDwr4Q_I.js +78276 -0
- package/dist/PdfPreview.client-BTTMM27i.js +112 -0
- package/dist/Pmtiles.client-4kOoUQcR.js +22377 -0
- package/dist/Swagger.client-Q7a5wb51.js +4 -0
- package/dist/XmlPreview.client-BYIIkDqf.js +84 -0
- package/dist/components-next.css +52 -1
- package/dist/components-next.js +42 -41
- package/dist/components.css +1 -1
- package/dist/main-CLUk9Jj7.js +105843 -0
- package/dist/pdf-vue3-BZh6kzke.js +273 -0
- package/dist/pdf.min-f72cfa08-DAetWL3M.js +9501 -0
- package/dist/{text-clamp.esm-DurZFOvT.js → text-clamp.esm-DP59tec5.js} +1 -1
- package/dist/vue3-json-viewer-DIQzFF6K.js +1089 -0
- package/dist/vue3-xml-viewer.common-BmKw6vER.js +5437 -0
- package/package.json +7 -5
- package/src/components/AvatarWithName.vue +6 -2
- package/src/components/BannerAction.vue +1 -1
- package/src/components/BrandedButton.vue +13 -8
- package/src/components/CopyButton.vue +7 -7
- package/src/components/DataserviceCard.vue +54 -23
- package/src/components/DatasetCard.vue +36 -24
- package/src/components/DatasetInformationPanel.vue +19 -18
- package/src/components/DatasetQuality.vue +21 -18
- package/src/components/DatasetQualityInline.vue +1 -1
- package/src/components/DatasetQualityItem.vue +3 -3
- package/src/components/DatasetQualityItemWarning.vue +2 -2
- package/src/components/DatasetQualityScore.vue +2 -2
- package/src/components/DatasetQualityTooltipContent.vue +29 -29
- package/src/components/DescriptionDetails.vue +2 -2
- package/src/components/ExtraAccordion.vue +10 -7
- package/src/components/OrganizationCard.vue +9 -4
- package/src/components/OrganizationNameWithCertificate.vue +25 -11
- package/src/components/Pagination.vue +26 -15
- package/src/components/ReadMore.vue +2 -2
- package/src/components/ResourceAccordion/DataStructure.vue +2 -2
- package/src/components/ResourceAccordion/EditButton.vue +10 -6
- package/src/components/ResourceAccordion/JsonPreview.client.vue +153 -0
- package/src/components/ResourceAccordion/MapContainer.client.vue +137 -0
- package/src/components/ResourceAccordion/Metadata.vue +33 -54
- package/src/components/ResourceAccordion/PdfPreview.client.vue +189 -0
- package/src/components/ResourceAccordion/Pmtiles.client.vue +166 -0
- package/src/components/ResourceAccordion/Preview.vue +39 -37
- package/src/components/ResourceAccordion/ResourceAccordion.vue +141 -63
- package/src/components/ResourceAccordion/ResourceIcon.vue +7 -1
- package/src/components/ResourceAccordion/SchemaBadge.vue +26 -26
- package/src/components/ResourceAccordion/{Swagger.vue → Swagger.client.vue} +1 -1
- package/src/components/ResourceAccordion/XmlPreview.client.vue +143 -0
- package/src/components/ReuseCard.vue +10 -7
- package/src/components/ReuseDetails.vue +3 -3
- package/src/components/SimpleBanner.vue +7 -4
- package/src/components/SmallChart.vue +23 -9
- package/src/components/StatBox.vue +92 -10
- package/src/config.ts +6 -2
- package/src/functions/api.ts +18 -18
- package/src/functions/dates.ts +81 -74
- package/src/functions/helpers.ts +5 -4
- package/src/functions/organizations.ts +5 -5
- package/src/functions/resources.ts +34 -5
- package/src/functions/schemas.ts +4 -3
- package/src/functions/tabularApi.ts +1 -1
- package/src/main.ts +10 -11
- package/src/types/badges.ts +3 -3
- package/src/types/contact_point.ts +5 -5
- package/src/types/dataservices.ts +16 -2
- package/src/types/datasets.ts +20 -2
- package/src/types/frequency.ts +5 -5
- package/src/types/granularity.ts +12 -4
- package/src/types/harvest.ts +2 -2
- package/src/types/licenses.ts +8 -8
- package/src/types/organizations.ts +6 -0
- package/src/types/resources.ts +3 -3
- package/src/types/reuses.ts +3 -1
- package/src/types/site.ts +8 -0
- package/src/types/ui.ts +2 -2
- package/src/types/users.ts +24 -8
- package/src/types/vue3-xml-viewer.d.ts +10 -0
- package/dist/Swagger-DjysB-OI.js +0 -67851
- package/dist/en-DCRve7vN.js +0 -613
- package/dist/fr-DCOnbL-p.js +0 -613
- package/dist/locales/de.js +0 -155
- package/dist/locales/en.js +0 -155
- package/dist/locales/es.js +0 -155
- package/dist/locales/fr.js +0 -155
- package/dist/locales/it.js +0 -155
- package/dist/locales/pt.js +0 -155
- package/dist/locales/sr.js +0 -155
- package/dist/main-CPW2vNLE.js +0 -32008
- package/src/components/DescriptionList/DescriptionDetails.stories.ts +0 -43
- package/src/components/DescriptionList/DescriptionList.stories.ts +0 -47
- package/src/components/DescriptionList/DescriptionTerm.stories.ts +0 -28
- package/src/locales/de.json +0 -154
- package/src/locales/en.json +0 -154
- package/src/locales/es.json +0 -154
- package/src/locales/fr.json +0 -154
- package/src/locales/it.json +0 -154
- package/src/locales/pt.json +0 -154
- package/src/locales/sr.json +0 -154
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<SimpleBanner
|
|
4
|
+
v-if="hasError"
|
|
5
|
+
type="warning"
|
|
6
|
+
class="flex items-center space-x-2"
|
|
7
|
+
>
|
|
8
|
+
<RiErrorWarningLine class="shink-0 size-6" />
|
|
9
|
+
<span>{{ t("L'aperçu cartographique de ce fichier n'a pas pu être chargé.") }}</span>
|
|
10
|
+
</SimpleBanner>
|
|
11
|
+
<div
|
|
12
|
+
v-else
|
|
13
|
+
class="-mx-4"
|
|
14
|
+
>
|
|
15
|
+
<div
|
|
16
|
+
v-if="pmtilesViewerUrl"
|
|
17
|
+
class="bg-blue-100 text-datagouv fr-hidden fr-unhidden-md p-4"
|
|
18
|
+
>
|
|
19
|
+
<div class="fr-grid-row fr-grid-row--middle fr-grid-row--gutters">
|
|
20
|
+
<div
|
|
21
|
+
class="fr-col-auto"
|
|
22
|
+
v-html="franceSvg"
|
|
23
|
+
/>
|
|
24
|
+
<div class="fr-col">
|
|
25
|
+
<p class="fr-text--bold fr-m-0">
|
|
26
|
+
{{ t("Explorer les données en détail") }}
|
|
27
|
+
</p>
|
|
28
|
+
<p class="fr-text--sm fr-m-0 f-italic">
|
|
29
|
+
{{ t("Utiliser un visualisateur PMTiles pour obtenir un aperçu des données.") }}
|
|
30
|
+
</p>
|
|
31
|
+
</div>
|
|
32
|
+
<p class="fr-col-auto fr-my-0">
|
|
33
|
+
<BrandedButton
|
|
34
|
+
:href="pmtilesViewerUrl"
|
|
35
|
+
:icon="RiExternalLinkFill"
|
|
36
|
+
icon-right
|
|
37
|
+
>
|
|
38
|
+
{{ t("Explorer la carte") }}
|
|
39
|
+
</BrandedButton>
|
|
40
|
+
</p>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
<div
|
|
44
|
+
ref="containerRef"
|
|
45
|
+
style="height: 600px;"
|
|
46
|
+
/>
|
|
47
|
+
<div class="fr-px-5v fr-pt-5v">
|
|
48
|
+
{{ t("Aperçu de la carte mis à jour le {date}", { date: lastUpdate }) }}
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
</template>
|
|
53
|
+
|
|
54
|
+
<script setup lang="ts">
|
|
55
|
+
import { computed, onMounted, ref } from 'vue'
|
|
56
|
+
import { useI18n } from 'vue-i18n'
|
|
57
|
+
import { RiErrorWarningLine, RiExternalLinkFill } from '@remixicon/vue'
|
|
58
|
+
import { Protocol, PMTiles } from 'pmtiles'
|
|
59
|
+
import maplibregl from 'maplibre-gl'
|
|
60
|
+
import DOMPurify from 'dompurify'
|
|
61
|
+
import { useComponentsConfig } from '../../config'
|
|
62
|
+
import { useFormatDate } from '../../functions/dates'
|
|
63
|
+
import type { Resource } from '../../types/resources'
|
|
64
|
+
import BrandedButton from '../BrandedButton.vue'
|
|
65
|
+
import styleVector from '../../../assets/json/vector.json'
|
|
66
|
+
import SimpleBanner from '../SimpleBanner.vue'
|
|
67
|
+
import franceSvg from './france.svg?raw'
|
|
68
|
+
|
|
69
|
+
const props = defineProps<{ resource: Resource }>()
|
|
70
|
+
|
|
71
|
+
const { t } = useI18n()
|
|
72
|
+
const { formatDate } = useFormatDate()
|
|
73
|
+
|
|
74
|
+
const config = useComponentsConfig()
|
|
75
|
+
|
|
76
|
+
const hasError = ref(false)
|
|
77
|
+
const pmtilesUrl = computed(() => props.resource.extras['analysis:parsing:pmtiles_url'])
|
|
78
|
+
const pmtilesViewerUrl = computed(() => {
|
|
79
|
+
return config.pmtilesViewerBaseUrl ? `${config.pmtilesViewerBaseUrl}${encodeURIComponent(pmtilesUrl.value)}` : null
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
const lastUpdate = computed(() => formatDate(props.resource.extras['analysis:parsing:finished_at']))
|
|
83
|
+
|
|
84
|
+
const container = useTemplateRef('containerRef')
|
|
85
|
+
|
|
86
|
+
async function displayMap() {
|
|
87
|
+
await import('maplibre-gl/dist/maplibre-gl.css')
|
|
88
|
+
|
|
89
|
+
const protocol = new Protocol()
|
|
90
|
+
maplibregl.addProtocol('pmtiles', protocol.tile)
|
|
91
|
+
|
|
92
|
+
const p = new PMTiles(pmtilesUrl.value)
|
|
93
|
+
protocol.add(p)
|
|
94
|
+
|
|
95
|
+
p.getHeader().then((h) => {
|
|
96
|
+
const map = new maplibregl.Map({
|
|
97
|
+
container: container.value, // container id
|
|
98
|
+
style: styleVector,
|
|
99
|
+
zoom: h.maxZoom - 2,
|
|
100
|
+
center: [h.centerLon, h.centerLat],
|
|
101
|
+
})
|
|
102
|
+
map.addControl(new maplibregl.NavigationControl())
|
|
103
|
+
|
|
104
|
+
const popup = new maplibregl.Popup({
|
|
105
|
+
closeButton: false,
|
|
106
|
+
closeOnClick: false,
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
function showMapPopup(e) {
|
|
110
|
+
if (!e.features || !e.features[0])
|
|
111
|
+
popup.remove()
|
|
112
|
+
else {
|
|
113
|
+
const coordinates = e.lngLat
|
|
114
|
+
const description = Object.keys(e.features[0].properties).map((element) => {
|
|
115
|
+
return `<b>${DOMPurify.sanitize(element)} :</b> ${DOMPurify.sanitize(e.features[0].properties[element])}`
|
|
116
|
+
}).join('<br>')
|
|
117
|
+
popup.setLngLat(coordinates).setHTML(description).addTo(map)
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
map.on('load', () => {
|
|
122
|
+
p.getMetadata().then((metadata) => {
|
|
123
|
+
map.addSource('pmtiles_source', {
|
|
124
|
+
type: 'vector',
|
|
125
|
+
url: `pmtiles://${pmtilesUrl.value}`,
|
|
126
|
+
attribution: '© <a href="https://openstreetmap.org">OpenStreetMap</a>',
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
metadata.tilestats.layers.forEach((layer) => {
|
|
130
|
+
const typeLayer = computed(() => {
|
|
131
|
+
switch (layer.geometry) {
|
|
132
|
+
case 'Polygon':
|
|
133
|
+
return 'fill'
|
|
134
|
+
case 'Point':
|
|
135
|
+
return `circle`
|
|
136
|
+
case 'LineString':
|
|
137
|
+
return `line`
|
|
138
|
+
default:
|
|
139
|
+
throwOnNever(layer.geometry, 'Unsupported geometry')
|
|
140
|
+
return ''
|
|
141
|
+
}
|
|
142
|
+
})
|
|
143
|
+
map.addLayer({
|
|
144
|
+
'id': layer.layer,
|
|
145
|
+
'source': 'pmtiles_source',
|
|
146
|
+
'source-layer': layer.layer,
|
|
147
|
+
'type': typeLayer.value,
|
|
148
|
+
'paint': {
|
|
149
|
+
[`${typeLayer.value}-color`]: 'steelblue',
|
|
150
|
+
[`${typeLayer.value}-opacity`]: { base: 1, stops: [[0, 0.9], [10, 0.6]] },
|
|
151
|
+
},
|
|
152
|
+
})
|
|
153
|
+
map.on('mousemove', layer.layer, showMapPopup)
|
|
154
|
+
map.on('touchmove', layer.layer, showMapPopup)
|
|
155
|
+
map.on('click', layer.layer, showMapPopup)
|
|
156
|
+
map.on('mouseleave', layer.layer, showMapPopup)
|
|
157
|
+
})
|
|
158
|
+
}).catch (() => hasError.value = true)
|
|
159
|
+
})
|
|
160
|
+
}).catch (() => hasError.value = true)
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
onMounted(() => {
|
|
164
|
+
displayMap()
|
|
165
|
+
})
|
|
166
|
+
</script>
|
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div>
|
|
3
|
-
<
|
|
3
|
+
<SimpleBanner
|
|
4
4
|
v-if="hasError"
|
|
5
|
-
|
|
5
|
+
type="warning"
|
|
6
|
+
class="flex items-center space-x-2"
|
|
6
7
|
>
|
|
7
|
-
<
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
aria-hidden="true"
|
|
11
|
-
/>
|
|
12
|
-
{{ t("The preview of this file failed to load.") }}
|
|
13
|
-
</p>
|
|
14
|
-
</div>
|
|
8
|
+
<RiErrorWarningLine class="shink-0 size-6" />
|
|
9
|
+
<span>{{ t("L'aperçu de ce fichier n'a pas pu être chargé.") }}</span>
|
|
10
|
+
</SimpleBanner>
|
|
15
11
|
<PreviewLoader v-else-if="loading" />
|
|
16
|
-
<
|
|
12
|
+
<div
|
|
13
|
+
v-else
|
|
14
|
+
class="-mx-4"
|
|
15
|
+
>
|
|
17
16
|
<div class="bg-blue-100 text-datagouv fr-hidden fr-unhidden-md p-4">
|
|
18
17
|
<div class="fr-grid-row fr-grid-row--middle fr-grid-row--gutters">
|
|
19
18
|
<div
|
|
@@ -22,10 +21,10 @@
|
|
|
22
21
|
/>
|
|
23
22
|
<div class="fr-col">
|
|
24
23
|
<p class="fr-text--bold fr-m-0">
|
|
25
|
-
{{ t("
|
|
24
|
+
{{ t("Explorer les données en détail") }}
|
|
26
25
|
</p>
|
|
27
26
|
<p class="fr-text--sm fr-m-0 f-italic">
|
|
28
|
-
{{ t("
|
|
27
|
+
{{ t("Utiliser notre outil pour obtenir un aperçu des données, en savoir plus sur les différentes colonnes ou réaliser des filtres et des tris.") }}
|
|
29
28
|
</p>
|
|
30
29
|
</div>
|
|
31
30
|
<p class="fr-col-auto fr-my-0">
|
|
@@ -34,15 +33,15 @@
|
|
|
34
33
|
:icon="RiExternalLinkFill"
|
|
35
34
|
icon-right
|
|
36
35
|
>
|
|
37
|
-
{{ t("
|
|
36
|
+
{{ t("Explorer les données") }}
|
|
38
37
|
</BrandedButton>
|
|
39
38
|
</p>
|
|
40
39
|
</div>
|
|
41
40
|
</div>
|
|
42
|
-
<div class="fr-table fr-table--no-background fr-p-0 fr-
|
|
41
|
+
<div class="fr-table fr-table--no-background fr-p-0 fr-m-0">
|
|
43
42
|
<table class="fr-mb-3w">
|
|
44
|
-
<caption class="
|
|
45
|
-
{{ t('
|
|
43
|
+
<caption class="sr-only">
|
|
44
|
+
{{ t('Prévisualisation de {name}', { name: resource.title }) }}
|
|
46
45
|
</caption>
|
|
47
46
|
<thead>
|
|
48
47
|
<tr>
|
|
@@ -51,18 +50,19 @@
|
|
|
51
50
|
:key="index"
|
|
52
51
|
scope="col"
|
|
53
52
|
>
|
|
54
|
-
<
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
53
|
+
<BrandedButton
|
|
54
|
+
color="secondary-softer"
|
|
55
|
+
:icon="isSortedBy(col) && sortConfig && sortConfig.type == 'asc' ? RiArrowUpLine : RiArrowDownLine"
|
|
56
|
+
icon-right
|
|
57
|
+
size="xs"
|
|
58
|
+
@click="sortByField(col)"
|
|
59
|
+
>
|
|
60
|
+
<!-- There is a weird bug with `sr-only`, I needed to add a relative parent to avoid full page x scrolling into the void… -->
|
|
61
|
+
<span class="relative">
|
|
62
62
|
{{ col }}
|
|
63
|
-
<span class="sr-only">{{ sortConfig && sortConfig.type == 'desc' ? t("
|
|
64
|
-
</
|
|
65
|
-
</
|
|
63
|
+
<span class="sr-only">{{ sortConfig && sortConfig.type == 'desc' ? t("Trier par ordre croissant") : t("Trier par ordre décroissant") }}</span>
|
|
64
|
+
</span>
|
|
65
|
+
</BrandedButton>
|
|
66
66
|
</th>
|
|
67
67
|
</tr>
|
|
68
68
|
</thead>
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
:key="colIndex"
|
|
77
77
|
class="cell-padding"
|
|
78
78
|
>
|
|
79
|
-
<div class="fr-grid-row fr-grid-row--middle fr-text--xs w-
|
|
79
|
+
<div class="fr-grid-row fr-grid-row--middle fr-text--xs w-full style-cell">
|
|
80
80
|
<div class="fr-my-auto">
|
|
81
81
|
{{ row[col] }}
|
|
82
82
|
</div>
|
|
@@ -94,30 +94,32 @@
|
|
|
94
94
|
@change="changePage"
|
|
95
95
|
/>
|
|
96
96
|
<div class="fr-px-5v">
|
|
97
|
-
{{ t("
|
|
98
|
-
{{ t('{count}
|
|
99
|
-
{{ t('{count}
|
|
97
|
+
{{ t("Dernière mise à jour de la prévisualisation : {date}", { date: lastUpdate }) }} —
|
|
98
|
+
{{ t('{count} colonnes', columns.length) }} —
|
|
99
|
+
{{ t('Lignes {count}', rowCount) }}
|
|
100
100
|
</div>
|
|
101
|
-
</
|
|
101
|
+
</div>
|
|
102
102
|
</div>
|
|
103
103
|
</template>
|
|
104
104
|
|
|
105
105
|
<script setup lang="ts">
|
|
106
106
|
import { computed, onMounted, ref } from 'vue'
|
|
107
107
|
import { useI18n } from 'vue-i18n'
|
|
108
|
-
import { RiArrowDownLine, RiArrowUpLine, RiExternalLinkFill } from '@remixicon/vue'
|
|
108
|
+
import { RiArrowDownLine, RiArrowUpLine, RiErrorWarningLine, RiExternalLinkFill } from '@remixicon/vue'
|
|
109
109
|
import Pagination from '../Pagination.vue'
|
|
110
110
|
import { getData, type SortConfig } from '../../functions/tabularApi'
|
|
111
|
-
import {
|
|
111
|
+
import { useFormatDate } from '../../functions/dates'
|
|
112
112
|
import type { Resource } from '../../types/resources'
|
|
113
113
|
import { useComponentsConfig } from '../../config'
|
|
114
114
|
import BrandedButton from '../BrandedButton.vue'
|
|
115
|
+
import SimpleBanner from '../SimpleBanner.vue'
|
|
115
116
|
import franceSvg from './france.svg?raw'
|
|
116
117
|
import PreviewLoader from './PreviewLoader.vue'
|
|
117
118
|
|
|
118
119
|
const props = defineProps<{ resource: Resource }>()
|
|
119
120
|
|
|
120
121
|
const { t } = useI18n()
|
|
122
|
+
const { formatDate } = useFormatDate()
|
|
121
123
|
|
|
122
124
|
const rows = ref<Array<Record<string, unknown>>>([])
|
|
123
125
|
const columns = ref<Array<string>>([])
|
|
@@ -126,7 +128,7 @@ const hasError = ref(false)
|
|
|
126
128
|
const sortConfig = ref<SortConfig>(null)
|
|
127
129
|
const rowCount = ref(0)
|
|
128
130
|
const config = useComponentsConfig()
|
|
129
|
-
const pageSize = computed(() => config.tabularApiPageSize ||
|
|
131
|
+
const pageSize = computed(() => config.tabularApiPageSize || 15)
|
|
130
132
|
const currentPage = ref(1)
|
|
131
133
|
|
|
132
134
|
/**
|
|
@@ -197,7 +199,7 @@ function sortByField(col: string) {
|
|
|
197
199
|
getTableInfos(currentPage.value, sortConfig.value)
|
|
198
200
|
};
|
|
199
201
|
|
|
200
|
-
const lastUpdate = formatDate(props.resource.extras['analysis:parsing:finished_at'])
|
|
202
|
+
const lastUpdate = computed(() => formatDate(props.resource.extras['analysis:parsing:finished_at']))
|
|
201
203
|
|
|
202
204
|
onMounted(() => {
|
|
203
205
|
getTableInfos(currentPage.value)
|