@datagouv/components-next 1.0.2-dev.30 → 1.0.2-dev.31

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 (26) hide show
  1. package/dist/{Datafair.client-CSUWxY1U.js → Datafair.client-BzyuQrsK.js} +1 -1
  2. package/dist/JsonPreview.client-CsFH4_pc.js +78 -0
  3. package/dist/{MapContainer.client-B0oJPrx5.js → MapContainer.client-PxTb3GFB.js} +2 -2
  4. package/dist/{PdfPreview.client-B2E_IWUj.js → PdfPreview.client-F9riTFzW.js} +561 -552
  5. package/dist/{Pmtiles.client-STSFvULL.js → Pmtiles.client-BdN6D_o3.js} +1 -1
  6. package/dist/Swagger.client-DRsUsdkD.js +4 -0
  7. package/dist/XmlPreview.client-CLDalkuE.js +70 -0
  8. package/dist/components-next.css +1 -1
  9. package/dist/components-next.js +56 -55
  10. package/dist/{index-kxzw3Ssm.js → index-DwQ7YeNi.js} +1 -1
  11. package/dist/{leaflet-src-DfyFSZpM.js → leaflet-src-DKk3Q492.js} +1 -1
  12. package/dist/{main-BMXOPzsN.js → main-BLApSdTQ.js} +869 -854
  13. package/dist/{vue3-xml-viewer.common-CwN-5lms.js → vue3-xml-viewer.common-DkEC3fSC.js} +1 -1
  14. package/package.json +1 -1
  15. package/src/components/ResourceAccordion/JsonPreview.client.vue +21 -17
  16. package/src/components/ResourceAccordion/Metadata.vue +1 -2
  17. package/src/components/ResourceAccordion/PdfPreview.client.vue +15 -3
  18. package/src/components/ResourceAccordion/ResourceAccordion.vue +1 -2
  19. package/src/components/ResourceAccordion/XmlPreview.client.vue +21 -17
  20. package/src/components/ResourceExplorer/ResourceExplorerViewer.vue +1 -2
  21. package/src/config.ts +2 -0
  22. package/src/functions/datasets.ts +0 -17
  23. package/src/functions/resources.ts +56 -1
  24. package/dist/JsonPreview.client-DWP5adeD.js +0 -72
  25. package/dist/Swagger.client-mrRTl6ll.js +0 -4
  26. package/dist/XmlPreview.client-C0zaJXWA.js +0 -64
@@ -1,4 +1,4 @@
1
- import { g as Ke } from "./main-BMXOPzsN.js";
1
+ import { g as Ke } from "./main-BLApSdTQ.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.30",
3
+ "version": "1.0.2-dev.31",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "engines": {
@@ -23,6 +23,9 @@
23
23
  : t("La taille du fichier est inconnue, l'aperçu n'est pas disponible. Téléchargez-le depuis l'onglet Téléchargements.")
24
24
  }}
25
25
  </PreviewUnavailable>
26
+ <PreviewUnavailable v-else-if="error === 'cors'">
27
+ {{ t("Ce fichier JSON ne peut pas être prévisualisé car il est hébergé sur un site distant qui restreint l'accès (CORS). Téléchargez-le depuis l'onglet Téléchargements.") }}
28
+ </PreviewUnavailable>
26
29
  <PreviewUnavailable v-else-if="error === 'network'">
