@datagouv/components-next 0.0.30 → 0.0.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.
- package/README.md +10 -2
- package/assets/main.css +4 -0
- package/dist/{JsonPreview.client-DEoTeNS0.js → JsonPreview.client-B5cv59th.js} +12 -12
- package/dist/{MapContainer.client-CNmXA5i0.js → MapContainer.client-DXVDyZYz.js} +1 -1
- package/dist/{PdfPreview.client-CsVdmxPR.js → PdfPreview.client-XwjUHnmx.js} +5 -5
- package/dist/{Pmtiles.client-GgcBwFa0.js → Pmtiles.client-DfnKDlpg.js} +1 -1
- package/dist/Swagger.client-BisHyZkP.js +4 -0
- package/dist/{XmlPreview.client-C0lxnMVl.js → XmlPreview.client-BSjMew4d.js} +14 -14
- package/dist/components-next.css +1 -1
- package/dist/components-next.js +32 -31
- package/dist/components.css +1 -1
- package/dist/{main-D5CXGAAc.js → main-Qu3kUOIH.js} +15092 -15081
- package/dist/{vue3-xml-viewer.common-WmBgOZ5X.js → vue3-xml-viewer.common-NQY1dx9T.js} +1 -1
- package/package.json +1 -1
- package/src/components/Avatar.vue +2 -1
- package/src/components/BrandedButton.vue +4 -1
- package/src/components/ClientOnly.vue +17 -0
- package/src/components/DataserviceCard.vue +50 -78
- package/src/components/DatasetCard.vue +6 -11
- package/src/components/DatasetQuality.vue +1 -2
- package/src/components/DatasetQualityInline.vue +1 -3
- package/src/components/OrganizationCard.vue +9 -7
- package/src/components/OwnerType.vue +1 -1
- package/src/components/ResourceAccordion/DataStructure.vue +6 -5
- package/src/components/ResourceAccordion/JsonPreview.client.vue +5 -5
- package/src/components/ResourceAccordion/PdfPreview.client.vue +3 -3
- package/src/components/ResourceAccordion/Preview.vue +5 -5
- package/src/components/ResourceAccordion/ResourceAccordion.vue +2 -2
- package/src/components/ResourceAccordion/SchemaBadge.vue +5 -3
- package/src/components/ResourceAccordion/XmlPreview.client.vue +5 -5
- package/src/components/Tabs/TabGroup.vue +13 -1
- package/src/components/Toggletip.vue +81 -49
- package/src/components/ValueWatcher.vue +18 -0
- package/src/composables/useReuseType.ts +2 -1
- package/src/config.ts +5 -4
- package/src/functions/organizations.ts +14 -0
- package/src/functions/reuses.ts +10 -7
- package/src/functions/schemas.ts +32 -31
- package/src/functions/tabularApi.ts +2 -3
- package/src/functions/users.ts +2 -2
- package/src/main.ts +2 -0
- package/src/types/dataservices.ts +1 -0
- package/src/types/site.ts +3 -0
- package/dist/Swagger.client-2tUSrvmQ.js +0 -4
- package/src/components/ToggletipButton.vue +0 -14
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
<script setup lang="ts">
|
|
13
13
|
import { computed } from 'vue'
|
|
14
|
-
import {
|
|
14
|
+
import { useGetUserAvatar } from '../functions/users'
|
|
15
15
|
import type { User } from '../types/users'
|
|
16
16
|
|
|
17
17
|
type Props = {
|
|
@@ -23,5 +23,6 @@ const props = withDefaults(defineProps<Props>(), {
|
|
|
23
23
|
rounded: false,
|
|
24
24
|
size: 40,
|
|
25
25
|
})
|
|
26
|
+
const getUserAvatar = useGetUserAvatar()
|
|
26
27
|
const avatarUrl = computed(() => getUserAvatar(props.user, props.size))
|
|
27
28
|
</script>
|
|
@@ -53,7 +53,7 @@ import AppLink from './AppLink.vue'
|
|
|
53
53
|
import { bannerActionTypeKey } from './BannerAction.vue'
|
|
54
54
|
import AnimatedLoader from './AnimatedLoader.vue'
|
|
55
55
|
|
|
56
|
-
type ColorType = 'primary' | 'primary-soft' | 'primary-softer' | 'secondary' | 'secondary-softer' | 'warning' | 'danger' | 'tertiary'
|
|
56
|
+
export type ColorType = 'primary' | 'primary-soft' | 'primary-softer' | 'secondary' | 'secondary-softer' | 'warning' | 'danger' | 'tertiary' | 'purple-flat' | 'green-flat' | 'white-flat'
|
|
57
57
|
|
|
58
58
|
const props = withDefaults(defineProps<{
|
|
59
59
|
size?: '2xs' | 'xs' | 'sm' | 'lg' | 'xl'
|
|
@@ -119,6 +119,9 @@ const colors = computed(() => {
|
|
|
119
119
|
'warning': `text-warning-dark bg-white !border-warning-dark ${!isDisabled.value ? '[&&]:hover:!bg-gray-some' : ''}`,
|
|
120
120
|
'danger': `!text-danger-dark bg-white !border-danger-dark ${!isDisabled.value ? '[&&]:hover:!bg-gray-some' : ''}`,
|
|
121
121
|
'tertiary': `!border-none bg-transparent text-datagouv-dark ${!isDisabled.value ? '[&&]:hover:!bg-gray-some' : ''}`,
|
|
122
|
+
'purple-flat': `!border-none bg-purple-dataservice text-white ${!isDisabled.value ? '[&&]:hover:!bg-purple-dataservice/90' : ''}`,
|
|
123
|
+
'green-flat': `!border-none bg-green-reuse text-white ${!isDisabled.value ? '[&&]:hover:!bg-green-reuse/90' : ''}`,
|
|
124
|
+
'white-flat': `!border-none bg-white ${!isDisabled.value ? '[&&]:hover:!bg-white/90' : ''}`,
|
|
122
125
|
}[color.value]
|
|
123
126
|
})
|
|
124
127
|
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<component
|
|
3
|
+
:is="config?.clientOnly"
|
|
4
|
+
v-if="config.clientOnly"
|
|
5
|
+
>
|
|
6
|
+
<slot />
|
|
7
|
+
</component>
|
|
8
|
+
<template v-else>
|
|
9
|
+
<slot />
|
|
10
|
+
</template>
|
|
11
|
+
</template>
|
|
12
|
+
|
|
13
|
+
<script setup lang="ts">
|
|
14
|
+
import { useComponentsConfig } from '../config'
|
|
15
|
+
|
|
16
|
+
const config = useComponentsConfig()
|
|
17
|
+
</script>
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<article
|
|
3
|
-
class="my-4 p-4 bg-white border
|
|
3
|
+
class="my-4 p-4 bg-white border fr-enlarge-link"
|
|
4
4
|
:class="{
|
|
5
5
|
'border-tabular-api': isTabularApi,
|
|
6
|
+
'border-gray-default': !isTabularApi,
|
|
6
7
|
'mt-6': showBadge,
|
|
7
8
|
}"
|
|
8
9
|
>
|
|
@@ -14,10 +15,7 @@
|
|
|
14
15
|
v-if="dataservice.access_type === 'restricted'"
|
|
15
16
|
class="fr-badge fr-badge--sm fr-badge--mention-grey text-gray-medium mr-2"
|
|
16
17
|
>
|
|
17
|
-
<
|
|
18
|
-
class="fr-icon-lock-line fr-icon--sm"
|
|
19
|
-
aria-hidden="true"
|
|
20
|
-
/>
|
|
18
|
+
<RiLockLine class="size-4 mr-1" />
|
|
21
19
|
{{ t('Accès restreint') }}
|
|
22
20
|
</p>
|
|
23
21
|
<p
|
|
@@ -31,64 +29,46 @@
|
|
|
31
29
|
v-if="dataservice.private"
|
|
32
30
|
class="fr-badge fr-badge--sm fr-badge--mention-grey text-gray-medium mr-2"
|
|
33
31
|
>
|
|
34
|
-
<
|
|
35
|
-
class="fr-icon-lock-line fr-icon--sm"
|
|
36
|
-
aria-hidden="true"
|
|
37
|
-
/>
|
|
32
|
+
<RiLockLine class="size-4 mr-1" />
|
|
38
33
|
{{ t('Brouillon') }}
|
|
39
34
|
</p>
|
|
40
35
|
<p
|
|
41
36
|
v-if="dataservice.archived_at"
|
|
42
37
|
class="fr-badge fr-badge--sm fr-badge--mention-grey text-gray-medium mr-2"
|
|
43
38
|
>
|
|
44
|
-
<
|
|
45
|
-
class="fr-icon-lock-line fr-icon--sm"
|
|
46
|
-
aria-hidden="true"
|
|
47
|
-
/>
|
|
39
|
+
<RiLockLine class="size-4 mr-1" />
|
|
48
40
|
{{ t('Archivé') }}
|
|
49
41
|
</p>
|
|
50
42
|
</div>
|
|
51
|
-
<h4 class="
|
|
43
|
+
<h4 class="text-base mb-0 flex items-center gap-1">
|
|
52
44
|
<slot
|
|
53
45
|
name="dataserviceUrl"
|
|
54
46
|
:dataservice="dataservice"
|
|
55
47
|
:dataservice-url="dataserviceUrl"
|
|
56
48
|
>
|
|
57
|
-
<
|
|
49
|
+
<RiSparklingLine
|
|
58
50
|
v-if="isTabularApi"
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
aria-hidden="true"
|
|
63
|
-
class="fr-mr-1v"
|
|
64
|
-
style="width:1rem"
|
|
65
|
-
><path d="M17.0007 1.20825 18.3195 3.68108 20.7923 4.99992 18.3195 6.31876 17.0007 8.79159 15.6818 6.31876 13.209 4.99992 15.6818 3.68108 17.0007 1.20825ZM10.6673 9.33325 15.6673 11.9999 10.6673 14.6666 8.00065 19.6666 5.33398 14.6666.333984 11.9999 5.33398 9.33325 8.00065 4.33325 10.6673 9.33325ZM11.4173 11.9999 9.18905 10.8115 8.00065 8.58325 6.81224 10.8115 4.58398 11.9999 6.81224 13.1883 8.00065 15.4166 9.18905 13.1883 11.4173 11.9999ZM19.6673 16.3333 18.0007 13.2083 16.334 16.3333 13.209 17.9999 16.334 19.6666 18.0007 22.7916 19.6673 19.6666 22.7923 17.9999 19.6673 16.3333Z" /></svg>
|
|
66
|
-
<span
|
|
51
|
+
class="size-4 flex-none"
|
|
52
|
+
/>
|
|
53
|
+
<RiTerminalLine
|
|
67
54
|
v-else
|
|
68
|
-
class="
|
|
69
|
-
aria-hidden="true"
|
|
55
|
+
class="size-4 flex-none"
|
|
70
56
|
/>
|
|
71
57
|
<AppLink
|
|
72
|
-
class="
|
|
58
|
+
class="truncate"
|
|
73
59
|
:to="dataserviceUrl"
|
|
74
60
|
>
|
|
75
|
-
|
|
76
|
-
:is="config.textClamp"
|
|
77
|
-
v-if="config.textClamp"
|
|
78
|
-
:auto-resize="true"
|
|
79
|
-
:text="dataservice.title"
|
|
80
|
-
:max-lines="1"
|
|
81
|
-
/>
|
|
61
|
+
{{ dataservice.title }}
|
|
82
62
|
</AppLink>
|
|
83
63
|
</slot>
|
|
84
64
|
</h4>
|
|
85
|
-
<
|
|
65
|
+
<div
|
|
86
66
|
v-if="dataservice.organization || dataservice.owner"
|
|
87
|
-
class="text-
|
|
67
|
+
class="text-gray-medium overflow-hidden flex items-center gap-1 mt-1 mb-0"
|
|
88
68
|
>
|
|
89
|
-
<
|
|
69
|
+
<p
|
|
90
70
|
v-if="dataservice.organization"
|
|
91
|
-
class="block not-enlarged overflow-hidden"
|
|
71
|
+
class="text-sm block not-enlarged overflow-hidden mb-0"
|
|
92
72
|
>
|
|
93
73
|
<AppLink
|
|
94
74
|
v-if="organizationUrl"
|
|
@@ -101,54 +81,44 @@
|
|
|
101
81
|
v-else
|
|
102
82
|
:organization="dataservice.organization"
|
|
103
83
|
/>
|
|
104
|
-
</span>
|
|
105
|
-
<component
|
|
106
|
-
:is="config.textClamp"
|
|
107
|
-
v-else-if="config.textClamp"
|
|
108
|
-
class="not-enlarged mr-1"
|
|
109
|
-
:auto-resize="true"
|
|
110
|
-
:text="ownerName"
|
|
111
|
-
:max-lines="1"
|
|
112
|
-
/>
|
|
113
|
-
<RiSubtractLine class="size-4 flex-none fill-gray-medium" />
|
|
114
|
-
<span class="block whitespace-nowrap">{{ t('Mis à jour {date}', { date: formatRelativeIfRecentDate(dataservice.metadata_modified_at, { dateStyle: 'medium' }) }) }}</span>
|
|
115
|
-
</p>
|
|
116
|
-
<div class="flex flex-wrap items-center gap-1 mt-1 text-gray-medium">
|
|
117
|
-
<p class="text-sm mb-0">
|
|
118
|
-
{{ t('Disponibilité :') }}
|
|
119
|
-
<span class="text-gray-plain">
|
|
120
|
-
<template v-if="dataservice.availability">
|
|
121
|
-
{{ t('{n}%', dataservice.availability) }}
|
|
122
|
-
</template>
|
|
123
|
-
<template v-else>
|
|
124
|
-
{{ t('inconnue') }}
|
|
125
|
-
</template>
|
|
126
|
-
</span>
|
|
127
84
|
</p>
|
|
128
|
-
<RiSubtractLine class="size-4 flex-none fill-gray-medium" />
|
|
129
85
|
<p
|
|
130
|
-
|
|
131
|
-
|
|
86
|
+
v-else
|
|
87
|
+
class="text-sm mb-0 truncate"
|
|
132
88
|
>
|
|
133
|
-
|
|
134
|
-
aria-hidden="true"
|
|
135
|
-
class="size-3.5"
|
|
136
|
-
/>{{ summarize(dataservice.metrics.views) }}
|
|
89
|
+
{{ ownerName }}
|
|
137
90
|
</p>
|
|
138
|
-
<
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
<RiStarLine
|
|
143
|
-
aria-hidden="true"
|
|
144
|
-
class="size-3.5"
|
|
145
|
-
/>{{ summarize(dataservice.metrics.followers) }}
|
|
91
|
+
<RiSubtractLine class="size-4 flex-none fill-gray-medium" />
|
|
92
|
+
<!-- This comment is only here to fix this issue https://github.com/datagouv/cdata/issues/653, it could be empty… -->
|
|
93
|
+
<p class="text-sm whitespace-nowrap mb-0">
|
|
94
|
+
{{ t('Mis à jour {date}', { date: formatRelativeIfRecentDate(dataservice.metadata_modified_at, { dateStyle: 'medium' }) }) }}
|
|
146
95
|
</p>
|
|
96
|
+
<RiSubtractLine class="size-4 flex-none fill-gray-medium" />
|
|
97
|
+
<div class="flex items-center gap-1">
|
|
98
|
+
<p
|
|
99
|
+
class="text-sm mb-0 flex items-center gap-0.5"
|
|
100
|
+
:aria-label="t('{n} vues | {n} vue | {n} vues', dataservice.metrics.views)"
|
|
101
|
+
>
|
|
102
|
+
<RiEyeLine
|
|
103
|
+
aria-hidden="true"
|
|
104
|
+
class="size-3.5"
|
|
105
|
+
/>{{ summarize(dataservice.metrics.views) }}
|
|
106
|
+
</p>
|
|
107
|
+
<p
|
|
108
|
+
class="text-sm mb-0 flex items-center gap-0.5"
|
|
109
|
+
:aria-label="t('{n} abonnés | {n} abonné | {n} abonnés', dataservice.metrics.followers)"
|
|
110
|
+
>
|
|
111
|
+
<RiStarLine
|
|
112
|
+
aria-hidden="true"
|
|
113
|
+
class="size-3.5"
|
|
114
|
+
/>{{ summarize(dataservice.metrics.followers) }}
|
|
115
|
+
</p>
|
|
116
|
+
</div>
|
|
147
117
|
</div>
|
|
148
118
|
<component
|
|
149
119
|
:is="config.textClamp"
|
|
150
120
|
v-if="config.textClamp && description && showDescription"
|
|
151
|
-
class="
|
|
121
|
+
class="text-sm mt-2 mb-0"
|
|
152
122
|
:auto-resize="true"
|
|
153
123
|
:text="description"
|
|
154
124
|
:max-lines="2"
|
|
@@ -160,7 +130,7 @@
|
|
|
160
130
|
import { computed, ref, watchEffect } from 'vue'
|
|
161
131
|
import { useI18n } from 'vue-i18n'
|
|
162
132
|
import type { RouteLocationRaw } from 'vue-router'
|
|
163
|
-
import { RiEyeLine, RiPassValidLine, RiStarLine, RiSubtractLine } from '@remixicon/vue'
|
|
133
|
+
import { RiEyeLine, RiLockLine, RiPassValidLine, RiSparklingLine, RiStarLine, RiSubtractLine, RiTerminalLine } from '@remixicon/vue'
|
|
164
134
|
import { useComponentsConfig } from '../config'
|
|
165
135
|
import { useFormatDate } from '../functions/dates'
|
|
166
136
|
import { summarize } from '../functions/helpers'
|
|
@@ -177,7 +147,7 @@ import AppLink from './AppLink.vue'
|
|
|
177
147
|
* The dataserviceUrl is a route location object to allow Vue Router to navigate to the details of a dataservice.
|
|
178
148
|
* It is used as a separate prop to allow other sites using the package to define their own dataservice pages.
|
|
179
149
|
*/
|
|
180
|
-
dataserviceUrl
|
|
150
|
+
dataserviceUrl?: RouteLocationRaw
|
|
181
151
|
|
|
182
152
|
/**
|
|
183
153
|
* The organizationUrl is an optional route location object to allow Vue Router to navigate to the details of the organization linked to tha dataservice.
|
|
@@ -192,6 +162,8 @@ const props = withDefaults(defineProps<Props>(), {
|
|
|
192
162
|
showDescription: true,
|
|
193
163
|
})
|
|
194
164
|
|
|
165
|
+
const dataserviceUrl = computed(() => props.dataserviceUrl || props.dataservice.self_web_url)
|
|
166
|
+
|
|
195
167
|
const { t } = useI18n()
|
|
196
168
|
const { formatRelativeIfRecentDate } = useFormatDate()
|
|
197
169
|
const ownerName = computed(() => getOwnerName(props.dataservice))
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="p-4 border bg-white border-gray-default relative hover:bg-gray-some">
|
|
3
|
-
<div :id />
|
|
4
3
|
<div
|
|
5
4
|
v-if="dataset.private || dataset.archived"
|
|
6
5
|
class="absolute top-0 fr-grid-row fr-grid-row--middle fr-mt-n3v fr-ml-n1v"
|
|
@@ -28,23 +27,23 @@
|
|
|
28
27
|
</div>
|
|
29
28
|
<div class="flex flex-wrap md:flex-nowrap gap-4 items-start">
|
|
30
29
|
<div class="flex-none">
|
|
31
|
-
<div class="flex justify-center items-center p-
|
|
30
|
+
<div class="flex justify-center items-center p-2 border border-gray-lower bg-[#fff]">
|
|
32
31
|
<Placeholder
|
|
33
32
|
v-if="dataset.organization"
|
|
34
33
|
type="dataset"
|
|
35
34
|
:src="dataset.organization.logo_thumbnail"
|
|
36
35
|
alt=""
|
|
37
|
-
:size="
|
|
36
|
+
:size="48"
|
|
38
37
|
/>
|
|
39
38
|
<Avatar
|
|
40
39
|
v-else-if="dataset.owner"
|
|
41
40
|
:user="dataset.owner"
|
|
42
|
-
:size="
|
|
41
|
+
:size="48"
|
|
43
42
|
/>
|
|
44
43
|
<Placeholder
|
|
45
44
|
v-else
|
|
46
45
|
type="dataset"
|
|
47
|
-
:size="
|
|
46
|
+
:size="48"
|
|
48
47
|
/>
|
|
49
48
|
</div>
|
|
50
49
|
</div>
|
|
@@ -104,10 +103,7 @@
|
|
|
104
103
|
</div>
|
|
105
104
|
<div class="mx-0 -mb-1 flex flex-wrap items-center text-sm text-gray-medium">
|
|
106
105
|
<div class="fr-hidden flex-sm dash-after-sm text-gray-medium -ml-2.5">
|
|
107
|
-
<DatasetQualityInline
|
|
108
|
-
:quality="dataset.quality"
|
|
109
|
-
:teleport-id="id"
|
|
110
|
-
/>
|
|
106
|
+
<DatasetQualityInline :quality="dataset.quality" />
|
|
111
107
|
</div>
|
|
112
108
|
<div class="flex flex-wrap items-center gap-1">
|
|
113
109
|
<p
|
|
@@ -164,7 +160,7 @@
|
|
|
164
160
|
<script setup lang="ts">
|
|
165
161
|
import { useI18n } from 'vue-i18n'
|
|
166
162
|
import type { RouteLocationRaw } from 'vue-router'
|
|
167
|
-
import { computed, ref,
|
|
163
|
+
import { computed, ref, watchEffect } from 'vue'
|
|
168
164
|
import { RiDownloadLine, RiEyeLine, RiLineChartLine, RiStarLine, RiSubtractLine } from '@remixicon/vue'
|
|
169
165
|
import type { Dataset, DatasetV2 } from '../types/datasets'
|
|
170
166
|
import { summarize } from '../functions/helpers'
|
|
@@ -203,7 +199,6 @@ const props = withDefaults(defineProps<Props>(), {
|
|
|
203
199
|
|
|
204
200
|
const { t } = useI18n()
|
|
205
201
|
const { formatRelativeIfRecentDate } = useFormatDate()
|
|
206
|
-
const id = useId()
|
|
207
202
|
const ownerName = computed(() => getOwnerName(props.dataset))
|
|
208
203
|
const config = useComponentsConfig()
|
|
209
204
|
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
<div class="m-0 flex flex-wrap items-center text-sm text-gray-medium">
|
|
3
3
|
<div class="fr-grid-row fr-grid-row--middle">
|
|
4
4
|
<Toggletip
|
|
5
|
-
|
|
6
|
-
:teleport-id
|
|
5
|
+
:button-props="{ class: 'relative z-2' }"
|
|
7
6
|
>
|
|
8
7
|
<template #toggletip>
|
|
9
8
|
<DatasetQualityTooltipContent :quality />
|
|
@@ -27,6 +26,5 @@ import Toggletip from './Toggletip.vue'
|
|
|
27
26
|
|
|
28
27
|
defineProps<{
|
|
29
28
|
quality: Quality
|
|
30
|
-
teleportId?: string
|
|
31
29
|
}>()
|
|
32
30
|
</script>
|
|
@@ -22,12 +22,14 @@
|
|
|
22
22
|
/>
|
|
23
23
|
</AppLink>
|
|
24
24
|
</p>
|
|
25
|
-
<div class="mb-2 flex flex-wrap items-center">
|
|
26
|
-
<
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
25
|
+
<div class="mb-2 flex flex-wrap gap-1 items-center">
|
|
26
|
+
<template v-if="type !== 'other'">
|
|
27
|
+
<OwnerType
|
|
28
|
+
class="mb-0 text-sm"
|
|
29
|
+
:type
|
|
30
|
+
/>
|
|
31
|
+
<RiSubtractLine class="size-4 fill-gray-medium" />
|
|
32
|
+
</template>
|
|
31
33
|
<div>
|
|
32
34
|
<div
|
|
33
35
|
v-if="organization.metrics"
|
|
@@ -51,7 +53,7 @@
|
|
|
51
53
|
</template>
|
|
52
54
|
|
|
53
55
|
<script setup lang="ts">
|
|
54
|
-
import { RiLineChartLine, RiDatabase2Line, RiTerminalLine } from '@remixicon/vue'
|
|
56
|
+
import { RiLineChartLine, RiDatabase2Line, RiTerminalLine, RiSubtractLine } from '@remixicon/vue'
|
|
55
57
|
import { computed, ref, watchEffect } from 'vue'
|
|
56
58
|
import { removeMarkdown } from '../functions/markdown'
|
|
57
59
|
import { getOrganizationType } from '../functions/organizations'
|
|
@@ -48,10 +48,11 @@
|
|
|
48
48
|
<script setup lang="ts">
|
|
49
49
|
import { onMounted, ref } from 'vue'
|
|
50
50
|
import type { Resource } from '../../types/resources'
|
|
51
|
-
import {
|
|
51
|
+
import { useGetProfile } from '../../functions/tabularApi'
|
|
52
52
|
import PreviewLoader from './PreviewLoader.vue'
|
|
53
53
|
|
|
54
54
|
const props = defineProps<{ resource: Resource }>()
|
|
55
|
+
const getProfile = useGetProfile()
|
|
55
56
|
|
|
56
57
|
type ColumnInfo = {
|
|
57
58
|
score: number
|
|
@@ -67,10 +68,10 @@ const hasColumnInfo = ref(false)
|
|
|
67
68
|
|
|
68
69
|
onMounted(async () => {
|
|
69
70
|
try {
|
|
70
|
-
const
|
|
71
|
-
if ('profile' in
|
|
72
|
-
columns.value = Object.keys(
|
|
73
|
-
columnsInfo.value =
|
|
71
|
+
const response = await getProfile(props.resource.id) // Assurez-vous que cette fonction retourne bien les données attendues
|
|
72
|
+
if ('profile' in response && response.profile) {
|
|
73
|
+
columns.value = Object.keys(response.profile.columns)
|
|
74
|
+
columnsInfo.value = response.profile.columns
|
|
74
75
|
hasColumnInfo.value = true
|
|
75
76
|
loading.value = false
|
|
76
77
|
}
|
|
@@ -96,17 +96,17 @@ const shouldLoadJson = computed(() => {
|
|
|
96
96
|
return false
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
-
// Check if
|
|
100
|
-
if (!config.
|
|
99
|
+
// Check if maxJsonPreviewCharSize is configured
|
|
100
|
+
if (!config.maxJsonPreviewCharSize) {
|
|
101
101
|
// If no limit is set, don't load unknown files
|
|
102
102
|
return false
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
-
// Convert
|
|
105
|
+
// Convert maxJsonPreviewCharSize from characters to bytes (rough estimate)
|
|
106
106
|
// Assuming average 1 byte per character for JSON
|
|
107
|
-
const
|
|
107
|
+
const maxByteSize = config.maxJsonPreviewCharSize
|
|
108
108
|
|
|
109
|
-
return size <=
|
|
109
|
+
return size <= maxByteSize
|
|
110
110
|
})
|
|
111
111
|
|
|
112
112
|
const fetchJsonData = async () => {
|
|
@@ -109,9 +109,9 @@ const shouldLoadPdf = computed(() => {
|
|
|
109
109
|
return false
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
-
// Use
|
|
113
|
-
const
|
|
114
|
-
return size <=
|
|
112
|
+
// Use maxPdfPreviewByteSize from config, fallback to 10 MB if not set
|
|
113
|
+
const maxByteSize = config.maxPdfPreviewByteSize ?? 10_000_000
|
|
114
|
+
return size <= maxByteSize
|
|
115
115
|
})
|
|
116
116
|
|
|
117
117
|
const loadPdf = async () => {
|
|
@@ -144,12 +144,12 @@ function isSortedBy(col: string) {
|
|
|
144
144
|
async function getTableInfos(page: number, sortConfig?: SortConfig) {
|
|
145
145
|
try {
|
|
146
146
|
// Check that this function return wanted data
|
|
147
|
-
const
|
|
148
|
-
if ('data' in
|
|
147
|
+
const response = await getData(config, props.resource.id, page, sortConfig)
|
|
148
|
+
if ('data' in response && response.data && response.data.length > 0) {
|
|
149
149
|
// Update existing rows
|
|
150
|
-
rows.value =
|
|
151
|
-
columns.value = Object.keys(
|
|
152
|
-
rowCount.value =
|
|
150
|
+
rows.value = response.data
|
|
151
|
+
columns.value = Object.keys(response.data[0]).filter(item => item !== '__id')
|
|
152
|
+
rowCount.value = response.meta.total
|
|
153
153
|
currentPage.value = page
|
|
154
154
|
loading.value = false
|
|
155
155
|
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
>
|
|
6
6
|
<header
|
|
7
7
|
:id="resourceHeaderId"
|
|
8
|
-
class="fr-p-4v flex flex-wrap gap-4 items-center justify-between relative"
|
|
8
|
+
class="fr-p-4v flex flex-wrap md:flex-nowrap gap-4 items-center justify-between relative"
|
|
9
9
|
>
|
|
10
10
|
<div>
|
|
11
11
|
<div class="flex items-center fr-mb-1v">
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
>
|
|
16
16
|
<button
|
|
17
17
|
type="button"
|
|
18
|
-
class="fr-p-0 flex items-baseline text-base leading-
|
|
18
|
+
class="fr-p-0 flex items-baseline text-base text-left leading-tight font-normal"
|
|
19
19
|
data-testid="expand-button"
|
|
20
20
|
:aria-expanded="open"
|
|
21
21
|
@click="toggle"
|
|
@@ -4,9 +4,8 @@
|
|
|
4
4
|
class="inline-flex mb-0 items-baseline text-xs"
|
|
5
5
|
>
|
|
6
6
|
<Toggletip
|
|
7
|
-
|
|
7
|
+
:button-props="{ class: 'relative z-2 -ml-3 top-1 -my-3' }"
|
|
8
8
|
no-margin
|
|
9
|
-
class="relative z-2 -ml-3 top-1 -my-3"
|
|
10
9
|
>
|
|
11
10
|
<template #toggletip="{ close }">
|
|
12
11
|
<div class="flex justify-between border-bottom">
|
|
@@ -100,13 +99,16 @@ import { useI18n } from 'vue-i18n'
|
|
|
100
99
|
import type { Resource } from '../../types/resources'
|
|
101
100
|
import Toggletip from '../Toggletip.vue'
|
|
102
101
|
import type { RegisteredSchema, ValidataError } from '../../functions/schemas'
|
|
103
|
-
import { findSchemaInCatalog,
|
|
102
|
+
import { findSchemaInCatalog, useGetCatalog, useGetSchemaDocumentation, useGetSchemaValidationUrl } from '../../functions/schemas'
|
|
104
103
|
|
|
105
104
|
const props = defineProps<{
|
|
106
105
|
resource: Resource
|
|
107
106
|
}>()
|
|
108
107
|
|
|
109
108
|
const { t } = useI18n()
|
|
109
|
+
const getSchemaValidationUrl = useGetSchemaValidationUrl()
|
|
110
|
+
const getSchemaDocumentation = useGetSchemaDocumentation()
|
|
111
|
+
const getCatalog = useGetCatalog()
|
|
110
112
|
|
|
111
113
|
const catalog = ref<Array<RegisteredSchema> | null>(null)
|
|
112
114
|
onMounted(async () => {
|
|
@@ -87,17 +87,17 @@ const shouldLoadXml = computed(() => {
|
|
|
87
87
|
return false
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
-
// Check if
|
|
91
|
-
if (!config.
|
|
90
|
+
// Check if maxXmlPreviewCharSize is configured
|
|
91
|
+
if (!config.maxXmlPreviewCharSize) {
|
|
92
92
|
// If no limit is set, don't load unknown files
|
|
93
93
|
return false
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
// Convert
|
|
96
|
+
// Convert maxXmlPreviewCharSize from characters to bytes (rough estimate)
|
|
97
97
|
// Assuming average 1 byte per character for XML
|
|
98
|
-
const
|
|
98
|
+
const maxByteSize = config.maxXmlPreviewCharSize
|
|
99
99
|
|
|
100
|
-
return size <=
|
|
100
|
+
return size <= maxByteSize
|
|
101
101
|
})
|
|
102
102
|
|
|
103
103
|
const fetchXmlData = async () => {
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
:class="{
|
|
5
5
|
'tabs-sm': size === 'sm',
|
|
6
6
|
}"
|
|
7
|
+
:default-index="props.defaultIndex"
|
|
8
|
+
@change="onChange"
|
|
7
9
|
>
|
|
8
10
|
<slot />
|
|
9
11
|
</TabGroup>
|
|
@@ -12,9 +14,19 @@
|
|
|
12
14
|
<script setup lang="ts">
|
|
13
15
|
import { TabGroup } from '@headlessui/vue'
|
|
14
16
|
|
|
15
|
-
withDefaults(defineProps<{
|
|
17
|
+
const props = withDefaults(defineProps<{
|
|
16
18
|
size?: 'sm' | 'md'
|
|
19
|
+
defaultIndex?: number
|
|
17
20
|
}>(), {
|
|
18
21
|
size: 'md',
|
|
22
|
+
defaultIndex: 0,
|
|
19
23
|
})
|
|
24
|
+
|
|
25
|
+
const emit = defineEmits<{
|
|
26
|
+
change: [value: number]
|
|
27
|
+
}>()
|
|
28
|
+
|
|
29
|
+
const onChange = (index: number) => {
|
|
30
|
+
emit('change', index)
|
|
31
|
+
}
|
|
20
32
|
</script>
|