@datagouv/components-next 0.0.32 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/README.md +5 -15
  2. package/assets/labels/hvd.svg +15 -0
  3. package/assets/labels/inspire.svg +20 -0
  4. package/assets/labels/sl.svg +5 -0
  5. package/assets/labels/spd.svg +5 -0
  6. package/assets/labels/sr.svg +5 -0
  7. package/dist/JsonPreview.client-NQ9byxF5.js +92 -0
  8. package/dist/{MapContainer.client-Dhfz-YU8.js → MapContainer.client-D7Y0OXMU.js} +17587 -6826
  9. package/dist/{PdfPreview.client--W0FK7CN.js → PdfPreview.client-DU6FbUh0.js} +47 -48
  10. package/dist/{Pmtiles.client-B6vRTwrm.js → Pmtiles.client-DCOxft6M.js} +7609 -7503
  11. package/dist/Swagger.client-DTHhEAFT.js +4 -0
  12. package/dist/XmlPreview.client-BEOCeCP8.js +84 -0
  13. package/dist/components-next.css +6 -6
  14. package/dist/components-next.js +95 -80
  15. package/dist/components.css +2 -2
  16. package/dist/en-CuSmdvir.js +30 -0
  17. package/dist/hvd-DYeke1vM.js +4 -0
  18. package/dist/inspire-BLXeJvob.js +4 -0
  19. package/dist/{main-yWiuApVL.js → main-DFEQrdg5.js} +53395 -55984
  20. package/dist/{pdf-vue3-Dm2ZCc3P.js → pdf-vue3-IkJO65RH.js} +2 -2
  21. package/dist/{pdf.min-f72cfa08-DAetWL3M.js → pdf.min-f72cfa08-CdgJTooZ.js} +78 -78
  22. package/dist/sl-VR8Tb1_u.js +4 -0
  23. package/dist/spd-BJ-Omhgt.js +4 -0
  24. package/dist/sr-DjSF-8xW.js +4 -0
  25. package/dist/{text-clamp.esm-Mb7Qdtu9.js → text-clamp.esm-B5kW_XMt.js} +54 -55
  26. package/dist/{vue3-json-viewer-B1fiyuLU.js → vue3-json-viewer-BXwup7nO.js} +88 -93
  27. package/dist/{vue3-xml-viewer.common-1QyofKqS.js → vue3-xml-viewer.common-RC76oYFu.js} +54 -54
  28. package/package.json +12 -11
  29. package/src/components/ActivityList/ActivityList.vue +159 -0
  30. package/src/components/ActivityList/UserActivityList.vue +30 -0
  31. package/src/components/AppLink.vue +3 -3
  32. package/src/components/Avatar.vue +1 -0
  33. package/src/components/DataserviceCard.vue +3 -3
  34. package/src/components/DatasetCard.vue +19 -18
  35. package/src/components/DatasetInformationPanel.vue +16 -16
  36. package/src/components/DatasetLabelTag.vue +40 -0
  37. package/src/components/DatasetQuality.vue +13 -10
  38. package/src/components/DatasetQualityInline.vue +5 -2
  39. package/src/components/DatasetQualityScore.vue +3 -3
  40. package/src/components/DatasetQualityTooltipContent.vue +2 -2
  41. package/src/components/DateRangeDetails.vue +7 -3
  42. package/src/components/ExtraAccordion.vue +3 -1
  43. package/src/components/OrganizationNameWithCertificate.vue +2 -2
  44. package/src/components/PaddedContainer.vue +28 -0
  45. package/src/components/Pagination.vue +2 -2
  46. package/src/components/Placeholder.vue +1 -1
  47. package/src/components/ReadMore.vue +17 -17
  48. package/src/components/ResourceAccordion/DataStructure.vue +8 -3
  49. package/src/components/ResourceAccordion/EditButton.vue +2 -2
  50. package/src/components/ResourceAccordion/JsonPreview.client.vue +7 -5
  51. package/src/components/ResourceAccordion/MapContainer.client.vue +2 -2
  52. package/src/components/ResourceAccordion/Metadata.vue +10 -10
  53. package/src/components/ResourceAccordion/PdfPreview.client.vue +7 -5
  54. package/src/components/ResourceAccordion/Pmtiles.client.vue +2 -2
  55. package/src/components/ResourceAccordion/Preview.vue +2 -2
  56. package/src/components/ResourceAccordion/ResourceAccordion.vue +23 -15
  57. package/src/components/ResourceAccordion/SchemaBadge.vue +4 -4
  58. package/src/components/ResourceAccordion/XmlPreview.client.vue +7 -5
  59. package/src/components/ReuseCard.vue +3 -3
  60. package/src/components/ReuseDetails.vue +2 -2
  61. package/src/components/SmallChart.vue +33 -30
  62. package/src/components/StatBox.vue +6 -6
  63. package/src/components/Toggletip.vue +0 -1
  64. package/src/components/TranslationT.vue +51 -0
  65. package/src/composables/useTranslation.ts +169 -0
  66. package/src/functions/activities.ts +36 -0
  67. package/src/functions/api.ts +4 -4
  68. package/src/functions/datasets.ts +28 -0
  69. package/src/functions/dates.ts +4 -4
  70. package/src/functions/helpers.ts +3 -3
  71. package/src/functions/organizations.ts +2 -2
  72. package/src/functions/pagination.ts +9 -0
  73. package/src/functions/resources.ts +2 -2
  74. package/src/functions/reuses.ts +3 -3
  75. package/src/main.ts +24 -20
  76. package/src/types/activity.ts +24 -0
  77. package/src/types/api.ts +8 -0
  78. package/src/types/badges.ts +4 -0
  79. package/src/types/dataservices.ts +6 -8
  80. package/src/types/datasets.ts +2 -1
  81. package/src/types/site.ts +1 -0
  82. package/src/types/topics.ts +17 -2
  83. package/dist/JsonPreview.client-BRhCOHlE.js +0 -93
  84. package/dist/Swagger.client-ch5H8aT2.js +0 -4
  85. package/dist/XmlPreview.client-BcbnRWAp.js +0 -85
