@datagouv/components-next 1.0.2-dev.15 → 1.0.2-dev.151

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 (115) hide show
  1. package/README.md +7 -6
  2. package/assets/main.css +4 -0
  3. package/dist/{Control-DuZJdKV_.js → Control-B9WQxlpJ.js} +1 -1
  4. package/dist/{Datafair.client-BtQqFBTQ.js → Datafair.client-MNAP27A-.js} +4 -4
  5. package/dist/{Event--kp8kMdJ.js → Event-iXDrp-fy.js} +31 -31
  6. package/dist/{Image-34hvypZI.js → Image-mNMBOofs.js} +9 -9
  7. package/dist/JsonPreview.client-C3dG7a_r.js +40 -0
  8. package/dist/{Map-BjUnLyj8.js → Map-BfqKMw0S.js} +1739 -1599
  9. package/dist/{MapContainer.client-DB6p6KF8.js → MapContainer.client-B5YiX3NO.js} +38 -39
  10. package/dist/{OSM-s40W6sQ2.js → OSM-CcrUhItr.js} +15 -23
  11. package/dist/{PdfPreview.client-Dr4VcIur.js → PdfPreview.client-CERt2f57.js} +823 -855
  12. package/dist/Pmtiles.client-D8ug3toD.js +26142 -0
  13. package/dist/PreviewWrapper.vue_vue_type_script_setup_true_lang--KItAayB.js +61 -0
  14. package/dist/{ScaleLine-KW-nXqp3.js → ScaleLine-VGQ7nkMS.js} +2 -2
  15. package/dist/{Tile-DbNFNPfU.js → Tile-CSpn0Ca8.js} +160 -163
  16. package/dist/{TileImage-BsXBxMtq.js → TileImage-CpbaEFwd.js} +143 -131
  17. package/dist/{View-BR92hTWP.js → View-BYBpt-AU.js} +483 -422
  18. package/dist/XmlPreview.client-1IAoOczZ.js +34 -0
  19. package/dist/{common-PJfpC179.js → common-BoeTUnDZ.js} +52 -52
  20. package/dist/components-next.css +1 -52
  21. package/dist/components-next.js +174 -142
  22. package/dist/components.css +2 -2
  23. package/dist/{index-D3rieddI.js → index-D86-g3i7.js} +21147 -15136
  24. package/dist/{leaflet-src-7m1mB8LI.js → leaflet-src-BjtNBpa8.js} +185 -187
  25. package/dist/main-BdrYl6mr.js +73598 -0
  26. package/dist/{proj-DsetBcW7.js → proj-DxGbobp7.js} +662 -626
  27. package/dist/{text-clamp.esm-B5kW_XMt.js → text-clamp.esm-DVseBqZZ.js} +4 -4
  28. package/dist/{tilecoord-Db24Px13.js → tilecoord-DvX7WWiA.js} +273 -264
  29. package/dist/{vue3-json-viewer-BXwup7nO.js → vue3-json-viewer-CJLQFzXZ.js} +10 -16
  30. package/dist/{vue3-xml-viewer.common-CJXShyPB.js → vue3-xml-viewer.common-BE7Fgsqp.js} +16 -16
  31. package/package.json +50 -36
  32. package/src/chart.ts +5 -0
  33. package/src/components/ActivityList/ActivityList.vue +3 -2
  34. package/src/components/Chart/ChartViewer.vue +233 -0
  35. package/src/components/Chart/ChartViewerWrapper.vue +182 -0
  36. package/src/components/DataserviceCard.vue +3 -0
  37. package/src/components/DatasetCard.vue +9 -4
  38. package/src/components/Form/Listbox.vue +101 -0
  39. package/src/components/Form/SearchableSelect.vue +2 -1
  40. package/src/components/InfiniteLoader.vue +53 -0
  41. package/src/components/ObjectCardHeader.vue +11 -4
  42. package/src/components/OpenApiViewer/ContentTypeSelect.vue +48 -0
  43. package/src/components/OpenApiViewer/EndpointRequest.vue +164 -0
  44. package/src/components/OpenApiViewer/EndpointResponses.vue +149 -0
  45. package/src/components/OpenApiViewer/OpenApiViewer.vue +308 -0
  46. package/src/components/OpenApiViewer/SchemaPanel.vue +53 -0
  47. package/src/components/OpenApiViewer/SchemaTree.vue +77 -0
  48. package/src/components/OpenApiViewer/openapi.ts +150 -0
  49. package/src/components/OrganizationNameWithCertificate.vue +3 -2
  50. package/src/components/Pagination.vue +8 -5
  51. package/src/components/RadioInput.vue +7 -2
  52. package/src/components/ResourceAccordion/DataStructure.vue +11 -33
  53. package/src/components/ResourceAccordion/Downloads.vue +160 -0
  54. package/src/components/ResourceAccordion/JsonPreview.client.vue +23 -104
  55. package/src/components/ResourceAccordion/MapContainer.client.vue +1 -3
  56. package/src/components/ResourceAccordion/Metadata.vue +1 -2
  57. package/src/components/ResourceAccordion/PdfPreview.client.vue +24 -87
  58. package/src/components/ResourceAccordion/Pmtiles.client.vue +3 -1
  59. package/src/components/ResourceAccordion/Preview.vue +11 -11
  60. package/src/components/ResourceAccordion/PreviewWrapper.vue +82 -0
  61. package/src/components/ResourceAccordion/ResourceAccordion.vue +12 -111
  62. package/src/components/ResourceAccordion/XmlPreview.client.vue +16 -98
  63. package/src/components/ResourceExplorer/ResourceExplorer.vue +22 -19
  64. package/src/components/ResourceExplorer/ResourceExplorerSidebar.vue +2 -2
  65. package/src/components/ResourceExplorer/ResourceExplorerViewer.vue +57 -148
  66. package/src/components/ResourceExplorer/ResourceSelector.vue +113 -0
  67. package/src/components/ReuseCard.vue +14 -6
  68. package/src/components/ReuseDetails.vue +2 -2
  69. package/src/components/ReuseHorizontalCard.vue +2 -2
  70. package/src/components/Search/GlobalSearch.vue +219 -117
  71. package/src/components/Search/SearchInput.vue +5 -4
  72. package/src/components/TabularExplorer/TabularCell.vue +51 -0
  73. package/src/components/TabularExplorer/TabularCellPopover.vue +170 -0
  74. package/src/components/TabularExplorer/TabularExplorer.vue +1165 -0
  75. package/src/components/TabularExplorer/TabularFilterContent.vue +353 -0
  76. package/src/components/TabularExplorer/TabularFilterPopover.vue +106 -0
  77. package/src/components/TabularExplorer/types.ts +86 -0
  78. package/src/composables/useHasTabularData.ts +15 -1
  79. package/src/composables/useMetrics.ts +1 -1
  80. package/src/composables/useResourceCapabilities.ts +22 -9
  81. package/src/composables/useSearchFilter.ts +120 -0
  82. package/src/composables/useStableQueryParams.ts +38 -6
  83. package/src/composables/useTabularProfile.ts +70 -0
  84. package/src/config.ts +20 -3
  85. package/src/functions/activities.ts +3 -3
  86. package/src/functions/api.ts +20 -42
  87. package/src/functions/api.types.ts +1 -0
  88. package/src/functions/charts.ts +79 -0
  89. package/src/functions/datasets.ts +0 -17
  90. package/src/functions/dates.ts +3 -2
  91. package/src/functions/metrics.ts +6 -4
  92. package/src/functions/resources.ts +110 -1
  93. package/src/functions/tabular.ts +171 -0
  94. package/src/functions/tabularApi.ts +96 -11
  95. package/src/main.ts +97 -10
  96. package/src/types/dataservices.ts +2 -0
  97. package/src/types/organizations.ts +10 -0
  98. package/src/types/pages.ts +0 -5
  99. package/src/types/posts.ts +2 -2
  100. package/src/types/reports.ts +5 -1
  101. package/src/types/resources.ts +0 -1
  102. package/src/types/reuses.ts +12 -1
  103. package/src/types/search.ts +63 -1
  104. package/src/types/site.ts +5 -3
  105. package/src/types/ui.ts +2 -0
  106. package/src/types/users.ts +2 -1
  107. package/src/types/visualizations.ts +93 -0
  108. package/assets/swagger-themes/newspaper.css +0 -1670
  109. package/dist/JsonPreview.client-DojrmGyU.js +0 -72
  110. package/dist/Pmtiles.client-DbMjfK00.js +0 -25185
  111. package/dist/Swagger.client-Db_xYKJv.js +0 -4
  112. package/dist/XmlPreview.client-CHxSFhd7.js +0 -64
  113. package/dist/main-D70Xt4a7.js +0 -105854
  114. package/src/components/ResourceAccordion/Swagger.client.vue +0 -48
  115. package/src/functions/pagination.ts +0 -9
