@datagouv/components-next 1.0.2-dev.18 → 1.0.2-dev.181

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 (151) 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-Ds3VQrRi.js → Datafair.client-CaxMyNif.js} +9 -9
  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/ImagePreview.client-CPmCyisP.js +36 -0
  8. package/dist/JsonPreview.client-CKOU-LBs.js +40 -0
  9. package/dist/{Map-BjUnLyj8.js → Map-BfqKMw0S.js} +1739 -1599
  10. package/dist/{MapContainer.client-B2BijMx5.js → MapContainer.client-IGYJWP5m.js} +41 -42
  11. package/dist/{OSM-s40W6sQ2.js → OSM-CcrUhItr.js} +15 -23
  12. package/dist/{PdfPreview.client-DJBMzrlC.js → PdfPreview.client-csUebU3A.js} +835 -856
  13. package/dist/Pmtiles.client-CLq7UHBg.js +26333 -0
  14. package/dist/PreviewWrapper.vue_vue_type_script_setup_true_lang-DeoHZXW1.js +60 -0
  15. package/dist/{ScaleLine-KW-nXqp3.js → ScaleLine-VGQ7nkMS.js} +2 -2
  16. package/dist/{Tile-DbNFNPfU.js → Tile-CSpn0Ca8.js} +160 -163
  17. package/dist/{TileImage-BsXBxMtq.js → TileImage-CpbaEFwd.js} +143 -131
  18. package/dist/{View-BR92hTWP.js → View-BYBpt-AU.js} +483 -422
  19. package/dist/XmlPreview.client-C1toAbQ0.js +34 -0
  20. package/dist/{common-PJfpC179.js → common-BoeTUnDZ.js} +52 -52
  21. package/dist/components-next.css +1 -52
  22. package/dist/components-next.js +193 -149
  23. package/dist/components.css +2 -2
  24. package/dist/{index-BFQX7Ccz.js → index-CaUlhl3k.js} +21842 -15810
  25. package/dist/{leaflet-src-7m1mB8LI.js → leaflet-src-ByYGrf8H.js} +185 -187
  26. package/dist/{main-vqhkVhVS.js → main-DD4ieUAo.js} +41500 -73223
  27. package/dist/{proj-DsetBcW7.js → proj-DxGbobp7.js} +662 -626
  28. package/dist/{text-clamp.esm-B5kW_XMt.js → text-clamp.esm-DVseBqZZ.js} +4 -4
  29. package/dist/{tilecoord-Db24Px13.js → tilecoord-DvX7WWiA.js} +273 -264
  30. package/dist/{vue3-json-viewer-BXwup7nO.js → vue3-json-viewer-CJLQFzXZ.js} +10 -16
  31. package/dist/{vue3-xml-viewer.common-BcNJo35o.js → vue3-xml-viewer.common-B1KPK4L4.js} +16 -16
  32. package/package.json +47 -38
  33. package/src/chart.ts +5 -0
  34. package/src/components/ActivityList/ActivityList.vue +3 -2
  35. package/src/components/AppLink.vue +3 -0
  36. package/src/components/BannerAction.vue +6 -2
  37. package/src/components/Chart/ChartViewer.vue +320 -0
  38. package/src/components/Chart/ChartViewerWrapper.vue +182 -0
  39. package/src/components/CopyButton.vue +6 -2
  40. package/src/components/DataserviceCard.vue +9 -0
  41. package/src/components/DataserviceQuality.vue +82 -0
  42. package/src/components/DataserviceQualityInline.vue +31 -0
  43. package/src/components/DataserviceQualityTooltipContent.vue +79 -0
  44. package/src/components/DatasetCard.vue +9 -4
  45. package/src/components/DatasetQuality.vue +11 -11
  46. package/src/components/DatasetQualityInline.vue +2 -2
  47. package/src/components/DatasetQualityTooltipContent.vue +1 -1
  48. package/src/components/Form/Listbox.vue +101 -0
  49. package/src/components/Form/SchemaSelect.vue +2 -0
  50. package/src/components/InfiniteLoader.vue +53 -0
  51. package/src/components/ObjectCardHeader.vue +11 -4
  52. package/src/components/OpenApiViewer/ContentTypeSelect.vue +48 -0
  53. package/src/components/OpenApiViewer/EndpointRequest.vue +164 -0
  54. package/src/components/OpenApiViewer/EndpointResponses.vue +149 -0
  55. package/src/components/OpenApiViewer/OpenApiViewer.vue +308 -0
  56. package/src/components/OpenApiViewer/SchemaPanel.vue +53 -0
  57. package/src/components/OpenApiViewer/SchemaTree.vue +77 -0
  58. package/src/components/OpenApiViewer/openapi.ts +150 -0
  59. package/src/components/OrganizationNameWithCertificate.vue +3 -2
  60. package/src/components/Pagination.vue +8 -5
  61. package/src/components/RadioInput.vue +7 -2
  62. package/src/components/ResourceAccordion/DataStructure.vue +11 -33
  63. package/src/components/ResourceAccordion/Datafair.client.vue +1 -1
  64. package/src/components/ResourceAccordion/Downloads.vue +160 -0
  65. package/src/components/ResourceAccordion/ImagePreview.client.vue +48 -0
  66. package/src/components/ResourceAccordion/JsonPreview.client.vue +23 -104
  67. package/src/components/ResourceAccordion/MapContainer.client.vue +2 -11
  68. package/src/components/ResourceAccordion/Metadata.vue +1 -2
  69. package/src/components/ResourceAccordion/PdfPreview.client.vue +58 -97
  70. package/src/components/ResourceAccordion/PdfSkeleton.vue +44 -0
  71. package/src/components/ResourceAccordion/Pmtiles.client.vue +28 -13
  72. package/src/components/ResourceAccordion/Preview.vue +11 -11
  73. package/src/components/ResourceAccordion/PreviewWrapper.vue +89 -0
  74. package/src/components/ResourceAccordion/ResourceAccordion.vue +23 -114
  75. package/src/components/ResourceAccordion/XmlPreview.client.vue +16 -98
  76. package/src/components/ResourceExplorer/ResourceExplorer.vue +102 -210
  77. package/src/components/ResourceExplorer/ResourceExplorerHeader.vue +74 -0
  78. package/src/components/ResourceExplorer/ResourceExplorerSidebar.vue +103 -71
  79. package/src/components/ResourceExplorer/ResourceExplorerViewer.vue +143 -291
  80. package/src/components/ResourceExplorer/ResourceMainAction.vue +240 -0
  81. package/src/components/ResourceExplorer/ResourceSelector.vue +51 -0
  82. package/src/components/ResourceExplorer/ResourceViewerHeader.vue +115 -0
  83. package/src/components/ResourceExplorer/ResourceViewerSkeleton.vue +94 -0
  84. package/src/components/ResourceListItem.vue +154 -0
  85. package/src/components/ReuseCard.vue +14 -6
  86. package/src/components/ReuseDetails.vue +2 -2
  87. package/src/components/ReuseHorizontalCard.vue +2 -2
  88. package/src/components/SchemaCard.vue +10 -1
  89. package/src/components/Search/Filter/AccessTypeFilter.vue +2 -2
  90. package/src/components/Search/GlobalSearch.vue +219 -117
  91. package/src/components/Search/SearchInput.vue +5 -4
  92. package/src/components/TabularExplorer/TabularActiveFilters.vue +79 -0
  93. package/src/components/TabularExplorer/TabularCell.vue +50 -0
  94. package/src/components/TabularExplorer/TabularCellPopover.vue +170 -0
  95. package/src/components/TabularExplorer/TabularColumnsMenu.vue +112 -0
  96. package/src/components/TabularExplorer/TabularExplorer.vue +299 -0
  97. package/src/components/TabularExplorer/TabularFilterContent.vue +362 -0
  98. package/src/components/TabularExplorer/TabularFilterPopover.vue +106 -0
  99. package/src/components/TabularExplorer/TabularMobileFilterButton.vue +21 -0
  100. package/src/components/TabularExplorer/TabularMobileFilters.vue +150 -0
  101. package/src/components/TabularExplorer/TabularRowsInfo.vue +31 -0
  102. package/src/components/TabularExplorer/TabularSkeleton.vue +92 -0
  103. package/src/components/TabularExplorer/TabularTable.vue +481 -0
  104. package/src/components/TabularExplorer/TabularToolbar.vue +25 -0
  105. package/src/components/TabularExplorer/types.ts +81 -0
  106. package/src/components/TabularExplorer/useColumnMetadata.ts +98 -0
  107. package/src/components/TabularExplorer/useTabularContext.ts +82 -0
  108. package/src/composables/useActiveDescendant.ts +5 -0
  109. package/src/composables/useDatasetResources.ts +164 -0
  110. package/src/composables/useHasTabularData.ts +15 -1
  111. package/src/composables/useMetrics.ts +1 -1
  112. package/src/composables/useResizable.ts +46 -0
  113. package/src/composables/useResourceCapabilities.ts +47 -21
  114. package/src/composables/useSearchFilter.ts +120 -0
  115. package/src/composables/useStableQueryParams.ts +38 -6
  116. package/src/composables/useTabularProfile.ts +70 -0
  117. package/src/config.ts +21 -3
  118. package/src/functions/activities.ts +3 -3
  119. package/src/functions/api.ts +20 -42
  120. package/src/functions/api.types.ts +1 -0
  121. package/src/functions/charts.ts +99 -0
  122. package/src/functions/datasets.ts +0 -17
  123. package/src/functions/dates.ts +3 -2
  124. package/src/functions/metrics.ts +6 -4
  125. package/src/functions/resources.ts +136 -1
  126. package/src/functions/schemas.ts +27 -0
  127. package/src/functions/tabular.ts +214 -0
  128. package/src/functions/tabularApi.ts +96 -11
  129. package/src/main.ts +117 -14
  130. package/src/types/dataservices.ts +17 -0
  131. package/src/types/organizations.ts +10 -0
  132. package/src/types/pages.ts +0 -5
  133. package/src/types/posts.ts +2 -2
  134. package/src/types/reports.ts +5 -1
  135. package/src/types/resources.ts +0 -1
  136. package/src/types/reuses.ts +12 -1
  137. package/src/types/search.ts +63 -1
  138. package/src/types/site.ts +5 -3
  139. package/src/types/ui.ts +2 -0
  140. package/src/types/users.ts +2 -1
  141. package/src/types/visualizations.ts +93 -0
  142. package/assets/swagger-themes/newspaper.css +0 -1670
  143. package/dist/JsonPreview.client-CYxmz0yV.js +0 -72
  144. package/dist/Pmtiles.client-C_hvRDuy.js +0 -25185
  145. package/dist/Swagger.client-B4y0hXME.js +0 -4
  146. package/dist/XmlPreview.client-LETEfNBH.js +0 -64
  147. package/src/components/ResourceAccordion/Swagger.client.vue +0 -48
  148. package/src/functions/pagination.ts +0 -9
  149. /package/src/components/{DatasetQualityItem.vue → QualityItem.vue} +0 -0
  150. /package/src/components/{DatasetQualityItemWarning.vue → QualityItemWarning.vue} +0 -0
  151. /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 v-if="tab.key === 'map'">
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
- <SwaggerClient
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
- <dl class="fr-pl-0">
269
- <dt
270
- v-if="resource.format === 'url'"
271
- class="font-bold fr-text--sm fr-mb-0"
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 === 'swagger'"
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
- <Swagger
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 SwaggerClient from './Swagger.client.vue'
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 XML files, show preview.
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: 'swagger', label: t('Swagger') })
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
- <div class="fr-text--xs">
3
- <div v-if="xmlData">
4
- <XmlViewer :xml="xmlData" />
5
- </div>
6
- <div
7
- v-else-if="loading"
8
- class="text-gray-medium"
9
- >
10
- {{ t("Chargement de l'aperçu XML...") }}
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 { computed, defineAsyncComponent, onMounted, ref } from 'vue'
14
+ import { defineAsyncComponent } from 'vue'
29
15
  import { useComponentsConfig } from '../../config'
30
- import PreviewUnavailable from './PreviewUnavailable.vue'
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((module) => {
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 xmlData = ref<string | null>(null)
50
- const loading = ref(false)
51
- const error = ref<string | null>(null)
52
- const fileTooLarge = ref(false)
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>