@@ -98,7 +98,7 @@
98
98
  </div>
99
99
  <RiSubtractLine class="size-4 flex-none fill-gray-medium" />
100
100
  <div class="text-gray-medium whitespace-nowrap">
101
- {{ $t('Mis à jour {date}', { date: formatRelativeIfRecentDate(dataset.last_update, { dateStyle: 'medium' }) }) }}
101
+ {{ t('Mis à jour {date}', { date: formatRelativeIfRecentDate(dataset.last_update, { dateStyle: 'medium' }) }) }}
102
102
  </div>
103
103
  </div>
104
104
  <div class="mx-0 -mb-1 flex flex-wrap items-center text-sm text-gray-medium">
@@ -146,10 +146,10 @@
146
146
  </div>
147
147
  <component
148
148
  :is="config.textClamp"
149
- v-if="showDescription && config && config.textClamp && description"
149
+ v-if="showShortDescription && config && config.textClamp && shortDescription"
150
150
  class="fr-text--sm fr-mt-1w fr-mb-0 overflow-wrap-anywhere"
151
151
  :auto-resize="true"
152
- :text="description"
152
+ :text="shortDescription"
153
153
  :max-lines="2"
154
154
  />
155
155
  </div>
@@ -158,7 +158,6 @@
158
158
  </template>
159
159
 
160
160
  <script setup lang="ts">
161
- import { useI18n } from 'vue-i18n'
162
161
  import type { RouteLocationRaw } from 'vue-router'
163
162
  import { computed, ref, watchEffect } from 'vue'
164
163
  import { RiDownloadLine, RiEyeLine, RiLineChartLine, RiStarLine, RiSubtractLine } from '@remixicon/vue'
@@ -167,44 +166,46 @@ import { summarize } from '../functions/helpers'
167
166
  import { useFormatDate } from '../functions/dates'
168
167
  import { getOwnerName } from '../functions/owned'
169
168
  import { removeMarkdown } from '../functions/markdown'
169
+ import { getShortDescription } from '../functions/datasets'
170
170
  import { useComponentsConfig } from '../config'
171
+ import { useTranslation } from '../composables/useTranslation'
171
172
  import DatasetQualityInline from './DatasetQualityInline.vue'
172
173
  import Avatar from './Avatar.vue'
173
174
  import Placeholder from './Placeholder.vue'
174
175
  import OrganizationNameWithCertificate from './OrganizationNameWithCertificate.vue'
175
176
  import AppLink from './AppLink.vue'
176
177
 
