@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.
Files changed (103) hide show
  1. package/README.md +34 -14
  2. package/assets/json/vector.json +2377 -0
  3. package/assets/main.css +3 -0
  4. package/assets/swagger-themes/newspaper.css +1669 -0
  5. package/assets/tailwind.config.js +1 -1
  6. package/dist/JsonPreview.client-BIz1_EiB.js +92 -0
  7. package/dist/MapContainer.client-ZDwr4Q_I.js +78276 -0
  8. package/dist/PdfPreview.client-BTTMM27i.js +112 -0
  9. package/dist/Pmtiles.client-4kOoUQcR.js +22377 -0
  10. package/dist/Swagger.client-Q7a5wb51.js +4 -0
  11. package/dist/XmlPreview.client-BYIIkDqf.js +84 -0
  12. package/dist/components-next.css +52 -1
  13. package/dist/components-next.js +42 -41
  14. package/dist/components.css +1 -1
  15. package/dist/main-CLUk9Jj7.js +105843 -0
  16. package/dist/pdf-vue3-BZh6kzke.js +273 -0
  17. package/dist/pdf.min-f72cfa08-DAetWL3M.js +9501 -0
  18. package/dist/{text-clamp.esm-DurZFOvT.js → text-clamp.esm-DP59tec5.js} +1 -1
  19. package/dist/vue3-json-viewer-DIQzFF6K.js +1089 -0
  20. package/dist/vue3-xml-viewer.common-BmKw6vER.js +5437 -0
  21. package/package.json +7 -5
  22. package/src/components/AvatarWithName.vue +6 -2
  23. package/src/components/BannerAction.vue +1 -1
  24. package/src/components/BrandedButton.vue +13 -8
  25. package/src/components/CopyButton.vue +7 -7
  26. package/src/components/DataserviceCard.vue +54 -23
  27. package/src/components/DatasetCard.vue +36 -24
  28. package/src/components/DatasetInformationPanel.vue +19 -18
  29. package/src/components/DatasetQuality.vue +21 -18
  30. package/src/components/DatasetQualityInline.vue +1 -1
  31. package/src/components/DatasetQualityItem.vue +3 -3
  32. package/src/components/DatasetQualityItemWarning.vue +2 -2
  33. package/src/components/DatasetQualityScore.vue +2 -2
  34. package/src/components/DatasetQualityTooltipContent.vue +29 -29
  35. package/src/components/DescriptionDetails.vue +2 -2
  36. package/src/components/ExtraAccordion.vue +10 -7
  37. package/src/components/OrganizationCard.vue +9 -4
  38. package/src/components/OrganizationNameWithCertificate.vue +25 -11
  39. package/src/components/Pagination.vue +26 -15
  40. package/src/components/ReadMore.vue +2 -2
  41. package/src/components/ResourceAccordion/DataStructure.vue +2 -2
  42. package/src/components/ResourceAccordion/EditButton.vue +10 -6
  43. package/src/components/ResourceAccordion/JsonPreview.client.vue +153 -0
  44. package/src/components/ResourceAccordion/MapContainer.client.vue +137 -0
  45. package/src/components/ResourceAccordion/Metadata.vue +33 -54
  46. package/src/components/ResourceAccordion/PdfPreview.client.vue +189 -0
  47. package/src/components/ResourceAccordion/Pmtiles.client.vue +166 -0
  48. package/src/components/ResourceAccordion/Preview.vue +39 -37
  49. package/src/components/ResourceAccordion/ResourceAccordion.vue +141 -63
  50. package/src/components/ResourceAccordion/ResourceIcon.vue +7 -1
  51. package/src/components/ResourceAccordion/SchemaBadge.vue +26 -26
  52. package/src/components/ResourceAccordion/{Swagger.vue → Swagger.client.vue} +1 -1
  53. package/src/components/ResourceAccordion/XmlPreview.client.vue +143 -0
  54. package/src/components/ReuseCard.vue +10 -7
  55. package/src/components/ReuseDetails.vue +3 -3
  56. package/src/components/SimpleBanner.vue +7 -4
  57. package/src/components/SmallChart.vue +23 -9
  58. package/src/components/StatBox.vue +92 -10
  59. package/src/config.ts +6 -2
  60. package/src/functions/api.ts +18 -18
  61. package/src/functions/dates.ts +81 -74
  62. package/src/functions/helpers.ts +5 -4
  63. package/src/functions/organizations.ts +5 -5
  64. package/src/functions/resources.ts +34 -5
  65. package/src/functions/schemas.ts +4 -3
  66. package/src/functions/tabularApi.ts +1 -1
  67. package/src/main.ts +10 -11
  68. package/src/types/badges.ts +3 -3
  69. package/src/types/contact_point.ts +5 -5
  70. package/src/types/dataservices.ts +16 -2
  71. package/src/types/datasets.ts +20 -2
  72. package/src/types/frequency.ts +5 -5
  73. package/src/types/granularity.ts +12 -4
  74. package/src/types/harvest.ts +2 -2
  75. package/src/types/licenses.ts +8 -8
  76. package/src/types/organizations.ts +6 -0
  77. package/src/types/resources.ts +3 -3
  78. package/src/types/reuses.ts +3 -1
  79. package/src/types/site.ts +8 -0
  80. package/src/types/ui.ts +2 -2
  81. package/src/types/users.ts +24 -8
  82. package/src/types/vue3-xml-viewer.d.ts +10 -0
  83. package/dist/Swagger-DjysB-OI.js +0 -67851
  84. package/dist/en-DCRve7vN.js +0 -613
  85. package/dist/fr-DCOnbL-p.js +0 -613
  86. package/dist/locales/de.js +0 -155
  87. package/dist/locales/en.js +0 -155
  88. package/dist/locales/es.js +0 -155
  89. package/dist/locales/fr.js +0 -155
  90. package/dist/locales/it.js +0 -155
  91. package/dist/locales/pt.js +0 -155
  92. package/dist/locales/sr.js +0 -155
  93. package/dist/main-CPW2vNLE.js +0 -32008
  94. package/src/components/DescriptionList/DescriptionDetails.stories.ts +0 -43
  95. package/src/components/DescriptionList/DescriptionList.stories.ts +0 -47
  96. package/src/components/DescriptionList/DescriptionTerm.stories.ts +0 -28
  97. package/src/locales/de.json +0 -154
  98. package/src/locales/en.json +0 -154
  99. package/src/locales/es.json +0 -154
  100. package/src/locales/fr.json +0 -154
  101. package/src/locales/it.json +0 -154
  102. package/src/locales/pt.json +0 -154
  103. package/src/locales/sr.json +0 -154
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datagouv/components-next",
3
- "version": "0.0.7",
3
+ "version": "0.0.9",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "./src/main.ts",
@@ -18,8 +18,7 @@
18
18
  "lint": "eslint . --fix",
