@datagouv/components-next 1.0.2-dev.12 → 1.0.2-dev.120

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 (110) hide show
  1. package/assets/main.css +4 -0
  2. package/dist/{Control-DuZJdKV_.js → Control-b-43UT2B.js} +10 -10
  3. package/dist/{Datafair.client-8haHXl47.js → Datafair.client-BrQPObQE.js} +4 -4
  4. package/dist/{Event--kp8kMdJ.js → Event-py_AAwJY.js} +35 -35
  5. package/dist/{Image-34hvypZI.js → Image-BHQYZWzH.js} +23 -23
  6. package/dist/JsonPreview.client-1IGVQ08V.js +40 -0
  7. package/dist/{Map-BjUnLyj8.js → Map-CtP7leHl.js} +1742 -1602
  8. package/dist/{MapContainer.client-l6HuXTHR.js → MapContainer.client-CZzHdzlZ.js} +37 -38
  9. package/dist/{OSM-s40W6sQ2.js → OSM-gdDSIsDA.js} +15 -23
  10. package/dist/{PdfPreview.client-4OueK-2Z.js → PdfPreview.client-DqQGGYo_.js} +823 -855
  11. package/dist/Pmtiles.client-BARkmNXd.js +26123 -0
  12. package/dist/PreviewWrapper.vue_vue_type_script_setup_true_lang-BVXRRGR-.js +61 -0
  13. package/dist/{ScaleLine-KW-nXqp3.js → ScaleLine-hG-FhNqy.js} +2 -2
  14. package/dist/{Tile-DbNFNPfU.js → Tile-D6rFonpT.js} +164 -167
  15. package/dist/{TileImage-BsXBxMtq.js → TileImage-cfrEgz5y.js} +131 -119
  16. package/dist/{View-BR92hTWP.js → View-vp7vDb9q.js} +482 -421
  17. package/dist/XmlPreview.client-BaVAAiZe.js +34 -0
  18. package/dist/{common-PJfpC179.js → common-C8efyyuc.js} +57 -57
  19. package/dist/components-next.css +1 -52
  20. package/dist/components-next.js +163 -140
  21. package/dist/components.css +2 -2
  22. package/dist/{index-CVTIoZQ0.js → index-C8S0AX5n.js} +21855 -15827
  23. package/dist/{leaflet-src-7m1mB8LI.js → leaflet-src-CTUz9_o9.js} +162 -164
  24. package/dist/main-BpO1p4v0.js +72447 -0
  25. package/dist/{proj-DsetBcW7.js → proj-CsjVeojN.js} +663 -627
  26. package/dist/{text-clamp.esm-B5kW_XMt.js → text-clamp.esm-DVseBqZZ.js} +4 -4
  27. package/dist/{tilecoord-Db24Px13.js → tilecoord-CPcQJnrF.js} +258 -249
  28. package/dist/{vue3-json-viewer-BXwup7nO.js → vue3-json-viewer-CJLQFzXZ.js} +10 -16
  29. package/dist/{vue3-xml-viewer.common-CWer_T5-.js → vue3-xml-viewer.common-BmpkRVgr.js} +1 -1
  30. package/package.json +50 -36
  31. package/src/chart.ts +5 -0
  32. package/src/components/ActivityList/ActivityList.vue +3 -2
  33. package/src/components/Chart/ChartViewer.vue +226 -0
  34. package/src/components/Chart/ChartViewerWrapper.vue +170 -0
  35. package/src/components/DataserviceCard.vue +3 -0
  36. package/src/components/DatasetCard.vue +9 -4
  37. package/src/components/Form/Listbox.vue +101 -0
  38. package/src/components/Form/SearchableSelect.vue +2 -1
  39. package/src/components/InfiniteLoader.vue +53 -0
  40. package/src/components/ObjectCardHeader.vue +11 -4
  41. package/src/components/OpenApiViewer/ContentTypeSelect.vue +48 -0
  42. package/src/components/OpenApiViewer/EndpointRequest.vue +164 -0
  43. package/src/components/OpenApiViewer/EndpointResponses.vue +149 -0
  44. package/src/components/OpenApiViewer/OpenApiViewer.vue +308 -0
  45. package/src/components/OpenApiViewer/SchemaPanel.vue +53 -0
  46. package/src/components/OpenApiViewer/SchemaTree.vue +77 -0
  47. package/src/components/OpenApiViewer/openapi.ts +150 -0
  48. package/src/components/OrganizationNameWithCertificate.vue +3 -2
  49. package/src/components/Pagination.vue +8 -5
  50. package/src/components/RadioInput.vue +7 -2
  51. package/src/components/ReadMore.vue +1 -1
  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 +14 -10
  64. package/src/components/ResourceExplorer/ResourceExplorerSidebar.vue +2 -2
  65. package/src/components/ResourceExplorer/ResourceExplorerViewer.vue +50 -148
  66. package/src/components/ResourceExplorer/ResourceSelector.vue +113 -0
  67. package/src/components/ReuseCard.vue +12 -4
  68. package/src/components/Search/GlobalSearch.vue +201 -113
  69. package/src/components/Search/SearchInput.vue +5 -4
  70. package/src/components/TabularExplorer/TabularCell.vue +51 -0
  71. package/src/components/TabularExplorer/TabularCellPopover.vue +170 -0
  72. package/src/components/TabularExplorer/TabularExplorer.vue +973 -0
  73. package/src/components/TabularExplorer/TabularFilterContent.vue +351 -0
  74. package/src/components/TabularExplorer/TabularFilterPopover.vue +111 -0
  75. package/src/components/TabularExplorer/types.ts +83 -0
  76. package/src/composables/useHasTabularData.ts +13 -0
  77. package/src/composables/useMetrics.ts +1 -1
  78. package/src/composables/useResourceCapabilities.ts +1 -1
  79. package/src/composables/useSearchFilter.ts +118 -0
  80. package/src/composables/useStableQueryParams.ts +38 -6
  81. package/src/composables/useTabularProfile.ts +70 -0
  82. package/src/config.ts +20 -3
  83. package/src/functions/activities.ts +3 -3
  84. package/src/functions/api.ts +9 -37
  85. package/src/functions/api.types.ts +1 -0
  86. package/src/functions/charts.ts +68 -0
  87. package/src/functions/datasets.ts +0 -17
  88. package/src/functions/metrics.ts +6 -4
  89. package/src/functions/resources.ts +56 -1
  90. package/src/functions/tabular.ts +60 -0
  91. package/src/functions/tabularApi.ts +138 -11
  92. package/src/main.ts +90 -9
  93. package/src/types/dataservices.ts +2 -0
  94. package/src/types/pages.ts +0 -5
  95. package/src/types/posts.ts +2 -2
  96. package/src/types/reports.ts +5 -1
  97. package/src/types/resources.ts +0 -1
  98. package/src/types/search.ts +63 -1
  99. package/src/types/site.ts +5 -3
  100. package/src/types/ui.ts +2 -0
  101. package/src/types/users.ts +2 -1
  102. package/src/types/visualizations.ts +89 -0
  103. package/assets/swagger-themes/newspaper.css +0 -1670
  104. package/dist/JsonPreview.client-D53pj9Cw.js +0 -72
  105. package/dist/Pmtiles.client-4j3VTYkz.js +0 -25185
  106. package/dist/Swagger.client-DPBmsH9q.js +0 -4
  107. package/dist/XmlPreview.client-XElkoA4F.js +0 -64
  108. package/dist/main-BbT-LUXy.js +0 -105854
  109. package/src/components/ResourceAccordion/Swagger.client.vue +0 -48
  110. 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
+ <RiFilter2Line
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
+ RiFilter2Line,
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>