177
- type Props = {
178
- dataset: Dataset | DatasetV2
178
+ type Props = {
179
+ dataset: Dataset | DatasetV2
179
180
 
180
- /**
181
+ /**
181
182
  * The datasetUrl is a route location object to allow Vue Router to navigate to the details of a dataset.
182
183
  * It is used as a separate prop to allow other sites using the package to define their own dataset pages.
183
184
  */
184
- datasetUrl: RouteLocationRaw
185
- datasetUrlInNewTab?: boolean
185
+ datasetUrl: RouteLocationRaw
186
+ datasetUrlInNewTab?: boolean
186
187
 
187
- /**
188
+ /**
188
189
  * The organizationUrl is an optional route location object to allow Vue Router to navigate to the details of the organization linked to tha dataset.
189
190
  * It is used as a separate prop to allow other sites using the package to define their own organization pages.
190
191
  */
191
- organizationUrl?: RouteLocationRaw
192
- showDescription?: boolean
193
- }
192
+ organizationUrl?: RouteLocationRaw
193
+ showShortDescription?: boolean
194
+ }
194
195
 
195
196
  const props = withDefaults(defineProps<Props>(), {
196
197
  style: () => ({}),
197
- showDescription: true,
198
+ showShortDescription: true,
198
199
  })
199
200
 
200
- const { t } = useI18n()
201
+ const { t } = useTranslation()
201
202
  const { formatRelativeIfRecentDate } = useFormatDate()
202
203
  const ownerName = computed(() => getOwnerName(props.dataset))
203
204
  const config = useComponentsConfig()
204
205
 
205
- const description = ref('')
206
+ const shortDescription = ref('')
206
207
  watchEffect(async () => {
207
- if (!props.showDescription) return
208
- description.value = await removeMarkdown(props.dataset.description)
208
+ if (!props.showShortDescription) return
209
+ shortDescription.value = await getShortDescription(props.dataset.description, props.dataset.description_short)
209
210
  })
210
211
  </script>
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <div class="py-6 mb-6 border-bottom border-gray-default">
3
3
  <h2 class="subtitle subtitle--uppercase">
4
- {{ $t('Informations') }}
4
+ {{ t('Informations') }}
5
5
  </h2>
6
6
  <div class="fr-text--sm fr-m-0">
7
7
  <dl class="fr-grid-row fr-grid-row--gutters">
@@ -10,7 +10,7 @@
10
10
  class="fr-col-12 fr-col-sm-6 fr-col-md-4"
11
11
  >
12
12
  <dt class="subtitle fr-mb-0">
13
- {{ $t('Licence') }}
13
+ {{ t('Licence') }}
14
14
  </dt>
15
15
  <dd class="text-sm m-0 text-gray-medium p-0">
16
16
  <code class="bg-grey-some px-1 text-gray-medium">
@@ -22,7 +22,7 @@
22
22
  </div>
23
23
  <div class="fr-col-12 fr-col-sm-6 fr-col-md-4">
24
24
  <dt class="subtitle fr-mb-0">
25
- {{ $t('Identifiant') }}
25
+ {{ t('Identifiant') }}
26
26
  </dt>
27
27
  <dd class="text-sm m-0 text-gray-medium p-0">
28
28
  {{ dataset.id }}
@@ -33,13 +33,13 @@
33
33
  </div>
34
34
  <div class="pb-6 mb-6 border-bottom border-gray-default">
35
35
  <h2 class="subtitle subtitle--uppercase">
36
- {{ $t('Temporalité') }}
36
+ {{ t('Temporalité') }}
37
37
  </h2>
38
38
  <div class="fr-text--sm fr-m-0">
39
39
  <dl class="fr-grid-row fr-grid-row--gutters">
40
40
  <div class="fr-col-12 fr-col-sm-6 fr-col-md-4">
41
41
  <dt class="subtitle fr-mb-0">
42
- {{ $t('Création') }}
42
+ {{ t('Création') }}
43
43
  </dt>
44
44
  <dd class="text-sm m-0 text-gray-medium p-0">
45
45
  {{ formatDate(dataset.created_at) }}
@@ -50,7 +50,7 @@
50
50
  class="fr-col-12 fr-col-sm-6 fr-col-md-4"
51
51
  >
52
52
  <dt class="subtitle fr-mb-0">
53
- {{ $t('Fréquence') }}
53
+ {{ t('Fréquence') }}
54
54
  </dt>
55
55
  <dd class="text-sm m-0 text-gray-medium p-0">
56
56
  {{ frequency.label }}
@@ -60,7 +60,7 @@
60
60
  <dl class="fr-grid-row fr-grid-row--gutters">
61
61
  <div class="fr-col-12 fr-col-sm-6 fr-col-md-4">
62
62
  <dt class="subtitle fr-mb-0">
63
- {{ $t('Dernière mise à jour') }}
63
+ {{ t('Dernière mise à jour') }}
64
64
  </dt>