19
19
  "format": "prettier --write src/",
20
20
  "css": "tailwindcss -i ./assets/main.css -o ./dist/components.css --minify --optimize",
21
- "i18n": "intlify compile --source ./src/locales/**/*.json --output ./dist/locales",
22
- "preversion": "npm run build-only && npm run css && npm run i18n",
21
+ "preversion": "npm run build-only && npm run css",
23
22
  "publish-stable": "npm publish --access public"
24
23
  },
25
24
  "dependencies": {
@@ -27,13 +26,15 @@
27
26
  "@remixicon/vue": "^4.5.0",
28
27
  "@vueuse/core": "^13.1.0",
29
28
  "chart.js": "^4.4.8",
29
+ "dompurify": "^3.2.5",
30
+ "maplibre-gl": "^5.5.0",
30
31
  "markdown-it": "^14.1.0",
31
32
  "ofetch": "^1.4.1",
33
+ "pmtiles": "^4.3.0",
32
34
  "popmotion": "^8.7.6",
33
35
  "remark": "^15.0.1",
34
36
  "remark-gfm": "^4.0.1",
35
37
  "strip-markdown": "^6.0.0",
36
- "swagger-themes": "^1.4.3",
37
38
  "swagger-ui": "^5.20.1",
38
39
  "vue": "^3.5.13",
39
40
  "vue-content-loader": "^2.0.1",
@@ -46,10 +47,11 @@
46
47
  "@tailwindcss/cli": "^4.0.8",
47
48
  "@tailwindcss/typography": "^0.5.16",
48
49
  "@tsconfig/node22": "^22.0.0",
50
+ "@types/geojson": "^7946.0.16",
49
51
  "@types/node": "^22.13.1",
50
52
  "@types/swagger-ui": "^3.52.4",
51
53
  "@vitejs/plugin-vue": "^5.2.1",
52
- "@vue/eslint-config-prettier": "^10.1.0",
54
+ "@vue/eslint-config-prettier": "^10.2.0",
53
55
  "@vue/eslint-config-typescript": "^14.3.0",
54
56
  "@vue/tsconfig": "^0.7.0",
55
57
  "eslint": "^9.18.0",
@@ -6,15 +6,19 @@
6
6
  :size
7
7
  :rounded="true"
8
8
  />
9
- <span class="fr-text--bold">
9
+ <AppLink
10
+ :to="user.page"
11
+ class="fr-text--bold"
12
+ >
10
13
  {{ user.first_name }}
11
14
  {{ user.last_name }}
12
- </span>
15
+ </AppLink>
13
16
  </span>
14
17
  </template>
15
18
 
16
19
  <script setup lang="ts">
17
20
  import type { User } from '../types/users'
21
+ import AppLink from './AppLink.vue'
18
22
  import Avatar from './Avatar.vue'
19
23
 
20
24
  withDefaults(defineProps<{
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <div
3
- class="group flex items-center justify-between rounded border p-2.5"
3
+ class="group flex items-center justify-between gap-2 rounded border p-2.5"
4
4
  :data-banner-action-type="type"
5
5
  :class="{
6
6
  '!border-datagouv bg-datagouv-lightest text-datagouv-dark': type === 'primary',
@@ -1,7 +1,8 @@
1
1
  <template>
2
+ <!-- 46 42 32 -->
2
3
  <component
3
4
  :is="href ? AppLink: 'button'"
4
- class="inline-flex items-center rounded-full font-medium border !bg-none !no-underline after:content-none"
5
+ class="inline-flex items-center justify-center rounded-full font-medium border !bg-none !no-underline after:content-none"
5
6
  :class="[colors, sizes, removePaddingsIfNoBorders, isDisabled ? '!opacity-50' : '', iconRight && !newTab ? 'flex-row-reverse space-x-reverse' : '']"
6
7
  :disabled="isDisabled"
7
8
  :aria-disabled="isDisabled"
@@ -47,19 +48,20 @@ import {
47
48
  useSlots,
48
49
  } from 'vue'
49
50
  import { RiExternalLinkLine } from '@remixicon/vue'
51
+ import type { RouteLocation } from 'vue-router'
50
52
  import AppLink from './AppLink.vue'
51
53
  import { bannerActionTypeKey } from './BannerAction.vue'
52
54
 
53
55
  type ColorType = 'primary' | 'primary-soft' | 'primary-softer' | 'secondary' | 'secondary-softer' | 'warning' | 'danger' | 'tertiary'
54
56
 
55
57
  const props = withDefaults(defineProps<{
56
- size?: '2xs' | 'xs' | 'sm' | 'lg'
58
+ size?: '2xs' | 'xs' | 'sm' | 'lg' | 'xl'
57
59
  color?: ColorType
58
60
  disabled?: boolean
59
61
  loading?: boolean
60
62
  icon?: Component
61
63
  iconAttrs?: Record<string, string>
62
- href?: string
64
+ href?: string | RouteLocation
63
65
  newTab?: boolean
64
66
  iconOnly?: boolean
65
67
  iconRight?: boolean
@@ -109,7 +111,7 @@ const isDisabled = computed(() => props.disabled || props.loading)
109
111
  const colors = computed(() => {
110
112
  return {
111
113
  'primary': `text-white bg-datagouv-dark !border-datagouv-dark ${!isDisabled.value ? 'hover:!bg-datagouv-hover hover:!border-datagouv-hover' : ''}`,
112
- 'primary-soft': `text-datagouv-dark bg-transparent !border-datagouv-dark ${!isDisabled.value ? '[&&]:hover:!bg-gray-some' : ''}`,
114
+ 'primary-soft': `text-datagouv-dark bg-white !border-datagouv-dark ${!isDisabled.value ? '[&&]:hover:!bg-gray-some' : ''}`,
113
115
  'primary-softer': `text-datagouv-dark bg-transparent !border-transparent ${!isDisabled.value ? '[&&]:hover:!bg-gray-some' : ''}`,
114
116
  'secondary': `text-gray-plain bg-white !border-gray-plain ${!isDisabled.value ? '[&&]:hover:!bg-gray-some' : ''}`,
115
117
  'secondary-softer': `text-gray-plain !border-transparent ${!isDisabled.value ? '[&&]:hover:!bg-gray-some' : ''}`,
@@ -121,9 +123,10 @@ const colors = computed(() => {
121
123
 
122
124
  const sizes = computed(() => {
123
125
  return {
124
- 'lg': `text-lg ${hasText.value ? 'px-4 py-2 space-x-2' : 'p-3'}`,
125
- 'sm': `text-sm leading-none ${hasText.value ? 'px-4 py-3 space-x-1' : 'p-2.5'}`,
126
- 'xs': `text-xs leading-[0.875rem] ${hasText.value ? 'px-4 py-2 space-x-1' : 'p-2'}`,
126
+ 'xl': `text-xl h-16 ${hasText.value ? 'px-4 space-x-2' : 'w-16 px-3'}`,
127
+ 'lg': `text-lg h-12 ${hasText.value ? 'px-4 space-x-2' : 'w-12 px-3'}`,
128
+ 'sm': `text-sm h-10 leading-none ${hasText.value ? 'px-4 space-x-1' : 'w-10 px-2.5'}`,
129
+ 'xs': `text-xs h-8 leading-[0.875rem] ${hasText.value ? 'px-4 space-x-1' : 'w-8 px-2'}`,
127
130
  '2xs': `text-xs leading-[0.875rem] p-1 space-x-1`,
128
131
  }[size.value]
129
132
  })
@@ -137,7 +140,8 @@ const removePaddingsIfNoBorders = computed(() => {
137
140
  if (props.keepMarginsEvenWithoutBorders) return ''
138
141
 
139
142
  return {
140
- 'lg': hasText.value ? '-mx-6' : '-mx-3',
143
+ 'xl': hasText.value ? '-mx-4' : '-mx-3',
144
+ 'lg': hasText.value ? '-mx-4' : '-mx-3',
141
145
  'sm': hasText.value ? '-mx-4' : '-mx-2.5',
142
146
  'xs': hasText.value ? '-mx-4' : '-mx-2',
143
147
  '2xs': '-m-1',
@@ -146,6 +150,7 @@ const removePaddingsIfNoBorders = computed(() => {
146
150
 
147
151
  const iconSize = computed(() => {
148
152
  return {
153
+ 'xl': (hasBorders.value || hasText.value) ? 'size-8' : 'size-10',
149
154
  'lg': (hasBorders.value || hasText.value) ? 'size-6' : 'size-8',
150
155
  'sm': (hasBorders.value || hasText.value) ? 'size-4' : 'size-6',
151
156
  'xs': (hasBorders.value || hasText.value) ? 'size-3' : 'size-5',
@@ -1,33 +1,33 @@
1
1
  <template>
2
2
  <button
3
3
  type="button"
4
- class="text-sm mb-0 whitespace-nowrap relative p-1 text-gray-medium leading-none"
4
+ class="text-sm mb-0 md:whitespace-nowrap relative p-1 text-gray-medium leading-none text-left"
5
5
  :class="{ 'border bg-white rounded-sm text-gray-title': hideLabel }"
6
6
  @click="copy"
7
7
  >
8
8
  <span
9
9
  v-if="copied"
10
- class="flex items-center"
10
+ class="flex items-center gap-1"
11
11
  :class="{ 'flex-row-reverse': reverse }"
12
12
  style="color: #3558a2;"
13
13
  >
14
- <RiCheckLine class="size-4 inline" />
14
+ <RiCheckLine class="flex-none size-4 inline" />
15
15
  <span
16
- class="fr-ml-1v copy-label"
16
+ class="copy-label"
17
17
  :class="{ 'fr-sr-only': hideLabel }"
18
18
  >{{ copiedLabel }}</span>
19
19
  </span>
20
20
  <span
21
21
  v-if="!copied"
22
- class="flex items-center"
22
+ class="flex items-center gap-1"
23
23
  :class="{ 'flex-row-reverse': reverse }"
24
24
  >
25
25
  <component
26
26
  :is="hideLabel ? RiClipboardLine : RiFileCopyLine"
27
- class="size-4 inline"
27
+ class="size-4 flex-none inline"
28
28
  />
29
29
  <span
30
- class="fr-ml-1v copy-link copy-label"
30
+ class="copy-link copy-label"
31
31
  :class="{ 'fr-sr-only': hideLabel }"
32
32
  >{{ label }}</span>
33
33
  </span>
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <article
3
- class="my-4 p-4 border border-gray-default fr-enlarge-link"
3
+ class="my-4 p-4 bg-white border border-gray-default fr-enlarge-link"
4
4
  :class="{
5
5
  'border-tabular-api': isTabularApi,
6
6
  'mt-6': showBadge,
@@ -18,7 +18,14 @@
18
18
  class="fr-icon-lock-line fr-icon--sm"
19
19
  aria-hidden="true"
20
20
  />
21
- {{ t('Restricted access') }}
21
+ {{ t('Accès restreint') }}
22
+ </p>
23
+ <p
24
+ v-else-if="dataservice.access_type === 'open_with_account'"
25
+ class="fr-badge fr-badge--sm fr-badge--mention-grey text-gray-medium mr-2"
26
+ >
27
+ <RiPassValidLine class="size-4 mr-1" />
28
+ {{ t('Ouvert avec un compte') }}
22
29
  </p>
23
30
  <p
24
31
  v-if="dataservice.private"
@@ -28,7 +35,7 @@
28
35
  class="fr-icon-lock-line fr-icon--sm"
29
36
  aria-hidden="true"
30
37
  />
31
- {{ t('Draft') }}
38
+ {{ t('Brouillon') }}
32
39
  </p>
33
40
  <p
34
41
  v-if="dataservice.archived_at"
@@ -38,7 +45,7 @@
38
45
  class="fr-icon-lock-line fr-icon--sm"
39
46
  aria-hidden="true"
40
47
  />
41
- {{ t('Archived') }}
48
+ {{ t('Archivé') }}
42
49
  </p>
43
50
  </div>
44
51
  <h4 class="fr-text--md fr-mb-0">
@@ -77,15 +84,15 @@
77
84
  </h4>
78
85
  <p
79
86
  v-if="dataservice.organization || dataservice.owner"
80
- class="text-sm text-gray-medium inline-flex mt-1 mb-0"
87
+ class="text-sm text-gray-medium overflow-hidden flex items-center gap-1 mt-1 mb-0"
81
88
  >
82
89
  <span
83
90
  v-if="dataservice.organization"
84
- class="not-enlarged"
91
+ class="block not-enlarged overflow-hidden"
85
92
  >
86
93
  <AppLink
87
94
  v-if="organizationUrl"
88
- class="fr-link fr-text--sm"
95
+ class="link text-sm overflow-hidden"
89
96
  :to="organizationUrl"
90
97
  >
91
98
  <OrganizationNameWithCertificate :organization="dataservice.organization" />
@@ -98,25 +105,46 @@
98
105
  <component
99
106
  :is="config.textClamp"
100
107
  v-else-if="config.textClamp"
101
- class="not-enlarged fr-mr-1v"
108
+ class="not-enlarged mr-1"
102
109
  :auto-resize="true"
103
110
  :text="ownerName"
104
111
  :max-lines="1"
105
112
  />
106
- <span class="dash-before whitespace-nowrap">{{ t('Updated {date}', { date: formatRelativeIfRecentDate(dataservice.metadata_modified_at, { dateStyle: 'medium' }) }) }}</span>
107
- </p>
108
- <p class="text-sm text-gray-medium mb-0 mt-1">
109
- <span class="fr-icon-information-line fr-icon--sm text-gray-medium" />
110
- {{ t('Availability :') }}
111
- <span class="text-gray-plain">
112
- <template v-if="dataservice.availability">
113
- {{ t('{n}%', dataservice.availability) }}
114
- </template>
115
- <template v-else>
116
- {{ t('unknown') }}
117
- </template>
118
- </span>
113
+ <RiSubtractLine class="size-4 flex-none fill-gray-medium" />
114
+ <span class="block whitespace-nowrap">{{ t('Mis à jour {date}', { date: formatRelativeIfRecentDate(dataservice.metadata_modified_at, { dateStyle: 'medium' }) }) }}</span>
119
115
  </p>
116
+ <div class="flex flex-wrap items-center gap-1 mt-1 text-gray-medium">
117
+ <p class="text-sm mb-0">
118
+ {{ t('Disponibilité :') }}
119
+ <span class="text-gray-plain">
120
+ <template v-if="dataservice.availability">
121
+ {{ t('{n}%', dataservice.availability) }}
122
+ </template>
123
+ <template v-else>
124
+ {{ t('inconnue') }}
125
+ </template>
126
+ </span>
127
+ </p>
128
+ <RiSubtractLine class="size-4 flex-none fill-gray-medium" />
129
+ <p
130
+ class="text-sm mb-0 flex items-center gap-0.5"
131
+ :aria-label="t('{n} vues | {n} vue | {n} vues', dataservice.metrics.views)"
132
+ >
133
+ <RiEyeLine
134
+ aria-hidden="true"
135
+ class="size-3.5"
136
+ />{{ summarize(dataservice.metrics.views) }}
137
+ </p>
138
+ <p
139
+ class="text-sm mb-0 flex items-center gap-0.5"
140
+ :aria-label="t('{n} abonnés | {n} abonné | {n} abonnés', dataservice.metrics.followers)"
141
+ >
142
+ <RiStarLine
143
+ aria-hidden="true"
144
+ class="size-3.5"
145
+ />{{ summarize(dataservice.metrics.followers) }}
146
+ </p>
147
+ </div>
120
148
  <component
121
149
  :is="config.textClamp"
122
150
  v-if="config.textClamp && description && showDescription"
@@ -132,8 +160,10 @@
132
160
  import { computed, ref, watchEffect } from 'vue'
133
161
  import { useI18n } from 'vue-i18n'
134
162
  import type { RouteLocationRaw } from 'vue-router'
163
+ import { RiEyeLine, RiPassValidLine, RiStarLine, RiSubtractLine } from '@remixicon/vue'
135
164
  import { useComponentsConfig } from '../config'
136
- import { formatRelativeIfRecentDate } from '../functions/dates'
165
+ import { useFormatDate } from '../functions/dates'
166
+ import { summarize } from '../functions/helpers'
137
167
  import { removeMarkdown } from '../functions/markdown'
138
168
  import { getOwnerName } from '../functions/owned'
139
169
  import type { Dataservice } from '../types/dataservices'
@@ -163,8 +193,9 @@ const props = withDefaults(defineProps<Props>(), {
163
193
  })
164
194
 
165
195
  const { t } = useI18n()
196
+ const { formatRelativeIfRecentDate } = useFormatDate()
166
197
  const ownerName = computed(() => getOwnerName(props.dataservice))
167
- const showBadge = computed(() => props.dataservice.access_type === 'restricted' || props.dataservice.private || props.dataservice.archived_at)
198
+ const showBadge = computed(() => props.dataservice.access_type === 'restricted' || props.dataservice.access_type === 'open_with_account' || props.dataservice.private || props.dataservice.archived_at)
168
199
 
169
200
  const config = useComponentsConfig()
170
201
  const isTabularApi = computed(() => {
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div class="p-4 border border-gray-default relative hover:bg-gray-some">
2
+ <div class="p-4 border bg-white border-gray-default relative hover:bg-gray-some">
3
3
  <div :id />
4
4
  <div
5
5
  v-if="dataset.private || dataset.archived"
@@ -13,7 +13,7 @@
13
13
  class="fr-icon-lock-line fr-icon--sm"
14
14
  aria-hidden="true"
15
15
  />
16
- {{ t('Draft') }}
16
+ {{ t('Brouillon') }}
17
17
  </p>
18
18
  <p
19
19
  v-if="dataset.archived"
@@ -23,7 +23,7 @@
23
23
  class="fr-icon-archive-line fr-icon--sm"
24
24
  aria-hidden="true"
25
25
  />
26
- {{ t('Archived') }}
26
+ {{ t('Archivé') }}
27
27
  </p>
28
28
  </div>
29
29
  <div class="flex flex-wrap md:flex-nowrap gap-4 items-start">
@@ -70,13 +70,13 @@
70
70
  </h4>
71
71
  <div
72
72
  v-if="dataset.organization || dataset.owner"
73
- class="text-sm m-0 flex truncate"
73
+ class="text-sm m-0 flex items-center truncate"
74
74
  >
75
75
  <template v-if="dataset.organization">
76
76
  <div class="-mr-0.5 flex-initial truncate">
77
77
  <AppLink
78
78
  v-if="organizationUrl"
79
- class="link text-sm flex items-center relative z-[2] truncate"
79
+ class="link text-sm overflow-hidden flex items-center relative z-[2] truncate"
80
80
  :to="organizationUrl"
81
81
  >
82
82
  <OrganizationNameWithCertificate :organization="dataset.organization" />
@@ -93,45 +93,55 @@
93
93
  >
94
94
  {{ ownerName }}
95
95
  </div>
96
- <div class="text-gray-medium dash-before-sm whitespace-nowrap">
97
- {{ $t('Updated {date}', { date: formatRelativeIfRecentDate(dataset.last_update, { dateStyle: 'medium' }) }) }}
96
+ <RiSubtractLine class="size-4 flex-none fill-gray-medium" />
97
+ <div class="text-gray-medium whitespace-nowrap">
98
+ {{ $t('Mis à jour {date}', { date: formatRelativeIfRecentDate(dataset.last_update, { dateStyle: 'medium' }) }) }}
98
99
  </div>
99
100
  </div>
100
101
  <div class="mx-0 -mb-1 flex flex-wrap items-center text-sm text-gray-medium">
101
- <div class="fr-hidden flex-sm dash-after-sm text-gray-500 -ml-2.5">
102
+ <div class="fr-hidden flex-sm dash-after-sm text-gray-medium -ml-2.5">
102
103
  <DatasetQualityInline
103
104
  :quality="dataset.quality"
104
105
  :teleport-id="id"
105
106
  />
106
107
  </div>
107
- <div class="fr-grid-row fr-grid-row--middle fr-mr-1v">
108
+ <div class="flex flex-wrap items-center gap-1">
108
109
  <p
109
- class="fr-text--sm fr-my-0"
110
- :aria-label="t('{n} resources downloads', dataset.metrics.resources_downloads)"
110
+ class="text-sm mb-0 flex items-center gap-0.5"
111
+ :aria-label="t('{n} vues | {n} vue | {n} vues', dataset.metrics.views)"
111
112
  >
112
- <span
113
- class="fr-icon-download-line fr-icon--sm fr-px-1v"
113
+ <RiEyeLine
114
114
  aria-hidden="true"
115
- />{{ summarize(dataset.metrics.resources_downloads) }}
115
+ class="size-3.5"
116
+ />{{ summarize(dataset.metrics.views) }}
116
117
  </p>
117
118
  <p
118
- class="fr-text--sm fr-my-0"
119
- :aria-label="t('{n} followers', dataset.metrics.followers)"
119
+ class="text-sm mb-0 flex items-center gap-0.5"
120
+ :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)"
120
121
  >
121
- <span
122
- class="fr-icon-star-line fr-icon--sm fr-px-1v"
122
+ <RiDownloadLine
123
123
  aria-hidden="true"
124
- />{{ summarize(dataset.metrics.followers) }}
124
+ class="size-3.5"
125
+ />{{ summarize(dataset.metrics.resources_downloads) }}
125
126
  </p>
126
127
  <p
127
- class="fr-text--sm fr-my-0"
128
- :aria-label="t('{n} reuses', dataset.metrics.reuses)"
128
+ class="text-sm mb-0 flex items-center gap-0.5"
129
+ :aria-label="t('{n} réutilisations | {n} réutilisation | {n} réutilisations', dataset.metrics.reuses)"
129
130
  >
130
- <span
131
- class="fr-icon-line-chart-line fr-icon--sm fr-px-1v"
131
+ <RiLineChartLine
132
132
  aria-hidden="true"
133
+ class="size-3.5"
133
134
  />{{ summarize(dataset.metrics.reuses) }}
134
135
  </p>
136
+ <p
137
+ class="text-sm mb-0 flex items-center gap-0.5"
138
+ :aria-label="t('{n} abonnés | {n} abonné | {n} abonnés', dataset.metrics.followers)"
139
+ >
140
+ <RiStarLine
141
+ aria-hidden="true"
142
+ class="size-3.5"
143
+ />{{ summarize(dataset.metrics.followers) }}
144
+ </p>
135
145
  </div>
136
146
  </div>
137
147
  <component
@@ -151,9 +161,10 @@
151
161
  import { useI18n } from 'vue-i18n'
152
162
  import type { RouteLocationRaw } from 'vue-router'
153
163
  import { computed, ref, useId, watchEffect } from 'vue'
164
+ import { RiDownloadLine, RiEyeLine, RiLineChartLine, RiStarLine, RiSubtractLine } from '@remixicon/vue'
154
165
  import type { Dataset, DatasetV2 } from '../types/datasets'
155
166
  import { summarize } from '../functions/helpers'
156
- import { formatRelativeIfRecentDate } from '../functions/dates'
167
+ import { useFormatDate } from '../functions/dates'
157
168
  import { getOwnerName } from '../functions/owned'
158
169
  import { removeMarkdown } from '../functions/markdown'
159
170
  import { useComponentsConfig } from '../config'
@@ -186,6 +197,7 @@ const props = withDefaults(defineProps<Props>(), {
186
197
  })
187
198
 
188
199
  const { t } = useI18n()
200
+ const { formatRelativeIfRecentDate } = useFormatDate()
189
201
  const id = useId()
190
202
  const ownerName = computed(() => getOwnerName(props.dataset))
191
203
  const config = useComponentsConfig()
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div class="py-6 mb-6 border-bottom border-gray-default">
2
+ <div class="py-6 mb-6 border-bottom border-gray-default">
3
3
  <h2 class="subtitle subtitle--uppercase">
4
4
  {{ $t('Informations') }}
5
5
  </h2>
@@ -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('License') }}
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
- ID
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('Temporality') }}
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('Creation') }}
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('Frequency') }}
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('Last update') }}
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('Spatial coverage') }}
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('Territorial coverage') }}
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('Granularity of territorial coverage') }}
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
- 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('Integrate on your website') }}
109
+ {{ $t('Intégrer sur votre site') }}
110
110
  <CopyButton
111
111
  :hide-label="true"
112
- :label="$t('Copy embed')"
113
- :copied-label="$t('Embed copied')"
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
  />
@@ -128,7 +128,7 @@
128
128
  </div>
129
129
  <div v-if="hasExtras">
130
130
  <ExtraAccordion
131
- :button-text="t('See extras')"
131
+ :button-text="t('Voir les extras')"
132
132
  :title-text="t('Extras')"
133
133
  :extra="props.dataset.extras"
134
134
  title-level="h2"
@@ -136,8 +136,8 @@
136
136
  </div>
137
137
  <div v-if="props.dataset?.harvest">
138
138
  <ExtraAccordion
139
- :button-text="t('See harvest')"
140
- :title-text="t('Harvest')"
139
+ :button-text="t('Voir le moissonage')"
140
+ :title-text="t('Moissonnage')"
141
141
  :extra="props.dataset.harvest"
142
142
  title-level="h2"
143
143
  />
@@ -147,7 +147,7 @@
147
147
  <script setup lang="ts">
148
148
  import { ref, computed } from 'vue'
149
149
  import { useI18n } from 'vue-i18n'
150
- import { formatDate } from '../functions/dates'
150
+ import { useFormatDate } from '../functions/dates'
151
151
  // import useOEmbed from '../../composables/useOEmbed'
152
152
  import type { Dataset, DatasetV2 } from '../types/datasets'
153
153
  import type { Granularity } from '../types/granularity'
@@ -162,6 +162,7 @@ const props = defineProps<{
162
162
  dataset: DatasetV2 | Dataset
163
163
  }>()
164
164
  const { t } = useI18n()
165
+ const { formatDate } = useFormatDate()
165
166
  // const embedText = useOEmbed('dataset', props.dataset.id)
166
167
  const textAreaRef = ref<HTMLTextAreaElement | null>(null)
167
168