27
30
  {{ 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.") }}
28
31
  </PreviewUnavailable>
@@ -37,8 +40,8 @@ import { computed, defineAsyncComponent, onMounted, ref } from 'vue'
37
40
  import { useComponentsConfig } from '../../config'
38
41
  import PreviewUnavailable from './PreviewUnavailable.vue'
39
42
  import type { Resource } from '../../types/resources'
43
+ import { getResourceFilesize, getResourceCorsStatus } from '../../functions/resources'
40
44
  import { useTranslation } from '../../composables/useTranslation'
41
- import { getResourceFilesize } from '../../functions/datasets'
42
45
 
43
46
  const JsonViewer = defineAsyncComponent(() =>
44
47
  import('vue3-json-viewer').then((module) => {
@@ -62,36 +65,37 @@ const fileTooLarge = ref(false)
62
65
 
63
66
  const fileSizeBytes = computed(() => getResourceFilesize(props.resource))
64
67
 
65
- const shouldLoadJson = computed(() => {
66
- const size = fileSizeBytes.value
67
- if (!size) {
68
- // If we don't know the size, don't risk loading a potentially huge file
69
- return false
70
- }
71
-
72
- // Check if maxJsonPreviewCharSize is configured
73
- if (!config.maxJsonPreviewCharSize) {
74
- // If no limit is set, don't load unknown files
75
- return false
76
- }
68
+ const corsStatus = computed(() => getResourceCorsStatus(props.resource))
77
69
 
70
+ const isSizeAllowed = computed(() => {
71
+ const size = fileSizeBytes.value
78
72
  // Convert maxJsonPreviewCharSize from characters to bytes (rough estimate)
79
73
  // Assuming average 1 byte per character for JSON
80
74
  const maxByteSize = config.maxJsonPreviewCharSize
81
75
 
76
+ // If we don't know the size or the max size, don't risk loading a potentially huge file
77
+ if (!size || !maxByteSize) return false
78
+
82
79
  return size <= maxByteSize
83
80
  })
84
81
 
85
82
  const fetchJsonData = async () => {
86
- // Check if file is too large or size is unknown before making the request
87
- if (!shouldLoadJson.value) {
83
+ error.value = null
84
+ fileTooLarge.value = false
85
+
86
+ // Check if file is too large or size is unknown
87
+ if (!isSizeAllowed.value) {
88
88
  fileTooLarge.value = true
89
89
  return
90
90
  }
91
91
 
92
- loading.value = true
93
- error.value = null
92
+ // Check if CORS is allowed
93
+ if (corsStatus.value === 'blocked') {
94
+ error.value = 'cors'
95
+ return
96
+ }
94
97
 
98
+ loading.value = true
95
99
  try {
96
100
  const response = await fetch(props.resource.url)
97
101
  // const response = await fetch('/test-data.json') // For testing locally without CORS issues
@@ -7,9 +7,8 @@ import DescriptionTerm from '../DescriptionTerm.vue'
7
7
  import { useFormatDate } from '../../functions/dates'
8
8
  import { filesize } from '../../functions/helpers'
9
9
  import ExtraAccordion from '../ExtraAccordion.vue'
10
- import { getResourceTitleId, getResourceLabel } from '../../functions/resources'
10
+ import { getResourceTitleId, getResourceLabel, getResourceFilesize } from '../../functions/resources'
11
11
  import { useTranslation } from '../../composables/useTranslation'
12
- import { getResourceFilesize } from '../../functions/datasets'
13
12
 
14
13
  const props = defineProps<{
15
14
  resource: Resource
@@ -24,6 +24,9 @@
24
24
  : t("La taille du fichier est inconnue, l'aperçu n'est pas disponible. Téléchargez-le depuis l'onglet Téléchargements.")
25
25
  }}
26
26
  </PreviewUnavailable>
27
+ <PreviewUnavailable v-else-if="error === 'cors'">
28
+ {{ t("Ce fichier PDF ne peut pas être prévisualisé car il est hébergé sur un site distant qui restreint l'accès (CORS). Téléchargez-le depuis l'onglet Téléchargements.") }}
29
+ </PreviewUnavailable>
27
30
  <PreviewUnavailable v-else-if="error === 'network'">
28
31
  {{ 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.") }}
29
32
  </PreviewUnavailable>
@@ -41,8 +44,8 @@ import type { PDFDocumentProxy } from 'pdfjs-dist'
41
44
  import PreviewUnavailable from './PreviewUnavailable.vue'
42
45
  import { useComponentsConfig } from '../../config'
43
46
  import type { Resource } from '../../types/resources'
47
+ import { getResourceFilesize, getResourceCorsStatus } from '../../functions/resources'
44
48
  import { useTranslation } from '../../composables/useTranslation'
45
- import { getResourceFilesize } from '../../functions/datasets'
46
49
 
47
50
  pdfjsLib.GlobalWorkerOptions.workerSrc = pdfjsWorker
48
51
 
@@ -97,6 +100,8 @@ async function renderPage(pageNum: number) {
97
100
 
98
101
  const fileSizeBytes = computed(() => getResourceFilesize(props.resource))
99
102
 
103
+ const corsStatus = computed(() => getResourceCorsStatus(props.resource))
104
+
100
105
  const shouldLoadPdf = computed(() => {
101
106
  const size = fileSizeBytes.value
102
107
  if (!size) {
@@ -110,14 +115,21 @@ const shouldLoadPdf = computed(() => {
110
115
  })
111
116
 
112
117
  const loadPdf = async () => {
118
+ error.value = null
119
+ fileTooLarge.value = false
120
+
113
121
  if (!shouldLoadPdf.value) {
114
122
  fileTooLarge.value = true
115
123
  return
116
124
  }
117
125
 
118
- loading.value = true
119
- error.value = null
126
+ // Check if CORS is allowed
127
+ if (corsStatus.value === 'blocked') {
128
+ error.value = 'cors'
129
+ return
130
+ }
120
131
 
132
+ loading.value = true
121
133
  try {
122
134
  const loadingTask = pdfjsLib.getDocument({
123
135
  url: props.resource.url,
@@ -387,9 +387,8 @@ import { trackEvent } from '../../functions/matomo'
387
387
  import CopyButton from '../CopyButton.vue'
388
388
  import { useComponentsConfig } from '../../config'
389
389
  import { getOwnerName } from '../../functions/owned'
390
- import { getResourceFormatIcon, getResourceTitleId, detectOgcService } from '../../functions/resources'
390
+ import { getResourceFormatIcon, getResourceTitleId, detectOgcService, getResourceExternalUrl, getResourceFilesize } from '../../functions/resources'
391
391
  import BrandedButton from '../BrandedButton.vue'
392
- import { getResourceExternalUrl, getResourceFilesize } from '../../functions/datasets'
393
392
  import { useTranslation } from '../../composables/useTranslation'
394
393
  import { useHasTabularData } from '../../composables/useHasTabularData'
395
394
  import Metadata from './Metadata.vue'
@@ -15,6 +15,9 @@
15
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
16
  }}
17
17
  </PreviewUnavailable>
18
+ <PreviewUnavailable v-else-if="error === 'cors'">
19
+ {{ t("Ce fichier XML ne peut pas être prévisualisé car il est hébergé sur un site distant qui restreint l'accès (CORS). Téléchargez-le depuis l'onglet Téléchargements.") }}
20
+ </PreviewUnavailable>
18
21
  <PreviewUnavailable v-else-if="error === 'network'">
19
22
  {{ 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
23
  </PreviewUnavailable>
@@ -29,9 +32,9 @@ import { computed, defineAsyncComponent, onMounted, ref } from 'vue'
29
32
  import { useComponentsConfig } from '../../config'
30
33
  import PreviewUnavailable from './PreviewUnavailable.vue'
31
34
  import type { Resource } from '../../types/resources'
35
+ import { getResourceFilesize, getResourceCorsStatus } from '../../functions/resources'
32
36
  import { useTranslation } from '../../composables/useTranslation'
33
37
  import '../../types/vue3-xml-viewer.d'
34
- import { getResourceFilesize } from '../../main'
35
38
 
36
39
  const XmlViewer = defineAsyncComponent(() =>
37
40
  import('vue3-xml-viewer').then((module) => {
@@ -53,36 +56,37 @@ const fileTooLarge = ref(false)
53
56
 
54
57
  const fileSizeBytes = computed(() => getResourceFilesize(props.resource))
55
58
 
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
- }
59
+ const corsStatus = computed(() => getResourceCorsStatus(props.resource))
68
60
 
61
+ const isSizeAllowed = computed(() => {
62
+ const size = fileSizeBytes.value
69
63
  // Convert maxXmlPreviewCharSize from characters to bytes (rough estimate)
70
64
  // Assuming average 1 byte per character for XML
71
65
  const maxByteSize = config.maxXmlPreviewCharSize
72
66
 
67
+ // If we don't know the size or the max size, don't risk loading a potentially huge file
68
+ if (!size || !maxByteSize) return false
69
+
73
70
  return size <= maxByteSize
74
71
  })
75
72
 
76
73
  const fetchXmlData = async () => {
77
- // Check if file is too large or size is unknown before making the request
78
- if (!shouldLoadXml.value) {
74
+ error.value = null
75
+ fileTooLarge.value = false
76
+
77
+ // Check if file is too large or size is unknown
78
+ if (!isSizeAllowed.value) {
79
79
  fileTooLarge.value = true
80
80
  return
81
81
  }
82
82
 
83
- loading.value = true
84
- error.value = null
83
+ // Check if CORS is allowed
84
+ if (corsStatus.value === 'blocked') {
85
+ error.value = 'cors'
86
+ return
87
+ }
85
88
 
89
+ loading.value = true
86
90
  try {
87
91
  const response = await fetch(props.resource.url)
88
92
  // const response = await fetch('/test-data.xml') // For testing locally without CORS issues
@@ -325,8 +325,7 @@ import DataStructure from '../ResourceAccordion/DataStructure.vue'
325
325
  import Metadata from '../ResourceAccordion/Metadata.vue'
326
326
  import SchemaBadge from '../ResourceAccordion/SchemaBadge.vue'
327
327
  import { filesize, summarize } from '../../functions/helpers'
328
- import { getResourceFormatIcon } from '../../functions/resources'
329
- import { getResourceExternalUrl, getResourceFilesize } from '../../functions/datasets'
328
+ import { getResourceFormatIcon, getResourceExternalUrl, getResourceFilesize } from '../../functions/resources'
330
329
  import { trackEvent } from '../../functions/matomo'
331
330
  import { useComponentsConfig } from '../../config'
332
331
  import { useFormatDate } from '../../functions/dates'
package/src/config.ts CHANGED
@@ -5,6 +5,8 @@ import type { FetchOptions } from 'ofetch'
5
5
  export type PluginConfig = {
6
6
  name: string // Name of the application (ex: data.gouv.fr)
7
7
  baseUrl: string
8
+ /** Hostnames allowed in Access-Control-Allow-Origin for resource preview CORS checks (e.g. data.gouv.fr). */
9
+ trustedDomains?: string[]
8
10
  apiBase: string
9
11
  devApiKey?: string | null
10
12
  datasetQualityGuideUrl?: string
@@ -1,6 +1,4 @@
1
1
  import { useComponentsConfig } from '../config'
2
- import type { Dataset, DatasetV2 } from '../types/datasets'
3
- import type { CommunityResource, Resource } from '../types/resources'
4
2
 
5
3
  function constructUrl(baseUrl: string, path: string): string {
6
4
  const url = new URL(baseUrl)
@@ -14,18 +12,3 @@ export function getDatasetOEmbedHtml(type: string, id: string): string {
14
12
  const staticUrl = constructUrl(config.baseUrl, 'oembed.js')
15
13
  return `<div data-udata-${type}="${id}"></div><script data-udata="${config.baseUrl}" src="${staticUrl}" async defer></script>`
16
14
  }
17
-
18
- export function isCommunityResource(resource: Resource | CommunityResource): boolean {
19
- return 'organization' in resource || 'owner' in resource
20
- }
21
-
22
- export function getResourceExternalUrl(dataset: Dataset | DatasetV2 | Omit<Dataset, 'resources' | 'community_resources'>, resource: Resource | CommunityResource): string {
23
- return `${dataset.page}${isCommunityResource(resource) ? '/community-resources' : ''}?resource_id=${resource.id}`
24
- }
25
-
26
- export function getResourceFilesize(resource: Resource): null | number {
27
- if (resource.filesize) return resource.filesize
28
- if ('analysis:content-length' in resource.extras) return resource.extras['analysis:content-length'] as number
29
-
30
- return null
31
- }
@@ -1,13 +1,15 @@
1
1
  import { readonly, type Component } from 'vue'
2
2
 
3
3
  import { RiEarthLine, RiMap2Line } from '@remixicon/vue'
4
+ import { useComponentsConfig } from '../config'
4
5
  import Archive from '../components/Icons/Archive.vue'
5
6
  import Code from '../components/Icons/Code.vue'
7
+ import type { Dataset, DatasetV2 } from '../types/datasets'
6
8
  import Documentation from '../components/Icons/Documentation.vue'
7
9
  import Image from '../components/Icons/Image.vue'
8
10
  import Link from '../components/Icons/Link.vue'
9
11
  import Table from '../components/Icons/Table.vue'
10
- import type { Resource } from '../types/resources'
12
+ import type { CommunityResource, Resource } from '../types/resources'
11
13
  import { useTranslation } from '../composables/useTranslation'
12
14
 
13
15
  export function getResourceFormatIcon(format: string): Component | null {
@@ -129,3 +131,56 @@ export const detectOgcService = (resource: Resource) => {
129
131
  }
130
132
  return false
131
133
  }
134
+
135
+ export function isCommunityResource(resource: Resource | CommunityResource): boolean {
136
+ return 'organization' in resource || 'owner' in resource
137
+ }
138
+
139
+ export function getResourceExternalUrl(dataset: Dataset | DatasetV2 | Omit<Dataset, 'resources' | 'community_resources'>, resource: Resource | CommunityResource): string {
140
+ return `${dataset.page}${isCommunityResource(resource) ? '/community-resources' : ''}?resource_id=${resource.id}`
141
+ }
142
+
143
+ export function getResourceFilesize(resource: Resource): null | number {
144
+ if (resource.filesize) return resource.filesize
145
+ if ('analysis:content-length' in resource.extras) return resource.extras['analysis:content-length'] as number
146
+
147
+ return null
148
+ }
149
+
150
+ type CorsStatus = 'allowed' | 'blocked' | 'unknown'
151
+
152
+ export const getResourceCorsStatus = (resource: Resource): CorsStatus => {
153
+ const extras = resource.extras
154
+ if (!extras || !('check:cors:allow-origin' in extras)) {
155
+ return 'unknown'
156
+ }
157
+
158
+ const allowOrigin = extras['check:cors:allow-origin'] as string | undefined
159
+ const rawMethods = extras['check:cors:allow-methods'] as string | undefined
160
+
161
+ // Check if allow-origin is '*' or contains one of our trusted domains
162
+ const config = useComponentsConfig()
163
+ const trustedDomains = config.trustedDomains ?? []
164
+ const hasPublicCors = allowOrigin === '*'
165
+ const hasSpecificCors = allowOrigin
166
+ ? trustedDomains.some((domain) => {
167
+ try {
168
+ const hostname = new URL(allowOrigin).hostname
169
+ return hostname === domain || hostname.endsWith(`.${domain}`)
170
+ }
171
+ catch {
172
+ return false
173
+ }
174
+ })
175
+ : false
176
+
177
+ const isOriginAllowed = hasPublicCors || hasSpecificCors
178
+
179
+ // Ensure GET method is allowed
180
+ const allowedMethods = rawMethods
181
+ ? rawMethods.split(',').map(m => m.trim().toUpperCase())
182
+ : []
183
+ const supportsGet = allowedMethods.length === 0 || allowedMethods.includes('GET')
184
+
185
+ return isOriginAllowed && supportsGet ? 'allowed' : 'blocked'
186
+ }
@@ -1,72 +0,0 @@
1
- import { defineComponent as z, defineAsyncComponent as C, ref as l, computed as x, onMounted as J, openBlock as t, createElementBlock as c, createVNode as S, unref as r, toDisplayString as i, createBlock as p, withCtx as d, createTextVNode as f, createCommentVNode as N } from "vue";
2
- import { u as B, a as L, b as V, _ as h } from "./main-BMXOPzsN.js";
3
- const b = { class: "fr-text--xs" }, E = { key: 0 }, P = {
4
- key: 1,
5
- class: "text-gray-medium"
6
- }, j = /* @__PURE__ */ z({
7
- __name: "JsonPreview.client",
8
- props: {
9
- resource: {}
10
- },
11
- setup(y) {
12
- const T = C(
13
- () => import("./vue3-json-viewer-BgCuOAH6.js").then((e) => (Promise.resolve({ }), e.JsonViewer))
14
- ), m = y, v = B(), { t: n } = L(), s = l(null), u = l(!1), a = l(null), g = l(!1), _ = x(() => V(m.resource)), w = x(() => {
15
- const e = _.value;
16
- if (!e || !v.maxJsonPreviewCharSize)
17
- return !1;
18
- const o = v.maxJsonPreviewCharSize;
19
- return e <= o;
20
- }), k = async () => {
21
- if (!w.value) {
22
- g.value = !0;
23
- return;
24
- }
25
- u.value = !0, a.value = null;
26
- try {
27
- const e = await fetch(m.resource.url);
28
- if (!e.ok)
29
- throw new Error(`HTTP error! status: ${e.status}`);
30
- const o = await e.json();
31
- s.value = o;
32
- } catch (e) {
33
- console.error("Error loading JSON:", e), e instanceof TypeError ? a.value = "network" : a.value = "generic", s.value = null;
34
- } finally {
35
- u.value = !1;
36
- }
37
- };
38
- return J(() => {
39
- k();
40
- }), (e, o) => (t(), c("div", b, [
41
- s.value ? (t(), c("div", E, [
42
- S(r(T), {
43
- value: s.value,
44
- boxed: "",
45
- sort: "",
46
- theme: "light",
47
- "max-depth": 3,
48
- "expand-depth": 2,
49
- "indent-width": 2
50
- }, null, 8, ["value"])
51
- ])) : u.value ? (t(), c("div", P, i(r(n)("Chargement de l'aperçu JSON...")), 1)) : g.value ? (t(), p(h, { key: 2 }, {
52
- default: d(() => [
53
- f(i(_.value ? r(n)("Le fichier JSON est trop volumineux pour être prévisualisé. Téléchargez-le depuis l'onglet Téléchargements.") : r(n)("La taille du fichier est inconnue, l'aperçu n'est pas disponible. Téléchargez-le depuis l'onglet Téléchargements.")), 1)
54
- ]),
55
- _: 1
56
- })) : a.value === "network" ? (t(), p(h, { key: 3 }, {
57
- default: d(() => [
58
- f(i(r(n)("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.")), 1)
59
- ]),
60
- _: 1
61
- })) : a.value ? (t(), p(h, { key: 4 }, {
62
- default: d(() => [
63
- f(i(r(n)("L'aperçu de ce fichier n'a pas pu être chargé. Téléchargez-le depuis l'onglet Téléchargements.")), 1)
64
- ]),
65
- _: 1
66
- })) : N("", !0)
67
- ]));
68
- }
69
- });
70
- export {
71
- j as default
72
- };
@@ -1,4 +0,0 @@
1
- import { i as f } from "./main-BMXOPzsN.js";
2
- export {
3
- f as default
4
- };
@@ -1,64 +0,0 @@
1
- import { defineComponent as z, defineAsyncComponent as C, ref as o, computed as x, onMounted as X, openBlock as t, createElementBlock as c, createVNode as L, unref as r, toDisplayString as i, createBlock as f, withCtx as m, createTextVNode as p, createCommentVNode as B } from "vue";
2
- import { u as S, a as V, b as E, _ as d } from "./main-BMXOPzsN.js";
3
- const M = { class: "fr-text--xs" }, P = { key: 0 }, b = {
4
- key: 1,
5
- class: "text-gray-medium"
6
- }, $ = /* @__PURE__ */ z({
7
- __name: "XmlPreview.client",
8
- props: {
9
- resource: {}
10
- },
11
- setup(y) {
12
- const T = C(
13
- () => import("./vue3-xml-viewer.common-CwN-5lms.js").then((e) => e.v).then((e) => e.default || e.XmlViewer)
14
- ), h = y, v = S(), { t: a } = V(), n = o(null), u = o(!1), l = o(null), g = o(!1), _ = x(() => E(h.resource)), w = x(() => {
15
- const e = _.value;
16
- if (!e || !v.maxXmlPreviewCharSize)
17
- return !1;
18
- const s = v.maxXmlPreviewCharSize;
19
- return e <= s;
20
- }), k = async () => {
21
- if (!w.value) {
22
- g.value = !0;
23
- return;
24
- }
25
- u.value = !0, l.value = null;
26
- try {
27
- const e = await fetch(h.resource.url);
28
- if (!e.ok)
29
- throw new Error(`HTTP error! status: ${e.status}`);
30
- const s = await e.text();
31
- n.value = s;
32
- } catch (e) {
33
- console.error("Error loading XML:", e), e instanceof TypeError ? l.value = "network" : l.value = "generic", n.value = null;
34
- } finally {
35
- u.value = !1;
36
- }
37
- };
38
- return X(() => {
39
- k();
40
- }), (e, s) => (t(), c("div", M, [
41
- n.value ? (t(), c("div", P, [
42
- L(r(T), { xml: n.value }, null, 8, ["xml"])
43
- ])) : u.value ? (t(), c("div", b, i(r(a)("Chargement de l'aperçu XML...")), 1)) : g.value ? (t(), f(d, { key: 2 }, {
44
- default: m(() => [
45
- p(i(_.value ? r(a)("Le fichier XML est trop volumineux pour être prévisualisé. Téléchargez-le depuis l'onglet Téléchargements.") : r(a)("La taille du fichier est inconnue, l'aperçu n'est pas disponible. Téléchargez-le depuis l'onglet Téléchargements.")), 1)
46
- ]),
47
- _: 1
48
- })) : l.value === "network" ? (t(), f(d, { key: 3 }, {
49
- default: m(() => [
50
- p(i(r(a)("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.")), 1)
51
- ]),
52
- _: 1
53
- })) : l.value ? (t(), f(d, { key: 4 }, {
54
- default: m(() => [
55
- p(i(r(a)("L'aperçu de ce fichier n'a pas pu être chargé. Téléchargez-le depuis l'onglet Téléchargements.")), 1)
56
- ]),
57
- _: 1
58
- })) : B("", !0)
59
- ]));
60
- }
61
- });
62
- export {
63
- $ as default
64
- };