65
65
  <dd class="text-sm m-0 text-gray-medium p-0">
66
66
  {{ formatDate(props.dataset.last_update) }}
@@ -71,7 +71,7 @@
71
71
  </div>
72
72
  <div class="pb-6 mb-6 border-bottom border-gray-default">
73
73
  <h2 class="subtitle subtitle--uppercase">
74
- {{ $t('Couverture spatiale') }}
74
+ {{ t('Couverture spatiale') }}
75
75
  </h2>
76
76
  <div class="fr-text--sm fr-m-0">
77
77
  <dl class="fr-grid-row fr-grid-row--gutters">
@@ -80,7 +80,7 @@
80
80
  class="fr-col-12 fr-col-sm-6 fr-col-md-4"
81
81
  >
82
82
  <dt class="subtitle fr-mb-0">
83
- {{ $t('Couverture territoriale') }}
83
+ {{ t('Couverture territoriale') }}
84
84
  </dt>
85
85
  <dd class="text-sm m-0 text-gray-medium p-0">
86
86
  {{ zonesLabels.join(', ') }}
@@ -91,7 +91,7 @@
91
91
  class="fr-col-12 fr-col-sm-6 fr-col-md-4"
92
92
  >
93
93
  <dt class="subtitle fr-mb-0">
94
- {{ $t('Granularité de la couverture territoriale') }}
94
+ {{ t('Granularité de la couverture territoriale') }}
95
95
  </dt>
96
96
  <dd class="text-sm m-0 text-gray-medium p-0">
97
97
  {{ granularity.name }}
@@ -102,15 +102,15 @@
102
102
  </div>
103
103
  <div class="pb-6 mb-6 border-bottom border-gray-default">
104
104
  <h2 class="subtitle subtitle--uppercase">
105
- {{ $t('Actions') }}
105
+ {{ t('Actions') }}
106
106
  </h2>
107
107
  <div class="fr-text--sm fr-m-0">
108
108
  <h3 class="subtitle fr-mb-1v">
109
- {{ $t('Intégrer sur votre site') }}
109
+ {{ t('Intégrer sur votre site') }}
110
110
  <CopyButton
111
111
  :hide-label="true"
112
- :label="$t(`Copier l'intégration`)"
113
- :copied-label="$t('Intégration copiée!')"
112
+ :label="t(`Copier l'intégration`)"
113
+ :copied-label="t('Intégration copiée !')"
114
114
  class="fr-my-1w fr-mr-1w"
115
115
  :text="getDatasetOEmbedHtml('dataset', dataset.id)"
116
116
  />
@@ -146,7 +146,6 @@
146
146
 
147
147
  <script setup lang="ts">
148
148
  import { ref, computed } from 'vue'
149
- import { useI18n } from 'vue-i18n'
150
149
  import { useFormatDate } from '../functions/dates'
151
150
  // import useOEmbed from '../../composables/useOEmbed'
152
151
  import type { Dataset, DatasetV2 } from '../types/datasets'
@@ -155,13 +154,14 @@ import type { Frequency } from '../types/frequency'
155
154
  import type { License } from '../types/licenses'
156
155
  import { useFetch } from '../functions/api'
157
156
  import { getDatasetOEmbedHtml } from '../functions/datasets'
157
+ import { useTranslation } from '../composables/useTranslation'
158
158
  import ExtraAccordion from './ExtraAccordion.vue'
159
159
  import CopyButton from './CopyButton.vue'
160
160
 
161
161
  const props = defineProps<{
162
162
  dataset: DatasetV2 | Dataset
163
163
  }>()
164
- const { t } = useI18n()
164
+ const { t } = useTranslation()
165
165
  const { formatDate } = useFormatDate()
166
166
  // const embedText = useOEmbed('dataset', props.dataset.id)
167
167
  const textAreaRef = ref<HTMLTextAreaElement | null>(null)