@@ -0,0 +1,170 @@
1
+ <template>
2
+ <ClientOnly>
3
+ <Teleport to="#tooltips">
4
+ <div
5
+ v-if="cell"
6
+ ref="panel"
7
+ class="bg-white border border-black/10 rounded-lg shadow-md w-80 absolute z-[800]"
8
+ :style="floatingStyles"
9
+ >
10
+ <!-- Value -->
11
+ <div class="px-3 pt-3 pb-2 border-b border-gray-default">
12
+ <p class="text-[10px] text-gray-plain mb-0">
13
+ {{ t('Valeur brute') }}
14
+ </p>
15
+ <p class="text-xs text-gray-title mb-0">
16
+ {{ displayValue }}
17
+ </p>
18
+ </div>
19
+
20
+ <!-- Type -->
21
+ <div class="flex items-center gap-2 px-3 py-2 border-b border-gray-default">
22
+ <span class="text-[10px] text-gray-plain">{{ t('Type') }}</span>
23
+ <span class="inline-flex items-center gap-1 bg-gray-some rounded px-1.5 py-0.5 text-xs text-gray-plain">
24
+ <component
25
+ :is="typeIcon"
26
+ class="size-3"
27
+ aria-hidden="true"
28
+ />
29
+ {{ typeLabel }}
30
+ </span>
31
+ <span class="text-[10px] text-gray-plain shrink-0">·</span>
32
+ <span class="text-[10px] text-gray-plain truncate min-w-0">{{ cell.column }}</span>
33
+ </div>
34
+
35
+ <!-- Actions -->
36
+ <div class="p-1">
37
+ <button
38
+ class="flex items-center gap-2.5 w-full px-3 py-2 rounded-md text-xs font-medium hover:bg-gray-50"
39
+ @click="filterByValue"
40
+ >
41
+ <RiFilterLine
42
+ class="size-4"
43
+ aria-hidden="true"
44
+ />
45
+ {{ t('Filtrer par cette valeur') }}
46
+ </button>
47
+ <button
48
+ class="flex items-center gap-2.5 w-full px-3 py-2 rounded-md text-xs font-medium hover:bg-gray-50"
49
+ @click="copyValue"
50
+ >
51
+ <RiCheckLine
52
+ v-if="copied"
53
+ class="size-4 text-green-500"
54
+ aria-hidden="true"
55
+ />
56
+ <RiFileCopyLine
57
+ v-else
58
+ class="size-4 text-gray-plain"
59
+ aria-hidden="true"
60
+ />
61
+ {{ copied ? t('Copié !') : t('Copier la valeur') }}
62
+ </button>
63
+ </div>
64
+ </div>
65
+ </Teleport>
66
+ </ClientOnly>
67
+ </template>
68
+
69
+ <script setup lang="ts">
70
+ import { computed, ref, useTemplateRef, watch } from 'vue'
71
+ import { flip, shift, autoUpdate, useFloating } from '@floating-ui/vue'
72
+ import { onClickOutside } from '@vueuse/core'
73
+ import {
74
+ RiFilterLine,
75
+ RiFileCopyLine,
76
+ RiCheckLine,
77
+ } from '@remixicon/vue'
78
+ import { toast } from 'vue-sonner'
79
+ import { useTranslation } from '../../composables/useTranslation'
80
+ import { buildTypeConfig } from '../../functions/tabular'
81
+ import ClientOnly from '../ClientOnly.vue'
82
+ import type { ColumnType, ColumnFilters } from './types'
83
+
84
+ export interface CellInfo {
85
+ column: string
86
+ columnType: ColumnType
87
+ value: unknown
88
+ element: HTMLElement
89
+ }
90
+
91
+ const cell = defineModel<CellInfo | null>('cell', { default: null })
92
+ const filters = defineModel<Record<string, ColumnFilters>>('filters', { default: () => ({}) })
93
+
94
+ const { t } = useTranslation()
95
+
96
+ const panelRef = useTemplateRef<HTMLElement>('panel')
97
+ const anchorRef = ref<HTMLElement | null>(null)
98
+
99
+ watch(cell, (c) => {
100
+ anchorRef.value = c?.element ?? null
101
+ })
102
+
103
+ const { floatingStyles } = useFloating(anchorRef, panelRef, {
104
+ placement: 'bottom-start',
105
+ middleware: [flip(), shift()],
106
+ whileElementsMounted: autoUpdate,
107
+ })
108
+
109
+ const displayValue = computed(() => {
110
+ if (!cell.value) return ''
111
+ const v = cell.value.value
112
+ if (v == null || v === '') return '–'
113
+ if (typeof v === 'object') return JSON.stringify(v)
114
+ return String(v)
115
+ })
116
+
117
+ const typeConfig = buildTypeConfig(t)
118
+
119
+ const typeIcon = computed(() => cell.value ? typeConfig[cell.value.columnType].icon : typeConfig.text.icon)
120
+ const typeLabel = computed(() => cell.value ? typeConfig[cell.value.columnType].label : '')
121
+
122
+ function close() {
123
+ cell.value = null
124
+ }
125
+
126
+ function filterByValue() {
127
+ if (!cell.value) return
128
+ const val = String(cell.value.value ?? '')
129
+ const col = cell.value.column
130
+ const existing = filters.value[col] ?? {}
131
+ if (cell.value.columnType === 'categorical' || cell.value.columnType === 'text' || cell.value.columnType === 'date') {
132
+ const current = existing.in ?? []
133
+ if (!current.includes(val)) {
134
+ filters.value = { ...filters.value, [col]: { ...existing, in: [...current, val] } }
135
+ }
136
+ }
137
+ else if (cell.value.columnType === 'number') {
138
+ const num = Number(cell.value.value)
139
+ if (Number.isFinite(num)) {
140
+ filters.value = { ...filters.value, [col]: { ...existing, min: num, max: num } }
141
+ }
142
+ }
143
+ else if (cell.value.columnType === 'boolean') {
144
+ filters.value = { ...filters.value, [col]: { ...existing, exact: val } }
145
+ }
146
+ close()
147
+ }
148
+
149
+ const copied = ref(false)
150
+
151
+ async function copyValue() {
152
+ try {
153
+ await navigator.clipboard.writeText(displayValue.value)
154
+ copied.value = true
155
+ setTimeout(() => {
156
+ copied.value = false
157
+ }, 1500)
158
+ }
159
+ catch {
160
+ toast.error(t('Impossible de copier dans le presse-papier'))
161
+ }
162
+ }
163
+
164
+ onClickOutside(panelRef, (e) => {
165
+ if (!cell.value) return
166
+ const clickedCell = (e.target as HTMLElement).closest('[data-cell]')
167
+ if (clickedCell && clickedCell === cell.value.element) return
168
+ close()
169
+ })
170
+ </script>