@datagouv/components-next 1.0.2-dev.149 → 1.0.2-dev.150

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.
@@ -1,4 +1,4 @@
1
- import { g as Ke } from "./main-BpmTmbJK.js";
1
+ import { g as Ke } from "./main-CWzZZ7OE.js";
2
2
  import We from "vue";
3
3
  function Fe($, K) {
4
4
  for (var V = 0; V < K.length; V++) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datagouv/components-next",
3
- "version": "1.0.2-dev.149",
3
+ "version": "1.0.2-dev.150",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "engines": {
@@ -122,6 +122,11 @@
122
122
  v-if="ogcWms"
123
123
  :resource="resource"
124
124
  />
125
+ <PreviewUnavailable v-if="!hasPmtiles && !ogcWms && hasPmtilesError">
126
+ {{ t("La carte n'a pas pu être générée automatiquement pour ce fichier.") }}
127
+ <br>
128
+ <span class="text-gray-medium text-xs">{{ pmtilesError }}</span>
129
+ </PreviewUnavailable>
125
130
  </div>
126
131
  <div v-if="tab.key === 'data'">
127
132
  <JsonPreview
@@ -275,6 +280,8 @@ const { formatRelativeIfRecentDate } = useFormatDate()
275
280
  const {
276
281
  hasTabularData,
277
282
  hasPmtiles,
283
+ hasPmtilesError,
284
+ pmtilesError,
278
285
  hasDatafairPreview,
279
286
  hasOpenAPIPreview,
280
287
  ogcService,
@@ -1,4 +1,5 @@
1
1
  import { useComponentsConfig } from '../config'
2
+ import { hasTabularParsingError } from '../functions/resources'
2
3
  import type { Resource } from '../types/resources'
3
4
 
4
5
  /**
@@ -20,7 +21,7 @@ export const useHasTabularData = () => {
20
21
  return (
21
22
  config.tabularApiUrl
22
23
  && resource.extras['analysis:parsing:parsing_table']
23
- && !resource.extras['analysis:parsing:error']
24
+ && !hasTabularParsingError(resource)
24
25
  && !sourceUnreachable
25
26
  && (config.tabularAllowRemote || resource.filetype === 'file')
26
27
  )
@@ -2,7 +2,7 @@ import { computed, toValue, type MaybeRefOrGetter } from 'vue'
2
2
  import { useComponentsConfig } from '../config'
3
3
  import { useTranslation } from './useTranslation'
4
4
  import { useHasTabularData } from './useHasTabularData'
5
- import { detectOgcService } from '../functions/resources'
5
+ import { detectOgcService, getParsingErrorMessage, getParsingErrorStep } from '../functions/resources'
6
6
  import { isOrganizationCertified } from '../functions/organizations'
7
7
  import type { Resource, WfsMetadata } from '../types/resources'
8
8
  import type { Dataset, DatasetV2 } from '../types/datasets'
@@ -49,6 +49,11 @@ export function useResourceCapabilities(
49
49
  const ogcService = computed(() => detectOgcService(toValue(resource)))
50
50
  const ogcWms = computed(() => ogcService.value === 'wms')
51
51
 
52
+ // The map is built from a pmtiles export; when that export fails we still want
53
+ // to show the Carte tab, but with the reason it could not be generated.
54
+ const hasPmtilesError = computed(() => getParsingErrorStep(toValue(resource)) === 'pmtiles_export')
55
+ const pmtilesError = computed(() => hasPmtilesError.value ? getParsingErrorMessage(toValue(resource)) : null)
56
+
52
57
  const generatedFormats = computed(() => {
53
58
  const r = toValue(resource)
54
59
  const formats = GENERATED_FORMATS
@@ -85,21 +90,27 @@ export function useResourceCapabilities(
85
90
  const r = toValue(resource)
86
91
  const options = []
87
92
 
88
- if (hasTabularData.value) {
89
- options.push({ key: 'data', label: t('Données') })
93
+ const dataTab = { key: 'data', label: hasTabularData.value ? t('Données') : t('Aperçu') }
94
+ const mapTab = { key: 'map', label: t('Carte') }
95
+ const hasMap = hasPmtiles.value || ogcWms.value
96
+
97
+ // The map is the most visual preview: when it is available, show it first.
98
+ // When its generation failed, keep the data preview first and surface the
99
+ // Carte tab (with its error) right after.
100
+ if (hasMap) {
101
+ options.push(mapTab, dataTab)
102
+ }
103
+ else if (hasPmtilesError.value) {
104
+ options.push(dataTab, mapTab)
90
105
  }
91
106
  else {
92
- options.push({ key: 'data', label: t('Aperçu') })
107
+ options.push(dataTab)
93
108
  }
94
109
 
95
110
  if (hasTabularData.value) {
96
111
  options.push({ key: 'data-structure', label: t('Structure des données') })
97
112
  }
98
113
 
99
- if (hasPmtiles.value || ogcWms.value) {
100
- options.push({ key: 'map', label: t('Carte') })
101
- }
102
-
103
114
  if (r.description) {
104
115
  options.push({ key: 'description', label: t('Description') })
105
116
  }
@@ -118,6 +129,8 @@ export function useResourceCapabilities(
118
129
  hasPreview,
119
130
  hasTabularData,
120
131
  hasPmtiles,
132
+ hasPmtilesError,
133
+ pmtilesError,
121
134
  hasDatafairPreview,
122
135
  hasOpenAPIPreview,
123
136
  ogcService,
@@ -167,6 +167,40 @@ export function getResourceFilesize(resource: Resource): null | number {
167
167
  return null
168
168
  }
169
169
 
170
+ // Parsing errors are stored as `<step>:<message>`, where `<step>` names the
171
+ // analysis step that failed (e.g. `pmtiles_export`, `geojson_export`).
172
+
173
+ /** The analysis step that failed, or null when there is no parsing error. */
174
+ export function getParsingErrorStep(resource: Resource): string | null {
175
+ const error = resource.extras['analysis:parsing:error']
176
+ if (typeof error !== 'string' || !error) return null
177
+ const [step] = error.split(':', 1)
178
+ return step ?? null
179
+ }
180
+
181
+ /** The parsing error message without its `<step>:` prefix, or null when there is none. */
182
+ export function getParsingErrorMessage(resource: Resource): string | null {
183
+ const error = resource.extras['analysis:parsing:error']
184
+ if (typeof error !== 'string' || !error) return null
185
+ const colon = error.indexOf(':')
186
+ return colon === -1 ? error : error.slice(colon + 1)
187
+ }
188
+
189
+ // Geo/format export steps run *after* the tabular table has been built, so a
190
+ // failure here (e.g. a huge geometry timing out the pmtiles export) leaves the
191
+ // tabular data fully usable and must not disable the tabular explorer.
192
+ const NON_TABULAR_PARSING_ERROR_STEPS = ['pmtiles_export', 'geojson_export']
193
+
194
+ /**
195
+ * Whether the resource's parsing error prevents reading its tabular data.
196
+ * Only errors from the tabular parsing itself are fatal; downstream geo/format
197
+ * export failures are not.
198
+ */
199
+ export function hasTabularParsingError(resource: Resource): boolean {
200
+ const step = getParsingErrorStep(resource)
201
+ return step !== null && !NON_TABULAR_PARSING_ERROR_STEPS.includes(step)
202
+ }
203
+
170
204
  type CorsStatus = 'allowed' | 'blocked' | 'unknown'
171
205
 
172
206
  export const getResourceCorsStatus = (resource: Resource): CorsStatus => {