@@ -0,0 +1,40 @@
1
+ <template>
2
+ <component
3
+ :is="url ? AppLink : 'span'"
4
+ :to="url"
5
+ class="text-xs leading-5 px-2 py-0.5 rounded-full uppercase inline-flex items-center"
6
+ :class="{
7
+ 'bg-none bg-datagouv hover:bg-datagouv-dark text-white gap-1': url,
8
+ 'bg-gray-lower gap-0.5': !url,
9
+ }"
10
+ >
11
+ <img
12
+ v-if="img"
13
+ :src="img"
14
+ alt=""
15
+ :class="{ 'bg-white rounded-full': url }"
16
+ >
17
+ {{ badge.label }}
18
+ </component>
19
+ </template>
20
+
21
+ <script setup lang="ts">
22
+ import { computedAsync } from '@vueuse/core'
23
+ import type { RouteLocationRaw } from 'vue-router'
24
+ import AppLink from './AppLink.vue'
25
+ import type { TranslatedBadge } from '@/types/badges'
26
+
27
+ const props = defineProps<{
28
+ badge: TranslatedBadge
29
+ url?: string | RouteLocationRaw
30
+ }>()
31
+
32
+ const img = computedAsync(async () => {
33
+ const labelImages = import.meta.glob('../../assets/labels/*.svg', {
34
+ query: '?url',
35
+ import: 'default',
36
+ })
37
+ const src = Object.keys(labelImages).find(path => path.includes(props.badge.kind))
38
+ return src && labelImages[src] ? await labelImages[src]() as string : undefined
39
+ })
40
+ </script>
@@ -1,14 +1,14 @@
1
1
  <template>
2
2
  <div class="flex items-center">
3
3
  <Toggletip
4
- :button-props="{ class: '-ml-2 mt-px', title: $t('Qualité des métadonnées') }"
4
+ :button-props="{ class: '-ml-2 mt-px', title: t('Qualité des métadonnées') }"
5
5
  >
6
6
  <template #toggletip>
7
7
  <DatasetQualityTooltipContent :quality />
8
8
  </template>
9
9
  </Toggletip>
10
10
  <div class="text-sm text-gray-plain font-bold">
11
- {{ $t('Qualité des métadonnées:') }}
11
+ {{ t('Qualité des métadonnées:') }}
12
12
  </div>
13
13
  </div>
14
14
  <DatasetQualityScore
@@ -19,35 +19,35 @@
19
19
  <ul class="list-none pl-0">
20
20
  <DatasetQualityItemWarning
21
21
  :quality-item="quality.dataset_description_quality"
22
- :message="$t('Description des données non renseignée')"
22
+ :message="t('Description des données non renseignée')"
23
23
  />
24
24
  <DatasetQualityItemWarning
25
25
  :quality-item="quality.resources_documentation"
26
- :message="$t('Documentation des fichiers manquante')"
26
+ :message="t('Documentation des fichiers manquante')"
27
27
  />
28
28
  <DatasetQualityItemWarning
29
29
  :quality-item="quality.license"
30
- :message="$t('Licence non renseignée')"
30
+ :message="t('Licence non renseignée')"
31
31
  />
32
32
  <DatasetQualityItemWarning
33
33
  :quality-item="quality.update_frequency && quality.update_fulfilled_in_time"
34
- :message="quality.update_frequency ? $t('Fréquence de mise à jour non respectée') : $t('Fréquence de mise à jour non renseignée')"
34
+ :message="quality.update_frequency ? t('Fréquence de mise à jour non respectée') : t('Fréquence de mise à jour non renseignée')"
35
35
  />
36
36
  <DatasetQualityItemWarning
37
37
  :quality-item="quality.has_open_format"
38
- :message="$t('Formats de fichiers non standards')"
38
+ :message="t('Formats de fichiers non standards')"
39
39
  />
40
40
  <DatasetQualityItemWarning
41
41
  :quality-item="quality.temporal_coverage"
42
- :message="$t('Couverture temporelle non renseignée')"
42
+ :message="t('Couverture temporelle non renseignée')"
43
43
  />
44
44
  <DatasetQualityItemWarning
45
45
  :quality-item="quality.spatial"
46
- :message="$t('Couverture spatiale non renseignée')"
46
+ :message="t('Couverture spatiale non renseignée')"
47
47
  />
48
48
  <DatasetQualityItemWarning
49
49
  :quality-item="quality.all_resources_available"
50
- :message="$t('Certains fichiers ne sont pas disponibles')"
50
+ :message="t('Certains fichiers ne sont pas disponibles')"
51
51
  />
52
52
  </ul>
53
53
  </template>
@@ -59,6 +59,7 @@ import DatasetQualityItemWarning from './DatasetQualityItemWarning.vue'
59
59
  import DatasetQualityScore from './DatasetQualityScore.vue'
60
60
  import Toggletip from './Toggletip.vue'
61
61
  import DatasetQualityTooltipContent from './DatasetQualityTooltipContent.vue'
62
+ import { useTranslation } from '../composables/useTranslation'
62
63
 
