@datagouv/components-next 1.0.2-dev.19 → 1.0.2-dev.191
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.
- package/README.md +7 -6
- package/assets/main.css +4 -0
- package/dist/{Control-DuZJdKV_.js → Control-B9WQxlpJ.js} +1 -1
- package/dist/{Datafair.client-Ds3VQrRi.js → Datafair.client-fxOwwaND.js} +9 -9
- package/dist/{Event--kp8kMdJ.js → Event-iXDrp-fy.js} +31 -31
- package/dist/{Image-34hvypZI.js → Image-mNMBOofs.js} +9 -9
- package/dist/ImagePreview.client-XSR9THWR.js +36 -0
- package/dist/JsonPreview.client-CU1FWFIy.js +40 -0
- package/dist/{Map-BjUnLyj8.js → Map-BfqKMw0S.js} +1739 -1599
- package/dist/{MapContainer.client-B2BijMx5.js → MapContainer.client-D0-Dn7jq.js} +41 -42
- package/dist/{OSM-s40W6sQ2.js → OSM-CcrUhItr.js} +15 -23
- package/dist/{PdfPreview.client-DJBMzrlC.js → PdfPreview.client-B7eDgq8y.js} +835 -856
- package/dist/Pmtiles.client-CCpvggkZ.js +26333 -0
- package/dist/PreviewWrapper.vue_vue_type_script_setup_true_lang-BzhNjYoY.js +60 -0
- package/dist/{ScaleLine-KW-nXqp3.js → ScaleLine-VGQ7nkMS.js} +2 -2
- package/dist/{Tile-DbNFNPfU.js → Tile-CSpn0Ca8.js} +160 -163
- package/dist/{TileImage-BsXBxMtq.js → TileImage-CpbaEFwd.js} +143 -131
- package/dist/{View-BR92hTWP.js → View-BYBpt-AU.js} +483 -422
- package/dist/XmlPreview.client-CyjpNh5i.js +34 -0
- package/dist/{common-PJfpC179.js → common-BoeTUnDZ.js} +52 -52
- package/dist/components-next.css +1 -52
- package/dist/components-next.js +194 -149
- package/dist/components.css +2 -2
- package/dist/{index-BFQX7Ccz.js → index-BBnxH-Nj.js} +21842 -15810
- package/dist/{leaflet-src-7m1mB8LI.js → leaflet-src-Be0Ohp2k.js} +185 -187
- package/dist/{main-vqhkVhVS.js → main-C2kCZkPD.js} +41515 -73245
- package/dist/{proj-DsetBcW7.js → proj-DxGbobp7.js} +662 -626
- package/dist/{text-clamp.esm-B5kW_XMt.js → text-clamp.esm-DVseBqZZ.js} +4 -4
- package/dist/{tilecoord-Db24Px13.js → tilecoord-DvX7WWiA.js} +273 -264
- package/dist/{vue3-json-viewer-BXwup7nO.js → vue3-json-viewer-CJLQFzXZ.js} +10 -16
- package/dist/{vue3-xml-viewer.common-BcNJo35o.js → vue3-xml-viewer.common-__BZsi8i.js} +16 -16
- package/package.json +47 -38
- package/src/chart.ts +5 -0
- package/src/components/ActivityList/ActivityList.vue +3 -2
- package/src/components/AppLink.vue +3 -0
- package/src/components/BannerAction.vue +6 -2
- package/src/components/Chart/ChartViewer.vue +320 -0
- package/src/components/Chart/ChartViewerWrapper.vue +182 -0
- package/src/components/CopyButton.vue +6 -2
- package/src/components/DataserviceCard.vue +9 -0
- package/src/components/DataserviceQuality.vue +82 -0
- package/src/components/DataserviceQualityInline.vue +31 -0
- package/src/components/DataserviceQualityTooltipContent.vue +79 -0
- package/src/components/DatasetCard.vue +9 -4
- package/src/components/DatasetQuality.vue +11 -11
- package/src/components/DatasetQualityInline.vue +2 -2
- package/src/components/DatasetQualityTooltipContent.vue +1 -1
- package/src/components/Form/Listbox.vue +101 -0
- package/src/components/Form/SchemaSelect.vue +2 -0
- package/src/components/InfiniteLoader.vue +53 -0
- package/src/components/ObjectCardHeader.vue +11 -4
- package/src/components/OpenApiViewer/ContentTypeSelect.vue +48 -0
- package/src/components/OpenApiViewer/EndpointRequest.vue +164 -0
- package/src/components/OpenApiViewer/EndpointResponses.vue +149 -0
- package/src/components/OpenApiViewer/OpenApiViewer.vue +308 -0
- package/src/components/OpenApiViewer/SchemaPanel.vue +53 -0
- package/src/components/OpenApiViewer/SchemaTree.vue +77 -0
- package/src/components/OpenApiViewer/openapi.ts +150 -0
- package/src/components/OrganizationNameWithCertificate.vue +3 -2
- package/src/components/Pagination.vue +23 -58
- package/src/components/RadioInput.vue +7 -2
- package/src/components/ResourceAccordion/DataStructure.vue +11 -33
- package/src/components/ResourceAccordion/Datafair.client.vue +1 -1
- package/src/components/ResourceAccordion/Downloads.vue +160 -0
- package/src/components/ResourceAccordion/ImagePreview.client.vue +48 -0
- package/src/components/ResourceAccordion/JsonPreview.client.vue +23 -104
- package/src/components/ResourceAccordion/MapContainer.client.vue +2 -11
- package/src/components/ResourceAccordion/Metadata.vue +1 -2
- package/src/components/ResourceAccordion/PdfPreview.client.vue +58 -97
- package/src/components/ResourceAccordion/PdfSkeleton.vue +44 -0
- package/src/components/ResourceAccordion/Pmtiles.client.vue +28 -13
- package/src/components/ResourceAccordion/Preview.vue +11 -11
- package/src/components/ResourceAccordion/PreviewWrapper.vue +89 -0
- package/src/components/ResourceAccordion/ResourceAccordion.vue +23 -114
- package/src/components/ResourceAccordion/XmlPreview.client.vue +16 -98
- package/src/components/ResourceExplorer/ResourceExplorer.vue +102 -210
- package/src/components/ResourceExplorer/ResourceExplorerHeader.vue +74 -0
- package/src/components/ResourceExplorer/ResourceExplorerSidebar.vue +103 -71
- package/src/components/ResourceExplorer/ResourceExplorerViewer.vue +143 -291
- package/src/components/ResourceExplorer/ResourceMainAction.vue +240 -0
- package/src/components/ResourceExplorer/ResourceSelector.vue +51 -0
- package/src/components/ResourceExplorer/ResourceViewerHeader.vue +115 -0
- package/src/components/ResourceExplorer/ResourceViewerSkeleton.vue +94 -0
- package/src/components/ResourceListItem.vue +161 -0
- package/src/components/ReuseCard.vue +14 -6
- package/src/components/ReuseDetails.vue +2 -2
- package/src/components/ReuseHorizontalCard.vue +2 -2
- package/src/components/SchemaCard.vue +10 -1
- package/src/components/Search/Filter/AccessTypeFilter.vue +2 -2
- package/src/components/Search/GlobalSearch.vue +220 -117
- package/src/components/Search/SearchInput.vue +5 -4
- package/src/components/Search/Sidemenu.vue +4 -3
- package/src/components/TabularExplorer/TabularActiveFilters.vue +79 -0
- package/src/components/TabularExplorer/TabularCell.vue +50 -0
- package/src/components/TabularExplorer/TabularCellPopover.vue +170 -0
- package/src/components/TabularExplorer/TabularColumnsMenu.vue +112 -0
- package/src/components/TabularExplorer/TabularExplorer.vue +299 -0
- package/src/components/TabularExplorer/TabularFilterContent.vue +362 -0
- package/src/components/TabularExplorer/TabularFilterPopover.vue +106 -0
- package/src/components/TabularExplorer/TabularMobileFilterButton.vue +21 -0
- package/src/components/TabularExplorer/TabularMobileFilters.vue +150 -0
- package/src/components/TabularExplorer/TabularRowsInfo.vue +31 -0
- package/src/components/TabularExplorer/TabularSkeleton.vue +92 -0
- package/src/components/TabularExplorer/TabularTable.vue +481 -0
- package/src/components/TabularExplorer/TabularToolbar.vue +25 -0
- package/src/components/TabularExplorer/types.ts +81 -0
- package/src/components/TabularExplorer/useColumnMetadata.ts +98 -0
- package/src/components/TabularExplorer/useTabularContext.ts +82 -0
- package/src/composables/useActiveDescendant.ts +5 -0
- package/src/composables/useDatasetResources.ts +164 -0
- package/src/composables/useHasTabularData.ts +15 -1
- package/src/composables/useMetrics.ts +1 -1
- package/src/composables/useResizable.ts +46 -0
- package/src/composables/useResourceCapabilities.ts +48 -40
- package/src/composables/useSearchFilter.ts +120 -0
- package/src/composables/useStableQueryParams.ts +38 -6
- package/src/composables/useTabularProfile.ts +70 -0
- package/src/composables/useTranslation.ts +24 -9
- package/src/config.ts +21 -3
- package/src/functions/activities.ts +3 -3
- package/src/functions/api.ts +20 -42
- package/src/functions/api.types.ts +1 -0
- package/src/functions/charts.ts +99 -0
- package/src/functions/datasets.ts +0 -17
- package/src/functions/dates.ts +3 -2
- package/src/functions/helpers.ts +15 -0
- package/src/functions/metrics.ts +63 -60
- package/src/functions/paginate.ts +46 -0
- package/src/functions/resourceCapabilities.ts +34 -0
- package/src/functions/resources.ts +136 -1
- package/src/functions/schemas.ts +27 -0
- package/src/functions/tabular.ts +214 -0
- package/src/functions/tabularApi.ts +96 -11
- package/src/main.ts +117 -14
- package/src/types/dataservices.ts +17 -0
- package/src/types/organizations.ts +10 -0
- package/src/types/pages.ts +0 -5
- package/src/types/posts.ts +2 -2
- package/src/types/reports.ts +5 -1
- package/src/types/resources.ts +0 -1
- package/src/types/reuses.ts +12 -1
- package/src/types/search.ts +63 -1
- package/src/types/site.ts +5 -3
- package/src/types/ui.ts +2 -0
- package/src/types/users.ts +2 -1
- package/src/types/visualizations.ts +93 -0
- package/assets/swagger-themes/newspaper.css +0 -1670
- package/dist/JsonPreview.client-CYxmz0yV.js +0 -72
- package/dist/Pmtiles.client-C_hvRDuy.js +0 -25185
- package/dist/Swagger.client-B4y0hXME.js +0 -4
- package/dist/XmlPreview.client-LETEfNBH.js +0 -64
- package/src/components/ResourceAccordion/Swagger.client.vue +0 -48
- package/src/functions/pagination.ts +0 -9
- /package/src/components/{DatasetQualityItem.vue → QualityItem.vue} +0 -0
- /package/src/components/{DatasetQualityItemWarning.vue → QualityItemWarning.vue} +0 -0
- /package/src/components/{DatasetQualityScore.vue → QualityScore.vue} +0 -0
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
:resource
|
|
57
57
|
/>
|
|
58
58
|
<RiSubtractLine
|
|
59
|
-
v-if="resource.schema"
|
|
59
|
+
v-if="resource.schema?.name || resource.schema?.url"
|
|
60
60
|
aria-hidden="true"
|
|
61
61
|
class="size-3 fill-gray-medium"
|
|
62
62
|
/>
|
|
@@ -197,7 +197,10 @@
|
|
|
197
197
|
:key="tab.key"
|
|
198
198
|
class="px-4"
|
|
199
199
|
>
|
|
200
|
-
<div
|
|
200
|
+
<div
|
|
201
|
+
v-if="tab.key === 'map'"
|
|
202
|
+
class="-mx-4 h-[600px]"
|
|
203
|
+
>
|
|
201
204
|
<Pmtiles
|
|
202
205
|
v-if="hasPmtiles"
|
|
203
206
|
:resource="resource"
|
|
@@ -224,6 +227,10 @@
|
|
|
224
227
|
v-else-if="resource.format && resource.format.toLowerCase() === 'xml'"
|
|
225
228
|
:resource="resource"
|
|
226
229
|
/>
|
|
230
|
+
<ImagePreview
|
|
231
|
+
v-else-if="isImagePreviewFormat(resource.format)"
|
|
232
|
+
:resource="resource"
|
|
233
|
+
/>
|
|
227
234
|
<!-- Show Datafair embedded preview (koumoul) -->
|
|
228
235
|
<DatafairPreview
|
|
229
236
|
v-else-if="hasDatafairPreview"
|
|
@@ -231,7 +238,7 @@
|
|
|
231
238
|
:dataset="dataset"
|
|
232
239
|
/>
|
|
233
240
|
<!-- Show Datafair embedded preview (koumoul) -->
|
|
234
|
-
<
|
|
241
|
+
<OpenApiViewer
|
|
235
242
|
v-else-if="hasOpenAPIPreview"
|
|
236
243
|
:url="resource.extras['apidocUrl'] as string"
|
|
237
244
|
/>
|
|
@@ -265,91 +272,13 @@
|
|
|
265
272
|
<div
|
|
266
273
|
v-if="tab.key === 'downloads'"
|
|
267
274
|
>
|
|
268
|
-
<
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
>
|
|
273
|
-
{{ t("URL d'origine") }}
|
|
274
|
-
</dt>
|
|
275
|
-
<dt
|
|
276
|
-
v-else
|
|
277
|
-
class="font-bold fr-text--sm fr-mb-0"
|
|
278
|
-
>
|
|
279
|
-
{{ t('Format original') }}
|
|
280
|
-
</dt>
|
|
281
|
-
<dd class="text-sm pl-0 mb-4 text-gray-medium h-8 flex flex-wrap items-center">
|
|
282
|
-
<span v-if="resource.format === 'url'">
|
|
283
|
-
<a
|
|
284
|
-
:href="resource.latest"
|
|
285
|
-
class="fr-link no-icon-after"
|
|
286
|
-
rel="ugc nofollow noopener"
|
|
287
|
-
target="_blank"
|
|
288
|
-
@click="trackEvent('Jeux de données', 'Télécharger un fichier', 'Bouton : télécharger un fichier')"
|
|
289
|
-
>
|
|
290
|
-
<component
|
|
291
|
-
:is="config.textClamp"
|
|
292
|
-
v-if="config && config.textClamp"
|
|
293
|
-
:auto-resize="true"
|
|
294
|
-
:max-lines="1"
|
|
295
|
-
:text="resource.url"
|
|
296
|
-
>
|
|
297
|
-
<template #after>
|
|
298
|
-
<span class="fr-ml-1v fr-icon-external-link-line fr-icon--sm" />
|
|
299
|
-
</template>
|
|
300
|
-
</component>
|
|
301
|
-
</a>
|
|
302
|
-
</span>
|
|
303
|
-
<span v-else>
|
|
304
|
-
<span class="text-datagouv fr-icon-download-line fr-icon--sm fr-mr-1v fr-mt-1v" />
|
|
305
|
-
<a
|
|
306
|
-
:href="resource.latest"
|
|
307
|
-
class="fr-link"
|
|
308
|
-
rel="ugc nofollow noopener"
|
|
309
|
-
@click="trackEvent('Jeux de données', 'Télécharger un fichier', `Bouton : format ${resource.format}`)"
|
|
310
|
-
>
|
|
311
|
-
<span>{{ t('Format {format}', { format: resource.format }) }}<span v-if="resourceFilesize"> - {{ filesize(resourceFilesize) }}</span></span>
|
|
312
|
-
</a>
|
|
313
|
-
</span>
|
|
314
|
-
<CopyButton
|
|
315
|
-
:label="t('Copier le lien')"
|
|
316
|
-
:copied-label="t('Lien copié !')"
|
|
317
|
-
:text="resource.latest"
|
|
318
|
-
class="relative"
|
|
319
|
-
/>
|
|
320
|
-
</dd>
|
|
321
|
-
<template v-if="generatedFormats.length">
|
|
322
|
-
<dt class="font-bold fr-text--sm fr-mb-0">
|
|
323
|
-
{{ t('Formats générés automatiquement par {platform} (dernière mise à jour {date})', { platform: config.name, date: conversionsLastUpdate }) }}
|
|
324
|
-
</dt>
|
|
325
|
-
<dd
|
|
326
|
-
v-for="generatedFormat in generatedFormats"
|
|
327
|
-
:key="generatedFormat.format"
|
|
328
|
-
class="text-sm pl-0 mb-4 text-gray-medium h-8 flex flex-wrap items-center"
|
|
329
|
-
>
|
|
330
|
-
<span>
|
|
331
|
-
<span class="text-datagouv fr-icon-download-line fr-icon--sm fr-mr-1v fr-mt-1v" />
|
|
332
|
-
<a
|
|
333
|
-
:href="generatedFormat.url"
|
|
334
|
-
class="fr-link"
|
|
335
|
-
rel="ugc nofollow noopener"
|
|
336
|
-
@click="trackEvent('Jeux de données', 'Télécharger un fichier', `Bouton : format ${generatedFormat.format}`)"
|
|
337
|
-
>
|
|
338
|
-
<span>{{ t('Format {format}', { format: generatedFormat.format }) }}<span v-if="generatedFormat.size"> - {{ filesize(generatedFormat.size) }}</span></span>
|
|
339
|
-
</a>
|
|
340
|
-
</span>
|
|
341
|
-
<CopyButton
|
|
342
|
-
:label="t('Copier le lien')"
|
|
343
|
-
:copied-label="t('Lien copié !')"
|
|
344
|
-
:text="generatedFormat.url"
|
|
345
|
-
class="relative"
|
|
346
|
-
/>
|
|
347
|
-
</dd>
|
|
348
|
-
</template>
|
|
349
|
-
</dl>
|
|
275
|
+
<Downloads
|
|
276
|
+
:resource="resource"
|
|
277
|
+
:dataset="dataset"
|
|
278
|
+
/>
|
|
350
279
|
</div>
|
|
351
280
|
<div
|
|
352
|
-
v-if="tab.key === '
|
|
281
|
+
v-if="tab.key === 'api'"
|
|
353
282
|
>
|
|
354
283
|
<div class="fr-mb-4w">
|
|
355
284
|
<p>{{ t("Cette API est générée automatiquement par {platform} à partir du fichier.", { platform: config.name }) }}</p>
|
|
@@ -357,7 +286,7 @@
|
|
|
357
286
|
<p>{{ t("- Si le fichier est supprimé, l'API sera également supprimée.") }}</p>
|
|
358
287
|
<p>{{ t("Pour des usages pérennes, prévoyez que cette API dépend directement du fichier source.") }}</p>
|
|
359
288
|
</div>
|
|
360
|
-
<
|
|
289
|
+
<OpenApiViewer
|
|
361
290
|
v-if="hasTabularData"
|
|
362
291
|
:url="`${config.tabularApiUrl}/api/resources/${props.resource.id}/swagger/`"
|
|
363
292
|
/>
|
|
@@ -387,9 +316,8 @@ import { trackEvent } from '../../functions/matomo'
|
|
|
387
316
|
import CopyButton from '../CopyButton.vue'
|
|
388
317
|
import { useComponentsConfig } from '../../config'
|
|
389
318
|
import { getOwnerName } from '../../functions/owned'
|
|
390
|
-
import { getResourceFormatIcon, getResourceTitleId, detectOgcService } from '../../functions/resources'
|
|
319
|
+
import { getResourceFormatIcon, getResourceTitleId, detectOgcService, getResourceExternalUrl, getResourceFilesize, isImagePreviewFormat } from '../../functions/resources'
|
|
391
320
|
import BrandedButton from '../BrandedButton.vue'
|
|
392
|
-
import { getResourceExternalUrl, getResourceFilesize } from '../../functions/datasets'
|
|
393
321
|
import { useTranslation } from '../../composables/useTranslation'
|
|
394
322
|
import { useHasTabularData } from '../../composables/useHasTabularData'
|
|
395
323
|
import Metadata from './Metadata.vue'
|
|
@@ -397,11 +325,11 @@ import SchemaBadge from './SchemaBadge.vue'
|
|
|
397
325
|
import ResourceIcon from './ResourceIcon.vue'
|
|
398
326
|
import EditButton from './EditButton.vue'
|
|
399
327
|
import DataStructure from './DataStructure.vue'
|
|
328
|
+
import Downloads from './Downloads.vue'
|
|
400
329
|
import Preview from './Preview.vue'
|
|
401
330
|
import { isOrganizationCertified } from '../../functions/organizations'
|
|
402
|
-
import
|
|
331
|
+
import OpenApiViewer from '../OpenApiViewer/OpenApiViewer.vue'
|
|
403
332
|
|
|
404
|
-
const GENERATED_FORMATS = ['parquet', 'pmtiles', 'geojson']
|
|
405
333
|
const URL_FORMATS = ['url', 'doi', 'www:link', ' www:link-1.0-http--link', 'www:link-1.0-http--partners', 'www:link-1.0-http--related', 'www:link-1.0-http--samples']
|
|
406
334
|
|
|
407
335
|
const props = withDefaults(defineProps<{
|
|
@@ -418,12 +346,12 @@ const props = withDefaults(defineProps<{
|
|
|
418
346
|
|
|
419
347
|
const config = useComponentsConfig()
|
|
420
348
|
|
|
421
|
-
const Swagger = defineAsyncComponent(() => import('./Swagger.client.vue'))
|
|
422
349
|
const MapContainer = defineAsyncComponent(() => import('./MapContainer.client.vue'))
|
|
423
350
|
const Pmtiles = defineAsyncComponent(() => import('./Pmtiles.client.vue'))
|
|
424
351
|
const JsonPreview = defineAsyncComponent(() => import('./JsonPreview.client.vue'))
|
|
425
352
|
const PdfPreview = defineAsyncComponent(() => import('./PdfPreview.client.vue'))
|
|
426
353
|
const XmlPreview = defineAsyncComponent(() => import('./XmlPreview.client.vue'))
|
|
354
|
+
const ImagePreview = defineAsyncComponent(() => import('./ImagePreview.client.vue'))
|
|
427
355
|
const DatafairPreview = defineAsyncComponent(() => import('./Datafair.client.vue'))
|
|
428
356
|
|
|
429
357
|
const { t } = useTranslation()
|
|
@@ -431,11 +359,11 @@ const { formatRelativeIfRecentDate } = useFormatDate()
|
|
|
431
359
|
const checkTabularData = useHasTabularData()
|
|
432
360
|
|
|
433
361
|
const hasPreview = computed(() => {
|
|
434
|
-
// For JSON, PDF, and
|
|
362
|
+
// For JSON, PDF, XML, and image files, show preview.
|
|
435
363
|
// We cannot check for CORS issues here because we cannot use an async component here.
|
|
436
364
|
// If there is a CORS issue when fetching the file for preview, it will be managed and displayed as an error banner by the preview component.
|
|
437
365
|
const format = props.resource.format?.toLowerCase()
|
|
438
|
-
return format === 'json' || format === 'pdf' || format === 'xml'
|
|
366
|
+
return format === 'json' || format === 'pdf' || format === 'xml' || isImagePreviewFormat(format)
|
|
439
367
|
})
|
|
440
368
|
|
|
441
369
|
const hasTabularData = computed(() => checkTabularData(props.resource))
|
|
@@ -462,24 +390,6 @@ const ogcService = computed(() => detectOgcService(props.resource))
|
|
|
462
390
|
|
|
463
391
|
const ogcWms = computed(() => ogcService.value === 'wms')
|
|
464
392
|
|
|
465
|
-
const generatedFormats = computed(() => {
|
|
466
|
-
const formats = GENERATED_FORMATS
|
|
467
|
-
.filter(format => `analysis:parsing:${format}_url` in props.resource.extras)
|
|
468
|
-
.map(format => ({
|
|
469
|
-
url: props.resource.extras[`analysis:parsing:${format}_url`] as string,
|
|
470
|
-
size: props.resource.extras[`analysis:parsing:${format}_size`] as number | undefined,
|
|
471
|
-
format: format,
|
|
472
|
-
}))
|
|
473
|
-
if ('analysis:parsing:parsing_table' in props.resource.extras) {
|
|
474
|
-
formats.push({
|
|
475
|
-
url: `${config.tabularApiUrl}/api/resources/${props.resource.id}/data/json/`,
|
|
476
|
-
size: undefined,
|
|
477
|
-
format: 'json',
|
|
478
|
-
})
|
|
479
|
-
}
|
|
480
|
-
return formats
|
|
481
|
-
})
|
|
482
|
-
|
|
483
393
|
const open = ref(props.expandedOnMount)
|
|
484
394
|
const toggle = () => {
|
|
485
395
|
open.value = !open.value
|
|
@@ -515,7 +425,7 @@ const tabsOptions = computed(() => {
|
|
|
515
425
|
options.push({ key: 'downloads', label: t('Téléchargements') })
|
|
516
426
|
|
|
517
427
|
if (hasTabularData.value) {
|
|
518
|
-
options.push({ key: '
|
|
428
|
+
options.push({ key: 'api', label: t('API') })
|
|
519
429
|
}
|
|
520
430
|
|
|
521
431
|
return options
|
|
@@ -542,7 +452,6 @@ const communityResource = computed<CommunityResource | null>(() => {
|
|
|
542
452
|
const owner = computed(() => communityResource.value ? getOwnerName(communityResource.value) : null)
|
|
543
453
|
|
|
544
454
|
const lastUpdate = props.resource.last_modified
|
|
545
|
-
const conversionsLastUpdate = computed(() => formatRelativeIfRecentDate(props.resource.extras['analysis:parsing:finished_at'] as string | undefined))
|
|
546
455
|
const availabilityChecked = props.resource.extras && 'check:available' in props.resource.extras
|
|
547
456
|
const resourceFilesize = computed(() => getResourceFilesize(props.resource))
|
|
548
457
|
|
|
@@ -1,42 +1,24 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
</div>
|
|
12
|
-
<PreviewUnavailable v-else-if="fileTooLarge">
|
|
13
|
-
{{ fileSizeBytes
|
|
14
|
-
? t("Le fichier XML est trop volumineux pour être prévisualisé. Téléchargez-le depuis l'onglet Téléchargements.")
|
|
15
|
-
: t("La taille du fichier est inconnue, l'aperçu n'est pas disponible. Téléchargez-le depuis l'onglet Téléchargements.")
|
|
16
|
-
}}
|
|
17
|
-
</PreviewUnavailable>
|
|
18
|
-
<PreviewUnavailable v-else-if="error === 'network'">
|
|
19
|
-
{{ t("Ce fichier est hébergé sur un site externe qui ne permet pas la prévisualisation. Téléchargez-le depuis l'onglet Téléchargements.") }}
|
|
20
|
-
</PreviewUnavailable>
|
|
21
|
-
<PreviewUnavailable v-else-if="error">
|
|
22
|
-
{{ t("L'aperçu de ce fichier n'a pas pu être chargé. Téléchargez-le depuis l'onglet Téléchargements.") }}
|
|
23
|
-
</PreviewUnavailable>
|
|
24
|
-
</div>
|
|
2
|
+
<PreviewWrapper
|
|
3
|
+
v-slot="{ data }"
|
|
4
|
+
file-type="XML"
|
|
5
|
+
:resource="resource"
|
|
6
|
+
:max-size="config.maxXmlPreviewCharSize"
|
|
7
|
+
:load="load"
|
|
8
|
+
>
|
|
9
|
+
<XmlViewer :xml="(data as string)" />
|
|
10
|
+
</PreviewWrapper>
|
|
25
11
|
</template>
|
|
26
12
|
|
|
27
13
|
<script setup lang="ts">
|
|
28
|
-
import {
|
|
14
|
+
import { defineAsyncComponent } from 'vue'
|
|
29
15
|
import { useComponentsConfig } from '../../config'
|
|
30
|
-
import
|
|
16
|
+
import PreviewWrapper from './PreviewWrapper.vue'
|
|
31
17
|
import type { Resource } from '../../types/resources'
|
|
32
|
-
import { useTranslation } from '../../composables/useTranslation'
|
|
33
18
|
import '../../types/vue3-xml-viewer.d'
|
|
34
|
-
import { getResourceFilesize } from '../../main'
|
|
35
19
|
|
|
36
20
|
const XmlViewer = defineAsyncComponent(() =>
|
|
37
|
-
import('vue3-xml-viewer').then(
|
|
38
|
-
return module.default || module.XmlViewer
|
|
39
|
-
}),
|
|
21
|
+
import('vue3-xml-viewer').then(module => module.default || module.XmlViewer),
|
|
40
22
|
)
|
|
41
23
|
|
|
42
24
|
const props = defineProps<{
|
|
@@ -44,74 +26,10 @@ const props = defineProps<{
|
|
|
44
26
|
}>()
|
|
45
27
|
|
|
46
28
|
const config = useComponentsConfig()
|
|
47
|
-
const { t } = useTranslation()
|
|
48
29
|
|
|
49
|
-
const
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
const fileSizeBytes = computed(() => getResourceFilesize(props.resource))
|
|
55
|
-
|
|
56
|
-
const shouldLoadXml = computed(() => {
|
|
57
|
-
const size = fileSizeBytes.value
|
|
58
|
-
if (!size) {
|
|
59
|
-
// If we don't know the size, don't risk loading a potentially huge file
|
|
60
|
-
return false
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// Check if maxXmlPreviewCharSize is configured
|
|
64
|
-
if (!config.maxXmlPreviewCharSize) {
|
|
65
|
-
// If no limit is set, don't load unknown files
|
|
66
|
-
return false
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// Convert maxXmlPreviewCharSize from characters to bytes (rough estimate)
|
|
70
|
-
// Assuming average 1 byte per character for XML
|
|
71
|
-
const maxByteSize = config.maxXmlPreviewCharSize
|
|
72
|
-
|
|
73
|
-
return size <= maxByteSize
|
|
74
|
-
})
|
|
75
|
-
|
|
76
|
-
const fetchXmlData = async () => {
|
|
77
|
-
// Check if file is too large or size is unknown before making the request
|
|
78
|
-
if (!shouldLoadXml.value) {
|
|
79
|
-
fileTooLarge.value = true
|
|
80
|
-
return
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
loading.value = true
|
|
84
|
-
error.value = null
|
|
85
|
-
|
|
86
|
-
try {
|
|
87
|
-
const response = await fetch(props.resource.url)
|
|
88
|
-
// const response = await fetch('/test-data.xml') // For testing locally without CORS issues
|
|
89
|
-
if (!response.ok) {
|
|
90
|
-
throw new Error(`HTTP error! status: ${response.status}`)
|
|
91
|
-
}
|
|
92
|
-
const data = await response.text()
|
|
93
|
-
|
|
94
|
-
// Use the XML data as string - let the XML viewer handle large files
|
|
95
|
-
xmlData.value = data
|
|
96
|
-
}
|
|
97
|
-
catch (err) {
|
|
98
|
-
console.error('Error loading XML:', err)
|
|
99
|
-
|
|
100
|
-
if (err instanceof TypeError) {
|
|
101
|
-
error.value = 'network'
|
|
102
|
-
}
|
|
103
|
-
else {
|
|
104
|
-
error.value = 'generic'
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
xmlData.value = null
|
|
108
|
-
}
|
|
109
|
-
finally {
|
|
110
|
-
loading.value = false
|
|
111
|
-
}
|
|
30
|
+
const load = async () => {
|
|
31
|
+
const response = await fetch(props.resource.url)
|
|
32
|
+
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`)
|
|
33
|
+
return response.text()
|
|
112
34
|
}
|
|
113
|
-
|
|
114
|
-
onMounted(() => {
|
|
115
|
-
fetchXmlData()
|
|
116
|
-
})
|
|
117
35
|
</script>
|