-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDatasetCard.vue
200 lines (193 loc) · 6.76 KB
/
DatasetCard.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
<template>
<div class="fr-my-2w fr-p-2w border border-gray-default relative hover:bg-gray-some">
<div
v-if="dataset.private || dataset.archived"
class="absolute top-0 fr-grid-row fr-grid-row--middle fr-mt-n3v fr-ml-n1v"
>
<p
v-if="dataset.private"
class="fr-badge fr-badge--sm fr-badge--mention-grey text-gray-medium mr-2"
>
<span
class="fr-icon-lock-line fr-icon--sm"
aria-hidden="true"
/>
{{ t('Draft') }}
</p>
<p
v-if="dataset.archived"
class="fr-badge fr-badge--sm fr-badge--mention-grey text-gray-medium mr-2"
>
<span
class="fr-icon-archive-line fr-icon--sm"
aria-hidden="true"
/>
{{ t('Archived') }}
</p>
</div>
<div class="fr-grid-row fr-grid-row--gutters fr-grid-row--top">
<div class="fr-col-auto">
<div class="flex justify-center items-center p-3 border border-gray-lower bg-[#fff]">
<Placeholder
v-if="dataset.organization"
type="dataset"
:src="dataset.organization.logo_thumbnail"
alt=""
:size="40"
/>
<Avatar
v-else-if="dataset.owner"
:user="dataset.owner"
:size="40"
/>
<Placeholder
v-else
type="dataset"
:size="40"
/>
</div>
</div>
<div class="fr-col-12 fr-col-sm">
<h4 class="fr-text--md mb-0 fr-grid-row">
<slot
name="datasetUrl"
:dataset="dataset"
:dataset-url="datasetUrl"
>
<AppLink
:to="datasetUrl"
class="text-gray-800 text-base bg-none fr-grid-row"
>
<component
:is="config.textClamp"
v-if="config && config.textClamp"
class="fr-col"
:auto-resize="true"
:text="dataset.title"
:max-lines="1"
/>
<small
v-if="dataset.acronym"
class="fr-col-auto fr-ml-1w"
>{{ dataset.acronym }}</small>
<span class="absolute inset-0" />
</AppLink>
</slot>
</h4>
<div
v-if="dataset.organization || dataset.owner"
class="text-sm m-0 flex truncate"
>
<template v-if="dataset.organization">
<div class="-mr-1 flex-initial">
<AppLink
v-if="organizationUrl"
class="link text-sm flex items-center relative z-[2]"
:to="organizationUrl"
>
<OrganizationNameWithCertificate :organization="dataset.organization" />
</AppLink>
<OrganizationNameWithCertificate
v-else
:organization="dataset.organization"
/>
</div>
</template>
<div
v-else
class="mr-1 truncate"
>
{{ ownerName }}
</div>
<div class="text-gray-medium dash-before-sm whitespace-nowrap">
{{ $t('Updated {date}', { date: formatRelativeIfRecentDate(dataset.last_update, { dateStyle: 'medium' }) }) }}
</div>
</div>
<div class="mx-0 -mb-1 flex flex-wrap items-center text-sm text-gray-medium">
<div class="fr-hidden flex-sm dash-after-sm text-gray-500">
<DatasetQualityInline :quality="dataset.quality" />
</div>
<div class="fr-grid-row fr-grid-row--middle fr-mr-1v">
<p
class="fr-text--sm fr-my-0"
:aria-label="t('{n} resources downloads', dataset.metrics.resources_downloads)"
>
<span
class="fr-icon-download-line fr-icon--sm fr-px-1v"
aria-hidden="true"
/>{{ summarize(dataset.metrics.resources_downloads) }}
</p>
<p
class="fr-text--sm fr-my-0"
:aria-label="t('{n} followers', dataset.metrics.followers)"
>
<span
class="fr-icon-star-line fr-icon--sm fr-px-1v"
aria-hidden="true"
/>{{ summarize(dataset.metrics.followers) }}
</p>
<p
class="fr-text--sm fr-my-0"
:aria-label="t('{n} reuses', dataset.metrics.reuses)"
>
<span
class="fr-icon-line-chart-line fr-icon--sm fr-px-1v"
aria-hidden="true"
/>{{ summarize(dataset.metrics.reuses) }}
</p>
</div>
</div>
<component
:is="config.textClamp"
v-if="showDescription && config && config.textClamp && description"
class="fr-text--sm fr-mt-1w fr-mb-0 overflow-wrap-anywhere"
:auto-resize="true"
:text="description"
:max-lines="2"
/>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import type { RouteLocationRaw } from 'vue-router'
import { computed, ref, watchEffect } from 'vue'
import type { Dataset, DatasetV2 } from '../types/datasets'
import { summarize } from '../functions/helpers'
import { formatRelativeIfRecentDate } from '../functions/dates'
import { getOwnerName } from '../functions/owned'
import { removeMarkdown } from '../functions/markdown'
import { useComponentsConfig } from '../config'
import DatasetQualityInline from './DatasetQualityInline.vue'
import Avatar from './Avatar.vue'
import Placeholder from './Placeholder.vue'
import OrganizationNameWithCertificate from './OrganizationNameWithCertificate.vue'
import AppLink from './AppLink.vue'
type Props = {
dataset: Dataset | DatasetV2
/**
* The datasetUrl is a route location object to allow Vue Router to navigate to the details of a dataset.
* It is used as a separate prop to allow other sites using the package to define their own dataset pages.
*/
datasetUrl: RouteLocationRaw
/**
* The organizationUrl is an optional route location object to allow Vue Router to navigate to the details of the organization linked to tha dataset.
* It is used as a separate prop to allow other sites using the package to define their own organization pages.
*/
organizationUrl?: RouteLocationRaw
showDescription?: boolean
}
const props = withDefaults(defineProps<Props>(), {
style: () => ({}),
showDescription: true,
})
const { t } = useI18n()
const ownerName = computed(() => getOwnerName(props.dataset))
const config = useComponentsConfig()
const description = ref('')
watchEffect(async () => {
if (!props.showDescription) return
description.value = await removeMarkdown(props.dataset.description)
})
</script>