63
64
  withDefaults(defineProps<{
64
65
  quality: Quality
@@ -66,4 +67,6 @@ withDefaults(defineProps<{
66
67
  }>(), {
67
68
  hideWarnings: true,
68
69
  })
70
+
71
+ const { t } = useTranslation()
69
72
  </script>
@@ -2,7 +2,7 @@
2
2
  <div class="m-0 flex flex-wrap items-center text-sm text-gray-medium">
3
3
  <div class="fr-grid-row fr-grid-row--middle">
4
4
  <Toggletip
5
- :button-props="{ class: 'relative z-2 ml-0.5', title: $t('Qualité des métadonnées') }"
5
+ :button-props="{ class: 'relative z-2 ml-0.5', title: t('Qualité des métadonnées') }"
6
6
  >
7
7
  <RiInformationLine class="size-4" />
8
8
  <template #toggletip>
@@ -10,7 +10,7 @@
10
10
  </template>
11
11
  </Toggletip>
12
12
  <p class="my-0 mr-1 text-gray-medium text-sm">
13
- {{ $t('Métadonnées :') }}
13
+ {{ t('Métadonnées :') }}
14
14
  </p>
15
15
  <div class="fr-grid-row fr-grid-row--middle fr-mr-1v">
16
16
  <DatasetQualityScore :score="quality.score" />
@@ -25,8 +25,11 @@ import type { Quality } from '../types/datasets'
25
25
  import DatasetQualityScore from './DatasetQualityScore.vue'
26
26
  import DatasetQualityTooltipContent from './DatasetQualityTooltipContent.vue'
27
27
  import Toggletip from './Toggletip.vue'
28
+ import { useTranslation } from '../composables/useTranslation'
28
29
 
29
30
  defineProps<{
30
31
  quality: Quality
31
32
  }>()
33
+
34
+ const { t } = useTranslation()
32
35
  </script>
@@ -20,7 +20,7 @@
20
20
 
21
21
  <script setup lang="ts">
22
22
  import { computed } from 'vue'
23
- import { useI18n } from 'vue-i18n'
23
+ import { useTranslation } from '../composables/useTranslation'
24
24
 
25
25
  const props = withDefaults(defineProps<{
26
26
  score: number
@@ -30,6 +30,6 @@ const props = withDefaults(defineProps<{
30
30
  })
31
31
  const quality_max_score = 1
32
32
  const high = quality_max_score * 2 / 3
33
- const { t, locale } = useI18n()
34
- const calculatedScore = computed(() => new Intl.NumberFormat(locale.value, { style: 'percent' }).format(props.score))
33
+ const { t, locale } = useTranslation()
34
+ const calculatedScore = computed(() => new Intl.NumberFormat(locale, { style: 'percent' }).format(props.score))
35
35
  </script>
@@ -65,15 +65,15 @@
65
65
  </template>
66
66
 
67
67
  <script setup lang="ts">
68
- import { useI18n } from 'vue-i18n'
69
68
  import type { Quality } from '../types/datasets'
70
69
  import { useComponentsConfig } from '../config'
70
+ import { useTranslation } from '../composables/useTranslation'
71
71
  import DatasetQualityItem from './DatasetQualityItem.vue'
72
72
 
73
73
  defineProps<{
74
74
  quality: Quality
75
75
  }>()
76
76
 
77
- const { t } = useI18n()
77
+ const { t } = useTranslation()
78
78
  const config = useComponentsConfig()
79
79
  </script>
@@ -4,13 +4,13 @@
4
4
 
5
5
  <script setup lang="ts">
6
6
  import { computed } from 'vue'
7
- import { useI18n } from 'vue-i18n'
7
+ import { useTranslation } from '../composables/useTranslation'
8
8
 
9
9
  const props = defineProps<{
10
10
  range: { start: string, end: string | null }
11
11
  }>()
12
12
 
13
- const { t } = useI18n()
13
+ const { t } = useTranslation()
14
14
 
15
15
  const start = computed(() => new Date(props.range.start))
16
16
  const end = computed(() => props.range.end ? new Date(props.range.end) : null)
@@ -56,7 +56,11 @@ const display = computed(() => {
56
56
  }
57
57
  }
58
58
 
59
- const addPronoun = (value: string | number | null) => {
59
+ // Function overloads to express that non-null input -> non-null output
60
+ function addPronoun(value: null): null
61
+ function addPronoun(value: string | number): string | number
62
+ function addPronoun(value: string | number | null): string | number | null
63
+ function addPronoun(value: string | number | null): string | number | null {
60
64
  if (!value) return null
61
65
  if (!hasPronoun) return value
62
66
  return t('le ') + value
@@ -28,7 +28,7 @@
28
28
  v-if="open"
29
29
  class="sr-only"
30
30
  >
31
- {{ $t('Fermer les détails') }}
31
+ {{ t('Fermer les détails') }}
32
32
  </span>
33
33
  </DisclosureButton>
34
34
  </div>
@@ -66,8 +66,10 @@ import {
66
66
  } from '@headlessui/vue'
67
67
  import { RiArrowDownSLine, RiArrowUpSLine } from '@remixicon/vue'
68
68
  import BrandedButton from './BrandedButton.vue'
69
+ import { useTranslation } from '../composables/useTranslation'
69
70
 
70
71
  const accordionId = useId()
72
+ const { t } = useTranslation()
71
73
 
72
74
  defineProps<{
73
75
  buttonText: string
@@ -37,16 +37,16 @@
37
37
 
38
38
  <script setup lang="ts">
39
39
  import { RiCheckboxCircleLine } from '@remixicon/vue'
40
- import { useI18n } from 'vue-i18n'
41
40
  import { getOrganizationType, isOrganizationCertified } from '../functions/organizations'
42
41
  import type { Organization } from '../types/organizations'
43
42
  import { useComponentsConfig } from '../config'
43
+ import { useTranslation } from '../composables/useTranslation'
44
44
  import OwnerTypeIcon from './OwnerTypeIcon.vue'
45
45
  import Tooltip from './Tooltip.vue'
46
46
 
47
47
  const config = useComponentsConfig()
48
48
 
49
- const { t } = useI18n()
49
+ const { t } = useTranslation()
50
50
  withDefaults(defineProps<{
51
51
  organization: Organization
52
52
  showAcronym?: boolean
@@ -0,0 +1,28 @@
1
+ <template>
2
+ <div
3
+ class="!p-6"
4
+ :class="background"
5
+ >
6
+ <slot />
7
+ </div>
8
+ </template>
9
+
10
+ <script setup lang="ts">
11
+ import { computed } from 'vue'
12
+
13
+ const props = withDefaults(defineProps<{
14
+ color?: 'white' | 'alt-grey'
15
+ }>(), {
16
+ color: 'white',
17
+ })
18
+
19
+ const background = computed(() => {
20
+ switch (props.color) {
21
+ case 'alt-grey':
22
+ return 'bg-gray-some'
23
+ case 'white':
24
+ default:
25
+ return 'bg-white'
26
+ }
27
+ })
28
+ </script>
@@ -101,7 +101,7 @@
101
101
 
102
102
  <script setup lang="ts">
103
103
  import { computed, useTemplateRef } from 'vue'
104
- import { useI18n } from 'vue-i18n'
104
+ import { useTranslation } from '../composables/useTranslation'
105
105
 
106
106
  type Props = {
107
107
  /**
@@ -173,7 +173,7 @@ function getVisiblePages(currentPage: number, pageCount: number) {
173
173
  return pagination
174
174
  }
175
175
 
176
- const { t } = useI18n()
176
+ const { t } = useTranslation()
177
177
  const pageCount = computed(() => Math.ceil(props.totalResults / props.pageSize))
178
178
  const visiblePages = computed(() => getVisiblePages(props.page, pageCount.value))
179
179
 
@@ -25,7 +25,7 @@ async function placeholderUrl() {
25
25
  import: 'default',
26
26
  })
27
27
  const name = Object.keys(placeholders).find(p => p.includes(props.type)) as string
28
- const module = placeholders[name]
28
+ const module = placeholders[name] as () => Promise<unknown>
29
29
  const placeholder = await module()
30
30
  return props.src ? props.src : placeholder as string
31
31
  }
@@ -23,10 +23,10 @@
23
23
  @click.stop="toggle"
24
24
  >
25
25
  <template v-if="expanded">
26
- {{ $t("Lire moins") }}
26
+ {{ t("Lire moins") }}
27
27
  </template>
28
28
  <template v-else>
29
- {{ $t("Lire plus") }}
29
+ {{ t("Lire plus") }}
30
30
  </template>
31
31
  </BrandedButton>
32
32
  </div>
@@ -34,10 +34,12 @@
34
34
  </template>
35
35
 
36
36
  <script setup lang="ts">
37
- import { templateRef, useElementSize } from '@vueuse/core'
38
- import { ref, watch } from 'vue'
39
- import { easing, tween, styler } from 'popmotion'
37
+ import { useElementSize } from '@vueuse/core'
38
+ import { ref, useTemplateRef, watch } from 'vue'
39
+ import { animate } from 'popmotion'
40
+ import styler from 'stylefire'
40
41
  import BrandedButton from './BrandedButton.vue'
42
+ import { useTranslation } from '../composables/useTranslation'
41
43
 
42
44
  const props = withDefaults(defineProps<{
43
45
  maxHeight?: string
@@ -45,11 +47,13 @@ const props = withDefaults(defineProps<{
45
47
  maxHeight: '',
46
48
  })
47
49
 
50
+ const { t } = useTranslation()
51
+
48
52
  const DEFAULT_HEIGHT = 284
49
53
  const expanded = ref(false)
50
54
  const readMoreRequired = ref(false)
51
- const containerRef = templateRef<HTMLElement | null>('containerRef')
52
- const readMoreRef = templateRef<HTMLElement | null>('readMoreRef')
55
+ const containerRef = useTemplateRef<HTMLElement | null>('containerRef')
56
+ const readMoreRef = useTemplateRef<HTMLElement | null>('readMoreRef')
53
57
  const { height } = useElementSize(containerRef)
54
58
  const containerHeight = ref(DEFAULT_HEIGHT)
55
59
  const getHeight = (elt: Element) => {
@@ -80,25 +84,21 @@ const toggle = () => {
80
84
  }
81
85
  const divStyler = styler(readMoreRef.value)
82
86
  if (expanded.value) {
83
- tween({
87
+ animate({
84
88
  from: { height: readMoreRef.value.scrollHeight },
85
89
  to: { height: getDefaultHeight() },
86
90
  duration: 300,
87
- ease: easing.anticipate,
88
- }).start({
89
- update: divStyler.set,
90
- complete: () => readMoreRef.value?.scrollIntoView({ behavior: 'smooth' }),
91
+ onComplete: () => readMoreRef.value?.scrollIntoView({ behavior: 'smooth' }),
92
+ onUpdate: divStyler.set,
91
93
  })
92
94
  }
93
95
  else {
94
- tween({
96
+ animate({
95
97
  from: { height: getDefaultHeight() },
96
98
  to: { height: readMoreRef.value.scrollHeight },
97
99
  duration: 300,
98
- ease: easing.anticipate,
99
- }).start({
100
- update: divStyler.set,
101
- complete: () => divStyler.set({ height: 'auto' }),
100
+ onUpdate: divStyler.set,
101
+ onComplete: () => divStyler.set({ height: 'auto' }),
102
102
  })
103
103
  }
104
104
  expanded.value = !expanded.value
@@ -8,7 +8,7 @@
8
8
  class="fr-icon-warning-line"
9
9
  aria-hidden="true"
10
10
  />
11
- {{ $t("La structure de données de ce fichier n'a pas pu être chargée.") }}
11
+ {{ t("La structure de données de ce fichier n'a pas pu être chargée.") }}
12
12
  </p>
13
13
  </div>
14
14
  <PreviewLoader v-else-if="loading" />
@@ -25,7 +25,7 @@
25
25
  class="fr-icon-warning-line"
26
26
  aria-hidden="true"
27
27
  />
28
- {{ $t("Aucune structure de données détectée pour ce fichier.") }}
28
+ {{ t("Aucune structure de données détectée pour ce fichier.") }}
29
29
  </p>
30
30
  </div>
31
31
  <template v-if="hasColumnInfo">
@@ -37,7 +37,10 @@
37
37
  <h5 class="fr-text--sm fr-text--bold fr-mt-0 fr-mb-1v">
38
38
  {{ column }}
39
39
  </h5>
40
- <code class="code">
40
+ <code
41
+ v-if="columnsInfo[column]"
42
+ class="code"
43
+ >
41
44
  {{ columnsInfo[column].format }}
42
45
  </code>
43
46
  </div>
@@ -49,10 +52,12 @@
49
52
  import { onMounted, ref } from 'vue'
50
53
  import type { Resource } from '../../types/resources'
51
54
  import { useGetProfile } from '../../functions/tabularApi'
55
+ import { useTranslation } from '../../composables/useTranslation'
52
56
  import PreviewLoader from './PreviewLoader.vue'
53
57
 
54
58
  const props = defineProps<{ resource: Resource }>()
55
59
  const getProfile = useGetProfile()
60
+ const { t } = useTranslation()
56
61
 
57
62
  type ColumnInfo = {
58
63
  score: number